1 /* 2 * iio/dac/max5821.c 3 * Copyright (C) 2014 Philippe Reynes 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/i2c.h> 13 #include <linux/iio/iio.h> 14 #include <linux/regulator/consumer.h> 15 16 #define MAX5821_MAX_DAC_CHANNELS 2 17 18 /* command bytes */ 19 #define MAX5821_LOAD_DAC_A_IN_REG_B 0x00 20 #define MAX5821_LOAD_DAC_B_IN_REG_A 0x10 21 #define MAX5821_EXTENDED_COMMAND_MODE 0xf0 22 #define MAX5821_READ_DAC_A_COMMAND 0xf1 23 #define MAX5821_READ_DAC_B_COMMAND 0xf2 24 25 #define MAX5821_EXTENDED_POWER_UP 0x00 26 #define MAX5821_EXTENDED_POWER_DOWN_MODE0 0x01 27 #define MAX5821_EXTENDED_POWER_DOWN_MODE1 0x02 28 #define MAX5821_EXTENDED_POWER_DOWN_MODE2 0x03 29 #define MAX5821_EXTENDED_DAC_A 0x04 30 #define MAX5821_EXTENDED_DAC_B 0x08 31 32 enum max5821_device_ids { 33 ID_MAX5821, 34 }; 35 36 struct max5821_data { 37 struct i2c_client *client; 38 struct regulator *vref_reg; 39 unsigned short vref_mv; 40 bool powerdown[MAX5821_MAX_DAC_CHANNELS]; 41 u8 powerdown_mode[MAX5821_MAX_DAC_CHANNELS]; 42 struct mutex lock; 43 }; 44 45 static const char * const max5821_powerdown_modes[] = { 46 "three_state", 47 "1kohm_to_gnd", 48 "100kohm_to_gnd", 49 }; 50 51 enum { 52 MAX5821_THREE_STATE, 53 MAX5821_1KOHM_TO_GND, 54 MAX5821_100KOHM_TO_GND 55 }; 56 57 static int max5821_get_powerdown_mode(struct iio_dev *indio_dev, 58 const struct iio_chan_spec *chan) 59 { 60 struct max5821_data *st = iio_priv(indio_dev); 61 62 return st->powerdown_mode[chan->channel]; 63 } 64 65 static int max5821_set_powerdown_mode(struct iio_dev *indio_dev, 66 const struct iio_chan_spec *chan, 67 unsigned int mode) 68 { 69 struct max5821_data *st = iio_priv(indio_dev); 70 71 st->powerdown_mode[chan->channel] = mode; 72 73 return 0; 74 } 75 76 static const struct iio_enum max5821_powerdown_mode_enum = { 77 .items = max5821_powerdown_modes, 78 .num_items = ARRAY_SIZE(max5821_powerdown_modes), 79 .get = max5821_get_powerdown_mode, 80 .set = max5821_set_powerdown_mode, 81 }; 82 83 static ssize_t max5821_read_dac_powerdown(struct iio_dev *indio_dev, 84 uintptr_t private, 85 const struct iio_chan_spec *chan, 86 char *buf) 87 { 88 struct max5821_data *st = iio_priv(indio_dev); 89 90 return sprintf(buf, "%d\n", st->powerdown[chan->channel]); 91 } 92 93 static int max5821_sync_powerdown_mode(struct max5821_data *data, 94 const struct iio_chan_spec *chan) 95 { 96 u8 outbuf[2]; 97 98 outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE; 99 100 if (chan->channel == 0) 101 outbuf[1] = MAX5821_EXTENDED_DAC_A; 102 else 103 outbuf[1] = MAX5821_EXTENDED_DAC_B; 104 105 if (data->powerdown[chan->channel]) 106 outbuf[1] |= data->powerdown_mode[chan->channel] + 1; 107 else 108 outbuf[1] |= MAX5821_EXTENDED_POWER_UP; 109 110 return i2c_master_send(data->client, outbuf, 2); 111 } 112 113 static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev, 114 uintptr_t private, 115 const struct iio_chan_spec *chan, 116 const char *buf, size_t len) 117 { 118 struct max5821_data *data = iio_priv(indio_dev); 119 bool powerdown; 120 int ret; 121 122 ret = strtobool(buf, &powerdown); 123 if (ret) 124 return ret; 125 126 data->powerdown[chan->channel] = powerdown; 127 128 ret = max5821_sync_powerdown_mode(data, chan); 129 if (ret < 0) 130 return ret; 131 132 return len; 133 } 134 135 static const struct iio_chan_spec_ext_info max5821_ext_info[] = { 136 { 137 .name = "powerdown", 138 .read = max5821_read_dac_powerdown, 139 .write = max5821_write_dac_powerdown, 140 .shared = IIO_SEPARATE, 141 }, 142 IIO_ENUM("powerdown_mode", IIO_SEPARATE, &max5821_powerdown_mode_enum), 143 IIO_ENUM_AVAILABLE("powerdown_mode", &max5821_powerdown_mode_enum), 144 { }, 145 }; 146 147 #define MAX5821_CHANNEL(chan) { \ 148 .type = IIO_VOLTAGE, \ 149 .indexed = 1, \ 150 .output = 1, \ 151 .channel = (chan), \ 152 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 153 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \ 154 .ext_info = max5821_ext_info, \ 155 } 156 157 static const struct iio_chan_spec max5821_channels[] = { 158 MAX5821_CHANNEL(0), 159 MAX5821_CHANNEL(1) 160 }; 161 162 static const u8 max5821_read_dac_command[] = { 163 MAX5821_READ_DAC_A_COMMAND, 164 MAX5821_READ_DAC_B_COMMAND 165 }; 166 167 static const u8 max5821_load_dac_command[] = { 168 MAX5821_LOAD_DAC_A_IN_REG_B, 169 MAX5821_LOAD_DAC_B_IN_REG_A 170 }; 171 172 static int max5821_get_value(struct iio_dev *indio_dev, 173 int *val, int channel) 174 { 175 struct max5821_data *data = iio_priv(indio_dev); 176 struct i2c_client *client = data->client; 177 u8 outbuf[1]; 178 u8 inbuf[2]; 179 int ret; 180 181 if ((channel != 0) && (channel != 1)) 182 return -EINVAL; 183 184 outbuf[0] = max5821_read_dac_command[channel]; 185 186 mutex_lock(&data->lock); 187 188 ret = i2c_master_send(client, outbuf, 1); 189 if (ret < 0) { 190 mutex_unlock(&data->lock); 191 return ret; 192 } else if (ret != 1) { 193 mutex_unlock(&data->lock); 194 return -EIO; 195 } 196 197 ret = i2c_master_recv(client, inbuf, 2); 198 if (ret < 0) { 199 mutex_unlock(&data->lock); 200 return ret; 201 } else if (ret != 2) { 202 mutex_unlock(&data->lock); 203 return -EIO; 204 } 205 206 mutex_unlock(&data->lock); 207 208 *val = ((inbuf[0] & 0x0f) << 6) | (inbuf[1] >> 2); 209 210 return IIO_VAL_INT; 211 } 212 213 static int max5821_set_value(struct iio_dev *indio_dev, 214 int val, int channel) 215 { 216 struct max5821_data *data = iio_priv(indio_dev); 217 struct i2c_client *client = data->client; 218 u8 outbuf[2]; 219 int ret; 220 221 if ((val < 0) || (val > 1023)) 222 return -EINVAL; 223 224 if ((channel != 0) && (channel != 1)) 225 return -EINVAL; 226 227 outbuf[0] = max5821_load_dac_command[channel]; 228 outbuf[0] |= val >> 6; 229 outbuf[1] = (val & 0x3f) << 2; 230 231 ret = i2c_master_send(client, outbuf, 2); 232 if (ret < 0) 233 return ret; 234 else if (ret != 2) 235 return -EIO; 236 else 237 return 0; 238 } 239 240 static int max5821_read_raw(struct iio_dev *indio_dev, 241 struct iio_chan_spec const *chan, 242 int *val, int *val2, long mask) 243 { 244 struct max5821_data *data = iio_priv(indio_dev); 245 246 switch (mask) { 247 case IIO_CHAN_INFO_RAW: 248 return max5821_get_value(indio_dev, val, chan->channel); 249 case IIO_CHAN_INFO_SCALE: 250 *val = data->vref_mv; 251 *val2 = 10; 252 return IIO_VAL_FRACTIONAL_LOG2; 253 default: 254 return -EINVAL; 255 } 256 } 257 258 static int max5821_write_raw(struct iio_dev *indio_dev, 259 struct iio_chan_spec const *chan, 260 int val, int val2, long mask) 261 { 262 if (val2 != 0) 263 return -EINVAL; 264 265 switch (mask) { 266 case IIO_CHAN_INFO_RAW: 267 return max5821_set_value(indio_dev, val, chan->channel); 268 default: 269 return -EINVAL; 270 } 271 } 272 273 #ifdef CONFIG_PM_SLEEP 274 static int max5821_suspend(struct device *dev) 275 { 276 u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, 277 MAX5821_EXTENDED_DAC_A | 278 MAX5821_EXTENDED_DAC_B | 279 MAX5821_EXTENDED_POWER_DOWN_MODE2 }; 280 281 return i2c_master_send(to_i2c_client(dev), outbuf, 2); 282 } 283 284 static int max5821_resume(struct device *dev) 285 { 286 u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, 287 MAX5821_EXTENDED_DAC_A | 288 MAX5821_EXTENDED_DAC_B | 289 MAX5821_EXTENDED_POWER_UP }; 290 291 return i2c_master_send(to_i2c_client(dev), outbuf, 2); 292 } 293 294 static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume); 295 #define MAX5821_PM_OPS (&max5821_pm_ops) 296 #else 297 #define MAX5821_PM_OPS NULL 298 #endif /* CONFIG_PM_SLEEP */ 299 300 static const struct iio_info max5821_info = { 301 .read_raw = max5821_read_raw, 302 .write_raw = max5821_write_raw, 303 .driver_module = THIS_MODULE, 304 }; 305 306 static int max5821_probe(struct i2c_client *client, 307 const struct i2c_device_id *id) 308 { 309 struct max5821_data *data; 310 struct iio_dev *indio_dev; 311 u32 tmp; 312 int ret; 313 314 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 315 if (!indio_dev) 316 return -ENOMEM; 317 data = iio_priv(indio_dev); 318 i2c_set_clientdata(client, indio_dev); 319 data->client = client; 320 mutex_init(&data->lock); 321 322 /* max5821 start in powerdown mode 100Kohm to ground */ 323 for (tmp = 0; tmp < MAX5821_MAX_DAC_CHANNELS; tmp++) { 324 data->powerdown[tmp] = true; 325 data->powerdown_mode[tmp] = MAX5821_100KOHM_TO_GND; 326 } 327 328 data->vref_reg = devm_regulator_get(&client->dev, "vref"); 329 if (IS_ERR(data->vref_reg)) { 330 ret = PTR_ERR(data->vref_reg); 331 dev_err(&client->dev, 332 "Failed to get vref regulator: %d\n", ret); 333 goto error_free_reg; 334 } 335 336 ret = regulator_enable(data->vref_reg); 337 if (ret) { 338 dev_err(&client->dev, 339 "Failed to enable vref regulator: %d\n", ret); 340 goto error_free_reg; 341 } 342 343 ret = regulator_get_voltage(data->vref_reg); 344 if (ret < 0) { 345 dev_err(&client->dev, 346 "Failed to get voltage on regulator: %d\n", ret); 347 goto error_disable_reg; 348 } 349 350 data->vref_mv = ret / 1000; 351 352 indio_dev->name = id->name; 353 indio_dev->dev.parent = &client->dev; 354 indio_dev->num_channels = ARRAY_SIZE(max5821_channels); 355 indio_dev->channels = max5821_channels; 356 indio_dev->modes = INDIO_DIRECT_MODE; 357 indio_dev->info = &max5821_info; 358 359 return iio_device_register(indio_dev); 360 361 error_disable_reg: 362 regulator_disable(data->vref_reg); 363 364 error_free_reg: 365 366 return ret; 367 } 368 369 static int max5821_remove(struct i2c_client *client) 370 { 371 struct iio_dev *indio_dev = i2c_get_clientdata(client); 372 struct max5821_data *data = iio_priv(indio_dev); 373 374 iio_device_unregister(indio_dev); 375 regulator_disable(data->vref_reg); 376 377 return 0; 378 } 379 380 static const struct i2c_device_id max5821_id[] = { 381 { "max5821", ID_MAX5821 }, 382 { } 383 }; 384 MODULE_DEVICE_TABLE(i2c, max5821_id); 385 386 static const struct of_device_id max5821_of_match[] = { 387 { .compatible = "maxim,max5821" }, 388 { } 389 }; 390 391 static struct i2c_driver max5821_driver = { 392 .driver = { 393 .name = "max5821", 394 .pm = MAX5821_PM_OPS, 395 }, 396 .probe = max5821_probe, 397 .remove = max5821_remove, 398 .id_table = max5821_id, 399 }; 400 module_i2c_driver(max5821_driver); 401 402 MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 403 MODULE_DESCRIPTION("MAX5821 DAC"); 404 MODULE_LICENSE("GPL v2"); 405