* [PATCH v3 0/2] iio: Add support for adc101 and adc121c to ti-adc081c @ 2016-04-11 14:24 Crestez Dan Leonard 2016-04-11 14:24 ` [PATCH v3 1/2] ti-adc081c: Add support for adc101c and adc121c Crestez Dan Leonard 2016-04-11 14:24 ` [PATCH v3 2/2] ti-adc081c: Initial triggered buffer support Crestez Dan Leonard 0 siblings, 2 replies; 5+ messages in thread From: Crestez Dan Leonard @ 2016-04-11 14:24 UTC (permalink / raw) To: Jonathan Cameron, linux-iio Cc: linux-kernel, Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler, Daniel Baluta, Crestez Dan Leonard Version 3 fixes review comments: * Avoid using VLAs in trigger_handler. * Add an array of model types and make driver_data an index in the table. Crestez Dan Leonard (2): ti-adc081c: Add support for adc101c and adc121c ti-adc081c: Initial triggered buffer support drivers/iio/adc/Kconfig | 6 +-- drivers/iio/adc/ti-adc081c.c | 118 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 15 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] ti-adc081c: Add support for adc101c and adc121c 2016-04-11 14:24 [PATCH v3 0/2] iio: Add support for adc101 and adc121c to ti-adc081c Crestez Dan Leonard @ 2016-04-11 14:24 ` Crestez Dan Leonard 2016-04-17 9:46 ` Jonathan Cameron 2016-04-11 14:24 ` [PATCH v3 2/2] ti-adc081c: Initial triggered buffer support Crestez Dan Leonard 1 sibling, 1 reply; 5+ messages in thread From: Crestez Dan Leonard @ 2016-04-11 14:24 UTC (permalink / raw) To: Jonathan Cameron, linux-iio Cc: linux-kernel, Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler, Daniel Baluta, Crestez Dan Leonard These chips have an almost identical interface but support a different number of value bits. Datasheet links for comparison: * http://www.ti.com/lit/ds/symlink/adc081c021.pdf * http://www.ti.com/lit/ds/symlink/adc101c021.pdf * http://www.ti.com/lit/ds/symlink/adc121c021.pdf Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com> --- drivers/iio/adc/Kconfig | 6 +++--- drivers/iio/adc/ti-adc081c.c | 51 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 5937030..25378c5 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -385,11 +385,11 @@ config ROCKCHIP_SARADC module will be called rockchip_saradc. config TI_ADC081C - tristate "Texas Instruments ADC081C021/027" + tristate "Texas Instruments ADC081C/ADC101C/ADC121C family" depends on I2C help - If you say yes here you get support for Texas Instruments ADC081C021 - and ADC081C027 ADC chips. + If you say yes here you get support for Texas Instruments ADC081C, + ADC101C and ADC121C ADC chips. This driver can also be built as a module. If so, the module will be called ti-adc081c. diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index ecbc121..b977340 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -1,9 +1,21 @@ /* + * TI ADC081C/ADC101C/ADC121C 8/10/12-bit ADC driver + * * Copyright (C) 2012 Avionic Design GmbH + * Copyright (C) 2016 Intel * * 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. + * + * Datasheets: + * http://www.ti.com/lit/ds/symlink/adc081c021.pdf + * http://www.ti.com/lit/ds/symlink/adc101c021.pdf + * http://www.ti.com/lit/ds/symlink/adc121c021.pdf + * + * The devices have a very similar interface and differ mostly in the number of + * bits handled. For the 8-bit and 10-bit models the least-significant 4 or 2 + * bits of value registers are reserved. */ #include <linux/err.h> @@ -17,6 +29,9 @@ struct adc081c { struct i2c_client *i2c; struct regulator *ref; + + /* 8, 10 or 12 */ + int bits; }; #define REG_CONV_RES 0x00 @@ -34,7 +49,7 @@ static int adc081c_read_raw(struct iio_dev *iio, if (err < 0) return err; - *value = (err >> 4) & 0xff; + *value = (err & 0xFFF) >> (12 - adc->bits); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -43,7 +58,7 @@ static int adc081c_read_raw(struct iio_dev *iio, return err; *value = err / 1000; - *shift = 8; + *shift = adc->bits; return IIO_VAL_FRACTIONAL_LOG2; @@ -60,6 +75,28 @@ static const struct iio_chan_spec adc081c_channel = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }; +struct adcxx1c_model { + int bits; +}; + +#define ADCxx1C_MODEL(_bits) \ + { \ + .bits = (_bits), \ + } + +/* Model ids are indexes in _models array */ +enum adcxx1c_model_id { + ADC081C = 0, + ADC101C = 1, + ADC121C = 2, +}; + +static struct adcxx1c_model adcxx1c_models[] = { + ADCxx1C_MODEL( 8), + ADCxx1C_MODEL(10), + ADCxx1C_MODEL(12), +}; + static const struct iio_info adc081c_info = { .read_raw = adc081c_read_raw, .driver_module = THIS_MODULE, @@ -70,6 +107,7 @@ static int adc081c_probe(struct i2c_client *client, { struct iio_dev *iio; struct adc081c *adc; + struct adcxx1c_model *model = &adcxx1c_models[id->driver_data]; int err; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) @@ -81,6 +119,7 @@ static int adc081c_probe(struct i2c_client *client, adc = iio_priv(iio); adc->i2c = client; + adc->bits = model->bits; adc->ref = devm_regulator_get(&client->dev, "vref"); if (IS_ERR(adc->ref)) @@ -124,7 +163,9 @@ static int adc081c_remove(struct i2c_client *client) } static const struct i2c_device_id adc081c_id[] = { - { "adc081c", 0 }, + { "adc081c", ADC081C }, + { "adc101c", ADC101C }, + { "adc121c", ADC121C }, { } }; MODULE_DEVICE_TABLE(i2c, adc081c_id); @@ -132,6 +173,8 @@ MODULE_DEVICE_TABLE(i2c, adc081c_id); #ifdef CONFIG_OF static const struct of_device_id adc081c_of_match[] = { { .compatible = "ti,adc081c" }, + { .compatible = "ti,adc101c" }, + { .compatible = "ti,adc121c" }, { } }; MODULE_DEVICE_TABLE(of, adc081c_of_match); @@ -149,5 +192,5 @@ static struct i2c_driver adc081c_driver = { module_i2c_driver(adc081c_driver); MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); -MODULE_DESCRIPTION("Texas Instruments ADC081C021/027 driver"); +MODULE_DESCRIPTION("Texas Instruments ADC081C/ADC101C/ADC121C driver"); MODULE_LICENSE("GPL v2"); -- 2.5.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] ti-adc081c: Add support for adc101c and adc121c 2016-04-11 14:24 ` [PATCH v3 1/2] ti-adc081c: Add support for adc101c and adc121c Crestez Dan Leonard @ 2016-04-17 9:46 ` Jonathan Cameron 0 siblings, 0 replies; 5+ messages in thread From: Jonathan Cameron @ 2016-04-17 9:46 UTC (permalink / raw) To: Crestez Dan Leonard, linux-iio Cc: linux-kernel, Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler, Daniel Baluta On 11/04/16 15:24, Crestez Dan Leonard wrote: > These chips have an almost identical interface but support a different > number of value bits. Datasheet links for comparison: > > * http://www.ti.com/lit/ds/symlink/adc081c021.pdf > * http://www.ti.com/lit/ds/symlink/adc101c021.pdf > * http://www.ti.com/lit/ds/symlink/adc121c021.pdf > > Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com> Very nice. Applied to the togreg branch of iio.git - initially pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > --- > drivers/iio/adc/Kconfig | 6 +++--- > drivers/iio/adc/ti-adc081c.c | 51 ++++++++++++++++++++++++++++++++++++++++---- > 2 files changed, 50 insertions(+), 7 deletions(-) > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index 5937030..25378c5 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -385,11 +385,11 @@ config ROCKCHIP_SARADC > module will be called rockchip_saradc. > > config TI_ADC081C > - tristate "Texas Instruments ADC081C021/027" > + tristate "Texas Instruments ADC081C/ADC101C/ADC121C family" > depends on I2C > help > - If you say yes here you get support for Texas Instruments ADC081C021 > - and ADC081C027 ADC chips. > + If you say yes here you get support for Texas Instruments ADC081C, > + ADC101C and ADC121C ADC chips. > > This driver can also be built as a module. If so, the module will be > called ti-adc081c. > diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c > index ecbc121..b977340 100644 > --- a/drivers/iio/adc/ti-adc081c.c > +++ b/drivers/iio/adc/ti-adc081c.c > @@ -1,9 +1,21 @@ > /* > + * TI ADC081C/ADC101C/ADC121C 8/10/12-bit ADC driver > + * > * Copyright (C) 2012 Avionic Design GmbH > + * Copyright (C) 2016 Intel > * > * 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. > + * > + * Datasheets: > + * http://www.ti.com/lit/ds/symlink/adc081c021.pdf > + * http://www.ti.com/lit/ds/symlink/adc101c021.pdf > + * http://www.ti.com/lit/ds/symlink/adc121c021.pdf > + * > + * The devices have a very similar interface and differ mostly in the number of > + * bits handled. For the 8-bit and 10-bit models the least-significant 4 or 2 > + * bits of value registers are reserved. > */ > > #include <linux/err.h> > @@ -17,6 +29,9 @@ > struct adc081c { > struct i2c_client *i2c; > struct regulator *ref; > + > + /* 8, 10 or 12 */ > + int bits; > }; > > #define REG_CONV_RES 0x00 > @@ -34,7 +49,7 @@ static int adc081c_read_raw(struct iio_dev *iio, > if (err < 0) > return err; > > - *value = (err >> 4) & 0xff; > + *value = (err & 0xFFF) >> (12 - adc->bits); > return IIO_VAL_INT; > > case IIO_CHAN_INFO_SCALE: > @@ -43,7 +58,7 @@ static int adc081c_read_raw(struct iio_dev *iio, > return err; > > *value = err / 1000; > - *shift = 8; > + *shift = adc->bits; > > return IIO_VAL_FRACTIONAL_LOG2; > > @@ -60,6 +75,28 @@ static const struct iio_chan_spec adc081c_channel = { > .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), > }; > > +struct adcxx1c_model { > + int bits; > +}; > + > +#define ADCxx1C_MODEL(_bits) \ > + { \ > + .bits = (_bits), \ > + } > + > +/* Model ids are indexes in _models array */ > +enum adcxx1c_model_id { > + ADC081C = 0, > + ADC101C = 1, > + ADC121C = 2, > +}; > + > +static struct adcxx1c_model adcxx1c_models[] = { > + ADCxx1C_MODEL( 8), > + ADCxx1C_MODEL(10), > + ADCxx1C_MODEL(12), > +}; > + > static const struct iio_info adc081c_info = { > .read_raw = adc081c_read_raw, > .driver_module = THIS_MODULE, > @@ -70,6 +107,7 @@ static int adc081c_probe(struct i2c_client *client, > { > struct iio_dev *iio; > struct adc081c *adc; > + struct adcxx1c_model *model = &adcxx1c_models[id->driver_data]; > int err; > > if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) > @@ -81,6 +119,7 @@ static int adc081c_probe(struct i2c_client *client, > > adc = iio_priv(iio); > adc->i2c = client; > + adc->bits = model->bits; > > adc->ref = devm_regulator_get(&client->dev, "vref"); > if (IS_ERR(adc->ref)) > @@ -124,7 +163,9 @@ static int adc081c_remove(struct i2c_client *client) > } > > static const struct i2c_device_id adc081c_id[] = { > - { "adc081c", 0 }, > + { "adc081c", ADC081C }, > + { "adc101c", ADC101C }, > + { "adc121c", ADC121C }, > { } > }; > MODULE_DEVICE_TABLE(i2c, adc081c_id); > @@ -132,6 +173,8 @@ MODULE_DEVICE_TABLE(i2c, adc081c_id); > #ifdef CONFIG_OF > static const struct of_device_id adc081c_of_match[] = { > { .compatible = "ti,adc081c" }, > + { .compatible = "ti,adc101c" }, > + { .compatible = "ti,adc121c" }, > { } > }; > MODULE_DEVICE_TABLE(of, adc081c_of_match); > @@ -149,5 +192,5 @@ static struct i2c_driver adc081c_driver = { > module_i2c_driver(adc081c_driver); > > MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); > -MODULE_DESCRIPTION("Texas Instruments ADC081C021/027 driver"); > +MODULE_DESCRIPTION("Texas Instruments ADC081C/ADC101C/ADC121C driver"); > MODULE_LICENSE("GPL v2"); > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] ti-adc081c: Initial triggered buffer support 2016-04-11 14:24 [PATCH v3 0/2] iio: Add support for adc101 and adc121c to ti-adc081c Crestez Dan Leonard 2016-04-11 14:24 ` [PATCH v3 1/2] ti-adc081c: Add support for adc101c and adc121c Crestez Dan Leonard @ 2016-04-11 14:24 ` Crestez Dan Leonard 2016-04-17 9:46 ` Jonathan Cameron 1 sibling, 1 reply; 5+ messages in thread From: Crestez Dan Leonard @ 2016-04-11 14:24 UTC (permalink / raw) To: Jonathan Cameron, linux-iio Cc: linux-kernel, Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler, Daniel Baluta, Crestez Dan Leonard Using this requires software triggers like CONFIG_IIO_HRTIMER_TRIGGER. The device can be configured to do internal periodic sampling but does not offer some sort of interrupt on data ready. Interrupts can only trigger when values get out of a specific range. Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com> --- drivers/iio/adc/ti-adc081c.c | 77 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index b977340..9fd032d 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -24,6 +24,9 @@ #include <linux/of.h> #include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> #include <linux/regulator/consumer.h> struct adc081c { @@ -69,21 +72,42 @@ static int adc081c_read_raw(struct iio_dev *iio, return -EINVAL; } -static const struct iio_chan_spec adc081c_channel = { - .type = IIO_VOLTAGE, - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), -}; +#define ADCxx1C_CHAN(_bits) { \ + .type = IIO_VOLTAGE, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = 16, \ + .shift = 12 - (_bits), \ + .endianness = IIO_CPU, \ + }, \ +} + +#define DEFINE_ADCxx1C_CHANNELS(_name, _bits) \ + static const struct iio_chan_spec _name ## _channels[] = { \ + ADCxx1C_CHAN((_bits)), \ + IIO_CHAN_SOFT_TIMESTAMP(1), \ + }; \ + +#define ADC081C_NUM_CHANNELS 2 struct adcxx1c_model { + const struct iio_chan_spec* channels; int bits; }; -#define ADCxx1C_MODEL(_bits) \ +#define ADCxx1C_MODEL(_name, _bits) \ { \ + .channels = _name ## _channels, \ .bits = (_bits), \ } +DEFINE_ADCxx1C_CHANNELS(adc081c, 8); +DEFINE_ADCxx1C_CHANNELS(adc101c, 10); +DEFINE_ADCxx1C_CHANNELS(adc121c, 12); + /* Model ids are indexes in _models array */ enum adcxx1c_model_id { ADC081C = 0, @@ -92,9 +116,9 @@ enum adcxx1c_model_id { }; static struct adcxx1c_model adcxx1c_models[] = { - ADCxx1C_MODEL( 8), - ADCxx1C_MODEL(10), - ADCxx1C_MODEL(12), + ADCxx1C_MODEL(adc081c, 8), + ADCxx1C_MODEL(adc101c, 10), + ADCxx1C_MODEL(adc121c, 12), }; static const struct iio_info adc081c_info = { @@ -102,6 +126,24 @@ static const struct iio_info adc081c_info = { .driver_module = THIS_MODULE, }; +static irqreturn_t adc081c_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct adc081c *data = iio_priv(indio_dev); + u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */ + int ret; + + ret = i2c_smbus_read_word_swapped(data->i2c, REG_CONV_RES); + if (ret < 0) + goto out; + buf[0] = ret; + iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); +out: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + static int adc081c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -134,18 +176,26 @@ static int adc081c_probe(struct i2c_client *client, iio->modes = INDIO_DIRECT_MODE; iio->info = &adc081c_info; - iio->channels = &adc081c_channel; - iio->num_channels = 1; + iio->channels = model->channels; + iio->num_channels = ADC081C_NUM_CHANNELS; + + err = iio_triggered_buffer_setup(iio, NULL, adc081c_trigger_handler, NULL); + if (err < 0) { + dev_err(&client->dev, "iio triggered buffer setup failed\n"); + goto err_regulator_disable; + } err = iio_device_register(iio); if (err < 0) - goto regulator_disable; + goto err_buffer_cleanup; i2c_set_clientdata(client, iio); return 0; -regulator_disable: +err_buffer_cleanup: + iio_triggered_buffer_cleanup(iio); +err_regulator_disable: regulator_disable(adc->ref); return err; @@ -157,6 +207,7 @@ static int adc081c_remove(struct i2c_client *client) struct adc081c *adc = iio_priv(iio); iio_device_unregister(iio); + iio_triggered_buffer_cleanup(iio); regulator_disable(adc->ref); return 0; -- 2.5.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/2] ti-adc081c: Initial triggered buffer support 2016-04-11 14:24 ` [PATCH v3 2/2] ti-adc081c: Initial triggered buffer support Crestez Dan Leonard @ 2016-04-17 9:46 ` Jonathan Cameron 0 siblings, 0 replies; 5+ messages in thread From: Jonathan Cameron @ 2016-04-17 9:46 UTC (permalink / raw) To: Crestez Dan Leonard, linux-iio Cc: linux-kernel, Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler, Daniel Baluta On 11/04/16 15:24, Crestez Dan Leonard wrote: > Using this requires software triggers like CONFIG_IIO_HRTIMER_TRIGGER. > > The device can be configured to do internal periodic sampling but does not > offer some sort of interrupt on data ready. Interrupts can only trigger when > values get out of a specific range. > > Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com> One totally trivial comment inline. Applied to the togreg branch of iio.git - pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > --- > drivers/iio/adc/ti-adc081c.c | 77 ++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 64 insertions(+), 13 deletions(-) > > diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c > index b977340..9fd032d 100644 > --- a/drivers/iio/adc/ti-adc081c.c > +++ b/drivers/iio/adc/ti-adc081c.c > @@ -24,6 +24,9 @@ > #include <linux/of.h> > > #include <linux/iio/iio.h> > +#include <linux/iio/buffer.h> > +#include <linux/iio/trigger_consumer.h> > +#include <linux/iio/triggered_buffer.h> > #include <linux/regulator/consumer.h> > > struct adc081c { > @@ -69,21 +72,42 @@ static int adc081c_read_raw(struct iio_dev *iio, > return -EINVAL; > } > > -static const struct iio_chan_spec adc081c_channel = { > - .type = IIO_VOLTAGE, > - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), > - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), > -}; > +#define ADCxx1C_CHAN(_bits) { \ > + .type = IIO_VOLTAGE, \ > + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ > + .scan_type = { \ > + .sign = 'u', \ > + .realbits = (_bits), \ > + .storagebits = 16, \ > + .shift = 12 - (_bits), \ > + .endianness = IIO_CPU, \ > + }, \ > +} > + > +#define DEFINE_ADCxx1C_CHANNELS(_name, _bits) \ > + static const struct iio_chan_spec _name ## _channels[] = { \ > + ADCxx1C_CHAN((_bits)), \ > + IIO_CHAN_SOFT_TIMESTAMP(1), \ > + }; \ > + > +#define ADC081C_NUM_CHANNELS 2 > > struct adcxx1c_model { > + const struct iio_chan_spec* channels; > int bits; > }; > > -#define ADCxx1C_MODEL(_bits) \ > +#define ADCxx1C_MODEL(_name, _bits) \ > { \ > + .channels = _name ## _channels, \ > .bits = (_bits), \ > } > > +DEFINE_ADCxx1C_CHANNELS(adc081c, 8); > +DEFINE_ADCxx1C_CHANNELS(adc101c, 10); > +DEFINE_ADCxx1C_CHANNELS(adc121c, 12); > + > /* Model ids are indexes in _models array */ > enum adcxx1c_model_id { > ADC081C = 0, > @@ -92,9 +116,9 @@ enum adcxx1c_model_id { > }; > > static struct adcxx1c_model adcxx1c_models[] = { > - ADCxx1C_MODEL( 8), > - ADCxx1C_MODEL(10), > - ADCxx1C_MODEL(12), > + ADCxx1C_MODEL(adc081c, 8), > + ADCxx1C_MODEL(adc101c, 10), > + ADCxx1C_MODEL(adc121c, 12), > }; > > static const struct iio_info adc081c_info = { > @@ -102,6 +126,24 @@ static const struct iio_info adc081c_info = { > .driver_module = THIS_MODULE, > }; > > +static irqreturn_t adc081c_trigger_handler(int irq, void *p) > +{ > + struct iio_poll_func *pf = p; > + struct iio_dev *indio_dev = pf->indio_dev; > + struct adc081c *data = iio_priv(indio_dev); > + u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */ > + int ret; > + > + ret = i2c_smbus_read_word_swapped(data->i2c, REG_CONV_RES); > + if (ret < 0) > + goto out; > + buf[0] = ret; > + iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); > +out: > + iio_trigger_notify_done(indio_dev->trig); > + return IRQ_HANDLED; > +} > + > static int adc081c_probe(struct i2c_client *client, > const struct i2c_device_id *id) > { > @@ -134,18 +176,26 @@ static int adc081c_probe(struct i2c_client *client, > iio->modes = INDIO_DIRECT_MODE; > iio->info = &adc081c_info; > > - iio->channels = &adc081c_channel; > - iio->num_channels = 1; > + iio->channels = model->channels; > + iio->num_channels = ADC081C_NUM_CHANNELS; > + > + err = iio_triggered_buffer_setup(iio, NULL, adc081c_trigger_handler, NULL); > + if (err < 0) { > + dev_err(&client->dev, "iio triggered buffer setup failed\n"); > + goto err_regulator_disable; > + } > > err = iio_device_register(iio); > if (err < 0) > - goto regulator_disable; > + goto err_buffer_cleanup; > > i2c_set_clientdata(client, iio); > > return 0; > > -regulator_disable: Technically an unrelated change, but can't say I really care! > +err_buffer_cleanup: > + iio_triggered_buffer_cleanup(iio); > +err_regulator_disable: > regulator_disable(adc->ref); > > return err; > @@ -157,6 +207,7 @@ static int adc081c_remove(struct i2c_client *client) > struct adc081c *adc = iio_priv(iio); > > iio_device_unregister(iio); > + iio_triggered_buffer_cleanup(iio); > regulator_disable(adc->ref); > > return 0; > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-04-17 9:46 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-04-11 14:24 [PATCH v3 0/2] iio: Add support for adc101 and adc121c to ti-adc081c Crestez Dan Leonard 2016-04-11 14:24 ` [PATCH v3 1/2] ti-adc081c: Add support for adc101c and adc121c Crestez Dan Leonard 2016-04-17 9:46 ` Jonathan Cameron 2016-04-11 14:24 ` [PATCH v3 2/2] ti-adc081c: Initial triggered buffer support Crestez Dan Leonard 2016-04-17 9:46 ` Jonathan Cameron
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).