From: shuaijie wang <[email protected]>
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
From: shuaijie wang <[email protected]>
Signed-off-by: shuaijie wang <[email protected]>
---
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<[email protected]>
+ *
+ * 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 ", ®_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", ®_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", ®_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, ®_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
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/[email protected]/config)
compiler: riscv64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
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
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/[email protected]/config)
compiler: xtensa-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
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
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/[email protected]/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 <[email protected]>
| Reported-by: Dan Carpenter <[email protected]>
| Closes: https://lore.kernel.org/r/[email protected]/
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
Hi Rob Herring,
On Fri, 31 May 2024 11:12:51 +0300, [email protected] 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/[email protected]/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 <[email protected]>
>| Reported-by: Dan Carpenter <[email protected]>
>| Closes: https://lore.kernel.org/r/[email protected]/
>
>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
On Thu, 30 May 2024 12:27:32 +0800, [email protected] 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/[email protected]/config)
>compiler: xtensa-linux-gcc (GCC) 13.2.0
>reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/[email protected]/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 <[email protected]>
>| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
>
>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
On Thu, 30 May 2024 06:49:02 +0800, [email protected] 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/[email protected]/config)
>compiler: riscv64-linux-gcc (GCC) 13.2.0
>reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240530/[email protected]/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 <[email protected]>
>| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
>
>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