mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
Merge commit '043518cce67dbcdf345684faacb9aedc54784bda'
* commit '043518cce67dbcdf345684faacb9aedc54784bda': (28 commits) ASoC: rockchip: multi-dais: Add legacy_dai_naming flag arm64: dts: rockchip: rk3588 boards: fix maximum-speed for usbdp node dt-bindings: opp: rockchip: Document rockchip,pvtpll soc: rockchip: opp_select: Add support to parse rockchip,pvtpll soc: rockchip: opp_select: Add support to parse cci grf dt-bindings: opp: rockchip: Document CCI GRF soc: rockchip: opp_select: Fix clk error for normal pll clk soc: rockchip: opp_select: Add support to set regulator helper init: Add CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK mm: memblock: fix only first memblock be freed. arm64: dts: rockchip: AMP memory use reserved-memory media: i2c: rk628: add hdmirx extcon drm/panel: panel-simple: Don't init gpio value at probe ASoC: rockchip: multicodec: Fix err path for adc-key ASoC: rockchip: spdifrx: Add legacy_dai_naming flag spi: spidev-rkslv: Fix compiler error media: i2c: ov8865: add camera driver media: i2c: add vcm driver ces6301 media: i2c: s5k3l8xx: adjust power sequence to suit spec media: i2c: gc05a2: adjust power sequence to suit spec ... Change-Id: I50aa93e3b8048e85dd446acd4922518652c05a1c
This commit is contained in:
@@ -51,6 +51,7 @@ In 'operating-points-v2' table:
|
||||
|
||||
- rockchip,grf: The phandle of the syscon node for GRF register.
|
||||
- rockchip,dsu-grf: the phandle of the syscon node for DSU GRF register.
|
||||
- rockchip,cci-grf: the phandle of the syscon node for CCI GRF register.
|
||||
- rockchip,opp-clocks: List of clocks for accessing pvtpll and read margin.
|
||||
- volt-mem-read-margin: The property is an array of 2-tuples items, and
|
||||
each item consists voltage an memory read margin like
|
||||
@@ -61,6 +62,7 @@ In 'operating-points-v2' table:
|
||||
target frequency less than the threshold frequency,
|
||||
there may be no need to set intermediate rate.
|
||||
|
||||
- rockchip,pvtpll: The phandle of the syscon node for PVTPLL register.
|
||||
- rockchip,pvtpll-table: The property is an array of 5-tuples items, and
|
||||
each item consists frequency and pvtpll config like
|
||||
<freq_khz ring length low_temp_ring low_temp_length>,
|
||||
|
||||
@@ -10,10 +10,15 @@
|
||||
#include "rk3562-amp.dtsi"
|
||||
|
||||
/ {
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x02000000 0x0 0x06400000>,
|
||||
<0x0 0x0a200000 0x0 0xf1e00000>;
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
amp_reserved: amp@800000 {
|
||||
reg = <0x0 0x00800000 0x0 0x01800000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -11,10 +11,15 @@
|
||||
#include "rk3562-amp.dtsi"
|
||||
|
||||
/ {
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x02000000 0x0 0x04b80000>,
|
||||
<0x0 0x0a200000 0x0 0x75e00000>;
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
amp_reserved: amp@800000 {
|
||||
reg = <0x0 0x00800000 0x0 0x01800000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
model = "Rockchip RK3566 EVB MIPITEST V10 Board";
|
||||
compatible = "rockchip,rk3566-evb-mipitest-v10", "rockchip,rk3566";
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
model = "Rockchip RK3566 EVB1 DDR4 V10 Board";
|
||||
compatible = "rockchip,rk3566-evb1-ddr4-v10", "rockchip,rk3566";
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
model = "Rockchip RK3566 EVB5 LP4X V10 Board";
|
||||
compatible = "rockchip,rk3566-evb5-lp4x-v10", "rockchip,rk3566";
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -8,10 +8,15 @@
|
||||
#include "rk3568-amp.dtsi"
|
||||
|
||||
/ {
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x03880000 0x0 0x04b80000>,
|
||||
<0x0 0x0a200000 0x0 0x75e00000>;
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
amp_reserved: amp@1800000 {
|
||||
reg = <0x0 0x01800000 0x0 0x01800000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
@@ -43,7 +43,7 @@
|
||||
vin-supply = <&dc_12v>;
|
||||
};
|
||||
|
||||
qsgmii_3v3: gpio-regulator {
|
||||
qsgmii_3v3: qsgmii-3v3 {
|
||||
compatible = "regulator-gpio";
|
||||
regulator-name = "qsgmii_3v3";
|
||||
regulator-min-microvolt = <0100000>;
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
pinctrl-0 = <&hp_det>;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
pcie30_3v3: gpio-regulator {
|
||||
pcie30_3v3: pcie30-3v3 {
|
||||
compatible = "regulator-gpio";
|
||||
regulator-name = "pcie30_3v3";
|
||||
regulator-min-microvolt = <100000>;
|
||||
@@ -80,7 +80,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
vcc3v3_pcie: gpio-regulator {
|
||||
vcc3v3_pcie: vcc3v3-pcie {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
pcie20_3v3: gpio-regulator {
|
||||
pcie20_3v3: pcie20-3v3 {
|
||||
compatible = "regulator-gpio";
|
||||
regulator-name = "pcie20_3v3";
|
||||
regulator-min-microvolt = <100000>;
|
||||
@@ -97,7 +97,7 @@
|
||||
vin-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
|
||||
pcie30_3v3: gpio-regulator {
|
||||
pcie30_3v3: pcie30-3v3 {
|
||||
compatible = "regulator-gpio";
|
||||
regulator-name = "pcie30_3v3";
|
||||
regulator-min-microvolt = <100000>;
|
||||
|
||||
@@ -23,12 +23,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x02000000 0x0 0x06400000>,
|
||||
<0x0 0x09400000 0x0 0xe6c00000>,
|
||||
<0x1 0x00000000 0x1 0x00000000>,
|
||||
<0x2 0xf0000000 0x0 0x10000000>;
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
amp_reserved: amp@800000 {
|
||||
reg = <0x0 0x00800000 0x0 0x01800000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -828,6 +828,7 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1 {
|
||||
maximum-speed = "high-speed";
|
||||
rockchip,dp-lane-mux = <3 2 1 0>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -837,7 +838,6 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1_u3 {
|
||||
maximum-speed = "high-speed";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -795,6 +795,7 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1 {
|
||||
maximum-speed = "high-speed";
|
||||
rockchip,dp-lane-mux = < 0 1 2 3 >;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -804,7 +805,6 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1_u3 {
|
||||
maximum-speed = "high-speed";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -368,6 +368,7 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1 {
|
||||
maximum-speed = "high-speed";
|
||||
rockchip,dp-lane-mux = <3 2 1 0>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -377,7 +378,6 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1_u3 {
|
||||
maximum-speed = "high-speed";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -388,6 +388,7 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1 {
|
||||
maximum-speed = "high-speed";
|
||||
rockchip,dp-lane-mux = <3 2 1 0>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -397,7 +398,6 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1_u3 {
|
||||
maximum-speed = "high-speed";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -647,6 +647,7 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1 {
|
||||
maximum-speed = "high-speed";
|
||||
rockchip,dp-lane-mux = <3 2 1 0>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -656,7 +657,6 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1_u3 {
|
||||
maximum-speed = "high-speed";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1 {
|
||||
maximum-speed = "high-speed";
|
||||
rockchip,dp-lane-mux = <3 2 1 0>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -233,7 +234,6 @@
|
||||
};
|
||||
|
||||
&usbdp_phy1_u3 {
|
||||
maximum-speed = "high-speed";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -585,8 +585,8 @@ static int panel_simple_suspend(struct device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(p->reset_gpio, 1);
|
||||
gpiod_set_value_cansleep(p->enable_gpio, 0);
|
||||
gpiod_direction_output(p->reset_gpio, 1);
|
||||
gpiod_direction_output(p->enable_gpio, 0);
|
||||
|
||||
panel_simple_regulator_disable(p);
|
||||
|
||||
@@ -630,7 +630,7 @@ static int panel_simple_resume(struct device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(p->enable_gpio, 1);
|
||||
gpiod_direction_output(p->enable_gpio, 1);
|
||||
|
||||
if (p->desc->delay.prepare)
|
||||
panel_simple_msleep(p->desc->delay.prepare);
|
||||
@@ -642,12 +642,12 @@ static int panel_simple_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(p->reset_gpio, 1);
|
||||
gpiod_direction_output(p->reset_gpio, 1);
|
||||
|
||||
if (p->desc->delay.reset)
|
||||
panel_simple_msleep(p->desc->delay.reset);
|
||||
|
||||
gpiod_set_value_cansleep(p->reset_gpio, 0);
|
||||
gpiod_direction_output(p->reset_gpio, 0);
|
||||
|
||||
if (p->desc->delay.init)
|
||||
panel_simple_msleep(p->desc->delay.init);
|
||||
|
||||
@@ -198,6 +198,8 @@ config TOUCHSCREEN_CHIPONE_ICN8505
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called chipone_icn8505.
|
||||
|
||||
source "drivers/input/touchscreen/chipone_tddi/Kconfig"
|
||||
|
||||
config TOUCHSCREEN_CY8CTMA140
|
||||
tristate "cy8ctma140 touchscreen"
|
||||
depends on I2C
|
||||
|
||||
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_BU21029) += bu21029_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8505) += chipone_icn8505.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_9551R) += chipone_tddi/
|
||||
obj-$(CONFIG_TOUCHSCREEN_CY8CTMA140) += cy8ctma140.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o
|
||||
|
||||
12
drivers/input/touchscreen/chipone_tddi/Kconfig
Normal file
12
drivers/input/touchscreen/chipone_tddi/Kconfig
Normal file
@@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# chipone Touchscreen driver configuration
|
||||
#
|
||||
|
||||
config TOUCHSCREEN_CHIPONE_9551R
|
||||
tristate "chipone Touchscreen"
|
||||
depends on I2C
|
||||
default n
|
||||
help
|
||||
Say Y here if you have chipone touch panel.
|
||||
If unsure, say N.
|
||||
17
drivers/input/touchscreen/chipone_tddi/Makefile
Normal file
17
drivers/input/touchscreen/chipone_tddi/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_9551R) += chipone-ts.o
|
||||
chipone-ts-y += cts_driver.o
|
||||
chipone-ts-y += cts_core.o
|
||||
chipone-ts-y += cts_sfctrlv2.o
|
||||
chipone-ts-y += cts_spi_flash.o
|
||||
chipone-ts-y += cts_firmware.o
|
||||
chipone-ts-y += cts_test.o
|
||||
chipone-ts-y += cts_charger_detect.o
|
||||
chipone-ts-y += cts_earjack_detect.o
|
||||
chipone-ts-y += cts_tcs.o
|
||||
chipone-ts-y += cts_platform.o
|
||||
chipone-ts-y += cts_tool.o
|
||||
chipone-ts-y += cts_sysfs.o
|
||||
chipone-ts-y += cts_strerror.o
|
||||
chipone-ts-y += cts_oem.o
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
static u8 icnl9951_driver_builtin_firmware[] = {
|
||||
};
|
||||
|
||||
static u8 icnl9951r_driver_builtin_firmware[] = {
|
||||
};
|
||||
|
||||
static struct cts_firmware cts_driver_builtin_firmwares[] = {
|
||||
{
|
||||
.name = "OEM-Project", /* MUST set non-NULL */
|
||||
.hwid = CTS_DEV_HWID_ICNL9951,
|
||||
.fwid = CTS_DEV_FWID_ICNL9951,
|
||||
.data = icnl9951_driver_builtin_firmware,
|
||||
.size = ARRAY_SIZE(icnl9951_driver_builtin_firmware),
|
||||
},
|
||||
{
|
||||
.name = "OEM-Project", /* MUST set non-NULL */
|
||||
.hwid = CTS_DEV_HWID_ICNL9951R,
|
||||
.fwid = CTS_DEV_FWID_ICNL9951R,
|
||||
.data = icnl9951r_driver_builtin_firmware,
|
||||
.size = ARRAY_SIZE(icnl9951r_driver_builtin_firmware),
|
||||
},
|
||||
|
||||
};
|
||||
1024
drivers/input/touchscreen/chipone_tddi/cts_charger_detect.c
Normal file
1024
drivers/input/touchscreen/chipone_tddi/cts_charger_detect.c
Normal file
File diff suppressed because it is too large
Load Diff
45
drivers/input/touchscreen/chipone_tddi/cts_charger_detect.h
Normal file
45
drivers/input/touchscreen/chipone_tddi/cts_charger_detect.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_CHARGER_DETECT_H
|
||||
#define CTS_CHARGER_DETECT_H
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
struct chipone_ts_data;
|
||||
|
||||
#ifdef CONFIG_CTS_CHARGER_DETECT
|
||||
extern int cts_charger_detect_init(struct chipone_ts_data *cts_data);
|
||||
extern int cts_charger_detect_deinit(struct chipone_ts_data *cts_data);
|
||||
extern int cts_start_charger_detect(struct chipone_ts_data *cts_data);
|
||||
extern int cts_stop_charger_detect(struct chipone_ts_data *cts_data);
|
||||
extern int cts_is_charger_attached(struct chipone_ts_data *cts_data,
|
||||
bool *attached);
|
||||
#else /* CONFIG_CTS_CHARGER_DETECT */
|
||||
static inline int cts_charger_detect_init(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int cts_charger_detect_deinit(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int cts_start_charger_detect(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int cts_stop_charger_detect(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int cts_is_charger_attached(struct chipone_ts_data *cts_data,
|
||||
bool *attached)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_CTS_CHARGER_DETECT */
|
||||
|
||||
#endif /* CTS_CHARGER_DETECT_H */
|
||||
242
drivers/input/touchscreen/chipone_tddi/cts_config.h
Normal file
242
drivers/input/touchscreen/chipone_tddi/cts_config.h
Normal file
@@ -0,0 +1,242 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_CONFIG_H
|
||||
#define CTS_CONFIG_H
|
||||
|
||||
/** Driver version */
|
||||
#define CFG_CTS_DRIVER_MAJOR_VERSION 3
|
||||
#define CFG_CTS_DRIVER_MINOR_VERSION 6
|
||||
#define CFG_CTS_DRIVER_PATCH_VERSION 3
|
||||
#define CFG_CTS_DRIVER_VERSION "v3.6.3"
|
||||
|
||||
/* Support Mediatek TPD arch */
|
||||
/* #define CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED */
|
||||
|
||||
/* Support Spreadtrum platform */
|
||||
#define CFG_CTS_PLATFORM_SPRD_SUPPORTED
|
||||
|
||||
/* Support cascade application */
|
||||
//#define CFG_CTS_CASCADE_SUPPORTED
|
||||
|
||||
/* Support RK dsi extcon notifier for suspend and resume */
|
||||
#define CONFIG_PM_DSI_EXTCON_NOTIFIER
|
||||
|
||||
/* Support both finger and stylus protocol, 11 */
|
||||
// #define CFG_CTS_FINGER_STYLUS_SUPPORTED
|
||||
|
||||
/* #define CFG_CTS_STYLUS_BTN_SUPPORTED */
|
||||
|
||||
#define CONFIG_CTS_I2C_HOST
|
||||
|
||||
/* For Goole Security */
|
||||
#define CFG_CTS_FOR_GKI
|
||||
|
||||
/** Whether reset pin is used */
|
||||
#define CFG_CTS_HAS_RESET_PIN
|
||||
|
||||
#ifndef CONFIG_CTS_I2C_HOST
|
||||
#ifndef CFG_CTS_HAS_RESET_PIN
|
||||
#define CFG_CTS_HAS_RESET_PIN
|
||||
#endif
|
||||
#define CFG_CTS_SPI_SPEED_KHZ 9600
|
||||
#endif /* CONFIG_CTS_I2C_HOST */
|
||||
|
||||
/* #define CFG_CTS_FORCE_UP */
|
||||
|
||||
/* #define CFG_CTS_HEARTBEAT_MECHANISM */
|
||||
|
||||
/* #define CFG_CTS_PALM_DETECT */
|
||||
#ifdef CFG_CTS_PALM_DETECT
|
||||
#define CFG_CTS_PALM_EVENT 240
|
||||
#define CFG_CTS_PALM_ID 0x80
|
||||
#endif
|
||||
|
||||
#define CONFIG_GENERIC_HARDIRQS
|
||||
|
||||
/** Whether force download firmware to chip */
|
||||
/* #define CFG_CTS_FIRMWARE_FORCE_UPDATE */
|
||||
|
||||
/** Use build in firmware or firmware file in fs*/
|
||||
#define CFG_CTS_DRIVER_BUILTIN_FIRMWARE
|
||||
#define CFG_CTS_FIRMWARE_IN_FS
|
||||
#ifdef CFG_CTS_FIRMWARE_IN_FS
|
||||
/* #define CFG_CTS_FW_UPDATE_SYS */
|
||||
#define CFG_CTS_FIRMWARE_FILENAME "chipone_firmware.bin"
|
||||
#endif /* CFG_CTS_FIRMWARE_IN_FS */
|
||||
|
||||
#define CFG_CTS_FIRMWARE_SIZE (120 * 1024)
|
||||
#define CFG_CTS_FACTORY_LIMIT_FILENAME "chipone_limit.bin"
|
||||
|
||||
/* IC type support */
|
||||
#define CFG_CTS_CHIP_NAME "CHIPONE-TDDI"
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/* Proc FS for backward compatibility for APK tool com.ICN85xx */
|
||||
#define CONFIG_CTS_LEGACY_TOOL
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
/* Sys FS for gesture report, debug feature etc. */
|
||||
#define CONFIG_CTS_SYSFS
|
||||
#endif /* CONFIG_SYSFS */
|
||||
|
||||
#define CFG_CTS_MAX_TOUCH_NUM (10)
|
||||
#define CFG_CTS_MAX_STYLUS_NUM (4)
|
||||
|
||||
/* Virtual key support */
|
||||
/* #define CONFIG_CTS_VIRTUALKEY */
|
||||
#ifdef CONFIG_CTS_VIRTUALKEY
|
||||
#define CFG_CTS_MAX_VKEY_NUM (4)
|
||||
#define CFG_CTS_NUM_VKEY (3)
|
||||
#define CFG_CTS_VKEY_KEYCODES {KEY_BACK, KEY_HOME, KEY_MENU}
|
||||
#endif /* CONFIG_CTS_VIRTUALKEY */
|
||||
|
||||
/* Gesture wakeup */
|
||||
#define CFG_CTS_GESTURE
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
#define GESTURE_UP 0x11
|
||||
#define GESTURE_C 0x12
|
||||
#define GESTURE_O 0x13
|
||||
#define GESTURE_M 0x14
|
||||
#define GESTURE_W 0x15
|
||||
#define GESTURE_E 0x16
|
||||
#define GESTURE_S 0x17
|
||||
#define GESTURE_Z 0x1d
|
||||
#define GESTURE_V 0x1e
|
||||
#define GESTURE_D_TAP 0x50
|
||||
#define GESTURE_DOWN 0x22
|
||||
#define GESTURE_LEFT 0x23
|
||||
#define GESTURE_RIGHT 0x24
|
||||
#define GESTURE_TAP 0x7f
|
||||
|
||||
#define CFG_CTS_NUM_GESTURE (14u)
|
||||
#define CFG_CTS_GESTURE_REPORT_KEY
|
||||
#define CFG_CTS_GESTURE_KEYMAP \
|
||||
{ \
|
||||
{ GESTURE_C, KEY_C,}, \
|
||||
{ GESTURE_W, KEY_W,}, \
|
||||
{ GESTURE_V, KEY_V,}, \
|
||||
{ GESTURE_D_TAP, KEY_F1,}, \
|
||||
{ GESTURE_Z, KEY_Z,}, \
|
||||
{ GESTURE_M, KEY_M,}, \
|
||||
{ GESTURE_O, KEY_O,}, \
|
||||
{ GESTURE_E, KEY_E,}, \
|
||||
{ GESTURE_S, KEY_S,}, \
|
||||
{ GESTURE_UP, KEY_UP,}, \
|
||||
{ GESTURE_DOWN, KEY_DOWN,}, \
|
||||
{ GESTURE_LEFT, KEY_LEFT,}, \
|
||||
{ GESTURE_RIGHT, KEY_RIGHT,}, \
|
||||
{ GESTURE_TAP, KEY_F2,}, \
|
||||
}
|
||||
#define CFG_CTS_GESTURE_REPORT_TRACE 0
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
#define CONFIG_CTS_GLOVE
|
||||
//#define CONFIG_CTS_EARJACK_DETECT
|
||||
//#define CONFIG_CTS_CHARGER_DETECT
|
||||
|
||||
/* #define CONFIG_CTS_TP_PROXIMITY */
|
||||
|
||||
/* ESD protection */
|
||||
//#define CONFIG_CTS_ESD_PROTECTION
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
#define CFG_CTS_ESD_PROTECTION_CHECK_PERIOD (2 * HZ)
|
||||
#define CFG_CTS_ESD_FAILED_CONFIRM_CNT 3
|
||||
#endif /* CONFIG_CTS_ESD_PROTECTION */
|
||||
|
||||
/* Use slot protocol (protocol B), comment it if use protocol A. */
|
||||
#define CONFIG_CTS_SLOTPROTOCOL
|
||||
|
||||
/* #define CTS_CONFIG_MKDIR_FOR_CTS_TEST */
|
||||
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
#define CFG_CTS_TOOL_PROC_FILENAME "cts_tool"
|
||||
#endif /* CONFIG_CTS_LEGACY_TOOL */
|
||||
|
||||
#define CFG_CTS_UPDATE_CRCCHECK
|
||||
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#define CONFIG_CTS_OF
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
||||
/****************************************************************************
|
||||
* MTK Platform configurations
|
||||
****************************************************************************/
|
||||
#ifdef CONFIG_MTK_I2C_EXTENSION
|
||||
#define TPD_SUPPORT_I2C_DMA
|
||||
#define CFG_CTS_MAX_I2C_XFER_SIZE (250)
|
||||
#define CFG_CTS_MAX_I2C_FIFO_XFER_SIZE (8)
|
||||
#else
|
||||
#define CFG_CTS_MAX_I2C_XFER_SIZE (128)
|
||||
#endif /* CONFIG_MTK_I2C_EXTENSION */
|
||||
|
||||
#define CFG_CTS_MAX_I2C_READ_SIZE (8192u)
|
||||
#define CFG_CTS_MAX_SPI_XFER_SIZE (8192u)
|
||||
#define CFG_CTS_INT_DATA_MAX_SIZE (8192u)
|
||||
|
||||
#define CTS_FW_LOG_REDIRECT_SIGN 0x60
|
||||
#define CTS_FW_LOG_BUF_LEN 128
|
||||
|
||||
//#define CFG_MTK_LEGEND_PLATFORM
|
||||
|
||||
#define CFG_CTS_DEVICE_NAME TPD_DEVICE
|
||||
#define CFG_CTS_DRIVER_NAME "chipone-tddi"
|
||||
|
||||
#ifdef CONFIG_CTS_OF
|
||||
#define CFG_CTS_OF_DEVICE_ID_NAME "mediatek,cap_touch"
|
||||
#endif /* CONFIG_CTS_OF */
|
||||
|
||||
#else /* CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED */
|
||||
/****************************************************************************
|
||||
* QCOM Platform configurations
|
||||
****************************************************************************/
|
||||
#ifndef CFG_CTS_PLATFORM_SPRD_SUPPORTED
|
||||
#define CONFIG_CTS_PM_FB_NOTIFIER
|
||||
#endif
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
#ifdef CONFIG_DRM
|
||||
#define CFG_CTS_DRM_NOTIFIER
|
||||
#endif /*CONFIG_DRM */
|
||||
#else /*CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_SUSPEND)
|
||||
/* #define CONFIG_CTS_PM_GENERIC */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
#ifndef CONFIG_CTS_PM_GENERIC
|
||||
#define CONFIG_CTS_PM_LEGACY
|
||||
#endif /*CONFIG_CTS_PM_GENERIC */
|
||||
#endif /*CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
|
||||
#define CFG_CTS_MAX_I2C_XFER_SIZE (48u)
|
||||
#define CFG_CTS_MAX_I2C_READ_SIZE (8192u)
|
||||
#define CFG_CTS_MAX_SPI_XFER_SIZE (8192u)
|
||||
#define CFG_CTS_INT_DATA_MAX_SIZE (8192u)
|
||||
|
||||
#define CTS_FW_LOG_REDIRECT_SIGN 0x60
|
||||
#define CTS_FW_LOG_BUF_LEN 128
|
||||
|
||||
#define CFG_CTS_DEVICE_NAME "chipone-tddi"
|
||||
#define CFG_CTS_DRIVER_NAME "chipone-tddi"
|
||||
|
||||
#ifdef CONFIG_CTS_OF
|
||||
#define CFG_CTS_OF_DEVICE_ID_NAME "chipone-tddi"
|
||||
#define CFG_CTS_OF_INT_GPIO_NAME "chipone,irq-gpio"
|
||||
#define CFG_CTS_OF_RST_GPIO_NAME "chipone,rst-gpio"
|
||||
|
||||
#ifdef CFG_CTS_MANUAL_CS
|
||||
#define CFG_CTS_OF_CS_GPIO_NAME "chipone,cs-gpio"
|
||||
#endif
|
||||
|
||||
#define CFG_CTS_OF_X_RESOLUTION_NAME "chipone,x-res"
|
||||
#define CFG_CTS_OF_Y_RESOLUTION_NAME "chipone,y-res"
|
||||
|
||||
#ifdef CFG_CTS_FW_UPDATE_SYS
|
||||
#define CFG_CTS_OF_PANEL_SUPPLIER "chipone,panel-supplier"
|
||||
#endif
|
||||
#endif /* CONFIG_CTS_OF */
|
||||
|
||||
#endif /* CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED */
|
||||
|
||||
#endif /* CTS_CONFIG_H */
|
||||
2874
drivers/input/touchscreen/chipone_tddi/cts_core.c
Normal file
2874
drivers/input/touchscreen/chipone_tddi/cts_core.c
Normal file
File diff suppressed because it is too large
Load Diff
988
drivers/input/touchscreen/chipone_tddi/cts_core.h
Normal file
988
drivers/input/touchscreen/chipone_tddi/cts_core.h
Normal file
@@ -0,0 +1,988 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_CORE_H
|
||||
#define CTS_CORE_H
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
enum cts_dev_hw_reg {
|
||||
CTS_DEV_HW_REG_HARDWARE_ID = 0x70000u,
|
||||
CTS_DEV_HW_REG_CLOCK_GATING = 0x70004u,
|
||||
CTS_DEV_HW_REG_RESET_CONFIG = 0x70008u,
|
||||
CTS_DEV_HW_REG_SW_RST_CTRL = 0x7000Au,
|
||||
CTS_DEV_HW_REG_BOOT_MODE = 0x70010u,
|
||||
CTS_DEV_HW_REG_CURRENT_MODE = 0x70011u,
|
||||
CTS_DEV_HW_REG_DDI_REG_CTRL = 0x7002Cu,
|
||||
CTS_DEV_HW_REG_CLK_DIV_CFG = 0x70033u,
|
||||
CTS_DEV_HW_REG_HPPROG = 0x70074u,
|
||||
CTS_DEV_HW_REG_SET_RESET = 0x700F8u,
|
||||
CTS_DEV_HW_REG_HW_STATUS = 0x7401Bu,
|
||||
CTS_DEV_HW_REG_I2C_CFG = 0x77001u,
|
||||
CTS_DEV_HW_REG_SPI_CFG = 0x78438u,
|
||||
};
|
||||
|
||||
enum cts_dev_boot_mode {
|
||||
CTS_DEV_BOOT_MODE_IDLE = 0,
|
||||
CTS_DEV_BOOT_MODE_FLASH = 1,
|
||||
CTS_DEV_BOOT_MODE_I2C_PRG_9911C = 2,
|
||||
CTS_DEV_BOOT_MODE_TCH_PRG_9916 = 2,
|
||||
CTS_DEV_BOOT_MODE_SRAM = 3,
|
||||
CTS_DEV_BOOT_MODE_DDI_PRG = 4,
|
||||
CTS_DEV_BOOT_MODE_SPI_PRG_9911C = 5,
|
||||
CTS_DEV_BOOT_MODE_MASK = 7,
|
||||
};
|
||||
|
||||
/* ICNL9951/ICNL9951R */
|
||||
#define CTS_PWR_MODE_ACTIVE (0x00)
|
||||
#define CTS_PWR_MODE_MNT (0x01)
|
||||
#define CTS_PWR_MODE_HIBERNATE (0x02)
|
||||
#define CTS_PWR_MODE_GSTR_WAKEUP (0x03)
|
||||
#define CTS_PWR_MODE_MNT_DBG (0x04)
|
||||
#define CTS_PWR_MODE_GSTR_DBG (0x05)
|
||||
#define CTS_PWR_MODE_WAIT_TO_HIBERNATE (0x06)
|
||||
#define CTS_PWR_MODE_WAIT_TO_GSTR (0x07)
|
||||
|
||||
//Krang work mode value
|
||||
#define CTS_KRANG_NORMAL_MODE (0x00)
|
||||
#define CTS_KRANG_STY_DBG_MODE (0x01)
|
||||
#define CTS_KRANG_FIN_DBG_MODE (0x02)
|
||||
#define CTS_KRANG_MNT_DBG_MODE (0x03)
|
||||
#define CTS_KRANG_GS_DBG_MODE (0x04)
|
||||
#define CTS_KRANG_OPEN_SHORT_DET_MODE (0x05)
|
||||
#define CTS_KRANG_CFG_MODE (0x06)
|
||||
#define CTS_KRANG_TEST_MODE (0x07)
|
||||
#define CTS_KRANG_DEF_MODE (0x08)
|
||||
|
||||
/** I2C addresses(7bits), transfer size and bitrate */
|
||||
#define CTS_DEV_NORMAL_MODE_I2CADDR (0x48)
|
||||
#define CTS_DEV_PROGRAM_MODE_I2CADDR (0x30)
|
||||
#define CTS_DEV_NORMAL_MODE_ADDR_WIDTH (2)
|
||||
#define CTS_DEV_PROGRAM_MODE_ADDR_WIDTH (3)
|
||||
#define CTS_DEV_NORMAL_MODE_SPIADDR (0xF0)
|
||||
#define CTS_DEV_PROGRAM_MODE_SPIADDR (0x60)
|
||||
|
||||
/** Chipone firmware register addresses under normal mode */
|
||||
enum cts_device_fw_reg {
|
||||
CTS_DEVICE_FW_REG_WORK_MODE = 0x0000,
|
||||
CTS_DEVICE_FW_REG_SYS_BUSY = 0x0001,
|
||||
CTS_DEVICE_FW_REG_DATA_READY = 0x0002,
|
||||
CTS_DEVICE_FW_REG_CMD = 0x0004,
|
||||
CTS_DEVICE_FW_REG_POWER_MODE = 0x0005,
|
||||
CTS_DEVICE_FW_REG_FW_LIB_MAIN_VERSION = 0x0009,
|
||||
CTS_DEVICE_FW_REG_CHIP_TYPE = 0x000A,
|
||||
CTS_DEVICE_FW_REG_VERSION = 0x000C,
|
||||
CTS_DEVICE_FW_REG_DDI_VERSION = 0x0010,
|
||||
CTS_DEVICE_FW_REG_GET_WORK_MODE = 0x003F,
|
||||
CTS_DEVICE_FW_REG_FW_LIB_SUB_VERSION = 0x0047,
|
||||
CTS_DEVICE_FW_REG_COMPENSATE_CAP_READY = 0x004E,
|
||||
|
||||
CTS_DEVICE_FW_REG_TOUCH_INFO = 0x1000,
|
||||
CTS_DEVICE_FW_REG_RAW_DATA = 0x2000,
|
||||
CTS_DEVICE_FW_REG_DIFF_DATA = 0x3000,
|
||||
CTS_DEVICE_FW_REG_GESTURE_INFO = 0x7000,
|
||||
CTS_DEVICE_FW_REG_PANEL_PARAM = 0x8000,
|
||||
CTS_DEVICE_FW_REG_NUM_TX = 0x8007,
|
||||
CTS_DEVICE_FW_REG_NUM_RX = 0x8008,
|
||||
CTS_DEVICE_FW_REG_INT_KEEP_TIME = 0x8047,
|
||||
CTS_DEVICE_FW_REG_RAWDATA_TARGET = 0x8049,
|
||||
CTS_DEVICE_FW_REG_X_RESOLUTION = 0x8090,
|
||||
CTS_DEVICE_FW_REG_Y_RESOLUTION = 0x8092,
|
||||
CTS_DEVICE_FW_REG_SWAP_AXES = 0x8094,
|
||||
CTS_DEVICE_FW_REG_GLOVE_MODE = 0x8095,
|
||||
CTS_DEVICE_FW_REG_TEST_WITH_DISPLAY_ON = 0x80A3,
|
||||
CTS_DEVICE_FW_REG_INT_MODE = 0x80D8,
|
||||
CTS_DEVICE_FW_REG_EARJACK_DETECT_SUPP = 0x8113,
|
||||
CTS_DEVICE_FW_REG_AUTO_COMPENSATE_EN = 0x8114,
|
||||
CTS_DEVICE_FW_REG_ESD_PROTECTION = 0x8156,
|
||||
CTS_DEVICE_FW_REG_FLAG_BITS = 0x8158,
|
||||
|
||||
CTS_DEVICE_FW_REG_COMPENSATE_CAP = 0xA000,
|
||||
CTS_DEVICE_FW_REG_DEBUG_INTF = 0xF000,
|
||||
};
|
||||
|
||||
/** Hardware IDs, read from hardware id register */
|
||||
enum cts_dev_hwid {
|
||||
CTS_DEV_HWID_ICNL9951 = 0x990510u,
|
||||
CTS_DEV_HWID_ICNL9951R = 0x991510u,
|
||||
|
||||
CTS_DEV_HWID_ANY = 0,
|
||||
CTS_DEV_HWID_INVALID = 0xFFFFFFFFu,
|
||||
};
|
||||
|
||||
/* Firmware IDs, read from firmware register @ref CTS_DEV_FW_REG_CHIP_TYPE
|
||||
* under normal mode
|
||||
*/
|
||||
enum cts_dev_fwid {
|
||||
CTS_DEV_FWID_ICNL9951 = 0x9951u,
|
||||
CTS_DEV_FWID_ICNL9951R = 0x99a3u,
|
||||
|
||||
CTS_DEV_FWID_ANY = 0u,
|
||||
CTS_DEV_FWID_INVALID = 0xFFFFu
|
||||
};
|
||||
|
||||
/** Commands written to firmware register @ref CTS_DEVICE_FW_REG_CMD under normal mode */
|
||||
enum cts_firmware_cmd {
|
||||
CTS_CMD_RESET = 1,
|
||||
CTS_CMD_SUSPEND = 2,
|
||||
CTS_CMD_ENTER_WRITE_PARA_TO_FLASH_MODE = 3,
|
||||
CTS_CMD_WRITE_PARA_TO_FLASH = 4,
|
||||
CTS_CMD_WRTITE_INT_HIGH = 5,
|
||||
CTS_CMD_WRTITE_INT_LOW = 6,
|
||||
CTS_CMD_RELASE_INT_TEST = 7,
|
||||
CTS_CMD_RECOVERY_TX_VOL = 0x10,
|
||||
CTS_CMD_DEC_TX_VOL_1 = 0x11,
|
||||
CTS_CMD_DEC_TX_VOL_2 = 0x12,
|
||||
CTS_CMD_DEC_TX_VOL_3 = 0x13,
|
||||
CTS_CMD_DEC_TX_VOL_4 = 0x14,
|
||||
CTS_CMD_DEC_TX_VOL_5 = 0x15,
|
||||
CTS_CMD_DEC_TX_VOL_6 = 0x16,
|
||||
CTS_CMD_ENABLE_READ_RAWDATA = 0x20,
|
||||
CTS_CMD_DISABLE_READ_RAWDATA = 0x21,
|
||||
CTS_CMD_SUSPEND_WITH_GESTURE = 0x40,
|
||||
CTS_CMD_QUIT_GESTURE_MONITOR = 0x41,
|
||||
CTS_CMD_CHARGER_ATTACHED = 0x55,
|
||||
CTS_CMD_EARJACK_ATTACHED = 0x57,
|
||||
CTS_CMD_EARJACK_DETACHED = 0x58,
|
||||
CTS_CMD_CHARGER_DETACHED = 0x66,
|
||||
CTS_CMD_ENABLE_FW_LOG_REDIRECT = 0x86,
|
||||
CTS_CMD_DISABLE_FW_LOG_REDIRECT = 0x87,
|
||||
CTS_CMD_ENABLE_READ_CNEG = 0x88,
|
||||
CTS_CMD_DISABLE_READ_CNEG = 0x89,
|
||||
CTS_CMD_FW_LOG_SHOW_FINISH = 0xE0,
|
||||
|
||||
#ifdef CONFIG_CTS_TP_PROXIMITY
|
||||
CTS_CMD_PROXIMITY_STATUS = 0x80,
|
||||
/* For vivo code, make a distinction between palm func and proximity func */
|
||||
CTS_CMD_PROXIMITY_NEAR_VIVO = 0x30,
|
||||
CTS_CMD_PROXIMITY_FAR_VIVO = 0x31,
|
||||
#endif
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
/** Touch message read back from chip */
|
||||
struct cts_device_touch_msg {
|
||||
u8 event:4;
|
||||
u8 id:4;
|
||||
|
||||
u8 xh:4;
|
||||
u8 yh:4;
|
||||
|
||||
u8 xl;
|
||||
u8 yl;
|
||||
|
||||
u8 pressure;
|
||||
|
||||
#define CTS_DEVICE_TOUCH_EVENT_NONE (0)
|
||||
#define CTS_DEVICE_TOUCH_EVENT_DOWN (1)
|
||||
#define CTS_DEVICE_TOUCH_EVENT_MOVE (2)
|
||||
#define CTS_DEVICE_TOUCH_EVENT_STAY (3)
|
||||
#define CTS_DEVICE_TOUCH_EVENT_UP (4)
|
||||
|
||||
};
|
||||
|
||||
/** Stylus message read back from chip */
|
||||
struct cts_device_stylus_msg {
|
||||
u8 event:4;
|
||||
u8 id:4;
|
||||
|
||||
u8 tip_xh:4;
|
||||
u8 tip_yh:4;
|
||||
u8 tip_xl;
|
||||
u8 tip_yl;
|
||||
|
||||
u8 ring_xh:4;
|
||||
u8 ring_yh:4;
|
||||
u8 ring_xl;
|
||||
u8 ring_yl;
|
||||
|
||||
u8 battary;
|
||||
u8 tilt;
|
||||
|
||||
u8 pressure_l;
|
||||
u8 pressure_h:5;//use low 5 bits
|
||||
u8 btn0:1;
|
||||
u8 btn1:1;
|
||||
u8 btn2:1;
|
||||
|
||||
u8 tiltx;
|
||||
u8 tilty;
|
||||
};
|
||||
|
||||
struct cts_firmware_status {
|
||||
uint16_t charger:1;
|
||||
uint16_t proximity:1;
|
||||
uint16_t earjack:1;
|
||||
uint16_t knuckle:1;
|
||||
uint16_t glove:1;
|
||||
uint16_t pocket:1;
|
||||
uint16_t game:1;
|
||||
uint16_t reserved:1;
|
||||
uint16_t high_temperature:1;
|
||||
uint16_t low_temperature:1;
|
||||
uint16_t bend_mode:1;
|
||||
uint16_t palm_status:1;
|
||||
uint16_t noise_mode:1;
|
||||
uint16_t base_trace:1;
|
||||
uint16_t water_mode:1;
|
||||
uint16_t ground:1;
|
||||
};
|
||||
/** Touch debug messages read back from chip [40 bytes] */
|
||||
struct cts_touch_debug_msg {
|
||||
u8 protocol_version;
|
||||
u8 fw_version;
|
||||
u32 reset_flag;
|
||||
u16 frame_index;
|
||||
u16 firmware_status;
|
||||
|
||||
u8 proximity;
|
||||
u8 work_mode;
|
||||
u8 power_mode;
|
||||
u8 curr_freq;
|
||||
u8 esd_0a_status;
|
||||
u8 fw_esd_status;
|
||||
u8 landscape_mode;
|
||||
u16 curr_freq_noise;
|
||||
u16 max_diff;
|
||||
u8 max_diff_row;
|
||||
u8 max_diff_col;
|
||||
u16 max_neg_diff;
|
||||
u8 max_neg_diff_row;
|
||||
u8 max_neg_diff_col;
|
||||
u8 data_method;
|
||||
u8 data_type;
|
||||
u8 reserved[11];
|
||||
};
|
||||
|
||||
/** Touch information read back from chip */
|
||||
struct cts_device_touch_info {
|
||||
u8 vkey_state;
|
||||
|
||||
u8 num_msg:4;
|
||||
#define PROTO_NORMAL 0x00
|
||||
#define PROTO_COMPRESSED 0x01
|
||||
u8 compressed_proto:2;
|
||||
#define FINGER_ONLY 0x01
|
||||
#define STYLUS_ONLY 0x02
|
||||
#define FINGER_STYLUS 0x03
|
||||
u8 finger_or_stylus:2;
|
||||
|
||||
u8 reserved0;
|
||||
|
||||
struct cts_device_touch_msg msgs[CFG_CTS_MAX_TOUCH_NUM];
|
||||
|
||||
u8 proximity;
|
||||
u8 palm_major;
|
||||
u8 palm_minor;
|
||||
u8 palm_flags;
|
||||
|
||||
#ifdef CFG_CTS_FINGER_STYLUS_SUPPORTED
|
||||
u8 stylus_num:4;
|
||||
u8 stylus_vernum:4;
|
||||
|
||||
struct cts_device_stylus_msg smsgs[CFG_CTS_MAX_STYLUS_NUM];
|
||||
|
||||
u8 reserved1;
|
||||
u8 reserved2;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cts_device_stylus_info {
|
||||
u8 vkey_state;
|
||||
|
||||
u8 num_msg:4;
|
||||
u8 compressed_proto:2;
|
||||
u8 finger_or_stylus:2;
|
||||
|
||||
u8 reserved0;
|
||||
|
||||
u8 event_num:4;
|
||||
u8 stylus_vernum:4;
|
||||
|
||||
struct cts_device_stylus_msg msgs[CFG_CTS_MAX_STYLUS_NUM];
|
||||
|
||||
u8 reserved1;
|
||||
};
|
||||
|
||||
|
||||
/** Gesture trace point read back from chip */
|
||||
struct cts_device_gesture_point {
|
||||
__le16 x;
|
||||
__le16 y;
|
||||
};
|
||||
|
||||
/** Gesture information read back from chip */
|
||||
/* total size 112 bytes */
|
||||
struct cts_device_gesture_info {
|
||||
u8 gesture_id;
|
||||
#define CTS_GESTURE_UP (0x11)
|
||||
#define CTS_GESTURE_C (0x12)
|
||||
#define CTS_GESTURE_O (0x13)
|
||||
#define CTS_GESTURE_M (0x14)
|
||||
#define CTS_GESTURE_W (0x15)
|
||||
#define CTS_GESTURE_E (0x16)
|
||||
#define CTS_GESTURE_S (0x17)
|
||||
#define CTS_GESTURE_B (0x18)
|
||||
#define CTS_GESTURE_T (0x19)
|
||||
#define CTS_GESTURE_H (0x1A)
|
||||
#define CTS_GESTURE_F (0x1B)
|
||||
#define CTS_GESTURE_X (0x1C)
|
||||
#define CTS_GESTURE_Z (0x1D)
|
||||
#define CTS_GESTURE_V (0x1E)
|
||||
#define CTS_GESTURE_D_TAP (0x50)
|
||||
#define CTS_GESTURE_TAP (0x7F)
|
||||
|
||||
u8 num_points;
|
||||
|
||||
#define CTS_CHIP_MAX_GESTURE_TRACE_POINT (27u)
|
||||
struct cts_device_gesture_point points[CTS_CHIP_MAX_GESTURE_TRACE_POINT];
|
||||
u8 reserved[2];
|
||||
|
||||
};
|
||||
|
||||
struct cts_tcs_cmd {
|
||||
uint16_t cmd_id : 8;
|
||||
uint16_t class_id : 5;
|
||||
uint16_t is_write : 1;
|
||||
uint16_t is_read : 1;
|
||||
uint16_t base_flag : 1;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
struct cts_device;
|
||||
|
||||
enum cts_crc_type {
|
||||
CTS_CRC16 = 1,
|
||||
CTS_CRC32 = 2,
|
||||
};
|
||||
|
||||
/** Chip hardware data, will never change */
|
||||
struct cts_device_hwdata {
|
||||
const char *name;
|
||||
u32 hwid;
|
||||
u16 fwid;
|
||||
u8 num_row;
|
||||
u8 num_col;
|
||||
u32 sram_size;
|
||||
|
||||
/* Address width under program mode */
|
||||
u8 program_addr_width;
|
||||
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
int (*enable_access_ddi_reg)(struct cts_device *cts_dev, bool enable);
|
||||
};
|
||||
|
||||
enum int_data_type {
|
||||
INT_DATA_TYPE_NONE = 0,
|
||||
INT_DATA_TYPE_RAWDATA = BIT(0),
|
||||
INT_DATA_TYPE_MANUAL_DIFF = BIT(1),
|
||||
INT_DATA_TYPE_REAL_DIFF = BIT(2),
|
||||
INT_DATA_TYPE_NOISE_DIFF = BIT(3),
|
||||
INT_DATA_TYPE_BASEDATA = BIT(4),
|
||||
INT_DATA_TYPE_CNEGDATA = BIT(5),
|
||||
INT_DATA_TYPE_MASK = 0xF03F,
|
||||
};
|
||||
|
||||
enum int_data_method {
|
||||
INT_DATA_METHOD_NONE = 0,
|
||||
INT_DATA_METHOD_HOST = 1,
|
||||
INT_DATA_METHOD_POLLING = 2,
|
||||
INT_DATA_METHOD_DEBUG = 3,
|
||||
INT_DATA_METHOD_CNT = 4,
|
||||
};
|
||||
|
||||
/** Chip firmware data */
|
||||
struct cts_device_fwdata {
|
||||
u16 version;
|
||||
u16 res_x;
|
||||
u16 res_y;
|
||||
u8 rows;
|
||||
u8 cols;
|
||||
|
||||
bool flip_x;
|
||||
bool flip_y;
|
||||
bool swap_axes;
|
||||
u8 ddi_version;
|
||||
u8 int_mode;
|
||||
u8 esd_method;
|
||||
u16 lib_version;
|
||||
u16 int_keep_time;
|
||||
u16 rawdata_target;
|
||||
bool has_int_data;
|
||||
u8 int_data_method;
|
||||
u16 int_data_types;
|
||||
size_t int_data_size;
|
||||
|
||||
u8 ic_application;
|
||||
u8 pen_freq_num;
|
||||
u8 cascade_num;
|
||||
|
||||
u8 pc_cols;
|
||||
u8 pc_rows;
|
||||
u8 pr_cols;
|
||||
u8 pr_rows;
|
||||
|
||||
u8 pc_cols_used;
|
||||
u8 pc_rows_used;
|
||||
u8 pr_cols_used;
|
||||
u8 pr_rows_used;
|
||||
};
|
||||
|
||||
/** Chip runtime data */
|
||||
struct cts_device_rtdata {
|
||||
u8 slave_addr;
|
||||
int addr_width;
|
||||
bool program_mode;
|
||||
bool has_flash;
|
||||
|
||||
bool suspended;
|
||||
bool updating;
|
||||
bool testing;
|
||||
|
||||
bool gesture_wakeup_enabled;
|
||||
bool gesture_d_tap_enabled;
|
||||
bool charger_exist;
|
||||
bool fw_log_redirect_enabled;
|
||||
bool glove_mode_enabled;
|
||||
|
||||
u8 esd_count;
|
||||
u16 firmware_status;
|
||||
|
||||
struct cts_device_touch_info touch_info;
|
||||
struct cts_device_gesture_info gesture_info;
|
||||
|
||||
#ifdef CONFIG_CTS_TP_PROXIMITY
|
||||
bool proximity_status;
|
||||
int proximity_num;
|
||||
#endif
|
||||
|
||||
u16 tcscmd[ALIGN(PAGE_SIZE + 10, 4)];
|
||||
int tcscmd_len;
|
||||
u16 curr_cmd;
|
||||
int curr_len;
|
||||
};
|
||||
|
||||
struct cts_firmware {
|
||||
const char *name; /* MUST set to non-NULL if driver builtin firmware */
|
||||
u32 hwid;
|
||||
u16 fwid;
|
||||
|
||||
u8 *data;
|
||||
size_t size;
|
||||
const struct firmware *fw;
|
||||
};
|
||||
|
||||
struct cts_device {
|
||||
struct cts_platform_data *pdata;
|
||||
|
||||
const struct cts_device_hwdata *hwdata;
|
||||
struct cts_device_fwdata fwdata;
|
||||
struct cts_device_rtdata rtdata;
|
||||
struct cts_firmware *firmware;
|
||||
const struct cts_flash *flash;
|
||||
bool enabled;
|
||||
u8 int_data[ALIGN(CFG_CTS_INT_DATA_MAX_SIZE + 10, 4)];
|
||||
};
|
||||
|
||||
struct cts_platform_data;
|
||||
|
||||
struct chipone_ts_data {
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
struct i2c_client *i2c_client;
|
||||
#else
|
||||
struct spi_device *spi_client;
|
||||
#endif
|
||||
struct device *device;
|
||||
struct cts_device cts_dev;
|
||||
struct cts_platform_data *pdata;
|
||||
struct workqueue_struct *workqueue;
|
||||
struct delayed_work fw_upgrade_work;
|
||||
struct work_struct ts_resume_work;
|
||||
#ifdef CONFIG_CTS_CHARGER_DETECT
|
||||
void *charger_detect_data;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_EARJACK_DETECT
|
||||
void *earjack_detect_data;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
struct workqueue_struct *esd_workqueue;
|
||||
struct delayed_work esd_work;
|
||||
bool esd_enabled;
|
||||
int esd_check_fail_cnt;
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_HEARTBEAT_MECHANISM
|
||||
struct workqueue_struct *heart_workqueue;
|
||||
struct delayed_work heart_work;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
struct proc_dir_entry *procfs_entry;
|
||||
#endif
|
||||
|
||||
void *oem_data;
|
||||
|
||||
bool force_reflash;
|
||||
// struct kobject *suspend_kobj;
|
||||
#ifdef CONFIG_PM_DSI_EXTCON_NOTIFIER
|
||||
struct extcon_dev *edev;
|
||||
struct notifier_block extcon_nb;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*static inline u32 get_unaligned_le24(const void *p)
|
||||
{
|
||||
const u8 *puc = (const u8 *)p;
|
||||
return (puc[0] | (puc[1] << 8) | (puc[2] << 16));
|
||||
}
|
||||
|
||||
static inline u32 get_unaligned_be24(const void *p)
|
||||
{
|
||||
const u8 *puc = (const u8 *)p;
|
||||
return (puc[2] | (puc[1] << 8) | (puc[0] << 16));
|
||||
}
|
||||
|
||||
static inline void put_unaligned_be24(u32 v, void *p)
|
||||
{
|
||||
u8 *puc = (u8 *) p;
|
||||
|
||||
puc[0] = (v >> 16) & 0xFF;
|
||||
puc[1] = (v >> 8) & 0xFF;
|
||||
puc[2] = (v >> 0) & 0xFF;
|
||||
}*/
|
||||
|
||||
#define wrap(max, x) ((max) - 1 - (x))
|
||||
|
||||
extern void cts_lock_device(struct cts_device *cts_dev);
|
||||
extern void cts_unlock_device(struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_dev_readb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 *b, int retry, int delay);
|
||||
extern int cts_dev_writeb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 b, int retry, int delay);
|
||||
|
||||
extern int cts_sram_writeb_retry(struct cts_device *cts_dev,
|
||||
u32 addr, u8 b, int retry, int delay);
|
||||
extern int cts_sram_writew_retry(struct cts_device *cts_dev,
|
||||
u32 addr, u16 w, int retry, int delay);
|
||||
extern int cts_sram_writel_retry(struct cts_device *cts_dev,
|
||||
u32 addr, u32 l, int retry, int delay);
|
||||
extern int cts_sram_writesb_retry(struct cts_device *cts_dev,
|
||||
u32 addr, const void *src, size_t len, int retry, int delay);
|
||||
extern int cts_sram_writesb_check_crc_retry(struct cts_device *cts_dev,
|
||||
u32 addr, const void *src, size_t len, u32 crc, int retry);
|
||||
|
||||
extern int cts_sram_readb_retry(struct cts_device *cts_dev,
|
||||
u32 addr, u8 *b, int retry, int delay);
|
||||
extern int cts_sram_readw_retry(struct cts_device *cts_dev,
|
||||
u32 addr, u16 *w, int retry, int delay);
|
||||
extern int cts_sram_readl_retry(struct cts_device *cts_dev,
|
||||
u32 addr, u32 *l, int retry, int delay);
|
||||
extern int cts_sram_readsb_retry(struct cts_device *cts_dev,
|
||||
u32 addr, void *dst, size_t len, int retry, int delay);
|
||||
|
||||
extern int cts_fw_reg_writeb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b, int retry, int delay);
|
||||
extern int cts_fw_reg_writew_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w, int retry, int delay);
|
||||
extern int cts_fw_reg_writel_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 l, int retry, int delay);
|
||||
extern int cts_fw_reg_writesb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, const void *src, size_t len, int retry, int delay);
|
||||
|
||||
extern int cts_fw_reg_readb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b, int retry, int delay);
|
||||
extern int cts_fw_reg_readw_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 *w, int retry, int delay);
|
||||
extern int cts_fw_reg_readl_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 *l, int retry, int delay);
|
||||
extern int cts_fw_reg_readsb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len,
|
||||
int retry, int delay);
|
||||
extern int cts_fw_reg_readsb_retry_delay_idle(struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len, int retry, int delay, int idle);
|
||||
|
||||
extern int cts_hw_reg_writeb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b, int retry, int delay);
|
||||
extern int cts_hw_reg_writew_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w, int retry, int delay);
|
||||
extern int cts_hw_reg_writel_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 l, int retry, int delay);
|
||||
extern int cts_hw_reg_writesb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, const void *src, size_t len, int retry, int delay);
|
||||
|
||||
extern int cts_hw_reg_readb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b, int retry, int delay);
|
||||
extern int cts_hw_reg_readw_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 *w, int retry, int delay);
|
||||
extern int cts_hw_reg_readl_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 *l, int retry, int delay);
|
||||
extern int cts_hw_reg_readsb_retry(struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len, int retry, int delay);
|
||||
|
||||
static inline int cts_hw_reg_readb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b)
|
||||
{
|
||||
return cts_hw_reg_readb_retry(cts_dev, reg_addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_writeb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b)
|
||||
{
|
||||
return cts_hw_reg_writeb_retry(cts_dev, reg_addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_writew(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w)
|
||||
{
|
||||
return cts_hw_reg_writew_retry(cts_dev, reg_addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_writeb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b)
|
||||
{
|
||||
return cts_fw_reg_writeb_retry(cts_dev, reg_addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_writew(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w)
|
||||
{
|
||||
return cts_fw_reg_writew_retry(cts_dev, reg_addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_writel(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 l)
|
||||
{
|
||||
return cts_fw_reg_writel_retry(cts_dev, reg_addr, l, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_writesb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, const void *src, size_t len)
|
||||
{
|
||||
return cts_fw_reg_writesb_retry(cts_dev, reg_addr, src, len, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_readb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b)
|
||||
{
|
||||
return cts_fw_reg_readb_retry(cts_dev, reg_addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_readw(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 *w)
|
||||
{
|
||||
return cts_fw_reg_readw_retry(cts_dev, reg_addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_readl(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 *l)
|
||||
{
|
||||
return cts_fw_reg_readl_retry(cts_dev, reg_addr, l, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_readsb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len)
|
||||
{
|
||||
return cts_fw_reg_readsb_retry(cts_dev, reg_addr, dst, len, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_fw_reg_readsb_delay_idle(struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len, int idle)
|
||||
{
|
||||
return cts_fw_reg_readsb_retry_delay_idle(cts_dev, reg_addr, dst, len,
|
||||
1, 0, idle);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_writeb_relaxed(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b)
|
||||
{
|
||||
return cts_hw_reg_writeb_retry(cts_dev, reg_addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_writew_relaxed(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w)
|
||||
{
|
||||
return cts_hw_reg_writew_retry(cts_dev, reg_addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_writel_relaxed(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 l)
|
||||
{
|
||||
return cts_hw_reg_writel_retry(cts_dev, reg_addr, l, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_writesb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, const void *src, size_t len)
|
||||
{
|
||||
return cts_hw_reg_writesb_retry(cts_dev, reg_addr, src, len, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_readb_relaxed(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b)
|
||||
{
|
||||
return cts_hw_reg_readb_retry(cts_dev, reg_addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_readw_relaxed(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 *w)
|
||||
{
|
||||
return cts_hw_reg_readw_retry(cts_dev, reg_addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_readl_relaxed(struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 *l)
|
||||
{
|
||||
return cts_hw_reg_readl_retry(cts_dev, reg_addr, l, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_hw_reg_readsb(struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len)
|
||||
{
|
||||
return cts_hw_reg_readsb_retry(cts_dev, reg_addr, dst, len, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_writeb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 b)
|
||||
{
|
||||
return cts_sram_writeb_retry(cts_dev, addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_writew(struct cts_device *cts_dev,
|
||||
u32 addr, u16 w)
|
||||
{
|
||||
return cts_sram_writew_retry(cts_dev, addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_writel(struct cts_device *cts_dev,
|
||||
u32 addr, u32 l)
|
||||
{
|
||||
return cts_sram_writel_retry(cts_dev, addr, l, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_writesb(struct cts_device *cts_dev, u32 addr,
|
||||
const void *src, size_t len)
|
||||
{
|
||||
return cts_sram_writesb_retry(cts_dev, addr, src, len, 10, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_readb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 *b)
|
||||
{
|
||||
return cts_sram_readb_retry(cts_dev, addr, b, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_readw(struct cts_device *cts_dev,
|
||||
u32 addr, u16 *w)
|
||||
{
|
||||
return cts_sram_readw_retry(cts_dev, addr, w, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_readl(struct cts_device *cts_dev,
|
||||
u32 addr, u32 *l)
|
||||
{
|
||||
return cts_sram_readl_retry(cts_dev, addr, l, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_readsb(struct cts_device *cts_dev,
|
||||
u32 addr, void *dst, size_t len)
|
||||
{
|
||||
return cts_sram_readsb_retry(cts_dev, addr, dst, len, 1, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
static inline void cts_set_program_addr(struct cts_device *cts_dev)
|
||||
{
|
||||
cts_dev->rtdata.slave_addr = CTS_DEV_PROGRAM_MODE_I2CADDR;
|
||||
cts_dev->rtdata.program_mode = true;
|
||||
cts_dev->rtdata.addr_width = CTS_DEV_PROGRAM_MODE_ADDR_WIDTH;
|
||||
}
|
||||
|
||||
static inline void cts_set_normal_addr(struct cts_device *cts_dev)
|
||||
{
|
||||
cts_dev->rtdata.slave_addr = CTS_DEV_NORMAL_MODE_I2CADDR;
|
||||
cts_dev->rtdata.program_mode = false;
|
||||
cts_dev->rtdata.addr_width = CTS_DEV_NORMAL_MODE_ADDR_WIDTH;
|
||||
}
|
||||
|
||||
int cts_i2c_writeb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 b, int retry, int delay);
|
||||
int cts_i2c_writeb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 b, int retry, int delay);
|
||||
int cts_i2c_writesb(struct cts_device *cts_dev, u32 addr,
|
||||
const u8 *src, size_t len, int retry, int delay);
|
||||
int cts_i2c_readb(struct cts_device *cts_dev,
|
||||
u32 addr, u8 *b, int retry, int delay);
|
||||
int cts_i2c_readl(struct cts_device *cts_dev,
|
||||
u32 addr, u32 *l, int retry, int delay);
|
||||
|
||||
#else
|
||||
static inline void cts_set_program_addr(struct cts_device *cts_dev)
|
||||
{
|
||||
cts_dev->rtdata.slave_addr = CTS_DEV_PROGRAM_MODE_SPIADDR;
|
||||
cts_dev->rtdata.program_mode = true;
|
||||
cts_dev->rtdata.addr_width = CTS_DEV_PROGRAM_MODE_ADDR_WIDTH;
|
||||
}
|
||||
|
||||
static inline void cts_set_normal_addr(struct cts_device *cts_dev)
|
||||
{
|
||||
cts_dev->rtdata.slave_addr = CTS_DEV_NORMAL_MODE_SPIADDR;
|
||||
cts_dev->rtdata.program_mode = false;
|
||||
cts_dev->rtdata.addr_width = CTS_DEV_NORMAL_MODE_ADDR_WIDTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int cts_irq_handler(struct cts_device *cts_dev);
|
||||
extern void cts_firmware_upgrade_work(struct work_struct *work);
|
||||
|
||||
extern bool cts_is_device_suspended(struct cts_device *cts_dev);
|
||||
extern int cts_suspend_device(struct cts_device *cts_dev);
|
||||
extern int cts_resume_device(struct cts_device *cts_dev);
|
||||
|
||||
extern bool cts_is_device_program_mode(struct cts_device *cts_dev);
|
||||
extern int cts_enter_program_mode(struct cts_device *cts_dev);
|
||||
extern int cts_enter_normal_mode(struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_probe_device(struct cts_device *cts_dev);
|
||||
extern int cts_send_command(struct cts_device *cts_dev, u8 cmd);
|
||||
|
||||
extern int cts_read_sram_normal_mode(struct cts_device *cts_dev,
|
||||
u32 addr, void *dst, size_t len, int retry, int delay);
|
||||
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
extern void cts_enable_gesture_wakeup(struct cts_device *cts_dev);
|
||||
extern void cts_disable_gesture_wakeup(struct cts_device *cts_dev);
|
||||
extern bool cts_is_gesture_wakeup_enabled(struct cts_device *cts_dev);
|
||||
extern int cts_get_gesture_info(struct cts_device *cts_dev, void *gesture_info);
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
extern bool cts_is_d_tap_supported(struct cts_device *cts_dev);
|
||||
extern int cts_set_d_tap_enabled(struct cts_device *cts_dev, bool enabled);
|
||||
|
||||
extern int cts_set_int_data_types(struct cts_device *cts_dev, u16 types);
|
||||
extern int cts_set_int_data_method(struct cts_device *cts_dev, u8 method);
|
||||
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
extern void cts_init_esd_protection(struct chipone_ts_data *cts_data);
|
||||
extern void cts_enable_esd_protection(struct chipone_ts_data *cts_data);
|
||||
extern void cts_disable_esd_protection(struct chipone_ts_data *cts_data);
|
||||
extern void cts_deinit_esd_protection(struct chipone_ts_data *cts_data);
|
||||
#else /* CONFIG_CTS_ESD_PROTECTION */
|
||||
static inline void cts_init_esd_protection(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cts_enable_esd_protection(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cts_disable_esd_protection(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cts_deinit_esd_protection(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_CTS_ESD_PROTECTION */
|
||||
|
||||
#ifdef CFG_CTS_HEARTBEAT_MECHANISM
|
||||
void cts_show_touch_debug_msg(void *debug);
|
||||
void cts_heartbeat_mechanism_work(struct work_struct *work);
|
||||
void cts_enable_heartbeat_mechanism(struct chipone_ts_data *cts_data);
|
||||
void cts_disable_heartbeat_mechanism(struct chipone_ts_data *cts_data);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_GLOVE
|
||||
extern int cts_enter_glove_mode(struct cts_device *cts_dev);
|
||||
extern int cts_exit_glove_mode(struct cts_device *cts_dev);
|
||||
int cts_is_glove_enabled(struct cts_device *cts_dev);
|
||||
int cts_set_glove_enabled(struct cts_device *cts_dev, bool enabled);
|
||||
#else
|
||||
static inline int cts_enter_glove_mode(struct cts_device *cts_dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cts_exit_glove_mode(struct cts_device *cts_dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cts_is_glove_enabled(struct cts_device *cts_dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cts_set_glove_enabled(struct cts_device *cts_dev, bool enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_CHARGER_DETECT
|
||||
extern bool cts_is_charger_exist(struct cts_device *cts_dev);
|
||||
extern int cts_set_dev_charger_attached(struct cts_device *cts_dev,
|
||||
bool attached);
|
||||
#else /* CONFIG_CTS_CHARGER_DETECT */
|
||||
static inline bool cts_is_charger_exist(struct cts_device *cts_dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int cts_set_dev_charger_attached(struct cts_device *cts_dev,
|
||||
bool attached)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CTS_CHARGER_DETECT */
|
||||
|
||||
#ifdef CONFIG_CTS_EARJACK_DETECT
|
||||
extern bool cts_is_earjack_exist(struct cts_device *cts_dev);
|
||||
extern int cts_set_dev_earjack_attached(struct cts_device *cts_dev, bool attached);
|
||||
#else /* CONFIG_CTS_EARJACK_DETECT */
|
||||
static inline bool cts_is_earjack_exist(struct cts_device *cts_dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int cts_set_dev_earjack_attached(struct cts_device *cts_dev, bool attached)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CTS_EARJACK_DETECT */
|
||||
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
extern int cts_tool_init(struct chipone_ts_data *cts_data);
|
||||
extern void cts_tool_deinit(struct chipone_ts_data *data);
|
||||
#else /* CONFIG_CTS_LEGACY_TOOL */
|
||||
static inline int cts_tool_init(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cts_tool_deinit(struct chipone_ts_data *data)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_CTS_LEGACY_TOOL */
|
||||
|
||||
extern bool cts_is_device_enabled(struct cts_device *cts_dev);
|
||||
extern int cts_start_device(struct cts_device *cts_dev);
|
||||
extern int cts_stop_device(struct cts_device *cts_dev);
|
||||
|
||||
#ifdef CFG_CTS_UPDATE_CRCCHECK
|
||||
extern int cts_sram_writesb_boot_crc_retry(struct cts_device *cts_dev,
|
||||
size_t len, u32 crc, int retry);
|
||||
#endif
|
||||
|
||||
extern const char *cts_dev_boot_mode2str(u8 boot_mode);
|
||||
extern bool cts_is_fwid_valid(u16 fwid);
|
||||
|
||||
extern int cts_reset_device(struct cts_device *cts_dev);
|
||||
extern int cts_wait_current_mode(struct cts_device *cts_dev, u8 tar_mode);
|
||||
|
||||
extern int kstrtobool(const char *s, bool *res);
|
||||
|
||||
extern int cts_suspend(struct chipone_ts_data *cts_data);
|
||||
extern int cts_resume(struct chipone_ts_data *cts_data);
|
||||
|
||||
extern struct chipone_ts_data *g_cts_data;
|
||||
|
||||
#endif /* CTS_CORE_H */
|
||||
1231
drivers/input/touchscreen/chipone_tddi/cts_driver.c
Normal file
1231
drivers/input/touchscreen/chipone_tddi/cts_driver.c
Normal file
File diff suppressed because it is too large
Load Diff
649
drivers/input/touchscreen/chipone_tddi/cts_earjack_detect.c
Normal file
649
drivers/input/touchscreen/chipone_tddi/cts_earjack_detect.c
Normal file
@@ -0,0 +1,649 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#define LOG_TAG "Earjack"
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_platform.h"
|
||||
#include "cts_core.h"
|
||||
#include "cts_sysfs.h"
|
||||
#include "cts_strerror.h"
|
||||
|
||||
#ifdef CONFIG_CTS_EARJACK_DETECT
|
||||
struct cts_earjack_detect_data {
|
||||
bool enable;
|
||||
bool running;
|
||||
bool state;
|
||||
|
||||
const char *earjack_state_filepath;
|
||||
struct delayed_work poll_work;
|
||||
u32 poll_interval;
|
||||
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
bool sysfs_attr_group_created;
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
|
||||
struct chipone_ts_data *cts_data;
|
||||
};
|
||||
|
||||
/* Over-ride setting for DTS */
|
||||
//#define CFG_CTS_DEF_EARJACK_DET_ENABLE
|
||||
|
||||
#define CFG_CTS_DEF_EARJACK_POLL_INTERVAL 2000u
|
||||
#if defined(CONFIG_MTK_PLATFORM)
|
||||
#define CFG_CTS_DEF_EARJACK_STATE_FILEPATH \
|
||||
"/sys/bus/platform/drivers/Accdet_Driver/state"
|
||||
#elif defined(CONFIG_ARCH_SPREADRUM)
|
||||
#define CFG_CTS_DEF_EARJACK_STATE_FILEPATH \
|
||||
"/sys/kernel/headset/state"
|
||||
#else
|
||||
/* Current QCOM NOT support earjack detect, please disable it or define the file path */
|
||||
#define CFG_CTS_DEF_EARJACK_STATE_FILEPATH ""
|
||||
#endif
|
||||
|
||||
static const char *earjack_state_str(bool state)
|
||||
{
|
||||
return state ? "ATTACHED" : "DETACHED";
|
||||
}
|
||||
|
||||
static int parse_earjack_detect_dt(struct cts_earjack_detect_data *ed_data,
|
||||
struct device_node *np)
|
||||
{
|
||||
const char *filepath;
|
||||
int ret;
|
||||
|
||||
cts_info("Parse dt");
|
||||
|
||||
#ifdef CFG_CTS_DEF_EARJACK_DET_ENABLE
|
||||
ed_data->enable = true;
|
||||
#else /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
|
||||
ed_data->enable =
|
||||
of_property_read_bool(np, "chipone,touch-earjack-detect-enable");
|
||||
#endif /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
|
||||
|
||||
ret = of_property_read_string(np,
|
||||
"chipone,touch-earjack-state-filepath", &filepath);
|
||||
if (ret) {
|
||||
cts_warn("Parse state filepath failed %d(%s)", ret, cts_strerror(ret));
|
||||
filepath = CFG_CTS_DEF_EARJACK_STATE_FILEPATH;
|
||||
}
|
||||
ed_data->earjack_state_filepath = kstrdup(filepath, GFP_KERNEL);
|
||||
if (ed_data->earjack_state_filepath == NULL) {
|
||||
cts_err("Dup earjack state filepath failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ed_data->poll_interval = CFG_CTS_DEF_EARJACK_POLL_INTERVAL;
|
||||
ret = of_property_read_u32(np,
|
||||
"chipone,touch-earjack-poll-interval", &ed_data->poll_interval);
|
||||
if (ret) {
|
||||
cts_warn("Parse poll interval failed %d(%s)", ret, cts_strerror(ret));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int start_earjack_detect(struct cts_earjack_detect_data *ed_data)
|
||||
{
|
||||
if (!ed_data->enable) {
|
||||
cts_warn("Start detect while NOT enabled");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ed_data->running) {
|
||||
cts_warn("Start detect while already RUNNING");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ed_data->earjack_state_filepath == NULL ||
|
||||
ed_data->earjack_state_filepath[0] == '\n') {
|
||||
cts_warn("Start detect with filepath = NULL/NUL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cts_info("Start detect check file: '%s'", ed_data->earjack_state_filepath);
|
||||
|
||||
if (!queue_delayed_work(ed_data->cts_data->workqueue,
|
||||
&ed_data->poll_work,
|
||||
msecs_to_jiffies(ed_data->poll_interval))) {
|
||||
cts_warn("Queue detect work while already on the queue");
|
||||
}
|
||||
|
||||
ed_data->running = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stop_earjack_detect(struct cts_earjack_detect_data *ed_data)
|
||||
{
|
||||
if (!ed_data->running) {
|
||||
cts_warn("Stop detect while NOT running");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cts_info("Stop detect");
|
||||
|
||||
if (!cancel_delayed_work_sync(&ed_data->poll_work)) {
|
||||
cts_warn("Cancel poll work while NOT pending");
|
||||
}
|
||||
ed_data->running = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_earjack_state(struct cts_earjack_detect_data *ed_data)
|
||||
{
|
||||
int ret;
|
||||
char buff[10];
|
||||
u32 state;
|
||||
#ifndef CFG_CTS_FOR_GKI
|
||||
struct file *file = NULL;
|
||||
loff_t pos = 0;
|
||||
int read_size;
|
||||
#endif
|
||||
|
||||
cts_dbg("Get state from file '%s'", ed_data->earjack_state_filepath);
|
||||
|
||||
#ifdef CFG_CTS_FOR_GKI
|
||||
cts_info("%s(): filp_open is forbiddon with GKI Version!", __func__);
|
||||
#else
|
||||
file = filp_open(ed_data->earjack_state_filepath, O_RDONLY, 0);
|
||||
if (IS_ERR(file)) {
|
||||
ret = (int)PTR_ERR(file);
|
||||
cts_err("Open file '%s' failed %d(%s)",
|
||||
ed_data->earjack_state_filepath, ret, cts_strerror(ret));
|
||||
return PTR_ERR(file);
|
||||
}
|
||||
|
||||
memset(buff, 0, sizeof(buff));
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
|
||||
read_size = kernel_read(file, buff, sizeof(buff), &pos);
|
||||
#else
|
||||
read_size = kernel_read(file, pos, buff, sizeof(buff));
|
||||
#endif
|
||||
if (read_size < 0) {
|
||||
cts_err("Read state file '%s' failed %d(%s)",
|
||||
ed_data->earjack_state_filepath,
|
||||
read_size, cts_strerror(read_size));
|
||||
filp_close(file, NULL);
|
||||
return read_size;
|
||||
}
|
||||
|
||||
cts_dbg("Read state file content: '%s'", buff);
|
||||
|
||||
ret = filp_close(file, NULL);
|
||||
if (ret) {
|
||||
cts_warn("Close file '%s' failed %d(%s)",
|
||||
ed_data->earjack_state_filepath, ret, cts_strerror(ret));
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = kstrtou32(buff, 0, &state);
|
||||
if (ret) {
|
||||
cts_err("Invalid string from state file: '%s'", buff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Assume "0" means detached */
|
||||
ed_data->state = !!state;
|
||||
|
||||
cts_dbg("State: %s", earjack_state_str(ed_data->state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sysfs */
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
|
||||
#define EARJACK_DET_SYSFS_GROUP_NAME "earjack-det"
|
||||
|
||||
static int enable_earjack_detect(struct cts_earjack_detect_data *ed_data)
|
||||
{
|
||||
cts_info("Enable detect");
|
||||
|
||||
ed_data->enable = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disable_earjack_detect(struct cts_earjack_detect_data *ed_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cts_info("Disable detect");
|
||||
|
||||
ret = stop_earjack_detect(ed_data);
|
||||
if (ret) {
|
||||
cts_err("Stop detect failed %d(%s)", ret, cts_strerror(ret));
|
||||
}
|
||||
|
||||
ed_data->enable = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t earjack_detect_enable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
|
||||
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'", attr->attr.name);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"Earjack detect: %s\n",
|
||||
ed_data->enable ? "ENABLED" : "DISABLED");
|
||||
}
|
||||
|
||||
/* Echo 0/n/N/of/Of/Of/OF/1/y/Y/on/oN/On/ON > enable */
|
||||
static ssize_t earjack_detect_enable_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
bool enable;
|
||||
int ret;
|
||||
|
||||
cts_info("Write sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s' size %zu",
|
||||
attr->attr.name, count);
|
||||
|
||||
cts_parse_arg(buf, count);
|
||||
|
||||
if (cts_argc != 1) {
|
||||
cts_err("Invalid num of args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kstrtobool(cts_argv[0], &enable);
|
||||
if (ret) {
|
||||
cts_err("Invalid param of enable");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
ret = enable_earjack_detect(ed_data);
|
||||
} else {
|
||||
ret = disable_earjack_detect(ed_data);
|
||||
}
|
||||
if (ret) {
|
||||
cts_err("%s earjack detect failed %d(%s)",
|
||||
enable ? "Enable" : "Disable", ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
|
||||
earjack_detect_enable_show, earjack_detect_enable_store);
|
||||
|
||||
static ssize_t earjack_detect_running_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
|
||||
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'",
|
||||
attr->attr.name);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"Earjack detect: %sRunning\n",
|
||||
ed_data->running ? "" : "Not-");
|
||||
}
|
||||
|
||||
/* Echo 0/n/N/of/Of/Of/OF/1/y/Y/on/oN/On/ON > runing */
|
||||
static ssize_t earjack_detect_running_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
bool running;
|
||||
int ret;
|
||||
|
||||
cts_info("Write sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s' size %zu",
|
||||
attr->attr.name, count);
|
||||
|
||||
cts_parse_arg(buf, count);
|
||||
|
||||
if (cts_argc != 1) {
|
||||
cts_err("Invalid num of args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kstrtobool(cts_argv[0], &running);
|
||||
if (ret) {
|
||||
cts_err("Invalid param of running");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (running) {
|
||||
ret = start_earjack_detect(ed_data);
|
||||
} else {
|
||||
ret = stop_earjack_detect(ed_data);
|
||||
}
|
||||
if (ret) {
|
||||
cts_err("%s earjack detect failed %d(%s)",
|
||||
running ? "Start" : "Stop", ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(running, S_IWUSR | S_IRUGO,
|
||||
earjack_detect_running_show, earjack_detect_running_store);
|
||||
|
||||
static ssize_t earjack_state_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
int ret;
|
||||
|
||||
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'",
|
||||
attr->attr.name);
|
||||
|
||||
ret = get_earjack_state(ed_data);
|
||||
if (ret) {
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"Get earjack state failed %d(%s)\n",
|
||||
ret, cts_strerror(ret));
|
||||
}
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"Earjack state: %s\n", earjack_state_str(ed_data->state));
|
||||
}
|
||||
static DEVICE_ATTR(state, S_IRUGO, earjack_state_show, NULL);
|
||||
|
||||
static ssize_t earjack_detect_param_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
|
||||
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'",
|
||||
attr->attr.name);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"Filepath: '%s'\n"
|
||||
"Poll int: %dms\n",
|
||||
ed_data->earjack_state_filepath, ed_data->poll_interval);
|
||||
}
|
||||
|
||||
/* echo filepath [interval] > param */
|
||||
static ssize_t earjack_detect_param_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
|
||||
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
|
||||
u32 interval;
|
||||
int ret;
|
||||
|
||||
cts_info("Write sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s' size %zu",
|
||||
attr->attr.name, count);
|
||||
|
||||
cts_parse_arg(buf, count);
|
||||
|
||||
if (cts_argc < 1 || cts_argc > 2) {
|
||||
cts_err("Invalid num of args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
interval = ed_data->poll_interval;
|
||||
if (cts_argc > 1) {
|
||||
ret = kstrtou32(cts_argv[1], 0, &interval);
|
||||
if (ret) {
|
||||
cts_err("Arg interval is invalid");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ed_data->earjack_state_filepath) {
|
||||
kfree(ed_data->earjack_state_filepath);
|
||||
}
|
||||
ed_data->earjack_state_filepath = kstrdup(cts_argv[0], GFP_KERNEL);
|
||||
if (ed_data->earjack_state_filepath == NULL) {
|
||||
cts_err("Dup earjack state filepath failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ed_data->poll_interval = interval;
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(param, S_IWUSR | S_IRUGO,
|
||||
earjack_detect_param_show, earjack_detect_param_store);
|
||||
|
||||
static struct attribute *earjack_detect_attrs[] = {
|
||||
&dev_attr_enable.attr,
|
||||
&dev_attr_running.attr,
|
||||
&dev_attr_state.attr,
|
||||
&dev_attr_param.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group earjack_detect_attr_group = {
|
||||
.name = EARJACK_DET_SYSFS_GROUP_NAME,
|
||||
.attrs = earjack_detect_attrs,
|
||||
};
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
|
||||
static void poll_earjack_state_work(struct work_struct *work)
|
||||
{
|
||||
struct cts_earjack_detect_data *ed_data;
|
||||
bool prev_state = false;
|
||||
int ret;
|
||||
|
||||
cts_dbg("Poll earjack state work");
|
||||
|
||||
ed_data = container_of(to_delayed_work(work),
|
||||
struct cts_earjack_detect_data, poll_work);
|
||||
|
||||
prev_state = ed_data->state;
|
||||
|
||||
ret = get_earjack_state(ed_data);
|
||||
if (ret) {
|
||||
cts_err("Get state failed %d(%s)", ret, cts_strerror(ret));
|
||||
} else {
|
||||
if (ed_data->state != prev_state) {
|
||||
cts_info("State changed: %s -> %s",
|
||||
earjack_state_str(prev_state),
|
||||
earjack_state_str(ed_data->state));
|
||||
|
||||
cts_lock_device(&ed_data->cts_data->cts_dev);
|
||||
ret = cts_set_dev_earjack_attached(
|
||||
&ed_data->cts_data->cts_dev, ed_data->state);
|
||||
cts_unlock_device(&ed_data->cts_data->cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Set dev earjack attached to %s failed %d(%s)",
|
||||
earjack_state_str(ed_data->state),
|
||||
ret, cts_strerror(ret));
|
||||
/* Set to previous state, try set again in next loop */
|
||||
ed_data->state = prev_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!queue_delayed_work(ed_data->cts_data->workqueue,
|
||||
&ed_data->poll_work,
|
||||
msecs_to_jiffies(ed_data->poll_interval))) {
|
||||
cts_warn("Queue detect work while already on the queue");
|
||||
}
|
||||
}
|
||||
|
||||
int cts_earjack_detect_init(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
struct cts_earjack_detect_data *ed_data;
|
||||
int ret = 0;
|
||||
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Init detect with cts_data = NULL");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ed_data = kzalloc(sizeof(*ed_data), GFP_KERNEL);
|
||||
if (ed_data == NULL) {
|
||||
cts_err("Alloc earjack detect data failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cts_info("Init detect");
|
||||
|
||||
#ifdef CONFIG_CTS_OF
|
||||
ret = parse_earjack_detect_dt(ed_data, cts_data->device->of_node);
|
||||
#else /* CONFIG_CTS_OF */
|
||||
#ifdef CFG_CTS_DEF_EARJACK_DET_ENABLE
|
||||
ed_data->enable = true;
|
||||
#else /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
|
||||
ed_data->enable = false;
|
||||
#endif /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
|
||||
ed_data->poll_interval = CFG_CTS_DEF_EARJACK_POLL_INTERVAL;
|
||||
ed_data->earjack_state_filepath = kstrdup(
|
||||
CFG_CTS_DEF_EARJACK_STATE_FILEPATH, GFP_KERNEL);
|
||||
if (ed_data->earjack_state_filepath == NULL) {
|
||||
cts_err("Dup earjack state filepath failed");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
#endif /* CONFIG_CTS_OF */
|
||||
if (ret) {
|
||||
cts_err("Get detect param failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
goto free_ed_data;
|
||||
}
|
||||
|
||||
cts_info("Detect: %sABLED", ed_data->enable ? "EN" : "DIS");
|
||||
cts_info(" Filepath: '%s'", ed_data->earjack_state_filepath);
|
||||
cts_info(" Poll Int: %dms", ed_data->poll_interval);
|
||||
|
||||
INIT_DELAYED_WORK(&ed_data->poll_work, poll_earjack_state_work);
|
||||
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
cts_info("Create sysfs attr group '%s'", EARJACK_DET_SYSFS_GROUP_NAME);
|
||||
ret = sysfs_create_group(&cts_data->device->kobj,
|
||||
&earjack_detect_attr_group);
|
||||
if (ret) {
|
||||
cts_warn("Create sysfs attr group '%s' failed %d(%s)",
|
||||
EARJACK_DET_SYSFS_GROUP_NAME, ret, cts_strerror(ret));
|
||||
} else {
|
||||
ed_data->sysfs_attr_group_created = true;
|
||||
}
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
|
||||
cts_data->earjack_detect_data = ed_data;
|
||||
ed_data->cts_data = cts_data;
|
||||
|
||||
return 0;
|
||||
|
||||
free_ed_data:
|
||||
kfree(ed_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_earjack_detect_deinit(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
struct cts_earjack_detect_data *ed_data;
|
||||
int ret;
|
||||
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Deinit detect with cts_data = NULL");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ed_data = cts_data->earjack_detect_data;
|
||||
if (ed_data == NULL) {
|
||||
cts_warn("Deinit detect with earjack_detect_data = NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cts_info("Deinit detect");
|
||||
|
||||
if (ed_data->running) {
|
||||
ret = stop_earjack_detect(ed_data);
|
||||
if (ret) {
|
||||
cts_err("Stop detect failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
if (ed_data->sysfs_attr_group_created) {
|
||||
cts_info("Remove sysfs attr group '%s'", EARJACK_DET_SYSFS_GROUP_NAME);
|
||||
sysfs_remove_group(&cts_data->device->kobj, &earjack_detect_attr_group);
|
||||
ed_data->sysfs_attr_group_created = false;
|
||||
}
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
|
||||
if(ed_data->earjack_state_filepath) {
|
||||
kfree(ed_data->earjack_state_filepath);
|
||||
ed_data->earjack_state_filepath = NULL;
|
||||
}
|
||||
|
||||
kfree(ed_data);
|
||||
cts_data->earjack_detect_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_is_earjack_attached(struct chipone_ts_data *cts_data, bool *attached)
|
||||
{
|
||||
struct cts_earjack_detect_data *ed_data;
|
||||
int ret;
|
||||
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Get state with cts_data = NULL");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ed_data = cts_data->earjack_detect_data;
|
||||
if (ed_data == NULL) {
|
||||
cts_err("Get state with earjack_detect_data = NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = get_earjack_state(ed_data);
|
||||
if (ret) {
|
||||
cts_err("Get state failed %d(%s)", ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
cts_info("Get curr state: %s", earjack_state_str(ed_data->state));
|
||||
|
||||
*attached = ed_data->state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_start_earjack_detect(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
struct cts_earjack_detect_data *ed_data;
|
||||
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Start detect with cts_data = NULL");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ed_data = cts_data->earjack_detect_data;
|
||||
if (ed_data == NULL) {
|
||||
cts_err("Start detect with earjack_detect_data = NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return start_earjack_detect(ed_data);
|
||||
}
|
||||
|
||||
int cts_stop_earjack_detect(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
struct cts_earjack_detect_data *ed_data;
|
||||
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Stop detect with cts_data = NULL");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ed_data = cts_data->earjack_detect_data;
|
||||
if (ed_data == NULL) {
|
||||
cts_err("Stop detect with earjack_detect_data = NULL");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return stop_earjack_detect(ed_data);
|
||||
}
|
||||
#endif /* CONFIG_CTS_EARJACK_DETECT */
|
||||
|
||||
42
drivers/input/touchscreen/chipone_tddi/cts_earjack_detect.h
Normal file
42
drivers/input/touchscreen/chipone_tddi/cts_earjack_detect.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_EARJACK_DETECT_H
|
||||
#define CTS_EARJACK_DETECT_H
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
//struct chipone_ts_data;
|
||||
|
||||
#ifdef CONFIG_CTS_EARJACK_DETECT
|
||||
extern int cts_earjack_detect_init(struct chipone_ts_data *cts_data);
|
||||
extern int cts_earjack_detect_deinit(struct chipone_ts_data *cts_data);
|
||||
extern int cts_start_earjack_detect(struct chipone_ts_data *cts_data);
|
||||
extern int cts_stop_earjack_detect(struct chipone_ts_data *cts_data);
|
||||
extern int cts_is_earjack_attached(struct chipone_ts_data *cts_data,
|
||||
bool *attached);
|
||||
#else /* CONFIG_CTS_EARJACK_DETECT */
|
||||
static inline int cts_earjack_detect_init(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cts_earjack_detect_deinit(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cts_start_earjack_detect(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int cts_stop_earjack_detect(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int cts_is_earjack_attached(struct chipone_ts_data *cts_data,
|
||||
bool *attached)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_CTS_EARJACK_DETECT */
|
||||
|
||||
#endif /* CTS_EARJACK_DETECT_H */
|
||||
|
||||
1044
drivers/input/touchscreen/chipone_tddi/cts_firmware.c
Normal file
1044
drivers/input/touchscreen/chipone_tddi/cts_firmware.c
Normal file
File diff suppressed because it is too large
Load Diff
33
drivers/input/touchscreen/chipone_tddi/cts_firmware.h
Normal file
33
drivers/input/touchscreen/chipone_tddi/cts_firmware.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_FIRMWARE_H
|
||||
#define CTS_FIRMWARE_H
|
||||
|
||||
#include "cts_config.h"
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
|
||||
|
||||
#define FIRMWARE_VERSION_OFFSET 0x100
|
||||
#define FIRMWARE_VERSION(firmware) \
|
||||
get_unaligned_le16((firmware)->data + FIRMWARE_VERSION_OFFSET)
|
||||
|
||||
struct cts_device;
|
||||
extern int cts_request_newer_firmware_from_fs(struct cts_device *cts_dev,
|
||||
const char *filepath, u16 curr_version);
|
||||
extern bool cts_is_firmware_updating(struct cts_device *cts_dev);
|
||||
extern int cts_request_firmware(struct cts_device *cts_dev,
|
||||
u32 hwid, u16 fwid, u16 device_fw_ver);
|
||||
extern int cts_update_firmware(struct cts_device *cts_dev);
|
||||
|
||||
#ifdef CFG_CTS_FIRMWARE_IN_FS
|
||||
extern int cts_update_firmware_from_file(struct cts_device *cts_dev,
|
||||
const char *filepath);
|
||||
|
||||
#endif /* CFG_CTS_FIRMWARE_IN_FS */
|
||||
|
||||
extern u16 cts_crc16(const u8 *data, size_t len);
|
||||
extern u32 cts_crc32(const u8 *data, size_t len);
|
||||
|
||||
#endif /* CTS_FIRMWARE_H */
|
||||
2127
drivers/input/touchscreen/chipone_tddi/cts_oem.c
Normal file
2127
drivers/input/touchscreen/chipone_tddi/cts_oem.c
Normal file
File diff suppressed because it is too large
Load Diff
12
drivers/input/touchscreen/chipone_tddi/cts_oem.h
Normal file
12
drivers/input/touchscreen/chipone_tddi/cts_oem.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_OEM_H
|
||||
#define CTS_OEM_H
|
||||
|
||||
struct chipone_ts_data;
|
||||
|
||||
extern int cts_oem_init(struct chipone_ts_data *cts_data);
|
||||
extern int cts_oem_deinit(struct chipone_ts_data *cts_data);
|
||||
|
||||
#endif /* CTS_VENDOR_H */
|
||||
|
||||
1919
drivers/input/touchscreen/chipone_tddi/cts_platform.c
Normal file
1919
drivers/input/touchscreen/chipone_tddi/cts_platform.c
Normal file
File diff suppressed because it is too large
Load Diff
309
drivers/input/touchscreen/chipone_tddi/cts_platform.h
Normal file
309
drivers/input/touchscreen/chipone_tddi/cts_platform.h
Normal file
@@ -0,0 +1,309 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_PLATFORM_H
|
||||
#define CTS_PLATFORM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/ctype.h>
|
||||
//#include <linux/unaligned/access_ok.h>
|
||||
#include <asm-generic/unaligned.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/rtmutex.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/suspend.h>
|
||||
/* #include <linux/wakelock.h> */
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_irq.h>
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_core.h"
|
||||
|
||||
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
||||
#ifdef TPD_SUPPORT_I2C_DMA
|
||||
#include <linux/dma-mapping.h>
|
||||
#endif /* TPD_SUPPORT_I2C_DMA */
|
||||
|
||||
#ifdef CONFIG_MTK_BOOT
|
||||
#include "mtk_boot_common.h"
|
||||
#endif /* CONFIG_MTK_BOOT */
|
||||
|
||||
#include "tpd.h"
|
||||
#include "tpd_debug.h"
|
||||
#include "upmu_common.h"
|
||||
#endif
|
||||
|
||||
extern bool cts_show_debug_log;
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG ""
|
||||
#endif /* LOG_TAG */
|
||||
|
||||
enum cts_driver_log_level {
|
||||
CTS_DRIVER_LOG_ERROR,
|
||||
CTS_DRIVER_LOG_WARN,
|
||||
CTS_DRIVER_LOG_INFO,
|
||||
CTS_DRIVER_LOG_DEBUG,
|
||||
};
|
||||
|
||||
extern int cts_start_driver_log_redirect(const char *filepath, bool append_to_file,
|
||||
char *log_buffer, int log_buf_size, int log_level);
|
||||
extern void cts_stop_driver_log_redirect(void);
|
||||
extern int cts_get_driver_log_redirect_size(void);
|
||||
extern void cts_log(int level, const char *fmt, ...);
|
||||
|
||||
#define cts_err(fmt, ...) \
|
||||
cts_log(CTS_DRIVER_LOG_ERROR, "<E>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
#define cts_warn(fmt, ...) \
|
||||
cts_log(CTS_DRIVER_LOG_WARN, "<W>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
#define cts_info(fmt, ...) \
|
||||
cts_log(CTS_DRIVER_LOG_INFO, "<I>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
#define cts_dbg(fmt, ...) \
|
||||
cts_log(CTS_DRIVER_LOG_DEBUG, "<D>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
|
||||
|
||||
struct cts_device;
|
||||
struct cts_device_touch_msg;
|
||||
struct cts_device_gesture_info;
|
||||
|
||||
struct cts_platform_data {
|
||||
int irq;
|
||||
|
||||
#ifndef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
||||
int int_gpio;
|
||||
#ifdef CFG_CTS_HAS_RESET_PIN
|
||||
int rst_gpio;
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_MANUAL_CS
|
||||
int cs_gpio;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
u32 res_x;
|
||||
u32 res_y;
|
||||
|
||||
#ifdef CONFIG_CTS_VIRTUALKEY
|
||||
u8 vkey_num;
|
||||
u8 vkey_state;
|
||||
u8 vkey_keycodes[CFG_CTS_MAX_VKEY_NUM];
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_FW_UPDATE_SYS
|
||||
const char *panel_supplier;
|
||||
#endif
|
||||
u32 build_id;
|
||||
u32 config_id;
|
||||
|
||||
struct cts_device *cts_dev;
|
||||
|
||||
struct input_dev *ts_input_dev;
|
||||
struct input_dev *pen_input_dev;
|
||||
|
||||
#ifndef CONFIG_GENERIC_HARDIRQS
|
||||
struct work_struct ts_irq_work;
|
||||
#endif
|
||||
|
||||
struct mutex dev_lock;
|
||||
struct spinlock irq_lock;
|
||||
bool irq_is_disable;
|
||||
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
u8 gesture_num;
|
||||
u8 gesture_keymap[CFG_CTS_NUM_GESTURE][2];
|
||||
bool irq_wake_enabled;
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
||||
#ifdef TPD_SUPPORT_I2C_DMA
|
||||
u8 *i2c_dma_buff_va;
|
||||
dma_addr_t i2c_dma_buff_pa;
|
||||
#endif /* TPD_SUPPORT_I2C_DMA */
|
||||
#else
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
struct notifier_block fb_notifier;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CFG_CTS_FORCE_UP
|
||||
struct delayed_work touch_timeout;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
struct i2c_client *i2c_client;
|
||||
u8 i2c_fifo_buf[CFG_CTS_MAX_I2C_XFER_SIZE];
|
||||
u8 i2c_rbuf[ALIGN(CFG_CTS_MAX_I2C_READ_SIZE, 4)];
|
||||
#else
|
||||
struct spi_device *spi_client;
|
||||
u8 spi_cache_buf[ALIGN(CFG_CTS_MAX_SPI_XFER_SIZE + 10, 4)];
|
||||
u8 spi_rx_buf[ALIGN(CFG_CTS_MAX_SPI_XFER_SIZE + 10, 4)];
|
||||
u8 spi_tx_buf[ALIGN(CFG_CTS_MAX_SPI_XFER_SIZE + 10, 4)];
|
||||
u32 spi_speed;
|
||||
|
||||
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
||||
#ifdef CFG_CTS_MANUAL_CS
|
||||
struct pinctrl *pinctrl1;
|
||||
struct pinctrl_state *spi_cs_low, *spi_cs_high;
|
||||
#endif
|
||||
#endif/* CONFIG_CTS_I2C_HOST */
|
||||
|
||||
#ifdef TPD_SUPPORT_I2C_DMA
|
||||
bool i2c_dma_available;
|
||||
#endif /* TPD_SUPPORT_I2C_DMA */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
extern size_t cts_plat_get_max_i2c_xfer_size(struct cts_platform_data *pdata);
|
||||
extern u8 *cts_plat_get_i2c_xfer_buf(struct cts_platform_data *pdata,
|
||||
size_t xfer_size);
|
||||
extern int cts_plat_i2c_write(struct cts_platform_data *pdata, u8 i2c_addr,
|
||||
const void *src, size_t len, int retry, int delay);
|
||||
extern int cts_plat_i2c_read(struct cts_platform_data *pdata, u8 i2c_addr,
|
||||
const u8 *wbuf, size_t wlen, void *rbuf,
|
||||
size_t rlen, int retry, int delay);
|
||||
#else /* CONFIG_CTS_I2C_HOST */
|
||||
extern size_t cts_plat_get_max_spi_xfer_size(struct cts_platform_data *pdata);
|
||||
extern u8 *cts_plat_get_spi_xfer_buf(struct cts_platform_data *pdata,
|
||||
size_t xfer_size);
|
||||
extern int cts_plat_spi_write(struct cts_platform_data *pdata, u8 i2c_addr,
|
||||
const void *src, size_t len, int retry, int delay);
|
||||
extern int cts_plat_spi_read(struct cts_platform_data *pdata, u8 i2c_addr,
|
||||
const u8 *wbuf, size_t wlen, void *rbuf,
|
||||
size_t rlen, int retry, int delay);
|
||||
extern int cts_plat_spi_read_delay_idle(struct cts_platform_data *pdata,
|
||||
u8 dev_addr, const u8 *wbuf, size_t wlen, void *rbuf, size_t rlen,
|
||||
int retry, int delay, int idle);
|
||||
extern int cts_spi_send_recv(struct cts_platform_data *pdata, size_t len,
|
||||
u8 *tx_buffer, u8 *rx_buffer);
|
||||
#endif /* CONFIG_CTS_I2C_HOST */
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
extern int cts_init_platform_data(struct cts_platform_data *pdata,
|
||||
struct i2c_client *i2c_client);
|
||||
#else
|
||||
extern int cts_init_platform_data(struct cts_platform_data *pdata,
|
||||
struct spi_device *spi);
|
||||
#endif
|
||||
|
||||
extern int cts_plat_is_normal_mode(struct cts_platform_data *pdata);
|
||||
#ifndef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
||||
extern int cts_deinit_platform_data(struct cts_platform_data *pdata);
|
||||
#endif
|
||||
extern int cts_plat_request_resource(struct cts_platform_data *pdata);
|
||||
extern void cts_plat_free_resource(struct cts_platform_data *pdata);
|
||||
|
||||
extern int cts_plat_request_irq(struct cts_platform_data *pdata);
|
||||
extern void cts_plat_free_irq(struct cts_platform_data *pdata);
|
||||
extern int cts_plat_enable_irq(struct cts_platform_data *pdata);
|
||||
extern int cts_plat_disable_irq(struct cts_platform_data *pdata);
|
||||
|
||||
#ifdef CFG_CTS_HAS_RESET_PIN
|
||||
extern int cts_plat_reset_device(struct cts_platform_data *pdata);
|
||||
#else /* CFG_CTS_HAS_RESET_PIN */
|
||||
static inline int cts_plat_reset_device(struct cts_platform_data *pdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CFG_CTS_HAS_RESET_PIN */
|
||||
|
||||
extern int cts_plat_init_touch_device(struct cts_platform_data *pdata);
|
||||
extern void cts_plat_deinit_touch_device(struct cts_platform_data *pdata);
|
||||
#ifdef CFG_CTS_PALM_DETECT
|
||||
void cts_report_palm_event(struct cts_platform_data *pdata);
|
||||
#endif
|
||||
extern int cts_plat_process_touch_msg(struct cts_platform_data *pdata,
|
||||
struct cts_device_touch_msg *msgs, int num);
|
||||
extern int cts_plat_process_stylus_msg(struct cts_platform_data *pdata,
|
||||
struct cts_device_stylus_msg *msgs, int num);
|
||||
#ifdef CFG_CTS_FINGER_STYLUS_SUPPORTED
|
||||
extern int cts_plat_process_touch_stylus(struct cts_platform_data *pdata,
|
||||
struct cts_device_touch_info *touch_info);
|
||||
#endif
|
||||
extern int cts_plat_release_all_touch(struct cts_platform_data *pdata);
|
||||
|
||||
#ifdef CONFIG_CTS_VIRTUALKEY
|
||||
extern int cts_plat_init_vkey_device(struct cts_platform_data *pdata);
|
||||
extern void cts_plat_deinit_vkey_device(struct cts_platform_data *pdata);
|
||||
extern int cts_plat_process_vkey(struct cts_platform_data *pdata,
|
||||
u8 vkey_state);
|
||||
extern int cts_plat_release_all_vkey(struct cts_platform_data *pdata);
|
||||
#else /* CONFIG_CTS_VIRTUALKEY */
|
||||
static inline int cts_plat_init_vkey_device(struct cts_platform_data *pdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cts_plat_deinit_vkey_device(struct cts_platform_data *pdata)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int cts_plat_process_vkey(struct cts_platform_data *pdata,
|
||||
u8 vkey_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cts_plat_release_all_vkey(struct cts_platform_data *pdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CTS_VIRTUALKEY */
|
||||
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
extern int cts_plat_enable_irq_wake(struct cts_platform_data *pdata);
|
||||
extern int cts_plat_disable_irq_wake(struct cts_platform_data *pdata);
|
||||
|
||||
extern int cts_plat_init_gesture(struct cts_platform_data *pdata);
|
||||
extern void cts_plat_deinit_gesture(struct cts_platform_data *pdata);
|
||||
extern int cts_plat_process_gesture_info(struct cts_platform_data *pdata,
|
||||
struct cts_device_gesture_info *gesture_info);
|
||||
#else /* CFG_CTS_GESTURE */
|
||||
static inline int cts_plat_init_gesture(struct cts_platform_data *pdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cts_plat_deinit_gesture(struct cts_platform_data *pdata)
|
||||
{
|
||||
}
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
extern int cts_plat_set_reset(struct cts_platform_data *pdata, int val);
|
||||
extern int cts_plat_get_int_pin(struct cts_platform_data *pdata);
|
||||
|
||||
#ifdef CFG_CTS_MANUAL_CS
|
||||
extern int cts_plat_set_cs(struct cts_platform_data *pdata, int val);
|
||||
#endif
|
||||
#endif /* CTS_PLATFORM_H */
|
||||
38
drivers/input/touchscreen/chipone_tddi/cts_sfctrl.h
Normal file
38
drivers/input/touchscreen/chipone_tddi/cts_sfctrl.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_SFCTRL_H
|
||||
#define CTS_SFCTRL_H
|
||||
|
||||
#include "cts_core.h"
|
||||
#include "cts_spi_flash.h"
|
||||
|
||||
struct cts_device;
|
||||
|
||||
struct cts_sfctrl_ops {
|
||||
int (*rdid)(struct cts_device *cts_dev, u32 *id);
|
||||
int (*se)(struct cts_device *cts_dev, u32 sector_addr);
|
||||
int (*be)(struct cts_device *cts_dev, u32 sector_addr);
|
||||
int (*read)(struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t len);
|
||||
int (*read_to_sram)(struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t len);
|
||||
int (*program)(struct cts_device *cts_dev,
|
||||
u32 flash_addr, const void *src, size_t len);
|
||||
int (*program_from_sram)(struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t len);
|
||||
int (*calc_sram_crc)(struct cts_device *cts_dev,
|
||||
u32 sram_addr, size_t len, u32 *crc);
|
||||
int (*calc_flash_crc)(struct cts_device *cts_dev,
|
||||
u32 flash_addr, size_t len, u32 *crc);
|
||||
};
|
||||
|
||||
struct cts_sfctrl {
|
||||
u32 reg_base;
|
||||
u32 xchg_sram_base;
|
||||
size_t xchg_sram_size;
|
||||
const struct cts_sfctrl_ops *ops;
|
||||
};
|
||||
|
||||
extern const struct cts_sfctrl_ops cts_sfctrlv2_ops;
|
||||
|
||||
#endif /* CTS_SFCTRL_H */
|
||||
342
drivers/input/touchscreen/chipone_tddi/cts_sfctrlv2.c
Normal file
342
drivers/input/touchscreen/chipone_tddi/cts_sfctrlv2.c
Normal file
@@ -0,0 +1,342 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#define LOG_TAG "SFCtrl"
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_platform.h"
|
||||
#include "cts_core.h"
|
||||
#include "cts_sfctrl.h"
|
||||
|
||||
#define rSFCTRLv2_CMD_SEL (0x0000)
|
||||
#define rSFCTRLv2_FLASH_ADDR (0x0004)
|
||||
#define rSFCTRLv2_SRAM_ADDR (0x0008)
|
||||
#define rSFCTRLv2_DATA_LENGTH (0x000C)
|
||||
#define rSFCTRLv2_START_DEXC (0x0010)
|
||||
#define rSFCTRLv2_RELEASE_FLASH (0x0014)
|
||||
#define rSFCTRLv2_HW_STATE (0x0018)
|
||||
#define rSFCTRLv2_CRC_RESULT (0x001C)
|
||||
#define rSFCTRLv2_SRAM_CRC_START (0x0020)
|
||||
#define rSFCTRLv2_FLASH_CRC_START (0x0022)
|
||||
#define rSFCTRLv2_SF_BUSY (0x0024)
|
||||
|
||||
/** Constants for register @ref rSFCTRLv2_CMD_SEL */
|
||||
enum sfctrlv2_cmd {
|
||||
SFCTRLv2_CMD_FAST_READ = 0x01u,
|
||||
SFCTRLv2_CMD_SE = 0x02u,
|
||||
SFCTRLv2_CMD_BE = 0x03u,
|
||||
SFCTRLv2_CMD_PP = 0x04u,
|
||||
SFCTRLv2_CMD_RDSR = 0x05u,
|
||||
SFCTRLv2_CMD_RDID = 0x06u
|
||||
};
|
||||
|
||||
/** SPI flash controller v2 operation flags. */
|
||||
enum sfctrlv2_opflags {
|
||||
SFCTRLv2_OPFLAG_READ = BIT(0),
|
||||
SFCTRLv2_OPFLAG_SET_FLASH_ADDR = BIT(1),
|
||||
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG = BIT(2),
|
||||
SFCTRLv2_OPFLAG_SET_DATA_LENGTH = BIT(3),
|
||||
SFCTRLv2_OPFLAG_WAIT_WIP_CLR = BIT(4),
|
||||
};
|
||||
|
||||
#define SFCTRLv2_CMD_RDID_FLAGS \
|
||||
(SFCTRLv2_OPFLAG_READ | \
|
||||
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG)
|
||||
|
||||
#define SFCTRLv2_CMD_RDSR_FLAGS \
|
||||
(SFCTRLv2_OPFLAG_READ | \
|
||||
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG)
|
||||
|
||||
#define SFCTRLv2_CMD_SE_FLAGS \
|
||||
(SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
|
||||
SFCTRLv2_OPFLAG_WAIT_WIP_CLR)
|
||||
|
||||
#define SFCTRLv2_CMD_BE_FLAGS \
|
||||
(SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
|
||||
SFCTRLv2_OPFLAG_WAIT_WIP_CLR)
|
||||
|
||||
#define SFCTRLv2_CMD_PP_FLAGS \
|
||||
(SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
|
||||
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG | \
|
||||
SFCTRLv2_OPFLAG_SET_DATA_LENGTH | \
|
||||
SFCTRLv2_OPFLAG_WAIT_WIP_CLR)
|
||||
|
||||
#define SFCTRLv2_CMD_FAST_READ_FLAGS \
|
||||
(SFCTRLv2_OPFLAG_READ | \
|
||||
SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
|
||||
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG | \
|
||||
SFCTRLv2_OPFLAG_SET_DATA_LENGTH)
|
||||
|
||||
#define sfctrl_reg_addr(cts_dev, offset) \
|
||||
((cts_dev)->hwdata->sfctrl->reg_base + offset)
|
||||
|
||||
#define DEFINE_SFCTRL_REG_ACCESS_FUNC(access_type, data_type) \
|
||||
static inline int sfctrl_reg_ ## access_type(struct cts_device *cts_dev, \
|
||||
u32 reg, data_type data) { \
|
||||
return cts_hw_reg_ ## access_type(cts_dev, sfctrl_reg_addr(cts_dev, reg), data); \
|
||||
}
|
||||
|
||||
DEFINE_SFCTRL_REG_ACCESS_FUNC(writeb_relaxed, u8)
|
||||
DEFINE_SFCTRL_REG_ACCESS_FUNC(writew_relaxed, u16)
|
||||
DEFINE_SFCTRL_REG_ACCESS_FUNC(writel_relaxed, u32)
|
||||
DEFINE_SFCTRL_REG_ACCESS_FUNC(readb_relaxed, u8 *)
|
||||
DEFINE_SFCTRL_REG_ACCESS_FUNC(readw_relaxed, u16 *)
|
||||
DEFINE_SFCTRL_REG_ACCESS_FUNC(readl_relaxed, u32 *)
|
||||
|
||||
#define sfctrl_write_reg_check_ret(access_type, reg, val) \
|
||||
do { \
|
||||
int ret; \
|
||||
cts_dbg("Write " #reg " to 0x%x", val); \
|
||||
ret = sfctrl_reg_ ## access_type(cts_dev, reg, val); \
|
||||
if (ret) { \
|
||||
cts_err("Write " #reg " failed %d", ret); \
|
||||
return ret; \
|
||||
} \
|
||||
} while (0)
|
||||
#define sfctrl_read_reg_check_ret(access_type, reg, val) \
|
||||
do { \
|
||||
int ret; \
|
||||
cts_dbg("Read " #reg ""); \
|
||||
ret = sfctrl_reg_ ## access_type(cts_dev, reg, val); \
|
||||
if (ret) { \
|
||||
cts_err("Read " #reg " failed %d", ret); \
|
||||
return ret; \
|
||||
} \
|
||||
} while (0)
|
||||
static int wait_sfctrl_xfer_comp(struct cts_device *cts_dev)
|
||||
{
|
||||
int retries = 0;
|
||||
u8 status;
|
||||
|
||||
do {
|
||||
sfctrl_read_reg_check_ret(readb_relaxed, rSFCTRLv2_SF_BUSY, &status);
|
||||
if (status == 0)
|
||||
return 0;
|
||||
mdelay(1);
|
||||
} while (status && retries++ < 1000);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int sfctrlv2_rdsr(struct cts_device *cts_dev, u8 *status)
|
||||
{
|
||||
#define RDSR_XCHG_SRAM_ADDR (cts_dev->hwdata->sfctrl->xchg_sram_base + cts_dev->hwdata->sfctrl->xchg_sram_size - 1)
|
||||
|
||||
int ret;
|
||||
|
||||
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_CMD_SEL,
|
||||
SFCTRLv2_CMD_RDSR);
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_SRAM_ADDR,
|
||||
RDSR_XCHG_SRAM_ADDR);
|
||||
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_START_DEXC, 1);
|
||||
|
||||
ret = wait_sfctrl_xfer_comp(cts_dev);
|
||||
if (ret != 0) {
|
||||
cts_err("Wait sfctrl ready failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cts_sram_readb(cts_dev, RDSR_XCHG_SRAM_ADDR, status);
|
||||
if (ret) {
|
||||
cts_err("Read exchange sram failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#undef RDSR_XCHG_SRAM_ADDR
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_flash_wip_clear(struct cts_device *cts_dev)
|
||||
{
|
||||
#define FLASH_SR_WIP BIT(0) /*!< Write in progress */
|
||||
|
||||
int ret, retries = 0;
|
||||
u8 status;
|
||||
|
||||
do {
|
||||
ret = sfctrlv2_rdsr(cts_dev, &status);
|
||||
if (ret) {
|
||||
cts_err("Read flash status register failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (status & FLASH_SR_WIP)
|
||||
mdelay(1);
|
||||
else
|
||||
return 0;
|
||||
} while (status & FLASH_SR_WIP && retries++ < 1000);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
#undef FLASH_SR_WIP
|
||||
}
|
||||
|
||||
static int sfctrlv2_transfer(struct cts_device *cts_dev,
|
||||
u8 cmd, void *data, u32 flash_addr, u32 sram_addr,
|
||||
size_t size, u32 flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_CMD_SEL, cmd);
|
||||
|
||||
if (flags & SFCTRLv2_OPFLAG_SRAM_DATA_XCHG) {
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_SRAM_ADDR,
|
||||
sram_addr);
|
||||
|
||||
/** - Write data to exchange SRAM if operation is write and
|
||||
* data != NULL(data not in SRAM)
|
||||
*/
|
||||
if ((!(flags & SFCTRLv2_OPFLAG_READ)) && data) {
|
||||
ret = cts_sram_writesb(cts_dev, sram_addr, data, size);
|
||||
if (ret) {
|
||||
cts_err("Write data to exchange sram 0x%06x size %zu failed %d",
|
||||
sram_addr, size, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SFCTRLv2_OPFLAG_SET_FLASH_ADDR) {
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_FLASH_ADDR,
|
||||
flash_addr);
|
||||
}
|
||||
if (flags & SFCTRLv2_OPFLAG_SET_DATA_LENGTH) {
|
||||
sfctrl_write_reg_check_ret(writel_relaxed,
|
||||
rSFCTRLv2_DATA_LENGTH, (u32) size);
|
||||
}
|
||||
|
||||
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_START_DEXC, 1);
|
||||
|
||||
ret = wait_sfctrl_xfer_comp(cts_dev);
|
||||
if (ret != 0) {
|
||||
cts_err("Wait sfctrl ready failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wait_flash_wip_clear(cts_dev);
|
||||
if (flags & SFCTRLv2_OPFLAG_WAIT_WIP_CLR && ret != 0) {
|
||||
cts_err("Wait WIP clear failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((flags & SFCTRLv2_OPFLAG_READ) && data) {
|
||||
ret = cts_sram_readsb(cts_dev, sram_addr, data, size);
|
||||
if (ret) {
|
||||
cts_err("Read data from exchange sram 0x%06x size %zu failed %d",
|
||||
sram_addr, size, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfctrlv2_rdid(struct cts_device *cts_dev, u32 *id)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[4];
|
||||
|
||||
ret = sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_RDID, buf,
|
||||
0, cts_dev->hwdata->sfctrl->xchg_sram_base, 3,
|
||||
SFCTRLv2_CMD_RDID_FLAGS);
|
||||
*id = ret ? 0 : get_unaligned_be24(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sfctrlv2_se(struct cts_device *cts_dev, u32 sector_addr)
|
||||
{
|
||||
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_SE, NULL,
|
||||
sector_addr, 0, 0, SFCTRLv2_CMD_SE_FLAGS);
|
||||
}
|
||||
|
||||
static int sfctrlv2_be(struct cts_device *cts_dev, u32 block_addr)
|
||||
{
|
||||
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_BE, NULL,
|
||||
block_addr, 0, 0, SFCTRLv2_CMD_BE_FLAGS);
|
||||
}
|
||||
|
||||
static int sfctrlv2_pp(struct cts_device *cts_dev,
|
||||
u32 flash_addr, const void *src, size_t size)
|
||||
{
|
||||
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_PP, (void *)src,
|
||||
flash_addr, cts_dev->hwdata->sfctrl->xchg_sram_base, size,
|
||||
SFCTRLv2_CMD_PP_FLAGS);
|
||||
}
|
||||
|
||||
static int sfctrlv2_program_flash_from_sram(struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t len)
|
||||
{
|
||||
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_PP, NULL,
|
||||
flash_addr, sram_addr, len, SFCTRLv2_CMD_PP_FLAGS);
|
||||
}
|
||||
|
||||
static int sfctrlv2_read(struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t size)
|
||||
{
|
||||
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_FAST_READ, dst,
|
||||
flash_addr, cts_dev->hwdata->sfctrl->xchg_sram_base, size,
|
||||
SFCTRLv2_CMD_FAST_READ_FLAGS);
|
||||
}
|
||||
|
||||
static int sfctrlv2_read_flash_to_sram(struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t size)
|
||||
{
|
||||
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_FAST_READ, NULL,
|
||||
flash_addr, sram_addr, size, SFCTRLv2_CMD_FAST_READ_FLAGS);
|
||||
}
|
||||
|
||||
static int sfctrlv2_calc_sram_crc(struct cts_device *cts_dev,
|
||||
u32 sram_addr, size_t size, u32 *crc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_SRAM_ADDR, sram_addr);
|
||||
mdelay(1);
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_DATA_LENGTH, (u32) size);
|
||||
mdelay(1);
|
||||
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_SRAM_CRC_START, 1);
|
||||
mdelay(10);
|
||||
|
||||
ret = wait_sfctrl_xfer_comp(cts_dev);
|
||||
if (ret != 0) {
|
||||
cts_err("Wait sfctrl ready failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sfctrl_read_reg_check_ret(readl_relaxed, rSFCTRLv2_CRC_RESULT, crc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfctrlv2_calc_flash_crc(struct cts_device *cts_dev,
|
||||
u32 flash_addr, size_t size, u32 *crc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cts_info("Calc crc from flash 0x%06x size %zu", flash_addr, size);
|
||||
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_FLASH_ADDR, flash_addr);
|
||||
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_DATA_LENGTH, (u32) size);
|
||||
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_FLASH_CRC_START, 1);
|
||||
|
||||
ret = wait_sfctrl_xfer_comp(cts_dev);
|
||||
if (ret != 0) {
|
||||
cts_err("Wait sfctrl ready failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sfctrl_read_reg_check_ret(readl_relaxed, rSFCTRLv2_CRC_RESULT, crc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct cts_sfctrl_ops cts_sfctrlv2_ops = {
|
||||
.rdid = sfctrlv2_rdid,
|
||||
.se = sfctrlv2_se,
|
||||
.be = sfctrlv2_be,
|
||||
.read = sfctrlv2_read,
|
||||
.read_to_sram = sfctrlv2_read_flash_to_sram,
|
||||
.program = sfctrlv2_pp,
|
||||
.program_from_sram = sfctrlv2_program_flash_from_sram,
|
||||
.calc_sram_crc = sfctrlv2_calc_sram_crc,
|
||||
.calc_flash_crc = sfctrlv2_calc_flash_crc,
|
||||
};
|
||||
536
drivers/input/touchscreen/chipone_tddi/cts_spi_flash.c
Normal file
536
drivers/input/touchscreen/chipone_tddi/cts_spi_flash.c
Normal file
@@ -0,0 +1,536 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#define LOG_TAG "Flash"
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_platform.h"
|
||||
#include "cts_core.h"
|
||||
#include "cts_sfctrl.h"
|
||||
#include "cts_spi_flash.h"
|
||||
#include "cts_strerror.h"
|
||||
|
||||
/* NOTE: double check command sets and memory organization when you add
|
||||
* more flash chips. This current list focusses on newer chips, which
|
||||
* have been converging on command sets which including JEDEC ID.
|
||||
*/
|
||||
static const struct cts_flash cts_flashes[] = {
|
||||
/* Winbond */
|
||||
{ "Winbond,W25Q10EW",
|
||||
0xEF6011, 256, 0x1000, 0x8000, 0x20000},
|
||||
{ "Winbond,W25Q20EW",
|
||||
0xEF6012, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Winbond,W25Q40EW",
|
||||
0xEF6013, 256, 0x1000, 0x8000, 0x80000},
|
||||
{ "Winbond,W25Q20BW",
|
||||
0xEF5012, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Winbond,W25Q40BW",
|
||||
0xEF5013, 256, 0x1000, 0x8000, 0x80000},
|
||||
|
||||
/* Giga device */
|
||||
{ "Giga,GD25LQ10B",
|
||||
0xC86011, 256, 0x1000, 0x8000, 0x20000},
|
||||
{ "Giga,GD25LD20CEIGR",
|
||||
0xC86012, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Giga,GD25LD40CEIGR",
|
||||
0xC86013, 256, 0x1000, 0x8000, 0x80000},
|
||||
|
||||
/* Macronix */
|
||||
{ "Macronix,MX25U1001E",
|
||||
0xC22531, 32, 0x1000, 0x10000, 0x20000},
|
||||
{ "Macronix,MX25R2035F",
|
||||
0xC22812, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Macronix,MX25R4035F",
|
||||
0xC22813, 256, 0x1000, 0x8000, 0x80000},
|
||||
|
||||
/* Puya-Semi */
|
||||
{ "Puya-Semi,P25Q20LUVHIR",
|
||||
0x856012, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Puya-Semi,P25Q40LUXHIR",
|
||||
0x856013, 256, 0x1000, 0x8000, 0x80000},
|
||||
{ "Puya-Semi,P25Q11L",
|
||||
0x854011, 256, 0x1000, 0x8000, 0x20000},
|
||||
{ "Puya-Semi,P25Q21L",
|
||||
0x854012, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Puya-Semi,P25T22L",
|
||||
0x854412, 256, 0x1000, 0x8000, 0x40000},
|
||||
|
||||
|
||||
/* Boya */
|
||||
{ "Boya,BY25D10",
|
||||
0x684011, 256, 0x1000, 0x8000, 0x20000},
|
||||
|
||||
/* EON */
|
||||
{ "EoN,EN25S20A",
|
||||
0x1C3812, 256, 0x1000, 0x8000, 0x40000},
|
||||
|
||||
/* XTXTECH */
|
||||
{ "XTX,XT25Q01",
|
||||
0x0B6011, 256, 0x1000, 0, 0x20000},
|
||||
{ "XTX,XT25Q02",
|
||||
0x0B6012, 256, 0x1000, 0, 0x40000},
|
||||
|
||||
/* Xinxin-Semi */
|
||||
{ "Xinxin-Semi,XM25QU20B",
|
||||
0x205012, 256, 0x1000, 0x8000, 0x40000},
|
||||
{ "Xinxin-Semi,XM25QU40B",
|
||||
0x205013, 256, 0x1000, 0x8000, 0x80000},
|
||||
|
||||
{ "KangYong,XK25Q20T",
|
||||
0xEB6012, 256, 0x1000, 0x8000, 0x40000},
|
||||
|
||||
/*ZBIT*/
|
||||
{ "ZBIT,ZB25LD40B",
|
||||
0x5E1013, 256, 0x1000, 0x8000, 0x80000},
|
||||
};
|
||||
|
||||
static const struct cts_flash *find_flash_by_jedec_id(u32 jedec_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cts_flashes); i++) {
|
||||
if (cts_flashes[i].jedec_id == jedec_id) {
|
||||
return &cts_flashes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int probe_flash(struct cts_device *cts_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cts_info("Probe flash");
|
||||
|
||||
if (cts_dev->hwdata->sfctrl->ops->rdid != NULL) {
|
||||
u32 id;
|
||||
|
||||
cts_info("Read JEDEC ID");
|
||||
|
||||
ret = cts_dev->hwdata->sfctrl->ops->rdid(cts_dev, &id);
|
||||
if (ret) {
|
||||
cts_err("Read JEDEC ID failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
cts_dev->flash = find_flash_by_jedec_id(id);
|
||||
if (cts_dev->flash == NULL) {
|
||||
cts_err("Unknown JEDEC ID: %06x", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cts_info("Flash type: '%s'", cts_dev->flash->name);
|
||||
return 0;
|
||||
} else {
|
||||
cts_err("Probe flash with sfctrl->ops->rdid == NULL");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
/** Make sure sector addr is sector aligned && < flash total size */
|
||||
static int erase_sector_retry(struct cts_device *cts_dev,
|
||||
u32 sector_addr, int retry)
|
||||
{
|
||||
int ret, retries;
|
||||
|
||||
cts_info(" Erase sector 0x%06x", sector_addr);
|
||||
|
||||
retries = 0;
|
||||
do {
|
||||
retries++;
|
||||
ret = cts_dev->hwdata->sfctrl->ops->se(cts_dev, sector_addr);
|
||||
if (ret) {
|
||||
cts_err("Erase sector 0x%06x failed %d(%s) retries %d",
|
||||
sector_addr, ret, cts_strerror(ret), retries);
|
||||
continue;
|
||||
}
|
||||
} while (retries < retry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Make sure sector addr is sector aligned && < flash total size */
|
||||
static inline int erase_sector(struct cts_device *cts_dev,
|
||||
u32 sector_addr)
|
||||
{
|
||||
return erase_sector_retry(cts_dev, sector_addr, CTS_FLASH_ERASE_DEFAULT_RETRY);
|
||||
}
|
||||
|
||||
/** Make sure block addr is block aligned && < flash total size */
|
||||
static int erase_block_retry(struct cts_device *cts_dev,
|
||||
u32 block_addr, int retry)
|
||||
{
|
||||
int ret, retries;
|
||||
|
||||
cts_info(" Erase block 0x%06x", block_addr);
|
||||
|
||||
retries = 0;
|
||||
do {
|
||||
retries++;
|
||||
|
||||
ret = cts_dev->hwdata->sfctrl->ops->be(cts_dev, block_addr);
|
||||
if (ret) {
|
||||
cts_err("Erase block 0x%06x failed %d(%s) retries %d",
|
||||
block_addr, ret, cts_strerror(ret), retries);
|
||||
continue;
|
||||
}
|
||||
} while (retries < retry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Make sure block addr is block aligned && < flash total size */
|
||||
static inline int erase_block(struct cts_device *cts_dev,
|
||||
u32 block_addr)
|
||||
{
|
||||
return erase_block_retry(cts_dev, block_addr,
|
||||
CTS_FLASH_ERASE_DEFAULT_RETRY);
|
||||
}
|
||||
|
||||
int cts_prepare_flash_operation(struct cts_device *cts_dev)
|
||||
{
|
||||
int ret;
|
||||
u8 diva = 0;
|
||||
bool program_mode = cts_is_device_program_mode(cts_dev);
|
||||
u32 hwid;
|
||||
bool enabled = cts_is_device_enabled(cts_dev);
|
||||
|
||||
cts_info("Prepare for flash operation");
|
||||
|
||||
if (!program_mode) {
|
||||
ret = cts_enter_program_mode(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Enter program mode failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
goto err_start_device;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cts_hw_reg_readb_retry(cts_dev, CTS_DEV_HW_REG_CLK_DIV_CFG, &diva, 5, 0);
|
||||
|
||||
if (ret) {
|
||||
cts_warn("Read DIVA failed %d(%s)", ret, cts_strerror(ret));
|
||||
} else {
|
||||
cts_dbg("Device DIVA = %d", diva);
|
||||
}
|
||||
|
||||
if (ret == 0 && diva == 0x0C) {
|
||||
cts_info("DIVA is ready already");
|
||||
} else {
|
||||
int retries;
|
||||
|
||||
/* Set HCLK to 10MHz */
|
||||
hwid = cts_dev->hwdata->hwid;
|
||||
if (hwid == CTS_DEV_HWID_ICNL9951) {
|
||||
|
||||
ret = cts_hw_reg_writeb_retry(cts_dev, CTS_DEV_HW_REG_CLK_DIV_CFG, 0x0C, 5, 0);
|
||||
if (ret) {
|
||||
cts_err("Write DIVA failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
goto err_enter_normal_mode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset SFCTL */
|
||||
ret = cts_hw_reg_writeb_retry(cts_dev, CTS_DEV_HW_REG_RESET_CONFIG, 0xFB, 5, 0);
|
||||
if (ret) {
|
||||
cts_err("Reset sfctl failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
goto err_enter_normal_mode;
|
||||
}
|
||||
|
||||
retries = 0;
|
||||
do {
|
||||
u8 state;
|
||||
|
||||
ret = cts_hw_reg_readb_relaxed(cts_dev, CTS_DEV_HW_REG_HW_STATUS, &state);
|
||||
if (ret == 0 && (state & 0x40) != 0)
|
||||
goto init_flash;
|
||||
|
||||
mdelay(2);
|
||||
} while (++retries < 1000);
|
||||
|
||||
if (ret) {
|
||||
cts_warn("Wait SFCTRL ready failed %d(%s)", ret, cts_strerror(ret));
|
||||
}
|
||||
// Go through and try
|
||||
}
|
||||
|
||||
init_flash:
|
||||
if (cts_dev->flash == NULL) {
|
||||
cts_info("Flash is not initialized, try to probe...");
|
||||
if ((ret = probe_flash(cts_dev)) != 0) {
|
||||
cts_dev->rtdata.has_flash = false;
|
||||
cts_warn("Probe flash failed %d(%s)",
|
||||
ret, cts_strerror(ret));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cts_dev->rtdata.has_flash = true;
|
||||
return 0;
|
||||
|
||||
err_enter_normal_mode:
|
||||
if (!program_mode) {
|
||||
int r = cts_enter_normal_mode(cts_dev);
|
||||
if (r) {
|
||||
cts_err("Enter normal mode failed %d(%s)",
|
||||
r, cts_strerror(r));
|
||||
}
|
||||
}
|
||||
err_start_device:
|
||||
if (enabled) {
|
||||
int r = cts_start_device(cts_dev);
|
||||
if (r) {
|
||||
cts_err("Start device failed %d(%s)",
|
||||
r, cts_strerror(r));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_post_flash_operation(struct cts_device *cts_dev)
|
||||
{
|
||||
u32 hwid;
|
||||
cts_info("Post flash operation");
|
||||
|
||||
hwid = cts_dev->hwdata->hwid;
|
||||
if (hwid == CTS_DEV_HWID_ICNL9951) {
|
||||
return cts_hw_reg_writeb_retry(cts_dev, CTS_DEV_HW_REG_CLK_DIV_CFG, 4, 5, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_read_flash_retry(struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t size, int retry)
|
||||
{
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
const struct cts_flash *flash;
|
||||
int ret;
|
||||
|
||||
cts_info("Read from 0x%06x size %zu", flash_addr, size);
|
||||
|
||||
sfctrl = cts_dev->hwdata->sfctrl;
|
||||
flash = cts_dev->flash;
|
||||
|
||||
if (flash == NULL ||
|
||||
sfctrl == NULL ||
|
||||
sfctrl->ops == NULL ||
|
||||
sfctrl->ops->read == NULL) {
|
||||
cts_err("Read not supported");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (flash_addr > flash->total_size) {
|
||||
cts_err("Read from 0x%06x > flash size 0x%06zx",
|
||||
flash_addr, flash->total_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
size = min(size, flash->total_size - flash_addr);
|
||||
|
||||
cts_info("Read actually from 0x%06x size %zu", flash_addr, size);
|
||||
|
||||
while (size) {
|
||||
size_t l;
|
||||
|
||||
l = min(sfctrl->xchg_sram_size, size);
|
||||
|
||||
ret = sfctrl->ops->read(cts_dev, flash_addr, dst, l);
|
||||
if(ret < 0) {
|
||||
cts_err("Read from 0x%06x size %zu failed %d(%s)",
|
||||
flash_addr, size, ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
dst += l;
|
||||
size -= l;
|
||||
flash_addr += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_program_flash(struct cts_device *cts_dev,
|
||||
u32 flash_addr, const void *src, size_t size)
|
||||
{
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
const struct cts_flash *flash;
|
||||
int ret;
|
||||
|
||||
cts_info("Program to 0x%06x size %zu", flash_addr, size);
|
||||
|
||||
sfctrl = cts_dev->hwdata->sfctrl;
|
||||
flash = cts_dev->flash;
|
||||
|
||||
if (flash == NULL ||
|
||||
sfctrl == NULL ||
|
||||
sfctrl->ops == NULL ||
|
||||
sfctrl->ops->program == NULL) {
|
||||
cts_err("Program not supported");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (flash_addr >= flash->total_size) {
|
||||
cts_err("Program from 0x%06x >= flash size 0x%06zx",
|
||||
flash_addr, flash->total_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
size = min(size, flash->total_size - flash_addr);
|
||||
|
||||
cts_info("Program actually to 0x%06x size %zu", flash_addr, size);
|
||||
|
||||
while (size) {
|
||||
size_t l, offset;
|
||||
|
||||
l = min(flash->page_size, size);
|
||||
offset = flash_addr & (flash->page_size - 1);
|
||||
|
||||
if (offset) {
|
||||
l = min(flash->page_size - offset, l);
|
||||
}
|
||||
|
||||
ret = sfctrl->ops->program(cts_dev, flash_addr, src, l);
|
||||
if(ret) {
|
||||
cts_err("Program to 0x%06x size %zu failed %d(%s)",
|
||||
flash_addr, l, ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
src += l;
|
||||
size -= l;
|
||||
flash_addr += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_program_flash_from_sram(struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t size)
|
||||
{
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
const struct cts_flash *flash;
|
||||
int ret;
|
||||
|
||||
cts_info("Program to 0x%06x from sram 0x%06x size %zu",
|
||||
flash_addr, sram_addr, size);
|
||||
|
||||
sfctrl = cts_dev->hwdata->sfctrl;
|
||||
flash = cts_dev->flash;
|
||||
|
||||
if (flash == NULL ||
|
||||
sfctrl == NULL ||
|
||||
sfctrl->ops == NULL ||
|
||||
sfctrl->ops->program_from_sram == NULL) {
|
||||
cts_err("Program from sram not supported");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (flash_addr >= flash->total_size) {
|
||||
cts_err("Program from 0x%06x >= flash size 0x%06zx",
|
||||
flash_addr, flash->total_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
size = min(size, flash->total_size - flash_addr);
|
||||
|
||||
cts_info("Program actually to 0x%06x from sram 0x%06x size %zu",
|
||||
flash_addr, sram_addr, size);
|
||||
|
||||
while (size) {
|
||||
size_t l, offset;
|
||||
|
||||
l = min(flash->page_size, size);
|
||||
offset = flash_addr & (flash->page_size - 1);
|
||||
|
||||
if (offset) {
|
||||
l = min(flash->page_size - offset, l);
|
||||
}
|
||||
|
||||
ret = sfctrl->ops->program_from_sram(cts_dev,
|
||||
flash_addr, sram_addr, l);
|
||||
if(ret) {
|
||||
cts_err("Program to 0x%06x from sram 0x%06x size %zu "
|
||||
"failed %d(%s)",
|
||||
flash_addr, sram_addr, l, ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
size -= l;
|
||||
flash_addr += l;
|
||||
sram_addr += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_erase_flash(struct cts_device *cts_dev, u32 addr, size_t size)
|
||||
{
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
const struct cts_flash *flash;
|
||||
int ret;
|
||||
|
||||
cts_info("Erase from 0x%06x size %zu", addr, size);
|
||||
|
||||
sfctrl = cts_dev->hwdata->sfctrl;
|
||||
flash = cts_dev->flash;
|
||||
|
||||
if (flash == NULL ||
|
||||
sfctrl == NULL || sfctrl->ops == NULL ||
|
||||
sfctrl->ops->se == NULL || sfctrl->ops->be == NULL ||
|
||||
flash == NULL) {
|
||||
cts_err("Oops");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Addr and size MUST sector aligned */
|
||||
addr = rounddown(addr, flash->sector_size);
|
||||
size = roundup(size, flash->sector_size);
|
||||
|
||||
if (addr > flash->total_size) {
|
||||
cts_err("Erase from 0x%06x > flash size 0x%06zx",
|
||||
addr, flash->total_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
size = min(size, flash->total_size - addr);
|
||||
|
||||
cts_info("Erase actually from 0x%06x size %zu", addr, size);
|
||||
|
||||
if (flash->block_size) {
|
||||
while (addr != ALIGN(addr, flash->block_size) &&
|
||||
size >= flash->sector_size) {
|
||||
ret = erase_sector(cts_dev, addr);
|
||||
if (ret) {
|
||||
cts_err("Erase sector 0x%06x size 0x%04zx failed %d(%s)",
|
||||
addr, flash->sector_size, ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
addr += flash->sector_size;
|
||||
size -= flash->sector_size;
|
||||
}
|
||||
|
||||
while (size >= flash->block_size) {
|
||||
ret = erase_block(cts_dev, addr);
|
||||
if (ret) {
|
||||
cts_err("Erase block 0x%06x size 0x%04zx failed %d(%s)",
|
||||
addr, flash->block_size, ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
addr += flash->block_size;
|
||||
size -= flash->block_size;
|
||||
}
|
||||
}
|
||||
|
||||
while (size >= flash->sector_size) {
|
||||
ret = erase_sector(cts_dev, addr);
|
||||
if (ret) {
|
||||
cts_err("Erase sector 0x%06x size 0x%04zx failed %d(%s)",
|
||||
addr, flash->sector_size, ret, cts_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
addr += flash->sector_size;
|
||||
size -= flash->sector_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
45
drivers/input/touchscreen/chipone_tddi/cts_spi_flash.h
Normal file
45
drivers/input/touchscreen/chipone_tddi/cts_spi_flash.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_SPI_FLASH_H
|
||||
#define CTS_SPI_FLASH_H
|
||||
|
||||
struct cts_flash {
|
||||
const char *name;
|
||||
u32 jedec_id; /* Device ID by command 0x9F */
|
||||
size_t page_size; /* Page size by command 0x02 */
|
||||
size_t sector_size; /* Sector size by command 0x20 */
|
||||
|
||||
/* Block size by command 0x52,
|
||||
* if 0 means block erase NOT supported
|
||||
*/
|
||||
size_t block_size;
|
||||
size_t total_size;
|
||||
|
||||
};
|
||||
|
||||
#define CTS_FLASH_READ_DEFAULT_RETRY (3)
|
||||
#define CTS_FLASH_ERASE_DEFAULT_RETRY (3)
|
||||
|
||||
struct cts_device;
|
||||
|
||||
extern int cts_prepare_flash_operation(struct cts_device *cts_dev);
|
||||
extern int cts_post_flash_operation(struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_read_flash_retry(struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t size, int retry);
|
||||
static inline int cts_read_flash(struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t size)
|
||||
{
|
||||
return cts_read_flash_retry(cts_dev, flash_addr, dst, size,
|
||||
CTS_FLASH_READ_DEFAULT_RETRY);
|
||||
}
|
||||
|
||||
extern int cts_erase_flash(struct cts_device *cts_dev, u32 addr,
|
||||
size_t size);
|
||||
|
||||
extern int cts_program_flash(struct cts_device *cts_dev,
|
||||
u32 flash_addr, const void *src, size_t size);
|
||||
extern int cts_program_flash_from_sram(struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t size);
|
||||
|
||||
#endif /* CTS_SPI_FLASH_H */
|
||||
175
drivers/input/touchscreen/chipone_tddi/cts_strerror.c
Normal file
175
drivers/input/touchscreen/chipone_tddi/cts_strerror.c
Normal file
@@ -0,0 +1,175 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include "cts_strerror.h"
|
||||
|
||||
#define ERROR_TEXT_ENTRY(errno, err_desc_str) \
|
||||
[(errno)] = #errno ", " err_desc_str
|
||||
|
||||
static char *_error_text[] = {
|
||||
[0] = "Success",
|
||||
ERROR_TEXT_ENTRY(EPERM, "Operation not permitted"),
|
||||
ERROR_TEXT_ENTRY(ENOENT, "No such file or directory"),
|
||||
ERROR_TEXT_ENTRY(ESRCH, "No such process"),
|
||||
ERROR_TEXT_ENTRY(EINTR, "Interrupted system call"),
|
||||
ERROR_TEXT_ENTRY(EIO, "Input/output error"),
|
||||
ERROR_TEXT_ENTRY(ENXIO, "No such device or address"),
|
||||
ERROR_TEXT_ENTRY(E2BIG, "Argument list too long"),
|
||||
ERROR_TEXT_ENTRY(ENOEXEC, "Exec format error"),
|
||||
ERROR_TEXT_ENTRY(EBADF, "Bad file descriptor"),
|
||||
ERROR_TEXT_ENTRY(ECHILD, "No child processes"),
|
||||
ERROR_TEXT_ENTRY(EAGAIN, "Resource temporarily unavailable"),
|
||||
ERROR_TEXT_ENTRY(ENOMEM, "Cannot allocate memory"),
|
||||
ERROR_TEXT_ENTRY(EACCES, "Permission denied"),
|
||||
ERROR_TEXT_ENTRY(EFAULT, "Bad address"),
|
||||
ERROR_TEXT_ENTRY(ENOTBLK, "Block device required"),
|
||||
ERROR_TEXT_ENTRY(EBUSY, "Device or resource busy"),
|
||||
ERROR_TEXT_ENTRY(EEXIST, "File exists"),
|
||||
ERROR_TEXT_ENTRY(EXDEV, "Invalid cross-device link"),
|
||||
ERROR_TEXT_ENTRY(ENODEV, "No such device"),
|
||||
ERROR_TEXT_ENTRY(ENOTDIR, "Not a directory"),
|
||||
ERROR_TEXT_ENTRY(EISDIR, "Is a directory"),
|
||||
ERROR_TEXT_ENTRY(EINVAL, "Invalid argument"),
|
||||
ERROR_TEXT_ENTRY(EMFILE, "Too many open files"),
|
||||
ERROR_TEXT_ENTRY(ENFILE, "Too many open files in system"),
|
||||
ERROR_TEXT_ENTRY(ENOTTY, "Inappropriate ioctl for device"),
|
||||
ERROR_TEXT_ENTRY(ETXTBSY, "Text file busy"),
|
||||
ERROR_TEXT_ENTRY(EFBIG, "File too large"),
|
||||
ERROR_TEXT_ENTRY(ENOSPC, "No space left on device"),
|
||||
ERROR_TEXT_ENTRY(ESPIPE, "Illegal seek"),
|
||||
ERROR_TEXT_ENTRY(EROFS, "Read-only file system"),
|
||||
ERROR_TEXT_ENTRY(EMLINK, "Too many links"),
|
||||
ERROR_TEXT_ENTRY(EPIPE, "Broken pipe"),
|
||||
ERROR_TEXT_ENTRY(EDOM, "Numerical argument out of domain"),
|
||||
ERROR_TEXT_ENTRY(ERANGE, "Numerical result out of range"),
|
||||
ERROR_TEXT_ENTRY(EDEADLK, "Resource deadlock avoided"),
|
||||
ERROR_TEXT_ENTRY(ENAMETOOLONG, "File name too long"),
|
||||
ERROR_TEXT_ENTRY(ENOLCK, "No locks available"),
|
||||
ERROR_TEXT_ENTRY(ENOSYS, "Function not implemented"),
|
||||
ERROR_TEXT_ENTRY(ENOTEMPTY, "Directory not empty"),
|
||||
ERROR_TEXT_ENTRY(ELOOP, "Too many levels of symbolic links"),
|
||||
ERROR_TEXT_ENTRY(EWOULDBLOCK, "Operation would block"),
|
||||
ERROR_TEXT_ENTRY(ENOMSG, "No message of desired type"),
|
||||
ERROR_TEXT_ENTRY(EIDRM, "Identifier removed"),
|
||||
ERROR_TEXT_ENTRY(ECHRNG, "Channel number out of range"),
|
||||
ERROR_TEXT_ENTRY(EL2NSYNC, "Level 2 not synchronized"),
|
||||
ERROR_TEXT_ENTRY(EL3HLT, "Level 3 halted"),
|
||||
ERROR_TEXT_ENTRY(EL3RST, "Level 3 reset"),
|
||||
ERROR_TEXT_ENTRY(ELNRNG, "Link number out of range"),
|
||||
ERROR_TEXT_ENTRY(EUNATCH, "Protocol driver not attached"),
|
||||
ERROR_TEXT_ENTRY(ENOCSI, "No CSI structure available"),
|
||||
ERROR_TEXT_ENTRY(EL2HLT, "Level 2 halted"),
|
||||
ERROR_TEXT_ENTRY(EBADE, "Invalid exchange"),
|
||||
ERROR_TEXT_ENTRY(EBADR, "Invalid request descriptor"),
|
||||
ERROR_TEXT_ENTRY(EXFULL, "Exchange full"),
|
||||
ERROR_TEXT_ENTRY(ENOANO, "No anode"),
|
||||
ERROR_TEXT_ENTRY(EBADRQC, "Invalid request code"),
|
||||
ERROR_TEXT_ENTRY(EBADSLT, "Invalid slot"),
|
||||
ERROR_TEXT_ENTRY(EDEADLOCK, "File locking deadlock error"),
|
||||
ERROR_TEXT_ENTRY(EBFONT, "Bad font file format"),
|
||||
ERROR_TEXT_ENTRY(ENOSTR, "Device not a stream"),
|
||||
ERROR_TEXT_ENTRY(ENODATA, "No data available"),
|
||||
ERROR_TEXT_ENTRY(ETIME, "Timer expired"),
|
||||
ERROR_TEXT_ENTRY(ENOSR, "Out of streams resources"),
|
||||
ERROR_TEXT_ENTRY(ENONET, "Machine is not on the network"),
|
||||
ERROR_TEXT_ENTRY(ENOPKG, "Package not installed"),
|
||||
ERROR_TEXT_ENTRY(EREMOTE, "Object is remote"),
|
||||
ERROR_TEXT_ENTRY(ENOLINK, "Link has been severed"),
|
||||
ERROR_TEXT_ENTRY(EADV, "Advertise error"),
|
||||
ERROR_TEXT_ENTRY(ESRMNT, "Srmount error"),
|
||||
ERROR_TEXT_ENTRY(ECOMM, "Communication error on send"),
|
||||
ERROR_TEXT_ENTRY(EPROTO, "Protocol error"),
|
||||
ERROR_TEXT_ENTRY(EMULTIHOP, "Multihop attempted"),
|
||||
ERROR_TEXT_ENTRY(EDOTDOT, "RFS specific error"),
|
||||
ERROR_TEXT_ENTRY(EBADMSG, "Bad message"),
|
||||
ERROR_TEXT_ENTRY(EOVERFLOW, "Value too large for defined data type"),
|
||||
ERROR_TEXT_ENTRY(ENOTUNIQ, "Name not unique on network"),
|
||||
ERROR_TEXT_ENTRY(EBADFD, "File descriptor in bad state"),
|
||||
ERROR_TEXT_ENTRY(EREMCHG, "Remote address changed"),
|
||||
ERROR_TEXT_ENTRY(ELIBACC, "Can not access a needed shared library"),
|
||||
ERROR_TEXT_ENTRY(ELIBBAD, "Accessing a corrupted shared library"),
|
||||
ERROR_TEXT_ENTRY(ELIBSCN, ".lib section in a.out corrupted"),
|
||||
ERROR_TEXT_ENTRY(ELIBMAX, "Attempting to link in too many shared libraries"),
|
||||
ERROR_TEXT_ENTRY(ELIBEXEC, "Cannot exec a shared library directly"),
|
||||
ERROR_TEXT_ENTRY(EILSEQ, "Invalid or incomplete multibyte or wide character"),
|
||||
ERROR_TEXT_ENTRY(ERESTART, "Interrupted system call should be restarted"),
|
||||
ERROR_TEXT_ENTRY(ESTRPIPE, "Streams pipe error"),
|
||||
ERROR_TEXT_ENTRY(EUSERS, "Too many users"),
|
||||
ERROR_TEXT_ENTRY(ENOTSOCK, "Socket operation on non-socket"),
|
||||
ERROR_TEXT_ENTRY(EDESTADDRREQ, "Destination address required"),
|
||||
ERROR_TEXT_ENTRY(EMSGSIZE, "Message too long"),
|
||||
ERROR_TEXT_ENTRY(EPROTOTYPE, "Protocol wrong type for socket"),
|
||||
ERROR_TEXT_ENTRY(ENOPROTOOPT, "Protocol not available"),
|
||||
ERROR_TEXT_ENTRY(EPROTONOSUPPORT, "Protocol not supported"),
|
||||
ERROR_TEXT_ENTRY(ESOCKTNOSUPPORT, "Socket type not supported"),
|
||||
ERROR_TEXT_ENTRY(EOPNOTSUPP, "Operation not supported"),
|
||||
ERROR_TEXT_ENTRY(EPFNOSUPPORT, "Protocol family not supported"),
|
||||
ERROR_TEXT_ENTRY(EAFNOSUPPORT, "Address family not supported by protocol"),
|
||||
ERROR_TEXT_ENTRY(EADDRINUSE, "Address already in use"),
|
||||
ERROR_TEXT_ENTRY(EADDRNOTAVAIL, "Cannot assign requested address"),
|
||||
ERROR_TEXT_ENTRY(ENETDOWN, "Network is down"),
|
||||
ERROR_TEXT_ENTRY(ENETUNREACH, "Network is unreachable"),
|
||||
ERROR_TEXT_ENTRY(ENETRESET, "Network dropped connection on reset"),
|
||||
ERROR_TEXT_ENTRY(ECONNABORTED, "Software caused connection abort"),
|
||||
ERROR_TEXT_ENTRY(ECONNRESET, "Connection reset by peer"),
|
||||
ERROR_TEXT_ENTRY(ENOBUFS, "No buffer space available"),
|
||||
ERROR_TEXT_ENTRY(EISCONN, "Transport endpoint is already connected"),
|
||||
ERROR_TEXT_ENTRY(ENOTCONN, "Transport endpoint is not connected"),
|
||||
ERROR_TEXT_ENTRY(ESHUTDOWN, "Cannot send after transport endpoint shutdown"),
|
||||
ERROR_TEXT_ENTRY(ETOOMANYREFS, "Too many references: cannot splice"),
|
||||
ERROR_TEXT_ENTRY(ETIMEDOUT, "Connection timed out"),
|
||||
ERROR_TEXT_ENTRY(ECONNREFUSED, "Connection refused"),
|
||||
ERROR_TEXT_ENTRY(EHOSTDOWN, "Host is down"),
|
||||
ERROR_TEXT_ENTRY(EHOSTUNREACH, "No route to host"),
|
||||
ERROR_TEXT_ENTRY(EALREADY, "Operation already in progress"),
|
||||
ERROR_TEXT_ENTRY(EINPROGRESS, "Operation now in progress"),
|
||||
ERROR_TEXT_ENTRY(ESTALE, "Stale file handle"),
|
||||
ERROR_TEXT_ENTRY(EUCLEAN, "Structure needs cleaning"),
|
||||
ERROR_TEXT_ENTRY(ENOTNAM, "Not a XENIX named type file"),
|
||||
ERROR_TEXT_ENTRY(ENAVAIL, "No XENIX semaphores available"),
|
||||
ERROR_TEXT_ENTRY(EISNAM, "Is a named type file"),
|
||||
ERROR_TEXT_ENTRY(EREMOTEIO, "Remote I/O error"),
|
||||
ERROR_TEXT_ENTRY(EDQUOT, "Disk quota exceeded"),
|
||||
ERROR_TEXT_ENTRY(ENOMEDIUM, "No medium found"),
|
||||
ERROR_TEXT_ENTRY(EMEDIUMTYPE, "Wrong medium type"),
|
||||
ERROR_TEXT_ENTRY(ECANCELED, "Operation canceled"),
|
||||
ERROR_TEXT_ENTRY(ENOKEY, "Required key not available"),
|
||||
ERROR_TEXT_ENTRY(EKEYEXPIRED, "Key has expired"),
|
||||
ERROR_TEXT_ENTRY(EKEYREVOKED, "Key has been revoked"),
|
||||
ERROR_TEXT_ENTRY(EKEYREJECTED, "Key was rejected by service"),
|
||||
ERROR_TEXT_ENTRY(EOWNERDEAD, "Owner died"),
|
||||
ERROR_TEXT_ENTRY(ENOTRECOVERABLE, "State not recoverable"),
|
||||
ERROR_TEXT_ENTRY(ERFKILL, "Operation not possible due to RF-kill"),
|
||||
ERROR_TEXT_ENTRY(EHWPOISON, "Memory page has hardware error"),
|
||||
ERROR_TEXT_ENTRY(ERESTARTSYS, "Restart system"),
|
||||
ERROR_TEXT_ENTRY(ERESTARTNOINTR, "Restart monitor"),
|
||||
ERROR_TEXT_ENTRY(ERESTARTNOHAND, "Restart if no handler"),
|
||||
ERROR_TEXT_ENTRY(ENOIOCTLCMD, "No ioctl command"),
|
||||
ERROR_TEXT_ENTRY(ERESTART_RESTARTBLOCK, "Restart by calling sys_restart_syscall"),
|
||||
ERROR_TEXT_ENTRY(EPROBE_DEFER, "Driver requests probe retry"),
|
||||
ERROR_TEXT_ENTRY(EOPENSTALE, "Open found a stale dentry"),
|
||||
ERROR_TEXT_ENTRY(EBADHANDLE, "Illegal NFS file handle"),
|
||||
ERROR_TEXT_ENTRY(ENOTSYNC, "Update synchronization mismatch"),
|
||||
ERROR_TEXT_ENTRY(EBADCOOKIE, "Cookie is stale"),
|
||||
ERROR_TEXT_ENTRY(ENOTSUPP, "Operation is not supported"),
|
||||
ERROR_TEXT_ENTRY(ETOOSMALL, "Buffer or request is too small"),
|
||||
ERROR_TEXT_ENTRY(ESERVERFAULT, "An untranslatable error occurred"),
|
||||
ERROR_TEXT_ENTRY(EBADTYPE, "Type not supported by server"),
|
||||
ERROR_TEXT_ENTRY(EJUKEBOX, "Request initiated, but will not complete before timeout"),
|
||||
ERROR_TEXT_ENTRY(EIOCBQUEUED, "IOCB queued, will get completion event"),
|
||||
};
|
||||
|
||||
#define ERROR_TEXT_ARRAY_SIZE (sizeof(_error_text) / sizeof(_error_text[0]))
|
||||
char *cts_strerror(int errno)
|
||||
{
|
||||
if (errno > 0) {
|
||||
return "<valid offset/length>";
|
||||
} else if (-errno < (int) ERROR_TEXT_ARRAY_SIZE) {
|
||||
char *s = _error_text[-errno];
|
||||
if (s) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return "<Unknown error>";
|
||||
}
|
||||
11
drivers/input/touchscreen/chipone_tddi/cts_strerror.h
Normal file
11
drivers/input/touchscreen/chipone_tddi/cts_strerror.h
Normal file
@@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_STRERROR_H
|
||||
#define CTS_STRERROR_H
|
||||
|
||||
#define CTS_ERR_FMT_STR "%d(%s)"
|
||||
#define CTS_ERR_ARG(errno) cts_strerror(errno)
|
||||
char *cts_strerror(int errno);
|
||||
|
||||
#endif
|
||||
|
||||
2904
drivers/input/touchscreen/chipone_tddi/cts_sysfs.c
Normal file
2904
drivers/input/touchscreen/chipone_tddi/cts_sysfs.c
Normal file
File diff suppressed because it is too large
Load Diff
27
drivers/input/touchscreen/chipone_tddi/cts_sysfs.h
Normal file
27
drivers/input/touchscreen/chipone_tddi/cts_sysfs.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_SYSFS_H
|
||||
#define CTS_SYSFS_H
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
struct device;
|
||||
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
extern int cts_argc;
|
||||
extern char *cts_argv[];
|
||||
extern int cts_sysfs_add_device(struct device *dev);
|
||||
extern void cts_sysfs_remove_device(struct device *dev);
|
||||
extern int cts_parse_arg(const char *buf, size_t count);
|
||||
#else /* CONFIG_CTS_SYSFS */
|
||||
static inline int cts_sysfs_add_device(struct device *dev)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void cts_sysfs_remove_device(struct device *dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
|
||||
#endif /* CTS_SYSFS_H */
|
||||
1901
drivers/input/touchscreen/chipone_tddi/cts_tcs.c
Normal file
1901
drivers/input/touchscreen/chipone_tddi/cts_tcs.c
Normal file
File diff suppressed because it is too large
Load Diff
127
drivers/input/touchscreen/chipone_tddi/cts_tcs.h
Normal file
127
drivers/input/touchscreen/chipone_tddi/cts_tcs.h
Normal file
@@ -0,0 +1,127 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef _CTS_TCS_H_
|
||||
#define _CTS_TCS_H_
|
||||
|
||||
int cts_tcs_read(struct cts_device *cts_dev,
|
||||
u16 cmd, u8 *buf, size_t len);
|
||||
int cts_tcs_write(struct cts_device *cts_dev,
|
||||
u16 cmd, u8 *buf, size_t len);
|
||||
|
||||
int cts_tcs_get_hwid_info(struct cts_device *cts_dev, u8 *info);
|
||||
int cts_tcs_get_fw_ver(struct cts_device *cts_dev, u16 *fwver);
|
||||
int cts_tcs_get_lib_ver(struct cts_device *cts_dev, u16 *libver);
|
||||
int cts_tcs_get_ddi_ver(struct cts_device *cts_dev, u8 *ddiver);
|
||||
int cts_tcs_get_res_x(struct cts_device *cts_dev, u16 *res_x);
|
||||
int cts_tcs_get_res_y(struct cts_device *cts_dev, u16 *res_y);
|
||||
int cts_tcs_get_rows(struct cts_device *cts_dev, u8 *rows);
|
||||
int cts_tcs_get_cols(struct cts_device *cts_dev, u8 *cols);
|
||||
int cts_tcs_get_rx_tx_info(struct cts_device *cts_dev, u8 *info);
|
||||
int cts_tcs_get_panel_rx_tx_info(struct cts_device *cts_dev, u8 *info);
|
||||
int cts_tcs_get_flip_x(struct cts_device *cts_dev, bool *flip_x);
|
||||
int cts_tcs_get_flip_y(struct cts_device *cts_dev, bool *flip_y);
|
||||
int cts_tcs_get_swap_axes(struct cts_device *cts_dev, bool *swap_axes);
|
||||
int cts_tcs_clr_gstr_ready_flag(struct cts_device *cts_dev);
|
||||
|
||||
int cts_tcs_get_int_mode(struct cts_device *cts_dev, u8 *int_mode);
|
||||
int cts_tcs_get_int_keep_time(struct cts_device *cts_dev,
|
||||
u16 *int_keep_time);
|
||||
int cts_tcs_get_rawdata_target(struct cts_device *cts_dev,
|
||||
u16 *rawdata_target);
|
||||
int cts_tcs_get_esd_method(struct cts_device *cts_dev, u8 *esd_method);
|
||||
|
||||
int cts_tcs_get_touchinfo(struct cts_device *cts_dev,
|
||||
struct cts_device_touch_info *touch_info);
|
||||
int cts_tcs_get_gestureinfo(struct cts_device *cts_dev,
|
||||
struct cts_device_gesture_info *gesture_info);
|
||||
int cts_tcs_get_touch_status(struct cts_device *cts_dev);
|
||||
int cts_tcs_get_esd_protection(struct cts_device *cts_dev,
|
||||
u8 *esd_protection);
|
||||
|
||||
int cts_tcs_read_hw_reg(struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_write_hw_reg(struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_read_ddi_reg(struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size);
|
||||
int cts_tcs_write_ddi_reg(struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size);
|
||||
int cts_tcs_read_reg(struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_write_reg(struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
|
||||
int cts_tcs_get_fw_id(struct cts_device *cts_dev, u16 *fwid);
|
||||
int cts_tcs_get_workmode(struct cts_device *cts_dev, u8 *workmode);
|
||||
int cts_tcs_set_workmode(struct cts_device *cts_dev, u8 workmode);
|
||||
int cts_tcs_set_openshort_mode(struct cts_device *cts_dev, u8 mode);
|
||||
int cts_tcs_get_curr_mode(struct cts_device *cts_dev, u8 *currmode);
|
||||
int cts_tcs_get_krang_current_workmode(struct cts_device *cts_dev, u8 *workmode);
|
||||
int cts_tcs_set_krang_workmode(struct cts_device *cts_dev, u8 workmode);
|
||||
|
||||
int cts_tcs_set_tx_vol(struct cts_device *cts_dev, u8 txvol);
|
||||
|
||||
int cts_tcs_set_short_test_type(struct cts_device *cts_dev, u8 short_type);
|
||||
int cts_tcs_set_openshort_enable(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_is_openshort_enabled(struct cts_device *cts_dev, u8 *enabled);
|
||||
|
||||
int cts_tcs_set_esd_enable(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_set_cneg_enable(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_set_mnt_enable(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_is_display_on(struct cts_device *cts_dev, u8 *display_on);
|
||||
int cts_tcs_set_display_on(struct cts_device *cts_dev, u8 display_on);
|
||||
int cts_tcs_is_cneg_enabled(struct cts_device *cts_dev, u8 *enabled);
|
||||
int cts_tcs_is_mnt_enabled(struct cts_device *cts_dev, u8 *enabled);
|
||||
int cts_tcs_set_pwr_mode(struct cts_device *cts_dev, u8 pwr_mode);
|
||||
int cts_tcs_get_has_int_data(struct cts_device *cts_dev, bool *has);
|
||||
int cts_tcs_get_int_data_types(struct cts_device *cts_dev, u16 *type);
|
||||
int cts_tcs_set_int_data_types(struct cts_device *cts_dev, u16 type);
|
||||
int cts_tcs_get_int_data_method(struct cts_device *cts_dev, u8 *method);
|
||||
int cts_tcs_set_int_data_method(struct cts_device *cts_dev, u8 method);
|
||||
int cts_tcs_calc_int_data_size(struct cts_device *cts_dev);
|
||||
|
||||
int cts_tcs_polling_data(struct cts_device *cts_dev,u8 *buf, size_t size);
|
||||
int cts_polling_test_data(struct cts_device *cts_dev,
|
||||
u8 *buf, size_t size, enum int_data_type type);
|
||||
|
||||
int cts_tcs_tool_get_rawdata(struct cts_device *cts_dev, u8 *buf, u16 data_source);
|
||||
int cts_tcs_tool_get_manual_diff(struct cts_device *cts_dev, u8 *buf, u16 data_source);
|
||||
int cts_tcs_tool_get_real_diff(struct cts_device *cts_dev, u8 *buf, u16 data_source);
|
||||
int cts_tcs_tool_get_basedata(struct cts_device *cts_dev, u8 *buf, u16 data_source);
|
||||
|
||||
int cts_tcs_top_get_rawdata(struct cts_device *cts_dev, u8 *buf, size_t size,
|
||||
u16 data_source);
|
||||
int cts_tcs_top_get_manual_diff(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size, u16 data_source);
|
||||
int cts_tcs_top_get_real_diff(struct cts_device *cts_dev, u8 *buf, size_t size,
|
||||
u16 data_source);
|
||||
int cts_tcs_top_get_noise_diff(struct cts_device *cts_dev, u8 *buf,size_t size,
|
||||
u16 data_source);
|
||||
int cts_tcs_top_get_basedata(struct cts_device *cts_dev, u8 *buf, size_t size,
|
||||
u16 data_source);
|
||||
int cts_tcs_top_get_cnegdata(struct cts_device *cts_dev, u8 *buf, size_t size,
|
||||
u16 data_source);
|
||||
int cts_tcs_reset_device(struct cts_device *cts_dev);
|
||||
int cts_tcs_set_int_test(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_set_int_pin(struct cts_device *cts_dev, u8 high);
|
||||
int cts_tcs_get_module_id(struct cts_device *cts_dev, u32 *modId);
|
||||
|
||||
int cts_tcs_tool_xtrans(struct cts_device *cts_dev, u8 *tx, size_t txlen,
|
||||
u8 *rx, size_t rxlen);
|
||||
|
||||
int cts_tcs_set_charger_plug(struct cts_device *cts_dev, u8 set);
|
||||
int cts_tcs_get_charger_plug(struct cts_device *cts_dev, u8 *isset);
|
||||
int cts_tcs_set_earjack_plug(struct cts_device *cts_dev, u8 set);
|
||||
int cts_tcs_get_earjack_plug(struct cts_device *cts_dev, u8 *isset);
|
||||
int cts_tcs_set_panel_direction(struct cts_device *cts_dev, u8 direction);
|
||||
int cts_tcs_get_panel_direction(struct cts_device *cts_dev, u8 *direction);
|
||||
int cts_tcs_set_game_mode(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_get_game_mode(struct cts_device *cts_dev, u8 *enabled);
|
||||
int cts_tcs_set_proximity_mode(struct cts_device *cts_dev, u8 enable);
|
||||
void cts_tcs_reinit_fw_status(struct cts_device *cts_dev);
|
||||
|
||||
int cts_tcs_set_product_en(struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_wait_krang_stop(struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_tcs_set_glove_mode(struct cts_device *cts_dev, u8 enable);
|
||||
#endif /* _CTS_TCS_H_ */
|
||||
2927
drivers/input/touchscreen/chipone_tddi/cts_test.c
Normal file
2927
drivers/input/touchscreen/chipone_tddi/cts_test.c
Normal file
File diff suppressed because it is too large
Load Diff
113
drivers/input/touchscreen/chipone_tddi/cts_test.h
Normal file
113
drivers/input/touchscreen/chipone_tddi/cts_test.h
Normal file
@@ -0,0 +1,113 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CTS_TEST_H
|
||||
#define CTS_TEST_H
|
||||
|
||||
struct cts_device;
|
||||
|
||||
#define CTS_TEST_FLAG_RESET_BEFORE_TEST (1u << 0)
|
||||
#define CTS_TEST_FLAG_RESET_AFTER_TEST (1u << 1)
|
||||
#define CTS_TEST_FLAG_DISPLAY_ON (1u << 2)
|
||||
#define CTS_TEST_FLAG_DISABLE_GAS (1u << 3)
|
||||
#define CTS_TEST_FLAG_DISABLE_LINESHIFT (1u << 4)
|
||||
|
||||
#define CTS_TEST_FLAG_VALIDATE_DATA (1u << 8)
|
||||
#define CTS_TEST_FLAG_VALIDATE_PER_NODE (1u << 9)
|
||||
#define CTS_TEST_FLAG_VALIDATE_MIN (1u << 10)
|
||||
#define CTS_TEST_FLAG_VALIDATE_MAX (1u << 11)
|
||||
#define CTS_TEST_FLAG_VALIDATE_SKIP_INVALID_NODE (1u << 12)
|
||||
#define CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED (1u << 13)
|
||||
|
||||
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE (1u << 16)
|
||||
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE (1u << 17)
|
||||
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE (1u << 18)
|
||||
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE_APPEND (1u << 19)
|
||||
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE_CSV (1u << 20)
|
||||
|
||||
#define CTS_TEST_FLAG_DRIVER_LOG_TO_USERSPACE (1u << 24)
|
||||
#define CTS_TEST_FLAG_DRIVER_LOG_TO_FILE (1u << 25)
|
||||
#define CTS_TEST_FLAG_DRIVER_LOG_TO_FILE_APPEND (1u << 26)
|
||||
|
||||
#define MAKE_INVALID_NODE(r, c) (((c) << 16) | (r))
|
||||
#define INVALID_NODE_ROW(node) ((u16)(node))
|
||||
#define INVALID_NODE_COL(node) ((u16)((node) >> 16))
|
||||
|
||||
enum cts_test_item {
|
||||
CTS_TEST_RESET_PIN = 1,
|
||||
CTS_TEST_INT_PIN,
|
||||
CTS_TEST_RAWDATA,
|
||||
CTS_TEST_NOISE,
|
||||
CTS_TEST_OPEN,
|
||||
CTS_TEST_SHORT,
|
||||
CTS_TEST_COMPENSATE_CAP,
|
||||
CTS_TEST_STYLUS_RAWDATA,
|
||||
CTS_TEST_STYLUS_NOISE,
|
||||
};
|
||||
|
||||
struct cts_test_param {
|
||||
int test_item;
|
||||
|
||||
__u32 flags;
|
||||
|
||||
__u32 num_invalid_node;
|
||||
__u32 *invalid_nodes;
|
||||
int *min;
|
||||
int *max;
|
||||
|
||||
int *test_result;
|
||||
s64 *elapsed_time_ms;
|
||||
|
||||
void *test_data_buf;
|
||||
int test_data_buf_size;
|
||||
int *test_data_wr_size;
|
||||
const char *test_data_filepath;
|
||||
|
||||
int driver_log_level;
|
||||
char *driver_log_buf;
|
||||
int driver_log_buf_size;
|
||||
int *driver_log_wr_size;
|
||||
const char *driver_log_filepath;
|
||||
|
||||
void *priv_param;
|
||||
int priv_param_size;
|
||||
};
|
||||
|
||||
struct cts_rawdata_test_priv_param {
|
||||
__u32 frames;
|
||||
//__u8 work_mode;
|
||||
};
|
||||
|
||||
struct cts_noise_test_priv_param {
|
||||
__u32 frames;
|
||||
//__u8 work_mode;
|
||||
};
|
||||
|
||||
extern const char *cts_test_item_str(int test_item);
|
||||
extern int cts_write_file(struct file *filp, const void *data, size_t size);
|
||||
extern int cts_mkdir_for_file(const char *filepath, umode_t mode);
|
||||
|
||||
extern int cts_start_dump_test_data_to_file(const char *filepath,
|
||||
bool append_to_file);
|
||||
extern void cts_stop_dump_test_data_to_file(void);
|
||||
|
||||
extern int cts_test_reset_pin(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_int_pin(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_rawdata(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_noise(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_open(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_short(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_compensate_cap(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_stylus_rawdata(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_stylus_noise(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
extern int cts_test_stylus_mnt_rawdata(struct cts_device *cts_dev,
|
||||
struct cts_test_param *param);
|
||||
#endif /* CTS_TEST_H */
|
||||
1207
drivers/input/touchscreen/chipone_tddi/cts_tool.c
Normal file
1207
drivers/input/touchscreen/chipone_tddi/cts_tool.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -157,6 +157,8 @@ struct cyttsp5_mt_platform_data {
|
||||
char const *inp_dev_name;
|
||||
int vkeys_x;
|
||||
int vkeys_y;
|
||||
int max_x;
|
||||
int max_y;
|
||||
int swap_x;
|
||||
int swap_y;
|
||||
int xy_exchange;
|
||||
|
||||
@@ -295,6 +295,18 @@ static void *create_and_get_mt_pdata(struct device_node *dev_node)
|
||||
if (!rc)
|
||||
pdata->vkeys_y = value;
|
||||
|
||||
rc = of_property_read_u32(dev_node, "cy,max_x", &value);
|
||||
if (!rc)
|
||||
pdata->max_x = value;
|
||||
else
|
||||
pdata->max_x = -1;
|
||||
|
||||
rc = of_property_read_u32(dev_node, "cy,max_y", &value);
|
||||
if (!rc)
|
||||
pdata->max_y = value;
|
||||
else
|
||||
pdata->max_y = -1;
|
||||
|
||||
rc = of_property_read_u32(dev_node, "cy,revert_x", &value);
|
||||
if (!rc)
|
||||
pdata->swap_x = value;
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
#define MT_PARAM_FUZZ(md, sig_ost) PARAM_FUZZ(md->pdata->frmwrk, sig_ost)
|
||||
#define MT_PARAM_FLAT(md, sig_ost) PARAM_FLAT(md->pdata->frmwrk, sig_ost)
|
||||
|
||||
static int screen_max_x = 1872;
|
||||
static int screen_max_y = 1404;
|
||||
static int screen_max_x = 0;
|
||||
static int screen_max_y = 0;
|
||||
static int revert_x_flag = 0;
|
||||
static int revert_y_flag = 0;
|
||||
static int exchange_x_y_flag = 0;
|
||||
@@ -636,17 +636,24 @@ static int cyttsp5_setup_input_device(struct device *dev)
|
||||
max = max_y;
|
||||
else if (i == CY_ABS_P_OST)
|
||||
max = max_p;
|
||||
|
||||
/*change x-y max value*/
|
||||
if(signal == ABS_MT_POSITION_X) {
|
||||
if (screen_max_x > 0)
|
||||
input_set_abs_params(md->input, signal, min, screen_max_x,
|
||||
MT_PARAM_FUZZ(md, i), MT_PARAM_FLAT(md, i));
|
||||
screen_max_x = max;
|
||||
dev_info(dev, "screen_max_x = %d\n", screen_max_x);
|
||||
}
|
||||
if(signal == ABS_MT_POSITION_Y) {
|
||||
} else if (signal == ABS_MT_POSITION_Y) {
|
||||
if (screen_max_y > 0)
|
||||
input_set_abs_params(md->input, signal, min, screen_max_y,
|
||||
MT_PARAM_FUZZ(md, i), MT_PARAM_FLAT(md, i));
|
||||
screen_max_y = max;
|
||||
dev_info(dev, "screen_max_y = %d\n", screen_max_y);
|
||||
} else {
|
||||
input_set_abs_params(md->input, signal, min, max,
|
||||
MT_PARAM_FUZZ(md, i), MT_PARAM_FLAT(md, i));
|
||||
}
|
||||
input_set_abs_params(md->input, signal, min, max,
|
||||
MT_PARAM_FUZZ(md, i), MT_PARAM_FLAT(md, i));
|
||||
parade_debug(dev, DEBUG_LEVEL_1,
|
||||
"%s: register signal=%02X min=%d max=%d\n",
|
||||
__func__, signal, min, max);
|
||||
@@ -747,6 +754,11 @@ int cyttsp5_mt_probe(struct device *dev)
|
||||
md->input->close = cyttsp5_mt_close;
|
||||
input_set_drvdata(md->input, md);
|
||||
|
||||
if (mt_pdata->max_x > 0)
|
||||
screen_max_x = mt_pdata->max_x;
|
||||
if (mt_pdata->max_y > 0)
|
||||
screen_max_y = mt_pdata->max_y;
|
||||
|
||||
/* get sysinfo */
|
||||
md->si = _cyttsp5_request_sysinfo(dev);
|
||||
|
||||
|
||||
@@ -2068,6 +2068,17 @@ config VIDEO_AW8601
|
||||
capability. This is designed for linear control of
|
||||
voice coil motors, controlled via I2C serial interface.
|
||||
|
||||
config VIDEO_CES6301
|
||||
tristate "CES6301 lens voice coil support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
help
|
||||
This is a driver for the CES6301 camera lens voice coil.
|
||||
CES6301 is a 10 bit DAC with 120mA output current sink
|
||||
capability. This is designed for linear control of
|
||||
voice coil motors, controlled via I2C serial interface.
|
||||
|
||||
config VIDEO_CN3927V
|
||||
tristate "CN3927V lens voice coil support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
|
||||
@@ -32,6 +32,7 @@ obj-$(CONFIG_VIDEO_BT866) += bt866.o
|
||||
obj-$(CONFIG_VIDEO_CAM_SLEEP_WAKEUP) += cam-sleep-wakeup.o
|
||||
obj-$(CONFIG_VIDEO_CCS) += ccs/
|
||||
obj-$(CONFIG_VIDEO_CCS_PLL) += ccs-pll.o
|
||||
obj-$(CONFIG_VIDEO_CES6301) += ces6301.o
|
||||
obj-$(CONFIG_VIDEO_CN3927V) += cn3927v.o
|
||||
obj-$(CONFIG_VIDEO_CS3308) += cs3308.o
|
||||
obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
|
||||
|
||||
1133
drivers/media/i2c/ces6301.c
Normal file
1133
drivers/media/i2c/ces6301.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,9 @@
|
||||
* Copyright (C) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* V0.0X01.0X01 init first version.
|
||||
* V0.0X01.0X01 update sensor driver.
|
||||
* 1. adjust power sequence to suit spec.
|
||||
* 2. fix bayer pattern to suit setting.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
@@ -84,7 +87,7 @@
|
||||
#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
|
||||
|
||||
#define GC05A2_NAME "gc05a2"
|
||||
#define GC05A2_MEDIA_BUS_FMT MEDIA_BUS_FMT_SRGGB10_1X10
|
||||
#define GC05A2_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG10_1X10
|
||||
|
||||
static const char * const gc05a2_supply_names[] = {
|
||||
"avdd", /* Analog power */
|
||||
@@ -1185,14 +1188,16 @@ static int __gc05a2_power_on(struct gc05a2 *gc05a2)
|
||||
dev_err(dev, "Failed to enable xvclk\n");
|
||||
return ret;
|
||||
}
|
||||
if (!IS_ERR(gc05a2->reset_gpio))
|
||||
gpiod_set_value_cansleep(gc05a2->reset_gpio, 0);
|
||||
|
||||
ret = regulator_bulk_enable(GC05A2_NUM_SUPPLIES, gc05a2->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulators\n");
|
||||
goto disable_clk;
|
||||
}
|
||||
usleep_range(2000, 2100);
|
||||
|
||||
if (!IS_ERR(gc05a2->reset_gpio))
|
||||
gpiod_set_value_cansleep(gc05a2->reset_gpio, 0);
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
if (!IS_ERR(gc05a2->reset_gpio))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
||||
#include <linux/compat.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/extcon-provider.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -121,6 +122,7 @@ struct rk628_csi {
|
||||
struct rk628_hdcp hdcp;
|
||||
bool i2s_enable_default;
|
||||
HAUDINFO audio_info;
|
||||
struct extcon_dev *extcon;
|
||||
struct rk628_combtxphy *txphy;
|
||||
struct rk628_dsi dsi;
|
||||
const struct rk628_plat_data *plat_data;
|
||||
@@ -228,6 +230,11 @@ static u8 rk628f_edid_init_data[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3,
|
||||
};
|
||||
|
||||
static const unsigned int rk628_csi_extcon_cable[] = {
|
||||
EXTCON_JACK_VIDEO_IN,
|
||||
EXTCON_NONE,
|
||||
};
|
||||
|
||||
static const struct mipi_timing rk628d_csi_mipi = {
|
||||
0x4a, 0xf, 0x5d, 0x3a, 0x3a, 0x5a, 0x1f
|
||||
};
|
||||
@@ -497,6 +504,7 @@ static void rk628_csi_delayed_work_enable_hotplug(struct work_struct *work)
|
||||
v4l2_ctrl_s_ctrl(csi->detect_tx_5v_ctrl, plugin);
|
||||
v4l2_dbg(1, debug, sd, "%s: 5v_det:%d\n", __func__, plugin);
|
||||
if (plugin) {
|
||||
extcon_set_state_sync(csi->extcon, EXTCON_JACK_VIDEO_IN, true);
|
||||
rk628_csi_enable_interrupts(sd, false);
|
||||
rk628_hdmirx_audio_setup(csi->audio_info);
|
||||
rk628_hdmirx_set_hdcp(csi->rk628, &csi->hdcp, csi->enable_hdcp);
|
||||
@@ -507,6 +515,7 @@ static void rk628_csi_delayed_work_enable_hotplug(struct work_struct *work)
|
||||
rk628_hdmirx_cec_state_reconfiguration(csi->rk628, csi->cec);
|
||||
rk628_csi_enable_interrupts(sd, true);
|
||||
} else {
|
||||
extcon_set_state_sync(csi->extcon, EXTCON_JACK_VIDEO_IN, false);
|
||||
rk628_hdmirx_plugout(sd);
|
||||
}
|
||||
mutex_unlock(&csi->confctl_mutex);
|
||||
@@ -3094,6 +3103,19 @@ static int rk628_csi_probe(struct i2c_client *client,
|
||||
if (IS_ERR(csi->classdev))
|
||||
goto err_hdl;
|
||||
|
||||
csi->extcon = devm_extcon_dev_allocate(dev, rk628_csi_extcon_cable);
|
||||
if (IS_ERR(csi->extcon)) {
|
||||
err = PTR_ERR(csi->extcon);
|
||||
v4l2_err(sd, "allocate extcon failed\n");
|
||||
goto err_hdl;
|
||||
}
|
||||
|
||||
err = devm_extcon_dev_register(dev, csi->extcon);
|
||||
if (err) {
|
||||
v4l2_err(sd, "failed to register extcon: %d\n", err);
|
||||
goto err_hdl;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&csi->delayed_work_enable_hotplug,
|
||||
rk628_csi_delayed_work_enable_hotplug);
|
||||
INIT_DELAYED_WORK(&csi->delayed_work_res_change,
|
||||
@@ -3104,6 +3126,7 @@ static int rk628_csi_probe(struct i2c_client *client,
|
||||
rk628,
|
||||
csi->i2s_enable_default);
|
||||
if (!csi->audio_info) {
|
||||
err = -ENOMEM;
|
||||
v4l2_err(sd, "request audio info fail\n");
|
||||
goto err_work_queues;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
* Copyright (C) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* V0.0X01.0X00 first version.
|
||||
* V0.0X01.0X01 update sensor driver.
|
||||
* 1. adjust power sequence to suit spec.
|
||||
* 2. add read/write reg error debug log.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -28,7 +31,7 @@
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
|
||||
|
||||
#define S5K3L8XX_MAJOR_I2C_ADDR 0x10
|
||||
#define S5K3L8XX_MINOR_I2C_ADDR 0x2D
|
||||
@@ -671,8 +674,11 @@ static int s5k3l8xx_write_reg(struct i2c_client *client, u16 reg,
|
||||
while (val_i < 4)
|
||||
buf[buf_i++] = val_p[val_i++];
|
||||
|
||||
if (i2c_master_send(client, buf, len + 2) != len + 2)
|
||||
if (i2c_master_send(client, buf, len + 2) != len + 2) {
|
||||
dev_err(&client->dev,
|
||||
"write reg(0x%x val:0x%x) failed !\n", reg, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -718,8 +724,11 @@ static int s5k3l8xx_read_reg(struct i2c_client *client, u16 reg,
|
||||
msgs[1].buf = &data_be_p[4 - len];
|
||||
|
||||
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (ret != ARRAY_SIZE(msgs))
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
dev_err(&client->dev,
|
||||
"read reg:0x%x failed !\n", reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*val = be32_to_cpu(data_be);
|
||||
|
||||
@@ -1126,8 +1135,6 @@ static int __s5k3l8xx_power_on(struct s5k3l8xx *s5k3l8xx)
|
||||
dev_err(dev, "Failed to enable xvclk\n");
|
||||
return ret;
|
||||
}
|
||||
if (!IS_ERR(s5k3l8xx->reset_gpio))
|
||||
gpiod_set_value_cansleep(s5k3l8xx->reset_gpio, 0);
|
||||
|
||||
ret = regulator_bulk_enable(S5K3L8XX_NUM_SUPPLIES, s5k3l8xx->supplies);
|
||||
if (ret < 0) {
|
||||
@@ -1135,6 +1142,14 @@ static int __s5k3l8xx_power_on(struct s5k3l8xx *s5k3l8xx)
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
/* need reset after all vdd power on */
|
||||
usleep_range(2000, 2100);
|
||||
|
||||
if (!IS_ERR(s5k3l8xx->reset_gpio))
|
||||
gpiod_set_value_cansleep(s5k3l8xx->reset_gpio, 0);
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
if (!IS_ERR(s5k3l8xx->reset_gpio))
|
||||
gpiod_set_value_cansleep(s5k3l8xx->reset_gpio, 1);
|
||||
|
||||
@@ -1142,8 +1157,8 @@ static int __s5k3l8xx_power_on(struct s5k3l8xx *s5k3l8xx)
|
||||
if (!IS_ERR(s5k3l8xx->pwdn_gpio))
|
||||
gpiod_set_value_cansleep(s5k3l8xx->pwdn_gpio, 1);
|
||||
|
||||
/* 8192 cycles prior to first SCCB transaction */
|
||||
delay_us = s5k3l8xx_cal_delay(8192);
|
||||
/* 23000 cycles prior to first SCCB transaction */
|
||||
delay_us = s5k3l8xx_cal_delay(23000);
|
||||
usleep_range(delay_us, delay_us * 2);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -187,7 +187,8 @@ static void serdes_bridge_enable(struct drm_bridge *bridge)
|
||||
|
||||
if (!ret) {
|
||||
extcon_set_state_sync(serdes->extcon, EXTCON_JACK_VIDEO_OUT, true);
|
||||
SERDES_DBG_MFD("%s: extcon is true\n", __func__);
|
||||
SERDES_DBG_MFD("%s: %s-%s extcon is true\n", __func__, dev_name(serdes->dev),
|
||||
serdes->chip_data->name);
|
||||
}
|
||||
|
||||
SERDES_DBG_MFD("%s: %s-%s ret=%d\n", __func__, dev_name(serdes->dev),
|
||||
@@ -204,6 +205,9 @@ serdes_bridge_detect(struct drm_bridge *bridge)
|
||||
if (serdes->chip_data->bridge_ops->detect)
|
||||
status = serdes->chip_data->bridge_ops->detect(serdes);
|
||||
|
||||
SERDES_DBG_MFD("%s:%s %s, %s\n", __func__, dev_name(serdes->dev),
|
||||
serdes->chip_data->name,
|
||||
(status == connector_status_connected) ? "connected" : "disconnect");
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -223,7 +227,7 @@ static int serdes_bridge_get_modes(struct drm_bridge *bridge,
|
||||
if (serdes_bridge->panel)
|
||||
ret = drm_panel_get_modes(serdes_bridge->panel, connector);
|
||||
|
||||
SERDES_DBG_MFD("%s:name=%s, node=%s\n", __func__,
|
||||
SERDES_DBG_MFD("%s:%s %s, node=%s\n", __func__, dev_name(serdes->dev),
|
||||
serdes->chip_data->name, serdes_bridge->dev->of_node->name);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -108,18 +108,9 @@ static void serdes_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
|
||||
for (i = 0; i < chip->ngpio; i++) {
|
||||
int gpio = i + chip->base;
|
||||
const char *label, *level;
|
||||
const char *level;
|
||||
|
||||
/* We report the GPIO even if it's not requested since
|
||||
* we're also reporting things like alternate
|
||||
* functions which apply even when the GPIO is not in
|
||||
* use as a GPIO.
|
||||
*/
|
||||
label = gpiochip_is_requested(chip, i);
|
||||
if (!label)
|
||||
label = "Unrequested";
|
||||
|
||||
seq_printf(s, " %s-gpio-%02d ", label, gpio);
|
||||
seq_printf(s, "gpio-%02d ", gpio);
|
||||
|
||||
if (serdes->chip_data->gpio_ops->get_level)
|
||||
ret = serdes->chip_data->gpio_ops->get_level(serdes, i);
|
||||
|
||||
@@ -213,7 +213,7 @@ static int serdes_panel_split_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to parse serdes DT\n");
|
||||
|
||||
serdes_panel_split->backlight = devm_of_find_backlight(dev);
|
||||
serdes_panel_split->backlight = of_find_backlight_by_node(dev->of_node);
|
||||
if (IS_ERR(serdes_panel_split->backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(serdes_panel_split->backlight),
|
||||
"failed to get serdes backlight\n");
|
||||
@@ -236,6 +236,10 @@ static int serdes_panel_split_probe(struct platform_device *pdev)
|
||||
static int serdes_panel_split_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct serdes_panel_split *serdes_panel_split = platform_get_drvdata(pdev);
|
||||
struct backlight_device *backlight = serdes_panel_split->backlight;
|
||||
|
||||
if (backlight)
|
||||
put_device(&backlight->dev);
|
||||
|
||||
drm_panel_remove(&serdes_panel_split->panel);
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ static int serdes_panel_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to parse serdes DT\n");
|
||||
|
||||
serdes_panel->backlight = devm_of_find_backlight(dev);
|
||||
serdes_panel->backlight = of_find_backlight_by_node(dev->of_node);
|
||||
if (IS_ERR(serdes_panel->backlight))
|
||||
return dev_err_probe(dev, PTR_ERR(serdes_panel->backlight),
|
||||
"failed to get serdes backlight\n");
|
||||
@@ -242,6 +242,10 @@ static int serdes_panel_probe(struct platform_device *pdev)
|
||||
static int serdes_panel_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct serdes_panel *serdes_panel = platform_get_drvdata(pdev);
|
||||
struct backlight_device *backlight = serdes_panel->backlight;
|
||||
|
||||
if (backlight)
|
||||
put_device(&backlight->dev);
|
||||
|
||||
drm_panel_remove(&serdes_panel->panel);
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
|
||||
#define DRIVER_NAME "rknpu"
|
||||
#define DRIVER_DESC "RKNPU driver"
|
||||
#define DRIVER_DATE "20240129"
|
||||
#define DRIVER_DATE "20240226"
|
||||
#define DRIVER_MAJOR 0
|
||||
#define DRIVER_MINOR 9
|
||||
#define DRIVER_PATCHLEVEL 4
|
||||
#define DRIVER_PATCHLEVEL 5
|
||||
|
||||
#define LOG_TAG "RKNPU"
|
||||
|
||||
@@ -58,11 +58,6 @@ struct rknpu_irqs_data {
|
||||
irqreturn_t (*irq_hdl)(int irq, void *ctx);
|
||||
};
|
||||
|
||||
struct rknpu_reset_data {
|
||||
const char *srst_a_name;
|
||||
const char *srst_h_name;
|
||||
};
|
||||
|
||||
struct rknpu_amount_data {
|
||||
uint16_t offset_clr_all;
|
||||
uint16_t offset_dt_wr;
|
||||
@@ -80,9 +75,7 @@ struct rknpu_config {
|
||||
__u32 pc_task_status_offset;
|
||||
__u32 pc_dma_ctrl;
|
||||
const struct rknpu_irqs_data *irqs;
|
||||
const struct rknpu_reset_data *resets;
|
||||
int num_irqs;
|
||||
int num_resets;
|
||||
__u64 nbuf_phyaddr;
|
||||
__u64 nbuf_size;
|
||||
__u64 max_submit_number;
|
||||
@@ -132,8 +125,8 @@ struct rknpu_device {
|
||||
void __iomem *bw_priority_base;
|
||||
struct rknpu_fence_context *fence_ctx;
|
||||
bool iommu_en;
|
||||
struct reset_control *srst_a[RKNPU_MAX_CORES];
|
||||
struct reset_control *srst_h[RKNPU_MAX_CORES];
|
||||
struct reset_control **srsts;
|
||||
int num_srsts;
|
||||
struct clk_bulk_data *clks;
|
||||
int num_clks;
|
||||
struct regulator *vdd;
|
||||
|
||||
@@ -162,7 +162,6 @@ static int rk3588_npu_set_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
u32 rm)
|
||||
{
|
||||
struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
|
||||
u32 offset = 0, val = 0;
|
||||
int i, ret = 0;
|
||||
|
||||
@@ -174,7 +173,7 @@ static int rk3588_npu_set_read_margin(struct device *dev,
|
||||
|
||||
LOG_DEV_DEBUG(dev, "set rm to %d\n", rm);
|
||||
|
||||
for (i = 0; i < rknpu_dev->config->num_irqs; i++) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
ret = regmap_read(opp_info->grf, offset, &val);
|
||||
if (ret < 0) {
|
||||
LOG_DEV_ERROR(dev, "failed to get rm from 0x%x\n",
|
||||
|
||||
@@ -81,15 +81,6 @@ static const struct rknpu_irqs_data rk3588_npu_irqs[] = {
|
||||
{ "npu2_irq", rknpu_core2_irq_handler }
|
||||
};
|
||||
|
||||
static const struct rknpu_reset_data rknpu_resets[] = { { "srst_a",
|
||||
"srst_h" } };
|
||||
|
||||
static const struct rknpu_reset_data rk3588_npu_resets[] = {
|
||||
{ "srst_a0", "srst_h0" },
|
||||
{ "srst_a1", "srst_h1" },
|
||||
{ "srst_a2", "srst_h2" }
|
||||
};
|
||||
|
||||
static const struct rknpu_amount_data rknpu_old_top_amount = {
|
||||
.offset_clr_all = 0x8010,
|
||||
.offset_dt_wr = 0x8034,
|
||||
@@ -121,9 +112,7 @@ static const struct rknpu_config rk356x_rknpu_config = {
|
||||
.pc_task_status_offset = 0x3c,
|
||||
.pc_dma_ctrl = 0,
|
||||
.irqs = rknpu_irqs,
|
||||
.resets = rknpu_resets,
|
||||
.num_irqs = ARRAY_SIZE(rknpu_irqs),
|
||||
.num_resets = ARRAY_SIZE(rknpu_resets),
|
||||
.nbuf_phyaddr = 0,
|
||||
.nbuf_size = 0,
|
||||
.max_submit_number = (1 << 12) - 1,
|
||||
@@ -142,9 +131,7 @@ static const struct rknpu_config rk3588_rknpu_config = {
|
||||
.pc_task_status_offset = 0x3c,
|
||||
.pc_dma_ctrl = 0,
|
||||
.irqs = rk3588_npu_irqs,
|
||||
.resets = rk3588_npu_resets,
|
||||
.num_irqs = ARRAY_SIZE(rk3588_npu_irqs),
|
||||
.num_resets = ARRAY_SIZE(rk3588_npu_resets),
|
||||
.nbuf_phyaddr = 0,
|
||||
.nbuf_size = 0,
|
||||
.max_submit_number = (1 << 12) - 1,
|
||||
@@ -163,9 +150,7 @@ static const struct rknpu_config rk3583_rknpu_config = {
|
||||
.pc_task_status_offset = 0x3c,
|
||||
.pc_dma_ctrl = 0,
|
||||
.irqs = rk3588_npu_irqs,
|
||||
.resets = rk3588_npu_resets,
|
||||
.num_irqs = 2,
|
||||
.num_resets = 2,
|
||||
.nbuf_phyaddr = 0,
|
||||
.nbuf_size = 0,
|
||||
.max_submit_number = (1 << 12) - 1,
|
||||
@@ -184,9 +169,7 @@ static const struct rknpu_config rv1106_rknpu_config = {
|
||||
.pc_task_status_offset = 0x3c,
|
||||
.pc_dma_ctrl = 0,
|
||||
.irqs = rknpu_irqs,
|
||||
.resets = rknpu_resets,
|
||||
.num_irqs = ARRAY_SIZE(rknpu_irqs),
|
||||
.num_resets = ARRAY_SIZE(rknpu_resets),
|
||||
.nbuf_phyaddr = 0,
|
||||
.nbuf_size = 0,
|
||||
.max_submit_number = (1 << 16) - 1,
|
||||
@@ -205,9 +188,7 @@ static const struct rknpu_config rk3562_rknpu_config = {
|
||||
.pc_task_status_offset = 0x48,
|
||||
.pc_dma_ctrl = 1,
|
||||
.irqs = rknpu_irqs,
|
||||
.resets = rknpu_resets,
|
||||
.num_irqs = ARRAY_SIZE(rknpu_irqs),
|
||||
.num_resets = ARRAY_SIZE(rknpu_resets),
|
||||
.nbuf_phyaddr = 0xfe400000,
|
||||
.nbuf_size = 256 * 1024,
|
||||
.max_submit_number = (1 << 16) - 1,
|
||||
|
||||
@@ -128,6 +128,7 @@ static inline struct rknpu_job *rknpu_job_alloc(struct rknpu_device *rknpu_dev,
|
||||
struct rknpu_submit *args)
|
||||
{
|
||||
struct rknpu_job *job = NULL;
|
||||
int i = 0;
|
||||
#ifdef CONFIG_ROCKCHIP_RKNPU_DRM_GEM
|
||||
struct rknpu_gem_object *task_obj = NULL;
|
||||
#endif
|
||||
@@ -143,6 +144,8 @@ static inline struct rknpu_job *rknpu_job_alloc(struct rknpu_device *rknpu_dev,
|
||||
((args->core_mask & RKNPU_CORE2_MASK) >> 2);
|
||||
atomic_set(&job->run_count, job->use_core_num);
|
||||
atomic_set(&job->interrupt_count, job->use_core_num);
|
||||
for (i = 0; i < rknpu_dev->config->num_irqs; i++)
|
||||
atomic_set(&job->submit_count[i], 0);
|
||||
#ifdef CONFIG_ROCKCHIP_RKNPU_DRM_GEM
|
||||
task_obj = (struct rknpu_gem_object *)(uintptr_t)args->task_obj_addr;
|
||||
if (task_obj)
|
||||
|
||||
@@ -28,27 +28,34 @@ static inline struct reset_control *rknpu_reset_control_get(struct device *dev,
|
||||
int rknpu_reset_get(struct rknpu_device *rknpu_dev)
|
||||
{
|
||||
#ifndef FPGA_PLATFORM
|
||||
struct reset_control *srst_a = NULL;
|
||||
struct reset_control *srst_h = NULL;
|
||||
int i = 0;
|
||||
int num_srsts = 0;
|
||||
|
||||
for (i = 0; i < rknpu_dev->config->num_resets; i++) {
|
||||
srst_a = rknpu_reset_control_get(
|
||||
rknpu_dev->dev,
|
||||
rknpu_dev->config->resets[i].srst_a_name);
|
||||
if (IS_ERR(srst_a))
|
||||
return PTR_ERR(srst_a);
|
||||
|
||||
rknpu_dev->srst_a[i] = srst_a;
|
||||
|
||||
srst_h = rknpu_reset_control_get(
|
||||
rknpu_dev->dev,
|
||||
rknpu_dev->config->resets[i].srst_h_name);
|
||||
if (IS_ERR(srst_h))
|
||||
return PTR_ERR(srst_h);
|
||||
|
||||
rknpu_dev->srst_h[i] = srst_h;
|
||||
num_srsts = of_count_phandle_with_args(rknpu_dev->dev->of_node,
|
||||
"resets", "#reset-cells");
|
||||
if (num_srsts <= 0) {
|
||||
LOG_DEV_ERROR(rknpu_dev->dev,
|
||||
"failed to get rknpu resets from dtb\n");
|
||||
return num_srsts;
|
||||
}
|
||||
|
||||
rknpu_dev->srsts = devm_kcalloc(rknpu_dev->dev, num_srsts,
|
||||
sizeof(*rknpu_dev->srsts), GFP_KERNEL);
|
||||
if (!rknpu_dev->srsts)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_srsts; ++i) {
|
||||
rknpu_dev->srsts[i] = devm_reset_control_get_exclusive_by_index(
|
||||
rknpu_dev->dev, i);
|
||||
if (IS_ERR(rknpu_dev->srsts[i])) {
|
||||
rknpu_dev->num_srsts = i;
|
||||
return PTR_ERR(rknpu_dev->srsts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
rknpu_dev->num_srsts = num_srsts;
|
||||
|
||||
return num_srsts;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -93,7 +100,7 @@ int rknpu_soft_reset(struct rknpu_device *rknpu_dev)
|
||||
#ifndef FPGA_PLATFORM
|
||||
struct iommu_domain *domain = NULL;
|
||||
struct rknpu_subcore_data *subcore_data = NULL;
|
||||
int ret = -EINVAL, i = 0;
|
||||
int ret = 0, i = 0;
|
||||
|
||||
if (rknpu_dev->bypass_soft_reset) {
|
||||
LOG_WARN("bypass soft reset\n");
|
||||
@@ -112,17 +119,17 @@ int rknpu_soft_reset(struct rknpu_device *rknpu_dev)
|
||||
wake_up(&subcore_data->job_done_wq);
|
||||
}
|
||||
|
||||
LOG_INFO("soft reset\n");
|
||||
LOG_INFO("soft reset, num: %d\n", rknpu_dev->num_srsts);
|
||||
|
||||
for (i = 0; i < rknpu_dev->config->num_resets; i++) {
|
||||
ret = rknpu_reset_assert(rknpu_dev->srst_a[i]);
|
||||
ret |= rknpu_reset_assert(rknpu_dev->srst_h[i]);
|
||||
for (i = 0; i < rknpu_dev->num_srsts; ++i)
|
||||
ret |= rknpu_reset_assert(rknpu_dev->srsts[i]);
|
||||
|
||||
udelay(10);
|
||||
udelay(10);
|
||||
|
||||
ret |= rknpu_reset_deassert(rknpu_dev->srst_a[i]);
|
||||
ret |= rknpu_reset_deassert(rknpu_dev->srst_h[i]);
|
||||
}
|
||||
for (i = 0; i < rknpu_dev->num_srsts; ++i)
|
||||
ret |= rknpu_reset_deassert(rknpu_dev->srsts[i]);
|
||||
|
||||
udelay(10);
|
||||
|
||||
if (ret) {
|
||||
LOG_DEV_ERROR(rknpu_dev->dev,
|
||||
|
||||
@@ -250,10 +250,25 @@ config ROCKCHIP_MINI_KERNEL
|
||||
config ROCKCHIP_THUNDER_BOOT
|
||||
bool "Rockchip Thunder Boot support"
|
||||
depends on NO_GKI
|
||||
select ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK if SMP
|
||||
help
|
||||
Say y here to enable Rockchip thunder boot support.
|
||||
This option make the kernel boot faster.
|
||||
|
||||
config ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK
|
||||
bool "Defer free large memblock to Buddy allocator"
|
||||
depends on SMP
|
||||
depends on NO_GKI
|
||||
help
|
||||
The physical memory of a system is divided into several types, like
|
||||
memory reserved for device, for kernel pagetable, etc. The remaining
|
||||
area is for Buddy allocator. Normally, The memory for Buddy is consist
|
||||
of different size blocks, so, under meeting the memory request of kernel
|
||||
booting, we can defer free the large block size to Buddy which can be
|
||||
done later in work queue in parallel to other kernel threads, and the
|
||||
size of the large block can be defined in kernel command line
|
||||
by "defer_free_block_size" boot parameter.
|
||||
|
||||
config ROCKCHIP_THUNDER_BOOT_MMC
|
||||
bool "Rockchip Thunder Boot from MMC"
|
||||
depends on ROCKCHIP_THUNDER_BOOT
|
||||
|
||||
@@ -59,7 +59,6 @@ struct pvtm_config {
|
||||
int temp_prop[2];
|
||||
const char *tz_name;
|
||||
struct thermal_zone_device *tz;
|
||||
struct regmap *grf;
|
||||
};
|
||||
|
||||
struct lkg_conversion_table {
|
||||
@@ -338,9 +337,6 @@ static int rockchip_parse_pvtm_config(struct device_node *np,
|
||||
if (of_property_read_u32(np, "rockchip,pvtm-offset",
|
||||
&pvtm->offset))
|
||||
return -EINVAL;
|
||||
pvtm->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
|
||||
if (IS_ERR(pvtm->grf))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (of_property_read_u32_array(np, "rockchip,pvtm-ch", pvtm->ch, 2))
|
||||
@@ -725,11 +721,11 @@ static unsigned long rockchip_pvtpll_get_rate(struct rockchip_opp_info *info)
|
||||
int i;
|
||||
|
||||
#define MIN_STABLE_DELTA 3
|
||||
regmap_read(info->grf, info->pvtpll_avg_offset, &rate0);
|
||||
regmap_read(info->pvtpll_base, info->pvtpll_avg_offset, &rate0);
|
||||
/* max delay 2ms */
|
||||
for (i = 0; i < 20; i++) {
|
||||
udelay(100);
|
||||
regmap_read(info->grf, info->pvtpll_avg_offset, &rate1);
|
||||
regmap_read(info->pvtpll_base, info->pvtpll_avg_offset, &rate1);
|
||||
delta = abs(rate1 - rate0);
|
||||
rate0 = rate1;
|
||||
if (delta <= MIN_STABLE_DELTA)
|
||||
@@ -854,7 +850,7 @@ static void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info)
|
||||
unsigned long rate, pvtpll_rate, old_rate, cur_rate, delta0, delta1;
|
||||
int i = 0, max_count, step, cur_step, ret;
|
||||
|
||||
if (!info || !info->grf)
|
||||
if (!info || !info->pvtpll_base)
|
||||
return;
|
||||
|
||||
dev_dbg(info->dev, "calibrating opp ...\n");
|
||||
@@ -1051,6 +1047,7 @@ out:
|
||||
}
|
||||
|
||||
static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np,
|
||||
struct rockchip_opp_info *info,
|
||||
const char *reg_name)
|
||||
{
|
||||
struct regulator *reg;
|
||||
@@ -1067,6 +1064,9 @@ static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np,
|
||||
return pvtm_value;
|
||||
}
|
||||
|
||||
if (!info || !info->pvtpll_base)
|
||||
return -ENOMEM;
|
||||
|
||||
pvtm = kzalloc(sizeof(*pvtm), GFP_KERNEL);
|
||||
if (!pvtm)
|
||||
return -ENOMEM;
|
||||
@@ -1102,7 +1102,7 @@ static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np,
|
||||
}
|
||||
usleep_range(pvtm->sample_time, pvtm->sample_time + 100);
|
||||
|
||||
ret = regmap_read(pvtm->grf, pvtm->offset, &pvtm_value);
|
||||
ret = regmap_read(info->pvtpll_base, pvtm->offset, &pvtm_value);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to get pvtm from 0x%x\n", pvtm->offset);
|
||||
goto resetore_volt;
|
||||
@@ -1179,8 +1179,9 @@ static int rockchip_get_pvtm(struct device *dev, struct device_node *np,
|
||||
}
|
||||
|
||||
static void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
|
||||
const char *reg_name, int bin, int process,
|
||||
int *volt_sel, int *scale_sel)
|
||||
struct rockchip_opp_info *info,
|
||||
const char *reg_name, int *volt_sel,
|
||||
int *scale_sel)
|
||||
{
|
||||
struct property *prop = NULL;
|
||||
char name[NAME_MAX];
|
||||
@@ -1188,7 +1189,7 @@ static void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
|
||||
u32 hw = 0;
|
||||
|
||||
if (of_property_read_bool(np, "rockchip,pvtm-pvtpll"))
|
||||
pvtm = rockchip_get_pvtm_pvtpll(dev, np, reg_name);
|
||||
pvtm = rockchip_get_pvtm_pvtpll(dev, np, info, reg_name);
|
||||
else
|
||||
pvtm = rockchip_get_pvtm(dev, np, reg_name);
|
||||
if (pvtm <= 0)
|
||||
@@ -1196,19 +1197,19 @@ static void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
|
||||
|
||||
if (!volt_sel)
|
||||
goto next;
|
||||
if (process >= 0) {
|
||||
if (info->process >= 0) {
|
||||
snprintf(name, sizeof(name),
|
||||
"rockchip,p%d-pvtm-voltage-sel", process);
|
||||
"rockchip,p%d-pvtm-voltage-sel", info->process);
|
||||
prop = of_find_property(np, name, NULL);
|
||||
} else if (bin > 0) {
|
||||
} else if (info->bin > 0) {
|
||||
of_property_read_u32(np, "rockchip,pvtm-hw", &hw);
|
||||
if (hw && (hw & BIT(bin))) {
|
||||
if (hw && (hw & BIT(info->bin))) {
|
||||
sprintf(name, "rockchip,pvtm-voltage-sel-hw");
|
||||
prop = of_find_property(np, name, NULL);
|
||||
}
|
||||
if (!prop) {
|
||||
snprintf(name, sizeof(name),
|
||||
"rockchip,pvtm-voltage-sel-B%d", bin);
|
||||
"rockchip,pvtm-voltage-sel-B%d", info->bin);
|
||||
prop = of_find_property(np, name, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1222,9 +1223,9 @@ next:
|
||||
if (!scale_sel)
|
||||
return;
|
||||
prop = NULL;
|
||||
if (process >= 0) {
|
||||
if (info->process >= 0) {
|
||||
snprintf(name, sizeof(name),
|
||||
"rockchip,p%d-pvtm-scaling-sel", process);
|
||||
"rockchip,p%d-pvtm-scaling-sel", info->process);
|
||||
prop = of_find_property(np, name, NULL);
|
||||
}
|
||||
if (!prop)
|
||||
@@ -1485,8 +1486,8 @@ static void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
|
||||
|
||||
rockchip_of_get_lkg_sel(dev, np, lkg_name, info->process,
|
||||
&lkg_volt_sel, &lkg_scale);
|
||||
rockchip_of_get_pvtm_sel(dev, np, reg_name, info->bin, info->process,
|
||||
&pvtm_volt_sel, &pvtm_scale);
|
||||
rockchip_of_get_pvtm_sel(dev, np, info, reg_name, &pvtm_volt_sel,
|
||||
&pvtm_scale);
|
||||
rockchip_of_get_bin_sel(dev, np, info->bin, &bin_scale);
|
||||
rockchip_of_get_bin_volt_sel(dev, np, info->bin, &bin_volt_sel);
|
||||
info->scale = max3(lkg_scale, pvtm_scale, bin_scale);
|
||||
@@ -1498,6 +1499,25 @@ static void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
static int rockchip_opp_set_regulator_helper(struct device *dev,
|
||||
struct rockchip_opp_info *info)
|
||||
{
|
||||
struct opp_table *opp_table;
|
||||
|
||||
if (!info || !info->data || !info->data->config_regulators)
|
||||
return 0;
|
||||
|
||||
opp_table = dev_pm_opp_get_opp_table(dev);
|
||||
if (IS_ERR(opp_table))
|
||||
return PTR_ERR(opp_table);
|
||||
|
||||
opp_table->config_regulators = info->data->config_regulators;
|
||||
|
||||
dev_pm_opp_put_opp_table(opp_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_opp_set_config(struct device *dev, struct rockchip_opp_info *info,
|
||||
const char *clk_name, const char *reg_name)
|
||||
{
|
||||
@@ -1560,6 +1580,16 @@ static int rockchip_opp_set_config(struct device *dev, struct rockchip_opp_info
|
||||
return info->opp_token;
|
||||
}
|
||||
|
||||
/*
|
||||
* The dev_pm_opp_set_config() only support setting regulator helper
|
||||
* for multiple regulators, but on some platforms, still need to set
|
||||
* regulator helper for single regulator.
|
||||
*/
|
||||
if (rockchip_opp_set_regulator_helper(dev, info)) {
|
||||
dev_err(dev, "failed to set opp regulator helper\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1671,8 +1701,16 @@ int rockchip_init_opp_info(struct device *dev, struct rockchip_opp_info *info,
|
||||
if (IS_ERR(info->grf))
|
||||
info->grf = NULL;
|
||||
info->dsu_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,dsu-grf");
|
||||
if (IS_ERR(info->dsu_grf))
|
||||
if (IS_ERR(info->dsu_grf)) {
|
||||
info->dsu_grf = NULL;
|
||||
info->cci_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,cci-grf");
|
||||
if (IS_ERR(info->cci_grf))
|
||||
info->cci_grf = NULL;
|
||||
}
|
||||
|
||||
info->pvtpll_base = syscon_regmap_lookup_by_phandle(np, "rockchip,pvtpll");
|
||||
if (IS_ERR(info->pvtpll_base))
|
||||
info->pvtpll_base = info->grf;
|
||||
|
||||
ret = rockchip_get_opp_clk(dev, np, info);
|
||||
if (ret)
|
||||
@@ -2278,7 +2316,7 @@ int rockchip_opp_config_clks(struct device *dev, struct opp_table *opp_table,
|
||||
unsigned long *target = data;
|
||||
int ret;
|
||||
|
||||
if (!info->is_runtime_active)
|
||||
if (info->is_scmi_clk && !info->is_runtime_active)
|
||||
return 0;
|
||||
|
||||
ret = clk_bulk_prepare_enable(info->nclocks, info->clocks);
|
||||
|
||||
@@ -442,11 +442,11 @@ static ssize_t spidev_rkmst_misc_write(struct file *filp, const char __user *buf
|
||||
if (!tempbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
prandom_bytes(tempbuf, len);
|
||||
get_random_bytes(tempbuf, len);
|
||||
spidev_rkmst_xfer(spidev, tempbuf, NULL, addr, len);
|
||||
start_time = ktime_get();
|
||||
for (i = 0; i < loops; i++) {
|
||||
prandom_bytes(spidev->txbuf, len);
|
||||
get_random_bytes(spidev->txbuf, len);
|
||||
spidev_rkmst_xfer(spidev, spidev->txbuf, spidev->rxbuf, addr, len);
|
||||
if (memcmp(spidev->rxbuf, tempbuf, len)) {
|
||||
dev_err(&spi->dev, "dulplex autotest failed, loops=%d\n", i);
|
||||
@@ -487,7 +487,7 @@ static ssize_t spidev_rkmst_misc_write(struct file *filp, const char __user *buf
|
||||
|
||||
start_time = ktime_get();
|
||||
for (i = 0; i < loops; i++) {
|
||||
prandom_bytes(spidev->txbuf, len);
|
||||
get_random_bytes(spidev->txbuf, len);
|
||||
spidev_rkmst_xfer(spidev, spidev->txbuf, NULL, addr, len);
|
||||
spidev_rkmst_xfer(spidev, NULL, spidev->rxbuf, addr, len);
|
||||
if (memcmp(spidev->rxbuf, spidev->txbuf, len)) {
|
||||
@@ -601,13 +601,11 @@ static int spidev_rkmst_probe(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spidev_rkmst_remove(struct spi_device *spi)
|
||||
static void spidev_rkmst_remove(struct spi_device *spi)
|
||||
{
|
||||
struct spidev_rkmst_data *spidev = dev_get_drvdata(&spi->dev);
|
||||
|
||||
misc_deregister(&spidev->misc_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
@@ -108,6 +108,7 @@ static int spidev_slv_write_and_read(struct spidev_rkslv_data *spidev, const voi
|
||||
.tx_buf = tx_buf,
|
||||
.rx_buf = rx_buf,
|
||||
.len = len,
|
||||
.bits_per_word = bit_per_word,
|
||||
};
|
||||
struct spi_message m;
|
||||
int ret;
|
||||
@@ -375,7 +376,7 @@ static int spidev_rkslv_probe(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spidev_rkslv_remove(struct spi_device *spi)
|
||||
static void spidev_rkslv_remove(struct spi_device *spi)
|
||||
{
|
||||
struct spidev_rkslv_data *spidev = dev_get_drvdata(&spi->dev);
|
||||
|
||||
@@ -383,8 +384,6 @@ static int spidev_rkslv_remove(struct spi_device *spi)
|
||||
spi_slave_abort(spi);
|
||||
kthread_stop(spidev->tsk);
|
||||
misc_deregister(&spidev->misc_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
@@ -24,7 +24,7 @@ extern unsigned long max_pfn;
|
||||
*/
|
||||
extern unsigned long long max_possible_pfn;
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK
|
||||
extern int defer_free_memblock(void *unused);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ struct pvtpll_opp_table {
|
||||
* @volt_rm_tbl: Pointer to voltage to memory read margin conversion table.
|
||||
* @grf: General Register Files regmap.
|
||||
* @dsu_grf: DSU General Register Files regmap.
|
||||
* @cci_grf: CCI General Register Files regmap.
|
||||
* @clocks: Pvtpll clocks.
|
||||
* @nclocks: Number of pvtpll clock.
|
||||
* @intermediate_threshold_freq: The frequency threshold of intermediate rate.
|
||||
@@ -103,13 +104,17 @@ struct rockchip_opp_info {
|
||||
struct mutex dvfs_mutex;
|
||||
const struct rockchip_opp_data *data;
|
||||
struct pvtpll_opp_table *opp_table;
|
||||
struct regmap *pvtpll_base;
|
||||
unsigned int pvtpll_avg_offset;
|
||||
unsigned int pvtpll_min_rate;
|
||||
unsigned int pvtpll_volt_step;
|
||||
|
||||
struct volt_rm_table *volt_rm_tbl;
|
||||
struct regmap *grf;
|
||||
struct regmap *dsu_grf;
|
||||
union {
|
||||
struct regmap *dsu_grf;
|
||||
struct regmap *cci_grf;
|
||||
};
|
||||
struct clk_bulk_data *clocks;
|
||||
int nclocks;
|
||||
unsigned long intermediate_threshold_freq;
|
||||
|
||||
@@ -1817,7 +1817,7 @@ static noinline void __init kernel_init_freeable(void)
|
||||
smp_init();
|
||||
sched_init_smp();
|
||||
|
||||
#if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_SMP)
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK
|
||||
kthread_run(defer_free_memblock, NULL, "defer_mem");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -101,9 +101,14 @@ struct pglist_data __refdata contig_page_data;
|
||||
EXPORT_SYMBOL(contig_page_data);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_SMP)
|
||||
static unsigned long defer_start __initdata;
|
||||
static unsigned long defer_end __initdata;
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK
|
||||
static int db_count __initdata;
|
||||
#define DB_COUNT_MAX 4
|
||||
|
||||
static struct deferred_block {
|
||||
unsigned long defer_start;
|
||||
unsigned long defer_end;
|
||||
} db[DB_COUNT_MAX] __initdata;
|
||||
|
||||
#define DEFAULT_DEFER_FREE_BLOCK_SIZE SZ_256M
|
||||
static unsigned long defer_free_block_size __initdata =
|
||||
@@ -2065,24 +2070,26 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_SMP)
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK
|
||||
int __init defer_free_memblock(void *unused)
|
||||
{
|
||||
if (defer_start == 0)
|
||||
return 0;
|
||||
int i;
|
||||
|
||||
pr_debug("start = %ld, end = %ld\n", defer_start, defer_end);
|
||||
for (i = 0; i < db_count; i++) {
|
||||
pr_debug("%s: start = %ld, end = %ld\n",
|
||||
__func__, db[i].defer_start, db[i].defer_end);
|
||||
|
||||
__free_pages_memory(defer_start, defer_end);
|
||||
__free_pages_memory(db[i].defer_start, db[i].defer_end);
|
||||
|
||||
totalram_pages_add(defer_end - defer_start);
|
||||
totalram_pages_add(db[i].defer_end - db[i].defer_start);
|
||||
|
||||
pr_info("%s: size %luM free %luM [%luM - %luM] total %luM\n", __func__,
|
||||
defer_free_block_size >> 20,
|
||||
(defer_end - defer_start) >> (20 - PAGE_SHIFT),
|
||||
defer_end >> (20 - PAGE_SHIFT),
|
||||
defer_start >> (20 - PAGE_SHIFT),
|
||||
totalram_pages() >> (20 - PAGE_SHIFT));
|
||||
pr_info("%s: size %luM free %luM [%luM - %luM] total %luM\n",
|
||||
__func__, defer_free_block_size >> 20,
|
||||
(db[i].defer_end - db[i].defer_start) >> (20 - PAGE_SHIFT),
|
||||
db[i].defer_start >> (20 - PAGE_SHIFT),
|
||||
db[i].defer_end >> (20 - PAGE_SHIFT),
|
||||
totalram_pages() >> (20 - PAGE_SHIFT));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -2097,11 +2104,12 @@ static unsigned long __init __free_memory_core(phys_addr_t start,
|
||||
if (start_pfn >= end_pfn)
|
||||
return 0;
|
||||
|
||||
#if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_SMP)
|
||||
if ((end - start) > defer_free_block_size) {
|
||||
defer_start = start_pfn;
|
||||
defer_end = end_pfn;
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK
|
||||
pr_debug("%s, start = %pa, end = %pa\n", __func__, &start, &end);
|
||||
if ((end - start) > defer_free_block_size && (db_count < ARRAY_SIZE(db))) {
|
||||
db[db_count].defer_start = start_pfn;
|
||||
db[db_count].defer_end = end_pfn;
|
||||
db_count++;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -322,6 +322,7 @@ static const struct snd_soc_dai_ops rockchip_mdais_dai_ops = {
|
||||
|
||||
static const struct snd_soc_component_driver rockchip_mdais_component = {
|
||||
.name = DAIS_DRV_NAME,
|
||||
.legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_mdais_match[] = {
|
||||
|
||||
@@ -691,10 +691,13 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
mc_data->adc = devm_iio_channel_get(&pdev->dev, "adc-detect");
|
||||
|
||||
if (IS_ERR(mc_data->adc)) {
|
||||
if (PTR_ERR(mc_data->adc) != -EPROBE_DEFER) {
|
||||
mc_data->adc = NULL;
|
||||
dev_warn(&pdev->dev, "Failed to get ADC channel");
|
||||
if (PTR_ERR(mc_data->adc) == -EPROBE_DEFER) {
|
||||
dev_warn(&pdev->dev, "deferred by saradc not ready\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
mc_data->adc = NULL;
|
||||
dev_warn(&pdev->dev, "Has no ADC channel\n");
|
||||
} else {
|
||||
if (mc_data->adc->channel->type != IIO_VOLTAGE)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -163,6 +163,7 @@ static struct snd_soc_dai_driver rk_spdifrx_dai = {
|
||||
|
||||
static const struct snd_soc_component_driver rk_spdifrx_component = {
|
||||
.name = "rockchip-spdifrx",
|
||||
.legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static bool rk_spdifrx_wr_reg(struct device *dev, unsigned int reg)
|
||||
|
||||
Reference in New Issue
Block a user