diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2012-06-04 05:36:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-05 01:02:25 -0400 |
commit | dbdc025bb239ce62c9b4d28c459a98f22ce9ec0a (patch) | |
tree | 2858c04b9d18852c1a4f4ca1c60c8e00b6180470 /drivers/iio/dac/max517.c | |
parent | 20374d1a36df3e20cd6742ba376684e5506254a8 (diff) |
staging:iio: Move DAC drivers out of staging
The IIO DAC drivers are in a reasonably good shape. They all make use of channel
spec and non of them provides non-documented sysfs attributes. Code style should
be OK as well, both checkpatch and coccicheck only report trivial issues.
So lets move the whole folder out of staging.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/iio/dac/max517.c')
-rw-r--r-- | drivers/iio/dac/max517.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c new file mode 100644 index 000000000000..92c77c82026c --- /dev/null +++ b/drivers/iio/dac/max517.c | |||
@@ -0,0 +1,243 @@ | |||
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 <linux/iio/iio.h> | ||
29 | #include <linux/iio/sysfs.h> | ||
30 | #include <linux/iio/dac/max517.h> | ||
31 | |||
32 | #define MAX517_DRV_NAME "max517" | ||
33 | |||
34 | /* Commands */ | ||
35 | #define COMMAND_CHANNEL0 0x00 | ||
36 | #define COMMAND_CHANNEL1 0x01 /* for MAX518 and MAX519 */ | ||
37 | #define COMMAND_PD 0x08 /* Power Down */ | ||
38 | |||
39 | enum max517_device_ids { | ||
40 | ID_MAX517, | ||
41 | ID_MAX518, | ||
42 | ID_MAX519, | ||
43 | }; | ||
44 | |||
45 | struct max517_data { | ||
46 | struct iio_dev *indio_dev; | ||
47 | struct i2c_client *client; | ||
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 int max517_set_value(struct iio_dev *indio_dev, | ||
57 | long val, int channel) | ||
58 | { | ||
59 | struct max517_data *data = iio_priv(indio_dev); | ||
60 | struct i2c_client *client = data->client; | ||
61 | u8 outbuf[2]; | ||
62 | int res; | ||
63 | |||
64 | if (val < 0 || val > 255) | ||
65 | return -EINVAL; | ||
66 | |||
67 | outbuf[0] = channel; | ||
68 | outbuf[1] = val; | ||
69 | |||
70 | res = i2c_master_send(client, outbuf, 2); | ||
71 | if (res < 0) | ||
72 | return res; | ||
73 | else if (res != 2) | ||
74 | return -EIO; | ||
75 | else | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int max517_read_raw(struct iio_dev *indio_dev, | ||
80 | struct iio_chan_spec const *chan, | ||
81 | int *val, | ||
82 | int *val2, | ||
83 | long m) | ||
84 | { | ||
85 | struct max517_data *data = iio_priv(indio_dev); | ||
86 | unsigned int scale_uv; | ||
87 | |||
88 | switch (m) { | ||
89 | case IIO_CHAN_INFO_SCALE: | ||
90 | /* Corresponds to Vref / 2^(bits) */ | ||
91 | scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8; | ||
92 | *val = scale_uv / 1000000; | ||
93 | *val2 = scale_uv % 1000000; | ||
94 | return IIO_VAL_INT_PLUS_MICRO; | ||
95 | default: | ||
96 | break; | ||
97 | } | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | |||
101 | static int max517_write_raw(struct iio_dev *indio_dev, | ||
102 | struct iio_chan_spec const *chan, int val, int val2, long mask) | ||
103 | { | ||
104 | int ret; | ||
105 | |||
106 | switch (mask) { | ||
107 | case IIO_CHAN_INFO_RAW: | ||
108 | ret = max517_set_value(indio_dev, val, chan->channel); | ||
109 | break; | ||
110 | default: | ||
111 | ret = -EINVAL; | ||
112 | break; | ||
113 | } | ||
114 | |||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | #ifdef CONFIG_PM_SLEEP | ||
119 | static int max517_suspend(struct device *dev) | ||
120 | { | ||
121 | u8 outbuf = COMMAND_PD; | ||
122 | |||
123 | return i2c_master_send(to_i2c_client(dev), &outbuf, 1); | ||
124 | } | ||
125 | |||
126 | static int max517_resume(struct device *dev) | ||
127 | { | ||
128 | u8 outbuf = 0; | ||
129 | |||
130 | return i2c_master_send(to_i2c_client(dev), &outbuf, 1); | ||
131 | } | ||
132 | |||
133 | static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume); | ||
134 | #define MAX517_PM_OPS (&max517_pm_ops) | ||
135 | #else | ||
136 | #define MAX517_PM_OPS NULL | ||
137 | #endif | ||
138 | |||
139 | static const struct iio_info max517_info = { | ||
140 | .read_raw = max517_read_raw, | ||
141 | .write_raw = max517_write_raw, | ||
142 | .driver_module = THIS_MODULE, | ||
143 | }; | ||
144 | |||
145 | #define MAX517_CHANNEL(chan) { \ | ||
146 | .type = IIO_VOLTAGE, \ | ||
147 | .indexed = 1, \ | ||
148 | .output = 1, \ | ||
149 | .channel = (chan), \ | ||
150 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | ||
151 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ | ||
152 | .scan_type = IIO_ST('u', 8, 8, 0), \ | ||
153 | } | ||
154 | |||
155 | static const struct iio_chan_spec max517_channels[] = { | ||
156 | MAX517_CHANNEL(0), | ||
157 | MAX517_CHANNEL(1) | ||
158 | }; | ||
159 | |||
160 | static int max517_probe(struct i2c_client *client, | ||
161 | const struct i2c_device_id *id) | ||
162 | { | ||
163 | struct max517_data *data; | ||
164 | struct iio_dev *indio_dev; | ||
165 | struct max517_platform_data *platform_data = client->dev.platform_data; | ||
166 | int err; | ||
167 | |||
168 | indio_dev = iio_device_alloc(sizeof(*data)); | ||
169 | if (indio_dev == NULL) { | ||
170 | err = -ENOMEM; | ||
171 | goto exit; | ||
172 | } | ||
173 | data = iio_priv(indio_dev); | ||
174 | i2c_set_clientdata(client, indio_dev); | ||
175 | data->client = client; | ||
176 | |||
177 | /* establish that the iio_dev is a child of the i2c device */ | ||
178 | indio_dev->dev.parent = &client->dev; | ||
179 | |||
180 | /* reduced channel set for MAX517 */ | ||
181 | if (id->driver_data == ID_MAX517) | ||
182 | indio_dev->num_channels = 1; | ||
183 | else | ||
184 | indio_dev->num_channels = 2; | ||
185 | indio_dev->channels = max517_channels; | ||
186 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
187 | indio_dev->info = &max517_info; | ||
188 | |||
189 | /* | ||
190 | * Reference voltage on MAX518 and default is 5V, else take vref_mv | ||
191 | * from platform_data | ||
192 | */ | ||
193 | if (id->driver_data == ID_MAX518 || !platform_data) { | ||
194 | data->vref_mv[0] = data->vref_mv[1] = 5000; /* mV */ | ||
195 | } else { | ||
196 | data->vref_mv[0] = platform_data->vref_mv[0]; | ||
197 | data->vref_mv[1] = platform_data->vref_mv[1]; | ||
198 | } | ||
199 | |||
200 | err = iio_device_register(indio_dev); | ||
201 | if (err) | ||
202 | goto exit_free_device; | ||
203 | |||
204 | dev_info(&client->dev, "DAC registered\n"); | ||
205 | |||
206 | return 0; | ||
207 | |||
208 | exit_free_device: | ||
209 | iio_device_free(indio_dev); | ||
210 | exit: | ||
211 | return err; | ||
212 | } | ||
213 | |||
214 | static int max517_remove(struct i2c_client *client) | ||
215 | { | ||
216 | iio_device_unregister(i2c_get_clientdata(client)); | ||
217 | iio_device_free(i2c_get_clientdata(client)); | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static const struct i2c_device_id max517_id[] = { | ||
223 | { "max517", ID_MAX517 }, | ||
224 | { "max518", ID_MAX518 }, | ||
225 | { "max519", ID_MAX519 }, | ||
226 | { } | ||
227 | }; | ||
228 | MODULE_DEVICE_TABLE(i2c, max517_id); | ||
229 | |||
230 | static struct i2c_driver max517_driver = { | ||
231 | .driver = { | ||
232 | .name = MAX517_DRV_NAME, | ||
233 | .pm = MAX517_PM_OPS, | ||
234 | }, | ||
235 | .probe = max517_probe, | ||
236 | .remove = max517_remove, | ||
237 | .id_table = max517_id, | ||
238 | }; | ||
239 | module_i2c_driver(max517_driver); | ||
240 | |||
241 | MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); | ||
242 | MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC"); | ||
243 | MODULE_LICENSE("GPL"); | ||