File Index
Files and directories
Sign in
FILE

afe4403.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/health/afe4403.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * AFE4403 Heart Rate Monitors and Low-Cost Pulse Oximeters
  4 *
  5 * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/
  6 *	Andrew F. Davis <afd@ti.com>
  7 */
  8
  9#include <linux/device.h>
 10#include <linux/err.h>
 11#include <linux/interrupt.h>
 12#include <linux/kernel.h>
 13#include <linux/module.h>
 14#include <linux/regmap.h>
 15#include <linux/spi/spi.h>
 16#include <linux/sysfs.h>
 17#include <linux/regulator/consumer.h>
 18
 19#include <linux/iio/iio.h>
 20#include <linux/iio/sysfs.h>
 21#include <linux/iio/buffer.h>
 22#include <linux/iio/trigger.h>
 23#include <linux/iio/triggered_buffer.h>
 24#include <linux/iio/trigger_consumer.h>
 25
 26#include <linux/unaligned.h>
 27
 28#include "afe440x.h"
 29
 30#define AFE4403_DRIVER_NAME		"afe4403"
 31
 32/* AFE4403 Registers */
 33#define AFE4403_TIAGAIN			0x20
 34#define AFE4403_TIA_AMB_GAIN		0x21
 35
 36enum afe4403_fields {
 37	/* Gains */
 38	F_RF_LED1, F_CF_LED1,
 39	F_RF_LED, F_CF_LED,
 40
 41	/* LED Current */
 42	F_ILED1, F_ILED2,
 43
 44	/* sentinel */
 45	F_MAX_FIELDS
 46};
 47
 48static const struct reg_field afe4403_reg_fields[] = {
 49	/* Gains */
 50	[F_RF_LED1]	= REG_FIELD(AFE4403_TIAGAIN, 0, 2),
 51	[F_CF_LED1]	= REG_FIELD(AFE4403_TIAGAIN, 3, 7),
 52	[F_RF_LED]	= REG_FIELD(AFE4403_TIA_AMB_GAIN, 0, 2),
 53	[F_CF_LED]	= REG_FIELD(AFE4403_TIA_AMB_GAIN, 3, 7),
 54	/* LED Current */
 55	[F_ILED1]	= REG_FIELD(AFE440X_LEDCNTRL, 0, 7),
 56	[F_ILED2]	= REG_FIELD(AFE440X_LEDCNTRL, 8, 15),
 57};
 58
 59/**
 60 * struct afe4403_data - AFE4403 device instance data
 61 * @spi: SPI device handle
 62 * @regmap: Register map of the device
 63 * @fields: Register fields of the device
 64 * @regulator: Pointer to the regulator for the IC
 65 * @trig: IIO trigger for this device
 66 * @irq: ADC_RDY line interrupt number
 67 * @buffer: Used to construct data layout to push into IIO buffer.
 68 */
 69struct afe4403_data {
 70	struct spi_device *spi;
 71	struct regmap *regmap;
 72	struct regmap_field *fields[F_MAX_FIELDS];
 73	struct regulator *regulator;
 74	struct iio_trigger *trig;
 75	int irq;
 76	/* Ensure suitable alignment for timestamp */
 77	s32 buffer[8] __aligned(8);
 78};
 79
 80enum afe4403_chan_id {
 81	LED2 = 1,
 82	ALED2,
 83	LED1,
 84	ALED1,
 85	LED2_ALED2,
 86	LED1_ALED1,
 87};
 88
 89static const unsigned int afe4403_channel_values[] = {
 90	[LED2] = AFE440X_LED2VAL,
 91	[ALED2] = AFE440X_ALED2VAL,
 92	[LED1] = AFE440X_LED1VAL,
 93	[ALED1] = AFE440X_ALED1VAL,
 94	[LED2_ALED2] = AFE440X_LED2_ALED2VAL,
 95	[LED1_ALED1] = AFE440X_LED1_ALED1VAL,
 96};
 97
 98static const unsigned int afe4403_channel_leds[] = {
 99	[LED2] = F_ILED2,
100	[LED1] = F_ILED1,
101};
102
103static const struct iio_chan_spec afe4403_channels[] = {
104	/* ADC values */
105	AFE440X_INTENSITY_CHAN(LED2, 0),
106	AFE440X_INTENSITY_CHAN(ALED2, 0),
107	AFE440X_INTENSITY_CHAN(LED1, 0),
108	AFE440X_INTENSITY_CHAN(ALED1, 0),
109	AFE440X_INTENSITY_CHAN(LED2_ALED2, 0),
110	AFE440X_INTENSITY_CHAN(LED1_ALED1, 0),
111	/* LED current */
112	AFE440X_CURRENT_CHAN(LED2),
113	AFE440X_CURRENT_CHAN(LED1),
114};
115
116static const struct afe440x_val_table afe4403_res_table[] = {
117	{ 500000 }, { 250000 }, { 100000 }, { 50000 },
118	{ 25000 }, { 10000 }, { 1000000 }, { 0 },
119};
120AFE440X_TABLE_ATTR(in_intensity_resistance_available, afe4403_res_table);
121
122static const struct afe440x_val_table afe4403_cap_table[] = {
123	{ 0, 5000 }, { 0, 10000 }, { 0, 20000 }, { 0, 25000 },
124	{ 0, 30000 }, { 0, 35000 }, { 0, 45000 }, { 0, 50000 },
125	{ 0, 55000 }, { 0, 60000 }, { 0, 70000 }, { 0, 75000 },
126	{ 0, 80000 }, { 0, 85000 }, { 0, 95000 }, { 0, 100000 },
127	{ 0, 155000 }, { 0, 160000 }, { 0, 170000 }, { 0, 175000 },
128	{ 0, 180000 }, { 0, 185000 }, { 0, 195000 }, { 0, 200000 },
129	{ 0, 205000 }, { 0, 210000 }, { 0, 220000 }, { 0, 225000 },
130	{ 0, 230000 }, { 0, 235000 }, { 0, 245000 }, { 0, 250000 },
131};
132AFE440X_TABLE_ATTR(in_intensity_capacitance_available, afe4403_cap_table);
133
134static ssize_t afe440x_show_register(struct device *dev,
135				     struct device_attribute *attr,
136				     char *buf)
137{
138	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
139	struct afe4403_data *afe = iio_priv(indio_dev);
140	struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
141	unsigned int reg_val;
142	int vals[2];
143	int ret;
144
145	ret = regmap_field_read(afe->fields[afe440x_attr->field], &reg_val);
146	if (ret)
147		return ret;
148
149	if (reg_val >= afe440x_attr->table_size)
150		return -EINVAL;
151
152	vals[0] = afe440x_attr->val_table[reg_val].integer;
153	vals[1] = afe440x_attr->val_table[reg_val].fract;
154
155	return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals);
156}
157
158static ssize_t afe440x_store_register(struct device *dev,
159				      struct device_attribute *attr,
160				      const char *buf, size_t count)
161{
162	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
163	struct afe4403_data *afe = iio_priv(indio_dev);
164	struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
165	int val, integer, fract, ret;
166
167	ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
168	if (ret)
169		return ret;
170
171	for (val = 0; val < afe440x_attr->table_size; val++)
172		if (afe440x_attr->val_table[val].integer == integer &&
173		    afe440x_attr->val_table[val].fract == fract)
174			break;
175	if (val == afe440x_attr->table_size)
176		return -EINVAL;
177
178	ret = regmap_field_write(afe->fields[afe440x_attr->field], val);
179	if (ret)
180		return ret;
181
182	return count;
183}
184
185static AFE440X_ATTR(in_intensity1_resistance, F_RF_LED, afe4403_res_table);
186static AFE440X_ATTR(in_intensity1_capacitance, F_CF_LED, afe4403_cap_table);
187
188static AFE440X_ATTR(in_intensity2_resistance, F_RF_LED, afe4403_res_table);
189static AFE440X_ATTR(in_intensity2_capacitance, F_CF_LED, afe4403_cap_table);
190
191static AFE440X_ATTR(in_intensity3_resistance, F_RF_LED1, afe4403_res_table);
192static AFE440X_ATTR(in_intensity3_capacitance, F_CF_LED1, afe4403_cap_table);
193
194static AFE440X_ATTR(in_intensity4_resistance, F_RF_LED1, afe4403_res_table);
195static AFE440X_ATTR(in_intensity4_capacitance, F_CF_LED1, afe4403_cap_table);
196
197static struct attribute *afe440x_attributes[] = {
198	&dev_attr_in_intensity_resistance_available.attr,
199	&dev_attr_in_intensity_capacitance_available.attr,
200	&afe440x_attr_in_intensity1_resistance.dev_attr.attr,
201	&afe440x_attr_in_intensity1_capacitance.dev_attr.attr,
202	&afe440x_attr_in_intensity2_resistance.dev_attr.attr,
203	&afe440x_attr_in_intensity2_capacitance.dev_attr.attr,
204	&afe440x_attr_in_intensity3_resistance.dev_attr.attr,
205	&afe440x_attr_in_intensity3_capacitance.dev_attr.attr,
206	&afe440x_attr_in_intensity4_resistance.dev_attr.attr,
207	&afe440x_attr_in_intensity4_capacitance.dev_attr.attr,
208	NULL
209};
210
211static const struct attribute_group afe440x_attribute_group = {
212	.attrs = afe440x_attributes
213};
214
215static int afe4403_read(struct afe4403_data *afe, unsigned int reg, u32 *val)
216{
217	u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
218	u8 rx[3];
219	int ret;
220
221	/* Enable reading from the device */
222	ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
223	if (ret)
224		return ret;
225
226	ret = spi_write_then_read(afe->spi, &reg, 1, rx, sizeof(rx));
227	if (ret)
228		return ret;
229
230	*val = get_unaligned_be24(&rx[0]);
231
232	/* Disable reading from the device */
233	tx[3] = AFE440X_CONTROL0_WRITE;
234	ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
235	if (ret)
236		return ret;
237
238	return 0;
239}
240
241static int afe4403_read_raw(struct iio_dev *indio_dev,
242			    struct iio_chan_spec const *chan,
243			    int *val, int *val2, long mask)
244{
245	struct afe4403_data *afe = iio_priv(indio_dev);
246	unsigned int reg, field;
247	int ret;
248
249	switch (chan->type) {
250	case IIO_INTENSITY:
251		switch (mask) {
252		case IIO_CHAN_INFO_RAW:
253			reg = afe4403_channel_values[chan->address];
254			ret = afe4403_read(afe, reg, val);
255			if (ret)
256				return ret;
257			return IIO_VAL_INT;
258		}
259		break;
260	case IIO_CURRENT:
261		switch (mask) {
262		case IIO_CHAN_INFO_RAW:
263			field = afe4403_channel_leds[chan->address];
264			ret = regmap_field_read(afe->fields[field], val);
265			if (ret)
266				return ret;
267			return IIO_VAL_INT;
268		case IIO_CHAN_INFO_SCALE:
269			*val = 0;
270			*val2 = 800000;
271			return IIO_VAL_INT_PLUS_MICRO;
272		}
273		break;
274	default:
275		break;
276	}
277
278	return -EINVAL;
279}
280
281static int afe4403_write_raw(struct iio_dev *indio_dev,
282			     struct iio_chan_spec const *chan,
283			     int val, int val2, long mask)
284{
285	struct afe4403_data *afe = iio_priv(indio_dev);
286	unsigned int field = afe4403_channel_leds[chan->address];
287
288	switch (chan->type) {
289	case IIO_CURRENT:
290		switch (mask) {
291		case IIO_CHAN_INFO_RAW:
292			return regmap_field_write(afe->fields[field], val);
293		}
294		break;
295	default:
296		break;
297	}
298
299	return -EINVAL;
300}
301
302static const struct iio_info afe4403_iio_info = {
303	.attrs = &afe440x_attribute_group,
304	.read_raw = afe4403_read_raw,
305	.write_raw = afe4403_write_raw,
306};
307
308static irqreturn_t afe4403_trigger_handler(int irq, void *private)
309{
310	struct iio_poll_func *pf = private;
311	struct iio_dev *indio_dev = pf->indio_dev;
312	struct afe4403_data *afe = iio_priv(indio_dev);
313	int ret, bit, i = 0;
314	u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
315	u8 rx[3];
316
317	/* Enable reading from the device */
318	ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
319	if (ret)
320		goto err;
321
322	iio_for_each_active_channel(indio_dev, bit) {
323		ret = spi_write_then_read(afe->spi,
324					  &afe4403_channel_values[bit], 1,
325					  rx, sizeof(rx));
326		if (ret)
327			goto err;
328
329		afe->buffer[i++] = get_unaligned_be24(&rx[0]);
330	}
331
332	/* Disable reading from the device */
333	tx[3] = AFE440X_CONTROL0_WRITE;
334	ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);
335	if (ret)
336		goto err;
337
338	iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
339					   pf->timestamp);
340err:
341	iio_trigger_notify_done(indio_dev->trig);
342
343	return IRQ_HANDLED;
344}
345
346static void afe4403_regulator_disable(void *data)
347{
348	struct regulator *regulator = data;
349
350	regulator_disable(regulator);
351}
352
353#define AFE4403_TIMING_PAIRS			\
354	{ AFE440X_LED2STC,	0x000050 },	\
355	{ AFE440X_LED2ENDC,	0x0003e7 },	\
356	{ AFE440X_LED1LEDSTC,	0x0007d0 },	\
357	{ AFE440X_LED1LEDENDC,	0x000bb7 },	\
358	{ AFE440X_ALED2STC,	0x000438 },	\
359	{ AFE440X_ALED2ENDC,	0x0007cf },	\
360	{ AFE440X_LED1STC,	0x000820 },	\
361	{ AFE440X_LED1ENDC,	0x000bb7 },	\
362	{ AFE440X_LED2LEDSTC,	0x000000 },	\
363	{ AFE440X_LED2LEDENDC,	0x0003e7 },	\
364	{ AFE440X_ALED1STC,	0x000c08 },	\
365	{ AFE440X_ALED1ENDC,	0x000f9f },	\
366	{ AFE440X_LED2CONVST,	0x0003ef },	\
367	{ AFE440X_LED2CONVEND,	0x0007cf },	\
368	{ AFE440X_ALED2CONVST,	0x0007d7 },	\
369	{ AFE440X_ALED2CONVEND,	0x000bb7 },	\
370	{ AFE440X_LED1CONVST,	0x000bbf },	\
371	{ AFE440X_LED1CONVEND,	0x009c3f },	\
372	{ AFE440X_ALED1CONVST,	0x000fa7 },	\
373	{ AFE440X_ALED1CONVEND,	0x001387 },	\
374	{ AFE440X_ADCRSTSTCT0,	0x0003e8 },	\
375	{ AFE440X_ADCRSTENDCT0,	0x0003eb },	\
376	{ AFE440X_ADCRSTSTCT1,	0x0007d0 },	\
377	{ AFE440X_ADCRSTENDCT1,	0x0007d3 },	\
378	{ AFE440X_ADCRSTSTCT2,	0x000bb8 },	\
379	{ AFE440X_ADCRSTENDCT2,	0x000bbb },	\
380	{ AFE440X_ADCRSTSTCT3,	0x000fa0 },	\
381	{ AFE440X_ADCRSTENDCT3,	0x000fa3 },	\
382	{ AFE440X_PRPCOUNT,	0x009c3f },	\
383	{ AFE440X_PDNCYCLESTC,	0x001518 },	\
384	{ AFE440X_PDNCYCLEENDC,	0x00991f }
385
386static const struct reg_sequence afe4403_reg_sequences[] = {
387	AFE4403_TIMING_PAIRS,
388	{ AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN },
389	{ AFE4403_TIAGAIN, AFE440X_TIAGAIN_ENSEPGAIN },
390};
391
392static const struct regmap_range afe4403_yes_ranges[] = {
393	regmap_reg_range(AFE440X_LED2VAL, AFE440X_LED1_ALED1VAL),
394};
395
396static const struct regmap_access_table afe4403_volatile_table = {
397	.yes_ranges = afe4403_yes_ranges,
398	.n_yes_ranges = ARRAY_SIZE(afe4403_yes_ranges),
399};
400
401static const struct regmap_config afe4403_regmap_config = {
402	.reg_bits = 8,
403	.val_bits = 24,
404
405	.max_register = AFE440X_PDNCYCLEENDC,
406	.cache_type = REGCACHE_MAPLE,
407	.volatile_table = &afe4403_volatile_table,
408};
409
410static const struct of_device_id afe4403_of_match[] = {
411	{ .compatible = "ti,afe4403", },
412	{ }
413};
414MODULE_DEVICE_TABLE(of, afe4403_of_match);
415
416static int afe4403_suspend(struct device *dev)
417{
418	struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev));
419	struct afe4403_data *afe = iio_priv(indio_dev);
420	int ret;
421
422	ret = regmap_set_bits(afe->regmap, AFE440X_CONTROL2,
423			      AFE440X_CONTROL2_PDN_AFE);
424	if (ret)
425		return ret;
426
427	ret = regulator_disable(afe->regulator);
428	if (ret) {
429		dev_err(dev, "Unable to disable regulator\n");
430		return ret;
431	}
432
433	return 0;
434}
435
436static int afe4403_resume(struct device *dev)
437{
438	struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev));
439	struct afe4403_data *afe = iio_priv(indio_dev);
440	int ret;
441
442	ret = regulator_enable(afe->regulator);
443	if (ret) {
444		dev_err(dev, "Unable to enable regulator\n");
445		return ret;
446	}
447
448	ret = regmap_clear_bits(afe->regmap, AFE440X_CONTROL2,
449				AFE440X_CONTROL2_PDN_AFE);
450	if (ret)
451		return ret;
452
453	return 0;
454}
455
456static DEFINE_SIMPLE_DEV_PM_OPS(afe4403_pm_ops, afe4403_suspend,
457				afe4403_resume);
458
459static int afe4403_probe(struct spi_device *spi)
460{
461	struct device *dev = &spi->dev;
462	struct iio_dev *indio_dev;
463	struct afe4403_data *afe;
464	int i, ret;
465
466	indio_dev = devm_iio_device_alloc(dev, sizeof(*afe));
467	if (!indio_dev)
468		return -ENOMEM;
469
470	afe = iio_priv(indio_dev);
471	spi_set_drvdata(spi, indio_dev);
472
473	afe->spi = spi;
474	afe->irq = spi->irq;
475
476	afe->regmap = devm_regmap_init_spi(spi, &afe4403_regmap_config);
477	if (IS_ERR(afe->regmap)) {
478		dev_err(dev, "Unable to allocate register map\n");
479		return PTR_ERR(afe->regmap);
480	}
481
482	for (i = 0; i < F_MAX_FIELDS; i++) {
483		afe->fields[i] = devm_regmap_field_alloc(dev, afe->regmap,
484							 afe4403_reg_fields[i]);
485		if (IS_ERR(afe->fields[i])) {
486			dev_err(dev, "Unable to allocate regmap fields\n");
487			return PTR_ERR(afe->fields[i]);
488		}
489	}
490
491	afe->regulator = devm_regulator_get(dev, "tx_sup");
492	if (IS_ERR(afe->regulator))
493		return dev_err_probe(dev, PTR_ERR(afe->regulator),
494				     "Unable to get regulator\n");
495
496	ret = regulator_enable(afe->regulator);
497	if (ret) {
498		dev_err(dev, "Unable to enable regulator\n");
499		return ret;
500	}
501	ret = devm_add_action_or_reset(dev, afe4403_regulator_disable, afe->regulator);
502	if (ret) {
503		dev_err(dev, "Unable to add regulator disable action\n");
504		return ret;
505	}
506
507	ret = regmap_write(afe->regmap, AFE440X_CONTROL0,
508			   AFE440X_CONTROL0_SW_RESET);
509	if (ret) {
510		dev_err(dev, "Unable to reset device\n");
511		return ret;
512	}
513
514	ret = regmap_multi_reg_write(afe->regmap, afe4403_reg_sequences,
515				     ARRAY_SIZE(afe4403_reg_sequences));
516	if (ret) {
517		dev_err(dev, "Unable to set register defaults\n");
518		return ret;
519	}
520
521	indio_dev->modes = INDIO_DIRECT_MODE;
522	indio_dev->channels = afe4403_channels;
523	indio_dev->num_channels = ARRAY_SIZE(afe4403_channels);
524	indio_dev->name = AFE4403_DRIVER_NAME;
525	indio_dev->info = &afe4403_iio_info;
526
527	if (afe->irq > 0) {
528		afe->trig = devm_iio_trigger_alloc(dev,
529						   "%s-dev%d",
530						   indio_dev->name,
531						   iio_device_id(indio_dev));
532		if (!afe->trig)
533			return -ENOMEM;
534
535		iio_trigger_set_drvdata(afe->trig, indio_dev);
536
537		ret = devm_iio_trigger_register(dev, afe->trig);
538		if (ret) {
539			dev_err(dev, "Unable to register IIO trigger\n");
540			return ret;
541		}
542
543		ret = devm_request_threaded_irq(dev, afe->irq,
544						iio_trigger_generic_data_rdy_poll,
545						NULL, IRQF_ONESHOT,
546						AFE4403_DRIVER_NAME,
547						afe->trig);
548		if (ret) {
549			dev_err(dev, "Unable to request IRQ\n");
550			return ret;
551		}
552	}
553
554	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
555					      &iio_pollfunc_store_time,
556					      afe4403_trigger_handler, NULL);
557	if (ret) {
558		dev_err(dev, "Unable to setup buffer\n");
559		return ret;
560	}
561
562	ret = devm_iio_device_register(dev, indio_dev);
563	if (ret) {
564		dev_err(dev, "Unable to register IIO device\n");
565		return ret;
566	}
567
568	return 0;
569}
570
571static const struct spi_device_id afe4403_ids[] = {
572	{ "afe4403", 0 },
573	{ }
574};
575MODULE_DEVICE_TABLE(spi, afe4403_ids);
576
577static struct spi_driver afe4403_spi_driver = {
578	.driver = {
579		.name = AFE4403_DRIVER_NAME,
580		.of_match_table = afe4403_of_match,
581		.pm = pm_sleep_ptr(&afe4403_pm_ops),
582	},
583	.probe = afe4403_probe,
584	.id_table = afe4403_ids,
585};
586module_spi_driver(afe4403_spi_driver);
587
588MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
589MODULE_DESCRIPTION("TI AFE4403 Heart Rate Monitor and Pulse Oximeter AFE");
590MODULE_LICENSE("GPL v2");
~/ Read-only file preview.