^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AFE4404 Heart Rate Monitors and Low-Cost Pulse Oximeters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Andrew F. Davis <afd@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "afe440x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AFE4404_DRIVER_NAME "afe4404"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* AFE4404 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AFE4404_TIA_GAIN_SEP 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AFE4404_TIA_GAIN 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AFE4404_PROG_TG_STC 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AFE4404_PROG_TG_ENDC 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define AFE4404_LED3LEDSTC 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define AFE4404_LED3LEDENDC 0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define AFE4404_CLKDIV_PRF 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define AFE4404_OFFDAC 0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define AFE4404_DEC 0x3d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define AFE4404_AVG_LED2_ALED2VAL 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define AFE4404_AVG_LED1_ALED1VAL 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* AFE4404 CONTROL2 register fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AFE440X_CONTROL2_OSC_ENABLE BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) enum afe4404_fields {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Gains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) F_TIA_GAIN_SEP, F_TIA_CF_SEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) F_TIA_GAIN, TIA_CF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* LED Current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) F_ILED1, F_ILED2, F_ILED3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Offset DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) F_OFFDAC_AMB2, F_OFFDAC_LED1, F_OFFDAC_AMB1, F_OFFDAC_LED2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) F_MAX_FIELDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const struct reg_field afe4404_reg_fields[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Gains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) [F_TIA_GAIN_SEP] = REG_FIELD(AFE4404_TIA_GAIN_SEP, 0, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) [F_TIA_CF_SEP] = REG_FIELD(AFE4404_TIA_GAIN_SEP, 3, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) [F_TIA_GAIN] = REG_FIELD(AFE4404_TIA_GAIN, 0, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) [TIA_CF] = REG_FIELD(AFE4404_TIA_GAIN, 3, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* LED Current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) [F_ILED1] = REG_FIELD(AFE440X_LEDCNTRL, 0, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) [F_ILED2] = REG_FIELD(AFE440X_LEDCNTRL, 6, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) [F_ILED3] = REG_FIELD(AFE440X_LEDCNTRL, 12, 17),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Offset DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) [F_OFFDAC_AMB2] = REG_FIELD(AFE4404_OFFDAC, 0, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) [F_OFFDAC_LED1] = REG_FIELD(AFE4404_OFFDAC, 5, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) [F_OFFDAC_AMB1] = REG_FIELD(AFE4404_OFFDAC, 10, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [F_OFFDAC_LED2] = REG_FIELD(AFE4404_OFFDAC, 15, 19),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * struct afe4404_data - AFE4404 device instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @dev: Device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @regmap: Register map of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @fields: Register fields of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @regulator: Pointer to the regulator for the IC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @trig: IIO trigger for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @irq: ADC_RDY line interrupt number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @buffer: Used to construct a scan to push to the iio buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct afe4404_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct regmap_field *fields[F_MAX_FIELDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct regulator *regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct iio_trigger *trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) s32 buffer[10] __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) enum afe4404_chan_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) LED2 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ALED2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) LED1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ALED1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) LED2_ALED2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) LED1_ALED1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const unsigned int afe4404_channel_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) [LED2] = AFE440X_LED2VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) [ALED2] = AFE440X_ALED2VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) [LED1] = AFE440X_LED1VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) [ALED1] = AFE440X_ALED1VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) [LED2_ALED2] = AFE440X_LED2_ALED2VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) [LED1_ALED1] = AFE440X_LED1_ALED1VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const unsigned int afe4404_channel_leds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) [LED2] = F_ILED2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) [ALED2] = F_ILED3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) [LED1] = F_ILED1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static const unsigned int afe4404_channel_offdacs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) [LED2] = F_OFFDAC_LED2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) [ALED2] = F_OFFDAC_AMB2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) [LED1] = F_OFFDAC_LED1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) [ALED1] = F_OFFDAC_AMB1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static const struct iio_chan_spec afe4404_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* ADC values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) AFE440X_INTENSITY_CHAN(LED2, BIT(IIO_CHAN_INFO_OFFSET)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) AFE440X_INTENSITY_CHAN(ALED2, BIT(IIO_CHAN_INFO_OFFSET)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) AFE440X_INTENSITY_CHAN(LED1, BIT(IIO_CHAN_INFO_OFFSET)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) AFE440X_INTENSITY_CHAN(ALED1, BIT(IIO_CHAN_INFO_OFFSET)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) AFE440X_INTENSITY_CHAN(LED2_ALED2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) AFE440X_INTENSITY_CHAN(LED1_ALED1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* LED current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) AFE440X_CURRENT_CHAN(LED2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) AFE440X_CURRENT_CHAN(ALED2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) AFE440X_CURRENT_CHAN(LED1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static const struct afe440x_val_table afe4404_res_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { .integer = 500000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { .integer = 250000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { .integer = 100000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { .integer = 50000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { .integer = 25000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { .integer = 10000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { .integer = 1000000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { .integer = 2000000, .fract = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) AFE440X_TABLE_ATTR(in_intensity_resistance_available, afe4404_res_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static const struct afe440x_val_table afe4404_cap_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { .integer = 0, .fract = 5000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { .integer = 0, .fract = 2500 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { .integer = 0, .fract = 10000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { .integer = 0, .fract = 7500 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { .integer = 0, .fract = 20000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { .integer = 0, .fract = 17500 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { .integer = 0, .fract = 25000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { .integer = 0, .fract = 22500 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) AFE440X_TABLE_ATTR(in_intensity_capacitance_available, afe4404_cap_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static ssize_t afe440x_show_register(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int vals[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ret = regmap_field_read(afe->fields[afe440x_attr->field], ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (reg_val >= afe440x_attr->table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) vals[0] = afe440x_attr->val_table[reg_val].integer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) vals[1] = afe440x_attr->val_table[reg_val].fract;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static ssize_t afe440x_store_register(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int val, integer, fract, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (val = 0; val < afe440x_attr->table_size; val++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (afe440x_attr->val_table[val].integer == integer &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) afe440x_attr->val_table[val].fract == fract)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (val == afe440x_attr->table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = regmap_field_write(afe->fields[afe440x_attr->field], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static AFE440X_ATTR(in_intensity1_resistance, F_TIA_GAIN_SEP, afe4404_res_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static AFE440X_ATTR(in_intensity1_capacitance, F_TIA_CF_SEP, afe4404_cap_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static AFE440X_ATTR(in_intensity2_resistance, F_TIA_GAIN_SEP, afe4404_res_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static AFE440X_ATTR(in_intensity2_capacitance, F_TIA_CF_SEP, afe4404_cap_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static AFE440X_ATTR(in_intensity3_resistance, F_TIA_GAIN, afe4404_res_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static AFE440X_ATTR(in_intensity3_capacitance, TIA_CF, afe4404_cap_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static AFE440X_ATTR(in_intensity4_resistance, F_TIA_GAIN, afe4404_res_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static AFE440X_ATTR(in_intensity4_capacitance, TIA_CF, afe4404_cap_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static struct attribute *afe440x_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) &dev_attr_in_intensity_resistance_available.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) &dev_attr_in_intensity_capacitance_available.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) &afe440x_attr_in_intensity1_resistance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) &afe440x_attr_in_intensity1_capacitance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) &afe440x_attr_in_intensity2_resistance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) &afe440x_attr_in_intensity2_capacitance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) &afe440x_attr_in_intensity3_resistance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) &afe440x_attr_in_intensity3_capacitance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) &afe440x_attr_in_intensity4_resistance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) &afe440x_attr_in_intensity4_capacitance.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static const struct attribute_group afe440x_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .attrs = afe440x_attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int afe4404_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned int value_reg = afe4404_channel_values[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unsigned int led_field = afe4404_channel_leds[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = regmap_read(afe->regmap, value_reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = regmap_field_read(afe->fields[offdac_field], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case IIO_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = regmap_field_read(afe->fields[led_field], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *val2 = 800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int afe4404_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned int led_field = afe4404_channel_leds[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return regmap_field_write(afe->fields[offdac_field], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case IIO_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return regmap_field_write(afe->fields[led_field], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static const struct iio_info afe4404_iio_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .attrs = &afe440x_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .read_raw = afe4404_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .write_raw = afe4404_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static irqreturn_t afe4404_trigger_handler(int irq, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct iio_poll_func *pf = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int ret, bit, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) for_each_set_bit(bit, indio_dev->active_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) indio_dev->masklength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = regmap_read(afe->regmap, afe4404_channel_values[bit],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) &afe->buffer[i++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) pf->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static const struct iio_trigger_ops afe4404_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* Default timings from data-sheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define AFE4404_TIMING_PAIRS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) { AFE440X_PRPCOUNT, 39999 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) { AFE440X_LED2LEDSTC, 0 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) { AFE440X_LED2LEDENDC, 398 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { AFE440X_LED2STC, 80 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) { AFE440X_LED2ENDC, 398 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) { AFE440X_ADCRSTSTCT0, 5600 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) { AFE440X_ADCRSTENDCT0, 5606 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) { AFE440X_LED2CONVST, 5607 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { AFE440X_LED2CONVEND, 6066 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) { AFE4404_LED3LEDSTC, 400 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) { AFE4404_LED3LEDENDC, 798 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) { AFE440X_ALED2STC, 480 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { AFE440X_ALED2ENDC, 798 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { AFE440X_ADCRSTSTCT1, 6068 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { AFE440X_ADCRSTENDCT1, 6074 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) { AFE440X_ALED2CONVST, 6075 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) { AFE440X_ALED2CONVEND, 6534 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) { AFE440X_LED1LEDSTC, 800 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) { AFE440X_LED1LEDENDC, 1198 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { AFE440X_LED1STC, 880 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) { AFE440X_LED1ENDC, 1198 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) { AFE440X_ADCRSTSTCT2, 6536 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { AFE440X_ADCRSTENDCT2, 6542 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) { AFE440X_LED1CONVST, 6543 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) { AFE440X_LED1CONVEND, 7003 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) { AFE440X_ALED1STC, 1280 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) { AFE440X_ALED1ENDC, 1598 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) { AFE440X_ADCRSTSTCT3, 7005 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) { AFE440X_ADCRSTENDCT3, 7011 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) { AFE440X_ALED1CONVST, 7012 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) { AFE440X_ALED1CONVEND, 7471 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) { AFE440X_PDNCYCLESTC, 7671 }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) { AFE440X_PDNCYCLEENDC, 39199 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static const struct reg_sequence afe4404_reg_sequences[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) AFE4404_TIMING_PAIRS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) { AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { AFE4404_TIA_GAIN_SEP, AFE440X_TIAGAIN_ENSEPGAIN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) { AFE440X_CONTROL2, AFE440X_CONTROL2_OSC_ENABLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static const struct regmap_range afe4404_yes_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) regmap_reg_range(AFE440X_LED2VAL, AFE440X_LED1_ALED1VAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) regmap_reg_range(AFE4404_AVG_LED2_ALED2VAL, AFE4404_AVG_LED1_ALED1VAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static const struct regmap_access_table afe4404_volatile_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .yes_ranges = afe4404_yes_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .n_yes_ranges = ARRAY_SIZE(afe4404_yes_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static const struct regmap_config afe4404_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .val_bits = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .max_register = AFE4404_AVG_LED1_ALED1VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .volatile_table = &afe4404_volatile_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static const struct of_device_id afe4404_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) { .compatible = "ti,afe4404", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) MODULE_DEVICE_TABLE(of, afe4404_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int __maybe_unused afe4404_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret = regmap_update_bits(afe->regmap, AFE440X_CONTROL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) AFE440X_CONTROL2_PDN_AFE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) AFE440X_CONTROL2_PDN_AFE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ret = regulator_disable(afe->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dev_err(dev, "Unable to disable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int __maybe_unused afe4404_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = regulator_enable(afe->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_err(dev, "Unable to enable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = regmap_update_bits(afe->regmap, AFE440X_CONTROL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) AFE440X_CONTROL2_PDN_AFE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static SIMPLE_DEV_PM_OPS(afe4404_pm_ops, afe4404_suspend, afe4404_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int afe4404_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct afe4404_data *afe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*afe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) afe->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) afe->irq = client->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) afe->regmap = devm_regmap_init_i2c(client, &afe4404_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (IS_ERR(afe->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dev_err(afe->dev, "Unable to allocate register map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return PTR_ERR(afe->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) for (i = 0; i < F_MAX_FIELDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) afe->fields[i] = devm_regmap_field_alloc(afe->dev, afe->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) afe4404_reg_fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (IS_ERR(afe->fields[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) dev_err(afe->dev, "Unable to allocate regmap fields\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return PTR_ERR(afe->fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) afe->regulator = devm_regulator_get(afe->dev, "tx_sup");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (IS_ERR(afe->regulator)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_err(afe->dev, "Unable to get regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return PTR_ERR(afe->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ret = regulator_enable(afe->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) dev_err(afe->dev, "Unable to enable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = regmap_write(afe->regmap, AFE440X_CONTROL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) AFE440X_CONTROL0_SW_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dev_err(afe->dev, "Unable to reset device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) goto disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ret = regmap_multi_reg_write(afe->regmap, afe4404_reg_sequences,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ARRAY_SIZE(afe4404_reg_sequences));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) dev_err(afe->dev, "Unable to set register defaults\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) indio_dev->channels = afe4404_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) indio_dev->num_channels = ARRAY_SIZE(afe4404_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) indio_dev->name = AFE4404_DRIVER_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) indio_dev->info = &afe4404_iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (afe->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) afe->trig = devm_iio_trigger_alloc(afe->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) "%s-dev%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!afe->trig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dev_err(afe->dev, "Unable to allocate IIO trigger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) goto disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) iio_trigger_set_drvdata(afe->trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) afe->trig->ops = &afe4404_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) afe->trig->dev.parent = afe->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ret = iio_trigger_register(afe->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dev_err(afe->dev, "Unable to register IIO trigger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = devm_request_threaded_irq(afe->dev, afe->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) iio_trigger_generic_data_rdy_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) NULL, IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) AFE4404_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) afe->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) dev_err(afe->dev, "Unable to request IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) goto disable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) afe4404_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dev_err(afe->dev, "Unable to setup buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) goto unregister_trigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dev_err(afe->dev, "Unable to register IIO device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) goto unregister_triggered_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) unregister_triggered_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) unregister_trigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (afe->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) iio_trigger_unregister(afe->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) disable_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) regulator_disable(afe->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int afe4404_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct afe4404_data *afe = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (afe->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) iio_trigger_unregister(afe->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ret = regulator_disable(afe->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dev_err(afe->dev, "Unable to disable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static const struct i2c_device_id afe4404_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) { "afe4404", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) MODULE_DEVICE_TABLE(i2c, afe4404_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static struct i2c_driver afe4404_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .name = AFE4404_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .of_match_table = afe4404_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .pm = &afe4404_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .probe = afe4404_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .remove = afe4404_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .id_table = afe4404_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) module_i2c_driver(afe4404_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) MODULE_DESCRIPTION("TI AFE4404 Heart Rate Monitor and Pulse Oximeter AFE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) MODULE_LICENSE("GPL v2");