From cbf73ae59bee340f423479eb48aef9a0efdd8010 Mon Sep 17 00:00:00 2001 From: Martin Kelly Date: Tue, 1 May 2018 10:56:42 -0700 Subject: [PATCH 01/42] iio: imu: inv_mpu6050: make loop a do-while Prior to this loop, we check if fifo_count < bytes_per_datum and bail if so. This means that when we hit the loop, we know that fifo_count >= bytes_per_datum, so the check is unneeded and we can turn the loop into a do-while for a slight performance improvement. Signed-off-by: Martin Kelly Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 97d965181635..1795418438e4 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -175,7 +175,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) if (kfifo_len(&st->timestamps) > fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR) goto flush_fifo; - while (fifo_count >= bytes_per_datum) { + do { result = regmap_bulk_read(st->map, st->reg->fifo_r_w, data, bytes_per_datum); if (result) @@ -194,7 +194,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) timestamp); fifo_count -= bytes_per_datum; - } + } while (fifo_count >= bytes_per_datum); end_session: mutex_unlock(&st->lock); From e2fad7450306df281d21111620124954d4cb2cd9 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 2 May 2018 15:05:23 +0200 Subject: [PATCH 02/42] iio: adc: stm32-dfsdm: Add support for stm32mp1 Add support for DFSDM (Digital Filter For Sigma Delta Modulators) to STM32MP1. This variant is close to STM32H7 DFSDM, it implements 6 filter instances. Registers map is also increased. Signed-off-by: Fabrice Gasnier Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/st,stm32-dfsdm-adc.txt | 7 +++++-- drivers/iio/adc/stm32-dfsdm-core.c | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt index ed7520d1d051..75ba25d062e1 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt @@ -8,14 +8,16 @@ It is mainly targeted for: - PDM microphones (audio digital microphone) It features up to 8 serial digital interfaces (SPI or Manchester) and -up to 4 filters on stm32h7. +up to 4 filters on stm32h7 or 6 filters on stm32mp1. Each child node match with a filter instance. Contents of a STM32 DFSDM root node: ------------------------------------ Required properties: -- compatible: Should be "st,stm32h7-dfsdm". +- compatible: Should be one of: + "st,stm32h7-dfsdm" + "st,stm32mp1-dfsdm" - reg: Offset and length of the DFSDM block register set. - clocks: IP and serial interfaces clocking. Should be set according to rcc clock ID and "clock-names". @@ -45,6 +47,7 @@ Required properties: "st,stm32-dfsdm-adc" for sigma delta ADCs "st,stm32-dfsdm-dmic" for audio digital microphone. - reg: Specifies the DFSDM filter instance used. + Valid values are from 0 to 3 on stm32h7, 0 to 5 on stm32mp1. - interrupts: IRQ lines connected to each DFSDM filter instance. - st,adc-channels: List of single-ended channels muxed for this ADC. valid values: diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index 1d0d8238d9b5..bf089f5d6225 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -25,6 +25,8 @@ struct stm32_dfsdm_dev_data { #define STM32H7_DFSDM_NUM_FILTERS 4 #define STM32H7_DFSDM_NUM_CHANNELS 8 +#define STM32MP1_DFSDM_NUM_FILTERS 6 +#define STM32MP1_DFSDM_NUM_CHANNELS 8 static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg) { @@ -61,6 +63,21 @@ static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_data = { .regmap_cfg = &stm32h7_dfsdm_regmap_cfg, }; +static const struct regmap_config stm32mp1_dfsdm_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = sizeof(u32), + .max_register = 0x7fc, + .volatile_reg = stm32_dfsdm_volatile_reg, + .fast_io = true, +}; + +static const struct stm32_dfsdm_dev_data stm32mp1_dfsdm_data = { + .num_filters = STM32MP1_DFSDM_NUM_FILTERS, + .num_channels = STM32MP1_DFSDM_NUM_CHANNELS, + .regmap_cfg = &stm32mp1_dfsdm_regmap_cfg, +}; + struct dfsdm_priv { struct platform_device *pdev; /* platform device */ @@ -248,6 +265,10 @@ static const struct of_device_id stm32_dfsdm_of_match[] = { .compatible = "st,stm32h7-dfsdm", .data = &stm32h7_dfsdm_data, }, + { + .compatible = "st,stm32mp1-dfsdm", + .data = &stm32mp1_dfsdm_data, + }, {} }; MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match); From 3345d4702329a4f5760f4c8100da391e07eb878d Mon Sep 17 00:00:00 2001 From: Richard Tresidder Date: Tue, 8 May 2018 15:59:54 +0800 Subject: [PATCH 03/42] iio: magnetometer: mag3110: Add ability to run in continuous mode Adds the ability to run the Mag3110 in continuous mode to speed up the sampling rate. Depending on the sampling rate requested the device can be put in or out of continuous mode automatically. Shifting out of continuous mode requires a potential 1 / ODR wait which is also implemented. Modified the sleep method when data is not ready to allow for sampling > 50sps to work. Signed-off-by: Richard Tresidder Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/mag3110.c | 158 +++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 18 deletions(-) diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index b34ace76d31b..f063355480ba 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -26,6 +26,7 @@ #define MAG3110_OUT_Y 0x03 #define MAG3110_OUT_Z 0x05 #define MAG3110_WHO_AM_I 0x07 +#define MAG3110_SYSMOD 0x08 #define MAG3110_OFF_X 0x09 /* MSB first */ #define MAG3110_OFF_Y 0x0b #define MAG3110_OFF_Z 0x0d @@ -39,6 +40,8 @@ #define MAG3110_CTRL_DR_SHIFT 5 #define MAG3110_CTRL_DR_DEFAULT 0 +#define MAG3110_SYSMOD_MODE_MASK GENMASK(1, 0) + #define MAG3110_CTRL_TM BIT(1) /* trigger single measurement */ #define MAG3110_CTRL_AC BIT(0) /* continuous measurements */ @@ -52,17 +55,20 @@ struct mag3110_data { struct i2c_client *client; struct mutex lock; u8 ctrl_reg1; + int sleep_val; }; static int mag3110_request(struct mag3110_data *data) { int ret, tries = 150; - /* trigger measurement */ - ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, - data->ctrl_reg1 | MAG3110_CTRL_TM); - if (ret < 0) - return ret; + if ((data->ctrl_reg1 & MAG3110_CTRL_AC) == 0) { + /* trigger measurement */ + ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, + data->ctrl_reg1 | MAG3110_CTRL_TM); + if (ret < 0) + return ret; + } while (tries-- > 0) { ret = i2c_smbus_read_byte_data(data->client, MAG3110_STATUS); @@ -71,7 +77,11 @@ static int mag3110_request(struct mag3110_data *data) /* wait for data ready */ if ((ret & MAG3110_STATUS_DRDY) == MAG3110_STATUS_DRDY) break; - msleep(20); + + if (data->sleep_val <= 20) + usleep_range(data->sleep_val * 250, data->sleep_val * 500); + else + msleep(20); } if (tries < 0) { @@ -144,6 +154,117 @@ static int mag3110_get_samp_freq_index(struct mag3110_data *data, val2); } +static int mag3110_calculate_sleep(struct mag3110_data *data) +{ + int ret, i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT; + + if (mag3110_samp_freq[i][0] > 0) + ret = 1000 / mag3110_samp_freq[i][0]; + else + ret = 1000; + + return ret == 0 ? 1 : ret; +} + +static int mag3110_standby(struct mag3110_data *data) +{ + return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, + data->ctrl_reg1 & ~MAG3110_CTRL_AC); +} + +static int mag3110_wait_standby(struct mag3110_data *data) +{ + int ret, tries = 30; + + /* + * Takes up to 1/ODR to come out of active mode into stby + * Longest expected period is 12.5seconds. + * We'll sleep for 500ms between checks + */ + while (tries-- > 0) { + ret = i2c_smbus_read_byte_data(data->client, MAG3110_SYSMOD); + if (ret < 0) { + dev_err(&data->client->dev, "i2c error\n"); + return ret; + } + /* wait for standby */ + if ((ret & MAG3110_SYSMOD_MODE_MASK) == 0) + break; + + msleep_interruptible(500); + } + + if (tries < 0) { + dev_err(&data->client->dev, "device not entering standby mode\n"); + return -EIO; + } + + return 0; +} + +static int mag3110_active(struct mag3110_data *data) +{ + return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, + data->ctrl_reg1); +} + +/* returns >0 if active, 0 if in standby and <0 on error */ +static int mag3110_is_active(struct mag3110_data *data) +{ + int reg; + + reg = i2c_smbus_read_byte_data(data->client, MAG3110_CTRL_REG1); + if (reg < 0) + return reg; + + return reg & MAG3110_CTRL_AC; +} + +static int mag3110_change_config(struct mag3110_data *data, u8 reg, u8 val) +{ + int ret; + int is_active; + + mutex_lock(&data->lock); + + is_active = mag3110_is_active(data); + if (is_active < 0) { + ret = is_active; + goto fail; + } + + /* config can only be changed when in standby */ + if (is_active > 0) { + ret = mag3110_standby(data); + if (ret < 0) + goto fail; + } + + /* + * After coming out of active we must wait for the part + * to transition to STBY. This can take up to 1 /ODR to occur + */ + ret = mag3110_wait_standby(data); + if (ret < 0) + goto fail; + + ret = i2c_smbus_write_byte_data(data->client, reg, val); + if (ret < 0) + goto fail; + + if (is_active > 0) { + ret = mag3110_active(data); + if (ret < 0) + goto fail; + } + + ret = 0; +fail: + mutex_unlock(&data->lock); + + return ret; +} + static int mag3110_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -235,11 +356,15 @@ static int mag3110_write_raw(struct iio_dev *indio_dev, ret = -EINVAL; break; } - - data->ctrl_reg1 &= ~MAG3110_CTRL_DR_MASK; + data->ctrl_reg1 &= 0xff & ~MAG3110_CTRL_DR_MASK + & ~MAG3110_CTRL_AC; data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT; - ret = i2c_smbus_write_byte_data(data->client, - MAG3110_CTRL_REG1, data->ctrl_reg1); + data->sleep_val = mag3110_calculate_sleep(data); + if (data->sleep_val < 40) + data->ctrl_reg1 |= MAG3110_CTRL_AC; + + ret = mag3110_change_config(data, MAG3110_CTRL_REG1, + data->ctrl_reg1); break; case IIO_CHAN_INFO_CALIBBIAS: if (val < -10000 || val > 10000) { @@ -337,12 +462,6 @@ static const struct iio_info mag3110_info = { static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0}; -static int mag3110_standby(struct mag3110_data *data) -{ - return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1, - data->ctrl_reg1 & ~MAG3110_CTRL_AC); -} - static int mag3110_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -374,8 +493,11 @@ static int mag3110_probe(struct i2c_client *client, indio_dev->available_scan_masks = mag3110_scan_masks; data->ctrl_reg1 = MAG3110_CTRL_DR_DEFAULT << MAG3110_CTRL_DR_SHIFT; - ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG1, - data->ctrl_reg1); + data->sleep_val = mag3110_calculate_sleep(data); + if (data->sleep_val < 40) + data->ctrl_reg1 |= MAG3110_CTRL_AC; + + ret = mag3110_change_config(data, MAG3110_CTRL_REG1, data->ctrl_reg1); if (ret < 0) return ret; From 0cb2aab8f820cfc764d18b9a2ee55f4a6003f782 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Mon, 7 May 2018 22:34:01 -0700 Subject: [PATCH 04/42] iio: potentiostat: lmp91000: add LMP91002 support LMP91002 is register compatible so add devicetree and i2c client ids Signed-off-by: Matt Ranostay Reviewed-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/potentiostat/lmp91000.txt | 9 ++++++--- drivers/iio/potentiostat/lmp91000.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/potentiostat/lmp91000.txt b/Documentation/devicetree/bindings/iio/potentiostat/lmp91000.txt index b9b621e94cd7..e6d0c2eb345c 100644 --- a/Documentation/devicetree/bindings/iio/potentiostat/lmp91000.txt +++ b/Documentation/devicetree/bindings/iio/potentiostat/lmp91000.txt @@ -1,10 +1,13 @@ -* Texas Instruments LMP91000 potentiostat +* Texas Instruments LMP91000 series of potentiostats -http://www.ti.com/lit/ds/symlink/lmp91000.pdf +LMP91000: http://www.ti.com/lit/ds/symlink/lmp91000.pdf +LMP91002: http://www.ti.com/lit/ds/symlink/lmp91002.pdf Required properties: - - compatible: should be "ti,lmp91000" + - compatible: should be one of the following: + "ti,lmp91000" + "ti,lmp91002" - reg: the I2C address of the device - io-channels: the phandle of the iio provider diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index 85714055cc74..90e895adf997 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -411,12 +411,14 @@ static int lmp91000_remove(struct i2c_client *client) static const struct of_device_id lmp91000_of_match[] = { { .compatible = "ti,lmp91000", }, + { .compatible = "ti,lmp91002", }, { }, }; MODULE_DEVICE_TABLE(of, lmp91000_of_match); static const struct i2c_device_id lmp91000_id[] = { { "lmp91000", 0 }, + { "lmp91002", 0 }, {} }; MODULE_DEVICE_TABLE(i2c, lmp91000_id); From 2a86487786b5c9ce7bee21efc9ce196bb7fe0aed Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Wed, 9 May 2018 20:17:18 +0200 Subject: [PATCH 05/42] iio: adc: ti-ads8688: add trigger and buffer support Signed-off-by: Sean Nyekjaer Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads8688.c | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 079f133144b0..184d686ebd99 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -17,6 +17,9 @@ #include #include +#include +#include +#include #include #define ADS8688_CMD_REG(x) (x << 8) @@ -155,6 +158,13 @@ static const struct attribute_group ads8688_attribute_group = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ | BIT(IIO_CHAN_INFO_SCALE) \ | BIT(IIO_CHAN_INFO_OFFSET), \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ } static const struct iio_chan_spec ads8684_channels[] = { @@ -371,6 +381,28 @@ static const struct iio_info ads8688_info = { .attrs = &ads8688_attribute_group, }; +static irqreturn_t ads8688_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + u16 buffer[8]; + int i, j = 0; + + for (i = 0; i < indio_dev->masklength; i++) { + if (!test_bit(i, indio_dev->active_scan_mask)) + continue; + buffer[j] = ads8688_read(indio_dev, i); + j++; + } + + iio_push_to_buffers_with_timestamp(indio_dev, buffer, + pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + static const struct ads8688_chip_info ads8688_chip_info_tbl[] = { [ID_ADS8684] = { .channels = ads8684_channels, @@ -402,7 +434,7 @@ static int ads8688_probe(struct spi_device *spi) ret = regulator_get_voltage(st->reg); if (ret < 0) - goto error_out; + goto err_regulator_disable; st->vref_mv = ret / 1000; } else { @@ -430,13 +462,22 @@ static int ads8688_probe(struct spi_device *spi) mutex_init(&st->lock); + ret = iio_triggered_buffer_setup(indio_dev, NULL, ads8688_trigger_handler, NULL); + if (ret < 0) { + dev_err(&spi->dev, "iio triggered buffer setup failed\n"); + goto err_regulator_disable; + } + ret = iio_device_register(indio_dev); if (ret) - goto error_out; + goto err_buffer_cleanup; return 0; -error_out: +err_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + +err_regulator_disable: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -449,6 +490,7 @@ static int ads8688_remove(struct spi_device *spi) struct ads8688_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); if (!IS_ERR(st->reg)) regulator_disable(st->reg); From a45d123887044622fa08b1a48e68c7db58f84b3b Mon Sep 17 00:00:00 2001 From: Richard Tresidder Date: Fri, 11 May 2018 16:54:59 +0800 Subject: [PATCH 06/42] iio: accell: mma8452: Reduce sleep time when data not ready Modified the sleep method when data is not ready to allow for sampling > 50sps to work. Signed-off-by: Richard Tresidder Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 7a2da7f9d4dc..7e3d82cff3d5 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -106,6 +106,7 @@ struct mma8452_data { u8 ctrl_reg1; u8 data_cfg; const struct mma_chip_info *chip_info; + int sleep_val; }; /** @@ -193,7 +194,11 @@ static int mma8452_drdy(struct mma8452_data *data) if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY) return 0; - msleep(20); + if (data->sleep_val <= 20) + usleep_range(data->sleep_val * 250, + data->sleep_val * 500); + else + msleep(20); } dev_err(&data->client->dev, "data not ready\n"); @@ -544,6 +549,18 @@ static int mma8452_read_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int mma8452_calculate_sleep(struct mma8452_data *data) +{ + int ret, i = mma8452_get_odr_index(data); + + if (mma8452_samp_freq[i][0] > 0) + ret = 1000 / mma8452_samp_freq[i][0]; + else + ret = 1000; + + return ret == 0 ? 1 : ret; +} + static int mma8452_standby(struct mma8452_data *data) { return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1, @@ -700,6 +717,8 @@ static int mma8452_write_raw(struct iio_dev *indio_dev, data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK; data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT; + data->sleep_val = mma8452_calculate_sleep(data); + ret = mma8452_change_config(data, MMA8452_CTRL_REG1, data->ctrl_reg1); break; @@ -1593,6 +1612,9 @@ static int mma8452_probe(struct i2c_client *client, data->ctrl_reg1 = MMA8452_CTRL_ACTIVE | (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT); + + data->sleep_val = mma8452_calculate_sleep(data); + ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1, data->ctrl_reg1); if (ret < 0) From 5cf05135b0b204cde00418045861f032b74fd072 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:15 -0400 Subject: [PATCH 07/42] staging: iio: tsl2x7x: remove unnecessary whitespace This patch removes unnecessary whitespace in preparation for moving this driver out of staging. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 22 +++++++++++----------- drivers/staging/iio/light/tsl2x7x.h | 1 - 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index cc863e8927f5..3ae2fd19ae9c 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -196,16 +196,16 @@ static const struct tsl2x7x_lux tmd2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = { }; static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = { - [tsl2571] = tsl2x71_lux_table, - [tsl2671] = tsl2x71_lux_table, - [tmd2671] = tmd2x71_lux_table, - [tsl2771] = tsl2x71_lux_table, - [tmd2771] = tmd2x71_lux_table, - [tsl2572] = tsl2x72_lux_table, - [tsl2672] = tsl2x72_lux_table, - [tmd2672] = tmd2x72_lux_table, - [tsl2772] = tsl2x72_lux_table, - [tmd2772] = tmd2x72_lux_table, + [tsl2571] = tsl2x71_lux_table, + [tsl2671] = tsl2x71_lux_table, + [tmd2671] = tmd2x71_lux_table, + [tsl2771] = tsl2x71_lux_table, + [tmd2771] = tmd2x71_lux_table, + [tsl2572] = tsl2x72_lux_table, + [tsl2672] = tsl2x72_lux_table, + [tmd2672] = tmd2x72_lux_table, + [tsl2772] = tsl2x72_lux_table, + [tmd2772] = tmd2x72_lux_table, }; static const struct tsl2x7x_settings tsl2x7x_default_settings = { @@ -1241,7 +1241,7 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - timestamp); + timestamp); } if (ret & TSL2X7X_STA_ALS_INTR) { diff --git a/drivers/staging/iio/light/tsl2x7x.h b/drivers/staging/iio/light/tsl2x7x.h index 1097ee890ce2..db344796fc1b 100644 --- a/drivers/staging/iio/light/tsl2x7x.h +++ b/drivers/staging/iio/light/tsl2x7x.h @@ -92,7 +92,6 @@ struct tsl2x7x_settings { * struct tsl2X7X_platform_data - Platform callback, glass and defaults * @platform_lux_table: Device specific glass coefficents * @platform_default_settings: Device specific power on defaults - * */ struct tsl2X7X_platform_data { struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE]; From 7b4db2e3e64a4a6028ff8cd1682df67df92a3ad4 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:16 -0400 Subject: [PATCH 08/42] staging: iio: tsl2x7x: use direct returns This patch changes the functions tsl2x7x_read_event_value() and tsl2x7x_read_raw() to use direct returns to simplify the code. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 49 ++++++++++------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index 3ae2fd19ae9c..c1e726fc87b7 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -1014,7 +1014,7 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, int *val, int *val2) { struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int ret = -EINVAL, filter_delay, mult; + int filter_delay, mult; u8 time; switch (info) { @@ -1023,27 +1023,23 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, switch (dir) { case IIO_EV_DIR_RISING: *val = chip->settings.als_thresh_high; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_EV_DIR_FALLING: *val = chip->settings.als_thresh_low; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; default: - break; + return -EINVAL; } } else { switch (dir) { case IIO_EV_DIR_RISING: *val = chip->settings.prox_thres_high; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_EV_DIR_FALLING: *val = chip->settings.prox_thres_low; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; default: - break; + return -EINVAL; } } break; @@ -1062,13 +1058,10 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, filter_delay = *val2 * mult; *val = filter_delay / 1000; *val2 = filter_delay % 1000; - ret = IIO_VAL_INT_PLUS_MICRO; - break; + return IIO_VAL_INT_PLUS_MICRO; default: - break; + return -EINVAL; } - - return ret; } static int tsl2x7x_read_raw(struct iio_dev *indio_dev, @@ -1078,7 +1071,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, long mask) { struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int ret = -EINVAL; switch (mask) { case IIO_CHAN_INFO_PROCESSED: @@ -1086,12 +1078,10 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, case IIO_LIGHT: tsl2x7x_get_lux(indio_dev); *val = chip->als_cur_info.lux; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; default: return -EINVAL; } - break; case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_INTENSITY: @@ -1100,13 +1090,11 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, *val = chip->als_cur_info.als_ch0; else *val = chip->als_cur_info.als_ch1; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_PROXIMITY: tsl2x7x_get_prox(indio_dev); *val = chip->prox_data; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; default: return -EINVAL; } @@ -1116,22 +1104,17 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, *val = tsl2x7x_als_gain[chip->settings.als_gain]; else *val = tsl2x7x_prox_gain[chip->settings.prox_gain]; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: *val = chip->settings.als_gain_trim; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: *val = 0; *val2 = (256 - chip->settings.als_time) * 2720; - ret = IIO_VAL_INT_PLUS_MICRO; - break; + return IIO_VAL_INT_PLUS_MICRO; default: - ret = -EINVAL; + return -EINVAL; } - - return ret; } static int tsl2x7x_write_raw(struct iio_dev *indio_dev, From cc566e90cba70966b5c84ac373110d499b8be4ac Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:17 -0400 Subject: [PATCH 09/42] staging: iio: tsl2x7x: turn chip off if IIO device registration fails This patch turns the chip off if IIO device registration fails so that the error handling mirrors the device remove to make review easier in preparation for moving this driver out of staging. This patch also adds a missing error check in the call to tsl2x7x_chip_on() in tsl2x7x_probe(). Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index c1e726fc87b7..f5ca5ada0358 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -1657,10 +1657,13 @@ static int tsl2x7x_probe(struct i2c_client *clientp, } tsl2x7x_defaults(chip); - tsl2x7x_chip_on(indio_dev); + ret = tsl2x7x_chip_on(indio_dev); + if (ret < 0) + return ret; ret = iio_device_register(indio_dev); if (ret) { + tsl2x7x_chip_off(indio_dev); dev_err(&clientp->dev, "%s: iio registration failed\n", __func__); return ret; From bfdf7f1024e535eb66250d9ffea30e599e1e5c5a Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:18 -0400 Subject: [PATCH 10/42] staging: iio: tsl2x7x: use macro to populate tsl2X7X_device_info This patch creates a macro that populates the tsl2X7X_device_info structure to reduce duplicated code in the driver. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 61 ++++++++--------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index f5ca5ada0358..51c1a90cb592 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -1305,52 +1305,23 @@ static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = { }, }; +#define TSL2X7X_DEVICE_INFO(type)[type] = \ + { \ + .attrs = &tsl2X7X_device_attr_group_tbl[type], \ + .read_raw = &tsl2x7x_read_raw, \ + .write_raw = &tsl2x7x_write_raw, \ + .read_event_value = &tsl2x7x_read_event_value, \ + .write_event_value = &tsl2x7x_write_event_value, \ + .read_event_config = &tsl2x7x_read_interrupt_config, \ + .write_event_config = &tsl2x7x_write_interrupt_config, \ + } + static const struct iio_info tsl2X7X_device_info[] = { - [ALS] = { - .attrs = &tsl2X7X_device_attr_group_tbl[ALS], - .read_raw = &tsl2x7x_read_raw, - .write_raw = &tsl2x7x_write_raw, - .read_event_value = &tsl2x7x_read_event_value, - .write_event_value = &tsl2x7x_write_event_value, - .read_event_config = &tsl2x7x_read_interrupt_config, - .write_event_config = &tsl2x7x_write_interrupt_config, - }, - [PRX] = { - .attrs = &tsl2X7X_device_attr_group_tbl[PRX], - .read_raw = &tsl2x7x_read_raw, - .write_raw = &tsl2x7x_write_raw, - .read_event_value = &tsl2x7x_read_event_value, - .write_event_value = &tsl2x7x_write_event_value, - .read_event_config = &tsl2x7x_read_interrupt_config, - .write_event_config = &tsl2x7x_write_interrupt_config, - }, - [ALSPRX] = { - .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX], - .read_raw = &tsl2x7x_read_raw, - .write_raw = &tsl2x7x_write_raw, - .read_event_value = &tsl2x7x_read_event_value, - .write_event_value = &tsl2x7x_write_event_value, - .read_event_config = &tsl2x7x_read_interrupt_config, - .write_event_config = &tsl2x7x_write_interrupt_config, - }, - [PRX2] = { - .attrs = &tsl2X7X_device_attr_group_tbl[PRX2], - .read_raw = &tsl2x7x_read_raw, - .write_raw = &tsl2x7x_write_raw, - .read_event_value = &tsl2x7x_read_event_value, - .write_event_value = &tsl2x7x_write_event_value, - .read_event_config = &tsl2x7x_read_interrupt_config, - .write_event_config = &tsl2x7x_write_interrupt_config, - }, - [ALSPRX2] = { - .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2], - .read_raw = &tsl2x7x_read_raw, - .write_raw = &tsl2x7x_write_raw, - .read_event_value = &tsl2x7x_read_event_value, - .write_event_value = &tsl2x7x_write_event_value, - .read_event_config = &tsl2x7x_read_interrupt_config, - .write_event_config = &tsl2x7x_write_interrupt_config, - }, + TSL2X7X_DEVICE_INFO(ALS), + TSL2X7X_DEVICE_INFO(PRX), + TSL2X7X_DEVICE_INFO(ALSPRX), + TSL2X7X_DEVICE_INFO(PRX2), + TSL2X7X_DEVICE_INFO(ALSPRX2), }; static const struct iio_event_spec tsl2x7x_events[] = { From 77b69a0e679b5ca67c5a2b925c195d22dadff12d Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:19 -0400 Subject: [PATCH 11/42] staging: iio: tsl2x7x: convert to use read_avail Make the sysfs attributes in_proximity0_calibscale_available, and in_intensity0_{calibscale,integration_time}_available be created using info_mask_separate_available on the channel configuration. The driver assumed that the ALS increment was 2.72 ms, and the upper range was 696 ms. Some other supported devices use 2.73 ms - 699 ms. This patch adds support for the multiple ranges. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 93 +++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index 51c1a90cb592..2d713d3c7c7b 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -209,9 +209,9 @@ static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = { }; static const struct tsl2x7x_settings tsl2x7x_default_settings = { - .als_time = 255, /* 2.73 ms */ + .als_time = 255, /* 2.72 / 2.73 ms */ .als_gain = 0, - .prox_time = 255, /* 2.73 ms */ + .prox_time = 255, /* 2.72 / 2.73 ms */ .prox_gain = 0, .wait_time = 255, .als_prox_config = 0, @@ -245,6 +245,23 @@ static const s16 tsl2x7x_prox_gain[] = { 8 }; +static const int tsl2x7x_int_time_avail[][6] = { + [tsl2571] = { 0, 2720, 0, 2720, 0, 696000 }, + [tsl2671] = { 0, 2720, 0, 2720, 0, 696000 }, + [tmd2671] = { 0, 2720, 0, 2720, 0, 696000 }, + [tsl2771] = { 0, 2720, 0, 2720, 0, 696000 }, + [tmd2771] = { 0, 2720, 0, 2720, 0, 696000 }, + [tsl2572] = { 0, 2730, 0, 2730, 0, 699000 }, + [tsl2672] = { 0, 2730, 0, 2730, 0, 699000 }, + [tmd2672] = { 0, 2730, 0, 2730, 0, 699000 }, + [tsl2772] = { 0, 2730, 0, 2730, 0, 699000 }, + [tmd2772] = { 0, 2730, 0, 2730, 0, 699000 }, +}; + +static int tsl2x7x_int_calibscale_avail[] = { 1, 8, 16, 120 }; + +static int tsl2x7x_prox_calibscale_avail[] = { 1, 2, 4, 8 }; + /* Channel variations */ enum { ALS, @@ -626,7 +643,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) /* set chip time scaling and saturation */ als_count = 256 - chip->settings.als_time; - als_time_us = als_count * 2720; + als_time_us = als_count * tsl2x7x_int_time_avail[chip->id][3]; chip->als_saturation = als_count * 768; /* 75% of full scale */ chip->als_gain_time_scale = als_time_us * tsl2x7x_als_gain[chip->settings.als_gain]; @@ -760,12 +777,33 @@ static int tsl2x7x_prox_cal(struct iio_dev *indio_dev) return tsl2x7x_invoke_change(indio_dev); } -static IIO_CONST_ATTR(in_intensity0_calibscale_available, "1 8 16 120"); +static int tsl2x7x_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); -static IIO_CONST_ATTR(in_proximity0_calibscale_available, "1 2 4 8"); + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + if (chan->type == IIO_INTENSITY) { + *length = ARRAY_SIZE(tsl2x7x_int_calibscale_avail); + *vals = tsl2x7x_int_calibscale_avail; + } else { + *length = ARRAY_SIZE(tsl2x7x_prox_calibscale_avail); + *vals = tsl2x7x_prox_calibscale_avail; + } + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_INT_TIME: + *length = ARRAY_SIZE(tsl2x7x_int_time_avail[chip->id]); + *vals = tsl2x7x_int_time_avail[chip->id]; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_RANGE; + } -static IIO_CONST_ATTR(in_intensity0_integration_time_available, - ".00272 - .696"); + return -EINVAL; +} static ssize_t in_illuminance0_target_input_show(struct device *dev, struct device_attribute *attr, @@ -1110,7 +1148,8 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: *val = 0; - *val2 = (256 - chip->settings.als_time) * 2720; + *val2 = (256 - chip->settings.als_time) * + tsl2x7x_int_time_avail[chip->id][3]; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; @@ -1167,7 +1206,8 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev, chip->settings.als_gain_trim = val; break; case IIO_CHAN_INFO_INT_TIME: - chip->settings.als_time = 256 - (val2 / 2720); + chip->settings.als_time = 256 - + (val2 / tsl2x7x_int_time_avail[chip->id][3]); break; default: return -EINVAL; @@ -1248,8 +1288,6 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) } static struct attribute *tsl2x7x_ALS_device_attrs[] = { - &iio_const_attr_in_intensity0_calibscale_available.dev_attr.attr, - &iio_const_attr_in_intensity0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1262,8 +1300,6 @@ static struct attribute *tsl2x7x_PRX_device_attrs[] = { }; static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { - &iio_const_attr_in_intensity0_calibscale_available.dev_attr.attr, - &iio_const_attr_in_intensity0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1272,18 +1308,14 @@ static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { static struct attribute *tsl2x7x_PRX2_device_attrs[] = { &dev_attr_in_proximity0_calibrate.attr, - &iio_const_attr_in_proximity0_calibscale_available.dev_attr.attr, NULL }; static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { - &iio_const_attr_in_intensity0_calibscale_available.dev_attr.attr, - &iio_const_attr_in_intensity0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, &dev_attr_in_proximity0_calibrate.attr, - &iio_const_attr_in_proximity0_calibscale_available.dev_attr.attr, NULL }; @@ -1309,6 +1341,7 @@ static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = { { \ .attrs = &tsl2X7X_device_attr_group_tbl[type], \ .read_raw = &tsl2x7x_read_raw, \ + .read_avail = &tsl2x7x_read_avail, \ .write_raw = &tsl2x7x_write_raw, \ .read_event_value = &tsl2x7x_read_event_value, \ .write_event_value = &tsl2x7x_write_event_value, \ @@ -1357,6 +1390,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_spec = tsl2x7x_events, .num_event_specs = ARRAY_SIZE(tsl2x7x_events), }, { @@ -1379,6 +1415,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_CALIBSCALE), }, { .type = IIO_INTENSITY, .indexed = 1, @@ -1425,6 +1464,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_spec = tsl2x7x_events, .num_event_specs = ARRAY_SIZE(tsl2x7x_events), }, { @@ -1455,6 +1497,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_CALIBSCALE), }, { .type = IIO_INTENSITY, .indexed = 1, @@ -1478,6 +1523,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_CALIBSCALE), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_spec = tsl2x7x_events, .num_event_specs = ARRAY_SIZE(tsl2x7x_events), }, @@ -1489,6 +1536,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_CALIBSCALE), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_CALIBSCALE), }, }, .chan_table_elements = 1, @@ -1509,6 +1558,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_spec = tsl2x7x_events, .num_event_specs = ARRAY_SIZE(tsl2x7x_events), }, { @@ -1522,6 +1574,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_CALIBSCALE), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_spec = tsl2x7x_events, .num_event_specs = ARRAY_SIZE(tsl2x7x_events), }, @@ -1540,6 +1594,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_CALIBSCALE), }, { .type = IIO_INTENSITY, .indexed = 1, @@ -1551,6 +1608,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_CALIBSCALE), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_CALIBSCALE), }, }, .chan_table_elements = 4, From 9861d2daaf28e7beaa0c655206c595094d47ccd8 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:20 -0400 Subject: [PATCH 12/42] staging: iio: tsl2x7x: correct IIO_EV_INFO_PERIOD values The thresh periods assumed an integration time of 3ms. This patch adds support for the correct integration time (2.72ms or 2.73ms). The code had the ALS filter values as going up to 15, however the values actually went up to 60 since the values scaled in increments of 5 once the persistence value went above 3. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 44 ++++++++++++++++------------- drivers/staging/iio/light/tsl2x7x.h | 1 - 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index 2d713d3c7c7b..0218eabcd6d7 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -103,8 +103,6 @@ #define TSL2X7X_CNTL_PROXPON_ENBL 0x0F #define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F -#define TSL2X7X_MIN_ITIME 3 - /* TAOS txx2x7x Device family members */ enum { tsl2571, @@ -984,7 +982,7 @@ static int tsl2x7x_write_event_value(struct iio_dev *indio_dev, int val, int val2) { struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int ret = -EINVAL, y, z, filter_delay; + int ret = -EINVAL, count, persistence; u8 time; switch (info) { @@ -1023,15 +1021,20 @@ static int tsl2x7x_write_event_value(struct iio_dev *indio_dev, else time = chip->settings.prox_time; - y = (TSL2X7X_MAX_TIMER_CNT - time) + 1; - z = y * TSL2X7X_MIN_ITIME; + count = 256 - time; + persistence = ((val * 1000000) + val2) / + (count * tsl2x7x_int_time_avail[chip->id][3]); - filter_delay = DIV_ROUND_UP((val * 1000) + val2, z); + if (chan->type == IIO_INTENSITY) { + /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */ + if (persistence > 3) + persistence = (persistence / 5) + 3; + + chip->settings.als_persistence = persistence; + } else { + chip->settings.prox_persistence = persistence; + } - if (chan->type == IIO_INTENSITY) - chip->settings.als_persistence = filter_delay; - else - chip->settings.prox_persistence = filter_delay; ret = 0; break; default: @@ -1052,7 +1055,7 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, int *val, int *val2) { struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int filter_delay, mult; + int filter_delay, persistence; u8 time; switch (info) { @@ -1084,18 +1087,21 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, case IIO_EV_INFO_PERIOD: if (chan->type == IIO_INTENSITY) { time = chip->settings.als_time; - mult = chip->settings.als_persistence; + persistence = chip->settings.als_persistence; + + /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */ + if (persistence > 3) + persistence = (persistence - 3) * 5; } else { time = chip->settings.prox_time; - mult = chip->settings.prox_persistence; + persistence = chip->settings.prox_persistence; } - /* Determine integration time */ - *val = (TSL2X7X_MAX_TIMER_CNT - time) + 1; - *val2 = *val * TSL2X7X_MIN_ITIME; - filter_delay = *val2 * mult; - *val = filter_delay / 1000; - *val2 = filter_delay % 1000; + filter_delay = persistence * (256 - time) * + tsl2x7x_int_time_avail[chip->id][3]; + + *val = filter_delay / 1000000; + *val2 = filter_delay % 1000000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; diff --git a/drivers/staging/iio/light/tsl2x7x.h b/drivers/staging/iio/light/tsl2x7x.h index db344796fc1b..b86f6b260f9f 100644 --- a/drivers/staging/iio/light/tsl2x7x.h +++ b/drivers/staging/iio/light/tsl2x7x.h @@ -31,7 +31,6 @@ struct tsl2x7x_lux { #define TSL2X7X_50_mA 0x01 #define TSL2X7X_25_mA 0x02 #define TSL2X7X_13_mA 0x03 -#define TSL2X7X_MAX_TIMER_CNT 0xFF /** * struct tsl2x7x_settings - Settings for the tsl2x7x driver From da18e8906278b82774fe5181d98e1e37a62fc1e6 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:21 -0400 Subject: [PATCH 13/42] staging: iio: tsl2x7x: add range checking to tsl2x7x_write_raw The CALIBBIAS and INT_TIME masks in tsl2x7x_write_raw did not have any range checking in place so this patch adds the appropriate range checking. The defines TSL2X7X_ALS_GAIN_TRIM_{MIN,MAX} are also introduced by this patch. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2x7x.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index 0218eabcd6d7..f9500afab30c 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -103,6 +103,9 @@ #define TSL2X7X_CNTL_PROXPON_ENBL 0x0F #define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F +#define TSL2X7X_ALS_GAIN_TRIM_MIN 250 +#define TSL2X7X_ALS_GAIN_TRIM_MAX 4000 + /* TAOS txx2x7x Device family members */ enum { tsl2571, @@ -581,7 +584,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) / lux_val; - if (ret < 250 || ret > 4000) + if (ret < TSL2X7X_ALS_GAIN_TRIM_MIN || ret > TSL2X7X_ALS_GAIN_TRIM_MAX) return -ERANGE; chip->settings.als_gain_trim = ret; @@ -1209,9 +1212,17 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev, } break; case IIO_CHAN_INFO_CALIBBIAS: + if (val < TSL2X7X_ALS_GAIN_TRIM_MIN || + val > TSL2X7X_ALS_GAIN_TRIM_MAX) + return -EINVAL; + chip->settings.als_gain_trim = val; break; case IIO_CHAN_INFO_INT_TIME: + if (val != 0 || val2 < tsl2x7x_int_time_avail[chip->id][1] || + val2 > tsl2x7x_int_time_avail[chip->id][5]) + return -EINVAL; + chip->settings.als_time = 256 - (val2 / tsl2x7x_int_time_avail[chip->id][3]); break; From 4e24c1719f3485780b2be559e5fc11d091139935 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:22 -0400 Subject: [PATCH 14/42] staging: iio: tsl2x7x: rename driver to tsl2772 This patch renames this driver from tsl2x7x to tsl2772 since it is highly likely that additional devices will be added to this driver that do not match that wildcard. The tsl2772 driver name was selected since that is currently the device with the most features that are supported by this driver. This patch also adds Brian Masney's copyright to tsl2772.h for all of the work that has been done to move this driver out of staging. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/Kconfig | 2 +- drivers/staging/iio/light/Makefile | 2 +- .../iio/light/{tsl2x7x.c => tsl2772.c} | 667 +++++++++--------- .../iio/light/{tsl2x7x.h => tsl2772.h} | 49 +- 4 files changed, 361 insertions(+), 359 deletions(-) rename drivers/staging/iio/light/{tsl2x7x.c => tsl2772.c} (67%) rename drivers/staging/iio/light/{tsl2x7x.h => tsl2772.h} (70%) diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index aacb0ae58c0e..dfa37386ad2c 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -3,7 +3,7 @@ # menu "Light sensors" -config TSL2x7x +config TSL2772 tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors" depends on I2C help diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index ab8dc3a3d10b..e7e77a11f02a 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -2,4 +2,4 @@ # Makefile for industrial I/O Light sensors # -obj-$(CONFIG_TSL2x7x) += tsl2x7x.o +obj-$(CONFIG_TSL2772) += tsl2772.o diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2772.c similarity index 67% rename from drivers/staging/iio/light/tsl2x7x.c rename to drivers/staging/iio/light/tsl2772.c index f9500afab30c..a59bf39c28d4 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2772.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Device driver for monitoring ambient light intensity in (lux) and proximity - * detection (prox) within the TAOS TSL2X7X family of devices. + * detection (prox) within the TAOS TSL2571, TSL2671, TMD2671, TSL2771, TMD2771, + * TSL2572, TSL2672, TMD2672, TSL2772, and TMD2772 devices. * * Copyright (c) 2012, TAOS Corporation. * Copyright (c) 2017-2018 Brian Masney @@ -18,95 +19,95 @@ #include #include #include -#include "tsl2x7x.h" +#include "tsl2772.h" /* Cal defs */ #define PROX_STAT_CAL 0 #define PROX_STAT_SAMP 1 #define MAX_SAMPLES_CAL 200 -/* TSL2X7X Device ID */ +/* TSL2772 Device ID */ #define TRITON_ID 0x00 #define SWORDFISH_ID 0x30 #define HALIBUT_ID 0x20 /* Lux calculation constants */ -#define TSL2X7X_LUX_CALC_OVER_FLOW 65535 +#define TSL2772_LUX_CALC_OVER_FLOW 65535 /* * TAOS Register definitions - Note: depending on device, some of these register * are not used and the register address is benign. */ -/* 2X7X register offsets */ -#define TSL2X7X_MAX_CONFIG_REG 16 +/* Register offsets */ +#define TSL2772_MAX_CONFIG_REG 16 /* Device Registers and Masks */ -#define TSL2X7X_CNTRL 0x00 -#define TSL2X7X_ALS_TIME 0X01 -#define TSL2X7X_PRX_TIME 0x02 -#define TSL2X7X_WAIT_TIME 0x03 -#define TSL2X7X_ALS_MINTHRESHLO 0X04 -#define TSL2X7X_ALS_MINTHRESHHI 0X05 -#define TSL2X7X_ALS_MAXTHRESHLO 0X06 -#define TSL2X7X_ALS_MAXTHRESHHI 0X07 -#define TSL2X7X_PRX_MINTHRESHLO 0X08 -#define TSL2X7X_PRX_MINTHRESHHI 0X09 -#define TSL2X7X_PRX_MAXTHRESHLO 0X0A -#define TSL2X7X_PRX_MAXTHRESHHI 0X0B -#define TSL2X7X_PERSISTENCE 0x0C -#define TSL2X7X_ALS_PRX_CONFIG 0x0D -#define TSL2X7X_PRX_COUNT 0x0E -#define TSL2X7X_GAIN 0x0F -#define TSL2X7X_NOTUSED 0x10 -#define TSL2X7X_REVID 0x11 -#define TSL2X7X_CHIPID 0x12 -#define TSL2X7X_STATUS 0x13 -#define TSL2X7X_ALS_CHAN0LO 0x14 -#define TSL2X7X_ALS_CHAN0HI 0x15 -#define TSL2X7X_ALS_CHAN1LO 0x16 -#define TSL2X7X_ALS_CHAN1HI 0x17 -#define TSL2X7X_PRX_LO 0x18 -#define TSL2X7X_PRX_HI 0x19 +#define TSL2772_CNTRL 0x00 +#define TSL2772_ALS_TIME 0X01 +#define TSL2772_PRX_TIME 0x02 +#define TSL2772_WAIT_TIME 0x03 +#define TSL2772_ALS_MINTHRESHLO 0X04 +#define TSL2772_ALS_MINTHRESHHI 0X05 +#define TSL2772_ALS_MAXTHRESHLO 0X06 +#define TSL2772_ALS_MAXTHRESHHI 0X07 +#define TSL2772_PRX_MINTHRESHLO 0X08 +#define TSL2772_PRX_MINTHRESHHI 0X09 +#define TSL2772_PRX_MAXTHRESHLO 0X0A +#define TSL2772_PRX_MAXTHRESHHI 0X0B +#define TSL2772_PERSISTENCE 0x0C +#define TSL2772_ALS_PRX_CONFIG 0x0D +#define TSL2772_PRX_COUNT 0x0E +#define TSL2772_GAIN 0x0F +#define TSL2772_NOTUSED 0x10 +#define TSL2772_REVID 0x11 +#define TSL2772_CHIPID 0x12 +#define TSL2772_STATUS 0x13 +#define TSL2772_ALS_CHAN0LO 0x14 +#define TSL2772_ALS_CHAN0HI 0x15 +#define TSL2772_ALS_CHAN1LO 0x16 +#define TSL2772_ALS_CHAN1HI 0x17 +#define TSL2772_PRX_LO 0x18 +#define TSL2772_PRX_HI 0x19 -/* tsl2X7X cmd reg masks */ -#define TSL2X7X_CMD_REG 0x80 -#define TSL2X7X_CMD_SPL_FN 0x60 -#define TSL2X7X_CMD_REPEAT_PROTO 0x00 -#define TSL2X7X_CMD_AUTOINC_PROTO 0x20 +/* tsl2772 cmd reg masks */ +#define TSL2772_CMD_REG 0x80 +#define TSL2772_CMD_SPL_FN 0x60 +#define TSL2772_CMD_REPEAT_PROTO 0x00 +#define TSL2772_CMD_AUTOINC_PROTO 0x20 -#define TSL2X7X_CMD_PROX_INT_CLR 0X05 -#define TSL2X7X_CMD_ALS_INT_CLR 0x06 -#define TSL2X7X_CMD_PROXALS_INT_CLR 0X07 +#define TSL2772_CMD_PROX_INT_CLR 0X05 +#define TSL2772_CMD_ALS_INT_CLR 0x06 +#define TSL2772_CMD_PROXALS_INT_CLR 0X07 -/* tsl2X7X cntrl reg masks */ -#define TSL2X7X_CNTL_ADC_ENBL 0x02 -#define TSL2X7X_CNTL_PWR_ON 0x01 +/* tsl2772 cntrl reg masks */ +#define TSL2772_CNTL_ADC_ENBL 0x02 +#define TSL2772_CNTL_PWR_ON 0x01 -/* tsl2X7X status reg masks */ -#define TSL2X7X_STA_ADC_VALID 0x01 -#define TSL2X7X_STA_PRX_VALID 0x02 -#define TSL2X7X_STA_ADC_PRX_VALID (TSL2X7X_STA_ADC_VALID | \ - TSL2X7X_STA_PRX_VALID) -#define TSL2X7X_STA_ALS_INTR 0x10 -#define TSL2X7X_STA_PRX_INTR 0x20 +/* tsl2772 status reg masks */ +#define TSL2772_STA_ADC_VALID 0x01 +#define TSL2772_STA_PRX_VALID 0x02 +#define TSL2772_STA_ADC_PRX_VALID (TSL2772_STA_ADC_VALID | \ + TSL2772_STA_PRX_VALID) +#define TSL2772_STA_ALS_INTR 0x10 +#define TSL2772_STA_PRX_INTR 0x20 -/* tsl2X7X cntrl reg masks */ -#define TSL2X7X_CNTL_REG_CLEAR 0x00 -#define TSL2X7X_CNTL_PROX_INT_ENBL 0X20 -#define TSL2X7X_CNTL_ALS_INT_ENBL 0X10 -#define TSL2X7X_CNTL_WAIT_TMR_ENBL 0X08 -#define TSL2X7X_CNTL_PROX_DET_ENBL 0X04 -#define TSL2X7X_CNTL_PWRON 0x01 -#define TSL2X7X_CNTL_ALSPON_ENBL 0x03 -#define TSL2X7X_CNTL_INTALSPON_ENBL 0x13 -#define TSL2X7X_CNTL_PROXPON_ENBL 0x0F -#define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F +/* tsl2772 cntrl reg masks */ +#define TSL2772_CNTL_REG_CLEAR 0x00 +#define TSL2772_CNTL_PROX_INT_ENBL 0X20 +#define TSL2772_CNTL_ALS_INT_ENBL 0X10 +#define TSL2772_CNTL_WAIT_TMR_ENBL 0X08 +#define TSL2772_CNTL_PROX_DET_ENBL 0X04 +#define TSL2772_CNTL_PWRON 0x01 +#define TSL2772_CNTL_ALSPON_ENBL 0x03 +#define TSL2772_CNTL_INTALSPON_ENBL 0x13 +#define TSL2772_CNTL_PROXPON_ENBL 0x0F +#define TSL2772_CNTL_INTPROXPON_ENBL 0x2F -#define TSL2X7X_ALS_GAIN_TRIM_MIN 250 -#define TSL2X7X_ALS_GAIN_TRIM_MAX 4000 +#define TSL2772_ALS_GAIN_TRIM_MIN 250 +#define TSL2772_ALS_GAIN_TRIM_MAX 4000 -/* TAOS txx2x7x Device family members */ +/* Device family members */ enum { tsl2571, tsl2671, @@ -121,39 +122,39 @@ enum { }; enum { - TSL2X7X_CHIP_UNKNOWN = 0, - TSL2X7X_CHIP_WORKING = 1, - TSL2X7X_CHIP_SUSPENDED = 2 + TSL2772_CHIP_UNKNOWN = 0, + TSL2772_CHIP_WORKING = 1, + TSL2772_CHIP_SUSPENDED = 2 }; /* Per-device data */ -struct tsl2x7x_als_info { +struct tsl2772_als_info { u16 als_ch0; u16 als_ch1; u16 lux; }; -struct tsl2x7x_chip_info { +struct tsl2772_chip_info { int chan_table_elements; struct iio_chan_spec channel_with_events[4]; struct iio_chan_spec channel_without_events[4]; const struct iio_info *info; }; -struct tsl2X7X_chip { +struct tsl2772_chip { kernel_ulong_t id; struct mutex prox_mutex; struct mutex als_mutex; struct i2c_client *client; u16 prox_data; - struct tsl2x7x_als_info als_cur_info; - struct tsl2x7x_settings settings; - struct tsl2X7X_platform_data *pdata; + struct tsl2772_als_info als_cur_info; + struct tsl2772_settings settings; + struct tsl2772_platform_data *pdata; int als_gain_time_scale; int als_saturation; - int tsl2x7x_chip_status; - u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG]; - const struct tsl2x7x_chip_info *chip_info; + int tsl2772_chip_status; + u8 tsl2772_config[TSL2772_MAX_CONFIG_REG]; + const struct tsl2772_chip_info *chip_info; const struct iio_info *info; s64 event_timestamp; /* @@ -161,7 +162,7 @@ struct tsl2X7X_chip { * updates via sysfs. * Sized to 9 = max 8 segments + 1 termination segment */ - struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE]; + struct tsl2772_lux tsl2772_device_lux[TSL2772_MAX_LUX_TABLE_SIZE]; }; /* @@ -172,31 +173,31 @@ struct tsl2X7X_chip { * The two rows in each table correspond to the Lux1 and Lux2 equations from * the datasheets. */ -static const struct tsl2x7x_lux tsl2x71_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = { +static const struct tsl2772_lux tsl2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = { { 53000, 106000 }, { 31800, 53000 }, { 0, 0 }, }; -static const struct tsl2x7x_lux tmd2x71_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = { +static const struct tsl2772_lux tmd2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = { { 24000, 48000 }, { 14400, 24000 }, { 0, 0 }, }; -static const struct tsl2x7x_lux tsl2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = { +static const struct tsl2772_lux tsl2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = { { 60000, 112200 }, { 37800, 60000 }, { 0, 0 }, }; -static const struct tsl2x7x_lux tmd2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = { +static const struct tsl2772_lux tmd2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = { { 20000, 35000 }, { 12600, 20000 }, { 0, 0 }, }; -static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = { +static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = { [tsl2571] = tsl2x71_lux_table, [tsl2671] = tsl2x71_lux_table, [tmd2671] = tmd2x71_lux_table, @@ -209,7 +210,7 @@ static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = { [tmd2772] = tmd2x72_lux_table, }; -static const struct tsl2x7x_settings tsl2x7x_default_settings = { +static const struct tsl2772_settings tsl2772_default_settings = { .als_time = 255, /* 2.72 / 2.73 ms */ .als_gain = 0, .prox_time = 255, /* 2.72 / 2.73 ms */ @@ -228,25 +229,25 @@ static const struct tsl2x7x_settings tsl2x7x_default_settings = { .prox_thres_high = 512, .prox_max_samples_cal = 30, .prox_pulse_count = 8, - .prox_diode = TSL2X7X_DIODE1, - .prox_power = TSL2X7X_100_mA + .prox_diode = TSL2772_DIODE1, + .prox_power = TSL2772_100_mA }; -static const s16 tsl2x7x_als_gain[] = { +static const s16 tsl2772_als_gain[] = { 1, 8, 16, 120 }; -static const s16 tsl2x7x_prox_gain[] = { +static const s16 tsl2772_prox_gain[] = { 1, 2, 4, 8 }; -static const int tsl2x7x_int_time_avail[][6] = { +static const int tsl2772_int_time_avail[][6] = { [tsl2571] = { 0, 2720, 0, 2720, 0, 696000 }, [tsl2671] = { 0, 2720, 0, 2720, 0, 696000 }, [tmd2671] = { 0, 2720, 0, 2720, 0, 696000 }, @@ -259,9 +260,9 @@ static const int tsl2x7x_int_time_avail[][6] = { [tmd2772] = { 0, 2730, 0, 2730, 0, 699000 }, }; -static int tsl2x7x_int_calibscale_avail[] = { 1, 8, 16, 120 }; +static int tsl2772_int_calibscale_avail[] = { 1, 8, 16, 120 }; -static int tsl2x7x_prox_calibscale_avail[] = { 1, 2, 4, 8 }; +static int tsl2772_prox_calibscale_avail[] = { 1, 2, 4, 8 }; /* Channel variations */ enum { @@ -285,12 +286,12 @@ static const u8 device_channel_config[] = { [tmd2772] = ALSPRX2 }; -static int tsl2x7x_read_status(struct tsl2X7X_chip *chip) +static int tsl2772_read_status(struct tsl2772_chip *chip) { int ret; ret = i2c_smbus_read_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_STATUS); + TSL2772_CMD_REG | TSL2772_STATUS); if (ret < 0) dev_err(&chip->client->dev, "%s: failed to read STATUS register: %d\n", __func__, @@ -299,12 +300,12 @@ static int tsl2x7x_read_status(struct tsl2X7X_chip *chip) return ret; } -static int tsl2x7x_write_control_reg(struct tsl2X7X_chip *chip, u8 data) +static int tsl2772_write_control_reg(struct tsl2772_chip *chip, u8 data) { int ret; ret = i2c_smbus_write_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CNTRL, data); + TSL2772_CMD_REG | TSL2772_CNTRL, data); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed to write to control register %x: %d\n", @@ -314,14 +315,14 @@ static int tsl2x7x_write_control_reg(struct tsl2X7X_chip *chip, u8 data) return ret; } -static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg, +static int tsl2772_read_autoinc_regs(struct tsl2772_chip *chip, int lower_reg, int upper_reg) { u8 buf[2]; int ret; ret = i2c_smbus_write_byte(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CMD_AUTOINC_PROTO | + TSL2772_CMD_REG | TSL2772_CMD_AUTOINC_PROTO | lower_reg); if (ret < 0) { dev_err(&chip->client->dev, @@ -331,7 +332,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg, } ret = i2c_smbus_read_byte_data(chip->client, - TSL2X7X_CMD_REG | lower_reg); + TSL2772_CMD_REG | lower_reg); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed to read from register %x: %d\n", __func__, @@ -341,7 +342,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg, buf[0] = ret; ret = i2c_smbus_read_byte_data(chip->client, - TSL2X7X_CMD_REG | upper_reg); + TSL2772_CMD_REG | upper_reg); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed to read from register %x: %d\n", __func__, @@ -351,7 +352,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg, buf[1] = ret; ret = i2c_smbus_write_byte(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CMD_REPEAT_PROTO | + TSL2772_CMD_REG | TSL2772_CMD_REPEAT_PROTO | lower_reg); if (ret < 0) { dev_err(&chip->client->dev, @@ -364,7 +365,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg, } /** - * tsl2x7x_get_lux() - Reads and calculates current lux value. + * tsl2772_get_lux() - Reads and calculates current lux value. * @indio_dev: pointer to IIO device * * The raw ch0 and ch1 values of the ambient light sensed in the last @@ -374,47 +375,47 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg, * coefficients. A lux gain trim is applied to each lux equation, and then the * maximum lux within the interval 0..65535 is selected. */ -static int tsl2x7x_get_lux(struct iio_dev *indio_dev) +static int tsl2772_get_lux(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); - struct tsl2x7x_lux *p; + struct tsl2772_chip *chip = iio_priv(indio_dev); + struct tsl2772_lux *p; int max_lux, ret; bool overflow; mutex_lock(&chip->als_mutex); - if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) { + if (chip->tsl2772_chip_status != TSL2772_CHIP_WORKING) { dev_err(&chip->client->dev, "%s: device is not enabled\n", __func__); ret = -EBUSY; goto out_unlock; } - ret = tsl2x7x_read_status(chip); + ret = tsl2772_read_status(chip); if (ret < 0) goto out_unlock; - if (!(ret & TSL2X7X_STA_ADC_VALID)) { + if (!(ret & TSL2772_STA_ADC_VALID)) { dev_err(&chip->client->dev, "%s: data not valid yet\n", __func__); ret = chip->als_cur_info.lux; /* return LAST VALUE */ goto out_unlock; } - ret = tsl2x7x_read_autoinc_regs(chip, TSL2X7X_ALS_CHAN0LO, - TSL2X7X_ALS_CHAN0HI); + ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN0LO, + TSL2772_ALS_CHAN0HI); if (ret < 0) goto out_unlock; chip->als_cur_info.als_ch0 = ret; - ret = tsl2x7x_read_autoinc_regs(chip, TSL2X7X_ALS_CHAN1LO, - TSL2X7X_ALS_CHAN1HI); + ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN1LO, + TSL2772_ALS_CHAN1HI); if (ret < 0) goto out_unlock; chip->als_cur_info.als_ch1 = ret; if (chip->als_cur_info.als_ch0 >= chip->als_saturation) { - max_lux = TSL2X7X_LUX_CALC_OVER_FLOW; + max_lux = TSL2772_LUX_CALC_OVER_FLOW; goto update_struct_with_max_lux; } @@ -426,7 +427,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) max_lux = 0; overflow = false; - for (p = (struct tsl2x7x_lux *)chip->tsl2x7x_device_lux; p->ch0 != 0; + for (p = (struct tsl2772_lux *)chip->tsl2772_device_lux; p->ch0 != 0; p++) { int lux; @@ -442,7 +443,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) */ lux = (lux * chip->settings.als_gain_trim) / 1000; - if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) { + if (lux > TSL2772_LUX_CALC_OVER_FLOW) { overflow = true; continue; } @@ -451,7 +452,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) } if (overflow && max_lux == 0) - max_lux = TSL2X7X_LUX_CALC_OVER_FLOW; + max_lux = TSL2772_LUX_CALC_OVER_FLOW; update_struct_with_max_lux: chip->als_cur_info.lux = max_lux; @@ -464,19 +465,19 @@ out_unlock: } /** - * tsl2x7x_get_prox() - Reads proximity data registers and updates + * tsl2772_get_prox() - Reads proximity data registers and updates * chip->prox_data. * * @indio_dev: pointer to IIO device */ -static int tsl2x7x_get_prox(struct iio_dev *indio_dev) +static int tsl2772_get_prox(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); int ret; mutex_lock(&chip->prox_mutex); - ret = tsl2x7x_read_status(chip); + ret = tsl2772_read_status(chip); if (ret < 0) goto prox_poll_err; @@ -486,7 +487,7 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev) case tmd2671: case tsl2771: case tmd2771: - if (!(ret & TSL2X7X_STA_ADC_VALID)) { + if (!(ret & TSL2772_STA_ADC_VALID)) { ret = -EINVAL; goto prox_poll_err; } @@ -496,14 +497,14 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev) case tmd2672: case tsl2772: case tmd2772: - if (!(ret & TSL2X7X_STA_PRX_VALID)) { + if (!(ret & TSL2772_STA_PRX_VALID)) { ret = -EINVAL; goto prox_poll_err; } break; } - ret = tsl2x7x_read_autoinc_regs(chip, TSL2X7X_PRX_LO, TSL2X7X_PRX_HI); + ret = tsl2772_read_autoinc_regs(chip, TSL2772_PRX_LO, TSL2772_PRX_HI); if (ret < 0) goto prox_poll_err; chip->prox_data = ret; @@ -515,46 +516,46 @@ prox_poll_err: } /** - * tsl2x7x_defaults() - Populates the device nominal operating parameters + * tsl2772_defaults() - Populates the device nominal operating parameters * with those provided by a 'platform' data struct or * with prefined defaults. * * @chip: pointer to device structure. */ -static void tsl2x7x_defaults(struct tsl2X7X_chip *chip) +static void tsl2772_defaults(struct tsl2772_chip *chip) { /* If Operational settings defined elsewhere.. */ if (chip->pdata && chip->pdata->platform_default_settings) memcpy(&chip->settings, chip->pdata->platform_default_settings, - sizeof(tsl2x7x_default_settings)); + sizeof(tsl2772_default_settings)); else - memcpy(&chip->settings, &tsl2x7x_default_settings, - sizeof(tsl2x7x_default_settings)); + memcpy(&chip->settings, &tsl2772_default_settings, + sizeof(tsl2772_default_settings)); /* Load up the proper lux table. */ if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0) - memcpy(chip->tsl2x7x_device_lux, + memcpy(chip->tsl2772_device_lux, chip->pdata->platform_lux_table, sizeof(chip->pdata->platform_lux_table)); else - memcpy(chip->tsl2x7x_device_lux, - tsl2x7x_default_lux_table_group[chip->id], - TSL2X7X_DEFAULT_TABLE_BYTES); + memcpy(chip->tsl2772_device_lux, + tsl2772_default_lux_table_group[chip->id], + TSL2772_DEFAULT_TABLE_BYTES); } /** - * tsl2x7x_als_calibrate() - Obtain single reading and calculate + * tsl2772_als_calibrate() - Obtain single reading and calculate * the als_gain_trim. * * @indio_dev: pointer to IIO device */ -static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) +static int tsl2772_als_calibrate(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); int ret, lux_val; ret = i2c_smbus_read_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CNTRL); + TSL2772_CMD_REG | TSL2772_CNTRL); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed to read from the CNTRL register\n", @@ -562,20 +563,20 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) return ret; } - if ((ret & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) - != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) { + if ((ret & (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON)) + != (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON)) { dev_err(&chip->client->dev, "%s: Device is not powered on and/or ADC is not enabled\n", __func__); return -EINVAL; - } else if ((ret & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) { + } else if ((ret & TSL2772_STA_ADC_VALID) != TSL2772_STA_ADC_VALID) { dev_err(&chip->client->dev, "%s: The two ADC channels have not completed an integration cycle\n", __func__); return -ENODATA; } - lux_val = tsl2x7x_get_lux(indio_dev); + lux_val = tsl2772_get_lux(indio_dev); if (lux_val < 0) { dev_err(&chip->client->dev, "%s: failed to get lux\n", __func__); @@ -584,7 +585,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) / lux_val; - if (ret < TSL2X7X_ALS_GAIN_TRIM_MIN || ret > TSL2X7X_ALS_GAIN_TRIM_MAX) + if (ret < TSL2772_ALS_GAIN_TRIM_MIN || ret > TSL2772_ALS_GAIN_TRIM_MAX) return -ERANGE; chip->settings.als_gain_trim = ret; @@ -592,51 +593,51 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) return ret; } -static int tsl2x7x_chip_on(struct iio_dev *indio_dev) +static int tsl2772_chip_on(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); int ret, i, als_count, als_time_us; u8 *dev_reg, reg_val; /* Non calculated parameters */ - chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = chip->settings.als_time; - chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = chip->settings.prox_time; - chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = chip->settings.wait_time; - chip->tsl2x7x_config[TSL2X7X_ALS_PRX_CONFIG] = + chip->tsl2772_config[TSL2772_ALS_TIME] = chip->settings.als_time; + chip->tsl2772_config[TSL2772_PRX_TIME] = chip->settings.prox_time; + chip->tsl2772_config[TSL2772_WAIT_TIME] = chip->settings.wait_time; + chip->tsl2772_config[TSL2772_ALS_PRX_CONFIG] = chip->settings.als_prox_config; - chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHLO] = + chip->tsl2772_config[TSL2772_ALS_MINTHRESHLO] = (chip->settings.als_thresh_low) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHHI] = + chip->tsl2772_config[TSL2772_ALS_MINTHRESHHI] = (chip->settings.als_thresh_low >> 8) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHLO] = + chip->tsl2772_config[TSL2772_ALS_MAXTHRESHLO] = (chip->settings.als_thresh_high) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHHI] = + chip->tsl2772_config[TSL2772_ALS_MAXTHRESHHI] = (chip->settings.als_thresh_high >> 8) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_PERSISTENCE] = + chip->tsl2772_config[TSL2772_PERSISTENCE] = (chip->settings.prox_persistence & 0xFF) << 4 | (chip->settings.als_persistence & 0xFF); - chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] = + chip->tsl2772_config[TSL2772_PRX_COUNT] = chip->settings.prox_pulse_count; - chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] = + chip->tsl2772_config[TSL2772_PRX_MINTHRESHLO] = (chip->settings.prox_thres_low) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] = + chip->tsl2772_config[TSL2772_PRX_MINTHRESHHI] = (chip->settings.prox_thres_low >> 8) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] = + chip->tsl2772_config[TSL2772_PRX_MAXTHRESHLO] = (chip->settings.prox_thres_high) & 0xFF; - chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] = + chip->tsl2772_config[TSL2772_PRX_MAXTHRESHHI] = (chip->settings.prox_thres_high >> 8) & 0xFF; /* and make sure we're not already on */ - if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) { + if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) { /* if forcing a register update - turn off, then on */ dev_info(&chip->client->dev, "device is already enabled\n"); return -EINVAL; } - /* Set the gain based on tsl2x7x_settings struct */ - chip->tsl2x7x_config[TSL2X7X_GAIN] = + /* Set the gain based on tsl2772_settings struct */ + chip->tsl2772_config[TSL2772_GAIN] = (chip->settings.als_gain & 0xFF) | ((chip->settings.prox_gain & 0xFF) << 2) | (chip->settings.prox_diode << 4) | @@ -644,16 +645,16 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) /* set chip time scaling and saturation */ als_count = 256 - chip->settings.als_time; - als_time_us = als_count * tsl2x7x_int_time_avail[chip->id][3]; + als_time_us = als_count * tsl2772_int_time_avail[chip->id][3]; chip->als_saturation = als_count * 768; /* 75% of full scale */ chip->als_gain_time_scale = als_time_us * - tsl2x7x_als_gain[chip->settings.als_gain]; + tsl2772_als_gain[chip->settings.als_gain]; /* - * TSL2X7X Specific power-on / adc enable sequence + * TSL2772 Specific power-on / adc enable sequence * Power on the device 1st. */ - ret = tsl2x7x_write_control_reg(chip, TSL2X7X_CNTL_PWR_ON); + ret = tsl2772_write_control_reg(chip, TSL2772_CNTL_PWR_ON); if (ret < 0) return ret; @@ -661,9 +662,9 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) * Use the following shadow copy for our delay before enabling ADC. * Write all the registers. */ - for (i = 0, dev_reg = chip->tsl2x7x_config; - i < TSL2X7X_MAX_CONFIG_REG; i++) { - int reg = TSL2X7X_CMD_REG + i; + for (i = 0, dev_reg = chip->tsl2772_config; + i < TSL2772_MAX_CONFIG_REG; i++) { + int reg = TSL2772_CMD_REG + i; ret = i2c_smbus_write_byte_data(chip->client, reg, *dev_reg++); @@ -678,20 +679,20 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) /* Power-on settling time */ usleep_range(3000, 3500); - reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL | - TSL2X7X_CNTL_PROX_DET_ENBL; + reg_val = TSL2772_CNTL_PWR_ON | TSL2772_CNTL_ADC_ENBL | + TSL2772_CNTL_PROX_DET_ENBL; if (chip->settings.als_interrupt_en) - reg_val |= TSL2X7X_CNTL_ALS_INT_ENBL; + reg_val |= TSL2772_CNTL_ALS_INT_ENBL; if (chip->settings.prox_interrupt_en) - reg_val |= TSL2X7X_CNTL_PROX_INT_ENBL; + reg_val |= TSL2772_CNTL_PROX_INT_ENBL; - ret = tsl2x7x_write_control_reg(chip, reg_val); + ret = tsl2772_write_control_reg(chip, reg_val); if (ret < 0) return ret; ret = i2c_smbus_write_byte(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | - TSL2X7X_CMD_PROXALS_INT_CLR); + TSL2772_CMD_REG | TSL2772_CMD_SPL_FN | + TSL2772_CMD_PROXALS_INT_CLR); if (ret < 0) { dev_err(&chip->client->dev, "%s: failed to clear interrupt status: %d\n", @@ -699,22 +700,22 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) return ret; } - chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING; + chip->tsl2772_chip_status = TSL2772_CHIP_WORKING; return ret; } -static int tsl2x7x_chip_off(struct iio_dev *indio_dev) +static int tsl2772_chip_off(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); /* turn device off */ - chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; - return tsl2x7x_write_control_reg(chip, 0x00); + chip->tsl2772_chip_status = TSL2772_CHIP_SUSPENDED; + return tsl2772_write_control_reg(chip, 0x00); } /** - * tsl2x7x_invoke_change - power cycle the device to implement the user + * tsl2772_invoke_change - power cycle the device to implement the user * parameters * @indio_dev: pointer to IIO device * @@ -722,22 +723,22 @@ static int tsl2x7x_chip_off(struct iio_dev *indio_dev) * (On/Off), cycle device to implement updated parameter, put device back into * proper state, and unlock resource. */ -static int tsl2x7x_invoke_change(struct iio_dev *indio_dev) +static int tsl2772_invoke_change(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int device_status = chip->tsl2x7x_chip_status; + struct tsl2772_chip *chip = iio_priv(indio_dev); + int device_status = chip->tsl2772_chip_status; int ret; mutex_lock(&chip->als_mutex); mutex_lock(&chip->prox_mutex); - if (device_status == TSL2X7X_CHIP_WORKING) { - ret = tsl2x7x_chip_off(indio_dev); + if (device_status == TSL2772_CHIP_WORKING) { + ret = tsl2772_chip_off(indio_dev); if (ret < 0) goto unlock; } - ret = tsl2x7x_chip_on(indio_dev); + ret = tsl2772_chip_on(indio_dev); unlock: mutex_unlock(&chip->prox_mutex); @@ -746,9 +747,9 @@ unlock: return ret; } -static int tsl2x7x_prox_cal(struct iio_dev *indio_dev) +static int tsl2772_prox_cal(struct iio_dev *indio_dev) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); int prox_history[MAX_SAMPLES_CAL + 1]; int i, ret, mean, max, sample_sum; @@ -758,7 +759,7 @@ static int tsl2x7x_prox_cal(struct iio_dev *indio_dev) for (i = 0; i < chip->settings.prox_max_samples_cal; i++) { usleep_range(15000, 17500); - ret = tsl2x7x_get_prox(indio_dev); + ret = tsl2772_get_prox(indio_dev); if (ret < 0) return ret; @@ -775,30 +776,30 @@ static int tsl2x7x_prox_cal(struct iio_dev *indio_dev) chip->settings.prox_thres_high = (max << 1) - mean; - return tsl2x7x_invoke_change(indio_dev); + return tsl2772_invoke_change(indio_dev); } -static int tsl2x7x_read_avail(struct iio_dev *indio_dev, +static int tsl2772_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length, long mask) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); switch (mask) { case IIO_CHAN_INFO_CALIBSCALE: if (chan->type == IIO_INTENSITY) { - *length = ARRAY_SIZE(tsl2x7x_int_calibscale_avail); - *vals = tsl2x7x_int_calibscale_avail; + *length = ARRAY_SIZE(tsl2772_int_calibscale_avail); + *vals = tsl2772_int_calibscale_avail; } else { - *length = ARRAY_SIZE(tsl2x7x_prox_calibscale_avail); - *vals = tsl2x7x_prox_calibscale_avail; + *length = ARRAY_SIZE(tsl2772_prox_calibscale_avail); + *vals = tsl2772_prox_calibscale_avail; } *type = IIO_VAL_INT; return IIO_AVAIL_LIST; case IIO_CHAN_INFO_INT_TIME: - *length = ARRAY_SIZE(tsl2x7x_int_time_avail[chip->id]); - *vals = tsl2x7x_int_time_avail[chip->id]; + *length = ARRAY_SIZE(tsl2772_int_time_avail[chip->id]); + *vals = tsl2772_int_time_avail[chip->id]; *type = IIO_VAL_INT_PLUS_MICRO; return IIO_AVAIL_RANGE; } @@ -810,7 +811,7 @@ static ssize_t in_illuminance0_target_input_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev)); return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target); } @@ -820,7 +821,7 @@ static ssize_t in_illuminance0_target_input_store(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); u16 value; int ret; @@ -828,7 +829,7 @@ static ssize_t in_illuminance0_target_input_store(struct device *dev, return -EINVAL; chip->settings.als_cal_target = value; - ret = tsl2x7x_invoke_change(indio_dev); + ret = tsl2772_invoke_change(indio_dev); if (ret < 0) return ret; @@ -846,11 +847,11 @@ static ssize_t in_illuminance0_calibrate_store(struct device *dev, if (kstrtobool(buf, &value) || !value) return -EINVAL; - ret = tsl2x7x_als_calibrate(indio_dev); + ret = tsl2772_als_calibrate(indio_dev); if (ret < 0) return ret; - ret = tsl2x7x_invoke_change(indio_dev); + ret = tsl2772_invoke_change(indio_dev); if (ret < 0) return ret; @@ -861,15 +862,15 @@ static ssize_t in_illuminance0_lux_table_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev)); int i = 0; int offset = 0; - while (i < TSL2X7X_MAX_LUX_TABLE_SIZE) { + while (i < TSL2772_MAX_LUX_TABLE_SIZE) { offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,", - chip->tsl2x7x_device_lux[i].ch0, - chip->tsl2x7x_device_lux[i].ch1); - if (chip->tsl2x7x_device_lux[i].ch0 == 0) { + chip->tsl2772_device_lux[i].ch0, + chip->tsl2772_device_lux[i].ch1); + if (chip->tsl2772_device_lux[i].ch0 == 0) { /* * We just printed the first "0" entry. * Now get rid of the extra "," and break. @@ -889,8 +890,8 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct tsl2X7X_chip *chip = iio_priv(indio_dev); - int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 2 + 1]; + struct tsl2772_chip *chip = iio_priv(indio_dev); + int value[ARRAY_SIZE(chip->tsl2772_device_lux) * 2 + 1]; int n, ret; get_options(buf, ARRAY_SIZE(value), value); @@ -903,23 +904,23 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev, */ n = value[0]; if ((n % 2) || n < 4 || - n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 2)) + n > ((ARRAY_SIZE(chip->tsl2772_device_lux) - 1) * 2)) return -EINVAL; if ((value[(n - 1)] | value[n]) != 0) return -EINVAL; - if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) { - ret = tsl2x7x_chip_off(indio_dev); + if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) { + ret = tsl2772_chip_off(indio_dev); if (ret < 0) return ret; } /* Zero out the table */ - memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux)); - memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4)); + memset(chip->tsl2772_device_lux, 0, sizeof(chip->tsl2772_device_lux)); + memcpy(chip->tsl2772_device_lux, &value[1], (value[0] * 4)); - ret = tsl2x7x_invoke_change(indio_dev); + ret = tsl2772_invoke_change(indio_dev); if (ret < 0) return ret; @@ -937,23 +938,23 @@ static ssize_t in_proximity0_calibrate_store(struct device *dev, if (kstrtobool(buf, &value) || !value) return -EINVAL; - ret = tsl2x7x_prox_cal(indio_dev); + ret = tsl2772_prox_cal(indio_dev); if (ret < 0) return ret; - ret = tsl2x7x_invoke_change(indio_dev); + ret = tsl2772_invoke_change(indio_dev); if (ret < 0) return ret; return len; } -static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev, +static int tsl2772_read_interrupt_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); if (chan->type == IIO_INTENSITY) return chip->settings.als_interrupt_en; @@ -961,30 +962,30 @@ static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev, return chip->settings.prox_interrupt_en; } -static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev, +static int tsl2772_write_interrupt_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, int val) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); if (chan->type == IIO_INTENSITY) chip->settings.als_interrupt_en = val ? true : false; else chip->settings.prox_interrupt_en = val ? true : false; - return tsl2x7x_invoke_change(indio_dev); + return tsl2772_invoke_change(indio_dev); } -static int tsl2x7x_write_event_value(struct iio_dev *indio_dev, +static int tsl2772_write_event_value(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 tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); int ret = -EINVAL, count, persistence; u8 time; @@ -1026,7 +1027,7 @@ static int tsl2x7x_write_event_value(struct iio_dev *indio_dev, count = 256 - time; persistence = ((val * 1000000) + val2) / - (count * tsl2x7x_int_time_avail[chip->id][3]); + (count * tsl2772_int_time_avail[chip->id][3]); if (chan->type == IIO_INTENSITY) { /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */ @@ -1047,17 +1048,17 @@ static int tsl2x7x_write_event_value(struct iio_dev *indio_dev, if (ret < 0) return ret; - return tsl2x7x_invoke_change(indio_dev); + return tsl2772_invoke_change(indio_dev); } -static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, +static int tsl2772_read_event_value(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 tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); int filter_delay, persistence; u8 time; @@ -1101,7 +1102,7 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, } filter_delay = persistence * (256 - time) * - tsl2x7x_int_time_avail[chip->id][3]; + tsl2772_int_time_avail[chip->id][3]; *val = filter_delay / 1000000; *val2 = filter_delay % 1000000; @@ -1111,19 +1112,19 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev, } } -static int tsl2x7x_read_raw(struct iio_dev *indio_dev, +static int tsl2772_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); switch (mask) { case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: - tsl2x7x_get_lux(indio_dev); + tsl2772_get_lux(indio_dev); *val = chip->als_cur_info.lux; return IIO_VAL_INT; default: @@ -1132,14 +1133,14 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_INTENSITY: - tsl2x7x_get_lux(indio_dev); + tsl2772_get_lux(indio_dev); if (chan->channel == 0) *val = chip->als_cur_info.als_ch0; else *val = chip->als_cur_info.als_ch1; return IIO_VAL_INT; case IIO_PROXIMITY: - tsl2x7x_get_prox(indio_dev); + tsl2772_get_prox(indio_dev); *val = chip->prox_data; return IIO_VAL_INT; default: @@ -1148,9 +1149,9 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_CALIBSCALE: if (chan->type == IIO_LIGHT) - *val = tsl2x7x_als_gain[chip->settings.als_gain]; + *val = tsl2772_als_gain[chip->settings.als_gain]; else - *val = tsl2x7x_prox_gain[chip->settings.prox_gain]; + *val = tsl2772_prox_gain[chip->settings.prox_gain]; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: *val = chip->settings.als_gain_trim; @@ -1158,20 +1159,20 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_INT_TIME: *val = 0; *val2 = (256 - chip->settings.als_time) * - tsl2x7x_int_time_avail[chip->id][3]; + tsl2772_int_time_avail[chip->id][3]; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } } -static int tsl2x7x_write_raw(struct iio_dev *indio_dev, +static int tsl2772_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); switch (mask) { case IIO_CHAN_INFO_CALIBSCALE: @@ -1212,25 +1213,25 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev, } break; case IIO_CHAN_INFO_CALIBBIAS: - if (val < TSL2X7X_ALS_GAIN_TRIM_MIN || - val > TSL2X7X_ALS_GAIN_TRIM_MAX) + if (val < TSL2772_ALS_GAIN_TRIM_MIN || + val > TSL2772_ALS_GAIN_TRIM_MAX) return -EINVAL; chip->settings.als_gain_trim = val; break; case IIO_CHAN_INFO_INT_TIME: - if (val != 0 || val2 < tsl2x7x_int_time_avail[chip->id][1] || - val2 > tsl2x7x_int_time_avail[chip->id][5]) + if (val != 0 || val2 < tsl2772_int_time_avail[chip->id][1] || + val2 > tsl2772_int_time_avail[chip->id][5]) return -EINVAL; chip->settings.als_time = 256 - - (val2 / tsl2x7x_int_time_avail[chip->id][3]); + (val2 / tsl2772_int_time_avail[chip->id][3]); break; default: return -EINVAL; } - return tsl2x7x_invoke_change(indio_dev); + return tsl2772_invoke_change(indio_dev); } static DEVICE_ATTR_RW(in_illuminance0_target_input); @@ -1242,7 +1243,7 @@ static DEVICE_ATTR_WO(in_proximity0_calibrate); static DEVICE_ATTR_RW(in_illuminance0_lux_table); /* Use the default register values to identify the Taos device */ -static int tsl2x7x_device_id_verif(int id, int target) +static int tsl2772_device_id_verif(int id, int target) { switch (target) { case tsl2571: @@ -1263,19 +1264,19 @@ static int tsl2x7x_device_id_verif(int id, int target) return -EINVAL; } -static irqreturn_t tsl2x7x_event_handler(int irq, void *private) +static irqreturn_t tsl2772_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev); int ret; - ret = tsl2x7x_read_status(chip); + ret = tsl2772_read_status(chip); if (ret < 0) return IRQ_HANDLED; /* What type of interrupt do we need to process */ - if (ret & TSL2X7X_STA_PRX_INTR) { + if (ret & TSL2772_STA_PRX_INTR) { iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, @@ -1284,7 +1285,7 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) timestamp); } - if (ret & TSL2X7X_STA_ALS_INTR) { + if (ret & TSL2772_STA_ALS_INTR) { iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, @@ -1294,8 +1295,8 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) } ret = i2c_smbus_write_byte(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | - TSL2X7X_CMD_PROXALS_INT_CLR); + TSL2772_CMD_REG | TSL2772_CMD_SPL_FN | + TSL2772_CMD_PROXALS_INT_CLR); if (ret < 0) dev_err(&chip->client->dev, "%s: failed to clear interrupt status: %d\n", @@ -1304,31 +1305,31 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) return IRQ_HANDLED; } -static struct attribute *tsl2x7x_ALS_device_attrs[] = { +static struct attribute *tsl2772_ALS_device_attrs[] = { &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, NULL }; -static struct attribute *tsl2x7x_PRX_device_attrs[] = { +static struct attribute *tsl2772_PRX_device_attrs[] = { &dev_attr_in_proximity0_calibrate.attr, NULL }; -static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { +static struct attribute *tsl2772_ALSPRX_device_attrs[] = { &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, NULL }; -static struct attribute *tsl2x7x_PRX2_device_attrs[] = { +static struct attribute *tsl2772_PRX2_device_attrs[] = { &dev_attr_in_proximity0_calibrate.attr, NULL }; -static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { +static struct attribute *tsl2772_ALSPRX2_device_attrs[] = { &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1336,45 +1337,45 @@ static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { NULL }; -static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = { +static const struct attribute_group tsl2772_device_attr_group_tbl[] = { [ALS] = { - .attrs = tsl2x7x_ALS_device_attrs, + .attrs = tsl2772_ALS_device_attrs, }, [PRX] = { - .attrs = tsl2x7x_PRX_device_attrs, + .attrs = tsl2772_PRX_device_attrs, }, [ALSPRX] = { - .attrs = tsl2x7x_ALSPRX_device_attrs, + .attrs = tsl2772_ALSPRX_device_attrs, }, [PRX2] = { - .attrs = tsl2x7x_PRX2_device_attrs, + .attrs = tsl2772_PRX2_device_attrs, }, [ALSPRX2] = { - .attrs = tsl2x7x_ALSPRX2_device_attrs, + .attrs = tsl2772_ALSPRX2_device_attrs, }, }; -#define TSL2X7X_DEVICE_INFO(type)[type] = \ +#define TSL2772_DEVICE_INFO(type)[type] = \ { \ - .attrs = &tsl2X7X_device_attr_group_tbl[type], \ - .read_raw = &tsl2x7x_read_raw, \ - .read_avail = &tsl2x7x_read_avail, \ - .write_raw = &tsl2x7x_write_raw, \ - .read_event_value = &tsl2x7x_read_event_value, \ - .write_event_value = &tsl2x7x_write_event_value, \ - .read_event_config = &tsl2x7x_read_interrupt_config, \ - .write_event_config = &tsl2x7x_write_interrupt_config, \ + .attrs = &tsl2772_device_attr_group_tbl[type], \ + .read_raw = &tsl2772_read_raw, \ + .read_avail = &tsl2772_read_avail, \ + .write_raw = &tsl2772_write_raw, \ + .read_event_value = &tsl2772_read_event_value, \ + .write_event_value = &tsl2772_write_event_value, \ + .read_event_config = &tsl2772_read_interrupt_config, \ + .write_event_config = &tsl2772_write_interrupt_config, \ } -static const struct iio_info tsl2X7X_device_info[] = { - TSL2X7X_DEVICE_INFO(ALS), - TSL2X7X_DEVICE_INFO(PRX), - TSL2X7X_DEVICE_INFO(ALSPRX), - TSL2X7X_DEVICE_INFO(PRX2), - TSL2X7X_DEVICE_INFO(ALSPRX2), +static const struct iio_info tsl2772_device_info[] = { + TSL2772_DEVICE_INFO(ALS), + TSL2772_DEVICE_INFO(PRX), + TSL2772_DEVICE_INFO(ALSPRX), + TSL2772_DEVICE_INFO(PRX2), + TSL2772_DEVICE_INFO(ALSPRX2), }; -static const struct iio_event_spec tsl2x7x_events[] = { +static const struct iio_event_spec tsl2772_events[] = { { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_RISING, @@ -1391,7 +1392,7 @@ static const struct iio_event_spec tsl2x7x_events[] = { }, }; -static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { +static const struct tsl2772_chip_info tsl2772_chip_info_tbl[] = { [ALS] = { .channel_with_events = { { @@ -1410,8 +1411,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, { .type = IIO_INTENSITY, .indexed = 1, @@ -1442,7 +1443,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { }, }, .chan_table_elements = 3, - .info = &tsl2X7X_device_info[ALS], + .info = &tsl2772_device_info[ALS], }, [PRX] = { .channel_with_events = { @@ -1451,8 +1452,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .indexed = 1, .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, }, .channel_without_events = { @@ -1464,7 +1465,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { }, }, .chan_table_elements = 1, - .info = &tsl2X7X_device_info[PRX], + .info = &tsl2772_device_info[PRX], }, [ALSPRX] = { .channel_with_events = { @@ -1484,8 +1485,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, { .type = IIO_INTENSITY, .indexed = 1, @@ -1496,8 +1497,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .indexed = 1, .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, }, .channel_without_events = { @@ -1530,7 +1531,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { }, }, .chan_table_elements = 4, - .info = &tsl2X7X_device_info[ALSPRX], + .info = &tsl2772_device_info[ALSPRX], }, [PRX2] = { .channel_with_events = { @@ -1542,8 +1543,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_CALIBSCALE), .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBSCALE), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, }, .channel_without_events = { @@ -1558,7 +1559,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { }, }, .chan_table_elements = 1, - .info = &tsl2X7X_device_info[PRX2], + .info = &tsl2772_device_info[PRX2], }, [ALSPRX2] = { .channel_with_events = { @@ -1578,8 +1579,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_CALIBSCALE), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, { .type = IIO_INTENSITY, .indexed = 1, @@ -1593,8 +1594,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { BIT(IIO_CHAN_INFO_CALIBSCALE), .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBSCALE), - .event_spec = tsl2x7x_events, - .num_event_specs = ARRAY_SIZE(tsl2x7x_events), + .event_spec = tsl2772_events, + .num_event_specs = ARRAY_SIZE(tsl2772_events), }, }, .channel_without_events = { @@ -1630,15 +1631,15 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { }, }, .chan_table_elements = 4, - .info = &tsl2X7X_device_info[ALSPRX2], + .info = &tsl2772_device_info[ALSPRX2], }, }; -static int tsl2x7x_probe(struct i2c_client *clientp, +static int tsl2772_probe(struct i2c_client *clientp, const struct i2c_device_id *id) { struct iio_dev *indio_dev; - struct tsl2X7X_chip *chip; + struct tsl2772_chip *chip; int ret; indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip)); @@ -1650,18 +1651,18 @@ static int tsl2x7x_probe(struct i2c_client *clientp, i2c_set_clientdata(clientp, indio_dev); ret = i2c_smbus_read_byte_data(chip->client, - TSL2X7X_CMD_REG | TSL2X7X_CHIPID); + TSL2772_CMD_REG | TSL2772_CHIPID); if (ret < 0) return ret; - if (tsl2x7x_device_id_verif(ret, id->driver_data) <= 0) { + if (tsl2772_device_id_verif(ret, id->driver_data) <= 0) { dev_info(&chip->client->dev, "%s: i2c device found does not match expected id\n", __func__); return -EINVAL; } - ret = i2c_smbus_write_byte(clientp, TSL2X7X_CMD_REG | TSL2X7X_CNTRL); + ret = i2c_smbus_write_byte(clientp, TSL2772_CMD_REG | TSL2772_CNTRL); if (ret < 0) { dev_err(&clientp->dev, "%s: Failed to write to CMD register: %d\n", @@ -1672,11 +1673,11 @@ static int tsl2x7x_probe(struct i2c_client *clientp, mutex_init(&chip->als_mutex); mutex_init(&chip->prox_mutex); - chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN; + chip->tsl2772_chip_status = TSL2772_CHIP_UNKNOWN; chip->pdata = dev_get_platdata(&clientp->dev); chip->id = id->driver_data; chip->chip_info = - &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]]; + &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]]; indio_dev->info = chip->chip_info->info; indio_dev->dev.parent = &clientp->dev; @@ -1689,10 +1690,10 @@ static int tsl2x7x_probe(struct i2c_client *clientp, ret = devm_request_threaded_irq(&clientp->dev, clientp->irq, NULL, - &tsl2x7x_event_handler, + &tsl2772_event_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "TSL2X7X_event", + "TSL2772_event", indio_dev); if (ret) { dev_err(&clientp->dev, @@ -1703,14 +1704,14 @@ static int tsl2x7x_probe(struct i2c_client *clientp, indio_dev->channels = chip->chip_info->channel_without_events; } - tsl2x7x_defaults(chip); - ret = tsl2x7x_chip_on(indio_dev); + tsl2772_defaults(chip); + ret = tsl2772_chip_on(indio_dev); if (ret < 0) return ret; ret = iio_device_register(indio_dev); if (ret) { - tsl2x7x_chip_off(indio_dev); + tsl2772_chip_off(indio_dev); dev_err(&clientp->dev, "%s: iio registration failed\n", __func__); return ret; @@ -1719,32 +1720,32 @@ static int tsl2x7x_probe(struct i2c_client *clientp, return 0; } -static int tsl2x7x_suspend(struct device *dev) +static int tsl2772_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - return tsl2x7x_chip_off(indio_dev); + return tsl2772_chip_off(indio_dev); } -static int tsl2x7x_resume(struct device *dev) +static int tsl2772_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - return tsl2x7x_chip_on(indio_dev); + return tsl2772_chip_on(indio_dev); } -static int tsl2x7x_remove(struct i2c_client *client) +static int tsl2772_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); - tsl2x7x_chip_off(indio_dev); + tsl2772_chip_off(indio_dev); iio_device_unregister(indio_dev); return 0; } -static const struct i2c_device_id tsl2x7x_idtable[] = { +static const struct i2c_device_id tsl2772_idtable[] = { { "tsl2571", tsl2571 }, { "tsl2671", tsl2671 }, { "tmd2671", tmd2671 }, @@ -1758,9 +1759,9 @@ static const struct i2c_device_id tsl2x7x_idtable[] = { {} }; -MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable); +MODULE_DEVICE_TABLE(i2c, tsl2772_idtable); -static const struct of_device_id tsl2x7x_of_match[] = { +static const struct of_device_id tsl2772_of_match[] = { { .compatible = "amstaos,tsl2571" }, { .compatible = "amstaos,tsl2671" }, { .compatible = "amstaos,tmd2671" }, @@ -1773,27 +1774,27 @@ static const struct of_device_id tsl2x7x_of_match[] = { { .compatible = "amstaos,tmd2772" }, {} }; -MODULE_DEVICE_TABLE(of, tsl2x7x_of_match); +MODULE_DEVICE_TABLE(of, tsl2772_of_match); -static const struct dev_pm_ops tsl2x7x_pm_ops = { - .suspend = tsl2x7x_suspend, - .resume = tsl2x7x_resume, +static const struct dev_pm_ops tsl2772_pm_ops = { + .suspend = tsl2772_suspend, + .resume = tsl2772_resume, }; -static struct i2c_driver tsl2x7x_driver = { +static struct i2c_driver tsl2772_driver = { .driver = { - .name = "tsl2x7x", - .of_match_table = tsl2x7x_of_match, - .pm = &tsl2x7x_pm_ops, + .name = "tsl2772", + .of_match_table = tsl2772_of_match, + .pm = &tsl2772_pm_ops, }, - .id_table = tsl2x7x_idtable, - .probe = tsl2x7x_probe, - .remove = tsl2x7x_remove, + .id_table = tsl2772_idtable, + .probe = tsl2772_probe, + .remove = tsl2772_remove, }; -module_i2c_driver(tsl2x7x_driver); +module_i2c_driver(tsl2772_driver); MODULE_AUTHOR("J. August Brenner "); MODULE_AUTHOR("Brian Masney "); -MODULE_DESCRIPTION("TAOS tsl2x7x ambient and proximity light sensor driver"); +MODULE_DESCRIPTION("TAOS tsl2772 ambient and proximity light sensor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/light/tsl2x7x.h b/drivers/staging/iio/light/tsl2772.h similarity index 70% rename from drivers/staging/iio/light/tsl2x7x.h rename to drivers/staging/iio/light/tsl2772.h index b86f6b260f9f..f8ade15a35e2 100644 --- a/drivers/staging/iio/light/tsl2x7x.h +++ b/drivers/staging/iio/light/tsl2772.h @@ -1,50 +1,51 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* * Device driver for monitoring ambient light intensity (lux) - * and proximity (prox) within the TAOS TSL2X7X family of devices. + * and proximity (prox) within the TAOS TSL2772 family of devices. * * Copyright (c) 2012, TAOS Corporation. + * Copyright (c) 2017-2018 Brian Masney */ -#ifndef __TSL2X7X_H -#define __TSL2X7X_H +#ifndef __TSL2772_H +#define __TSL2772_H -struct tsl2x7x_lux { +struct tsl2772_lux { unsigned int ch0; unsigned int ch1; }; /* Max number of segments allowable in LUX table */ -#define TSL2X7X_MAX_LUX_TABLE_SIZE 6 +#define TSL2772_MAX_LUX_TABLE_SIZE 6 /* The default LUX tables all have 3 elements. */ -#define TSL2X7X_DEF_LUX_TABLE_SZ 3 -#define TSL2X7X_DEFAULT_TABLE_BYTES (sizeof(struct tsl2x7x_lux) * \ - TSL2X7X_DEF_LUX_TABLE_SZ) +#define TSL2772_DEF_LUX_TABLE_SZ 3 +#define TSL2772_DEFAULT_TABLE_BYTES (sizeof(struct tsl2772_lux) * \ + TSL2772_DEF_LUX_TABLE_SZ) /* Proximity diode to use */ -#define TSL2X7X_DIODE0 0x01 -#define TSL2X7X_DIODE1 0x02 -#define TSL2X7X_DIODE_BOTH 0x03 +#define TSL2772_DIODE0 0x01 +#define TSL2772_DIODE1 0x02 +#define TSL2772_DIODE_BOTH 0x03 /* LED Power */ -#define TSL2X7X_100_mA 0x00 -#define TSL2X7X_50_mA 0x01 -#define TSL2X7X_25_mA 0x02 -#define TSL2X7X_13_mA 0x03 +#define TSL2772_100_mA 0x00 +#define TSL2772_50_mA 0x01 +#define TSL2772_25_mA 0x02 +#define TSL2772_13_mA 0x03 /** - * struct tsl2x7x_settings - Settings for the tsl2x7x driver + * struct tsl2772_settings - Settings for the tsl2772 driver * @als_time: Integration time of the ALS channel ADCs in 2.73 ms * increments. Total integration time is * (256 - als_time) * 2.73. - * @als_gain: Index into the tsl2x7x_als_gain array. + * @als_gain: Index into the tsl2772_als_gain array. * @als_gain_trim: Default gain trim to account for aperture effects. * @wait_time: Time between proximity and ALS cycles in 2.73 * periods. * @prox_time: Integration time of the proximity ADC in 2.73 ms * increments. Total integration time is * (256 - prx_time) * 2.73. - * @prox_gain: Index into the tsl2x7x_prx_gain array. + * @prox_gain: Index into the tsl2772_prx_gain array. * @als_prox_config: The value of the ALS / Proximity configuration * register. * @als_cal_target: Known external ALS reading for calibration. @@ -64,7 +65,7 @@ struct tsl2x7x_lux { * LED(s) for proximity sensing. * @prox_power The amount of power to use for the external LED(s). */ -struct tsl2x7x_settings { +struct tsl2772_settings { int als_time; int als_gain; int als_gain_trim; @@ -88,13 +89,13 @@ struct tsl2x7x_settings { }; /** - * struct tsl2X7X_platform_data - Platform callback, glass and defaults + * struct tsl2772_platform_data - Platform callback, glass and defaults * @platform_lux_table: Device specific glass coefficents * @platform_default_settings: Device specific power on defaults */ -struct tsl2X7X_platform_data { - struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE]; - struct tsl2x7x_settings *platform_default_settings; +struct tsl2772_platform_data { + struct tsl2772_lux platform_lux_table[TSL2772_MAX_LUX_TABLE_SIZE]; + struct tsl2772_settings *platform_default_settings; }; -#endif /* __TSL2X7X_H */ +#endif /* __TSL2772_H */ From c06c4d793584b965bf5fa3fb107f6279643574e2 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 May 2018 20:12:23 -0400 Subject: [PATCH 15/42] staging: iio: tsl2x7x/tsl2772: move out of staging Move the tsl2772 driver out of staging and into mainline. Signed-off-by: Brian Masney Signed-off-by: Jonathan Cameron --- drivers/iio/light/Kconfig | 8 ++++++++ drivers/iio/light/Makefile | 1 + drivers/{staging => }/iio/light/tsl2772.c | 2 +- drivers/staging/iio/Kconfig | 1 - drivers/staging/iio/Makefile | 1 - drivers/staging/iio/light/Kconfig | 14 -------------- drivers/staging/iio/light/Makefile | 5 ----- .../linux/platform_data}/tsl2772.h | 0 8 files changed, 10 insertions(+), 22 deletions(-) rename drivers/{staging => }/iio/light/tsl2772.c (99%) delete mode 100644 drivers/staging/iio/light/Kconfig delete mode 100644 drivers/staging/iio/light/Makefile rename {drivers/staging/iio/light => include/linux/platform_data}/tsl2772.h (100%) diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 074e50657366..c7ef8d1862d6 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -409,6 +409,14 @@ config TSL2583 Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices. Access ALS data via iio, sysfs. +config TSL2772 + tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors" + depends on I2C + help + Support for: tsl2571, tsl2671, tmd2671, tsl2771, tmd2771, tsl2572, tsl2672, + tmd2672, tsl2772, tmd2772 devices. + Provides iio_events and direct access via sysfs. + config TSL4531 tristate "TAOS TSL4531 ambient light sensors" depends on I2C diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index f1777036d4f8..80943af5d627 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_ST_UVIS25_SPI) += st_uvis25_spi.o obj-$(CONFIG_TCS3414) += tcs3414.o obj-$(CONFIG_TCS3472) += tcs3472.o obj-$(CONFIG_TSL2583) += tsl2583.o +obj-$(CONFIG_TSL2772) += tsl2772.o obj-$(CONFIG_TSL4531) += tsl4531.o obj-$(CONFIG_US5182D) += us5182d.o obj-$(CONFIG_VCNL4000) += vcnl4000.o diff --git a/drivers/staging/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c similarity index 99% rename from drivers/staging/iio/light/tsl2772.c rename to drivers/iio/light/tsl2772.c index a59bf39c28d4..34d42a2504c9 100644 --- a/drivers/staging/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -19,7 +19,7 @@ #include #include #include -#include "tsl2772.h" +#include /* Cal defs */ #define PROX_STAT_CAL 0 diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index bd9445956511..aee2335a25a1 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -11,7 +11,6 @@ source "drivers/staging/iio/cdc/Kconfig" source "drivers/staging/iio/frequency/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/impedance-analyzer/Kconfig" -source "drivers/staging/iio/light/Kconfig" source "drivers/staging/iio/meter/Kconfig" source "drivers/staging/iio/resolver/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index e99a375c07b9..c28d657497de 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -10,6 +10,5 @@ obj-y += cdc/ obj-y += frequency/ obj-y += gyro/ obj-y += impedance-analyzer/ -obj-y += light/ obj-y += meter/ obj-y += resolver/ diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig deleted file mode 100644 index dfa37386ad2c..000000000000 --- a/drivers/staging/iio/light/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# -# Light sensors -# -menu "Light sensors" - -config TSL2772 - tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors" - depends on I2C - help - Support for: tsl2571, tsl2671, tmd2671, tsl2771, tmd2771, tsl2572, tsl2672, - tmd2672, tsl2772, tmd2772 devices. - Provides iio_events and direct access via sysfs. - -endmenu diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile deleted file mode 100644 index e7e77a11f02a..000000000000 --- a/drivers/staging/iio/light/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for industrial I/O Light sensors -# - -obj-$(CONFIG_TSL2772) += tsl2772.o diff --git a/drivers/staging/iio/light/tsl2772.h b/include/linux/platform_data/tsl2772.h similarity index 100% rename from drivers/staging/iio/light/tsl2772.h rename to include/linux/platform_data/tsl2772.h From 4833dc4bb98ec40010957215b8127a454bbaea8e Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Sat, 12 May 2018 20:20:39 -0400 Subject: [PATCH 16/42] iio: tsl2583: correct values in integration_time_available The times reported by the in_illuminance_integration_time_available sysfs attribute are actually in milliseconds, not microseconds. This patch corrects the times with the correct unit. The fixes tag is inaccurate as the issue existed when the driver was still in staging. However, lots of changes occured before it graduated so this is as a good a point as any for backports. Signed-off-by: Brian Masney Fixes: f44d5c8ac399 ("staging: iio: tsl2583: move out of staging") Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2583.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c index f2e50edaa242..4b5d9988f025 100644 --- a/drivers/iio/light/tsl2583.c +++ b/drivers/iio/light/tsl2583.c @@ -600,7 +600,7 @@ done: static IIO_CONST_ATTR(in_illuminance_calibscale_available, "1 8 16 111"); static IIO_CONST_ATTR(in_illuminance_integration_time_available, - "0.000050 0.000100 0.000150 0.000200 0.000250 0.000300 0.000350 0.000400 0.000450 0.000500 0.000550 0.000600 0.000650"); + "0.050 0.100 0.150 0.200 0.250 0.300 0.350 0.400 0.450 0.500 0.550 0.600 0.650"); static IIO_DEVICE_ATTR_RW(in_illuminance_input_target, 0); static IIO_DEVICE_ATTR_WO(in_illuminance_calibrate, 0); static IIO_DEVICE_ATTR_RW(in_illuminance_lux_table, 0); From bed1895e78b510ecc425ab01ef96ddba0881acc5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 15 May 2018 15:06:24 +0200 Subject: [PATCH 17/42] dt-bindings: iio: afe: Spelling s/mesaurement/measurement/ Signed-off-by: Geert Uytterhoeven Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/afe/current-sense-amplifier.txt | 2 +- .../devicetree/bindings/iio/afe/current-sense-shunt.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.txt b/Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.txt index 0ddbaebba8ce..821b61b8c542 100644 --- a/Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.txt +++ b/Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.txt @@ -2,7 +2,7 @@ Current Sense Amplifier ======================= When an io-channel measures the output voltage from a current sense -amplifier, the interesting mesaurement is almost always the current +amplifier, the interesting measurement is almost always the current through the sense resistor, not the voltage output. This binding describes such a current sense circuit. diff --git a/Documentation/devicetree/bindings/iio/afe/current-sense-shunt.txt b/Documentation/devicetree/bindings/iio/afe/current-sense-shunt.txt index 8e7b3e408a52..0f67108a07b6 100644 --- a/Documentation/devicetree/bindings/iio/afe/current-sense-shunt.txt +++ b/Documentation/devicetree/bindings/iio/afe/current-sense-shunt.txt @@ -2,7 +2,7 @@ Current Sense Shunt =================== When an io-channel measures the voltage over a current sense shunt, -the interesting mesaurement is almost always the current through the +the interesting measurement is almost always the current through the shunt, not the voltage over it. This binding describes such a current sense circuit. From ed582db639cfe65e2d901fca1be8fd813a18fec4 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Tue, 15 May 2018 17:19:17 +0200 Subject: [PATCH 18/42] iio: adc: stm32-dfsdm: include stm32-dfsdm-adc.h Fix the following sparse warnings: CHECK drivers/iio/adc/stm32-dfsdm-adc.c symbol 'stm32_dfsdm_get_buff_cb' was not declared. Should it be static? symbol 'stm32_dfsdm_release_buff_cb' was not declared. Should it be static? BTW, move interrupt.h to sort headers alphabetically. Signed-off-by: Fabrice Gasnier Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-dfsdm-adc.c | 4 ++-- include/linux/iio/adc/stm32-dfsdm-adc.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 1b78becaba5d..31462aef7238 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -8,11 +8,11 @@ #include #include -#include +#include #include #include -#include #include +#include #include #include #include diff --git a/include/linux/iio/adc/stm32-dfsdm-adc.h b/include/linux/iio/adc/stm32-dfsdm-adc.h index e7dc7a542a4e..0da298b41737 100644 --- a/include/linux/iio/adc/stm32-dfsdm-adc.h +++ b/include/linux/iio/adc/stm32-dfsdm-adc.h @@ -9,6 +9,8 @@ #ifndef STM32_DFSDM_ADC_H #define STM32_DFSDM_ADC_H +#include + int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev, int (*cb)(const void *data, size_t size, void *private), From be1b24d2454117113260f2fe59a427d01de4e131 Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Fri, 18 May 2018 18:22:50 +0300 Subject: [PATCH 19/42] iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support The AD5691R/AD5692R/AD5693/AD5693R are a family of one channel DACs with 12-bit, 14-bit and 16-bit precision respectively. The devices have either no built-in reference, or built-in 2.5V reference. These devices are pretty similar to AD5671R/AD5675R and AD5694/AD5694R/AD5695R/AD5696/AD5696R, except that they have one channel. Another difference is that they use a write control register(addr 0x04) for setting the power down modes and the internal reference instead of separate registers for each function. Datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/AD5693R_5692R_5691R_5693.pdf Signed-off-by: Stefan Popa Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 93 +++++++++++++++++++++++++++++++++--- drivers/iio/dac/ad5686.h | 16 +++++++ drivers/iio/dac/ad5696-i2c.c | 7 ++- 3 files changed, 109 insertions(+), 7 deletions(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 89c5f089ae7f..1fc0c5642209 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -70,6 +70,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, bool readin; int ret; struct ad5686_state *st = iio_priv(indio_dev); + unsigned int val, ref_bit_msk; + u8 shift; ret = strtobool(buf, &readin); if (ret) @@ -80,9 +82,24 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, else st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); - ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, 0, - st->pwr_down_mask & st->pwr_down_mode); + switch (st->chip_info->regmap_type) { + case AD5686_REGMAP: + shift = 0; + ref_bit_msk = 0; + break; + case AD5693_REGMAP: + shift = 13; + ref_bit_msk = AD5693_REF_BIT_MSK; + break; + default: + return -EINVAL; + } + val = ((st->pwr_down_mask & st->pwr_down_mode) << shift); + if (!st->use_internal_vref) + val |= ref_bit_msk; + + ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, 0, val); return ret ? ret : len; } @@ -175,6 +192,11 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { .ext_info = ad5686_ext_info, \ } +#define DECLARE_AD5693_CHANNELS(name, bits, _shift) \ +static struct iio_chan_spec name[] = { \ + AD5868_CHANNEL(0, 0, bits, _shift), \ +} + #define DECLARE_AD5686_CHANNELS(name, bits, _shift) \ static struct iio_chan_spec name[] = { \ AD5868_CHANNEL(0, 1, bits, _shift), \ @@ -200,72 +222,112 @@ DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0); DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4); DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2); DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0); +DECLARE_AD5693_CHANNELS(ad5693_channels, 16, 0); +DECLARE_AD5693_CHANNELS(ad5692r_channels, 14, 2); +DECLARE_AD5693_CHANNELS(ad5691r_channels, 12, 4); static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { [ID_AD5671R] = { .channels = ad5672_channels, .int_vref_mv = 2500, .num_channels = 8, + .regmap_type = AD5686_REGMAP, }, [ID_AD5672R] = { .channels = ad5672_channels, .int_vref_mv = 2500, .num_channels = 8, + .regmap_type = AD5686_REGMAP, }, [ID_AD5675R] = { .channels = ad5676_channels, .int_vref_mv = 2500, .num_channels = 8, + .regmap_type = AD5686_REGMAP, }, [ID_AD5676] = { .channels = ad5676_channels, .num_channels = 8, + .regmap_type = AD5686_REGMAP, }, [ID_AD5676R] = { .channels = ad5676_channels, .int_vref_mv = 2500, .num_channels = 8, + .regmap_type = AD5686_REGMAP, }, [ID_AD5684] = { .channels = ad5684_channels, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5684R] = { .channels = ad5684_channels, .int_vref_mv = 2500, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5685R] = { .channels = ad5685r_channels, .int_vref_mv = 2500, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5686] = { .channels = ad5686_channels, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5686R] = { .channels = ad5686_channels, .int_vref_mv = 2500, .num_channels = 4, + .regmap_type = AD5686_REGMAP, + }, + [ID_AD5691R] = { + .channels = ad5691r_channels, + .int_vref_mv = 2500, + .num_channels = 1, + .regmap_type = AD5693_REGMAP, + }, + [ID_AD5692R] = { + .channels = ad5692r_channels, + .int_vref_mv = 2500, + .num_channels = 1, + .regmap_type = AD5693_REGMAP, + }, + [ID_AD5693] = { + .channels = ad5693_channels, + .num_channels = 1, + .regmap_type = AD5693_REGMAP, + }, + [ID_AD5693R] = { + .channels = ad5693_channels, + .int_vref_mv = 2500, + .num_channels = 1, + .regmap_type = AD5693_REGMAP, }, [ID_AD5694] = { .channels = ad5684_channels, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5694R] = { .channels = ad5684_channels, .int_vref_mv = 2500, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5696] = { .channels = ad5686_channels, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, [ID_AD5696R] = { .channels = ad5686_channels, .int_vref_mv = 2500, .num_channels = 4, + .regmap_type = AD5686_REGMAP, }, }; @@ -276,7 +338,9 @@ int ad5686_probe(struct device *dev, { struct ad5686_state *st; struct iio_dev *indio_dev; - int ret, voltage_uv = 0; + unsigned int val, ref_bit_msk; + u8 cmd; + int ret, i, voltage_uv = 0; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (indio_dev == NULL) @@ -310,7 +374,8 @@ int ad5686_probe(struct device *dev, st->vref_mv = st->chip_info->int_vref_mv; /* Set all the power down mode for all channels to 1K pulldown */ - st->pwr_down_mode = 0x55; + for (i = 0; i < st->chip_info->num_channels; i++) + st->pwr_down_mode |= (0x01 << (i * 2)); indio_dev->dev.parent = dev; indio_dev->name = name; @@ -319,8 +384,24 @@ int ad5686_probe(struct device *dev, indio_dev->channels = st->chip_info->channels; indio_dev->num_channels = st->chip_info->num_channels; - ret = st->write(st, AD5686_CMD_INTERNAL_REFER_SETUP, - 0, !!voltage_uv); + switch (st->chip_info->regmap_type) { + case AD5686_REGMAP: + cmd = AD5686_CMD_INTERNAL_REFER_SETUP; + ref_bit_msk = 0; + break; + case AD5693_REGMAP: + cmd = AD5686_CMD_CONTROL_REG; + ref_bit_msk = AD5693_REF_BIT_MSK; + st->use_internal_vref = !voltage_uv; + break; + default: + ret = -EINVAL; + goto error_disable_reg; + } + + val = (voltage_uv | ref_bit_msk); + + ret = st->write(st, cmd, 0, !!val); if (ret) goto error_disable_reg; diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 05f0ce9d2de1..6c6879db60e4 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -35,6 +35,9 @@ #define AD5686_LDAC_PWRDN_100K 0x2 #define AD5686_LDAC_PWRDN_3STATE 0x3 +#define AD5686_CMD_CONTROL_REG 0x4 +#define AD5693_REF_BIT_MSK BIT(12) + /** * ad5686_supported_device_ids: */ @@ -49,6 +52,10 @@ enum ad5686_supported_device_ids { ID_AD5685R, ID_AD5686, ID_AD5686R, + ID_AD5691R, + ID_AD5692R, + ID_AD5693, + ID_AD5693R, ID_AD5694, ID_AD5694R, ID_AD5695R, @@ -56,6 +63,11 @@ enum ad5686_supported_device_ids { ID_AD5696R, }; +enum ad5686_regmap_type { + AD5686_REGMAP, + AD5693_REGMAP +}; + struct ad5686_state; typedef int (*ad5686_write_func)(struct ad5686_state *st, @@ -68,12 +80,14 @@ typedef int (*ad5686_read_func)(struct ad5686_state *st, u8 addr); * @int_vref_mv: AD5620/40/60: the internal reference voltage * @num_channels: number of channels * @channel: channel specification + * @regmap_type: register map layout variant */ struct ad5686_chip_info { u16 int_vref_mv; unsigned int num_channels; struct iio_chan_spec *channels; + enum ad5686_regmap_type regmap_type; }; /** @@ -84,6 +98,7 @@ struct ad5686_chip_info { * @vref_mv: actual reference voltage used * @pwr_down_mask: power down mask * @pwr_down_mode: current power down mode + * @use_internal_vref: set to true if the internal reference voltage is used * @data: spi transfer buffers */ @@ -96,6 +111,7 @@ struct ad5686_state { unsigned int pwr_down_mode; ad5686_write_func write; ad5686_read_func read; + bool use_internal_vref; /* * DMA (thus cache coherency maintenance) requires the diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index 275e0321bcf8..d18735d7d938 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * AD5671R, AD5675R, AD5694, AD5694R, AD5695R, AD5696, AD5696R + * AD5671R, AD5675R, AD5691R, AD5692R, AD5693, AD5693R, + * AD5694, AD5694R, AD5695R, AD5696, AD5696R * Digital to analog converters driver * * Copyright 2018 Analog Devices Inc. @@ -72,6 +73,10 @@ static int ad5686_i2c_remove(struct i2c_client *i2c) static const struct i2c_device_id ad5686_i2c_id[] = { {"ad5671r", ID_AD5671R}, {"ad5675r", ID_AD5675R}, + {"ad5691r", ID_AD5691R}, + {"ad5692r", ID_AD5692R}, + {"ad5693", ID_AD5693}, + {"ad5693r", ID_AD5693R}, {"ad5694", ID_AD5694}, {"ad5694r", ID_AD5694R}, {"ad5695r", ID_AD5695R}, From 1dbae4c6cdeccf87767003a9d3b6d24b40446100 Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Fri, 18 May 2018 18:23:34 +0300 Subject: [PATCH 20/42] iio:dac:ad5686: Add AD5681R/AD5682R/AD5683/AD5683R support The AD5681R/AD5682R/AD5683/AD5683R are a family of one channel DACs with 12-bit, 14-bit and 16-bit precision respectively. The devices have either no built-in reference, or built-in 2.5V reference. These devices are similar to AD5691R/AD5692R/AD5693/AD5693R except with a few notable differences: * they use the SPI interface instead of I2C * in the write control register, DB18 and DB17 are used for setting the power mode, while DB16 is the REF bit. This is why a new regmap type was defined and checked accordingly. * the shift register is 24 bits wide, the first four bits are the command bits followed by the data bits. As the data comprises of 20-bit, 18-bit or 16-bit input code, this means that 4 LSB bits are don't care. This is why the data needs to be shifted on the left with four bits. Therefore, AD5683_REGMAP is checked inside a switch case in the ad5686_spi_write() function. On the other hand, similar devices such as AD5693R family, have the 4 MSB command bits followed by 4 don't care bits. Datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/AD5683R_5682R_5681R_5683.pdf Signed-off-by: Stefan Popa Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686-spi.c | 38 ++++++++++++++++++++++++++++++------ drivers/iio/dac/ad5686.c | 32 ++++++++++++++++++++++++++++++ drivers/iio/dac/ad5686.h | 8 ++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/drivers/iio/dac/ad5686-spi.c b/drivers/iio/dac/ad5686-spi.c index 6bb09e9259e6..1df9143f55e9 100644 --- a/drivers/iio/dac/ad5686-spi.c +++ b/drivers/iio/dac/ad5686-spi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * AD5672R, AD5676, AD5676R, AD5684, AD5684R, AD5684R, AD5685R, AD5686, AD5686R + * AD5672R, AD5676, AD5676R, AD5681R, AD5682R, AD5683, AD5683R, + * AD5684, AD5684R, AD5685R, AD5686, AD5686R * Digital to analog converters driver * * Copyright 2018 Analog Devices Inc. @@ -15,12 +16,27 @@ static int ad5686_spi_write(struct ad5686_state *st, u8 cmd, u8 addr, u16 val) { struct spi_device *spi = to_spi_device(st->dev); + u8 tx_len, *buf; - st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | - AD5686_ADDR(addr) | - val); + switch (st->chip_info->regmap_type) { + case AD5683_REGMAP: + st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | + AD5683_DATA(val)); + buf = &st->data[0].d8[1]; + tx_len = 3; + break; + case AD5686_REGMAP: + st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | + AD5686_ADDR(addr) | + val); + buf = &st->data[0].d8[1]; + tx_len = 3; + break; + default: + return -EINVAL; + } - return spi_write(spi, &st->data[0].d8[1], 3); + return spi_write(spi, buf, tx_len); } static int ad5686_spi_read(struct ad5686_state *st, u8 addr) @@ -37,9 +53,15 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 addr) }, }; struct spi_device *spi = to_spi_device(st->dev); + u8 cmd = 0; int ret; - st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) | + if (st->chip_info->regmap_type == AD5686_REGMAP) + cmd = AD5686_CMD_READBACK_ENABLE; + else if (st->chip_info->regmap_type == AD5683_REGMAP) + cmd = AD5686_CMD_READBACK_ENABLE_V2; + + st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | AD5686_ADDR(addr)); st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP)); @@ -67,6 +89,10 @@ static const struct spi_device_id ad5686_spi_id[] = { {"ad5672r", ID_AD5672R}, {"ad5676", ID_AD5676}, {"ad5676r", ID_AD5676R}, + {"ad5681r", ID_AD5681R}, + {"ad5682r", ID_AD5682R}, + {"ad5683", ID_AD5683}, + {"ad5683r", ID_AD5683R}, {"ad5684", ID_AD5684}, {"ad5684r", ID_AD5684R}, {"ad5685", ID_AD5685R}, /* Does not exist */ diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 1fc0c5642209..e136f0fd38f0 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -83,6 +83,10 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); switch (st->chip_info->regmap_type) { + case AD5683_REGMAP: + shift = 13; + ref_bit_msk = AD5683_REF_BIT_MSK; + break; case AD5686_REGMAP: shift = 0; ref_bit_msk = 0; @@ -256,6 +260,29 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 8, .regmap_type = AD5686_REGMAP, }, + [ID_AD5681R] = { + .channels = ad5691r_channels, + .int_vref_mv = 2500, + .num_channels = 1, + .regmap_type = AD5683_REGMAP, + }, + [ID_AD5682R] = { + .channels = ad5692r_channels, + .int_vref_mv = 2500, + .num_channels = 1, + .regmap_type = AD5683_REGMAP, + }, + [ID_AD5683] = { + .channels = ad5693_channels, + .num_channels = 1, + .regmap_type = AD5683_REGMAP, + }, + [ID_AD5683R] = { + .channels = ad5693_channels, + .int_vref_mv = 2500, + .num_channels = 1, + .regmap_type = AD5683_REGMAP, + }, [ID_AD5684] = { .channels = ad5684_channels, .num_channels = 4, @@ -385,6 +412,11 @@ int ad5686_probe(struct device *dev, indio_dev->num_channels = st->chip_info->num_channels; switch (st->chip_info->regmap_type) { + case AD5683_REGMAP: + cmd = AD5686_CMD_CONTROL_REG; + ref_bit_msk = AD5683_REF_BIT_MSK; + st->use_internal_vref = !voltage_uv; + break; case AD5686_REGMAP: cmd = AD5686_CMD_INTERNAL_REFER_SETUP; ref_bit_msk = 0; diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 6c6879db60e4..d05cda9f1edd 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -13,6 +13,7 @@ #include #include +#define AD5683_DATA(x) ((x) << 4) #define AD5686_ADDR(x) ((x) << 16) #define AD5686_CMD(x) ((x) << 20) @@ -36,6 +37,8 @@ #define AD5686_LDAC_PWRDN_3STATE 0x3 #define AD5686_CMD_CONTROL_REG 0x4 +#define AD5686_CMD_READBACK_ENABLE_V2 0x5 +#define AD5683_REF_BIT_MSK BIT(12) #define AD5693_REF_BIT_MSK BIT(12) /** @@ -47,6 +50,10 @@ enum ad5686_supported_device_ids { ID_AD5675R, ID_AD5676, ID_AD5676R, + ID_AD5681R, + ID_AD5682R, + ID_AD5683, + ID_AD5683R, ID_AD5684, ID_AD5684R, ID_AD5685R, @@ -64,6 +71,7 @@ enum ad5686_supported_device_ids { }; enum ad5686_regmap_type { + AD5683_REGMAP, AD5686_REGMAP, AD5693_REGMAP }; From c8e97b62e16ead1b438a8c1218a56d4509727058 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:21:06 +0200 Subject: [PATCH 21/42] staging: iio: ad2s1200: Remove unneeded newline in license Remove unneeded newline in license, as it does not improve readability. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index ea7336645116..df3b34200a89 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -7,7 +7,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * */ #include From c1b6a7d72d9be356e366df7d252bdbda602339b4 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:21:23 +0200 Subject: [PATCH 22/42] staging: iio: ad2s1200: Remove unneeded initializations Remove 2 initializations which are unneeded, because the initialized values are never used. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index df3b34200a89..9bdcf0c86217 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -47,7 +47,7 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, long m) { struct ad2s1200_state *st = iio_priv(indio_dev); - int ret = 0; + int ret; mutex_lock(&st->lock); gpio_set_value(st->sample, 0); @@ -105,7 +105,7 @@ static int ad2s1200_probe(struct spi_device *spi) unsigned short *pins = spi->dev.platform_data; struct ad2s1200_state *st; struct iio_dev *indio_dev; - int pn, ret = 0; + int pn, ret; for (pn = 0; pn < AD2S1200_PN; pn++) { ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT, From bc683b47c31d68050fd1cd5231804c3be2df1766 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:21:34 +0200 Subject: [PATCH 23/42] staging: iio: ad2s1200: Add kernel docs to driver state Add missing kernel docs to the ad2s1200 driver state. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 9bdcf0c86217..068aa86e9c11 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -32,6 +32,14 @@ /* clock period in nano second */ #define AD2S1200_TSCLK (1000000000 / AD2S1200_HZ) +/** + * struct ad2s1200_state - driver instance specific data. + * @lock: protects both the GPIO pins and the rx buffer. + * @sdev: spi device. + * @sample: GPIO pin SAMPLE. + * @rdvel: GPIO pin RDVEL. + * @rx: buffer for spi transfers. + */ struct ad2s1200_state { struct mutex lock; struct spi_device *sdev; From 94cdefa81b99dd37239cdb147bc5a1473a3cdacc Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:21:44 +0200 Subject: [PATCH 24/42] staging: iio: ad2s1200: Setup spi before iio device register The spi should be set up before the device is registered as an iio device. This patch moves the setup to before the device registration. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 068aa86e9c11..430cc62591fe 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -143,15 +143,16 @@ static int ad2s1200_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels); indio_dev->name = spi_get_device_id(spi)->name; - ret = devm_iio_device_register(&spi->dev, indio_dev); - if (ret) - return ret; - spi->max_speed_hz = AD2S1200_HZ; spi->mode = SPI_MODE_3; - spi_setup(spi); + ret = spi_setup(spi); - return 0; + if (ret < 0) { + dev_err(&spi->dev, "spi_setup failed!\n"); + return ret; + } + + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad2s1200_id[] = { From 5af93e6aa7f8768a75067c13d5d301212954953d Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:21:56 +0200 Subject: [PATCH 25/42] staging: iio: ad2s1200: Replace legacy gpio API with modern API The legacy, integer based gpio API is replaced with the modern descriptor based API. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 430cc62591fe..b2c46a8c6b77 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -43,8 +44,8 @@ struct ad2s1200_state { struct mutex lock; struct spi_device *sdev; - int sample; - int rdvel; + struct gpio_desc *sample; + struct gpio_desc *rdvel; __be16 rx ____cacheline_aligned; }; @@ -58,12 +59,12 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, int ret; mutex_lock(&st->lock); - gpio_set_value(st->sample, 0); + gpiod_set_value(st->sample, 0); /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */ udelay(1); - gpio_set_value(st->sample, 1); - gpio_set_value(st->rdvel, !!(chan->type == IIO_ANGL)); + gpiod_set_value(st->sample, 1); + gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL)); ret = spi_read(st->sdev, &st->rx, 2); if (ret < 0) { @@ -133,8 +134,8 @@ static int ad2s1200_probe(struct spi_device *spi) st = iio_priv(indio_dev); mutex_init(&st->lock); st->sdev = spi; - st->sample = pins[0]; - st->rdvel = pins[1]; + st->sample = gpio_to_desc(pins[0]); + st->rdvel = gpio_to_desc(pins[1]); indio_dev->dev.parent = &spi->dev; indio_dev->info = &ad2s1200_info; From 1946980b8f4227ff8543ea21dea8dddd5b161310 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:22:32 +0200 Subject: [PATCH 26/42] staging: iio: ad2s1200: Replace platform data with dt bindings Remove usage of platform data, and replace it with device tree facilities. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index b2c46a8c6b77..9a8aa2448897 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -25,9 +25,6 @@ #define DRV_NAME "ad2s1200" -/* input pin sample and rdvel is controlled by driver */ -#define AD2S1200_PN 2 - /* input clock on serial interface */ #define AD2S1200_HZ 8192000 /* clock period in nano second */ @@ -111,20 +108,9 @@ static const struct iio_info ad2s1200_info = { static int ad2s1200_probe(struct spi_device *spi) { - unsigned short *pins = spi->dev.platform_data; struct ad2s1200_state *st; struct iio_dev *indio_dev; - int pn, ret; - - for (pn = 0; pn < AD2S1200_PN; pn++) { - ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT, - DRV_NAME); - if (ret) { - dev_err(&spi->dev, "request gpio pin %d failed\n", - pins[pn]); - return ret; - } - } + int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) @@ -134,8 +120,20 @@ static int ad2s1200_probe(struct spi_device *spi) st = iio_priv(indio_dev); mutex_init(&st->lock); st->sdev = spi; - st->sample = gpio_to_desc(pins[0]); - st->rdvel = gpio_to_desc(pins[1]); + + st->sample = devm_gpiod_get(&spi->dev, "adi,sample", GPIOD_OUT_LOW); + if (IS_ERR(st->sample)) { + dev_err(&spi->dev, "Failed to claim SAMPLE gpio: err=%ld\n", + PTR_ERR(st->sample)); + return PTR_ERR(st->sample); + } + + st->rdvel = devm_gpiod_get(&spi->dev, "adi,rdvel", GPIOD_OUT_LOW); + if (IS_ERR(st->rdvel)) { + dev_err(&spi->dev, "Failed to claim RDVEL gpio: err=%ld\n", + PTR_ERR(st->rdvel)); + return PTR_ERR(st->rdvel); + } indio_dev->dev.parent = &spi->dev; indio_dev->info = &ad2s1200_info; From 2363c010ce65a68a4a9bcc27c99b7b5e1a478b8a Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:22:41 +0200 Subject: [PATCH 27/42] staging: iio: ad2s1200: Add dt table Add device tree table for matching with the vendor ID. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 9a8aa2448897..67d9747f88a6 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -154,6 +154,13 @@ static int ad2s1200_probe(struct spi_device *spi) return devm_iio_device_register(&spi->dev, indio_dev); } +static const struct of_device_id ad2s1200_of_match[] = { + { .compatible = "adi,ad2s1200", }, + { .compatible = "adi,ad2s1205", }, + { } +}; +MODULE_DEVICE_TABLE(of, ad2s1200_of_match); + static const struct spi_device_id ad2s1200_id[] = { { "ad2s1200" }, { "ad2s1205" }, @@ -164,6 +171,7 @@ MODULE_DEVICE_TABLE(spi, ad2s1200_id); static struct spi_driver ad2s1200_driver = { .driver = { .name = DRV_NAME, + .of_match_table = of_match_ptr(ad2s1200_of_match), }, .probe = ad2s1200_probe, .id_table = ad2s1200_id, From d3e6ed841671de3b25776b5e91f33112e8f5bca6 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:23:01 +0200 Subject: [PATCH 28/42] staging: iio: ad2s1200: Add scaling factor for angular velocity channel The sysfs iio ABI states radians per second is expected as the unit for angular velocity, but the 12-bit angular velocity register has revolution per seconds as its unit. So a scaling factor of approximately 2 * Pi is added to the angular velocity channel. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 67 ++++++++++++++++--------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 67d9747f88a6..7b8af558e921 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -55,37 +55,55 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, struct ad2s1200_state *st = iio_priv(indio_dev); int ret; - mutex_lock(&st->lock); - gpiod_set_value(st->sample, 0); + switch (m) { + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + /* 2 * Pi ~= 6.283185 */ + *val = 6; + *val2 = 283185; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + break; + case IIO_CHAN_INFO_RAW: + mutex_lock(&st->lock); + gpiod_set_value(st->sample, 0); - /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */ - udelay(1); - gpiod_set_value(st->sample, 1); - gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL)); + /* delay (6 * AD2S1200_TSCLK + 20) nano seconds */ + udelay(1); + gpiod_set_value(st->sample, 1); + gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL)); - ret = spi_read(st->sdev, &st->rx, 2); - if (ret < 0) { + ret = spi_read(st->sdev, &st->rx, 2); + if (ret < 0) { + mutex_unlock(&st->lock); + return ret; + } + + switch (chan->type) { + case IIO_ANGL: + *val = be16_to_cpup(&st->rx) >> 4; + break; + case IIO_ANGL_VEL: + *val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11); + break; + default: + mutex_unlock(&st->lock); + return -EINVAL; + } + + /* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */ + udelay(1); mutex_unlock(&st->lock); - return ret; - } - switch (chan->type) { - case IIO_ANGL: - *val = be16_to_cpup(&st->rx) >> 4; - break; - case IIO_ANGL_VEL: - *val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11); - break; + return IIO_VAL_INT; default: - mutex_unlock(&st->lock); - return -EINVAL; + break; } - /* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */ - udelay(1); - mutex_unlock(&st->lock); - - return IIO_VAL_INT; + return -EINVAL; } static const struct iio_chan_spec ad2s1200_channels[] = { @@ -99,6 +117,7 @@ static const struct iio_chan_spec ad2s1200_channels[] = { .indexed = 1, .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), } }; From f9db7370be0e93ce4264781e1ada631a32a61e9b Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:23:14 +0200 Subject: [PATCH 29/42] staging: iio: ad2s1200: Add scaling factor for angle channel A scaling factor of approximately 2 * Pi / (2^12 -1) is added, to scale the 12-bits angular position to radians. A return type of IIO_VAL_INT_PLUS_NANO is used, so that the scale of both the angle channel and angular velocity channel has 7 significant digits. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 7b8af558e921..10d6d79dce79 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -58,6 +58,11 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_SCALE: switch (chan->type) { + case IIO_ANGL: + /* 2 * Pi / (2^12 - 1) ~= 0.001534355 */ + *val = 0; + *val2 = 1534355; + return IIO_VAL_INT_PLUS_NANO; case IIO_ANGL_VEL: /* 2 * Pi ~= 6.283185 */ *val = 6; @@ -112,6 +117,7 @@ static const struct iio_chan_spec ad2s1200_channels[] = { .indexed = 1, .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_ANGL_VEL, .indexed = 1, From 9c3e81ab74df8f3f7f79410599278e2270d43756 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:23:25 +0200 Subject: [PATCH 30/42] staging: iio: ad2s1200: Add copyright Add David Veenstra as a copyright holders and as an author, for all of the staging clean ups of the ad2s1200 driver. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 10d6d79dce79..28e618af9939 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -2,6 +2,7 @@ * ad2s1200.c simple support for the ADI Resolver to Digital Converters: * AD2S1200/1205 * + * Copyright (c) 2018-2018 David Veenstra * Copyright (c) 2010-2010 Analog Devices Inc. * * This program is free software; you can redistribute it and/or modify @@ -203,6 +204,7 @@ static struct spi_driver ad2s1200_driver = { }; module_spi_driver(ad2s1200_driver); +MODULE_AUTHOR("David Veenstra "); MODULE_AUTHOR("Graff Yang "); MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver"); MODULE_LICENSE("GPL v2"); From ad28d315544074a7e9bfa07014263760e57855d2 Mon Sep 17 00:00:00 2001 From: David Veenstra Date: Fri, 18 May 2018 20:23:40 +0200 Subject: [PATCH 31/42] staging: iio: ad2s1200: Move driver out of staging Move the iio driver for the ad2s1200 and ad2s1205 resolver-to-digital converter out of staging, into mainline iio subsystems. Signed-off-by: David Veenstra Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/resolver/Kconfig | 17 +++++++++++++++++ drivers/iio/resolver/Makefile | 5 +++++ drivers/{staging => }/iio/resolver/ad2s1200.c | 0 drivers/staging/iio/resolver/Kconfig | 12 ------------ drivers/staging/iio/resolver/Makefile | 1 - 7 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 drivers/iio/resolver/Kconfig create mode 100644 drivers/iio/resolver/Makefile rename drivers/{staging => }/iio/resolver/ad2s1200.c (100%) diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index d69e85a8bdc3..d08aeb41cd07 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -93,6 +93,7 @@ source "drivers/iio/potentiometer/Kconfig" source "drivers/iio/potentiostat/Kconfig" source "drivers/iio/pressure/Kconfig" source "drivers/iio/proximity/Kconfig" +source "drivers/iio/resolver/Kconfig" source "drivers/iio/temperature/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index d8cba9c229c0..cb5993251381 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -36,5 +36,6 @@ obj-y += potentiometer/ obj-y += potentiostat/ obj-y += pressure/ obj-y += proximity/ +obj-y += resolver/ obj-y += temperature/ obj-y += trigger/ diff --git a/drivers/iio/resolver/Kconfig b/drivers/iio/resolver/Kconfig new file mode 100644 index 000000000000..2ced9f22aa70 --- /dev/null +++ b/drivers/iio/resolver/Kconfig @@ -0,0 +1,17 @@ +# +# Resolver/Synchro drivers +# +menu "Resolver to digital converters" + +config AD2S1200 + tristate "Analog Devices ad2s1200/ad2s1205 driver" + depends on SPI + depends on GPIOLIB || COMPILE_TEST + help + Say yes here to build support for Analog Devices spi resolver + to digital converters, ad2s1200 and ad2s1205, provides direct access + via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad2s1200. +endmenu diff --git a/drivers/iio/resolver/Makefile b/drivers/iio/resolver/Makefile new file mode 100644 index 000000000000..4e1dccae07e7 --- /dev/null +++ b/drivers/iio/resolver/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Resolver/Synchro drivers +# + +obj-$(CONFIG_AD2S1200) += ad2s1200.o diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/iio/resolver/ad2s1200.c similarity index 100% rename from drivers/staging/iio/resolver/ad2s1200.c rename to drivers/iio/resolver/ad2s1200.c diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig index 1c7e2860d6b7..6a469ee6101f 100644 --- a/drivers/staging/iio/resolver/Kconfig +++ b/drivers/staging/iio/resolver/Kconfig @@ -13,18 +13,6 @@ config AD2S90 To compile this driver as a module, choose M here: the module will be called ad2s90. -config AD2S1200 - tristate "Analog Devices ad2s1200/ad2s1205 driver" - depends on SPI - depends on GPIOLIB || COMPILE_TEST - help - Say yes here to build support for Analog Devices spi resolver - to digital converters, ad2s1200 and ad2s1205, provides direct access - via sysfs. - - To compile this driver as a module, choose M here: the - module will be called ad2s1200. - config AD2S1210 tristate "Analog Devices ad2s1210 driver" depends on SPI diff --git a/drivers/staging/iio/resolver/Makefile b/drivers/staging/iio/resolver/Makefile index 14375e444ebf..8d901dc7500b 100644 --- a/drivers/staging/iio/resolver/Makefile +++ b/drivers/staging/iio/resolver/Makefile @@ -3,5 +3,4 @@ # obj-$(CONFIG_AD2S90) += ad2s90.o -obj-$(CONFIG_AD2S1200) += ad2s1200.o obj-$(CONFIG_AD2S1210) += ad2s1210.o From cfbcdb6a98056b9054907d2e744f3ba163c6b093 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 12 May 2018 18:51:01 +0100 Subject: [PATCH 32/42] staging:iio:meter: Drop ADE7753 driver I announced the intent to drop some of these meter drivers on the IIO list last cycle. This device is obsolete and not easily obtained. No one has come forward with suitable test hardware and the driver would need a lot of work to move out of staging. As such I am dropping it. We can always bring it back again if a user / tester emerges in the future. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/Kconfig | 10 - drivers/staging/iio/meter/Makefile | 1 - drivers/staging/iio/meter/ade7753.c | 630 ---------------------------- 3 files changed, 641 deletions(-) delete mode 100644 drivers/staging/iio/meter/ade7753.c diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index 64cd3704ec6e..62db8d6498f5 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -3,16 +3,6 @@ # menu "Active energy metering IC" -config ADE7753 - tristate "Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver" - depends on SPI - help - Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction - Metering IC with di/dt Sensor Interface. - - To compile this driver as a module, choose M here: the - module will be called ade7753. - config ADE7754 tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver" depends on SPI diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index 19e7982f5563..8b2592b32845 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -3,7 +3,6 @@ # Makefile for metering ic drivers # -obj-$(CONFIG_ADE7753) += ade7753.o obj-$(CONFIG_ADE7754) += ade7754.o ade7758-y := ade7758_core.o diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c deleted file mode 100644 index 275e8dfff836..000000000000 --- a/drivers/staging/iio/meter/ade7753.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "meter.h" - -#define ADE7753_WAVEFORM 0x01 -#define ADE7753_AENERGY 0x02 -#define ADE7753_RAENERGY 0x03 -#define ADE7753_LAENERGY 0x04 -#define ADE7753_VAENERGY 0x05 -#define ADE7753_RVAENERGY 0x06 -#define ADE7753_LVAENERGY 0x07 -#define ADE7753_LVARENERGY 0x08 -#define ADE7753_MODE 0x09 -#define ADE7753_IRQEN 0x0A -#define ADE7753_STATUS 0x0B -#define ADE7753_RSTSTATUS 0x0C -#define ADE7753_CH1OS 0x0D -#define ADE7753_CH2OS 0x0E -#define ADE7753_GAIN 0x0F -#define ADE7753_PHCAL 0x10 -#define ADE7753_APOS 0x11 -#define ADE7753_WGAIN 0x12 -#define ADE7753_WDIV 0x13 -#define ADE7753_CFNUM 0x14 -#define ADE7753_CFDEN 0x15 -#define ADE7753_IRMS 0x16 -#define ADE7753_VRMS 0x17 -#define ADE7753_IRMSOS 0x18 -#define ADE7753_VRMSOS 0x19 -#define ADE7753_VAGAIN 0x1A -#define ADE7753_VADIV 0x1B -#define ADE7753_LINECYC 0x1C -#define ADE7753_ZXTOUT 0x1D -#define ADE7753_SAGCYC 0x1E -#define ADE7753_SAGLVL 0x1F -#define ADE7753_IPKLVL 0x20 -#define ADE7753_VPKLVL 0x21 -#define ADE7753_IPEAK 0x22 -#define ADE7753_RSTIPEAK 0x23 -#define ADE7753_VPEAK 0x24 -#define ADE7753_RSTVPEAK 0x25 -#define ADE7753_TEMP 0x26 -#define ADE7753_PERIOD 0x27 -#define ADE7753_TMODE 0x3D -#define ADE7753_CHKSUM 0x3E -#define ADE7753_DIEREV 0x3F - -#define ADE7753_READ_REG(a) a -#define ADE7753_WRITE_REG(a) ((a) | 0x80) - -#define ADE7753_MAX_TX 4 -#define ADE7753_MAX_RX 4 -#define ADE7753_STARTUP_DELAY 1000 - -#define ADE7753_SPI_SLOW (u32)(300 * 1000) -#define ADE7753_SPI_BURST (u32)(1000 * 1000) -#define ADE7753_SPI_FAST (u32)(2000 * 1000) - -/** - * struct ade7753_state - device instance specific data - * @us: actual spi_device - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx, rx and write frequency - **/ -struct ade7753_state { - struct spi_device *us; - struct mutex buf_lock; - u8 tx[ADE7753_MAX_TX] ____cacheline_aligned; - u8 rx[ADE7753_MAX_RX]; -}; - -static int ade7753_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7753_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int __ade7753_spi_write_reg_16(struct device *dev, u8 reg_address, - u16 value) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - - st->tx[0] = ADE7753_WRITE_REG(reg_address); - st->tx[1] = (value >> 8) & 0xFF; - st->tx[2] = value & 0xFF; - - return spi_write(st->us, st->tx, 3); -} - -static int ade7753_spi_write_reg_16(struct device *dev, u8 reg_address, - u16 value) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - ret = __ade7753_spi_write_reg_16(dev, reg_address, value); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7753_spi_read_reg_8(struct device *dev, - u8 reg_address, - u8 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - ssize_t ret; - - ret = spi_w8r8(st->us, ADE7753_READ_REG(reg_address)); - if (ret < 0) { - dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", - reg_address); - return ret; - } - *val = ret; - - return 0; -} - -static int ade7753_spi_read_reg_16(struct device *dev, - u8 reg_address, - u16 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - ssize_t ret; - - ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address)); - if (ret < 0) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - return ret; - } - - *val = ret; - - return 0; -} - -static int ade7753_spi_read_reg_24(struct device *dev, - u8 reg_address, - u32 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 1, - }, { - .rx_buf = st->tx, - .bits_per_word = 8, - .len = 3, - } - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7753_READ_REG(reg_address); - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - if (ret) { - dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", - reg_address); - goto error_ret; - } - *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static ssize_t ade7753_read_8bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u8 val; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7753_spi_read_reg_8(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7753_read_16bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 val; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7753_spi_read_reg_16(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7753_read_24bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u32 val; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7753_spi_read_reg_24(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7753_write_8bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u8 val; - - ret = kstrtou8(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7753_spi_write_reg_8(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static ssize_t ade7753_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u16 val; - - ret = kstrtou16(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7753_spi_write_reg_16(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static int ade7753_reset(struct device *dev) -{ - u16 val; - int ret; - - ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val); - if (ret) - return ret; - - val |= BIT(6); /* Software Chip Reset */ - - return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val); -} - -static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY); -static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY); -static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY); -static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY); -static IIO_DEV_ATTR_CFDEN(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_CFDEN); -static IIO_DEV_ATTR_CFNUM(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_CFNUM); -static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM); -static IIO_DEV_ATTR_PHCAL(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_PHCAL); -static IIO_DEV_ATTR_APOS(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_APOS); -static IIO_DEV_ATTR_SAGCYC(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_SAGCYC); -static IIO_DEV_ATTR_SAGLVL(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_SAGLVL); -static IIO_DEV_ATTR_LINECYC(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_LINECYC); -static IIO_DEV_ATTR_WDIV(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_WDIV); -static IIO_DEV_ATTR_IRMS(0644, - ade7753_read_24bit, - NULL, - ADE7753_IRMS); -static IIO_DEV_ATTR_VRMS(0444, - ade7753_read_24bit, - NULL, - ADE7753_VRMS); -static IIO_DEV_ATTR_IRMSOS(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_IRMSOS); -static IIO_DEV_ATTR_VRMSOS(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_VRMSOS); -static IIO_DEV_ATTR_WGAIN(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_WGAIN); -static IIO_DEV_ATTR_VAGAIN(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_VAGAIN); -static IIO_DEV_ATTR_PGA_GAIN(0644, - ade7753_read_16bit, - ade7753_write_16bit, - ADE7753_GAIN); -static IIO_DEV_ATTR_IPKLVL(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_IPKLVL); -static IIO_DEV_ATTR_VPKLVL(0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_VPKLVL); -static IIO_DEV_ATTR_IPEAK(0444, - ade7753_read_24bit, - NULL, - ADE7753_IPEAK); -static IIO_DEV_ATTR_VPEAK(0444, - ade7753_read_24bit, - NULL, - ADE7753_VPEAK); -static IIO_DEV_ATTR_VPERIOD(0444, - ade7753_read_16bit, - NULL, - ADE7753_PERIOD); - -static IIO_DEVICE_ATTR(choff_1, 0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_CH1OS); - -static IIO_DEVICE_ATTR(choff_2, 0644, - ade7753_read_8bit, - ade7753_write_8bit, - ADE7753_CH2OS); - -static int ade7753_set_irq(struct device *dev, bool enable) -{ - int ret; - u8 irqen; - - ret = ade7753_spi_read_reg_8(dev, ADE7753_IRQEN, &irqen); - if (ret) - goto error_ret; - - if (enable) - irqen |= BIT(3); /* Enables an interrupt when a data is - * present in the waveform register - */ - else - irqen &= ~BIT(3); - - ret = ade7753_spi_write_reg_8(dev, ADE7753_IRQEN, irqen); - -error_ret: - return ret; -} - -/* Power down the device */ -static int ade7753_stop_device(struct device *dev) -{ - u16 val; - int ret; - - ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val); - if (ret) - return ret; - - val |= BIT(4); /* AD converters can be turned off */ - - return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val); -} - -static int ade7753_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct device *dev = &indio_dev->dev; - struct ade7753_state *st = iio_priv(indio_dev); - - /* use low spi speed for init */ - st->us->mode = SPI_MODE_3; - spi_setup(st->us); - - /* Disable IRQ */ - ret = ade7753_set_irq(dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - ade7753_reset(dev); - usleep_range(ADE7753_STARTUP_DELAY, ADE7753_STARTUP_DELAY + 100); - -err_ret: - return ret; -} - -static ssize_t ade7753_read_frequency(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 t; - int sps; - - ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &t); - if (ret) - return ret; - - t = (t >> 11) & 0x3; - sps = 27900 / (1 + t); - - return sprintf(buf, "%d\n", sps); -} - -static ssize_t ade7753_write_frequency(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7753_state *st = iio_priv(indio_dev); - u16 val; - int ret; - u16 reg, t; - - ret = kstrtou16(buf, 10, &val); - if (ret) - return ret; - if (!val) - return -EINVAL; - - mutex_lock(&st->buf_lock); - - t = 27900 / val; - if (t > 0) - t--; - - if (t > 1) - st->us->max_speed_hz = ADE7753_SPI_SLOW; - else - st->us->max_speed_hz = ADE7753_SPI_FAST; - - ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, ®); - if (ret) - goto out; - - reg &= ~(3 << 11); - reg |= t << 11; - - ret = __ade7753_spi_write_reg_16(dev, ADE7753_MODE, reg); - -out: - mutex_unlock(&st->buf_lock); - - return ret ? ret : len; -} - -static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit); -static IIO_CONST_ATTR(in_temp_offset, "-25 C"); -static IIO_CONST_ATTR(in_temp_scale, "0.67 C"); - -static IIO_DEV_ATTR_SAMP_FREQ(0644, - ade7753_read_frequency, - ade7753_write_frequency); - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500"); - -static struct attribute *ade7753_attributes[] = { - &iio_dev_attr_in_temp_raw.dev_attr.attr, - &iio_const_attr_in_temp_offset.dev_attr.attr, - &iio_const_attr_in_temp_scale.dev_attr.attr, - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_phcal.dev_attr.attr, - &iio_dev_attr_cfden.dev_attr.attr, - &iio_dev_attr_aenergy.dev_attr.attr, - &iio_dev_attr_laenergy.dev_attr.attr, - &iio_dev_attr_vaenergy.dev_attr.attr, - &iio_dev_attr_lvaenergy.dev_attr.attr, - &iio_dev_attr_cfnum.dev_attr.attr, - &iio_dev_attr_apos.dev_attr.attr, - &iio_dev_attr_sagcyc.dev_attr.attr, - &iio_dev_attr_saglvl.dev_attr.attr, - &iio_dev_attr_linecyc.dev_attr.attr, - &iio_dev_attr_chksum.dev_attr.attr, - &iio_dev_attr_pga_gain.dev_attr.attr, - &iio_dev_attr_wgain.dev_attr.attr, - &iio_dev_attr_choff_1.dev_attr.attr, - &iio_dev_attr_choff_2.dev_attr.attr, - &iio_dev_attr_wdiv.dev_attr.attr, - &iio_dev_attr_irms.dev_attr.attr, - &iio_dev_attr_vrms.dev_attr.attr, - &iio_dev_attr_irmsos.dev_attr.attr, - &iio_dev_attr_vrmsos.dev_attr.attr, - &iio_dev_attr_vagain.dev_attr.attr, - &iio_dev_attr_ipklvl.dev_attr.attr, - &iio_dev_attr_vpklvl.dev_attr.attr, - &iio_dev_attr_ipeak.dev_attr.attr, - &iio_dev_attr_vpeak.dev_attr.attr, - &iio_dev_attr_vperiod.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ade7753_attribute_group = { - .attrs = ade7753_attributes, -}; - -static const struct iio_info ade7753_info = { - .attrs = &ade7753_attribute_group, -}; - -static int ade7753_probe(struct spi_device *spi) -{ - int ret; - struct ade7753_state *st; - struct iio_dev *indio_dev; - - /* setup the industrialio driver allocated elements */ - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - /* this is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - st = iio_priv(indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - - indio_dev->name = spi->dev.driver->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &ade7753_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Get the device into a sane initial state */ - ret = ade7753_initial_setup(indio_dev); - if (ret) - return ret; - - return iio_device_register(indio_dev); -} - -static int ade7753_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - ade7753_stop_device(&indio_dev->dev); - - return 0; -} - -static struct spi_driver ade7753_driver = { - .driver = { - .name = "ade7753", - }, - .probe = ade7753_probe, - .remove = ade7753_remove, -}; -module_spi_driver(ade7753_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Meter"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:ade7753"); From d15d4be9da50c1b6cd319a527d8ab2da28853dd9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 12 May 2018 18:51:02 +0100 Subject: [PATCH 33/42] staging:iio:meter: Drop ADE7754 driver I announced the intent to drop some of these meter drivers on the IIO list last cycle. This device is obsolete and not easily obtained. No one has come forward with suitable test hardware and the driver would need a lot of work to move out of staging. As such I am dropping it. We can always bring it back again if a user / tester emerges in the future. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/Kconfig | 10 - drivers/staging/iio/meter/Makefile | 2 - drivers/staging/iio/meter/ade7754.c | 664 ---------------------------- 3 files changed, 676 deletions(-) delete mode 100644 drivers/staging/iio/meter/ade7754.c diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index 62db8d6498f5..d60f052415c8 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -3,16 +3,6 @@ # menu "Active energy metering IC" -config ADE7754 - tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver" - depends on SPI - help - Say yes here to build support for Analog Devices ADE7754 Polyphase - Multifunction Energy Metering IC Driver. - - To compile this driver as a module, choose M here: the - module will be called ade7754. - config ADE7758 tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver" depends on SPI diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index 8b2592b32845..42f4157969de 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -3,8 +3,6 @@ # Makefile for metering ic drivers # -obj-$(CONFIG_ADE7754) += ade7754.o - ade7758-y := ade7758_core.o ade7758-$(CONFIG_IIO_BUFFER) += ade7758_ring.o ade7758_trigger.o obj-$(CONFIG_ADE7758) += ade7758.o diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c deleted file mode 100644 index 9aa067736715..000000000000 --- a/drivers/staging/iio/meter/ade7754.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * ADE7754 Polyphase Multifunction Energy Metering IC Driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "meter.h" - -#define ADE7754_AENERGY 0x01 -#define ADE7754_RAENERGY 0x02 -#define ADE7754_LAENERGY 0x03 -#define ADE7754_VAENERGY 0x04 -#define ADE7754_RVAENERGY 0x05 -#define ADE7754_LVAENERGY 0x06 -#define ADE7754_PERIOD 0x07 -#define ADE7754_TEMP 0x08 -#define ADE7754_WFORM 0x09 -#define ADE7754_OPMODE 0x0A -#define ADE7754_MMODE 0x0B -#define ADE7754_WAVMODE 0x0C -#define ADE7754_WATMODE 0x0D -#define ADE7754_VAMODE 0x0E -#define ADE7754_IRQEN 0x0F -#define ADE7754_STATUS 0x10 -#define ADE7754_RSTATUS 0x11 -#define ADE7754_ZXTOUT 0x12 -#define ADE7754_LINCYC 0x13 -#define ADE7754_SAGCYC 0x14 -#define ADE7754_SAGLVL 0x15 -#define ADE7754_VPEAK 0x16 -#define ADE7754_IPEAK 0x17 -#define ADE7754_GAIN 0x18 -#define ADE7754_AWG 0x19 -#define ADE7754_BWG 0x1A -#define ADE7754_CWG 0x1B -#define ADE7754_AVAG 0x1C -#define ADE7754_BVAG 0x1D -#define ADE7754_CVAG 0x1E -#define ADE7754_APHCAL 0x1F -#define ADE7754_BPHCAL 0x20 -#define ADE7754_CPHCAL 0x21 -#define ADE7754_AAPOS 0x22 -#define ADE7754_BAPOS 0x23 -#define ADE7754_CAPOS 0x24 -#define ADE7754_CFNUM 0x25 -#define ADE7754_CFDEN 0x26 -#define ADE7754_WDIV 0x27 -#define ADE7754_VADIV 0x28 -#define ADE7754_AIRMS 0x29 -#define ADE7754_BIRMS 0x2A -#define ADE7754_CIRMS 0x2B -#define ADE7754_AVRMS 0x2C -#define ADE7754_BVRMS 0x2D -#define ADE7754_CVRMS 0x2E -#define ADE7754_AIRMSOS 0x2F -#define ADE7754_BIRMSOS 0x30 -#define ADE7754_CIRMSOS 0x31 -#define ADE7754_AVRMSOS 0x32 -#define ADE7754_BVRMSOS 0x33 -#define ADE7754_CVRMSOS 0x34 -#define ADE7754_AAPGAIN 0x35 -#define ADE7754_BAPGAIN 0x36 -#define ADE7754_CAPGAIN 0x37 -#define ADE7754_AVGAIN 0x38 -#define ADE7754_BVGAIN 0x39 -#define ADE7754_CVGAIN 0x3A -#define ADE7754_CHKSUM 0x3E -#define ADE7754_VERSION 0x3F - -#define ADE7754_READ_REG(a) a -#define ADE7754_WRITE_REG(a) ((a) | 0x80) - -#define ADE7754_MAX_TX 4 -#define ADE7754_MAX_RX 4 -#define ADE7754_STARTUP_DELAY 1000 - -#define ADE7754_SPI_SLOW (u32)(300 * 1000) -#define ADE7754_SPI_BURST (u32)(1000 * 1000) -#define ADE7754_SPI_FAST (u32)(2000 * 1000) - -/** - * struct ade7754_state - device instance specific data - * @us: actual spi_device - * @buf_lock: mutex to protect tx, rx and write frequency - * @tx: transmit buffer - * @rx: receive buffer - **/ -struct ade7754_state { - struct spi_device *us; - struct mutex buf_lock; - u8 tx[ADE7754_MAX_TX] ____cacheline_aligned; - u8 rx[ADE7754_MAX_RX]; -}; - -/* Unlocked version of ade7754_spi_write_reg_8 function */ -static int __ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - - st->tx[0] = ADE7754_WRITE_REG(reg_address); - st->tx[1] = val; - return spi_write(st->us, st->tx, 2); -} - -static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - ret = __ade7754_spi_write_reg_8(dev, reg_address, val); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7754_spi_write_reg_16(struct device *dev, - u8 reg_address, u16 val) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7754_WRITE_REG(reg_address); - st->tx[1] = (val >> 8) & 0xFF; - st->tx[2] = val & 0xFF; - ret = spi_write(st->us, st->tx, 3); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7754_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - int ret; - - ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address)); - if (ret < 0) { - dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", - reg_address); - return ret; - } - *val = ret; - - return 0; -} - -static int ade7754_spi_read_reg_16(struct device *dev, - u8 reg_address, u16 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - int ret; - - ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address)); - if (ret < 0) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - return ret; - } - - *val = ret; - - return 0; -} - -static int ade7754_spi_read_reg_24(struct device *dev, - u8 reg_address, u32 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 4, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7754_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - if (ret) { - dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", - reg_address); - goto error_ret; - } - *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static ssize_t ade7754_read_8bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u8 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7754_spi_read_reg_8(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7754_read_16bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7754_spi_read_reg_16(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7754_read_24bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u32 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7754_spi_read_reg_24(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val & 0xFFFFFF); -} - -static ssize_t ade7754_write_8bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u8 val; - - ret = kstrtou8(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7754_spi_write_reg_8(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static ssize_t ade7754_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u16 val; - - ret = kstrtou16(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7754_spi_write_reg_16(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static int ade7754_reset(struct device *dev) -{ - int ret; - u8 val; - - ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); - if (ret < 0) - return ret; - - val |= BIT(6); /* Software Chip Reset */ - return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); -} - -static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY); -static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY); -static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY); -static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY); -static IIO_DEV_ATTR_VPEAK(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_VPEAK); -static IIO_DEV_ATTR_IPEAK(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_VPEAK); -static IIO_DEV_ATTR_APHCAL(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_APHCAL); -static IIO_DEV_ATTR_BPHCAL(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_BPHCAL); -static IIO_DEV_ATTR_CPHCAL(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_CPHCAL); -static IIO_DEV_ATTR_AAPOS(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_AAPOS); -static IIO_DEV_ATTR_BAPOS(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_BAPOS); -static IIO_DEV_ATTR_CAPOS(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_CAPOS); -static IIO_DEV_ATTR_WDIV(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_WDIV); -static IIO_DEV_ATTR_VADIV(0644, - ade7754_read_8bit, - ade7754_write_8bit, - ADE7754_VADIV); -static IIO_DEV_ATTR_CFNUM(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_CFNUM); -static IIO_DEV_ATTR_CFDEN(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_CFDEN); -static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_AAPGAIN); -static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_BAPGAIN); -static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(0644, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_CAPGAIN); -static IIO_DEV_ATTR_AIRMS(0444, - ade7754_read_24bit, - NULL, - ADE7754_AIRMS); -static IIO_DEV_ATTR_BIRMS(0444, - ade7754_read_24bit, - NULL, - ADE7754_BIRMS); -static IIO_DEV_ATTR_CIRMS(0444, - ade7754_read_24bit, - NULL, - ADE7754_CIRMS); -static IIO_DEV_ATTR_AVRMS(0444, - ade7754_read_24bit, - NULL, - ADE7754_AVRMS); -static IIO_DEV_ATTR_BVRMS(0444, - ade7754_read_24bit, - NULL, - ADE7754_BVRMS); -static IIO_DEV_ATTR_CVRMS(0444, - ade7754_read_24bit, - NULL, - ADE7754_CVRMS); -static IIO_DEV_ATTR_AIRMSOS(0444, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_AIRMSOS); -static IIO_DEV_ATTR_BIRMSOS(0444, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_BIRMSOS); -static IIO_DEV_ATTR_CIRMSOS(0444, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_CIRMSOS); -static IIO_DEV_ATTR_AVRMSOS(0444, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_AVRMSOS); -static IIO_DEV_ATTR_BVRMSOS(0444, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_BVRMSOS); -static IIO_DEV_ATTR_CVRMSOS(0444, - ade7754_read_16bit, - ade7754_write_16bit, - ADE7754_CVRMSOS); - -static int ade7754_set_irq(struct device *dev, bool enable) -{ - int ret; - u16 irqen; - - ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen); - if (ret) - return ret; - - if (enable) - irqen |= BIT(14); /* Enables an interrupt when a data is - * present in the waveform register - */ - else - irqen &= ~BIT(14); - - return ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); -} - -/* Power down the device */ -static int ade7754_stop_device(struct device *dev) -{ - int ret; - u8 val; - - ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); - if (ret < 0) { - dev_err(dev, "unable to power down the device, error: %d", - ret); - return ret; - } - - val |= 7 << 3; /* ADE7754 powered down */ - return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); -} - -static int ade7754_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct ade7754_state *st = iio_priv(indio_dev); - struct device *dev = &indio_dev->dev; - - /* use low spi speed for init */ - st->us->mode = SPI_MODE_3; - spi_setup(st->us); - - /* Disable IRQ */ - ret = ade7754_set_irq(dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - ade7754_reset(dev); - usleep_range(ADE7754_STARTUP_DELAY, ADE7754_STARTUP_DELAY + 100); - -err_ret: - return ret; -} - -static ssize_t ade7754_read_frequency(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u8 t; - int sps; - - ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, &t); - if (ret) - return ret; - - t = (t >> 3) & 0x3; - sps = 26000 / (1 + t); - - return sprintf(buf, "%d\n", sps); -} - -static ssize_t ade7754_write_frequency(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7754_state *st = iio_priv(indio_dev); - u16 val; - int ret; - u8 reg, t; - - ret = kstrtou16(buf, 10, &val); - if (ret) - return ret; - if (!val) - return -EINVAL; - - mutex_lock(&st->buf_lock); - - t = 26000 / val; - if (t > 0) - t--; - - if (t > 1) - st->us->max_speed_hz = ADE7754_SPI_SLOW; - else - st->us->max_speed_hz = ADE7754_SPI_FAST; - - ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, ®); - if (ret) - goto out; - - reg &= ~(3 << 3); - reg |= t << 3; - - ret = __ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg); - -out: - mutex_unlock(&st->buf_lock); - - return ret ? ret : len; -} -static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit); -static IIO_CONST_ATTR(in_temp_offset, "129 C"); -static IIO_CONST_ATTR(in_temp_scale, "4 C"); - -static IIO_DEV_ATTR_SAMP_FREQ(0644, - ade7754_read_frequency, - ade7754_write_frequency); - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000"); - -static struct attribute *ade7754_attributes[] = { - &iio_dev_attr_in_temp_raw.dev_attr.attr, - &iio_const_attr_in_temp_offset.dev_attr.attr, - &iio_const_attr_in_temp_scale.dev_attr.attr, - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_aenergy.dev_attr.attr, - &iio_dev_attr_laenergy.dev_attr.attr, - &iio_dev_attr_vaenergy.dev_attr.attr, - &iio_dev_attr_lvaenergy.dev_attr.attr, - &iio_dev_attr_vpeak.dev_attr.attr, - &iio_dev_attr_ipeak.dev_attr.attr, - &iio_dev_attr_aphcal.dev_attr.attr, - &iio_dev_attr_bphcal.dev_attr.attr, - &iio_dev_attr_cphcal.dev_attr.attr, - &iio_dev_attr_aapos.dev_attr.attr, - &iio_dev_attr_bapos.dev_attr.attr, - &iio_dev_attr_capos.dev_attr.attr, - &iio_dev_attr_wdiv.dev_attr.attr, - &iio_dev_attr_vadiv.dev_attr.attr, - &iio_dev_attr_cfnum.dev_attr.attr, - &iio_dev_attr_cfden.dev_attr.attr, - &iio_dev_attr_active_power_a_gain.dev_attr.attr, - &iio_dev_attr_active_power_b_gain.dev_attr.attr, - &iio_dev_attr_active_power_c_gain.dev_attr.attr, - &iio_dev_attr_airms.dev_attr.attr, - &iio_dev_attr_birms.dev_attr.attr, - &iio_dev_attr_cirms.dev_attr.attr, - &iio_dev_attr_avrms.dev_attr.attr, - &iio_dev_attr_bvrms.dev_attr.attr, - &iio_dev_attr_cvrms.dev_attr.attr, - &iio_dev_attr_airmsos.dev_attr.attr, - &iio_dev_attr_birmsos.dev_attr.attr, - &iio_dev_attr_cirmsos.dev_attr.attr, - &iio_dev_attr_avrmsos.dev_attr.attr, - &iio_dev_attr_bvrmsos.dev_attr.attr, - &iio_dev_attr_cvrmsos.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ade7754_attribute_group = { - .attrs = ade7754_attributes, -}; - -static const struct iio_info ade7754_info = { - .attrs = &ade7754_attribute_group, -}; - -static int ade7754_probe(struct spi_device *spi) -{ - int ret; - struct ade7754_state *st; - struct iio_dev *indio_dev; - - /* setup the industrialio driver allocated elements */ - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - /* this is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - st = iio_priv(indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - - indio_dev->name = spi->dev.driver->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &ade7754_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Get the device into a sane initial state */ - ret = ade7754_initial_setup(indio_dev); - if (ret) - goto powerdown_on_error; - ret = iio_device_register(indio_dev); - if (ret) - goto powerdown_on_error; - return ret; - -powerdown_on_error: - ade7754_stop_device(&indio_dev->dev); - return ret; -} - -static int ade7754_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - ade7754_stop_device(&indio_dev->dev); - - return 0; -} - -static struct spi_driver ade7754_driver = { - .driver = { - .name = "ade7754", - }, - .probe = ade7754_probe, - .remove = ade7754_remove, -}; -module_spi_driver(ade7754_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:ad7754"); From 1f31ee3508fec4ce9af45f8336c286795e12f77f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 12 May 2018 18:51:03 +0100 Subject: [PATCH 34/42] staging:iio:meter: Drop ADE7758 driver I announced the intent to drop some of these meter drivers on the IIO list last cycle. This device is obsolete and not easily obtained. No one has come forward with suitable test hardware and the driver would need a lot of work to move out of staging. As such I am dropping it. We can always bring it back again if a user / tester emerges in the future. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/Kconfig | 12 - drivers/staging/iio/meter/Makefile | 4 - drivers/staging/iio/meter/ade7758.h | 183 ---- drivers/staging/iio/meter/ade7758_core.c | 955 -------------------- drivers/staging/iio/meter/ade7758_ring.c | 177 ---- drivers/staging/iio/meter/ade7758_trigger.c | 108 --- 6 files changed, 1439 deletions(-) delete mode 100644 drivers/staging/iio/meter/ade7758.h delete mode 100644 drivers/staging/iio/meter/ade7758_core.c delete mode 100644 drivers/staging/iio/meter/ade7758_ring.c delete mode 100644 drivers/staging/iio/meter/ade7758_trigger.c diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index d60f052415c8..451ac47bb0cc 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -3,18 +3,6 @@ # menu "Active energy metering IC" -config ADE7758 - tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver" - depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_KFIFO_BUF if IIO_BUFFER - help - Say yes here to build support for Analog Devices ADE7758 Polyphase - Multifunction Energy Metering IC with Per Phase Information Driver. - - To compile this driver as a module, choose M here: the - module will be called ade7758. - config ADE7759 tristate "Analog Devices ADE7759 Active Energy Metering IC Driver" depends on SPI diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index 42f4157969de..a36ff1668275 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -3,10 +3,6 @@ # Makefile for metering ic drivers # -ade7758-y := ade7758_core.o -ade7758-$(CONFIG_IIO_BUFFER) += ade7758_ring.o ade7758_trigger.o -obj-$(CONFIG_ADE7758) += ade7758.o - obj-$(CONFIG_ADE7759) += ade7759.o obj-$(CONFIG_ADE7854) += ade7854.o obj-$(CONFIG_ADE7854_I2C) += ade7854-i2c.o diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h deleted file mode 100644 index 2de81b53e786..000000000000 --- a/drivers/staging/iio/meter/ade7758.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * ADE7758 Poly Phase Multifunction Energy Metering IC driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#ifndef _ADE7758_H -#define _ADE7758_H - -#define ADE7758_AWATTHR 0x01 -#define ADE7758_BWATTHR 0x02 -#define ADE7758_CWATTHR 0x03 -#define ADE7758_AVARHR 0x04 -#define ADE7758_BVARHR 0x05 -#define ADE7758_CVARHR 0x06 -#define ADE7758_AVAHR 0x07 -#define ADE7758_BVAHR 0x08 -#define ADE7758_CVAHR 0x09 -#define ADE7758_AIRMS 0x0A -#define ADE7758_BIRMS 0x0B -#define ADE7758_CIRMS 0x0C -#define ADE7758_AVRMS 0x0D -#define ADE7758_BVRMS 0x0E -#define ADE7758_CVRMS 0x0F -#define ADE7758_FREQ 0x10 -#define ADE7758_TEMP 0x11 -#define ADE7758_WFORM 0x12 -#define ADE7758_OPMODE 0x13 -#define ADE7758_MMODE 0x14 -#define ADE7758_WAVMODE 0x15 -#define ADE7758_COMPMODE 0x16 -#define ADE7758_LCYCMODE 0x17 -#define ADE7758_MASK 0x18 -#define ADE7758_STATUS 0x19 -#define ADE7758_RSTATUS 0x1A -#define ADE7758_ZXTOUT 0x1B -#define ADE7758_LINECYC 0x1C -#define ADE7758_SAGCYC 0x1D -#define ADE7758_SAGLVL 0x1E -#define ADE7758_VPINTLVL 0x1F -#define ADE7758_IPINTLVL 0x20 -#define ADE7758_VPEAK 0x21 -#define ADE7758_IPEAK 0x22 -#define ADE7758_GAIN 0x23 -#define ADE7758_AVRMSGAIN 0x24 -#define ADE7758_BVRMSGAIN 0x25 -#define ADE7758_CVRMSGAIN 0x26 -#define ADE7758_AIGAIN 0x27 -#define ADE7758_BIGAIN 0x28 -#define ADE7758_CIGAIN 0x29 -#define ADE7758_AWG 0x2A -#define ADE7758_BWG 0x2B -#define ADE7758_CWG 0x2C -#define ADE7758_AVARG 0x2D -#define ADE7758_BVARG 0x2E -#define ADE7758_CVARG 0x2F -#define ADE7758_AVAG 0x30 -#define ADE7758_BVAG 0x31 -#define ADE7758_CVAG 0x32 -#define ADE7758_AVRMSOS 0x33 -#define ADE7758_BVRMSOS 0x34 -#define ADE7758_CVRMSOS 0x35 -#define ADE7758_AIRMSOS 0x36 -#define ADE7758_BIRMSOS 0x37 -#define ADE7758_CIRMSOS 0x38 -#define ADE7758_AWAITOS 0x39 -#define ADE7758_BWAITOS 0x3A -#define ADE7758_CWAITOS 0x3B -#define ADE7758_AVAROS 0x3C -#define ADE7758_BVAROS 0x3D -#define ADE7758_CVAROS 0x3E -#define ADE7758_APHCAL 0x3F -#define ADE7758_BPHCAL 0x40 -#define ADE7758_CPHCAL 0x41 -#define ADE7758_WDIV 0x42 -#define ADE7758_VADIV 0x44 -#define ADE7758_VARDIV 0x43 -#define ADE7758_APCFNUM 0x45 -#define ADE7758_APCFDEN 0x46 -#define ADE7758_VARCFNUM 0x47 -#define ADE7758_VARCFDEN 0x48 -#define ADE7758_CHKSUM 0x7E -#define ADE7758_VERSION 0x7F - -#define ADE7758_READ_REG(a) a -#define ADE7758_WRITE_REG(a) ((a) | 0x80) - -#define ADE7758_MAX_TX 8 -#define ADE7758_MAX_RX 4 -#define ADE7758_STARTUP_DELAY 1000 - -#define AD7758_NUM_WAVSEL 5 -#define AD7758_NUM_PHSEL 3 -#define AD7758_NUM_WAVESRC (AD7758_NUM_WAVSEL * AD7758_NUM_PHSEL) - -#define AD7758_PHASE_A 0 -#define AD7758_PHASE_B 1 -#define AD7758_PHASE_C 2 -#define AD7758_CURRENT 0 -#define AD7758_VOLTAGE 1 -#define AD7758_ACT_PWR 2 -#define AD7758_REACT_PWR 3 -#define AD7758_APP_PWR 4 -#define AD7758_WT(p, w) (((w) << 2) | (p)) - -/** - * struct ade7758_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx, rx, read and write frequency - **/ -struct ade7758_state { - struct spi_device *us; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; - struct spi_transfer ring_xfer[4]; - struct spi_message ring_msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - unsigned char rx_buf[8] ____cacheline_aligned; - unsigned char tx_buf[8]; - -}; - -#ifdef CONFIG_IIO_BUFFER -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -void ade7758_remove_trigger(struct iio_dev *indio_dev); -int ade7758_probe_trigger(struct iio_dev *indio_dev); - -ssize_t ade7758_read_data_from_ring(struct device *dev, - struct device_attribute *attr, char *buf); - -int ade7758_configure_ring(struct iio_dev *indio_dev); -void ade7758_unconfigure_ring(struct iio_dev *indio_dev); - -int ade7758_set_irq(struct device *dev, bool enable); - -int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val); -int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void ade7758_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int ade7758_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static int ade7758_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void ade7758_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int ade7758_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void ade7758_uninitialize_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ - -#endif diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c deleted file mode 100644 index 4e0dbf5c5705..000000000000 --- a/drivers/staging/iio/meter/ade7758_core.c +++ /dev/null @@ -1,955 +0,0 @@ -/* - * ADE7758 Poly Phase Multifunction Energy Metering IC driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "meter.h" -#include "ade7758.h" - -static int __ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - - st->tx[0] = ADE7758_WRITE_REG(reg_address); - st->tx[1] = val; - - return spi_write(st->us, st->tx, 2); -} - -int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - ret = __ade7758_spi_write_reg_8(dev, reg_address, val); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7758_spi_write_reg_16(struct device *dev, u8 reg_address, - u16 value) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 3, - } - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7758_WRITE_REG(reg_address); - st->tx[1] = (value >> 8) & 0xFF; - st->tx[2] = value & 0xFF; - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7758_spi_write_reg_24(struct device *dev, u8 reg_address, - u32 value) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 4, - } - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7758_WRITE_REG(reg_address); - st->tx[1] = (value >> 16) & 0xFF; - st->tx[2] = (value >> 8) & 0xFF; - st->tx[3] = value & 0xFF; - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int __ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 1, - .delay_usecs = 4, - }, - { - .tx_buf = &st->tx[1], - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 1, - }, - }; - - st->tx[0] = ADE7758_READ_REG(reg_address); - st->tx[1] = 0; - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - if (ret) { - dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", - reg_address); - goto error_ret; - } - *val = st->rx[0]; - -error_ret: - return ret; -} - -int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - int ret; - - mutex_lock(&st->buf_lock); - ret = __ade7758_spi_read_reg_8(dev, reg_address, val); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7758_spi_read_reg_16(struct device *dev, u8 reg_address, - u16 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 1, - .delay_usecs = 4, - }, - { - .tx_buf = &st->tx[1], - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7758_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - goto error_ret; - } - - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int ade7758_spi_read_reg_24(struct device *dev, u8 reg_address, - u32 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 1, - .delay_usecs = 4, - }, - { - .tx_buf = &st->tx[1], - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 3, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7758_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - if (ret) { - dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", - reg_address); - goto error_ret; - } - *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static ssize_t ade7758_read_8bit(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret; - u8 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7758_spi_read_reg_8(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7758_read_16bit(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret; - u16 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7758_spi_read_reg_16(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7758_read_24bit(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret; - u32 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7758_spi_read_reg_24(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val & 0xFFFFFF); -} - -static ssize_t ade7758_write_8bit(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u8 val; - - ret = kstrtou8(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7758_spi_write_reg_8(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static ssize_t ade7758_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u16 val; - - ret = kstrtou16(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7758_spi_write_reg_16(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static int ade7758_reset(struct device *dev) -{ - int ret; - u8 val; - - ret = ade7758_spi_read_reg_8(dev, ADE7758_OPMODE, &val); - if (ret < 0) { - dev_err(dev, "Failed to read opmode reg\n"); - return ret; - } - val |= BIT(6); /* Software Chip Reset */ - ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val); - if (ret < 0) - dev_err(dev, "Failed to write opmode reg\n"); - return ret; -} - -static IIO_DEV_ATTR_VPEAK(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_VPEAK); -static IIO_DEV_ATTR_IPEAK(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_VPEAK); -static IIO_DEV_ATTR_APHCAL(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_APHCAL); -static IIO_DEV_ATTR_BPHCAL(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_BPHCAL); -static IIO_DEV_ATTR_CPHCAL(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_CPHCAL); -static IIO_DEV_ATTR_WDIV(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_WDIV); -static IIO_DEV_ATTR_VADIV(0644, - ade7758_read_8bit, - ade7758_write_8bit, - ADE7758_VADIV); -static IIO_DEV_ATTR_AIRMS(0444, - ade7758_read_24bit, - NULL, - ADE7758_AIRMS); -static IIO_DEV_ATTR_BIRMS(0444, - ade7758_read_24bit, - NULL, - ADE7758_BIRMS); -static IIO_DEV_ATTR_CIRMS(0444, - ade7758_read_24bit, - NULL, - ADE7758_CIRMS); -static IIO_DEV_ATTR_AVRMS(0444, - ade7758_read_24bit, - NULL, - ADE7758_AVRMS); -static IIO_DEV_ATTR_BVRMS(0444, - ade7758_read_24bit, - NULL, - ADE7758_BVRMS); -static IIO_DEV_ATTR_CVRMS(0444, - ade7758_read_24bit, - NULL, - ADE7758_CVRMS); -static IIO_DEV_ATTR_AIRMSOS(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_AIRMSOS); -static IIO_DEV_ATTR_BIRMSOS(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_BIRMSOS); -static IIO_DEV_ATTR_CIRMSOS(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_CIRMSOS); -static IIO_DEV_ATTR_AVRMSOS(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_AVRMSOS); -static IIO_DEV_ATTR_BVRMSOS(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_BVRMSOS); -static IIO_DEV_ATTR_CVRMSOS(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_CVRMSOS); -static IIO_DEV_ATTR_AIGAIN(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_AIGAIN); -static IIO_DEV_ATTR_BIGAIN(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_BIGAIN); -static IIO_DEV_ATTR_CIGAIN(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_CIGAIN); -static IIO_DEV_ATTR_AVRMSGAIN(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_AVRMSGAIN); -static IIO_DEV_ATTR_BVRMSGAIN(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_BVRMSGAIN); -static IIO_DEV_ATTR_CVRMSGAIN(0644, - ade7758_read_16bit, - ade7758_write_16bit, - ADE7758_CVRMSGAIN); - -int ade7758_set_irq(struct device *dev, bool enable) -{ - int ret; - u32 irqen; - - ret = ade7758_spi_read_reg_24(dev, ADE7758_MASK, &irqen); - if (ret) - return ret; - - if (enable) - irqen |= BIT(16); /* Enables an interrupt when a data is - * present in the waveform register - */ - else - irqen &= ~BIT(16); - - ret = ade7758_spi_write_reg_24(dev, ADE7758_MASK, irqen); - - return ret; -} - -/* Power down the device */ -static int ade7758_stop_device(struct device *dev) -{ - int ret; - u8 val; - - ret = ade7758_spi_read_reg_8(dev, ADE7758_OPMODE, &val); - if (ret < 0) { - dev_err(dev, "Failed to read opmode reg\n"); - return ret; - } - val |= 7 << 3; /* ADE7758 powered down */ - ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val); - if (ret < 0) - dev_err(dev, "Failed to write opmode reg\n"); - return ret; -} - -static int ade7758_initial_setup(struct iio_dev *indio_dev) -{ - struct ade7758_state *st = iio_priv(indio_dev); - struct device *dev = &indio_dev->dev; - int ret; - - /* use low spi speed for init */ - st->us->mode = SPI_MODE_1; - spi_setup(st->us); - - /* Disable IRQ */ - ret = ade7758_set_irq(dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - ade7758_reset(dev); - usleep_range(ADE7758_STARTUP_DELAY, ADE7758_STARTUP_DELAY + 100); - -err_ret: - return ret; -} - -static int ade7758_read_samp_freq(struct device *dev, int *val) -{ - int ret; - u8 t; - - ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &t); - if (ret) - return ret; - - t = (t >> 5) & 0x3; - *val = 26040 / (1 << t); - - return 0; -} - -static int ade7758_write_samp_freq(struct device *dev, int val) -{ - int ret; - u8 reg, t; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7758_state *st = iio_priv(indio_dev); - - switch (val) { - case 26040: - t = 0; - break; - case 13020: - t = 1; - break; - case 6510: - t = 2; - break; - case 3255: - t = 3; - break; - default: - return -EINVAL; - } - - mutex_lock(&st->buf_lock); - - ret = __ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, ®); - if (ret) - goto out; - - reg &= ~(5 << 3); - reg |= t << 5; - - ret = __ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg); - -out: - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7758_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long mask) -{ - int ret; - - switch (mask) { - case IIO_CHAN_INFO_SAMP_FREQ: - - ret = ade7758_read_samp_freq(&indio_dev->dev, val); - - return ret; - default: - return -EINVAL; - } - - return ret; -} - -static int ade7758_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, int val2, long mask) -{ - int ret; - - switch (mask) { - case IIO_CHAN_INFO_SAMP_FREQ: - if (val2) - return -EINVAL; - - ret = ade7758_write_samp_freq(&indio_dev->dev, val); - - return ret; - default: - return -EINVAL; - } - - return ret; -} - -static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit); -static IIO_CONST_ATTR(in_temp_offset, "129 C"); -static IIO_CONST_ATTR(in_temp_scale, "4 C"); - -static IIO_DEV_ATTR_AWATTHR(ade7758_read_16bit, - ADE7758_AWATTHR); -static IIO_DEV_ATTR_BWATTHR(ade7758_read_16bit, - ADE7758_BWATTHR); -static IIO_DEV_ATTR_CWATTHR(ade7758_read_16bit, - ADE7758_CWATTHR); -static IIO_DEV_ATTR_AVARHR(ade7758_read_16bit, - ADE7758_AVARHR); -static IIO_DEV_ATTR_BVARHR(ade7758_read_16bit, - ADE7758_BVARHR); -static IIO_DEV_ATTR_CVARHR(ade7758_read_16bit, - ADE7758_CVARHR); -static IIO_DEV_ATTR_AVAHR(ade7758_read_16bit, - ADE7758_AVAHR); -static IIO_DEV_ATTR_BVAHR(ade7758_read_16bit, - ADE7758_BVAHR); -static IIO_DEV_ATTR_CVAHR(ade7758_read_16bit, - ADE7758_CVAHR); - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255"); - -static struct attribute *ade7758_attributes[] = { - &iio_dev_attr_in_temp_raw.dev_attr.attr, - &iio_const_attr_in_temp_offset.dev_attr.attr, - &iio_const_attr_in_temp_scale.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_awatthr.dev_attr.attr, - &iio_dev_attr_bwatthr.dev_attr.attr, - &iio_dev_attr_cwatthr.dev_attr.attr, - &iio_dev_attr_avarhr.dev_attr.attr, - &iio_dev_attr_bvarhr.dev_attr.attr, - &iio_dev_attr_cvarhr.dev_attr.attr, - &iio_dev_attr_avahr.dev_attr.attr, - &iio_dev_attr_bvahr.dev_attr.attr, - &iio_dev_attr_cvahr.dev_attr.attr, - &iio_dev_attr_vpeak.dev_attr.attr, - &iio_dev_attr_ipeak.dev_attr.attr, - &iio_dev_attr_aphcal.dev_attr.attr, - &iio_dev_attr_bphcal.dev_attr.attr, - &iio_dev_attr_cphcal.dev_attr.attr, - &iio_dev_attr_wdiv.dev_attr.attr, - &iio_dev_attr_vadiv.dev_attr.attr, - &iio_dev_attr_airms.dev_attr.attr, - &iio_dev_attr_birms.dev_attr.attr, - &iio_dev_attr_cirms.dev_attr.attr, - &iio_dev_attr_avrms.dev_attr.attr, - &iio_dev_attr_bvrms.dev_attr.attr, - &iio_dev_attr_cvrms.dev_attr.attr, - &iio_dev_attr_aigain.dev_attr.attr, - &iio_dev_attr_bigain.dev_attr.attr, - &iio_dev_attr_cigain.dev_attr.attr, - &iio_dev_attr_avrmsgain.dev_attr.attr, - &iio_dev_attr_bvrmsgain.dev_attr.attr, - &iio_dev_attr_cvrmsgain.dev_attr.attr, - &iio_dev_attr_airmsos.dev_attr.attr, - &iio_dev_attr_birmsos.dev_attr.attr, - &iio_dev_attr_cirmsos.dev_attr.attr, - &iio_dev_attr_avrmsos.dev_attr.attr, - &iio_dev_attr_bvrmsos.dev_attr.attr, - &iio_dev_attr_cvrmsos.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ade7758_attribute_group = { - .attrs = ade7758_attributes, -}; - -static const struct iio_chan_spec ade7758_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), - .scan_index = 0, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_CURRENT, - .indexed = 1, - .channel = 0, - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), - .scan_index = 1, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 0, - .extend_name = "apparent", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), - .scan_index = 2, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 0, - .extend_name = "active", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), - .scan_index = 3, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 0, - .extend_name = "reactive", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), - .scan_index = 4, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), - .scan_index = 5, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_CURRENT, - .indexed = 1, - .channel = 1, - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), - .scan_index = 6, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 1, - .extend_name = "apparent", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), - .scan_index = 7, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 1, - .extend_name = "active", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), - .scan_index = 8, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 1, - .extend_name = "reactive", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), - .scan_index = 9, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 2, - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), - .scan_index = 10, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_CURRENT, - .indexed = 1, - .channel = 2, - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), - .scan_index = 11, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 2, - .extend_name = "apparent", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), - .scan_index = 12, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 2, - .extend_name = "active", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), - .scan_index = 13, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, { - .type = IIO_POWER, - .indexed = 1, - .channel = 2, - .extend_name = "reactive", - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), - .scan_index = 14, - .scan_type = { - .sign = 's', - .realbits = 24, - .storagebits = 32, - }, - }, - IIO_CHAN_SOFT_TIMESTAMP(15), -}; - -static const struct iio_info ade7758_info = { - .attrs = &ade7758_attribute_group, - .read_raw = &ade7758_read_raw, - .write_raw = &ade7758_write_raw, -}; - -static int ade7758_probe(struct spi_device *spi) -{ - int ret; - struct ade7758_state *st; - struct iio_dev *indio_dev; - - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - - st = iio_priv(indio_dev); - /* this is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - /* Allocate the comms buffers */ - st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL); - if (!st->rx) - return -ENOMEM; - st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL); - if (!st->tx) { - ret = -ENOMEM; - goto error_free_rx; - } - st->us = spi; - mutex_init(&st->buf_lock); - - indio_dev->name = spi->dev.driver->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &ade7758_info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = ade7758_channels; - indio_dev->num_channels = ARRAY_SIZE(ade7758_channels); - - ret = ade7758_configure_ring(indio_dev); - if (ret) - goto error_free_tx; - - /* Get the device into a sane initial state */ - ret = ade7758_initial_setup(indio_dev); - if (ret) - goto error_unreg_ring_funcs; - - if (spi->irq) { - ret = ade7758_probe_trigger(indio_dev); - if (ret) - goto error_unreg_ring_funcs; - } - - ret = iio_device_register(indio_dev); - if (ret) - goto error_remove_trigger; - - return 0; - -error_remove_trigger: - if (spi->irq) - ade7758_remove_trigger(indio_dev); -error_unreg_ring_funcs: - ade7758_unconfigure_ring(indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); - return ret; -} - -static int ade7758_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ade7758_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - ade7758_stop_device(&indio_dev->dev); - ade7758_remove_trigger(indio_dev); - ade7758_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - - return 0; -} - -static const struct spi_device_id ade7758_id[] = { - {"ade7758", 0}, - {} -}; -MODULE_DEVICE_TABLE(spi, ade7758_id); - -static struct spi_driver ade7758_driver = { - .driver = { - .name = "ade7758", - }, - .probe = ade7758_probe, - .remove = ade7758_remove, - .id_table = ade7758_id, -}; -module_spi_driver(ade7758_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c deleted file mode 100644 index 6d7444d6e880..000000000000 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * ADE7758 Poly Phase Multifunction Energy Metering IC driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "ade7758.h" - -/** - * ade7758_spi_read_burst() - read data registers - * @indio_dev: the IIO device - **/ -static int ade7758_spi_read_burst(struct iio_dev *indio_dev) -{ - struct ade7758_state *st = iio_priv(indio_dev); - int ret; - - ret = spi_sync(st->us, &st->ring_msg); - if (ret) - dev_err(&st->us->dev, "problem when reading WFORM value\n"); - - return ret; -} - -static int ade7758_write_waveform_type(struct device *dev, unsigned int type) -{ - int ret; - u8 reg; - - ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, ®); - if (ret) - goto out; - - reg &= ~0x1F; - reg |= type & 0x1F; - - ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg); -out: - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is too device - * specific to be rolled into the core. - */ -static irqreturn_t ade7758_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ade7758_state *st = iio_priv(indio_dev); - s64 dat64[2]; - u32 *dat32 = (u32 *)dat64; - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - if (ade7758_spi_read_burst(indio_dev) >= 0) - *dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF; - - iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp); - - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -/** - * ade7758_ring_preenable() setup the parameters of the ring before enabling - * - * The complex nature of the setting of the number of bytes per datum is due - * to this driver currently ensuring that the timestamp is stored at an 8 - * byte boundary. - **/ -static int ade7758_ring_preenable(struct iio_dev *indio_dev) -{ - unsigned int channel; - - if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - return -EINVAL; - - channel = find_first_bit(indio_dev->active_scan_mask, - indio_dev->masklength); - - ade7758_write_waveform_type(&indio_dev->dev, - indio_dev->channels[channel].address); - - return 0; -} - -static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = { - .preenable = &ade7758_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .validate_scan_mask = &iio_validate_scan_mask_onehot, -}; - -void ade7758_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); -} - -int ade7758_configure_ring(struct iio_dev *indio_dev) -{ - struct ade7758_state *st = iio_priv(indio_dev); - struct iio_buffer *buffer; - int ret = 0; - - buffer = iio_kfifo_allocate(); - if (!buffer) - return -ENOMEM; - - iio_device_attach_buffer(indio_dev, buffer); - - indio_dev->setup_ops = &ade7758_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &ade7758_trigger_handler, - 0, - indio_dev, - "ade7759_consumer%d", - indio_dev->id); - if (!indio_dev->pollfunc) { - ret = -ENOMEM; - goto error_iio_kfifo_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - - st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS); - st->tx_buf[1] = 0; - st->tx_buf[2] = 0; - st->tx_buf[3] = 0; - st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM); - st->tx_buf[5] = 0; - st->tx_buf[6] = 0; - st->tx_buf[7] = 0; - - /* build spi ring message */ - st->ring_xfer[0].tx_buf = &st->tx_buf[0]; - st->ring_xfer[0].len = 1; - st->ring_xfer[0].bits_per_word = 8; - st->ring_xfer[0].delay_usecs = 4; - st->ring_xfer[1].rx_buf = &st->rx_buf[1]; - st->ring_xfer[1].len = 3; - st->ring_xfer[1].bits_per_word = 8; - st->ring_xfer[1].cs_change = 1; - - st->ring_xfer[2].tx_buf = &st->tx_buf[4]; - st->ring_xfer[2].len = 1; - st->ring_xfer[2].bits_per_word = 8; - st->ring_xfer[2].delay_usecs = 1; - st->ring_xfer[3].rx_buf = &st->rx_buf[5]; - st->ring_xfer[3].len = 3; - st->ring_xfer[3].bits_per_word = 8; - - spi_message_init(&st->ring_msg); - spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); - spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); - spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg); - spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg); - - return 0; - -error_iio_kfifo_free: - iio_kfifo_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c deleted file mode 100644 index 4f6b338cffeb..000000000000 --- a/drivers/staging/iio/meter/ade7758_trigger.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ADE7758 Poly Phase Multifunction Energy Metering IC driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include - -#include -#include -#include "ade7758.h" - -/** - * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private) -{ - disable_irq_nosync(irq); - iio_trigger_poll(private); - - return IRQ_HANDLED; -} - -/** - * ade7758_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); - - dev_dbg(&indio_dev->dev, "(%d)\n", state); - return ade7758_set_irq(&indio_dev->dev, state); -} - -/** - * ade7758_trig_try_reen() try renabling irq for data rdy trigger - * @trig: the datardy trigger - **/ -static int ade7758_trig_try_reen(struct iio_trigger *trig) -{ - struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); - struct ade7758_state *st = iio_priv(indio_dev); - - enable_irq(st->us->irq); - /* irq reenabled so success! */ - return 0; -} - -static const struct iio_trigger_ops ade7758_trigger_ops = { - .set_trigger_state = &ade7758_data_rdy_trigger_set_state, - .try_reenable = &ade7758_trig_try_reen, -}; - -int ade7758_probe_trigger(struct iio_dev *indio_dev) -{ - struct ade7758_state *st = iio_priv(indio_dev); - int ret; - - st->trig = iio_trigger_alloc("%s-dev%d", - spi_get_device_id(st->us)->name, - indio_dev->id); - if (!st->trig) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - ade7758_data_rdy_trig_poll, - IRQF_TRIGGER_LOW, - spi_get_device_id(st->us)->name, - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &ade7758_trigger_ops; - iio_trigger_set_drvdata(st->trig, indio_dev); - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = iio_trigger_get(st->trig); - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void ade7758_remove_trigger(struct iio_dev *indio_dev) -{ - struct ade7758_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} From be3be7814a83fb823bb13a91e2011241bd7d2d1d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 12 May 2018 18:51:04 +0100 Subject: [PATCH 35/42] staging:iio:meter: Drop ADE7759 driver I announced the intent to drop some of these meter drivers on the IIO list last cycle. This device is obsolete and not easily obtained. No one has come forward with suitable test hardware and the driver would need a lot of work to move out of staging. As such I am dropping it. We can always bring it back again if a user / tester emerges in the future. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/Kconfig | 10 - drivers/staging/iio/meter/Makefile | 1 - drivers/staging/iio/meter/ade7759.c | 558 ---------------------------- 3 files changed, 569 deletions(-) delete mode 100644 drivers/staging/iio/meter/ade7759.c diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index 451ac47bb0cc..e01eb8abcdce 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -3,16 +3,6 @@ # menu "Active energy metering IC" -config ADE7759 - tristate "Analog Devices ADE7759 Active Energy Metering IC Driver" - depends on SPI - help - Say yes here to build support for Analog Devices ADE7758 Active Energy - Metering IC with di/dt Sensor Interface. - - To compile this driver as a module, choose M here: the - module will be called ade7759. - config ADE7854 tristate "Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver" depends on SPI || I2C diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index a36ff1668275..ed4547e38f3a 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -3,7 +3,6 @@ # Makefile for metering ic drivers # -obj-$(CONFIG_ADE7759) += ade7759.o obj-$(CONFIG_ADE7854) += ade7854.o obj-$(CONFIG_ADE7854_I2C) += ade7854-i2c.o obj-$(CONFIG_ADE7854_SPI) += ade7854-spi.o diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c deleted file mode 100644 index c078b770fa53..000000000000 --- a/drivers/staging/iio/meter/ade7759.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * ADE7759 Active Energy Metering IC with di/dt Sensor Interface Driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "meter.h" - -#define ADE7759_WAVEFORM 0x01 -#define ADE7759_AENERGY 0x02 -#define ADE7759_RSTENERGY 0x03 -#define ADE7759_STATUS 0x04 -#define ADE7759_RSTSTATUS 0x05 -#define ADE7759_MODE 0x06 -#define ADE7759_CFDEN 0x07 -#define ADE7759_CH1OS 0x08 -#define ADE7759_CH2OS 0x09 -#define ADE7759_GAIN 0x0A -#define ADE7759_APGAIN 0x0B -#define ADE7759_PHCAL 0x0C -#define ADE7759_APOS 0x0D -#define ADE7759_ZXTOUT 0x0E -#define ADE7759_SAGCYC 0x0F -#define ADE7759_IRQEN 0x10 -#define ADE7759_SAGLVL 0x11 -#define ADE7759_TEMP 0x12 -#define ADE7759_LINECYC 0x13 -#define ADE7759_LENERGY 0x14 -#define ADE7759_CFNUM 0x15 -#define ADE7759_CHKSUM 0x1E -#define ADE7759_DIEREV 0x1F - -#define ADE7759_READ_REG(a) a -#define ADE7759_WRITE_REG(a) ((a) | 0x80) - -#define ADE7759_MAX_TX 6 -#define ADE7759_MAX_RX 6 -#define ADE7759_STARTUP_DELAY 1000 - -#define ADE7759_SPI_SLOW (u32)(300 * 1000) -#define ADE7759_SPI_BURST (u32)(1000 * 1000) -#define ADE7759_SPI_FAST (u32)(2000 * 1000) - -/** - * struct ade7759_state - device instance specific data - * @us: actual spi_device - * @buf_lock: mutex to protect tx and rx and write frequency - * @tx: transmit buffer - * @rx: receive buffer - **/ -struct ade7759_state { - struct spi_device *us; - struct mutex buf_lock; - u8 tx[ADE7759_MAX_TX] ____cacheline_aligned; - u8 rx[ADE7759_MAX_RX]; -}; - -static int ade7759_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7759_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/*Unlocked version of ade7759_spi_write_reg_16 function */ -static int __ade7759_spi_write_reg_16(struct device *dev, - u8 reg_address, - u16 value) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - - st->tx[0] = ADE7759_WRITE_REG(reg_address); - st->tx[1] = (value >> 8) & 0xFF; - st->tx[2] = value & 0xFF; - return spi_write(st->us, st->tx, 3); -} - -static int ade7759_spi_write_reg_16(struct device *dev, - u8 reg_address, - u16 value) -{ - int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - ret = __ade7759_spi_write_reg_16(dev, reg_address, value); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int ade7759_spi_read_reg_8(struct device *dev, - u8 reg_address, - u8 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - int ret; - - ret = spi_w8r8(st->us, ADE7759_READ_REG(reg_address)); - if (ret < 0) { - dev_err(&st->us->dev, - "problem when reading 8 bit register 0x%02X", - reg_address); - return ret; - } - *val = ret; - - return 0; -} - -static int ade7759_spi_read_reg_16(struct device *dev, - u8 reg_address, - u16 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - int ret; - - ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address)); - if (ret < 0) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - return ret; - } - - *val = ret; - - return 0; -} - -static int ade7759_spi_read_reg_40(struct device *dev, - u8 reg_address, - u64 *val) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 6, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7759_READ_REG(reg_address); - memset(&st->tx[1], 0, 5); - - ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 40 bit register 0x%02X", - reg_address); - goto error_ret; - } - *val = ((u64)st->rx[1] << 32) | ((u64)st->rx[2] << 24) | - (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static ssize_t ade7759_read_8bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u8 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7759_spi_read_reg_8(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7759_read_16bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7759_spi_read_reg_16(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val); -} - -static ssize_t ade7759_read_40bit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u64 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = ade7759_spi_read_reg_40(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%llu\n", val); -} - -static ssize_t ade7759_write_8bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u8 val; - - ret = kstrtou8(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7759_spi_write_reg_8(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static ssize_t ade7759_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - u16 val; - - ret = kstrtou16(buf, 10, &val); - if (ret) - goto error_ret; - ret = ade7759_spi_write_reg_16(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static int ade7759_reset(struct device *dev) -{ - int ret; - u16 val; - - ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); - if (ret < 0) - return ret; - - val |= BIT(6); /* Software Chip Reset */ - return ade7759_spi_write_reg_16(dev, - ADE7759_MODE, - val); -} - -static IIO_DEV_ATTR_AENERGY(ade7759_read_40bit, ADE7759_AENERGY); -static IIO_DEV_ATTR_CFDEN(0644, - ade7759_read_16bit, - ade7759_write_16bit, - ADE7759_CFDEN); -static IIO_DEV_ATTR_CFNUM(0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_CFNUM); -static IIO_DEV_ATTR_CHKSUM(ade7759_read_8bit, ADE7759_CHKSUM); -static IIO_DEV_ATTR_PHCAL(0644, - ade7759_read_16bit, - ade7759_write_16bit, - ADE7759_PHCAL); -static IIO_DEV_ATTR_APOS(0644, - ade7759_read_16bit, - ade7759_write_16bit, - ADE7759_APOS); -static IIO_DEV_ATTR_SAGCYC(0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_SAGCYC); -static IIO_DEV_ATTR_SAGLVL(0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_SAGLVL); -static IIO_DEV_ATTR_LINECYC(0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_LINECYC); -static IIO_DEV_ATTR_LENERGY(ade7759_read_40bit, ADE7759_LENERGY); -static IIO_DEV_ATTR_PGA_GAIN(0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_GAIN); -static IIO_DEV_ATTR_ACTIVE_POWER_GAIN(0644, - ade7759_read_16bit, - ade7759_write_16bit, - ADE7759_APGAIN); - -static IIO_DEVICE_ATTR(choff_1, 0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_CH1OS); - -static IIO_DEVICE_ATTR(choff_2, 0644, - ade7759_read_8bit, - ade7759_write_8bit, - ADE7759_CH2OS); - -static int ade7759_set_irq(struct device *dev, bool enable) -{ - int ret; - u8 irqen; - - ret = ade7759_spi_read_reg_8(dev, ADE7759_IRQEN, &irqen); - if (ret) - goto error_ret; - - if (enable) - irqen |= BIT(3); /* Enables an interrupt when a data is - * present in the waveform register - */ - else - irqen &= ~BIT(3); - - ret = ade7759_spi_write_reg_8(dev, ADE7759_IRQEN, irqen); - -error_ret: - return ret; -} - -/* Power down the device */ -static int ade7759_stop_device(struct device *dev) -{ - int ret; - u16 val; - - ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); - if (ret < 0) { - dev_err(dev, "unable to power down the device, error: %d\n", - ret); - return ret; - } - - val |= BIT(4); /* AD converters can be turned off */ - - return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val); -} - -static int ade7759_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct ade7759_state *st = iio_priv(indio_dev); - struct device *dev = &indio_dev->dev; - - /* use low spi speed for init */ - st->us->mode = SPI_MODE_3; - spi_setup(st->us); - - /* Disable IRQ */ - ret = ade7759_set_irq(dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - ade7759_reset(dev); - usleep_range(ADE7759_STARTUP_DELAY, ADE7759_STARTUP_DELAY + 100); - -err_ret: - return ret; -} - -static ssize_t ade7759_read_frequency(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 t; - int sps; - - ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &t); - if (ret) - return ret; - - t = (t >> 3) & 0x3; - sps = 27900 / (1 + t); - - return sprintf(buf, "%d\n", sps); -} - -static ssize_t ade7759_write_frequency(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ade7759_state *st = iio_priv(indio_dev); - u16 val; - int ret; - u16 reg, t; - - ret = kstrtou16(buf, 10, &val); - if (ret) - return ret; - if (!val) - return -EINVAL; - - mutex_lock(&st->buf_lock); - - t = 27900 / val; - if (t > 0) - t--; - - if (t > 1) - st->us->max_speed_hz = ADE7759_SPI_SLOW; - else - st->us->max_speed_hz = ADE7759_SPI_FAST; - - ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, ®); - if (ret) - goto out; - - reg &= ~(3 << 13); - reg |= t << 13; - - ret = __ade7759_spi_write_reg_16(dev, ADE7759_MODE, reg); - -out: - mutex_unlock(&st->buf_lock); - - return ret ? ret : len; -} -static IIO_DEV_ATTR_TEMP_RAW(ade7759_read_8bit); -static IIO_CONST_ATTR(in_temp_offset, "70 C"); -static IIO_CONST_ATTR(in_temp_scale, "1 C"); - -static IIO_DEV_ATTR_SAMP_FREQ(0644, - ade7759_read_frequency, - ade7759_write_frequency); - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500"); - -static struct attribute *ade7759_attributes[] = { - &iio_dev_attr_in_temp_raw.dev_attr.attr, - &iio_const_attr_in_temp_offset.dev_attr.attr, - &iio_const_attr_in_temp_scale.dev_attr.attr, - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_phcal.dev_attr.attr, - &iio_dev_attr_cfden.dev_attr.attr, - &iio_dev_attr_aenergy.dev_attr.attr, - &iio_dev_attr_cfnum.dev_attr.attr, - &iio_dev_attr_apos.dev_attr.attr, - &iio_dev_attr_sagcyc.dev_attr.attr, - &iio_dev_attr_saglvl.dev_attr.attr, - &iio_dev_attr_linecyc.dev_attr.attr, - &iio_dev_attr_lenergy.dev_attr.attr, - &iio_dev_attr_chksum.dev_attr.attr, - &iio_dev_attr_pga_gain.dev_attr.attr, - &iio_dev_attr_active_power_gain.dev_attr.attr, - &iio_dev_attr_choff_1.dev_attr.attr, - &iio_dev_attr_choff_2.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ade7759_attribute_group = { - .attrs = ade7759_attributes, -}; - -static const struct iio_info ade7759_info = { - .attrs = &ade7759_attribute_group, -}; - -static int ade7759_probe(struct spi_device *spi) -{ - int ret; - struct ade7759_state *st; - struct iio_dev *indio_dev; - - /* setup the industrialio driver allocated elements */ - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!indio_dev) - return -ENOMEM; - /* this is only used for removal purposes */ - spi_set_drvdata(spi, indio_dev); - - st = iio_priv(indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->info = &ade7759_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Get the device into a sane initial state */ - ret = ade7759_initial_setup(indio_dev); - if (ret) - return ret; - - return iio_device_register(indio_dev); -} - -static int ade7759_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - ade7759_stop_device(&indio_dev->dev); - - return 0; -} - -static struct spi_driver ade7759_driver = { - .driver = { - .name = "ade7759", - }, - .probe = ade7759_probe, - .remove = ade7759_remove, -}; -module_spi_driver(ade7759_driver); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7759 Active Energy Metering IC Driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:ad7759"); From 71b52d2c746b2915d615e29f5873e1ee5f3c5f52 Mon Sep 17 00:00:00 2001 From: Martin Kelly Date: Thu, 17 May 2018 17:14:45 -0700 Subject: [PATCH 36/42] tools: iio: iio_generic_buffer: fix types to match Several types are mismatched and causing implicit conversions. Fix them up so the types match. Signed-off-by: Martin Kelly Signed-off-by: Jonathan Cameron --- tools/iio/iio_generic_buffer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c index f0c6f54a8b2f..aa765c11992b 100644 --- a/tools/iio/iio_generic_buffer.c +++ b/tools/iio/iio_generic_buffer.c @@ -334,7 +334,10 @@ int main(int argc, char **argv) unsigned long timedelay = 1000000; unsigned long buf_len = 128; - int ret, c, i, j, toread; + ssize_t i; + unsigned long j; + unsigned long toread; + int ret, c; int fp = -1; int num_channels = 0; From 55dda0abcf9d36bf5c3e21c8423b7c00a1125e27 Mon Sep 17 00:00:00 2001 From: Martin Kelly Date: Thu, 17 May 2018 17:14:46 -0700 Subject: [PATCH 37/42] tools: iio: iio_generic_buffer: allow continuous looping Sometimes it's useful to stream samples forever, such as when stress-testing a driver overnight to check for memory leaks or other issues. When the program receives a signal, it will gracefully cleanup, so it is still safe to terminate at any time. Add support for specifying a negative -c option, meaning that we should loop forever. To do so, we need to use a long long (instead of just long) for num_loops so that current code specifying num_loops greater than UNSIGNED_LONG_MAX doesn't break. Signed-off-by: Martin Kelly Signed-off-by: Jonathan Cameron --- tools/iio/iio_generic_buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c index aa765c11992b..3040830d7797 100644 --- a/tools/iio/iio_generic_buffer.c +++ b/tools/iio/iio_generic_buffer.c @@ -248,7 +248,7 @@ void print_usage(void) "Capture, convert and output data from IIO device buffer\n" " -a Auto-activate all available channels\n" " -A Force-activate ALL channels\n" - " -c Do n conversions\n" + " -c Do n conversions, or loop forever if n < 0\n" " -e Disable wait for event (new data)\n" " -g Use trigger-less mode\n" " -l Set buffer length to n samples\n" @@ -330,12 +330,12 @@ static const struct option longopts[] = { int main(int argc, char **argv) { - unsigned long num_loops = 2; + unsigned long long num_loops = 2; unsigned long timedelay = 1000000; unsigned long buf_len = 128; ssize_t i; - unsigned long j; + unsigned long long j; unsigned long toread; int ret, c; int fp = -1; @@ -369,7 +369,7 @@ int main(int argc, char **argv) break; case 'c': errno = 0; - num_loops = strtoul(optarg, &dummy, 10); + num_loops = strtoll(optarg, &dummy, 10); if (errno) { ret = -errno; goto error; @@ -637,7 +637,7 @@ int main(int argc, char **argv) goto error; } - for (j = 0; j < num_loops; j++) { + for (j = 0; j < num_loops || num_loops < 0; j++) { if (!noevents) { struct pollfd pfd = { .fd = fp, From 2636d005758928c2884ac610589f383c73919bcf Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Mon, 21 May 2018 09:40:05 +0300 Subject: [PATCH 38/42] iio: amplifiers: ad8366: move channel init before iio_device_register() Otherwise a race condition can occur, where userspace can start operations before the channels have been properly initialized. Signed-off-by: Alexandru Ardelean Signed-off-by: Jonathan Cameron --- drivers/iio/amplifiers/ad8366.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index 43667866321e..0138337aedd1 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c @@ -161,12 +161,14 @@ static int ad8366_probe(struct spi_device *spi) indio_dev->channels = ad8366_channels; indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); + ret = ad8366_write(indio_dev, 0 , 0); + if (ret < 0) + goto error_disable_reg; + ret = iio_device_register(indio_dev); if (ret) goto error_disable_reg; - ad8366_write(indio_dev, 0, 0); - return 0; error_disable_reg: From dd63b4fa0dea703e6ec494d39b14b3fff0e63a46 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 21 May 2018 10:16:54 +0100 Subject: [PATCH 39/42] iio: adc: fix spelling mistake: "Freeacale" -> "Freescale" Trivial fix to spelling mistake in module description text Signed-off-by: Colin Ian King Signed-off-by: Jonathan Cameron --- drivers/iio/adc/imx7d_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c index cfab31162845..ad6764fb2a23 100644 --- a/drivers/iio/adc/imx7d_adc.c +++ b/drivers/iio/adc/imx7d_adc.c @@ -604,5 +604,5 @@ static struct platform_driver imx7d_adc_driver = { module_platform_driver(imx7d_adc_driver); MODULE_AUTHOR("Haibo Chen "); -MODULE_DESCRIPTION("Freeacale IMX7D ADC driver"); +MODULE_DESCRIPTION("Freescale IMX7D ADC driver"); MODULE_LICENSE("GPL v2"); From 0f6a2165af72914965fca0990ff11d3aa5a4dd10 Mon Sep 17 00:00:00 2001 From: Silvan Murer Date: Mon, 21 May 2018 14:21:27 +0200 Subject: [PATCH 40/42] iio: dac: fix missing of_match_table assignment in the LTC 2632 device Signed-off-by: Silvan Murer Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ltc2632.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c index af2ddd0dd341..08a78f08a2ba 100644 --- a/drivers/iio/dac/ltc2632.c +++ b/drivers/iio/dac/ltc2632.c @@ -275,15 +275,6 @@ static const struct spi_device_id ltc2632_id[] = { }; MODULE_DEVICE_TABLE(spi, ltc2632_id); -static struct spi_driver ltc2632_driver = { - .driver = { - .name = "ltc2632", - }, - .probe = ltc2632_probe, - .id_table = ltc2632_id, -}; -module_spi_driver(ltc2632_driver); - static const struct of_device_id ltc2632_of_match[] = { { .compatible = "lltc,ltc2632-l12", @@ -308,6 +299,16 @@ static const struct of_device_id ltc2632_of_match[] = { }; MODULE_DEVICE_TABLE(of, ltc2632_of_match); +static struct spi_driver ltc2632_driver = { + .driver = { + .name = "ltc2632", + .of_match_table = of_match_ptr(ltc2632_of_match), + }, + .probe = ltc2632_probe, + .id_table = ltc2632_id, +}; +module_spi_driver(ltc2632_driver); + MODULE_AUTHOR("Maxime Roussin-Belanger "); MODULE_DESCRIPTION("LTC2632 DAC SPI driver"); MODULE_LICENSE("GPL v2"); From 9ff1d5009fc4b47ac0e6d7818dac0158e1804c3e Mon Sep 17 00:00:00 2001 From: Silvan Murer Date: Mon, 21 May 2018 14:21:28 +0200 Subject: [PATCH 41/42] iio: dac: Add support for external reference voltage through the regulator framework. Signed-off-by: Silvan Murer Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/dac/ltc2632.txt | 14 ++++ drivers/iio/dac/ltc2632.c | 70 ++++++++++++++++--- 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt index eb911e5a8ab4..e0d5fea33031 100644 --- a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt +++ b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt @@ -12,12 +12,26 @@ Required properties: Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt apply. In particular, "reg" and "spi-max-frequency" properties must be given. +Optional properties: + - vref-supply: Phandle to the external reference voltage supply. This should + only be set if there is an external reference voltage connected to the VREF + pin. If the property is not set the internal reference is used. + Example: + vref: regulator-vref { + compatible = "regulator-fixed"; + regulator-name = "vref-ltc2632"; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + }; + spi_master { dac: ltc2632@0 { compatible = "lltc,ltc2632-l12"; reg = <0>; /* CS0 */ spi-max-frequency = <1000000>; + vref-supply = <&vref>; /* optional */ }; }; diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c index 08a78f08a2ba..cca278eaa138 100644 --- a/drivers/iio/dac/ltc2632.c +++ b/drivers/iio/dac/ltc2632.c @@ -2,6 +2,7 @@ * LTC2632 Digital to analog convertors spi driver * * Copyright 2017 Maxime Roussin-Bélanger + * expanded by Silvan Murer * * Licensed under the GPL-2. */ @@ -10,6 +11,7 @@ #include #include #include +#include #define LTC2632_DAC_CHANNELS 2 @@ -28,7 +30,7 @@ /** * struct ltc2632_chip_info - chip specific information * @channels: channel spec for the DAC - * @vref_mv: reference voltage + * @vref_mv: internal reference voltage */ struct ltc2632_chip_info { const struct iio_chan_spec *channels; @@ -39,10 +41,14 @@ struct ltc2632_chip_info { * struct ltc2632_state - driver instance specific data * @spi_dev: pointer to the spi_device struct * @powerdown_cache_mask used to show current channel powerdown state + * @vref_mv used reference voltage (internal or external) + * @vref_reg regulator for the reference voltage */ struct ltc2632_state { struct spi_device *spi_dev; unsigned int powerdown_cache_mask; + int vref_mv; + struct regulator *vref_reg; }; enum ltc2632_supported_device_ids { @@ -90,7 +96,7 @@ static int ltc2632_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_SCALE: - *val = chip_info->vref_mv; + *val = st->vref_mv; *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; } @@ -246,6 +252,45 @@ static int ltc2632_probe(struct spi_device *spi) chip_info = (struct ltc2632_chip_info *) spi_get_device_id(spi)->driver_data; + st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref"); + if (PTR_ERR(st->vref_reg) == -ENODEV) { + /* use internal reference voltage */ + st->vref_reg = NULL; + st->vref_mv = chip_info->vref_mv; + + ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER, + 0, 0, 0); + if (ret) { + dev_err(&spi->dev, + "Set internal reference command failed, %d\n", + ret); + return ret; + } + } else if (IS_ERR(st->vref_reg)) { + dev_err(&spi->dev, + "Error getting voltage reference regulator\n"); + return PTR_ERR(st->vref_reg); + } else { + /* use external reference voltage */ + ret = regulator_enable(st->vref_reg); + if (ret) { + dev_err(&spi->dev, + "enable reference regulator failed, %d\n", + ret); + return ret; + } + st->vref_mv = regulator_get_voltage(st->vref_reg) / 1000; + + ret = ltc2632_spi_write(spi, LTC2632_CMD_EXTERNAL_REFER, + 0, 0, 0); + if (ret) { + dev_err(&spi->dev, + "Set external reference command failed, %d\n", + ret); + return ret; + } + } + indio_dev->dev.parent = &spi->dev; indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name : spi_get_device_id(spi)->name; @@ -254,14 +299,20 @@ static int ltc2632_probe(struct spi_device *spi) indio_dev->channels = chip_info->channels; indio_dev->num_channels = LTC2632_DAC_CHANNELS; - ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER, 0, 0, 0); - if (ret) { - dev_err(&spi->dev, - "Set internal reference command failed, %d\n", ret); - return ret; - } + return iio_device_register(indio_dev); +} - return devm_iio_device_register(&spi->dev, indio_dev); +static int ltc2632_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ltc2632_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + if (st->vref_reg) + regulator_disable(st->vref_reg); + + return 0; } static const struct spi_device_id ltc2632_id[] = { @@ -305,6 +356,7 @@ static struct spi_driver ltc2632_driver = { .of_match_table = of_match_ptr(ltc2632_of_match), }, .probe = ltc2632_probe, + .remove = ltc2632_remove, .id_table = ltc2632_id, }; module_spi_driver(ltc2632_driver); From 96c92d42e9c93b2647d55b84ad883b11baa76307 Mon Sep 17 00:00:00 2001 From: Martin Kelly Date: Mon, 21 May 2018 11:41:54 -0700 Subject: [PATCH 42/42] iio: imu: inv_mpu6050: add comment about frequencies Although the driver allows frequencies between 4 and 1000 Hz, only the frequencies advertised in the available frequencies file are backed properly by a low-pass filter to prevent aliasing, so it's best to use them. Since this is not obvious to the user, add a comment explaining what's going on. Signed-off-by: Martin Kelly Acked-by: Jean-Baptiste Maneyrol Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 43fba5f7532b..f9c0624505a2 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -798,7 +798,14 @@ static const struct iio_chan_spec inv_mpu_channels[] = { INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z), }; -/* constant IIO attribute */ +/* + * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and + * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the + * low-pass filter. Specifically, each of these sampling rates are about twice + * the bandwidth of a corresponding low-pass filter, which should eliminate + * aliasing following the Nyquist principle. By picking a frequency different + * from these, the user risks aliasing effects. + */ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500"); static IIO_CONST_ATTR(in_anglvel_scale_available, "0.000133090 0.000266181 0.000532362 0.001064724");