xref: /linux/drivers/iio/adc/rohm-bd79112.c (revision 4f38da1f027ea2c9f01bb71daa7a299c191b6940)
1*edf2fc7bSMatti Vaittinen // SPDX-License-Identifier: GPL-2.0-only
2*edf2fc7bSMatti Vaittinen /*
3*edf2fc7bSMatti Vaittinen  * ROHM ADC driver for BD79112 signal monitoring hub.
4*edf2fc7bSMatti Vaittinen  * Copyright (C) 2025, ROHM Semiconductor.
5*edf2fc7bSMatti Vaittinen  *
6*edf2fc7bSMatti Vaittinen  * SPI communication derived from ad7923.c and ti-ads7950.c
7*edf2fc7bSMatti Vaittinen  */
8*edf2fc7bSMatti Vaittinen 
9*edf2fc7bSMatti Vaittinen #include <linux/array_size.h>
10*edf2fc7bSMatti Vaittinen #include <linux/bitfield.h>
11*edf2fc7bSMatti Vaittinen #include <linux/bitops.h>
12*edf2fc7bSMatti Vaittinen #include <linux/bits.h>
13*edf2fc7bSMatti Vaittinen #include <linux/dev_printk.h>
14*edf2fc7bSMatti Vaittinen #include <linux/err.h>
15*edf2fc7bSMatti Vaittinen #include <linux/errno.h>
16*edf2fc7bSMatti Vaittinen #include <linux/gpio/driver.h>
17*edf2fc7bSMatti Vaittinen #include <linux/mod_devicetable.h>
18*edf2fc7bSMatti Vaittinen #include <linux/module.h>
19*edf2fc7bSMatti Vaittinen #include <linux/regmap.h>
20*edf2fc7bSMatti Vaittinen #include <linux/regulator/consumer.h>
21*edf2fc7bSMatti Vaittinen #include <linux/spi/spi.h>
22*edf2fc7bSMatti Vaittinen #include <linux/types.h>
23*edf2fc7bSMatti Vaittinen #include <asm/byteorder.h>
24*edf2fc7bSMatti Vaittinen 
25*edf2fc7bSMatti Vaittinen #include <linux/iio/adc-helpers.h>
26*edf2fc7bSMatti Vaittinen #include <linux/iio/iio.h>
27*edf2fc7bSMatti Vaittinen 
28*edf2fc7bSMatti Vaittinen #define BD79112_MAX_NUM_CHANNELS 32
29*edf2fc7bSMatti Vaittinen 
30*edf2fc7bSMatti Vaittinen struct bd79112_data {
31*edf2fc7bSMatti Vaittinen 	struct spi_device *spi;
32*edf2fc7bSMatti Vaittinen 	struct regmap *map;
33*edf2fc7bSMatti Vaittinen 	struct device *dev;
34*edf2fc7bSMatti Vaittinen 	struct gpio_chip gc;
35*edf2fc7bSMatti Vaittinen 	unsigned long gpio_valid_mask;
36*edf2fc7bSMatti Vaittinen 	unsigned int vref_mv;
37*edf2fc7bSMatti Vaittinen 	struct spi_transfer read_xfer[2];
38*edf2fc7bSMatti Vaittinen 	struct spi_transfer write_xfer;
39*edf2fc7bSMatti Vaittinen 	struct spi_message read_msg;
40*edf2fc7bSMatti Vaittinen 	struct spi_message write_msg;
41*edf2fc7bSMatti Vaittinen 	/* 16-bit TX, valid data in high byte */
42*edf2fc7bSMatti Vaittinen 	u8 read_tx[2] __aligned(IIO_DMA_MINALIGN);
43*edf2fc7bSMatti Vaittinen 	/* 8-bit address followed by 8-bit data */
44*edf2fc7bSMatti Vaittinen 	u8 reg_write_tx[2];
45*edf2fc7bSMatti Vaittinen 	/* 12-bit of ADC data or 8 bit of reg data */
46*edf2fc7bSMatti Vaittinen 	__be16 read_rx;
47*edf2fc7bSMatti Vaittinen };
48*edf2fc7bSMatti Vaittinen 
49*edf2fc7bSMatti Vaittinen /*
50*edf2fc7bSMatti Vaittinen  * The ADC data is read issuing SPI-command matching the channel number.
51*edf2fc7bSMatti Vaittinen  * We treat this as a register address.
52*edf2fc7bSMatti Vaittinen  */
53*edf2fc7bSMatti Vaittinen #define BD79112_REG_AGIO0A		0x00
54*edf2fc7bSMatti Vaittinen #define BD79112_REG_AGIO15B		0x1f
55*edf2fc7bSMatti Vaittinen 
56*edf2fc7bSMatti Vaittinen /*
57*edf2fc7bSMatti Vaittinen  * ADC STATUS_FLAG appended to ADC data will be set, if the ADC result is being
58*edf2fc7bSMatti Vaittinen  * read for a channel, which input pin is muxed to be a GPIO.
59*edf2fc7bSMatti Vaittinen  */
60*edf2fc7bSMatti Vaittinen #define BD79112_ADC_STATUS_FLAG BIT(14)
61*edf2fc7bSMatti Vaittinen 
62*edf2fc7bSMatti Vaittinen /*
63*edf2fc7bSMatti Vaittinen  * The BD79112 requires "R/W bit" to be set for SPI register (not ADC data)
64*edf2fc7bSMatti Vaittinen  * reads and an "IOSET bit" to be set for read/write operations (which aren't
65*edf2fc7bSMatti Vaittinen  * reading the ADC data).
66*edf2fc7bSMatti Vaittinen  */
67*edf2fc7bSMatti Vaittinen #define BD79112_BIT_RW			BIT(4)
68*edf2fc7bSMatti Vaittinen #define BD79112_BIT_IO			BIT(5)
69*edf2fc7bSMatti Vaittinen 
70*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_VALUE_B8_15	(BD79112_BIT_IO | 0x0)
71*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_VALUE_B0_B7	(BD79112_BIT_IO | 0x1)
72*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_VALUE_A8_15	(BD79112_BIT_IO | 0x2)
73*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_VALUE_A0_A7	(BD79112_BIT_IO | 0x3)
74*edf2fc7bSMatti Vaittinen 
75*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_EN_B7_B15	(BD79112_BIT_IO | 0x4)
76*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_EN_B0_B7	(BD79112_BIT_IO | 0x5)
77*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_EN_A8_A15	(BD79112_BIT_IO | 0x6)
78*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPI_EN_A0_A7	(BD79112_BIT_IO | 0x7)
79*edf2fc7bSMatti Vaittinen 
80*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_EN_B7_B15	(BD79112_BIT_IO | 0x8)
81*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_EN_B0_B7	(BD79112_BIT_IO | 0x9)
82*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_EN_A8_A15	(BD79112_BIT_IO | 0xa)
83*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_EN_A0_A7	(BD79112_BIT_IO | 0xb)
84*edf2fc7bSMatti Vaittinen 
85*edf2fc7bSMatti Vaittinen #define BD79112_NUM_GPIO_EN_REGS	8
86*edf2fc7bSMatti Vaittinen #define BD79112_FIRST_GPIO_EN_REG	BD79112_REG_GPI_EN_B7_B15
87*edf2fc7bSMatti Vaittinen 
88*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_VALUE_B8_15	(BD79112_BIT_IO | 0xc)
89*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_VALUE_B0_B7	(BD79112_BIT_IO | 0xd)
90*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_VALUE_A8_15	(BD79112_BIT_IO | 0xe)
91*edf2fc7bSMatti Vaittinen #define BD79112_REG_GPO_VALUE_A0_A7	(BD79112_BIT_IO | 0xf)
92*edf2fc7bSMatti Vaittinen 
93*edf2fc7bSMatti Vaittinen #define BD79112_REG_MAX BD79112_REG_GPO_VALUE_A0_A7
94*edf2fc7bSMatti Vaittinen 
95*edf2fc7bSMatti Vaittinen /*
96*edf2fc7bSMatti Vaittinen  * Read transaction consists of two 16-bit sequences separated by CSB.
97*edf2fc7bSMatti Vaittinen  * For register read, 'IOSET' bit must be set. For ADC read, IOSET is cleared
98*edf2fc7bSMatti Vaittinen  * and ADDR equals the channel number (0 ... 31).
99*edf2fc7bSMatti Vaittinen  *
100*edf2fc7bSMatti Vaittinen  * First 16-bit sequence, MOSI as below, MISO data ignored:
101*edf2fc7bSMatti Vaittinen  * - SCK: | 1 | 2 |   3   |    4   | 5 .. 8 | 9 .. 16 |
102*edf2fc7bSMatti Vaittinen  * - MOSI:| 0 | 0 | IOSET | RW (1) |  ADDR  |  8'b0   |
103*edf2fc7bSMatti Vaittinen  *
104*edf2fc7bSMatti Vaittinen  * CSB released and re-acquired between these sequences
105*edf2fc7bSMatti Vaittinen  *
106*edf2fc7bSMatti Vaittinen  * Second 16-bit sequence, MISO as below, MOSI data ignored:
107*edf2fc7bSMatti Vaittinen  *   For Register read data is 8 bits:
108*edf2fc7bSMatti Vaittinen  *   - SCK: | 1 .. 8 |   9 .. 16   |
109*edf2fc7bSMatti Vaittinen  *   - MISO:|  8'b0  | 8-bit data  |
110*edf2fc7bSMatti Vaittinen  *
111*edf2fc7bSMatti Vaittinen  *   For ADC read data is 12 bits:
112*edf2fc7bSMatti Vaittinen  *   - SCK: | 1 |      2      | 3  4 |   4 .. 16   |
113*edf2fc7bSMatti Vaittinen  *   - MISO:| 0 | STATUS_FLAG | 2'b0 | 12-bit data |
114*edf2fc7bSMatti Vaittinen  *     The 'STATUS_FLAG' is set if the read input pin was configured as a GPIO.
115*edf2fc7bSMatti Vaittinen  */
116*edf2fc7bSMatti Vaittinen static int bd79112_reg_read(void *context, unsigned int reg, unsigned int *val)
117*edf2fc7bSMatti Vaittinen {
118*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = context;
119*edf2fc7bSMatti Vaittinen 	int ret;
120*edf2fc7bSMatti Vaittinen 
121*edf2fc7bSMatti Vaittinen 	if (reg & BD79112_BIT_IO)
122*edf2fc7bSMatti Vaittinen 		reg |= BD79112_BIT_RW;
123*edf2fc7bSMatti Vaittinen 
124*edf2fc7bSMatti Vaittinen 	data->read_tx[0] = reg;
125*edf2fc7bSMatti Vaittinen 
126*edf2fc7bSMatti Vaittinen 	ret = spi_sync(data->spi, &data->read_msg);
127*edf2fc7bSMatti Vaittinen 	if (!ret)
128*edf2fc7bSMatti Vaittinen 		*val = be16_to_cpu(data->read_rx);
129*edf2fc7bSMatti Vaittinen 
130*edf2fc7bSMatti Vaittinen 	return ret;
131*edf2fc7bSMatti Vaittinen }
132*edf2fc7bSMatti Vaittinen 
133*edf2fc7bSMatti Vaittinen /*
134*edf2fc7bSMatti Vaittinen  * Write, single 16-bit sequence (broken down below):
135*edf2fc7bSMatti Vaittinen  *
136*edf2fc7bSMatti Vaittinen  * First 8-bit, MOSI as below, MISO data ignored:
137*edf2fc7bSMatti Vaittinen  * - SCK: | 1 | 2 | 3   | 4     | 5 .. 8 |
138*edf2fc7bSMatti Vaittinen  * - MOSI:| 0 | 0 |IOSET| RW(0) | ADDR   |
139*edf2fc7bSMatti Vaittinen  *
140*edf2fc7bSMatti Vaittinen  * Last 8 SCK cycles (b8 ... b15), MISO contains register data, MOSI ignored.
141*edf2fc7bSMatti Vaittinen  * - SCK: | 9 .. 16 |
142*edf2fc7bSMatti Vaittinen  * - MISO:|  data   |
143*edf2fc7bSMatti Vaittinen  */
144*edf2fc7bSMatti Vaittinen static int bd79112_reg_write(void *context, unsigned int reg, unsigned int val)
145*edf2fc7bSMatti Vaittinen {
146*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = context;
147*edf2fc7bSMatti Vaittinen 
148*edf2fc7bSMatti Vaittinen 	data->reg_write_tx[0] = reg;
149*edf2fc7bSMatti Vaittinen 	data->reg_write_tx[1] = val;
150*edf2fc7bSMatti Vaittinen 
151*edf2fc7bSMatti Vaittinen 	return spi_sync(data->spi, &data->write_msg);
152*edf2fc7bSMatti Vaittinen }
153*edf2fc7bSMatti Vaittinen 
154*edf2fc7bSMatti Vaittinen static int _get_gpio_reg(unsigned int offset, unsigned int base)
155*edf2fc7bSMatti Vaittinen {
156*edf2fc7bSMatti Vaittinen 	int regoffset = offset / 8;
157*edf2fc7bSMatti Vaittinen 
158*edf2fc7bSMatti Vaittinen 	if (offset > 31)
159*edf2fc7bSMatti Vaittinen 		return -EINVAL;
160*edf2fc7bSMatti Vaittinen 
161*edf2fc7bSMatti Vaittinen 	return base - regoffset;
162*edf2fc7bSMatti Vaittinen }
163*edf2fc7bSMatti Vaittinen 
164*edf2fc7bSMatti Vaittinen #define GET_GPIO_BIT(offset) BIT((offset) % 8)
165*edf2fc7bSMatti Vaittinen #define GET_GPO_EN_REG(offset)  _get_gpio_reg((offset), BD79112_REG_GPO_EN_A0_A7)
166*edf2fc7bSMatti Vaittinen #define GET_GPI_EN_REG(offset)  _get_gpio_reg((offset), BD79112_REG_GPI_EN_A0_A7)
167*edf2fc7bSMatti Vaittinen #define GET_GPO_VAL_REG(offset)  _get_gpio_reg((offset), BD79112_REG_GPO_VALUE_A0_A7)
168*edf2fc7bSMatti Vaittinen #define GET_GPI_VAL_REG(offset)  _get_gpio_reg((offset), BD79112_REG_GPI_VALUE_A0_A7)
169*edf2fc7bSMatti Vaittinen 
170*edf2fc7bSMatti Vaittinen static const struct regmap_range bd71815_volatile_ro_ranges[] = {
171*edf2fc7bSMatti Vaittinen 	{
172*edf2fc7bSMatti Vaittinen 		/* Read ADC data */
173*edf2fc7bSMatti Vaittinen 		.range_min = BD79112_REG_AGIO0A,
174*edf2fc7bSMatti Vaittinen 		.range_max = BD79112_REG_AGIO15B,
175*edf2fc7bSMatti Vaittinen 	}, {
176*edf2fc7bSMatti Vaittinen 		/* GPI state */
177*edf2fc7bSMatti Vaittinen 		.range_min = BD79112_REG_GPI_VALUE_B8_15,
178*edf2fc7bSMatti Vaittinen 		.range_max = BD79112_REG_GPI_VALUE_A0_A7,
179*edf2fc7bSMatti Vaittinen 	},
180*edf2fc7bSMatti Vaittinen };
181*edf2fc7bSMatti Vaittinen 
182*edf2fc7bSMatti Vaittinen static const struct regmap_access_table bd79112_volatile_regs = {
183*edf2fc7bSMatti Vaittinen 	.yes_ranges = &bd71815_volatile_ro_ranges[0],
184*edf2fc7bSMatti Vaittinen 	.n_yes_ranges = ARRAY_SIZE(bd71815_volatile_ro_ranges),
185*edf2fc7bSMatti Vaittinen };
186*edf2fc7bSMatti Vaittinen 
187*edf2fc7bSMatti Vaittinen static const struct regmap_access_table bd79112_ro_regs = {
188*edf2fc7bSMatti Vaittinen 	.no_ranges = &bd71815_volatile_ro_ranges[0],
189*edf2fc7bSMatti Vaittinen 	.n_no_ranges = ARRAY_SIZE(bd71815_volatile_ro_ranges),
190*edf2fc7bSMatti Vaittinen };
191*edf2fc7bSMatti Vaittinen 
192*edf2fc7bSMatti Vaittinen static const struct regmap_config bd79112_regmap = {
193*edf2fc7bSMatti Vaittinen 	.reg_read = bd79112_reg_read,
194*edf2fc7bSMatti Vaittinen 	.reg_write = bd79112_reg_write,
195*edf2fc7bSMatti Vaittinen 	.volatile_table = &bd79112_volatile_regs,
196*edf2fc7bSMatti Vaittinen 	.wr_table = &bd79112_ro_regs,
197*edf2fc7bSMatti Vaittinen 	.cache_type = REGCACHE_MAPLE,
198*edf2fc7bSMatti Vaittinen 	.max_register = BD79112_REG_MAX,
199*edf2fc7bSMatti Vaittinen };
200*edf2fc7bSMatti Vaittinen 
201*edf2fc7bSMatti Vaittinen static int bd79112_read_raw(struct iio_dev *indio_dev,
202*edf2fc7bSMatti Vaittinen 			    struct iio_chan_spec const *chan, int *val,
203*edf2fc7bSMatti Vaittinen 			    int *val2, long m)
204*edf2fc7bSMatti Vaittinen {
205*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = iio_priv(indio_dev);
206*edf2fc7bSMatti Vaittinen 	int ret;
207*edf2fc7bSMatti Vaittinen 
208*edf2fc7bSMatti Vaittinen 	switch (m) {
209*edf2fc7bSMatti Vaittinen 	case IIO_CHAN_INFO_RAW:
210*edf2fc7bSMatti Vaittinen 		ret = regmap_read(data->map, chan->channel, val);
211*edf2fc7bSMatti Vaittinen 		if (ret < 0)
212*edf2fc7bSMatti Vaittinen 			return ret;
213*edf2fc7bSMatti Vaittinen 
214*edf2fc7bSMatti Vaittinen 		return IIO_VAL_INT;
215*edf2fc7bSMatti Vaittinen 
216*edf2fc7bSMatti Vaittinen 	case IIO_CHAN_INFO_SCALE:
217*edf2fc7bSMatti Vaittinen 		*val = data->vref_mv;
218*edf2fc7bSMatti Vaittinen 		*val2 = 12;
219*edf2fc7bSMatti Vaittinen 
220*edf2fc7bSMatti Vaittinen 		return IIO_VAL_FRACTIONAL_LOG2;
221*edf2fc7bSMatti Vaittinen 	default:
222*edf2fc7bSMatti Vaittinen 		return -EINVAL;
223*edf2fc7bSMatti Vaittinen 	}
224*edf2fc7bSMatti Vaittinen }
225*edf2fc7bSMatti Vaittinen 
226*edf2fc7bSMatti Vaittinen static const struct iio_info bd79112_info = {
227*edf2fc7bSMatti Vaittinen 	.read_raw = bd79112_read_raw,
228*edf2fc7bSMatti Vaittinen };
229*edf2fc7bSMatti Vaittinen 
230*edf2fc7bSMatti Vaittinen static const struct iio_chan_spec bd79112_chan_template = {
231*edf2fc7bSMatti Vaittinen 	.type = IIO_VOLTAGE,
232*edf2fc7bSMatti Vaittinen 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
233*edf2fc7bSMatti Vaittinen 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
234*edf2fc7bSMatti Vaittinen 	.indexed = 1,
235*edf2fc7bSMatti Vaittinen };
236*edf2fc7bSMatti Vaittinen 
237*edf2fc7bSMatti Vaittinen static int bd79112_gpio_init_valid_mask(struct gpio_chip *gc,
238*edf2fc7bSMatti Vaittinen 					unsigned long *valid_mask,
239*edf2fc7bSMatti Vaittinen 					unsigned int ngpios)
240*edf2fc7bSMatti Vaittinen {
241*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
242*edf2fc7bSMatti Vaittinen 
243*edf2fc7bSMatti Vaittinen 	*valid_mask = data->gpio_valid_mask;
244*edf2fc7bSMatti Vaittinen 
245*edf2fc7bSMatti Vaittinen 	return 0;
246*edf2fc7bSMatti Vaittinen }
247*edf2fc7bSMatti Vaittinen 
248*edf2fc7bSMatti Vaittinen static int bd79112_gpio_dir_get(struct gpio_chip *gc, unsigned int offset)
249*edf2fc7bSMatti Vaittinen {
250*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
251*edf2fc7bSMatti Vaittinen 	unsigned int reg, bit, val;
252*edf2fc7bSMatti Vaittinen 	int ret;
253*edf2fc7bSMatti Vaittinen 
254*edf2fc7bSMatti Vaittinen 	bit = GET_GPIO_BIT(offset);
255*edf2fc7bSMatti Vaittinen 	reg = GET_GPO_EN_REG(offset);
256*edf2fc7bSMatti Vaittinen 
257*edf2fc7bSMatti Vaittinen 	ret = regmap_read(data->map, reg, &val);
258*edf2fc7bSMatti Vaittinen 	if (ret)
259*edf2fc7bSMatti Vaittinen 		return ret;
260*edf2fc7bSMatti Vaittinen 
261*edf2fc7bSMatti Vaittinen 	if (bit & val)
262*edf2fc7bSMatti Vaittinen 		return GPIO_LINE_DIRECTION_OUT;
263*edf2fc7bSMatti Vaittinen 
264*edf2fc7bSMatti Vaittinen 	reg = GET_GPI_EN_REG(offset);
265*edf2fc7bSMatti Vaittinen 	ret = regmap_read(data->map, reg, &val);
266*edf2fc7bSMatti Vaittinen 	if (ret)
267*edf2fc7bSMatti Vaittinen 		return ret;
268*edf2fc7bSMatti Vaittinen 
269*edf2fc7bSMatti Vaittinen 	if (bit & val)
270*edf2fc7bSMatti Vaittinen 		return GPIO_LINE_DIRECTION_IN;
271*edf2fc7bSMatti Vaittinen 
272*edf2fc7bSMatti Vaittinen 	/*
273*edf2fc7bSMatti Vaittinen 	 * Ouch. Seems the pin is ADC input - shouldn't happen as changing mux
274*edf2fc7bSMatti Vaittinen 	 * at runtime is not supported and non GPIO pins should be invalidated
275*edf2fc7bSMatti Vaittinen 	 * by the valid_mask at probe. Maybe someone wrote a register bypassing
276*edf2fc7bSMatti Vaittinen 	 * the driver?
277*edf2fc7bSMatti Vaittinen 	 */
278*edf2fc7bSMatti Vaittinen 	dev_err(data->dev, "Pin not a GPIO\n");
279*edf2fc7bSMatti Vaittinen 
280*edf2fc7bSMatti Vaittinen 	return -EINVAL;
281*edf2fc7bSMatti Vaittinen }
282*edf2fc7bSMatti Vaittinen 
283*edf2fc7bSMatti Vaittinen static int bd79112_gpio_get(struct gpio_chip *gc, unsigned int offset)
284*edf2fc7bSMatti Vaittinen {
285*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
286*edf2fc7bSMatti Vaittinen 	unsigned int reg, bit, val;
287*edf2fc7bSMatti Vaittinen 	int ret;
288*edf2fc7bSMatti Vaittinen 
289*edf2fc7bSMatti Vaittinen 	bit = GET_GPIO_BIT(offset);
290*edf2fc7bSMatti Vaittinen 	reg = GET_GPI_VAL_REG(offset);
291*edf2fc7bSMatti Vaittinen 
292*edf2fc7bSMatti Vaittinen 	ret = regmap_read(data->map, reg, &val);
293*edf2fc7bSMatti Vaittinen 	if (ret)
294*edf2fc7bSMatti Vaittinen 		return ret;
295*edf2fc7bSMatti Vaittinen 
296*edf2fc7bSMatti Vaittinen 	return !!(val & bit);
297*edf2fc7bSMatti Vaittinen }
298*edf2fc7bSMatti Vaittinen 
299*edf2fc7bSMatti Vaittinen static int bd79112_gpio_set(struct gpio_chip *gc, unsigned int offset,
300*edf2fc7bSMatti Vaittinen 			    int value)
301*edf2fc7bSMatti Vaittinen {
302*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
303*edf2fc7bSMatti Vaittinen 	unsigned int reg, bit;
304*edf2fc7bSMatti Vaittinen 
305*edf2fc7bSMatti Vaittinen 	bit = GET_GPIO_BIT(offset);
306*edf2fc7bSMatti Vaittinen 	reg = GET_GPO_VAL_REG(offset);
307*edf2fc7bSMatti Vaittinen 
308*edf2fc7bSMatti Vaittinen 	return regmap_assign_bits(data->map, reg, bit, value);
309*edf2fc7bSMatti Vaittinen }
310*edf2fc7bSMatti Vaittinen 
311*edf2fc7bSMatti Vaittinen static int bd79112_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
312*edf2fc7bSMatti Vaittinen 				     unsigned long *bits)
313*edf2fc7bSMatti Vaittinen {
314*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
315*edf2fc7bSMatti Vaittinen 	unsigned long i, bank_mask;
316*edf2fc7bSMatti Vaittinen 
317*edf2fc7bSMatti Vaittinen 	for_each_set_clump8(i, bank_mask, mask, gc->ngpio) {
318*edf2fc7bSMatti Vaittinen 		unsigned long bank_bits;
319*edf2fc7bSMatti Vaittinen 		unsigned int reg;
320*edf2fc7bSMatti Vaittinen 		int ret;
321*edf2fc7bSMatti Vaittinen 
322*edf2fc7bSMatti Vaittinen 		bank_bits = bitmap_get_value8(bits, i);
323*edf2fc7bSMatti Vaittinen 		reg = BD79112_REG_GPO_VALUE_A0_A7 - i / 8;
324*edf2fc7bSMatti Vaittinen 		ret = regmap_update_bits(data->map, reg, bank_mask, bank_bits);
325*edf2fc7bSMatti Vaittinen 		if (ret)
326*edf2fc7bSMatti Vaittinen 			return ret;
327*edf2fc7bSMatti Vaittinen 	}
328*edf2fc7bSMatti Vaittinen 
329*edf2fc7bSMatti Vaittinen 	return 0;
330*edf2fc7bSMatti Vaittinen }
331*edf2fc7bSMatti Vaittinen 
332*edf2fc7bSMatti Vaittinen static int bd79112_gpio_dir_set(struct bd79112_data *data, unsigned int offset,
333*edf2fc7bSMatti Vaittinen 				int dir)
334*edf2fc7bSMatti Vaittinen {
335*edf2fc7bSMatti Vaittinen 	unsigned int gpi_reg, gpo_reg, bit;
336*edf2fc7bSMatti Vaittinen 	int ret;
337*edf2fc7bSMatti Vaittinen 
338*edf2fc7bSMatti Vaittinen 	bit = GET_GPIO_BIT(offset);
339*edf2fc7bSMatti Vaittinen 	gpi_reg = GET_GPI_EN_REG(offset);
340*edf2fc7bSMatti Vaittinen 	gpo_reg =  GET_GPO_EN_REG(offset);
341*edf2fc7bSMatti Vaittinen 
342*edf2fc7bSMatti Vaittinen 	if (dir == GPIO_LINE_DIRECTION_OUT) {
343*edf2fc7bSMatti Vaittinen 		ret = regmap_clear_bits(data->map, gpi_reg, bit);
344*edf2fc7bSMatti Vaittinen 		if (ret)
345*edf2fc7bSMatti Vaittinen 			return ret;
346*edf2fc7bSMatti Vaittinen 
347*edf2fc7bSMatti Vaittinen 		return regmap_set_bits(data->map, gpo_reg, bit);
348*edf2fc7bSMatti Vaittinen 	}
349*edf2fc7bSMatti Vaittinen 
350*edf2fc7bSMatti Vaittinen 	ret = regmap_set_bits(data->map, gpi_reg, bit);
351*edf2fc7bSMatti Vaittinen 	if (ret)
352*edf2fc7bSMatti Vaittinen 		return ret;
353*edf2fc7bSMatti Vaittinen 
354*edf2fc7bSMatti Vaittinen 	return regmap_clear_bits(data->map, gpo_reg, bit);
355*edf2fc7bSMatti Vaittinen }
356*edf2fc7bSMatti Vaittinen 
357*edf2fc7bSMatti Vaittinen static int bd79112_gpio_input(struct gpio_chip *gc, unsigned int offset)
358*edf2fc7bSMatti Vaittinen {
359*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
360*edf2fc7bSMatti Vaittinen 
361*edf2fc7bSMatti Vaittinen 	return bd79112_gpio_dir_set(data, offset, GPIO_LINE_DIRECTION_IN);
362*edf2fc7bSMatti Vaittinen }
363*edf2fc7bSMatti Vaittinen 
364*edf2fc7bSMatti Vaittinen static int bd79112_gpio_output(struct gpio_chip *gc, unsigned int offset,
365*edf2fc7bSMatti Vaittinen 			       int value)
366*edf2fc7bSMatti Vaittinen {
367*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data = gpiochip_get_data(gc);
368*edf2fc7bSMatti Vaittinen 	int ret;
369*edf2fc7bSMatti Vaittinen 
370*edf2fc7bSMatti Vaittinen 	ret = bd79112_gpio_set(gc, offset, value);
371*edf2fc7bSMatti Vaittinen 	if (ret)
372*edf2fc7bSMatti Vaittinen 		return ret;
373*edf2fc7bSMatti Vaittinen 
374*edf2fc7bSMatti Vaittinen 	return bd79112_gpio_dir_set(data, offset, GPIO_LINE_DIRECTION_OUT);
375*edf2fc7bSMatti Vaittinen }
376*edf2fc7bSMatti Vaittinen 
377*edf2fc7bSMatti Vaittinen static const struct gpio_chip bd79112_gpio_chip = {
378*edf2fc7bSMatti Vaittinen 	.label			= "bd79112-gpio",
379*edf2fc7bSMatti Vaittinen 	.get_direction		= bd79112_gpio_dir_get,
380*edf2fc7bSMatti Vaittinen 	.direction_input	= bd79112_gpio_input,
381*edf2fc7bSMatti Vaittinen 	.direction_output	= bd79112_gpio_output,
382*edf2fc7bSMatti Vaittinen 	.get			= bd79112_gpio_get,
383*edf2fc7bSMatti Vaittinen 	.set			= bd79112_gpio_set,
384*edf2fc7bSMatti Vaittinen 	.set_multiple		= bd79112_gpio_set_multiple,
385*edf2fc7bSMatti Vaittinen 	.init_valid_mask	= bd79112_gpio_init_valid_mask,
386*edf2fc7bSMatti Vaittinen 	.can_sleep		= true,
387*edf2fc7bSMatti Vaittinen 	.ngpio			= 32,
388*edf2fc7bSMatti Vaittinen 	.base			= -1,
389*edf2fc7bSMatti Vaittinen };
390*edf2fc7bSMatti Vaittinen 
391*edf2fc7bSMatti Vaittinen static unsigned int bd79112_get_gpio_pins(const struct iio_chan_spec *cs, int num_channels)
392*edf2fc7bSMatti Vaittinen {
393*edf2fc7bSMatti Vaittinen 	unsigned int i, gpio_channels;
394*edf2fc7bSMatti Vaittinen 
395*edf2fc7bSMatti Vaittinen 	/*
396*edf2fc7bSMatti Vaittinen 	 * Let's initialize the mux config to say that all 32 channels are
397*edf2fc7bSMatti Vaittinen 	 * GPIOs. Then we can just loop through the iio_chan_spec and clear the
398*edf2fc7bSMatti Vaittinen 	 * bits for found ADC channels.
399*edf2fc7bSMatti Vaittinen 	 */
400*edf2fc7bSMatti Vaittinen 	gpio_channels = GENMASK(31, 0);
401*edf2fc7bSMatti Vaittinen 	for (i = 0; i < num_channels; i++)
402*edf2fc7bSMatti Vaittinen 		gpio_channels &= ~BIT(cs[i].channel);
403*edf2fc7bSMatti Vaittinen 
404*edf2fc7bSMatti Vaittinen 	return gpio_channels;
405*edf2fc7bSMatti Vaittinen }
406*edf2fc7bSMatti Vaittinen 
407*edf2fc7bSMatti Vaittinen /* ADC channels as named in the data-sheet */
408*edf2fc7bSMatti Vaittinen static const char * const bd79112_chan_names[] = {
409*edf2fc7bSMatti Vaittinen 	"AGIO0A", "AGIO1A", "AGIO2A", "AGIO3A",		/* 0 - 3 */
410*edf2fc7bSMatti Vaittinen 	"AGIO4A", "AGIO5A", "AGIO6A", "AGIO7A",		/* 4 - 7 */
411*edf2fc7bSMatti Vaittinen 	"AGIO8A", "AGIO9A", "AGIO10A", "AGIO11A",	/* 8 - 11 */
412*edf2fc7bSMatti Vaittinen 	"AGIO12A", "AGIO13A", "AGIO14A", "AGIO15A",	/* 12 - 15 */
413*edf2fc7bSMatti Vaittinen 	"AGIO0B", "AGIO1B", "AGIO2B", "AGIO3B",		/* 16 - 19 */
414*edf2fc7bSMatti Vaittinen 	"AGIO4B", "AGIO5B", "AGIO6B", "AGIO7B",		/* 20 - 23 */
415*edf2fc7bSMatti Vaittinen 	"AGIO8B", "AGIO9B", "AGIO10B", "AGIO11B",	/* 24 - 27 */
416*edf2fc7bSMatti Vaittinen 	"AGIO12B", "AGIO13B", "AGIO14B", "AGIO15B",	/* 28 - 31 */
417*edf2fc7bSMatti Vaittinen };
418*edf2fc7bSMatti Vaittinen 
419*edf2fc7bSMatti Vaittinen static int bd79112_probe(struct spi_device *spi)
420*edf2fc7bSMatti Vaittinen {
421*edf2fc7bSMatti Vaittinen 	struct bd79112_data *data;
422*edf2fc7bSMatti Vaittinen 	struct iio_dev *iio_dev;
423*edf2fc7bSMatti Vaittinen 	struct iio_chan_spec *cs;
424*edf2fc7bSMatti Vaittinen 	struct device *dev = &spi->dev;
425*edf2fc7bSMatti Vaittinen 	unsigned long gpio_pins, pin;
426*edf2fc7bSMatti Vaittinen 	unsigned int i;
427*edf2fc7bSMatti Vaittinen 	int ret;
428*edf2fc7bSMatti Vaittinen 
429*edf2fc7bSMatti Vaittinen 	iio_dev = devm_iio_device_alloc(dev, sizeof(*data));
430*edf2fc7bSMatti Vaittinen 	if (!iio_dev)
431*edf2fc7bSMatti Vaittinen 		return -ENOMEM;
432*edf2fc7bSMatti Vaittinen 
433*edf2fc7bSMatti Vaittinen 	data = iio_priv(iio_dev);
434*edf2fc7bSMatti Vaittinen 	data->spi = spi;
435*edf2fc7bSMatti Vaittinen 	data->dev = dev;
436*edf2fc7bSMatti Vaittinen 	data->map = devm_regmap_init(dev, NULL, data, &bd79112_regmap);
437*edf2fc7bSMatti Vaittinen 	if (IS_ERR(data->map))
438*edf2fc7bSMatti Vaittinen 		return dev_err_probe(dev, PTR_ERR(data->map),
439*edf2fc7bSMatti Vaittinen 				     "Failed to initialize Regmap\n");
440*edf2fc7bSMatti Vaittinen 
441*edf2fc7bSMatti Vaittinen 	ret = devm_regulator_get_enable_read_voltage(dev, "vdd");
442*edf2fc7bSMatti Vaittinen 	if (ret < 0)
443*edf2fc7bSMatti Vaittinen 		return dev_err_probe(dev, ret, "Failed to get the Vdd\n");
444*edf2fc7bSMatti Vaittinen 
445*edf2fc7bSMatti Vaittinen 	data->vref_mv = ret / 1000;
446*edf2fc7bSMatti Vaittinen 
447*edf2fc7bSMatti Vaittinen 	ret = devm_regulator_get_enable(dev, "iovdd");
448*edf2fc7bSMatti Vaittinen 	if (ret < 0)
449*edf2fc7bSMatti Vaittinen 		return dev_err_probe(dev, ret, "Failed to enable I/O voltage\n");
450*edf2fc7bSMatti Vaittinen 
451*edf2fc7bSMatti Vaittinen 	data->read_xfer[0].tx_buf = &data->read_tx[0];
452*edf2fc7bSMatti Vaittinen 	data->read_xfer[0].len = sizeof(data->read_tx);
453*edf2fc7bSMatti Vaittinen 	data->read_xfer[0].cs_change = 1;
454*edf2fc7bSMatti Vaittinen 	data->read_xfer[1].rx_buf = &data->read_rx;
455*edf2fc7bSMatti Vaittinen 	data->read_xfer[1].len = sizeof(data->read_rx);
456*edf2fc7bSMatti Vaittinen 	spi_message_init_with_transfers(&data->read_msg, data->read_xfer, 2);
457*edf2fc7bSMatti Vaittinen 	ret = devm_spi_optimize_message(dev, spi, &data->read_msg);
458*edf2fc7bSMatti Vaittinen 	if (ret < 0)
459*edf2fc7bSMatti Vaittinen 		return dev_err_probe(dev, ret,
460*edf2fc7bSMatti Vaittinen 				     "Failed to optimize SPI read message\n");
461*edf2fc7bSMatti Vaittinen 
462*edf2fc7bSMatti Vaittinen 	data->write_xfer.tx_buf = &data->reg_write_tx[0];
463*edf2fc7bSMatti Vaittinen 	data->write_xfer.len = sizeof(data->reg_write_tx);
464*edf2fc7bSMatti Vaittinen 	spi_message_init_with_transfers(&data->write_msg, &data->write_xfer, 1);
465*edf2fc7bSMatti Vaittinen 	ret = devm_spi_optimize_message(dev, spi, &data->write_msg);
466*edf2fc7bSMatti Vaittinen 	if (ret < 0)
467*edf2fc7bSMatti Vaittinen 		return dev_err_probe(dev, ret,
468*edf2fc7bSMatti Vaittinen 				     "Failed to optimize SPI write message\n");
469*edf2fc7bSMatti Vaittinen 
470*edf2fc7bSMatti Vaittinen 	ret = devm_iio_adc_device_alloc_chaninfo_se(dev, &bd79112_chan_template,
471*edf2fc7bSMatti Vaittinen 						    BD79112_MAX_NUM_CHANNELS - 1,
472*edf2fc7bSMatti Vaittinen 						    &cs);
473*edf2fc7bSMatti Vaittinen 
474*edf2fc7bSMatti Vaittinen 	/* Register all pins as GPIOs if there are no ADC channels */
475*edf2fc7bSMatti Vaittinen 	if (ret == -ENOENT)
476*edf2fc7bSMatti Vaittinen 		goto register_gpios;
477*edf2fc7bSMatti Vaittinen 
478*edf2fc7bSMatti Vaittinen 	if (ret < 0)
479*edf2fc7bSMatti Vaittinen 		return ret;
480*edf2fc7bSMatti Vaittinen 
481*edf2fc7bSMatti Vaittinen 	iio_dev->num_channels = ret;
482*edf2fc7bSMatti Vaittinen 	iio_dev->channels = cs;
483*edf2fc7bSMatti Vaittinen 
484*edf2fc7bSMatti Vaittinen 	for (i = 0; i < iio_dev->num_channels; i++)
485*edf2fc7bSMatti Vaittinen 		cs[i].datasheet_name = bd79112_chan_names[cs[i].channel];
486*edf2fc7bSMatti Vaittinen 
487*edf2fc7bSMatti Vaittinen 	iio_dev->info = &bd79112_info;
488*edf2fc7bSMatti Vaittinen 	iio_dev->name = "bd79112";
489*edf2fc7bSMatti Vaittinen 	iio_dev->modes = INDIO_DIRECT_MODE;
490*edf2fc7bSMatti Vaittinen 
491*edf2fc7bSMatti Vaittinen 	/*
492*edf2fc7bSMatti Vaittinen 	 * Ensure all channels are ADCs. This allows us to register the IIO
493*edf2fc7bSMatti Vaittinen 	 * device early (before checking which pins are to be used for GPIO)
494*edf2fc7bSMatti Vaittinen 	 * without having to worry about some pins being initially used for
495*edf2fc7bSMatti Vaittinen 	 * GPIO.
496*edf2fc7bSMatti Vaittinen 	 */
497*edf2fc7bSMatti Vaittinen 	for (i = 0; i < BD79112_NUM_GPIO_EN_REGS; i++) {
498*edf2fc7bSMatti Vaittinen 		ret = regmap_write(data->map, BD79112_FIRST_GPIO_EN_REG + i, 0);
499*edf2fc7bSMatti Vaittinen 		if (ret)
500*edf2fc7bSMatti Vaittinen 			return dev_err_probe(dev, ret,
501*edf2fc7bSMatti Vaittinen 					     "Failed to initialize channels\n");
502*edf2fc7bSMatti Vaittinen 	}
503*edf2fc7bSMatti Vaittinen 
504*edf2fc7bSMatti Vaittinen 	ret = devm_iio_device_register(data->dev, iio_dev);
505*edf2fc7bSMatti Vaittinen 	if (ret)
506*edf2fc7bSMatti Vaittinen 		return dev_err_probe(data->dev, ret, "Failed to register ADC\n");
507*edf2fc7bSMatti Vaittinen 
508*edf2fc7bSMatti Vaittinen register_gpios:
509*edf2fc7bSMatti Vaittinen 	gpio_pins = bd79112_get_gpio_pins(iio_dev->channels,
510*edf2fc7bSMatti Vaittinen 					  iio_dev->num_channels);
511*edf2fc7bSMatti Vaittinen 
512*edf2fc7bSMatti Vaittinen 	/* If all channels are reserved for ADC, then we're done. */
513*edf2fc7bSMatti Vaittinen 	if (!gpio_pins)
514*edf2fc7bSMatti Vaittinen 		return 0;
515*edf2fc7bSMatti Vaittinen 
516*edf2fc7bSMatti Vaittinen 	/* Default all the GPIO pins to GPI */
517*edf2fc7bSMatti Vaittinen 	for_each_set_bit(pin, &gpio_pins, BD79112_MAX_NUM_CHANNELS) {
518*edf2fc7bSMatti Vaittinen 		ret = bd79112_gpio_dir_set(data, pin, GPIO_LINE_DIRECTION_IN);
519*edf2fc7bSMatti Vaittinen 		if (ret)
520*edf2fc7bSMatti Vaittinen 			return dev_err_probe(dev, ret,
521*edf2fc7bSMatti Vaittinen 					     "Failed to mark pin as GPI\n");
522*edf2fc7bSMatti Vaittinen 	}
523*edf2fc7bSMatti Vaittinen 
524*edf2fc7bSMatti Vaittinen 	data->gpio_valid_mask = gpio_pins;
525*edf2fc7bSMatti Vaittinen 	data->gc = bd79112_gpio_chip;
526*edf2fc7bSMatti Vaittinen 	data->gc.parent = dev;
527*edf2fc7bSMatti Vaittinen 
528*edf2fc7bSMatti Vaittinen 	return devm_gpiochip_add_data(dev, &data->gc, data);
529*edf2fc7bSMatti Vaittinen }
530*edf2fc7bSMatti Vaittinen 
531*edf2fc7bSMatti Vaittinen static const struct of_device_id bd79112_of_match[] = {
532*edf2fc7bSMatti Vaittinen 	{ .compatible = "rohm,bd79112" },
533*edf2fc7bSMatti Vaittinen 	{ }
534*edf2fc7bSMatti Vaittinen };
535*edf2fc7bSMatti Vaittinen MODULE_DEVICE_TABLE(of, bd79112_of_match);
536*edf2fc7bSMatti Vaittinen 
537*edf2fc7bSMatti Vaittinen static const struct spi_device_id bd79112_id[] = {
538*edf2fc7bSMatti Vaittinen 	{ "bd79112" },
539*edf2fc7bSMatti Vaittinen 	{ }
540*edf2fc7bSMatti Vaittinen };
541*edf2fc7bSMatti Vaittinen MODULE_DEVICE_TABLE(spi, bd79112_id);
542*edf2fc7bSMatti Vaittinen 
543*edf2fc7bSMatti Vaittinen static struct spi_driver bd79112_driver = {
544*edf2fc7bSMatti Vaittinen 	.driver = {
545*edf2fc7bSMatti Vaittinen 		.name = "bd79112",
546*edf2fc7bSMatti Vaittinen 		.of_match_table = bd79112_of_match,
547*edf2fc7bSMatti Vaittinen 	},
548*edf2fc7bSMatti Vaittinen 	.probe = bd79112_probe,
549*edf2fc7bSMatti Vaittinen 	.id_table = bd79112_id,
550*edf2fc7bSMatti Vaittinen };
551*edf2fc7bSMatti Vaittinen module_spi_driver(bd79112_driver);
552*edf2fc7bSMatti Vaittinen 
553*edf2fc7bSMatti Vaittinen MODULE_AUTHOR("Matti Vaittinen <mazziesaccount@gmail.com>");
554*edf2fc7bSMatti Vaittinen MODULE_DESCRIPTION("Driver for ROHM BD79112 ADC/GPIO");
555*edf2fc7bSMatti Vaittinen MODULE_LICENSE("GPL");
556*edf2fc7bSMatti Vaittinen MODULE_IMPORT_NS("IIO_DRIVER");
557