From 2e1a57d5b0adbb5bd1d85245ec29b6d3cc7edc69 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Wed, 21 Aug 2024 16:54:52 -0500 Subject: mfd: axp20x: Add ADC, BAT, and USB cells for AXP717 Add support for the AXP717 PMIC to utilize the ADC (for reading voltage, current, and temperature information from the PMIC) as well as the USB charger and battery. Signed-off-by: Chris Morgan Link: https://lore.kernel.org/r/20240821215456.962564-12-macroalpha82@gmail.com Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 25 ++++++++++++++++++++++++- include/linux/mfd/axp20x.h | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index dacd3c96c9f5..4051551757f2 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -209,13 +209,23 @@ static const struct regmap_access_table axp313a_volatile_table = { }; static const struct regmap_range axp717_writeable_ranges[] = { + regmap_reg_range(AXP717_PMU_FAULT, AXP717_MODULE_EN_CONTROL_1), + regmap_reg_range(AXP717_MIN_SYS_V_CONTROL, AXP717_BOOST_CONTROL), + regmap_reg_range(AXP717_VSYS_V_POWEROFF, AXP717_VSYS_V_POWEROFF), regmap_reg_range(AXP717_IRQ0_EN, AXP717_IRQ4_EN), regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE), + regmap_reg_range(AXP717_ICC_CHG_SET, AXP717_CV_CHG_SET), regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL), + regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL), + regmap_reg_range(AXP717_ADC_DATA_SEL, AXP717_ADC_DATA_SEL), }; static const struct regmap_range axp717_volatile_ranges[] = { + regmap_reg_range(AXP717_ON_INDICATE, AXP717_PMU_FAULT), regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE), + regmap_reg_range(AXP717_BATT_PERCENT_DATA, AXP717_BATT_PERCENT_DATA), + regmap_reg_range(AXP717_BATT_V_H, AXP717_BATT_CHRG_I_L), + regmap_reg_range(AXP717_ADC_DATA_H, AXP717_ADC_DATA_L), }; static const struct regmap_access_table axp717_writeable_table = { @@ -308,6 +318,12 @@ static const struct resource axp22x_usb_power_supply_resources[] = { DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), }; +static const struct resource axp717_usb_power_supply_resources[] = { + DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_OVER_V, "VBUS_OVER_V"), + DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), + DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), +}; + /* AXP803 and AXP813/AXP818 share the same interrupts */ static const struct resource axp803_usb_power_supply_resources[] = { DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), @@ -422,7 +438,7 @@ static const struct regmap_config axp717_regmap_config = { .val_bits = 8, .wr_table = &axp717_writeable_table, .volatile_table = &axp717_volatile_table, - .max_register = AXP717_CPUSLDO_CONTROL, + .max_register = AXP717_ADC_DATA_L, .cache_type = REGCACHE_MAPLE, }; @@ -1024,6 +1040,13 @@ static struct mfd_cell axp313a_cells[] = { static struct mfd_cell axp717_cells[] = { MFD_CELL_NAME("axp20x-regulator"), MFD_CELL_RES("axp20x-pek", axp717_pek_resources), + MFD_CELL_OF("axp717-adc", + NULL, NULL, 0, 0, "x-powers,axp717-adc"), + MFD_CELL_OF("axp20x-usb-power-supply", + axp717_usb_power_supply_resources, NULL, 0, 0, + "x-powers,axp717-usb-power-supply"), + MFD_CELL_OF("axp20x-battery-power-supply", + NULL, NULL, 0, 0, "x-powers,axp717-battery-power-supply"), }; static const struct resource axp288_adc_resources[] = { diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index 8c0a33a2e9ce..9b7ef473adcb 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -115,6 +115,16 @@ enum axp20x_variants { #define AXP313A_IRQ_STATE 0x21 #define AXP717_ON_INDICATE 0x00 +#define AXP717_PMU_STATUS_2 0x01 +#define AXP717_BC_DETECT 0x05 +#define AXP717_PMU_FAULT 0x08 +#define AXP717_MODULE_EN_CONTROL_1 0x0b +#define AXP717_MIN_SYS_V_CONTROL 0x15 +#define AXP717_INPUT_VOL_LIMIT_CTRL 0x16 +#define AXP717_INPUT_CUR_LIMIT_CTRL 0x17 +#define AXP717_MODULE_EN_CONTROL_2 0x19 +#define AXP717_BOOST_CONTROL 0x1e +#define AXP717_VSYS_V_POWEROFF 0x24 #define AXP717_IRQ0_EN 0x40 #define AXP717_IRQ1_EN 0x41 #define AXP717_IRQ2_EN 0x42 @@ -125,6 +135,9 @@ enum axp20x_variants { #define AXP717_IRQ2_STATE 0x4a #define AXP717_IRQ3_STATE 0x4b #define AXP717_IRQ4_STATE 0x4c +#define AXP717_ICC_CHG_SET 0x62 +#define AXP717_ITERM_CHG_SET 0x63 +#define AXP717_CV_CHG_SET 0x64 #define AXP717_DCDC_OUTPUT_CONTROL 0x80 #define AXP717_DCDC1_CONTROL 0x83 #define AXP717_DCDC2_CONTROL 0x84 @@ -145,6 +158,19 @@ enum axp20x_variants { #define AXP717_CLDO3_CONTROL 0x9d #define AXP717_CLDO4_CONTROL 0x9e #define AXP717_CPUSLDO_CONTROL 0x9f +#define AXP717_BATT_PERCENT_DATA 0xa4 +#define AXP717_ADC_CH_EN_CONTROL 0xc0 +#define AXP717_BATT_V_H 0xc4 +#define AXP717_BATT_V_L 0xc5 +#define AXP717_VBUS_V_H 0xc6 +#define AXP717_VBUS_V_L 0xc7 +#define AXP717_VSYS_V_H 0xc8 +#define AXP717_VSYS_V_L 0xc9 +#define AXP717_BATT_CHRG_I_H 0xca +#define AXP717_BATT_CHRG_I_L 0xcb +#define AXP717_ADC_DATA_SEL 0xcd +#define AXP717_ADC_DATA_H 0xce +#define AXP717_ADC_DATA_L 0xcf #define AXP806_STARTUP_SRC 0x00 #define AXP806_CHIP_ID 0x03 -- cgit From 3b92fc43bfd961fe83c82efd6bc8a852a29ea4de Mon Sep 17 00:00:00 2001 From: Barnabás Czémán Date: Mon, 19 Aug 2024 00:29:39 +0200 Subject: iio: magnetometer: ak8975: Relax failure on unknown id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relax failure when driver gets an unknown device id for allow probe for register compatible devices. Signed-off-by: Barnabás Czémán Link: https://patch.msgid.link/20240819-ak09918-v4-1-f0734d14cfb9@mainlining.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index ccbebe5b66cd..67d5d1f2402f 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -484,10 +484,14 @@ static int ak8975_who_i_am(struct i2c_client *client, if (wia_val[1] == AK09916_DEVICE_ID) return 0; break; - default: - dev_err(&client->dev, "Type %d unknown\n", type); } - return -ENODEV; + + dev_info(&client->dev, "Device ID %x is unknown.\n", wia_val[1]); + /* + * Let driver to probe on unknown id for support more register + * compatible variants. + */ + return 0; } /* -- cgit From 129464e86c7445a858b790ac2d28d35f58256bbe Mon Sep 17 00:00:00 2001 From: Barnabás Czémán Date: Mon, 19 Aug 2024 00:29:40 +0200 Subject: iio: magnetometer: ak8975: Fix reading for ak099xx sensors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move ST2 reading with overflow handling after measurement data reading. ST2 register read have to be read after read measurment data, because it means end of the reading and realease the lock on the data. Remove ST2 read skip on interrupt based waiting because ST2 required to be read out at and of the axis read. Fixes: 57e73a423b1e ("iio: ak8975: add ak09911 and ak09912 support") Signed-off-by: Barnabás Czémán Link: https://patch.msgid.link/20240819-ak09918-v4-2-f0734d14cfb9@mainlining.org Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 67d5d1f2402f..1d5f79b7005b 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -696,22 +696,8 @@ static int ak8975_start_read_axis(struct ak8975_data *data, if (ret < 0) return ret; - /* This will be executed only for non-interrupt based waiting case */ - if (ret & data->def->ctrl_masks[ST1_DRDY]) { - ret = i2c_smbus_read_byte_data(client, - data->def->ctrl_regs[ST2]); - if (ret < 0) { - dev_err(&client->dev, "Error in reading ST2\n"); - return ret; - } - if (ret & (data->def->ctrl_masks[ST2_DERR] | - data->def->ctrl_masks[ST2_HOFL])) { - dev_err(&client->dev, "ST2 status error 0x%x\n", ret); - return -EINVAL; - } - } - - return 0; + /* Return with zero if the data is ready. */ + return !data->def->ctrl_regs[ST1_DRDY]; } /* Retrieve raw flux value for one of the x, y, or z axis. */ @@ -738,6 +724,20 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val) if (ret < 0) goto exit; + /* Read out ST2 for release lock on measurment data. */ + ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]); + if (ret < 0) { + dev_err(&client->dev, "Error in reading ST2\n"); + goto exit; + } + + if (ret & (data->def->ctrl_masks[ST2_DERR] | + data->def->ctrl_masks[ST2_HOFL])) { + dev_err(&client->dev, "ST2 status error 0x%x\n", ret); + ret = -EINVAL; + goto exit; + } + mutex_unlock(&data->lock); pm_runtime_mark_last_busy(&data->client->dev); -- cgit From c19bf7faea5b3e85c8a6da12155b3968c6105ba3 Mon Sep 17 00:00:00 2001 From: Danila Tikhonov Date: Mon, 19 Aug 2024 00:29:41 +0200 Subject: dt-bindings: iio: magnetometer: Add ak09118 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document asahi-kasei,ak09918 compatible as a fallback compatible, ak09918 is register compatible with ak09912. Signed-off-by: Danila Tikhonov Signed-off-by: Barnabás Czémán Acked-by: Conor Dooley Link: https://patch.msgid.link/20240819-ak09918-v4-3-f0734d14cfb9@mainlining.org Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml b/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml index fe5145d3b73c..e8ca9a234027 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml +++ b/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml @@ -18,6 +18,10 @@ properties: - asahi-kasei,ak09911 - asahi-kasei,ak09912 - asahi-kasei,ak09916 + - items: + # ak09918 is register compatible with ak09912. + - const: asahi-kasei,ak09918 + - const: asahi-kasei,ak09912 - enum: - ak8975 - ak8963 -- cgit From 89cf93bfb3bedbaa1b7678c66cabd7ba0df6f05c Mon Sep 17 00:00:00 2001 From: Danila Tikhonov Date: Mon, 19 Aug 2024 00:29:42 +0200 Subject: iio: magnetometer: ak8975: Add AK09118 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add additional AK09118 to the magnetometer driver which has the same register mapping and scaling as the AK09112 device. Signed-off-by: Danila Tikhonov Acked-by: Krzysztof Kozlowski Signed-off-by: Barnabás Czémán Link: https://patch.msgid.link/20240819-ak09918-v4-4-f0734d14cfb9@mainlining.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/Kconfig | 2 +- drivers/iio/magnetometer/ak8975.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig index cd2917d71904..8eb718f5e50f 100644 --- a/drivers/iio/magnetometer/Kconfig +++ b/drivers/iio/magnetometer/Kconfig @@ -39,7 +39,7 @@ config AK8975 select IIO_TRIGGERED_BUFFER help Say yes here to build support for Asahi Kasei AK8975, AK8963, - AK09911, AK09912 or AK09916 3-Axis Magnetometer. + AK09911, AK09912, AK09916 or AK09918 3-Axis Magnetometer. To compile this driver as a module, choose M here: the module will be called ak8975. diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 1d5f79b7005b..18077fb463a9 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -78,6 +78,7 @@ */ #define AK09912_REG_WIA1 0x00 #define AK09912_REG_WIA2 0x01 +#define AK09918_DEVICE_ID 0x0C #define AK09916_DEVICE_ID 0x09 #define AK09912_DEVICE_ID 0x04 #define AK09911_DEVICE_ID 0x05 @@ -209,6 +210,7 @@ enum asahi_compass_chipset { AK09911, AK09912, AK09916, + AK09918, }; enum ak_ctrl_reg_addr { @@ -371,6 +373,34 @@ static const struct ak_def ak_def_array[] = { AK09912_REG_HXL, AK09912_REG_HYL, AK09912_REG_HZL}, + }, + [AK09918] = { + /* ak09918 is register compatible with ak09912 this is for avoid + * unknown id messages. + */ + .type = AK09918, + .raw_to_gauss = ak09912_raw_to_gauss, + .range = 32752, + .ctrl_regs = { + AK09912_REG_ST1, + AK09912_REG_ST2, + AK09912_REG_CNTL2, + AK09912_REG_ASAX, + AK09912_MAX_REGS}, + .ctrl_masks = { + AK09912_REG_ST1_DRDY_MASK, + AK09912_REG_ST2_HOFL_MASK, + 0, + AK09912_REG_CNTL2_MODE_MASK}, + .ctrl_modes = { + AK09912_REG_CNTL_MODE_POWER_DOWN, + AK09912_REG_CNTL_MODE_ONCE, + AK09912_REG_CNTL_MODE_SELF_TEST, + AK09912_REG_CNTL_MODE_FUSE_ROM}, + .data_regs = { + AK09912_REG_HXL, + AK09912_REG_HYL, + AK09912_REG_HZL}, } }; @@ -452,6 +482,7 @@ static int ak8975_who_i_am(struct i2c_client *client, /* * Signature for each device: * Device | WIA1 | WIA2 + * AK09918 | DEVICE_ID_| AK09918_DEVICE_ID * AK09916 | DEVICE_ID_| AK09916_DEVICE_ID * AK09912 | DEVICE_ID | AK09912_DEVICE_ID * AK09911 | DEVICE_ID | AK09911_DEVICE_ID @@ -484,6 +515,10 @@ static int ak8975_who_i_am(struct i2c_client *client, if (wia_val[1] == AK09916_DEVICE_ID) return 0; break; + case AK09918: + if (wia_val[1] == AK09918_DEVICE_ID) + return 0; + break; } dev_info(&client->dev, "Device ID %x is unknown.\n", wia_val[1]); @@ -1071,6 +1106,7 @@ static const struct i2c_device_id ak8975_id[] = { {"ak09911", (kernel_ulong_t)&ak_def_array[AK09911] }, {"ak09912", (kernel_ulong_t)&ak_def_array[AK09912] }, {"ak09916", (kernel_ulong_t)&ak_def_array[AK09916] }, + {"ak09918", (kernel_ulong_t)&ak_def_array[AK09918] }, {} }; MODULE_DEVICE_TABLE(i2c, ak8975_id); @@ -1085,6 +1121,7 @@ static const struct of_device_id ak8975_of_match[] = { { .compatible = "asahi-kasei,ak09912", .data = &ak_def_array[AK09912] }, { .compatible = "ak09912", .data = &ak_def_array[AK09912] }, { .compatible = "asahi-kasei,ak09916", .data = &ak_def_array[AK09916] }, + { .compatible = "asahi-kasei,ak09918", .data = &ak_def_array[AK09918] }, {} }; MODULE_DEVICE_TABLE(of, ak8975_of_match); -- cgit From dae65fc2bc76851520bd4ae748fe09656cc65057 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sat, 24 Aug 2024 01:07:18 +0300 Subject: iio: proximity: cros_ec_mkbp_proximity: Switch to including mod_devicetable.h for struct of_device_id definition of.h was only included for this definition, so include the correct header instead. Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20240823220718.743596-1-andy.shevchenko@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/cros_ec_mkbp_proximity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/proximity/cros_ec_mkbp_proximity.c b/drivers/iio/proximity/cros_ec_mkbp_proximity.c index 4df506bb8b38..cff57d851762 100644 --- a/drivers/iio/proximity/cros_ec_mkbp_proximity.c +++ b/drivers/iio/proximity/cros_ec_mkbp_proximity.c @@ -6,10 +6,10 @@ */ #include +#include #include #include #include -#include #include #include #include -- cgit From 3f131813d70191f187f804c176a03d4f9e80ba73 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sat, 24 Aug 2024 02:00:56 +0300 Subject: iio: accel: bmc150: use fwnode_irq_get_byname() Use the generic fwnode_irq_get_byname() in place of of_irq_get_byname() to get the IRQ number from the interrupt pin. Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20240823230056.745872-1-andy.shevchenko@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 03121d020470..14ce03c70ab5 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -10,9 +10,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -514,7 +514,7 @@ static void bmc150_accel_interrupts_setup(struct iio_dev *indio_dev, */ irq_info = bmc150_accel_interrupts_int1; if (data->type == BOSCH_BMC156 || - irq == of_irq_get_byname(dev->of_node, "INT2")) + irq == fwnode_irq_get_byname(dev_fwnode(dev), "INT2")) irq_info = bmc150_accel_interrupts_int2; for (i = 0; i < BMC150_ACCEL_INTERRUPTS; i++) -- cgit From 525e9cd5ac056e827b7a31bf48b8980d5f2e726b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sat, 24 Aug 2024 02:01:07 +0300 Subject: iio: accel: bmc150: Improve bmc150_apply_bosc0200_acpi_orientation() By using ACPI_HANDLE() the handler argument can be retrieved directly. Replace ACPI_COMPANION() + dereference with ACPI_HANDLE(). Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20240823230107.745900-1-andy.shevchenko@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 14ce03c70ab5..0f32c1e92b4d 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -387,7 +387,7 @@ static bool bmc150_apply_bosc0200_acpi_orientation(struct device *dev, struct iio_mount_matrix *orientation) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct acpi_device *adev = ACPI_COMPANION(dev); + acpi_handle handle = ACPI_HANDLE(dev); char *name, *alt_name, *label; if (strcmp(dev_name(dev), "i2c-BOSC0200:base") == 0) { @@ -398,9 +398,9 @@ static bool bmc150_apply_bosc0200_acpi_orientation(struct device *dev, label = "accel-display"; } - if (acpi_has_method(adev->handle, "ROTM")) { + if (acpi_has_method(handle, "ROTM")) { name = "ROTM"; - } else if (acpi_has_method(adev->handle, alt_name)) { + } else if (acpi_has_method(handle, alt_name)) { name = alt_name; indio_dev->label = label; } else { -- cgit From 16531118ba63dd9bcd65203d04a9c9d6f6800547 Mon Sep 17 00:00:00 2001 From: Denis Benato Date: Sat, 24 Aug 2024 16:11:22 +0200 Subject: iio: bmi323: peripheral in lowest power state on suspend The bmi323 is mounted on some devices that are powered by an internal battery: help in reducing system overall power drain while the system is in s2idle or the imu driver is not loaded by resetting it in its lowest power draining state. Signed-off-by: Denis Benato Link: https://patch.msgid.link/20240824141122.334620-2-benato.denis96@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/bmi323/bmi323_core.c | 161 ++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/bmi323/bmi323_core.c b/drivers/iio/imu/bmi323/bmi323_core.c index 4b2b211a3e88..671401ce80dc 100644 --- a/drivers/iio/imu/bmi323/bmi323_core.c +++ b/drivers/iio/imu/bmi323/bmi323_core.c @@ -118,6 +118,38 @@ static const struct bmi323_hw bmi323_hw[2] = { }, }; +static const unsigned int bmi323_reg_savestate[] = { + BMI323_INT_MAP1_REG, + BMI323_INT_MAP2_REG, + BMI323_IO_INT_CTR_REG, + BMI323_IO_INT_CONF_REG, + BMI323_ACC_CONF_REG, + BMI323_GYRO_CONF_REG, + BMI323_FEAT_IO0_REG, + BMI323_FIFO_WTRMRK_REG, + BMI323_FIFO_CONF_REG +}; + +static const unsigned int bmi323_ext_reg_savestate[] = { + BMI323_GEN_SET1_REG, + BMI323_TAP1_REG, + BMI323_TAP2_REG, + BMI323_TAP3_REG, + BMI323_FEAT_IO0_S_TAP_MSK, + BMI323_STEP_SC1_REG, + BMI323_ANYMO1_REG, + BMI323_NOMO1_REG, + BMI323_ANYMO1_REG + BMI323_MO2_OFFSET, + BMI323_NOMO1_REG + BMI323_MO2_OFFSET, + BMI323_ANYMO1_REG + BMI323_MO3_OFFSET, + BMI323_NOMO1_REG + BMI323_MO3_OFFSET +}; + +struct bmi323_regs_runtime_pm { + unsigned int reg_settings[ARRAY_SIZE(bmi323_reg_savestate)]; + unsigned int ext_reg_settings[ARRAY_SIZE(bmi323_ext_reg_savestate)]; +}; + struct bmi323_data { struct device *dev; struct regmap *regmap; @@ -130,6 +162,7 @@ struct bmi323_data { u32 odrns[BMI323_SENSORS_CNT]; u32 odrhz[BMI323_SENSORS_CNT]; unsigned int feature_events; + struct bmi323_regs_runtime_pm runtime_pm_status; /* * Lock to protect the members of device's private data from concurrent @@ -1972,6 +2005,11 @@ static void bmi323_disable(void *data_ptr) bmi323_set_mode(data, BMI323_ACCEL, ACC_GYRO_MODE_DISABLE); bmi323_set_mode(data, BMI323_GYRO, ACC_GYRO_MODE_DISABLE); + + /* + * Place the peripheral in its lowest power consuming state. + */ + regmap_write(data->regmap, BMI323_CMD_REG, BMI323_RST_VAL); } static int bmi323_set_bw(struct bmi323_data *data, @@ -2030,6 +2068,13 @@ static int bmi323_init(struct bmi323_data *data) return dev_err_probe(data->dev, -EINVAL, "Sensor power error = 0x%x\n", val); + return 0; +} + +static int bmi323_init_reset(struct bmi323_data *data) +{ + int ret; + /* * Set the Bandwidth coefficient which defines the 3 dB cutoff * frequency in relation to the ODR. @@ -2078,12 +2123,18 @@ int bmi323_core_probe(struct device *dev) data = iio_priv(indio_dev); data->dev = dev; data->regmap = regmap; + data->irq_pin = BMI323_IRQ_DISABLED; + data->state = BMI323_IDLE; mutex_init(&data->mutex); ret = bmi323_init(data); if (ret) return -EINVAL; + ret = bmi323_init_reset(data); + if (ret) + return -EINVAL; + if (!iio_read_acpi_mount_matrix(dev, &data->orientation, "ROTM")) { ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) @@ -2117,7 +2168,7 @@ int bmi323_core_probe(struct device *dev) return dev_err_probe(data->dev, ret, "Unable to register iio device\n"); - return 0; + return bmi323_fifo_disable(data); } EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); @@ -2125,13 +2176,119 @@ EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); static int bmi323_core_runtime_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct bmi323_data *data = iio_priv(indio_dev); + struct bmi323_regs_runtime_pm *savestate = &data->runtime_pm_status; + int ret; + + guard(mutex)(&data->mutex); - return iio_device_suspend_triggering(indio_dev); + ret = iio_device_suspend_triggering(indio_dev); + if (ret) + return ret; + + /* Save registers meant to be restored by resume pm callback. */ + for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_reg_savestate); i++) { + ret = regmap_read(data->regmap, bmi323_reg_savestate[i], + &savestate->reg_settings[i]); + if (ret) { + dev_err(data->dev, + "Error reading bmi323 reg 0x%x: %d\n", + bmi323_reg_savestate[i], ret); + return ret; + } + } + + for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { + ret = bmi323_read_ext_reg(data, bmi323_reg_savestate[i], + &savestate->reg_settings[i]); + if (ret) { + dev_err(data->dev, + "Error reading bmi323 external reg 0x%x: %d\n", + bmi323_reg_savestate[i], ret); + return ret; + } + } + + /* Perform soft reset to place the device in its lowest power state. */ + ret = regmap_write(data->regmap, BMI323_CMD_REG, BMI323_RST_VAL); + if (ret) + return ret; + + return 0; } static int bmi323_core_runtime_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct bmi323_data *data = iio_priv(indio_dev); + struct bmi323_regs_runtime_pm *savestate = &data->runtime_pm_status; + unsigned int val; + int ret; + + guard(mutex)(&data->mutex); + + /* + * Perform the device power-on and initial setup once again + * after being reset in the lower power state by runtime-pm. + */ + ret = bmi323_init(data); + if (!ret) + return ret; + + /* Register must be cleared before changing an active config */ + ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0); + if (ret) { + dev_err(data->dev, "Error stopping feature engine\n"); + return ret; + } + + for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { + ret = bmi323_write_ext_reg(data, bmi323_reg_savestate[i], + savestate->reg_settings[i]); + if (ret) { + dev_err(data->dev, + "Error writing bmi323 external reg 0x%x: %d\n", + bmi323_reg_savestate[i], ret); + return ret; + } + } + + for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_reg_savestate); i++) { + ret = regmap_write(data->regmap, bmi323_reg_savestate[i], + savestate->reg_settings[i]); + if (ret) { + dev_err(data->dev, + "Error writing bmi323 reg 0x%x: %d\n", + bmi323_reg_savestate[i], ret); + return ret; + } + } + + /* + * Clear old FIFO samples that might be generated before suspend + * or generated from a peripheral state not equal to the saved one. + */ + if (data->state == BMI323_BUFFER_FIFO) { + ret = regmap_write(data->regmap, BMI323_FIFO_CTRL_REG, + BMI323_FIFO_FLUSH_MSK); + if (ret) { + dev_err(data->dev, "Error flushing FIFO buffer: %d\n", ret); + return ret; + } + } + + ret = regmap_read(data->regmap, BMI323_ERR_REG, &val); + if (ret) { + dev_err(data->dev, + "Error reading bmi323 error register: %d\n", ret); + return ret; + } + + if (val) { + dev_err(data->dev, + "Sensor power error in PM = 0x%x\n", val); + return -EINVAL; + } return iio_device_resume_triggering(indio_dev); } -- cgit From 2ba49fc41b1c399a98468b0e144cfb6f3ad37b64 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 20 Aug 2024 10:58:35 -0500 Subject: iio: adc: ad4695: add 2nd regmap for 16-bit registers The AD4695 and similar chips have some multibyte registers that have to be read/written in a single operation. So we need to add a 2nd regmap for these registers. These registers are removed from the 8-bit regmap allowable ranges and AD4695_MAX_REG is dropped since it would be ambiguous now. debugfs register access is also updated to automatically use the correct regmap depending on the register address. Signed-off-by: David Lechner Link: https://patch.msgid.link/20240820-ad4695-gain-offset-v1-1-c8f6e3b47551@baylibre.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad4695.c | 83 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c index b8547914f00f..63d816ad2d1f 100644 --- a/drivers/iio/adc/ad4695.c +++ b/drivers/iio/adc/ad4695.c @@ -34,6 +34,7 @@ /* AD4695 registers */ #define AD4695_REG_SPI_CONFIG_A 0x0000 #define AD4695_REG_SPI_CONFIG_A_SW_RST (BIT(7) | BIT(0)) +#define AD4695_REG_SPI_CONFIG_A_ADDR_DIR BIT(5) #define AD4695_REG_SPI_CONFIG_B 0x0001 #define AD4695_REG_SPI_CONFIG_B_INST_MODE BIT(7) #define AD4695_REG_DEVICE_TYPE 0x0003 @@ -77,7 +78,6 @@ #define AD4695_REG_GAIN_IN(n) (0x00C0 | (2 * (n))) #define AD4695_REG_AS_SLOT(n) (0x0100 | (n)) #define AD4695_REG_AS_SLOT_INX GENMASK(3, 0) -#define AD4695_MAX_REG 0x017F /* Conversion mode commands */ #define AD4695_CMD_EXIT_CNV_MODE 0x0A @@ -121,6 +121,7 @@ struct ad4695_channel_config { struct ad4695_state { struct spi_device *spi; struct regmap *regmap; + struct regmap *regmap16; struct gpio_desc *reset_gpio; /* voltages channels plus temperature and timestamp */ struct iio_chan_spec iio_chan[AD4695_MAX_CHANNELS + 2]; @@ -150,8 +151,10 @@ static const struct regmap_range ad4695_regmap_rd_ranges[] = { regmap_reg_range(AD4695_REG_SPI_CONFIG_C, AD4695_REG_SPI_STATUS), regmap_reg_range(AD4695_REG_STATUS, AD4695_REG_ALERT_STATUS2), regmap_reg_range(AD4695_REG_CLAMP_STATUS, AD4695_REG_CLAMP_STATUS), - regmap_reg_range(AD4695_REG_SETUP, AD4695_REG_TEMP_CTRL), - regmap_reg_range(AD4695_REG_CONFIG_IN(0), AD4695_MAX_REG), + regmap_reg_range(AD4695_REG_SETUP, AD4695_REG_AC_CTRL), + regmap_reg_range(AD4695_REG_GPIO_CTRL, AD4695_REG_TEMP_CTRL), + regmap_reg_range(AD4695_REG_CONFIG_IN(0), AD4695_REG_CONFIG_IN(15)), + regmap_reg_range(AD4695_REG_AS_SLOT(0), AD4695_REG_AS_SLOT(127)), }; static const struct regmap_access_table ad4695_regmap_rd_table = { @@ -164,8 +167,10 @@ static const struct regmap_range ad4695_regmap_wr_ranges[] = { regmap_reg_range(AD4695_REG_SCRATCH_PAD, AD4695_REG_SCRATCH_PAD), regmap_reg_range(AD4695_REG_LOOP_MODE, AD4695_REG_LOOP_MODE), regmap_reg_range(AD4695_REG_SPI_CONFIG_C, AD4695_REG_SPI_STATUS), - regmap_reg_range(AD4695_REG_SETUP, AD4695_REG_TEMP_CTRL), - regmap_reg_range(AD4695_REG_CONFIG_IN(0), AD4695_MAX_REG), + regmap_reg_range(AD4695_REG_SETUP, AD4695_REG_AC_CTRL), + regmap_reg_range(AD4695_REG_GPIO_CTRL, AD4695_REG_TEMP_CTRL), + regmap_reg_range(AD4695_REG_CONFIG_IN(0), AD4695_REG_CONFIG_IN(15)), + regmap_reg_range(AD4695_REG_AS_SLOT(0), AD4695_REG_AS_SLOT(127)), }; static const struct regmap_access_table ad4695_regmap_wr_table = { @@ -174,15 +179,47 @@ static const struct regmap_access_table ad4695_regmap_wr_table = { }; static const struct regmap_config ad4695_regmap_config = { - .name = "ad4695", + .name = "ad4695-8", .reg_bits = 16, .val_bits = 8, - .max_register = AD4695_MAX_REG, + .max_register = AD4695_REG_AS_SLOT(127), .rd_table = &ad4695_regmap_rd_table, .wr_table = &ad4695_regmap_wr_table, .can_multi_write = true, }; +static const struct regmap_range ad4695_regmap16_rd_ranges[] = { + regmap_reg_range(AD4695_REG_STD_SEQ_CONFIG, AD4695_REG_STD_SEQ_CONFIG), + regmap_reg_range(AD4695_REG_UPPER_IN(0), AD4695_REG_GAIN_IN(15)), +}; + +static const struct regmap_access_table ad4695_regmap16_rd_table = { + .yes_ranges = ad4695_regmap16_rd_ranges, + .n_yes_ranges = ARRAY_SIZE(ad4695_regmap16_rd_ranges), +}; + +static const struct regmap_range ad4695_regmap16_wr_ranges[] = { + regmap_reg_range(AD4695_REG_STD_SEQ_CONFIG, AD4695_REG_STD_SEQ_CONFIG), + regmap_reg_range(AD4695_REG_UPPER_IN(0), AD4695_REG_GAIN_IN(15)), +}; + +static const struct regmap_access_table ad4695_regmap16_wr_table = { + .yes_ranges = ad4695_regmap16_wr_ranges, + .n_yes_ranges = ARRAY_SIZE(ad4695_regmap16_wr_ranges), +}; + +static const struct regmap_config ad4695_regmap16_config = { + .name = "ad4695-16", + .reg_bits = 16, + .reg_stride = 2, + .val_bits = 16, + .val_format_endian = REGMAP_ENDIAN_LITTLE, + .max_register = AD4695_REG_GAIN_IN(15), + .rd_table = &ad4695_regmap16_rd_table, + .wr_table = &ad4695_regmap16_wr_table, + .can_multi_write = true, +}; + static const struct iio_chan_spec ad4695_channel_template = { .type = IIO_VOLTAGE, .indexed = 1, @@ -646,13 +683,24 @@ static int ad4695_debugfs_reg_access(struct iio_dev *indio_dev, struct ad4695_state *st = iio_priv(indio_dev); iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { - if (readval) - return regmap_read(st->regmap, reg, readval); - - return regmap_write(st->regmap, reg, writeval); + if (readval) { + if (regmap_check_range_table(st->regmap, reg, + &ad4695_regmap_rd_table)) + return regmap_read(st->regmap, reg, readval); + if (regmap_check_range_table(st->regmap16, reg, + &ad4695_regmap16_rd_table)) + return regmap_read(st->regmap16, reg, readval); + } else { + if (regmap_check_range_table(st->regmap, reg, + &ad4695_regmap_wr_table)) + return regmap_write(st->regmap, reg, writeval); + if (regmap_check_range_table(st->regmap16, reg, + &ad4695_regmap16_wr_table)) + return regmap_write(st->regmap16, reg, writeval); + } } - unreachable(); + return -EINVAL; } static const struct iio_info ad4695_info = { @@ -807,6 +855,11 @@ static int ad4695_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(st->regmap), "Failed to initialize regmap\n"); + st->regmap16 = devm_regmap_init_spi(spi, &ad4695_regmap16_config); + if (IS_ERR(st->regmap16)) + return dev_err_probe(dev, PTR_ERR(st->regmap16), + "Failed to initialize regmap16\n"); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad4695_power_supplies), ad4695_power_supplies); @@ -876,9 +929,9 @@ static int ad4695_probe(struct spi_device *spi) msleep(AD4695_T_WAKEUP_SW_MS); } - /* Needed for debugfs since it only access registers 1 byte at a time. */ - ret = regmap_set_bits(st->regmap, AD4695_REG_SPI_CONFIG_C, - AD4695_REG_SPI_CONFIG_C_MB_STRICT); + /* Needed for regmap16 to be able to work correctly. */ + ret = regmap_set_bits(st->regmap, AD4695_REG_SPI_CONFIG_A, + AD4695_REG_SPI_CONFIG_A_ADDR_DIR); if (ret) return ret; -- cgit From 7763e40f35af295e051a0065c14fec528e3c99e6 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 20 Aug 2024 10:58:36 -0500 Subject: iio: adc: ad4695: implement calibration support The AD4695 has a calibration feature that allows the user to compensate for variations in the analog front end. This implements this feature in the driver using the standard `calibgain` and `calibbias` attributes. Signed-off-by: David Lechner Link: https://patch.msgid.link/20240820-ad4695-gain-offset-v1-2-c8f6e3b47551@baylibre.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad4695.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c index 63d816ad2d1f..595ec4158e73 100644 --- a/drivers/iio/adc/ad4695.c +++ b/drivers/iio/adc/ad4695.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -225,7 +226,11 @@ static const struct iio_chan_spec ad4695_channel_template = { .indexed = 1, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), .scan_type = { .sign = 'u', .realbits = 16, @@ -619,7 +624,8 @@ static int ad4695_read_raw(struct iio_dev *indio_dev, struct ad4695_state *st = iio_priv(indio_dev); struct ad4695_channel_config *cfg = &st->channels_cfg[chan->scan_index]; u8 realbits = chan->scan_type.realbits; - int ret; + unsigned int reg_val; + int ret, tmp; switch (mask) { case IIO_CHAN_INFO_RAW: @@ -670,6 +676,152 @@ static int ad4695_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_CALIBSCALE: + switch (chan->type) { + case IIO_VOLTAGE: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret = regmap_read(st->regmap16, + AD4695_REG_GAIN_IN(chan->scan_index), + ®_val); + if (ret) + return ret; + + *val = reg_val; + *val2 = 15; + + return IIO_VAL_FRACTIONAL_LOG2; + } + unreachable(); + default: + return -EINVAL; + } + case IIO_CHAN_INFO_CALIBBIAS: + switch (chan->type) { + case IIO_VOLTAGE: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret = regmap_read(st->regmap16, + AD4695_REG_OFFSET_IN(chan->scan_index), + ®_val); + if (ret) + return ret; + + tmp = sign_extend32(reg_val, 15); + + *val = tmp / 4; + *val2 = abs(tmp) % 4 * MICRO / 4; + + if (tmp < 0 && *val2) { + *val *= -1; + *val2 *= -1; + } + + return IIO_VAL_INT_PLUS_MICRO; + } + unreachable(); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int ad4695_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ad4695_state *st = iio_priv(indio_dev); + unsigned int reg_val; + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + switch (chan->type) { + case IIO_VOLTAGE: + if (val < 0 || val2 < 0) + reg_val = 0; + else if (val > 1) + reg_val = U16_MAX; + else + reg_val = (val * (1 << 16) + + mul_u64_u32_div(val2, 1 << 16, + MICRO)) / 2; + + return regmap_write(st->regmap16, + AD4695_REG_GAIN_IN(chan->scan_index), + reg_val); + default: + return -EINVAL; + } + case IIO_CHAN_INFO_CALIBBIAS: + switch (chan->type) { + case IIO_VOLTAGE: + if (val2 >= 0 && val > S16_MAX / 4) + reg_val = S16_MAX; + else if ((val2 < 0 ? -val : val) < S16_MIN / 4) + reg_val = S16_MIN; + else if (val2 < 0) + reg_val = clamp_t(int, + -(val * 4 + -val2 * 4 / MICRO), + S16_MIN, S16_MAX); + else if (val < 0) + reg_val = clamp_t(int, + val * 4 - val2 * 4 / MICRO, + S16_MIN, S16_MAX); + else + reg_val = clamp_t(int, + val * 4 + val2 * 4 / MICRO, + S16_MIN, S16_MAX); + + return regmap_write(st->regmap16, + AD4695_REG_OFFSET_IN(chan->scan_index), + reg_val); + default: + return -EINVAL; + } + default: + return -EINVAL; + } + } + unreachable(); +} + +static int ad4695_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + static const int ad4695_calibscale_available[6] = { + /* Range of 0 (inclusive) to 2 (exclusive) */ + 0, 15, 1, 15, U16_MAX, 15 + }; + static const int ad4695_calibbias_available[6] = { + /* + * Datasheet says FSR/8 which translates to signed/4. The step + * depends on oversampling ratio which is always 1 for now. + */ + S16_MIN / 4, 0, 0, MICRO / 4, S16_MAX / 4, S16_MAX % 4 * MICRO / 4 + }; + + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + switch (chan->type) { + case IIO_VOLTAGE: + *vals = ad4695_calibscale_available; + *type = IIO_VAL_FRACTIONAL_LOG2; + return IIO_AVAIL_RANGE; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_CALIBBIAS: + switch (chan->type) { + case IIO_VOLTAGE: + *vals = ad4695_calibbias_available; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_RANGE; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -705,6 +857,8 @@ static int ad4695_debugfs_reg_access(struct iio_dev *indio_dev, static const struct iio_info ad4695_info = { .read_raw = &ad4695_read_raw, + .write_raw = &ad4695_write_raw, + .read_avail = &ad4695_read_avail, .debugfs_reg_access = &ad4695_debugfs_reg_access, }; -- cgit From b5fe2f7bac9cec5f39cbfd55bc70d974a315c8b2 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 20 Aug 2024 10:58:37 -0500 Subject: doc: iio: ad4695: update for calibration support Calibration support has been added to the ad4695 driver, so update the documentation to reflect this. Signed-off-by: David Lechner Link: https://patch.msgid.link/20240820-ad4695-gain-offset-v1-3-c8f6e3b47551@baylibre.com Signed-off-by: Jonathan Cameron --- Documentation/iio/ad4695.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/iio/ad4695.rst b/Documentation/iio/ad4695.rst index 7612596bb6e9..33ed29b7c98a 100644 --- a/Documentation/iio/ad4695.rst +++ b/Documentation/iio/ad4695.rst @@ -143,13 +143,18 @@ present, then the external reference voltage is used and the internal buffer is disabled. If ``refin-supply`` is present, then the internal buffered reference voltage is used. +Gain/offset calibration +----------------------- + +System calibration is supported using the channel gain and offset registers via +the ``calibscale`` and ``calibbias`` attributes respectively. + Unimplemented features ---------------------- - Additional wiring modes - Threshold events - Oversampling -- Gain/offset calibration - GPIO support - CRC support -- cgit From 192be245741a1f3c05221b49282f3f4795aebb2c Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 20 Aug 2024 10:58:38 -0500 Subject: iio: ABI: document ad4695 new attributes The ad4695 driver now supports calibration using the in_voltageY_calib{scale,bias}[_available] attributes. Only one of these was documented before. This adds rest. Signed-off-by: David Lechner Link: https://patch.msgid.link/20240820-ad4695-gain-offset-v1-4-c8f6e3b47551@baylibre.com Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 345d58535dc9..89943c2d54e8 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -541,6 +541,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_proximity_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_resistance_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_temp_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibbias What: /sys/bus/iio/devices/iio:deviceX/out_currentY_calibbias What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_calibbias KernelVersion: 2.6.35 @@ -556,6 +557,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_calibbias_available What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_calibbias_available What: /sys/bus/iio/devices/iio:deviceX/in_temp_calibbias_available What: /sys/bus/iio/devices/iio:deviceX/in_proximity_calibbias_available +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibbias_available What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_calibbias_available KernelVersion: 5.8 Contact: linux-iio@vger.kernel.org @@ -603,6 +605,7 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/in_illuminanceY_calibscale_available What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_calibscale_available What: /sys/bus/iio/devices/iio:deviceX/in_proximityY_calibscale_available +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale_available KernelVersion: 4.8 Contact: linux-iio@vger.kernel.org Description: -- cgit From 31c022a4f4bbdf9787bbb9549e37597344ee46b5 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Tue, 20 Aug 2024 21:02:26 +0200 Subject: iio: adc: xilinx-ams: use device_* to iterate over device child nodes Use `device_for_each_child_node_scoped()` in `ams_parse_firmware()` to explicitly state device child node access, and simplify the child node handling as it is not required outside the loop. Signed-off-by: Javier Carrasco Reviewed-by: Mike Leach Link: https://patch.msgid.link/20240820-device_child_node_access-v3-1-1ee09bdedb9e@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/xilinx-ams.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c index f051358d6b50..ebc583b07e0c 100644 --- a/drivers/iio/adc/xilinx-ams.c +++ b/drivers/iio/adc/xilinx-ams.c @@ -1275,7 +1275,6 @@ static int ams_parse_firmware(struct iio_dev *indio_dev) struct ams *ams = iio_priv(indio_dev); struct iio_chan_spec *ams_channels, *dev_channels; struct device *dev = indio_dev->dev.parent; - struct fwnode_handle *child = NULL; struct fwnode_handle *fwnode = dev_fwnode(dev); size_t ams_size; int ret, ch_cnt = 0, i, rising_off, falling_off; @@ -1297,16 +1296,12 @@ static int ams_parse_firmware(struct iio_dev *indio_dev) num_channels += ret; } - fwnode_for_each_child_node(fwnode, child) { - if (fwnode_device_is_available(child)) { - ret = ams_init_module(indio_dev, child, ams_channels + num_channels); - if (ret < 0) { - fwnode_handle_put(child); - return ret; - } + device_for_each_child_node_scoped(dev, child) { + ret = ams_init_module(indio_dev, child, ams_channels + num_channels); + if (ret < 0) + return ret; - num_channels += ret; - } + num_channels += ret; } for (i = 0; i < num_channels; i++) { -- cgit From 631598c419985327110135efb696d9f9fe67bffd Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 14 Aug 2024 11:26:29 +0200 Subject: iio: dac: ad5449: drop support for platform data There are no longer any users of the platform data struct. Remove support for it from the driver. Signed-off-by: Bartosz Golaszewski Link: https://patch.msgid.link/20240814092629.9862-1-brgl@bgdev.pl Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5449.c | 15 ++------------ include/linux/platform_data/ad5449.h | 39 ------------------------------------ 2 files changed, 2 insertions(+), 52 deletions(-) delete mode 100644 include/linux/platform_data/ad5449.h diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index 4572d6f49275..953fcfa2110b 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -20,8 +20,6 @@ #include #include -#include - #define AD5449_MAX_CHANNELS 2 #define AD5449_MAX_VREFS 2 @@ -268,7 +266,6 @@ static const char *ad5449_vref_name(struct ad5449 *st, int n) static int ad5449_spi_probe(struct spi_device *spi) { - struct ad5449_platform_data *pdata = spi->dev.platform_data; const struct spi_device_id *id = spi_get_device_id(spi); struct iio_dev *indio_dev; struct ad5449 *st; @@ -306,16 +303,8 @@ static int ad5449_spi_probe(struct spi_device *spi) mutex_init(&st->lock); if (st->chip_info->has_ctrl) { - unsigned int ctrl = 0x00; - if (pdata) { - if (pdata->hardware_clear_to_midscale) - ctrl |= AD5449_CTRL_HCLR_TO_MIDSCALE; - ctrl |= pdata->sdo_mode << AD5449_CTRL_SDO_OFFSET; - st->has_sdo = pdata->sdo_mode != AD5449_SDO_DISABLED; - } else { - st->has_sdo = true; - } - ad5449_write(indio_dev, AD5449_CMD_CTRL, ctrl); + st->has_sdo = true; + ad5449_write(indio_dev, AD5449_CMD_CTRL, 0x0); } ret = iio_device_register(indio_dev); diff --git a/include/linux/platform_data/ad5449.h b/include/linux/platform_data/ad5449.h deleted file mode 100644 index d687ef5726c2..000000000000 --- a/include/linux/platform_data/ad5449.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog - * Converter driver. - * - * Copyright 2012 Analog Devices Inc. - * Author: Lars-Peter Clausen - */ - -#ifndef __LINUX_PLATFORM_DATA_AD5449_H__ -#define __LINUX_PLATFORM_DATA_AD5449_H__ - -/** - * enum ad5449_sdo_mode - AD5449 SDO pin configuration - * @AD5449_SDO_DRIVE_FULL: Drive the SDO pin with full strength. - * @AD5449_SDO_DRIVE_WEAK: Drive the SDO pin with not full strength. - * @AD5449_SDO_OPEN_DRAIN: Operate the SDO pin in open-drain mode. - * @AD5449_SDO_DISABLED: Disable the SDO pin, in this mode it is not possible to - * read back from the device. - */ -enum ad5449_sdo_mode { - AD5449_SDO_DRIVE_FULL = 0x0, - AD5449_SDO_DRIVE_WEAK = 0x1, - AD5449_SDO_OPEN_DRAIN = 0x2, - AD5449_SDO_DISABLED = 0x3, -}; - -/** - * struct ad5449_platform_data - Platform data for the ad5449 DAC driver - * @sdo_mode: SDO pin mode - * @hardware_clear_to_midscale: Whether asserting the hardware CLR pin sets the - * outputs to midscale (true) or to zero scale(false). - */ -struct ad5449_platform_data { - enum ad5449_sdo_mode sdo_mode; - bool hardware_clear_to_midscale; -}; - -#endif -- cgit From 2f1dddc922a4d77162f839ee8faa50209bbe5168 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Mon, 26 Aug 2024 14:17:28 -0500 Subject: iio: adc: mcp320x: Drop vendorless compatible strings The vendorless compatible strings are deprecated and weren't retained when the binding was converted to schema. As a result, they are listed as undocumented when running "make dt_compatible_check". Rather than add them back to the schema, let's just drop them as they are unnecessary. Furthermore, they are unnecessary as the SPI matching will strip the vendor prefix on compatible string and match that against the spi_device_id table. Signed-off-by: Rob Herring (Arm) Link: https://patch.msgid.link/20240826191728.1415189-1-robh@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp320x.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index da1421bd7b62..57cff3772ebe 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -459,16 +459,6 @@ static int mcp320x_probe(struct spi_device *spi) } static const struct of_device_id mcp320x_dt_ids[] = { - /* NOTE: The use of compatibles with no vendor prefix is deprecated. */ - { .compatible = "mcp3001" }, - { .compatible = "mcp3002" }, - { .compatible = "mcp3004" }, - { .compatible = "mcp3008" }, - { .compatible = "mcp3201" }, - { .compatible = "mcp3202" }, - { .compatible = "mcp3204" }, - { .compatible = "mcp3208" }, - { .compatible = "mcp3301" }, { .compatible = "microchip,mcp3001" }, { .compatible = "microchip,mcp3002" }, { .compatible = "microchip,mcp3004" }, -- cgit From 17601ab9d75918b11515b7f23730f99059cf038e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 27 Aug 2024 00:22:39 +0300 Subject: iio: imu: st_lsm6dsx: Use iio_read_acpi_mount_matrix() helper Replace the duplicate ACPI "ROTM" data parsing code with the new shared iio_read_acpi_mount_matrix() helper. Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20240826212344.866928-2-andy.shevchenko@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 70 +--------------------------- 1 file changed, 1 insertion(+), 69 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 937ff9c5a74c..722b43f9203b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2646,73 +2646,6 @@ static int st_lsm6dsx_init_regulators(struct device *dev) return 0; } -#ifdef CONFIG_ACPI - -static int lsm6dsx_get_acpi_mount_matrix(struct device *dev, - struct iio_mount_matrix *orientation) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_device *adev = ACPI_COMPANION(dev); - union acpi_object *obj, *elements; - acpi_status status; - int i, j, val[3]; - char *str; - - if (!has_acpi_companion(dev)) - return -EINVAL; - - if (!acpi_has_method(adev->handle, "ROTM")) - return -EINVAL; - - status = acpi_evaluate_object(adev->handle, "ROTM", NULL, &buffer); - if (ACPI_FAILURE(status)) { - dev_warn(dev, "Failed to get ACPI mount matrix: %d\n", status); - return -EINVAL; - } - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) - goto unknown_format; - - elements = obj->package.elements; - for (i = 0; i < 3; i++) { - if (elements[i].type != ACPI_TYPE_STRING) - goto unknown_format; - - str = elements[i].string.pointer; - if (sscanf(str, "%d %d %d", &val[0], &val[1], &val[2]) != 3) - goto unknown_format; - - for (j = 0; j < 3; j++) { - switch (val[j]) { - case -1: str = "-1"; break; - case 0: str = "0"; break; - case 1: str = "1"; break; - default: goto unknown_format; - } - orientation->rotation[i * 3 + j] = str; - } - } - - kfree(buffer.pointer); - return 0; - -unknown_format: - dev_warn(dev, "Unknown ACPI mount matrix format, ignoring\n"); - kfree(buffer.pointer); - return -EINVAL; -} - -#else - -static int lsm6dsx_get_acpi_mount_matrix(struct device *dev, - struct iio_mount_matrix *orientation) -{ - return -EOPNOTSUPP; -} - -#endif - int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, struct regmap *regmap) { @@ -2787,8 +2720,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } - err = lsm6dsx_get_acpi_mount_matrix(hw->dev, &hw->orientation); - if (err) { + if (!iio_read_acpi_mount_matrix(hw->dev, &hw->orientation, "ROTM")) { err = iio_read_mount_matrix(hw->dev, &hw->orientation); if (err) return err; -- cgit From da83fd152e544c2222b2e098a3ce0f704617eb24 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 27 Aug 2024 00:22:40 +0300 Subject: iio: imu: st_lsm6dsx: Remove useless dev_fwnode() calls The device property APIs designed that way that they will return an error when there is no valid fwnode provided. Moreover, the check for NULL of dev_fwnode() is not fully correct as in some (currently rare) cases it may contain an error pointer. This is not a problem anyway (see keyword 'valid' above) that's why the code works properly even without this change. Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20240826212344.866928-3-andy.shevchenko@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 722b43f9203b..ed0267929725 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2127,25 +2127,15 @@ static const struct iio_info st_lsm6dsx_gyro_info = { .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; -static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) -{ - struct device *dev = hw->dev; - - if (!dev_fwnode(dev)) - return -EINVAL; - - return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin); -} - static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, const struct st_lsm6dsx_reg **drdy_reg) { + struct device *dev = hw->dev; int err = 0, drdy_pin; - if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) { + if (device_property_read_u32(dev, "st,drdy-int-pin", &drdy_pin) < 0) { struct st_sensors_platform_data *pdata; - struct device *dev = hw->dev; pdata = (struct st_sensors_platform_data *)dev->platform_data; drdy_pin = pdata ? pdata->drdy_int_pin : 1; @@ -2180,7 +2170,7 @@ static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) hub_settings = &hw->settings->shub_settings; pdata = (struct st_sensors_platform_data *)dev->platform_data; - if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) || + if (device_property_read_bool(dev, "st,pullups") || (pdata && pdata->pullups)) { if (hub_settings->pullup_en.sec_page) { err = st_lsm6dsx_set_page(hw, true); @@ -2565,7 +2555,7 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) return err; pdata = (struct st_sensors_platform_data *)dev->platform_data; - if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) || + if (device_property_read_bool(dev, "drive-open-drain") || (pdata && pdata->open_drain)) { reg = &hw->settings->irq_config.od; err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, @@ -2693,8 +2683,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, hub_settings = &hw->settings->shub_settings; if (hub_settings->master_en.addr && - (!dev_fwnode(dev) || - !device_property_read_bool(dev, "st,disable-sensor-hub"))) { + !device_property_read_bool(dev, "st,disable-sensor-hub")) { err = st_lsm6dsx_shub_probe(hw, name); if (err < 0) return err; @@ -2735,7 +2724,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } - if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) || + if (device_property_read_bool(dev, "wakeup-source") || (pdata && pdata->wakeup_source)) device_init_wakeup(dev, true); -- cgit From 3c6b818b097dd6932859bcc3d6722a74ec5931c1 Mon Sep 17 00:00:00 2001 From: Zhu Jun Date: Wed, 28 Aug 2024 02:31:29 -0700 Subject: tools/iio: Add memory allocation failure check for trigger_name Added a check to handle memory allocation failure for `trigger_name` and return `-ENOMEM`. Signed-off-by: Zhu Jun Link: https://patch.msgid.link/20240828093129.3040-1-zhujun2@cmss.chinamobile.com Signed-off-by: Jonathan Cameron --- tools/iio/iio_generic_buffer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c index 0d0a7a19d6f9..9ef5ee087eda 100644 --- a/tools/iio/iio_generic_buffer.c +++ b/tools/iio/iio_generic_buffer.c @@ -498,6 +498,10 @@ int main(int argc, char **argv) return -ENOMEM; } trigger_name = malloc(IIO_MAX_NAME_LENGTH); + if (!trigger_name) { + ret = -ENOMEM; + goto error; + } ret = read_sysfs_string("name", trig_dev_name, trigger_name); free(trig_dev_name); if (ret < 0) { -- cgit From cf082dbedaeb291000ffb2f1dac3b854a928dbee Mon Sep 17 00:00:00 2001 From: Thomas Bonnefille Date: Thu, 29 Aug 2024 14:31:50 +0200 Subject: dt-bindings: iio: adc: sophgo,cv1800b-saradc: Add Sophgo CV1800B SARADC The Sophgo CV1800B SARADC is a Successive Approximation ADC that can be found in the Sophgo CV1800B SoC. Signed-off-by: Thomas Bonnefille Reviewed-by: Conor Dooley Link: https://patch.msgid.link/20240829-sg2002-adc-v5-1-aacb381e869b@bootlin.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/sophgo,cv1800b-saradc.yaml | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/sophgo,cv1800b-saradc.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/sophgo,cv1800b-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/sophgo,cv1800b-saradc.yaml new file mode 100644 index 000000000000..f652b98615f7 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/sophgo,cv1800b-saradc.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/sophgo,cv1800b-saradc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: + Sophgo CV1800B SoC 3 channels Successive Approximation Analog to + Digital Converters + +maintainers: + - Thomas Bonnefille + +description: + Datasheet at https://github.com/sophgo/sophgo-doc/releases + +properties: + compatible: + const: sophgo,cv1800b-saradc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^channel@[0-2]$": + $ref: adc.yaml + + properties: + reg: + items: + - minimum: 0 + maximum: 2 + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + #include + adc@30f0000 { + compatible = "sophgo,cv1800b-saradc"; + reg = <0x030f0000 0x1000>; + clocks = <&clk CLK_SARADC>; + interrupts = <100 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + }; + + channel@1 { + reg = <1>; + }; + + channel@2 { + reg = <2>; + }; + }; -- cgit From d1022ff5f9b93cccfb4a84854828eb1b5d5202ba Mon Sep 17 00:00:00 2001 From: Thomas Bonnefille Date: Thu, 29 Aug 2024 14:31:51 +0200 Subject: iio: adc: sophgo-saradc: Add driver for Sophgo CV1800B SARADC This adds a driver for the Sophgo CV1800B SARADC. Signed-off-by: Thomas Bonnefille Link: https://patch.msgid.link/20240829-sg2002-adc-v5-2-aacb381e869b@bootlin.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/sophgo-cv1800b-adc.c | 227 +++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 drivers/iio/adc/sophgo-cv1800b-adc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 88e8ce2e78b3..97ece1a4b7e3 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1192,6 +1192,16 @@ config SC27XX_ADC This driver can also be built as a module. If so, the module will be called sc27xx_adc. +config SOPHGO_CV1800B_ADC + tristate "Sophgo CV1800B SARADC" + depends on ARCH_SOPHGO || COMPILE_TEST + help + Say yes here to build support for the SARADC integrated inside + the Sophgo CV1800B SoC. + + This driver can also be built as a module. If so, the module + will be called sophgo_cv1800b_adc. + config SPEAR_ADC tristate "ST SPEAr ADC" depends on PLAT_SPEAR || COMPILE_TEST diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 8b80664c6d6b..7b91cd98c0e0 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_RZG2L_ADC) += rzg2l_adc.o obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o +obj-$(CONFIG_SOPHGO_CV1800B_ADC) += sophgo-cv1800b-adc.o obj-$(CONFIG_SPEAR_ADC) += spear_adc.o obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o diff --git a/drivers/iio/adc/sophgo-cv1800b-adc.c b/drivers/iio/adc/sophgo-cv1800b-adc.c new file mode 100644 index 000000000000..0951deb7b111 --- /dev/null +++ b/drivers/iio/adc/sophgo-cv1800b-adc.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Sophgo CV1800B SARADC Driver + * + * Copyright (C) Bootlin 2024 + * Author: Thomas Bonnefille + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CV1800B_ADC_CTRL_REG 0x04 +#define CV1800B_ADC_EN BIT(0) +#define CV1800B_ADC_SEL(x) BIT((x) + 5) +#define CV1800B_ADC_STATUS_REG 0x08 +#define CV1800B_ADC_BUSY BIT(0) +#define CV1800B_ADC_CYC_SET_REG 0x0C +#define CV1800B_MASK_STARTUP_CYCLE GENMASK(4, 0) +#define CV1800B_MASK_SAMPLE_WINDOW GENMASK(11, 8) +#define CV1800B_MASK_CLKDIV GENMASK(15, 12) +#define CV1800B_MASK_COMPARE_CYCLE GENMASK(19, 16) +#define CV1800B_ADC_CH_RESULT_REG(x) (0x14 + 4 * (x)) +#define CV1800B_ADC_CH_RESULT GENMASK(11, 0) +#define CV1800B_ADC_CH_VALID BIT(15) +#define CV1800B_ADC_INTR_EN_REG 0x20 +#define CV1800B_ADC_INTR_CLR_REG 0x24 +#define CV1800B_ADC_INTR_CLR_BIT BIT(0) +#define CV1800B_ADC_INTR_STA_REG 0x28 +#define CV1800B_ADC_INTR_STA_BIT BIT(0) +#define CV1800B_READ_TIMEOUT_MS 1000 +#define CV1800B_READ_TIMEOUT_US (CV1800B_READ_TIMEOUT_MS * 1000) + +#define CV1800B_ADC_CHANNEL(index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ + .scan_index = index, \ + } + +struct cv1800b_adc { + struct completion completion; + void __iomem *regs; + struct mutex lock; /* ADC Control and Result register */ + struct clk *clk; + int irq; +}; + +static const struct iio_chan_spec sophgo_channels[] = { + CV1800B_ADC_CHANNEL(0), + CV1800B_ADC_CHANNEL(1), + CV1800B_ADC_CHANNEL(2), +}; + +static void cv1800b_adc_start_measurement(struct cv1800b_adc *saradc, + int channel) +{ + writel(0, saradc->regs + CV1800B_ADC_CTRL_REG); + writel(CV1800B_ADC_SEL(channel) | CV1800B_ADC_EN, + saradc->regs + CV1800B_ADC_CTRL_REG); +} + +static int cv1800b_adc_wait(struct cv1800b_adc *saradc) +{ + if (saradc->irq < 0) { + u32 reg; + + return readl_poll_timeout(saradc->regs + CV1800B_ADC_STATUS_REG, + reg, !(reg & CV1800B_ADC_BUSY), + 500, CV1800B_READ_TIMEOUT_US); + } + + return wait_for_completion_timeout(&saradc->completion, + msecs_to_jiffies(CV1800B_READ_TIMEOUT_MS)) > 0 ? + 0 : -ETIMEDOUT; +} + +static int cv1800b_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct cv1800b_adc *saradc = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: { + u32 sample; + + scoped_guard(mutex, &saradc->lock) { + int ret; + + cv1800b_adc_start_measurement(saradc, chan->scan_index); + ret = cv1800b_adc_wait(saradc); + if (ret < 0) + return ret; + + sample = readl(saradc->regs + CV1800B_ADC_CH_RESULT_REG(chan->scan_index)); + } + if (!(sample & CV1800B_ADC_CH_VALID)) + return -ENODATA; + + *val = sample & CV1800B_ADC_CH_RESULT; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_SCALE: + *val = 3300; + *val2 = 12; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CHAN_INFO_SAMP_FREQ: { + u32 status_reg = readl(saradc->regs + CV1800B_ADC_CYC_SET_REG); + unsigned int clk_div = (1 + FIELD_GET(CV1800B_MASK_CLKDIV, status_reg)); + unsigned int freq = clk_get_rate(saradc->clk) / clk_div; + unsigned int nb_startup_cycle = 1 + FIELD_GET(CV1800B_MASK_STARTUP_CYCLE, status_reg); + unsigned int nb_sample_cycle = 1 + FIELD_GET(CV1800B_MASK_SAMPLE_WINDOW, status_reg); + unsigned int nb_compare_cycle = 1 + FIELD_GET(CV1800B_MASK_COMPARE_CYCLE, status_reg); + + *val = freq / (nb_startup_cycle + nb_sample_cycle + nb_compare_cycle); + return IIO_VAL_INT; + } + default: + return -EINVAL; + } +} + +static irqreturn_t cv1800b_adc_interrupt_handler(int irq, void *private) +{ + struct cv1800b_adc *saradc = private; + u32 reg = readl(saradc->regs + CV1800B_ADC_INTR_STA_REG); + + if (!(FIELD_GET(CV1800B_ADC_INTR_STA_BIT, reg))) + return IRQ_NONE; + + writel(CV1800B_ADC_INTR_CLR_BIT, saradc->regs + CV1800B_ADC_INTR_CLR_REG); + complete(&saradc->completion); + + return IRQ_HANDLED; +} + +static const struct iio_info cv1800b_adc_info = { + .read_raw = &cv1800b_adc_read_raw, +}; + +static int cv1800b_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cv1800b_adc *saradc; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*saradc)); + if (!indio_dev) + return -ENOMEM; + + saradc = iio_priv(indio_dev); + indio_dev->name = "sophgo-cv1800b-adc"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &cv1800b_adc_info; + indio_dev->num_channels = ARRAY_SIZE(sophgo_channels); + indio_dev->channels = sophgo_channels; + + saradc->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(saradc->clk)) + return PTR_ERR(saradc->clk); + + saradc->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(saradc->regs)) + return PTR_ERR(saradc->regs); + + saradc->irq = platform_get_irq_optional(pdev, 0); + if (saradc->irq > 0) { + init_completion(&saradc->completion); + ret = devm_request_irq(dev, saradc->irq, + cv1800b_adc_interrupt_handler, 0, + dev_name(dev), saradc); + if (ret) + return ret; + + writel(1, saradc->regs + CV1800B_ADC_INTR_EN_REG); + } + + ret = devm_mutex_init(dev, &saradc->lock); + if (ret) + return ret; + + writel(FIELD_PREP(CV1800B_MASK_STARTUP_CYCLE, 15) | + FIELD_PREP(CV1800B_MASK_SAMPLE_WINDOW, 15) | + FIELD_PREP(CV1800B_MASK_CLKDIV, 1) | + FIELD_PREP(CV1800B_MASK_COMPARE_CYCLE, 15), + saradc->regs + CV1800B_ADC_CYC_SET_REG); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id cv1800b_adc_match[] = { + { .compatible = "sophgo,cv1800b-saradc", }, + { } +}; +MODULE_DEVICE_TABLE(of, cv1800b_adc_match); + +static struct platform_driver cv1800b_adc_driver = { + .driver = { + .name = "sophgo-cv1800b-saradc", + .of_match_table = cv1800b_adc_match, + }, + .probe = cv1800b_adc_probe, +}; +module_platform_driver(cv1800b_adc_driver); + +MODULE_AUTHOR("Thomas Bonnefille "); +MODULE_DESCRIPTION("Sophgo CV1800B SARADC driver"); +MODULE_LICENSE("GPL"); -- cgit From 61075d0cbfbdfd7217266f9919d15e58aa80982a Mon Sep 17 00:00:00 2001 From: shuaijie wang Date: Tue, 27 Aug 2024 08:02:28 +0000 Subject: dt-bindings: iio: aw96103: Add bindings for aw96103/aw96105 sensor Add device tree bindings for aw96103/aw96105 proximity sensor. Reviewed-by: Krzysztof Kozlowski Signed-off-by: shuaijie wang Link: https://patch.msgid.link/20240827080229.1431784-2-wangshuaijie@awinic.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/proximity/awinic,aw96103.yaml | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/proximity/awinic,aw96103.yaml diff --git a/Documentation/devicetree/bindings/iio/proximity/awinic,aw96103.yaml b/Documentation/devicetree/bindings/iio/proximity/awinic,aw96103.yaml new file mode 100644 index 000000000000..7a83ceced11c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/proximity/awinic,aw96103.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/proximity/awinic,aw96103.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Awinic's AW96103 capacitive proximity sensor and similar + +maintainers: + - Wang Shuaijie + +description: | + Awinic's AW96103/AW96105 proximity sensor. + The specific absorption rate (SAR) is a metric that measures + the degree of absorption of electromagnetic radiation emitted by + wireless devices, such as mobile phones and tablets, by human tissue. + In mobile phone applications, the proximity sensor is primarily + used to detect the proximity of the human body to the phone. When the + phone approaches the human body, it will actively reduce the transmit + power of the antenna to keep the SAR within a safe range. Therefore, + we also refer to the proximity sensor as a SAR sensor. + +properties: + compatible: + enum: + - awinic,aw96103 + - awinic,aw96105 + + reg: + maxItems: 1 + + interrupts: + description: + Generated by the device to announce that a close/far + proximity event has happened. + maxItems: 1 + + vcc-supply: true + +required: + - compatible + - reg + - interrupts + - vcc-supply + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + proximity@12 { + compatible = "awinic,aw96103"; + reg = <0x12>; + interrupt-parent = <&gpio>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; + vcc-supply = <&pp1800_prox>; + }; + }; -- cgit From 07b241262dcad07671c444ca955903325de28e9e Mon Sep 17 00:00:00 2001 From: shuaijie wang Date: Tue, 27 Aug 2024 08:02:29 +0000 Subject: iio: proximity: aw96103: Add support for aw96103/aw96105 proximity sensor AW96103 is a low power consumption capacitive touch and proximity controller. Each channel can be independently config as sensor input, shield output. Channel Information: aw96103: 3-channel aw96105: 5-channel Signed-off-by: shuaijie wang Link: https://patch.msgid.link/20240827080229.1431784-3-wangshuaijie@awinic.com Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/Kconfig | 11 + drivers/iio/proximity/Makefile | 1 + drivers/iio/proximity/aw96103.c | 846 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 858 insertions(+) create mode 100644 drivers/iio/proximity/aw96103.c diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index 0694f625b432..31c679074b25 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig @@ -233,4 +233,15 @@ config VL53L0X_I2C To compile this driver as a module, choose M here: the module will be called vl53l0x-i2c. +config AW96103 + tristate "AW96103/AW96105 Awinic proximity sensor" + select REGMAP_I2C + depends on I2C + help + Say Y here to build a driver for Awinic's AW96103/AW96105 capacitive + proximity sensor. + + To compile this driver as a module, choose M here: the + module will be called aw96103. + endmenu diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile index ab381cd27dbb..c5e76995764a 100644 --- a/drivers/iio/proximity/Makefile +++ b/drivers/iio/proximity/Makefile @@ -22,4 +22,5 @@ obj-$(CONFIG_SX_COMMON) += sx_common.o obj-$(CONFIG_SX9500) += sx9500.o obj-$(CONFIG_VCNL3020) += vcnl3020.o obj-$(CONFIG_VL53L0X_I2C) += vl53l0x-i2c.o +obj-$(CONFIG_AW96103) += aw96103.o diff --git a/drivers/iio/proximity/aw96103.c b/drivers/iio/proximity/aw96103.c new file mode 100644 index 000000000000..db9d78e961fd --- /dev/null +++ b/drivers/iio/proximity/aw96103.c @@ -0,0 +1,846 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AWINIC aw96103 proximity sensor driver + * + * Author: Wang Shuaijie + * + * Copyright (c) 2024 awinic Technology CO., LTD + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AW_DATA_PROCESS_FACTOR 1024 +#define AW96103_CHIP_ID 0xa961 +#define AW96103_BIN_VALID_DATA_OFFSET 64 +#define AW96103_BIN_DATA_LEN_OFFSET 16 +#define AW96103_BIN_DATA_REG_NUM_SIZE 4 +#define AW96103_BIN_CHIP_TYPE_SIZE 8 +#define AW96103_BIN_CHIP_TYPE_OFFSET 24 + +#define AW96103_REG_SCANCTRL0 0x0000 +#define AW96103_REG_STAT0 0x0090 +#define AW96103_REG_BLFILT_CH0 0x00A8 +#define AW96103_REG_BLRSTRNG_CH0 0x00B4 +#define AW96103_REG_DIFF_CH0 0x0240 +#define AW96103_REG_FWVER2 0x0410 +#define AW96103_REG_CMD 0xF008 +#define AW96103_REG_IRQSRC 0xF080 +#define AW96103_REG_IRQEN 0xF084 +#define AW96103_REG_RESET 0xFF0C +#define AW96103_REG_CHIPID 0xFF10 +#define AW96103_REG_EEDA0 0x0408 +#define AW96103_REG_EEDA1 0x040C +#define AW96103_REG_PROXCTRL_CH0 0x00B0 +#define AW96103_REG_PROXTH0_CH0 0x00B8 +#define AW96103_PROXTH_CH_STEP 0x3C +#define AW96103_THHYST_MASK GENMASK(13, 12) +#define AW96103_INDEB_MASK GENMASK(11, 10) +#define AW96103_OUTDEB_MASK GENMASK(9, 8) +#define AW96103_INITOVERIRQ_MASK BIT(0) +#define AW96103_BLFILT_CH_STEP 0x3C +#define AW96103_BLRSTRNG_MASK GENMASK(5, 0) +#define AW96103_CHIPID_MASK GENMASK(31, 16) +#define AW96103_BLERRTRIG_MASK BIT(25) +#define AW96103_CHAN_EN_MASK GENMASK(5, 0) +#define AW96103_REG_PROXCTRL_CH(x) \ + (AW96103_REG_PROXCTRL_CH0 + (x) * AW96103_PROXTH_CH_STEP) + +#define AW96103_REG_PROXTH0_CH(x) \ + (AW96103_REG_PROXTH0_CH0 + (x) * AW96103_PROXTH_CH_STEP) + +/** + * struct aw_bin - Store the data obtained from parsing the configuration file. + * @chip_type: Frame header information-chip type + * @valid_data_len: Length of valid data obtained after parsing + * @valid_data_addr: The offset address of the valid data obtained + * after parsing relative to info + * @len: The size of the bin file obtained from the firmware + * @data: Store the bin file obtained from the firmware + */ +struct aw_bin { + unsigned char chip_type[8]; + unsigned int valid_data_len; + unsigned int valid_data_addr; + unsigned int len; + unsigned char data[] __counted_by(len); +}; + +enum aw96103_sar_vers { + AW96103 = 2, + AW96103A = 6, + AW96103B = 0xa, +}; + +enum aw96103_operation_mode { + AW96103_ACTIVE_MODE = 1, + AW96103_SLEEP_MODE = 2, + AW96103_DEEPSLEEP_MODE = 3, + AW96103B_DEEPSLEEP_MODE = 4, +}; + +enum aw96103_sensor_type { + AW96103_VAL, + AW96105_VAL, +}; + +struct aw_channels_info { + bool used; + unsigned int old_irq_status; +}; + +struct aw_chip_info { + const char *name; + struct iio_chan_spec const *channels; + int num_channels; +}; + +struct aw96103 { + unsigned int hostirqen; + struct regmap *regmap; + struct device *dev; + /* + * There is one more logical channel than the actual channels, + * and the extra logical channel is used for temperature detection + * but not for status detection. The specific channel used for + * temperature detection is determined by the register configuration. + */ + struct aw_channels_info channels_arr[6]; + unsigned int max_channels; + unsigned int chan_en; +}; + +static const unsigned int aw96103_reg_default[] = { + 0x0000, 0x00003f3f, 0x0004, 0x00000064, 0x0008, 0x0017c11e, + 0x000c, 0x05000000, 0x0010, 0x00093ffd, 0x0014, 0x19240009, + 0x0018, 0xd81c0207, 0x001c, 0xff000000, 0x0020, 0x00241900, + 0x0024, 0x00093ff7, 0x0028, 0x58020009, 0x002c, 0xd81c0207, + 0x0030, 0xff000000, 0x0034, 0x00025800, 0x0038, 0x00093fdf, + 0x003c, 0x7d3b0009, 0x0040, 0xd81c0207, 0x0044, 0xff000000, + 0x0048, 0x003b7d00, 0x004c, 0x00093f7f, 0x0050, 0xe9310009, + 0x0054, 0xd81c0207, 0x0058, 0xff000000, 0x005c, 0x0031e900, + 0x0060, 0x00093dff, 0x0064, 0x1a0c0009, 0x0068, 0xd81c0207, + 0x006c, 0xff000000, 0x0070, 0x000c1a00, 0x0074, 0x80093fff, + 0x0078, 0x043d0009, 0x007c, 0xd81c0207, 0x0080, 0xff000000, + 0x0084, 0x003d0400, 0x00a0, 0xe6400000, 0x00a4, 0x00000000, + 0x00a8, 0x010408d2, 0x00ac, 0x00000000, 0x00b0, 0x00000000, + 0x00b8, 0x00005fff, 0x00bc, 0x00000000, 0x00c0, 0x00000000, + 0x00c4, 0x00000000, 0x00c8, 0x00000000, 0x00cc, 0x00000000, + 0x00d0, 0x00000000, 0x00d4, 0x00000000, 0x00d8, 0x00000000, + 0x00dc, 0xe6447800, 0x00e0, 0x78000000, 0x00e4, 0x010408d2, + 0x00e8, 0x00000000, 0x00ec, 0x00000000, 0x00f4, 0x00005fff, + 0x00f8, 0x00000000, 0x00fc, 0x00000000, 0x0100, 0x00000000, + 0x0104, 0x00000000, 0x0108, 0x00000000, 0x010c, 0x02000000, + 0x0110, 0x00000000, 0x0114, 0x00000000, 0x0118, 0xe6447800, + 0x011c, 0x78000000, 0x0120, 0x010408d2, 0x0124, 0x00000000, + 0x0128, 0x00000000, 0x0130, 0x00005fff, 0x0134, 0x00000000, + 0x0138, 0x00000000, 0x013c, 0x00000000, 0x0140, 0x00000000, + 0x0144, 0x00000000, 0x0148, 0x02000000, 0x014c, 0x00000000, + 0x0150, 0x00000000, 0x0154, 0xe6447800, 0x0158, 0x78000000, + 0x015c, 0x010408d2, 0x0160, 0x00000000, 0x0164, 0x00000000, + 0x016c, 0x00005fff, 0x0170, 0x00000000, 0x0174, 0x00000000, + 0x0178, 0x00000000, 0x017c, 0x00000000, 0x0180, 0x00000000, + 0x0184, 0x02000000, 0x0188, 0x00000000, 0x018c, 0x00000000, + 0x0190, 0xe6447800, 0x0194, 0x78000000, 0x0198, 0x010408d2, + 0x019c, 0x00000000, 0x01a0, 0x00000000, 0x01a8, 0x00005fff, + 0x01ac, 0x00000000, 0x01b0, 0x00000000, 0x01b4, 0x00000000, + 0x01b8, 0x00000000, 0x01bc, 0x00000000, 0x01c0, 0x02000000, + 0x01c4, 0x00000000, 0x01c8, 0x00000000, 0x01cc, 0xe6407800, + 0x01d0, 0x78000000, 0x01d4, 0x010408d2, 0x01d8, 0x00000000, + 0x01dc, 0x00000000, 0x01e4, 0x00005fff, 0x01e8, 0x00000000, + 0x01ec, 0x00000000, 0x01f0, 0x00000000, 0x01f4, 0x00000000, + 0x01f8, 0x00000000, 0x01fc, 0x02000000, 0x0200, 0x00000000, + 0x0204, 0x00000000, 0x0208, 0x00000008, 0x020c, 0x0000000d, + 0x41fc, 0x00000000, 0x4400, 0x00000000, 0x4410, 0x00000000, + 0x4420, 0x00000000, 0x4430, 0x00000000, 0x4440, 0x00000000, + 0x4450, 0x00000000, 0x4460, 0x00000000, 0x4470, 0x00000000, + 0xf080, 0x00003018, 0xf084, 0x00000fff, 0xf800, 0x00000000, + 0xf804, 0x00002e00, 0xf8d0, 0x00000001, 0xf8d4, 0x00000000, + 0xff00, 0x00000301, 0xff0c, 0x01000000, 0xffe0, 0x00000000, + 0xfff4, 0x00004011, 0x0090, 0x00000000, 0x0094, 0x00000000, + 0x0098, 0x00000000, 0x009c, 0x3f3f3f3f, +}; + +static const struct iio_event_spec aw_common_events[3] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_PERIOD), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_PERIOD), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_HYSTERESIS) | + BIT(IIO_EV_INFO_VALUE), + } +}; + +#define AW_IIO_CHANNEL(idx) \ +{ \ + .type = IIO_PROXIMITY, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .indexed = 1, \ + .channel = idx, \ + .event_spec = aw_common_events, \ + .num_event_specs = ARRAY_SIZE(aw_common_events), \ +} \ + +static const struct iio_chan_spec aw96103_channels[] = { + AW_IIO_CHANNEL(0), + AW_IIO_CHANNEL(1), + AW_IIO_CHANNEL(2), + AW_IIO_CHANNEL(3), +}; + +static const struct iio_chan_spec aw96105_channels[] = { + AW_IIO_CHANNEL(0), + AW_IIO_CHANNEL(1), + AW_IIO_CHANNEL(2), + AW_IIO_CHANNEL(3), + AW_IIO_CHANNEL(4), + AW_IIO_CHANNEL(5), +}; + +static const struct aw_chip_info aw_chip_info_tbl[] = { + [AW96103_VAL] = { + .name = "aw96103_sensor", + .channels = aw96103_channels, + .num_channels = ARRAY_SIZE(aw96103_channels), + }, + [AW96105_VAL] = { + .name = "aw96105_sensor", + .channels = aw96105_channels, + .num_channels = ARRAY_SIZE(aw96105_channels), + }, +}; + +static void aw96103_parsing_bin_file(struct aw_bin *bin) +{ + bin->valid_data_addr = AW96103_BIN_VALID_DATA_OFFSET; + bin->valid_data_len = + *(unsigned int *)(bin->data + AW96103_BIN_DATA_LEN_OFFSET) - + AW96103_BIN_DATA_REG_NUM_SIZE; + memcpy(bin->chip_type, bin->data + AW96103_BIN_CHIP_TYPE_OFFSET, + AW96103_BIN_CHIP_TYPE_SIZE); +} + +static const struct regmap_config aw96103_regmap_confg = { + .reg_bits = 16, + .val_bits = 32, +}; + +static int aw96103_get_diff_raw(struct aw96103 *aw96103, unsigned int chan, + int *buf) +{ + u32 data; + int ret; + + ret = regmap_read(aw96103->regmap, + AW96103_REG_DIFF_CH0 + chan * 4, &data); + if (ret) + return ret; + *buf = (int)(data / AW_DATA_PROCESS_FACTOR); + + return 0; +} + +static int aw96103_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct aw96103 *aw96103 = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = aw96103_get_diff_raw(aw96103, chan->channel, val); + if (ret) + return ret; + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int aw96103_read_thresh(struct aw96103 *aw96103, + const struct iio_chan_spec *chan, int *val) +{ + int ret; + + ret = regmap_read(aw96103->regmap, + AW96103_REG_PROXTH0_CH(chan->channel), val); + if (ret) + return ret; + + return IIO_VAL_INT; +} + +static int aw96103_read_out_debounce(struct aw96103 *aw96103, + const struct iio_chan_spec *chan, + int *val) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(aw96103->regmap, + AW96103_REG_PROXCTRL_CH(chan->channel), ®_val); + if (ret) + return ret; + *val = FIELD_GET(AW96103_OUTDEB_MASK, reg_val); + + return IIO_VAL_INT; +} + +static int aw96103_read_in_debounce(struct aw96103 *aw96103, + const struct iio_chan_spec *chan, int *val) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(aw96103->regmap, + AW96103_REG_PROXCTRL_CH(chan->channel), ®_val); + if (ret) + return ret; + *val = FIELD_GET(AW96103_INDEB_MASK, reg_val); + + return IIO_VAL_INT; +} + +static int aw96103_read_hysteresis(struct aw96103 *aw96103, + const struct iio_chan_spec *chan, int *val) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(aw96103->regmap, + AW96103_REG_PROXCTRL_CH(chan->channel), ®_val); + if (ret) + return ret; + *val = FIELD_GET(AW96103_THHYST_MASK, reg_val); + + return IIO_VAL_INT; +} + +static int aw96103_read_event_val(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct aw96103 *aw96103 = iio_priv(indio_dev); + + if (chan->type != IIO_PROXIMITY) + return -EINVAL; + + switch (info) { + case IIO_EV_INFO_VALUE: + return aw96103_read_thresh(aw96103, chan, val); + case IIO_EV_INFO_PERIOD: + switch (dir) { + case IIO_EV_DIR_RISING: + return aw96103_read_out_debounce(aw96103, chan, val); + case IIO_EV_DIR_FALLING: + return aw96103_read_in_debounce(aw96103, chan, val); + default: + return -EINVAL; + } + case IIO_EV_INFO_HYSTERESIS: + return aw96103_read_hysteresis(aw96103, chan, val); + default: + return -EINVAL; + } +} + +static int aw96103_write_event_val(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, int val2) +{ + struct aw96103 *aw96103 = iio_priv(indio_dev); + + if (chan->type != IIO_PROXIMITY) + return -EINVAL; + + switch (info) { + case IIO_EV_INFO_VALUE: + return regmap_write(aw96103->regmap, + AW96103_REG_PROXTH0_CH(chan->channel), val); + case IIO_EV_INFO_PERIOD: + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_update_bits(aw96103->regmap, + AW96103_REG_PROXCTRL_CH(chan->channel), + AW96103_OUTDEB_MASK, + FIELD_PREP(AW96103_OUTDEB_MASK, val)); + + case IIO_EV_DIR_FALLING: + return regmap_update_bits(aw96103->regmap, + AW96103_REG_PROXCTRL_CH(chan->channel), + AW96103_INDEB_MASK, + FIELD_PREP(AW96103_INDEB_MASK, val)); + default: + return -EINVAL; + } + case IIO_EV_INFO_HYSTERESIS: + return regmap_update_bits(aw96103->regmap, + AW96103_REG_PROXCTRL_CH(chan->channel), + AW96103_THHYST_MASK, + FIELD_PREP(AW96103_THHYST_MASK, val)); + default: + return -EINVAL; + } +} + +static int aw96103_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct aw96103 *aw96103 = iio_priv(indio_dev); + + return aw96103->channels_arr[chan->channel].used; +} + +static int aw96103_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, int state) +{ + struct aw96103 *aw96103 = iio_priv(indio_dev); + + aw96103->channels_arr[chan->channel].used = !!state; + + return regmap_update_bits(aw96103->regmap, AW96103_REG_SCANCTRL0, + BIT(chan->channel), + state ? BIT(chan->channel) : 0); +} + +static struct iio_info iio_info = { + .read_raw = aw96103_read_raw, + .read_event_value = aw96103_read_event_val, + .write_event_value = aw96103_write_event_val, + .read_event_config = aw96103_read_event_config, + .write_event_config = aw96103_write_event_config, +}; + +static int aw96103_channel_scan_start(struct aw96103 *aw96103) +{ + int ret; + + ret = regmap_write(aw96103->regmap, AW96103_REG_CMD, + AW96103_ACTIVE_MODE); + if (ret) + return ret; + + return regmap_write(aw96103->regmap, AW96103_REG_IRQEN, + aw96103->hostirqen); +} + +static int aw96103_reg_version_comp(struct aw96103 *aw96103, + struct aw_bin *aw_bin) +{ + u32 blfilt1_data, fw_ver; + unsigned char i; + int ret; + + ret = regmap_read(aw96103->regmap, AW96103_REG_FWVER2, &fw_ver); + if (ret) + return ret; + /* + * If the chip version is AW96103A and the loaded register + * configuration file is for AW96103, special handling of the + * AW96103_REG_BLRSTRNG_CH0 register is required. + */ + if ((fw_ver != AW96103A) || (aw_bin->chip_type[7] != '\0')) + return 0; + + for (i = 0; i < aw96103->max_channels; i++) { + ret = regmap_read(aw96103->regmap, + AW96103_REG_BLFILT_CH0 + (AW96103_BLFILT_CH_STEP * i), + &blfilt1_data); + if (ret) + return ret; + if (FIELD_GET(AW96103_BLERRTRIG_MASK, blfilt1_data) != 1) + return 0; + + ret = regmap_update_bits(aw96103->regmap, + AW96103_REG_BLRSTRNG_CH0 + (AW96103_BLFILT_CH_STEP * i), + AW96103_BLRSTRNG_MASK, 1 << i); + if (ret) + return ret; + } + + return 0; +} + +static int aw96103_bin_valid_loaded(struct aw96103 *aw96103, + struct aw_bin *aw_bin_data_s) +{ + unsigned int start_addr = aw_bin_data_s->valid_data_addr; + u32 i, reg_data; + u16 reg_addr; + int ret; + + for (i = 0; i < aw_bin_data_s->valid_data_len; + i += 6, start_addr += 6) { + reg_addr = get_unaligned_le16(aw_bin_data_s->data + start_addr); + reg_data = get_unaligned_le32(aw_bin_data_s->data + + start_addr + 2); + if ((reg_addr == AW96103_REG_EEDA0) || + (reg_addr == AW96103_REG_EEDA1)) + continue; + if (reg_addr == AW96103_REG_IRQEN) { + aw96103->hostirqen = reg_data; + continue; + } + if (reg_addr == AW96103_REG_SCANCTRL0) + aw96103->chan_en = FIELD_GET(AW96103_CHAN_EN_MASK, + reg_data); + + ret = regmap_write(aw96103->regmap, reg_addr, reg_data); + if (ret < 0) + return ret; + } + + ret = aw96103_reg_version_comp(aw96103, aw_bin_data_s); + if (ret) + return ret; + + return aw96103_channel_scan_start(aw96103); +} + +static int aw96103_para_loaded(struct aw96103 *aw96103) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(aw96103_reg_default); i += 2) { + ret = regmap_write(aw96103->regmap, + (u16)aw96103_reg_default[i], + (u32)aw96103_reg_default[i + 1]); + if (ret) + return ret; + if (aw96103_reg_default[i] == AW96103_REG_IRQEN) + aw96103->hostirqen = aw96103_reg_default[i + 1]; + else if (aw96103_reg_default[i] == AW96103_REG_SCANCTRL0) + aw96103->chan_en = FIELD_GET(AW96103_CHAN_EN_MASK, + aw96103_reg_default[i + 1]); + } + + return aw96103_channel_scan_start(aw96103); +} + +static int aw96103_cfg_all_loaded(const struct firmware *cont, + struct aw96103 *aw96103) +{ + if (!cont) + return -EINVAL; + + struct aw_bin *aw_bin __free(kfree) = + kzalloc(cont->size + sizeof(*aw_bin), GFP_KERNEL); + if (!aw_bin) + return -ENOMEM; + + aw_bin->len = cont->size; + memcpy(aw_bin->data, cont->data, cont->size); + release_firmware(cont); + aw96103_parsing_bin_file(aw_bin); + + return aw96103_bin_valid_loaded(aw96103, aw_bin); +} + +static void aw96103_cfg_update(const struct firmware *fw, void *data) +{ + struct aw96103 *aw96103 = data; + int ret, i; + + if (!fw || !fw->data) { + dev_err(aw96103->dev, "No firmware.\n"); + return; + } + + ret = aw96103_cfg_all_loaded(fw, aw96103); + /* + * If loading the register configuration file fails, + * load the default register configuration in the driver to + * ensure the basic functionality of the device. + */ + if (ret) { + ret = aw96103_para_loaded(aw96103); + if (ret) { + dev_err(aw96103->dev, "load param error.\n"); + return; + } + } + + for (i = 0; i < aw96103->max_channels; i++) { + if ((aw96103->chan_en >> i) & 0x01) + aw96103->channels_arr[i].used = true; + else + aw96103->channels_arr[i].used = false; + } +} + +static int aw96103_sw_reset(struct aw96103 *aw96103) +{ + int ret; + + ret = regmap_write(aw96103->regmap, AW96103_REG_RESET, 0); + /* + * After reset, the initialization process starts to perform and + * it will last for a bout 20ms. + */ + msleep(20); + + return ret; +} + +enum aw96103_irq_trigger_position { + FAR = 0, + TRIGGER_TH0 = 0x01, + TRIGGER_TH1 = 0x03, + TRIGGER_TH2 = 0x07, + TRIGGER_TH3 = 0x0f, +}; + +static irqreturn_t aw96103_irq(int irq, void *data) +{ + unsigned int irq_status, curr_status_val, curr_status; + struct iio_dev *indio_dev = data; + struct aw96103 *aw96103 = iio_priv(indio_dev); + int ret, i; + + ret = regmap_read(aw96103->regmap, AW96103_REG_IRQSRC, &irq_status); + if (ret) + return IRQ_HANDLED; + + ret = regmap_read(aw96103->regmap, AW96103_REG_STAT0, &curr_status_val); + if (ret) + return IRQ_HANDLED; + + /* + * Iteratively analyze the interrupt status of different channels, + * with each channel having 4 interrupt states. + */ + for (i = 0; i < aw96103->max_channels; i++) { + if (!aw96103->channels_arr[i].used) + continue; + + curr_status = (((curr_status_val >> (24 + i)) & 0x1)) | + (((curr_status_val >> (16 + i)) & 0x1) << 1) | + (((curr_status_val >> (8 + i)) & 0x1) << 2) | + (((curr_status_val >> i) & 0x1) << 3); + if (aw96103->channels_arr[i].old_irq_status == curr_status) + continue; + + switch (curr_status) { + case FAR: + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, i, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + iio_get_time_ns(indio_dev)); + break; + case TRIGGER_TH0: + case TRIGGER_TH1: + case TRIGGER_TH2: + case TRIGGER_TH3: + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, i, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + iio_get_time_ns(indio_dev)); + break; + default: + return IRQ_HANDLED; + } + aw96103->channels_arr[i].old_irq_status = curr_status; + } + + return IRQ_HANDLED; +} + +static int aw96103_interrupt_init(struct iio_dev *indio_dev, + struct i2c_client *i2c) +{ + struct aw96103 *aw96103 = iio_priv(indio_dev); + unsigned int irq_status; + int ret; + + ret = regmap_write(aw96103->regmap, AW96103_REG_IRQEN, 0); + if (ret) + return ret; + ret = regmap_read(aw96103->regmap, AW96103_REG_IRQSRC, &irq_status); + if (ret) + return ret; + ret = devm_request_threaded_irq(aw96103->dev, i2c->irq, NULL, + aw96103_irq, IRQF_ONESHOT, + "aw96103_irq", indio_dev); + if (ret) + return ret; + + return regmap_write(aw96103->regmap, AW96103_REG_IRQEN, + aw96103->hostirqen); +} + +static int aw96103_wait_chip_init(struct aw96103 *aw96103) +{ + unsigned int cnt = 20; + u32 reg_data; + int ret; + + while (cnt--) { + /* + * The device should generate an initialization completion + * interrupt within 20ms. + */ + ret = regmap_read(aw96103->regmap, AW96103_REG_IRQSRC, + ®_data); + if (ret) + return ret; + + if (FIELD_GET(AW96103_INITOVERIRQ_MASK, reg_data)) + return 0; + fsleep(1000); + } + + return -ETIMEDOUT; +} + +static int aw96103_read_chipid(struct aw96103 *aw96103) +{ + unsigned char cnt = 0; + u32 reg_val = 0; + int ret; + + while (cnt < 3) { + /* + * This retry mechanism and the subsequent delay are just + * attempts to read the chip ID as much as possible, + * preventing occasional communication failures from causing + * the chip ID read to fail. + */ + ret = regmap_read(aw96103->regmap, AW96103_REG_CHIPID, + ®_val); + if (ret < 0) { + cnt++; + fsleep(2000); + continue; + } + break; + } + if (cnt == 3) + return -ETIMEDOUT; + + if (FIELD_GET(AW96103_CHIPID_MASK, reg_val) != AW96103_CHIP_ID) + dev_info(aw96103->dev, + "unexpected chipid, id=0x%08X\n", reg_val); + + return 0; +} + +static int aw96103_i2c_probe(struct i2c_client *i2c) +{ + const struct aw_chip_info *chip_info; + struct iio_dev *indio_dev; + struct aw96103 *aw96103; + int ret; + + indio_dev = devm_iio_device_alloc(&i2c->dev, sizeof(*aw96103)); + if (!indio_dev) + return -ENOMEM; + + aw96103 = iio_priv(indio_dev); + aw96103->dev = &i2c->dev; + chip_info = i2c_get_match_data(i2c); + aw96103->max_channels = chip_info->num_channels; + + aw96103->regmap = devm_regmap_init_i2c(i2c, &aw96103_regmap_confg); + if (IS_ERR(aw96103->regmap)) + return PTR_ERR(aw96103->regmap); + + ret = devm_regulator_get_enable(aw96103->dev, "vcc"); + if (ret < 0) + return ret; + + ret = aw96103_read_chipid(aw96103); + if (ret) + return ret; + + ret = aw96103_sw_reset(aw96103); + if (ret) + return ret; + + ret = aw96103_wait_chip_init(aw96103); + if (ret) + return ret; + + ret = request_firmware_nowait(THIS_MODULE, true, "aw96103_0.bin", + aw96103->dev, GFP_KERNEL, aw96103, + aw96103_cfg_update); + if (ret) + return ret; + + ret = aw96103_interrupt_init(indio_dev, i2c); + if (ret) + return ret; + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = chip_info->num_channels; + indio_dev->channels = chip_info->channels; + indio_dev->info = &iio_info; + indio_dev->name = chip_info->name; + + return devm_iio_device_register(aw96103->dev, indio_dev); +} + +static const struct of_device_id aw96103_dt_match[] = { + { + .compatible = "awinic,aw96103", + .data = &aw_chip_info_tbl[AW96103_VAL] + }, + { + .compatible = "awinic,aw96105", + .data = &aw_chip_info_tbl[AW96105_VAL] + }, + { } +}; +MODULE_DEVICE_TABLE(of, aw96103_dt_match); + +static const struct i2c_device_id aw96103_i2c_id[] = { + { "aw96103", (kernel_ulong_t)&aw_chip_info_tbl[AW96103_VAL] }, + { "aw96105", (kernel_ulong_t)&aw_chip_info_tbl[AW96105_VAL] }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aw96103_i2c_id); + +static struct i2c_driver aw96103_i2c_driver = { + .driver = { + .name = "aw96103_sensor", + .of_match_table = aw96103_dt_match, + }, + .probe = aw96103_i2c_probe, + .id_table = aw96103_i2c_id, +}; +module_i2c_driver(aw96103_i2c_driver); + +MODULE_AUTHOR("Wang Shuaijie "); +MODULE_DESCRIPTION("Driver for Awinic AW96103 proximity sensor"); +MODULE_LICENSE("GPL v2"); -- cgit From 09e3bdfe499d5b0ed24c123f7c5a12459db217db Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 18 Aug 2024 19:09:12 +0100 Subject: iio: adc: standardize on formatting for id match tables This is a frequent minor comment in reviews, so start cleaning up existing drivers in the hope we get fewer cases of cut and paste. There are not kernel wide rules for these, but for IIO the style that I prefer (and hence most common) is: - Space after { and before } - No comma after terminator { } This may cause merge conflicts but they should be trivial to resolve hence I have not broken this into per driver patches. Link: https://patch.msgid.link/20240818180912.719399-1-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7091r5.c | 6 ++-- drivers/iio/adc/ad7124.c | 4 +-- drivers/iio/adc/ad7192.c | 6 ++-- drivers/iio/adc/ad7266.c | 4 +-- drivers/iio/adc/ad7280a.c | 4 +-- drivers/iio/adc/ad7291.c | 4 +-- drivers/iio/adc/ad7292.c | 4 +-- drivers/iio/adc/ad7298.c | 4 +-- drivers/iio/adc/ad7476.c | 58 ++++++++++++++++++------------------- drivers/iio/adc/ad7606_par.c | 2 +- drivers/iio/adc/ad7606_spi.c | 4 +-- drivers/iio/adc/ad7766.c | 14 ++++----- drivers/iio/adc/ad7768-1.c | 2 +- drivers/iio/adc/ad7780.c | 10 +++---- drivers/iio/adc/ad7793.c | 20 ++++++------- drivers/iio/adc/ad7887.c | 4 +-- drivers/iio/adc/ad7923.c | 18 ++++++------ drivers/iio/adc/ad9467.c | 4 +-- drivers/iio/adc/aspeed_adc.c | 2 +- drivers/iio/adc/at91_adc.c | 2 +- drivers/iio/adc/axp288_adc.c | 2 +- drivers/iio/adc/bcm_iproc_adc.c | 2 +- drivers/iio/adc/berlin2-adc.c | 2 +- drivers/iio/adc/ep93xx_adc.c | 2 +- drivers/iio/adc/exynos_adc.c | 2 +- drivers/iio/adc/hi8435.c | 2 +- drivers/iio/adc/hx711.c | 2 +- drivers/iio/adc/ina2xx-adc.c | 14 ++++----- drivers/iio/adc/ingenic-adc.c | 2 +- drivers/iio/adc/lpc32xx_adc.c | 2 +- drivers/iio/adc/ltc2496.c | 2 +- drivers/iio/adc/ltc2497.c | 2 +- drivers/iio/adc/max1027.c | 16 +++++----- drivers/iio/adc/max11100.c | 4 +-- drivers/iio/adc/max1118.c | 4 +-- drivers/iio/adc/max1241.c | 4 +-- drivers/iio/adc/max34408.c | 4 +-- drivers/iio/adc/max9611.c | 6 ++-- drivers/iio/adc/mp2629_adc.c | 4 +-- drivers/iio/adc/mt6360-adc.c | 2 +- drivers/iio/adc/nau7802.c | 2 +- drivers/iio/adc/pac1921.c | 4 +-- drivers/iio/adc/pac1934.c | 6 ++-- drivers/iio/adc/qcom-pm8xxx-xoadc.c | 2 +- drivers/iio/adc/qcom-spmi-rradc.c | 2 +- drivers/iio/adc/rockchip_saradc.c | 2 +- drivers/iio/adc/rtq6056.c | 2 +- drivers/iio/adc/stm32-adc.c | 2 +- drivers/iio/adc/stm32-dfsdm-adc.c | 2 +- drivers/iio/adc/stm32-dfsdm-core.c | 2 +- drivers/iio/adc/stmpe-adc.c | 2 +- drivers/iio/adc/ti-adc0832.c | 4 +-- drivers/iio/adc/ti-adc084s021.c | 4 +-- drivers/iio/adc/ti-adc12138.c | 4 +-- drivers/iio/adc/ti-adc161s626.c | 8 ++--- drivers/iio/adc/ti-ads1015.c | 4 +-- drivers/iio/adc/ti-ads124s08.c | 2 +- drivers/iio/adc/ti-ads131e08.c | 4 +-- drivers/iio/adc/ti-ads7924.c | 4 +-- drivers/iio/adc/ti-ads7950.c | 2 +- drivers/iio/adc/ti-ads8344.c | 2 +- drivers/iio/adc/ti-ads8688.c | 6 ++-- drivers/iio/adc/ti-lmp92064.c | 2 +- drivers/iio/adc/ti-tlc4541.c | 8 ++--- 64 files changed, 169 insertions(+), 169 deletions(-) diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c index a75837334157..1b59708abf30 100644 --- a/drivers/iio/adc/ad7091r5.c +++ b/drivers/iio/adc/ad7091r5.c @@ -112,13 +112,13 @@ static int ad7091r5_i2c_probe(struct i2c_client *i2c) static const struct of_device_id ad7091r5_dt_ids[] = { { .compatible = "adi,ad7091r5", .data = &ad7091r5_init_info }, - {}, + { } }; MODULE_DEVICE_TABLE(of, ad7091r5_dt_ids); static const struct i2c_device_id ad7091r5_i2c_ids[] = { - {"ad7091r5", (kernel_ulong_t)&ad7091r5_init_info }, - {} + { "ad7091r5", (kernel_ulong_t)&ad7091r5_init_info }, + { } }; MODULE_DEVICE_TABLE(i2c, ad7091r5_i2c_ids); diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 37aa3bdcdf4f..c5ace69bfa43 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -1008,14 +1008,14 @@ static const struct of_device_id ad7124_of_match[] = { .data = &ad7124_chip_info_tbl[ID_AD7124_4], }, { .compatible = "adi,ad7124-8", .data = &ad7124_chip_info_tbl[ID_AD7124_8], }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad7124_of_match); static const struct spi_device_id ad71124_ids[] = { { "ad7124-4", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_4] }, { "ad7124-8", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_8] }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad71124_ids); diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index 10ce66b999c6..7042ddfdfc03 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -286,7 +286,7 @@ static const struct iio_chan_spec_ext_info ad7192_calibsys_ext_info[] = { &ad7192_syscalib_mode_enum), IIO_ENUM_AVAILABLE("sys_calibration_mode", IIO_SHARED_BY_TYPE, &ad7192_syscalib_mode_enum), - {} + { } }; static struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd) @@ -1431,7 +1431,7 @@ static const struct of_device_id ad7192_of_match[] = { { .compatible = "adi,ad7193", .data = &ad7192_chip_info_tbl[ID_AD7193] }, { .compatible = "adi,ad7194", .data = &ad7192_chip_info_tbl[ID_AD7194] }, { .compatible = "adi,ad7195", .data = &ad7192_chip_info_tbl[ID_AD7195] }, - {} + { } }; MODULE_DEVICE_TABLE(of, ad7192_of_match); @@ -1441,7 +1441,7 @@ static const struct spi_device_id ad7192_ids[] = { { "ad7193", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7193] }, { "ad7194", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7194] }, { "ad7195", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7195] }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad7192_ids); diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index 88f39533f249..7949b076fb87 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -457,8 +457,8 @@ static int ad7266_probe(struct spi_device *spi) } static const struct spi_device_id ad7266_id[] = { - {"ad7265", 0}, - {"ad7266", 0}, + { "ad7265", 0 }, + { "ad7266", 0 }, { } }; MODULE_DEVICE_TABLE(spi, ad7266_id); diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c index 7bfa090da4df..35aa39fe4bde 100644 --- a/drivers/iio/adc/ad7280a.c +++ b/drivers/iio/adc/ad7280a.c @@ -1090,8 +1090,8 @@ static int ad7280_probe(struct spi_device *spi) } static const struct spi_device_id ad7280_id[] = { - {"ad7280a", 0}, - {} + { "ad7280a", 0 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7280_id); diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index b59b2a51623c..4c7f887adbbf 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -537,14 +537,14 @@ static int ad7291_probe(struct i2c_client *client) static const struct i2c_device_id ad7291_id[] = { { "ad7291" }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, ad7291_id); static const struct of_device_id ad7291_of_match[] = { { .compatible = "adi,ad7291" }, - {} + { } }; MODULE_DEVICE_TABLE(of, ad7291_of_match); diff --git a/drivers/iio/adc/ad7292.c b/drivers/iio/adc/ad7292.c index ede80f380911..a398973f313d 100644 --- a/drivers/iio/adc/ad7292.c +++ b/drivers/iio/adc/ad7292.c @@ -301,13 +301,13 @@ static int ad7292_probe(struct spi_device *spi) static const struct spi_device_id ad7292_id_table[] = { { "ad7292", 0 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad7292_id_table); static const struct of_device_id ad7292_of_match[] = { { .compatible = "adi,ad7292" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad7292_of_match); diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index 0128436367db..b35bd4d9ef81 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -355,8 +355,8 @@ static const struct acpi_device_id ad7298_acpi_ids[] = { MODULE_DEVICE_TABLE(acpi, ad7298_acpi_ids); static const struct spi_device_id ad7298_id[] = { - {"ad7298", 0}, - {} + { "ad7298", 0 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7298_id); diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 80aebed47d1f..aeb8e383fe71 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -409,35 +409,35 @@ static int ad7476_probe(struct spi_device *spi) } static const struct spi_device_id ad7476_id[] = { - {"ad7091", ID_AD7091}, - {"ad7091r", ID_AD7091R}, - {"ad7273", ID_AD7273}, - {"ad7274", ID_AD7274}, - {"ad7276", ID_AD7276}, - {"ad7277", ID_AD7277}, - {"ad7278", ID_AD7278}, - {"ad7466", ID_AD7466}, - {"ad7467", ID_AD7467}, - {"ad7468", ID_AD7468}, - {"ad7475", ID_AD7475}, - {"ad7476", ID_AD7466}, - {"ad7476a", ID_AD7466}, - {"ad7477", ID_AD7467}, - {"ad7477a", ID_AD7467}, - {"ad7478", ID_AD7468}, - {"ad7478a", ID_AD7468}, - {"ad7495", ID_AD7495}, - {"ad7910", ID_AD7467}, - {"ad7920", ID_AD7466}, - {"ad7940", ID_AD7940}, - {"adc081s", ID_ADC081S}, - {"adc101s", ID_ADC101S}, - {"adc121s", ID_ADC121S}, - {"ads7866", ID_ADS7866}, - {"ads7867", ID_ADS7867}, - {"ads7868", ID_ADS7868}, - {"ltc2314-14", ID_LTC2314_14}, - {} + { "ad7091", ID_AD7091 }, + { "ad7091r", ID_AD7091R }, + { "ad7273", ID_AD7273 }, + { "ad7274", ID_AD7274 }, + { "ad7276", ID_AD7276}, + { "ad7277", ID_AD7277 }, + { "ad7278", ID_AD7278 }, + { "ad7466", ID_AD7466 }, + { "ad7467", ID_AD7467 }, + { "ad7468", ID_AD7468 }, + { "ad7475", ID_AD7475 }, + { "ad7476", ID_AD7466 }, + { "ad7476a", ID_AD7466 }, + { "ad7477", ID_AD7467 }, + { "ad7477a", ID_AD7467 }, + { "ad7478", ID_AD7468 }, + { "ad7478a", ID_AD7468 }, + { "ad7495", ID_AD7495 }, + { "ad7910", ID_AD7467 }, + { "ad7920", ID_AD7466 }, + { "ad7940", ID_AD7940 }, + { "adc081s", ID_ADC081S }, + { "adc101s", ID_ADC101S }, + { "adc121s", ID_ADC121S }, + { "ads7866", ID_ADS7866 }, + { "ads7867", ID_ADS7867 }, + { "ads7868", ID_ADS7868 }, + { "ltc2314-14", ID_LTC2314_14 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7476_id); diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c index d8408052262e..b5975bbfcbe0 100644 --- a/drivers/iio/adc/ad7606_par.c +++ b/drivers/iio/adc/ad7606_par.c @@ -83,7 +83,7 @@ static const struct of_device_id ad7606_of_match[] = { { .compatible = "adi,ad7606-4" }, { .compatible = "adi,ad7606-6" }, { .compatible = "adi,ad7606-8" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad7606_of_match); diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index 287a0591533b..62ec12195307 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -334,7 +334,7 @@ static const struct spi_device_id ad7606_id_table[] = { { "ad7606-8", ID_AD7606_8 }, { "ad7606b", ID_AD7606B }, { "ad7616", ID_AD7616 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad7606_id_table); @@ -345,7 +345,7 @@ static const struct of_device_id ad7606_of_match[] = { { .compatible = "adi,ad7606-8" }, { .compatible = "adi,ad7606b" }, { .compatible = "adi,ad7616" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad7606_of_match); diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c index 3079a0872947..4d570383ef02 100644 --- a/drivers/iio/adc/ad7766.c +++ b/drivers/iio/adc/ad7766.c @@ -291,13 +291,13 @@ static int ad7766_probe(struct spi_device *spi) } static const struct spi_device_id ad7766_id[] = { - {"ad7766", ID_AD7766}, - {"ad7766-1", ID_AD7766_1}, - {"ad7766-2", ID_AD7766_2}, - {"ad7767", ID_AD7766}, - {"ad7767-1", ID_AD7766_1}, - {"ad7767-2", ID_AD7766_2}, - {} + { "ad7766", ID_AD7766 }, + { "ad7766-1", ID_AD7766_1 }, + { "ad7766-2", ID_AD7766_2 }, + { "ad7767", ID_AD7766 }, + { "ad7767-1", ID_AD7766_1 }, + { "ad7767-2", ID_AD7766_2 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7766_id); diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index 721672fe84ab..113703fb7245 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -655,7 +655,7 @@ MODULE_DEVICE_TABLE(spi, ad7768_id_table); static const struct of_device_id ad7768_of_match[] = { { .compatible = "adi,ad7768-1" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad7768_of_match); diff --git a/drivers/iio/adc/ad7780.c b/drivers/iio/adc/ad7780.c index a813fe04787c..e9b0c577c9cc 100644 --- a/drivers/iio/adc/ad7780.c +++ b/drivers/iio/adc/ad7780.c @@ -355,11 +355,11 @@ static int ad7780_probe(struct spi_device *spi) } static const struct spi_device_id ad7780_id[] = { - {"ad7170", ID_AD7170}, - {"ad7171", ID_AD7171}, - {"ad7780", ID_AD7780}, - {"ad7781", ID_AD7781}, - {} + { "ad7170", ID_AD7170 }, + { "ad7171", ID_AD7171 }, + { "ad7780", ID_AD7780 }, + { "ad7781", ID_AD7781 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7780_id); diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index d4ad7e0b515a..abebd519cafa 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -824,16 +824,16 @@ static int ad7793_probe(struct spi_device *spi) } static const struct spi_device_id ad7793_id[] = { - {"ad7785", ID_AD7785}, - {"ad7792", ID_AD7792}, - {"ad7793", ID_AD7793}, - {"ad7794", ID_AD7794}, - {"ad7795", ID_AD7795}, - {"ad7796", ID_AD7796}, - {"ad7797", ID_AD7797}, - {"ad7798", ID_AD7798}, - {"ad7799", ID_AD7799}, - {} + { "ad7785", ID_AD7785 }, + { "ad7792", ID_AD7792 }, + { "ad7793", ID_AD7793 }, + { "ad7794", ID_AD7794 }, + { "ad7795", ID_AD7795 }, + { "ad7796", ID_AD7796 }, + { "ad7797", ID_AD7797 }, + { "ad7798", ID_AD7798 }, + { "ad7799", ID_AD7799 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7793_id); diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index 965bdc8aa696..6265ce7df703 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -329,8 +329,8 @@ static int ad7887_probe(struct spi_device *spi) } static const struct spi_device_id ad7887_id[] = { - {"ad7887", ID_AD7887}, - {} + { "ad7887", ID_AD7887 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7887_id); diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 9d6bf6d0927a..09680015a7ab 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -361,14 +361,14 @@ static int ad7923_probe(struct spi_device *spi) } static const struct spi_device_id ad7923_id[] = { - {"ad7904", AD7904}, - {"ad7914", AD7914}, - {"ad7923", AD7924}, - {"ad7924", AD7924}, - {"ad7908", AD7908}, - {"ad7918", AD7918}, - {"ad7928", AD7928}, - {} + { "ad7904", AD7904 }, + { "ad7914", AD7914 }, + { "ad7923", AD7924 }, + { "ad7924", AD7924 }, + { "ad7908", AD7908 }, + { "ad7918", AD7918 }, + { "ad7928", AD7928 }, + { } }; MODULE_DEVICE_TABLE(spi, ad7923_id); @@ -380,7 +380,7 @@ static const struct of_device_id ad7923_of_match[] = { { .compatible = "adi,ad7908", }, { .compatible = "adi,ad7918", }, { .compatible = "adi,ad7928", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ad7923_of_match); diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index ce0bae94aa3a..05fb7a75531f 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -1252,7 +1252,7 @@ static const struct of_device_id ad9467_of_match[] = { { .compatible = "adi,ad9643", .data = &ad9643_chip_tbl, }, { .compatible = "adi,ad9649", .data = &ad9649_chip_tbl, }, { .compatible = "adi,ad9652", .data = &ad9652_chip_tbl, }, - {} + { } }; MODULE_DEVICE_TABLE(of, ad9467_of_match); @@ -1263,7 +1263,7 @@ static const struct spi_device_id ad9467_ids[] = { { "ad9643", (kernel_ulong_t)&ad9643_chip_tbl }, { "ad9649", (kernel_ulong_t)&ad9649_chip_tbl, }, { "ad9652", (kernel_ulong_t)&ad9652_chip_tbl, }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ad9467_ids); diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 064cddaf6399..1d5fd5f534b8 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -694,7 +694,7 @@ static const struct of_device_id aspeed_adc_matches[] = { { .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data }, { .compatible = "aspeed,ast2600-adc0", .data = &ast2600_adc0_model_data }, { .compatible = "aspeed,ast2600-adc1", .data = &ast2600_adc1_model_data }, - {}, + { } }; MODULE_DEVICE_TABLE(of, aspeed_adc_matches); diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 510e826014e6..9c39acff17e6 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1335,7 +1335,7 @@ static const struct of_device_id at91_adc_dt_ids[] = { { .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps }, { .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps }, { .compatible = "atmel,sama5d3-adc", .data = &sama5d3_caps }, - {}, + { } }; MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index f135cf2362df..8c3acc0cd7e9 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -299,7 +299,7 @@ static int axp288_adc_probe(struct platform_device *pdev) static const struct platform_device_id axp288_adc_id_table[] = { { .name = "axp288_adc" }, - {}, + { } }; static struct platform_driver axp288_adc_driver = { diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 6bc149c51414..cdfe304eaa20 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -606,7 +606,7 @@ static void iproc_adc_remove(struct platform_device *pdev) static const struct of_device_id iproc_adc_of_match[] = { {.compatible = "brcm,iproc-static-adc", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, iproc_adc_of_match); diff --git a/drivers/iio/adc/berlin2-adc.c b/drivers/iio/adc/berlin2-adc.c index 4cdddc6e36e9..fa04e0a5f645 100644 --- a/drivers/iio/adc/berlin2-adc.c +++ b/drivers/iio/adc/berlin2-adc.c @@ -351,7 +351,7 @@ static int berlin2_adc_probe(struct platform_device *pdev) static const struct of_device_id berlin2_adc_match[] = { { .compatible = "marvell,berlin2-adc", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, berlin2_adc_match); diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c index 971942ce4c66..cc38d5e0608e 100644 --- a/drivers/iio/adc/ep93xx_adc.c +++ b/drivers/iio/adc/ep93xx_adc.c @@ -228,7 +228,7 @@ static void ep93xx_adc_remove(struct platform_device *pdev) static const struct of_device_id ep93xx_adc_of_ids[] = { { .compatible = "cirrus,ep9301-adc" }, - {} + { } }; MODULE_DEVICE_TABLE(of, ep93xx_adc_of_ids); diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 78fada4b7b1c..4d00ee8dd14d 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -519,7 +519,7 @@ static const struct of_device_id exynos_adc_match[] = { .compatible = "samsung,exynos7-adc", .data = &exynos7_adc_data, }, - {}, + { } }; MODULE_DEVICE_TABLE(of, exynos_adc_match); diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index 771fa12bdc02..fb635a756440 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -524,7 +524,7 @@ static int hi8435_probe(struct spi_device *spi) static const struct of_device_id hi8435_dt_ids[] = { { .compatible = "holt,hi8435" }, - {}, + { } }; MODULE_DEVICE_TABLE(of, hi8435_dt_ids); diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c index 376f4e02de97..8da0419ecfa3 100644 --- a/drivers/iio/adc/hx711.c +++ b/drivers/iio/adc/hx711.c @@ -552,7 +552,7 @@ static int hx711_probe(struct platform_device *pdev) static const struct of_device_id of_hx711_match[] = { { .compatible = "avia,hx711", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, of_hx711_match); diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 0fc24bceb58a..48c95e12e791 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -1052,12 +1052,12 @@ static void ina2xx_remove(struct i2c_client *client) } static const struct i2c_device_id ina2xx_id[] = { - {"ina219", ina219}, - {"ina220", ina219}, - {"ina226", ina226}, - {"ina230", ina226}, - {"ina231", ina226}, - {} + { "ina219", ina219 }, + { "ina220", ina219 }, + { "ina226", ina226 }, + { "ina230", ina226 }, + { "ina231", ina226 }, + { } }; MODULE_DEVICE_TABLE(i2c, ina2xx_id); @@ -1082,7 +1082,7 @@ static const struct of_device_id ina2xx_of_match[] = { .compatible = "ti,ina231", .data = (void *)ina226 }, - {}, + { } }; MODULE_DEVICE_TABLE(of, ina2xx_of_match); diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c index af70ca760797..1e802c8779a4 100644 --- a/drivers/iio/adc/ingenic-adc.c +++ b/drivers/iio/adc/ingenic-adc.c @@ -908,7 +908,7 @@ static const struct of_device_id ingenic_adc_of_match[] = { { .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data, }, { .compatible = "ingenic,jz4760b-adc", .data = &jz4760_adc_soc_data, }, { .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ingenic_adc_of_match); diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c index e34ed7dacd89..43a7bc8158b5 100644 --- a/drivers/iio/adc/lpc32xx_adc.c +++ b/drivers/iio/adc/lpc32xx_adc.c @@ -217,7 +217,7 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) static const struct of_device_id lpc32xx_adc_match[] = { { .compatible = "nxp,lpc3220-adc" }, - {}, + { } }; MODULE_DEVICE_TABLE(of, lpc32xx_adc_match); diff --git a/drivers/iio/adc/ltc2496.c b/drivers/iio/adc/ltc2496.c index 2593fa4322eb..f06dd0b9a858 100644 --- a/drivers/iio/adc/ltc2496.c +++ b/drivers/iio/adc/ltc2496.c @@ -94,7 +94,7 @@ static const struct ltc2497_chip_info ltc2496_info = { static const struct of_device_id ltc2496_of_match[] = { { .compatible = "lltc,ltc2496", .data = <c2496_info, }, - {}, + { } }; MODULE_DEVICE_TABLE(of, ltc2496_of_match); diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 6401a7727c31..f010b2fd1202 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -151,7 +151,7 @@ MODULE_DEVICE_TABLE(i2c, ltc2497_id); static const struct of_device_id ltc2497_of_match[] = { { .compatible = "lltc,ltc2497", .data = <c2497_info[TYPE_LTC2497] }, { .compatible = "lltc,ltc2499", .data = <c2497_info[TYPE_LTC2499] }, - {}, + { } }; MODULE_DEVICE_TABLE(of, ltc2497_of_match); diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index 136fcf753837..f5ba4a1b5a7d 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -73,13 +73,13 @@ enum max1027_id { }; static const struct spi_device_id max1027_id[] = { - {"max1027", max1027}, - {"max1029", max1029}, - {"max1031", max1031}, - {"max1227", max1227}, - {"max1229", max1229}, - {"max1231", max1231}, - {} + { "max1027", max1027 }, + { "max1029", max1029 }, + { "max1031", max1031 }, + { "max1227", max1227 }, + { "max1229", max1229 }, + { "max1231", max1231 }, + { } }; MODULE_DEVICE_TABLE(spi, max1027_id); @@ -90,7 +90,7 @@ static const struct of_device_id max1027_adc_dt_ids[] = { { .compatible = "maxim,max1227" }, { .compatible = "maxim,max1229" }, { .compatible = "maxim,max1231" }, - {}, + { } }; MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids); diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index 49e38dca8fe2..2f07437caec3 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c @@ -143,8 +143,8 @@ static int max11100_probe(struct spi_device *spi) } static const struct of_device_id max11100_ids[] = { - {.compatible = "maxim,max11100"}, - { }, + { .compatible = "maxim,max11100" }, + { } }; MODULE_DEVICE_TABLE(of, max11100_ids); diff --git a/drivers/iio/adc/max1118.c b/drivers/iio/adc/max1118.c index 0beccfde81f2..3d0a7d0eb7ee 100644 --- a/drivers/iio/adc/max1118.c +++ b/drivers/iio/adc/max1118.c @@ -260,7 +260,7 @@ static const struct spi_device_id max1118_id[] = { { "max1117", max1117 }, { "max1118", max1118 }, { "max1119", max1119 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, max1118_id); @@ -268,7 +268,7 @@ static const struct of_device_id max1118_dt_ids[] = { { .compatible = "maxim,max1117" }, { .compatible = "maxim,max1118" }, { .compatible = "maxim,max1119" }, - {}, + { } }; MODULE_DEVICE_TABLE(of, max1118_dt_ids); diff --git a/drivers/iio/adc/max1241.c b/drivers/iio/adc/max1241.c index 500bb09ab19b..d62c1a011659 100644 --- a/drivers/iio/adc/max1241.c +++ b/drivers/iio/adc/max1241.c @@ -177,12 +177,12 @@ static int max1241_probe(struct spi_device *spi) static const struct spi_device_id max1241_id[] = { { "max1241", max1241 }, - {} + { } }; static const struct of_device_id max1241_dt_ids[] = { { .compatible = "maxim,max1241" }, - {} + { } }; MODULE_DEVICE_TABLE(of, max1241_dt_ids); diff --git a/drivers/iio/adc/max34408.c b/drivers/iio/adc/max34408.c index 6c2ea2bc52c6..ffec22be2d59 100644 --- a/drivers/iio/adc/max34408.c +++ b/drivers/iio/adc/max34408.c @@ -250,14 +250,14 @@ static const struct of_device_id max34408_of_match[] = { .compatible = "maxim,max34409", .data = &max34409_model_data, }, - {} + { } }; MODULE_DEVICE_TABLE(of, max34408_of_match); static const struct i2c_device_id max34408_id[] = { { "max34408", (kernel_ulong_t)&max34408_model_data }, { "max34409", (kernel_ulong_t)&max34409_model_data }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, max34408_id); diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index 76e517b7b1e4..14fe42fc4b7d 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -504,9 +504,9 @@ static int max9611_init(struct max9611_dev *max9611) } static const struct of_device_id max9611_of_table[] = { - {.compatible = "maxim,max9611", .data = "max9611"}, - {.compatible = "maxim,max9612", .data = "max9612"}, - { }, + { .compatible = "maxim,max9611", .data = "max9611" }, + { .compatible = "maxim,max9612", .data = "max9612" }, + { } }; MODULE_DEVICE_TABLE(of, max9611_of_table); diff --git a/drivers/iio/adc/mp2629_adc.c b/drivers/iio/adc/mp2629_adc.c index 5f672765d4a2..5fbf9b6abd9c 100644 --- a/drivers/iio/adc/mp2629_adc.c +++ b/drivers/iio/adc/mp2629_adc.c @@ -184,8 +184,8 @@ static void mp2629_adc_remove(struct platform_device *pdev) } static const struct of_device_id mp2629_adc_of_match[] = { - { .compatible = "mps,mp2629_adc"}, - {} + { .compatible = "mps,mp2629_adc" }, + { } }; MODULE_DEVICE_TABLE(of, mp2629_adc_of_match); diff --git a/drivers/iio/adc/mt6360-adc.c b/drivers/iio/adc/mt6360-adc.c index f74347663ad8..e2ec805e834f 100644 --- a/drivers/iio/adc/mt6360-adc.c +++ b/drivers/iio/adc/mt6360-adc.c @@ -355,7 +355,7 @@ static int mt6360_adc_probe(struct platform_device *pdev) static const struct of_device_id mt6360_adc_of_id[] = { { .compatible = "mediatek,mt6360-adc", }, - {} + { } }; MODULE_DEVICE_TABLE(of, mt6360_adc_of_id); diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c index 600151a62f1f..458544cb8ee4 100644 --- a/drivers/iio/adc/nau7802.c +++ b/drivers/iio/adc/nau7802.c @@ -539,7 +539,7 @@ MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id); static const struct of_device_id nau7802_dt_ids[] = { { .compatible = "nuvoton,nau7802" }, - {}, + { } }; MODULE_DEVICE_TABLE(of, nau7802_dt_ids); diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c index 8200a47bdf21..4c2a1c07bc39 100644 --- a/drivers/iio/adc/pac1921.c +++ b/drivers/iio/adc/pac1921.c @@ -1234,13 +1234,13 @@ static int pac1921_probe(struct i2c_client *client) static const struct i2c_device_id pac1921_id[] = { { .name = "pac1921", 0 }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, pac1921_id); static const struct of_device_id pac1921_of_match[] = { { .compatible = "microchip,pac1921" }, - {} + { } }; MODULE_DEVICE_TABLE(of, pac1921_of_match); diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c index ae24a27805ab..8210728034d0 100644 --- a/drivers/iio/adc/pac1934.c +++ b/drivers/iio/adc/pac1934.c @@ -1571,7 +1571,7 @@ static const struct i2c_device_id pac1934_id[] = { { .name = "pac1932", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1932] }, { .name = "pac1933", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1933] }, { .name = "pac1934", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1934] }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, pac1934_id); @@ -1592,7 +1592,7 @@ static const struct of_device_id pac1934_of_match[] = { .compatible = "microchip,pac1934", .data = &pac1934_chip_config[PAC1934] }, - {} + { } }; MODULE_DEVICE_TABLE(of, pac1934_of_match); @@ -1602,7 +1602,7 @@ MODULE_DEVICE_TABLE(of, pac1934_of_match); */ static const struct acpi_device_id pac1934_acpi_match[] = { { "MCHP1930", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1934] }, - {} + { } }; MODULE_DEVICE_TABLE(acpi, pac1934_acpi_match); diff --git a/drivers/iio/adc/qcom-pm8xxx-xoadc.c b/drivers/iio/adc/qcom-pm8xxx-xoadc.c index c9d2c66434e4..9e1112f5acc6 100644 --- a/drivers/iio/adc/qcom-pm8xxx-xoadc.c +++ b/drivers/iio/adc/qcom-pm8xxx-xoadc.c @@ -1006,7 +1006,7 @@ static const struct of_device_id pm8xxx_xoadc_id_table[] = { .compatible = "qcom,pm8921-adc", .data = &pm8921_variant, }, - { }, + { } }; MODULE_DEVICE_TABLE(of, pm8xxx_xoadc_id_table); diff --git a/drivers/iio/adc/qcom-spmi-rradc.c b/drivers/iio/adc/qcom-spmi-rradc.c index 1402df68dd52..6aa70b4629a7 100644 --- a/drivers/iio/adc/qcom-spmi-rradc.c +++ b/drivers/iio/adc/qcom-spmi-rradc.c @@ -1002,7 +1002,7 @@ static int rradc_probe(struct platform_device *pdev) static const struct of_device_id rradc_match_table[] = { { .compatible = "qcom,pm660-rradc" }, { .compatible = "qcom,pmi8998-rradc" }, - {} + { } }; MODULE_DEVICE_TABLE(of, rradc_match_table); diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index 71f58e3a8307..240cfa391674 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -331,7 +331,7 @@ static const struct of_device_id rockchip_saradc_match[] = { .compatible = "rockchip,rk3588-saradc", .data = &rk3588_saradc_data, }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rockchip_saradc_match); diff --git a/drivers/iio/adc/rtq6056.c b/drivers/iio/adc/rtq6056.c index 45b1b81c9fdd..56ed948a8ae1 100644 --- a/drivers/iio/adc/rtq6056.c +++ b/drivers/iio/adc/rtq6056.c @@ -865,7 +865,7 @@ static const struct richtek_dev_data rtq6059_devdata = { static const struct of_device_id rtq6056_device_match[] = { { .compatible = "richtek,rtq6056", .data = &rtq6056_devdata }, { .compatible = "richtek,rtq6059", .data = &rtq6059_devdata }, - {} + { } }; MODULE_DEVICE_TABLE(of, rtq6056_device_match); diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index c901ba1bc6ba..32ca26ed59f7 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -2638,7 +2638,7 @@ static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32h7-adc", .data = (void *)&stm32h7_adc_cfg }, { .compatible = "st,stm32mp1-adc", .data = (void *)&stm32mp1_adc_cfg }, { .compatible = "st,stm32mp13-adc", .data = (void *)&stm32mp13_adc_cfg }, - {}, + { } }; MODULE_DEVICE_TABLE(of, stm32_adc_of_match); diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 1a24d496fc61..2037f73426d4 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1466,7 +1466,7 @@ static const struct iio_chan_spec_ext_info dfsdm_adc_audio_ext_info[] = { .read = dfsdm_adc_audio_get_spiclk, .write = dfsdm_adc_audio_set_spiclk, }, - {}, + { } }; static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev) diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index a05d978b8cb8..bef59fcc0d80 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -299,7 +299,7 @@ static const struct of_device_id stm32_dfsdm_of_match[] = { .compatible = "st,stm32mp1-dfsdm", .data = &stm32mp1_dfsdm_data, }, - {} + { } }; MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match); diff --git a/drivers/iio/adc/stmpe-adc.c b/drivers/iio/adc/stmpe-adc.c index 8e56def1c9e5..b0add5a2eab5 100644 --- a/drivers/iio/adc/stmpe-adc.c +++ b/drivers/iio/adc/stmpe-adc.c @@ -347,7 +347,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume); static const struct of_device_id stmpe_adc_ids[] = { { .compatible = "st,stmpe-adc", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, stmpe_adc_ids); diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index d7800e1fa536..e2dbd070c7c4 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -309,7 +309,7 @@ static const struct of_device_id adc0832_dt_ids[] = { { .compatible = "ti,adc0832", }, { .compatible = "ti,adc0834", }, { .compatible = "ti,adc0838", }, - {} + { } }; MODULE_DEVICE_TABLE(of, adc0832_dt_ids); @@ -318,7 +318,7 @@ static const struct spi_device_id adc0832_id[] = { { "adc0832", adc0832 }, { "adc0834", adc0834 }, { "adc0838", adc0838 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, adc0832_id); diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c index 4a07c6295a2b..bf98f9bf942a 100644 --- a/drivers/iio/adc/ti-adc084s021.c +++ b/drivers/iio/adc/ti-adc084s021.c @@ -242,13 +242,13 @@ static int adc084s021_probe(struct spi_device *spi) static const struct of_device_id adc084s021_of_match[] = { { .compatible = "ti,adc084s021", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, adc084s021_of_match); static const struct spi_device_id adc084s021_id[] = { { ADC084S021_DRIVER_NAME, 0 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, adc084s021_id); diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index a2cd8c454e11..7f065f457b36 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -519,7 +519,7 @@ static const struct of_device_id adc12138_dt_ids[] = { { .compatible = "ti,adc12130", }, { .compatible = "ti,adc12132", }, { .compatible = "ti,adc12138", }, - {} + { } }; MODULE_DEVICE_TABLE(of, adc12138_dt_ids); @@ -527,7 +527,7 @@ static const struct spi_device_id adc12138_id[] = { { "adc12130", adc12130 }, { "adc12132", adc12132 }, { "adc12138", adc12138 }, - {} + { } }; MODULE_DEVICE_TABLE(spi, adc12138_id); diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c index f7c78d0dd449..474e733fb8e0 100644 --- a/drivers/iio/adc/ti-adc161s626.c +++ b/drivers/iio/adc/ti-adc161s626.c @@ -226,14 +226,14 @@ static int ti_adc_probe(struct spi_device *spi) static const struct of_device_id ti_adc_dt_ids[] = { { .compatible = "ti,adc141s626", }, { .compatible = "ti,adc161s626", }, - {} + { } }; MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); static const struct spi_device_id ti_adc_id[] = { - {"adc141s626", TI_ADC141S626}, - {"adc161s626", TI_ADC161S626}, - {}, + { "adc141s626", TI_ADC141S626 }, + { "adc161s626", TI_ADC161S626 }, + { } }; MODULE_DEVICE_TABLE(spi, ti_adc_id); diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index ca432c49eab1..6d1bc9659946 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -1173,7 +1173,7 @@ static const struct i2c_device_id ads1015_id[] = { { "ads1015", (kernel_ulong_t)&ads1015_data }, { "ads1115", (kernel_ulong_t)&ads1115_data }, { "tla2024", (kernel_ulong_t)&tla2024_data }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, ads1015_id); @@ -1181,7 +1181,7 @@ static const struct of_device_id ads1015_of_match[] = { { .compatible = "ti,ads1015", .data = &ads1015_data }, { .compatible = "ti,ads1115", .data = &ads1115_data }, { .compatible = "ti,tla2024", .data = &tla2024_data }, - {} + { } }; MODULE_DEVICE_TABLE(of, ads1015_of_match); diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index c115f892232a..14941f384dad 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -357,7 +357,7 @@ MODULE_DEVICE_TABLE(spi, ads124s_id); static const struct of_device_id ads124s_of_table[] = { { .compatible = "ti,ads124s06" }, { .compatible = "ti,ads124s08" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ads124s_of_table); diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index 55366ffb0489..91a427eb0882 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -918,7 +918,7 @@ static const struct of_device_id ads131e08_of_match[] = { .data = &ads131e08_info_tbl[ads131e06], }, { .compatible = "ti,ads131e08", .data = &ads131e08_info_tbl[ads131e08], }, - {} + { } }; MODULE_DEVICE_TABLE(of, ads131e08_of_match); @@ -926,7 +926,7 @@ static const struct spi_device_id ads131e08_ids[] = { { "ads131e04", (kernel_ulong_t)&ads131e08_info_tbl[ads131e04] }, { "ads131e06", (kernel_ulong_t)&ads131e08_info_tbl[ads131e06] }, { "ads131e08", (kernel_ulong_t)&ads131e08_info_tbl[ads131e08] }, - {} + { } }; MODULE_DEVICE_TABLE(spi, ads131e08_ids); diff --git a/drivers/iio/adc/ti-ads7924.c b/drivers/iio/adc/ti-ads7924.c index 4da78302359b..66b54c0d75aa 100644 --- a/drivers/iio/adc/ti-ads7924.c +++ b/drivers/iio/adc/ti-ads7924.c @@ -448,13 +448,13 @@ static int ads7924_probe(struct i2c_client *client) static const struct i2c_device_id ads7924_id[] = { { "ads7924" }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, ads7924_id); static const struct of_device_id ads7924_of_match[] = { { .compatible = "ti,ads7924", }, - {} + { } }; MODULE_DEVICE_TABLE(of, ads7924_of_match); diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c index 263fc3a1b87e..af28672aa803 100644 --- a/drivers/iio/adc/ti-ads7950.c +++ b/drivers/iio/adc/ti-ads7950.c @@ -705,7 +705,7 @@ static const struct of_device_id ads7950_of_table[] = { { .compatible = "ti,ads7959", .data = &ti_ads7950_chip_info[TI_ADS7959] }, { .compatible = "ti,ads7960", .data = &ti_ads7950_chip_info[TI_ADS7960] }, { .compatible = "ti,ads7961", .data = &ti_ads7950_chip_info[TI_ADS7961] }, - { }, + { } }; MODULE_DEVICE_TABLE(of, ads7950_of_table); diff --git a/drivers/iio/adc/ti-ads8344.c b/drivers/iio/adc/ti-ads8344.c index bbd85cb47f81..3bec8a2e61ab 100644 --- a/drivers/iio/adc/ti-ads8344.c +++ b/drivers/iio/adc/ti-ads8344.c @@ -175,7 +175,7 @@ static int ads8344_probe(struct spi_device *spi) static const struct of_device_id ads8344_of_match[] = { { .compatible = "ti,ads8344", }, - {} + { } }; MODULE_DEVICE_TABLE(of, ads8344_of_match); diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 94cc823b26f3..9b1814f1965a 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -452,9 +452,9 @@ static int ads8688_probe(struct spi_device *spi) } static const struct spi_device_id ads8688_id[] = { - {"ads8684", ID_ADS8684}, - {"ads8688", ID_ADS8688}, - {} + { "ads8684", ID_ADS8684 }, + { "ads8688", ID_ADS8688 }, + { } }; MODULE_DEVICE_TABLE(spi, ads8688_id); diff --git a/drivers/iio/adc/ti-lmp92064.c b/drivers/iio/adc/ti-lmp92064.c index 84ba5c4a0eea..169e3591320b 100644 --- a/drivers/iio/adc/ti-lmp92064.c +++ b/drivers/iio/adc/ti-lmp92064.c @@ -360,7 +360,7 @@ static int lmp92064_adc_probe(struct spi_device *spi) static const struct spi_device_id lmp92064_id_table[] = { { "lmp92064" }, - {} + { } }; MODULE_DEVICE_TABLE(spi, lmp92064_id_table); diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c index 30f629a553a1..08de997584fd 100644 --- a/drivers/iio/adc/ti-tlc4541.c +++ b/drivers/iio/adc/ti-tlc4541.c @@ -237,14 +237,14 @@ static void tlc4541_remove(struct spi_device *spi) static const struct of_device_id tlc4541_dt_ids[] = { { .compatible = "ti,tlc3541", }, { .compatible = "ti,tlc4541", }, - {} + { } }; MODULE_DEVICE_TABLE(of, tlc4541_dt_ids); static const struct spi_device_id tlc4541_id[] = { - {"tlc3541", TLC3541}, - {"tlc4541", TLC4541}, - {} + { "tlc3541", TLC3541 }, + { "tlc4541", TLC4541 }, + { } }; MODULE_DEVICE_TABLE(spi, tlc4541_id); -- cgit From dfc58f467f7163b28d8aaadafd86d93dd08ea01c Mon Sep 17 00:00:00 2001 From: zhangjiao Date: Thu, 29 Aug 2024 13:33:09 +0800 Subject: tools: iio: rm .*.cmd when make clean rm .*.cmd when make clean Signed-off-by: zhangjiao Link: https://patch.msgid.link/20240829053309.10563-1-zhangjiao2@cmss.chinamobile.com Signed-off-by: Jonathan Cameron --- tools/iio/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/iio/Makefile b/tools/iio/Makefile index fa720f062229..3bcce0b7d10f 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -58,7 +58,7 @@ $(OUTPUT)iio_generic_buffer: $(IIO_GENERIC_BUFFER_IN) clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/linux/iio - find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete -o -name '\.*.cmd' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ -- cgit From c7ac44751d18c53230bd86b4e13b361abd9590bb Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Wed, 21 Aug 2024 16:54:42 -0500 Subject: iio: adc: axp20x_adc: Add adc_en1 and adc_en2 to axp_data Add the register for adc_en1 and adc_en2 to the axp_data struct. This allows us to specify a different register to enable the adc channels for different devices such as the AXP717. Acked-by: Jonathan Cameron Signed-off-by: Chris Morgan Acked-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20240821215456.962564-2-macroalpha82@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/axp20x_adc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index b487e577befb..368ba6ee7a80 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -889,7 +889,9 @@ struct axp_data { const struct iio_info *iio_info; int num_channels; struct iio_chan_spec const *channels; + unsigned long adc_en1; unsigned long adc_en1_mask; + unsigned long adc_en2; unsigned long adc_en2_mask; int (*adc_rate)(struct axp20x_adc_iio *info, int rate); @@ -910,7 +912,9 @@ static const struct axp_data axp20x_data = { .iio_info = &axp20x_adc_iio_info, .num_channels = ARRAY_SIZE(axp20x_adc_channels), .channels = axp20x_adc_channels, + .adc_en1 = AXP20X_ADC_EN1, .adc_en1_mask = AXP20X_ADC_EN1_MASK, + .adc_en2 = AXP20X_ADC_EN2, .adc_en2_mask = AXP20X_ADC_EN2_MASK, .adc_rate = axp20x_adc_rate, .maps = axp20x_maps, @@ -920,6 +924,7 @@ static const struct axp_data axp22x_data = { .iio_info = &axp22x_adc_iio_info, .num_channels = ARRAY_SIZE(axp22x_adc_channels), .channels = axp22x_adc_channels, + .adc_en1 = AXP20X_ADC_EN1, .adc_en1_mask = AXP22X_ADC_EN1_MASK, .adc_rate = axp22x_adc_rate, .maps = axp22x_maps, @@ -929,6 +934,7 @@ static const struct axp_data axp813_data = { .iio_info = &axp813_adc_iio_info, .num_channels = ARRAY_SIZE(axp813_adc_channels), .channels = axp813_adc_channels, + .adc_en1 = AXP20X_ADC_EN1, .adc_en1_mask = AXP22X_ADC_EN1_MASK, .adc_rate = axp813_adc_rate, .maps = axp22x_maps, @@ -988,14 +994,16 @@ static int axp20x_probe(struct platform_device *pdev) indio_dev->channels = info->data->channels; /* Enable the ADCs on IP */ - regmap_write(info->regmap, AXP20X_ADC_EN1, info->data->adc_en1_mask); + regmap_write(info->regmap, info->data->adc_en1, + info->data->adc_en1_mask); if (info->data->adc_en2_mask) - regmap_set_bits(info->regmap, AXP20X_ADC_EN2, + regmap_set_bits(info->regmap, info->data->adc_en2, info->data->adc_en2_mask); /* Configure ADCs rate */ - info->data->adc_rate(info, 100); + if (info->data->adc_rate) + info->data->adc_rate(info, 100); ret = iio_map_array_register(indio_dev, info->data->maps); if (ret < 0) { @@ -1015,10 +1023,10 @@ fail_register: iio_map_array_unregister(indio_dev); fail_map: - regmap_write(info->regmap, AXP20X_ADC_EN1, 0); + regmap_write(info->regmap, info->data->adc_en1, 0); if (info->data->adc_en2_mask) - regmap_write(info->regmap, AXP20X_ADC_EN2, 0); + regmap_write(info->regmap, info->data->adc_en2, 0); return ret; } @@ -1031,10 +1039,10 @@ static void axp20x_remove(struct platform_device *pdev) iio_device_unregister(indio_dev); iio_map_array_unregister(indio_dev); - regmap_write(info->regmap, AXP20X_ADC_EN1, 0); + regmap_write(info->regmap, info->data->adc_en1, 0); if (info->data->adc_en2_mask) - regmap_write(info->regmap, AXP20X_ADC_EN2, 0); + regmap_write(info->regmap, info->data->adc_en2, 0); } static struct platform_driver axp20x_adc_driver = { -- cgit From 85d3af3e9fccdc42b9651640dc84ef1d7955b693 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Wed, 21 Aug 2024 16:54:49 -0500 Subject: dt-bindings: iio: adc: Add AXP717 compatible Add compatible binding for the axp717. Acked-by: Jonathan Cameron Acked-by: Krzysztof Kozlowski Signed-off-by: Chris Morgan Link: https://patch.msgid.link/20240821215456.962564-9-macroalpha82@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml b/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml index d40689f233f2..1caa896fce82 100644 --- a/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml @@ -37,6 +37,17 @@ description: | 3 | batt_dischrg_i 4 | ts_v + AXP717 + ------ + 0 | batt_v + 1 | ts_v + 2 | vbus_v + 3 | vsys_v + 4 | pmic_temp + 5 | batt_chrg_i + 6 | vmid_v + 7 | bkup_batt_v + AXP813 ------ 0 | pmic_temp @@ -52,6 +63,7 @@ properties: oneOf: - const: x-powers,axp209-adc - const: x-powers,axp221-adc + - const: x-powers,axp717-adc - const: x-powers,axp813-adc - items: -- cgit From 5ba0cb92584ba5e107c97001e09013c1da0772a8 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Wed, 21 Aug 2024 16:54:53 -0500 Subject: iio: adc: axp20x_adc: add support for AXP717 ADC Add support for the AXP717 ADC. The AXP717 differs from other ADCs in this series by utilizing a 14 bit ADC for all channels (a full 16 bits with the first 2 digits reserved). It also differs by lacking a battery discharge current channel. Note that while the current charge channel itself is included in this driver for the AXP717 and listed in the datasheet, no scale or offset was given for this channel. For now no scale or offset is provided in this driver. Acked-by: Jonathan Cameron Signed-off-by: Chris Morgan Link: https://patch.msgid.link/20240821215456.962564-13-macroalpha82@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/axp20x_adc.c | 160 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index 368ba6ee7a80..d43c8d124a0c 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -5,6 +5,7 @@ * Quentin Schulz */ +#include #include #include #include @@ -30,6 +31,8 @@ #define AXP22X_ADC_EN1_MASK (GENMASK(7, 5) | BIT(0)) +#define AXP717_ADC_EN1_MASK GENMASK(7, 0) + #define AXP192_GPIO30_IN_RANGE_GPIO0 BIT(0) #define AXP192_GPIO30_IN_RANGE_GPIO1 BIT(1) #define AXP192_GPIO30_IN_RANGE_GPIO2 BIT(2) @@ -43,6 +46,13 @@ #define AXP22X_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK) +#define AXP717_ADC_DATA_TS 0x00 +#define AXP717_ADC_DATA_TEMP 0x01 +#define AXP717_ADC_DATA_VMID 0x02 +#define AXP717_ADC_DATA_BKUP_BATT 0x03 + +#define AXP717_ADC_DATA_MASK GENMASK(13, 0) + #define AXP813_V_I_ADC_RATE_MASK GENMASK(5, 4) #define AXP813_ADC_RATE_MASK (AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK) #define AXP813_TS_GPIO0_ADC_RATE_HZ(x) AXP20X_ADC_RATE_HZ(x) @@ -125,6 +135,20 @@ enum axp22x_adc_channel_i { AXP22X_BATT_DISCHRG_I, }; +enum axp717_adc_channel_v { + AXP717_BATT_V = 0, + AXP717_TS_IN, + AXP717_VBUS_V, + AXP717_VSYS_V, + AXP717_DIE_TEMP_V, + AXP717_VMID_V = 6, + AXP717_BKUP_BATT_V, +}; + +enum axp717_adc_channel_i { + AXP717_BATT_CHRG_I = 5, +}; + enum axp813_adc_channel_v { AXP813_TS_IN = 0, AXP813_GPIO0_V, @@ -179,6 +203,22 @@ static struct iio_map axp22x_maps[] = { }, { /* sentinel */ } }; +static struct iio_map axp717_maps[] = { + { + .consumer_dev_name = "axp20x-usb-power-supply", + .consumer_channel = "vbus_v", + .adc_channel_label = "vbus_v", + }, { + .consumer_dev_name = "axp20x-battery-power-supply", + .consumer_channel = "batt_v", + .adc_channel_label = "batt_v", + }, { + .consumer_dev_name = "axp20x-battery-power-supply", + .consumer_channel = "batt_chrg_i", + .adc_channel_label = "batt_chrg_i", + }, +}; + /* * Channels are mapped by physical system. Their channels share the same index. * i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw. @@ -274,6 +314,29 @@ static const struct iio_chan_spec axp22x_adc_channels[] = { AXP22X_TS_ADC_H), }; +/* + * Scale and offset is unknown for temp, ts, batt_chrg_i, vmid_v, and + * bkup_batt_v channels. Leaving scale and offset undefined for now. + */ +static const struct iio_chan_spec axp717_adc_channels[] = { + AXP20X_ADC_CHANNEL(AXP717_BATT_V, "batt_v", IIO_VOLTAGE, + AXP717_BATT_V_H), + AXP20X_ADC_CHANNEL(AXP717_TS_IN, "ts_v", IIO_VOLTAGE, + AXP717_ADC_DATA_H), + AXP20X_ADC_CHANNEL(AXP717_VBUS_V, "vbus_v", IIO_VOLTAGE, + AXP717_VBUS_V_H), + AXP20X_ADC_CHANNEL(AXP717_VSYS_V, "vsys_v", IIO_VOLTAGE, + AXP717_VSYS_V_H), + AXP20X_ADC_CHANNEL(AXP717_DIE_TEMP_V, "pmic_temp", IIO_TEMP, + AXP717_ADC_DATA_H), + AXP20X_ADC_CHANNEL(AXP717_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT, + AXP717_BATT_CHRG_I_H), + AXP20X_ADC_CHANNEL(AXP717_VMID_V, "vmid_v", IIO_VOLTAGE, + AXP717_ADC_DATA_H), + AXP20X_ADC_CHANNEL(AXP717_BKUP_BATT_V, "bkup_batt_v", IIO_VOLTAGE, + AXP717_ADC_DATA_H), +}; + static const struct iio_chan_spec axp813_adc_channels[] = { { .type = IIO_TEMP, @@ -354,6 +417,51 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; } +static int axp717_adc_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val) +{ + struct axp20x_adc_iio *info = iio_priv(indio_dev); + u8 bulk_reg[2]; + int ret; + + /* + * A generic "ADC data" channel is used for TS, tdie, vmid, + * and vbackup. This channel must both first be enabled and + * also selected before it can be read. + */ + switch (chan->channel) { + case AXP717_TS_IN: + regmap_write(info->regmap, AXP717_ADC_DATA_SEL, + AXP717_ADC_DATA_TS); + break; + case AXP717_DIE_TEMP_V: + regmap_write(info->regmap, AXP717_ADC_DATA_SEL, + AXP717_ADC_DATA_TEMP); + break; + case AXP717_VMID_V: + regmap_write(info->regmap, AXP717_ADC_DATA_SEL, + AXP717_ADC_DATA_VMID); + break; + case AXP717_BKUP_BATT_V: + regmap_write(info->regmap, AXP717_ADC_DATA_SEL, + AXP717_ADC_DATA_BKUP_BATT); + break; + default: + break; + } + + /* + * All channels are 14 bits, with the first 2 bits on the high + * register reserved and the remaining bits as the ADC value. + */ + ret = regmap_bulk_read(info->regmap, chan->address, bulk_reg, 2); + if (ret < 0) + return ret; + + *val = FIELD_GET(AXP717_ADC_DATA_MASK, get_unaligned_be16(bulk_reg)); + return IIO_VAL_INT; +} + static int axp813_adc_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val) { @@ -571,6 +679,27 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val, } } +static int axp717_adc_scale(struct iio_chan_spec const *chan, int *val, + int *val2) +{ + switch (chan->type) { + case IIO_VOLTAGE: + *val = 1; + return IIO_VAL_INT; + + case IIO_CURRENT: + *val = 1; + return IIO_VAL_INT; + + case IIO_TEMP: + *val = 100; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + static int axp813_adc_scale(struct iio_chan_spec const *chan, int *val, int *val2) { @@ -746,6 +875,22 @@ static int axp22x_read_raw(struct iio_dev *indio_dev, } } +static int axp717_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return axp717_adc_scale(chan, val, val2); + + case IIO_CHAN_INFO_RAW: + return axp717_adc_raw(indio_dev, chan, val); + + default: + return -EINVAL; + } +} + static int axp813_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -860,6 +1005,10 @@ static const struct iio_info axp22x_adc_iio_info = { .read_raw = axp22x_read_raw, }; +static const struct iio_info axp717_adc_iio_info = { + .read_raw = axp717_read_raw, +}; + static const struct iio_info axp813_adc_iio_info = { .read_raw = axp813_read_raw, }; @@ -930,6 +1079,15 @@ static const struct axp_data axp22x_data = { .maps = axp22x_maps, }; +static const struct axp_data axp717_data = { + .iio_info = &axp717_adc_iio_info, + .num_channels = ARRAY_SIZE(axp717_adc_channels), + .channels = axp717_adc_channels, + .adc_en1 = AXP717_ADC_CH_EN_CONTROL, + .adc_en1_mask = AXP717_ADC_EN1_MASK, + .maps = axp717_maps, +}; + static const struct axp_data axp813_data = { .iio_info = &axp813_adc_iio_info, .num_channels = ARRAY_SIZE(axp813_adc_channels), @@ -944,6 +1102,7 @@ static const struct of_device_id axp20x_adc_of_match[] = { { .compatible = "x-powers,axp192-adc", .data = (void *)&axp192_data, }, { .compatible = "x-powers,axp209-adc", .data = (void *)&axp20x_data, }, { .compatible = "x-powers,axp221-adc", .data = (void *)&axp22x_data, }, + { .compatible = "x-powers,axp717-adc", .data = (void *)&axp717_data, }, { .compatible = "x-powers,axp813-adc", .data = (void *)&axp813_data, }, { /* sentinel */ } }; @@ -953,6 +1112,7 @@ static const struct platform_device_id axp20x_adc_id_match[] = { { .name = "axp192-adc", .driver_data = (kernel_ulong_t)&axp192_data, }, { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, }, { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, }, + { .name = "axp717-adc", .driver_data = (kernel_ulong_t)&axp717_data, }, { .name = "axp813-adc", .driver_data = (kernel_ulong_t)&axp813_data, }, { /* sentinel */ }, }; -- cgit