Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dirk Eibach and committed by
Jean Delvare
c0046867 fdf241a8

+207 -81
+62 -18
Documentation/devicetree/bindings/hwmon/ads1015.txt
··· 5 5 The inputs can be used single ended or in certain differential combinations. 6 6 7 7 For configuration all possible combinations are mapped to 8 channels: 8 - 0: Voltage over AIN0 and AIN1. 9 - 1: Voltage over AIN0 and AIN3. 10 - 2: Voltage over AIN1 and AIN3. 11 - 3: Voltage over AIN2 and AIN3. 12 - 4: Voltage over AIN0 and GND. 13 - 5: Voltage over AIN1 and GND. 14 - 6: Voltage over AIN2 and GND. 15 - 7: Voltage over AIN3 and GND. 8 + 0: Voltage over AIN0 and AIN1. 9 + 1: Voltage over AIN0 and AIN3. 10 + 2: Voltage over AIN1 and AIN3. 11 + 3: Voltage over AIN2 and AIN3. 12 + 4: Voltage over AIN0 and GND. 13 + 5: Voltage over AIN1 and GND. 14 + 6: Voltage over AIN2 and GND. 15 + 7: Voltage over AIN3 and GND. 16 16 17 - Optional properties: 17 + Each channel can be configured individually: 18 + - pga is the programmable gain amplifier (values are full scale) 19 + 0: +/- 6.144 V 20 + 1: +/- 4.096 V 21 + 2: +/- 2.048 V (default) 22 + 3: +/- 1.024 V 23 + 4: +/- 0.512 V 24 + 5: +/- 0.256 V 25 + - data_rate in samples per second 26 + 0: 128 27 + 1: 250 28 + 2: 490 29 + 3: 920 30 + 4: 1600 (default) 31 + 5: 2400 32 + 6: 3300 18 33 19 - - exported-channels : exported_channels is a bitmask that specifies which 20 - channels should be accessable by the user. 34 + 1) The /ads1015 node 21 35 22 - Example: 23 - ads1015@49 { 24 - compatible = "ti,ads1015"; 25 - reg = <0x49>; 26 - exported-channels = <0x14>; 27 - }; 36 + Required properties: 28 37 29 - In this example only channel 2 and 4 would be accessable by the user. 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 + 56 + 2) 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 + };
+27 -22
Documentation/hwmon/ads1015
··· 19 19 20 20 The inputs can be used single ended or in certain differential combinations. 21 21 22 - The inputs can be exported to 8 sysfs input files in0_input - in7_input: 22 + The inputs can be made available by 8 sysfs input files in0_input - in7_input: 23 23 in0: Voltage over AIN0 and AIN1. 24 24 in1: Voltage over AIN0 and AIN3. 25 25 in2: Voltage over AIN1 and AIN3. ··· 29 29 in6: Voltage over AIN2 and GND. 30 30 in7: Voltage over AIN3 and GND. 31 31 32 - Which inputs are exported can be configured using platform data or devicetree. 32 + Which inputs are available can be configured using platform data or devicetree. 33 33 34 34 By default all inputs are exported. 35 35 36 36 Platform Data 37 37 ------------- 38 38 39 - In linux/i2c/ads1015.h platform data is defined as: 40 - 41 - struct ads1015_platform_data { 42 - unsigned int exported_channels; 43 - }; 44 - 45 - exported_channels is a bitmask that specifies which inputs should be exported. 39 + In linux/i2c/ads1015.h platform data is defined, channel_data contains 40 + configuration data for the used input combinations: 41 + - pga is the programmable gain amplifier (values are full scale) 42 + 0: +/- 6.144 V 43 + 1: +/- 4.096 V 44 + 2: +/- 2.048 V 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 47 57 Example: 48 58 struct 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 52 - In this case only in2_input and in4_input would be created. 65 + In 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 54 68 Devicetree 55 69 ---------- 56 70 57 - The ads1015 node may have an "exported-channels" property. 58 - exported_channels is a bitmask that specifies which inputs should be exported. 59 - 60 - Example: 61 - ads1015@49 { 62 - compatible = "ti,ads1015"; 63 - reg = <0x49>; 64 - exported-channels = < 0x14 >; 65 - }; 66 - 67 - In this case only in2_input and in4_input would be created. 71 + Configuration is also possible via devicetree: 72 + Documentation/devicetree/bindings/hwmon/ads1015.txt
+109 -40
drivers/hwmon/ads1015.c
··· 45 45 static const unsigned int fullscale_table[8] = { 46 46 6144, 4096, 2048, 1024, 512, 256, 256, 256 }; 47 47 48 - #define ADS1015_CONFIG_CHANNELS 8 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 + 49 52 #define ADS1015_DEFAULT_CHANNELS 0xff 53 + #define ADS1015_DEFAULT_PGA 2 54 + #define ADS1015_DEFAULT_DATA_RATE 4 50 55 51 56 struct ads1015_data { 52 57 struct device *hwmon_dev; 53 58 struct mutex update_lock; /* mutex protect updates */ 59 + struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; 54 60 }; 55 61 56 62 static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg) ··· 77 71 { 78 72 u16 config; 79 73 s16 conversion; 80 - unsigned int pga; 81 - int fullscale; 82 - unsigned int k; 83 74 struct ads1015_data *data = i2c_get_clientdata(client); 75 + unsigned int pga = data->channel_data[channel].pga; 76 + int fullscale; 77 + unsigned int data_rate = data->channel_data[channel].data_rate; 78 + unsigned int conversion_time_ms; 84 79 int res; 85 80 86 81 mutex_lock(&data->update_lock); 87 82 88 - /* get fullscale voltage */ 83 + /* get channel parameters */ 89 84 res = ads1015_read_reg(client, ADS1015_CONFIG); 90 85 if (res < 0) 91 86 goto err_unlock; 92 87 config = res; 93 - pga = (config >> 9) & 0x0007; 94 88 fullscale = fullscale_table[pga]; 89 + conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); 95 90 96 - /* set channel and start single conversion */ 97 - config &= ~(0x0007 << 12); 98 - config |= (1 << 15) | (1 << 8) | (channel & 0x0007) << 12; 91 + /* setup and start single conversion */ 92 + config &= 0x001f; 93 + config |= (1 << 15) | (1 << 8); 94 + config |= (channel & 0x0007) << 12; 95 + config |= (pga & 0x0007) << 9; 96 + config |= (data_rate & 0x0007) << 5; 99 97 100 - /* wait until conversion finished */ 101 98 res = ads1015_write_reg(client, ADS1015_CONFIG, config); 102 99 if (res < 0) 103 100 goto err_unlock; 104 - for (k = 0; k < 5; ++k) { 105 - msleep(1); 106 - res = ads1015_read_reg(client, ADS1015_CONFIG); 107 - if (res < 0) 108 - goto err_unlock; 109 - config = res; 110 - if (config & (1 << 15)) 111 - break; 112 - } 113 - if (k == 5) { 101 + 102 + /* wait until conversion finished */ 103 + msleep(conversion_time_ms); 104 + res = ads1015_read_reg(client, ADS1015_CONFIG); 105 + if (res < 0) 106 + goto err_unlock; 107 + config = res; 108 + if (!(config & (1 << 15))) { 109 + /* conversion not finished in time */ 114 110 res = -EIO; 115 111 goto err_unlock; 116 112 } ··· 168 160 int k; 169 161 170 162 hwmon_device_unregister(data->hwmon_dev); 171 - for (k = 0; k < ADS1015_CONFIG_CHANNELS; ++k) 163 + for (k = 0; k < ADS1015_CHANNELS; ++k) 172 164 device_remove_file(&client->dev, &ads1015_in[k].dev_attr); 173 165 kfree(data); 174 166 return 0; 175 167 } 176 168 177 - static unsigned int ads1015_get_exported_channels(struct i2c_client *client) 178 - { 179 - struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev); 180 169 #ifdef CONFIG_OF 181 - struct device_node *np = client->dev.of_node; 182 - const __be32 *of_channels; 183 - int of_channels_size; 170 + static int ads1015_get_channels_config_of(struct i2c_client *client) 171 + { 172 + struct ads1015_data *data = i2c_get_clientdata(client); 173 + struct device_node *node; 174 + 175 + if (!client->dev.of_node 176 + || !of_get_next_child(client->dev.of_node, NULL)) 177 + return -EINVAL; 178 + 179 + for_each_child_of_node(client->dev.of_node, node) { 180 + const __be32 *property; 181 + int len; 182 + unsigned int channel; 183 + unsigned int pga = ADS1015_DEFAULT_PGA; 184 + unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE; 185 + 186 + property = of_get_property(node, "reg", &len); 187 + if (!property || len != sizeof(int)) { 188 + dev_err(&client->dev, "invalid reg on %s\n", 189 + node->full_name); 190 + continue; 191 + } 192 + 193 + channel = be32_to_cpup(property); 194 + if (channel > ADS1015_CHANNELS) { 195 + dev_err(&client->dev, 196 + "invalid channel index %d on %s\n", 197 + channel, node->full_name); 198 + continue; 199 + } 200 + 201 + property = of_get_property(node, "ti,gain", &len); 202 + if (property && len == sizeof(int)) { 203 + pga = be32_to_cpup(property); 204 + if (pga > 6) { 205 + dev_err(&client->dev, 206 + "invalid gain on %s\n", 207 + node->full_name); 208 + } 209 + } 210 + 211 + property = of_get_property(node, "ti,datarate", &len); 212 + if (property && len == sizeof(int)) { 213 + data_rate = be32_to_cpup(property); 214 + if (data_rate > 7) { 215 + dev_err(&client->dev, 216 + "invalid data_rate on %s\n", 217 + node->full_name); 218 + } 219 + } 220 + 221 + data->channel_data[channel].enabled = true; 222 + data->channel_data[channel].pga = pga; 223 + data->channel_data[channel].data_rate = data_rate; 224 + } 225 + 226 + return 0; 227 + } 184 228 #endif 185 229 230 + static void ads1015_get_channels_config(struct i2c_client *client) 231 + { 232 + unsigned int k; 233 + struct ads1015_data *data = i2c_get_clientdata(client); 234 + struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev); 235 + 186 236 /* prefer platform data */ 187 - if (pdata) 188 - return pdata->exported_channels; 237 + if (pdata) { 238 + memcpy(data->channel_data, pdata->channel_data, 239 + sizeof(data->channel_data)); 240 + return; 241 + } 189 242 190 243 #ifdef CONFIG_OF 191 - /* fallback on OF */ 192 - of_channels = of_get_property(np, "exported-channels", 193 - &of_channels_size); 194 - if (of_channels && (of_channels_size == sizeof(*of_channels))) 195 - return be32_to_cpup(of_channels); 244 + if (!ads1015_get_channels_config_of(client)) 245 + return; 196 246 #endif 197 247 198 248 /* fallback on default configuration */ 199 - return ADS1015_DEFAULT_CHANNELS; 249 + for (k = 0; k < ADS1015_CHANNELS; ++k) { 250 + data->channel_data[k].enabled = true; 251 + data->channel_data[k].pga = ADS1015_DEFAULT_PGA; 252 + data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE; 253 + } 200 254 } 201 255 202 256 static int ads1015_probe(struct i2c_client *client, ··· 266 196 { 267 197 struct ads1015_data *data; 268 198 int err; 269 - unsigned int exported_channels; 270 199 unsigned int k; 271 200 272 201 data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL); ··· 278 209 mutex_init(&data->update_lock); 279 210 280 211 /* build sysfs attribute group */ 281 - exported_channels = ads1015_get_exported_channels(client); 282 - for (k = 0; k < ADS1015_CONFIG_CHANNELS; ++k) { 283 - if (!(exported_channels & (1<<k))) 212 + ads1015_get_channels_config(client); 213 + for (k = 0; k < ADS1015_CHANNELS; ++k) { 214 + if (!data->channel_data[k].enabled) 284 215 continue; 285 216 err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); 286 217 if (err) ··· 296 227 return 0; 297 228 298 229 exit_remove: 299 - for (k = 0; k < ADS1015_CONFIG_CHANNELS; ++k) 230 + for (k = 0; k < ADS1015_CHANNELS; ++k) 300 231 device_remove_file(&client->dev, &ads1015_in[k].dev_attr); 301 232 exit_free: 302 233 kfree(data);
+9 -1
include/linux/i2c/ads1015.h
··· 21 21 #ifndef LINUX_ADS1015_H 22 22 #define LINUX_ADS1015_H 23 23 24 + #define ADS1015_CHANNELS 8 25 + 26 + struct ads1015_channel_data { 27 + bool enabled; 28 + unsigned int pga; 29 + unsigned int data_rate; 30 + }; 31 + 24 32 struct ads1015_platform_data { 25 - unsigned int exported_channels; 33 + struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; 26 34 }; 27 35 28 36 #endif /* LINUX_ADS1015_H */