1 // SPDX-License-Identifier: GPL-2.0+
3 * Analog Devices AD5272 digital potentiometer driver
4 * Copyright (C) 2018 Phil Reid <preid@electromag.com.au>
6 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/AD5272_5274.pdf
8 * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address
9 * ad5272 1 1024 20, 50, 100 01011xx
10 * ad5274 1 256 20, 100 01011xx
13 #include <linux/delay.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/i2c.h>
16 #include <linux/iio/iio.h>
17 #include <linux/module.h>
18 #include <linux/mod_devicetable.h>
20 #define AD5272_RDAC_WR 1
21 #define AD5272_RDAC_RD 2
22 #define AD5272_RESET 4
25 #define AD5272_RDAC_WR_EN BIT(1)
41 static const struct ad5272_cfg ad5272_cfg
[] = {
42 [AD5272_020
] = { .max_pos
= 1024, .kohms
= 20 },
43 [AD5272_050
] = { .max_pos
= 1024, .kohms
= 50 },
44 [AD5272_100
] = { .max_pos
= 1024, .kohms
= 100 },
45 [AD5274_020
] = { .max_pos
= 256, .kohms
= 20, .shift
= 2 },
46 [AD5274_100
] = { .max_pos
= 256, .kohms
= 100, .shift
= 2 },
50 struct i2c_client
*client
;
52 const struct ad5272_cfg
*cfg
;
53 u8 buf
[2] __aligned(IIO_DMA_MINALIGN
);
56 static const struct iio_chan_spec ad5272_channel
= {
57 .type
= IIO_RESISTANCE
,
59 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
60 .info_mask_shared_by_type
= BIT(IIO_CHAN_INFO_SCALE
),
63 static int ad5272_write(struct ad5272_data
*data
, int reg
, int val
)
67 data
->buf
[0] = (reg
<< 2) | ((val
>> 8) & 0x3);
68 data
->buf
[1] = (u8
)val
;
70 mutex_lock(&data
->lock
);
71 ret
= i2c_master_send(data
->client
, data
->buf
, sizeof(data
->buf
));
72 mutex_unlock(&data
->lock
);
73 return ret
< 0 ? ret
: 0;
76 static int ad5272_read(struct ad5272_data
*data
, int reg
, int *val
)
80 data
->buf
[0] = reg
<< 2;
83 mutex_lock(&data
->lock
);
84 ret
= i2c_master_send(data
->client
, data
->buf
, sizeof(data
->buf
));
88 ret
= i2c_master_recv(data
->client
, data
->buf
, sizeof(data
->buf
));
92 *val
= ((data
->buf
[0] & 0x3) << 8) | data
->buf
[1];
95 mutex_unlock(&data
->lock
);
99 static int ad5272_read_raw(struct iio_dev
*indio_dev
,
100 struct iio_chan_spec
const *chan
,
101 int *val
, int *val2
, long mask
)
103 struct ad5272_data
*data
= iio_priv(indio_dev
);
107 case IIO_CHAN_INFO_RAW
: {
108 ret
= ad5272_read(data
, AD5272_RDAC_RD
, val
);
109 *val
= *val
>> data
->cfg
->shift
;
110 return ret
? ret
: IIO_VAL_INT
;
112 case IIO_CHAN_INFO_SCALE
:
113 *val
= 1000 * data
->cfg
->kohms
;
114 *val2
= data
->cfg
->max_pos
;
115 return IIO_VAL_FRACTIONAL
;
121 static int ad5272_write_raw(struct iio_dev
*indio_dev
,
122 struct iio_chan_spec
const *chan
,
123 int val
, int val2
, long mask
)
125 struct ad5272_data
*data
= iio_priv(indio_dev
);
127 if (mask
!= IIO_CHAN_INFO_RAW
)
130 if (val
>= data
->cfg
->max_pos
|| val
< 0 || val2
)
133 return ad5272_write(data
, AD5272_RDAC_WR
, val
<< data
->cfg
->shift
);
136 static const struct iio_info ad5272_info
= {
137 .read_raw
= ad5272_read_raw
,
138 .write_raw
= ad5272_write_raw
,
141 static int ad5272_reset(struct ad5272_data
*data
)
143 struct gpio_desc
*reset_gpio
;
145 reset_gpio
= devm_gpiod_get_optional(&data
->client
->dev
, "reset",
147 if (IS_ERR(reset_gpio
))
148 return PTR_ERR(reset_gpio
);
152 gpiod_set_value(reset_gpio
, 0);
154 ad5272_write(data
, AD5272_RESET
, 0);
156 usleep_range(1000, 2000);
161 static int ad5272_probe(struct i2c_client
*client
)
163 const struct i2c_device_id
*id
= i2c_client_get_device_id(client
);
164 struct device
*dev
= &client
->dev
;
165 struct iio_dev
*indio_dev
;
166 struct ad5272_data
*data
;
169 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
173 i2c_set_clientdata(client
, indio_dev
);
175 data
= iio_priv(indio_dev
);
176 data
->client
= client
;
177 mutex_init(&data
->lock
);
178 data
->cfg
= &ad5272_cfg
[id
->driver_data
];
180 ret
= ad5272_reset(data
);
184 ret
= ad5272_write(data
, AD5272_CTL
, AD5272_RDAC_WR_EN
);
188 indio_dev
->info
= &ad5272_info
;
189 indio_dev
->channels
= &ad5272_channel
;
190 indio_dev
->num_channels
= 1;
191 indio_dev
->name
= client
->name
;
193 return devm_iio_device_register(dev
, indio_dev
);
196 static const struct of_device_id ad5272_dt_ids
[] = {
197 { .compatible
= "adi,ad5272-020", .data
= (void *)AD5272_020
},
198 { .compatible
= "adi,ad5272-050", .data
= (void *)AD5272_050
},
199 { .compatible
= "adi,ad5272-100", .data
= (void *)AD5272_100
},
200 { .compatible
= "adi,ad5274-020", .data
= (void *)AD5274_020
},
201 { .compatible
= "adi,ad5274-100", .data
= (void *)AD5274_100
},
204 MODULE_DEVICE_TABLE(of
, ad5272_dt_ids
);
206 static const struct i2c_device_id ad5272_id
[] = {
207 { "ad5272-020", AD5272_020
},
208 { "ad5272-050", AD5272_050
},
209 { "ad5272-100", AD5272_100
},
210 { "ad5274-020", AD5274_020
},
211 { "ad5274-100", AD5274_100
},
214 MODULE_DEVICE_TABLE(i2c
, ad5272_id
);
216 static struct i2c_driver ad5272_driver
= {
219 .of_match_table
= ad5272_dt_ids
,
221 .probe
= ad5272_probe
,
222 .id_table
= ad5272_id
,
225 module_i2c_driver(ad5272_driver
);
227 MODULE_AUTHOR("Phil Reid <preid@eletromag.com.au>");
228 MODULE_DESCRIPTION("AD5272 digital potentiometer");
229 MODULE_LICENSE("GPL v2");