aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCrestez Dan Leonard <leonard.crestez@intel.com>2016-04-11 10:24:27 -0400
committerJonathan Cameron <jic23@kernel.org>2016-04-17 05:46:50 -0400
commit08e05d1fce5c87e5eaf16655c45db6beb4d93701 (patch)
tree865d39ed4afe2dfe0c3c0aa26cdff776428e9be6
parenta6b5ec887b85df039055be316420b1520c23eb6b (diff)
ti-adc081c: Initial triggered buffer support
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> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/adc/ti-adc081c.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c
index b977340fbdb8..9fd032d9f402 100644
--- a/drivers/iio/adc/ti-adc081c.c
+++ b/drivers/iio/adc/ti-adc081c.c
@@ -24,6 +24,9 @@
24#include <linux/of.h> 24#include <linux/of.h>
25 25
26#include <linux/iio/iio.h> 26#include <linux/iio/iio.h>
27#include <linux/iio/buffer.h>
28#include <linux/iio/trigger_consumer.h>
29#include <linux/iio/triggered_buffer.h>
27#include <linux/regulator/consumer.h> 30#include <linux/regulator/consumer.h>
28 31
29struct adc081c { 32struct adc081c {
@@ -69,21 +72,42 @@ static int adc081c_read_raw(struct iio_dev *iio,
69 return -EINVAL; 72 return -EINVAL;
70} 73}
71 74
72static const struct iio_chan_spec adc081c_channel = { 75#define ADCxx1C_CHAN(_bits) { \
73 .type = IIO_VOLTAGE, 76 .type = IIO_VOLTAGE, \
74 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 77 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
75 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 78 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
76}; 79 .scan_type = { \
80 .sign = 'u', \
81 .realbits = (_bits), \
82 .storagebits = 16, \
83 .shift = 12 - (_bits), \
84 .endianness = IIO_CPU, \
85 }, \
86}
87
88#define DEFINE_ADCxx1C_CHANNELS(_name, _bits) \
89 static const struct iio_chan_spec _name ## _channels[] = { \
90 ADCxx1C_CHAN((_bits)), \
91 IIO_CHAN_SOFT_TIMESTAMP(1), \
92 }; \
93
94#define ADC081C_NUM_CHANNELS 2
77 95
78struct adcxx1c_model { 96struct adcxx1c_model {
97 const struct iio_chan_spec* channels;
79 int bits; 98 int bits;
80}; 99};
81 100
82#define ADCxx1C_MODEL(_bits) \ 101#define ADCxx1C_MODEL(_name, _bits) \
83 { \ 102 { \
103 .channels = _name ## _channels, \
84 .bits = (_bits), \ 104 .bits = (_bits), \
85 } 105 }
86 106
107DEFINE_ADCxx1C_CHANNELS(adc081c, 8);
108DEFINE_ADCxx1C_CHANNELS(adc101c, 10);
109DEFINE_ADCxx1C_CHANNELS(adc121c, 12);
110
87/* Model ids are indexes in _models array */ 111/* Model ids are indexes in _models array */
88enum adcxx1c_model_id { 112enum adcxx1c_model_id {
89 ADC081C = 0, 113 ADC081C = 0,
@@ -92,9 +116,9 @@ enum adcxx1c_model_id {
92}; 116};
93 117
94static struct adcxx1c_model adcxx1c_models[] = { 118static struct adcxx1c_model adcxx1c_models[] = {
95 ADCxx1C_MODEL( 8), 119 ADCxx1C_MODEL(adc081c, 8),
96 ADCxx1C_MODEL(10), 120 ADCxx1C_MODEL(adc101c, 10),
97 ADCxx1C_MODEL(12), 121 ADCxx1C_MODEL(adc121c, 12),
98}; 122};
99 123
100static const struct iio_info adc081c_info = { 124static const struct iio_info adc081c_info = {
@@ -102,6 +126,24 @@ static const struct iio_info adc081c_info = {
102 .driver_module = THIS_MODULE, 126 .driver_module = THIS_MODULE,
103}; 127};
104 128
129static irqreturn_t adc081c_trigger_handler(int irq, void *p)
130{
131 struct iio_poll_func *pf = p;
132 struct iio_dev *indio_dev = pf->indio_dev;
133 struct adc081c *data = iio_priv(indio_dev);
134 u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */
135 int ret;
136
137 ret = i2c_smbus_read_word_swapped(data->i2c, REG_CONV_RES);
138 if (ret < 0)
139 goto out;
140 buf[0] = ret;
141 iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns());
142out:
143 iio_trigger_notify_done(indio_dev->trig);
144 return IRQ_HANDLED;
145}
146
105static int adc081c_probe(struct i2c_client *client, 147static int adc081c_probe(struct i2c_client *client,
106 const struct i2c_device_id *id) 148 const struct i2c_device_id *id)
107{ 149{
@@ -134,18 +176,26 @@ static int adc081c_probe(struct i2c_client *client,
134 iio->modes = INDIO_DIRECT_MODE; 176 iio->modes = INDIO_DIRECT_MODE;
135 iio->info = &adc081c_info; 177 iio->info = &adc081c_info;
136 178
137 iio->channels = &adc081c_channel; 179 iio->channels = model->channels;
138 iio->num_channels = 1; 180 iio->num_channels = ADC081C_NUM_CHANNELS;
181
182 err = iio_triggered_buffer_setup(iio, NULL, adc081c_trigger_handler, NULL);
183 if (err < 0) {
184 dev_err(&client->dev, "iio triggered buffer setup failed\n");
185 goto err_regulator_disable;
186 }
139 187
140 err = iio_device_register(iio); 188 err = iio_device_register(iio);
141 if (err < 0) 189 if (err < 0)
142 goto regulator_disable; 190 goto err_buffer_cleanup;
143 191
144 i2c_set_clientdata(client, iio); 192 i2c_set_clientdata(client, iio);
145 193
146 return 0; 194 return 0;
147 195
148regulator_disable: 196err_buffer_cleanup:
197 iio_triggered_buffer_cleanup(iio);
198err_regulator_disable:
149 regulator_disable(adc->ref); 199 regulator_disable(adc->ref);
150 200
151 return err; 201 return err;
@@ -157,6 +207,7 @@ static int adc081c_remove(struct i2c_client *client)
157 struct adc081c *adc = iio_priv(iio); 207 struct adc081c *adc = iio_priv(iio);
158 208
159 iio_device_unregister(iio); 209 iio_device_unregister(iio);
210 iio_triggered_buffer_cleanup(iio);
160 regulator_disable(adc->ref); 211 regulator_disable(adc->ref);
161 212
162 return 0; 213 return 0;