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

Staging: iio: add driver for MAX517/518/519

IIO Driver for Maxim MAX517, MAX518 and MAX519 DAC

Signed-off-by: Roland Stigge <stigge@antcom.de>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Roland Stigge and committed by
Greg Kroah-Hartman
6ddc5fb4 18545cfd

+364
+41
drivers/staging/iio/Documentation/dac/max517
··· 1 + Kernel driver max517 2 + ==================== 3 + 4 + Supported chips: 5 + * Maxim MAX517, MAX518, MAX519 6 + Prefix: 'max517' 7 + Datasheet: Publicly available at the Maxim website 8 + http://www.maxim-ic.com/ 9 + 10 + Author: 11 + Roland Stigge <stigge@antcom.de> 12 + 13 + Description 14 + ----------- 15 + 16 + The Maxim MAX517/518/519 is an 8-bit DAC on the I2C bus. The following table 17 + shows the different feature sets of the variants MAX517, MAX518 and MAX519: 18 + 19 + Feature MAX517 MAX518 MAX519 20 + -------------------------------------------------------------------------- 21 + One output channel X 22 + Two output channels X X 23 + Simultaneous output updates X X 24 + Supply voltage as reference X 25 + Separate reference input X 26 + Reference input for each DAC X 27 + 28 + Via the iio sysfs interface, there are three attributes available: out1_raw, 29 + out2_raw and out12_raw. With out1_raw and out2_raw, the current output values 30 + (0..255) of the DACs can be written to the device. out12_raw can be used to set 31 + both output channel values simultaneously. 32 + 33 + With MAX517, only out1_raw is available. 34 + 35 + Via out1_scale (and where appropriate, out2_scale), the current scaling factor 36 + in mV can be read. 37 + 38 + When the operating system goes to a power down state, the Power Down function 39 + of the chip is activated, reducing the supply current to 4uA. 40 + 41 + On power-up, the device is in 0V-output state.
+10
drivers/staging/iio/dac/Kconfig
··· 19 19 20 20 To compile this driver as a module, choose M here: the 21 21 module will be called ad5446. 22 + 23 + config MAX517 24 + tristate "Maxim MAX517/518/519 DAC driver" 25 + depends on I2C && EXPERIMENTAL 26 + help 27 + If you say yes here you get support for the Maxim chips MAX517, 28 + MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs). 29 + 30 + This driver can also be built as a module. If so, the module 31 + will be called max517.
+1
drivers/staging/iio/dac/Makefile
··· 4 4 5 5 obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o 6 6 obj-$(CONFIG_AD5446) += ad5446.o 7 + obj-$(CONFIG_MAX517) += max517.o
+293
drivers/staging/iio/dac/max517.c
··· 1 + /* 2 + * max517.c - Support for Maxim MAX517, MAX518 and MAX519 3 + * 4 + * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/init.h> 23 + #include <linux/slab.h> 24 + #include <linux/jiffies.h> 25 + #include <linux/i2c.h> 26 + #include <linux/err.h> 27 + 28 + #include "../iio.h" 29 + #include "dac.h" 30 + 31 + #include "max517.h" 32 + 33 + #define MAX517_DRV_NAME "max517" 34 + 35 + /* Commands */ 36 + #define COMMAND_CHANNEL0 0x00 37 + #define COMMAND_CHANNEL1 0x01 /* for MAX518 and MAX519 */ 38 + #define COMMAND_PD 0x08 /* Power Down */ 39 + 40 + enum max517_device_ids { 41 + ID_MAX517, 42 + ID_MAX518, 43 + ID_MAX519, 44 + }; 45 + 46 + struct max517_data { 47 + struct iio_dev *indio_dev; 48 + unsigned short vref_mv[2]; 49 + }; 50 + 51 + /* 52 + * channel: bit 0: channel 1 53 + * bit 1: channel 2 54 + * (this way, it's possible to set both channels at once) 55 + */ 56 + static ssize_t max517_set_value(struct device *dev, 57 + struct device_attribute *attr, 58 + const char *buf, size_t count, int channel) 59 + { 60 + struct i2c_client *client = to_i2c_client(dev); 61 + u8 outbuf[4]; /* 1x or 2x command + value */ 62 + int outbuf_size = 0; 63 + int res; 64 + long val; 65 + 66 + res = strict_strtol(buf, 10, &val); 67 + 68 + if (res) 69 + return res; 70 + 71 + if (val < 0 || val > 255) 72 + return -EINVAL; 73 + 74 + if (channel & 1) { 75 + outbuf[outbuf_size++] = COMMAND_CHANNEL0; 76 + outbuf[outbuf_size++] = val; 77 + } 78 + if (channel & 2) { 79 + outbuf[outbuf_size++] = COMMAND_CHANNEL1; 80 + outbuf[outbuf_size++] = val; 81 + } 82 + 83 + /* 84 + * At this point, there are always 1 or 2 two-byte commands in 85 + * outbuf. With 2 commands, the device can set two outputs 86 + * simultaneously, latching the values upon the end of the I2C 87 + * transfer. 88 + */ 89 + 90 + res = i2c_master_send(client, outbuf, outbuf_size); 91 + if (res < 0) 92 + return res; 93 + 94 + return count; 95 + } 96 + 97 + static ssize_t max517_set_value_1(struct device *dev, 98 + struct device_attribute *attr, 99 + const char *buf, size_t count) 100 + { 101 + return max517_set_value(dev, attr, buf, count, 1); 102 + } 103 + static IIO_DEV_ATTR_OUT_RAW(1, max517_set_value_1, 0); 104 + 105 + static ssize_t max517_set_value_2(struct device *dev, 106 + struct device_attribute *attr, 107 + const char *buf, size_t count) 108 + { 109 + return max517_set_value(dev, attr, buf, count, 2); 110 + } 111 + static IIO_DEV_ATTR_OUT_RAW(2, max517_set_value_2, 1); 112 + 113 + static ssize_t max517_set_value_both(struct device *dev, 114 + struct device_attribute *attr, 115 + const char *buf, size_t count) 116 + { 117 + return max517_set_value(dev, attr, buf, count, 3); 118 + } 119 + static IIO_DEVICE_ATTR_NAMED(out1and2_raw, out1&2_raw, S_IWUSR, NULL, 120 + max517_set_value_both, -1); 121 + 122 + static ssize_t max517_show_scale(struct device *dev, 123 + struct device_attribute *attr, 124 + char *buf, int channel) 125 + { 126 + struct iio_dev *dev_info = dev_get_drvdata(dev); 127 + struct max517_data *data = iio_dev_get_devdata(dev_info); 128 + /* Corresponds to Vref / 2^(bits) */ 129 + unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8; 130 + 131 + return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); 132 + } 133 + 134 + static ssize_t max517_show_scale1(struct device *dev, 135 + struct device_attribute *attr, 136 + char *buf) 137 + { 138 + return max517_show_scale(dev, attr, buf, 1); 139 + } 140 + static IIO_DEVICE_ATTR(out1_scale, S_IRUGO, max517_show_scale1, NULL, 0); 141 + 142 + static ssize_t max517_show_scale2(struct device *dev, 143 + struct device_attribute *attr, 144 + char *buf) 145 + { 146 + return max517_show_scale(dev, attr, buf, 2); 147 + } 148 + static IIO_DEVICE_ATTR(out2_scale, S_IRUGO, max517_show_scale2, NULL, 0); 149 + 150 + /* On MAX517 variant, we have two outputs */ 151 + static struct attribute *max517_attributes[] = { 152 + &iio_dev_attr_out1_raw.dev_attr.attr, 153 + &iio_dev_attr_out1_scale.dev_attr.attr, 154 + NULL 155 + }; 156 + 157 + static struct attribute_group max517_attribute_group = { 158 + .attrs = max517_attributes, 159 + }; 160 + 161 + /* On MAX518 and MAX518 variant, we have two outputs */ 162 + static struct attribute *max518_attributes[] = { 163 + &iio_dev_attr_out1_raw.dev_attr.attr, 164 + &iio_dev_attr_out1_scale.dev_attr.attr, 165 + &iio_dev_attr_out2_raw.dev_attr.attr, 166 + &iio_dev_attr_out2_scale.dev_attr.attr, 167 + &iio_dev_attr_out1and2_raw.dev_attr.attr, 168 + NULL 169 + }; 170 + 171 + static struct attribute_group max518_attribute_group = { 172 + .attrs = max518_attributes, 173 + }; 174 + 175 + static int max517_suspend(struct i2c_client *client, pm_message_t mesg) 176 + { 177 + u8 outbuf = COMMAND_PD; 178 + 179 + return i2c_master_send(client, &outbuf, 1); 180 + } 181 + 182 + static int max517_resume(struct i2c_client *client) 183 + { 184 + u8 outbuf = 0; 185 + 186 + return i2c_master_send(client, &outbuf, 1); 187 + } 188 + 189 + static int max517_probe(struct i2c_client *client, 190 + const struct i2c_device_id *id) 191 + { 192 + struct max517_data *data; 193 + struct max517_platform_data *platform_data = client->dev.platform_data; 194 + int err; 195 + 196 + data = kzalloc(sizeof(struct max517_data), GFP_KERNEL); 197 + if (!data) { 198 + err = -ENOMEM; 199 + goto exit; 200 + } 201 + 202 + i2c_set_clientdata(client, data); 203 + 204 + data->indio_dev = iio_allocate_device(); 205 + if (data->indio_dev == NULL) { 206 + err = -ENOMEM; 207 + goto exit_free_data; 208 + } 209 + 210 + /* establish that the iio_dev is a child of the i2c device */ 211 + data->indio_dev->dev.parent = &client->dev; 212 + 213 + /* reduced attribute set for MAX517 */ 214 + if (id->driver_data == ID_MAX517) 215 + data->indio_dev->attrs = &max517_attribute_group; 216 + else 217 + data->indio_dev->attrs = &max518_attribute_group; 218 + data->indio_dev->dev_data = (void *)(data); 219 + data->indio_dev->driver_module = THIS_MODULE; 220 + data->indio_dev->modes = INDIO_DIRECT_MODE; 221 + 222 + /* 223 + * Reference voltage on MAX518 and default is 5V, else take vref_mv 224 + * from platform_data 225 + */ 226 + if (id->driver_data == ID_MAX518 || !platform_data) { 227 + data->vref_mv[0] = data->vref_mv[1] = 5000; /* mV */ 228 + } else { 229 + data->vref_mv[0] = platform_data->vref_mv[0]; 230 + data->vref_mv[1] = platform_data->vref_mv[1]; 231 + } 232 + 233 + err = iio_device_register(data->indio_dev); 234 + if (err) 235 + goto exit_free_device; 236 + 237 + dev_info(&client->dev, "DAC registered\n"); 238 + 239 + return 0; 240 + 241 + exit_free_device: 242 + iio_free_device(data->indio_dev); 243 + exit_free_data: 244 + kfree(data); 245 + exit: 246 + return err; 247 + } 248 + 249 + static int max517_remove(struct i2c_client *client) 250 + { 251 + struct max517_data *data = i2c_get_clientdata(client); 252 + 253 + iio_free_device(data->indio_dev); 254 + kfree(data); 255 + 256 + return 0; 257 + } 258 + 259 + static const struct i2c_device_id max517_id[] = { 260 + { "max517", ID_MAX517 }, 261 + { "max518", ID_MAX518 }, 262 + { "max519", ID_MAX519 }, 263 + { } 264 + }; 265 + MODULE_DEVICE_TABLE(i2c, max517_id); 266 + 267 + static struct i2c_driver max517_driver = { 268 + .driver = { 269 + .name = MAX517_DRV_NAME, 270 + }, 271 + .probe = max517_probe, 272 + .remove = max517_remove, 273 + .suspend = max517_suspend, 274 + .resume = max517_resume, 275 + .id_table = max517_id, 276 + }; 277 + 278 + static int __init max517_init(void) 279 + { 280 + return i2c_add_driver(&max517_driver); 281 + } 282 + 283 + static void __exit max517_exit(void) 284 + { 285 + i2c_del_driver(&max517_driver); 286 + } 287 + 288 + MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 289 + MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC"); 290 + MODULE_LICENSE("GPL"); 291 + 292 + module_init(max517_init); 293 + module_exit(max517_exit);
+19
drivers/staging/iio/dac/max517.h
··· 1 + /* 2 + * MAX517 DAC driver 3 + * 4 + * Copyright 2011 Roland Stigge <stigge@antcom.de> 5 + * 6 + * Licensed under the GPL-2 or later. 7 + */ 8 + #ifndef IIO_DAC_MAX517_H_ 9 + #define IIO_DAC_MAX517_H_ 10 + 11 + /* 12 + * TODO: struct max517_platform_data needs to go into include/linux/iio 13 + */ 14 + 15 + struct max517_platform_data { 16 + u16 vref_mv[2]; 17 + }; 18 + 19 + #endif /* IIO_DAC_MAX517_H_ */