aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/ads1015.c
diff options
context:
space:
mode:
authorDirk Eibach <eibach@gdsys.de>2011-03-21 12:59:37 -0400
committerJean Delvare <khali@endymion.delvare>2011-03-21 12:59:37 -0400
commitc0046867f34bb81ec3f237ebbc5241ae678b8379 (patch)
treea5d9e95c3fcd09a53dac9ce88abb00f4bef4a4fc /drivers/hwmon/ads1015.c
parentfdf241a8ed93236915c70717a4b6dfb856274496 (diff)
hwmon: (ads1015) Make gain and datarate configurable
Configuration for ads1015 gain and datarate is possible via devicetree or platform data. This is a followup patch to previous ads1015 patches on Jean Delvares tree. Signed-off-by: Dirk Eibach <eibach@gdsys.de> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/ads1015.c')
-rw-r--r--drivers/hwmon/ads1015.c149
1 files changed, 109 insertions, 40 deletions
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index fa02f20b79ff..e9beeda4cbe5 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -45,12 +45,18 @@ enum {
45static const unsigned int fullscale_table[8] = { 45static const unsigned int fullscale_table[8] = {
46 6144, 4096, 2048, 1024, 512, 256, 256, 256 }; 46 6144, 4096, 2048, 1024, 512, 256, 256, 256 };
47 47
48#define ADS1015_CONFIG_CHANNELS 8 48/* Data rates in samples per second */
49static const unsigned int data_rate_table[8] = {
50 128, 250, 490, 920, 1600, 2400, 3300, 3300 };
51
49#define ADS1015_DEFAULT_CHANNELS 0xff 52#define ADS1015_DEFAULT_CHANNELS 0xff
53#define ADS1015_DEFAULT_PGA 2
54#define ADS1015_DEFAULT_DATA_RATE 4
50 55
51struct ads1015_data { 56struct ads1015_data {
52 struct device *hwmon_dev; 57 struct device *hwmon_dev;
53 struct mutex update_lock; /* mutex protect updates */ 58 struct mutex update_lock; /* mutex protect updates */
59 struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
54}; 60};
55 61
56static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg) 62static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg)
@@ -71,40 +77,42 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
71{ 77{
72 u16 config; 78 u16 config;
73 s16 conversion; 79 s16 conversion;
74 unsigned int pga;
75 int fullscale;
76 unsigned int k;
77 struct ads1015_data *data = i2c_get_clientdata(client); 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;
78 int res; 85 int res;
79 86
80 mutex_lock(&data->update_lock); 87 mutex_lock(&data->update_lock);
81 88
82 /* get fullscale voltage */ 89 /* get channel parameters */
83 res = ads1015_read_reg(client, ADS1015_CONFIG); 90 res = ads1015_read_reg(client, ADS1015_CONFIG);
84 if (res < 0) 91 if (res < 0)
85 goto err_unlock; 92 goto err_unlock;
86 config = res; 93 config = res;
87 pga = (config >> 9) & 0x0007;
88 fullscale = fullscale_table[pga]; 94 fullscale = fullscale_table[pga];
95 conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
89 96
90 /* set channel and start single conversion */ 97 /* setup and start single conversion */
91 config &= ~(0x0007 << 12); 98 config &= 0x001f;
92 config |= (1 << 15) | (1 << 8) | (channel & 0x0007) << 12; 99 config |= (1 << 15) | (1 << 8);
100 config |= (channel & 0x0007) << 12;
101 config |= (pga & 0x0007) << 9;
102 config |= (data_rate & 0x0007) << 5;
93 103
94 /* wait until conversion finished */
95 res = ads1015_write_reg(client, ADS1015_CONFIG, config); 104 res = ads1015_write_reg(client, ADS1015_CONFIG, config);
96 if (res < 0) 105 if (res < 0)
97 goto err_unlock; 106 goto err_unlock;
98 for (k = 0; k < 5; ++k) { 107
99 msleep(1); 108 /* wait until conversion finished */
100 res = ads1015_read_reg(client, ADS1015_CONFIG); 109 msleep(conversion_time_ms);
101 if (res < 0) 110 res = ads1015_read_reg(client, ADS1015_CONFIG);
102 goto err_unlock; 111 if (res < 0)
103 config = res; 112 goto err_unlock;
104 if (config & (1 << 15)) 113 config = res;
105 break; 114 if (!(config & (1 << 15))) {
106 } 115 /* conversion not finished in time */
107 if (k == 5) {
108 res = -EIO; 116 res = -EIO;
109 goto err_unlock; 117 goto err_unlock;
110 } 118 }
@@ -160,35 +168,97 @@ static int ads1015_remove(struct i2c_client *client)
160 int k; 168 int k;
161 169
162 hwmon_device_unregister(data->hwmon_dev); 170 hwmon_device_unregister(data->hwmon_dev);
163 for (k = 0; k < ADS1015_CONFIG_CHANNELS; ++k) 171 for (k = 0; k < ADS1015_CHANNELS; ++k)
164 device_remove_file(&client->dev, &ads1015_in[k].dev_attr); 172 device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
165 kfree(data); 173 kfree(data);
166 return 0; 174 return 0;
167} 175}
168 176
169static unsigned int ads1015_get_exported_channels(struct i2c_client *client)
170{
171 struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev);
172#ifdef CONFIG_OF 177#ifdef CONFIG_OF
173 struct device_node *np = client->dev.of_node; 178static int ads1015_get_channels_config_of(struct i2c_client *client)
174 const __be32 *of_channels; 179{
175 int of_channels_size; 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}
176#endif 236#endif
177 237
238static 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
178 /* prefer platform data */ 244 /* prefer platform data */
179 if (pdata) 245 if (pdata) {
180 return pdata->exported_channels; 246 memcpy(data->channel_data, pdata->channel_data,
247 sizeof(data->channel_data));
248 return;
249 }
181 250
182#ifdef CONFIG_OF 251#ifdef CONFIG_OF
183 /* fallback on OF */ 252 if (!ads1015_get_channels_config_of(client))
184 of_channels = of_get_property(np, "exported-channels", 253 return;
185 &of_channels_size);
186 if (of_channels && (of_channels_size == sizeof(*of_channels)))
187 return be32_to_cpup(of_channels);
188#endif 254#endif
189 255
190 /* fallback on default configuration */ 256 /* fallback on default configuration */
191 return ADS1015_DEFAULT_CHANNELS; 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 }
192} 262}
193 263
194static int ads1015_probe(struct i2c_client *client, 264static int ads1015_probe(struct i2c_client *client,
@@ -196,7 +266,6 @@ static int ads1015_probe(struct i2c_client *client,
196{ 266{
197 struct ads1015_data *data; 267 struct ads1015_data *data;
198 int err; 268 int err;
199 unsigned int exported_channels;
200 unsigned int k; 269 unsigned int k;
201 270
202 data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL); 271 data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL);
@@ -209,9 +278,9 @@ static int ads1015_probe(struct i2c_client *client,
209 mutex_init(&data->update_lock); 278 mutex_init(&data->update_lock);
210 279
211 /* build sysfs attribute group */ 280 /* build sysfs attribute group */
212 exported_channels = ads1015_get_exported_channels(client); 281 ads1015_get_channels_config(client);
213 for (k = 0; k < ADS1015_CONFIG_CHANNELS; ++k) { 282 for (k = 0; k < ADS1015_CHANNELS; ++k) {
214 if (!(exported_channels & (1<<k))) 283 if (!data->channel_data[k].enabled)
215 continue; 284 continue;
216 err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); 285 err = device_create_file(&client->dev, &ads1015_in[k].dev_attr);
217 if (err) 286 if (err)
@@ -227,7 +296,7 @@ static int ads1015_probe(struct i2c_client *client,
227 return 0; 296 return 0;
228 297
229exit_remove: 298exit_remove:
230 for (k = 0; k < ADS1015_CONFIG_CHANNELS; ++k) 299 for (k = 0; k < ADS1015_CHANNELS; ++k)
231 device_remove_file(&client->dev, &ads1015_in[k].dev_attr); 300 device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
232exit_free: 301exit_free:
233 kfree(data); 302 kfree(data);