cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

afe4403.c (16351B)


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