2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2025-01-10 14:43:54 +08:00
linux-next/drivers/iio/adc/ti-ads1015.c
Greg Kroah-Hartman 98c2f10d23 First round of IIO new device support, features and cleanups for the 4.14 cycle.
4 completely new drivers in this set and plenty of other stuff.
 
 One ABI change due to a silly mistake a long time back. Hopefully no
 one will notice.  It effects the numerical order of consumer device
 channels which was the reverse of the obvious.  It's going the slow
 way to allow us some margin to spot if we have broken userspace or
 not (seems unlikely)
 
 New Device Support
 * ccs811
   - new driver for the Volatile Organic Compounds (VOC) sensor.
 * dln2 adc
   - new driver for the ADC on this flexible usb board.
 * EP93xx
   - new driver for this Cirrus logic SoC ADC.
 * ltc2471
   - new ADC driver support the ltc2471 and ltc2473
 * st_accel
   - add trivial table entries to support H3LIS331DL, LIS331DL, LIS3LV02DL.
 * st_gyro
   - add L3GD20H support (again) having fixed the various things that were
     broken in the first try.  Includes devicetree binding.
 * stm32 dac
   - add support for the DACs in the STM32F4 series
 
 Features
 * Documentation
   - add missing power attribute documentation to the ABI docs.
 * at91-sama5d2
   - add hardware trigger and buffered capture support with bindings.
   - suspend and resume functionality.
 * bmc150
   - support for the BOSC0200 ACPI device id seen on some tablets.
 * hdc100x
   - devicetree bindings
   - document supported devices
   - match table and device ids.
 * hts221
   - support active low interrupts (with bindings)
   - open drain mode with bindings.
 * htu21
   - OF match table and bindings.
 * lsm6dsx
   - open drain mode with bindings
 * ltc2497
   - add support for board file based consumer mapping.
 * ms5367
   - OF match table and bindings.
 * mt7622
   - binding document and OF match table.
   - suspend and resume support.
 * rpr0521
   - triggered buffer support.
 * tsys01
   - OF match table and bindings.
 
 Cleanups and minor fixes
 * core
   - fix ordering of IIO channels to entry numbers when using
     iio_map_array_register rather than reversing them.
   - use the new %pOF format specifier rather than full name for the
     device tree nodes.
 * ad7280a
   - fix potential issue with macro argument reuse.
 * ad7766
   - drop a pointless NULL value check as it's done in the gpiod code.
 * adis16400
   - unsigned -> unsigned int.
 * at91 adc
   - make some init data static to reduce code size.
 * at91-sama5d2 ADC
   - make some init data static to reduce code size.
 * da311
   - make some init data static to reduce code size.
 * hid-sensor-rotation
   - drop an unnecessary static.
 * hts221
   - refactor the write_with_mask code.
   - move the BDU configuration to probe time as there is no reason for it
     to change.
   - avoid overwriting reserved data during power-down.  This is a fix, but
     the infrastructure need was too invasive to send it to mainline except
     in a merge window.  It's not a regression as it was always wrong.
   - avoid reconfigure the sampling frequency multiple times by just
     doing it in the write_raw function directly.
   - refactor the power_on/off calls into a set_enable.
   - move the dry-enable logic into trig_set_state as that is the only
     place it was used.
 * ina219
   - fix polling of ina226 conversion ready flag.
 * imx7d
   - add vendor name in kconfig for consistency with similar parts.
 * mcp3422
   - Change initial channel to 0 as it feels more logical.
   - Check for some errors in probe.
 * meson-saradc
   - add a check of of_match_device return value.
 * mpu3050
   - allow open drain for any interrupt type.
 * rockchip adc
   - add check on of_match_device return value.
 * sca3000
   - drop a trailing whitespace.
 * stm32 adc
   - make array stm32h7_adc_ckmodes_spec static.
 * stm32 dac
   - fix an error message.
 * stm32 timers
   - fix clock name in docs to match reality after changes.
 * st_accel
   - explicit OF table (spi).
   - add missing entries to OF table (i2c).
   - rename of_device_id table to drop the part name.
   - adding missing lis3l02dq entry to bindings.
   - rename H3LIS331DL_DRIVER_NAME to line up with similar entries in driver.
 * st_gyro
   - explicit OF table (spi).
 * st_magn
   - explicit OF table (spi).
   - enable multiread for lis3mdl.
 * st_pressure
   - explicit OF table (spi).
 * st_sensors common.
   - move st_sensors_of_i2c_probe and rename to make it available for spi
   drivers.
 * tsc3472
   - don't write an extra byte when writing the ATIME register.
   - add a link to the datasheet.
 * tsl2x7x - continued staging cleanups
   - add of_match_table.
   - drop redundant power_state sysfs attribute.
   - drop wrapper tsl2x7x_i2c_read.
   - clean up i2c calls made in tsl2x7x_als_calibrate.
   - refactor the read and write _event_value callbacks to handle additional
     elements.
   - use usleep_range instead of mdelay.
   - check return value from tsl2x7x_invoke_change.
 * zpa2326
   - add some newline to the end of logging macros.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAll3oWIRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FoimeBAAs2WBPr8kQZeDfdjNS5isk+GoBJ4btHDL
 +BpBODylDku/WIJb7hpBymH2Xs/7qUuYLYwz0P1XVrSo/1kK+krJQR0DUwcracfy
 gqMS4KEmgWbhmBV2ksPfCGcoT5rimxLUqpka5+WWAszNtwi7YOt5FadTb9yK4WdG
 Di5AzaVLKAUBpQrrHdFPXewxenVs1P/X0ES7fSNU1SIL2bRAaPDj9duu3URivt9l
 XRh7qqNpuNMIQ3MmeEeLDJkyeeeWHYdnps/XDfW0i5VElxwZImTPD+AFAoc2E51J
 pujvXlu1a6FgMH+hp7hbOxNuf3eKlIq9mrfGre4K6DkTB0gro3oU2bCa5BEq/be1
 PrKQZsfkK0KmrLCh0UqwTTcWdorOfussWpZ6Ib4/l4JQEeII/odwyZJ3vHNlm0Gy
 0n/TVfNVQEY2zLswWdUOaQ2bvLGaXoeIBH0sMtCPOKks/4u692qZg3LAC1g5mEKF
 4ykKG8oJ/UvWcqb00Z1H1qkT+B0ZmOEZzf6M7rFlPKr48DHrbu1YZcoaPYoBxeWP
 nL9S0zdygs06HI3/5Rl4Vv7HMTCbKabOp7eamW3IDqRpcW6dLzsXrG/e3YFbvMxq
 sGfd3g8jXaf1rlA9qP5FOHdQM2ySoi/WliwShH46LTY17sHSwQd46FYDKn4ZMT4q
 6oMBnYOeadg=
 =imPz
 -----END PGP SIGNATURE-----

Merge tag 'iio-for-4.14a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

First round of IIO new device support, features and cleanups for the 4.14 cycle.

4 completely new drivers in this set and plenty of other stuff.

One ABI change due to a silly mistake a long time back. Hopefully no
one will notice.  It effects the numerical order of consumer device
channels which was the reverse of the obvious.  It's going the slow
way to allow us some margin to spot if we have broken userspace or
not (seems unlikely)

New Device Support
* ccs811
  - new driver for the Volatile Organic Compounds (VOC) sensor.
* dln2 adc
  - new driver for the ADC on this flexible usb board.
* EP93xx
  - new driver for this Cirrus logic SoC ADC.
* ltc2471
  - new ADC driver support the ltc2471 and ltc2473
* st_accel
  - add trivial table entries to support H3LIS331DL, LIS331DL, LIS3LV02DL.
* st_gyro
  - add L3GD20H support (again) having fixed the various things that were
    broken in the first try.  Includes devicetree binding.
* stm32 dac
  - add support for the DACs in the STM32F4 series

Features
* Documentation
  - add missing power attribute documentation to the ABI docs.
* at91-sama5d2
  - add hardware trigger and buffered capture support with bindings.
  - suspend and resume functionality.
* bmc150
  - support for the BOSC0200 ACPI device id seen on some tablets.
* hdc100x
  - devicetree bindings
  - document supported devices
  - match table and device ids.
* hts221
  - support active low interrupts (with bindings)
  - open drain mode with bindings.
* htu21
  - OF match table and bindings.
* lsm6dsx
  - open drain mode with bindings
* ltc2497
  - add support for board file based consumer mapping.
* ms5367
  - OF match table and bindings.
* mt7622
  - binding document and OF match table.
  - suspend and resume support.
* rpr0521
  - triggered buffer support.
* tsys01
  - OF match table and bindings.

Cleanups and minor fixes
* core
  - fix ordering of IIO channels to entry numbers when using
    iio_map_array_register rather than reversing them.
  - use the new %pOF format specifier rather than full name for the
    device tree nodes.
* ad7280a
  - fix potential issue with macro argument reuse.
* ad7766
  - drop a pointless NULL value check as it's done in the gpiod code.
* adis16400
  - unsigned -> unsigned int.
* at91 adc
  - make some init data static to reduce code size.
* at91-sama5d2 ADC
  - make some init data static to reduce code size.
* da311
  - make some init data static to reduce code size.
* hid-sensor-rotation
  - drop an unnecessary static.
* hts221
  - refactor the write_with_mask code.
  - move the BDU configuration to probe time as there is no reason for it
    to change.
  - avoid overwriting reserved data during power-down.  This is a fix, but
    the infrastructure need was too invasive to send it to mainline except
    in a merge window.  It's not a regression as it was always wrong.
  - avoid reconfigure the sampling frequency multiple times by just
    doing it in the write_raw function directly.
  - refactor the power_on/off calls into a set_enable.
  - move the dry-enable logic into trig_set_state as that is the only
    place it was used.
* ina219
  - fix polling of ina226 conversion ready flag.
* imx7d
  - add vendor name in kconfig for consistency with similar parts.
* mcp3422
  - Change initial channel to 0 as it feels more logical.
  - Check for some errors in probe.
* meson-saradc
  - add a check of of_match_device return value.
* mpu3050
  - allow open drain for any interrupt type.
* rockchip adc
  - add check on of_match_device return value.
* sca3000
  - drop a trailing whitespace.
* stm32 adc
  - make array stm32h7_adc_ckmodes_spec static.
* stm32 dac
  - fix an error message.
* stm32 timers
  - fix clock name in docs to match reality after changes.
* st_accel
  - explicit OF table (spi).
  - add missing entries to OF table (i2c).
  - rename of_device_id table to drop the part name.
  - adding missing lis3l02dq entry to bindings.
  - rename H3LIS331DL_DRIVER_NAME to line up with similar entries in driver.
* st_gyro
  - explicit OF table (spi).
* st_magn
  - explicit OF table (spi).
  - enable multiread for lis3mdl.
* st_pressure
  - explicit OF table (spi).
* st_sensors common.
  - move st_sensors_of_i2c_probe and rename to make it available for spi
  drivers.
* tsc3472
  - don't write an extra byte when writing the ATIME register.
  - add a link to the datasheet.
* tsl2x7x - continued staging cleanups
  - add of_match_table.
  - drop redundant power_state sysfs attribute.
  - drop wrapper tsl2x7x_i2c_read.
  - clean up i2c calls made in tsl2x7x_als_calibrate.
  - refactor the read and write _event_value callbacks to handle additional
    elements.
  - use usleep_range instead of mdelay.
  - check return value from tsl2x7x_invoke_change.
* zpa2326
  - add some newline to the end of logging macros.
2017-07-27 21:29:49 -07:00

736 lines
18 KiB
C

/*
* ADS1015 - Texas Instruments Analog-to-Digital Converter
*
* Copyright (c) 2016, Intel Corporation.
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* IIO driver for ADS1015 ADC 7-bit I2C slave address:
* * 0x48 - ADDR connected to Ground
* * 0x49 - ADDR connected to Vdd
* * 0x4A - ADDR connected to SDA
* * 0x4B - ADDR connected to SCL
*/
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/platform_data/ads1015.h>
#include <linux/iio/iio.h>
#include <linux/iio/types.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#define ADS1015_DRV_NAME "ads1015"
#define ADS1015_CONV_REG 0x00
#define ADS1015_CFG_REG 0x01
#define ADS1015_CFG_DR_SHIFT 5
#define ADS1015_CFG_MOD_SHIFT 8
#define ADS1015_CFG_PGA_SHIFT 9
#define ADS1015_CFG_MUX_SHIFT 12
#define ADS1015_CFG_DR_MASK GENMASK(7, 5)
#define ADS1015_CFG_MOD_MASK BIT(8)
#define ADS1015_CFG_PGA_MASK GENMASK(11, 9)
#define ADS1015_CFG_MUX_MASK GENMASK(14, 12)
/* device operating modes */
#define ADS1015_CONTINUOUS 0
#define ADS1015_SINGLESHOT 1
#define ADS1015_SLEEP_DELAY_MS 2000
#define ADS1015_DEFAULT_PGA 2
#define ADS1015_DEFAULT_DATA_RATE 4
#define ADS1015_DEFAULT_CHAN 0
enum chip_ids {
ADS1015,
ADS1115,
};
enum ads1015_channels {
ADS1015_AIN0_AIN1 = 0,
ADS1015_AIN0_AIN3,
ADS1015_AIN1_AIN3,
ADS1015_AIN2_AIN3,
ADS1015_AIN0,
ADS1015_AIN1,
ADS1015_AIN2,
ADS1015_AIN3,
ADS1015_TIMESTAMP,
};
static const unsigned int ads1015_data_rate[] = {
128, 250, 490, 920, 1600, 2400, 3300, 3300
};
static const unsigned int ads1115_data_rate[] = {
8, 16, 32, 64, 128, 250, 475, 860
};
static const struct {
int scale;
int uscale;
} ads1015_scale[] = {
{3, 0},
{2, 0},
{1, 0},
{0, 500000},
{0, 250000},
{0, 125000},
{0, 125000},
{0, 125000},
};
#define ADS1015_V_CHAN(_chan, _addr) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.address = _addr, \
.channel = _chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = _addr, \
.scan_type = { \
.sign = 's', \
.realbits = 12, \
.storagebits = 16, \
.shift = 4, \
.endianness = IIO_CPU, \
}, \
.datasheet_name = "AIN"#_chan, \
}
#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr) { \
.type = IIO_VOLTAGE, \
.differential = 1, \
.indexed = 1, \
.address = _addr, \
.channel = _chan, \
.channel2 = _chan2, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = _addr, \
.scan_type = { \
.sign = 's', \
.realbits = 12, \
.storagebits = 16, \
.shift = 4, \
.endianness = IIO_CPU, \
}, \
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
}
#define ADS1115_V_CHAN(_chan, _addr) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.address = _addr, \
.channel = _chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = _addr, \
.scan_type = { \
.sign = 's', \
.realbits = 16, \
.storagebits = 16, \
.endianness = IIO_CPU, \
}, \
.datasheet_name = "AIN"#_chan, \
}
#define ADS1115_V_DIFF_CHAN(_chan, _chan2, _addr) { \
.type = IIO_VOLTAGE, \
.differential = 1, \
.indexed = 1, \
.address = _addr, \
.channel = _chan, \
.channel2 = _chan2, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = _addr, \
.scan_type = { \
.sign = 's', \
.realbits = 16, \
.storagebits = 16, \
.endianness = IIO_CPU, \
}, \
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
}
struct ads1015_data {
struct regmap *regmap;
/*
* Protects ADC ops, e.g: concurrent sysfs/buffered
* data reads, configuration updates
*/
struct mutex lock;
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
unsigned int *data_rate;
};
static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg)
{
return (reg == ADS1015_CFG_REG);
}
static const struct regmap_config ads1015_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.max_register = ADS1015_CFG_REG,
.writeable_reg = ads1015_is_writeable_reg,
};
static const struct iio_chan_spec ads1015_channels[] = {
ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1),
ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3),
ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3),
ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3),
ADS1015_V_CHAN(0, ADS1015_AIN0),
ADS1015_V_CHAN(1, ADS1015_AIN1),
ADS1015_V_CHAN(2, ADS1015_AIN2),
ADS1015_V_CHAN(3, ADS1015_AIN3),
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
};
static const struct iio_chan_spec ads1115_channels[] = {
ADS1115_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1),
ADS1115_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3),
ADS1115_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3),
ADS1115_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3),
ADS1115_V_CHAN(0, ADS1015_AIN0),
ADS1115_V_CHAN(1, ADS1015_AIN1),
ADS1115_V_CHAN(2, ADS1015_AIN2),
ADS1115_V_CHAN(3, ADS1015_AIN3),
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
};
static int ads1015_set_power_state(struct ads1015_data *data, bool on)
{
int ret;
struct device *dev = regmap_get_device(data->regmap);
if (on) {
ret = pm_runtime_get_sync(dev);
if (ret < 0)
pm_runtime_put_noidle(dev);
} else {
pm_runtime_mark_last_busy(dev);
ret = pm_runtime_put_autosuspend(dev);
}
return ret;
}
static
int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
{
int ret, pga, dr, conv_time;
bool change;
if (chan < 0 || chan >= ADS1015_CHANNELS)
return -EINVAL;
pga = data->channel_data[chan].pga;
dr = data->channel_data[chan].data_rate;
ret = regmap_update_bits_check(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_MUX_MASK |
ADS1015_CFG_PGA_MASK,
chan << ADS1015_CFG_MUX_SHIFT |
pga << ADS1015_CFG_PGA_SHIFT,
&change);
if (ret < 0)
return ret;
if (change) {
conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
usleep_range(conv_time, conv_time + 1);
}
return regmap_read(data->regmap, ADS1015_CONV_REG, val);
}
static irqreturn_t ads1015_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ads1015_data *data = iio_priv(indio_dev);
s16 buf[8]; /* 1x s16 ADC val + 3x s16 padding + 4x s16 timestamp */
int chan, ret, res;
memset(buf, 0, sizeof(buf));
mutex_lock(&data->lock);
chan = find_first_bit(indio_dev->active_scan_mask,
indio_dev->masklength);
ret = ads1015_get_adc_result(data, chan, &res);
if (ret < 0) {
mutex_unlock(&data->lock);
goto err;
}
buf[0] = res;
mutex_unlock(&data->lock);
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_get_time_ns(indio_dev));
err:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int ads1015_set_scale(struct ads1015_data *data, int chan,
int scale, int uscale)
{
int i, ret, rindex = -1;
for (i = 0; i < ARRAY_SIZE(ads1015_scale); i++)
if (ads1015_scale[i].scale == scale &&
ads1015_scale[i].uscale == uscale) {
rindex = i;
break;
}
if (rindex < 0)
return -EINVAL;
ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_PGA_MASK,
rindex << ADS1015_CFG_PGA_SHIFT);
if (ret < 0)
return ret;
data->channel_data[chan].pga = rindex;
return 0;
}
static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)
{
int i, ret, rindex = -1;
for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++)
if (data->data_rate[i] == rate) {
rindex = i;
break;
}
if (rindex < 0)
return -EINVAL;
ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_DR_MASK,
rindex << ADS1015_CFG_DR_SHIFT);
if (ret < 0)
return ret;
data->channel_data[chan].data_rate = rindex;
return 0;
}
static int ads1015_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
int ret, idx;
struct ads1015_data *data = iio_priv(indio_dev);
mutex_lock(&indio_dev->mlock);
mutex_lock(&data->lock);
switch (mask) {
case IIO_CHAN_INFO_RAW: {
int shift = chan->scan_type.shift;
if (iio_buffer_enabled(indio_dev)) {
ret = -EBUSY;
break;
}
ret = ads1015_set_power_state(data, true);
if (ret < 0)
break;
ret = ads1015_get_adc_result(data, chan->address, val);
if (ret < 0) {
ads1015_set_power_state(data, false);
break;
}
*val = sign_extend32(*val >> shift, 15 - shift);
ret = ads1015_set_power_state(data, false);
if (ret < 0)
break;
ret = IIO_VAL_INT;
break;
}
case IIO_CHAN_INFO_SCALE:
idx = data->channel_data[chan->address].pga;
*val = ads1015_scale[idx].scale;
*val2 = ads1015_scale[idx].uscale;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
idx = data->channel_data[chan->address].data_rate;
*val = data->data_rate[idx];
ret = IIO_VAL_INT;
break;
default:
ret = -EINVAL;
break;
}
mutex_unlock(&data->lock);
mutex_unlock(&indio_dev->mlock);
return ret;
}
static int ads1015_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val,
int val2, long mask)
{
struct ads1015_data *data = iio_priv(indio_dev);
int ret;
mutex_lock(&data->lock);
switch (mask) {
case IIO_CHAN_INFO_SCALE:
ret = ads1015_set_scale(data, chan->address, val, val2);
break;
case IIO_CHAN_INFO_SAMP_FREQ:
ret = ads1015_set_data_rate(data, chan->address, val);
break;
default:
ret = -EINVAL;
break;
}
mutex_unlock(&data->lock);
return ret;
}
static int ads1015_buffer_preenable(struct iio_dev *indio_dev)
{
return ads1015_set_power_state(iio_priv(indio_dev), true);
}
static int ads1015_buffer_postdisable(struct iio_dev *indio_dev)
{
return ads1015_set_power_state(iio_priv(indio_dev), false);
}
static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = {
.preenable = ads1015_buffer_preenable,
.postenable = iio_triggered_buffer_postenable,
.predisable = iio_triggered_buffer_predisable,
.postdisable = ads1015_buffer_postdisable,
.validate_scan_mask = &iio_validate_scan_mask_onehot,
};
static IIO_CONST_ATTR(scale_available, "3 2 1 0.5 0.25 0.125");
static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available,
sampling_frequency_available, "128 250 490 920 1600 2400 3300");
static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available,
sampling_frequency_available, "8 16 32 64 128 250 475 860");
static struct attribute *ads1015_attributes[] = {
&iio_const_attr_scale_available.dev_attr.attr,
&iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr,
NULL,
};
static const struct attribute_group ads1015_attribute_group = {
.attrs = ads1015_attributes,
};
static struct attribute *ads1115_attributes[] = {
&iio_const_attr_scale_available.dev_attr.attr,
&iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr,
NULL,
};
static const struct attribute_group ads1115_attribute_group = {
.attrs = ads1115_attributes,
};
static const struct iio_info ads1015_info = {
.driver_module = THIS_MODULE,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
.attrs = &ads1015_attribute_group,
};
static const struct iio_info ads1115_info = {
.driver_module = THIS_MODULE,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
.attrs = &ads1115_attribute_group,
};
#ifdef CONFIG_OF
static int ads1015_get_channels_config_of(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ads1015_data *data = iio_priv(indio_dev);
struct device_node *node;
if (!client->dev.of_node ||
!of_get_next_child(client->dev.of_node, NULL))
return -EINVAL;
for_each_child_of_node(client->dev.of_node, node) {
u32 pval;
unsigned int channel;
unsigned int pga = ADS1015_DEFAULT_PGA;
unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
if (of_property_read_u32(node, "reg", &pval)) {
dev_err(&client->dev, "invalid reg on %pOF\n",
node);
continue;
}
channel = pval;
if (channel >= ADS1015_CHANNELS) {
dev_err(&client->dev,
"invalid channel index %d on %pOF\n",
channel, node);
continue;
}
if (!of_property_read_u32(node, "ti,gain", &pval)) {
pga = pval;
if (pga > 6) {
dev_err(&client->dev, "invalid gain on %pOF\n",
node);
of_node_put(node);
return -EINVAL;
}
}
if (!of_property_read_u32(node, "ti,datarate", &pval)) {
data_rate = pval;
if (data_rate > 7) {
dev_err(&client->dev,
"invalid data_rate on %pOF\n",
node);
of_node_put(node);
return -EINVAL;
}
}
data->channel_data[channel].pga = pga;
data->channel_data[channel].data_rate = data_rate;
}
return 0;
}
#endif
static void ads1015_get_channels_config(struct i2c_client *client)
{
unsigned int k;
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ads1015_data *data = iio_priv(indio_dev);
struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev);
/* prefer platform data */
if (pdata) {
memcpy(data->channel_data, pdata->channel_data,
sizeof(data->channel_data));
return;
}
#ifdef CONFIG_OF
if (!ads1015_get_channels_config_of(client))
return;
#endif
/* fallback on default configuration */
for (k = 0; k < ADS1015_CHANNELS; ++k) {
data->channel_data[k].pga = ADS1015_DEFAULT_PGA;
data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE;
}
}
static int ads1015_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct ads1015_data *data;
int ret;
enum chip_ids chip;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
mutex_init(&data->lock);
indio_dev->dev.parent = &client->dev;
indio_dev->dev.of_node = client->dev.of_node;
indio_dev->name = ADS1015_DRV_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
if (client->dev.of_node)
chip = (enum chip_ids)of_device_get_match_data(&client->dev);
else
chip = id->driver_data;
switch (chip) {
case ADS1015:
indio_dev->channels = ads1015_channels;
indio_dev->num_channels = ARRAY_SIZE(ads1015_channels);
indio_dev->info = &ads1015_info;
data->data_rate = (unsigned int *) &ads1015_data_rate;
break;
case ADS1115:
indio_dev->channels = ads1115_channels;
indio_dev->num_channels = ARRAY_SIZE(ads1115_channels);
indio_dev->info = &ads1115_info;
data->data_rate = (unsigned int *) &ads1115_data_rate;
break;
}
/* we need to keep this ABI the same as used by hwmon ADS1015 driver */
ads1015_get_channels_config(client);
data->regmap = devm_regmap_init_i2c(client, &ads1015_regmap_config);
if (IS_ERR(data->regmap)) {
dev_err(&client->dev, "Failed to allocate register map\n");
return PTR_ERR(data->regmap);
}
ret = iio_triggered_buffer_setup(indio_dev, NULL,
ads1015_trigger_handler,
&ads1015_buffer_setup_ops);
if (ret < 0) {
dev_err(&client->dev, "iio triggered buffer setup failed\n");
return ret;
}
ret = pm_runtime_set_active(&client->dev);
if (ret)
goto err_buffer_cleanup;
pm_runtime_set_autosuspend_delay(&client->dev, ADS1015_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);
pm_runtime_enable(&client->dev);
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "Failed to register IIO device\n");
goto err_buffer_cleanup;
}
return 0;
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
static int ads1015_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ads1015_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);
iio_triggered_buffer_cleanup(indio_dev);
/* power down single shot mode */
return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_MOD_MASK,
ADS1015_SINGLESHOT << ADS1015_CFG_MOD_SHIFT);
}
#ifdef CONFIG_PM
static int ads1015_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ads1015_data *data = iio_priv(indio_dev);
return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_MOD_MASK,
ADS1015_SINGLESHOT << ADS1015_CFG_MOD_SHIFT);
}
static int ads1015_runtime_resume(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ads1015_data *data = iio_priv(indio_dev);
return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_MOD_MASK,
ADS1015_CONTINUOUS << ADS1015_CFG_MOD_SHIFT);
}
#endif
static const struct dev_pm_ops ads1015_pm_ops = {
SET_RUNTIME_PM_OPS(ads1015_runtime_suspend,
ads1015_runtime_resume, NULL)
};
static const struct i2c_device_id ads1015_id[] = {
{"ads1015", ADS1015},
{"ads1115", ADS1115},
{}
};
MODULE_DEVICE_TABLE(i2c, ads1015_id);
static const struct of_device_id ads1015_of_match[] = {
{
.compatible = "ti,ads1015",
.data = (void *)ADS1015
},
{
.compatible = "ti,ads1115",
.data = (void *)ADS1115
},
{}
};
MODULE_DEVICE_TABLE(of, ads1015_of_match);
static struct i2c_driver ads1015_driver = {
.driver = {
.name = ADS1015_DRV_NAME,
.of_match_table = ads1015_of_match,
.pm = &ads1015_pm_ops,
},
.probe = ads1015_probe,
.remove = ads1015_remove,
.id_table = ads1015_id,
};
module_i2c_driver(ads1015_driver);
MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
MODULE_DESCRIPTION("Texas Instruments ADS1015 ADC driver");
MODULE_LICENSE("GPL v2");