summaryrefslogtreecommitdiffstats
path: root/drivers/iio/health
diff options
context:
space:
mode:
authorAndrew F. Davis <afd@ti.com>2016-02-06 14:35:21 -0500
committerJonathan Cameron <jic23@kernel.org>2016-02-06 16:55:32 -0500
commiteec96d1e2d318bc734728111cfe3b203b58943b9 (patch)
treec30c22f239860aeddce84bbdc49aa0e33778c26a /drivers/iio/health
parent535e58f17a765ecbd651913233f210b383676504 (diff)
iio: health: Add driver for the TI AFE4403 heart monitor
Add driver for the TI AFE4403 heart rate monitor and pulse oximeter. This device detects reflected LED light fluctuations and presents an ADC value to the user space for further signal processing. Data sheet located here: http://www.ti.com/product/AFE4403/datasheet Signed-off-by: Andrew F. Davis <afd@ti.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/health')
-rw-r--r--drivers/iio/health/Kconfig12
-rw-r--r--drivers/iio/health/Makefile1
-rw-r--r--drivers/iio/health/afe4403.c708
3 files changed, 721 insertions, 0 deletions
diff --git a/drivers/iio/health/Kconfig b/drivers/iio/health/Kconfig
index 632a14b7dd6f..f0c19779ac27 100644
--- a/drivers/iio/health/Kconfig
+++ b/drivers/iio/health/Kconfig
@@ -7,6 +7,18 @@ menu "Health Sensors"
7 7
8menu "Heart Rate Monitors" 8menu "Heart Rate Monitors"
9 9
10config AFE4403
11 tristate "TI AFE4403 Heart Rate Monitor"
12 depends on SPI_MASTER
13 select IIO_BUFFER
14 select IIO_TRIGGERED_BUFFER
15 help
16 Say yes to choose the Texas Instruments AFE4403
17 heart rate monitor and low-cost pulse oximeter.
18
19 To compile this driver as a module, choose M here: the
20 module will be called afe4403.
21
10config AFE4404 22config AFE4404
11 tristate "TI AFE4404 heart rate and pulse oximeter sensor" 23 tristate "TI AFE4404 heart rate and pulse oximeter sensor"
12 depends on I2C 24 depends on I2C
diff --git a/drivers/iio/health/Makefile b/drivers/iio/health/Makefile
index b37c0d5e07b8..9955a2ae8df1 100644
--- a/drivers/iio/health/Makefile
+++ b/drivers/iio/health/Makefile
@@ -4,5 +4,6 @@
4 4
5# When adding new entries keep the list in alphabetical order 5# When adding new entries keep the list in alphabetical order
6 6
7obj-$(CONFIG_AFE4403) += afe4403.o
7obj-$(CONFIG_AFE4404) += afe4404.o 8obj-$(CONFIG_AFE4404) += afe4404.o
8obj-$(CONFIG_MAX30100) += max30100.o 9obj-$(CONFIG_MAX30100) += max30100.o
diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c
new file mode 100644
index 000000000000..91c046e40d2f
--- /dev/null
+++ b/drivers/iio/health/afe4403.c
@@ -0,0 +1,708 @@
1/*
2 * AFE4403 Heart Rate Monitors and Low-Cost Pulse Oximeters
3 *
4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#include <linux/device.h>
18#include <linux/err.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/regmap.h>
23#include <linux/spi/spi.h>
24#include <linux/sysfs.h>
25#include <linux/regulator/consumer.h>
26
27#include <linux/iio/iio.h>
28#include <linux/iio/sysfs.h>
29#include <linux/iio/buffer.h>
30#include <linux/iio/trigger.h>
31#include <linux/iio/triggered_buffer.h>
32#include <linux/iio/trigger_consumer.h>
33
34#include "afe440x.h"
35
36#define AFE4403_DRIVER_NAME "afe4403"
37
38/* AFE4403 Registers */
39#define AFE4403_TIAGAIN 0x20
40#define AFE4403_TIA_AMB_GAIN 0x21
41
42/* AFE4403 GAIN register fields */
43#define AFE4403_TIAGAIN_RES_MASK GENMASK(2, 0)
44#define AFE4403_TIAGAIN_RES_SHIFT 0
45#define AFE4403_TIAGAIN_CAP_MASK GENMASK(7, 3)
46#define AFE4403_TIAGAIN_CAP_SHIFT 3
47
48/* AFE4403 LEDCNTRL register fields */
49#define AFE440X_LEDCNTRL_LED1_MASK GENMASK(15, 8)
50#define AFE440X_LEDCNTRL_LED1_SHIFT 8
51#define AFE440X_LEDCNTRL_LED2_MASK GENMASK(7, 0)
52#define AFE440X_LEDCNTRL_LED2_SHIFT 0
53#define AFE440X_LEDCNTRL_LED_RANGE_MASK GENMASK(17, 16)
54#define AFE440X_LEDCNTRL_LED_RANGE_SHIFT 16
55
56/* AFE4403 CONTROL2 register fields */
57#define AFE440X_CONTROL2_PWR_DWN_TX BIT(2)
58#define AFE440X_CONTROL2_EN_SLOW_DIAG BIT(8)
59#define AFE440X_CONTROL2_DIAG_OUT_TRI BIT(10)
60#define AFE440X_CONTROL2_TX_BRDG_MOD BIT(11)
61#define AFE440X_CONTROL2_TX_REF_MASK GENMASK(18, 17)
62#define AFE440X_CONTROL2_TX_REF_SHIFT 17
63
64/* AFE4404 NULL fields */
65#define NULL_MASK 0
66#define NULL_SHIFT 0
67
68/* AFE4403 LEDCNTRL values */
69#define AFE440X_LEDCNTRL_RANGE_TX_HALF 0x1
70#define AFE440X_LEDCNTRL_RANGE_TX_FULL 0x2
71#define AFE440X_LEDCNTRL_RANGE_TX_OFF 0x3
72
73/* AFE4403 CONTROL2 values */
74#define AFE440X_CONTROL2_TX_REF_025 0x0
75#define AFE440X_CONTROL2_TX_REF_050 0x1
76#define AFE440X_CONTROL2_TX_REF_100 0x2
77#define AFE440X_CONTROL2_TX_REF_075 0x3
78
79/* AFE4403 CONTROL3 values */
80#define AFE440X_CONTROL3_CLK_DIV_2 0x0
81#define AFE440X_CONTROL3_CLK_DIV_4 0x2
82#define AFE440X_CONTROL3_CLK_DIV_6 0x3
83#define AFE440X_CONTROL3_CLK_DIV_8 0x4
84#define AFE440X_CONTROL3_CLK_DIV_12 0x5
85#define AFE440X_CONTROL3_CLK_DIV_1 0x7
86
87/* AFE4403 TIAGAIN_CAP values */
88#define AFE4403_TIAGAIN_CAP_5_P 0x0
89#define AFE4403_TIAGAIN_CAP_10_P 0x1
90#define AFE4403_TIAGAIN_CAP_20_P 0x2
91#define AFE4403_TIAGAIN_CAP_30_P 0x3
92#define AFE4403_TIAGAIN_CAP_55_P 0x8
93#define AFE4403_TIAGAIN_CAP_155_P 0x10
94
95/* AFE4403 TIAGAIN_RES values */
96#define AFE4403_TIAGAIN_RES_500_K 0x0
97#define AFE4403_TIAGAIN_RES_250_K 0x1
98#define AFE4403_TIAGAIN_RES_100_K 0x2
99#define AFE4403_TIAGAIN_RES_50_K 0x3
100#define AFE4403_TIAGAIN_RES_25_K 0x4
101#define AFE4403_TIAGAIN_RES_10_K 0x5
102#define AFE4403_TIAGAIN_RES_1_M 0x6
103#define AFE4403_TIAGAIN_RES_NONE 0x7
104
105/**
106 * struct afe4403_data
107 * @dev - Device structure
108 * @spi - SPI device handle
109 * @regmap - Register map of the device
110 * @regulator - Pointer to the regulator for the IC
111 * @trig - IIO trigger for this device
112 * @irq - ADC_RDY line interrupt number
113 */
114struct afe4403_data {
115 struct device *dev;
116 struct spi_device *spi;
117 struct regmap *regmap;
118 struct regulator *regulator;
119 struct iio_trigger *trig;
120 int irq;
121};
122
123enum afe4403_chan_id {
124 LED1,
125 ALED1,
126 LED2,
127 ALED2,
128 LED1_ALED1,
129 LED2_ALED2,
130 ILED1,
131 ILED2,
132};
133
134static const struct afe440x_reg_info afe4403_reg_info[] = {
135 [LED1] = AFE440X_REG_INFO(AFE440X_LED1VAL, 0, NULL),
136 [ALED1] = AFE440X_REG_INFO(AFE440X_ALED1VAL, 0, NULL),
137 [LED2] = AFE440X_REG_INFO(AFE440X_LED2VAL, 0, NULL),
138 [ALED2] = AFE440X_REG_INFO(AFE440X_ALED2VAL, 0, NULL),
139 [LED1_ALED1] = AFE440X_REG_INFO(AFE440X_LED1_ALED1VAL, 0, NULL),
140 [LED2_ALED2] = AFE440X_REG_INFO(AFE440X_LED2_ALED2VAL, 0, NULL),
141 [ILED1] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE440X_LEDCNTRL_LED1),
142 [ILED2] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE440X_LEDCNTRL_LED2),
143};
144
145static const struct iio_chan_spec afe4403_channels[] = {
146 /* ADC values */
147 AFE440X_INTENSITY_CHAN(LED1, "led1", 0),
148 AFE440X_INTENSITY_CHAN(ALED1, "led1_ambient", 0),
149 AFE440X_INTENSITY_CHAN(LED2, "led2", 0),
150 AFE440X_INTENSITY_CHAN(ALED2, "led2_ambient", 0),
151 AFE440X_INTENSITY_CHAN(LED1_ALED1, "led1-led1_ambient", 0),
152 AFE440X_INTENSITY_CHAN(LED2_ALED2, "led2-led2_ambient", 0),
153 /* LED current */
154 AFE440X_CURRENT_CHAN(ILED1, "led1"),
155 AFE440X_CURRENT_CHAN(ILED2, "led2"),
156};
157
158static const struct afe440x_val_table afe4403_res_table[] = {
159 { 500000 }, { 250000 }, { 100000 }, { 50000 },
160 { 25000 }, { 10000 }, { 1000000 }, { 0 },
161};
162AFE440X_TABLE_ATTR(tia_resistance_available, afe4403_res_table);
163
164static const struct afe440x_val_table afe4403_cap_table[] = {
165 { 0, 5000 }, { 0, 10000 }, { 0, 20000 }, { 0, 25000 },
166 { 0, 30000 }, { 0, 35000 }, { 0, 45000 }, { 0, 50000 },
167 { 0, 55000 }, { 0, 60000 }, { 0, 70000 }, { 0, 75000 },
168 { 0, 80000 }, { 0, 85000 }, { 0, 95000 }, { 0, 100000 },
169 { 0, 155000 }, { 0, 160000 }, { 0, 170000 }, { 0, 175000 },
170 { 0, 180000 }, { 0, 185000 }, { 0, 195000 }, { 0, 200000 },
171 { 0, 205000 }, { 0, 210000 }, { 0, 220000 }, { 0, 225000 },
172 { 0, 230000 }, { 0, 235000 }, { 0, 245000 }, { 0, 250000 },
173};
174AFE440X_TABLE_ATTR(tia_capacitance_available, afe4403_cap_table);
175
176static ssize_t afe440x_show_register(struct device *dev,
177 struct device_attribute *attr,
178 char *buf)
179{
180 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
181 struct afe4403_data *afe = iio_priv(indio_dev);
182 struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
183 unsigned int reg_val, type;
184 int vals[2];
185 int ret, val_len;
186
187 ret = regmap_read(afe->regmap, afe440x_attr->reg, &reg_val);
188 if (ret)
189 return ret;
190
191 reg_val &= afe440x_attr->mask;
192 reg_val >>= afe440x_attr->shift;
193
194 switch (afe440x_attr->type) {
195 case SIMPLE:
196 type = IIO_VAL_INT;
197 val_len = 1;
198 vals[0] = reg_val;
199 break;
200 case RESISTANCE:
201 case CAPACITANCE:
202 type = IIO_VAL_INT_PLUS_MICRO;
203 val_len = 2;
204 if (reg_val < afe440x_attr->table_size) {
205 vals[0] = afe440x_attr->val_table[reg_val].integer;
206 vals[1] = afe440x_attr->val_table[reg_val].fract;
207 break;
208 }
209 return -EINVAL;
210 default:
211 return -EINVAL;
212 }
213
214 return iio_format_value(buf, type, val_len, vals);
215}
216
217static ssize_t afe440x_store_register(struct device *dev,
218 struct device_attribute *attr,
219 const char *buf, size_t count)
220{
221 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
222 struct afe4403_data *afe = iio_priv(indio_dev);
223 struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
224 int val, integer, fract, ret;
225
226 ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
227 if (ret)
228 return ret;
229
230 switch (afe440x_attr->type) {
231 case SIMPLE:
232 val = integer;
233 break;
234 case RESISTANCE:
235 case CAPACITANCE:
236 for (val = 0; val < afe440x_attr->table_size; val++)
237 if (afe440x_attr->val_table[val].integer == integer &&
238 afe440x_attr->val_table[val].fract == fract)
239 break;
240 if (val == afe440x_attr->table_size)
241 return -EINVAL;
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 ret = regmap_update_bits(afe->regmap, afe440x_attr->reg,
248 afe440x_attr->mask,
249 (val << afe440x_attr->shift));
250 if (ret)
251 return ret;
252
253 return count;
254}
255
256static AFE440X_ATTR(tia_separate_en, AFE4403_TIAGAIN, AFE440X_TIAGAIN_ENSEPGAIN, SIMPLE, NULL, 0);
257
258static AFE440X_ATTR(tia_resistance1, AFE4403_TIAGAIN, AFE4403_TIAGAIN_RES, RESISTANCE, afe4403_res_table, ARRAY_SIZE(afe4403_res_table));
259static AFE440X_ATTR(tia_capacitance1, AFE4403_TIAGAIN, AFE4403_TIAGAIN_CAP, CAPACITANCE, afe4403_cap_table, ARRAY_SIZE(afe4403_cap_table));
260
261static AFE440X_ATTR(tia_resistance2, AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES, RESISTANCE, afe4403_res_table, ARRAY_SIZE(afe4403_res_table));
262static AFE440X_ATTR(tia_capacitance2, AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES, CAPACITANCE, afe4403_cap_table, ARRAY_SIZE(afe4403_cap_table));
263
264static struct attribute *afe440x_attributes[] = {
265 &afe440x_attr_tia_separate_en.dev_attr.attr,
266 &afe440x_attr_tia_resistance1.dev_attr.attr,
267 &afe440x_attr_tia_capacitance1.dev_attr.attr,
268 &afe440x_attr_tia_resistance2.dev_attr.attr,
269 &afe440x_attr_tia_capacitance2.dev_attr.attr,
270 &dev_attr_tia_resistance_available.attr,
271 &dev_attr_tia_capacitance_available.attr,
272 NULL
273};
274
275static const struct attribute_group afe440x_attribute_group = {
276 .attrs = afe440x_attributes
277};
278
279static int afe4403_read(struct afe4403_data *afe, unsigned int reg, u32 *val)
280{
281 u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
282 u8 rx[3];
283 int ret;
284
285 /* Enable reading from the device */
286 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
287 if (ret)
288 return ret;
289
290 ret = spi_write_then_read(afe->spi, &reg, 1, rx, 3);
291 if (ret)
292 return ret;
293
294 *val = (rx[0] << 16) |
295 (rx[1] << 8) |
296 (rx[2]);
297
298 /* Disable reading from the device */
299 tx[3] = AFE440X_CONTROL0_WRITE;
300 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
301 if (ret)
302 return ret;
303
304 return 0;
305}
306
307static int afe4403_read_raw(struct iio_dev *indio_dev,
308 struct iio_chan_spec const *chan,
309 int *val, int *val2, long mask)
310{
311 struct afe4403_data *afe = iio_priv(indio_dev);
312 const struct afe440x_reg_info reg_info = afe4403_reg_info[chan->address];
313 int ret;
314
315 switch (chan->type) {
316 case IIO_INTENSITY:
317 switch (mask) {
318 case IIO_CHAN_INFO_RAW:
319 ret = afe4403_read(afe, reg_info.reg, val);
320 if (ret)
321 return ret;
322 return IIO_VAL_INT;
323 case IIO_CHAN_INFO_OFFSET:
324 ret = regmap_read(afe->regmap, reg_info.offreg,
325 val);
326 if (ret)
327 return ret;
328 *val &= reg_info.mask;
329 *val >>= reg_info.shift;
330 return IIO_VAL_INT;
331 }
332 break;
333 case IIO_CURRENT:
334 switch (mask) {
335 case IIO_CHAN_INFO_RAW:
336 ret = regmap_read(afe->regmap, reg_info.reg, val);
337 if (ret)
338 return ret;
339 *val &= reg_info.mask;
340 *val >>= reg_info.shift;
341 return IIO_VAL_INT;
342 case IIO_CHAN_INFO_SCALE:
343 *val = 0;
344 *val2 = 800000;
345 return IIO_VAL_INT_PLUS_MICRO;
346 }
347 break;
348 default:
349 break;
350 }
351
352 return -EINVAL;
353}
354
355static int afe4403_write_raw(struct iio_dev *indio_dev,
356 struct iio_chan_spec const *chan,
357 int val, int val2, long mask)
358{
359 struct afe4403_data *afe = iio_priv(indio_dev);
360 const struct afe440x_reg_info reg_info = afe4403_reg_info[chan->address];
361
362 switch (chan->type) {
363 case IIO_INTENSITY:
364 switch (mask) {
365 case IIO_CHAN_INFO_OFFSET:
366 return regmap_update_bits(afe->regmap,
367 reg_info.offreg,
368 reg_info.mask,
369 (val << reg_info.shift));
370 }
371 break;
372 case IIO_CURRENT:
373 switch (mask) {
374 case IIO_CHAN_INFO_RAW:
375 return regmap_update_bits(afe->regmap,
376 reg_info.reg,
377 reg_info.mask,
378 (val << reg_info.shift));
379 }
380 break;
381 default:
382 break;
383 }
384
385 return -EINVAL;
386}
387
388static const struct iio_info afe4403_iio_info = {
389 .attrs = &afe440x_attribute_group,
390 .read_raw = afe4403_read_raw,
391 .write_raw = afe4403_write_raw,
392 .driver_module = THIS_MODULE,
393};
394
395static irqreturn_t afe4403_trigger_handler(int irq, void *private)
396{
397 struct iio_poll_func *pf = private;
398 struct iio_dev *indio_dev = pf->indio_dev;
399 struct afe4403_data *afe = iio_priv(indio_dev);
400 int ret, bit, i = 0;
401 s32 buffer[8];
402 u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
403 u8 rx[3];
404
405 /* Enable reading from the device */
406 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
407 if (ret)
408 goto err;
409
410 for_each_set_bit(bit, indio_dev->active_scan_mask,
411 indio_dev->masklength) {
412 ret = spi_write_then_read(afe->spi,
413 &afe4403_reg_info[bit].reg, 1,
414 rx, 3);
415 if (ret)
416 goto err;
417
418 buffer[i++] = (rx[0] << 16) |
419 (rx[1] << 8) |
420 (rx[2]);
421 }
422
423 /* Disable reading from the device */
424 tx[3] = AFE440X_CONTROL0_WRITE;
425 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
426 if (ret)
427 goto err;
428
429 iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
430err:
431 iio_trigger_notify_done(indio_dev->trig);
432
433 return IRQ_HANDLED;
434}
435
436static const struct iio_trigger_ops afe4403_trigger_ops = {
437 .owner = THIS_MODULE,
438};
439
440#define AFE4403_TIMING_PAIRS \
441 { AFE440X_LED2STC, 0x000050 }, \
442 { AFE440X_LED2ENDC, 0x0003e7 }, \
443 { AFE440X_LED1LEDSTC, 0x0007d0 }, \
444 { AFE440X_LED1LEDENDC, 0x000bb7 }, \
445 { AFE440X_ALED2STC, 0x000438 }, \
446 { AFE440X_ALED2ENDC, 0x0007cf }, \
447 { AFE440X_LED1STC, 0x000820 }, \
448 { AFE440X_LED1ENDC, 0x000bb7 }, \
449 { AFE440X_LED2LEDSTC, 0x000000 }, \
450 { AFE440X_LED2LEDENDC, 0x0003e7 }, \
451 { AFE440X_ALED1STC, 0x000c08 }, \
452 { AFE440X_ALED1ENDC, 0x000f9f }, \
453 { AFE440X_LED2CONVST, 0x0003ef }, \
454 { AFE440X_LED2CONVEND, 0x0007cf }, \
455 { AFE440X_ALED2CONVST, 0x0007d7 }, \
456 { AFE440X_ALED2CONVEND, 0x000bb7 }, \
457 { AFE440X_LED1CONVST, 0x000bbf }, \
458 { AFE440X_LED1CONVEND, 0x009c3f }, \
459 { AFE440X_ALED1CONVST, 0x000fa7 }, \
460 { AFE440X_ALED1CONVEND, 0x001387 }, \
461 { AFE440X_ADCRSTSTCT0, 0x0003e8 }, \
462 { AFE440X_ADCRSTENDCT0, 0x0003eb }, \
463 { AFE440X_ADCRSTSTCT1, 0x0007d0 }, \
464 { AFE440X_ADCRSTENDCT1, 0x0007d3 }, \
465 { AFE440X_ADCRSTSTCT2, 0x000bb8 }, \
466 { AFE440X_ADCRSTENDCT2, 0x000bbb }, \
467 { AFE440X_ADCRSTSTCT3, 0x000fa0 }, \
468 { AFE440X_ADCRSTENDCT3, 0x000fa3 }, \
469 { AFE440X_PRPCOUNT, 0x009c3f }, \
470 { AFE440X_PDNCYCLESTC, 0x001518 }, \
471 { AFE440X_PDNCYCLEENDC, 0x00991f }
472
473static const struct reg_sequence afe4403_reg_sequences[] = {
474 AFE4403_TIMING_PAIRS,
475 { AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN | 0x000007},
476 { AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES_1_M },
477 { AFE440X_LEDCNTRL, (0x14 << AFE440X_LEDCNTRL_LED1_SHIFT) |
478 (0x14 << AFE440X_LEDCNTRL_LED2_SHIFT) },
479 { AFE440X_CONTROL2, AFE440X_CONTROL2_TX_REF_050 <<
480 AFE440X_CONTROL2_TX_REF_SHIFT },
481};
482
483static const struct regmap_range afe4403_yes_ranges[] = {
484 regmap_reg_range(AFE440X_LED2VAL, AFE440X_LED1_ALED1VAL),
485};
486
487static const struct regmap_access_table afe4403_volatile_table = {
488 .yes_ranges = afe4403_yes_ranges,
489 .n_yes_ranges = ARRAY_SIZE(afe4403_yes_ranges),
490};
491
492static const struct regmap_config afe4403_regmap_config = {
493 .reg_bits = 8,
494 .val_bits = 24,
495
496 .max_register = AFE440X_PDNCYCLEENDC,
497 .cache_type = REGCACHE_RBTREE,
498 .volatile_table = &afe4403_volatile_table,
499};
500
501#ifdef CONFIG_OF
502static const struct of_device_id afe4403_of_match[] = {
503 { .compatible = "ti,afe4403", },
504 { /* sentinel */ }
505};
506MODULE_DEVICE_TABLE(of, afe4403_of_match);
507#endif
508
509static int afe4403_suspend(struct device *dev)
510{
511 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
512 struct afe4403_data *afe = iio_priv(indio_dev);
513 int ret;
514
515 ret = regmap_update_bits(afe->regmap, AFE440X_CONTROL2,
516 AFE440X_CONTROL2_PDN_AFE,
517 AFE440X_CONTROL2_PDN_AFE);
518 if (ret)
519 return ret;
520
521 ret = regulator_disable(afe->regulator);
522 if (ret) {
523 dev_err(dev, "Unable to disable regulator\n");
524 return ret;
525 }
526
527 return 0;
528}
529
530static int afe4403_resume(struct device *dev)
531{
532 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
533 struct afe4403_data *afe = iio_priv(indio_dev);
534 int ret;
535
536 ret = regulator_enable(afe->regulator);
537 if (ret) {
538 dev_err(dev, "Unable to enable regulator\n");
539 return ret;
540 }
541
542 ret = regmap_update_bits(afe->regmap, AFE440X_CONTROL2,
543 AFE440X_CONTROL2_PDN_AFE, 0);
544 if (ret)
545 return ret;
546
547 return 0;
548}
549
550static SIMPLE_DEV_PM_OPS(afe4403_pm_ops, afe4403_suspend, afe4403_resume);
551
552static int afe4403_probe(struct spi_device *spi)
553{
554 struct iio_dev *indio_dev;
555 struct afe4403_data *afe;
556 int ret;
557
558 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*afe));
559 if (!indio_dev)
560 return -ENOMEM;
561
562 afe = iio_priv(indio_dev);
563 spi_set_drvdata(spi, indio_dev);
564
565 afe->dev = &spi->dev;
566 afe->spi = spi;
567 afe->irq = spi->irq;
568
569 afe->regmap = devm_regmap_init_spi(spi, &afe4403_regmap_config);
570 if (IS_ERR(afe->regmap)) {
571 dev_err(afe->dev, "Unable to allocate register map\n");
572 return PTR_ERR(afe->regmap);
573 }
574
575 afe->regulator = devm_regulator_get(afe->dev, "tx_sup");
576 if (IS_ERR(afe->regulator)) {
577 dev_err(afe->dev, "Unable to get regulator\n");
578 return PTR_ERR(afe->regulator);
579 }
580 ret = regulator_enable(afe->regulator);
581 if (ret) {
582 dev_err(afe->dev, "Unable to enable regulator\n");
583 return ret;
584 }
585
586 ret = regmap_write(afe->regmap, AFE440X_CONTROL0,
587 AFE440X_CONTROL0_SW_RESET);
588 if (ret) {
589 dev_err(afe->dev, "Unable to reset device\n");
590 goto err_disable_reg;
591 }
592
593 ret = regmap_multi_reg_write(afe->regmap, afe4403_reg_sequences,
594 ARRAY_SIZE(afe4403_reg_sequences));
595 if (ret) {
596 dev_err(afe->dev, "Unable to set register defaults\n");
597 goto err_disable_reg;
598 }
599
600 indio_dev->modes = INDIO_DIRECT_MODE;
601 indio_dev->dev.parent = afe->dev;
602 indio_dev->channels = afe4403_channels;
603 indio_dev->num_channels = ARRAY_SIZE(afe4403_channels);
604 indio_dev->name = AFE4403_DRIVER_NAME;
605 indio_dev->info = &afe4403_iio_info;
606
607 if (afe->irq > 0) {
608 afe->trig = devm_iio_trigger_alloc(afe->dev,
609 "%s-dev%d",
610 indio_dev->name,
611 indio_dev->id);
612 if (!afe->trig) {
613 dev_err(afe->dev, "Unable to allocate IIO trigger\n");
614 ret = -ENOMEM;
615 goto err_disable_reg;
616 }
617
618 iio_trigger_set_drvdata(afe->trig, indio_dev);
619
620 afe->trig->ops = &afe4403_trigger_ops;
621 afe->trig->dev.parent = afe->dev;
622
623 ret = iio_trigger_register(afe->trig);
624 if (ret) {
625 dev_err(afe->dev, "Unable to register IIO trigger\n");
626 goto err_disable_reg;
627 }
628
629 ret = devm_request_threaded_irq(afe->dev, afe->irq,
630 iio_trigger_generic_data_rdy_poll,
631 NULL, IRQF_ONESHOT,
632 AFE4403_DRIVER_NAME,
633 afe->trig);
634 if (ret) {
635 dev_err(afe->dev, "Unable to request IRQ\n");
636 goto err_trig;
637 }
638 }
639
640 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
641 afe4403_trigger_handler, NULL);
642 if (ret) {
643 dev_err(afe->dev, "Unable to setup buffer\n");
644 goto err_trig;
645 }
646
647 ret = iio_device_register(indio_dev);
648 if (ret) {
649 dev_err(afe->dev, "Unable to register IIO device\n");
650 goto err_buff;
651 }
652
653 return 0;
654
655err_buff:
656 iio_triggered_buffer_cleanup(indio_dev);
657err_trig:
658 if (afe->irq > 0)
659 iio_trigger_unregister(afe->trig);
660err_disable_reg:
661 regulator_disable(afe->regulator);
662
663 return ret;
664}
665
666static int afe4403_remove(struct spi_device *spi)
667{
668 struct iio_dev *indio_dev = spi_get_drvdata(spi);
669 struct afe4403_data *afe = iio_priv(indio_dev);
670 int ret;
671
672 iio_device_unregister(indio_dev);
673
674 iio_triggered_buffer_cleanup(indio_dev);
675
676 if (afe->irq > 0)
677 iio_trigger_unregister(afe->trig);
678
679 ret = regulator_disable(afe->regulator);
680 if (ret) {
681 dev_err(afe->dev, "Unable to disable regulator\n");
682 return ret;
683 }
684
685 return 0;
686}
687
688static const struct spi_device_id afe4403_ids[] = {
689 { "afe4403", 0 },
690 { /* sentinel */ }
691};
692MODULE_DEVICE_TABLE(spi, afe4403_ids);
693
694static struct spi_driver afe4403_spi_driver = {
695 .driver = {
696 .name = AFE4403_DRIVER_NAME,
697 .of_match_table = of_match_ptr(afe4403_of_match),
698 .pm = &afe4403_pm_ops,
699 },
700 .probe = afe4403_probe,
701 .remove = afe4403_remove,
702 .id_table = afe4403_ids,
703};
704module_spi_driver(afe4403_spi_driver);
705
706MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
707MODULE_DESCRIPTION("TI AFE4403 Heart Rate and Pulse Oximeter");
708MODULE_LICENSE("GPL v2");