~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/hwmon/ads1015.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ads1015.c - lm_sensors driver for ads1015 12-bit 4-input ADC
 
3
 * (C) Copyright 2010
 
4
 * Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
 
5
 *
 
6
 * Based on the ads7828 driver by Steve Hardy.
 
7
 *
 
8
 * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads1015.pdf
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License as published by
 
12
 * the Free Software Foundation; either version 2 of the License, or
 
13
 * (at your option) any later version.
 
14
 *
 
15
 * This program is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 * GNU General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU General Public License
 
21
 * along with this program; if not, write to the Free Software
 
22
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
23
 */
 
24
 
 
25
#include <linux/module.h>
 
26
#include <linux/init.h>
 
27
#include <linux/slab.h>
 
28
#include <linux/delay.h>
 
29
#include <linux/i2c.h>
 
30
#include <linux/hwmon.h>
 
31
#include <linux/hwmon-sysfs.h>
 
32
#include <linux/err.h>
 
33
#include <linux/mutex.h>
 
34
#include <linux/of.h>
 
35
 
 
36
#include <linux/i2c/ads1015.h>
 
37
 
 
38
/* ADS1015 registers */
 
39
enum {
 
40
        ADS1015_CONVERSION = 0,
 
41
        ADS1015_CONFIG = 1,
 
42
};
 
43
 
 
44
/* PGA fullscale voltages in mV */
 
45
static const unsigned int fullscale_table[8] = {
 
46
        6144, 4096, 2048, 1024, 512, 256, 256, 256 };
 
47
 
 
48
/* Data rates in samples per second */
 
49
static const unsigned int data_rate_table[8] = {
 
50
        128, 250, 490, 920, 1600, 2400, 3300, 3300 };
 
51
 
 
52
#define ADS1015_DEFAULT_CHANNELS 0xff
 
53
#define ADS1015_DEFAULT_PGA 2
 
54
#define ADS1015_DEFAULT_DATA_RATE 4
 
55
 
 
56
struct ads1015_data {
 
57
        struct device *hwmon_dev;
 
58
        struct mutex update_lock; /* mutex protect updates */
 
59
        struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
 
60
};
 
61
 
 
62
static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg)
 
63
{
 
64
        s32 data = i2c_smbus_read_word_data(client, reg);
 
65
 
 
66
        return (data < 0) ? data : swab16(data);
 
67
}
 
68
 
 
69
static s32 ads1015_write_reg(struct i2c_client *client, unsigned int reg,
 
70
                             u16 val)
 
71
{
 
72
        return i2c_smbus_write_word_data(client, reg, swab16(val));
 
73
}
 
74
 
 
75
static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
 
76
                              int *value)
 
77
{
 
78
        u16 config;
 
79
        s16 conversion;
 
80
        struct ads1015_data *data = i2c_get_clientdata(client);
 
81
        unsigned int pga = data->channel_data[channel].pga;
 
82
        int fullscale;
 
83
        unsigned int data_rate = data->channel_data[channel].data_rate;
 
84
        unsigned int conversion_time_ms;
 
85
        int res;
 
86
 
 
87
        mutex_lock(&data->update_lock);
 
88
 
 
89
        /* get channel parameters */
 
90
        res = ads1015_read_reg(client, ADS1015_CONFIG);
 
91
        if (res < 0)
 
92
                goto err_unlock;
 
93
        config = res;
 
94
        fullscale = fullscale_table[pga];
 
95
        conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
 
96
 
 
97
        /* setup and start single conversion */
 
98
        config &= 0x001f;
 
99
        config |= (1 << 15) | (1 << 8);
 
100
        config |= (channel & 0x0007) << 12;
 
101
        config |= (pga & 0x0007) << 9;
 
102
        config |= (data_rate & 0x0007) << 5;
 
103
 
 
104
        res = ads1015_write_reg(client, ADS1015_CONFIG, config);
 
105
        if (res < 0)
 
106
                goto err_unlock;
 
107
 
 
108
        /* wait until conversion finished */
 
109
        msleep(conversion_time_ms);
 
110
        res = ads1015_read_reg(client, ADS1015_CONFIG);
 
111
        if (res < 0)
 
112
                goto err_unlock;
 
113
        config = res;
 
114
        if (!(config & (1 << 15))) {
 
115
                /* conversion not finished in time */
 
116
                res = -EIO;
 
117
                goto err_unlock;
 
118
        }
 
119
 
 
120
        res = ads1015_read_reg(client, ADS1015_CONVERSION);
 
121
        if (res < 0)
 
122
                goto err_unlock;
 
123
        conversion = res;
 
124
 
 
125
        mutex_unlock(&data->update_lock);
 
126
 
 
127
        *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
 
128
 
 
129
        return 0;
 
130
 
 
131
err_unlock:
 
132
        mutex_unlock(&data->update_lock);
 
133
        return res;
 
134
}
 
135
 
 
136
/* sysfs callback function */
 
137
static ssize_t show_in(struct device *dev, struct device_attribute *da,
 
138
        char *buf)
 
139
{
 
140
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 
141
        struct i2c_client *client = to_i2c_client(dev);
 
142
        int in;
 
143
        int res;
 
144
 
 
145
        res = ads1015_read_value(client, attr->index, &in);
 
146
 
 
147
        return (res < 0) ? res : sprintf(buf, "%d\n", in);
 
148
}
 
149
 
 
150
static const struct sensor_device_attribute ads1015_in[] = {
 
151
        SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
 
152
        SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
 
153
        SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
 
154
        SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
 
155
        SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
 
156
        SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
 
157
        SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
 
158
        SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
 
159
};
 
160
 
 
161
/*
 
162
 * Driver interface
 
163
 */
 
164
 
 
165
static int ads1015_remove(struct i2c_client *client)
 
166
{
 
167
        struct ads1015_data *data = i2c_get_clientdata(client);
 
168
        int k;
 
169
 
 
170
        hwmon_device_unregister(data->hwmon_dev);
 
171
        for (k = 0; k < ADS1015_CHANNELS; ++k)
 
172
                device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
 
173
        kfree(data);
 
174
        return 0;
 
175
}
 
176
 
 
177
#ifdef CONFIG_OF
 
178
static int ads1015_get_channels_config_of(struct i2c_client *client)
 
179
{
 
180
        struct ads1015_data *data = i2c_get_clientdata(client);
 
181
        struct device_node *node;
 
182
 
 
183
        if (!client->dev.of_node
 
184
            || !of_get_next_child(client->dev.of_node, NULL))
 
185
                return -EINVAL;
 
186
 
 
187
        for_each_child_of_node(client->dev.of_node, node) {
 
188
                const __be32 *property;
 
189
                int len;
 
190
                unsigned int channel;
 
191
                unsigned int pga = ADS1015_DEFAULT_PGA;
 
192
                unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
 
193
 
 
194
                property = of_get_property(node, "reg", &len);
 
195
                if (!property || len != sizeof(int)) {
 
196
                        dev_err(&client->dev, "invalid reg on %s\n",
 
197
                                node->full_name);
 
198
                        continue;
 
199
                }
 
200
 
 
201
                channel = be32_to_cpup(property);
 
202
                if (channel > ADS1015_CHANNELS) {
 
203
                        dev_err(&client->dev,
 
204
                                "invalid channel index %d on %s\n",
 
205
                                channel, node->full_name);
 
206
                        continue;
 
207
                }
 
208
 
 
209
                property = of_get_property(node, "ti,gain", &len);
 
210
                if (property && len == sizeof(int)) {
 
211
                        pga = be32_to_cpup(property);
 
212
                        if (pga > 6) {
 
213
                                dev_err(&client->dev,
 
214
                                        "invalid gain on %s\n",
 
215
                                        node->full_name);
 
216
                        }
 
217
                }
 
218
 
 
219
                property = of_get_property(node, "ti,datarate", &len);
 
220
                if (property && len == sizeof(int)) {
 
221
                        data_rate = be32_to_cpup(property);
 
222
                        if (data_rate > 7) {
 
223
                                dev_err(&client->dev,
 
224
                                        "invalid data_rate on %s\n",
 
225
                                        node->full_name);
 
226
                        }
 
227
                }
 
228
 
 
229
                data->channel_data[channel].enabled = true;
 
230
                data->channel_data[channel].pga = pga;
 
231
                data->channel_data[channel].data_rate = data_rate;
 
232
        }
 
233
 
 
234
        return 0;
 
235
}
 
236
#endif
 
237
 
 
238
static void ads1015_get_channels_config(struct i2c_client *client)
 
239
{
 
240
        unsigned int k;
 
241
        struct ads1015_data *data = i2c_get_clientdata(client);
 
242
        struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev);
 
243
 
 
244
        /* prefer platform data */
 
245
        if (pdata) {
 
246
                memcpy(data->channel_data, pdata->channel_data,
 
247
                       sizeof(data->channel_data));
 
248
                return;
 
249
        }
 
250
 
 
251
#ifdef CONFIG_OF
 
252
        if (!ads1015_get_channels_config_of(client))
 
253
                return;
 
254
#endif
 
255
 
 
256
        /* fallback on default configuration */
 
257
        for (k = 0; k < ADS1015_CHANNELS; ++k) {
 
258
                data->channel_data[k].enabled = true;
 
259
                data->channel_data[k].pga = ADS1015_DEFAULT_PGA;
 
260
                data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE;
 
261
        }
 
262
}
 
263
 
 
264
static int ads1015_probe(struct i2c_client *client,
 
265
                         const struct i2c_device_id *id)
 
266
{
 
267
        struct ads1015_data *data;
 
268
        int err;
 
269
        unsigned int k;
 
270
 
 
271
        data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL);
 
272
        if (!data) {
 
273
                err = -ENOMEM;
 
274
                goto exit;
 
275
        }
 
276
 
 
277
        i2c_set_clientdata(client, data);
 
278
        mutex_init(&data->update_lock);
 
279
 
 
280
        /* build sysfs attribute group */
 
281
        ads1015_get_channels_config(client);
 
282
        for (k = 0; k < ADS1015_CHANNELS; ++k) {
 
283
                if (!data->channel_data[k].enabled)
 
284
                        continue;
 
285
                err = device_create_file(&client->dev, &ads1015_in[k].dev_attr);
 
286
                if (err)
 
287
                        goto exit_free;
 
288
        }
 
289
 
 
290
        data->hwmon_dev = hwmon_device_register(&client->dev);
 
291
        if (IS_ERR(data->hwmon_dev)) {
 
292
                err = PTR_ERR(data->hwmon_dev);
 
293
                goto exit_remove;
 
294
        }
 
295
 
 
296
        return 0;
 
297
 
 
298
exit_remove:
 
299
        for (k = 0; k < ADS1015_CHANNELS; ++k)
 
300
                device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
 
301
exit_free:
 
302
        kfree(data);
 
303
exit:
 
304
        return err;
 
305
}
 
306
 
 
307
static const struct i2c_device_id ads1015_id[] = {
 
308
        { "ads1015", 0 },
 
309
        { }
 
310
};
 
311
MODULE_DEVICE_TABLE(i2c, ads1015_id);
 
312
 
 
313
static struct i2c_driver ads1015_driver = {
 
314
        .driver = {
 
315
                .name = "ads1015",
 
316
        },
 
317
        .probe = ads1015_probe,
 
318
        .remove = ads1015_remove,
 
319
        .id_table = ads1015_id,
 
320
};
 
321
 
 
322
static int __init sensors_ads1015_init(void)
 
323
{
 
324
        return i2c_add_driver(&ads1015_driver);
 
325
}
 
326
 
 
327
static void __exit sensors_ads1015_exit(void)
 
328
{
 
329
        i2c_del_driver(&ads1015_driver);
 
330
}
 
331
 
 
332
MODULE_AUTHOR("Dirk Eibach <eibach@gdsys.de>");
 
333
MODULE_DESCRIPTION("ADS1015 driver");
 
334
MODULE_LICENSE("GPL");
 
335
 
 
336
module_init(sensors_ads1015_init);
 
337
module_exit(sensors_ads1015_exit);