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: http://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>
19 #define AD5272_RDAC_WR 1
20 #define AD5272_RDAC_RD 2
21 #define AD5272_RESET 4
24 #define AD5272_RDAC_WR_EN BIT(1)
40 static const struct ad5272_cfg ad5272_cfg
[] = {
41 [AD5272_020
] = { .max_pos
= 1024, .kohms
= 20 },
42 [AD5272_050
] = { .max_pos
= 1024, .kohms
= 50 },
43 [AD5272_100
] = { .max_pos
= 1024, .kohms
= 100 },
44 [AD5274_020
] = { .max_pos
= 256, .kohms
= 20, .shift
= 2 },
45 [AD5274_100
] = { .max_pos
= 256, .kohms
= 100, .shift
= 2 },
49 struct i2c_client
*client
;
51 const struct ad5272_cfg
*cfg
;
52 u8 buf
[2] ____cacheline_aligned
;
55 static const struct iio_chan_spec ad5272_channel
= {
56 .type
= IIO_RESISTANCE
,
58 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
59 .info_mask_shared_by_type
= BIT(IIO_CHAN_INFO_SCALE
),
62 static int ad5272_write(struct ad5272_data
*data
, int reg
, int val
)
66 data
->buf
[0] = (reg
<< 2) | ((val
>> 8) & 0x3);
67 data
->buf
[1] = (u8
)val
;
69 mutex_lock(&data
->lock
);
70 ret
= i2c_master_send(data
->client
, data
->buf
, sizeof(data
->buf
));
71 mutex_unlock(&data
->lock
);
72 return ret
< 0 ? ret
: 0;
75 static int ad5272_read(struct ad5272_data
*data
, int reg
, int *val
)
79 data
->buf
[0] = reg
<< 2;
82 mutex_lock(&data
->lock
);
83 ret
= i2c_master_send(data
->client
, data
->buf
, sizeof(data
->buf
));
87 ret
= i2c_master_recv(data
->client
, data
->buf
, sizeof(data
->buf
));
91 *val
= ((data
->buf
[0] & 0x3) << 8) | data
->buf
[1];
94 mutex_unlock(&data
->lock
);
98 static int ad5272_read_raw(struct iio_dev
*indio_dev
,
99 struct iio_chan_spec
const *chan
,
100 int *val
, int *val2
, long mask
)
102 struct ad5272_data
*data
= iio_priv(indio_dev
);
106 case IIO_CHAN_INFO_RAW
: {
107 ret
= ad5272_read(data
, AD5272_RDAC_RD
, val
);
108 *val
= *val
>> data
->cfg
->shift
;
109 return ret
? ret
: IIO_VAL_INT
;
111 case IIO_CHAN_INFO_SCALE
:
112 *val
= 1000 * data
->cfg
->kohms
;
113 *val2
= data
->cfg
->max_pos
;
114 return IIO_VAL_FRACTIONAL
;
120 static int ad5272_write_raw(struct iio_dev
*indio_dev
,
121 struct iio_chan_spec
const *chan
,
122 int val
, int val2
, long mask
)
124 struct ad5272_data
*data
= iio_priv(indio_dev
);
126 if (mask
!= IIO_CHAN_INFO_RAW
)
129 if (val
>= data
->cfg
->max_pos
|| val
< 0 || val2
)
132 return ad5272_write(data
, AD5272_RDAC_WR
, val
<< data
->cfg
->shift
);
135 static const struct iio_info ad5272_info
= {
136 .read_raw
= ad5272_read_raw
,
137 .write_raw
= ad5272_write_raw
,
140 static int ad5272_reset(struct ad5272_data
*data
)
142 struct gpio_desc
*reset_gpio
;
144 reset_gpio
= devm_gpiod_get_optional(&data
->client
->dev
, "reset",
146 if (IS_ERR(reset_gpio
))
147 return PTR_ERR(reset_gpio
);
151 gpiod_set_value(reset_gpio
, 1);
153 ad5272_write(data
, AD5272_RESET
, 0);
155 usleep_range(1000, 2000);
160 static int ad5272_probe(struct i2c_client
*client
,
161 const struct i2c_device_id
*id
)
163 struct device
*dev
= &client
->dev
;
164 struct iio_dev
*indio_dev
;
165 struct ad5272_data
*data
;
168 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
172 i2c_set_clientdata(client
, indio_dev
);
174 data
= iio_priv(indio_dev
);
175 data
->client
= client
;
176 mutex_init(&data
->lock
);
177 data
->cfg
= &ad5272_cfg
[id
->driver_data
];
179 ret
= ad5272_reset(data
);
183 ret
= ad5272_write(data
, AD5272_CTL
, AD5272_RDAC_WR_EN
);
187 indio_dev
->dev
.parent
= dev
;
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 #if defined(CONFIG_OF)
197 static const struct of_device_id ad5272_dt_ids
[] = {
198 { .compatible
= "adi,ad5272-020", .data
= (void *)AD5272_020
},
199 { .compatible
= "adi,ad5272-050", .data
= (void *)AD5272_050
},
200 { .compatible
= "adi,ad5272-100", .data
= (void *)AD5272_100
},
201 { .compatible
= "adi,ad5274-020", .data
= (void *)AD5274_020
},
202 { .compatible
= "adi,ad5274-100", .data
= (void *)AD5274_100
},
205 MODULE_DEVICE_TABLE(of
, ad5272_dt_ids
);
206 #endif /* CONFIG_OF */
208 static const struct i2c_device_id ad5272_id
[] = {
209 { "ad5272-020", AD5272_020
},
210 { "ad5272-050", AD5272_050
},
211 { "ad5272-100", AD5272_100
},
212 { "ad5274-020", AD5274_020
},
213 { "ad5274-100", AD5274_100
},
216 MODULE_DEVICE_TABLE(i2c
, ad5272_id
);
218 static struct i2c_driver ad5272_driver
= {
221 .of_match_table
= of_match_ptr(ad5272_dt_ids
),
223 .probe
= ad5272_probe
,
224 .id_table
= ad5272_id
,
227 module_i2c_driver(ad5272_driver
);
229 MODULE_AUTHOR("Phil Reid <preid@eletromag.com.au>");
230 MODULE_DESCRIPTION("AD5272 digital potentiometer");
231 MODULE_LICENSE("GPL v2");