aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/hwmon/ads1015.txt88
-rw-r--r--Documentation/hwmon/ads101549
-rw-r--r--drivers/hwmon/ads1015.c149
-rw-r--r--include/linux/i2c/ads1015.h10
4 files changed, 211 insertions, 85 deletions
diff --git a/Documentation/devicetree/bindings/hwmon/ads1015.txt b/Documentation/devicetree/bindings/hwmon/ads1015.txt
index 0f30616384c5..918a507d1159 100644
--- a/Documentation/devicetree/bindings/hwmon/ads1015.txt
+++ b/Documentation/devicetree/bindings/hwmon/ads1015.txt
@@ -5,25 +5,69 @@ This device is a 12-bit A-D converter with 4 inputs.
5The inputs can be used single ended or in certain differential combinations. 5The inputs can be used single ended or in certain differential combinations.
6 6
7For configuration all possible combinations are mapped to 8 channels: 7For configuration all possible combinations are mapped to 8 channels:
80: Voltage over AIN0 and AIN1. 8 0: Voltage over AIN0 and AIN1.
91: Voltage over AIN0 and AIN3. 9 1: Voltage over AIN0 and AIN3.
102: Voltage over AIN1 and AIN3. 10 2: Voltage over AIN1 and AIN3.
113: Voltage over AIN2 and AIN3. 11 3: Voltage over AIN2 and AIN3.
124: Voltage over AIN0 and GND. 12 4: Voltage over AIN0 and GND.
135: Voltage over AIN1 and GND. 13 5: Voltage over AIN1 and GND.
146: Voltage over AIN2 and GND. 14 6: Voltage over AIN2 and GND.
157: Voltage over AIN3 and GND. 15 7: Voltage over AIN3 and GND.
16 16
17Optional properties: 17Each channel can be configured individually:
18 18 - pga is the programmable gain amplifier (values are full scale)
19 - exported-channels : exported_channels is a bitmask that specifies which 19 0: +/- 6.144 V
20 channels should be accessable by the user. 20 1: +/- 4.096 V
21 21 2: +/- 2.048 V (default)
22Example: 22 3: +/- 1.024 V
23ads1015@49 { 23 4: +/- 0.512 V
24 compatible = "ti,ads1015"; 24 5: +/- 0.256 V
25 reg = <0x49>; 25 - data_rate in samples per second
26 exported-channels = <0x14>; 26 0: 128
27}; 27 1: 250
28 28 2: 490
29In this example only channel 2 and 4 would be accessable by the user. 29 3: 920
30 4: 1600 (default)
31 5: 2400
32 6: 3300
33
341) The /ads1015 node
35
36 Required properties:
37
38 - compatible : must be "ti,ads1015"
39 - reg : I2C bus address of the device
40 - #address-cells : must be <1>
41 - #size-cells : must be <0>
42
43 The node contains child nodes for each channel that the platform uses.
44
45 Example ADS1015 node:
46
47 ads1015@49 {
48 compatible = "ti,ads1015";
49 reg = <0x49>;
50 #address-cells = <1>;
51 #size-cells = <0>;
52
53 [ child node definitions... ]
54 }
55
562) channel nodes
57
58 Required properties:
59
60 - reg : the channel number
61
62 Optional properties:
63
64 - ti,gain : the programmable gain amplifier setting
65 - ti,datarate : the converter data rate
66
67 Example ADS1015 channel node:
68
69 channel@4 {
70 reg = <4>;
71 ti,gain = <3>;
72 ti,datarate = <5>;
73 };
diff --git a/Documentation/hwmon/ads1015 b/Documentation/hwmon/ads1015
index 56ee7977b1a8..f6fe9c203733 100644
--- a/Documentation/hwmon/ads1015
+++ b/Documentation/hwmon/ads1015
@@ -19,7 +19,7 @@ This device is a 12-bit A-D converter with 4 inputs.
19 19
20The inputs can be used single ended or in certain differential combinations. 20The inputs can be used single ended or in certain differential combinations.
21 21
22The inputs can be exported to 8 sysfs input files in0_input - in7_input: 22The inputs can be made available by 8 sysfs input files in0_input - in7_input:
23in0: Voltage over AIN0 and AIN1. 23in0: Voltage over AIN0 and AIN1.
24in1: Voltage over AIN0 and AIN3. 24in1: Voltage over AIN0 and AIN3.
25in2: Voltage over AIN1 and AIN3. 25in2: Voltage over AIN1 and AIN3.
@@ -29,39 +29,44 @@ in5: Voltage over AIN1 and GND.
29in6: Voltage over AIN2 and GND. 29in6: Voltage over AIN2 and GND.
30in7: Voltage over AIN3 and GND. 30in7: Voltage over AIN3 and GND.
31 31
32Which inputs are exported can be configured using platform data or devicetree. 32Which inputs are available can be configured using platform data or devicetree.
33 33
34By default all inputs are exported. 34By default all inputs are exported.
35 35
36Platform Data 36Platform Data
37------------- 37-------------
38 38
39In linux/i2c/ads1015.h platform data is defined as: 39In linux/i2c/ads1015.h platform data is defined, channel_data contains
40 40configuration data for the used input combinations:
41struct ads1015_platform_data { 41- pga is the programmable gain amplifier (values are full scale)
42 unsigned int exported_channels; 42 0: +/- 6.144 V
43}; 43 1: +/- 4.096 V
44 44 2: +/- 2.048 V
45exported_channels is a bitmask that specifies which inputs should be exported. 45 3: +/- 1.024 V
46 4: +/- 0.512 V
47 5: +/- 0.256 V
48- data_rate in samples per second
49 0: 128
50 1: 250
51 2: 490
52 3: 920
53 4: 1600
54 5: 2400
55 6: 3300
46 56
47Example: 57Example:
48struct ads1015_platform_data data = { 58struct ads1015_platform_data data = {
49 .exported_channels = (1 << 2) | (1 << 4) 59 .channel_data = {
60 [2] = { .enabled = true, .pga = 1, .data_rate = 0 },
61 [4] = { .enabled = true, .pga = 4, .data_rate = 5 },
62 }
50}; 63};
51 64
52In this case only in2_input and in4_input would be created. 65In this case only in2_input (FS +/- 4.096 V, 128 SPS) and in4_input
66(FS +/- 0.512 V, 2400 SPS) would be created.
53 67
54Devicetree 68Devicetree
55---------- 69----------
56 70
57The ads1015 node may have an "exported-channels" property. 71Configuration is also possible via devicetree:
58exported_channels is a bitmask that specifies which inputs should be exported. 72Documentation/devicetree/bindings/hwmon/ads1015.txt
59
60Example:
61ads1015@49 {
62 compatible = "ti,ads1015";
63 reg = <0x49>;
64 exported-channels = < 0x14 >;
65};
66
67In this case only in2_input and in4_input would be created.
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);
diff --git a/include/linux/i2c/ads1015.h b/include/linux/i2c/ads1015.h
index 8541c6acfafd..d5aa2a045669 100644
--- a/include/linux/i2c/ads1015.h
+++ b/include/linux/i2c/ads1015.h
@@ -21,8 +21,16 @@
21#ifndef LINUX_ADS1015_H 21#ifndef LINUX_ADS1015_H
22#define LINUX_ADS1015_H 22#define LINUX_ADS1015_H
23 23
24#define ADS1015_CHANNELS 8
25
26struct ads1015_channel_data {
27 bool enabled;
28 unsigned int pga;
29 unsigned int data_rate;
30};
31
24struct ads1015_platform_data { 32struct ads1015_platform_data {
25 unsigned int exported_channels; 33 struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
26}; 34};
27 35
28#endif /* LINUX_ADS1015_H */ 36#endif /* LINUX_ADS1015_H */