Browse Source

Second set of iio new device support, features and cleanups for the 4.9 cycle.

New device support
 * ad8801 dac
   - new driver supporting ad8801 and ad8803 DACs.
 * adc12138
   - new driver supporting TI adc12130/adc12132 and adc12138 ADCs.
 * ltc2485 adc
   - new driver
 * mxc6255
   - add support for the mxc6225 part name and fixup the ID check so it works.
 * vz89x VOC sensor
   - add support for the vz89te part which drops the voc_short channel and adds
     CRCs compared to other supported parts.
 
 New features
 * core
   - immutable triggers.  These effectively grant exclusive control over a
     trigger. The typical usecase is a device representing an analog part
     (perhaps a MUX) that needs to control the sampling of a downstream
     ADC.
   - resource managed trigger registration and triggered_buffer_init.
   - iio_push_event now protected against case of the event interface
     registration not having yet occured.  Only matters if an interrupt
     can occur during this window - might happen on shared interrupt lines.
   - helper to let a driver query if the trigger it is using is provided by
     itself (using the convention of both device and trigger having the same
     parent).
 * tools
   - iio-utils. Used channel modifier scaling in preference to generic scaling
     when both exist.
 * at91-adc
   - Add support for touchscreen switches closure time needed by some newer
     parts.
 * stx104
   - support the ADC channels on this ADC/DAC board. As these are the primary
     feature of the board also move the driver to the iio/adc directory.
 * sx9500
   - device tree bindings.
 
 Cleanups / Fixes
 * ad5755
   - fix an off-by-one on devnr limit check (introduced earlier this cycle)
 * ad7266
   - drop NULL check on devm_regulator_get_optional as it can't return NULL.
 * ak8974
   - avoid an unused functional warning due to rework in PM core code.
   - remove .owner field setting as done by i2c_core.
 * ina2xx
   - clear out a left over debug field from chip global data.
 * hid-sensors
   - avoid an unused functional warning due to rework in PM core code.
 * maxim-thermocouple
   - fix non static symbol warnings.
 * ms5611
   - fetch and enable regulators unconditionally when they aren't optional.
 * sca3000
   - whitespace cleanup.
 * st_sensors
   - fetch and enable regulators unconditionally rather than having them
     supported as optional regulators (missunderstanding on my part amongst
     others a while back)
   - followup to previous patch fixes error checking on the regulators.
   - mark symbols static where possible.
   - use the 'is it my trigger' help function.  This prevents the odd case
     of another device triggering from the st-sensors trigger whilst the
     st-sensors trigger is itself not using it but rather using say an hrtimer.
 * ti-ads1015
   - add missing of_node_put.
 * vz89x
   - rework to all support of new devices.
   - prevent reading of a corrupted buffer.
   - fixup a return value of 0/1 in a bool returning function.
 
 Address updates
 - Vlad Dogaru email address change.
 -----BEGIN PGP SIGNATURE-----
 
 iQIuBAABCAAYBQJX1wW9ERxqaWMyM0BrZXJuZWwub3JnAAoJEFSFNJnE9BaII9UP
 /jXkXtaL62pvipMuEujmpR7j/A+GhmSWHhnbJ9XXeGZStGMUummTyaM+6WZoCKUH
 bMtZh/ETsn+FI7mD7P/FtwHauoxSmndcaAfB6cDKQMVakbXbz4VHrim256cY3gvq
 dzF5nYX+wDue6D7k55VPrtV1isBfipeCXKBtzBlAXaVE2FK2qKP+PIlAln8Ql5/l
 b5B3pvqu0YVED4t2MzyVWcVidPOEh9GgwHu7Ba+kjVi6zuB4w+r5ZreIObb5IR54
 FDcEwL6vV9AlmX15Pc18NO+50bZ8TvgT4y7ISqaOwszaIEoDAc0hXT7TdUOscmtt
 LIbhzHVMVkPSjxvtpz2ui8GfqzhxLi3ZzfNHRegOqH4b2Cpoh4zdwn7nCyJEHZV5
 simAL00FGjzp6B4Zp+Ly6ygKzpF3iXZce0Qjlr/ge+ioNIrfuK10sdLw8NZA5GUB
 JcFYijcFLUb0Cu/KjZ7njlfdAN9Tt94xzpnllM8+j4M50Nhbw05YNhIxB7RxmeSH
 Y44/oBLG51SgtlIg5Z4rULRAcOC5dty73Inb0n4lbN/pjgIcnh+EYtPeI2fA8vyB
 XYqr4xx+A3ZX1yKpYLYO+JYtVsVq9RGYdb501uBhEE3/GWEpxZvbyqHnPwwfM+Pf
 ZNuBceBxM3yyi4Z/lKkZnQbaF/1fFoG7FO1n6iRpb8Ci
 =V1xL
 -----END PGP SIGNATURE-----

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

Jonathan writes:

Second set of iio new device support, features and cleanups for the 4.9 cycle.

New device support
* ad8801 dac
  - new driver supporting ad8801 and ad8803 DACs.
* adc12138
  - new driver supporting TI adc12130/adc12132 and adc12138 ADCs.
* ltc2485 adc
  - new driver
* mxc6255
  - add support for the mxc6225 part name and fixup the ID check so it works.
* vz89x VOC sensor
  - add support for the vz89te part which drops the voc_short channel and adds
    CRCs compared to other supported parts.

New features
* core
  - immutable triggers.  These effectively grant exclusive control over a
    trigger. The typical usecase is a device representing an analog part
    (perhaps a MUX) that needs to control the sampling of a downstream
    ADC.
  - resource managed trigger registration and triggered_buffer_init.
  - iio_push_event now protected against case of the event interface
    registration not having yet occured.  Only matters if an interrupt
    can occur during this window - might happen on shared interrupt lines.
  - helper to let a driver query if the trigger it is using is provided by
    itself (using the convention of both device and trigger having the same
    parent).
* tools
  - iio-utils. Used channel modifier scaling in preference to generic scaling
    when both exist.
* at91-adc
  - Add support for touchscreen switches closure time needed by some newer
    parts.
* stx104
  - support the ADC channels on this ADC/DAC board. As these are the primary
    feature of the board also move the driver to the iio/adc directory.
* sx9500
  - device tree bindings.

Cleanups / Fixes
* ad5755
  - fix an off-by-one on devnr limit check (introduced earlier this cycle)
* ad7266
  - drop NULL check on devm_regulator_get_optional as it can't return NULL.
* ak8974
  - avoid an unused functional warning due to rework in PM core code.
  - remove .owner field setting as done by i2c_core.
* ina2xx
  - clear out a left over debug field from chip global data.
* hid-sensors
  - avoid an unused functional warning due to rework in PM core code.
* maxim-thermocouple
  - fix non static symbol warnings.
* ms5611
  - fetch and enable regulators unconditionally when they aren't optional.
* sca3000
  - whitespace cleanup.
* st_sensors
  - fetch and enable regulators unconditionally rather than having them
    supported as optional regulators (missunderstanding on my part amongst
    others a while back)
  - followup to previous patch fixes error checking on the regulators.
  - mark symbols static where possible.
  - use the 'is it my trigger' help function.  This prevents the odd case
    of another device triggering from the st-sensors trigger whilst the
    st-sensors trigger is itself not using it but rather using say an hrtimer.
* ti-ads1015
  - add missing of_node_put.
* vz89x
  - rework to all support of new devices.
  - prevent reading of a corrupted buffer.
  - fixup a return value of 0/1 in a bool returning function.

Address updates
- Vlad Dogaru email address change.
master
Greg Kroah-Hartman 5 years ago
parent
commit
552edf8d79
  1. 1
      .mailmap
  2. 37
      Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt
  3. 24
      Documentation/devicetree/bindings/iio/proximity/sx9500.txt
  4. 4
      Documentation/driver-model/devres.txt
  5. 4
      MAINTAINERS
  6. 4
      drivers/iio/accel/mxc6255.c
  7. 36
      drivers/iio/adc/Kconfig
  8. 3
      drivers/iio/adc/Makefile
  9. 4
      drivers/iio/adc/ad7266.c
  10. 13
      drivers/iio/adc/at91_adc.c
  11. 5
      drivers/iio/adc/ina2xx-adc.c
  12. 148
      drivers/iio/adc/ltc2485.c
  13. 153
      drivers/iio/adc/stx104.c
  14. 552
      drivers/iio/adc/ti-adc12138.c
  15. 2
      drivers/iio/adc/ti-ads1015.c
  16. 4
      drivers/iio/adc/ti-ads8688.c
  17. 42
      drivers/iio/buffer/industrialio-triggered-buffer.c
  18. 201
      drivers/iio/chemical/vz89x.c
  19. 9
      drivers/iio/common/hid-sensors/hid-sensor-trigger.c
  20. 2
      drivers/iio/common/st_sensors/st_sensors_buffer.c
  21. 53
      drivers/iio/common/st_sensors/st_sensors_core.c
  22. 4
      drivers/iio/common/st_sensors/st_sensors_trigger.c
  23. 20
      drivers/iio/dac/Kconfig
  24. 2
      drivers/iio/dac/Makefile
  25. 2
      drivers/iio/dac/ad5755.c
  26. 239
      drivers/iio/dac/ad8801.c
  27. 3
      drivers/iio/industrialio-core.c
  28. 8
      drivers/iio/industrialio-event.c
  29. 95
      drivers/iio/industrialio-trigger.c
  30. 7
      drivers/iio/magnetometer/ak8974.c
  31. 6
      drivers/iio/pressure/ms5611_core.c
  32. 7
      drivers/iio/proximity/sx9500.c
  33. 6
      drivers/iio/temperature/maxim_thermocouple.c
  34. 2
      drivers/staging/iio/accel/sca3000_core.c
  35. 3
      include/linux/iio/iio.h
  36. 26
      include/linux/iio/trigger.h
  37. 8
      include/linux/iio/triggered_buffer.h
  38. 11
      tools/iio/iio_utils.c

1
.mailmap

@ -159,6 +159,7 @@ Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com>
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
Takashi YOSHII <takashi.yoshii.zj@renesas.com>

37
Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt

@ -0,0 +1,37 @@
* Texas Instruments' ADC12130/ADC12132/ADC12138
Required properties:
- compatible: Should be one of
* "ti,adc12130"
* "ti,adc12132"
* "ti,adc12138"
- reg: SPI chip select number for the device
- interrupts: Should contain interrupt for EOC (end of conversion)
- clocks: phandle to conversion clock input
- spi-max-frequency: Definision as per
Documentation/devicetree/bindings/spi/spi-bus.txt
- vref-p-supply: The regulator supply for positive analog voltage reference
Optional properties:
- vref-n-supply: The regulator supply for negative analog voltage reference
(Note that this must not go below GND or exceed vref-p)
If not specified, this is assumed to be analog ground.
- ti,acquisition-time: The number of conversion clock periods for the S/H's
acquisition time. Should be one of 6, 10, 18, 34. If not specified,
default value of 10 is used.
For high source impedances, this value can be increased to 18 or 34.
For less ADC accuracy and/or slower CCLK frequencies this value may be
decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the
datasheet for details.
Example:
adc@0 {
compatible = "ti,adc12138";
reg = <0>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio1>;
clocks = <&cclk>;
vref-p-supply = <&ldo4_reg>;
spi-max-frequency = <5000000>;
ti,acquisition-time = <6>;
};

24
Documentation/devicetree/bindings/iio/proximity/sx9500.txt

@ -0,0 +1,24 @@
Semtech's SX9500 capacitive proximity button device driver
Required properties:
- compatible: must be "semtech,sx9500"
- reg: i2c address where to find the device
- interrupt-parent : should be the phandle for the interrupt controller
- interrupts : the sole interrupt generated by the device
Refer to interrupt-controller/interrupts.txt for generic
interrupt client node bindings.
Optional properties:
- reset-gpios: Reference to the GPIO connected to the device's active
low reset pin.
Example:
sx9500@28 {
compatible = "semtech,sx9500";
reg = <0x28>;
interrupt-parent = <&gpio2>;
interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
};

4
Documentation/driver-model/devres.txt

@ -266,8 +266,12 @@ IIO
devm_iio_device_unregister()
devm_iio_kfifo_allocate()
devm_iio_kfifo_free()
devm_iio_triggered_buffer_setup()
devm_iio_triggered_buffer_cleanup()
devm_iio_trigger_alloc()
devm_iio_trigger_free()
devm_iio_trigger_register()
devm_iio_trigger_unregister()
devm_iio_channel_get()
devm_iio_channel_release()
devm_iio_channel_get_all()

4
MAINTAINERS

@ -810,11 +810,11 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: sound/aoa/
APEX EMBEDDED SYSTEMS STX104 DAC DRIVER
APEX EMBEDDED SYSTEMS STX104 IIO DRIVER
M: William Breathitt Gray <vilhelm.gray@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/iio/dac/stx104.c
F: drivers/iio/adc/stx104.c
APM DRIVER
M: Jiri Kosina <jikos@kernel.org>

4
drivers/iio/accel/mxc6255.c

@ -154,7 +154,7 @@ static int mxc6255_probe(struct i2c_client *client,
return ret;
}
if (chip_id != MXC6255_CHIP_ID) {
if ((chip_id & 0x1f) != MXC6255_CHIP_ID) {
dev_err(&client->dev, "Invalid chip id %x\n", chip_id);
return -ENODEV;
}
@ -171,12 +171,14 @@ static int mxc6255_probe(struct i2c_client *client,
}
static const struct acpi_device_id mxc6255_acpi_match[] = {
{"MXC6225", 0},
{"MXC6255", 0},
{ }
};
MODULE_DEVICE_TABLE(acpi, mxc6255_acpi_match);
static const struct i2c_device_id mxc6255_id[] = {
{"mxc6225", 0},
{"mxc6255", 0},
{ }
};

36
drivers/iio/adc/Kconfig

@ -264,6 +264,15 @@ config LPC18XX_ADC
To compile this driver as a module, choose M here: the module will be
called lpc18xx_adc.
config LTC2485
tristate "Linear Technology LTC2485 ADC driver"
depends on I2C
help
Say yes here to build support for Linear Technology LTC2485 ADC.
To compile this driver as a module, choose M here: the module will be
called ltc2485.
config MAX1027
tristate "Maxim max1027 ADC driver"
depends on SPI
@ -410,6 +419,21 @@ config ROCKCHIP_SARADC
To compile this driver as a module, choose M here: the
module will be called rockchip_saradc.
config STX104
tristate "Apex Embedded Systems STX104 driver"
depends on X86 && ISA_BUS_API
select GPIOLIB
help
Say yes here to build support for the Apex Embedded Systems STX104
integrated analog PC/104 card.
This driver supports the 16 channels of single-ended (8 channels of
differential) analog inputs, 2 channels of analog output, 4 digital
inputs, and 4 digital outputs provided by the STX104.
The base port addresses for the devices may be configured via the base
array module parameter.
config TI_ADC081C
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C
@ -430,6 +454,18 @@ config TI_ADC0832
This driver can also be built as a module. If so, the module will be
called ti-adc0832.
config TI_ADC12138
tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
If you say yes here you get support for Texas Instruments ADC12130,
ADC12132 and ADC12138 chips.
This driver can also be built as a module. If so, the module will be
called ti-adc12138.
config TI_ADC128S052
tristate "Texas Instruments ADC128S052/ADC122S021/ADC124S021"
depends on SPI

3
drivers/iio/adc/Makefile

@ -27,6 +27,7 @@ obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
obj-$(CONFIG_LTC2485) += ltc2485.o
obj-$(CONFIG_MAX1027) += max1027.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
@ -39,8 +40,10 @@ obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
obj-$(CONFIG_STX104) += stx104.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o

4
drivers/iio/adc/ad7266.c

@ -481,7 +481,7 @@ error_free_gpios:
if (!st->fixed_addr)
gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
error_disable_reg:
if (!IS_ERR_OR_NULL(st->reg))
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return ret;
@ -496,7 +496,7 @@ static int ad7266_remove(struct spi_device *spi)
iio_triggered_buffer_cleanup(indio_dev);
if (!st->fixed_addr)
gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
if (!IS_ERR_OR_NULL(st->reg))
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return 0;

13
drivers/iio/adc/at91_adc.c

@ -113,6 +113,7 @@
#define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */
#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4)
#define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */
#define AT91_ADC_TSMR_SCTIM_(x) ((x) << 16)
#define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */
#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28)
#define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */
@ -150,6 +151,7 @@
#define MAX_RLPOS_BITS 10
#define TOUCH_SAMPLE_PERIOD_US_RL 10000 /* 10ms, the SoC can't keep up with 2ms */
#define TOUCH_SHTIM 0xa
#define TOUCH_SCTIM_US 10 /* 10us for the Touchscreen Switches Closure Time */
/**
* struct at91_adc_reg_desc - Various informations relative to registers
@ -1001,7 +1003,9 @@ static void atmel_ts_close(struct input_dev *dev)
static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
{
struct iio_dev *idev = iio_priv_to_dev(st);
u32 reg = 0;
u32 tssctim = 0;
int i = 0;
/* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
@ -1034,11 +1038,20 @@ static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
return 0;
}
/* Touchscreen Switches Closure time needed for allowing the value to
* stabilize.
* Switch Closure Time = (TSSCTIM * 4) ADCClock periods
*/
tssctim = DIV_ROUND_UP(TOUCH_SCTIM_US * adc_clk_khz / 1000, 4);
dev_dbg(&idev->dev, "adc_clk at: %d KHz, tssctim at: %d\n",
adc_clk_khz, tssctim);
if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS;
else
reg = AT91_ADC_TSMR_TSMODE_5WIRE;
reg |= AT91_ADC_TSMR_SCTIM_(tssctim) & AT91_ADC_TSMR_SCTIM;
reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average)
& AT91_ADC_TSMR_TSAV;
reg |= AT91_ADC_TSMR_PENDBC_(st->ts_pendbc) & AT91_ADC_TSMR_PENDBC;

5
drivers/iio/adc/ina2xx-adc.c

@ -114,7 +114,6 @@ struct ina2xx_chip_info {
struct mutex state_lock;
unsigned int shunt_resistor;
int avg;
s64 prev_ns; /* track buffer capture time, check for underruns */
int int_time_vbus; /* Bus voltage integration time uS */
int int_time_vshunt; /* Shunt voltage integration time uS */
bool allow_async_readout;
@ -509,8 +508,6 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
iio_push_to_buffers_with_timestamp(indio_dev,
(unsigned int *)data, time_a);
chip->prev_ns = time_a;
return (unsigned long)(time_b - time_a) / 1000;
};
@ -554,8 +551,6 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev)
dev_dbg(&indio_dev->dev, "Async readout mode: %d\n",
chip->allow_async_readout);
chip->prev_ns = iio_get_time_ns(indio_dev);
chip->task = kthread_run(ina2xx_capture_thread, (void *)indio_dev,
"%s:%d-%uus", indio_dev->name, indio_dev->id,
sampling_us);

148
drivers/iio/adc/ltc2485.c

@ -0,0 +1,148 @@
/*
* ltc2485.c - Driver for Linear Technology LTC2485 ADC
*
* Copyright (C) 2016 Alison Schofield <amsfield22@gmail.com>
*
* 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.
*
* Datasheet: http://cds.linear.com/docs/en/datasheet/2485fd.pdf
*/
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
/* Power-on configuration: rejects both 50/60Hz, operates at 1x speed */
#define LTC2485_CONFIG_DEFAULT 0
struct ltc2485_data {
struct i2c_client *client;
ktime_t time_prev; /* last conversion */
};
static void ltc2485_wait_conv(struct ltc2485_data *data)
{
const unsigned int conv_time = 147; /* conversion time ms */
unsigned int time_elapsed;
/* delay if conversion time not passed since last read or write */
time_elapsed = ktime_ms_delta(ktime_get(), data->time_prev);
if (time_elapsed < conv_time)
msleep(conv_time - time_elapsed);
}
static int ltc2485_read(struct ltc2485_data *data, int *val)
{
struct i2c_client *client = data->client;
__be32 buf = 0;
int ret;
ltc2485_wait_conv(data);
ret = i2c_master_recv(client, (char *)&buf, 4);
if (ret < 0) {
dev_err(&client->dev, "i2c_master_recv failed\n");
return ret;
}
data->time_prev = ktime_get();
*val = sign_extend32(be32_to_cpu(buf) >> 6, 24);
return ret;
}
static int ltc2485_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct ltc2485_data *data = iio_priv(indio_dev);
int ret;
if (mask == IIO_CHAN_INFO_RAW) {
ret = ltc2485_read(data, val);
if (ret < 0)
return ret;
return IIO_VAL_INT;
} else if (mask == IIO_CHAN_INFO_SCALE) {
*val = 5000; /* on board vref millivolts */
*val2 = 25; /* 25 (24 + sign) data bits */
return IIO_VAL_FRACTIONAL_LOG2;
} else {
return -EINVAL;
}
}
static const struct iio_chan_spec ltc2485_channel[] = {
{
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)
},
};
static const struct iio_info ltc2485_info = {
.read_raw = ltc2485_read_raw,
.driver_module = THIS_MODULE,
};
static int ltc2485_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct ltc2485_data *data;
int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
I2C_FUNC_SMBUS_WRITE_BYTE))
return -EOPNOTSUPP;
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);
data->client = client;
indio_dev->dev.parent = &client->dev;
indio_dev->name = id->name;
indio_dev->info = &ltc2485_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ltc2485_channel;
indio_dev->num_channels = ARRAY_SIZE(ltc2485_channel);
ret = i2c_smbus_write_byte(data->client, LTC2485_CONFIG_DEFAULT);
if (ret < 0)
return ret;
data->time_prev = ktime_get();
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id ltc2485_id[] = {
{ "ltc2485", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2485_id);
static struct i2c_driver ltc2485_driver = {
.driver = {
.name = "ltc2485",
},
.probe = ltc2485_probe,
.id_table = ltc2485_id,
};
module_i2c_driver(ltc2485_driver);
MODULE_AUTHOR("Alison Schofield <amsfield22@gmail.com>");
MODULE_DESCRIPTION("Linear Technology LTC2485 ADC driver");
MODULE_LICENSE("GPL v2");

153
drivers/iio/dac/stx104.c → drivers/iio/adc/stx104.c

@ -1,5 +1,5 @@
/*
* DAC driver for the Apex Embedded Systems STX104
* IIO driver for the Apex Embedded Systems STX104
* Copyright (C) 2016 William Breathitt Gray
*
* This program is free software; you can redistribute it and/or modify
@ -20,19 +20,30 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/isa.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#define STX104_NUM_CHAN 2
#define STX104_CHAN(chan) { \
#define STX104_OUT_CHAN(chan) { \
.type = IIO_VOLTAGE, \
.channel = chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.indexed = 1, \
.output = 1 \
}
#define STX104_IN_CHAN(chan, diff) { \
.type = IIO_VOLTAGE, \
.channel = chan, \
.channel2 = chan, \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.indexed = 1, \
.differential = diff \
}
#define STX104_NUM_OUT_CHAN 2
#define STX104_EXTENT 16
@ -47,8 +58,8 @@ MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
* @base: base port address of the IIO device
*/
struct stx104_iio {
unsigned chan_out_states[STX104_NUM_CHAN];
unsigned base;
unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
unsigned int base;
};
/**
@ -79,28 +90,95 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{
struct stx104_iio *const priv = iio_priv(indio_dev);
unsigned int adc_config;
int adbu;
int gain;
switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN:
/* get gain configuration */
adc_config = inb(priv->base + 11);
gain = adc_config & 0x3;
*val = 1 << gain;
return IIO_VAL_INT;
case IIO_CHAN_INFO_RAW:
if (chan->output) {
*val = priv->chan_out_states[chan->channel];
return IIO_VAL_INT;
}
/* select ADC channel */
outb(chan->channel | (chan->channel << 4), priv->base + 2);
/* trigger ADC sample capture and wait for completion */
outb(0, priv->base);
while (inb(priv->base + 8) & BIT(7));
*val = inw(priv->base);
return IIO_VAL_INT;
case IIO_CHAN_INFO_OFFSET:
/* get ADC bipolar/unipolar configuration */
adc_config = inb(priv->base + 11);
adbu = !(adc_config & BIT(2));
*val = -32768 * adbu;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
/* get ADC bipolar/unipolar and gain configuration */
adc_config = inb(priv->base + 11);
adbu = !(adc_config & BIT(2));
gain = adc_config & 0x3;
*val = 5;
*val2 = 15 - adbu + gain;
return IIO_VAL_FRACTIONAL_LOG2;
}
if (mask != IIO_CHAN_INFO_RAW)
return -EINVAL;
*val = priv->chan_out_states[chan->channel];
return IIO_VAL_INT;
return -EINVAL;
}
static int stx104_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val, int val2, long mask)
{
struct stx104_iio *const priv = iio_priv(indio_dev);
const unsigned chan_addr_offset = 2 * chan->channel;
if (mask != IIO_CHAN_INFO_RAW)
switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN:
/* Only four gain states (x1, x2, x4, x8) */
switch (val) {
case 1:
outb(0, priv->base + 11);
break;
case 2:
outb(1, priv->base + 11);
break;
case 4:
outb(2, priv->base + 11);
break;
case 8:
outb(3, priv->base + 11);
break;
default:
return -EINVAL;
}
return 0;
case IIO_CHAN_INFO_RAW:
if (chan->output) {
/* DAC can only accept up to a 16-bit value */
if ((unsigned int)val > 65535)
return -EINVAL;
priv->chan_out_states[chan->channel] = val;
outw(val, priv->base + 4 + 2 * chan->channel);
return 0;
}
return -EINVAL;
}
priv->chan_out_states[chan->channel] = val;
outw(val, priv->base + 4 + chan_addr_offset);
return 0;
return -EINVAL;
}
static const struct iio_info stx104_info = {
@ -109,9 +187,22 @@ static const struct iio_info stx104_info = {
.write_raw = stx104_write_raw
};
static const struct iio_chan_spec stx104_channels[STX104_NUM_CHAN] = {
STX104_CHAN(0),
STX104_CHAN(1)
/* single-ended input channels configuration */
static const struct iio_chan_spec stx104_channels_sing[] = {
STX104_OUT_CHAN(0), STX104_OUT_CHAN(1),
STX104_IN_CHAN(0, 0), STX104_IN_CHAN(1, 0), STX104_IN_CHAN(2, 0),
STX104_IN_CHAN(3, 0), STX104_IN_CHAN(4, 0), STX104_IN_CHAN(5, 0),
STX104_IN_CHAN(6, 0), STX104_IN_CHAN(7, 0), STX104_IN_CHAN(8, 0),
STX104_IN_CHAN(9, 0), STX104_IN_CHAN(10, 0), STX104_IN_CHAN(11, 0),
STX104_IN_CHAN(12, 0), STX104_IN_CHAN(13, 0), STX104_IN_CHAN(14, 0),
STX104_IN_CHAN(15, 0)
};
/* differential input channels configuration */
static const struct iio_chan_spec stx104_channels_diff[] = {
STX104_OUT_CHAN(0), STX104_OUT_CHAN(1),
STX104_IN_CHAN(0, 1), STX104_IN_CHAN(1, 1), STX104_IN_CHAN(2, 1),
STX104_IN_CHAN(3, 1), STX104_IN_CHAN(4, 1), STX104_IN_CHAN(5, 1),
STX104_IN_CHAN(6, 1), STX104_IN_CHAN(7, 1)
};
static int stx104_gpio_get_direction(struct gpio_chip *chip,
@ -204,13 +295,27 @@ static int stx104_probe(struct device *dev, unsigned int id)
indio_dev->info = &stx104_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = stx104_channels;
indio_dev->num_channels = STX104_NUM_CHAN;
/* determine if differential inputs */
if (inb(base[id] + 8) & BIT(5)) {
indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff);
indio_dev->channels = stx104_channels_diff;
} else {
indio_dev->num_channels = ARRAY_SIZE(stx104_channels_sing);
indio_dev->channels = stx104_channels_sing;
}
indio_dev->name = dev_name(dev);
priv = iio_priv(indio_dev);
priv->base = base[id];
/* configure device for software trigger operation */
outb(0, base[id] + 9);
/* initialize gain setting to x1 */
outb(0, base[id] + 11);
/* initialize DAC output to 0V */
outw(0, base[id] + 4);
outw(0, base[id] + 6);
@ -271,5 +376,5 @@ static struct isa_driver stx104_driver = {
module_isa_driver(stx104_driver, num_stx104);
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
MODULE_DESCRIPTION("Apex Embedded Systems STX104 DAC driver");
MODULE_DESCRIPTION("Apex Embedded Systems STX104 IIO driver");
MODULE_LICENSE("GPL v2");

552
drivers/iio/adc/ti-adc12138.c

@ -0,0 +1,552 @@
/*
* ADC12130/ADC12132/ADC12138 12-bit plus sign ADC driver
*
* Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
*
* 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.
*
* Datasheet: http://www.ti.com/lit/ds/symlink/adc12138.pdf
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/clk.h>
#include <linux/spi/spi.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/regulator/consumer.h>
#define ADC12138_MODE_AUTO_CAL 0x08
#define ADC12138_MODE_READ_STATUS 0x0c
#define ADC12138_MODE_ACQUISITION_TIME_6 0x0e
#define ADC12138_MODE_ACQUISITION_TIME_10 0x4e
#define ADC12138_MODE_ACQUISITION_TIME_18 0x8e
#define ADC12138_MODE_ACQUISITION_TIME_34 0xce
#define ADC12138_STATUS_CAL BIT(6)
enum {
adc12130,
adc12132,
adc12138,
};
struct adc12138 {
struct spi_device *spi;
unsigned int id;
/* conversion clock */
struct clk *cclk;
/* positive analog voltage reference */
struct regulator *vref_p;
/* negative analog voltage reference */
struct regulator *vref_n;
struct mutex lock;
struct completion complete;
/* The number of cclk periods for the S/H's acquisition time */
unsigned int acquisition_time;
u8 tx_buf[2] ____cacheline_aligned;
u8 rx_buf[2];
};
#define ADC12138_VOLTAGE_CHANNEL(chan) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
| BIT(IIO_CHAN_INFO_OFFSET), \
.scan_index = chan, \
.scan_type = { \
.sign = 's', \
.realbits = 13, \
.storagebits = 16, \
.shift = 3, \
.endianness = IIO_BE, \
}, \
}
#define ADC12138_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (chan1), \
.channel2 = (chan2), \
.differential = 1, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
| BIT(IIO_CHAN_INFO_OFFSET), \
.scan_index = si, \
.scan_type = { \
.sign = 's', \
.realbits = 13, \
.storagebits = 16, \
.shift = 3, \
.endianness = IIO_BE, \
}, \
}
static const struct iio_chan_spec adc12132_channels[] = {
ADC12138_VOLTAGE_CHANNEL(0),
ADC12138_VOLTAGE_CHANNEL(1),
ADC12138_VOLTAGE_CHANNEL_DIFF(0, 1, 2),
ADC12138_VOLTAGE_CHANNEL_DIFF(1, 0, 3),
IIO_CHAN_SOFT_TIMESTAMP(4),
};
static const struct iio_chan_spec adc12138_channels[] = {
ADC12138_VOLTAGE_CHANNEL(0),
ADC12138_VOLTAGE_CHANNEL(1),
ADC12138_VOLTAGE_CHANNEL(2),
ADC12138_VOLTAGE_CHANNEL(3),
ADC12138_VOLTAGE_CHANNEL(4),
ADC12138_VOLTAGE_CHANNEL(5),
ADC12138_VOLTAGE_CHANNEL(6),
ADC12138_VOLTAGE_CHANNEL(7),
ADC12138_VOLTAGE_CHANNEL_DIFF(0, 1, 8),
ADC12138_VOLTAGE_CHANNEL_DIFF(1, 0, 9),
ADC12138_VOLTAGE_CHANNEL_DIFF(2, 3, 10),
ADC12138_VOLTAGE_CHANNEL_DIFF(3, 2, 11),
ADC12138_VOLTAGE_CHANNEL_DIFF(4, 5, 12),
ADC12138_VOLTAGE_CHANNEL_DIFF(5, 4, 13),
ADC12138_VOLTAGE_CHANNEL_DIFF(6, 7, 14),
ADC12138_VOLTAGE_CHANNEL_DIFF(7, 6, 15),
IIO_CHAN_SOFT_TIMESTAMP(16),
};
static int adc12138_mode_programming(struct adc12138 *adc, u8 mode,
void *rx_buf, int len)
{
struct spi_transfer xfer = {
.tx_buf = adc->tx_buf,
.rx_buf = adc->rx_buf,
.len = len,
};
int ret;
/* Skip unused bits for ADC12130 and ADC12132 */
if (adc->id != adc12138)
mode = (mode & 0xc0) | ((mode & 0x0f) << 2);
adc->tx_buf[0] = mode;
ret = spi_sync_transfer(adc->spi, &xfer, 1);
if (ret)
return ret;
memcpy(rx_buf, adc->rx_buf, len);
return 0;
}
static int adc12138_read_status(struct adc12138 *adc)
{
u8 rx_buf[2];
int ret;
ret = adc12138_mode_programming(adc, ADC12138_MODE_READ_STATUS,
rx_buf, 2);
if (ret)
return ret;
return (rx_buf[0] << 1) | (rx_buf[1] >> 7);
}
static int __adc12138_start_conv(struct adc12138 *adc,
struct iio_chan_spec const *channel,
void *data, int len)
{
const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
u8 mode = (ch_to_mux[channel->channel] << 4) |
(channel->differential ? 0 : 0x80);
return adc12138_mode_programming(adc, mode, data, len);
}
static int adc12138_start_conv(struct adc12138 *adc,
struct iio_chan_spec const *channel)
{
u8 trash;
return __adc12138_start_conv(adc, channel, &trash, 1);
}
static int adc12138_start_and_read_conv(struct adc12138 *adc,
struct iio_chan_spec const *channel,
__be16 *data)
{
return __adc12138_start_conv(adc, channel, data, 2);
}
static int adc12138_read_conv_data(struct adc12138 *adc, __be16 *value)
{
/* Issue a read status instruction and read previous conversion data */
return adc12138_mode_programming(adc, ADC12138_MODE_READ_STATUS,
value, sizeof(*value));
}
static int adc12138_wait_eoc(struct adc12138 *adc, unsigned long timeout)
{
if (!wait_for_completion_timeout(&adc->complete, timeout))
return -ETIMEDOUT;
return 0;
}
static int adc12138_adc_conversion(struct adc12138 *adc,
struct iio_chan_spec const *channel,
__be16 *value)
{
int ret;
reinit_completion(&adc->complete);
ret = adc12138_start_conv(adc, channel);
if (ret)
return ret;
ret = adc12138_wait_eoc(adc, msecs_to_jiffies(100));
if (ret)
return ret;
return adc12138_read_conv_data(adc, value);
}
static int adc12138_read_raw(struct iio_dev *iio,
struct iio_chan_spec const *channel, int *value,
int *shift, long mask)
{
struct adc12138 *adc = iio_priv(iio);
int ret;
__be16 data;
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&adc->lock);
ret = adc12138_adc_conversion(adc, channel, &data);
mutex_unlock(&adc->lock);
if (ret)
return ret;
*value = sign_extend32(be16_to_cpu(data) >> 3, 12);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
ret = regulator_get_voltage(adc->vref_p);
if (ret < 0)
return ret;
*value = ret;
if (!IS_ERR(adc->vref_n)) {
ret = regulator_get_voltage(adc->vref_n);
if (ret < 0)
return ret;
*value -= ret;
}
/* convert regulator output voltage to mV */
*value /= 1000;
*shift = channel->scan_type.realbits - 1;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET:
if (!IS_ERR(adc->vref_n)) {
*value = regulator_get_voltage(adc->vref_n);
if (*value < 0)
return *value;
} else {
*value = 0;
}
/* convert regulator output voltage to mV */
*value /= 1000;
return IIO_VAL_INT;
}
return -EINVAL;
}
static const struct iio_info adc12138_info = {
.read_raw = adc12138_read_raw,
.driver_module = THIS_MODULE,
};
static int adc12138_init(struct adc12138 *adc)
{
int ret;
int status;
u8 mode;
u8 trash;
reinit_completion(&adc->complete);
ret = adc12138_mode_programming(adc, ADC12138_MODE_AUTO_CAL, &trash, 1);
if (ret)
return ret;
/* data output at this time has no significance */
status = adc12138_read_status(adc);
if (status < 0)
return status;
adc12138_wait_eoc(adc, msecs_to_jiffies(100));
status = adc12138_read_status(adc);
if (status & ADC12138_STATUS_CAL) {
dev_warn(&adc->spi->dev,
"Auto Cal sequence is still in progress: %#x\n",
status);
return -EIO;
}
switch (adc->acquisition_time) {
case 6:
mode = ADC12138_MODE_ACQUISITION_TIME_6;
break;
case 10:
mode = ADC12138_MODE_ACQUISITION_TIME_10;
break;
case 18:
mode = ADC12138_MODE_ACQUISITION_TIME_18;
break;
case 34:
mode = ADC12138_MODE_ACQUISITION_TIME_34;
break;
default:
return -EINVAL;
}
return adc12138_mode_programming(adc, mode, &trash, 1);
}
static irqreturn_t adc12138_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc12138 *adc = iio_priv(indio_dev);
__be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */
__be16 trash;
int ret;
int scan_index;
int i = 0;
mutex_lock(&adc->lock);
for_each_set_bit(scan_index, indio_dev->active_scan_mask,
indio_dev->masklength) {
const struct iio_chan_spec *scan_chan =
&indio_dev->channels[scan_index];
reinit_completion(&adc->complete);
ret = adc12138_start_and_read_conv(adc, scan_chan,
i ? &data[i - 1] : &trash);
if (ret) {
dev_warn(&adc->spi->dev,
"failed to start conversion\n");
goto out;
}
ret = adc12138_wait_eoc(adc, msecs_to_jiffies(100));
if (ret) {
dev_warn(&adc->spi->dev, "wait eoc timeout\n");
goto out;
}
i++;
}
if (i) {
ret = adc12138_read_conv_data(adc, &data[i - 1]);
if (ret) {
dev_warn(&adc->spi->dev,
"failed to get conversion data\n");
goto out;
}
}
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_get_time_ns(indio_dev));
out:
mutex_unlock(&adc->lock);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static irqreturn_t adc12138_eoc_handler(int irq, void *p)
{
struct iio_dev *indio_dev = p;
struct adc12138 *adc = iio_priv(indio_dev);
complete(&adc->complete);
return IRQ_HANDLED;
}
static int adc12138_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct adc12138 *adc;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
adc = iio_priv(indio_dev);
adc->spi = spi;
adc->id = spi_get_device_id(spi)->driver_data;
mutex_init(&adc->lock);
init_completion(&adc->complete);
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adc12138_info;
indio_dev->modes = INDIO_DIRECT_MODE;
switch (adc->id) {
case adc12130:
case adc12132:
indio_dev->channels = adc12132_channels;
indio_dev->num_channels = ARRAY_SIZE(adc12132_channels);
break;
case adc12138:
indio_dev->channels = adc12138_channels;
indio_dev->num_channels = ARRAY_SIZE(adc12138_channels);
break;
default:
return -EINVAL;
}
ret = of_property_read_u32(spi->dev.of_node, "ti,acquisition-time",
&adc->acquisition_time);
if (ret)
adc->acquisition_time = 10;
adc->cclk = devm_clk_get(&spi->dev, NULL);
if (IS_ERR(adc->cclk))
return PTR_ERR(adc->cclk);
adc->vref_p = devm_regulator_get(&spi->dev, "vref-p");
if (IS_ERR(adc->vref_p))
return PTR_ERR(adc->vref_p);
adc->vref_n = devm_regulator_get_optional(&spi->dev, "vref-n");
if (IS_ERR(adc->vref_n)) {
/*
* Assume vref_n is 0V if an optional regulator is not
* specified, otherwise return the error code.
*/
ret = PTR_ERR(adc->vref_n);
if (ret != -ENODEV)
return ret;
}
ret = devm_request_irq(&spi->dev, spi->irq, adc12138_eoc_handler,
IRQF_TRIGGER_RISING, indio_dev->name, indio_dev);
if (ret)
return ret;
ret = clk_prepare_enable(adc->cclk);
if (ret)
return ret;
ret = regulator_enable(adc->vref_p);
if (ret)
goto err_clk_disable;
if (!IS_ERR(adc->vref_n)) {
ret = regulator_enable(adc->vref_n);
if (ret)
goto err_vref_p_disable;
}
ret = adc12138_init(adc);
if (ret)
goto err_vref_n_disable;
spi_set_drvdata(spi, indio_dev);
ret = iio_triggered_buffer_setup(indio_dev, NULL,
adc12138_trigger_handler, NULL);
if (ret)
goto err_vref_n_disable;
ret = iio_device_register(indio_dev);
if (ret)
goto err_buffer_cleanup;
return 0;
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_vref_n_disable:
if (!IS_ERR(adc->vref_n))
regulator_disable(adc->vref_n);
err_vref_p_disable:
regulator_disable(adc->vref_p);
err_clk_disable:
clk_disable_unprepare(adc->cclk);
return ret;
}
static int adc12138_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adc12138 *adc = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (!IS_ERR(adc->vref_n))
regulator_disable(adc->vref_n);
regulator_disable(adc->vref_p);
clk_disable_unprepare(adc->cclk);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id adc12138_dt_ids[] = {
{ .compatible = "ti,adc12130", },
{ .compatible = "ti,adc12132", },
{ .compatible = "ti,adc12138", },
{}
};
MODULE_DEVICE_TABLE(of, adc12138_dt_ids);
#endif
static const struct spi_device_id adc12138_id[] = {
{ "adc12130", adc12130 },
{ "adc12132", adc12132 },
{ "adc12138", adc12138 },
{}
};
MODULE_DEVICE_TABLE(spi, adc12138_id);
static struct spi_driver adc12138_driver = {
.driver = {
.name = "adc12138",
.of_match_table = of_match_ptr(adc12138_dt_ids),
},
.probe = adc12138_probe,
.remove = adc12138_remove,
.id_table = adc12138_id,
};
module_spi_driver(adc12138_driver);
MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
MODULE_DESCRIPTION("ADC12130/ADC12132/ADC12138 driver");
MODULE_LICENSE("GPL v2");

2
drivers/iio/adc/ti-ads1015.c

@ -522,6 +522,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
if (pga > 6) {
dev_err(&client->dev, "invalid gain on %s\n",
node->full_name);
of_node_put(node);
return -EINVAL;
}
}
@ -532,6 +533,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
dev_err(&client->dev,
"invalid data_rate on %s\n",
node->full_name);
of_node_put(node);
return -EINVAL;
}
}

4
drivers/iio/adc/ti-ads8688.c

@ -438,7 +438,7 @@ static int ads8688_probe(struct spi_device *spi)
return 0;
error_out:
if (!IS_ERR_OR_NULL(st->reg))
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return ret;
@ -451,7 +451,7 @@ static int ads8688_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
if (!IS_ERR_OR_NULL(st->reg))
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return 0;

42
drivers/iio/buffer/industrialio-triggered-buffer.c

@ -98,6 +98,48 @@ void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
}
EXPORT_SYMBOL(iio_triggered_buffer_cleanup);
static void devm_iio_triggered_buffer_clean(struct device *dev, void *res)
{
iio_triggered_buffer_cleanup(*(struct iio_dev **)res);
}
int devm_iio_triggered_buffer_setup(struct device *dev,
struct iio_dev *indio_dev,
irqreturn_t (*h)(int irq, void *p),
irqreturn_t (*thread)(int irq, void *p),
const struct iio_buffer_setup_ops *ops)
{
struct iio_dev **ptr;
int ret;
ptr = devres_alloc(devm_iio_triggered_buffer_clean, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return -ENOMEM;
*ptr = indio_dev;
ret = iio_triggered_buffer_setup(indio_dev, h, thread, ops);
if (!ret)
devres_add(dev, ptr);
else
devres_free(ptr);
return ret;
}
EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_setup);
void devm_iio_triggered_buffer_cleanup(struct device *dev,
struct iio_dev *indio_dev)
{
int rc;
rc = devres_release(dev, devm_iio_triggered_buffer_clean,
devm_iio_device_match, indio_dev);
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_cleanup);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
MODULE_LICENSE("GPL");

201
drivers/iio/chemical/vz89x.c

@ -19,25 +19,55 @@
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define VZ89X_REG_MEASUREMENT 0x09
#define VZ89X_REG_MEASUREMENT_SIZE 6
#define VZ89X_REG_MEASUREMENT_RD_SIZE 6
#define VZ89X_REG_MEASUREMENT_WR_SIZE 3
#define VZ89X_VOC_CO2_IDX 0
#define VZ89X_VOC_SHORT_IDX 1
#define VZ89X_VOC_TVOC_IDX 2
#define VZ89X_VOC_RESISTANCE_IDX 3
#define VZ89TE_REG_MEASUREMENT 0x0c
#define VZ89TE_REG_MEASUREMENT_RD_SIZE 7
#define VZ89TE_REG_MEASUREMENT_WR_SIZE 6
#define VZ89TE_VOC_TVOC_IDX 0
#define VZ89TE_VOC_CO2_IDX 1
#define VZ89TE_VOC_RESISTANCE_IDX 2
enum {
VZ89X,
VZ89TE,
};
struct vz89x_chip_data;
struct vz89x_data {
struct i2c_client *client;
const struct vz89x_chip_data *chip;
struct mutex lock;
int (*xfer)(struct vz89x_data *data, u8 cmd);
bool is_valid;
unsigned long last_update;
u8 buffer[VZ89X_REG_MEASUREMENT_SIZE];
u8 buffer[VZ89TE_REG_MEASUREMENT_RD_SIZE];
};
struct vz89x_chip_data {
bool (*valid)(struct vz89x_data *data);
const struct iio_chan_spec *channels;
u8 num_channels;
u8 cmd;
u8 read_size;
u8 write_size;
};
static const struct iio_chan_spec vz89x_channels[] = {
@ -70,6 +100,40 @@ static const struct iio_chan_spec vz89x_channels[] = {
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.address = VZ89X_VOC_RESISTANCE_IDX,
.scan_index = -1,
.scan_type = {
.endianness = IIO_LE,
},
},
};
static const struct iio_chan_spec vz89te_channels[] = {
{
.type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_VOC,
.modified = 1,
.info_mask_separate =
BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_RAW),
.address = VZ89TE_VOC_TVOC_IDX,
},
{
.type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_CO2,
.modified = 1,
.info_mask_separate =
BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_RAW),
.address = VZ89TE_VOC_CO2_IDX,
},
{
.type = IIO_RESISTANCE,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.address = VZ89TE_VOC_RESISTANCE_IDX,
.scan_index = -1,
.scan_type = {
.endianness = IIO_BE,
},
},
};
@ -93,29 +157,45 @@ static const struct attribute_group vz89x_attrs_group = {
* always zero, and by also confirming the VOC_short isn't zero.
*/
static int vz89x_measurement_is_valid(struct vz89x_data *data)
static bool vz89x_measurement_is_valid(struct vz89x_data *data)
{
if (data->buffer[VZ89X_VOC_SHORT_IDX] == 0)
return 1;
return true;
return !!(data->buffer[VZ89X_REG_MEASUREMENT_SIZE - 1] > 0);
return !!(data->buffer[data->chip->read_size - 1] > 0);
}
/* VZ89TE device has a modified CRC-8 two complement check */
static bool vz89te_measurement_is_valid(struct vz89x_data *data)
{
u8 crc = 0;
int i, sum = 0;
for (i = 0; i < (data->chip->read_size - 1); i++) {
sum = crc + data->buffer[i];
crc = sum;
crc += sum / 256;
}
return !((0xff - crc) == data->buffer[data->chip->read_size - 1]);
}
static int vz89x_i2c_xfer(struct vz89x_data *data, u8 cmd)
{
const struct vz89x_chip_data *chip = data->chip;
struct i2c_client *client = data->client;
struct i2c_msg msg[2];
int ret;
u8 buf[3] = { cmd, 0, 0};
u8 buf[6] = { cmd, 0, 0, 0, 0, 0xf3 };
msg[0].addr = client->addr;
msg[0].flags = client->flags;
msg[0].len = 3;
msg[0].len = chip->write_size;
msg[0].buf = (char *) &buf;
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
msg[1].len = VZ89X_REG_MEASUREMENT_SIZE;
msg[1].len = chip->read_size;
msg[1].buf = (char *) &data->buffer;
ret = i2c_transfer(client->adapter, msg, 2);
@ -133,7 +213,7 @@ static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd)
if (ret < 0)
return ret;
for (i = 0; i < VZ89X_REG_MEASUREMENT_SIZE; i++) {
for (i = 0; i < data->chip->read_size; i++) {
ret = i2c_smbus_read_byte(client);
if (ret < 0)
return ret;
@ -145,30 +225,47 @@ static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd)
static int vz89x_get_measurement(struct vz89x_data *data)
{
const struct vz89x_chip_data *chip = data->chip;
int ret;
/* sensor can only be polled once a second max per datasheet */
if (!time_after(jiffies, data->last_update + HZ))
return 0;
return data->is_valid ? 0 : -EAGAIN;
data->is_valid = false;
data->last_update = jiffies;
ret = data->xfer(data, VZ89X_REG_MEASUREMENT);
ret = data->xfer(data, chip->cmd);
if (ret < 0)
return ret;
ret = vz89x_measurement_is_valid(data);
ret = chip->valid(data);
if (ret)
return -EAGAIN;
data->last_update = jiffies;