From 8745465e884c06736aafc6c0e7344ac3a3c7df94 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Wed, 3 Jan 2024 13:08:51 +0100 Subject: iio: light: as73211: use IIO_VAL_FRACTIONAL for intensity scales The scale values associated to the light channels are calculated as a division that can be better expressed as an IIO_VAL_FRACTIONAL type instead of the current IIO_VAL_INT. Note that the constant values used for the calculation were scaled up to work with integers, turning the nW/cm^2 units from the datasheet into nW/m^2, which would not be necessary with the IIO_VAL_FRACTIONAL type. But to avoid issues from current users of the driver, the units must be kept. Signed-off-by: Javier Carrasco Signed-off-by: Jonathan Cameron --- drivers/iio/light/as73211.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c index ec97a3a46839..b4c6f389a292 100644 --- a/drivers/iio/light/as73211.c +++ b/drivers/iio/light/as73211.c @@ -356,25 +356,24 @@ static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec cons return IIO_VAL_INT_PLUS_MICRO; case IIO_INTENSITY: { - unsigned int scale; switch (chan->channel2) { case IIO_MOD_X: - scale = AS73211_SCALE_X; + *val = AS73211_SCALE_X; break; case IIO_MOD_Y: - scale = AS73211_SCALE_Y; + *val = AS73211_SCALE_Y; break; case IIO_MOD_Z: - scale = AS73211_SCALE_Z; + *val = AS73211_SCALE_Z; break; default: return -EINVAL; } - scale /= as73211_gain(data); - scale /= as73211_integration_time_1024cyc(data); - *val = scale; - return IIO_VAL_INT; + *val2 = as73211_integration_time_1024cyc(data) * + as73211_gain(data); + + return IIO_VAL_FRACTIONAL; default: return -EINVAL; -- cgit v1.2.3 From 02324a09cbe2ae38ab081dd5a1f620ccfd3c62b7 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Wed, 3 Jan 2024 13:08:53 +0100 Subject: iio: light: as73211: add support for as7331 The AMS AS7331 is a UV light sensor with three channels: UVA, UVB and UVC (also known as deep UV and referenced as DUV in the iio core). Its internal structure and forming blocks are practically identical to the ones the AS73211 contains: API, internal DAC, I2C interface and registers, measurement modes, number of channels and pinout. The only difference between them is the photodiodes used to acquire light, which means that only some modifications are required to add support for the AS7331 in the existing driver. The temperature channel is identical for both devices and only the channel modifiers of the IIO_INTENSITY channels need to account for the device type. The scale values have been obtained from the chapter "7.5 Transfer Function" of the official datasheet[1] for the configuration chosen as basis (Nclk = 1024 and GAIN = 1). Those values keep the units from the datasheet (nW/cm^2), as opposed to the units used for the AS73211 (nW/m^2). Add a new device-specific data structure to account for the device differences: channel types and scale of LSB per channel. [1] https://ams.com/documents/20143/9106314/AS7331_DS001047_4-00.pdf Tested-by: Christian Eggers Signed-off-by: Javier Carrasco Signed-off-by: Jonathan Cameron --- drivers/iio/light/Kconfig | 5 +- drivers/iio/light/as73211.c | 141 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 118 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 143003232d1c..fd5a9879a582 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -87,13 +87,14 @@ config APDS9960 module will be called apds9960 config AS73211 - tristate "AMS AS73211 XYZ color sensor" + tristate "AMS AS73211 XYZ color sensor and AMS AS7331 UV sensor" depends on I2C select IIO_BUFFER select IIO_TRIGGERED_BUFFER help If you say yes here you get support for the AMS AS73211 - JENCOLOR(R) Digital XYZ Sensor. + JENCOLOR(R) Digital XYZ and the AMS AS7331 UVA, UVB and UVC + ultraviolet sensors. For triggered measurements, you will need an additional trigger driver like IIO_HRTIMER_TRIGGER or IIO_SYSFS_TRIGGER. diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c index b4c6f389a292..be0068081ebb 100644 --- a/drivers/iio/light/as73211.c +++ b/drivers/iio/light/as73211.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor + * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor and AMS AS7331 + * UVA, UVB and UVC (DUV) Ultraviolet Sensor * * Author: Christian Eggers * @@ -9,7 +10,9 @@ * Color light sensor with 16-bit channels for x, y, z and temperature); * 7-bit I2C slave address 0x74 .. 0x77. * - * Datasheet: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf + * Datasheets: + * AS73211: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf + * AS7331: https://ams.com/documents/20143/9106314/AS7331_DS001047_4-00.pdf */ #include @@ -84,6 +87,20 @@ static const int as73211_hardwaregain_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, }; +struct as73211_data; + +/** + * struct as73211_spec_dev_data - device-specific data + * @intensity_scale: Function to retrieve intensity scale values. + * @channels: Device channels. + * @num_channels: Number of channels of the device. + */ +struct as73211_spec_dev_data { + int (*intensity_scale)(struct as73211_data *data, int chan, int *val, int *val2); + struct iio_chan_spec const *channels; + int num_channels; +}; + /** * struct as73211_data - Instance data for one AS73211 * @client: I2C client. @@ -94,6 +111,7 @@ static const int as73211_hardwaregain_avail[] = { * @mutex: Keeps cached registers in sync with the device. * @completion: Completion to wait for interrupt. * @int_time_avail: Available integration times (depend on sampling frequency). + * @spec_dev: device-specific configuration. */ struct as73211_data { struct i2c_client *client; @@ -104,6 +122,7 @@ struct as73211_data { struct mutex mutex; struct completion completion; int int_time_avail[AS73211_SAMPLE_TIME_NUM * 2]; + const struct as73211_spec_dev_data *spec_dev; }; #define AS73211_COLOR_CHANNEL(_color, _si, _addr) { \ @@ -138,6 +157,10 @@ struct as73211_data { #define AS73211_SCALE_Y 298384270 /* nW/m^2 */ #define AS73211_SCALE_Z 160241927 /* nW/m^2 */ +#define AS7331_SCALE_UVA 340000 /* nW/cm^2 */ +#define AS7331_SCALE_UVB 378000 /* nW/cm^2 */ +#define AS7331_SCALE_UVC 166000 /* nW/cm^2 */ + /* Channel order MUST match devices result register order */ #define AS73211_SCAN_INDEX_TEMP 0 #define AS73211_SCAN_INDEX_X 1 @@ -176,6 +199,28 @@ static const struct iio_chan_spec as73211_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), }; +static const struct iio_chan_spec as7331_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + .address = AS73211_OUT_TEMP, + .scan_index = AS73211_SCAN_INDEX_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + } + }, + AS73211_COLOR_CHANNEL(LIGHT_UVA, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1), + AS73211_COLOR_CHANNEL(LIGHT_UVB, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2), + AS73211_COLOR_CHANNEL(LIGHT_DUV, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3), + IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), +}; + static unsigned int as73211_integration_time_1024cyc(struct as73211_data *data) { /* @@ -316,6 +361,48 @@ static int as73211_req_data(struct as73211_data *data) return 0; } +static int as73211_intensity_scale(struct as73211_data *data, int chan, + int *val, int *val2) +{ + switch (chan) { + case IIO_MOD_X: + *val = AS73211_SCALE_X; + break; + case IIO_MOD_Y: + *val = AS73211_SCALE_Y; + break; + case IIO_MOD_Z: + *val = AS73211_SCALE_Z; + break; + default: + return -EINVAL; + } + *val2 = as73211_integration_time_1024cyc(data) * as73211_gain(data); + + return IIO_VAL_FRACTIONAL; +} + +static int as7331_intensity_scale(struct as73211_data *data, int chan, + int *val, int *val2) +{ + switch (chan) { + case IIO_MOD_LIGHT_UVA: + *val = AS7331_SCALE_UVA; + break; + case IIO_MOD_LIGHT_UVB: + *val = AS7331_SCALE_UVB; + break; + case IIO_MOD_LIGHT_DUV: + *val = AS7331_SCALE_UVC; + break; + default: + return -EINVAL; + } + *val2 = as73211_integration_time_1024cyc(data) * as73211_gain(data); + + return IIO_VAL_FRACTIONAL; +} + static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { @@ -355,29 +442,13 @@ static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec cons *val2 = AS73211_SCALE_TEMP_MICRO; return IIO_VAL_INT_PLUS_MICRO; - case IIO_INTENSITY: { - - switch (chan->channel2) { - case IIO_MOD_X: - *val = AS73211_SCALE_X; - break; - case IIO_MOD_Y: - *val = AS73211_SCALE_Y; - break; - case IIO_MOD_Z: - *val = AS73211_SCALE_Z; - break; - default: - return -EINVAL; - } - *val2 = as73211_integration_time_1024cyc(data) * - as73211_gain(data); - - return IIO_VAL_FRACTIONAL; + case IIO_INTENSITY: + return data->spec_dev->intensity_scale(data, chan->channel2, + val, val2); default: return -EINVAL; - }} + } case IIO_CHAN_INFO_SAMP_FREQ: /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ @@ -675,13 +746,17 @@ static int as73211_probe(struct i2c_client *client) i2c_set_clientdata(client, indio_dev); data->client = client; + data->spec_dev = i2c_get_match_data(client); + if (!data->spec_dev) + return -EINVAL; + mutex_init(&data->mutex); init_completion(&data->completion); indio_dev->info = &as73211_info; indio_dev->name = AS73211_DRV_NAME; - indio_dev->channels = as73211_channels; - indio_dev->num_channels = ARRAY_SIZE(as73211_channels); + indio_dev->channels = data->spec_dev->channels; + indio_dev->num_channels = data->spec_dev->num_channels; indio_dev->modes = INDIO_DIRECT_MODE; ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); @@ -771,14 +846,28 @@ static int as73211_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(as73211_pm_ops, as73211_suspend, as73211_resume); +static const struct as73211_spec_dev_data as73211_spec = { + .intensity_scale = as73211_intensity_scale, + .channels = as73211_channels, + .num_channels = ARRAY_SIZE(as73211_channels), +}; + +static const struct as73211_spec_dev_data as7331_spec = { + .intensity_scale = as7331_intensity_scale, + .channels = as7331_channels, + .num_channels = ARRAY_SIZE(as7331_channels), +}; + static const struct of_device_id as73211_of_match[] = { - { .compatible = "ams,as73211" }, + { .compatible = "ams,as73211", &as73211_spec }, + { .compatible = "ams,as7331", &as7331_spec }, { } }; MODULE_DEVICE_TABLE(of, as73211_of_match); static const struct i2c_device_id as73211_id[] = { - { "as73211", 0 }, + { "as73211", (kernel_ulong_t)&as73211_spec }, + { "as7331", (kernel_ulong_t)&as7331_spec }, { } }; MODULE_DEVICE_TABLE(i2c, as73211_id); -- cgit v1.2.3 From a9058f287016f24c1d88acd062933424e623fa32 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 4 Jan 2024 17:01:52 +0100 Subject: iio: accel: da280: Simplify id-matching da280_match_acpi_device() is a DIY version of acpi_device_get_match_data(), so it can be dropped. And things can be simplified further by using i2c_get_match_data() which will also check i2c_client_id style ids. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20240104160152.304100-1-hdegoede@redhat.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/da280.c | 64 ++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c index 572bfe9694b0..756e2ea7c056 100644 --- a/drivers/iio/accel/da280.c +++ b/drivers/iio/accel/da280.c @@ -23,8 +23,6 @@ #define DA280_MODE_ENABLE 0x1e #define DA280_MODE_DISABLE 0x9e -enum da280_chipset { da217, da226, da280 }; - /* * a value of + or -4096 corresponds to + or - 1G * scale = 9.81 / 4096 = 0.002395019 @@ -47,6 +45,11 @@ static const struct iio_chan_spec da280_channels[] = { DA280_CHANNEL(DA280_REG_ACC_Z_LSB, Z), }; +struct da280_match_data { + const char *name; + int num_channels; +}; + struct da280_data { struct i2c_client *client; }; @@ -89,17 +92,6 @@ static const struct iio_info da280_info = { .read_raw = da280_read_raw, }; -static enum da280_chipset da280_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return -EINVAL; - - return (enum da280_chipset) id->driver_data; -} - static void da280_disable(void *client) { da280_enable(client, false); @@ -107,16 +99,21 @@ static void da280_disable(void *client) static int da280_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); - int ret; + const struct da280_match_data *match_data; struct iio_dev *indio_dev; struct da280_data *data; - enum da280_chipset chip; + int ret; ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID); if (ret != DA280_CHIP_ID) return (ret < 0) ? ret : -ENODEV; + match_data = i2c_get_match_data(client); + if (!match_data) { + dev_err(&client->dev, "Error match-data not set\n"); + return -EINVAL; + } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; @@ -127,23 +124,8 @@ static int da280_probe(struct i2c_client *client) indio_dev->info = &da280_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = da280_channels; - - if (ACPI_HANDLE(&client->dev)) { - chip = da280_match_acpi_device(&client->dev); - } else { - chip = id->driver_data; - } - - if (chip == da217) { - indio_dev->name = "da217"; - indio_dev->num_channels = 3; - } else if (chip == da226) { - indio_dev->name = "da226"; - indio_dev->num_channels = 2; - } else { - indio_dev->name = "da280"; - indio_dev->num_channels = 3; - } + indio_dev->num_channels = match_data->num_channels; + indio_dev->name = match_data->name; ret = da280_enable(client, true); if (ret < 0) @@ -168,17 +150,21 @@ static int da280_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume); +static const struct da280_match_data da217_match_data = { "da217", 3 }; +static const struct da280_match_data da226_match_data = { "da226", 2 }; +static const struct da280_match_data da280_match_data = { "da280", 3 }; + static const struct acpi_device_id da280_acpi_match[] = { - {"NSA2513", da217}, - {"MIRAACC", da280}, - {}, + { "NSA2513", (kernel_ulong_t)&da217_match_data }, + { "MIRAACC", (kernel_ulong_t)&da280_match_data }, + {} }; MODULE_DEVICE_TABLE(acpi, da280_acpi_match); static const struct i2c_device_id da280_i2c_id[] = { - { "da217", da217 }, - { "da226", da226 }, - { "da280", da280 }, + { "da217", (kernel_ulong_t)&da217_match_data }, + { "da226", (kernel_ulong_t)&da226_match_data }, + { "da280", (kernel_ulong_t)&da280_match_data }, {} }; MODULE_DEVICE_TABLE(i2c, da280_i2c_id); -- cgit v1.2.3 From 0ba6014a2317b8dae9e31cd293f6666c5172efe9 Mon Sep 17 00:00:00 2001 From: Mohammed Billoo Date: Sat, 6 Jan 2024 12:48:35 -0500 Subject: iio: adc: ti-ads1015: Use correct pga upper bound The devicetree binding and datasheets (for both the ADS1015 and ADS1115) show that the PGA index should have a maximum value of 5, and not 6. Signed-off-by: Mohammed Billoo Link: https://lore.kernel.org/r/20240106174836.1086714-1-mab.kernel@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads1015.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 6799ea49dbc7..6ae967e4d8fa 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -925,7 +925,7 @@ static int ads1015_client_get_channels_config(struct i2c_client *client) if (!fwnode_property_read_u32(node, "ti,gain", &pval)) { pga = pval; - if (pga > 6) { + if (pga > 5) { dev_err(dev, "invalid gain on %pfw\n", node); fwnode_handle_put(node); return -EINVAL; -- cgit v1.2.3 From 9e65506ca9c7ff716c8441a33417820ad61d3a16 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:32 +0200 Subject: iio: pressure: mprls0025pa fix off-by-one enum Fix off-by-one error in transfer-function property. The honeywell,transfer-function property takes values between 1-3 so make sure the proper enum gets used. Fixes: 713337d9143ed ("iio: pressure: Honeywell mprls0025pa pressure sensor") Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-5-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mprls0025pa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index 30fb2de36821..e3f0de020a40 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -323,6 +323,7 @@ static int mpr_probe(struct i2c_client *client) struct iio_dev *indio_dev; struct device *dev = &client->dev; s64 scale, offset; + u32 func; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) return dev_err_probe(dev, -EOPNOTSUPP, @@ -362,10 +363,11 @@ static int mpr_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "honeywell,pmax-pascal could not be read\n"); ret = device_property_read_u32(dev, - "honeywell,transfer-function", &data->function); + "honeywell,transfer-function", &func); if (ret) return dev_err_probe(dev, ret, "honeywell,transfer-function could not be read\n"); + data->function = func - 1; if (data->function > MPR_FUNCTION_C) return dev_err_probe(dev, -EINVAL, "honeywell,transfer-function %d invalid\n", -- cgit v1.2.3 From 0a0fb0e63e5178905e9fdba8195686b4e2de26c4 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:33 +0200 Subject: iio: pressure: mprls0025pa improve driver error resilience Improve driver error resilience by ignoring the measurement if any of the 3 error flags gets set while interacting with the sensor. Based on the datasheet, in table 14 on page 14, the status byte contains: bit 5 busy flag - 1 if device is busy bit 2 memory integrity/error flag - 1 if integrity test failed bit 0 math saturation - 1 if internal math saturation has occurred Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-6-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mprls0025pa.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index e3f0de020a40..233cc1dc38ad 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -39,6 +39,8 @@ #define MPR_I2C_MEMORY BIT(2) /* integrity test passed */ #define MPR_I2C_MATH BIT(0) /* internal math saturation */ +#define MPR_I2C_ERR_FLAG (MPR_I2C_BUSY | MPR_I2C_MEMORY | MPR_I2C_MATH) + /* * support _RAW sysfs interface: * @@ -213,7 +215,7 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press) status); return status; } - if (!(status & MPR_I2C_BUSY)) + if (!(status & MPR_I2C_ERR_FLAG)) break; } if (i == nloops) { @@ -233,7 +235,7 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press) return -EIO; } - if (buf[0] & MPR_I2C_BUSY) { + if (buf[0] & MPR_I2C_ERR_FLAG) { /* * it should never be the case that status still indicates * business -- cgit v1.2.3 From b586b40e1952a343ae68142d16512f39596ca71b Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:34 +0200 Subject: iio: pressure: mprls0025pa remove defaults This driver supports 32*3 combinations of fixed ranges and transfer functions, plus custom ranges. So statistically a user has more than 99% chance that the provided default configuration will generate invalid pressure readings if the bindings are not initialized and the driver is instantiated via sysfs. The current patch removes this loophole making sure the driver loads only if the firmware properties are present. Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-7-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mprls0025pa.c | 48 ++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index 233cc1dc38ad..e0a2a60c6245 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -353,34 +353,26 @@ static int mpr_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "can't get and enable vdd supply\n"); - if (dev_fwnode(dev)) { - ret = device_property_read_u32(dev, "honeywell,pmin-pascal", - &data->pmin); - if (ret) - return dev_err_probe(dev, ret, - "honeywell,pmin-pascal could not be read\n"); - ret = device_property_read_u32(dev, "honeywell,pmax-pascal", - &data->pmax); - if (ret) - return dev_err_probe(dev, ret, - "honeywell,pmax-pascal could not be read\n"); - ret = device_property_read_u32(dev, - "honeywell,transfer-function", &func); - if (ret) - return dev_err_probe(dev, ret, - "honeywell,transfer-function could not be read\n"); - data->function = func - 1; - if (data->function > MPR_FUNCTION_C) - return dev_err_probe(dev, -EINVAL, - "honeywell,transfer-function %d invalid\n", - data->function); - } else { - /* when loaded as i2c device we need to use default values */ - dev_notice(dev, "firmware node not found; using defaults\n"); - data->pmin = 0; - data->pmax = 172369; /* 25 psi */ - data->function = MPR_FUNCTION_A; - } + ret = device_property_read_u32(dev, "honeywell,pmin-pascal", + &data->pmin); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmin-pascal could not be read\n"); + ret = device_property_read_u32(dev, "honeywell,pmax-pascal", + &data->pmax); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmax-pascal could not be read\n"); + ret = device_property_read_u32(dev, + "honeywell,transfer-function", &func); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,transfer-function could not be read\n"); + data->function = func - 1; + if (data->function > MPR_FUNCTION_C) + return dev_err_probe(dev, -EINVAL, + "honeywell,transfer-function %d invalid\n", + data->function); data->outmin = mpr_func_spec[data->function].output_min; data->outmax = mpr_func_spec[data->function].output_max; -- cgit v1.2.3 From 369cc90a020f1cbc5c08bd53a23fb0c69c4ec3df Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:35 +0200 Subject: iio: pressure: mprls0025pa whitespace cleanup Fix indentation and whitespace in code that will not get refactored. Make URL inside comment copy-paste friendly. Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-8-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mprls0025pa.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index e0a2a60c6245..fef3ca69c4f0 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -5,10 +5,7 @@ * Copyright (c) Andreas Klinger * * Data sheet: - * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/ - * products/sensors/pressure-sensors/board-mount-pressure-sensors/ - * micropressure-mpr-series/documents/ - * sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf + * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf * * 7-bit I2C default slave address: 0x18 */ @@ -84,9 +81,9 @@ struct mpr_func_spec { }; static const struct mpr_func_spec mpr_func_spec[] = { - [MPR_FUNCTION_A] = {.output_min = 1677722, .output_max = 15099494}, - [MPR_FUNCTION_B] = {.output_min = 419430, .output_max = 3774874}, - [MPR_FUNCTION_C] = {.output_min = 3355443, .output_max = 13421773}, + [MPR_FUNCTION_A] = { .output_min = 1677722, .output_max = 15099494 }, + [MPR_FUNCTION_B] = { .output_min = 419430, .output_max = 3774874 }, + [MPR_FUNCTION_C] = { .output_min = 3355443, .output_max = 13421773 }, }; struct mpr_chan { @@ -273,7 +270,7 @@ static irqreturn_t mpr_trigger_handler(int irq, void *p) goto err; iio_push_to_buffers_with_timestamp(indio_dev, &data->chan, - iio_get_time_ns(indio_dev)); + iio_get_time_ns(indio_dev)); err: mutex_unlock(&data->lock); @@ -351,7 +348,7 @@ static int mpr_probe(struct i2c_client *client) ret = devm_regulator_get_enable(dev, "vdd"); if (ret) return dev_err_probe(dev, ret, - "can't get and enable vdd supply\n"); + "can't get and enable vdd supply\n"); ret = device_property_read_u32(dev, "honeywell,pmin-pascal", &data->pmin); @@ -379,42 +376,44 @@ static int mpr_probe(struct i2c_client *client) /* use 64 bit calculation for preserving a reasonable precision */ scale = div_s64(((s64)(data->pmax - data->pmin)) * NANO, - data->outmax - data->outmin); + data->outmax - data->outmin); data->scale = div_s64_rem(scale, NANO, &data->scale2); /* * multiply with NANO before dividing by scale and later divide by NANO * again. */ offset = ((-1LL) * (s64)data->outmin) * NANO - - div_s64(div_s64((s64)data->pmin * NANO, scale), NANO); + div_s64(div_s64((s64)data->pmin * NANO, scale), NANO); data->offset = div_s64_rem(offset, NANO, &data->offset2); if (data->irq > 0) { ret = devm_request_irq(dev, data->irq, mpr_eoc_handler, - IRQF_TRIGGER_RISING, client->name, data); + IRQF_TRIGGER_RISING, + client->name, + data); if (ret) return dev_err_probe(dev, ret, - "request irq %d failed\n", data->irq); + "request irq %d failed\n", data->irq); } data->gpiod_reset = devm_gpiod_get_optional(dev, "reset", - GPIOD_OUT_HIGH); + GPIOD_OUT_HIGH); if (IS_ERR(data->gpiod_reset)) return dev_err_probe(dev, PTR_ERR(data->gpiod_reset), - "request reset-gpio failed\n"); + "request reset-gpio failed\n"); mpr_reset(data); ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, - mpr_trigger_handler, NULL); + mpr_trigger_handler, NULL); if (ret) return dev_err_probe(dev, ret, - "iio triggered buffer setup failed\n"); + "iio triggered buffer setup failed\n"); ret = devm_iio_device_register(dev, indio_dev); if (ret) return dev_err_probe(dev, ret, - "unable to register iio device\n"); + "unable to register iio device\n"); return 0; } -- cgit v1.2.3 From 63cd31d320b50b7e004964c04ce3e73935cd3873 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:36 +0200 Subject: iio: pressure: mprls0025pa refactor to split core and i2c parts. Refactor driver by splitting the code into core and i2c. Seemingly redundant read/write function parameters are required for compatibility with the SPI driver. Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-9-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Kconfig | 6 ++ drivers/iio/pressure/Makefile | 1 + drivers/iio/pressure/mprls0025pa.c | 185 ++++++++++----------------------- drivers/iio/pressure/mprls0025pa.h | 102 ++++++++++++++++++ drivers/iio/pressure/mprls0025pa_i2c.c | 100 ++++++++++++++++++ 5 files changed, 262 insertions(+), 132 deletions(-) create mode 100644 drivers/iio/pressure/mprls0025pa.h create mode 100644 drivers/iio/pressure/mprls0025pa_i2c.c (limited to 'drivers') diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 79adfd059c3a..f03007cfec85 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -182,6 +182,7 @@ config MPL3115 config MPRLS0025PA tristate "Honeywell MPRLS0025PA (MicroPressure sensors series)" depends on I2C + select MPRLS0025PA_I2C if I2C select IIO_BUFFER select IIO_TRIGGERED_BUFFER help @@ -192,6 +193,11 @@ config MPRLS0025PA To compile this driver as a module, choose M here: the module will be called mprls0025pa. +config MPRLS0025PA_I2C + tristate + depends on MPRLS0025PA + depends on I2C + config MS5611 tristate "Measurement Specialties MS5611 pressure sensor driver" select IIO_BUFFER diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index b0f8b94662f2..7754135e190c 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_MPL115_I2C) += mpl115_i2c.o obj-$(CONFIG_MPL115_SPI) += mpl115_spi.o obj-$(CONFIG_MPL3115) += mpl3115.o obj-$(CONFIG_MPRLS0025PA) += mprls0025pa.o +obj-$(CONFIG_MPRLS0025PA_I2C) += mprls0025pa_i2c.o obj-$(CONFIG_MS5611) += ms5611_core.o obj-$(CONFIG_MS5611_I2C) += ms5611_i2c.o obj-$(CONFIG_MS5611_SPI) += ms5611_spi.o diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index fef3ca69c4f0..ce20cf362fac 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -7,12 +7,11 @@ * Data sheet: * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf * - * 7-bit I2C default slave address: 0x18 */ -#include -#include -#include +#include +#include +#include #include #include #include @@ -22,7 +21,6 @@ #include #include -#include #include #include @@ -30,13 +28,15 @@ #include -/* bits in i2c status byte */ -#define MPR_I2C_POWER BIT(6) /* device is powered */ -#define MPR_I2C_BUSY BIT(5) /* device is busy */ -#define MPR_I2C_MEMORY BIT(2) /* integrity test passed */ -#define MPR_I2C_MATH BIT(0) /* internal math saturation */ +#include "mprls0025pa.h" -#define MPR_I2C_ERR_FLAG (MPR_I2C_BUSY | MPR_I2C_MEMORY | MPR_I2C_MATH) +/* bits in status byte */ +#define MPR_ST_POWER BIT(6) /* device is powered */ +#define MPR_ST_BUSY BIT(5) /* device is busy */ +#define MPR_ST_MEMORY BIT(2) /* integrity test passed */ +#define MPR_ST_MATH BIT(0) /* internal math saturation */ + +#define MPR_ST_ERR_FLAG (MPR_ST_BUSY | MPR_ST_MEMORY | MPR_ST_MATH) /* * support _RAW sysfs interface: @@ -69,12 +69,6 @@ * transfer function B: 2.5% to 22.5% of 2^24 * transfer function C: 20% to 80% of 2^24 */ -enum mpr_func_id { - MPR_FUNCTION_A, - MPR_FUNCTION_B, - MPR_FUNCTION_C, -}; - struct mpr_func_spec { u32 output_min; u32 output_max; @@ -86,45 +80,6 @@ static const struct mpr_func_spec mpr_func_spec[] = { [MPR_FUNCTION_C] = { .output_min = 3355443, .output_max = 13421773 }, }; -struct mpr_chan { - s32 pres; /* pressure value */ - s64 ts; /* timestamp */ -}; - -struct mpr_data { - struct i2c_client *client; - struct mutex lock; /* - * access to device during read - */ - u32 pmin; /* minimal pressure in pascal */ - u32 pmax; /* maximal pressure in pascal */ - enum mpr_func_id function; /* transfer function */ - u32 outmin; /* - * minimal numerical range raw - * value from sensor - */ - u32 outmax; /* - * maximal numerical range raw - * value from sensor - */ - int scale; /* int part of scale */ - int scale2; /* nano part of scale */ - int offset; /* int part of offset */ - int offset2; /* nano part of offset */ - struct gpio_desc *gpiod_reset; /* reset */ - int irq; /* - * end of conversion irq; - * used to distinguish between - * irq mode and reading in a - * loop until data is ready - */ - struct completion completion; /* handshake from irq to read */ - struct mpr_chan chan; /* - * channel values for buffered - * mode - */ -}; - static const struct iio_chan_spec mpr_channels[] = { { .type = IIO_PRESSURE, @@ -152,11 +107,11 @@ static void mpr_reset(struct mpr_data *data) } /** - * mpr_read_pressure() - Read pressure value from sensor via I2C + * mpr_read_pressure() - Read pressure value from sensor * @data: Pointer to private data struct. * @press: Output value read from sensor. * - * Reading from the sensor by sending and receiving I2C telegrams. + * Reading from the sensor by sending and receiving telegrams. * * If there is an end of conversion (EOC) interrupt registered the function * waits for a maximum of one second for the interrupt. @@ -169,25 +124,17 @@ static void mpr_reset(struct mpr_data *data) */ static int mpr_read_pressure(struct mpr_data *data, s32 *press) { - struct device *dev = &data->client->dev; + struct device *dev = data->dev; int ret, i; - u8 wdata[] = {0xAA, 0x00, 0x00}; - s32 status; int nloops = 10; - u8 buf[4]; reinit_completion(&data->completion); - ret = i2c_master_send(data->client, wdata, sizeof(wdata)); + ret = data->ops->write(data, MPR_CMD_SYNC, MPR_PKT_SYNC_LEN); if (ret < 0) { dev_err(dev, "error while writing ret: %d\n", ret); return ret; } - if (ret != sizeof(wdata)) { - dev_err(dev, "received size doesn't fit - ret: %d / %u\n", ret, - (u32)sizeof(wdata)); - return -EIO; - } if (data->irq > 0) { ret = wait_for_completion_timeout(&data->completion, HZ); @@ -205,14 +152,14 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press) * quite long */ usleep_range(5000, 10000); - status = i2c_smbus_read_byte(data->client); - if (status < 0) { + ret = data->ops->read(data, MPR_CMD_NOP, 1); + if (ret < 0) { dev_err(dev, "error while reading, status: %d\n", - status); - return status; + ret); + return ret; } - if (!(status & MPR_I2C_ERR_FLAG)) + if (!(data->buffer[0] & MPR_ST_ERR_FLAG)) break; } if (i == nloops) { @@ -221,29 +168,19 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press) } } - ret = i2c_master_recv(data->client, buf, sizeof(buf)); - if (ret < 0) { - dev_err(dev, "error in i2c_master_recv ret: %d\n", ret); + ret = data->ops->read(data, MPR_CMD_NOP, MPR_PKT_NOP_LEN); + if (ret < 0) return ret; - } - if (ret != sizeof(buf)) { - dev_err(dev, "received size doesn't fit - ret: %d / %u\n", ret, - (u32)sizeof(buf)); - return -EIO; - } - if (buf[0] & MPR_I2C_ERR_FLAG) { - /* - * it should never be the case that status still indicates - * business - */ - dev_err(dev, "data still not ready: %08x\n", buf[0]); + if (data->buffer[0] & MPR_ST_ERR_FLAG) { + dev_err(data->dev, + "unexpected status byte %02x\n", data->buffer[0]); return -ETIMEDOUT; } - *press = get_unaligned_be24(&buf[1]); + *press = get_unaligned_be24(&data->buffer[1]); - dev_dbg(dev, "received: %*ph cnt: %d\n", ret, buf, *press); + dev_dbg(dev, "received: %*ph cnt: %d\n", ret, data->buffer, *press); return 0; } @@ -315,26 +252,22 @@ static const struct iio_info mpr_info = { .read_raw = &mpr_read_raw, }; -static int mpr_probe(struct i2c_client *client) +int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) { int ret; struct mpr_data *data; struct iio_dev *indio_dev; - struct device *dev = &client->dev; s64 scale, offset; u32 func; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) - return dev_err_probe(dev, -EOPNOTSUPP, - "I2C functionality not supported\n"); - indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) - return dev_err_probe(dev, -ENOMEM, "couldn't get iio_dev\n"); + return -ENOMEM; data = iio_priv(indio_dev); - data->client = client; - data->irq = client->irq; + data->dev = dev; + data->ops = ops; + data->irq = irq; mutex_init(&data->lock); init_completion(&data->completion); @@ -350,16 +283,10 @@ static int mpr_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "can't get and enable vdd supply\n"); - ret = device_property_read_u32(dev, "honeywell,pmin-pascal", - &data->pmin); + ret = data->ops->init(data->dev); if (ret) - return dev_err_probe(dev, ret, - "honeywell,pmin-pascal could not be read\n"); - ret = device_property_read_u32(dev, "honeywell,pmax-pascal", - &data->pmax); - if (ret) - return dev_err_probe(dev, ret, - "honeywell,pmax-pascal could not be read\n"); + return ret; + ret = device_property_read_u32(dev, "honeywell,transfer-function", &func); if (ret) @@ -371,6 +298,21 @@ static int mpr_probe(struct i2c_client *client) "honeywell,transfer-function %d invalid\n", data->function); + ret = device_property_read_u32(dev, "honeywell,pmin-pascal", + &data->pmin); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmin-pascal could not be read\n"); + ret = device_property_read_u32(dev, "honeywell,pmax-pascal", + &data->pmax); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmax-pascal could not be read\n"); + + if (data->pmin >= data->pmax) + return dev_err_probe(dev, -EINVAL, + "pressure limits are invalid\n"); + data->outmin = mpr_func_spec[data->function].output_min; data->outmax = mpr_func_spec[data->function].output_max; @@ -389,7 +331,7 @@ static int mpr_probe(struct i2c_client *client) if (data->irq > 0) { ret = devm_request_irq(dev, data->irq, mpr_eoc_handler, IRQF_TRIGGER_RISING, - client->name, + dev_name(dev), data); if (ret) return dev_err_probe(dev, ret, @@ -417,29 +359,8 @@ static int mpr_probe(struct i2c_client *client) return 0; } - -static const struct of_device_id mpr_matches[] = { - { .compatible = "honeywell,mprls0025pa" }, - { } -}; -MODULE_DEVICE_TABLE(of, mpr_matches); - -static const struct i2c_device_id mpr_id[] = { - { "mprls0025pa" }, - { } -}; -MODULE_DEVICE_TABLE(i2c, mpr_id); - -static struct i2c_driver mpr_driver = { - .probe = mpr_probe, - .id_table = mpr_id, - .driver = { - .name = "mprls0025pa", - .of_match_table = mpr_matches, - }, -}; -module_i2c_driver(mpr_driver); +EXPORT_SYMBOL_NS(mpr_common_probe, IIO_HONEYWELL_MPRLS0025PA); MODULE_AUTHOR("Andreas Klinger "); -MODULE_DESCRIPTION("Honeywell MPRLS0025PA I2C driver"); +MODULE_DESCRIPTION("Honeywell MPR pressure sensor core driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/pressure/mprls0025pa.h b/drivers/iio/pressure/mprls0025pa.h new file mode 100644 index 000000000000..9d5c30afa9d6 --- /dev/null +++ b/drivers/iio/pressure/mprls0025pa.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver + * + * Copyright (c) Andreas Klinger + * + * Data sheet: + * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf + */ + +#ifndef _MPRLS0025PA_H +#define _MPRLS0025PA_H + +#include +#include +#include +#include +#include +#include + +#include + +#define MPR_MEASUREMENT_RD_SIZE 4 +#define MPR_CMD_NOP 0xf0 +#define MPR_CMD_SYNC 0xaa +#define MPR_PKT_NOP_LEN MPR_MEASUREMENT_RD_SIZE +#define MPR_PKT_SYNC_LEN 3 + +struct device; + +struct iio_chan_spec; +struct iio_dev; + +struct mpr_data; +struct mpr_ops; + +/** + * struct mpr_chan + * @pres: pressure value + * @ts: timestamp + */ +struct mpr_chan { + s32 pres; + s64 ts; +}; + +enum mpr_func_id { + MPR_FUNCTION_A, + MPR_FUNCTION_B, + MPR_FUNCTION_C, +}; + +/** + * struct mpr_data + * @dev: current device structure + * @ops: functions that implement the sensor reads/writes, bus init + * @lock: access to device during read + * @pmin: minimal pressure in pascal + * @pmax: maximal pressure in pascal + * @function: transfer function + * @outmin: minimum raw pressure in counts (based on transfer function) + * @outmax: maximum raw pressure in counts (based on transfer function) + * @scale: pressure scale + * @scale2: pressure scale, decimal number + * @offset: pressure offset + * @offset2: pressure offset, decimal number + * @gpiod_reset: reset + * @irq: end of conversion irq. used to distinguish between irq mode and + * reading in a loop until data is ready + * @completion: handshake from irq to read + * @chan: channel values for buffered mode + * @buffer: raw conversion data + */ +struct mpr_data { + struct device *dev; + const struct mpr_ops *ops; + struct mutex lock; + u32 pmin; + u32 pmax; + enum mpr_func_id function; + u32 outmin; + u32 outmax; + int scale; + int scale2; + int offset; + int offset2; + struct gpio_desc *gpiod_reset; + int irq; + struct completion completion; + struct mpr_chan chan; + u8 buffer[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); +}; + +struct mpr_ops { + int (*init)(struct device *dev); + int (*read)(struct mpr_data *data, const u8 cmd, const u8 cnt); + int (*write)(struct mpr_data *data, const u8 cmd, const u8 cnt); +}; + +int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq); + +#endif diff --git a/drivers/iio/pressure/mprls0025pa_i2c.c b/drivers/iio/pressure/mprls0025pa_i2c.c new file mode 100644 index 000000000000..7a5c5aa2b456 --- /dev/null +++ b/drivers/iio/pressure/mprls0025pa_i2c.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver + * + * Copyright (c) Andreas Klinger + * + * Data sheet: + * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf + */ + +#include +#include +#include +#include +#include +#include + +#include "mprls0025pa.h" + +static int mpr_i2c_init(struct device *unused) +{ + return 0; +} + +static int mpr_i2c_read(struct mpr_data *data, const u8 unused, const u8 cnt) +{ + int ret; + struct i2c_client *client = to_i2c_client(data->dev); + + if (cnt > MPR_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + memset(data->buffer, 0, MPR_MEASUREMENT_RD_SIZE); + ret = i2c_master_recv(client, data->buffer, cnt); + if (ret < 0) + return ret; + else if (ret != cnt) + return -EIO; + + return 0; +} + +static int mpr_i2c_write(struct mpr_data *data, const u8 cmd, const u8 unused) +{ + int ret; + struct i2c_client *client = to_i2c_client(data->dev); + u8 wdata[MPR_PKT_SYNC_LEN]; + + memset(wdata, 0, sizeof(wdata)); + wdata[0] = cmd; + + ret = i2c_master_send(client, wdata, MPR_PKT_SYNC_LEN); + if (ret < 0) + return ret; + else if (ret != MPR_PKT_SYNC_LEN) + return -EIO; + + return 0; +} + +static const struct mpr_ops mpr_i2c_ops = { + .init = mpr_i2c_init, + .read = mpr_i2c_read, + .write = mpr_i2c_write, +}; + +static int mpr_i2c_probe(struct i2c_client *client) +{ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) + return -EOPNOTSUPP; + + return mpr_common_probe(&client->dev, &mpr_i2c_ops, client->irq); +} + +static const struct of_device_id mpr_i2c_match[] = { + { .compatible = "honeywell,mprls0025pa" }, + {} +}; +MODULE_DEVICE_TABLE(of, mpr_i2c_match); + +static const struct i2c_device_id mpr_i2c_id[] = { + { "mprls0025pa" }, + {} +}; +MODULE_DEVICE_TABLE(i2c, mpr_i2c_id); + +static struct i2c_driver mpr_i2c_driver = { + .probe = mpr_i2c_probe, + .id_table = mpr_i2c_id, + .driver = { + .name = "mprls0025pa", + .of_match_table = mpr_i2c_match, + }, +}; +module_i2c_driver(mpr_i2c_driver); + +MODULE_AUTHOR("Andreas Klinger "); +MODULE_DESCRIPTION("Honeywell MPR pressure sensor i2c driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_HONEYWELL_MPRLS0025PA); -- cgit v1.2.3 From d8fd0449e2208407a2f4b191b6d4161203c50f0c Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:37 +0200 Subject: iio: pressure: mprls0025pa add triplet property Add honeywell,pressure-triplet property that automatically initializes pmin-pascal, pmax-pascal so that the user is not required to look-up the chip in the datasheet and convert various units to pascals himself. Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-10-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mprls0025pa.c | 105 ++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index ce20cf362fac..33a15d4c642c 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -80,6 +80,78 @@ static const struct mpr_func_spec mpr_func_spec[] = { [MPR_FUNCTION_C] = { .output_min = 3355443, .output_max = 13421773 }, }; +enum mpr_variants { + MPR0001BA = 0x00, MPR01_6BA = 0x01, MPR02_5BA = 0x02, MPR0060MG = 0x03, + MPR0100MG = 0x04, MPR0160MG = 0x05, MPR0250MG = 0x06, MPR0400MG = 0x07, + MPR0600MG = 0x08, MPR0001BG = 0x09, MPR01_6BG = 0x0a, MPR02_5BG = 0x0b, + MPR0100KA = 0x0c, MPR0160KA = 0x0d, MPR0250KA = 0x0e, MPR0006KG = 0x0f, + MPR0010KG = 0x10, MPR0016KG = 0x11, MPR0025KG = 0x12, MPR0040KG = 0x13, + MPR0060KG = 0x14, MPR0100KG = 0x15, MPR0160KG = 0x16, MPR0250KG = 0x17, + MPR0015PA = 0x18, MPR0025PA = 0x19, MPR0030PA = 0x1a, MPR0001PG = 0x1b, + MPR0005PG = 0x1c, MPR0015PG = 0x1d, MPR0030PG = 0x1e, MPR0300YG = 0x1f, + MPR_VARIANTS_MAX +}; + +static const char * const mpr_triplet_variants[MPR_VARIANTS_MAX] = { + [MPR0001BA] = "0001BA", [MPR01_6BA] = "01.6BA", [MPR02_5BA] = "02.5BA", + [MPR0060MG] = "0060MG", [MPR0100MG] = "0100MG", [MPR0160MG] = "0160MG", + [MPR0250MG] = "0250MG", [MPR0400MG] = "0400MG", [MPR0600MG] = "0600MG", + [MPR0001BG] = "0001BG", [MPR01_6BG] = "01.6BG", [MPR02_5BG] = "02.5BG", + [MPR0100KA] = "0100KA", [MPR0160KA] = "0160KA", [MPR0250KA] = "0250KA", + [MPR0006KG] = "0006KG", [MPR0010KG] = "0010KG", [MPR0016KG] = "0016KG", + [MPR0025KG] = "0025KG", [MPR0040KG] = "0040KG", [MPR0060KG] = "0060KG", + [MPR0100KG] = "0100KG", [MPR0160KG] = "0160KG", [MPR0250KG] = "0250KG", + [MPR0015PA] = "0015PA", [MPR0025PA] = "0025PA", [MPR0030PA] = "0030PA", + [MPR0001PG] = "0001PG", [MPR0005PG] = "0005PG", [MPR0015PG] = "0015PG", + [MPR0030PG] = "0030PG", [MPR0300YG] = "0300YG" +}; + +/** + * struct mpr_range_config - list of pressure ranges based on nomenclature + * @pmin: lowest pressure that can be measured + * @pmax: highest pressure that can be measured + */ +struct mpr_range_config { + const s32 pmin; + const s32 pmax; +}; + +/* All min max limits have been converted to pascals */ +static const struct mpr_range_config mpr_range_config[MPR_VARIANTS_MAX] = { + [MPR0001BA] = { .pmin = 0, .pmax = 100000 }, + [MPR01_6BA] = { .pmin = 0, .pmax = 160000 }, + [MPR02_5BA] = { .pmin = 0, .pmax = 250000 }, + [MPR0060MG] = { .pmin = 0, .pmax = 6000 }, + [MPR0100MG] = { .pmin = 0, .pmax = 10000 }, + [MPR0160MG] = { .pmin = 0, .pmax = 16000 }, + [MPR0250MG] = { .pmin = 0, .pmax = 25000 }, + [MPR0400MG] = { .pmin = 0, .pmax = 40000 }, + [MPR0600MG] = { .pmin = 0, .pmax = 60000 }, + [MPR0001BG] = { .pmin = 0, .pmax = 100000 }, + [MPR01_6BG] = { .pmin = 0, .pmax = 160000 }, + [MPR02_5BG] = { .pmin = 0, .pmax = 250000 }, + [MPR0100KA] = { .pmin = 0, .pmax = 100000 }, + [MPR0160KA] = { .pmin = 0, .pmax = 160000 }, + [MPR0250KA] = { .pmin = 0, .pmax = 250000 }, + [MPR0006KG] = { .pmin = 0, .pmax = 6000 }, + [MPR0010KG] = { .pmin = 0, .pmax = 10000 }, + [MPR0016KG] = { .pmin = 0, .pmax = 16000 }, + [MPR0025KG] = { .pmin = 0, .pmax = 25000 }, + [MPR0040KG] = { .pmin = 0, .pmax = 40000 }, + [MPR0060KG] = { .pmin = 0, .pmax = 60000 }, + [MPR0100KG] = { .pmin = 0, .pmax = 100000 }, + [MPR0160KG] = { .pmin = 0, .pmax = 160000 }, + [MPR0250KG] = { .pmin = 0, .pmax = 250000 }, + [MPR0015PA] = { .pmin = 0, .pmax = 103421 }, + [MPR0025PA] = { .pmin = 0, .pmax = 172369 }, + [MPR0030PA] = { .pmin = 0, .pmax = 206843 }, + [MPR0001PG] = { .pmin = 0, .pmax = 6895 }, + [MPR0005PG] = { .pmin = 0, .pmax = 34474 }, + [MPR0015PG] = { .pmin = 0, .pmax = 103421 }, + [MPR0030PG] = { .pmin = 0, .pmax = 206843 }, + [MPR0300YG] = { .pmin = 0, .pmax = 39997 } +}; + static const struct iio_chan_spec mpr_channels[] = { { .type = IIO_PRESSURE, @@ -257,6 +329,7 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) int ret; struct mpr_data *data; struct iio_dev *indio_dev; + const char *triplet; s64 scale, offset; u32 func; @@ -298,16 +371,32 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) "honeywell,transfer-function %d invalid\n", data->function); - ret = device_property_read_u32(dev, "honeywell,pmin-pascal", - &data->pmin); - if (ret) - return dev_err_probe(dev, ret, + ret = device_property_read_string(dev, "honeywell,pressure-triplet", + &triplet); + if (ret) { + ret = device_property_read_u32(dev, "honeywell,pmin-pascal", + &data->pmin); + if (ret) + return dev_err_probe(dev, ret, "honeywell,pmin-pascal could not be read\n"); - ret = device_property_read_u32(dev, "honeywell,pmax-pascal", - &data->pmax); - if (ret) - return dev_err_probe(dev, ret, + + ret = device_property_read_u32(dev, "honeywell,pmax-pascal", + &data->pmax); + if (ret) + return dev_err_probe(dev, ret, "honeywell,pmax-pascal could not be read\n"); + } else { + ret = device_property_match_property_string(dev, + "honeywell,pressure-triplet", + mpr_triplet_variants, + MPR_VARIANTS_MAX); + if (ret < 0) + return dev_err_probe(dev, -EINVAL, + "honeywell,pressure-triplet is invalid\n"); + + data->pmin = mpr_range_config[ret].pmin; + data->pmax = mpr_range_config[ret].pmax; + } if (data->pmin >= data->pmax) return dev_err_probe(dev, -EINVAL, -- cgit v1.2.3 From a0858f0cd28e822b91376ae288d5548bc1847531 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:38 +0200 Subject: iio: pressure: mprls0025pa add SPI driver Add SPI component of the driver. Tested-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-11-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Kconfig | 8 ++- drivers/iio/pressure/Makefile | 1 + drivers/iio/pressure/mprls0025pa_spi.c | 92 ++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 drivers/iio/pressure/mprls0025pa_spi.c (limited to 'drivers') diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index f03007cfec85..5da7931dc537 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -181,8 +181,9 @@ config MPL3115 config MPRLS0025PA tristate "Honeywell MPRLS0025PA (MicroPressure sensors series)" - depends on I2C + depends on (I2C || SPI_MASTER) select MPRLS0025PA_I2C if I2C + select MPRLS0025PA_SPI if SPI_MASTER select IIO_BUFFER select IIO_TRIGGERED_BUFFER help @@ -198,6 +199,11 @@ config MPRLS0025PA_I2C depends on MPRLS0025PA depends on I2C +config MPRLS0025PA_SPI + tristate + depends on MPRLS0025PA + depends on SPI_MASTER + config MS5611 tristate "Measurement Specialties MS5611 pressure sensor driver" select IIO_BUFFER diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 7754135e190c..a93709e35760 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_MPL115_SPI) += mpl115_spi.o obj-$(CONFIG_MPL3115) += mpl3115.o obj-$(CONFIG_MPRLS0025PA) += mprls0025pa.o obj-$(CONFIG_MPRLS0025PA_I2C) += mprls0025pa_i2c.o +obj-$(CONFIG_MPRLS0025PA_SPI) += mprls0025pa_spi.o obj-$(CONFIG_MS5611) += ms5611_core.o obj-$(CONFIG_MS5611_I2C) += ms5611_i2c.o obj-$(CONFIG_MS5611_SPI) += ms5611_spi.o diff --git a/drivers/iio/pressure/mprls0025pa_spi.c b/drivers/iio/pressure/mprls0025pa_spi.c new file mode 100644 index 000000000000..3aed14cd95c5 --- /dev/null +++ b/drivers/iio/pressure/mprls0025pa_spi.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MPRLS0025PA - Honeywell MicroPressure MPR series SPI sensor driver + * + * Copyright (c) 2024 Petre Rodan + * + * Data sheet: + * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mprls0025pa.h" + +struct mpr_spi_buf { + u8 tx[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); +}; + +static int mpr_spi_init(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct mpr_spi_buf *buf; + + buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + spi_set_drvdata(spi, buf); + + return 0; +} + +static int mpr_spi_xfer(struct mpr_data *data, const u8 cmd, const u8 pkt_len) +{ + struct spi_device *spi = to_spi_device(data->dev); + struct mpr_spi_buf *buf = spi_get_drvdata(spi); + struct spi_transfer xfer; + + if (pkt_len > MPR_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + buf->tx[0] = cmd; + xfer.tx_buf = buf->tx; + xfer.rx_buf = data->buffer; + xfer.len = pkt_len; + + return spi_sync_transfer(spi, &xfer, 1); +} + +static const struct mpr_ops mpr_spi_ops = { + .init = mpr_spi_init, + .read = mpr_spi_xfer, + .write = mpr_spi_xfer, +}; + +static int mpr_spi_probe(struct spi_device *spi) +{ + return mpr_common_probe(&spi->dev, &mpr_spi_ops, spi->irq); +} + +static const struct of_device_id mpr_spi_match[] = { + { .compatible = "honeywell,mprls0025pa" }, + {} +}; +MODULE_DEVICE_TABLE(of, mpr_spi_match); + +static const struct spi_device_id mpr_spi_id[] = { + { "mprls0025pa" }, + {} +}; +MODULE_DEVICE_TABLE(spi, mpr_spi_id); + +static struct spi_driver mpr_spi_driver = { + .driver = { + .name = "mprls0025pa", + .of_match_table = mpr_spi_match, + }, + .probe = mpr_spi_probe, + .id_table = mpr_spi_id, +}; +module_spi_driver(mpr_spi_driver); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell MPR pressure sensor spi driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_HONEYWELL_MPRLS0025PA); -- cgit v1.2.3 From e91847646081a4096173d43481577939ad054e88 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 31 Dec 2023 18:34:51 +0000 Subject: iio: accel: da280: Stop using ACPI_PTR() In general using ACPI_PTR() leads to more fragile code for a very minor saving in storage in the case of !CONFIG_ACPI so in IIO we prefer not to use it if the only ACPI specific code is the acpi_device_id table. In this case will also suppress a unused variable warning. Reported-by: kernel test robot Link: https://lore.kernel.org/oe-kbuild-all/202302142222.vVU0E4eu-lkp@intel.com/ Cc: Hans de Goede Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20231231183514.566609-2-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/da280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c index 756e2ea7c056..992286828844 100644 --- a/drivers/iio/accel/da280.c +++ b/drivers/iio/accel/da280.c @@ -172,7 +172,7 @@ MODULE_DEVICE_TABLE(i2c, da280_i2c_id); static struct i2c_driver da280_driver = { .driver = { .name = "da280", - .acpi_match_table = ACPI_PTR(da280_acpi_match), + .acpi_match_table = da280_acpi_match, .pm = pm_sleep_ptr(&da280_pm_ops), }, .probe = da280_probe, -- cgit v1.2.3 From ab3764c77560a8cd1b2b22500494a7951f277522 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 31 Dec 2023 18:34:52 +0000 Subject: iio: accel: kxcjk-1013: Move acpi_device_id table under ifdef CONFIG_ACPI This avoids a build warning due to the use of ACPI_PTR(). Given the driver already has APCI specific code under CONFIG_ACPI move the table rather than removing the ACPI_PTR() call as we already have the complexity of CONFIG_ACPI. Dropped a pointless comma after {} terminator whilst moving the code. Cc: Hans de Goede Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20231231183514.566609-3-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 894709286b0c..c5f5b1ce7954 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -422,6 +422,23 @@ static int kiox010a_dsm(struct device *dev, int fn_index) ACPI_FREE(obj); return 0; } + +static const struct acpi_device_id kx_acpi_match[] = { + {"KXCJ1013", KXCJK1013}, + {"KXCJ1008", KXCJ91008}, + {"KXCJ9000", KXCJ91008}, + {"KIOX0008", KXCJ91008}, + {"KIOX0009", KXTJ21009}, + {"KIOX000A", KXCJ91008}, + {"KIOX010A", KXCJ91008}, /* KXCJ91008 in the display of a yoga 2-in-1 */ + {"KIOX020A", KXCJ91008}, /* KXCJ91008 in the base of a yoga 2-in-1 */ + {"KXTJ1009", KXTJ21009}, + {"KXJ2109", KXTJ21009}, + {"SMO8500", KXCJ91008}, + { } +}; +MODULE_DEVICE_TABLE(acpi, kx_acpi_match); + #endif static int kxcjk1013_set_mode(struct kxcjk1013_data *data, @@ -1687,22 +1704,6 @@ static const struct dev_pm_ops kxcjk1013_pm_ops = { kxcjk1013_runtime_resume, NULL) }; -static const struct acpi_device_id kx_acpi_match[] = { - {"KXCJ1013", KXCJK1013}, - {"KXCJ1008", KXCJ91008}, - {"KXCJ9000", KXCJ91008}, - {"KIOX0008", KXCJ91008}, - {"KIOX0009", KXTJ21009}, - {"KIOX000A", KXCJ91008}, - {"KIOX010A", KXCJ91008}, /* KXCJ91008 in the display of a yoga 2-in-1 */ - {"KIOX020A", KXCJ91008}, /* KXCJ91008 in the base of a yoga 2-in-1 */ - {"KXTJ1009", KXTJ21009}, - {"KXJ2109", KXTJ21009}, - {"SMO8500", KXCJ91008}, - { }, -}; -MODULE_DEVICE_TABLE(acpi, kx_acpi_match); - static const struct i2c_device_id kxcjk1013_id[] = { {"kxcjk1013", KXCJK1013}, {"kxcj91008", KXCJ91008}, -- cgit v1.2.3 From 9b397c11e04adb86b8bbf2bd969ef6fad005f1ab Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 31 Dec 2023 18:34:53 +0000 Subject: iio: accel: mma9551: Drop ACPI_PTR() usage Avoiding unused variable warnings when using this macro adds complexity that in simple cases like this one is not justified for the small saving in data. Whilst here tidy up a trivial bit of unusual indentation. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20231231183514.566609-4-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9551.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index d823f2edc6d4..083c08f65baf 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -604,9 +604,9 @@ MODULE_DEVICE_TABLE(i2c, mma9551_id); static struct i2c_driver mma9551_driver = { .driver = { .name = MMA9551_DRV_NAME, - .acpi_match_table = ACPI_PTR(mma9551_acpi_match), + .acpi_match_table = mma9551_acpi_match, .pm = pm_ptr(&mma9551_pm_ops), - }, + }, .probe = mma9551_probe, .remove = mma9551_remove, .id_table = mma9551_id, -- cgit v1.2.3 From 3572c3700ebd4e73da0ac236f573e53294414d31 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 31 Dec 2023 18:34:54 +0000 Subject: iio: accel: mma9553: Drop ACPI_PTR() usage Avoiding unused variable warnings when using this macro adds complexity that in simple cases like this one is not justified for the small saving in data. Whilst here tidy up a trivial bit of unusual indentation. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20231231183514.566609-5-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9553.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index d01aba4aecba..3cbd0fd4e624 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -1243,9 +1243,9 @@ MODULE_DEVICE_TABLE(i2c, mma9553_id); static struct i2c_driver mma9553_driver = { .driver = { .name = MMA9553_DRV_NAME, - .acpi_match_table = ACPI_PTR(mma9553_acpi_match), + .acpi_match_table = mma9553_acpi_match, .pm = pm_ptr(&mma9553_pm_ops), - }, + }, .probe = mma9553_probe, .remove = mma9553_remove, .id_table = mma9553_id, -- cgit v1.2.3 From a55c3fec3bf6710b0f43252c4954d2df3ecd48a6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 31 Dec 2023 18:34:55 +0000 Subject: iio: accel: mxc4005: Drop ACPI_PTR() usage Avoiding unused variable warnings when using this macro adds complexity that in simple cases like this one is not justified for the small saving in data. Switch include to mod_devicetable.h as that contains the only ACPI specif