diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2012-06-04 05:36:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-05 00:47:31 -0400 |
commit | fe4586a8753117a089acb54f75870d07c8e474d0 (patch) | |
tree | 392cb4395c454bf8e4d179273a54857e1de97ac6 /drivers/staging/iio | |
parent | 66eb90505eaf38f3e88491eb9090cd7be7c2da03 (diff) |
staging:iio:dac:ad5686: Convert to extended channel attributes
Use extended channel attributes instead of raw sysfs files for the additional
channel attributes. This allows us to remove some boilerplate code.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r-- | drivers/staging/iio/dac/ad5686.c | 196 |
1 files changed, 80 insertions, 116 deletions
diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index c1e903ebc7b..f07e19721c9 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c | |||
@@ -93,40 +93,6 @@ enum ad5686_supported_device_ids { | |||
93 | ID_AD5685, | 93 | ID_AD5685, |
94 | ID_AD5686, | 94 | ID_AD5686, |
95 | }; | 95 | }; |
96 | #define AD5868_CHANNEL(chan, bits, shift) { \ | ||
97 | .type = IIO_VOLTAGE, \ | ||
98 | .indexed = 1, \ | ||
99 | .output = 1, \ | ||
100 | .channel = chan, \ | ||
101 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | ||
102 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | ||
103 | .address = AD5686_ADDR_DAC(chan), \ | ||
104 | .scan_type = IIO_ST('u', bits, 16, shift) \ | ||
105 | } | ||
106 | static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { | ||
107 | [ID_AD5684] = { | ||
108 | .channel[0] = AD5868_CHANNEL(0, 12, 4), | ||
109 | .channel[1] = AD5868_CHANNEL(1, 12, 4), | ||
110 | .channel[2] = AD5868_CHANNEL(2, 12, 4), | ||
111 | .channel[3] = AD5868_CHANNEL(3, 12, 4), | ||
112 | .int_vref_mv = 2500, | ||
113 | }, | ||
114 | [ID_AD5685] = { | ||
115 | .channel[0] = AD5868_CHANNEL(0, 14, 2), | ||
116 | .channel[1] = AD5868_CHANNEL(1, 14, 2), | ||
117 | .channel[2] = AD5868_CHANNEL(2, 14, 2), | ||
118 | .channel[3] = AD5868_CHANNEL(3, 14, 2), | ||
119 | .int_vref_mv = 2500, | ||
120 | }, | ||
121 | [ID_AD5686] = { | ||
122 | .channel[0] = AD5868_CHANNEL(0, 16, 0), | ||
123 | .channel[1] = AD5868_CHANNEL(1, 16, 0), | ||
124 | .channel[2] = AD5868_CHANNEL(2, 16, 0), | ||
125 | .channel[3] = AD5868_CHANNEL(3, 16, 0), | ||
126 | .int_vref_mv = 2500, | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | static int ad5686_spi_write(struct ad5686_state *st, | 96 | static int ad5686_spi_write(struct ad5686_state *st, |
131 | u8 cmd, u8 addr, u16 val, u8 shift) | 97 | u8 cmd, u8 addr, u16 val, u8 shift) |
132 | { | 98 | { |
@@ -170,73 +136,63 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 addr) | |||
170 | return be32_to_cpu(st->data[2].d32); | 136 | return be32_to_cpu(st->data[2].d32); |
171 | } | 137 | } |
172 | 138 | ||
173 | static ssize_t ad5686_read_powerdown_mode(struct device *dev, | 139 | static const char * const ad5686_powerdown_modes[] = { |
174 | struct device_attribute *attr, char *buf) | 140 | "1kohm_to_gnd", |
141 | "100kohm_to_gnd", | ||
142 | "three_state" | ||
143 | }; | ||
144 | |||
145 | static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev, | ||
146 | const struct iio_chan_spec *chan) | ||
175 | { | 147 | { |
176 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
177 | struct ad5686_state *st = iio_priv(indio_dev); | 148 | struct ad5686_state *st = iio_priv(indio_dev); |
178 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
179 | 149 | ||
180 | char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; | 150 | return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1; |
181 | |||
182 | return sprintf(buf, "%s\n", mode[(st->pwr_down_mode >> | ||
183 | (this_attr->address * 2)) & 0x3]); | ||
184 | } | 151 | } |
185 | 152 | ||
186 | static ssize_t ad5686_write_powerdown_mode(struct device *dev, | 153 | static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev, |
187 | struct device_attribute *attr, | 154 | const struct iio_chan_spec *chan, unsigned int mode) |
188 | const char *buf, size_t len) | ||
189 | { | 155 | { |
190 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
191 | struct ad5686_state *st = iio_priv(indio_dev); | 156 | struct ad5686_state *st = iio_priv(indio_dev); |
192 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
193 | unsigned mode; | ||
194 | |||
195 | if (sysfs_streq(buf, "1kohm_to_gnd")) | ||
196 | mode = AD5686_LDAC_PWRDN_1K; | ||
197 | else if (sysfs_streq(buf, "100kohm_to_gnd")) | ||
198 | mode = AD5686_LDAC_PWRDN_100K; | ||
199 | else if (sysfs_streq(buf, "three_state")) | ||
200 | mode = AD5686_LDAC_PWRDN_3STATE; | ||
201 | else | ||
202 | return -EINVAL; | ||
203 | 157 | ||
204 | st->pwr_down_mode &= ~(0x3 << (this_attr->address * 2)); | 158 | st->pwr_down_mode &= ~(0x3 << (chan->channel * 2)); |
205 | st->pwr_down_mode |= (mode << (this_attr->address * 2)); | 159 | st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2)); |
206 | 160 | ||
207 | return len; | 161 | return 0; |
208 | } | 162 | } |
209 | 163 | ||
210 | static ssize_t ad5686_read_dac_powerdown(struct device *dev, | 164 | static const struct iio_enum ad5686_powerdown_mode_enum = { |
211 | struct device_attribute *attr, | 165 | .items = ad5686_powerdown_modes, |
212 | char *buf) | 166 | .num_items = ARRAY_SIZE(ad5686_powerdown_modes), |
167 | .get = ad5686_get_powerdown_mode, | ||
168 | .set = ad5686_set_powerdown_mode, | ||
169 | }; | ||
170 | |||
171 | static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev, | ||
172 | uintptr_t private, const struct iio_chan_spec *chan, char *buf) | ||
213 | { | 173 | { |
214 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
215 | struct ad5686_state *st = iio_priv(indio_dev); | 174 | struct ad5686_state *st = iio_priv(indio_dev); |
216 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
217 | 175 | ||
218 | return sprintf(buf, "%d\n", !!(st->pwr_down_mask & | 176 | return sprintf(buf, "%d\n", !!(st->pwr_down_mask & |
219 | (0x3 << (this_attr->address * 2)))); | 177 | (0x3 << (chan->channel * 2)))); |
220 | } | 178 | } |
221 | 179 | ||
222 | static ssize_t ad5686_write_dac_powerdown(struct device *dev, | 180 | static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, |
223 | struct device_attribute *attr, | 181 | uintptr_t private, const struct iio_chan_spec *chan, const char *buf, |
224 | const char *buf, size_t len) | 182 | size_t len) |
225 | { | 183 | { |
226 | bool readin; | 184 | bool readin; |
227 | int ret; | 185 | int ret; |
228 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
229 | struct ad5686_state *st = iio_priv(indio_dev); | 186 | struct ad5686_state *st = iio_priv(indio_dev); |
230 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
231 | 187 | ||
232 | ret = strtobool(buf, &readin); | 188 | ret = strtobool(buf, &readin); |
233 | if (ret) | 189 | if (ret) |
234 | return ret; | 190 | return ret; |
235 | 191 | ||
236 | if (readin == true) | 192 | if (readin == true) |
237 | st->pwr_down_mask |= (0x3 << (this_attr->address * 2)); | 193 | st->pwr_down_mask |= (0x3 << (chan->channel * 2)); |
238 | else | 194 | else |
239 | st->pwr_down_mask &= ~(0x3 << (this_attr->address * 2)); | 195 | st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); |
240 | 196 | ||
241 | ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0, | 197 | ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0, |
242 | st->pwr_down_mask & st->pwr_down_mode, 0); | 198 | st->pwr_down_mask & st->pwr_down_mode, 0); |
@@ -244,48 +200,6 @@ static ssize_t ad5686_write_dac_powerdown(struct device *dev, | |||
244 | return ret ? ret : len; | 200 | return ret ? ret : len; |
245 | } | 201 | } |
246 | 202 | ||
247 | static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, | ||
248 | "1kohm_to_gnd 100kohm_to_gnd three_state"); | ||
249 | |||
250 | #define IIO_DEV_ATTR_DAC_POWERDOWN_MODE(_num) \ | ||
251 | IIO_DEVICE_ATTR(out_voltage##_num##_powerdown_mode, \ | ||
252 | S_IRUGO | S_IWUSR, \ | ||
253 | ad5686_read_powerdown_mode, \ | ||
254 | ad5686_write_powerdown_mode, _num) | ||
255 | |||
256 | static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(0); | ||
257 | static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(1); | ||
258 | static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(2); | ||
259 | static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(3); | ||
260 | |||
261 | #define IIO_DEV_ATTR_DAC_POWERDOWN(_num) \ | ||
262 | IIO_DEVICE_ATTR(out_voltage##_num##_powerdown, \ | ||
263 | S_IRUGO | S_IWUSR, \ | ||
264 | ad5686_read_dac_powerdown, \ | ||
265 | ad5686_write_dac_powerdown, _num) | ||
266 | |||
267 | static IIO_DEV_ATTR_DAC_POWERDOWN(0); | ||
268 | static IIO_DEV_ATTR_DAC_POWERDOWN(1); | ||
269 | static IIO_DEV_ATTR_DAC_POWERDOWN(2); | ||
270 | static IIO_DEV_ATTR_DAC_POWERDOWN(3); | ||
271 | |||
272 | static struct attribute *ad5686_attributes[] = { | ||
273 | &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, | ||
274 | &iio_dev_attr_out_voltage1_powerdown.dev_attr.attr, | ||
275 | &iio_dev_attr_out_voltage2_powerdown.dev_attr.attr, | ||
276 | &iio_dev_attr_out_voltage3_powerdown.dev_attr.attr, | ||
277 | &iio_dev_attr_out_voltage0_powerdown_mode.dev_attr.attr, | ||
278 | &iio_dev_attr_out_voltage1_powerdown_mode.dev_attr.attr, | ||
279 | &iio_dev_attr_out_voltage2_powerdown_mode.dev_attr.attr, | ||
280 | &iio_dev_attr_out_voltage3_powerdown_mode.dev_attr.attr, | ||
281 | &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, | ||
282 | NULL, | ||
283 | }; | ||
284 | |||
285 | static const struct attribute_group ad5686_attribute_group = { | ||
286 | .attrs = ad5686_attributes, | ||
287 | }; | ||
288 | |||
289 | static int ad5686_read_raw(struct iio_dev *indio_dev, | 203 | static int ad5686_read_raw(struct iio_dev *indio_dev, |
290 | struct iio_chan_spec const *chan, | 204 | struct iio_chan_spec const *chan, |
291 | int *val, | 205 | int *val, |
@@ -349,10 +263,57 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, | |||
349 | static const struct iio_info ad5686_info = { | 263 | static const struct iio_info ad5686_info = { |
350 | .read_raw = ad5686_read_raw, | 264 | .read_raw = ad5686_read_raw, |
351 | .write_raw = ad5686_write_raw, | 265 | .write_raw = ad5686_write_raw, |
352 | .attrs = &ad5686_attribute_group, | ||
353 | .driver_module = THIS_MODULE, | 266 | .driver_module = THIS_MODULE, |
354 | }; | 267 | }; |
355 | 268 | ||
269 | static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { | ||
270 | { | ||
271 | .name = "powerdown", | ||
272 | .read = ad5686_read_dac_powerdown, | ||
273 | .write = ad5686_write_dac_powerdown, | ||
274 | }, | ||
275 | IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum), | ||
276 | IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum), | ||
277 | { }, | ||
278 | }; | ||
279 | |||
280 | #define AD5868_CHANNEL(chan, bits, shift) { \ | ||
281 | .type = IIO_VOLTAGE, \ | ||
282 | .indexed = 1, \ | ||
283 | .output = 1, \ | ||
284 | .channel = chan, \ | ||
285 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | ||
286 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | ||
287 | .address = AD5686_ADDR_DAC(chan), \ | ||
288 | .scan_type = IIO_ST('u', bits, 16, shift), \ | ||
289 | .ext_info = ad5686_ext_info, \ | ||
290 | } | ||
291 | |||
292 | static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { | ||
293 | [ID_AD5684] = { | ||
294 | .channel[0] = AD5868_CHANNEL(0, 12, 4), | ||
295 | .channel[1] = AD5868_CHANNEL(1, 12, 4), | ||
296 | .channel[2] = AD5868_CHANNEL(2, 12, 4), | ||
297 | .channel[3] = AD5868_CHANNEL(3, 12, 4), | ||
298 | .int_vref_mv = 2500, | ||
299 | }, | ||
300 | [ID_AD5685] = { | ||
301 | .channel[0] = AD5868_CHANNEL(0, 14, 2), | ||
302 | .channel[1] = AD5868_CHANNEL(1, 14, 2), | ||
303 | .channel[2] = AD5868_CHANNEL(2, 14, 2), | ||
304 | .channel[3] = AD5868_CHANNEL(3, 14, 2), | ||
305 | .int_vref_mv = 2500, | ||
306 | }, | ||
307 | [ID_AD5686] = { | ||
308 | .channel[0] = AD5868_CHANNEL(0, 16, 0), | ||
309 | .channel[1] = AD5868_CHANNEL(1, 16, 0), | ||
310 | .channel[2] = AD5868_CHANNEL(2, 16, 0), | ||
311 | .channel[3] = AD5868_CHANNEL(3, 16, 0), | ||
312 | .int_vref_mv = 2500, | ||
313 | }, | ||
314 | }; | ||
315 | |||
316 | |||
356 | static int __devinit ad5686_probe(struct spi_device *spi) | 317 | static int __devinit ad5686_probe(struct spi_device *spi) |
357 | { | 318 | { |
358 | struct ad5686_state *st; | 319 | struct ad5686_state *st; |
@@ -385,6 +346,9 @@ static int __devinit ad5686_probe(struct spi_device *spi) | |||
385 | 346 | ||
386 | st->spi = spi; | 347 | st->spi = spi; |
387 | 348 | ||
349 | /* Set all the power down mode for all channels to 1K pulldown */ | ||
350 | st->pwr_down_mode = 0x55; | ||
351 | |||
388 | indio_dev->dev.parent = &spi->dev; | 352 | indio_dev->dev.parent = &spi->dev; |
389 | indio_dev->name = spi_get_device_id(spi)->name; | 353 | indio_dev->name = spi_get_device_id(spi)->name; |
390 | indio_dev->info = &ad5686_info; | 354 | indio_dev->info = &ad5686_info; |