1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
36#define COMMAND_CHANNEL0 0x00
37#define COMMAND_CHANNEL1 0x01
38#define COMMAND_PD 0x08
39
40enum max517_device_ids {
41 ID_MAX517,
42 ID_MAX518,
43 ID_MAX519,
44};
45
46struct max517_data {
47 struct iio_dev *indio_dev;
48 struct i2c_client *client;
49 unsigned short vref_mv[2];
50};
51
52
53
54
55
56
57static ssize_t max517_set_value(struct device *dev,
58 struct device_attribute *attr,
59 const char *buf, size_t count, int channel)
60{
61 struct iio_dev *dev_info = dev_get_drvdata(dev);
62 struct max517_data *data = iio_dev_get_devdata(dev_info);
63 struct i2c_client *client = data->client;
64 u8 outbuf[4];
65 int outbuf_size = 0;
66 int res;
67 long val;
68
69 res = strict_strtol(buf, 10, &val);
70
71 if (res)
72 return res;
73
74 if (val < 0 || val > 255)
75 return -EINVAL;
76
77 if (channel & 1) {
78 outbuf[outbuf_size++] = COMMAND_CHANNEL0;
79 outbuf[outbuf_size++] = val;
80 }
81 if (channel & 2) {
82 outbuf[outbuf_size++] = COMMAND_CHANNEL1;
83 outbuf[outbuf_size++] = val;
84 }
85
86
87
88
89
90
91
92
93 res = i2c_master_send(client, outbuf, outbuf_size);
94 if (res < 0)
95 return res;
96
97 return count;
98}
99
100static ssize_t max517_set_value_1(struct device *dev,
101 struct device_attribute *attr,
102 const char *buf, size_t count)
103{
104 return max517_set_value(dev, attr, buf, count, 1);
105}
106static IIO_DEV_ATTR_OUT_RAW(1, max517_set_value_1, 0);
107
108static ssize_t max517_set_value_2(struct device *dev,
109 struct device_attribute *attr,
110 const char *buf, size_t count)
111{
112 return max517_set_value(dev, attr, buf, count, 2);
113}
114static IIO_DEV_ATTR_OUT_RAW(2, max517_set_value_2, 1);
115
116static ssize_t max517_set_value_both(struct device *dev,
117 struct device_attribute *attr,
118 const char *buf, size_t count)
119{
120 return max517_set_value(dev, attr, buf, count, 3);
121}
122static IIO_DEVICE_ATTR_NAMED(out1and2_raw, out1&2_raw, S_IWUSR, NULL,
123 max517_set_value_both, -1);
124
125static ssize_t max517_show_scale(struct device *dev,
126 struct device_attribute *attr,
127 char *buf, int channel)
128{
129 struct iio_dev *dev_info = dev_get_drvdata(dev);
130 struct max517_data *data = iio_dev_get_devdata(dev_info);
131
132 unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8;
133
134 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
135}
136
137static ssize_t max517_show_scale1(struct device *dev,
138 struct device_attribute *attr,
139 char *buf)
140{
141 return max517_show_scale(dev, attr, buf, 1);
142}
143static IIO_DEVICE_ATTR(out1_scale, S_IRUGO, max517_show_scale1, NULL, 0);
144
145static ssize_t max517_show_scale2(struct device *dev,
146 struct device_attribute *attr,
147 char *buf)
148{
149 return max517_show_scale(dev, attr, buf, 2);
150}
151static IIO_DEVICE_ATTR(out2_scale, S_IRUGO, max517_show_scale2, NULL, 0);
152
153
154static struct attribute *max517_attributes[] = {
155 &iio_dev_attr_out1_raw.dev_attr.attr,
156 &iio_dev_attr_out1_scale.dev_attr.attr,
157 NULL
158};
159
160static struct attribute_group max517_attribute_group = {
161 .attrs = max517_attributes,
162};
163
164
165static struct attribute *max518_attributes[] = {
166 &iio_dev_attr_out1_raw.dev_attr.attr,
167 &iio_dev_attr_out1_scale.dev_attr.attr,
168 &iio_dev_attr_out2_raw.dev_attr.attr,
169 &iio_dev_attr_out2_scale.dev_attr.attr,
170 &iio_dev_attr_out1and2_raw.dev_attr.attr,
171 NULL
172};
173
174static struct attribute_group max518_attribute_group = {
175 .attrs = max518_attributes,
176};
177
178static int max517_suspend(struct i2c_client *client, pm_message_t mesg)
179{
180 u8 outbuf = COMMAND_PD;
181
182 return i2c_master_send(client, &outbuf, 1);
183}
184
185static int max517_resume(struct i2c_client *client)
186{
187 u8 outbuf = 0;
188
189 return i2c_master_send(client, &outbuf, 1);
190}
191
192static int max517_probe(struct i2c_client *client,
193 const struct i2c_device_id *id)
194{
195 struct max517_data *data;
196 struct max517_platform_data *platform_data = client->dev.platform_data;
197 int err;
198
199 data = kzalloc(sizeof(struct max517_data), GFP_KERNEL);
200 if (!data) {
201 err = -ENOMEM;
202 goto exit;
203 }
204
205 i2c_set_clientdata(client, data);
206
207 data->client = client;
208
209 data->indio_dev = iio_allocate_device();
210 if (data->indio_dev == NULL) {
211 err = -ENOMEM;
212 goto exit_free_data;
213 }
214
215
216 data->indio_dev->dev.parent = &client->dev;
217
218
219 if (id->driver_data == ID_MAX517)
220 data->indio_dev->attrs = &max517_attribute_group;
221 else
222 data->indio_dev->attrs = &max518_attribute_group;
223 data->indio_dev->dev_data = (void *)(data);
224 data->indio_dev->driver_module = THIS_MODULE;
225 data->indio_dev->modes = INDIO_DIRECT_MODE;
226
227
228
229
230
231 if (id->driver_data == ID_MAX518 || !platform_data) {
232 data->vref_mv[0] = data->vref_mv[1] = 5000;
233 } else {
234 data->vref_mv[0] = platform_data->vref_mv[0];
235 data->vref_mv[1] = platform_data->vref_mv[1];
236 }
237
238 err = iio_device_register(data->indio_dev);
239 if (err)
240 goto exit_free_device;
241
242 dev_info(&client->dev, "DAC registered\n");
243
244 return 0;
245
246exit_free_device:
247 iio_free_device(data->indio_dev);
248exit_free_data:
249 kfree(data);
250exit:
251 return err;
252}
253
254static int max517_remove(struct i2c_client *client)
255{
256 struct max517_data *data = i2c_get_clientdata(client);
257
258 iio_free_device(data->indio_dev);
259 kfree(data);
260
261 return 0;
262}
263
264static const struct i2c_device_id max517_id[] = {
265 { "max517", ID_MAX517 },
266 { "max518", ID_MAX518 },
267 { "max519", ID_MAX519 },
268 { }
269};
270MODULE_DEVICE_TABLE(i2c, max517_id);
271
272static struct i2c_driver max517_driver = {
273 .driver = {
274 .name = MAX517_DRV_NAME,
275 },
276 .probe = max517_probe,
277 .remove = max517_remove,
278 .suspend = max517_suspend,
279 .resume = max517_resume,
280 .id_table = max517_id,
281};
282
283static int __init max517_init(void)
284{
285 return i2c_add_driver(&max517_driver);
286}
287
288static void __exit max517_exit(void)
289{
290 i2c_del_driver(&max517_driver);
291}
292
293MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
294MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC");
295MODULE_LICENSE("GPL");
296
297module_init(max517_init);
298module_exit(max517_exit);
299