1 /* 2 * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver 3 * 4 * Copyright 2010-2011 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2. 7 */ 8 9 #include <linux/interrupt.h> 10 #include <linux/fs.h> 11 #include <linux/device.h> 12 #include <linux/kernel.h> 13 #include <linux/spi/spi.h> 14 #include <linux/slab.h> 15 #include <linux/sysfs.h> 16 #include <linux/regulator/consumer.h> 17 #include <linux/module.h> 18 19 #include <linux/iio/iio.h> 20 #include <linux/iio/sysfs.h> 21 22 #include "ad5624r.h" 23 24 static int ad5624r_spi_write(struct spi_device *spi, 25 u8 cmd, u8 addr, u16 val, u8 len) 26 { 27 u32 data; 28 u8 msg[3]; 29 30 /* 31 * The input shift register is 24 bits wide. The first two bits are 32 * don't care bits. The next three are the command bits, C2 to C0, 33 * followed by the 3-bit DAC address, A2 to A0, and then the 34 * 16-, 14-, 12-bit data-word. The data-word comprises the 16-, 35 * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, 36 * for the AD5664R, AD5644R, and AD5624R, respectively. 37 */ 38 data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len)); 39 msg[0] = data >> 16; 40 msg[1] = data >> 8; 41 msg[2] = data; 42 43 return spi_write(spi, msg, 3); 44 } 45 46 static int ad5624r_read_raw(struct iio_dev *indio_dev, 47 struct iio_chan_spec const *chan, 48 int *val, 49 int *val2, 50 long m) 51 { 52 struct ad5624r_state *st = iio_priv(indio_dev); 53 unsigned long scale_uv; 54 55 switch (m) { 56 case IIO_CHAN_INFO_SCALE: 57 scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; 58 *val = scale_uv / 1000; 59 *val2 = (scale_uv % 1000) * 1000; 60 return IIO_VAL_INT_PLUS_MICRO; 61 62 } 63 return -EINVAL; 64 } 65 66 static int ad5624r_write_raw(struct iio_dev *indio_dev, 67 struct iio_chan_spec const *chan, 68 int val, 69 int val2, 70 long mask) 71 { 72 struct ad5624r_state *st = iio_priv(indio_dev); 73 int ret; 74 75 switch (mask) { 76 case IIO_CHAN_INFO_RAW: 77 if (val >= (1 << chan->scan_type.realbits) || val < 0) 78 return -EINVAL; 79 80 return ad5624r_spi_write(st->us, 81 AD5624R_CMD_WRITE_INPUT_N_UPDATE_N, 82 chan->address, val, 83 chan->scan_type.shift); 84 default: 85 ret = -EINVAL; 86 } 87 88 return -EINVAL; 89 } 90 91 static const char * const ad5624r_powerdown_modes[] = { 92 "1kohm_to_gnd", 93 "100kohm_to_gnd", 94 "three_state" 95 }; 96 97 static int ad5624r_get_powerdown_mode(struct iio_dev *indio_dev, 98 const struct iio_chan_spec *chan) 99 { 100 struct ad5624r_state *st = iio_priv(indio_dev); 101 102 return st->pwr_down_mode; 103 } 104 105 static int ad5624r_set_powerdown_mode(struct iio_dev *indio_dev, 106 const struct iio_chan_spec *chan, unsigned int mode) 107 { 108 struct ad5624r_state *st = iio_priv(indio_dev); 109 110 st->pwr_down_mode = mode; 111 112 return 0; 113 } 114 115 static const struct iio_enum ad5624r_powerdown_mode_enum = { 116 .items = ad5624r_powerdown_modes, 117 .num_items = ARRAY_SIZE(ad5624r_powerdown_modes), 118 .get = ad5624r_get_powerdown_mode, 119 .set = ad5624r_set_powerdown_mode, 120 }; 121 122 static ssize_t ad5624r_read_dac_powerdown(struct iio_dev *indio_dev, 123 uintptr_t private, const struct iio_chan_spec *chan, char *buf) 124 { 125 struct ad5624r_state *st = iio_priv(indio_dev); 126 127 return sprintf(buf, "%d\n", 128 !!(st->pwr_down_mask & (1 << chan->channel))); 129 } 130 131 static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev, 132 uintptr_t private, const struct iio_chan_spec *chan, const char *buf, 133 size_t len) 134 { 135 bool pwr_down; 136 int ret; 137 struct ad5624r_state *st = iio_priv(indio_dev); 138 139 ret = strtobool(buf, &pwr_down); 140 if (ret) 141 return ret; 142 143 if (pwr_down) 144 st->pwr_down_mask |= (1 << chan->channel); 145 else 146 st->pwr_down_mask &= ~(1 << chan->channel); 147 148 ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, 149 (st->pwr_down_mode << 4) | 150 st->pwr_down_mask, 16); 151 152 return ret ? ret : len; 153 } 154 155 static const struct iio_info ad5624r_info = { 156 .write_raw = ad5624r_write_raw, 157 .read_raw = ad5624r_read_raw, 158 .driver_module = THIS_MODULE, 159 }; 160 161 static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = { 162 { 163 .name = "powerdown", 164 .read = ad5624r_read_dac_powerdown, 165 .write = ad5624r_write_dac_powerdown, 166 }, 167 IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum), 168 IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum), 169 { }, 170 }; 171 172 #define AD5624R_CHANNEL(_chan, _bits) { \ 173 .type = IIO_VOLTAGE, \ 174 .indexed = 1, \ 175 .output = 1, \ 176 .channel = (_chan), \ 177 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ 178 IIO_CHAN_INFO_SCALE_SHARED_BIT, \ 179 .address = (_chan), \ 180 .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ 181 .ext_info = ad5624r_ext_info, \ 182 } 183 184 #define DECLARE_AD5624R_CHANNELS(_name, _bits) \ 185 const struct iio_chan_spec _name##_channels[] = { \ 186 AD5624R_CHANNEL(0, _bits), \ 187 AD5624R_CHANNEL(1, _bits), \ 188 AD5624R_CHANNEL(2, _bits), \ 189 AD5624R_CHANNEL(3, _bits), \ 190 } 191 192 static DECLARE_AD5624R_CHANNELS(ad5624r, 12); 193 static DECLARE_AD5624R_CHANNELS(ad5644r, 14); 194 static DECLARE_AD5624R_CHANNELS(ad5664r, 16); 195 196 static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = { 197 [ID_AD5624R3] = { 198 .channels = ad5624r_channels, 199 .int_vref_mv = 1250, 200 }, 201 [ID_AD5624R5] = { 202 .channels = ad5624r_channels, 203 .int_vref_mv = 2500, 204 }, 205 [ID_AD5644R3] = { 206 .channels = ad5644r_channels, 207 .int_vref_mv = 1250, 208 }, 209 [ID_AD5644R5] = { 210 .channels = ad5644r_channels, 211 .int_vref_mv = 2500, 212 }, 213 [ID_AD5664R3] = { 214 .channels = ad5664r_channels, 215 .int_vref_mv = 1250, 216 }, 217 [ID_AD5664R5] = { 218 .channels = ad5664r_channels, 219 .int_vref_mv = 2500, 220 }, 221 }; 222 223 static int __devinit ad5624r_probe(struct spi_device *spi) 224 { 225 struct ad5624r_state *st; 226 struct iio_dev *indio_dev; 227 int ret, voltage_uv = 0; 228 229 indio_dev = iio_device_alloc(sizeof(*st)); 230 if (indio_dev == NULL) { 231 ret = -ENOMEM; 232 goto error_ret; 233 } 234 st = iio_priv(indio_dev); 235 st->reg = regulator_get(&spi->dev, "vcc"); 236 if (!IS_ERR(st->reg)) { 237 ret = regulator_enable(st->reg); 238 if (ret) 239 goto error_put_reg; 240 241 voltage_uv = regulator_get_voltage(st->reg); 242 } 243 244 spi_set_drvdata(spi, indio_dev); 245 st->chip_info = 246 &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data]; 247 248 if (voltage_uv) 249 st->vref_mv = voltage_uv / 1000; 250 else 251 st->vref_mv = st->chip_info->int_vref_mv; 252 253 st->us = spi; 254 255 indio_dev->dev.parent = &spi->dev; 256 indio_dev->name = spi_get_device_id(spi)->name; 257 indio_dev->info = &ad5624r_info; 258 indio_dev->modes = INDIO_DIRECT_MODE; 259 indio_dev->channels = st->chip_info->channels; 260 indio_dev->num_channels = AD5624R_DAC_CHANNELS; 261 262 ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, 263 !!voltage_uv, 16); 264 if (ret) 265 goto error_disable_reg; 266 267 ret = iio_device_register(indio_dev); 268 if (ret) 269 goto error_disable_reg; 270 271 return 0; 272 273 error_disable_reg: 274 if (!IS_ERR(st->reg)) 275 regulator_disable(st->reg); 276 error_put_reg: 277 if (!IS_ERR(st->reg)) 278 regulator_put(st->reg); 279 iio_device_free(indio_dev); 280 error_ret: 281 282 return ret; 283 } 284 285 static int __devexit ad5624r_remove(struct spi_device *spi) 286 { 287 struct iio_dev *indio_dev = spi_get_drvdata(spi); 288 struct ad5624r_state *st = iio_priv(indio_dev); 289 290 iio_device_unregister(indio_dev); 291 if (!IS_ERR(st->reg)) { 292 regulator_disable(st->reg); 293 regulator_put(st->reg); 294 } 295 iio_device_free(indio_dev); 296 297 return 0; 298 } 299 300 static const struct spi_device_id ad5624r_id[] = { 301 {"ad5624r3", ID_AD5624R3}, 302 {"ad5644r3", ID_AD5644R3}, 303 {"ad5664r3", ID_AD5664R3}, 304 {"ad5624r5", ID_AD5624R5}, 305 {"ad5644r5", ID_AD5644R5}, 306 {"ad5664r5", ID_AD5664R5}, 307 {} 308 }; 309 MODULE_DEVICE_TABLE(spi, ad5624r_id); 310 311 static struct spi_driver ad5624r_driver = { 312 .driver = { 313 .name = "ad5624r", 314 .owner = THIS_MODULE, 315 }, 316 .probe = ad5624r_probe, 317 .remove = __devexit_p(ad5624r_remove), 318 .id_table = ad5624r_id, 319 }; 320 module_spi_driver(ad5624r_driver); 321 322 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 323 MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver"); 324 MODULE_LICENSE("GPL v2"); 325