Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: add support of the max5821

Signed-off-by: Philippe Reynes <tremyfr@yahoo.fr>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Philippe Reynes and committed by
Jonathan Cameron
47298897 03d79558

+428
+14
Documentation/devicetree/bindings/iio/dac/max5821.txt
··· 1 + Maxim max5821 DAC device driver 2 + 3 + Required properties: 4 + - compatible: Must be "maxim,max5821" 5 + - reg: Should contain the DAC I2C address 6 + - vref-supply: Phandle to the vref power supply 7 + 8 + Example: 9 + 10 + max5821@38 { 11 + compatible = "maxim,max5821"; 12 + reg = <0x38>; 13 + vref-supply = <&reg_max5821>; 14 + };
+8
drivers/iio/dac/Kconfig
··· 152 152 This driver can also be built as a module. If so, the module 153 153 will be called max517. 154 154 155 + config MAX5821 156 + tristate "Maxim MAX5821 DAC driver" 157 + depends on I2C 158 + depends on OF 159 + help 160 + Say yes here to build support for Maxim MAX5821 161 + 10 bits DAC. 162 + 155 163 config MCP4725 156 164 tristate "MCP4725 DAC driver" 157 165 depends on I2C
+1
drivers/iio/dac/Makefile
··· 17 17 obj-$(CONFIG_AD5686) += ad5686.o 18 18 obj-$(CONFIG_AD7303) += ad7303.o 19 19 obj-$(CONFIG_MAX517) += max517.o 20 + obj-$(CONFIG_MAX5821) += max5821.o 20 21 obj-$(CONFIG_MCP4725) += mcp4725.o 21 22 obj-$(CONFIG_MCP4922) += mcp4922.o
+405
drivers/iio/dac/max5821.c
··· 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 + .owner = THIS_MODULE, 396 + }, 397 + .probe = max5821_probe, 398 + .remove = max5821_remove, 399 + .id_table = max5821_id, 400 + }; 401 + module_i2c_driver(max5821_driver); 402 + 403 + MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 404 + MODULE_DESCRIPTION("MAX5821 DAC"); 405 + MODULE_LICENSE("GPL v2");