linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V1 0/5] Add support for Awinic SAR sensor.
@ 2024-05-29 13:06 wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor wangshuaijie
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: wangshuaijie @ 2024-05-29 13:06 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, jeff, linux-input,
	devicetree, linux-kernel
  Cc: wangshuaijie, liweilei, kangjiajun

From: shuaijie wang <wangshuaijie@awinic.com>

Add drivers that support Awinic SAR (Specific Absorption Rate)
sensors to the Linux kernel.

The AW9610X series and AW963XX series are high-sensitivity
capacitive proximity detection sensors.

This device detects human proximity and assists electronic devices
in reducing SAR to pass SAR related certifications.

The device reduces RF power and reduces harm when detecting human proximity.
Increase power and improve signal quality when the human body is far away.

This patch implements device initialization, registration,
I/O operation handling and interrupt handling, and passed basic testing.

shuaijie wang (5):
  dt-bindings: input: Add YAML to Awinic sar sensor.
  Add universal interface for the aw_sar driver.
  Add aw9610x series related interfaces to the aw_sar driver.
  Add aw963xx series related interfaces to the aw_sar driver.
  Add support for Awinic sar sensor.

 .../bindings/input/awinic,aw_sar.yaml         |  110 +
 drivers/input/misc/Kconfig                    |    9 +
 drivers/input/misc/Makefile                   |    1 +
 drivers/input/misc/aw_sar/Makefile            |    2 +
 drivers/input/misc/aw_sar/aw9610x/aw9610x.c   |  884 +++++++
 drivers/input/misc/aw_sar/aw9610x/aw9610x.h   |  324 +++
 drivers/input/misc/aw_sar/aw963xx/aw963xx.c   |  986 ++++++++
 drivers/input/misc/aw_sar/aw963xx/aw963xx.h   |  749 ++++++
 drivers/input/misc/aw_sar/aw_sar.c            | 2039 +++++++++++++++++
 drivers/input/misc/aw_sar/aw_sar.h            |   15 +
 .../misc/aw_sar/comm/aw_sar_chip_interface.h  |   27 +
 .../misc/aw_sar/comm/aw_sar_comm_interface.c  |  656 ++++++
 .../misc/aw_sar/comm/aw_sar_comm_interface.h  |  172 ++
 drivers/input/misc/aw_sar/comm/aw_sar_type.h  |  396 ++++
 14 files changed, 6370 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
 create mode 100644 drivers/input/misc/aw_sar/Makefile
 create mode 100644 drivers/input/misc/aw_sar/aw9610x/aw9610x.c
 create mode 100644 drivers/input/misc/aw_sar/aw9610x/aw9610x.h
 create mode 100644 drivers/input/misc/aw_sar/aw963xx/aw963xx.c
 create mode 100644 drivers/input/misc/aw_sar/aw963xx/aw963xx.h
 create mode 100644 drivers/input/misc/aw_sar/aw_sar.c
 create mode 100644 drivers/input/misc/aw_sar/aw_sar.h
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_chip_interface.h
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.c
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.h
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_type.h


base-commit: e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
-- 
2.45.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor.
  2024-05-29 13:06 [PATCH V1 0/5] Add support for Awinic SAR sensor wangshuaijie
@ 2024-05-29 13:06 ` wangshuaijie
  2024-05-29 14:25   ` Rob Herring (Arm)
  2024-05-31  1:36   ` Rob Herring
  2024-05-29 13:06 ` [PATCH V1 2/5] Add universal interface for the aw_sar driver wangshuaijie
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 16+ messages in thread
From: wangshuaijie @ 2024-05-29 13:06 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, jeff, linux-input,
	devicetree, linux-kernel
  Cc: wangshuaijie, liweilei, kangjiajun

From: shuaijie wang <wangshuaijie@awinic.com>

Add the awinic,aw_sar.yaml file to adapt to the awinic sar sensor driver.

Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
---
 .../bindings/input/awinic,aw_sar.yaml         | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/awinic,aw_sar.yaml

diff --git a/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml b/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
new file mode 100644
index 000000000000..ed4ec29c9b4d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/awinic,aw_sar.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Awinic sar sensor driver family
+
+maintainers:
+  - Shuaijie Wang <wangshuaijie@awinic.com>
+
+properties:
+  compatible:
+    enum:
+      - awinic,aw_aw96103
+      - awinic,aw_aw96105
+      - awinic,aw_aw96303
+      - awinic,aw_aw96305
+      - awinic,aw_aw96308
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  sar-num:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      set the index of the sar sensor.
+
+  vcc0-supply:
+    description:
+      Optional regulator for chip, 1.7V-3.6V.
+
+  channel_use_flag:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The flag of channels used.
+      Configure according to the specific chip channel used.
+      Bit[31:0] Each bit represents a channel.
+      If the customer uses ch0 and ch2, then channel_use_flag=<0x05>
+
+  aw_sar,update_fw:
+    type: boolean
+    description:
+      Choose if you want to update the firmware.
+
+  aw_sar,monitor_esd:
+    type: boolean
+    description:
+      Choose if you want to monitor ESD.
+
+  aw_sar,pin_set_inter_pull-up:
+    type: boolean
+    description:
+      Choose if you want to set the interrupt pin to internal pull-up.
+
+  aw_sar,using_pm_ops:
+    type: boolean
+    description:
+      Choose if you want to use suspend and resume related function.
+
+  aw_sar,use_plug_cail:
+    type: boolean
+    description:
+      Choose If you want to perform calibration when plugging and unplugging the charger.
+
+  start-mode:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When connecting to aw963xx, select the location where the firmware starts.
+      set 0 if start in rom.
+      set 1 if start in ram
+
+  irq-mux:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      set csx as irq pin. config this field when connect to aw96308/aw96305BFOR
+
+required:
+  - compatible
+  - reg
+  - sar-num
+  - interrupts
+  - channel_use_flag
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        awinic_sar@12 {
+            compatible = "awinic,aw_sar";
+            reg = <0x12>;
+            sar-num = < 0 >;
+            interrupt-parent = < &tlmm >;
+            interrupts = <72 0>;
+            //vcc0-supply = <&pm660l_l4>;
+            channel_use_flag = <0xff>;
+            aw_sar,update_fw;
+            //aw_sar,monitor_esd;
+            start-mode = < 1 >;
+            irq-mux = < 2 >;
+        };
+    };
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH V1 2/5] Add universal interface for the aw_sar driver.
  2024-05-29 13:06 [PATCH V1 0/5] Add support for Awinic SAR sensor wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor wangshuaijie
@ 2024-05-29 13:06 ` wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 3/5] Add aw9610x series related interfaces to " wangshuaijie
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-05-29 13:06 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, jeff, linux-input,
	devicetree, linux-kernel
  Cc: wangshuaijie, liweilei, kangjiajun

From: shuaijie wang <wangshuaijie@awinic.com>

Add i2c read-write interfaces and interfaces for parsing bin files.

Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
---
 .../misc/aw_sar/comm/aw_sar_chip_interface.h  |  27 +
 .../misc/aw_sar/comm/aw_sar_comm_interface.c  | 656 ++++++++++++++++++
 .../misc/aw_sar/comm/aw_sar_comm_interface.h  | 172 +++++
 drivers/input/misc/aw_sar/comm/aw_sar_type.h  | 396 +++++++++++
 4 files changed, 1251 insertions(+)
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_chip_interface.h
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.c
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.h
 create mode 100644 drivers/input/misc/aw_sar/comm/aw_sar_type.h

diff --git a/drivers/input/misc/aw_sar/comm/aw_sar_chip_interface.h b/drivers/input/misc/aw_sar/comm/aw_sar_chip_interface.h
new file mode 100644
index 000000000000..d406e48e8136
--- /dev/null
+++ b/drivers/input/misc/aw_sar/comm/aw_sar_chip_interface.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _SAR_SUPPORT_CHIP_H_
+#define _SAR_SUPPORT_CHIP_H_
+#include "aw_sar_type.h"
+
+enum aw_sar_driver_list_t {
+	AW_SAR_AW9610X,
+	AW_SAR_AW963XX,
+
+	AW_SAR_DRIVER_MAX,
+};
+
+int32_t aw9610x_check_chipid(void *data);
+int32_t aw9610x_init(struct aw_sar *p_sar);
+void aw9610x_deinit(struct aw_sar *p_sar);
+
+int32_t aw963xx_check_chipid(void *data);
+int32_t aw963xx_init(struct aw_sar *p_sar);
+void aw963xx_deinit(struct aw_sar *p_sar);
+
+
+static const struct aw_sar_driver_type g_aw_sar_driver_list[] = {
+	{ AW_SAR_AW9610X, aw9610x_check_chipid, aw9610x_init, aw9610x_deinit },
+	{ AW_SAR_AW963XX, aw963xx_check_chipid, aw963xx_init, aw963xx_deinit },
+};
+
+#endif
diff --git a/drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.c b/drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.c
new file mode 100644
index 000000000000..1d62ebb60acc
--- /dev/null
+++ b/drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.c
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "aw_sar_comm_interface.h"
+
+#define AW_I2C_RW_RETRY_TIME_MIN		(2000)
+#define AW_I2C_RW_RETRY_TIME_MAX		(3000)
+#define AW_RETRIES				(5)
+
+static int32_t awinic_i2c_write(struct i2c_client *i2c, uint8_t *tr_data, uint16_t len)
+{
+	struct i2c_msg msg;
+
+	msg.addr = i2c->addr;
+	msg.flags = 0;
+	msg.len = len;
+	msg.buf = tr_data;
+
+	return i2c_transfer(i2c->adapter, &msg, 1);
+}
+
+static int32_t awinic_i2c_read(struct i2c_client *i2c, uint8_t *addr,
+				uint8_t addr_len, uint8_t *data, uint16_t data_len)
+{
+	struct i2c_msg msg[2];
+
+	msg[0].addr = i2c->addr;
+	msg[0].flags = 0;
+	msg[0].len = addr_len;
+	msg[0].buf = addr;
+
+	msg[1].addr = i2c->addr;
+	msg[1].flags = 1;
+	msg[1].len = data_len;
+	msg[1].buf = data;
+
+	return i2c_transfer(i2c->adapter, msg, 2);
+}
+
+/**
+ * @brief Read register interface
+ *
+ * @param i2c: i2c client.
+ * @param reg_addr16: 16 bit register address.
+ * @param *reg_data32: 32 bit register data.
+ * @return 0 if init succeeded.
+ */
+int32_t aw_sar_i2c_read(struct i2c_client *i2c, uint16_t reg_addr16,  uint32_t *reg_data32)
+{
+	uint8_t r_buf[6] = { 0 };
+	int8_t cnt = 5;
+	int32_t ret;
+
+	if (!i2c)
+		return -EINVAL;
+
+	r_buf[0] = (unsigned char)(reg_addr16 >> OFFSET_BIT_8);
+	r_buf[1] = (unsigned char)(reg_addr16);
+
+	do {
+		ret = awinic_i2c_read(i2c, r_buf, 2, &r_buf[2], 4);
+		if (ret < 0)
+			dev_err(&i2c->dev, "i2c read error reg: 0x%04x, ret= %d cnt= %d",
+					reg_addr16, ret, cnt);
+		else
+			break;
+		usleep_range(2000, 3000);
+	} while (cnt--);
+
+	if (cnt < 0) {
+		dev_err(&i2c->dev, "i2c read error!");
+		return ret;
+	}
+
+	*reg_data32 = ((uint32_t)r_buf[5] << OFFSET_BIT_0) | ((uint32_t)r_buf[4] << OFFSET_BIT_8) |
+		      ((uint32_t)r_buf[3] << OFFSET_BIT_16) | ((uint32_t)r_buf[2] << OFFSET_BIT_24);
+
+	return 0;
+}
+
+/**
+ * @brief write register interface
+ *
+ * @param i2c: i2c client.
+ * @param reg_addr16: 16 bit register address.
+ * @param reg_data32: 32 bit register data.
+ * @return 0 if init succeeded.
+ */
+int32_t aw_sar_i2c_write(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t reg_data32)
+{
+	uint8_t w_buf[6] = { 0 };
+	int8_t cnt = 5;
+	int32_t ret;
+
+	if (!i2c)
+		return -EINVAL;
+
+	/*reg_addr*/
+	w_buf[0] = (uint8_t)(reg_addr16 >> OFFSET_BIT_8);
+	w_buf[1] = (uint8_t)(reg_addr16);
+	/*data*/
+	w_buf[2] = (uint8_t)(reg_data32 >> OFFSET_BIT_24);
+	w_buf[3] = (uint8_t)(reg_data32 >> OFFSET_BIT_16);
+	w_buf[4] = (uint8_t)(reg_data32 >> OFFSET_BIT_8);
+	w_buf[5] = (uint8_t)(reg_data32);
+
+	do {
+		ret = awinic_i2c_write(i2c, w_buf, ARRAY_SIZE(w_buf));
+		if (ret < 0) {
+			dev_err(&i2c->dev,
+					"i2c write error reg: 0x%04x data: 0x%08x, ret= %d cnt= %d",
+					reg_addr16, reg_data32, ret, cnt);
+		} else {
+			break;
+		}
+	} while (cnt--);
+
+	if (cnt < 0) {
+		dev_err(&i2c->dev, "i2c write error!");
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * @brief Write the corresponding bit of the register
+ *
+ * @param i2c:i2c client.
+ * @param reg_addr16: 16 bit register address.
+ * @param mask: Write the corresponding bit as 0
+ * @param val: Write corresponding data to the register
+ * @return 0 if init succeeded.
+ */
+int32_t
+aw_sar_i2c_write_bits(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t mask, uint32_t val)
+{
+	uint32_t reg_val;
+
+	aw_sar_i2c_read(i2c, reg_addr16, &reg_val);
+	reg_val &= mask;
+	reg_val |= (val & (~mask));
+	aw_sar_i2c_write(i2c, reg_addr16, reg_val);
+
+	return 0;
+}
+
+/**
+ * @brief Continuously write data to the chip
+ *
+ * @param i2c:i2c client.
+ * @param *tr_data: Data written
+ * @param len: Length of data written
+ * @return 0 if init succeeded.
+ */
+int32_t aw_sar_i2c_write_seq(struct i2c_client *i2c, uint8_t *tr_data, uint16_t len)
+{
+	int8_t cnt = AW_RETRIES;
+	int32_t ret;
+
+	do {
+		ret = awinic_i2c_write(i2c, tr_data, len);
+		if (ret < 0)
+			dev_err(&i2c->dev, "awinic i2c write seq error %d", ret);
+		else
+			break;
+		usleep_range(AW_I2C_RW_RETRY_TIME_MIN, AW_I2C_RW_RETRY_TIME_MAX);
+	} while (cnt--);
+
+	if (cnt < 0) {
+		dev_err(&i2c->dev, "awinic i2c write error!");
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * @brief Continuously Read data from chip
+ *
+ * @param i2c:i2c client.
+ * @param *addr: Read address
+ * @param addr_len: Length of read address (byte)
+ * @param *data: Data written
+ * @param data_len: Length of data written
+ * @return 0 if init succeeded.
+ */
+int32_t aw_sar_i2c_read_seq(struct i2c_client *i2c, uint8_t *addr,
+				uint8_t addr_len, uint8_t *data, uint16_t data_len)
+{
+	int8_t cnt = AW_RETRIES;
+	int32_t ret;
+
+	do {
+		ret = awinic_i2c_read(i2c, addr, addr_len, data, data_len);
+		if (ret < 0)
+			dev_err(&i2c->dev, "awinic sar i2c write error %d", ret);
+		else
+			break;
+		usleep_range(AW_I2C_RW_RETRY_TIME_MIN, AW_I2C_RW_RETRY_TIME_MAX);
+	} while (cnt--);
+
+	if (cnt < 0) {
+		dev_err(&i2c->dev, "awinic sar i2c read error!");
+		return ret;
+	}
+
+	return 0;
+}
+
+/******************************Parse bin file code start****************************************/
+
+#define AWINIC_CODE_VERSION "V0.0.7-V1.0.4"  /* "code version"-"excel version" */
+
+enum bin_header_version_enum {
+	HEADER_VERSION_1_0_0 = 0x01000000,
+};
+
+enum data_type_enum {
+	DATA_TYPE_REGISTER = 0x00000000,
+	DATA_TYPE_DSP_REG = 0x00000010,
+	DATA_TYPE_DSP_CFG = 0x00000011,
+	DATA_TYPE_SOC_REG = 0x00000020,
+	DATA_TYPE_SOC_APP = 0x00000021,
+	DATA_TYPE_MULTI_BINS = 0x00002000,
+};
+
+#define BigLittleSwap16(A)	((((unsigned short int)(A) & 0xff00) >> 8) | \
+				(((unsigned short int)(A) & 0x00ff) << 8))
+
+#define BigLittleSwap32(A)	((((unsigned long)(A) & 0xff000000) >> 24) | \
+				(((unsigned long)(A) & 0x00ff0000) >> 8) | \
+				(((unsigned long)(A) & 0x0000ff00) << 8) | \
+				(((unsigned long)(A) & 0x000000ff) << 24))
+
+static int aw_parse_bin_header_1_0_0(struct aw_bin *bin);
+
+/**
+ *
+ * Interface function
+ *
+ * return value:
+ *       value = 0 :success;
+ *       value = -1 :check bin header version
+ *       value = -2 :check bin data type
+ *       value = -3 :check sum or check bin data len error
+ *       value = -4 :check data version
+ *       value = -5 :check register num
+ *       value = -6 :check dsp reg num
+ *       value = -7 :check soc app num
+ *       value = -8 :bin is NULL point
+ *
+ **/
+
+/********************************************************
+ *
+ * check sum data
+ *
+ ********************************************************/
+static enum aw_bin_err_val aw_check_sum(struct aw_bin *bin, int bin_num)
+{
+	unsigned char *p_check_sum;
+	unsigned int sum_data = 0;
+	unsigned int check_sum;
+	unsigned int i;
+
+	p_check_sum = &(bin->info.data[(bin->header_info[bin_num].valid_data_addr -
+			bin->header_info[bin_num].header_len)]);
+	check_sum = AW_SAR_GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
+				*(p_check_sum + 1), *(p_check_sum));
+
+	for (i = 4; i < bin->header_info[bin_num].bin_data_len +
+			bin->header_info[bin_num].header_len; i++)
+		sum_data += *(p_check_sum + i);
+
+	if (sum_data != check_sum) {
+		p_check_sum = NULL;
+		return AW_BIN_ERROR_SUM_OR_DATA_LEN;
+	}
+	p_check_sum = NULL;
+
+	return AW_BIN_ERROR_NONE;
+}
+
+static enum aw_bin_err_val aw_check_register_num_v1(struct aw_bin *bin, int bin_num)
+{
+	unsigned int check_register_num;
+	unsigned int parse_register_num;
+	char *p_check_sum;
+
+	p_check_sum =
+	    &(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
+	parse_register_num = AW_SAR_GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
+					*(p_check_sum + 1), *(p_check_sum));
+	check_register_num = (bin->header_info[bin_num].bin_data_len - 4) /
+				(bin->header_info[bin_num].reg_byte_len +
+				bin->header_info[bin_num].data_byte_len);
+	if (parse_register_num != check_register_num) {
+		p_check_sum = NULL;
+		return AW_BIN_ERROR_REGISTER_NUM;
+	}
+	bin->header_info[bin_num].reg_num = parse_register_num;
+	bin->header_info[bin_num].valid_data_len = bin->header_info[bin_num].bin_data_len - 4;
+	p_check_sum = NULL;
+	bin->header_info[bin_num].valid_data_addr =
+	    bin->header_info[bin_num].valid_data_addr + 4;
+
+	return AW_BIN_ERROR_NONE;
+}
+
+static enum aw_bin_err_val aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num)
+{
+	unsigned int check_dsp_reg_num;
+	unsigned int parse_dsp_reg_num;
+	char *p_check_sum;
+
+	p_check_sum =
+	    &(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
+	parse_dsp_reg_num = AW_SAR_GET_32_DATA(*(p_check_sum + 7),
+					*(p_check_sum + 6),
+					*(p_check_sum + 5),
+					*(p_check_sum + 4));
+	bin->header_info[bin_num].reg_data_byte_len =
+	    AW_SAR_GET_32_DATA(*(p_check_sum + 11), *(p_check_sum + 10),
+			*(p_check_sum + 9), *(p_check_sum + 8));
+	check_dsp_reg_num = (bin->header_info[bin_num].bin_data_len -
+				12) / bin->header_info[bin_num].reg_data_byte_len;
+	if (parse_dsp_reg_num != check_dsp_reg_num) {
+		p_check_sum = NULL;
+		return AW_BIN_ERROR_DSP_REG_NUM;
+	}
+	bin->header_info[bin_num].download_addr =
+	    AW_SAR_GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
+			*(p_check_sum + 1), *(p_check_sum));
+	bin->header_info[bin_num].reg_num = parse_dsp_reg_num;
+	bin->header_info[bin_num].valid_data_len = bin->header_info[bin_num].bin_data_len - 12;
+	p_check_sum = NULL;
+	bin->header_info[bin_num].valid_data_addr =
+	    bin->header_info[bin_num].valid_data_addr + 12;
+
+	return AW_BIN_ERROR_NONE;
+}
+
+static enum aw_bin_err_val aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num)
+{
+	unsigned int check_soc_app_num;
+	unsigned int parse_soc_app_num;
+	char *p_check_sum;
+
+	p_check_sum = &(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
+	bin->header_info[bin_num].app_version = AW_SAR_GET_32_DATA(*(p_check_sum + 3),
+							    *(p_check_sum + 2),
+							    *(p_check_sum + 1),
+							    *(p_check_sum));
+	parse_soc_app_num = AW_SAR_GET_32_DATA(*(p_check_sum + 11), *(p_check_sum + 10),
+					*(p_check_sum + 9), *(p_check_sum + 8));
+	check_soc_app_num = bin->header_info[bin_num].bin_data_len - 12;
+	if (parse_soc_app_num != check_soc_app_num) {
+		p_check_sum = NULL;
+		return AW_BIN_ERROR_SOC_APP_NUM;
+	}
+	bin->header_info[bin_num].reg_num = parse_soc_app_num;
+	bin->header_info[bin_num].download_addr =
+	    AW_SAR_GET_32_DATA(*(p_check_sum + 7), *(p_check_sum + 6),
+			*(p_check_sum + 5), *(p_check_sum + 4));
+	bin->header_info[bin_num].valid_data_len =
+	    bin->header_info[bin_num].bin_data_len - 12;
+	p_check_sum = NULL;
+	bin->header_info[bin_num].valid_data_addr =
+	    bin->header_info[bin_num].valid_data_addr + 12;
+
+	return AW_BIN_ERROR_NONE;
+}
+
+/************************
+ *
+ ***bin header 1_0_0
+ ***
+ ************************/
+static void aw_get_single_bin_header_1_0_0(struct aw_bin *bin)
+{
+	int i;
+
+	bin->header_info[bin->all_bin_parse_num].header_len = 60;
+	bin->header_info[bin->all_bin_parse_num].check_sum =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 3), *(bin->p_addr + 2),
+			*(bin->p_addr + 1), *(bin->p_addr));
+	bin->header_info[bin->all_bin_parse_num].header_ver =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
+			*(bin->p_addr + 5), *(bin->p_addr + 4));
+	bin->header_info[bin->all_bin_parse_num].bin_data_type =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 11), *(bin->p_addr + 10),
+			*(bin->p_addr + 9), *(bin->p_addr + 8));
+	bin->header_info[bin->all_bin_parse_num].bin_data_ver =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 15), *(bin->p_addr + 14),
+			*(bin->p_addr + 13), *(bin->p_addr + 12));
+	bin->header_info[bin->all_bin_parse_num].bin_data_len =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 19), *(bin->p_addr + 18),
+			*(bin->p_addr + 17), *(bin->p_addr + 16));
+	bin->header_info[bin->all_bin_parse_num].ui_ver =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 23), *(bin->p_addr + 22),
+			*(bin->p_addr + 21), *(bin->p_addr + 20));
+	bin->header_info[bin->all_bin_parse_num].reg_byte_len =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 35), *(bin->p_addr + 34),
+			*(bin->p_addr + 33), *(bin->p_addr + 32));
+	bin->header_info[bin->all_bin_parse_num].data_byte_len =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 39), *(bin->p_addr + 38),
+			*(bin->p_addr + 37), *(bin->p_addr + 36));
+	bin->header_info[bin->all_bin_parse_num].device_addr =
+	    AW_SAR_GET_32_DATA(*(bin->p_addr + 43), *(bin->p_addr + 42),
+			*(bin->p_addr + 41), *(bin->p_addr + 40));
+	for (i = 0; i < 8; i++) {
+		bin->header_info[bin->all_bin_parse_num].chip_type[i] =
+		    *(bin->p_addr + 24 + i);
+	}
+//	bin->header_info[bin->all_bin_parse_num].chip_type[i] = '\0';
+//	DBG("enter chip_type is %s\n", bin->header_info[bin->all_bin_parse_num].chip_type);
+
+	bin->header_info[bin->all_bin_parse_num].reg_num = 0x00000000;
+	bin->header_info[bin->all_bin_parse_num].reg_data_byte_len = 0x00000000;
+	bin->header_info[bin->all_bin_parse_num].download_addr = 0x00000000;
+	bin->header_info[bin->all_bin_parse_num].app_version = 0x00000000;
+	bin->header_info[bin->all_bin_parse_num].valid_data_len = 0x00000000;
+	bin->all_bin_parse_num += 1;
+}
+
+static enum aw_bin_err_val aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num,
+		int bin_serial_num, struct aw_bin *bin)
+{
+	unsigned int bin_start_addr;
+	unsigned int valid_data_len;
+	enum aw_bin_err_val ret;
+
+	if (!bin_serial_num) {
+		bin_start_addr = AW_SAR_GET_32_DATA(*(bin->p_addr + 67),
+					     *(bin->p_addr + 66),
+					     *(bin->p_addr + 65),
+					     *(bin->p_addr + 64));
+		bin->p_addr += (60 + bin_start_addr);
+		bin->header_info[bin->all_bin_parse_num].valid_data_addr =
+		    bin->header_info[bin->all_bin_parse_num -
+				     1].valid_data_addr + 4 + 8 * bin_num + 60;
+	} else {
+		valid_data_len =
+		    bin->header_info[bin->all_bin_parse_num - 1].bin_data_len;
+		bin->p_addr += (60 + valid_data_len);
+		bin->header_info[bin->all_bin_parse_num].valid_data_addr =
+		    bin->header_info[bin->all_bin_parse_num -
+				     1].valid_data_addr +
+		    bin->header_info[bin->all_bin_parse_num - 1].bin_data_len +
+		    60;
+	}
+
+	ret = aw_parse_bin_header_1_0_0(bin);
+	return ret;
+}
+
+/* Get the number of bins in multi bins, and set a for loop, loop processing each bin data */
+static enum aw_bin_err_val aw_get_multi_bin_header_1_0_0(struct aw_bin *bin)
+{
+	unsigned int bin_num;
+	enum aw_bin_err_val ret;
+	int i;
+
+	bin_num = AW_SAR_GET_32_DATA(*(bin->p_addr + 63),
+			      *(bin->p_addr + 62),
+			      *(bin->p_addr + 61), *(bin->p_addr + 60));
+	if (bin->multi_bin_parse_num == 1)
+		bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
+	aw_get_single_bin_header_1_0_0(bin);
+
+	for (i = 0; i < bin_num; i++) {
+		ret = aw_parse_each_of_multi_bins_1_0_0(bin_num, i, bin);
+		if (ret < 0)
+			return ret;
+	}
+	return AW_BIN_ERROR_NONE;
+}
+
+/********************************************************
+ *
+ * If the bin framework header version is 1.0.0,
+ * determine the data type of bin, and then perform different processing
+ * according to the data type
+ * If it is a single bin data type, write the data directly into the structure array
+ * If it is a multi-bin data type, first obtain the number of bins,
+ * and then recursively call the bin frame header processing function
+ * according to the bin number to process the frame header information of each bin separately
+ *
+ ********************************************************/
+static enum aw_bin_err_val aw_parse_bin_header_1_0_0(struct aw_bin *bin)
+{
+	unsigned int bin_data_type;
+	enum aw_bin_err_val ret;
+
+	bin_data_type = AW_SAR_GET_32_DATA(*(bin->p_addr + 11),
+				    *(bin->p_addr + 10),
+				    *(bin->p_addr + 9), *(bin->p_addr + 8));
+	switch (bin_data_type) {
+	case DATA_TYPE_REGISTER:
+	case DATA_TYPE_DSP_REG:
+	case DATA_TYPE_SOC_APP:
+		// Divided into two processing methods,
+		// one is single bin processing,
+		// and the other is single bin processing in multi bin
+		bin->single_bin_parse_num += 1;
+		if (!bin->multi_bin_parse_num)
+			bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
+		aw_get_single_bin_header_1_0_0(bin);
+		break;
+	case DATA_TYPE_MULTI_BINS:
+		/* Get the number of times to enter multi bins */
+		bin->multi_bin_parse_num += 1;
+		ret = aw_get_multi_bin_header_1_0_0(bin);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		return AW_BIN_ERROR_DATA_TYPE;
+	}
+	return AW_BIN_ERROR_NONE;
+}
+
+/* get the bin's header version */
+static enum aw_bin_err_val aw_check_bin_header_version(struct aw_bin *bin)
+{
+	unsigned int header_version;
+	enum aw_bin_err_val ret;
+
+	header_version = AW_SAR_GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
+				     *(bin->p_addr + 5), *(bin->p_addr + 4));
+
+
+	// Write data to the corresponding structure array
+	// according to different formats of the bin frame header version
+	switch (header_version) {
+	case HEADER_VERSION_1_0_0:
+		ret = aw_parse_bin_header_1_0_0(bin);
+		return ret;
+	default:
+		return AW_BIN_ERROR_HEADER_VERSION;
+	}
+}
+
+/**
+ * @brief Parse bin file
+ *
+ * @param bin: Store the contents of the parsed bin file
+ * @return 0 if init succeeded, other if error
+ */
+enum aw_bin_err_val aw_sar_parsing_bin_file(struct aw_bin *bin)
+{
+	enum aw_bin_err_val ret;
+	int i;
+
+	if (!bin)
+		return AW_BIN_ERROR_NULL_POINT;
+	bin->p_addr = bin->info.data;
+	bin->all_bin_parse_num = 0;
+	bin->multi_bin_parse_num = 0;
+	bin->single_bin_parse_num = 0;
+
+	/* filling bins header info */
+	ret = aw_check_bin_header_version(bin);
+	if (ret < 0)
+		return ret;
+	bin->p_addr = NULL;
+
+	/* check bin header info */
+	for (i = 0; i < bin->all_bin_parse_num; i++) {
+		/* check sum */
+		ret = aw_check_sum(bin, i);
+		if (ret < 0)
+			return ret;
+
+		/* check register num */
+		if (bin->header_info[i].bin_data_type == DATA_TYPE_REGISTER) {
+			ret = aw_check_register_num_v1(bin, i);
+			if (ret < 0)
+				return ret;
+			/* check dsp reg num */
+		} else if (bin->header_info[i].bin_data_type == DATA_TYPE_DSP_REG) {
+			ret = aw_check_dsp_reg_num_v1(bin, i);
+			if (ret < 0)
+				return ret;
+			/* check soc app num */
+		} else if (bin->header_info[i].bin_data_type == DATA_TYPE_SOC_APP) {
+			ret = aw_check_soc_app_num_v1(bin, i);
+			if (ret < 0)
+				return ret;
+		} else {
+			bin->header_info[i].valid_data_len = bin->header_info[i].bin_data_len;
+		}
+	}
+
+	return AW_BIN_ERROR_NONE;
+}
+/*********************************Parse bin file code end************************************/
+
+/**
+ * @brief Calculate the second power
+ *
+ * @param cnt: ifrequency
+ * @return the second power
+ */
+uint32_t aw_sar_pow2(uint32_t cnt)
+{
+	uint32_t sum = 1;
+	uint32_t i;
+
+	if (cnt == 0) {
+		sum = 1;
+	} else {
+		for (i = 0; i < cnt; i++)
+			sum *= 2;
+	}
+
+	return sum;
+}
+
+/**
+ * @brief Calculate the second power
+ *
+ * @param *aw_bin: Information after parsing bin file
+ * @param *i2c: i2c client.
+ * @return 0 if init succeeded.
+ */
+int32_t aw_sar_load_reg(struct aw_bin *aw_bin, struct i2c_client *i2c)
+{
+	uint32_t start_addr = aw_bin->header_info[0].valid_data_addr;
+	uint16_t reg_addr;
+	uint32_t reg_data;
+	int32_t ret;
+	uint32_t i;
+
+	for (i = 0; i < aw_bin->header_info[0].valid_data_len; i += 6, start_addr += 6) {
+		reg_addr = (aw_bin->info.data[start_addr]) |
+				aw_bin->info.data[start_addr + 1] << OFFSET_BIT_8;
+		reg_data = aw_bin->info.data[start_addr + 2] |
+			(aw_bin->info.data[start_addr + 3] << OFFSET_BIT_8) |
+			(aw_bin->info.data[start_addr + 4] << OFFSET_BIT_16) |
+			(aw_bin->info.data[start_addr + 5] << OFFSET_BIT_24);
+
+		ret = aw_sar_i2c_write(i2c, reg_addr, reg_data);
+		if (ret < 0) {
+			dev_err(&i2c->dev, "i2c write err");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+void aw_sar_delay_ms(uint32_t ms)
+{
+	mdelay(ms);
+}
+
diff --git a/drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.h b/drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.h
new file mode 100644
index 000000000000..6f35193f2aee
--- /dev/null
+++ b/drivers/input/misc/aw_sar/comm/aw_sar_comm_interface.h
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _AW_SAR_PLAT_HW_INTERFACE_H_
+#define _AW_SAR_PLAT_HW_INTERFACE_H_
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/of_gpio.h>
+#include <linux/power_supply.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+enum aw_sar_chip_list_t {
+	AW_SAR_NONE_CHECK_CHIP,
+
+	SAR_AW9610X = 1 << 1,
+	SAR_AW9610XA = 1 << 2,
+
+	SAR_AW96303 = 1 << 6,
+	SAR_AW96305 = 1 << 7,
+	SAR_AW96308 = 1 << 8,
+	SAR_AW96310 = 1 << 9,
+	SAR_AW96312 = 1 << 10,
+};
+
+enum AW_SAR_UPDATE_FW_MODE {
+	PROT_UPDATE_FW,
+	REG_UPDATE_FW,
+};
+
+#ifndef AW_TRUE
+#define AW_TRUE					(1)
+#endif
+
+#ifndef AW_FALSE
+#define AW_FALSE				(0)
+#endif
+
+#define AW_ERR_IRQ_INIT_OVER			(0xAA)
+
+enum aw_sar_rst_val {
+	AW_OK,
+	AW_BIN_PARA_INVALID,
+	AW_PROT_UPDATE_ERR,
+	AW_REG_LOAD_ERR,
+};
+
+#ifndef OFFSET_BIT_0
+#define OFFSET_BIT_0				(0)
+#endif
+
+#ifndef OFFSET_BIT_8
+#define OFFSET_BIT_8				(8)
+#endif
+
+#ifndef OFFSET_BIT_16
+#define OFFSET_BIT_16				(16)
+#endif
+
+#ifndef OFFSET_BIT_24
+#define OFFSET_BIT_24				(24)
+#endif
+
+#define AW_SAR_GET_32_DATA(w, x, y, z)	((unsigned int)(((w) << 24) | ((x) << 16) | ((y) << 8) | (z)))
+
+enum AW_SAR_HOST_IRQ_STAT {
+	IRQ_ENABLE,
+	IRQ_DISABLE,
+};
+
+#define AW_SAR_BIN_NUM_MAX   100
+
+enum aw_bin_err_val {
+	AW_BIN_ERROR_NONE = 0,
+	AW_BIN_ERROR_HEADER_VERSION = -1,
+	AW_BIN_ERROR_DATA_TYPE = -2,
+	AW_BIN_ERROR_SUM_OR_DATA_LEN = -3,
+	AW_BIN_ERROR_DATA_VERSION = -4,
+	AW_BIN_ERROR_REGISTER_NUM = -5,
+	AW_BIN_ERROR_DSP_REG_NUM = -6,
+	AW_BIN_ERROR_SOC_APP_NUM = -7,
+	AW_BIN_ERROR_NULL_POINT = -8,
+};
+
+/**
+ * struct bin_header_info -
+ * @header_len: Frame header length
+ * @check_sum: Frame header information-Checksum
+ * @header_ver: Frame header information-Frame header version
+ * @bin_data_type: Frame header information-Data type
+ * @bin_data_ver: Frame header information-Data version
+ * @bin_data_len: Frame header information-Data length
+ * @ui_ver: Frame header information-ui version
+ * @chip_type: Frame header information-chip type
+ * @reg_byte_len: Frame header information-reg byte len
+ * @data_byte_len: Frame header information-data byte len
+ * @device_addr: Frame header information-device addr
+ * @valid_data_len: Length of valid data obtained after parsing
+ * @valid_data_addr: The offset address of the valid data obtained
+ *    after parsing relative to info
+ * @reg_num: The number of registers obtained after parsing
+ * @reg_data_byte_len: The byte length of the register obtained after parsing
+ * @download_addr: The starting address or download address obtained after parsing
+ * @app_version: The software version number obtained after parsing
+ */
+struct bin_header_info {
+	unsigned int header_len;
+	unsigned int check_sum;
+	unsigned int header_ver;
+	unsigned int bin_data_type;
+	unsigned int bin_data_ver;
+	unsigned int bin_data_len;
+	unsigned int ui_ver;
+	unsigned char chip_type[8];
+	unsigned int reg_byte_len;
+	unsigned int data_byte_len;
+	unsigned int device_addr;
+	unsigned int valid_data_len;
+	unsigned int valid_data_addr;
+	unsigned int reg_num;
+	unsigned int reg_data_byte_len;
+	unsigned int download_addr;
+	unsigned int app_version;
+};
+
+/**
+ * struct bin_container -
+ * @len: The size of the bin file obtained from the firmware
+ * @data: Store the bin file obtained from the firmware
+ */
+struct bin_container {
+	unsigned int len;
+	unsigned char data[];
+};
+
+/**
+ * struct aw_bin -
+ * @p_addr: Offset pointer (backward offset pointer to obtain frame header information and
+ *    important information)
+ * @all_bin_parse_num: The number of all bin files
+ * @multi_bin_parse_num: The number of single bin files
+ * @single_bin_parse_num: The number of multiple bin files
+ * @header_info: Frame header information and
+ *    other important data obtained after parsing
+ * @info: Obtained bin file data that needs to be parsed
+ */
+struct aw_bin {
+	char *p_addr;
+	unsigned int all_bin_parse_num;
+	unsigned int multi_bin_parse_num;
+	unsigned int single_bin_parse_num;
+	struct bin_header_info header_info[AW_SAR_BIN_NUM_MAX];
+	struct bin_container info;
+};
+
+//I2C communication API
+extern int32_t aw_sar_i2c_read(struct i2c_client *i2c, uint16_t reg_addr16,  uint32_t *reg_data32);
+extern int32_t aw_sar_i2c_write(struct i2c_client *i2c, uint16_t reg_addr16, uint32_t reg_data32);
+extern int32_t aw_sar_i2c_write_bits(struct i2c_client *i2c, uint16_t reg_addr16,
+		uint32_t mask, uint32_t val);
+extern int32_t aw_sar_i2c_write_seq(struct i2c_client *i2c, uint8_t *tr_data, uint16_t len);
+extern int32_t aw_sar_i2c_read_seq(struct i2c_client *i2c, uint8_t *addr,
+		uint8_t addr_len, uint8_t *data, uint16_t data_len);
+extern void aw_sar_delay_ms(uint32_t ms);
+
+extern enum aw_bin_err_val aw_sar_parsing_bin_file(struct aw_bin *bin);
+extern uint32_t aw_sar_pow2(uint32_t cnt);
+extern int32_t aw_sar_load_reg(struct aw_bin *aw_bin, struct i2c_client *i2c);
+
+#endif
diff --git a/drivers/input/misc/aw_sar/comm/aw_sar_type.h b/drivers/input/misc/aw_sar/comm/aw_sar_type.h
new file mode 100644
index 000000000000..8f217f8e21dd
--- /dev/null
+++ b/drivers/input/misc/aw_sar/comm/aw_sar_type.h
@@ -0,0 +1,396 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _SAR_TYPE_H_
+#define _SAR_TYPE_H_
+
+#include "aw_sar_comm_interface.h"
+
+typedef int32_t (*aw_sar_chip_other_operation_t)(void *data);
+typedef void (*aw_sar_chip_other_opera_free_t)(void *data);
+
+enum aw_i2c_flags {
+	AW_SAR_I2C_WR,
+	AW_SAR_I2C_RD,
+	AW_SAR_PACKAGE_RD,
+};
+
+enum sar_health_check {
+	AW_SAR_HEALTHY = 0,
+	AW_SAR_UNHEALTHY = 1,
+};
+typedef int32_t (*aw_sar_bin_opera_t)(struct aw_bin *aw_bin, void *load_bin_para);
+typedef int32_t (*aw_sar_bin_load_fail_opera_t)(struct aw_bin *aw_bin, void *load_bin_para);
+
+struct aw_sar_get_chip_info_t {
+	void (*p_get_chip_info_node_fn)(void *data, char *buf, ssize_t *p_len);
+};
+
+struct aw_sar_load_bin_t {
+	const uint8_t *bin_name;
+	aw_sar_bin_opera_t bin_opera_func;
+	aw_sar_bin_load_fail_opera_t bin_load_fail_opera;
+
+	void (*p_get_prot_update_fw_node_fn)(void *data, char *buf, ssize_t *p_len);
+
+	/*Perform different operations to update parameters*/
+	int32_t (*p_update_fn)(void *data);
+};
+
+struct aw_sar_reg_data {
+	unsigned char rw;
+	unsigned short reg;
+};
+
+struct aw_sar_awrw_t {
+	ssize_t (*p_set_awrw_node_fn)(void *data, const char *buf, size_t count);
+	ssize_t (*p_get_awrw_node_fn)(void *data, char *buf);
+};
+
+struct aw_sar_reg_list_t {
+	uint8_t reg_none_access;
+	uint8_t reg_rd_access;
+	uint8_t reg_wd_access;
+	const struct aw_sar_reg_data *reg_perm;
+	uint32_t reg_num;
+};
+
+typedef void (*aw_sar_update_work_t)(struct work_struct *work);
+struct aw_sar_update_static_t {
+	aw_sar_update_work_t update_work_func;
+	uint32_t delay_ms;
+};
+
+typedef irqreturn_t (*aw_sar_irq_t)(int irq, void *data);
+typedef uint32_t (*sar_rc_irqscr_t)(void *i2c);
+/*
+ * If the return value is 1, there is an initialization completion interrupt;
+ * if the return value is 0, there is no
+ */
+typedef uint32_t (*aw_sar_is_init_over_irq)(uint32_t irq_status);
+typedef void (*aw_sar_irq_spec_handler_t)(uint32_t irq_status, void *data);
+
+struct aw_sar_check_chipid_t {
+	/*Read chipid and check chipid, Must be implemented externally*/
+	int32_t (*p_check_chipid_fn)(void *data);
+};
+
+struct aw_sar_irq_init_t {
+	unsigned long flags;
+	unsigned long irq_flags;
+	irq_handler_t handler;
+	irq_handler_t thread_fn;
+	/*Interrupt processing parameters*/
+	sar_rc_irqscr_t rc_irq_fn;
+	//aw_sar_is_init_over_irq is_init_over_irq_fn;
+	aw_sar_irq_spec_handler_t irq_spec_handler_fn;
+
+	/*Use a different initialization interrupt to initialize the operation*/
+	int32_t (*p_irq_init_fn)(void *data);
+	/*Release interrupt resource*/
+//	void const (*p_irq_deinit_fn)(void *data);
+	int (*p_irq_deinit_fn)(void *data);
+};
+
+struct aw_sar_pm_t {
+	uint32_t suspend_set_mode;
+	uint32_t resume_set_mode;
+	uint32_t shutdown_set_mode;
+	//system api
+	int32_t (*p_suspend_fn)(void *data);
+	int32_t (*p_resume_fn)(void *data);
+	int32_t (*p_shutdown_fn)(void *data);
+};
+
+struct aw_sar_chip_mode_t {
+	uint32_t init_mode;
+	uint32_t active;
+	uint32_t pre_init_mode;
+};
+
+struct aw_sar_regulator_config_t {
+	//Note that "_sar_num" after VCC name is defined by SAR C auto add
+	const uint8_t *vcc_name;
+	int32_t min_uV;
+	int32_t max_uV;
+};
+
+struct aw_channels_info {
+	uint16_t used;
+	uint32_t last_channel_info;
+	struct input_dev *input;
+	uint8_t name[20];
+};
+
+struct aw_sar_dts_info {
+	uint32_t sar_num;
+	int32_t irq_gpio;
+	uint32_t channel_use_flag;
+	bool use_regulator_flag;
+	bool use_inter_pull_up;
+	bool use_pm;
+	bool update_fw_flag;
+	bool use_plug_cail_flag;
+	bool monitor_esd_flag;
+};
+
+struct aw_sar_irq_init_comm_t {
+	int32_t to_irq;
+	uint8_t host_irq_stat;
+	void *data;
+	uint8_t label[30];
+	uint8_t dev_id[30];
+};
+
+struct aw_sar_load_bin_comm_t {
+	uint8_t bin_name[30];
+	uint32_t bin_data_ver;
+	aw_sar_bin_opera_t bin_opera_func;
+	aw_sar_bin_load_fail_opera_t bin_load_fail_opera_func;
+};
+
+struct aw_awrw_info {
+	uint8_t rw_flag;
+	uint8_t addr_len;
+	uint8_t data_len;
+	uint8_t reg_num;
+	uint32_t i2c_tranfar_data_len;
+	uint8_t *p_i2c_tranfar_data;
+};
+
+/****************mode set start******************/
+typedef void (*sar_enable_clock_t)(void *i2c);
+typedef void (*sar_operation_irq_t)(int to_irq);
+typedef void (*sar_mode_update_t)(void *i2c);
+
+struct aw_sar_mode_switch_ops {
+	sar_enable_clock_t enable_clock;
+	sar_rc_irqscr_t rc_irqscr;
+	sar_mode_update_t mode_update;
+};
+
+struct aw_sar_chip_mode {
+	uint8_t curr_mode;
+	uint8_t last_mode;
+};
+
+struct aw_sar_mode_set_t {
+	uint8_t chip_id;
+	struct aw_sar_chip_mode chip_mode;
+	struct aw_sar_mode_switch_ops mode_switch_ops;
+};
+
+struct aw_sar_mode_t {
+	const struct aw_sar_mode_set_t *mode_set_arr;
+	uint8_t mode_set_arr_len;
+	ssize_t (*p_set_mode_node_fn)(void *data, uint8_t curr_mode);
+	ssize_t (*p_get_mode_node_fn)(void *data, char *buf);
+};
+/********************mode set end****************/
+
+struct aw_sar_init_over_irq_t {
+	int16_t wait_times;
+	uint8_t daley_step;
+	uint32_t reg_irqsrc;
+	uint32_t irq_offset_bit;
+	uint32_t irq_mask;
+	uint32_t irq_flag;
+	/*
+	 * Perform different verification initialization
+	 * to complete the interrupt operation
+	 */
+	int32_t (*p_check_init_over_irq_fn)(void *data);
+	/*
+	 * When initialization fails, get the corresponding error type and
+	 * apply it to the chip with flash
+	 */
+	int32_t (*p_get_err_type_fn)(void *data);
+};
+
+struct aw_sar_soft_rst_t {
+	uint16_t reg_rst;
+	uint32_t reg_rst_val;
+	uint32_t delay_ms;
+	/*Perform different soft reset operations*/
+	int32_t (*p_soft_reset_fn)(void *data);
+};
+
+struct aw_sar_aot_t {
+	uint32_t aot_reg;
+	uint32_t aot_mask;
+	uint32_t aot_flag;
+	ssize_t (*p_set_aot_node_fn)(void *data);
+};
+
+struct aw_sar_diff_t {
+	uint16_t diff0_reg;
+	uint16_t diff_step;
+	//Data format:S21.10, Floating point types generally need to be removed
+	uint32_t rm_float;
+	ssize_t (*p_get_diff_node_fn)(void *data, char *buf);
+};
+
+struct aw_sar_offset_t {
+	ssize_t (*p_get_offset_node_fn)(void *data, char *buf);
+};
+
+struct aw_sar_pinctrl {
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *default_sta;
+	struct pinctrl_state *int_out_high;
+	struct pinctrl_state *int_out_low;
+};
+
+//update reg node
+struct aw_sar_para_load_t {
+	const uint32_t *reg_arr;
+	uint32_t reg_arr_len;
+};
+
+struct aw_sar_platform_config {
+	/*The chip needs to parse more DTS contents for addition*/
+	int32_t (*p_add_parse_dts_fn)(void *data);
+
+	const struct aw_sar_regulator_config_t *p_regulator_config;
+
+	/*The chip needs to add more nodes*/
+	int32_t (*p_add_node_create_fn)(void *data);
+	/*Release the added node*/
+	int32_t (*p_add_node_free_fn)(void *data);
+
+	/*Use a different initialization interrupt to initialize the operation*/
+	int32_t (*p_input_init_fn)(void *data);
+	/*Release input resource*/
+	int32_t (*p_input_deinit_fn)(void *data);
+
+	//The parameters passed in are required for interrupt initialization
+	const struct aw_sar_irq_init_t *p_irq_init;
+
+	//The chip is set to different modes in different power management interfaces
+	const struct aw_sar_pm_t *p_pm_chip_mode;
+};
+
+struct aw_sar_power_on_prox_detection_t {
+	//en_flag is true enable
+	void (*p_power_on_prox_detection_en_fn)(void *data, uint8_t en_flag);
+	uint32_t irq_en_cali_bit;
+	uint8_t power_on_prox_en_flag;
+};
+
+
+/*Parameter passed in by different SAR sensors.
+ *It must be implemented in each sensor code.
+ *If it is not necessary that some members can be assigned null,
+ *the corresponding function will not be implemented
+ */
+struct aw_sar_chip_config {
+	uint8_t ch_num_max; //Number of channels of the chip
+
+	//Chip related platform content configuration
+	const struct aw_sar_platform_config *p_platform_config;
+	//Parameters required for verification of chipid
+	const struct aw_sar_check_chipid_t *p_check_chipid;
+	//Parameters required for soft reset
+	const struct aw_sar_soft_rst_t *p_soft_rst;
+	//Verify the parameters required to initialize a complete interrupt
+	const struct aw_sar_init_over_irq_t *p_init_over_irq;
+	//Parameters required for load boot bin file,
+	//If the chip does not have flash, please ignore and assign the value to null
+	const struct aw_sar_load_bin_t *p_fw_bin;
+	//Parameters required for load register bin file
+	const struct aw_sar_load_bin_t *p_reg_bin;
+	//The mode set before and after the initialization of the chip
+	const struct aw_sar_chip_mode_t *p_chip_mode;
+
+	//Node usage parameters
+	//Register permission table
+	const struct aw_sar_reg_list_t *p_reg_list;
+	//Default register table
+	const struct aw_sar_para_load_t *p_reg_arr;
+	//Parameters required for set Auto-Offset-Tuning(aot)
+	const struct aw_sar_aot_t *p_aot;
+	//Parameters required for get chip diff val
+	const struct aw_sar_diff_t *p_diff;
+	//Parameters required for get chip offset val
+	const struct aw_sar_offset_t *p_offset;
+	//Set the parameters of different working modes of the chip
+	const struct aw_sar_mode_t *p_mode;
+	//Upgrading firmware using the debug node protocol
+	const struct aw_sar_load_bin_t *p_prox_fw;
+	//Upgrading firmware using the debug node reg
+	const struct aw_sar_load_bin_t *p_reg_fw;
+	//Obtain the necessary information of the chip
+	const struct aw_sar_get_chip_info_t *p_get_chip_info;
+	//Continuous read/write register interface
+	const struct aw_sar_awrw_t *p_aw_sar_awrw;
+	//Parameters required for load boot bin file,
+	//If the chip does not have flash, please ignore and assign the value to null
+	const struct aw_sar_load_bin_t *p_boot_bin;
+
+	/*Other operations during initialization, Add according to different usage*/
+	aw_sar_chip_other_operation_t p_other_operation;
+	/*If requested by resources, please release*/
+	aw_sar_chip_other_opera_free_t p_other_opera_free;
+
+	const struct aw_sar_power_on_prox_detection_t *power_on_prox_detection;
+};
+
+struct aw_sar {
+	struct i2c_client *i2c;
+	struct device *dev;
+	struct regulator *vcc;
+	struct delayed_work update_work;
+	//Set pin pull-up mode
+	struct aw_sar_pinctrl pinctrl;
+	/* eds work */
+	struct delayed_work monitor_work;
+	struct workqueue_struct *monitor_wq;
+
+	uint8_t chip_type;
+	uint8_t chip_name[20];
+
+	bool power_enable;
+	bool fw_fail_flag;
+	uint8_t last_mode;
+
+	/*handler_anomalies*/
+	uint8_t fault_flag;
+	uint8_t driver_code_initover_flag;
+	/*handler_anomalies*/
+
+	uint8_t ret_val;
+	uint8_t curr_use_driver_type;
+	int32_t prot_update_state;
+
+	uint8_t aot_irq_num;
+	uint8_t enter_irq_handle_num;
+	uint8_t exit_power_on_prox_detection;
+
+	struct work_struct ps_notify_work;
+	struct notifier_block ps_notif;
+	bool ps_is_present;
+
+	//Parameters related to platform logic
+	struct aw_sar_dts_info dts_info;
+	struct aw_sar_load_bin_comm_t load_bin;
+	struct aw_sar_irq_init_comm_t irq_init;
+	struct aw_awrw_info awrw_info;
+	struct aw_channels_info *channels_arr;
+
+	//Private arguments required for public functions
+	const struct aw_sar_chip_config *p_sar_para;
+	//Private arguments required for private functions
+	void *priv_data;
+};
+
+//Determine whether the chip exists by verifying chipid
+typedef int32_t (*aw_sar_who_am_i_t)(void *data);
+typedef int32_t (*aw_sar_chip_init_t)(struct aw_sar *p_sar);
+typedef void (*aw_sar_chip_deinit_t)(struct aw_sar *p_sar);
+
+struct aw_sar_driver_type {
+	uint8_t driver_type;
+	aw_sar_who_am_i_t p_who_am_i;
+	aw_sar_chip_init_t p_chip_init;
+	aw_sar_chip_deinit_t p_chip_deinit;
+};
+
+#endif
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH V1 3/5] Add aw9610x series related interfaces to the aw_sar driver.
  2024-05-29 13:06 [PATCH V1 0/5] Add support for Awinic SAR sensor wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 2/5] Add universal interface for the aw_sar driver wangshuaijie
@ 2024-05-29 13:06 ` wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 4/5] Add aw963xx " wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 5/5] Add support for Awinic sar sensor wangshuaijie
  4 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-05-29 13:06 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, jeff, linux-input,
	devicetree, linux-kernel
  Cc: wangshuaijie, liweilei, kangjiajun

From: shuaijie wang <wangshuaijie@awinic.com>

Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
---
 drivers/input/misc/aw_sar/aw9610x/aw9610x.c | 884 ++++++++++++++++++++
 drivers/input/misc/aw_sar/aw9610x/aw9610x.h | 324 +++++++
 2 files changed, 1208 insertions(+)
 create mode 100644 drivers/input/misc/aw_sar/aw9610x/aw9610x.c
 create mode 100644 drivers/input/misc/aw_sar/aw9610x/aw9610x.h

diff --git a/drivers/input/misc/aw_sar/aw9610x/aw9610x.c b/drivers/input/misc/aw_sar/aw9610x/aw9610x.c
new file mode 100644
index 000000000000..a7745649813f
--- /dev/null
+++ b/drivers/input/misc/aw_sar/aw9610x/aw9610x.c
@@ -0,0 +1,884 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AWINIC sar sensor driver (aw9610x)
+ *
+ * Author: Shuaijie Wang<wangshuaijie@awinic.com>
+ *
+ * Copyright (c) 2024 awinic Technology CO., LTD
+ */
+#include "aw9610x.h"
+
+#define AW9610X_I2C_NAME "aw9610x_sar"
+
+static struct aw_sar *g_aw_sar;
+
+static int32_t aw9610x_baseline_filter(struct aw_sar *p_sar)
+{
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t status0;
+	uint32_t status1;
+	uint8_t i;
+
+	aw_sar_i2c_read(p_sar->i2c, REG_STAT1, &status1);
+	aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &status0);
+
+	for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
+		if (((status1 >> i) & 0x01) == 1) {
+			if (aw9610x->satu_flag[i] == 0) {
+				aw_sar_i2c_read(p_sar->i2c, REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS,
+						&aw9610x->satu_data[i]);
+				aw_sar_i2c_write(p_sar->i2c, REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS,
+						((aw9610x->satu_data[i] | 0x1fc) & 0x3fffffff));
+				aw9610x->satu_flag[i] = 1;
+			}
+		} else if (((status1 >> i) & 0x01) == 0) {
+			if (aw9610x->satu_flag[i] == 1) {
+				if (((status0 >> (i + 24)) & 0x01) == 0) {
+					aw_sar_i2c_write(p_sar->i2c,
+							REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS,
+							aw9610x->satu_data[i]);
+					aw9610x->satu_flag[i] = 0;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void aw9610x_saturat_release_handle(struct aw_sar *p_sar)
+{
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t satu_irq;
+	uint32_t status0;
+	uint8_t i;
+
+	satu_irq = (aw9610x->irq_status >> 7) & 0x01;
+	if (satu_irq == 1) {
+		aw9610x_baseline_filter(p_sar);
+	} else {
+		aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &status0);
+		for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
+			if (aw9610x->satu_flag[i] == 1) {
+				if (((status0 >> (i + 24)) & 0x01) == 0) {
+					aw_sar_i2c_write(p_sar->i2c,
+							REG_BLFILT_CH0 + i * AW_CL1SPE_DEAL_OS,
+							aw9610x->satu_data[i]);
+					aw9610x->satu_flag[i] = 0;
+				}
+			}
+		}
+	}
+}
+
+static void aw9610x_irq_handle(struct aw_sar *p_sar)
+{
+	uint32_t curr_status_val;
+	uint32_t curr_status;
+	uint8_t i;
+
+	aw_sar_i2c_read(p_sar->i2c, REG_STAT0, &curr_status_val);
+	if (!p_sar->channels_arr) {
+		dev_err(p_sar->dev, "input err!!!");
+		return;
+	}
+
+	for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
+		curr_status =
+			(((uint8_t)(curr_status_val >> (24 + i)) & 0x1))
+#ifdef AW_INPUT_TRIGGER_TH1
+			| (((uint8_t)(curr_status_val >> (16 + i)) & 0x1) << 1)
+#endif
+#ifdef AW_INPUT_TRIGGER_TH2
+			| (((uint8_t)(curr_status_val >> (8 + i)) & 0x1) << 2)
+#endif
+#ifdef AW_INPUT_TRIGGER_TH3
+			| (((uint8_t)(curr_status_val >> (i)) & 0x1) << 3)
+#endif
+			;
+
+		if (p_sar->channels_arr[i].used == AW_FALSE)
+			continue;
+
+		if (p_sar->channels_arr[i].last_channel_info == curr_status)
+			continue;
+
+		switch (curr_status) {
+		case AW9610X_FAR:
+			input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 0);
+			break;
+		case AW9610X_TRIGGER_TH0:
+			input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 1);
+			break;
+#ifdef AW_INPUT_TRIGGER_TH1
+		case AW9610X_TRIGGER_TH1:
+			input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 2);
+			break;
+#endif
+#ifdef AW_INPUT_TRIGGER_TH2
+		case AW9610X_TRIGGER_TH2:
+			input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 3);
+			break;
+#endif
+#ifdef AW_INPUT_TRIGGER_TH3
+		case AW9610X_TRIGGER_TH3:
+			input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 4);
+			break;
+#endif
+		default:
+			dev_err(p_sar->dev, "error abs distance");
+			return;
+		}
+		input_sync(p_sar->channels_arr[i].input);
+
+		p_sar->channels_arr[i].last_channel_info = curr_status;
+	}
+}
+
+static void aw9610x_version_aw9610x_private(struct aw_sar *p_sar)
+{
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+
+	if (aw9610x->satu_release == AW9610X_FUNC_ON)
+		aw9610x_saturat_release_handle(p_sar);
+}
+
+static void aw9610x_irq_handle_func(uint32_t irq_status, void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+
+	dev_info(p_sar->dev, "IRQSRC = 0x%x", irq_status);
+
+	switch (aw9610x->vers) {
+	case AW9610X:
+		aw9610x_version_aw9610x_private(p_sar);
+		break;
+	case AW9610XA:
+		break;
+	default:
+		break;
+	}
+
+	aw9610x_irq_handle(p_sar);
+}
+
+int32_t aw9610x_check_chipid(void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t reg_val;
+	int32_t ret;
+
+	if (!p_sar)
+		return -EINVAL;
+
+	ret = aw_sar_i2c_read(p_sar->i2c, REG_CHIPID, &reg_val);
+	if (ret < 0) {
+		dev_err(p_sar->dev, "read CHIP ID failed: %d", ret);
+		return ret;
+	}
+	reg_val = reg_val >> 16;
+
+	if (reg_val != AW9610X_CHIP_ID) {
+		dev_err(p_sar->dev, "unsupport dev, chipid is (0x%04x)", reg_val);
+		return -EINVAL;
+	}
+	dev_info(p_sar->dev, "aw9610x detected, 0x%04x", reg_val);
+	memcpy(p_sar->chip_name, "AW9610X", 8);
+
+	return 0;
+}
+
+static const struct aw_sar_check_chipid_t g_aw9610x_check_chipid = {
+	.p_check_chipid_fn = aw9610x_check_chipid,
+};
+
+static ssize_t aw9610x_operation_mode_get(void *data, char *buf)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	ssize_t len = 0;
+
+	if (p_sar->last_mode == AW9610X_ACTIVE_MODE)
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Active\n");
+	else if (p_sar->last_mode == AW9610X_SLEEP_MODE)
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Sleep\n");
+	else if ((p_sar->last_mode == AW9610X_DEEPSLEEP_MODE) && (aw9610x->vers == AW9610XA))
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: DeepSleep\n");
+	else
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Unconfirmed\n");
+
+	return len;
+}
+
+static void aw9610x_chip_info_get(void *data, char *buf, ssize_t *p_len)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t reg_data;
+
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len,
+			"sar%u\n", p_sar->dts_info.sar_num);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "The driver supports UI\n");
+
+	aw_sar_i2c_read(p_sar->i2c, REG_CHIPID, &reg_data);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "chipid is 0x%08x\n", reg_data);
+
+	aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &reg_data);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "REG_HOSTIRQEN is 0x%08x\n", reg_data);
+
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len,
+			"chip_name:%s bin_prase_chip_name:%s\n",
+			aw9610x->chip_name, aw9610x->chip_type);
+}
+
+static const struct aw_sar_get_chip_info_t g_aw9610x_get_chip_info = {
+	.p_get_chip_info_node_fn = aw9610x_chip_info_get,
+};
+
+static void aw9610x_reg_version_comp(struct aw_sar *p_sar, struct aw_bin *aw_bin)
+{
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t blfilt1_data;
+	uint32_t blfilt1_tmp;
+	uint8_t i;
+
+	if ((aw9610x->chip_name[7] == 'A') &&
+		(aw_bin->header_info[0].chip_type[7] == '\0')) {
+		for (i = 0; i < 6; i++) {
+			aw_sar_i2c_read(p_sar->i2c, REG_BLFILT_CH0 + (0x3c * i), &blfilt1_data);
+			blfilt1_tmp = (blfilt1_data >> 25) & 0x1;
+			if (blfilt1_tmp == 1)
+				aw_sar_i2c_write_bits(p_sar->i2c, REG_BLRSTRNG_CH0 + (0x3c * i),
+						~(0x3f), 1 << i);
+		}
+	}
+}
+
+static int32_t aw9610x_load_reg_bin(struct aw_bin *aw_bin, void *load_bin_para)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	int32_t ret;
+
+	dev_info(p_sar->dev, "reg chip name: %s, soc chip name: %s, len = %d",
+			p_sar->chip_name, aw_bin->header_info[0].chip_type, aw_bin->info.len);
+
+	snprintf(aw9610x->chip_type, sizeof(aw9610x->chip_type), "%s",
+			aw_bin->header_info[0].chip_type);
+	ret = strncmp(aw9610x->chip_name, aw_bin->header_info[0].chip_type,
+			sizeof(aw_bin->header_info[0].chip_type));
+	if (ret != 0)
+		dev_err(p_sar->dev, "load_binname(%s) incompatible with chip type(%s)",
+			p_sar->chip_name, aw_bin->header_info[0].chip_type);
+
+	p_sar->load_bin.bin_data_ver = aw_bin->header_info[0].bin_data_ver;
+
+	ret = aw_sar_load_reg(aw_bin, p_sar->i2c);
+	aw9610x_reg_version_comp(p_sar, aw_bin);
+
+	return ret;
+}
+
+static ssize_t aw9610x_get_self_cap_offset(void *data, char *buf)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint8_t temp_data[20] = { 0 };
+	uint32_t coff_data_int;
+	uint32_t coff_data_dec;
+	uint32_t coff_data;
+	uint32_t reg_val;
+	ssize_t len = 0;
+	uint8_t i;
+
+	for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
+		aw_sar_i2c_read(p_sar->i2c,
+			REG_AFECFG1_CH0 + i * AW_CL1SPE_CALI_OS, &reg_val);
+		coff_data = (reg_val >> 24) * 900 + ((reg_val >> 16) & 0xff) * 13;
+		coff_data_int = coff_data / 1000;
+		coff_data_dec = coff_data % 1000;
+		snprintf(temp_data, sizeof(temp_data), "%u.%u", coff_data_int, coff_data_dec);
+		len += snprintf(buf+len, PAGE_SIZE-len, "PARASITIC_DATA_CH%d = %s pf\n",
+				i, temp_data);
+	}
+
+	return len;
+}
+
+static const struct aw_sar_offset_t g_aw9610x_offset = {
+	.p_get_offset_node_fn = aw9610x_get_self_cap_offset,
+};
+
+static uint32_t attr_buf[] = {
+	8, 10,
+	9, 100,
+	10, 1000,
+};
+
+static void aw9610x_addrblock_load(struct aw_sar *p_sar, const char *buf)
+{
+	struct aw9610x *aw9610x = p_sar->priv_data;
+	uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
+	uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
+	uint32_t addrbuf[4] = { 0 };
+	uint8_t temp_buf[2] = { 0 };
+	uint32_t i;
+
+	for (i = 0; i < addr_bytes; i++) {
+		if (reg_num < attr_buf[1]) {
+			temp_buf[0] = buf[attr_buf[0] + i * 5];
+			temp_buf[1] = buf[attr_buf[0] + i * 5 + 1];
+		} else if (reg_num >= attr_buf[1] && reg_num < attr_buf[3]) {
+			temp_buf[0] = buf[attr_buf[2] + i * 5];
+			temp_buf[1] = buf[attr_buf[2] + i * 5 + 1];
+		} else if (reg_num >= attr_buf[3] && reg_num < attr_buf[5]) {
+			temp_buf[0] = buf[attr_buf[4] + i * 5];
+			temp_buf[1] = buf[attr_buf[4] + i * 5 + 1];
+		}
+		if (sscanf(temp_buf, "%02x", &addrbuf[i]) == 1)
+			aw9610x->aw_i2c_package.init_addr[i] = (uint8_t)addrbuf[i];
+	}
+}
+
+static int32_t aw9610x_awrw_write_seq(struct aw_sar *p_sar)
+{
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
+	uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
+	uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
+	uint8_t *p_reg_data = aw9610x->aw_i2c_package.p_reg_data;
+	uint8_t w_buf[228];
+	uint32_t msg_idx;
+	uint8_t msg_cnt;
+
+	for (msg_idx = 0; msg_idx < addr_bytes; msg_idx++)
+		w_buf[msg_idx] = aw9610x->aw_i2c_package.init_addr[msg_idx];
+
+	msg_cnt = addr_bytes;
+	for (msg_idx = 0; msg_idx < data_bytes * reg_num; msg_idx++) {
+		w_buf[msg_cnt] = *p_reg_data++;
+		msg_cnt++;
+	}
+
+	return aw_sar_i2c_write_seq(p_sar->i2c, w_buf, msg_cnt);
+}
+
+static void aw9610x_datablock_load(struct aw_sar *p_sar, const char *buf)
+{
+	struct aw9610x *aw9610x = p_sar->priv_data;
+	uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
+	uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
+	uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
+	uint8_t reg_data[220] = { 0 };
+	uint32_t databuf[220] = { 0 };
+	uint8_t temp_buf[2] = { 0 };
+	uint32_t i;
+
+	for (i = 0; i < data_bytes * reg_num; i++) {
+		if (reg_num < attr_buf[1]) {
+			temp_buf[0] = buf[attr_buf[0] + (addr_bytes + i) * 5];
+			temp_buf[1] =
+				buf[attr_buf[0] + (addr_bytes + i) * 5 + 1];
+		} else if (reg_num >= attr_buf[1] && reg_num < attr_buf[3]) {
+			temp_buf[0] = buf[attr_buf[2] + (addr_bytes + i) * 5];
+			temp_buf[1] =
+				buf[attr_buf[2] + (addr_bytes + i) * 5 + 1];
+		} else if (reg_num >= attr_buf[3] && reg_num < attr_buf[5]) {
+			temp_buf[0] = buf[attr_buf[4] + (addr_bytes + i) * 5];
+			temp_buf[1] =
+				buf[attr_buf[4] + (addr_bytes + i) * 5 + 1];
+		}
+		sscanf(temp_buf, "%02x", &databuf[i]);
+		reg_data[i] = (uint8_t)databuf[i];
+	}
+	aw9610x->aw_i2c_package.p_reg_data = reg_data;
+	aw9610x_awrw_write_seq(p_sar);
+}
+
+static int32_t aw9610x_awrw_read_seq(struct aw_sar *p_sar, uint8_t *reg_data)
+{
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
+	uint8_t addr_bytes = aw9610x->aw_i2c_package.addr_bytes;
+	uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
+	uint16_t msg_cnt = (uint16_t)(data_bytes * reg_num);
+	uint8_t w_buf[4];
+	uint8_t buf[228];
+	uint32_t msg_idx;
+	int32_t ret;
+
+	for (msg_idx = 0; msg_idx < addr_bytes; msg_idx++)
+		w_buf[msg_idx] = aw9610x->aw_i2c_package.init_addr[msg_idx];
+
+	ret = aw_sar_i2c_read_seq(p_sar->i2c, w_buf, 2, (uint8_t *)buf, msg_cnt);
+
+	for (msg_idx = 0; msg_idx < msg_cnt; msg_idx++)
+		reg_data[msg_idx] = buf[msg_idx];
+
+	return ret;
+}
+
+static ssize_t aw9610x_awrw_get(void *data, char *buf)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint8_t data_bytes = aw9610x->aw_i2c_package.data_bytes;
+	uint8_t reg_num = aw9610x->aw_i2c_package.reg_num;
+	uint8_t reg_data[228] = { 0 };
+	ssize_t len = 0;
+	uint8_t i;
+
+	aw9610x_awrw_read_seq(p_sar, reg_data);
+	for (i = 0; i < reg_num * data_bytes; i++)
+		len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x,", reg_data[i]);
+
+	snprintf(buf + len - 1, PAGE_SIZE - len, "\n");
+
+	return len;
+};
+
+static ssize_t aw9610x_awrw_set(void *data, const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t datatype[3] = { 0 };
+
+	if (sscanf(buf, "%u %u %u", &datatype[0], &datatype[1], &datatype[2]) == 3) {
+		aw9610x->aw_i2c_package.addr_bytes = (uint8_t)datatype[0];
+		aw9610x->aw_i2c_package.data_bytes = (uint8_t)datatype[1];
+		aw9610x->aw_i2c_package.reg_num = (uint8_t)datatype[2];
+
+		aw9610x_addrblock_load(p_sar, buf);
+		if (count > 7 + 5 * aw9610x->aw_i2c_package.addr_bytes)
+			aw9610x_datablock_load(p_sar, buf);
+	}
+
+	return count;
+}
+
+static int32_t aw9610x_get_chip_version(void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t firmvers;
+	uint32_t fw_ver;
+	int32_t ret;
+
+	aw_sar_i2c_read(p_sar->i2c, REG_FWVER, &firmvers);
+
+	ret = aw_sar_i2c_read(p_sar->i2c, REG_FWVER2, &fw_ver);
+	if (ret < 0) {
+		dev_err(p_sar->dev, "read REG_FWVER2 err!");
+		return ret;
+	}
+	snprintf(aw9610x->chip_name, sizeof(aw9610x->chip_name), "AW9610X");
+	p_sar->chip_type = AW_SAR_NONE_CHECK_CHIP;
+
+	if (fw_ver == AW_CHIP_AW9610XA) {
+		aw9610x->vers = AW9610XA;
+		memcpy(aw9610x->chip_name + strlen(aw9610x->chip_name), "A", 2);
+		p_sar->chip_type = SAR_AW9610XA;
+	} else {
+		aw9610x->vers = AW9610X;
+		p_sar->chip_type = SAR_AW9610X;
+		aw9610x->chip_name[7] = '\0';
+	}
+	dev_info(p_sar->dev, "the IC is = %s", aw9610x->chip_name);
+
+	return 0;
+}
+
+#ifdef AW9610X_TVS_ABNORMAL_CAIL
+static ssize_t aw9610x_set_aot(void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint32_t max_delay_ms = AW9610X_AOT_OVER_DELAY_MAX_MS;
+	uint32_t irqen_reg_val;
+	uint32_t reg_val_tmp;
+	uint32_t scan_over_cnt;
+	uint32_t scan_over_en;
+	uint32_t ch_en;
+	uint32_t i;
+
+	//1. disable chip irq
+	aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &irqen_reg_val);
+	aw_sar_i2c_write(p_sar->i2c, REG_IRQEN, AW_REG_IRQEN_CLOSE);
+
+	//2. aot cail
+	aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL0, ~(AW9610X_AOT_MASK << AW9610X_AOT_BIT),
+						AW9610X_AOT_MASK << AW9610X_AOT_BIT);
+	// aot over
+	for (i = 0; i < max_delay_ms; i++) {
+		aw_sar_i2c_read(p_sar->i2c, REG_IRQSRC, &reg_val_tmp);
+		if (((reg_val_tmp >> AW_REG_IRQSRC_AOT_OVER_BIT) & 0x01) == 1)
+			break;
+		mdelay(1);
+	}
+
+	//3. scan 8 cnt over
+	aw_sar_i2c_read(p_sar->i2c, REG_SCANCTRL0, &ch_en);
+	aw_sar_i2c_read(p_sar->i2c, REG_CHINTEN, &scan_over_en);
+	if ((ch_en & AW9610X_AOT_MASK) != (scan_over_en & AW9610X_AOT_MASK))
+		aw_sar_i2c_write_bits(p_sar->i2c, REG_CHINTEN, ~(AW9610X_AOT_MASK),
+				ch_en & (AW9610X_AOT_MASK));
+
+	for (scan_over_cnt = 0; scan_over_cnt < AW9610X_AOT_SCAN_OVER_CNT; scan_over_cnt++) {
+		for (i = 0; i < max_delay_ms; i++) {
+			aw_sar_i2c_read(p_sar->i2c, REG_IRQSRC, &reg_val_tmp);
+			if (((reg_val_tmp >> REG_IRQSRC_SCAN_OVER_BIT) & 0x01) == 1)
+				break;
+			mdelay(1);
+		}
+	}
+	if ((ch_en & AW9610X_AOT_MASK) != (scan_over_en & AW9610X_AOT_MASK))
+		aw_sar_i2c_write_bits(p_sar->i2c, REG_CHINTEN, ~(AW9610X_AOT_MASK),
+				ch_en & (AW9610X_AOT_MASK));
+
+	if (aw9610x->vers == AW9610XA)
+		//4. chip set sleep mode
+		aw_sar_i2c_write(p_sar->i2c, REG_CMD, AW9610X_SLEEP_MODE);
+	else if (aw9610x->vers == AW9610X)
+		aw_sar_i2c_write(p_sar->i2c, REG_CMD, AW9610X_DEEPSLEEP_MODE);
+
+	for (i = 0; i < max_delay_ms; i++) {
+		aw_sar_i2c_read(p_sar->i2c, REG_WST, &reg_val_tmp);
+		if ((reg_val_tmp & 0xFF) == REG_REG_WST_SLEEP_MODE)
+			break;
+		mdelay(1);
+	}
+
+	//5. write baseline data
+	for (i = 0; i < AW9610X_CHANNEL_MAX; i++) {
+		aw_sar_i2c_read(p_sar->i2c, REG_COMP_CH0 + i * AW9610X_REG_OFFSET_STEP,
+				&reg_val_tmp);
+		aw_sar_i2c_write(p_sar->i2c, REG_BASELINE_CH0 + i * AW9610X_REG_OFFSET_STEP,
+				reg_val_tmp);
+	}
+
+	//6. chip set active, irq recovery
+	aw_sar_i2c_write(p_sar->i2c, REG_CMD, AW9610X_ACTIVE_MODE);
+	aw_sar_i2c_write(p_sar->i2c, REG_IRQEN, irqen_reg_val);
+
+	return 0;
+}
+#else
+static ssize_t aw9610x_set_aot(void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+
+	aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL0, ~(AW9610X_AOT_MASK << AW9610X_AOT_BIT),
+						(AW9610X_AOT_MASK) << AW9610X_AOT_BIT);
+	return 0;
+}
+#endif
+
+static const struct aw_sar_aot_t g_aw9610x_aot = {
+	.p_set_aot_node_fn = aw9610x_set_aot,
+};
+
+/**********************mode operation start*******************************/
+static void aw9610x_enable_clock(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_OSCEN, AW9610X_CPU_WORK_MASK);
+}
+
+static uint32_t aw9610x_rc_irqscr(void *i2c)
+{
+	uint32_t val;
+
+	aw_sar_i2c_read(i2c, REG_IRQSRC, &val);
+
+	return val;
+}
+
+//Note: TVS exceptions need to be handled after active
+static void aw9610x_set_active_cmd(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_CMD, AW9610X_ACTIVE_MODE);
+
+#ifdef AW9610X_TVS_ABNORMAL_CAIL
+	if (g_aw_sar != NULL)
+		aw9610x_set_aot(g_aw_sar);
+#endif
+}
+
+static void aw9610x_set_sleep_cmd(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_CMD, AW9610X_SLEEP_MODE);
+}
+
+static void aw9610x_set_deepsleep_cmd(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_CMD, AW9610X_DEEPSLEEP_MODE);
+}
+
+static const struct aw_sar_mode_set_t g_aw9610x_mode_set[] = {
+	{
+		.chip_id = SAR_AW9610XA | SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_ACTIVE_MODE,
+			.last_mode = AW9610X_DEEPSLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = aw9610x_enable_clock,
+			.rc_irqscr = NULL,
+			.mode_update = aw9610x_set_active_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610XA | SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_ACTIVE_MODE,
+			.last_mode = AW9610X_SLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = aw9610x_set_active_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610XA | SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_ACTIVE_MODE,
+			.last_mode = AW9610X_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = aw9610x_set_active_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610XA | SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_SLEEP_MODE,
+			.last_mode = AW9610X_DEEPSLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = aw9610x_enable_clock,
+			.rc_irqscr = NULL,
+			.mode_update = aw9610x_set_sleep_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610XA | SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_SLEEP_MODE,
+			.last_mode = AW9610X_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = aw9610x_set_sleep_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610XA | SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_DEEPSLEEP_MODE,
+			.last_mode = AW9610X_SLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = aw9610x_set_deepsleep_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610XA,
+		.chip_mode = {
+			.curr_mode = AW9610X_DEEPSLEEP_MODE,
+			.last_mode = AW9610X_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = aw9610x_rc_irqscr,
+			.mode_update = aw9610x_set_deepsleep_cmd,
+		},
+	},
+	{
+		.chip_id = SAR_AW9610X,
+		.chip_mode = {
+			.curr_mode = AW9610X_DEEPSLEEP_MODE,
+			.last_mode = AW9610X_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = NULL,
+		},
+	},
+};
+/**********************mode operation end*******************************/
+
+static const struct aw_sar_irq_init_t g_aw9610x_irq_init = {
+	.flags = GPIOF_DIR_IN | GPIOF_INIT_HIGH,
+	.irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+	.handler = NULL,
+	.thread_fn = NULL,
+	.rc_irq_fn = aw9610x_rc_irqscr,
+	.irq_spec_handler_fn = aw9610x_irq_handle_func,
+};
+
+static const struct aw_sar_soft_rst_t g_aw9610x_soft_rst = {
+	.reg_rst = REG_RESET,
+	.reg_rst_val = 0,
+	.delay_ms = 20,
+};
+
+static const struct aw_sar_init_over_irq_t g_aw9610x_init_over_irq = {
+	.wait_times = 20,
+	.daley_step = 1,
+	.reg_irqsrc = REG_IRQSRC,
+	.irq_offset_bit = 0,
+	.irq_mask = 0x1,
+	.irq_flag = 0x1,
+};
+
+static const struct aw_sar_load_bin_t g_aw9610x_load_reg_bin = {
+	.bin_name = "aw9610x",
+	.bin_opera_func = aw9610x_load_reg_bin,
+	.p_update_fn = NULL,
+};
+
+static const struct aw_sar_para_load_t g_aw9610x_reg_arr_para = {
+	.reg_arr = aw9610x_reg_default,
+	.reg_arr_len = ARRAY_SIZE(aw9610x_reg_default),
+};
+
+static const struct aw_sar_diff_t g_aw9610x_diff = {
+	.diff0_reg = REG_DIFF_CH0,
+	.diff_step = 4,
+	.rm_float = AW9610x_DATA_PROCESS_FACTOR,
+};
+
+static const struct aw_sar_mode_t g_aw9610x_mode = {
+	.mode_set_arr = &g_aw9610x_mode_set[0],
+	.mode_set_arr_len = ARRAY_SIZE(g_aw9610x_mode_set),
+	.p_set_mode_node_fn = NULL,
+	.p_get_mode_node_fn = aw9610x_operation_mode_get,
+};
+
+static const struct aw_sar_reg_list_t g_aw9610x_reg_list = {
+	.reg_none_access = REG_NONE_ACCESS,
+	.reg_rd_access = REG_RD_ACCESS,
+	.reg_wd_access = REG_WR_ACCESS,
+	.reg_perm = (struct aw_sar_reg_data *)&g_aw9610x_reg_access[0],
+	.reg_num = ARRAY_SIZE(g_aw9610x_reg_access),
+};
+
+static const struct aw_sar_pm_t g_aw9610x_pm_chip_mode = {
+	.suspend_set_mode = AW9610X_SLEEP_MODE,
+	.resume_set_mode = AW9610X_ACTIVE_MODE,
+	.shutdown_set_mode = AW9610X_SLEEP_MODE,
+};
+
+static const struct aw_sar_chip_mode_t g_aw9610x_chip_mode = {
+	.init_mode = AW9610X_ACTIVE_MODE,
+	.active = AW9610X_ACTIVE_MODE,
+	.pre_init_mode = AW9610X_SLEEP_MODE,
+};
+
+static const struct aw_sar_regulator_config_t g_regulator_config = {
+	.vcc_name = "vcc",
+	.min_uV = AW9610X_SAR_VCC_MIN_UV,
+	.max_uV = AW9610X_SAR_VCC_MAX_UV,
+};
+
+struct aw_sar_awrw_t g_aw9610x_awrw = {
+	.p_set_awrw_node_fn = aw9610x_awrw_set,
+	.p_get_awrw_node_fn = aw9610x_awrw_get,
+};
+
+static const struct aw_sar_platform_config g_aw9610x_platform_config = {
+	.p_regulator_config = &g_regulator_config,
+	.p_irq_init = &g_aw9610x_irq_init,
+	.p_pm_chip_mode = &g_aw9610x_pm_chip_mode,
+};
+
+static void aw9610x_power_on_prox_detection(void *data, uint8_t en_flag)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw9610x *aw9610x = (struct aw9610x *)p_sar->priv_data;
+	uint8_t ch;
+
+	if (en_flag == true) {
+		for (ch = 0; ch < AW9610X_CHANNEL_MAX; ch++) {
+			aw_sar_i2c_read(p_sar->i2c,
+				REG_BLFILT_CH0 + (REG_BLFILT_CH1 - REG_BLFILT_CH0) * ch,
+				&(aw9610x->last_blfilta[ch]));
+			aw_sar_i2c_write_bits(p_sar->i2c,
+				REG_BLFILT_CH0 + (REG_BLFILT_CH1 - REG_BLFILT_CH0) * ch,
+				~(0x3f << 13), (1 << 13));
+		}
+		aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &aw9610x->last_irq_en);
+		aw_sar_i2c_write_bits(p_sar->i2c, REG_IRQEN, ~(1 << 3), 1 << 3);
+	} else if (en_flag == false) {
+		for (ch = 0; ch < AW9610X_CHANNEL_MAX; ch++) {
+			aw_sar_i2c_write(p_sar->i2c,
+				REG_BLFILT_CH0 + (REG_BLFILT_CH1 - REG_BLFILT_CH0) * ch,
+				aw9610x->last_blfilta[ch]);
+		}
+		aw_sar_i2c_write(p_sar->i2c, REG_IRQEN, aw9610x->last_irq_en);
+	}
+}
+
+static const struct aw_sar_power_on_prox_detection_t g_aw9610x_power_on_prox_detection = {
+	.p_power_on_prox_detection_en_fn = aw9610x_power_on_prox_detection,
+	.irq_en_cali_bit = 3,
+	.power_on_prox_en_flag = true,
+};
+
+static const struct aw_sar_chip_config g_aw9610x_chip_config = {
+	.ch_num_max = AW9610X_CHANNEL_MAX,
+
+	.p_platform_config = &g_aw9610x_platform_config,
+
+	.p_check_chipid = &g_aw9610x_check_chipid,
+	.p_soft_rst = &g_aw9610x_soft_rst,
+	.p_init_over_irq = &g_aw9610x_init_over_irq,
+	.p_fw_bin = NULL,
+	.p_reg_bin = &g_aw9610x_load_reg_bin,
+	.p_chip_mode = &g_aw9610x_chip_mode,
+
+	//Node usage parameters
+	.p_reg_list = &g_aw9610x_reg_list,
+	.p_reg_arr = &g_aw9610x_reg_arr_para,
+	.p_aot = &g_aw9610x_aot,
+	.p_diff = &g_aw9610x_diff,
+	.p_offset = &g_aw9610x_offset,
+	.p_mode = &g_aw9610x_mode,
+	.p_prox_fw = NULL,
+	.p_get_chip_info = &g_aw9610x_get_chip_info,
+	.p_aw_sar_awrw = &g_aw9610x_awrw,
+	.p_boot_bin = NULL,
+
+	.p_other_operation = aw9610x_get_chip_version,
+	.p_other_opera_free = NULL,
+	.power_on_prox_detection = &g_aw9610x_power_on_prox_detection,
+};
+
+int32_t aw9610x_init(struct aw_sar *p_sar)
+{
+	if (!p_sar)
+		return -EINVAL;
+
+	g_aw_sar = p_sar;
+
+	p_sar->priv_data = devm_kzalloc(p_sar->dev, sizeof(struct aw9610x), GFP_KERNEL);
+	if (!p_sar->priv_data)
+		return -ENOMEM;
+
+	//Chip private function operation
+	p_sar->p_sar_para = &g_aw9610x_chip_config;
+
+	return 0;
+}
+
+void aw9610x_deinit(struct aw_sar *p_sar)
+{
+	if (p_sar->priv_data != NULL)
+		devm_kfree(p_sar->dev, p_sar->priv_data);
+}
diff --git a/drivers/input/misc/aw_sar/aw9610x/aw9610x.h b/drivers/input/misc/aw_sar/aw9610x/aw9610x.h
new file mode 100644
index 000000000000..6f72e4c20374
--- /dev/null
+++ b/drivers/input/misc/aw_sar/aw9610x/aw9610x.h
@@ -0,0 +1,324 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _AW9610X_H_
+#define _AW9610X_H_
+#include "../comm/aw_sar_type.h"
+
+//#define AW9610X_TVS_ABNORMAL_CAIL
+#define AW9610X_AOT_SCAN_OVER_CNT (32)
+
+#define AW9610X_CHIP_ID					(0xa961)
+#define AW9610x_DATA_PROCESS_FACTOR			(1024)
+#define AW_CHIP_AW9610XA				(0x03000b00)
+#define AW9610X_CPU_WORK_MASK				(1)
+
+#define AW9610X_SAR_VCC_MIN_UV				(1700000)
+#define AW9610X_SAR_VCC_MAX_UV				(3600000)
+
+#define AW_REG_IRQEN_CLOSE				(0)
+#define AW_REG_IRQSRC_AOT_OVER_BIT			(3)
+#define REG_IRQSRC_SCAN_OVER_BIT			(4)
+#define REG_REG_WST_SLEEP_MODE				(0x3)
+#define AW9610X_AOT_OVER_DELAY_MAX_MS			(6000)
+#define AW9610X_AOT_MASK				(0x3f)
+#define AW9610X_AOT_BIT					(8)
+#define AW9610X_REG_OFFSET_STEP				(4)
+
+enum aw9610x_sar_vers {
+	AW9610X = 2,
+	AW9610XA = 6,
+	AW9610XB = 0xa,
+};
+
+enum aw9610x_operation_mode {
+	AW9610X_ACTIVE_MODE = 1,
+	AW9610X_SLEEP_MODE,
+	AW9610X_DEEPSLEEP_MODE,
+	AW9610XB_DEEPSLEEP_MODE,
+};
+
+/**********************************************
+ *spereg addr offset
+ **********************************************/
+enum aw9610x_spereg_addr_offset {
+	AW_CL1SPE_CALI_OS = 20,
+	AW_CL1SPE_DEAL_OS = 60,
+	AW_CL2SPE_CALI_OS = 4,
+	AW_CL2SPE_DEAL_OS = 4,
+};
+
+
+/**********************************************
+ *the flag of i2c read/write
+ **********************************************/
+enum aw9610x_function_flag {
+	AW9610X_FUNC_OFF,
+	AW9610X_FUNC_ON,
+};
+
+/**********************************************
+ * multiple sar define
+ **********************************************/
+enum aw9610x_multiple_sar {
+	AW_SAR0,
+	AW_SAR1,
+	AW_SAR_MAX,
+};
+
+#define AW9610X_CHANNEL_MAX	(6)
+
+enum aw9610x_irq_trigger_position {
+	AW9610X_FAR,
+	AW9610X_TRIGGER_TH0,
+	AW9610X_TRIGGER_TH1 = 0x03,
+	AW9610X_TRIGGER_TH2 = 0x07,
+	AW9610X_TRIGGER_TH3 = 0x0f,
+};
+
+struct aw_i2c_package {
+	uint8_t addr_bytes;
+	uint8_t data_bytes;
+	uint8_t reg_num;
+	uint8_t init_addr[4];
+	uint8_t *p_reg_data;
+};
+
+struct aw9610x {
+	uint8_t vers;
+	uint8_t channel;
+	uint32_t irq_status;
+	uint8_t chip_name[9];
+	uint8_t chip_type[9];
+	bool satu_release;
+
+	struct aw_i2c_package aw_i2c_package;
+
+	uint8_t satu_flag[6];
+	uint32_t satu_data[6];
+	uint32_t last_blfilta[AW9610X_CHANNEL_MAX];
+	uint32_t last_irq_en;
+};
+
+/********************************************
+ * Register List
+ ********************************************/
+#define AFE_BASE_ADDR					(0x0000)
+#define DSP_BASE_ADDR					(0x0000)
+#define STAT_BASE_ADDR					(0x0000)
+#define SFR_BASE_ADDR					(0x0000)
+#define DATA_BASE_ADDR					(0x0000)
+
+#define REG_SCANCTRL0					((0x0000) + AFE_BASE_ADDR)
+#define REG_AFECFG1_CH0					((0x0014) + AFE_BASE_ADDR)
+
+#define REG_FWVER					((0x0088) + STAT_BASE_ADDR)
+#define REG_WST						((0x008C) + STAT_BASE_ADDR)
+#define REG_STAT0					((0x0090) + STAT_BASE_ADDR)
+#define REG_STAT1					((0x0094) + STAT_BASE_ADDR)
+#define REG_CHINTEN					((0x009C) + STAT_BASE_ADDR)
+
+#define REG_BLFILT_CH0					((0x00A8) + DSP_BASE_ADDR)
+#define REG_BLRSTRNG_CH0				((0x00B4) + DSP_BASE_ADDR)
+#define REG_BLFILT_CH1					((0x00E4) + DSP_BASE_ADDR)
+
+#define REG_COMP_CH0					((0x0210) + DATA_BASE_ADDR)
+#define REG_BASELINE_CH0				((0x0228) + DATA_BASE_ADDR)
+#define REG_DIFF_CH0					((0x0240) + DATA_BASE_ADDR)
+#define REG_FWVER2					((0x0410) + DATA_BASE_ADDR)
+
+#define REG_CMD						((0xF008) + SFR_BASE_ADDR)
+#define REG_IRQSRC					((0xF080) + SFR_BASE_ADDR)
+#define REG_IRQEN					((0xF084) + SFR_BASE_ADDR)
+#define REG_OSCEN					((0xFF00) + SFR_BASE_ADDR)
+#define REG_RESET					((0xFF0C) + SFR_BASE_ADDR)
+#define REG_CHIPID					((0xFF10) + SFR_BASE_ADDR)
+
+struct aw_reg_data {
+	unsigned char rw;
+	unsigned short reg;
+};
+/********************************************
+ * Register Access
+ *******************************************/
+#define REG_NONE_ACCESS					(0)
+#define REG_RD_ACCESS					(1 << 0)
+#define REG_WR_ACCESS					(1 << 1)
+
+static const struct aw_reg_data g_aw9610x_reg_access[] = {
+	{ .reg = REG_SCANCTRL0,				.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG1_CH0,			.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+
+	{ .reg = REG_FWVER,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_WST,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_STAT0,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_STAT1,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_CHINTEN,				.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+
+	{ .reg = REG_BLFILT_CH0,			.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_BLRSTRNG_CH0,			.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_BLFILT_CH1,			.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+
+
+	{ .reg = REG_COMP_CH0,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_BASELINE_CH0,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_DIFF_CH0,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_FWVER2,				.rw = REG_RD_ACCESS, },
+
+	{ .reg = REG_CMD,				.rw = REG_NONE_ACCESS, },
+	{ .reg = REG_IRQSRC,				.rw = REG_RD_ACCESS, },
+	{ .reg = REG_IRQEN,				.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_OSCEN,				.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_RESET,				.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_CHIPID,				.rw = REG_RD_ACCESS, },
+};
+
+
+/******************************************************
+ * Register Detail
+ ******************************************************/
+static const uint32_t aw9610x_reg_default[] = {
+	0x0000, 0x00003f3f,
+	0x0004, 0x00000064,
+	0x0008, 0x0017c11e,
+	0x000c, 0x05000000,
+	0x0010, 0x00093ffd,
+	0x0014, 0x19240009,
+	0x0018, 0xd81c0207,
+	0x001c, 0xff000000,
+	0x0020, 0x00241900,
+	0x0024, 0x00093ff7,
+	0x0028, 0x58020009,
+	0x002c, 0xd81c0207,
+	0x0030, 0xff000000,
+	0x0034, 0x00025800,
+	0x0038, 0x00093fdf,
+	0x003c, 0x7d3b0009,
+	0x0040, 0xd81c0207,
+	0x0044, 0xff000000,
+	0x0048, 0x003b7d00,
+	0x004c, 0x00093f7f,
+	0x0050, 0xe9310009,
+	0x0054, 0xd81c0207,
+	0x0058, 0xff000000,
+	0x005c, 0x0031e900,
+	0x0060, 0x00093dff,
+	0x0064, 0x1a0c0009,
+	0x0068, 0xd81c0207,
+	0x006c, 0xff000000,
+	0x0070, 0x000c1a00,
+	0x0074, 0x80093fff,
+	0x0078, 0x043d0009,
+	0x007c, 0xd81c0207,
+	0x0080, 0xff000000,
+	0x0084, 0x003d0400,
+	0x00a0, 0xe6400000,
+	0x00a4, 0x00000000,
+	0x00a8, 0x010408d2,
+	0x00ac, 0x00000000,
+	0x00b0, 0x00000000,
+	0x00b8, 0x00005fff,
+	0x00bc, 0x00000000,
+	0x00c0, 0x00000000,
+	0x00c4, 0x00000000,
+	0x00c8, 0x00000000,
+	0x00cc, 0x00000000,
+	0x00d0, 0x00000000,
+	0x00d4, 0x00000000,
+	0x00d8, 0x00000000,
+	0x00dc, 0xe6447800,
+	0x00e0, 0x78000000,
+	0x00e4, 0x010408d2,
+	0x00e8, 0x00000000,
+	0x00ec, 0x00000000,
+	0x00f4, 0x00005fff,
+	0x00f8, 0x00000000,
+	0x00fc, 0x00000000,
+	0x0100, 0x00000000,
+	0x0104, 0x00000000,
+	0x0108, 0x00000000,
+	0x010c, 0x02000000,
+	0x0110, 0x00000000,
+	0x0114, 0x00000000,
+	0x0118, 0xe6447800,
+	0x011c, 0x78000000,
+	0x0120, 0x010408d2,
+	0x0124, 0x00000000,
+	0x0128, 0x00000000,
+	0x0130, 0x00005fff,
+	0x0134, 0x00000000,
+	0x0138, 0x00000000,
+	0x013c, 0x00000000,
+	0x0140, 0x00000000,
+	0x0144, 0x00000000,
+	0x0148, 0x02000000,
+	0x014c, 0x00000000,
+	0x0150, 0x00000000,
+	0x0154, 0xe6447800,
+	0x0158, 0x78000000,
+	0x015c, 0x010408d2,
+	0x0160, 0x00000000,
+	0x0164, 0x00000000,
+	0x016c, 0x00005fff,
+	0x0170, 0x00000000,
+	0x0174, 0x00000000,
+	0x0178, 0x00000000,
+	0x017c, 0x00000000,
+	0x0180, 0x00000000,
+	0x0184, 0x02000000,
+	0x0188, 0x00000000,
+	0x018c, 0x00000000,
+	0x0190, 0xe6447800,
+	0x0194, 0x78000000,
+	0x0198, 0x010408d2,
+	0x019c, 0x00000000,
+	0x01a0, 0x00000000,
+	0x01a8, 0x00005fff,
+	0x01ac, 0x00000000,
+	0x01b0, 0x00000000,
+	0x01b4, 0x00000000,
+	0x01b8, 0x00000000,
+	0x01bc, 0x00000000,
+	0x01c0, 0x02000000,
+	0x01c4, 0x00000000,
+	0x01c8, 0x00000000,
+	0x01cc, 0xe6407800,
+	0x01d0, 0x78000000,
+	0x01d4, 0x010408d2,
+	0x01d8, 0x00000000,
+	0x01dc, 0x00000000,
+	0x01e4, 0x00005fff,
+	0x01e8, 0x00000000,
+	0x01ec, 0x00000000,
+	0x01f0, 0x00000000,
+	0x01f4, 0x00000000,
+	0x01f8, 0x00000000,
+	0x01fc, 0x02000000,
+	0x0200, 0x00000000,
+	0x0204, 0x00000000,
+	0x0208, 0x00000008,
+	0x020c, 0x0000000d,
+	0x41fc, 0x00000000,
+	0x4400, 0x00000000,
+	0x4410, 0x00000000,
+	0x4420, 0x00000000,
+	0x4430, 0x00000000,
+	0x4440, 0x00000000,
+	0x4450, 0x00000000,
+	0x4460, 0x00000000,
+	0x4470, 0x00000000,
+	0xf080, 0x00003018,
+	0xf084, 0x00000fff,
+	0xf800, 0x00000000,
+	0xf804, 0x00002e00,
+	0xf8d0, 0x00000001,
+	0xf8d4, 0x00000000,
+	0xff00, 0x00000301,
+	0xff0c, 0x01000000,
+	0xffe0, 0x00000000,
+	0xfff4, 0x00004011,
+	0x0090, 0x00000000,
+	0x0094, 0x00000000,
+	0x0098, 0x00000000,
+	0x009c, 0x3f3f3f3f,
+};
+
+#endif
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH V1 4/5] Add aw963xx series related interfaces to the aw_sar driver.
  2024-05-29 13:06 [PATCH V1 0/5] Add support for Awinic SAR sensor wangshuaijie
                   ` (2 preceding siblings ...)
  2024-05-29 13:06 ` [PATCH V1 3/5] Add aw9610x series related interfaces to " wangshuaijie
@ 2024-05-29 13:06 ` wangshuaijie
  2024-05-29 13:06 ` [PATCH V1 5/5] Add support for Awinic sar sensor wangshuaijie
  4 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-05-29 13:06 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, jeff, linux-input,
	devicetree, linux-kernel
  Cc: wangshuaijie, liweilei, kangjiajun

From: shuaijie wang <wangshuaijie@awinic.com>

Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
---
 drivers/input/misc/aw_sar/aw963xx/aw963xx.c | 986 ++++++++++++++++++++
 drivers/input/misc/aw_sar/aw963xx/aw963xx.h | 749 +++++++++++++++
 2 files changed, 1735 insertions(+)
 create mode 100644 drivers/input/misc/aw_sar/aw963xx/aw963xx.c
 create mode 100644 drivers/input/misc/aw_sar/aw963xx/aw963xx.h

diff --git a/drivers/input/misc/aw_sar/aw963xx/aw963xx.c b/drivers/input/misc/aw_sar/aw963xx/aw963xx.c
new file mode 100644
index 000000000000..4105756749d7
--- /dev/null
+++ b/drivers/input/misc/aw_sar/aw963xx/aw963xx.c
@@ -0,0 +1,986 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AWINIC sar sensor driver (aw963xx)
+ *
+ * Author: Shuaijie Wang<wangshuaijie@awinic.com>
+ *
+ * Copyright (c) 2024 awinic Technology CO., LTD
+ */
+#include "aw963xx.h"
+#include "../aw_sar.h"
+
+#define AW963XX_I2C_NAME "aw963xx_sar"
+
+static void aw963xx_set_cs_as_irq(struct aw_sar *p_sar, int flag);
+static void aw963xx_get_ref_ch_enable(struct aw_sar *p_sar);
+
+static int32_t aw963xx_read_init_over_irq(void *load_bin_para)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
+	uint32_t cnt = 1000;
+	uint32_t reg;
+	int32_t ret;
+
+	while (cnt--) {
+		ret = aw_sar_i2c_read(p_sar->i2c, REG_IRQSRC, &reg);
+		if (ret != 0) {
+			dev_err(p_sar->dev, "i2c error %d", ret);
+			return ret;
+		}
+		if ((reg & 0x01) == 0x01) {
+			aw_sar_i2c_read(p_sar->i2c, REG_FWVER, &reg);
+			return 0;
+		}
+		mdelay(1);
+	}
+
+	aw_sar_i2c_read(p_sar->i2c, REG_FWVER, &reg);
+
+	return -EINVAL;
+}
+
+static void aw963xx_convert_little_endian_2_big_endian(struct aw_bin *aw_bin)
+{
+	uint32_t start_index = aw_bin->header_info[0].valid_data_addr;
+	uint32_t fw_len = aw_bin->header_info[0].reg_num;
+	uint32_t uints = fw_len / AW963XX_SRAM_UPDATE_ONE_UINT_SIZE;
+	uint8_t tmp1;
+	uint8_t tmp2;
+	uint8_t tmp3;
+	uint8_t tmp4;
+	int i;
+
+	for (i = 0; i < uints; i++) {
+		tmp1 = aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE + 3];
+		tmp2 = aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE + 2];
+		tmp3 = aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE + 1];
+		tmp4 = aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE];
+		aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE]     = tmp1;
+		aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE + 1] = tmp2;
+		aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE + 2] = tmp3;
+		aw_bin->info.data[start_index + i * AW963XX_SRAM_UPDATE_ONE_UINT_SIZE + 3] = tmp4;
+	}
+}
+
+/**
+ * @brief  |----------------code ram-----------------|
+ *       0x2000                                    0x4fff
+ *         |--- app wrote here ---|--fill with 0xff--|
+ *
+ *         if the size of app is less than the size of code ram, the rest of the
+ *         ram is filled with 0xff.
+ * @param load_bin_para
+ * @param offset the rear addr of app
+ * @return int32_t
+ */
+static int32_t aw963xx_sram_fill_not_wrote_area(void *load_bin_para, uint32_t offset)
+{
+	uint32_t last_pack_len = (AW963XX_SRAM_END_ADDR - offset) %
+						AW963XX_SRAM_UPDATE_ONE_PACK_SIZE;
+	uint32_t pack_cnt = last_pack_len == 0 ?
+			((AW963XX_SRAM_END_ADDR - offset) / AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) :
+			((AW963XX_SRAM_END_ADDR - offset) / AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) + 1;
+	uint8_t buf[AW963XX_SRAM_UPDATE_ONE_PACK_SIZE + 2] = { 0 };
+	struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
+	uint32_t download_addr_with_ofst;
+	uint8_t *r_buf;
+	int32_t ret;
+	uint32_t i;
+
+	r_buf = devm_kzalloc(p_sar->dev, AW963XX_SRAM_UPDATE_ONE_PACK_SIZE, GFP_KERNEL);
+	if (!r_buf)
+		return -ENOMEM;
+
+	memset(buf, 0xff, sizeof(buf));
+	for (i = 0; i < pack_cnt; i++) {
+		memset(r_buf, 0, AW963XX_SRAM_UPDATE_ONE_PACK_SIZE);
+		download_addr_with_ofst = offset + i * AW963XX_SRAM_UPDATE_ONE_PACK_SIZE;
+		buf[0] = (uint8_t)(download_addr_with_ofst >> OFFSET_BIT_8);
+		buf[1] = (uint8_t)(download_addr_with_ofst);
+		if (i != (pack_cnt - 1)) {
+			ret = aw_sar_i2c_write_seq(p_sar->i2c, buf,
+					AW963XX_SRAM_UPDATE_ONE_PACK_SIZE + 2);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, write_seq error!", i);
+				devm_kfree(p_sar->dev, r_buf);
+				return ret;
+			}
+			ret = aw_sar_i2c_read_seq(p_sar->i2c, buf, 2, r_buf,
+					AW963XX_SRAM_UPDATE_ONE_PACK_SIZE);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, read_seq error!", i);
+				devm_kfree(p_sar->dev, r_buf);
+				return ret;
+			}
+			if (memcmp(&buf[2], r_buf, AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) != 0) {
+				dev_err(p_sar->dev, "read is not equal to write ");
+				devm_kfree(p_sar->dev, r_buf);
+				return -EINVAL;
+			}
+		} else {
+			ret = aw_sar_i2c_write_seq(p_sar->i2c, buf, last_pack_len + 2);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, write_seq error!", i);
+				devm_kfree(p_sar->dev, r_buf);
+				return ret;
+			}
+			ret = aw_sar_i2c_read_seq(p_sar->i2c, buf, 2, r_buf, last_pack_len);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, read_seq error!", i);
+				devm_kfree(p_sar->dev, r_buf);
+				return ret;
+			}
+			if (memcmp(&buf[2], r_buf, last_pack_len) != 0) {
+				dev_err(p_sar->dev, "read is not equal to write ");
+				devm_kfree(p_sar->dev, r_buf);
+				return -EINVAL;
+			}
+		}
+	}
+
+	devm_kfree(p_sar->dev, r_buf);
+
+	return 0;
+}
+
+static int32_t aw963xx_sram_data_write(struct aw_bin *aw_bin, void *load_bin_para)
+{
+	uint8_t buf[AW963XX_SRAM_UPDATE_ONE_PACK_SIZE + 2] = { 0 };
+	uint32_t start_index = aw_bin->header_info[0].valid_data_addr;
+	uint32_t fw_bin_version = aw_bin->header_info[0].app_version;
+	uint32_t download_addr = AW963XX_RAM_START_ADDR;
+	uint32_t fw_len = aw_bin->header_info[0].reg_num;
+	uint32_t last_pack_len = fw_len % AW963XX_SRAM_UPDATE_ONE_PACK_SIZE;
+	struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
+	uint32_t download_addr_with_ofst = 0;
+	uint32_t pack_cnt;
+	uint8_t *r_buf;
+	int32_t ret;
+	uint32_t i;
+
+	r_buf = devm_kzalloc(p_sar->dev, AW963XX_SRAM_UPDATE_ONE_PACK_SIZE, GFP_KERNEL);
+	if (!r_buf)
+		return -ENOMEM;
+
+	pack_cnt = ((fw_len % AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) == 0) ?
+			(fw_len / AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) :
+			(fw_len / AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) + 1;
+
+	dev_info(p_sar->dev, "fw_bin_version = 0x%x", fw_bin_version);
+	for (i = 0; i < pack_cnt; i++) {
+		memset(r_buf, 0, AW963XX_SRAM_UPDATE_ONE_PACK_SIZE);
+		download_addr_with_ofst = download_addr + i * AW963XX_SRAM_UPDATE_ONE_PACK_SIZE;
+		buf[0] = (uint8_t)(download_addr_with_ofst >> OFFSET_BIT_8);
+		buf[1] = (uint8_t)(download_addr_with_ofst);
+		if (i != (pack_cnt - 1)) {
+			memcpy(&buf[2], &aw_bin->info.data[start_index +
+					i * AW963XX_SRAM_UPDATE_ONE_PACK_SIZE],
+					AW963XX_SRAM_UPDATE_ONE_PACK_SIZE);
+			ret = aw_sar_i2c_write_seq(p_sar->i2c, buf,
+					AW963XX_SRAM_UPDATE_ONE_PACK_SIZE + 2);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, write_seq error!", i);
+				goto err_out;
+			}
+			ret = aw_sar_i2c_read_seq(p_sar->i2c, buf, 2, r_buf,
+					AW963XX_SRAM_UPDATE_ONE_PACK_SIZE);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, read_seq error!", i);
+				goto err_out;
+			}
+			if (memcmp(&buf[2], r_buf, AW963XX_SRAM_UPDATE_ONE_PACK_SIZE) != 0) {
+				dev_err(p_sar->dev, "read is not equal to write ");
+				ret = -EIO;
+				goto err_out;
+			}
+		} else { // last pack process
+			memcpy(&buf[2], &aw_bin->info.data[start_index +
+					i * AW963XX_SRAM_UPDATE_ONE_PACK_SIZE], last_pack_len);
+			ret = aw_sar_i2c_write_seq(p_sar->i2c, buf, last_pack_len + 2);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, write_seq error!", i);
+				goto err_out;
+			}
+			ret = aw_sar_i2c_read_seq(p_sar->i2c, buf, 2, r_buf, last_pack_len);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, read_seq error!", i);
+				goto err_out;
+			}
+			if (memcmp(&buf[2], r_buf, last_pack_len) != 0) {
+				dev_err(p_sar->dev, "read is not equal to write ");
+				ret = -EIO;
+				goto err_out;
+			}
+			/* fill 0xff in the area that not worte. */
+			ret = aw963xx_sram_fill_not_wrote_area(load_bin_para,
+					download_addr_with_ofst + last_pack_len);
+			if (ret != 0) {
+				dev_err(p_sar->dev, "cnt%d, sram_fill_not_wrote_area error!", i);
+				goto err_out;
+			}
+		}
+	}
+
+err_out:
+	devm_kfree(p_sar->dev, r_buf);
+
+	return ret;
+}
+
+static int32_t aw963xx_update_firmware(struct aw_bin *aw_bin, void *load_bin_para)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
+	struct aw963xx *aw963xx = (struct aw963xx *)p_sar->priv_data;
+	struct i2c_client *i2c = p_sar->i2c;
+	int32_t ret;
+
+	if (aw963xx->start_mode == AW963XX_ROM_MODE) {
+		dev_info(p_sar->dev, "no need to update fw.");
+		return 0;
+	}
+
+	//step1: close coderam shutdown mode
+	aw_sar_i2c_write(i2c, 0xfff4, 0x3c00d11f);
+	aw_sar_i2c_write(i2c, 0xc400, 0x21660000);
+
+	// step 2: reset mcu only and set boot mode to 1. (0xf800 0x00010100)
+	aw_sar_i2c_write(i2c, REG_CPU_MODE_SET, AW963XX_RESET_CPU_SET_BOOT_SATRT);
+
+	// step 3: enable data ram. (0xFFE4 0x3C000000)
+	aw_sar_i2c_write(i2c, REG_RAM_PASSWORD, AW963XX_NO_ENCRYPTION);
+
+	// setp 4: convert LD to BD
+	aw963xx_convert_little_endian_2_big_endian(aw_bin);
+
+	// step 5: write ram data.
+	ret = aw963xx_sram_data_write(aw_bin, load_bin_para);
+	if (ret == 0)
+		dev_info(p_sar->dev, "sram_data_write OK");
+	else
+		dev_err(p_sar->dev, "sram_data_write error");
+
+	mdelay(3);
+
+	// step 6: exit reset mcu and boot cpu in ram. (0xf800 0x00000100)
+	aw_sar_i2c_write(i2c, REG_CPU_MODE_SET, AW963XX_EXIT_RESET_CPU_SET_BOOT_SATRT);
+
+	// step 7: reset cpu (0xFF0C 0x0)
+	aw_sar_i2c_write(i2c, REG_CPU_RESET, AW963XX_RESET_SET);
+
+	//step 8: Wait for chip initialization to complete
+	msleep(AW963XX_CHIP_INIT_MAX_TIME_MS);
+
+	return aw963xx_read_init_over_irq(load_bin_para);
+}
+
+static int32_t aw963xx_load_reg_bin(struct aw_bin *aw_bin, void *load_bin_para)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)load_bin_para;
+	struct aw963xx *aw963xx = (struct aw963xx *)p_sar->priv_data;
+	int32_t ret;
+
+	dev_dbg(p_sar->dev, "reg chip name: %s, soc chip name: %s, len = %d",
+			p_sar->chip_name, aw_bin->header_info[0].chip_type, aw_bin->info.len);
+
+	ret = strncmp(p_sar->chip_name, aw_bin->header_info[0].chip_type,
+			sizeof(aw_bin->header_info[0].chip_type));
+	if (ret != 0)
+		dev_err(p_sar->dev, "load_binname(%s) incompatible with chip type(%s)",
+			p_sar->chip_name, aw_bin->header_info[0].chip_type);
+
+	p_sar->load_bin.bin_data_ver = aw_bin->header_info[0].bin_data_ver;
+
+	ret = aw_sar_load_reg(aw_bin, p_sar->i2c);
+
+	if (!strncmp(p_sar->chip_name, AW96308, sizeof(AW96308)) ||
+		!strncmp(p_sar->chip_name, AW96305BFOR, sizeof(AW96305BFOR))) {
+		dev_dbg(p_sar->dev, "set cs%d as irq", aw963xx->irq_mux);
+		aw963xx_set_cs_as_irq(p_sar, aw963xx->irq_mux);
+	}
+
+	return ret;
+}
+
+static void aw963xx_irq_handle_func(uint32_t irq_status, void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t ch_th[AW963XX_CHANNEL_NUM_MAX] = { 0 };
+	uint32_t curr_status_val[4] = { 0 };
+	int32_t ret;
+	int8_t i;
+	int8_t j;
+
+	if (((irq_status & 0x01) == 1) && (p_sar->driver_code_initover_flag == 1)) {
+		dev_dbg(p_sar->dev, "not healthy!");
+		p_sar->fault_flag = AW_SAR_UNHEALTHY;
+	}
+
+	for (i = 0; i < AW963XX_VALID_TH; i++)
+		ret = aw_sar_i2c_read(p_sar->i2c, REG_STAT0 + i * (REG_STAT1 - REG_STAT0),
+					&curr_status_val[i]);
+
+	for (j = 0; j < AW963XX_CHANNEL_NUM_MAX; j++) {
+		if (!p_sar->channels_arr[j].input)
+			continue;
+
+		for (i = 0; i < AW963XX_VALID_TH; i++)
+			ch_th[j] |= ((curr_status_val[i] >> j) & 0x01) << i;
+
+		if (p_sar->channels_arr[j].last_channel_info != ch_th[j]) {
+			if ((ch_th[j] >> 3 & 0x01) == 1) {	//th3
+				input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 4);
+			} else if ((ch_th[j] >> 2 & 0x01) == 1) { //th2
+				input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 3);
+			} else if ((ch_th[j] >> 1 & 0x01) == 1) { //th1
+				input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 2);
+			} else if ((ch_th[j] >> 0 & 0x01) == 1) { //th0
+				input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 1);
+			} else {	//far
+				input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 0);
+			}
+			input_sync(p_sar->channels_arr[j].input);
+			p_sar->channels_arr[j].last_channel_info = ch_th[j];
+		}
+	}
+}
+
+static ssize_t aw963xx_operation_mode_get(void *data, char *buf)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	ssize_t len = 0;
+
+	if (p_sar->last_mode == AW963XX_ACTIVE_MODE)
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Active\n");
+	else if (p_sar->last_mode == AW963XX_SLEEP_MODE)
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Sleep\n");
+	else if (p_sar->last_mode == AW963XX_DEEPSLEEP_MODE)
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: DeepSleep\n");
+	else
+		len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Unconfirmed\n");
+
+	return len;
+}
+
+static void aw963xx_sar_chip_info_get(void *data, char *buf, ssize_t *p_len)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t reg_data;
+
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len,
+			"sar%u\n", p_sar->dts_info.sar_num);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "The driver supports UI\n");
+
+	aw_sar_i2c_read(p_sar->i2c, REG_CHIP_ID0, &reg_data);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "chipid is 0x%08x\n", reg_data);
+
+	aw_sar_i2c_read(p_sar->i2c, REG_IRQEN, &reg_data);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "REG_HOSTIRQEN is 0x%08x\n", reg_data);
+
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "aw963xx Bin data version:0x%08x\n",
+			p_sar->load_bin.bin_data_ver);
+}
+
+static int32_t aw963xx_get_signed_cap(void *data, uint16_t reg_addr)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	int32_t s_ofst_c = 0;
+	uint32_t off_m_bit;
+	uint32_t off_c_bit;
+	uint32_t reg_data;
+	uint32_t off_c;
+	uint32_t off_m;
+	int32_t off_f;
+	uint32_t i;
+
+	aw_sar_i2c_read(p_sar->i2c, reg_addr, &reg_data);
+
+	off_f = ((reg_data >> AW_BIT16) & ONE_WORD) * AW963XX_STEP_LEN_UNSIGNED_CAP_FINE_ADJ;
+	off_c = (reg_data >> AW_BIT8) & ONE_WORD;
+	off_m = reg_data & ONE_WORD;
+
+	for (i = 0; i < 8; i++) {
+		off_m_bit = (off_m >> i) & 0x01;
+		off_c_bit = (off_c >> i) & 0x01;
+		s_ofst_c += ((1 - 2 * off_m_bit) * off_c_bit * aw_sar_pow2(i)) *
+			AW963XX_STEP_LEN_UNSIGNED_CAP_ROUGH_ADJ;
+	}
+
+	return (s_ofst_c + off_f);
+}
+
+static uint32_t aw963xx_get_unsigned_cap(void *data, uint16_t reg_addr)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t reg_data;
+	uint32_t rough;
+	uint32_t fine;
+
+	aw_sar_i2c_read(p_sar->i2c, reg_addr, &reg_data);
+
+	rough = ((reg_data >> AW_BIT8) & ONE_WORD) * AW963XX_STEP_LEN_UNSIGNED_CAP_ROUGH_ADJ;
+	fine = ((reg_data >> AW_BIT16) & ONE_WORD) * AW963XX_STEP_LEN_UNSIGNED_CAP_FINE_ADJ;
+
+	return (rough + fine);
+}
+
+static void aw963xx_get_ref_ch_enable(struct aw_sar *p_sar)
+{
+	struct aw963xx *aw963xx = (struct aw963xx *)p_sar->priv_data;
+	uint32_t refa_ch;
+	uint32_t refb_ch;
+	uint32_t reg_data;
+	int32_t i;
+
+	for (i = 0; i < AW963XX_CHANNEL_NUM_MAX; i++) {
+		aw_sar_i2c_read(p_sar->i2c,
+				REG_FILTCTRL0_CH0 +
+				i * (REG_FILTCTRL0_CH1 - REG_FILTCTRL0_CH0),
+				&reg_data);
+		if ((reg_data >> AW963XX_FILTCTRL0_CHX_REFAEN) & 0x01) {
+			refa_ch = (reg_data >> AW963XX_FILTCTRL0_CHX_REFASEL) & 0x1f;
+			aw963xx->ref_ch_en[refa_ch] = AW963XX_REF_EN;
+		}
+		if ((reg_data >> AW963XX_FILTCTRL0_CHX_REFBEN) & 0x01) {
+			refb_ch = (reg_data >> AW963XX_FILTCTRL0_CHX_REFBSEL) & 0x1f;
+			aw963xx->ref_ch_en[refb_ch] = AW963XX_REF_EN;
+		}
+	}
+}
+
+//Note: Because the kernel cannot handle floating-point types, it expands mul by 10 times
+static uint8_t aw963xx_get_offset_multiple(struct aw_sar *p_sar, uint8_t ch)
+{
+	uint32_t reg_data;
+	uint8_t mul = 1;
+
+	aw_sar_i2c_read(p_sar->i2c, REG_AFECFG2_CH0 + ch * (REG_AFECFG2_CH1 - REG_AFECFG2_CH0),
+			&reg_data);
+	if ((reg_data >> 27) & 0x1) {
+		if (((reg_data >> 29) & 0x3) == 0)
+			mul = 16;
+		else if (((reg_data >> 29) & 0x3) == 1)
+			mul = 20;
+		else if (((reg_data >> 29) & 0x3) == 2)
+			mul = 26;
+		else if (((reg_data >> 29) & 0x3) == 3)
+			mul = 40;
+		return mul;
+	}
+
+	aw_sar_i2c_read(p_sar->i2c, REG_AFECFG3_CH0 +
+			ch * (REG_AFECFG3_CH1 - REG_AFECFG3_CH0),
+			&reg_data);
+	if ((reg_data >> 11) & 0x1)
+		mul = 20;
+	else
+		mul = 10;
+
+	return mul;
+}
+
+static ssize_t aw963xx_get_cap_offset(void *data, char *buf)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw963xx *aw963xx = (struct aw963xx *)p_sar->priv_data;
+	int32_t signed_cap_ofst;
+	uint32_t mode = 0xff;
+	uint32_t reg_data;
+	uint32_t cap_ofst;
+	uint8_t mul = 10;
+	ssize_t len = 0;
+	uint32_t tmp;
+	uint32_t i;
+
+	aw963xx_get_ref_ch_enable(p_sar);
+
+	for (i = 0; i < AW963XX_CHANNEL_NUM_MAX; i++) {
+		aw_sar_i2c_read(p_sar->i2c,
+				REG_AFESOFTCFG0_CH0 +
+				i * (REG_AFESOFTCFG0_CH1 - REG_AFESOFTCFG0_CH0),
+				&reg_data);
+		mul = aw963xx_get_offset_multiple(p_sar, i);
+		mode = reg_data & 0x0ff;
+		switch (mode) {
+		case AW963XX_UNSIGNED_CAP:	//self-capacitance mode unsigned cail
+			cap_ofst = aw963xx_get_unsigned_cap(p_sar,
+				REG_AFECFG1_CH0 + i * (REG_AFECFG1_CH1 - REG_AFECFG1_CH0));
+		//Because it has been expanded by 1000 times before,
+		//the accuracy of removing mul's expansion loss can be ignored
+			cap_ofst = cap_ofst * mul / 10;
+			len += snprintf(buf + len, PAGE_SIZE - len,
+					"unsigned cap ofst ch%u: %u.%u pf\r\n",
+					i,
+					cap_ofst / AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE,
+					cap_ofst % AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE);
+			break;
+		case AW963XX_SIGNED_CAP:	//self-capacitance mode signed cail
+			signed_cap_ofst = aw963xx_get_signed_cap(p_sar,
+					REG_AFECFG1_CH0 + i * (REG_AFECFG1_CH1 - REG_AFECFG1_CH0));
+			signed_cap_ofst = signed_cap_ofst * mul / 10;
+			if (signed_cap_ofst < 0) {
+				tmp = -signed_cap_ofst;
+						dev_info(p_sar->dev, "cap_ofst2 = 0x%x",
+								signed_cap_ofst);
+				len += snprintf(buf + len, PAGE_SIZE - len,
+						"signed cap ofst ch%u: -%u.%upf\r\n",
+						i,
+						tmp / AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE,
+						tmp % AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE);
+			} else {
+				len += snprintf(buf + len, PAGE_SIZE - len,
+						"signed cap ofst ch%u: %d.%dpf\r\n",
+						i,
+						signed_cap_ofst /
+						AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE,
+						signed_cap_ofst %
+						AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE);
+			}
+			break;
+		case AW963XX_MUTUAL_CAP:	//mutual-capacitance mode
+			if (aw963xx->ref_ch_en[i] == AW963XX_REF_EN) {
+				cap_ofst = aw963xx_get_unsigned_cap(p_sar,
+					REG_AFECFG1_M_CH0 +
+					i * (REG_AFECFG1_M_CH1 - REG_AFECFG1_M_CH0));
+				cap_ofst = cap_ofst * mul / 10;
+				len += snprintf(buf + len, PAGE_SIZE - len,
+						"ref unsigned cap ofst ch%u: %u.%udpf\r\n",
+						i,
+						cap_ofst / AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE,
+						cap_ofst % AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE);
+			} else {
+				signed_cap_ofst = aw963xx_get_signed_cap(p_sar,
+							REG_AFECFG1_CH0 +
+							i * (REG_AFECFG1_CH1 - REG_AFECFG1_CH0));
+				signed_cap_ofst = signed_cap_ofst * mul / 10;
+				if (signed_cap_ofst < 0) {
+					tmp = -signed_cap_ofst;
+						dev_info(p_sar->dev,
+								"cap_ofst2 = 0x%x",
+								signed_cap_ofst);
+					len += snprintf(buf + len, PAGE_SIZE - len,
+							"mutual cap ofst ch%u: -%u.%udpf\r\n",
+							i,
+							tmp / AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE,
+							tmp % AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE);
+				} else {
+					len += snprintf(buf + len, PAGE_SIZE - len,
+							"mutual cap ofst ch%u: %d.%dpf\r\n",
+							i,
+							signed_cap_ofst /
+							AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE,
+							signed_cap_ofst %
+							AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE);
+				}
+			}
+			break;
+		default:
+			dev_info(p_sar->dev, "aw963xx ofst error 0x%x", reg_data & 0x0f);
+			break;
+		}
+	}
+
+	return len;
+}
+
+static void aw963xx_set_cs_as_irq(struct aw_sar *p_sar, int flag)
+{
+	if (flag == AW963XX_CS2_IRQ) {
+		aw_sar_i2c_write(p_sar->i2c, 0xfff4, 0x3c00d013);
+		aw_sar_i2c_write(p_sar->i2c, 0xc100, 0x00000020);
+		aw_sar_i2c_write(p_sar->i2c, 0xe018, 0x00000004);
+	} else if (flag == AW963XX_CS5_IRQ) {
+		aw_sar_i2c_write(p_sar->i2c, 0xfff4, 0x3c00d013);
+		aw_sar_i2c_write(p_sar->i2c, 0xc100, 0x00000800);
+		aw_sar_i2c_write(p_sar->i2c, 0xe018, 0x00000020);
+	} else {
+		aw_sar_i2c_write(p_sar->i2c, 0xfff4, 0x3c00d013);
+		aw_sar_i2c_write(p_sar->i2c, 0xc100, 0x00000000);
+		aw_sar_i2c_write(p_sar->i2c, 0xe018, 0x00000000);
+	}
+}
+
+int32_t aw963xx_check_chipid(void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t reg_val;
+	int32_t ret;
+
+	if (!p_sar)
+		return -EINVAL;
+
+	ret = aw_sar_i2c_read(p_sar->i2c, REG_CHIP_ID0, &reg_val);
+	if (ret < 0) {
+		dev_err(p_sar->dev, "read CHIP ID failed: %d", ret);
+		return ret;
+	}
+
+	switch (reg_val) {
+	case AW96303_CHIP_ID:
+		dev_info(p_sar->dev, "aw96303 detected, 0x%04x", reg_val);
+		memcpy(p_sar->chip_name, AW96303, 8);
+		ret = 0;
+		break;
+	case AW96305_CHIP_ID:
+		dev_info(p_sar->dev, "aw96305 detected, 0x%04x", reg_val);
+		memcpy(p_sar->chip_name, AW96305, 8);
+		ret = 0;
+		break;
+	case AW96305BFOR_CHIP_ID:
+		dev_info(p_sar->dev, "aw96305bfor detected, 0x%04x", reg_val);
+		memcpy(p_sar->chip_name, AW96305BFOR, 8);
+		ret = 0;
+		break;
+	case AW96308_CHIP_ID:
+		dev_info(p_sar->dev, "aw96308 detected, 0x%04x", reg_val);
+		memcpy(p_sar->chip_name, AW96308, 8);
+		ret = 0;
+		break;
+	case AW96310_CHIP_ID:
+		dev_info(p_sar->dev, "aw96310 detected, 0x%04x", reg_val);
+		memcpy(p_sar->chip_name, AW96310, 8);
+		ret = 0;
+		break;
+	default:
+		dev_info(p_sar->dev, "chip id error, 0x%04x", reg_val);
+		ret =  -EIO;
+		break;
+	}
+
+	return ret;
+}
+
+/**********************mode operation start*******************************/
+static void aw963xx_enable_clock(void *i2c)
+{
+	aw_sar_i2c_write_bits(i2c, REG_CHIPSTAT, ~AW963XX_CPU_OSC_CTRL_MASK,
+			AW963XX_CPU_OSC_CTRL_MASK);
+}
+
+static uint32_t aw963xx_rc_irqscr(void *i2c)
+{
+	uint32_t val;
+
+	aw_sar_i2c_read(i2c, REG_IRQSRC, &val);
+
+	return val;
+}
+
+static void aw963xx_set_active_cmd(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_CMD, AW963XX_ACTIVE_MODE);
+}
+
+static void aw963xx_set_sleep_cmd(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_CMD, AW963XX_SLEEP_MODE);
+}
+
+static void aw963xx_set_deepsleep_cmd(void *i2c)
+{
+	aw_sar_i2c_write(i2c, REG_CMD, AW963XX_DEEPSLEEP_MODE);
+}
+
+static const struct aw_sar_mode_set_t g_aw963xx_mode_set[] = {
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_ACTIVE_MODE,
+			.last_mode = AW963XX_DEEPSLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = aw963xx_enable_clock,
+			.rc_irqscr = NULL,
+			.mode_update = aw963xx_set_active_cmd,
+		},
+	},
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_ACTIVE_MODE,
+			.last_mode = AW963XX_SLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = aw963xx_set_active_cmd,
+		},
+	},
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_ACTIVE_MODE,
+			.last_mode = AW963XX_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = NULL,
+			.mode_update = aw963xx_set_active_cmd,
+		},
+	},
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_SLEEP_MODE,
+			.last_mode = AW963XX_DEEPSLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = aw963xx_enable_clock,
+			.rc_irqscr = aw963xx_rc_irqscr,
+			.mode_update = aw963xx_set_sleep_cmd,
+		},
+	},
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_SLEEP_MODE,
+			.last_mode = AW963XX_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = aw963xx_rc_irqscr,
+			.mode_update = aw963xx_set_sleep_cmd,
+		},
+	},
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_DEEPSLEEP_MODE,
+			.last_mode = AW963XX_SLEEP_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = aw963xx_rc_irqscr,
+			.mode_update = aw963xx_set_deepsleep_cmd,
+		},
+	},
+	{
+		.chip_id = AW_SAR_NONE_CHECK_CHIP,
+		.chip_mode = {
+			.curr_mode = AW963XX_DEEPSLEEP_MODE,
+			.last_mode = AW963XX_ACTIVE_MODE,
+		},
+		.mode_switch_ops = {
+			.enable_clock = NULL,
+			.rc_irqscr = aw963xx_rc_irqscr,
+			.mode_update = aw963xx_set_deepsleep_cmd,
+		},
+	},
+};
+
+static void aw963xx_sar_get_firmware_info(void *data, char *buf, ssize_t *p_len)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t reg_data;
+
+	aw_sar_i2c_read(p_sar->i2c, REG_FWVER, &reg_data);
+	*p_len += snprintf(buf + *p_len, PAGE_SIZE - *p_len, "firmware is 0x%08x\n", reg_data);
+}
+
+static int32_t aw963xx_parse_dts(void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	struct aw963xx *aw963xx = (struct aw963xx *)p_sar->priv_data;
+	struct device_node *np = p_sar->i2c->dev.of_node;
+	int32_t val;
+
+	val = of_property_read_u32(np, "irq-mux", &aw963xx->irq_mux);
+	if (val != 0)
+		dev_err(p_sar->dev, "irq-mux not detected");
+	else
+		dev_info(p_sar->dev, "irq-mux =  %d", aw963xx->irq_mux);
+
+	val = of_property_read_u32(np, "start-mode", &aw963xx->start_mode);
+	if (val != 0)
+		dev_err(p_sar->dev, "start-mode not detected");
+	else
+		dev_info(p_sar->dev, "start-mode =  %d", aw963xx->start_mode);
+
+	return 0;
+}
+
+static const struct aw_sar_mode_t g_aw963xx_mode = {
+	.mode_set_arr = &g_aw963xx_mode_set[0],
+	.mode_set_arr_len = ARRAY_SIZE(g_aw963xx_mode_set),
+	.p_set_mode_node_fn = NULL,
+	.p_get_mode_node_fn = aw963xx_operation_mode_get,
+};
+
+static const struct aw_sar_diff_t g_aw963xx_diff = {
+	.diff0_reg = REG_DIFF_CH0,
+	.diff_step = REG_DIFF_CH1 - REG_DIFF_CH0,
+	.rm_float = AW963XX_DATA_PROCESS_FACTOR,
+	.p_get_diff_node_fn = NULL,
+};
+
+static const struct aw_sar_offset_t g_aw963xx_offset = {
+	.p_get_offset_node_fn = aw963xx_get_cap_offset,
+};
+
+static const struct aw_sar_aot_t g_aw963xx_aot = {
+	.aot_reg = REG_SCANCTRL1,
+	.aot_mask = ~0xfff,
+	.aot_flag = 0xfff,
+};
+
+static const struct aw_sar_para_load_t g_aw963xx_reg_arr_para = {
+	.reg_arr = aw963xx_reg_default,
+	.reg_arr_len = ARRAY_SIZE(aw963xx_reg_default),
+};
+
+static const struct aw_sar_regulator_config_t g_regulator_config = {
+	.vcc_name = "vcc",
+	.min_uV = AW963XX_SAR_VCC_MIN_UV,
+	.max_uV = AW963XX_SAR_VCC_MAX_UV,
+};
+
+static const struct aw_sar_reg_list_t g_aw963xx_reg_list = {
+	.reg_none_access = REG_NONE_ACCESS,
+	.reg_rd_access = REG_RD_ACCESS,
+	.reg_wd_access = REG_WR_ACCESS,
+	.reg_perm = (struct aw_sar_reg_data *)&g_aw963xx_reg_access[0],
+	.reg_num = ARRAY_SIZE(g_aw963xx_reg_access),
+};
+
+static const struct aw_sar_chip_mode_t g_aw963xx_chip_mode = {
+	.init_mode = AW963XX_ACTIVE_MODE,
+	.active = AW963XX_ACTIVE_MODE,
+	.pre_init_mode = AW963XX_SLEEP_MODE,
+};
+
+static const struct aw_sar_load_bin_t g_aw963xx_load_reg_bin = {
+	.bin_name = "aw963xx_reg",
+	.bin_opera_func = aw963xx_load_reg_bin,
+	.p_update_fn = NULL,
+};
+
+static const struct aw_sar_load_bin_t g_aw963xx_load_fw_bin = {
+	.bin_name = "aw963xx_fw",
+	.bin_opera_func = aw963xx_update_firmware,
+	.p_get_prot_update_fw_node_fn = aw963xx_sar_get_firmware_info,
+	.bin_load_fail_opera = NULL,
+};
+
+static const struct aw_sar_get_chip_info_t g_aw963xx_get_chip_info = {
+	.p_get_chip_info_node_fn = aw963xx_sar_chip_info_get,
+};
+
+static const struct aw_sar_check_chipid_t g_aw963xx_check_chipid = {
+	.p_check_chipid_fn = aw963xx_check_chipid,
+};
+
+static const struct aw_sar_irq_init_t g_aw963xx_irq_init = {
+	.flags = GPIOF_DIR_IN | GPIOF_INIT_HIGH,
+	.irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+	.handler = NULL,
+	.thread_fn = NULL,
+	.rc_irq_fn = aw963xx_rc_irqscr,
+	.irq_spec_handler_fn = aw963xx_irq_handle_func,
+
+	.p_irq_init_fn = NULL,
+	.p_irq_deinit_fn = NULL,
+};
+
+static const struct aw_sar_soft_rst_t g_aw963xx_soft_rst = {
+	.reg_rst = REG_SA_RSTNALL,
+	.reg_rst_val = AW963XX_SOFT_RST_EN,
+	.delay_ms = AW963XX_CHIP_INIT_MAX_TIME_MS,
+	.p_soft_reset_fn = NULL,
+};
+
+static const struct aw_sar_init_over_irq_t g_aw963xx_init_over_irq = {
+	.wait_times = 100,
+	.daley_step = 1,
+	.reg_irqsrc = REG_IRQSRC,
+	.irq_offset_bit = 0,
+	.irq_mask = 0x1,
+	.irq_flag = 0x1,
+
+	.p_check_init_over_irq_fn = NULL,
+	.p_get_err_type_fn = NULL,
+};
+
+static const struct aw_sar_pm_t g_aw963xx_pm_chip_mode = {
+	.suspend_set_mode = AW963XX_SLEEP_MODE,
+	.resume_set_mode = AW963XX_ACTIVE_MODE,
+	.shutdown_set_mode = AW963XX_SLEEP_MODE,
+};
+
+static const struct aw_sar_platform_config g_aw963xx_platform_config = {
+	.p_add_parse_dts_fn = &aw963xx_parse_dts,
+	.p_regulator_config = &g_regulator_config,
+	.p_irq_init = &g_aw963xx_irq_init,
+	.p_pm_chip_mode = &g_aw963xx_pm_chip_mode,
+};
+
+static void aw963xx_power_on_prox_detection(void *data, uint8_t en_flag)
+{
+
+}
+
+static const struct aw_sar_power_on_prox_detection_t g_aw933xx_power_on_prox_detection = {
+	.p_power_on_prox_detection_en_fn = aw963xx_power_on_prox_detection,
+	.irq_en_cali_bit = 3,
+	.power_on_prox_en_flag = true,
+};
+
+static const struct aw_sar_chip_config g_aw963xx_chip_config = {
+	.ch_num_max = AW963XX_CHANNEL_NUM_MAX,
+	.p_platform_config = &g_aw963xx_platform_config,
+
+	.p_check_chipid = &g_aw963xx_check_chipid,
+	.p_soft_rst = &g_aw963xx_soft_rst,
+	.p_init_over_irq = &g_aw963xx_init_over_irq,
+	.p_fw_bin = &g_aw963xx_load_fw_bin,
+	.p_reg_bin = &g_aw963xx_load_reg_bin,
+	.p_chip_mode = &g_aw963xx_chip_mode,
+
+	//Node usage parameters
+	.p_reg_list = &g_aw963xx_reg_list,
+	.p_reg_arr = &g_aw963xx_reg_arr_para,
+	.p_aot = &g_aw963xx_aot,
+	.p_diff = &g_aw963xx_diff,
+	.p_offset = &g_aw963xx_offset,
+	.p_mode = &g_aw963xx_mode,
+	.p_prox_fw = &g_aw963xx_load_fw_bin,
+	.p_get_chip_info = &g_aw963xx_get_chip_info,
+	.p_aw_sar_awrw = NULL,
+	.p_boot_bin = NULL,
+
+	.p_other_operation = NULL,
+	.p_other_opera_free = NULL,
+
+	.power_on_prox_detection = &g_aw933xx_power_on_prox_detection,
+};
+
+int32_t aw963xx_init(struct aw_sar *p_sar)
+{
+	struct aw963xx *aw963xx;
+
+	if (!p_sar)
+		return -EINVAL;
+
+	p_sar->priv_data = devm_kzalloc(p_sar->dev, sizeof(struct aw963xx), GFP_KERNEL);
+	if (!p_sar->priv_data)
+		return -ENOMEM;
+
+	//Chip private function operation
+	p_sar->p_sar_para = &g_aw963xx_chip_config;
+
+	aw963xx = (struct aw963xx *)p_sar->priv_data;
+
+	return 0;
+}
+
+void aw963xx_deinit(struct aw_sar *p_sar)
+{
+	struct aw963xx *aw963xx;
+
+	if ((!p_sar) || (!p_sar->priv_data))
+		return;
+
+	aw963xx = (struct aw963xx *)p_sar->priv_data;
+
+
+	if (p_sar->priv_data != NULL)
+		devm_kfree(p_sar->dev, p_sar->priv_data);
+}
diff --git a/drivers/input/misc/aw_sar/aw963xx/aw963xx.h b/drivers/input/misc/aw_sar/aw963xx/aw963xx.h
new file mode 100644
index 000000000000..a9ebbf2334b2
--- /dev/null
+++ b/drivers/input/misc/aw_sar/aw963xx/aw963xx.h
@@ -0,0 +1,749 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef AW963XX_H_
+#define AW963XX_H_
+#include "../comm/aw_sar_type.h"
+
+#define AW963XX_CHANNEL_NUM_MAX				(12)
+#define AW963XX_VALID_TH				(2)
+#define AW963XX_DATA_PROCESS_FACTOR			(1024)
+#define AW963XX_SAR_VCC_MIN_UV				(1700000)
+#define AW963XX_SAR_VCC_MAX_UV				(3600000)
+#define AW963XX_SRAM_UPDATE_ONE_PACK_SIZE		(1024)
+#define AW963XX_SRAM_UPDATE_ONE_UINT_SIZE		(4)
+#define AW963XX_SRAM_START_ADDR				(0x2000)
+#define AW963XX_SRAM_END_ADDR				(0x4ff4 + 4)
+#define AW963XX_SRAM_SIZE	(AW963XX_SRAM_END_ADDR - AW963XX_SRAM_START_ADDR)
+
+#define AW963XX_STEP_LEN_UNSIGNED_CAP_ROUGH_ADJ		(9900)
+#define AW963XX_STEP_LEN_UNSIGNED_CAP_FINE_ADJ		(152)
+#define AW963XX_STEP_LEN_UNSIGNED_CAP_ENLARGE		(10000)
+
+#define AW963XX_CPU_OSC_CTRL_MASK			(1)
+
+#define ONE_WORD					(0xff)
+#define AW_BIT8						(8)
+#define AW_BIT16					(16)
+#define AW96303						("AW96303")
+#define AW96305						("AW96305")
+#define AW96305BFOR					("AW96305BFOR")
+#define AW96308						("AW96308")
+#define AW96310						("AW96310")
+
+enum aw963xx_cap_mode {
+	AW963XX_UNSIGNED_CAP = 0,
+	AW963XX_SIGNED_CAP = 4,
+	AW963XX_MUTUAL_CAP = 5,
+};
+
+enum aw963xx_approach_state {
+	AW963XX_FAR_AWAY = 0,
+	AW963XX_APPROACH = 1,
+};
+
+enum aw963xx_cs_2_irq {
+	AW963XX_CS2_IRQ = 2,
+	AW963XX_CS5_IRQ = 5,
+};
+
+enum aw963xx_operation_mode {
+	AW963XX_ACTIVE_MODE = 0x01,
+	AW963XX_SLEEP_MODE = 0x02,
+	AW963XX_DEEPSLEEP_MODE = 0x03,
+};
+
+enum aw963xx_chip_id {
+	AW96303_CHIP_ID = 0xA9630340,
+	AW96305_CHIP_ID = 0xA9630520,
+	AW96305BFOR_CHIP_ID = 0xA9630500,
+	AW96308_CHIP_ID = 0xA9630810,
+	AW96310_CHIP_ID = 0xA9631010,
+};
+
+enum aw963xx_boot_mode {
+	AW963XX_ROM_MODE = 0,
+	AW963XX_RAM_MODE = 1,
+};
+
+struct aw963xx {
+	uint32_t irq_mux;
+	uint32_t start_mode;
+	uint32_t ref_ch_en[AW963XX_CHANNEL_NUM_MAX];
+	void *p_aw_sar;
+
+	uint32_t last_blfilta[AW963XX_CHANNEL_NUM_MAX];
+	uint32_t last_irq_en;
+
+};
+
+#define REG_CPU_MODE_SET				(0xf800)
+#define AW963XX_RESET_CPU_SET_BOOT_SATRT		(0x00010100)
+#define AW963XX_EXIT_RESET_CPU_SET_BOOT_SATRT		(0x00000100)
+#define REG_CPU_RESET					(0XFF0C)
+#define AW963XX_RESET_SET				(0)
+#define REG_RAM_PASSWORD				(0xFFE4)
+#define AW963XX_NO_ENCRYPTION				(0x3C000000)
+#define AW963XX_FILTCTRL0_CHX_REFAEN			(16)
+#define AW963XX_FILTCTRL0_CHX_REFASEL			(11)
+#define AW963XX_FILTCTRL0_CHX_REFBEN			(9)
+#define AW963XX_FILTCTRL0_CHX_REFBSEL			(4)
+#define AW963XX_REF_EN					(1)
+#define REG_SA_RSTNALL					(0xFF0C)
+#define AW963XX_SOFT_RST_EN				(0)
+#define AW963XX_CHIP_INIT_MAX_TIME_MS			(30)
+
+#define AW963XX_RAM_START_ADDR				(0x2000)
+
+#define AFE_BASE_ADDR					(0x0000)
+#define DSP_BASE_ADDR					(0x0000)
+#define STAT_BASE_ADDR					(0x0000)
+#define DATA_BASE_ADDR					(0x0000)
+#define SFR_BASE_ADDR					(0x0000)
+#define HIDDEN_BASE_ADDR				(0x0000)
+
+#define REG_STAT0					((0x0020) + STAT_BASE_ADDR)
+#define REG_STAT1					((0x0024) + STAT_BASE_ADDR)
+#define REG_FWVER					((0x005C) + STAT_BASE_ADDR)
+
+#define REG_DIFF_CH0					((0x01EC) + DATA_BASE_ADDR)
+#define REG_DIFF_CH1					((0x0304) + DATA_BASE_ADDR)
+
+#define REG_FILTCTRL0_CH0				((0x0130) + DSP_BASE_ADDR)
+#define REG_FILTCTRL0_CH1				((0x0248) + DSP_BASE_ADDR)
+
+#define REG_SCANCTRL1					((0x0004) + AFE_BASE_ADDR)
+#define REG_AFESOFTCFG0_CH0				((0x010C) + AFE_BASE_ADDR)
+#define REG_AFECFG1_CH0					((0x0118) + AFE_BASE_ADDR)
+#define REG_AFECFG3_CH0					((0x0120) + AFE_BASE_ADDR)
+#define REG_AFESOFTCFG0_CH1				((0x0224) + AFE_BASE_ADDR)
+#define REG_AFECFG1_CH1					((0x0230) + AFE_BASE_ADDR)
+#define REG_AFECFG3_CH1					((0x0238) + AFE_BASE_ADDR)
+
+#define REG_AFECFG1_M_CH0				((0x10F8) + HIDDEN_BASE_ADDR)
+#define REG_AFECFG1_M_CH1				((0x1184) + HIDDEN_BASE_ADDR)
+
+#define REG_IRQSRC					((0xF080) + SFR_BASE_ADDR)
+#define REG_IRQEN					((0xF084) + SFR_BASE_ADDR)
+#define REG_CHIPSTAT					((0xFF00) + SFR_BASE_ADDR)
+#define REG_CHIP_ID0					((0xFF10) + SFR_BASE_ADDR)
+
+#define	REG_CMD						((0xf008) + SFR_BASE_ADDR)
+#define REG_AFECFG2_CH0					((0x011c) + AFE_BASE_ADDR)
+#define REG_AFECFG2_CH1					((0x0234) + AFE_BASE_ADDR)
+
+struct reg_data {
+	unsigned char rw;
+	unsigned short reg;
+};
+/********************************************
+ * Register Access
+ *******************************************/
+#define REG_NONE_ACCESS					(0)
+#define REG_RD_ACCESS					(1 << 0)
+#define REG_WR_ACCESS					(1 << 1)
+static const struct reg_data g_aw963xx_reg_access[] = {
+	{ .reg = REG_SCANCTRL1,			.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFESOFTCFG0_CH0,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG1_CH0,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG3_CH0,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFESOFTCFG0_CH1,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG1_CH1,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG3_CH1,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_STAT0,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_STAT1,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_FWVER,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_DIFF_CH0,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_DIFF_CH1,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_FILTCTRL0_CH0,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_FILTCTRL0_CH1,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG1_M_CH0,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_AFECFG1_M_CH1,		.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_IRQSRC,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_IRQEN,			.rw = REG_RD_ACCESS | REG_WR_ACCESS, },
+	{ .reg = REG_CHIPSTAT,			.rw = REG_RD_ACCESS, },
+	{ .reg = REG_CHIP_ID0,			.rw = REG_RD_ACCESS, },
+};
+static const uint32_t aw963xx_reg_default[] = {
+	0x0000, 0x000000FF,
+	0x0004, 0x00000FFF,
+	0x0008, 0x00000FFF,
+	0x000C, 0x00000064,
+	0x0010, 0x0000705F,
+	0x0014, 0x80000000,
+	0x0060, 0x00000000,
+	0x0064, 0x00000000,
+	0x0068, 0x00000000,
+	0x006C, 0x00000000,
+	0x0070, 0x00000000,
+	0x0074, 0x00000000,
+	0x0078, 0x00000000,
+	0x007C, 0x00000000,
+	0x0080, 0x00000000,
+	0x0084, 0x00000000,
+	0x0088, 0x00000000,
+	0x008C, 0x00000000,
+	0x0168, 0x00000000,
+	0x016C, 0x003F0000,
+	0x0170, 0x00050100,
+	0x0174, 0x00000000,
+	0x0178, 0x341C9207,
+	0x017C, 0x00008000,
+	0x0180, 0x00000909,
+	0x0184, 0x00000001,
+	0x0188, 0x00000000,
+	0x0318, 0x00000000,
+	0x031C, 0x003F0000,
+	0x0320, 0x00050100,
+	0x0324, 0x00000000,
+	0x0328, 0x341C9207,
+	0x032C, 0x00008000,
+	0x0330, 0x00000909,
+	0x0334, 0x00000008,
+	0x0338, 0x00000000,
+	0x04C8, 0x00000000,
+	0x04CC, 0x003F0000,
+	0x04D0, 0x00050100,
+	0x04D4, 0x00000000,
+	0x04D8, 0x341C9207,
+	0x04DC, 0x00008000,
+	0x04E0, 0x00000909,
+	0x04E4, 0x00000040,
+	0x04E8, 0x00000000,
+	0x0678, 0x00000000,
+	0x067C, 0x003F0000,
+	0x0680, 0x00050100,
+	0x0684, 0x00000000,
+	0x0688, 0x341C9207,
+	0x068C, 0x00008000,
+	0x0690, 0x00000909,
+	0x0694, 0x00000200,
+	0x0698, 0x00000000,
+	0x0828, 0x00000000,
+	0x082C, 0x003F0000,
+	0x0830, 0x00050100,
+	0x0834, 0x00000000,
+	0x0838, 0x341C9207,
+	0x083C, 0x00008000,
+	0x0840, 0x00000909,
+	0x0844, 0x00001000,
+	0x0848, 0x00000000,
+	0x09D8, 0x00000000,
+	0x09DC, 0x003F0000,
+	0x09E0, 0x00050100,
+	0x09E4, 0x00000000,
+	0x09E8, 0x341C9207,
+	0x09EC, 0x00008000,
+	0x09F0, 0x00000909,
+	0x09F4, 0x00008000,
+	0x09F8, 0x00000000,
+	0x0B88, 0x00000000,
+	0x0B8C, 0x003F0000,
+	0x0B90, 0x00050100,
+	0x0B94, 0x00000000,
+	0x0B98, 0x341C9207,
+	0x0B9C, 0x00008000,
+	0x0BA0, 0x00000909,
+	0x0BA4, 0x00040000,
+	0x0BA8, 0x00000000,
+	0x0D38, 0x00000000,
+	0x0D3C, 0x003F0000,
+	0x0D40, 0x00050100,
+	0x0D44, 0x00000000,
+	0x0D48, 0x341C9207,
+	0x0D4C, 0x00008000,
+	0x0D50, 0x00000909,
+	0x0D54, 0x00200000,
+	0x0D58, 0x00000000,
+	0x0EE8, 0x00000000,
+	0x0EEC, 0x003F0000,
+	0x0EF0, 0x00050100,
+	0x0EF4, 0x00000000,
+	0x0EF8, 0x341C9207,
+	0x0EFC, 0x00008000,
+	0x0F00, 0x00000909,
+	0x0F04, 0x00000000,
+	0x0F08, 0x00000000,
+	0x1098, 0x00000000,
+	0x109C, 0x003F0000,
+	0x10A0, 0x00050100,
+	0x10A4, 0x00000000,
+	0x10A8, 0x341C9207,
+	0x10AC, 0x00008000,
+	0x10B0, 0x00000909,
+	0x10B4, 0x00000000,
+	0x10B8, 0x00000000,
+	0x1248, 0x00000000,
+	0x124C, 0x003F0000,
+	0x1250, 0x00050100,
+	0x1254, 0x00000000,
+	0x1258, 0x341C9207,
+	0x125C, 0x00008000,
+	0x1260, 0x00000909,
+	0x1264, 0x00000000,
+	0x1268, 0x00000000,
+	0x13F8, 0x00000000,
+	0x13FC, 0x003F0000,
+	0x1400, 0x00050100,
+	0x1404, 0x00000000,
+	0x1408, 0x341C9207,
+	0x140C, 0x00008000,
+	0x1410, 0x00000909,
+	0x1414, 0x00000000,
+	0x1418, 0x00000000,
+	0x018C, 0xE0400000,
+	0x0190, 0x00000000,
+	0x0194, 0x00000000,
+	0x0198, 0x000A0000,
+	0x019C, 0x000008D2,
+	0x01A0, 0x00000000,
+	0x01A4, 0x00000040,
+	0x01A8, 0x000186A0,
+	0x01AC, 0x00030D40,
+	0x01B0, 0x00061A80,
+	0x01B4, 0x000C3500,
+	0x01B8, 0x00000000,
+	0x01BC, 0x00000000,
+	0x01C0, 0x00000000,
+	0x01C4, 0x00000000,
+	0x01C8, 0x00000000,
+	0x01CC, 0x00000000,
+	0x033C, 0xE0400000,
+	0x0340, 0x00000000,
+	0x0344, 0x00000000,
+	0x0348, 0x000A0000,
+	0x034C, 0x000008D2,
+	0x0350, 0x00000000,
+	0x0354, 0x00000040,
+	0x0358, 0x000186A0,
+	0x035C, 0x00030D40,
+	0x0360, 0x00061A80,
+	0x0364, 0x000C3500,
+	0x0368, 0x00000000,
+	0x036C, 0x00000000,
+	0x0370, 0x00000000,
+	0x0374, 0x00000000,
+	0x0378, 0x00000000,
+	0x037C, 0x00000000,
+	0x04EC, 0xE0400000,
+	0x04F0, 0x00000000,
+	0x04F4, 0x00000000,
+	0x04F8, 0x000A0000,
+	0x04FC, 0x000008D2,
+	0x0500, 0x00000000,
+	0x0504, 0x00000040,
+	0x0508, 0x000186A0,
+	0x050C, 0x00030D40,
+	0x0510, 0x00061A80,
+	0x0514, 0x000C3500,
+	0x0518, 0x00000000,
+	0x051C, 0x00000000,
+	0x0520, 0x00000000,
+	0x0524, 0x00000000,
+	0x0528, 0x00000000,
+	0x052C, 0x00000000,
+	0x069C, 0xE0400000,
+	0x06A0, 0x00000000,
+	0x06A4, 0x00000000,
+	0x06A8, 0x000A0000,
+	0x06AC, 0x000008D2,
+	0x06B0, 0x00000000,
+	0x06B4, 0x00000040,
+	0x06B8, 0x000186A0,
+	0x06BC, 0x00030D40,
+	0x06C0, 0x00061A80,
+	0x06C4, 0x000C3500,
+	0x06C8, 0x00000000,
+	0x06CC, 0x00000000,
+	0x06D0, 0x00000000,
+	0x06D4, 0x00000000,
+	0x06D8, 0x00000000,
+	0x06DC, 0x00000000,
+	0x084C, 0xE0400000,
+	0x0850, 0x00000000,
+	0x0854, 0x00000000,
+	0x0858, 0x000A0000,
+	0x085C, 0x000008D2,
+	0x0860, 0x00000000,
+	0x0864, 0x00000040,
+	0x0868, 0x000186A0,
+	0x086C, 0x00030D40,
+	0x0870, 0x00061A80,
+	0x0874, 0x000C3500,
+	0x0878, 0x00000000,
+	0x087C, 0x00000000,
+	0x0880, 0x00000000,
+	0x0884, 0x00000000,
+	0x0888, 0x00000000,
+	0x088C, 0x00000000,
+	0x09FC, 0xE0400000,
+	0x0A00, 0x00000000,
+	0x0A04, 0x00000000,
+	0x0A08, 0x000A0000,
+	0x0A0C, 0x000008D2,
+	0x0A10, 0x00000000,
+	0x0A14, 0x00000040,
+	0x0A18, 0x000186A0,
+	0x0A1C, 0x00030D40,
+	0x0A20, 0x00061A80,
+	0x0A24, 0x000C3500,
+	0x0A28, 0x00000000,
+	0x0A2C, 0x00000000,
+	0x0A30, 0x00000000,
+	0x0A34, 0x00000000,
+	0x0A38, 0x00000000,
+	0x0A3C, 0x00000000,
+	0x0BAC, 0xE0400000,
+	0x0BB0, 0x00000000,
+	0x0BB4, 0x00000000,
+	0x0BB8, 0x000A0000,
+	0x0BBC, 0x000008D2,
+	0x0BC0, 0x00000000,
+	0x0BC4, 0x00000040,
+	0x0BC8, 0x000186A0,
+	0x0BCC, 0x00030D40,
+	0x0BD0, 0x00061A80,
+	0x0BD4, 0x000C3500,
+	0x0BD8, 0x00000000,
+	0x0BDC, 0x00000000,
+	0x0BE0, 0x00000000,
+	0x0BE4, 0x00000000,
+	0x0BE8, 0x00000000,
+	0x0BEC, 0x00000000,
+	0x0D5C, 0xE0400000,
+	0x0D60, 0x00000000,
+	0x0D64, 0x00000000,
+	0x0D68, 0x000A0000,
+	0x0D6C, 0x000008D2,
+	0x0D70, 0x00000000,
+	0x0D74, 0x00000040,
+	0x0D78, 0x000186A0,
+	0x0D7C, 0x00030D40,
+	0x0D80, 0x00061A80,
+	0x0D84, 0x000C3500,
+	0x0D88, 0x00000000,
+	0x0D8C, 0x00000000,
+	0x0D90, 0x00000000,
+	0x0D94, 0x00000000,
+	0x0D98, 0x00000000,
+	0x0D9C, 0x00000000,
+	0x0F0C, 0xE0400000,
+	0x0F10, 0x00000000,
+	0x0F14, 0x00000000,
+	0x0F18, 0x000A0000,
+	0x0F1C, 0x000008D2,
+	0x0F20, 0x00000000,
+	0x0F24, 0x00000040,
+	0x0F28, 0x000186A0,
+	0x0F2C, 0x00000000,
+	0x0F30, 0x00000000,
+	0x0F34, 0x00000000,
+	0x0F38, 0x00000000,
+	0x0F3C, 0x00000000,
+	0x0F40, 0x00000000,
+	0x0F44, 0x00000000,
+	0x0F48, 0x00000000,
+	0x0F4C, 0x00000000,
+	0x10BC, 0xE0400000,
+	0x10C0, 0x00000000,
+	0x10C4, 0x00000000,
+	0x10C8, 0x000A0000,
+	0x10CC, 0x000008D2,
+	0x10D0, 0x00000000,
+	0x10D4, 0x00000040,
+	0x10D8, 0x00000000,
+	0x10DC, 0x00000000,
+	0x10E0, 0x00000000,
+	0x10E4, 0x00000000,
+	0x10E8, 0x00000000,
+	0x10EC, 0x00000000,
+	0x10F0, 0x00000000,
+	0x10F4, 0x00000000,
+	0x10F8, 0x00000000,
+	0x10FC, 0x00000000,
+	0x126C, 0xE0400000,
+	0x1270, 0x00000000,
+	0x1274, 0x00000000,
+	0x1278, 0x000A0000,
+	0x127C, 0x000008D2,
+	0x1280, 0x00000000,
+	0x1284, 0x00000040,
+	0x1288, 0x00000000,
+	0x128C, 0x00000000,
+	0x1290, 0x00000000,
+	0x1294, 0x00000000,
+	0x1298, 0x00000000,
+	0x129C, 0x00000000,
+	0x12A0, 0x00000000,
+	0x12A4, 0x00000000,
+	0x12A8, 0x00000000,
+	0x12AC, 0x00000000,
+	0x141C, 0xE0400000,
+	0x1420, 0x00000000,
+	0x1424, 0x00000000,
+	0x1428, 0x000A0000,
+	0x142C, 0x000008D2,
+	0x1430, 0x00000000,
+	0x1434, 0x00000040,
+	0x1438, 0x00000000,
+	0x143C, 0x00000000,
+	0x1440, 0x00000000,
+	0x1444, 0x00000000,
+	0x1448, 0x00000000,
+	0x144C, 0x00000000,
+	0x1450, 0x00000000,
+	0x1454, 0x00000000,
+	0x1458, 0x00000000,
+	0x145C, 0x00000000,
+	0x01D0, 0x00000000,
+	0x01D4, 0x00000000,
+	0x01D8, 0x00000000,
+	0x01DC, 0x00000000,
+	0x01E0, 0x00000000,
+	0x01E4, 0xFFFFFFFF,
+	0x01E8, 0x00000000,
+	0x01EC, 0x00000000,
+	0x01F0, 0x00000000,
+	0x01F4, 0x00000000,
+	0x01F8, 0x070004B0,
+	0x01FC, 0x0E000000,
+	0x0200, 0xF2000000,
+	0x0204, 0x02000000,
+	0x0208, 0x02000000,
+	0x020C, 0x00002000,
+	0x0210, 0x00010000,
+	0x0214, 0x80007530,
+	0x0220, 0x00000000,
+	0x0224, 0x00000000,
+	0x0380, 0x00000000,
+	0x0384, 0x00000000,
+	0x0388, 0x00000000,
+	0x038C, 0x00000000,
+	0x0390, 0x00000000,
+	0x0394, 0xFFFFFFFF,
+	0x0398, 0x00000000,
+	0x039C, 0x00000000,
+	0x03A0, 0x00000000,
+	0x03A4, 0x00000000,
+	0x03A8, 0x070004B0,
+	0x03AC, 0x0E000000,
+	0x03B0, 0xF2000000,
+	0x03B4, 0x02000000,
+	0x03B8, 0x02000000,
+	0x03BC, 0x00002000,
+	0x03C0, 0x00010000,
+	0x03C4, 0x80007530,
+	0x03D0, 0x00000000,
+	0x03D4, 0x00000000,
+	0x0530, 0x00000000,
+	0x0534, 0x00000000,
+	0x0538, 0x00000000,
+	0x053C, 0x00000000,
+	0x0540, 0x00000000,
+	0x0544, 0xFFFFFFFF,
+	0x0548, 0x00000000,
+	0x054C, 0x00000000,
+	0x0550, 0x00000000,
+	0x0554, 0x00000000,
+	0x0558, 0x070004B0,
+	0x055C, 0x0E000000,
+	0x0560, 0xF2000000,
+	0x0564, 0x02000000,
+	0x0568, 0x02000000,
+	0x056C, 0x00002000,
+	0x0570, 0x00010000,
+	0x0574, 0x80007530,
+	0x0580, 0x00000000,
+	0x0584, 0x00000000,
+	0x06E0, 0x00000000,
+	0x06E4, 0x00000000,
+	0x06E8, 0x00000000,
+	0x06EC, 0x00000000,
+	0x06F0, 0x00000000,
+	0x06F4, 0xFFFFFFFF,
+	0x06F8, 0x00000000,
+	0x06FC, 0x00000000,
+	0x0700, 0x00000000,
+	0x0704, 0x00000000,
+	0x0708, 0x070004B0,
+	0x070C, 0x0E000000,
+	0x0710, 0xF2000000,
+	0x0714, 0x02000000,
+	0x0718, 0x02000000,
+	0x071C, 0x00002000,
+	0x0720, 0x00010000,
+	0x0724, 0x80007530,
+	0x0730, 0x00000000,
+	0x0734, 0x00000000,
+	0x0890, 0x00000000,
+	0x0894, 0x00000000,
+	0x0898, 0x00000000,
+	0x089C, 0x00000000,
+	0x08A0, 0x00000000,
+	0x08A4, 0xFFFFFFFF,
+	0x08A8, 0x00000000,
+	0x08AC, 0x00000000,
+	0x08B0, 0x00000000,
+	0x08B4, 0x00000000,
+	0x08B8, 0x070004B0,
+	0x08BC, 0x0E000000,
+	0x08C0, 0xF2000000,
+	0x08C4, 0x02000000,
+	0x08C8, 0x02000000,
+	0x08CC, 0x00002000,
+	0x08D0, 0x00010000,
+	0x08D4, 0x80007530,
+	0x08E0, 0x00000000,
+	0x08E4, 0x00000000,
+	0x0A40, 0x00000000,
+	0x0A44, 0x00000000,
+	0x0A48, 0x00000000,
+	0x0A4C, 0x00000000,
+	0x0A50, 0x00000000,
+	0x0A54, 0xFFFFFFFF,
+	0x0A58, 0x00000000,
+	0x0A5C, 0x00000000,
+	0x0A60, 0x00000000,
+	0x0A64, 0x00000000,
+	0x0A68, 0x070004B0,
+	0x0A6C, 0x0E000000,
+	0x0A70, 0xF2000000,
+	0x0A74, 0x02000000,
+	0x0A78, 0x02000000,
+	0x0A7C, 0x00002000,
+	0x0A80, 0x00010000,
+	0x0A84, 0x80007530,
+	0x0A90, 0x00000000,
+	0x0A94, 0x00000000,
+	0x0BF0, 0x00000000,
+	0x0BF4, 0x00000000,
+	0x0BF8, 0x00000000,
+	0x0BFC, 0x00000000,
+	0x0C00, 0x00000000,
+	0x0C04, 0xFFFFFFFF,
+	0x0C08, 0x00000000,
+	0x0C0C, 0x00000000,
+	0x0C10, 0x00000000,
+	0x0C14, 0x00000000,
+	0x0C18, 0x070004B0,
+	0x0C1C, 0x0E000000,
+	0x0C20, 0xF2000000,
+	0x0C24, 0x02000000,
+	0x0C28, 0x02000000,
+	0x0C2C, 0x00002000,
+	0x0C30, 0x00010000,
+	0x0C34, 0x80007530,
+	0x0C40, 0x00000000,
+	0x0C44, 0x00000000,
+	0x0DA0, 0x00000000,
+	0x0DA4, 0x00000000,
+	0x0DA8, 0x00000000,
+	0x0DAC, 0x00000000,
+	0x0DB0, 0x00000000,
+	0x0DB4, 0xFFFFFFFF,
+	0x0DB8, 0x00000000,
+	0x0DBC, 0x00000000,
+	0x0DC0, 0x00000000,
+	0x0DC4, 0x00000000,
+	0x0DC8, 0x070004B0,
+	0x0DCC, 0x0E000000,
+	0x0DD0, 0xF2000000,
+	0x0DD4, 0x02000000,
+	0x0DD8, 0x02000000,
+	0x0DDC, 0x00002000,
+	0x0DE0, 0x00010000,
+	0x0DE4, 0x80007530,
+	0x0DF0, 0x00000000,
+	0x0DF4, 0x00000000,
+	0x0F50, 0x00000000,
+	0x0F54, 0x00000000,
+	0x0F58, 0x00000000,
+	0x0F5C, 0x00000000,
+	0x0F60, 0x00000000,
+	0x0F64, 0xFFFFFFFF,
+	0x0F68, 0x00000000,
+	0x0F6C, 0x00000000,
+	0x0F70, 0x00000000,
+	0x0F74, 0x00000000,
+	0x0F78, 0x070004B0,
+	0x0F7C, 0x0E000000,
+	0x0F80, 0xF2000000,
+	0x0F84, 0x02000000,
+	0x0F88, 0x02000000,
+	0x0F8C, 0x00002000,
+	0x0F90, 0x00010000,
+	0x0F94, 0x80007530,
+	0x0FA0, 0x00000000,
+	0x0FA4, 0x00000000,
+	0x1100, 0x00000000,
+	0x1104, 0x00000000,
+	0x1108, 0x00000000,
+	0x110C, 0x00000000,
+	0x1110, 0x00000000,
+	0x1114, 0xFFFFFFFF,
+	0x1118, 0x00000000,
+	0x111C, 0x00000000,
+	0x1120, 0x00000000,
+	0x1124, 0x00000000,
+	0x1128, 0x070004B0,
+	0x112C, 0x0E000000,
+	0x1130, 0xF2000000,
+	0x1134, 0x02000000,
+	0x1138, 0x02000000,
+	0x113C, 0x00002000,
+	0x1140, 0x00010000,
+	0x1144, 0x80007530,
+	0x1150, 0x00000000,
+	0x1154, 0x00000000,
+	0x12B0, 0x00000000,
+	0x12B4, 0x00000000,
+	0x12B8, 0x00000000,
+	0x12BC, 0x00000000,
+	0x12C0, 0x00000000,
+	0x12C4, 0xFFFFFFFF,
+	0x12C8, 0x00000000,
+	0x12CC, 0x00000000,
+	0x12D0, 0x00000000,
+	0x12D4, 0x00000000,
+	0x12D8, 0x070004B0,
+	0x12DC, 0x0E000000,
+	0x12E0, 0xF2000000,
+	0x12E4, 0x02000000,
+	0x12E8, 0x02000000,
+	0x12EC, 0x00002000,
+	0x12F0, 0x00010000,
+	0x12F4, 0x80007530,
+	0x1300, 0x00000000,
+	0x1304, 0x00000000,
+	0x1460, 0x00000000,
+	0x1464, 0x00000000,
+	0x1468, 0x00000000,
+	0x146C, 0x00000000,
+	0x1470, 0x00000000,
+	0x1474, 0xFFFFFFFF,
+	0x1478, 0x00000000,
+	0x147C, 0x00000000,
+	0x1480, 0x00000000,
+	0x1484, 0x00000000,
+	0x1488, 0x070004B0,
+	0x148C, 0x0E000000,
+	0x1490, 0xF2000000,
+	0x1494, 0x02000000,
+	0x1498, 0x02000000,
+	0x149C, 0x00002000,
+	0x14A0, 0x00010000,
+	0x14A4, 0x80007530,
+	0x14B0, 0x00000000,
+	0x14B4, 0x00000000,
+	0xF084, 0x00000006,
+	0x004C, 0xFFFFFFFF,
+	0x0050, 0xFFFFFFFF,
+	0x0054, 0xFFFFFFFF,
+	0x0058, 0xFFFFFFFF,
+	0x0090, 0x00000000,
+	0x0094, 0x00000064,
+	0x0098, 0x40000000,
+	0x009C, 0x00000000,
+	0x00A0, 0x00140014,
+	0x00A4, 0x0019000D,
+	0x00A8, 0x0096004B,
+};
+#endif
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-29 13:06 [PATCH V1 0/5] Add support for Awinic SAR sensor wangshuaijie
                   ` (3 preceding siblings ...)
  2024-05-29 13:06 ` [PATCH V1 4/5] Add aw963xx " wangshuaijie
@ 2024-05-29 13:06 ` wangshuaijie
  2024-05-29 22:49   ` kernel test robot
                     ` (2 more replies)
  4 siblings, 3 replies; 16+ messages in thread
From: wangshuaijie @ 2024-05-29 13:06 UTC (permalink / raw)
  To: dmitry.torokhov, robh, krzk+dt, conor+dt, jeff, linux-input,
	devicetree, linux-kernel
  Cc: wangshuaijie, liweilei, kangjiajun

From: shuaijie wang <wangshuaijie@awinic.com>

Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
---
 drivers/input/misc/Kconfig         |    9 +
 drivers/input/misc/Makefile        |    1 +
 drivers/input/misc/aw_sar/Makefile |    2 +
 drivers/input/misc/aw_sar/aw_sar.c | 2039 ++++++++++++++++++++++++++++
 drivers/input/misc/aw_sar/aw_sar.h |   15 +
 5 files changed, 2066 insertions(+)
 create mode 100644 drivers/input/misc/aw_sar/Makefile
 create mode 100644 drivers/input/misc/aw_sar/aw_sar.c
 create mode 100644 drivers/input/misc/aw_sar/aw_sar.h

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 6ba984d7f0b1..ac56fdd21839 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -939,4 +939,13 @@ config INPUT_STPMIC1_ONKEY
 	  To compile this driver as a module, choose M here: the
 	  module will be called stpmic1_onkey.
 
+config AWINIC_SAR
+	tristate "Awinic sar sensor support"
+	depends on I2C
+	help
+	  Say Y to enable support for the Awinic sar sensor driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called awinic_sar.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 04296a4abe8e..6ee1870ea677 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -90,3 +90,4 @@ obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
 obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
 obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
 obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR)	+= ideapad_slidebar.o
+obj-$(CONFIG_AWINIC_SAR)		+= aw_sar/
diff --git a/drivers/input/misc/aw_sar/Makefile b/drivers/input/misc/aw_sar/Makefile
new file mode 100644
index 000000000000..c357ecaa4f98
--- /dev/null
+++ b/drivers/input/misc/aw_sar/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_AWINIC_SAR) += awinic_sar.o
+awinic_sar-objs := ./comm/aw_sar_comm_interface.o aw_sar.o ./aw9610x/aw9610x.o ./aw963xx/aw963xx.o
diff --git a/drivers/input/misc/aw_sar/aw_sar.c b/drivers/input/misc/aw_sar/aw_sar.c
new file mode 100644
index 000000000000..c0c37658a482
--- /dev/null
+++ b/drivers/input/misc/aw_sar/aw_sar.c
@@ -0,0 +1,2039 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AWINIC sar sensor driver
+ *
+ * Author: Shuaijie Wang<wangshuaijie@awinic.com>
+ *
+ * Copyright (c) 2024 awinic Technology CO., LTD
+ */
+#include "./comm/aw_sar_chip_interface.h"
+#include "aw_sar.h"
+
+#define AW_SAR_I2C_NAME		"awinic_sar"
+
+/*
+ * Please check which power_supply on your platform
+ * can get the charger insertion information, then select it.
+ * eg: "usb"/"charger"/"mtk-master-charger"/"mtk_charger_type"
+ */
+#define USB_POWER_SUPPLY_NAME   "charger"
+/*
+ * Check which of your power_supply properties is available
+ * for the charger insertion information and select it.
+ * eg: POWER_SUPPLY_PROP_ONLINE/POWER_SUPPLY_PROP_PRESENT
+ */
+#define AW_USB_PROP_ONLINE	POWER_SUPPLY_PROP_ONLINE
+
+#define AW_I2C_RW_RETRY_TIME_MIN		(2000)
+#define AW_I2C_RW_RETRY_TIME_MAX		(3000)
+#define AW_RETRIES				(5)
+
+#define AW_SAR_AWRW_OffSET			(20)
+#define AW_SAR_AWRW_DATA_WIDTH			(5)
+#define AW_DATA_OffSET_2			(2)
+#define AW_DATA_OffSET_3			(3)
+#define AW_POWER_ON_SYSFS_DELAY_MS		(5000)
+#define AW_SAR_MONITOR_ESD_DELAY_MS		(5000)
+#define AW_SAR_OFFSET_LEN			(15)
+#define AW_SAR_VCC_MIN_UV			(1700000)
+#define AW_SAR_VCC_MAX_UV			(3600000)
+
+static struct mutex aw_sar_lock;
+
+static int32_t aw_sar_get_chip_info(struct aw_sar *p_sar);
+static void aw_sar_sensor_free(struct aw_sar *p_sar);
+
+//Because disable/enable_irq api Therefore, IRQ is embedded
+void aw_sar_disable_irq(struct aw_sar *p_sar)
+{
+	if (p_sar->irq_init.host_irq_stat == IRQ_ENABLE) {
+		disable_irq(p_sar->irq_init.to_irq);
+		p_sar->irq_init.host_irq_stat = IRQ_DISABLE;
+	}
+}
+
+void aw_sar_enable_irq(struct aw_sar *p_sar)
+{
+	if (p_sar->irq_init.host_irq_stat == IRQ_DISABLE) {
+		enable_irq(p_sar->irq_init.to_irq);
+		p_sar->irq_init.host_irq_stat = IRQ_ENABLE;
+	}
+}
+
+//Chip logic part start
+//Load default array function
+static int32_t
+aw_sar_para_loaded_func(struct i2c_client *i2c, const struct aw_sar_para_load_t *para_load)
+{
+	int32_t ret;
+	int32_t i;
+
+	for (i = 0; i < para_load->reg_arr_len; i = i + 2) {
+		ret = aw_sar_i2c_write(i2c, (uint16_t)para_load->reg_arr[i],
+						para_load->reg_arr[i + 1]);
+		if (ret != 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+//Mode setting function
+static void aw_sar_mode_set_func(struct i2c_client *i2c, int to_irq,
+		struct aw_sar_mode_set_t *mode_set_para,
+		const struct aw_sar_mode_set_t *mode_set, uint8_t len)
+{
+	uint8_t i;
+
+	for (i = 0; i < len; i++) {
+		if ((mode_set[i].chip_mode.curr_mode == mode_set_para->chip_mode.curr_mode) &&
+				(mode_set[i].chip_mode.last_mode == mode_set_para->chip_mode.last_mode) &&
+				((mode_set[i].chip_id == AW_SAR_NONE_CHECK_CHIP) ||
+				 ((mode_set[i].chip_id & mode_set_para->chip_id) != 0))) {
+			if (mode_set[i].mode_switch_ops.enable_clock != NULL)
+				mode_set[i].mode_switch_ops.enable_clock(i2c);
+			if (mode_set[i].mode_switch_ops.rc_irqscr != NULL)
+				mode_set[i].mode_switch_ops.rc_irqscr(i2c);
+			if (mode_set[i].mode_switch_ops.mode_update != NULL)
+				mode_set[i].mode_switch_ops.mode_update(i2c);
+			break;
+		}
+	}
+}
+
+static int32_t aw_sar_check_init_over_irq_func(struct i2c_client *i2c,
+					const struct aw_sar_init_over_irq_t *p_check_irq)
+{
+	int16_t cnt = p_check_irq->wait_times;
+	uint32_t irq_stat;
+	int32_t ret;
+
+	do {
+		ret = aw_sar_i2c_read(i2c, p_check_irq->reg_irqsrc, &irq_stat);
+		if (ret < 0)
+			return ret;
+		if (((irq_stat >> p_check_irq->irq_offset_bit) & p_check_irq->irq_mask) ==
+				p_check_irq->irq_flag)
+			return 0;
+		mdelay(1);
+	} while (cnt--);
+
+	if (cnt < 0)
+		dev_err(&i2c->dev, "init over irq error!");
+
+	return AW_ERR_IRQ_INIT_OVER;
+}
+
+static int32_t
+aw_sar_soft_reset_func(struct i2c_client *i2c, const struct aw_sar_soft_rst_t *p_soft_rst)
+{
+	int32_t ret;
+
+	ret = aw_sar_i2c_write(i2c, p_soft_rst->reg_rst, p_soft_rst->reg_rst_val);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "soft_reset error: %d", ret);
+		return ret;
+	}
+
+	msleep(p_soft_rst->delay_ms);
+
+	return 0;
+}
+//Chip logic part end
+
+static int32_t aw_sar_parse_bin(const struct firmware *cont, struct aw_sar *p_sar)
+{
+	enum aw_bin_err_val bin_ret;
+	struct aw_bin *aw_bin;
+	int32_t ret;
+
+	if (!cont) {
+		dev_err(p_sar->dev, "def_reg_bin request error!");
+		return -EINVAL;
+	}
+
+	dev_dbg(p_sar->dev, "Bin file size: %d", (uint32_t)cont->size);
+
+	aw_bin = devm_kzalloc(p_sar->dev, cont->size + sizeof(struct aw_bin), GFP_KERNEL);
+	if (!aw_bin) {
+		release_firmware(cont);
+		dev_err(p_sar->dev, "failed to allcating memory!");
+		return -ENOMEM;
+	}
+
+	aw_bin->info.len = cont->size;
+	memcpy(aw_bin->info.data, cont->data, cont->size);
+
+	bin_ret = aw_sar_parsing_bin_file(aw_bin);
+	if (bin_ret < 0) {
+		dev_err(p_sar->dev, "parse bin fail! bin_ret = %d", bin_ret);
+		goto err;
+	}
+
+	//Write bin file execution process
+	if (p_sar->load_bin.bin_opera_func != NULL) {
+		ret = p_sar->load_bin.bin_opera_func(aw_bin, p_sar);
+		if (ret != 0) {
+			dev_err(p_sar->dev, "load_bin_to_chip error!");
+			if (p_sar->load_bin.bin_load_fail_opera_func != NULL) {
+				ret = p_sar->load_bin.bin_load_fail_opera_func(aw_bin, p_sar);
+				if (ret != 0) {
+					dev_err(p_sar->dev, "bin_load_fail_opera_func error!");
+					goto err;
+				}
+			} else {
+				goto err;
+			}
+		}
+	} else {
+		dev_err(p_sar->dev, "bin_opera_func is null error!");
+	}
+
+	if (aw_bin != NULL)
+		devm_kfree(p_sar->dev, aw_bin);
+
+	return 0;
+err:
+	if (aw_bin != NULL)
+		devm_kfree(p_sar->dev, aw_bin);
+
+	return -EINVAL;
+}
+
+static int32_t aw_sar_load_bin_comm(struct aw_sar *p_sar)
+{
+	const struct firmware *fw;
+	int32_t ret;
+
+	ret = request_firmware(&fw, p_sar->load_bin.bin_name, p_sar->dev);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "parse %s error!", p_sar->load_bin.bin_name);
+		return ret;
+	}
+
+	ret = aw_sar_parse_bin(fw, p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "reg_bin %s load error!", p_sar->load_bin.bin_name);
+		return ret;
+	}
+	release_firmware(fw);
+
+	return 0;
+}
+
+static int32_t aw_sar_parse_dts_comm(struct device *dev, struct device_node *np,
+		struct aw_sar_dts_info *p_dts_info)
+{
+	int32_t val;
+
+	val = of_property_read_u32(np, "sar-num", &p_dts_info->sar_num);
+	dev_info(dev, "sar num = %d", p_dts_info->sar_num);
+	if (val != 0) {
+		dev_err(dev, "multiple sar failed!");
+		return -EINVAL;
+	}
+
+	p_dts_info->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0);
+	if (p_dts_info->irq_gpio < 0) {
+		p_dts_info->irq_gpio = -1;
+		dev_err(dev, "no irq gpio provided.");
+		return -EINVAL;
+	}
+
+	val = of_property_read_u32(np, "channel_use_flag", &p_dts_info->channel_use_flag);
+	if (val != 0) {
+		dev_err(dev, "channel_use_flag failed!");
+		return -EINVAL;
+	}
+
+	//GPIO is set as internal pull-up input
+	p_dts_info->use_inter_pull_up = of_property_read_bool(np, "aw_sar,pin_set_inter_pull-up");
+	p_dts_info->use_pm = of_property_read_bool(np, "aw_sar,using_pm_ops");
+	p_dts_info->update_fw_flag = of_property_read_bool(np, "aw_sar,update_fw");
+	p_dts_info->use_plug_cail_flag = of_property_read_bool(np, "aw_sar,use_plug_cail");
+	p_dts_info->monitor_esd_flag = of_property_read_bool(np, "aw_sar,monitor_esd");
+
+	return 0;
+}
+
+static int32_t aw_sar_parse_dts(struct aw_sar *p_sar)
+{
+	int32_t ret;
+
+	ret = aw_sar_parse_dts_comm(p_sar->dev, p_sar->i2c->dev.of_node, &p_sar->dts_info);
+
+	//Special requirements of SAR chip
+	if (p_sar->p_sar_para->p_platform_config->p_add_parse_dts_fn != NULL)
+		ret |= p_sar->p_sar_para->p_platform_config->p_add_parse_dts_fn(p_sar);
+
+	return ret;
+}
+
+static irqreturn_t aw_sar_irq(int32_t irq, void *data)
+{
+	struct aw_sar *p_sar = (struct aw_sar *)data;
+	uint32_t irq_status;
+
+	//step1: read clear interrupt
+	if (p_sar->p_sar_para->p_platform_config->p_irq_init->rc_irq_fn != NULL)
+		irq_status = p_sar->p_sar_para->p_platform_config->p_irq_init->rc_irq_fn(p_sar->i2c);
+
+	//step2: Read the status register for status reporting
+	if (p_sar->p_sar_para->p_platform_config->p_irq_init->irq_spec_handler_fn != NULL)
+		p_sar->p_sar_para->p_platform_config->p_irq_init->irq_spec_handler_fn(irq_status,
+				p_sar);
+
+	//step3: The chip
+
+	if ((!p_sar->dts_info.monitor_esd_flag) && (p_sar->fault_flag == AW_SAR_UNHEALTHY)) {
+		p_sar->fault_flag = AW_SAR_HEALTHY;
+		disable_irq_nosync(p_sar->irq_init.to_irq);
+		p_sar->irq_init.host_irq_stat = IRQ_DISABLE;
+		//aw_sar_soft_reset(p_sar);
+		schedule_delayed_work(&p_sar->update_work, msecs_to_jiffies(500));
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int32_t aw_sar_irq_init_comm(struct aw_sar *p_sar, const struct aw_sar_irq_init_t *p_irq_init)
+{
+	irq_handler_t thread_fn = p_irq_init->thread_fn;
+	int32_t ret;
+
+	snprintf(p_sar->irq_init.label, sizeof(p_sar->irq_init.label),
+				"aw_sar%u_gpio", p_sar->dts_info.sar_num);
+	snprintf(p_sar->irq_init.dev_id, sizeof(p_sar->irq_init.dev_id),
+				"aw_sar%u_irq", p_sar->dts_info.sar_num);
+
+	if (gpio_is_valid(p_sar->dts_info.irq_gpio)) {
+		p_sar->irq_init.to_irq = gpio_to_irq(p_sar->dts_info.irq_gpio);
+		ret = devm_gpio_request_one(p_sar->dev,
+						p_sar->dts_info.irq_gpio,
+						p_irq_init->flags,
+						p_sar->irq_init.label);
+		if (ret) {
+			dev_err(p_sar->dev,
+				"request irq gpio failed, ret = %d", ret);
+			return ret;
+		}
+		if (!thread_fn)
+			thread_fn = aw_sar_irq;
+		ret = devm_request_threaded_irq(p_sar->dev,
+				p_sar->irq_init.to_irq,
+				p_irq_init->handler,
+				thread_fn,
+				p_irq_init->irq_flags,
+				p_sar->irq_init.dev_id,
+				p_sar);
+		if (ret != 0) {
+			dev_err(p_sar->dev,
+					"failed to request IRQ %d: %d",
+					p_sar->irq_init.to_irq, ret);
+			return ret;
+		}
+	} else {
+		dev_err(p_sar->dev, "irq gpio invalid!");
+		return -EINVAL;
+	}
+
+	p_sar->irq_init.host_irq_stat = IRQ_DISABLE;
+	disable_irq(p_sar->irq_init.to_irq);
+
+	return 0;
+}
+
+static int32_t aw_sar_irq_init(struct aw_sar *p_sar)
+{
+
+	if (!p_sar->p_sar_para->p_platform_config->p_irq_init) {
+		dev_err(p_sar->dev, "AW_INVALID_PARA");
+		return -EINVAL;
+	}
+
+	if (p_sar->p_sar_para->p_platform_config->p_irq_init->p_irq_init_fn != NULL) {
+		dev_err(p_sar->dev, "p_irq_init_fn");
+		return p_sar->p_sar_para->p_platform_config->p_irq_init->p_irq_init_fn(p_sar);
+	}
+
+	return aw_sar_irq_init_comm(p_sar, p_sar->p_sar_para->p_platform_config->p_irq_init);
+}
+
+static void aw_sar_irq_free(struct aw_sar *p_sar)
+{
+	if ((p_sar->p_sar_para->p_platform_config != NULL) &&
+		(p_sar->p_sar_para->p_platform_config->p_irq_init != NULL) &&
+		(p_sar->p_sar_para->p_platform_config->p_irq_init->p_irq_deinit_fn != NULL)) {
+		p_sar->p_sar_para->p_platform_config->p_irq_init->p_irq_deinit_fn(p_sar);
+		dev_err(p_sar->dev, "AW_INVALID_PARA");
+		return;
+	}
+}
+
+static int32_t aw_sar_input_init_comm(struct aw_sar *p_sar)
+{
+	int32_t ret;
+	uint32_t i;
+
+	p_sar->channels_arr = devm_kzalloc(p_sar->dev,
+				sizeof(struct aw_channels_info) *
+				p_sar->p_sar_para->ch_num_max,
+				GFP_KERNEL);
+	if (!p_sar->channels_arr) {
+		dev_err(p_sar->dev, "devm_kzalloc err");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < p_sar->p_sar_para->ch_num_max; i++) {
+		snprintf(p_sar->channels_arr[i].name,
+				sizeof(p_sar->channels_arr->name),
+				"aw_sar%u_ch%ud",
+				p_sar->dts_info.sar_num, i);
+
+		p_sar->channels_arr[i].last_channel_info = 0;
+
+		if ((p_sar->dts_info.channel_use_flag >> i) & 0x01) {
+			p_sar->channels_arr[i].used = AW_TRUE;
+			p_sar->channels_arr[i].input = devm_input_allocate_device(p_sar->dev);
+			if (!p_sar->channels_arr[i].input)
+				return -EINVAL;
+			p_sar->channels_arr[i].input->name = p_sar->channels_arr[i].name;
+			input_set_abs_params(p_sar->channels_arr[i].input,
+						ABS_DISTANCE, -1, 100, 0, 0);
+			ret = input_register_device(p_sar->channels_arr[i].input);
+			if (ret) {
+				dev_err(p_sar->dev, "failed to register input device");
+				return ret;
+			}
+		} else {
+			p_sar->channels_arr[i].used = AW_FALSE;
+			p_sar->channels_arr[i].input = NULL;
+		}
+	}
+
+	return 0;
+}
+
+static int32_t aw_sar_input_init(struct aw_sar *p_sar)
+{
+	if (p_sar->p_sar_para->p_platform_config->p_input_init_fn != NULL)
+		return p_sar->p_sar_para->p_platform_config->p_input_init_fn(p_sar);
+
+	return aw_sar_input_init_comm(p_sar);
+}
+
+static void aw_sar_input_free(struct aw_sar *p_sar)
+{
+	if ((p_sar->p_sar_para->p_platform_config != NULL) &&
+		(p_sar->p_sar_para->p_platform_config->p_input_deinit_fn != NULL)) {
+		p_sar->p_sar_para->p_platform_config->p_input_deinit_fn(p_sar);
+	}
+}
+
+static int32_t aw_sar_check_init_over_irq_comm(struct aw_sar *p_sar)
+{
+	int32_t ret;
+
+	if (!p_sar->p_sar_para->p_init_over_irq)
+		return -EINVAL;
+
+	ret = aw_sar_check_init_over_irq_func(p_sar->i2c, p_sar->p_sar_para->p_init_over_irq);
+	if (ret == AW_ERR_IRQ_INIT_OVER) {
+		if (p_sar->p_sar_para->p_init_over_irq->p_get_err_type_fn != NULL) {
+			//Consider the abnormality reasonable
+			if (p_sar->p_sar_para->p_init_over_irq->p_get_err_type_fn(p_sar) == 0) {
+				p_sar->fw_fail_flag = AW_TRUE;
+				return 0;
+			}
+		}
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+//If there is no special operation on the chip, execute the common process
+int32_t aw_sar_check_init_over_irq(struct aw_sar *p_sar)
+{
+	if (!p_sar->p_sar_para->p_init_over_irq)
+		return -EINVAL;
+
+	if (p_sar->p_sar_para->p_init_over_irq->p_check_init_over_irq_fn != NULL)
+		return p_sar->p_sar_para->p_init_over_irq->p_check_init_over_irq_fn(p_sar);
+
+	return aw_sar_check_init_over_irq_comm(p_sar);
+}
+
+static int32_t aw_sar_chip_other_operation(struct aw_sar *p_sar)
+{
+	if (p_sar->p_sar_para->p_other_operation != NULL)
+		return p_sar->p_sar_para->p_other_operation(p_sar);
+
+	return 0;
+}
+
+static void aw_sar_chip_other_operation_free(struct aw_sar *p_sar)
+{
+	if (p_sar->p_sar_para->p_other_opera_free != NULL)
+		p_sar->p_sar_para->p_other_opera_free(p_sar);
+}
+
+int32_t aw_sar_soft_reset(struct aw_sar *p_sar)
+{
+	if (!p_sar->p_sar_para->p_soft_rst)
+		return -EINVAL;
+
+	//If a private interface is defined, the private interface is used
+	if (p_sar->p_sar_para->p_soft_rst->p_soft_reset_fn != NULL)
+		return p_sar->p_sar_para->p_soft_rst->p_soft_reset_fn(p_sar);
+
+	return aw_sar_soft_reset_func(p_sar->i2c, p_sar->p_sar_para->p_soft_rst);
+}
+
+static int32_t aw_sar_check_chipid(struct aw_sar *p_sar)
+{
+	if (!p_sar->p_sar_para)
+		return -EINVAL;
+
+	if (p_sar->p_sar_para->p_check_chipid != NULL) {
+		if (p_sar->p_sar_para->p_check_chipid->p_check_chipid_fn != NULL)
+			return p_sar->p_sar_para->p_check_chipid->p_check_chipid_fn(p_sar);
+	}
+
+	return -EINVAL;
+}
+
+int32_t aw_sar_load_def_reg_bin(struct aw_sar *p_sar)
+{
+	if ((!p_sar->p_sar_para->p_reg_bin) ||
+		(!p_sar->p_sar_para->p_reg_bin->bin_name)) {
+		dev_err(p_sar->dev, "p_reg_bin is NULL or bin_name is NULL error");
+		p_sar->ret_val = AW_BIN_PARA_INVALID;
+		return -EINVAL;
+	}
+
+	snprintf(p_sar->load_bin.bin_name, sizeof(p_sar->load_bin.bin_name),
+			"%s_%u.bin", p_sar->p_sar_para->p_reg_bin->bin_name,
+			p_sar->dts_info.sar_num);
+
+	p_sar->load_bin.bin_opera_func = p_sar->p_sar_para->p_reg_bin->bin_opera_func;
+
+	return aw_sar_load_bin_comm(p_sar);
+}
+
+static int32_t aw_sar_para_loaded(struct aw_sar *p_sar)
+{
+	if (!p_sar->p_sar_para->p_reg_arr)
+		return -EINVAL;
+
+	aw_sar_para_loaded_func(p_sar->i2c, p_sar->p_sar_para->p_reg_arr);
+
+	return 0;
+}
+
+static int32_t aw_sar_reg_update_boot_work(struct aw_sar *p_sar)
+{
+	if ((!p_sar->p_sar_para->p_boot_bin) || (!p_sar->p_sar_para->p_boot_bin->bin_name))
+		return -EINVAL;
+
+	snprintf(p_sar->load_bin.bin_name, sizeof(p_sar->load_bin.bin_name),
+			"%s_%u.bin", p_sar->p_sar_para->p_boot_bin->bin_name,
+			p_sar->dts_info.sar_num);
+
+	p_sar->load_bin.bin_opera_func = p_sar->p_sar_para->p_boot_bin->bin_opera_func;
+
+	return aw_sar_load_bin_comm(p_sar);
+}
+
+static int32_t aw_sar_update_fw_para(struct aw_sar *p_sar, const struct aw_sar_load_bin_t *p_bin)
+{
+	if ((!p_bin) || (!p_bin->bin_name))
+		return -EINVAL;
+
+	p_sar->load_bin.bin_opera_func = p_bin->bin_opera_func;
+	p_sar->load_bin.bin_load_fail_opera_func = p_bin->bin_load_fail_opera;
+
+	snprintf(p_sar->load_bin.bin_name, sizeof(p_sar->load_bin.bin_name),
+			"%s_%u.bin", p_bin->bin_name, p_sar->dts_info.sar_num);
+
+	return 0;
+}
+
+int32_t aw_sar_update_fw(struct aw_sar *p_sar)
+{
+	if (aw_sar_update_fw_para(p_sar, p_sar->p_sar_para->p_fw_bin) != 0)
+		return -EINVAL;
+
+	return aw_sar_load_bin_comm(p_sar);
+}
+
+static int32_t aw_sar_node_prox_update_fw(struct aw_sar *p_sar)
+{
+	if (aw_sar_update_fw_para(p_sar, p_sar->p_sar_para->p_prox_fw) != 0)
+		return -EINVAL;
+
+	return aw_sar_load_bin_comm(p_sar);
+}
+
+static int32_t aw_sar_node_reg_update_fw(struct aw_sar *p_sar)
+{
+	if (aw_sar_update_fw_para(p_sar, p_sar->p_sar_para->p_reg_fw))
+		return -EINVAL;
+
+	return aw_sar_load_bin_comm(p_sar);
+}
+
+static int32_t aw_sar_awrw_data_analysis(struct aw_sar *p_sar, const char *buf, uint8_t len)
+{
+	uint32_t theory_len = len * AW_SAR_AWRW_DATA_WIDTH + AW_SAR_AWRW_OffSET;
+	uint32_t actual_len = strlen(buf);
+	uint8_t data_temp[2] = { 0 };
+	uint32_t tranfar_data_temp;
+	uint8_t index = 0;
+	uint32_t i;
+
+	if (theory_len != actual_len) {
+		dev_err(p_sar->dev, "error theory_len = %d actual_len = %d",
+				theory_len, actual_len);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < len * AW_SAR_AWRW_DATA_WIDTH; i += AW_SAR_AWRW_DATA_WIDTH) {
+		data_temp[0] = buf[AW_SAR_AWRW_OffSET + i + AW_DATA_OffSET_2];
+		data_temp[1] = buf[AW_SAR_AWRW_OffSET + i + AW_DATA_OffSET_3];
+
+		if (sscanf(data_temp, "%02x", &tranfar_data_temp) == 1)
+			p_sar->awrw_info.p_i2c_tranfar_data[index] = (uint8_t)tranfar_data_temp;
+		index++;
+	}
+
+	return 0;
+}
+
+static int32_t aw_sar_awrw_write(struct aw_sar *p_sar, const char *buf)
+{
+	int32_t ret;
+
+	ret = aw_sar_awrw_data_analysis(p_sar, buf, p_sar->awrw_info.i2c_tranfar_data_len);
+	if (ret == 0)
+		aw_sar_i2c_write_seq(p_sar->i2c, p_sar->awrw_info.p_i2c_tranfar_data,
+					p_sar->awrw_info.i2c_tranfar_data_len);
+
+	return ret;
+}
+
+static int32_t aw_sar_awrw_read(struct aw_sar *p_sar, const char *buf)
+{
+	int32_t ret = 0;
+	uint8_t *p_buf = p_sar->awrw_info.p_i2c_tranfar_data + p_sar->awrw_info.addr_len;
+	uint32_t len = (uint16_t)(p_sar->awrw_info.data_len * p_sar->awrw_info.reg_num);
+
+	ret = aw_sar_awrw_data_analysis(p_sar, buf, p_sar->awrw_info.addr_len);
+	if (ret == 0) {
+		ret = aw_sar_i2c_read_seq(p_sar->i2c,
+				p_sar->awrw_info.p_i2c_tranfar_data,
+				p_sar->awrw_info.addr_len,
+				p_sar->awrw_info.p_i2c_tranfar_data + p_sar->awrw_info.addr_len,
+				(uint16_t)(p_sar->awrw_info.data_len * p_sar->awrw_info.reg_num));
+		if (ret != 0)
+			memset(p_buf, 0xff, len);
+	}
+
+	return ret;
+}
+
+static int32_t aw_sar_awrw_get_func(struct aw_sar *p_sar, char *buf)
+{
+	uint32_t len = 0;
+	uint32_t i;
+
+	if (!p_sar->awrw_info.p_i2c_tranfar_data) {
+		dev_err(p_sar->dev, "p_i2c_tranfar_data is NULL");
+		return len;
+	}
+
+	if (p_sar->awrw_info.rw_flag == AW_SAR_PACKAGE_RD) {
+		for (i = 0; i < p_sar->awrw_info.i2c_tranfar_data_len; i++) {
+			len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x,",
+				p_sar->awrw_info.p_i2c_tranfar_data[i]);
+		}
+	} else {
+		for (i = 0; i < (p_sar->awrw_info.data_len) * (p_sar->awrw_info.reg_num); i++) {
+			len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x,",
+				p_sar->awrw_info.p_i2c_tranfar_data[p_sar->awrw_info.addr_len + i]);
+		}
+	}
+	snprintf(buf + len - 1, PAGE_SIZE - len, "\n");
+
+	devm_kfree(p_sar->dev, p_sar->awrw_info.p_i2c_tranfar_data);
+	p_sar->awrw_info.p_i2c_tranfar_data = NULL;
+
+	return len;
+}
+
+//Function: continuous read register interface
+static ssize_t awrw_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	ssize_t ret;
+
+	mutex_lock(&aw_sar_lock);
+	if ((p_sar->p_sar_para->p_aw_sar_awrw != NULL) &&
+		(p_sar->p_sar_para->p_aw_sar_awrw->p_get_awrw_node_fn != NULL)) {
+		ret = (ssize_t)p_sar->p_sar_para->p_aw_sar_awrw->p_get_awrw_node_fn(p_sar, buf);
+		mutex_unlock(&aw_sar_lock);
+		return ret;
+	}
+
+	ret = (ssize_t)aw_sar_awrw_get_func(p_sar, buf);
+
+	mutex_unlock(&aw_sar_lock);
+
+	return ret;
+}
+
+static int32_t aw_sar_awrw_handle(struct aw_sar *p_sar, const char *buf)
+{
+	int32_t ret;
+
+	p_sar->awrw_info.i2c_tranfar_data_len = p_sar->awrw_info.addr_len +
+						p_sar->awrw_info.data_len *
+						p_sar->awrw_info.reg_num;
+
+	if (p_sar->awrw_info.p_i2c_tranfar_data != NULL) {
+		devm_kfree(p_sar->dev, p_sar->awrw_info.p_i2c_tranfar_data);
+		p_sar->awrw_info.p_i2c_tranfar_data = NULL;
+	}
+
+	p_sar->awrw_info.p_i2c_tranfar_data = devm_kzalloc(p_sar->dev,
+			p_sar->awrw_info.i2c_tranfar_data_len, GFP_KERNEL);
+	if (!p_sar->awrw_info.p_i2c_tranfar_data)
+		return -ENOMEM;
+
+	if (p_sar->awrw_info.rw_flag == AW_SAR_I2C_WR) {
+		ret = aw_sar_awrw_write(p_sar, buf);
+		if (ret != 0)
+			dev_err(p_sar->dev, "awrw_write error");
+		if (p_sar->awrw_info.p_i2c_tranfar_data != NULL) {
+			devm_kfree(p_sar->dev, p_sar->awrw_info.p_i2c_tranfar_data);
+			p_sar->awrw_info.p_i2c_tranfar_data = NULL;
+		}
+	} else if (p_sar->awrw_info.rw_flag == AW_SAR_I2C_RD) {
+		ret = aw_sar_awrw_read(p_sar, buf);
+		if (ret != 0)
+			dev_err(p_sar->dev, "awrw_read error");
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int32_t aw_sar_awrw_set_func(struct aw_sar *p_sar, const char *buf)
+{
+	uint32_t rw_flag;
+	uint32_t addr_bytes;
+	uint32_t data_bytes;
+	uint32_t package_nums;
+	uint32_t addr_tmp;
+	uint32_t buf_index0;
+	uint32_t buf_index1;
+	uint32_t r_buf_len = 0;
+	uint32_t tr_offset = 0;
+	uint8_t addr[4] = { 0 };
+	uint32_t theory_len;
+	uint32_t actual_len;
+	uint32_t reg_num;
+	uint32_t i;
+	uint32_t j;
+
+	//step1: Parse frame header
+	if (sscanf(buf, "0x%02x 0x%02x 0x%02x ", &rw_flag, &addr_bytes, &data_bytes) != 3) {
+		dev_err(p_sar->dev, "sscanf0 parse error!");
+		return -EINVAL;
+	}
+	p_sar->awrw_info.rw_flag = (uint8_t)rw_flag;
+	p_sar->awrw_info.addr_len = (uint8_t)addr_bytes;
+	p_sar->awrw_info.data_len = (uint8_t)data_bytes;
+
+	if (addr_bytes > 4) {
+		dev_err(p_sar->dev, "para error!");
+		return -EINVAL;
+	}
+
+	if ((rw_flag == AW_SAR_I2C_WR) || (rw_flag == AW_SAR_I2C_RD)) {
+		if (sscanf(buf + AW_SAR_OFFSET_LEN, "0x%02x ", &reg_num) != 1) {
+			dev_err(p_sar->dev, "sscanf1 parse error!");
+			return -EINVAL;
+		}
+		p_sar->awrw_info.reg_num = (uint8_t)reg_num;
+		aw_sar_awrw_handle(p_sar, buf);
+	} else if (rw_flag == AW_SAR_PACKAGE_RD) {
+		//step2: Get number of packages
+		if (sscanf(buf + AW_SAR_OFFSET_LEN, "0x%02x ", &package_nums) != 1) {
+			dev_err(p_sar->dev, "sscanf2 parse error!");
+			return -EINVAL;
+		}
+		theory_len = AW_SAR_OFFSET_LEN + AW_SAR_AWRW_DATA_WIDTH +
+				package_nums * (AW_SAR_AWRW_DATA_WIDTH +
+				AW_SAR_AWRW_DATA_WIDTH * addr_bytes);
+		actual_len = strlen(buf);
+		if (theory_len != actual_len) {
+			dev_err(p_sar->dev, "theory_len:%d, actual_len:%d error!",
+					theory_len, actual_len);
+			return -EINVAL;
+		}
+
+		//step3: Get the size of read data and apply for space
+		for (i = 0; i < package_nums; i++) {
+			buf_index0 = AW_SAR_OFFSET_LEN + AW_SAR_AWRW_DATA_WIDTH +
+				(AW_SAR_AWRW_DATA_WIDTH * addr_bytes +
+				 AW_SAR_AWRW_DATA_WIDTH) * i;
+			if (sscanf(buf + buf_index0, "0x%02x", &reg_num) != 1) {
+				dev_err(p_sar->dev, "sscanf3 parse error!");
+				return -EINVAL;
+			}
+			r_buf_len += reg_num * data_bytes;
+		}
+
+		p_sar->awrw_info.i2c_tranfar_data_len = r_buf_len;
+
+		if (p_sar->awrw_info.p_i2c_tranfar_data != NULL) {
+			devm_kfree(p_sar->dev, p_sar->awrw_info.p_i2c_tranfar_data);
+			p_sar->awrw_info.p_i2c_tranfar_data = NULL;
+		}
+		p_sar->awrw_info.p_i2c_tranfar_data = devm_kzalloc(p_sar->dev,
+								r_buf_len, GFP_KERNEL);
+		if (!p_sar->awrw_info.p_i2c_tranfar_data)
+			return -ENOMEM;
+
+		//step3: Resolve register address and read data in packets
+		for (i = 0; i < package_nums; i++) {
+			buf_index0 = AW_SAR_OFFSET_LEN + AW_SAR_AWRW_DATA_WIDTH +
+				(AW_SAR_AWRW_DATA_WIDTH * addr_bytes + AW_SAR_AWRW_DATA_WIDTH) * i;
+			if (sscanf(buf + buf_index0, "0x%02x", &reg_num) != 1) {
+				dev_err(p_sar->dev, "sscanf4 parse error!");
+				return -EINVAL;
+			}
+
+			for (j = 0; j < addr_bytes; j += 1) {
+				buf_index1 = buf_index0 + AW_SAR_AWRW_DATA_WIDTH +
+					(j * AW_SAR_AWRW_DATA_WIDTH);
+				if (sscanf(buf + buf_index1, "0x%02x", &addr_tmp) == 1) {
+					addr[j] = (uint8_t)addr_tmp;
+				} else {
+					dev_err(p_sar->dev, "sscanf5 parse error!");
+					return -EINVAL;
+				}
+			}
+			aw_sar_i2c_read_seq(p_sar->i2c,
+					addr,
+					addr_bytes,
+					p_sar->awrw_info.p_i2c_tranfar_data + tr_offset,
+					(uint16_t)(data_bytes * reg_num));
+			tr_offset += data_bytes * reg_num;
+		}
+	}
+
+	return 0;
+}
+
+//Function: continuous write register interface
+static ssize_t
+awrw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+
+	mutex_lock(&aw_sar_lock);
+
+	if ((p_sar->p_sar_para->p_aw_sar_awrw != NULL) &&
+		(p_sar->p_sar_para->p_aw_sar_awrw->p_set_awrw_node_fn != NULL)) {
+		p_sar->p_sar_para->p_aw_sar_awrw->p_set_awrw_node_fn(p_sar, buf, count);
+		mutex_unlock(&aw_sar_lock);
+		return count;
+	}
+
+	aw_sar_awrw_set_func(p_sar, buf);
+
+	mutex_unlock(&aw_sar_lock);
+
+	return count;
+}
+//Print all readable register values
+static ssize_t reg_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	uint8_t reg_rd_access;
+	uint32_t reg_data;
+	ssize_t len = 0;
+	int32_t ret;
+	uint16_t i;
+
+	if (!p_sar->p_sar_para->p_reg_list)
+		return len;
+
+	reg_rd_access = p_sar->p_sar_para->p_reg_list->reg_rd_access;
+
+	for (i = 0; i < p_sar->p_sar_para->p_reg_list->reg_num; i++) {
+		if (p_sar->p_sar_para->p_reg_list->reg_perm[i].rw & reg_rd_access) {
+			ret = aw_sar_i2c_read(p_sar->i2c,
+					p_sar->p_sar_para->p_reg_list->reg_perm[i].reg, &reg_data);
+			if (ret < 0)
+				len += snprintf(buf + len, PAGE_SIZE - len,
+						"i2c read error ret = %d\n", ret);
+			len += snprintf(buf + len, PAGE_SIZE - len,
+						"%x,%x\n",
+						p_sar->p_sar_para->p_reg_list->reg_perm[i].reg,
+						reg_data);
+		}
+	}
+
+	return len;
+}
+
+//Write register interface with write permission
+static ssize_t
+reg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	uint32_t databuf[2] = { 0, 0 };
+	uint8_t reg_wd_access;
+	uint16_t i;
+
+	if (!p_sar->p_sar_para->p_reg_list) {
+		dev_err(p_sar->dev, "AW_INVALID_PARA");
+		return count;
+	}
+
+	reg_wd_access = p_sar->p_sar_para->p_reg_list->reg_wd_access;
+
+	if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) != 2)
+		return count;
+
+	for (i = 0; i < p_sar->p_sar_para->p_reg_list->reg_num; i++) {
+		if ((uint16_t)databuf[0] == p_sar->p_sar_para->p_reg_list->reg_perm[i].reg) {
+			if (p_sar->p_sar_para->p_reg_list->reg_perm[i].rw & reg_wd_access) {
+				aw_sar_i2c_write(p_sar->i2c,
+					(uint16_t)databuf[0], (uint32_t)databuf[1]);
+			}
+			break;
+		}
+	}
+
+	return count;
+}
+
+//set chip Soft reset
+static ssize_t
+soft_rst_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	uint32_t flag;
+
+	if (kstrtouint(buf, 0, &flag) != 0) {
+		dev_err(p_sar->dev, "kstrtouint parse err");
+		return count;
+	}
+
+	if (flag == AW_TRUE)
+		aw_sar_soft_reset(p_sar);
+
+	return count;
+}
+
+static int32_t aw_sar_aot(struct aw_sar *p_sar)
+{
+	if (!p_sar->p_sar_para->p_aot)
+		return -EINVAL;
+
+	if (p_sar->p_sar_para->p_aot->p_set_aot_node_fn != NULL)
+		return p_sar->p_sar_para->p_aot->p_set_aot_node_fn(p_sar);
+
+	return aw_sar_i2c_write_bits(p_sar->i2c, p_sar->p_sar_para->p_aot->aot_reg,
+					p_sar->p_sar_para->p_aot->aot_mask,
+					p_sar->p_sar_para->p_aot->aot_flag);
+}
+
+//Perform Auto-Offset-Tuning (AOT)
+static ssize_t
+aot_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	uint32_t cali_flag;
+
+	if (kstrtouint(buf, 0, &cali_flag) != 0)
+		return count;
+
+	if (cali_flag == AW_TRUE)
+		aw_sar_aot(p_sar);
+	else
+		dev_err(p_sar->dev, "fail to set aot cali");
+
+	return count;
+}
+
+//update Register configuration and set the chip active mode
+int32_t aw_sar_update_reg_set_func(struct aw_sar *p_sar)
+{
+	aw_sar_load_def_reg_bin(p_sar);
+	aw_sar_mode_set(p_sar, p_sar->p_sar_para->p_chip_mode->active);
+
+	return 0;
+}
+
+//Update register configuration
+static ssize_t
+update_reg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	uint32_t flag;
+
+	if (kstrtouint(buf, 0, &flag) != 0) {
+		dev_err(p_sar->dev, "kstrtouint parse error");
+		return count;
+	}
+
+	if (flag == AW_TRUE) {
+		mutex_lock(&aw_sar_lock);
+		aw_sar_soft_reset(p_sar);
+		aw_sar_update_reg_set_func(p_sar);
+		mutex_unlock(&aw_sar_lock);
+	}
+
+	return count;
+}
+
+//get chip diff val
+static ssize_t aw_sar_get_diff(struct aw_sar *p_sar, char *buf)
+{
+	const struct aw_sar_diff_t *diff = p_sar->p_sar_para->p_diff;
+	int32_t diff_val;
+	ssize_t len = 0;
+	uint32_t data;
+	int32_t ret;
+	uint32_t i;
+
+	if (!p_sar->p_sar_para->p_diff)
+		return -EINVAL;
+
+	//If a private interface is defined, the private interface is used
+	if (p_sar->p_sar_para->p_diff->p_get_diff_node_fn != NULL)
+		return p_sar->p_sar_para->p_diff->p_get_diff_node_fn(p_sar, buf);
+
+	for (i = 0; i < p_sar->p_sar_para->ch_num_max; i++) {
+		ret = aw_sar_i2c_read(p_sar->i2c, diff->diff0_reg + i * diff->diff_step, &data);
+		if (ret != 0) {
+			dev_err(p_sar->dev, "read diff err: %d", ret);
+			return ret;
+		}
+		diff_val = (int32_t)data / (int32_t)diff->rm_float;
+		len += snprintf(buf + len, PAGE_SIZE - len, "DIFF_CH%u = %d\n", i, diff_val);
+	}
+
+	return len;
+}
+
+
+//Print diff values of all channels of the chip.
+static ssize_t diff_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+
+	return aw_sar_get_diff(p_sar, buf);
+}
+
+void aw_sar_mode_set(struct aw_sar *p_sar, uint8_t curr_mode)
+{
+	struct aw_sar_mode_set_t mode_set_para;
+
+	if (!p_sar->p_sar_para->p_mode)
+		return;
+
+	//If a private interface is defined, the private interface is used
+	if (p_sar->p_sar_para->p_mode->p_set_mode_node_fn != NULL) {
+		p_sar->p_sar_para->p_mode->p_set_mode_node_fn(p_sar, curr_mode);
+		return;
+	}
+
+	mode_set_para.chip_id = p_sar->chip_type;
+	mode_set_para.chip_mode.curr_mode = curr_mode;
+	mode_set_para.chip_mode.last_mode = p_sar->last_mode;
+
+	aw_sar_mode_set_func(p_sar->i2c, p_sar->irq_init.to_irq, &mode_set_para,
+		p_sar->p_sar_para->p_mode->mode_set_arr,
+		p_sar->p_sar_para->p_mode->mode_set_arr_len);
+	p_sar->last_mode = curr_mode;
+}
+
+//Set the chip to enter different modes
+static ssize_t mode_operation_store(struct device *dev, struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	uint32_t mode;
+
+	if (kstrtouint(buf, 0, &mode) != 0) {
+		dev_err(p_sar->dev, "kstrtouint parse err");
+		return count;
+	}
+	aw_sar_mode_set(p_sar, mode);
+
+	return count;
+}
+
+//Get the current mode of the chip
+static ssize_t mode_operation_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	ssize_t len = 0;
+
+	if (!p_sar->p_sar_para->p_mode)
+		return len;
+
+	if (p_sar->p_sar_para->p_mode->p_get_mode_node_fn != NULL)
+		len = p_sar->p_sar_para->p_mode->p_get_mode_node_fn(p_sar, buf);
+
+	return len;
+}
+
+//Print information related information
+static ssize_t chip_info_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	ssize_t len = 0;
+
+	len += snprintf(buf + len, PAGE_SIZE - len, "reg_load_state: %d\n", p_sar->ret_val);
+
+	if ((p_sar->p_sar_para->p_get_chip_info != NULL) &&
+		(p_sar->p_sar_para->p_get_chip_info->p_get_chip_info_node_fn != NULL)) {
+		p_sar->p_sar_para->p_get_chip_info->p_get_chip_info_node_fn(p_sar, buf, &len);
+	}
+
+	return len;
+}
+
+static ssize_t offset_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	ssize_t len = 0;
+
+	if ((p_sar->p_sar_para->p_offset != NULL) &&
+		(p_sar->p_sar_para->p_offset->p_get_offset_node_fn != NULL))
+		len = (ssize_t)p_sar->p_sar_para->p_offset->p_get_offset_node_fn(p_sar, buf);
+
+	return len;
+}
+
+static DEVICE_ATTR_RW(awrw);
+static DEVICE_ATTR_RW(reg);
+static DEVICE_ATTR_WO(soft_rst);
+static DEVICE_ATTR_WO(aot);
+static DEVICE_ATTR_WO(update_reg);
+static DEVICE_ATTR_RO(diff);
+static DEVICE_ATTR_RW(mode_operation);
+static DEVICE_ATTR_RO(chip_info);
+static DEVICE_ATTR_RO(offset);
+
+static struct attribute *aw_sar_attributes[] = {
+	&dev_attr_awrw.attr,
+	&dev_attr_reg.attr,
+	&dev_attr_soft_rst.attr,
+	&dev_attr_aot.attr,
+	&dev_attr_update_reg.attr,
+	&dev_attr_diff.attr,
+	&dev_attr_mode_operation.attr,
+	&dev_attr_chip_info.attr,
+	&dev_attr_offset.attr,
+	NULL
+};
+
+static const struct attribute_group aw_sar_attribute_group = {
+	.attrs = aw_sar_attributes,
+};
+
+//firmware upgrade through write register mode, and the operation is supported by flash chip
+static ssize_t prot_update_fw_store(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+
+
+	mutex_lock(&aw_sar_lock);
+	aw_sar_disable_irq(p_sar);
+
+	p_sar->prot_update_state = aw_sar_node_prox_update_fw(p_sar);
+
+	aw_sar_enable_irq(p_sar);
+	mutex_unlock(&aw_sar_lock);
+
+	return count;
+}
+
+//firmware upgrade throughr Write register mode,and the operation is supported by flash chip
+static ssize_t reg_update_fw_store(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+
+	mutex_lock(&aw_sar_lock);
+	aw_sar_disable_irq(p_sar);
+
+	aw_sar_node_reg_update_fw(p_sar);
+
+	aw_sar_enable_irq(p_sar);
+	mutex_unlock(&aw_sar_lock);
+
+	return count;
+}
+
+//boot upgrade throughr Write register mode,and the operation is supported by flash chip
+static ssize_t reg_update_boot_store(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+
+	if (!p_sar->p_sar_para->p_boot_bin)
+		return count;
+
+	mutex_lock(&aw_sar_lock);
+	aw_sar_disable_irq(p_sar);
+
+	aw_sar_reg_update_boot_work(p_sar);
+
+	aw_sar_enable_irq(p_sar);
+	mutex_unlock(&aw_sar_lock);
+
+	return count;
+}
+
+//Print the protocol upgrade status. 0 is success, Not 0 is failure
+//Print the current firmware version number
+static ssize_t prot_update_fw_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct aw_sar *p_sar = dev_get_drvdata(dev);
+	ssize_t len = 0;
+
+	len += snprintf(buf + len, PAGE_SIZE - len,
+		"protocol update state:%s!\n",
+		(p_sar->prot_update_state == 0) ? "ok" : "error");
+	if ((p_sar->p_sar_para->p_prox_fw != NULL) &&
+		(p_sar->p_sar_para->p_prox_fw->p_get_prot_update_fw_node_fn != NULL))
+		p_sar->p_sar_para->p_prox_fw->p_get_prot_update_fw_node_fn(p_sar, buf, &len);
+
+	return len;
+}
+
+static DEVICE_ATTR_RW(prot_update_fw);
+static DEVICE_ATTR_WO(reg_update_fw);
+static DEVICE_ATTR_WO(reg_update_boot);
+
+static struct attribute *aw_sar_update_attributes[] = {
+	&dev_attr_prot_update_fw.attr,
+	&dev_attr_reg_update_fw.attr,
+	&dev_attr_reg_update_boot.attr,
+	NULL
+};
+
+static const struct attribute_group aw_sar_update_attribute_group = {
+	.attrs = aw_sar_update_attributes,
+};
+
+static void aw_sar_update_work(struct work_struct *work)
+{
+	struct aw_sar *p_sar = container_of(work, struct aw_sar, update_work.work);
+	int32_t ret;
+
+	mutex_lock(&aw_sar_lock);
+
+	if (p_sar->dts_info.update_fw_flag == true) {
+		ret = aw_sar_update_fw(p_sar);
+		if (ret != 0) {
+			dev_err(p_sar->dev, "protocol upgrade firmware error!");
+			p_sar->ret_val = AW_PROT_UPDATE_ERR;
+		}
+	}
+
+	//2.Parse the bin file and load the register configuration
+	ret = aw_sar_load_def_reg_bin(p_sar);
+	if (ret != 0) {
+		p_sar->ret_val = AW_REG_LOAD_ERR;
+		dev_err(p_sar->dev, "reg_bin load err!");
+		aw_sar_para_loaded(p_sar);
+	}
+
+	//3.active chip
+	aw_sar_mode_set(p_sar, p_sar->p_sar_para->p_chip_mode->init_mode);
+	if (p_sar->irq_init.host_irq_stat == IRQ_DISABLE) {
+		enable_irq(p_sar->irq_init.to_irq);
+		p_sar->irq_init.host_irq_stat = IRQ_ENABLE;
+	}
+	p_sar->driver_code_initover_flag = 1;
+	mutex_unlock(&aw_sar_lock);
+}
+
+static void aw_sar_update(struct aw_sar *p_sar)
+{
+	if (!p_sar->p_sar_para->p_reg_bin)
+		return;
+
+	if (p_sar->p_sar_para->p_reg_bin->p_update_fn != NULL)
+		p_sar->p_sar_para->p_reg_bin->p_update_fn(p_sar);
+
+	if (p_sar->driver_code_initover_flag) {
+		schedule_delayed_work(&p_sar->update_work, msecs_to_jiffies(0));
+	} else {
+		INIT_DELAYED_WORK(&p_sar->update_work, aw_sar_update_work);
+		schedule_delayed_work(&p_sar->update_work,
+				msecs_to_jiffies(AW_POWER_ON_SYSFS_DELAY_MS));
+	}
+}
+
+static int32_t aw_sar_create_node(struct aw_sar *p_sar)
+{
+	int32_t ret;
+
+	i2c_set_clientdata(p_sar->i2c, p_sar);
+
+	ret = sysfs_create_group(&p_sar->i2c->dev.kobj, &aw_sar_attribute_group);
+
+	if (p_sar->dts_info.update_fw_flag == true)
+		ret |= sysfs_create_group(&p_sar->i2c->dev.kobj, &aw_sar_update_attribute_group);
+
+	//Special requirements of SAR chip
+	if (p_sar->p_sar_para->p_platform_config->p_add_node_create_fn != NULL)
+		ret |= p_sar->p_sar_para->p_platform_config->p_add_node_create_fn(p_sar);
+
+	return ret;
+}
+
+static void aw_sar_node_free(struct aw_sar *p_sar)
+{
+	sysfs_remove_group(&p_sar->i2c->dev.kobj, &aw_sar_attribute_group);
+
+	if (p_sar->dts_info.update_fw_flag == true)
+		sysfs_remove_group(&p_sar->i2c->dev.kobj, &aw_sar_update_attribute_group);
+
+	//Special requirements of SAR chip
+	if ((p_sar->p_sar_para->p_platform_config != NULL) &&
+		(p_sar->p_sar_para->p_platform_config->p_add_node_free_fn != NULL))
+		p_sar->p_sar_para->p_platform_config->p_add_node_free_fn(p_sar);
+}
+
+//The interrupt pin is set to internal pull-up start
+static void aw_sar_int_output(struct aw_sar *p_sar, int32_t level)
+{
+	if (level == 0) {
+		if (p_sar->pinctrl.pinctrl)
+			pinctrl_select_state(p_sar->pinctrl.pinctrl, p_sar->pinctrl.int_out_low);
+		else
+			dev_err(p_sar->dev, "Failed set int pin output low\n");
+	} else if (level == 1) {
+		if (p_sar->pinctrl.pinctrl)
+			pinctrl_select_state(p_sar->pinctrl.pinctrl, p_sar->pinctrl.int_out_high);
+		else
+			dev_err(p_sar->dev, "Failed set int pin output high\n");
+	}
+}
+
+static int32_t aw_sar_pinctrl_init(struct aw_sar *p_sar)
+{
+	struct aw_sar_pinctrl *pinctrl = &p_sar->pinctrl;
+	uint8_t pin_default_name[50] = { 0 };
+	uint8_t pin_output_low_name[50] = { 0 };
+	uint8_t pin_output_high_name[50] = { 0 };
+
+	pinctrl->pinctrl = devm_pinctrl_get(p_sar->dev);
+	if (IS_ERR_OR_NULL(pinctrl->pinctrl)) {
+		dev_err(p_sar->dev, "No pinctrl found\n");
+		pinctrl->pinctrl = NULL;
+		return -EINVAL;
+	}
+
+	snprintf(pin_default_name, sizeof(pin_default_name),
+					"aw_default_sar%u", p_sar->dts_info.sar_num);
+	pinctrl->default_sta = pinctrl_lookup_state(pinctrl->pinctrl, pin_default_name);
+	if (IS_ERR_OR_NULL(pinctrl->default_sta)) {
+		dev_err(p_sar->dev, "Failed get pinctrl state:default state");
+		goto exit_pinctrl_init;
+	}
+
+	snprintf(pin_output_high_name, sizeof(pin_output_high_name),
+				"aw_int_output_high_sar%u", p_sar->dts_info.sar_num);
+	pinctrl->int_out_high = pinctrl_lookup_state(pinctrl->pinctrl, pin_output_high_name);
+	if (IS_ERR_OR_NULL(pinctrl->int_out_high)) {
+		dev_err(p_sar->dev, "Failed get pinctrl state:output_high");
+		goto exit_pinctrl_init;
+	}
+
+	snprintf(pin_output_low_name, sizeof(pin_output_low_name),
+				"aw_int_output_low_sar%u", p_sar->dts_info.sar_num);
+	pinctrl->int_out_low = pinctrl_lookup_state(pinctrl->pinctrl, pin_output_low_name);
+	if (IS_ERR_OR_NULL(pinctrl->int_out_low)) {
+		dev_err(p_sar->dev, "Failed get pinctrl state:output_low");
+		goto exit_pinctrl_init;
+	}
+
+	return 0;
+
+exit_pinctrl_init:
+	devm_pinctrl_put(pinctrl->pinctrl);
+	pinctrl->pinctrl = NULL;
+
+	return -EINVAL;
+}
+
+static void aw_sar_pinctrl_deinit(struct aw_sar *p_sar)
+{
+	if (p_sar->pinctrl.pinctrl)
+		devm_pinctrl_put(p_sar->pinctrl.pinctrl);
+}
+//The interrupt pin is set to internal pull-up end
+
+//AW_SAR_REGULATOR_POWER_ON start
+static int32_t aw_sar_regulator_power_init(struct aw_sar *p_sar)
+{
+	uint8_t vcc_name[20] = { 0 };
+	int32_t rc;
+
+	snprintf(vcc_name, sizeof(vcc_name), "vcc%u", p_sar->dts_info.sar_num);
+	p_sar->vcc = regulator_get(p_sar->dev, vcc_name);
+	if (IS_ERR(p_sar->vcc)) {
+		rc = PTR_ERR(p_sar->vcc);
+		dev_err(p_sar->dev, "regulator get failed vcc rc = %d", rc);
+		return rc;
+	}
+
+	if (regulator_count_voltages(p_sar->vcc) > 0) {
+		rc = regulator_set_voltage(p_sar->vcc, AW_SAR_VCC_MIN_UV, AW_SAR_VCC_MAX_UV);
+		if (rc) {
+			dev_err(p_sar->dev, "regulator set vol failed rc = %d", rc);
+			goto reg_vcc_put;
+		}
+	}
+
+	return 0;
+
+reg_vcc_put:
+	regulator_put(p_sar->vcc);
+	return rc;
+}
+
+static void aw_sar_power_deinit(struct aw_sar *p_sar)
+{
+	if (p_sar->power_enable) {
+		//Turn off the power output. However,
+		//it may not be turned off immediately
+		//There are scenes where power sharing can exist
+		regulator_disable(p_sar->vcc);
+		regulator_put(p_sar->vcc);
+	}
+}
+
+static void aw_sar_power_enable(struct aw_sar *p_sar, bool on)
+{
+	int32_t rc;
+
+	if (on) {
+		rc = regulator_enable(p_sar->vcc);
+		if (rc) {
+			dev_err(p_sar->dev, "regulator_enable vol failed rc = %d", rc);
+		} else {
+			p_sar->power_enable = AW_TRUE;
+			msleep(20);
+		}
+	} else {
+		rc = regulator_disable(p_sar->vcc);
+		if (rc)
+			dev_err(p_sar->dev, "regulator_disable vol failed rc = %d", rc);
+		else
+			p_sar->power_enable = AW_FALSE;
+	}
+}
+
+static int32_t regulator_is_get_voltage(struct aw_sar *p_sar)
+{
+	uint32_t cnt = 10;
+	int32_t voltage_val;
+
+	while (cnt--) {
+		voltage_val = regulator_get_voltage(p_sar->vcc);
+		if (voltage_val >= AW_SAR_VCC_MIN_UV)
+			return 0;
+		mdelay(1);
+	}
+	//Ensure that the chip initialization is completed
+	msleep(20);
+
+	return -EINVAL;
+}
+//AW_SAR_REGULATOR_POWER_ON end
+
+static void aw_sar_init_lock(struct aw_sar *p_sar)
+{
+	//Initialize lock, To protect the thread safety of updating bin file
+	mutex_init(&aw_sar_lock);
+	//Required for mode setting
+	p_sar->last_mode = p_sar->p_sar_para->p_chip_mode->pre_init_mode;
+	p_sar->fw_fail_flag = AW_FALSE;
+	p_sar->ret_val = 0;
+}
+
+// AW_SAR_USB_PLUG_CAIL start
+static void aw_sar_ps_notify_callback_work(struct work_struct *work)
+{
+	struct aw_sar *p_sar = container_of(work, struct aw_sar, ps_notify_work);
+
+	aw_sar_aot(p_sar);
+}
+
+static int aw_sar_ps_get_state(struct aw_sar *p_sar, struct power_supply *psy, bool *present)
+{
+	union power_supply_propval pval = { 0 };
+	int retval;
+
+	retval = power_supply_get_property(psy, AW_USB_PROP_ONLINE, &pval);
+	if (retval) {
+		dev_err(p_sar->dev, "%s psy get property failed", psy->desc->name);
+		return retval;
+	}
+	*present = (pval.intval) ? true : false;
+
+	return 0;
+}
+
+static int aw_sar_ps_notify_callback(struct notifier_block *self,
+		unsigned long event, void *p)
+{
+	struct aw_sar *p_sar = container_of(self, struct aw_sar, ps_notif);
+	struct power_supply *psy = p;
+	bool present;
+	int retval;
+
+	if (event == PSY_EVENT_PROP_CHANGED
+		&& psy && psy->desc->get_property && psy->desc->name &&
+		!strncmp(psy->desc->name, USB_POWER_SUPPLY_NAME,
+			sizeof(USB_POWER_SUPPLY_NAME))) {
+		retval = aw_sar_ps_get_state(p_sar, psy, &present);
+		if (retval) {
+			dev_err(p_sar->dev, "psy get property failed");
+			return retval;
+		}
+		if (event == PSY_EVENT_PROP_CHANGED) {
+			if (p_sar->ps_is_present == present)
+				return 0;
+		}
+		p_sar->ps_is_present = present;
+		schedule_work(&p_sar->ps_notify_work);
+	}
+	return 0;
+}
+
+static int aw_sar_ps_notify_init(struct aw_sar *p_sar)
+{
+	struct power_supply *psy;
+	int ret;
+
+	INIT_WORK(&p_sar->ps_notify_work, aw_sar_ps_notify_callback_work);
+	p_sar->ps_notif.notifier_call = (notifier_fn_t)aw_sar_ps_notify_callback;
+	ret = power_supply_reg_notifier(&p_sar->ps_notif);
+	if (ret) {
+		dev_err(p_sar->dev, "Unable to register ps_notifier: %d", ret);
+		return ret;
+	}
+	psy = power_supply_get_by_name(USB_POWER_SUPPLY_NAME);
+	if (!psy) {
+		dev_err(p_sar->dev, "Unable to get power_supply: %s", USB_POWER_SUPPLY_NAME);
+		goto free_ps_notifier;
+	}
+	ret = aw_sar_ps_get_state(p_sar, psy, &p_sar->ps_is_present);
+	if (ret) {
+		dev_err(p_sar->dev, "psy get property failed rc=%d", ret);
+		goto free_ps_notifier;
+	}
+	return 0;
+
+free_ps_notifier:
+	power_supply_unreg_notifier(&p_sar->ps_notif);
+
+	return -EINVAL;
+}
+// AW_SAR_USB_PLUG_CAIL end
+
+static int32_t aw_sar_platform_rsc_init(struct aw_sar *p_sar)
+{
+	int32_t ret;
+
+	if (!p_sar->p_sar_para->p_platform_config)
+		return -EINVAL;
+
+	//step 1.parsing dts data
+	ret = aw_sar_parse_dts(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "parse dts error!");
+		return ret;
+	}
+
+	//Initialization lock and some variables
+	aw_sar_init_lock(p_sar);
+
+	//Configure whether to use USB plug-in calibration in DTS according to customer requirements
+	if (p_sar->dts_info.use_plug_cail_flag == true) {
+		ret = aw_sar_ps_notify_init(p_sar);
+		if (ret < 0) {
+			dev_err(p_sar->dev, "error creating power supply notify");
+			goto err_ps_notify_init;
+		}
+	}
+
+	//The interrupt pin is set to internal pull-up and configured by DTS
+	if (p_sar->dts_info.use_inter_pull_up == true) {
+		ret = aw_sar_pinctrl_init(p_sar);
+		if (ret < 0) {
+			/* if define pinctrl must define the following state
+			 * to let int-pin work normally: default, int_output_high,
+			 * int_output_low, int_input
+			 */
+			dev_err(p_sar->dev, "Failed get wanted pinctrl state");
+			goto err_pinctrl_init;
+		}
+		aw_sar_int_output(p_sar, 1);
+	}
+
+	//step 2.Create debug file node
+	ret = aw_sar_create_node(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "create node error!");
+		goto err_sysfs_nodes;
+	}
+
+	//step 3.Initialization interrupt
+	ret = aw_sar_irq_init(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "interrupt initialization error!");
+		goto err_irq_init;
+	}
+
+	//step 4.Initialization input Subsystem
+	ret = aw_sar_input_init(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "input_init error!");
+		goto err_input_init;
+	}
+
+	return 0;
+
+err_input_init:
+	aw_sar_input_free(p_sar);
+	aw_sar_irq_free(p_sar);
+err_irq_init:
+	aw_sar_node_free(p_sar);
+err_sysfs_nodes:
+	if (p_sar->dts_info.use_inter_pull_up == true)
+		aw_sar_pinctrl_deinit(p_sar);
+err_pinctrl_init:
+	if (p_sar->dts_info.use_plug_cail_flag == true)
+		power_supply_unreg_notifier(&p_sar->ps_notif);
+err_ps_notify_init:
+	mutex_destroy(&aw_sar_lock);
+
+	return ret;
+}
+
+/**
+ * @brief sar sensor initialization logic.
+ *
+ * @param p_sar  data stored in type 'struct aw_sar *'.
+ * @return 0 if init succeeded. others if unpack error.
+ */
+static int32_t aw_sar_chip_init(struct aw_sar *p_sar)
+{
+	int32_t ret;
+
+	//step 1.check chipid,Verify whether the chip communication is successful
+	ret = aw_sar_check_chipid(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "check_chipid error!");
+		goto communication_fail;
+	}
+
+	//step 2.Check chip initialization completed,
+	ret = aw_sar_soft_reset(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "soft_reset error!");
+		goto communication_fail;
+	}
+
+	ret = aw_sar_check_init_over_irq(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "check_init_over_irqt error!");
+		goto communication_fail;
+	}
+
+	//step 3.chip other operation
+	ret = aw_sar_chip_other_operation(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "chip_other_operation error!");
+		goto free_other_opera;
+	}
+
+	//step 4.Parse the bin file, upgrade the firmware, and load the register prize
+	aw_sar_update(p_sar);
+
+	return 0;
+
+free_other_opera:
+	aw_sar_chip_other_operation_free(p_sar);
+communication_fail:
+
+	return ret;
+}
+
+static int32_t aw_sar_init(struct aw_sar *p_sar)
+{
+	int32_t ret;
+
+	//step 1: Platform resource initialization
+	ret = aw_sar_platform_rsc_init(p_sar);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "platform_rsc_init error!");
+		return ret;
+	}
+
+	//step 2: Chip initialization
+	ret = aw_sar_chip_init(p_sar);
+	if (ret != 0) {
+		aw_sar_input_free(p_sar);
+		aw_sar_irq_free(p_sar);
+		aw_sar_node_free(p_sar);
+		if (p_sar->dts_info.use_inter_pull_up == true)
+			aw_sar_pinctrl_deinit(p_sar);
+		if (p_sar->dts_info.use_plug_cail_flag == true)
+			power_supply_unreg_notifier(&p_sar->ps_notif);
+		mutex_destroy(&aw_sar_lock);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int32_t aw_sar_regulator_power(struct aw_sar *p_sar)
+{
+	struct aw_sar_dts_info *p_dts_info = &p_sar->dts_info;
+	int32_t ret = 0;
+
+	p_dts_info->use_regulator_flag =
+		of_property_read_bool(p_sar->i2c->dev.of_node, "aw_sar,regulator-power-supply");
+
+	//Configure the use of regulator power supply in DTS
+	if (p_sar->dts_info.use_regulator_flag == true) {
+		ret = aw_sar_regulator_power_init(p_sar);
+		if (ret != 0) {
+			dev_err(p_sar->dev, "power init failed");
+			return ret;
+		}
+		aw_sar_power_enable(p_sar, AW_TRUE);
+		ret = regulator_is_get_voltage(p_sar);
+		if (ret != 0) {
+			dev_err(p_sar->dev, "get_voltage failed");
+			aw_sar_power_deinit(p_sar);
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * @brief Distinguish different chips by chip name and obtain relevant chip information
+ *
+ * @param p_sar Structure to be filled
+ * @return 0 if init succeeded.
+ */
+static int32_t aw_sar_get_chip_info(struct aw_sar *p_sar)
+{
+	int32_t ret;
+	uint8_t i;
+
+	for (i = 0; i < AW_SAR_DRIVER_MAX; i++) {
+		if (g_aw_sar_driver_list[i].p_who_am_i != NULL) {
+			ret = g_aw_sar_driver_list[i].p_who_am_i(p_sar);
+			if (ret == 0) {
+				p_sar->curr_use_driver_type = g_aw_sar_driver_list[i].driver_type;
+				if (!g_aw_sar_driver_list[i].p_chip_init) {
+					dev_err(p_sar->dev,
+							"drvier:%d p_chip_init is null  error!", i);
+					continue;
+				}
+				g_aw_sar_driver_list[i].p_chip_init(p_sar);
+				dev_info(p_sar->dev, "current use drvier is :%d",
+						g_aw_sar_driver_list[i].driver_type);
+				return 0;
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+static void aw_sar_monitor_work(struct work_struct *aw_work)
+{
+	struct aw_sar *p_sar = container_of(aw_work, struct aw_sar, monitor_work.work);
+	uint32_t data;
+	int32_t ret;
+
+	ret = aw_sar_i2c_read(p_sar->i2c, 0x0000, &data);
+	if (ret != 0) {
+		dev_err(p_sar->dev, "read 0x0000 err: %d", ret);
+		return;
+	}
+	if (data == 0 && p_sar->driver_code_initover_flag) {
+		dev_err(p_sar->dev, "aw_chip may reset");
+		aw_sar_disable_irq(p_sar);
+		ret = aw_sar_chip_init(p_sar);
+		if (ret != 0)
+			return;
+	}
+	queue_delayed_work(p_sar->monitor_wq, &p_sar->monitor_work,
+			msecs_to_jiffies(AW_SAR_MONITOR_ESD_DELAY_MS));
+}
+
+static int32_t aw_sar_monitor_esd_init(struct aw_sar *p_sar)
+{
+	p_sar->monitor_wq = create_singlethread_workqueue("aw_sar_workqueue");
+	if (!p_sar->monitor_wq) {
+		dev_err(&p_sar->i2c->dev, "aw_sar_workqueue error");
+		return -EINVAL;
+	}
+	INIT_DELAYED_WORK(&p_sar->monitor_work, aw_sar_monitor_work);
+	queue_delayed_work(p_sar->monitor_wq, &p_sar->monitor_work,
+			msecs_to_jiffies(AW_SAR_MONITOR_ESD_DELAY_MS));
+
+	return 0;
+}
+
+static void aw_sar_sensor_free(struct aw_sar *p_sar)
+{
+	if (g_aw_sar_driver_list[p_sar->curr_use_driver_type].p_chip_deinit != NULL)
+		g_aw_sar_driver_list[p_sar->curr_use_driver_type].p_chip_deinit(p_sar);
+}
+
+
+/**
+ * @brief Drive logic entry
+ *
+ */
+static int32_t aw_sar_i2c_probe(struct i2c_client *i2c)
+{
+	struct aw_sar *p_sar;
+	int32_t ret;
+
+	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
+		pr_err("check_functionality failed!\n");
+		return -EIO;
+	}
+
+	p_sar = devm_kzalloc(&i2c->dev, sizeof(struct aw_sar), GFP_KERNEL);
+	if (!p_sar) {
+		ret = -ENOMEM;
+		goto err_malloc;
+	}
+
+	p_sar->dev = &i2c->dev;
+	p_sar->i2c = i2c;
+	i2c_set_clientdata(i2c, p_sar);
+
+	//1.Judge whether to use regular power supply. If yes, supply power
+	ret = aw_sar_regulator_power(p_sar);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "regulator_power error!");
+		goto err_malloc;
+	}
+
+	//2.Get chip initialization resources
+	ret = aw_sar_get_chip_info(p_sar);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "chip_init error!");
+		goto err_chip_init;
+	}
+
+	//3.Chip initialization process
+	ret = aw_sar_init(p_sar);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "sar_init error!");
+		goto err_sar_init;
+	}
+
+	if (p_sar->dts_info.monitor_esd_flag) {
+		ret = aw_sar_monitor_esd_init(p_sar);
+		if (ret != 0) {
+			dev_err(&i2c->dev, "monitor_esd_init error!");
+			goto err_esd_init;
+		}
+	}
+
+	dev_dbg(&i2c->dev, "probe success!");
+
+	return 0;
+
+err_esd_init:
+	aw_sar_input_free(p_sar);
+	aw_sar_irq_free(p_sar);
+	aw_sar_node_free(p_sar);
+	if (p_sar->dts_info.use_inter_pull_up == true)
+		aw_sar_pinctrl_deinit(p_sar);
+	if (p_sar->dts_info.use_plug_cail_flag == true)
+		power_supply_unreg_notifier(&p_sar->ps_notif);
+	mutex_destroy(&aw_sar_lock);
+err_sar_init:
+	aw_sar_sensor_free(p_sar);
+err_chip_init:
+if (p_sar->dts_info.use_regulator_flag == true)
+	aw_sar_power_deinit(p_sar);
+err_malloc:
+	return ret;
+}
+
+static void aw_sar_i2c_remove(struct i2c_client *i2c)
+{
+	struct aw_sar *p_sar  = i2c_get_clientdata(i2c);
+
+	aw_sar_chip_other_operation_free(p_sar);
+
+	aw_sar_node_free(p_sar);
+
+	aw_sar_irq_free(p_sar);
+
+	aw_sar_input_free(p_sar);
+
+	if (p_sar->dts_info.use_inter_pull_up == true)
+		aw_sar_pinctrl_deinit(p_sar);
+
+	if (p_sar->dts_info.use_regulator_flag == true)
+		aw_sar_power_deinit(p_sar);
+
+	if (p_sar->dts_info.use_plug_cail_flag == true)
+		power_supply_unreg_notifier(&p_sar->ps_notif);
+
+	aw_sar_sensor_free(p_sar);
+}
+
+static int aw_sar_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct aw_sar *p_sar = i2c_get_clientdata(client);
+
+	if (p_sar->dts_info.use_pm == true) {
+		if ((!p_sar->p_sar_para->p_platform_config) ||
+			(!p_sar->p_sar_para->p_platform_config->p_pm_chip_mode))
+			return 0;
+		if (p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->p_suspend_fn) {
+			p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->p_suspend_fn(p_sar);
+			return 0;
+		}
+		aw_sar_mode_set(p_sar,
+			p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->suspend_set_mode);
+	}
+
+	if (p_sar->dts_info.monitor_esd_flag)
+		cancel_delayed_work_sync(&p_sar->monitor_work);
+
+	return 0;
+}
+
+static int aw_sar_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct aw_sar *p_sar = i2c_get_clientdata(client);
+
+	if (p_sar->dts_info.use_pm == true) {
+		if ((!p_sar->p_sar_para->p_platform_config) ||
+			(!p_sar->p_sar_para->p_platform_config->p_pm_chip_mode))
+			return 0;
+		if (p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->p_resume_fn) {
+			p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->p_resume_fn(p_sar);
+			return 0;
+		}
+		aw_sar_mode_set(p_sar,
+			p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->resume_set_mode);
+	}
+
+	if (p_sar->dts_info.monitor_esd_flag)
+		queue_delayed_work(p_sar->monitor_wq, &p_sar->monitor_work,
+				msecs_to_jiffies(AW_SAR_MONITOR_ESD_DELAY_MS));
+
+	return 0;
+}
+
+static void aw_sar_i2c_shutdown(struct i2c_client *i2c)
+{
+	struct aw_sar *p_sar  = i2c_get_clientdata(i2c);
+
+	if ((!p_sar->p_sar_para->p_platform_config) ||
+		(!p_sar->p_sar_para->p_platform_config->p_pm_chip_mode))
+		return;
+
+	if (p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->p_shutdown_fn) {
+		p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->p_shutdown_fn(p_sar);
+		return;
+	}
+
+	aw_sar_mode_set(p_sar,
+		p_sar->p_sar_para->p_platform_config->p_pm_chip_mode->shutdown_set_mode);
+}
+
+static const struct dev_pm_ops aw_sar_pm_ops = {
+	.suspend = aw_sar_suspend,
+	.resume = aw_sar_resume,
+};
+
+static const struct of_device_id aw_sar_dt_match[] = {
+	{ .compatible = "awinic,aw96103" },
+	{ .compatible = "awinic,aw96105" },
+	{ .compatible = "awinic,aw96303" },
+	{ .compatible = "awinic,aw96305" },
+	{ .compatible = "awinic,aw96308" },
+};
+
+static const struct i2c_device_id aw_sar_i2c_id[] = {
+	{ AW_SAR_I2C_NAME, 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, aw_sar_i2c_id);
+
+static struct i2c_driver aw_sar_i2c_driver = {
+	.driver = {
+		.name = AW_SAR_I2C_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(aw_sar_dt_match),
+		.pm = &aw_sar_pm_ops,
+	},
+	.probe = aw_sar_i2c_probe,
+	.remove = aw_sar_i2c_remove,
+	.shutdown = aw_sar_i2c_shutdown,
+	.id_table = aw_sar_i2c_id,
+};
+
+static int32_t __init aw_sar_i2c_init(void)
+{
+	int32_t ret;
+
+	ret = i2c_add_driver(&aw_sar_i2c_driver);
+	if (ret) {
+		pr_err("fail to add aw_sar device into i2c\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+module_init(aw_sar_i2c_init);
+static void __exit aw_sar_i2c_exit(void)
+{
+	i2c_del_driver(&aw_sar_i2c_driver);
+}
+module_exit(aw_sar_i2c_exit);
+MODULE_DESCRIPTION("AWINIC SAR Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/misc/aw_sar/aw_sar.h b/drivers/input/misc/aw_sar/aw_sar.h
new file mode 100644
index 000000000000..7a139f56e9c3
--- /dev/null
+++ b/drivers/input/misc/aw_sar/aw_sar.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef AW_SAR_H_
+#define AW_SAR_H_
+
+void aw_sar_disable_irq(struct aw_sar *p_sar);
+void aw_sar_enable_irq(struct aw_sar *p_sar);
+
+int32_t aw_sar_soft_reset(struct aw_sar *p_sar);
+int32_t aw_sar_check_init_over_irq(struct aw_sar *p_sar);
+int32_t aw_sar_update_fw(struct aw_sar *p_sar);
+int32_t aw_sar_load_def_reg_bin(struct aw_sar *p_sar);
+void aw_sar_mode_set(struct aw_sar *p_sar, uint8_t curr_mode);
+int32_t aw_sar_update_reg_set_func(struct aw_sar *p_sar);
+
+#endif
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor.
  2024-05-29 13:06 ` [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor wangshuaijie
@ 2024-05-29 14:25   ` Rob Herring (Arm)
  2024-06-05  9:04     ` wangshuaijie
  2024-05-31  1:36   ` Rob Herring
  1 sibling, 1 reply; 16+ messages in thread
From: Rob Herring (Arm) @ 2024-05-29 14:25 UTC (permalink / raw)
  To: wangshuaijie
  Cc: kangjiajun, dmitry.torokhov, jeff, linux-input, liweilei,
	conor+dt, krzk+dt, devicetree, linux-kernel


On Wed, 29 May 2024 13:06:04 +0000, wangshuaijie@awinic.com wrote:
> From: shuaijie wang <wangshuaijie@awinic.com>
> 
> Add the awinic,aw_sar.yaml file to adapt to the awinic sar sensor driver.
> 
> Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
> ---
>  .../bindings/input/awinic,aw_sar.yaml         | 110 ++++++++++++++++++
>  1 file changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/input/awinic,aw_sar.example.dtb: awinic_sar@12: 'aw_sar,update_fw' does not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^100ask,.*', '^70mai,.*', '^8dev,.*', '^GEFanuc,.*', '^IBM,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acbel,.*', '^acelink,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^adieng,.*', '^admatec,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^airoha,.*', '^al,.*', '^alcatel,.*', '^aldec,.*', '^alfa-network,.*', '^allegro,.*', '^alliedvision,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^amphenol,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^anbernic,.*', '^andestech,.*', '^anvo,.*', '^aosong,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arcom,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asrock,.*', '^asteralabs,.*', '^asus,.*', '^atheros,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^belling,.*', '^bhf,.*', '^bigtreetech,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bsh,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^bytedance,.*', '^calamp,.*', '^calao,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^chargebyte,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chongzhou,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^clockwork,.*', '^cloos,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coolpi,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^ctera,.*', '^ctu,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cyx,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^densitron,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dimonoff,.*', '^diodes,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebbg,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edgeble,.*', '^edimax,.*', '^edt,.*', '^ees,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embedfire,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^enclustra,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^engleder,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairchild,.*', '^fairphone,.*', '^faraday,.*', '^fascontek,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^freebox,.*', '^freecom,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^fxtec,.*', '^galaxycore,.*', '^gardena,.*', '^gateway,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^gemtek,.*', '^genesys,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^glinet,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goldelico,.*', '^goodix,.*', '^google,.*', '^goramo,.*', '^gplus,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haochuangyi,.*', '^haoyu,.*', '^hardkernel,.*', '^hechuang,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisi,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperf,.*', '^hoperun,.*', '^hp,.*', '^hpe,.*', '^hsg,.*', '^htc,.*', '^huawei,.*', '^hugsun,.*', '^hwacom,.*', '^hxt,.*', '^hycon,.*', '^hydis,.*', '^hynitron,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^iei,.*', '^ifi,.*', '^ilitek,.*', '^imagis,.*', '^img,.*', '^imi,.*', '^inanbo,.*', '^incircuit,.*', '^indiedroid,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^ingrasys,.*', '^injoinic,.*', '^innocomm,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inventec,.*', '^inversepath,.*', '^iom,.*', '^irondevice,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jadard,.*', '^jasonic,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^jide,.*', '^joz,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^lctech,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^lineartechnology,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongmasses,.*', '^loongson,.*', '^lsi,.*', '^lunzn,.*', '^luxul,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marantec,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^maxlinear,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsensing,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^methode,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^milkv,.*', '^miniand,.*', '^minix,.*', '^mips,.*', '^miramems,.*', '^mitsubishi,.*', '^mitsumi,.*', '^mixel,.*', '^miyoo,.*', '^mntre,.*', '^mobileye,.*', '^modtronix,.*', '^moortec,.*', '^mosaixtech,.*', '^motorcomm,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxic,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^newvision,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novatek,.*', '^novtech,.*', '^numonyx,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^ocs,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^oneplus,.*', '^onie,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^openailab,.*', '^opencores,.*', '^openembed,.*', '^openpandora,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^osmc,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^polyhex,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^powkiddy,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^quanta,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^rve,.*', '^saef,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sercomm,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shift,.*', '^shimafuji,.*', '^shineworld,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silan,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sinowealth,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smartrg,.*', '^smi,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^sophgo,.*', '^sourceparts,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^square,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^starterkit,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^storopack,.*', '^summit,.*', '^sunchip,.*', '^sundance,.*', '^sunplus,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^synopsys,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^team-source-display,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^techwell,.*', '^teejet,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tesla,.*', '^tfc,.*', '^thead,.*', '^thine,.*', '^thingyjp,.*', '^thundercomm,.*', '^thwc,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^transpeed,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^turing,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ufispace,.*', '^ugoos,.*', '^uni-t,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^usr,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^vertexcom,.*', '^via,.*', '^vialab,.*', '^vicor,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^voltafield,.*', '^vot,.*', '^vscom,.*', '^vxt,.*', '^wacom,.*', '^wanchanglong,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^widora,.*', '^wiligear,.*', '^willsemi,.*', '^winbond,.*', '^wingtech,.*', '^winlink,.*', '^winstar,.*', '^wirelesstag,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xen,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yadro,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^yiming,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/vendor-prefixes.yaml#
Documentation/devicetree/bindings/input/awinic,aw_sar.example.dtb: /example-0/i2c/awinic_sar@12: failed to match any schema with compatible: ['awinic,aw_sar']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240529130608.783624-2-wangshuaijie@awinic.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-29 13:06 ` [PATCH V1 5/5] Add support for Awinic sar sensor wangshuaijie
@ 2024-05-29 22:49   ` kernel test robot
  2024-06-05  9:03     ` wangshuaijie
  2024-05-30  4:27   ` kernel test robot
  2024-05-31  8:12   ` Dan Carpenter
  2 siblings, 1 reply; 16+ messages in thread
From: kernel test robot @ 2024-05-29 22:49 UTC (permalink / raw)
  To: wangshuaijie, dmitry.torokhov, robh, krzk+dt, conor+dt, jeff,
	linux-input, devicetree, linux-kernel
  Cc: oe-kbuild-all, wangshuaijie, liweilei, kangjiajun

Hi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc]

url:    https://github.com/intel-lab-lkp/linux/commits/wangshuaijie-awinic-com/dt-bindings-input-Add-YAML-to-Awinic-sar-sensor/20240529-211303
base:   e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
patch link:    https://lore.kernel.org/r/20240529130608.783624-6-wangshuaijie%40awinic.com
patch subject: [PATCH V1 5/5] Add support for Awinic sar sensor.
config: riscv-randconfig-r071-20240530 (https://download.01.org/0day-ci/archive/20240530/202405300600.3YW7nPfV-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/202405300600.3YW7nPfV-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405300600.3YW7nPfV-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:489:28: warning: conflicting types for 'aw_parse_bin_header_1_0_0' due to enum/integer mismatch; have 'enum aw_bin_err_val(struct aw_bin *)' [-Wenum-int-mismatch]
     489 | static enum aw_bin_err_val aw_parse_bin_header_1_0_0(struct aw_bin *bin)
         |                            ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:234:12: note: previous declaration of 'aw_parse_bin_header_1_0_0' with type 'int(struct aw_bin *)'
     234 | static int aw_parse_bin_header_1_0_0(struct aw_bin *bin);
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~
--
>> drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:166:9: warning: no previous prototype for 'aw9610x_check_chipid' [-Wmissing-prototypes]
     166 | int32_t aw9610x_check_chipid(void *data)
         |         ^~~~~~~~~~~~~~~~~~~~
>> drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:863:9: warning: no previous prototype for 'aw9610x_init' [-Wmissing-prototypes]
     863 | int32_t aw9610x_init(struct aw_sar *p_sar)
         |         ^~~~~~~~~~~~
>> drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:880:6: warning: no previous prototype for 'aw9610x_deinit' [-Wmissing-prototypes]
     880 | void aw9610x_deinit(struct aw_sar *p_sar)
         |      ^~~~~~~~~~~~~~
--
   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: In function 'aw963xx_irq_handle_func':
>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:309:17: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
     309 |         int32_t ret;
         |                 ^~~
   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: At top level:
>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:602:9: warning: no previous prototype for 'aw963xx_check_chipid' [-Wmissing-prototypes]
     602 | int32_t aw963xx_check_chipid(void *data)
         |         ^~~~~~~~~~~~~~~~~~~~
>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:955:9: warning: no previous prototype for 'aw963xx_init' [-Wmissing-prototypes]
     955 | int32_t aw963xx_init(struct aw_sar *p_sar)
         |         ^~~~~~~~~~~~
   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: In function 'aw963xx_init':
>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:957:25: warning: variable 'aw963xx' set but not used [-Wunused-but-set-variable]
     957 |         struct aw963xx *aw963xx;
         |                         ^~~~~~~
   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: At top level:
>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:974:6: warning: no previous prototype for 'aw963xx_deinit' [-Wmissing-prototypes]
     974 | void aw963xx_deinit(struct aw_sar *p_sar)
         |      ^~~~~~~~~~~~~~
   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: In function 'aw963xx_deinit':
   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:976:25: warning: variable 'aw963xx' set but not used [-Wunused-but-set-variable]
     976 |         struct aw963xx *aw963xx;
         |                         ^~~~~~~
--
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:39: warning: Cannot understand  * @brief Read register interface
    on line 39 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:80: warning: Cannot understand  * @brief write register interface
    on line 80 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:125: warning: Cannot understand  * @brief Write the corresponding bit of the register
    on line 125 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:147: warning: Cannot understand  * @brief Continuously write data to the chip
    on line 147 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:177: warning: Cannot understand  * @brief Continuously Read data from chip
    on line 177 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:237: warning: Cannot understand  *
    on line 237 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:544: warning: Cannot understand  * @brief Parse bin file
    on line 544 - I thought it was a doc line
>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:599: warning: Cannot understand  * @brief Calculate the second power
    on line 599 - I thought it was a doc line
   drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:620: warning: Cannot understand  * @brief Calculate the second power
    on line 620 - I thought it was a doc line
--
>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:66: warning: Cannot understand  * @brief  |----------------code ram-----------------|
    on line 66 - I thought it was a doc line
--
>> drivers/input/misc/aw_sar/aw_sar.c:1647: warning: Cannot understand  * @brief sar sensor initialization logic.
    on line 1647 - I thought it was a doc line
>> drivers/input/misc/aw_sar/aw_sar.c:1750: warning: Cannot understand  * @brief Distinguish different chips by chip name and obtain relevant chip information
    on line 1750 - I thought it was a doc line
>> drivers/input/misc/aw_sar/aw_sar.c:1825: warning: Cannot understand  * @brief Drive logic entry
    on line 1825 - I thought it was a doc line


vim +489 drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c

b01a8a3a3fadc9 shuaijie wang 2024-05-29  477  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  478  /********************************************************
b01a8a3a3fadc9 shuaijie wang 2024-05-29  479   *
b01a8a3a3fadc9 shuaijie wang 2024-05-29  480   * If the bin framework header version is 1.0.0,
b01a8a3a3fadc9 shuaijie wang 2024-05-29  481   * determine the data type of bin, and then perform different processing
b01a8a3a3fadc9 shuaijie wang 2024-05-29  482   * according to the data type
b01a8a3a3fadc9 shuaijie wang 2024-05-29  483   * If it is a single bin data type, write the data directly into the structure array
b01a8a3a3fadc9 shuaijie wang 2024-05-29  484   * If it is a multi-bin data type, first obtain the number of bins,
b01a8a3a3fadc9 shuaijie wang 2024-05-29  485   * and then recursively call the bin frame header processing function
b01a8a3a3fadc9 shuaijie wang 2024-05-29  486   * according to the bin number to process the frame header information of each bin separately
b01a8a3a3fadc9 shuaijie wang 2024-05-29  487   *
b01a8a3a3fadc9 shuaijie wang 2024-05-29  488   ********************************************************/
b01a8a3a3fadc9 shuaijie wang 2024-05-29 @489  static enum aw_bin_err_val aw_parse_bin_header_1_0_0(struct aw_bin *bin)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  490  {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  491  	unsigned int bin_data_type;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  492  	enum aw_bin_err_val ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  493  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  494  	bin_data_type = AW_SAR_GET_32_DATA(*(bin->p_addr + 11),
b01a8a3a3fadc9 shuaijie wang 2024-05-29  495  				    *(bin->p_addr + 10),
b01a8a3a3fadc9 shuaijie wang 2024-05-29  496  				    *(bin->p_addr + 9), *(bin->p_addr + 8));
b01a8a3a3fadc9 shuaijie wang 2024-05-29  497  	switch (bin_data_type) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  498  	case DATA_TYPE_REGISTER:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  499  	case DATA_TYPE_DSP_REG:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  500  	case DATA_TYPE_SOC_APP:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  501  		// Divided into two processing methods,
b01a8a3a3fadc9 shuaijie wang 2024-05-29  502  		// one is single bin processing,
b01a8a3a3fadc9 shuaijie wang 2024-05-29  503  		// and the other is single bin processing in multi bin
b01a8a3a3fadc9 shuaijie wang 2024-05-29  504  		bin->single_bin_parse_num += 1;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  505  		if (!bin->multi_bin_parse_num)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  506  			bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  507  		aw_get_single_bin_header_1_0_0(bin);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  508  		break;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  509  	case DATA_TYPE_MULTI_BINS:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  510  		/* Get the number of times to enter multi bins */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  511  		bin->multi_bin_parse_num += 1;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  512  		ret = aw_get_multi_bin_header_1_0_0(bin);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  513  		if (ret < 0)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  514  			return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  515  		break;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  516  	default:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  517  		return AW_BIN_ERROR_DATA_TYPE;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  518  	}
b01a8a3a3fadc9 shuaijie wang 2024-05-29  519  	return AW_BIN_ERROR_NONE;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  520  }
b01a8a3a3fadc9 shuaijie wang 2024-05-29  521  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  522  /* get the bin's header version */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  523  static enum aw_bin_err_val aw_check_bin_header_version(struct aw_bin *bin)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  524  {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  525  	unsigned int header_version;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  526  	enum aw_bin_err_val ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  527  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  528  	header_version = AW_SAR_GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
b01a8a3a3fadc9 shuaijie wang 2024-05-29  529  				     *(bin->p_addr + 5), *(bin->p_addr + 4));
b01a8a3a3fadc9 shuaijie wang 2024-05-29  530  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  531  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  532  	// Write data to the corresponding structure array
b01a8a3a3fadc9 shuaijie wang 2024-05-29  533  	// according to different formats of the bin frame header version
b01a8a3a3fadc9 shuaijie wang 2024-05-29  534  	switch (header_version) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  535  	case HEADER_VERSION_1_0_0:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  536  		ret = aw_parse_bin_header_1_0_0(bin);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  537  		return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  538  	default:
b01a8a3a3fadc9 shuaijie wang 2024-05-29  539  		return AW_BIN_ERROR_HEADER_VERSION;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  540  	}
b01a8a3a3fadc9 shuaijie wang 2024-05-29  541  }
b01a8a3a3fadc9 shuaijie wang 2024-05-29  542  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  543  /**
b01a8a3a3fadc9 shuaijie wang 2024-05-29 @544   * @brief Parse bin file
b01a8a3a3fadc9 shuaijie wang 2024-05-29  545   *
b01a8a3a3fadc9 shuaijie wang 2024-05-29  546   * @param bin: Store the contents of the parsed bin file
b01a8a3a3fadc9 shuaijie wang 2024-05-29  547   * @return 0 if init succeeded, other if error
b01a8a3a3fadc9 shuaijie wang 2024-05-29  548   */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  549  enum aw_bin_err_val aw_sar_parsing_bin_file(struct aw_bin *bin)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  550  {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  551  	enum aw_bin_err_val ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  552  	int i;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  553  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  554  	if (!bin)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  555  		return AW_BIN_ERROR_NULL_POINT;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  556  	bin->p_addr = bin->info.data;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  557  	bin->all_bin_parse_num = 0;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  558  	bin->multi_bin_parse_num = 0;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  559  	bin->single_bin_parse_num = 0;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  560  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  561  	/* filling bins header info */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  562  	ret = aw_check_bin_header_version(bin);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  563  	if (ret < 0)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  564  		return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  565  	bin->p_addr = NULL;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  566  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  567  	/* check bin header info */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  568  	for (i = 0; i < bin->all_bin_parse_num; i++) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  569  		/* check sum */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  570  		ret = aw_check_sum(bin, i);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  571  		if (ret < 0)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  572  			return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  573  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  574  		/* check register num */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  575  		if (bin->header_info[i].bin_data_type == DATA_TYPE_REGISTER) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  576  			ret = aw_check_register_num_v1(bin, i);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  577  			if (ret < 0)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  578  				return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  579  			/* check dsp reg num */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  580  		} else if (bin->header_info[i].bin_data_type == DATA_TYPE_DSP_REG) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  581  			ret = aw_check_dsp_reg_num_v1(bin, i);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  582  			if (ret < 0)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  583  				return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  584  			/* check soc app num */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  585  		} else if (bin->header_info[i].bin_data_type == DATA_TYPE_SOC_APP) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  586  			ret = aw_check_soc_app_num_v1(bin, i);
b01a8a3a3fadc9 shuaijie wang 2024-05-29  587  			if (ret < 0)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  588  				return ret;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  589  		} else {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  590  			bin->header_info[i].valid_data_len = bin->header_info[i].bin_data_len;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  591  		}
b01a8a3a3fadc9 shuaijie wang 2024-05-29  592  	}
b01a8a3a3fadc9 shuaijie wang 2024-05-29  593  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  594  	return AW_BIN_ERROR_NONE;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  595  }
b01a8a3a3fadc9 shuaijie wang 2024-05-29  596  /*********************************Parse bin file code end************************************/
b01a8a3a3fadc9 shuaijie wang 2024-05-29  597  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  598  /**
b01a8a3a3fadc9 shuaijie wang 2024-05-29 @599   * @brief Calculate the second power
b01a8a3a3fadc9 shuaijie wang 2024-05-29  600   *
b01a8a3a3fadc9 shuaijie wang 2024-05-29  601   * @param cnt: ifrequency
b01a8a3a3fadc9 shuaijie wang 2024-05-29  602   * @return the second power
b01a8a3a3fadc9 shuaijie wang 2024-05-29  603   */
b01a8a3a3fadc9 shuaijie wang 2024-05-29  604  uint32_t aw_sar_pow2(uint32_t cnt)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  605  {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  606  	uint32_t sum = 1;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  607  	uint32_t i;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  608  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  609  	if (cnt == 0) {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  610  		sum = 1;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  611  	} else {
b01a8a3a3fadc9 shuaijie wang 2024-05-29  612  		for (i = 0; i < cnt; i++)
b01a8a3a3fadc9 shuaijie wang 2024-05-29  613  			sum *= 2;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  614  	}
b01a8a3a3fadc9 shuaijie wang 2024-05-29  615  
b01a8a3a3fadc9 shuaijie wang 2024-05-29  616  	return sum;
b01a8a3a3fadc9 shuaijie wang 2024-05-29  617  }
b01a8a3a3fadc9 shuaijie wang 2024-05-29  618  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-29 13:06 ` [PATCH V1 5/5] Add support for Awinic sar sensor wangshuaijie
  2024-05-29 22:49   ` kernel test robot
@ 2024-05-30  4:27   ` kernel test robot
  2024-06-05  9:03     ` wangshuaijie
  2024-05-31  8:12   ` Dan Carpenter
  2 siblings, 1 reply; 16+ messages in thread
From: kernel test robot @ 2024-05-30  4:27 UTC (permalink / raw)
  To: wangshuaijie, dmitry.torokhov, robh, krzk+dt, conor+dt, jeff,
	linux-input, devicetree, linux-kernel
  Cc: oe-kbuild-all, wangshuaijie, liweilei, kangjiajun

Hi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc]

url:    https://github.com/intel-lab-lkp/linux/commits/wangshuaijie-awinic-com/dt-bindings-input-Add-YAML-to-Awinic-sar-sensor/20240529-211303
base:   e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
patch link:    https://lore.kernel.org/r/20240529130608.783624-6-wangshuaijie%40awinic.com
patch subject: [PATCH V1 5/5] Add support for Awinic sar sensor.
config: xtensa-randconfig-r064-20240530 (https://download.01.org/0day-ci/archive/20240530/202405301244.1ZqAu1Pf-lkp@intel.com/config)
compiler: xtensa-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/202405301244.1ZqAu1Pf-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405301244.1ZqAu1Pf-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/input/misc/aw_sar/aw_sar.c:1992:34: warning: 'aw_sar_dt_match' defined but not used [-Wunused-const-variable=]
    1992 | static const struct of_device_id aw_sar_dt_match[] = {
         |                                  ^~~~~~~~~~~~~~~


vim +/aw_sar_dt_match +1992 drivers/input/misc/aw_sar/aw_sar.c

  1991	
> 1992	static const struct of_device_id aw_sar_dt_match[] = {
  1993		{ .compatible = "awinic,aw96103" },
  1994		{ .compatible = "awinic,aw96105" },
  1995		{ .compatible = "awinic,aw96303" },
  1996		{ .compatible = "awinic,aw96305" },
  1997		{ .compatible = "awinic,aw96308" },
  1998	};
  1999	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor.
  2024-05-29 13:06 ` [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor wangshuaijie
  2024-05-29 14:25   ` Rob Herring (Arm)
@ 2024-05-31  1:36   ` Rob Herring
  2024-06-05  9:02     ` wangshuaijie
  1 sibling, 1 reply; 16+ messages in thread
From: Rob Herring @ 2024-05-31  1:36 UTC (permalink / raw)
  To: wangshuaijie
  Cc: dmitry.torokhov, krzk+dt, conor+dt, jeff, linux-input, devicetree,
	linux-kernel, liweilei, kangjiajun

On Wed, May 29, 2024 at 01:06:04PM +0000, wangshuaijie@awinic.com wrote:
> From: shuaijie wang <wangshuaijie@awinic.com>
> 
> Add the awinic,aw_sar.yaml file to adapt to the awinic sar sensor driver.
> 
> Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
> ---
>  .../bindings/input/awinic,aw_sar.yaml         | 110 ++++++++++++++++++
>  1 file changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
> 
> diff --git a/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml b/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
> new file mode 100644
> index 000000000000..ed4ec29c9b4d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
> @@ -0,0 +1,110 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/awinic,aw_sar.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Awinic sar sensor driver family
> +
> +maintainers:
> +  - Shuaijie Wang <wangshuaijie@awinic.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - awinic,aw_aw96103
> +      - awinic,aw_aw96105
> +      - awinic,aw_aw96303
> +      - awinic,aw_aw96305
> +      - awinic,aw_aw96308
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  sar-num:

Custom properties need vendor prefix.

> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      set the index of the sar sensor.

What is 'sar'? It's never defined.

How is the index determined? We generally don't do indexes in DT unless 
there is some correlation to the h/w.

> +
> +  vcc0-supply:
> +    description:
> +      Optional regulator for chip, 1.7V-3.6V.
> +
> +  channel_use_flag:

vendor prefix needed plus use '-' rather than '_'. Here and elsewhere.

> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      The flag of channels used.
> +      Configure according to the specific chip channel used.
> +      Bit[31:0] Each bit represents a channel.

So a mask rather than a flag.

Up to 32 channels possible? If not, add constraints.

> +      If the customer uses ch0 and ch2, then channel_use_flag=<0x05>
> +
> +  aw_sar,update_fw:
> +    type: boolean
> +    description:
> +      Choose if you want to update the firmware.

DT is mostly fixed. So someone would want to update the firmware every 
time?

> +
> +  aw_sar,monitor_esd:
> +    type: boolean
> +    description:
> +      Choose if you want to monitor ESD.
> +
> +  aw_sar,pin_set_inter_pull-up:
> +    type: boolean
> +    description:
> +      Choose if you want to set the interrupt pin to internal pull-up.
> +
> +  aw_sar,using_pm_ops:
> +    type: boolean
> +    description:
> +      Choose if you want to use suspend and resume related function.

OS configuration. Doesn't belong in DT.

> +
> +  aw_sar,use_plug_cail:
> +    type: boolean
> +    description:
> +      Choose If you want to perform calibration when plugging and unplugging the charger.
> +
> +  start-mode:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When connecting to aw963xx, select the location where the firmware starts.
> +      set 0 if start in rom.
> +      set 1 if start in ram

Looks like constraints.

> +
> +  irq-mux:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      set csx as irq pin. config this field when connect to aw96308/aw96305BFOR

Constraints? Can you imply this based on the compatible?

> +
> +required:
> +  - compatible
> +  - reg
> +  - sar-num
> +  - interrupts
> +  - channel_use_flag
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        awinic_sar@12 {
> +            compatible = "awinic,aw_sar";
> +            reg = <0x12>;
> +            sar-num = < 0 >;
> +            interrupt-parent = < &tlmm >;
> +            interrupts = <72 0>;
> +            //vcc0-supply = <&pm660l_l4>;

Why commented?

> +            channel_use_flag = <0xff>;
> +            aw_sar,update_fw;
> +            //aw_sar,monitor_esd;
> +            start-mode = < 1 >;
> +            irq-mux = < 2 >;
> +        };
> +    };
> -- 
> 2.45.1
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-29 13:06 ` [PATCH V1 5/5] Add support for Awinic sar sensor wangshuaijie
  2024-05-29 22:49   ` kernel test robot
  2024-05-30  4:27   ` kernel test robot
@ 2024-05-31  8:12   ` Dan Carpenter
  2024-06-05  8:42     ` wangshuaijie
  2 siblings, 1 reply; 16+ messages in thread
From: Dan Carpenter @ 2024-05-31  8:12 UTC (permalink / raw)
  To: oe-kbuild, wangshuaijie, dmitry.torokhov, robh, krzk+dt, conor+dt,
	jeff, linux-input, devicetree, linux-kernel
  Cc: lkp, oe-kbuild-all, wangshuaijie, liweilei, kangjiajun

Hi,

kernel test robot noticed the following build warnings:

url:    https://github.com/intel-lab-lkp/linux/commits/wangshuaijie-awinic-com/dt-bindings-input-Add-YAML-to-Awinic-sar-sensor/20240529-211303
base:   e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
patch link:    https://lore.kernel.org/r/20240529130608.783624-6-wangshuaijie%40awinic.com
patch subject: [PATCH V1 5/5] Add support for Awinic sar sensor.
config: riscv-randconfig-r071-20240530 (https://download.01.org/0day-ci/archive/20240531/202405310138.ry5jf9hL-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 13.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202405310138.ry5jf9hL-lkp@intel.com/

New smatch warnings:
drivers/input/misc/aw_sar/aw_sar.c:221 aw_sar_load_bin_comm() warn: 'fw' from request_firmware() not released on lines: 217.
drivers/input/misc/aw_sar/aw_sar.c:283 aw_sar_irq() error: uninitialized symbol 'irq_status'.
drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:479 aw9610x_get_chip_version() error: __builtin_memcpy() 'aw9610x->chip_name[__builtin_choose_expr((4 == 1), __builtin_strlen(aw9610x->chip_name), __fortify_strlen(aw9610x->chip_name))]' too small (1 vs 2)
drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:227 aw963xx_sram_data_write() error: uninitialized symbol 'ret'.
drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:522 aw963xx_get_cap_offset() warn: inconsistent indenting

Old smatch warnings:
drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:557 aw963xx_get_cap_offset() warn: inconsistent indenting

vim +/fw +221 drivers/input/misc/aw_sar/aw_sar.c

e5df082e247559 shuaijie wang 2024-05-29  203  static int32_t aw_sar_load_bin_comm(struct aw_sar *p_sar)
e5df082e247559 shuaijie wang 2024-05-29  204  {
e5df082e247559 shuaijie wang 2024-05-29  205  	const struct firmware *fw;
e5df082e247559 shuaijie wang 2024-05-29  206  	int32_t ret;
e5df082e247559 shuaijie wang 2024-05-29  207  
e5df082e247559 shuaijie wang 2024-05-29  208  	ret = request_firmware(&fw, p_sar->load_bin.bin_name, p_sar->dev);
e5df082e247559 shuaijie wang 2024-05-29  209  	if (ret != 0) {
e5df082e247559 shuaijie wang 2024-05-29  210  		dev_err(p_sar->dev, "parse %s error!", p_sar->load_bin.bin_name);
e5df082e247559 shuaijie wang 2024-05-29  211  		return ret;
e5df082e247559 shuaijie wang 2024-05-29  212  	}
e5df082e247559 shuaijie wang 2024-05-29  213  
e5df082e247559 shuaijie wang 2024-05-29  214  	ret = aw_sar_parse_bin(fw, p_sar);
e5df082e247559 shuaijie wang 2024-05-29  215  	if (ret != 0) {
e5df082e247559 shuaijie wang 2024-05-29  216  		dev_err(p_sar->dev, "reg_bin %s load error!", p_sar->load_bin.bin_name);

release_firmware(fw);

e5df082e247559 shuaijie wang 2024-05-29  217  		return ret;
e5df082e247559 shuaijie wang 2024-05-29  218  	}
e5df082e247559 shuaijie wang 2024-05-29  219  	release_firmware(fw);
e5df082e247559 shuaijie wang 2024-05-29  220  
e5df082e247559 shuaijie wang 2024-05-29 @221  	return 0;
e5df082e247559 shuaijie wang 2024-05-29  222  }
e5df082e247559 shuaijie wang 2024-05-29  223  
e5df082e247559 shuaijie wang 2024-05-29  224  static int32_t aw_sar_parse_dts_comm(struct device *dev, struct device_node *np,
e5df082e247559 shuaijie wang 2024-05-29  225  		struct aw_sar_dts_info *p_dts_info)
e5df082e247559 shuaijie wang 2024-05-29  226  {
e5df082e247559 shuaijie wang 2024-05-29  227  	int32_t val;
e5df082e247559 shuaijie wang 2024-05-29  228  
e5df082e247559 shuaijie wang 2024-05-29  229  	val = of_property_read_u32(np, "sar-num", &p_dts_info->sar_num);
e5df082e247559 shuaijie wang 2024-05-29  230  	dev_info(dev, "sar num = %d", p_dts_info->sar_num);
e5df082e247559 shuaijie wang 2024-05-29  231  	if (val != 0) {
e5df082e247559 shuaijie wang 2024-05-29  232  		dev_err(dev, "multiple sar failed!");
e5df082e247559 shuaijie wang 2024-05-29  233  		return -EINVAL;
e5df082e247559 shuaijie wang 2024-05-29  234  	}
e5df082e247559 shuaijie wang 2024-05-29  235  
e5df082e247559 shuaijie wang 2024-05-29  236  	p_dts_info->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0);
e5df082e247559 shuaijie wang 2024-05-29  237  	if (p_dts_info->irq_gpio < 0) {
e5df082e247559 shuaijie wang 2024-05-29  238  		p_dts_info->irq_gpio = -1;
e5df082e247559 shuaijie wang 2024-05-29  239  		dev_err(dev, "no irq gpio provided.");
e5df082e247559 shuaijie wang 2024-05-29  240  		return -EINVAL;
e5df082e247559 shuaijie wang 2024-05-29  241  	}
e5df082e247559 shuaijie wang 2024-05-29  242  
e5df082e247559 shuaijie wang 2024-05-29  243  	val = of_property_read_u32(np, "channel_use_flag", &p_dts_info->channel_use_flag);
e5df082e247559 shuaijie wang 2024-05-29  244  	if (val != 0) {
e5df082e247559 shuaijie wang 2024-05-29  245  		dev_err(dev, "channel_use_flag failed!");
e5df082e247559 shuaijie wang 2024-05-29  246  		return -EINVAL;
e5df082e247559 shuaijie wang 2024-05-29  247  	}
e5df082e247559 shuaijie wang 2024-05-29  248  
e5df082e247559 shuaijie wang 2024-05-29  249  	//GPIO is set as internal pull-up input
e5df082e247559 shuaijie wang 2024-05-29  250  	p_dts_info->use_inter_pull_up = of_property_read_bool(np, "aw_sar,pin_set_inter_pull-up");
e5df082e247559 shuaijie wang 2024-05-29  251  	p_dts_info->use_pm = of_property_read_bool(np, "aw_sar,using_pm_ops");
e5df082e247559 shuaijie wang 2024-05-29  252  	p_dts_info->update_fw_flag = of_property_read_bool(np, "aw_sar,update_fw");
e5df082e247559 shuaijie wang 2024-05-29  253  	p_dts_info->use_plug_cail_flag = of_property_read_bool(np, "aw_sar,use_plug_cail");
e5df082e247559 shuaijie wang 2024-05-29  254  	p_dts_info->monitor_esd_flag = of_property_read_bool(np, "aw_sar,monitor_esd");
e5df082e247559 shuaijie wang 2024-05-29  255  
e5df082e247559 shuaijie wang 2024-05-29  256  	return 0;
e5df082e247559 shuaijie wang 2024-05-29  257  }
e5df082e247559 shuaijie wang 2024-05-29  258  
e5df082e247559 shuaijie wang 2024-05-29  259  static int32_t aw_sar_parse_dts(struct aw_sar *p_sar)
e5df082e247559 shuaijie wang 2024-05-29  260  {
e5df082e247559 shuaijie wang 2024-05-29  261  	int32_t ret;
e5df082e247559 shuaijie wang 2024-05-29  262  
e5df082e247559 shuaijie wang 2024-05-29  263  	ret = aw_sar_parse_dts_comm(p_sar->dev, p_sar->i2c->dev.of_node, &p_sar->dts_info);
e5df082e247559 shuaijie wang 2024-05-29  264  
e5df082e247559 shuaijie wang 2024-05-29  265  	//Special requirements of SAR chip
e5df082e247559 shuaijie wang 2024-05-29  266  	if (p_sar->p_sar_para->p_platform_config->p_add_parse_dts_fn != NULL)
e5df082e247559 shuaijie wang 2024-05-29  267  		ret |= p_sar->p_sar_para->p_platform_config->p_add_parse_dts_fn(p_sar);
e5df082e247559 shuaijie wang 2024-05-29  268  
e5df082e247559 shuaijie wang 2024-05-29  269  	return ret;
e5df082e247559 shuaijie wang 2024-05-29  270  }
e5df082e247559 shuaijie wang 2024-05-29  271  
e5df082e247559 shuaijie wang 2024-05-29  272  static irqreturn_t aw_sar_irq(int32_t irq, void *data)
e5df082e247559 shuaijie wang 2024-05-29  273  {
e5df082e247559 shuaijie wang 2024-05-29  274  	struct aw_sar *p_sar = (struct aw_sar *)data;
e5df082e247559 shuaijie wang 2024-05-29  275  	uint32_t irq_status;
e5df082e247559 shuaijie wang 2024-05-29  276  
e5df082e247559 shuaijie wang 2024-05-29  277  	//step1: read clear interrupt
e5df082e247559 shuaijie wang 2024-05-29  278  	if (p_sar->p_sar_para->p_platform_config->p_irq_init->rc_irq_fn != NULL)
e5df082e247559 shuaijie wang 2024-05-29  279  		irq_status = p_sar->p_sar_para->p_platform_config->p_irq_init->rc_irq_fn(p_sar->i2c);
e5df082e247559 shuaijie wang 2024-05-29  280  
e5df082e247559 shuaijie wang 2024-05-29  281  	//step2: Read the status register for status reporting
e5df082e247559 shuaijie wang 2024-05-29  282  	if (p_sar->p_sar_para->p_platform_config->p_irq_init->irq_spec_handler_fn != NULL)
e5df082e247559 shuaijie wang 2024-05-29 @283  		p_sar->p_sar_para->p_platform_config->p_irq_init->irq_spec_handler_fn(irq_status,
e5df082e247559 shuaijie wang 2024-05-29  284  				p_sar);

Probably if ->irq_spec_handler_fn is non-NULL then ->rc_irq_fn is also
non-NULL, but the static checker doesn't know that so it warns about
uninitialized variables.

e5df082e247559 shuaijie wang 2024-05-29  285  
e5df082e247559 shuaijie wang 2024-05-29  286  	//step3: The chip
e5df082e247559 shuaijie wang 2024-05-29  287  
e5df082e247559 shuaijie wang 2024-05-29  288  	if ((!p_sar->dts_info.monitor_esd_flag) && (p_sar->fault_flag == AW_SAR_UNHEALTHY)) {
e5df082e247559 shuaijie wang 2024-05-29  289  		p_sar->fault_flag = AW_SAR_HEALTHY;
e5df082e247559 shuaijie wang 2024-05-29  290  		disable_irq_nosync(p_sar->irq_init.to_irq);
e5df082e247559 shuaijie wang 2024-05-29  291  		p_sar->irq_init.host_irq_stat = IRQ_DISABLE;
e5df082e247559 shuaijie wang 2024-05-29  292  		//aw_sar_soft_reset(p_sar);
e5df082e247559 shuaijie wang 2024-05-29  293  		schedule_delayed_work(&p_sar->update_work, msecs_to_jiffies(500));
e5df082e247559 shuaijie wang 2024-05-29  294  	}
e5df082e247559 shuaijie wang 2024-05-29  295  
e5df082e247559 shuaijie wang 2024-05-29  296  	return IRQ_HANDLED;
e5df082e247559 shuaijie wang 2024-05-29  297  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-31  8:12   ` Dan Carpenter
@ 2024-06-05  8:42     ` wangshuaijie
  0 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-06-05  8:42 UTC (permalink / raw)
  To: dan.carpenter
  Cc: conor+dt, devicetree, dmitry.torokhov, jeff, kangjiajun, krzk+dt,
	linux-input, linux-kernel, liweilei, lkp, oe-kbuild-all,
	oe-kbuild, robh, wangshuaijie

Hi Rob Herring,

On Fri, 31 May 2024 11:12:51 +0300, dan.carpenter@linaro.org wrote:
>Hi,
>
>kernel test robot noticed the following build warnings:
>
>url:    https://github.com/intel-lab-lkp/linux/commits/wangshuaijie-awinic-com/dt-bindings-input-Add-YAML-to-Awinic-sar-sensor/20240529-211303
>base:   e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
>patch link:    https://lore.kernel.org/r/20240529130608.783624-6-wangshuaijie%40awinic.com
>patch subject: [PATCH V1 5/5] Add support for Awinic sar sensor.
>config: riscv-randconfig-r071-20240530 (https://download.01.org/0day-ci/archive/20240531/202405310138.ry5jf9hL-lkp@intel.com/config)
>compiler: riscv64-linux-gcc (GCC) 13.2.0
>
>If you fix the issue in a separate patch/commit (i.e. not just a new version of
>the same patch/commit), kindly add following tags
>| Reported-by: kernel test robot <lkp@intel.com>
>| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
>| Closes: https://lore.kernel.org/r/202405310138.ry5jf9hL-lkp@intel.com/
>
>New smatch warnings:
>drivers/input/misc/aw_sar/aw_sar.c:221 aw_sar_load_bin_comm() warn: 'fw' from request_firmware() not released on lines: 217.
>drivers/input/misc/aw_sar/aw_sar.c:283 aw_sar_irq() error: uninitialized symbol 'irq_status'.
>drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:479 aw9610x_get_chip_version() error: __builtin_memcpy() 'aw9610x->chip_name[__builtin_choose_expr((4 == 1), __builtin_strlen(aw9610x->chip_name), __fortify_strlen(aw9610x->chip_name))]' too small (1 vs 2)
>drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:227 aw963xx_sram_data_write() error: uninitialized symbol 'ret'.
>drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:522 aw963xx_get_cap_offset() warn: inconsistent indenting
>
>Old smatch warnings:
>drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:557 aw963xx_get_cap_offset() warn: inconsistent indenting
>

The patch for version v2 will fix these issues.

>vim +/fw +221 drivers/input/misc/aw_sar/aw_sar.c
>
>e5df082e247559 shuaijie wang 2024-05-29  203  static int32_t aw_sar_load_bin_comm(struct aw_sar *p_sar)
>e5df082e247559 shuaijie wang 2024-05-29  204  {
>e5df082e247559 shuaijie wang 2024-05-29  205  	const struct firmware *fw;
>e5df082e247559 shuaijie wang 2024-05-29  206  	int32_t ret;
>e5df082e247559 shuaijie wang 2024-05-29  207  
>e5df082e247559 shuaijie wang 2024-05-29  208  	ret = request_firmware(&fw, p_sar->load_bin.bin_name, p_sar->dev);
>e5df082e247559 shuaijie wang 2024-05-29  209  	if (ret != 0) {
>e5df082e247559 shuaijie wang 2024-05-29  210  		dev_err(p_sar->dev, "parse %s error!", p_sar->load_bin.bin_name);
>e5df082e247559 shuaijie wang 2024-05-29  211  		return ret;
>e5df082e247559 shuaijie wang 2024-05-29  212  	}
>e5df082e247559 shuaijie wang 2024-05-29  213  
>e5df082e247559 shuaijie wang 2024-05-29  214  	ret = aw_sar_parse_bin(fw, p_sar);
>e5df082e247559 shuaijie wang 2024-05-29  215  	if (ret != 0) {
>e5df082e247559 shuaijie wang 2024-05-29  216  		dev_err(p_sar->dev, "reg_bin %s load error!", p_sar->load_bin.bin_name);
>
>release_firmware(fw);
>

The patch for version v2 will fix this issue.

>e5df082e247559 shuaijie wang 2024-05-29  217  		return ret;
>e5df082e247559 shuaijie wang 2024-05-29  218  	}
>e5df082e247559 shuaijie wang 2024-05-29  219  	release_firmware(fw);
>e5df082e247559 shuaijie wang 2024-05-29  220  
>e5df082e247559 shuaijie wang 2024-05-29 @221  	return 0;
>e5df082e247559 shuaijie wang 2024-05-29  222  }
>e5df082e247559 shuaijie wang 2024-05-29  223  
>e5df082e247559 shuaijie wang 2024-05-29  224  static int32_t aw_sar_parse_dts_comm(struct device *dev, struct device_node *np,
>e5df082e247559 shuaijie wang 2024-05-29  225  		struct aw_sar_dts_info *p_dts_info)
>e5df082e247559 shuaijie wang 2024-05-29  226  {
>e5df082e247559 shuaijie wang 2024-05-29  227  	int32_t val;
>e5df082e247559 shuaijie wang 2024-05-29  228  
>e5df082e247559 shuaijie wang 2024-05-29  229  	val = of_property_read_u32(np, "sar-num", &p_dts_info->sar_num);
>e5df082e247559 shuaijie wang 2024-05-29  230  	dev_info(dev, "sar num = %d", p_dts_info->sar_num);
>e5df082e247559 shuaijie wang 2024-05-29  231  	if (val != 0) {
>e5df082e247559 shuaijie wang 2024-05-29  232  		dev_err(dev, "multiple sar failed!");
>e5df082e247559 shuaijie wang 2024-05-29  233  		return -EINVAL;
>e5df082e247559 shuaijie wang 2024-05-29  234  	}
>e5df082e247559 shuaijie wang 2024-05-29  235  
>e5df082e247559 shuaijie wang 2024-05-29  236  	p_dts_info->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0);
>e5df082e247559 shuaijie wang 2024-05-29  237  	if (p_dts_info->irq_gpio < 0) {
>e5df082e247559 shuaijie wang 2024-05-29  238  		p_dts_info->irq_gpio = -1;
>e5df082e247559 shuaijie wang 2024-05-29  239  		dev_err(dev, "no irq gpio provided.");
>e5df082e247559 shuaijie wang 2024-05-29  240  		return -EINVAL;
>e5df082e247559 shuaijie wang 2024-05-29  241  	}
>e5df082e247559 shuaijie wang 2024-05-29  242  
>e5df082e247559 shuaijie wang 2024-05-29  243  	val = of_property_read_u32(np, "channel_use_flag", &p_dts_info->channel_use_flag);
>e5df082e247559 shuaijie wang 2024-05-29  244  	if (val != 0) {
>e5df082e247559 shuaijie wang 2024-05-29  245  		dev_err(dev, "channel_use_flag failed!");
>e5df082e247559 shuaijie wang 2024-05-29  246  		return -EINVAL;
>e5df082e247559 shuaijie wang 2024-05-29  247  	}
>e5df082e247559 shuaijie wang 2024-05-29  248  
>e5df082e247559 shuaijie wang 2024-05-29  249  	//GPIO is set as internal pull-up input
>e5df082e247559 shuaijie wang 2024-05-29  250  	p_dts_info->use_inter_pull_up = of_property_read_bool(np, "aw_sar,pin_set_inter_pull-up");
>e5df082e247559 shuaijie wang 2024-05-29  251  	p_dts_info->use_pm = of_property_read_bool(np, "aw_sar,using_pm_ops");
>e5df082e247559 shuaijie wang 2024-05-29  252  	p_dts_info->update_fw_flag = of_property_read_bool(np, "aw_sar,update_fw");
>e5df082e247559 shuaijie wang 2024-05-29  253  	p_dts_info->use_plug_cail_flag = of_property_read_bool(np, "aw_sar,use_plug_cail");
>e5df082e247559 shuaijie wang 2024-05-29  254  	p_dts_info->monitor_esd_flag = of_property_read_bool(np, "aw_sar,monitor_esd");
>e5df082e247559 shuaijie wang 2024-05-29  255  
>e5df082e247559 shuaijie wang 2024-05-29  256  	return 0;
>e5df082e247559 shuaijie wang 2024-05-29  257  }
>e5df082e247559 shuaijie wang 2024-05-29  258  
>e5df082e247559 shuaijie wang 2024-05-29  259  static int32_t aw_sar_parse_dts(struct aw_sar *p_sar)
>e5df082e247559 shuaijie wang 2024-05-29  260  {
>e5df082e247559 shuaijie wang 2024-05-29  261  	int32_t ret;
>e5df082e247559 shuaijie wang 2024-05-29  262  
>e5df082e247559 shuaijie wang 2024-05-29  263  	ret = aw_sar_parse_dts_comm(p_sar->dev, p_sar->i2c->dev.of_node, &p_sar->dts_info);
>e5df082e247559 shuaijie wang 2024-05-29  264  
>e5df082e247559 shuaijie wang 2024-05-29  265  	//Special requirements of SAR chip
>e5df082e247559 shuaijie wang 2024-05-29  266  	if (p_sar->p_sar_para->p_platform_config->p_add_parse_dts_fn != NULL)
>e5df082e247559 shuaijie wang 2024-05-29  267  		ret |= p_sar->p_sar_para->p_platform_config->p_add_parse_dts_fn(p_sar);
>e5df082e247559 shuaijie wang 2024-05-29  268  
>e5df082e247559 shuaijie wang 2024-05-29  269  	return ret;
>e5df082e247559 shuaijie wang 2024-05-29  270  }
>e5df082e247559 shuaijie wang 2024-05-29  271  
>e5df082e247559 shuaijie wang 2024-05-29  272  static irqreturn_t aw_sar_irq(int32_t irq, void *data)
>e5df082e247559 shuaijie wang 2024-05-29  273  {
>e5df082e247559 shuaijie wang 2024-05-29  274  	struct aw_sar *p_sar = (struct aw_sar *)data;
>e5df082e247559 shuaijie wang 2024-05-29  275  	uint32_t irq_status;
>e5df082e247559 shuaijie wang 2024-05-29  276  
>e5df082e247559 shuaijie wang 2024-05-29  277  	//step1: read clear interrupt
>e5df082e247559 shuaijie wang 2024-05-29  278  	if (p_sar->p_sar_para->p_platform_config->p_irq_init->rc_irq_fn != NULL)
>e5df082e247559 shuaijie wang 2024-05-29  279  		irq_status = p_sar->p_sar_para->p_platform_config->p_irq_init->rc_irq_fn(p_sar->i2c);
>e5df082e247559 shuaijie wang 2024-05-29  280  
>e5df082e247559 shuaijie wang 2024-05-29  281  	//step2: Read the status register for status reporting
>e5df082e247559 shuaijie wang 2024-05-29  282  	if (p_sar->p_sar_para->p_platform_config->p_irq_init->irq_spec_handler_fn != NULL)
>e5df082e247559 shuaijie wang 2024-05-29 @283  		p_sar->p_sar_para->p_platform_config->p_irq_init->irq_spec_handler_fn(irq_status,
>e5df082e247559 shuaijie wang 2024-05-29  284  				p_sar);
>
>Probably if ->irq_spec_handler_fn is non-NULL then ->rc_irq_fn is also
>non-NULL, but the static checker doesn't know that so it warns about
>uninitialized variables.
>

The patch for version v2 will fix this issue.

>e5df082e247559 shuaijie wang 2024-05-29  285  
>e5df082e247559 shuaijie wang 2024-05-29  286  	//step3: The chip
>e5df082e247559 shuaijie wang 2024-05-29  287  
>e5df082e247559 shuaijie wang 2024-05-29  288  	if ((!p_sar->dts_info.monitor_esd_flag) && (p_sar->fault_flag == AW_SAR_UNHEALTHY)) {
>e5df082e247559 shuaijie wang 2024-05-29  289  		p_sar->fault_flag = AW_SAR_HEALTHY;
>e5df082e247559 shuaijie wang 2024-05-29  290  		disable_irq_nosync(p_sar->irq_init.to_irq);
>e5df082e247559 shuaijie wang 2024-05-29  291  		p_sar->irq_init.host_irq_stat = IRQ_DISABLE;
>e5df082e247559 shuaijie wang 2024-05-29  292  		//aw_sar_soft_reset(p_sar);
>e5df082e247559 shuaijie wang 2024-05-29  293  		schedule_delayed_work(&p_sar->update_work, msecs_to_jiffies(500));
>e5df082e247559 shuaijie wang 2024-05-29  294  	}
>e5df082e247559 shuaijie wang 2024-05-29  295  
>e5df082e247559 shuaijie wang 2024-05-29  296  	return IRQ_HANDLED;
>e5df082e247559 shuaijie wang 2024-05-29  297  }
>
>-- 
>0-DAY CI Kernel Test Service
--

Thanks,

Wang Shuaijie

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor.
  2024-05-31  1:36   ` Rob Herring
@ 2024-06-05  9:02     ` wangshuaijie
  0 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-06-05  9:02 UTC (permalink / raw)
  To: robh
  Cc: conor+dt, devicetree, dmitry.torokhov, jeff, kangjiajun, krzk+dt,
	linux-input, linux-kernel, liweilei, wangshuaijie

On Thu, 30 May 2024 20:36:07 -0500, robh@kernel.org wrote:
>On Wed, May 29, 2024 at 01:06:04PM +0000, wangshuaijie@awinic.com wrote:
>> From: shuaijie wang <wangshuaijie@awinic.com>
>> 
>> Add the awinic,aw_sar.yaml file to adapt to the awinic sar sensor driver.
>> 
>> Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
>> ---
>>  .../bindings/input/awinic,aw_sar.yaml         | 110 ++++++++++++++++++
>>  1 file changed, 110 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
>> 
>> diff --git 
>> a/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml 
>> b/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
>> new file mode 100644
>> index 000000000000..ed4ec29c9b4d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
>> @@ -0,0 +1,110 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/input/awinic,aw_sar.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Awinic sar sensor driver family
>> +
>> +maintainers:
>> +  - Shuaijie Wang <wangshuaijie@awinic.com>
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - awinic,aw_aw96103
>> +      - awinic,aw_aw96105
>> +      - awinic,aw_aw96303
>> +      - awinic,aw_aw96305
>> +      - awinic,aw_aw96308
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  sar-num:
>
>Custom properties need vendor prefix.

The patch for version v2 will fix this issue.

>
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      set the index of the sar sensor.
>
>What is 'sar'? It's never defined.

SAR(Specific Absorption Rate), The patch for version v2 will include this explanation.

>
>How is the index determined? We generally don't do indexes in DT unless there is some correlation to the h/w.

Perhaps using "label" is more appropriate, as it represents the order of the SAR sensor.
The patch for version v2 will fix this issue.

>
>> +
>> +  vcc0-supply:
>> +    description:
>> +      Optional regulator for chip, 1.7V-3.6V.
>> +
>> +  channel_use_flag:
>
>vendor prefix needed plus use '-' rather than '_'. Here and elsewhere.

The patch for version v2 will fix this issue.

>
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      The flag of channels used.
>> +      Configure according to the specific chip channel used.
>> +      Bit[31:0] Each bit represents a channel.
>
>So a mask rather than a flag.

The patch for version v2 will fix this issue.

>
>Up to 32 channels possible? If not, add constraints.
>
>> +      If the customer uses ch0 and ch2, then channel_use_flag=<0x05>
>> +
>> +  aw_sar,update_fw:
>> +    type: boolean
>> +    description:
>> +      Choose if you want to update the firmware.
>
>DT is mostly fixed. So someone would want to update the firmware every time?

In certain situations, if the program in the chip's ROM does not meet the needs,
it is necessary to reload new firmware into the SRAM after each power-on,
and then use the new firmware.

>
>> +
>> +  aw_sar,monitor_esd:
>> +    type: boolean
>> +    description:
>> +      Choose if you want to monitor ESD.
>> +
>> +  aw_sar,pin_set_inter_pull-up:
>> +    type: boolean
>> +    description:
>> +      Choose if you want to set the interrupt pin to internal pull-up.
>> +
>> +  aw_sar,using_pm_ops:
>> +    type: boolean
>> +    description:
>> +      Choose if you want to use suspend and resume related function.
>
>OS configuration. Doesn't belong in DT.

Perhaps this name is not quite appropriate. It mainly determines whether to
put the chip into sleep mode in the PM, and there are other operations in
the PM that are not controlled by this option.

>
>> +
>> +  aw_sar,use_plug_cail:
>> +    type: boolean
>> +    description:
>> +      Choose If you want to perform calibration when plugging and unplugging the charger.
>> +
>> +  start-mode:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      When connecting to aw963xx, select the location where the firmware starts.
>> +      set 0 if start in rom.
>> +      set 1 if start in ram
>
>Looks like constraints.

Only the AW963XX series chips need to configure this option.
I will redescribe it in the V2 version of the patch.

>
>> +
>> +  irq-mux:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      set csx as irq pin. config this field when connect to 
>> + aw96308/aw96305BFOR
>
>Constraints? Can you imply this based on the compatible?

Yes, only AW96308 and AW96305BFOR need to configure this option.
I will redescribe it in the V2 version of the patch.

>
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - sar-num
>> +  - interrupts
>> +  - channel_use_flag
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/gpio/gpio.h>
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>> +    i2c {
>> +        #address-cells = <1>;
>> +        #size-cells = <0>;
>> +        awinic_sar@12 {
>> +            compatible = "awinic,aw_sar";
>> +            reg = <0x12>;
>> +            sar-num = < 0 >;
>> +            interrupt-parent = < &tlmm >;
>> +            interrupts = <72 0>;
>> +            //vcc0-supply = <&pm660l_l4>;
>
>Why commented?

This is a non-essential configuration,
and I will remove it in the v2 version of the patch.

>
>> +            channel_use_flag = <0xff>;
>> +            aw_sar,update_fw;
>> +            //aw_sar,monitor_esd;
>> +            start-mode = < 1 >;
>> +            irq-mux = < 2 >;
>> +        };
>> +    };
>> --
>> 2.45.1
>> 
>

--
Thanks,

Wang Shuaijie

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-30  4:27   ` kernel test robot
@ 2024-06-05  9:03     ` wangshuaijie
  0 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-06-05  9:03 UTC (permalink / raw)
  To: lkp
  Cc: conor+dt, devicetree, dmitry.torokhov, jeff, kangjiajun, krzk+dt,
	linux-input, linux-kernel, liweilei, oe-kbuild-all, robh,
	wangshuaijie

On Thu, 30 May 2024 12:27:32 +0800, lkp@intel.com wrote:
>Hi,
>
>kernel test robot noticed the following build warnings:
>
>[auto build test WARNING on e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc]
>
>url:    https://github.com/intel-lab-lkp/linux/commits/wangshuaijie-awinic-com/dt-bindings-input-Add-YAML-to-Awinic-sar-sensor/20240529-211303
>base:   e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
>patch link:    https://lore.kernel.org/r/20240529130608.783624-6-wangshuaijie%40awinic.com
>patch subject: [PATCH V1 5/5] Add support for Awinic sar sensor.
>config: xtensa-randconfig-r064-20240530 (https://download.01.org/0day-ci/archive/20240530/202405301244.1ZqAu1Pf-lkp@intel.com/config)
>compiler: xtensa-linux-gcc (GCC) 13.2.0
>reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/202405301244.1ZqAu1Pf-lkp@intel.com/reproduce)
>
>If you fix the issue in a separate patch/commit (i.e. not just a new version of
>the same patch/commit), kindly add following tags
>| Reported-by: kernel test robot <lkp@intel.com>
>| Closes: https://lore.kernel.org/oe-kbuild-all/202405301244.1ZqAu1Pf-lkp@intel.com/
>
>All warnings (new ones prefixed by >>):
>
>>> drivers/input/misc/aw_sar/aw_sar.c:1992:34: warning: 'aw_sar_dt_match' defined but not used [-Wunused-const-variable=]
>    1992 | static const struct of_device_id aw_sar_dt_match[] = {
>         |                                  ^~~~~~~~~~~~~~~
>
>
>vim +/aw_sar_dt_match +1992 drivers/input/misc/aw_sar/aw_sar.c
>
>  1991	
>> 1992	static const struct of_device_id aw_sar_dt_match[] = {
>  1993		{ .compatible = "awinic,aw96103" },
>  1994		{ .compatible = "awinic,aw96105" },
>  1995		{ .compatible = "awinic,aw96303" },
>  1996		{ .compatible = "awinic,aw96305" },
>  1997		{ .compatible = "awinic,aw96308" },
>  1998	};
>  1999	
>

The patch for version v2 will fix this issue.

>-- 
>0-DAY CI Kernel Test Service

--
Thanks,

Wang Shuaijie

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 5/5] Add support for Awinic sar sensor.
  2024-05-29 22:49   ` kernel test robot
@ 2024-06-05  9:03     ` wangshuaijie
  0 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-06-05  9:03 UTC (permalink / raw)
  To: lkp
  Cc: conor+dt, devicetree, dmitry.torokhov, jeff, kangjiajun, krzk+dt,
	linux-input, linux-kernel, liweilei, oe-kbuild-all, robh,
	wangshuaijie

On Thu, 30 May 2024 06:49:02 +0800, lkp@intel.com wrote:
>Hi,
>
>kernel test robot noticed the following build warnings:
>
>[auto build test WARNING on e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc]
>
>url:    https://github.com/intel-lab-lkp/linux/commits/wangshuaijie-awinic-com/dt-bindings-input-Add-YAML-to-Awinic-sar-sensor/20240529-211303
>base:   e0cce98fe279b64f4a7d81b7f5c3a23d80b92fbc
>patch link:    https://lore.kernel.org/r/20240529130608.783624-6-wangshuaijie%40awinic.com
>patch subject: [PATCH V1 5/5] Add support for Awinic sar sensor.
>config: riscv-randconfig-r071-20240530 (https://download.01.org/0day-ci/archive/20240530/202405300600.3YW7nPfV-lkp@intel.com/config)
>compiler: riscv64-linux-gcc (GCC) 13.2.0
>reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/202405300600.3YW7nPfV-lkp@intel.com/reproduce)
>
>If you fix the issue in a separate patch/commit (i.e. not just a new version of
>the same patch/commit), kindly add following tags
>| Reported-by: kernel test robot <lkp@intel.com>
>| Closes: https://lore.kernel.org/oe-kbuild-all/202405300600.3YW7nPfV-lkp@intel.com/
>
>All warnings (new ones prefixed by >>):
>
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:489:28: warning: conflicting types for 'aw_parse_bin_header_1_0_0' due to enum/integer mismatch; have 'enum aw_bin_err_val(struct aw_bin *)' [-Wenum-int-mismatch]
>     489 | static enum aw_bin_err_val aw_parse_bin_header_1_0_0(struct aw_bin *bin)
>         |                            ^~~~~~~~~~~~~~~~~~~~~~~~~
>   drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:234:12: note: previous declaration of 'aw_parse_bin_header_1_0_0' with type 'int(struct aw_bin *)'
>     234 | static int aw_parse_bin_header_1_0_0(struct aw_bin *bin);
>         |            ^~~~~~~~~~~~~~~~~~~~~~~~~
>--

The patch for version v2 will fix this issue.

>>> drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:166:9: warning: no previous prototype for 'aw9610x_check_chipid' [-Wmissing-prototypes]
>     166 | int32_t aw9610x_check_chipid(void *data)
>         |         ^~~~~~~~~~~~~~~~~~~~
>>> drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:863:9: warning: no previous prototype for 'aw9610x_init' [-Wmissing-prototypes]
>     863 | int32_t aw9610x_init(struct aw_sar *p_sar)
>         |         ^~~~~~~~~~~~
>>> drivers/input/misc/aw_sar/./aw9610x/aw9610x.c:880:6: warning: no previous prototype for 'aw9610x_deinit' [-Wmissing-prototypes]
>     880 | void aw9610x_deinit(struct aw_sar *p_sar)
>         |      ^~~~~~~~~~~~~~
>--

The patch for version v2 will fix this issue.

>   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: In function 'aw963xx_irq_handle_func':
>>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:309:17: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
>     309 |         int32_t ret;
>         |                 ^~~
>   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: At top level:
>>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:602:9: warning: no previous prototype for 'aw963xx_check_chipid' [-Wmissing-prototypes]
>     602 | int32_t aw963xx_check_chipid(void *data)
>         |         ^~~~~~~~~~~~~~~~~~~~
>>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:955:9: warning: no previous prototype for 'aw963xx_init' [-Wmissing-prototypes]
>     955 | int32_t aw963xx_init(struct aw_sar *p_sar)
>         |         ^~~~~~~~~~~~
>   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: In function 'aw963xx_init':
>>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:957:25: warning: variable 'aw963xx' set but not used [-Wunused-but-set-variable]
>     957 |         struct aw963xx *aw963xx;
>         |                         ^~~~~~~
>   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: At top level:
>>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:974:6: warning: no previous prototype for 'aw963xx_deinit' [-Wmissing-prototypes]
>     974 | void aw963xx_deinit(struct aw_sar *p_sar)
>         |      ^~~~~~~~~~~~~~
>   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c: In function 'aw963xx_deinit':
>   drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:976:25: warning: variable 'aw963xx' set but not used [-Wunused-but-set-variable]
>     976 |         struct aw963xx *aw963xx;
>         |                         ^~~~~~~
>--

The patch for version v2 will fix this issue.

>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:39: warning: Cannot understand  * @brief Read register interface
>    on line 39 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:80: warning: Cannot understand  * @brief write register interface
>    on line 80 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:125: warning: Cannot understand  * @brief Write the corresponding bit of the register
>    on line 125 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:147: warning: Cannot understand  * @brief Continuously write data to the chip
>    on line 147 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:177: warning: Cannot understand  * @brief Continuously Read data from chip
>    on line 177 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:237: warning: Cannot understand  *
>    on line 237 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:544: warning: Cannot understand  * @brief Parse bin file
>    on line 544 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:599: warning: Cannot understand  * @brief Calculate the second power
>    on line 599 - I thought it was a doc line
>   drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c:620: warning: Cannot understand  * @brief Calculate the second power
>    on line 620 - I thought it was a doc line
>--

The patch for version v2 will fix this issue.

>>> drivers/input/misc/aw_sar/./aw963xx/aw963xx.c:66: warning: Cannot understand  * @brief  |----------------code ram-----------------|
>    on line 66 - I thought it was a doc line
>--

The patch for version v2 will fix this issue.

>>> drivers/input/misc/aw_sar/aw_sar.c:1647: warning: Cannot understand  * @brief sar sensor initialization logic.
>    on line 1647 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/aw_sar.c:1750: warning: Cannot understand  * @brief Distinguish different chips by chip name and obtain relevant chip information
>    on line 1750 - I thought it was a doc line
>>> drivers/input/misc/aw_sar/aw_sar.c:1825: warning: Cannot understand  * @brief Drive logic entry
>    on line 1825 - I thought it was a doc line
>

The patch for version v2 will fix this issue.

>
>vim +489 drivers/input/misc/aw_sar/./comm/aw_sar_comm_interface.c
>
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  477  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  478  /********************************************************
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  479   *
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  480   * If the bin framework header version is 1.0.0,
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  481   * determine the data type of bin, and then perform different processing
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  482   * according to the data type
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  483   * If it is a single bin data type, write the data directly into the structure array
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  484   * If it is a multi-bin data type, first obtain the number of bins,
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  485   * and then recursively call the bin frame header processing function
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  486   * according to the bin number to process the frame header information of each bin separately
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  487   *
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  488   ********************************************************/
>b01a8a3a3fadc9 shuaijie wang 2024-05-29 @489  static enum aw_bin_err_val aw_parse_bin_header_1_0_0(struct aw_bin *bin)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  490  {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  491  	unsigned int bin_data_type;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  492  	enum aw_bin_err_val ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  493  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  494  	bin_data_type = AW_SAR_GET_32_DATA(*(bin->p_addr + 11),
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  495  				    *(bin->p_addr + 10),
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  496  				    *(bin->p_addr + 9), *(bin->p_addr + 8));
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  497  	switch (bin_data_type) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  498  	case DATA_TYPE_REGISTER:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  499  	case DATA_TYPE_DSP_REG:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  500  	case DATA_TYPE_SOC_APP:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  501  		// Divided into two processing methods,
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  502  		// one is single bin processing,
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  503  		// and the other is single bin processing in multi bin
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  504  		bin->single_bin_parse_num += 1;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  505  		if (!bin->multi_bin_parse_num)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  506  			bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  507  		aw_get_single_bin_header_1_0_0(bin);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  508  		break;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  509  	case DATA_TYPE_MULTI_BINS:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  510  		/* Get the number of times to enter multi bins */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  511  		bin->multi_bin_parse_num += 1;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  512  		ret = aw_get_multi_bin_header_1_0_0(bin);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  513  		if (ret < 0)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  514  			return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  515  		break;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  516  	default:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  517  		return AW_BIN_ERROR_DATA_TYPE;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  518  	}
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  519  	return AW_BIN_ERROR_NONE;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  520  }
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  521  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  522  /* get the bin's header version */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  523  static enum aw_bin_err_val aw_check_bin_header_version(struct aw_bin *bin)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  524  {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  525  	unsigned int header_version;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  526  	enum aw_bin_err_val ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  527  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  528  	header_version = AW_SAR_GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  529  				     *(bin->p_addr + 5), *(bin->p_addr + 4));
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  530  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  531  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  532  	// Write data to the corresponding structure array
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  533  	// according to different formats of the bin frame header version
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  534  	switch (header_version) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  535  	case HEADER_VERSION_1_0_0:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  536  		ret = aw_parse_bin_header_1_0_0(bin);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  537  		return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  538  	default:
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  539  		return AW_BIN_ERROR_HEADER_VERSION;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  540  	}
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  541  }
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  542  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  543  /**
>b01a8a3a3fadc9 shuaijie wang 2024-05-29 @544   * @brief Parse bin file
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  545   *
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  546   * @param bin: Store the contents of the parsed bin file
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  547   * @return 0 if init succeeded, other if error
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  548   */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  549  enum aw_bin_err_val aw_sar_parsing_bin_file(struct aw_bin *bin)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  550  {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  551  	enum aw_bin_err_val ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  552  	int i;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  553  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  554  	if (!bin)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  555  		return AW_BIN_ERROR_NULL_POINT;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  556  	bin->p_addr = bin->info.data;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  557  	bin->all_bin_parse_num = 0;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  558  	bin->multi_bin_parse_num = 0;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  559  	bin->single_bin_parse_num = 0;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  560  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  561  	/* filling bins header info */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  562  	ret = aw_check_bin_header_version(bin);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  563  	if (ret < 0)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  564  		return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  565  	bin->p_addr = NULL;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  566  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  567  	/* check bin header info */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  568  	for (i = 0; i < bin->all_bin_parse_num; i++) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  569  		/* check sum */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  570  		ret = aw_check_sum(bin, i);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  571  		if (ret < 0)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  572  			return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  573  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  574  		/* check register num */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  575  		if (bin->header_info[i].bin_data_type == DATA_TYPE_REGISTER) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  576  			ret = aw_check_register_num_v1(bin, i);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  577  			if (ret < 0)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  578  				return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  579  			/* check dsp reg num */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  580  		} else if (bin->header_info[i].bin_data_type == DATA_TYPE_DSP_REG) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  581  			ret = aw_check_dsp_reg_num_v1(bin, i);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  582  			if (ret < 0)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  583  				return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  584  			/* check soc app num */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  585  		} else if (bin->header_info[i].bin_data_type == DATA_TYPE_SOC_APP) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  586  			ret = aw_check_soc_app_num_v1(bin, i);
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  587  			if (ret < 0)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  588  				return ret;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  589  		} else {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  590  			bin->header_info[i].valid_data_len = bin->header_info[i].bin_data_len;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  591  		}
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  592  	}
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  593  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  594  	return AW_BIN_ERROR_NONE;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  595  }
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  596  /*********************************Parse bin file code end************************************/
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  597  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  598  /**
>b01a8a3a3fadc9 shuaijie wang 2024-05-29 @599   * @brief Calculate the second power
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  600   *
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  601   * @param cnt: ifrequency
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  602   * @return the second power
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  603   */
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  604  uint32_t aw_sar_pow2(uint32_t cnt)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  605  {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  606  	uint32_t sum = 1;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  607  	uint32_t i;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  608  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  609  	if (cnt == 0) {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  610  		sum = 1;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  611  	} else {
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  612  		for (i = 0; i < cnt; i++)
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  613  			sum *= 2;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  614  	}
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  615  
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  616  	return sum;
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  617  }
>b01a8a3a3fadc9 shuaijie wang 2024-05-29  618  
>
>-- 
>0-DAY CI Kernel Test Service
--

Thanks,

Wang Shuaijie

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor.
  2024-05-29 14:25   ` Rob Herring (Arm)
@ 2024-06-05  9:04     ` wangshuaijie
  0 siblings, 0 replies; 16+ messages in thread
From: wangshuaijie @ 2024-06-05  9:04 UTC (permalink / raw)
  To: robh
  Cc: conor+dt, devicetree, dmitry.torokhov, jeff, kangjiajun, krzk+dt,
	linux-input, linux-kernel, liweilei, wangshuaijie

On Wed, 29 May 2024 09:25:23 -0500, robh@kernel.org Wrote:
>On Wed, 29 May 2024 13:06:04 +0000, wangshuaijie@awinic.com wrote:
>> From: shuaijie wang <wangshuaijie@awinic.com>
>> 
>> Add the awinic,aw_sar.yaml file to adapt to the awinic sar sensor driver.
>> 
>> Signed-off-by: shuaijie wang <wangshuaijie@awinic.com>
>> ---
>>  .../bindings/input/awinic,aw_sar.yaml         | 110 ++++++++++++++++++
>>  1 file changed, 110 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/input/awinic,aw_sar.yaml
>> 
>
>My bot found errors running 'make dt_binding_check' on your patch:
>
>yamllint warnings/errors:
>
>dtschema/dtc warnings/errors:
>/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/input/awinic,aw_sar.example.dtb: awinic_sar@12: 'aw_sar,update_fw' does not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^100ask,.*', '^70mai,.*', '^8dev,.*', '^GEFanuc,.*', '^IBM,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acbel,.*', '^acelink,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^adieng,.*', '^admatec,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^airoha,.*', '^al,.*', '^alcatel,.*', '^aldec,.*', '^alfa-network,.*', '^allegro,.*', '^alliedvision,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^amphenol,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^anbernic,.*', '^andestech,.*', '^anvo,.*', '^aosong,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arcom,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asrock,.*', '^asteralabs,.*', '^asus,.*', '^atheros,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^belling,.*', '^bhf,.*', '^bigtreetech,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bsh,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^bytedance,.*', '^calamp,.*', '^calao,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^chargebyte,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chongzhou,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^clockwork,.*', '^cloos,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coolpi,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^ctera,.*', '^ctu,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cyx,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^densitron,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dimonoff,.*', '^diodes,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebbg,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edgeble,.*', '^edimax,.*', '^edt,.*', '^ees,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embedfire,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^enclustra,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^engleder,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairchild,.*', '^fairphone,.*', '^faraday,.*', '^fascontek,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^freebox,.*', '^freecom,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^fxtec,.*', '^galaxycore,.*', '^gardena,.*', '^gateway,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^gemtek,.*', '^genesys,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^glinet,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goldelico,.*', '^goodix,.*', '^google,.*', '^goramo,.*', '^gplus,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haochuangyi,.*', '^haoyu,.*', '^hardkernel,.*', '^hechuang,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisi,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperf,.*', '^hoperun,.*', '^hp,.*', '^hpe,.*', '^hsg,.*', '^htc,.*', '^huawei,.*', '^hugsun,.*', '^hwacom,.*', '^hxt,.*', '^hycon,.*', '^hydis,.*', '^hynitron,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^iei,.*', '^ifi,.*', '^ilitek,.*', '^imagis,.*', '^img,.*', '^imi,.*', '^inanbo,.*', '^incircuit,.*', '^indiedroid,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^ingrasys,.*', '^injoinic,.*', '^innocomm,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inventec,.*', '^inversepath,.*', '^iom,.*', '^irondevice,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jadard,.*', '^jasonic,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^jide,.*', '^joz,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^lctech,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^lineartechnology,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongmasses,.*', '^loongson,.*', '^lsi,.*', '^lunzn,.*', '^luxul,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marantec,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^maxlinear,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsensing,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^methode,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^milkv,.*', '^miniand,.*', '^minix,.*', '^mips,.*', '^miramems,.*', '^mitsubishi,.*', '^mitsumi,.*', '^mixel,.*', '^miyoo,.*', '^mntre,.*', '^mobileye,.*', '^modtronix,.*', '^moortec,.*', '^mosaixtech,.*', '^motorcomm,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxic,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^newvision,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novatek,.*', '^novtech,.*', '^numonyx,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^ocs,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^oneplus,.*', '^onie,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^openailab,.*', '^opencores,.*', '^openembed,.*', '^openpandora,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^osmc,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^polyhex,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^powkiddy,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^quanta,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^rve,.*', '^saef,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sercomm,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shift,.*', '^shimafuji,.*', '^shineworld,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silan,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sinowealth,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smartrg,.*', '^smi,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^sophgo,.*', '^sourceparts,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^square,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^starterkit,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^storopack,.*', '^summit,.*', '^sunchip,.*', '^sundance,.*', '^sunplus,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^synopsys,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^team-source-display,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^techwell,.*', '^teejet,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tesla,.*', '^tfc,.*', '^thead,.*', '^thine,.*', '^thingyjp,.*', '^thundercomm,.*', '^thwc,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^transpeed,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^turing,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ufispace,.*', '^ugoos,.*', '^uni-t,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^usr,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^vertexcom,.*', '^via,.*', '^vialab,.*', '^vicor,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^voltafield,.*', '^vot,.*', '^vscom,.*', '^vxt,.*', '^wacom,.*', '^wanchanglong,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^widora,.*', '^wiligear,.*', '^willsemi,.*', '^winbond,.*', '^wingtech,.*', '^winlink,.*', '^winstar,.*', '^wirelesstag,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xen,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yadro,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^yiming,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*', 'pinctrl-[0-9]+'
>	from schema $id: http://devicetree.org/schemas/vendor-prefixes.yaml#
>Documentation/devicetree/bindings/input/awinic,aw_sar.example.dtb: /example-0/i2c/awinic_sar@12: failed to match any schema with compatible: ['awinic,aw_sar']
>

The patch for version v2 will fix these issues.

>doc reference errors (make refcheckdocs):
>
>See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240529130608.783624-2-wangshuaijie@awinic.com
>
>The base for the series is generally the latest rc1. A different dependency
>should be noted in *this* patch.
>
>If you already ran 'make dt_binding_check' and didn't see the above
>error(s), then make sure 'yamllint' is installed and dt-schema is up to
>date:
>
>pip3 install dtschema --upgrade
>
>Please check and re-submit after running the above command yourself. Note
>that DT_SCHEMA_FILES can be set to your schema file to speed up checking
>your schema. However, it must be unset to test all examples with your schema.
--

Thanks,

Wang Shuaijie

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2024-06-05  9:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-29 13:06 [PATCH V1 0/5] Add support for Awinic SAR sensor wangshuaijie
2024-05-29 13:06 ` [PATCH V1 1/5] dt-bindings: input: Add YAML to Awinic sar sensor wangshuaijie
2024-05-29 14:25   ` Rob Herring (Arm)
2024-06-05  9:04     ` wangshuaijie
2024-05-31  1:36   ` Rob Herring
2024-06-05  9:02     ` wangshuaijie
2024-05-29 13:06 ` [PATCH V1 2/5] Add universal interface for the aw_sar driver wangshuaijie
2024-05-29 13:06 ` [PATCH V1 3/5] Add aw9610x series related interfaces to " wangshuaijie
2024-05-29 13:06 ` [PATCH V1 4/5] Add aw963xx " wangshuaijie
2024-05-29 13:06 ` [PATCH V1 5/5] Add support for Awinic sar sensor wangshuaijie
2024-05-29 22:49   ` kernel test robot
2024-06-05  9:03     ` wangshuaijie
2024-05-30  4:27   ` kernel test robot
2024-06-05  9:03     ` wangshuaijie
2024-05-31  8:12   ` Dan Carpenter
2024-06-05  8:42     ` wangshuaijie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).