0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/device.h>
0010 #include <linux/err.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/i2c.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/regmap.h>
0016 #include <linux/sysfs.h>
0017 #include <linux/regulator/consumer.h>
0018
0019 #include <linux/iio/iio.h>
0020 #include <linux/iio/sysfs.h>
0021 #include <linux/iio/buffer.h>
0022 #include <linux/iio/trigger.h>
0023 #include <linux/iio/triggered_buffer.h>
0024 #include <linux/iio/trigger_consumer.h>
0025
0026 #include "afe440x.h"
0027
0028 #define AFE4404_DRIVER_NAME "afe4404"
0029
0030
0031 #define AFE4404_TIA_GAIN_SEP 0x20
0032 #define AFE4404_TIA_GAIN 0x21
0033 #define AFE4404_PROG_TG_STC 0x34
0034 #define AFE4404_PROG_TG_ENDC 0x35
0035 #define AFE4404_LED3LEDSTC 0x36
0036 #define AFE4404_LED3LEDENDC 0x37
0037 #define AFE4404_CLKDIV_PRF 0x39
0038 #define AFE4404_OFFDAC 0x3a
0039 #define AFE4404_DEC 0x3d
0040 #define AFE4404_AVG_LED2_ALED2VAL 0x3f
0041 #define AFE4404_AVG_LED1_ALED1VAL 0x40
0042
0043
0044 #define AFE440X_CONTROL2_OSC_ENABLE BIT(9)
0045
0046 enum afe4404_fields {
0047
0048 F_TIA_GAIN_SEP, F_TIA_CF_SEP,
0049 F_TIA_GAIN, TIA_CF,
0050
0051
0052 F_ILED1, F_ILED2, F_ILED3,
0053
0054
0055 F_OFFDAC_AMB2, F_OFFDAC_LED1, F_OFFDAC_AMB1, F_OFFDAC_LED2,
0056
0057
0058 F_MAX_FIELDS
0059 };
0060
0061 static const struct reg_field afe4404_reg_fields[] = {
0062
0063 [F_TIA_GAIN_SEP] = REG_FIELD(AFE4404_TIA_GAIN_SEP, 0, 2),
0064 [F_TIA_CF_SEP] = REG_FIELD(AFE4404_TIA_GAIN_SEP, 3, 5),
0065 [F_TIA_GAIN] = REG_FIELD(AFE4404_TIA_GAIN, 0, 2),
0066 [TIA_CF] = REG_FIELD(AFE4404_TIA_GAIN, 3, 5),
0067
0068 [F_ILED1] = REG_FIELD(AFE440X_LEDCNTRL, 0, 5),
0069 [F_ILED2] = REG_FIELD(AFE440X_LEDCNTRL, 6, 11),
0070 [F_ILED3] = REG_FIELD(AFE440X_LEDCNTRL, 12, 17),
0071
0072 [F_OFFDAC_AMB2] = REG_FIELD(AFE4404_OFFDAC, 0, 4),
0073 [F_OFFDAC_LED1] = REG_FIELD(AFE4404_OFFDAC, 5, 9),
0074 [F_OFFDAC_AMB1] = REG_FIELD(AFE4404_OFFDAC, 10, 14),
0075 [F_OFFDAC_LED2] = REG_FIELD(AFE4404_OFFDAC, 15, 19),
0076 };
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 struct afe4404_data {
0089 struct device *dev;
0090 struct regmap *regmap;
0091 struct regmap_field *fields[F_MAX_FIELDS];
0092 struct regulator *regulator;
0093 struct iio_trigger *trig;
0094 int irq;
0095 s32 buffer[10] __aligned(8);
0096 };
0097
0098 enum afe4404_chan_id {
0099 LED2 = 1,
0100 ALED2,
0101 LED1,
0102 ALED1,
0103 LED2_ALED2,
0104 LED1_ALED1,
0105 };
0106
0107 static const unsigned int afe4404_channel_values[] = {
0108 [LED2] = AFE440X_LED2VAL,
0109 [ALED2] = AFE440X_ALED2VAL,
0110 [LED1] = AFE440X_LED1VAL,
0111 [ALED1] = AFE440X_ALED1VAL,
0112 [LED2_ALED2] = AFE440X_LED2_ALED2VAL,
0113 [LED1_ALED1] = AFE440X_LED1_ALED1VAL,
0114 };
0115
0116 static const unsigned int afe4404_channel_leds[] = {
0117 [LED2] = F_ILED2,
0118 [ALED2] = F_ILED3,
0119 [LED1] = F_ILED1,
0120 };
0121
0122 static const unsigned int afe4404_channel_offdacs[] = {
0123 [LED2] = F_OFFDAC_LED2,
0124 [ALED2] = F_OFFDAC_AMB2,
0125 [LED1] = F_OFFDAC_LED1,
0126 [ALED1] = F_OFFDAC_AMB1,
0127 };
0128
0129 static const struct iio_chan_spec afe4404_channels[] = {
0130
0131 AFE440X_INTENSITY_CHAN(LED2, BIT(IIO_CHAN_INFO_OFFSET)),
0132 AFE440X_INTENSITY_CHAN(ALED2, BIT(IIO_CHAN_INFO_OFFSET)),
0133 AFE440X_INTENSITY_CHAN(LED1, BIT(IIO_CHAN_INFO_OFFSET)),
0134 AFE440X_INTENSITY_CHAN(ALED1, BIT(IIO_CHAN_INFO_OFFSET)),
0135 AFE440X_INTENSITY_CHAN(LED2_ALED2, 0),
0136 AFE440X_INTENSITY_CHAN(LED1_ALED1, 0),
0137
0138 AFE440X_CURRENT_CHAN(LED2),
0139 AFE440X_CURRENT_CHAN(ALED2),
0140 AFE440X_CURRENT_CHAN(LED1),
0141 };
0142
0143 static const struct afe440x_val_table afe4404_res_table[] = {
0144 { .integer = 500000, .fract = 0 },
0145 { .integer = 250000, .fract = 0 },
0146 { .integer = 100000, .fract = 0 },
0147 { .integer = 50000, .fract = 0 },
0148 { .integer = 25000, .fract = 0 },
0149 { .integer = 10000, .fract = 0 },
0150 { .integer = 1000000, .fract = 0 },
0151 { .integer = 2000000, .fract = 0 },
0152 };
0153 AFE440X_TABLE_ATTR(in_intensity_resistance_available, afe4404_res_table);
0154
0155 static const struct afe440x_val_table afe4404_cap_table[] = {
0156 { .integer = 0, .fract = 5000 },
0157 { .integer = 0, .fract = 2500 },
0158 { .integer = 0, .fract = 10000 },
0159 { .integer = 0, .fract = 7500 },
0160 { .integer = 0, .fract = 20000 },
0161 { .integer = 0, .fract = 17500 },
0162 { .integer = 0, .fract = 25000 },
0163 { .integer = 0, .fract = 22500 },
0164 };
0165 AFE440X_TABLE_ATTR(in_intensity_capacitance_available, afe4404_cap_table);
0166
0167 static ssize_t afe440x_show_register(struct device *dev,
0168 struct device_attribute *attr,
0169 char *buf)
0170 {
0171 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0172 struct afe4404_data *afe = iio_priv(indio_dev);
0173 struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
0174 unsigned int reg_val;
0175 int vals[2];
0176 int ret;
0177
0178 ret = regmap_field_read(afe->fields[afe440x_attr->field], ®_val);
0179 if (ret)
0180 return ret;
0181
0182 if (reg_val >= afe440x_attr->table_size)
0183 return -EINVAL;
0184
0185 vals[0] = afe440x_attr->val_table[reg_val].integer;
0186 vals[1] = afe440x_attr->val_table[reg_val].fract;
0187
0188 return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals);
0189 }
0190
0191 static ssize_t afe440x_store_register(struct device *dev,
0192 struct device_attribute *attr,
0193 const char *buf, size_t count)
0194 {
0195 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0196 struct afe4404_data *afe = iio_priv(indio_dev);
0197 struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
0198 int val, integer, fract, ret;
0199
0200 ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
0201 if (ret)
0202 return ret;
0203
0204 for (val = 0; val < afe440x_attr->table_size; val++)
0205 if (afe440x_attr->val_table[val].integer == integer &&
0206 afe440x_attr->val_table[val].fract == fract)
0207 break;
0208 if (val == afe440x_attr->table_size)
0209 return -EINVAL;
0210
0211 ret = regmap_field_write(afe->fields[afe440x_attr->field], val);
0212 if (ret)
0213 return ret;
0214
0215 return count;
0216 }
0217
0218 static AFE440X_ATTR(in_intensity1_resistance, F_TIA_GAIN_SEP, afe4404_res_table);
0219 static AFE440X_ATTR(in_intensity1_capacitance, F_TIA_CF_SEP, afe4404_cap_table);
0220
0221 static AFE440X_ATTR(in_intensity2_resistance, F_TIA_GAIN_SEP, afe4404_res_table);
0222 static AFE440X_ATTR(in_intensity2_capacitance, F_TIA_CF_SEP, afe4404_cap_table);
0223
0224 static AFE440X_ATTR(in_intensity3_resistance, F_TIA_GAIN, afe4404_res_table);
0225 static AFE440X_ATTR(in_intensity3_capacitance, TIA_CF, afe4404_cap_table);
0226
0227 static AFE440X_ATTR(in_intensity4_resistance, F_TIA_GAIN, afe4404_res_table);
0228 static AFE440X_ATTR(in_intensity4_capacitance, TIA_CF, afe4404_cap_table);
0229
0230 static struct attribute *afe440x_attributes[] = {
0231 &dev_attr_in_intensity_resistance_available.attr,
0232 &dev_attr_in_intensity_capacitance_available.attr,
0233 &afe440x_attr_in_intensity1_resistance.dev_attr.attr,
0234 &afe440x_attr_in_intensity1_capacitance.dev_attr.attr,
0235 &afe440x_attr_in_intensity2_resistance.dev_attr.attr,
0236 &afe440x_attr_in_intensity2_capacitance.dev_attr.attr,
0237 &afe440x_attr_in_intensity3_resistance.dev_attr.attr,
0238 &afe440x_attr_in_intensity3_capacitance.dev_attr.attr,
0239 &afe440x_attr_in_intensity4_resistance.dev_attr.attr,
0240 &afe440x_attr_in_intensity4_capacitance.dev_attr.attr,
0241 NULL
0242 };
0243
0244 static const struct attribute_group afe440x_attribute_group = {
0245 .attrs = afe440x_attributes
0246 };
0247
0248 static int afe4404_read_raw(struct iio_dev *indio_dev,
0249 struct iio_chan_spec const *chan,
0250 int *val, int *val2, long mask)
0251 {
0252 struct afe4404_data *afe = iio_priv(indio_dev);
0253 unsigned int value_reg = afe4404_channel_values[chan->address];
0254 unsigned int led_field = afe4404_channel_leds[chan->address];
0255 unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
0256 int ret;
0257
0258 switch (chan->type) {
0259 case IIO_INTENSITY:
0260 switch (mask) {
0261 case IIO_CHAN_INFO_RAW:
0262 ret = regmap_read(afe->regmap, value_reg, val);
0263 if (ret)
0264 return ret;
0265 return IIO_VAL_INT;
0266 case IIO_CHAN_INFO_OFFSET:
0267 ret = regmap_field_read(afe->fields[offdac_field], val);
0268 if (ret)
0269 return ret;
0270 return IIO_VAL_INT;
0271 }
0272 break;
0273 case IIO_CURRENT:
0274 switch (mask) {
0275 case IIO_CHAN_INFO_RAW:
0276 ret = regmap_field_read(afe->fields[led_field], val);
0277 if (ret)
0278 return ret;
0279 return IIO_VAL_INT;
0280 case IIO_CHAN_INFO_SCALE:
0281 *val = 0;
0282 *val2 = 800000;
0283 return IIO_VAL_INT_PLUS_MICRO;
0284 }
0285 break;
0286 default:
0287 break;
0288 }
0289
0290 return -EINVAL;
0291 }
0292
0293 static int afe4404_write_raw(struct iio_dev *indio_dev,
0294 struct iio_chan_spec const *chan,
0295 int val, int val2, long mask)
0296 {
0297 struct afe4404_data *afe = iio_priv(indio_dev);
0298 unsigned int led_field = afe4404_channel_leds[chan->address];
0299 unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
0300
0301 switch (chan->type) {
0302 case IIO_INTENSITY:
0303 switch (mask) {
0304 case IIO_CHAN_INFO_OFFSET:
0305 return regmap_field_write(afe->fields[offdac_field], val);
0306 }
0307 break;
0308 case IIO_CURRENT:
0309 switch (mask) {
0310 case IIO_CHAN_INFO_RAW:
0311 return regmap_field_write(afe->fields[led_field], val);
0312 }
0313 break;
0314 default:
0315 break;
0316 }
0317
0318 return -EINVAL;
0319 }
0320
0321 static const struct iio_info afe4404_iio_info = {
0322 .attrs = &afe440x_attribute_group,
0323 .read_raw = afe4404_read_raw,
0324 .write_raw = afe4404_write_raw,
0325 };
0326
0327 static irqreturn_t afe4404_trigger_handler(int irq, void *private)
0328 {
0329 struct iio_poll_func *pf = private;
0330 struct iio_dev *indio_dev = pf->indio_dev;
0331 struct afe4404_data *afe = iio_priv(indio_dev);
0332 int ret, bit, i = 0;
0333
0334 for_each_set_bit(bit, indio_dev->active_scan_mask,
0335 indio_dev->masklength) {
0336 ret = regmap_read(afe->regmap, afe4404_channel_values[bit],
0337 &afe->buffer[i++]);
0338 if (ret)
0339 goto err;
0340 }
0341
0342 iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
0343 pf->timestamp);
0344 err:
0345 iio_trigger_notify_done(indio_dev->trig);
0346
0347 return IRQ_HANDLED;
0348 }
0349
0350
0351 #define AFE4404_TIMING_PAIRS \
0352 { AFE440X_PRPCOUNT, 39999 }, \
0353 { AFE440X_LED2LEDSTC, 0 }, \
0354 { AFE440X_LED2LEDENDC, 398 }, \
0355 { AFE440X_LED2STC, 80 }, \
0356 { AFE440X_LED2ENDC, 398 }, \
0357 { AFE440X_ADCRSTSTCT0, 5600 }, \
0358 { AFE440X_ADCRSTENDCT0, 5606 }, \
0359 { AFE440X_LED2CONVST, 5607 }, \
0360 { AFE440X_LED2CONVEND, 6066 }, \
0361 { AFE4404_LED3LEDSTC, 400 }, \
0362 { AFE4404_LED3LEDENDC, 798 }, \
0363 { AFE440X_ALED2STC, 480 }, \
0364 { AFE440X_ALED2ENDC, 798 }, \
0365 { AFE440X_ADCRSTSTCT1, 6068 }, \
0366 { AFE440X_ADCRSTENDCT1, 6074 }, \
0367 { AFE440X_ALED2CONVST, 6075 }, \
0368 { AFE440X_ALED2CONVEND, 6534 }, \
0369 { AFE440X_LED1LEDSTC, 800 }, \
0370 { AFE440X_LED1LEDENDC, 1198 }, \
0371 { AFE440X_LED1STC, 880 }, \
0372 { AFE440X_LED1ENDC, 1198 }, \
0373 { AFE440X_ADCRSTSTCT2, 6536 }, \
0374 { AFE440X_ADCRSTENDCT2, 6542 }, \
0375 { AFE440X_LED1CONVST, 6543 }, \
0376 { AFE440X_LED1CONVEND, 7003 }, \
0377 { AFE440X_ALED1STC, 1280 }, \
0378 { AFE440X_ALED1ENDC, 1598 }, \
0379 { AFE440X_ADCRSTSTCT3, 7005 }, \
0380 { AFE440X_ADCRSTENDCT3, 7011 }, \
0381 { AFE440X_ALED1CONVST, 7012 }, \
0382 { AFE440X_ALED1CONVEND, 7471 }, \
0383 { AFE440X_PDNCYCLESTC, 7671 }, \
0384 { AFE440X_PDNCYCLEENDC, 39199 }
0385
0386 static const struct reg_sequence afe4404_reg_sequences[] = {
0387 AFE4404_TIMING_PAIRS,
0388 { AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN },
0389 { AFE4404_TIA_GAIN_SEP, AFE440X_TIAGAIN_ENSEPGAIN },
0390 { AFE440X_CONTROL2, AFE440X_CONTROL2_OSC_ENABLE },
0391 };
0392
0393 static const struct regmap_range afe4404_yes_ranges[] = {
0394 regmap_reg_range(AFE440X_LED2VAL, AFE440X_LED1_ALED1VAL),
0395 regmap_reg_range(AFE4404_AVG_LED2_ALED2VAL, AFE4404_AVG_LED1_ALED1VAL),
0396 };
0397
0398 static const struct regmap_access_table afe4404_volatile_table = {
0399 .yes_ranges = afe4404_yes_ranges,
0400 .n_yes_ranges = ARRAY_SIZE(afe4404_yes_ranges),
0401 };
0402
0403 static const struct regmap_config afe4404_regmap_config = {
0404 .reg_bits = 8,
0405 .val_bits = 24,
0406
0407 .max_register = AFE4404_AVG_LED1_ALED1VAL,
0408 .cache_type = REGCACHE_RBTREE,
0409 .volatile_table = &afe4404_volatile_table,
0410 };
0411
0412 static const struct of_device_id afe4404_of_match[] = {
0413 { .compatible = "ti,afe4404", },
0414 { }
0415 };
0416 MODULE_DEVICE_TABLE(of, afe4404_of_match);
0417
0418 static int afe4404_suspend(struct device *dev)
0419 {
0420 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0421 struct afe4404_data *afe = iio_priv(indio_dev);
0422 int ret;
0423
0424 ret = regmap_update_bits(afe->regmap, AFE440X_CONTROL2,
0425 AFE440X_CONTROL2_PDN_AFE,
0426 AFE440X_CONTROL2_PDN_AFE);
0427 if (ret)
0428 return ret;
0429
0430 ret = regulator_disable(afe->regulator);
0431 if (ret) {
0432 dev_err(dev, "Unable to disable regulator\n");
0433 return ret;
0434 }
0435
0436 return 0;
0437 }
0438
0439 static int afe4404_resume(struct device *dev)
0440 {
0441 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0442 struct afe4404_data *afe = iio_priv(indio_dev);
0443 int ret;
0444
0445 ret = regulator_enable(afe->regulator);
0446 if (ret) {
0447 dev_err(dev, "Unable to enable regulator\n");
0448 return ret;
0449 }
0450
0451 ret = regmap_update_bits(afe->regmap, AFE440X_CONTROL2,
0452 AFE440X_CONTROL2_PDN_AFE, 0);
0453 if (ret)
0454 return ret;
0455
0456 return 0;
0457 }
0458
0459 static DEFINE_SIMPLE_DEV_PM_OPS(afe4404_pm_ops, afe4404_suspend,
0460 afe4404_resume);
0461
0462 static int afe4404_probe(struct i2c_client *client,
0463 const struct i2c_device_id *id)
0464 {
0465 struct iio_dev *indio_dev;
0466 struct afe4404_data *afe;
0467 int i, ret;
0468
0469 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*afe));
0470 if (!indio_dev)
0471 return -ENOMEM;
0472
0473 afe = iio_priv(indio_dev);
0474 i2c_set_clientdata(client, indio_dev);
0475
0476 afe->dev = &client->dev;
0477 afe->irq = client->irq;
0478
0479 afe->regmap = devm_regmap_init_i2c(client, &afe4404_regmap_config);
0480 if (IS_ERR(afe->regmap)) {
0481 dev_err(afe->dev, "Unable to allocate register map\n");
0482 return PTR_ERR(afe->regmap);
0483 }
0484
0485 for (i = 0; i < F_MAX_FIELDS; i++) {
0486 afe->fields[i] = devm_regmap_field_alloc(afe->dev, afe->regmap,
0487 afe4404_reg_fields[i]);
0488 if (IS_ERR(afe->fields[i])) {
0489 dev_err(afe->dev, "Unable to allocate regmap fields\n");
0490 return PTR_ERR(afe->fields[i]);
0491 }
0492 }
0493
0494 afe->regulator = devm_regulator_get(afe->dev, "tx_sup");
0495 if (IS_ERR(afe->regulator))
0496 return dev_err_probe(afe->dev, PTR_ERR(afe->regulator),
0497 "Unable to get regulator\n");
0498
0499 ret = regulator_enable(afe->regulator);
0500 if (ret) {
0501 dev_err(afe->dev, "Unable to enable regulator\n");
0502 return ret;
0503 }
0504
0505 ret = regmap_write(afe->regmap, AFE440X_CONTROL0,
0506 AFE440X_CONTROL0_SW_RESET);
0507 if (ret) {
0508 dev_err(afe->dev, "Unable to reset device\n");
0509 goto disable_reg;
0510 }
0511
0512 ret = regmap_multi_reg_write(afe->regmap, afe4404_reg_sequences,
0513 ARRAY_SIZE(afe4404_reg_sequences));
0514 if (ret) {
0515 dev_err(afe->dev, "Unable to set register defaults\n");
0516 goto disable_reg;
0517 }
0518
0519 indio_dev->modes = INDIO_DIRECT_MODE;
0520 indio_dev->channels = afe4404_channels;
0521 indio_dev->num_channels = ARRAY_SIZE(afe4404_channels);
0522 indio_dev->name = AFE4404_DRIVER_NAME;
0523 indio_dev->info = &afe4404_iio_info;
0524
0525 if (afe->irq > 0) {
0526 afe->trig = devm_iio_trigger_alloc(afe->dev,
0527 "%s-dev%d",
0528 indio_dev->name,
0529 iio_device_id(indio_dev));
0530 if (!afe->trig) {
0531 dev_err(afe->dev, "Unable to allocate IIO trigger\n");
0532 ret = -ENOMEM;
0533 goto disable_reg;
0534 }
0535
0536 iio_trigger_set_drvdata(afe->trig, indio_dev);
0537
0538 ret = iio_trigger_register(afe->trig);
0539 if (ret) {
0540 dev_err(afe->dev, "Unable to register IIO trigger\n");
0541 goto disable_reg;
0542 }
0543
0544 ret = devm_request_threaded_irq(afe->dev, afe->irq,
0545 iio_trigger_generic_data_rdy_poll,
0546 NULL, IRQF_ONESHOT,
0547 AFE4404_DRIVER_NAME,
0548 afe->trig);
0549 if (ret) {
0550 dev_err(afe->dev, "Unable to request IRQ\n");
0551 goto disable_reg;
0552 }
0553 }
0554
0555 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
0556 afe4404_trigger_handler, NULL);
0557 if (ret) {
0558 dev_err(afe->dev, "Unable to setup buffer\n");
0559 goto unregister_trigger;
0560 }
0561
0562 ret = iio_device_register(indio_dev);
0563 if (ret) {
0564 dev_err(afe->dev, "Unable to register IIO device\n");
0565 goto unregister_triggered_buffer;
0566 }
0567
0568 return 0;
0569
0570 unregister_triggered_buffer:
0571 iio_triggered_buffer_cleanup(indio_dev);
0572 unregister_trigger:
0573 if (afe->irq > 0)
0574 iio_trigger_unregister(afe->trig);
0575 disable_reg:
0576 regulator_disable(afe->regulator);
0577
0578 return ret;
0579 }
0580
0581 static int afe4404_remove(struct i2c_client *client)
0582 {
0583 struct iio_dev *indio_dev = i2c_get_clientdata(client);
0584 struct afe4404_data *afe = iio_priv(indio_dev);
0585 int ret;
0586
0587 iio_device_unregister(indio_dev);
0588
0589 iio_triggered_buffer_cleanup(indio_dev);
0590
0591 if (afe->irq > 0)
0592 iio_trigger_unregister(afe->trig);
0593
0594 ret = regulator_disable(afe->regulator);
0595 if (ret)
0596 dev_err(afe->dev, "Unable to disable regulator\n");
0597
0598 return 0;
0599 }
0600
0601 static const struct i2c_device_id afe4404_ids[] = {
0602 { "afe4404", 0 },
0603 { }
0604 };
0605 MODULE_DEVICE_TABLE(i2c, afe4404_ids);
0606
0607 static struct i2c_driver afe4404_i2c_driver = {
0608 .driver = {
0609 .name = AFE4404_DRIVER_NAME,
0610 .of_match_table = afe4404_of_match,
0611 .pm = pm_sleep_ptr(&afe4404_pm_ops),
0612 },
0613 .probe = afe4404_probe,
0614 .remove = afe4404_remove,
0615 .id_table = afe4404_ids,
0616 };
0617 module_i2c_driver(afe4404_i2c_driver);
0618
0619 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
0620 MODULE_DESCRIPTION("TI AFE4404 Heart Rate Monitor and Pulse Oximeter AFE");
0621 MODULE_LICENSE("GPL v2");