1 /* 2 * Maxim MAX197 A/D Converter driver 3 * 4 * Copyright (c) 2012 Savoir-faire Linux Inc. 5 * Vivien Didelot <vivien.didelot@savoirfairelinux.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * For further information, see the Documentation/hwmon/max197.rst file. 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/mod_devicetable.h> 17 #include <linux/init.h> 18 #include <linux/err.h> 19 #include <linux/slab.h> 20 #include <linux/mutex.h> 21 #include <linux/device.h> 22 #include <linux/sysfs.h> 23 #include <linux/hwmon.h> 24 #include <linux/hwmon-sysfs.h> 25 #include <linux/platform_device.h> 26 #include <linux/platform_data/max197.h> 27 28 #define MAX199_LIMIT 4000 /* 4V */ 29 #define MAX197_LIMIT 10000 /* 10V */ 30 31 #define MAX197_NUM_CH 8 /* 8 Analog Input Channels */ 32 33 /* Control byte format */ 34 #define MAX197_BIP (1 << 3) /* Bipolarity */ 35 #define MAX197_RNG (1 << 4) /* Full range */ 36 37 #define MAX197_SCALE 12207 /* Scale coefficient for raw data */ 38 39 /* List of supported chips */ 40 enum max197_chips { max197, max199 }; 41 42 /** 43 * struct max197_data - device instance specific data 44 * @pdata: Platform data. 45 * @hwmon_dev: The hwmon device. 46 * @lock: Read/Write mutex. 47 * @limit: Max range value (10V for MAX197, 4V for MAX199). 48 * @scale: Need to scale. 49 * @ctrl_bytes: Channels control byte. 50 */ 51 struct max197_data { 52 struct max197_platform_data *pdata; 53 struct device *hwmon_dev; 54 struct mutex lock; 55 int limit; 56 bool scale; 57 u8 ctrl_bytes[MAX197_NUM_CH]; 58 }; 59 60 static inline void max197_set_unipolarity(struct max197_data *data, int channel) 61 { 62 data->ctrl_bytes[channel] &= ~MAX197_BIP; 63 } 64 65 static inline void max197_set_bipolarity(struct max197_data *data, int channel) 66 { 67 data->ctrl_bytes[channel] |= MAX197_BIP; 68 } 69 70 static inline void max197_set_half_range(struct max197_data *data, int channel) 71 { 72 data->ctrl_bytes[channel] &= ~MAX197_RNG; 73 } 74 75 static inline void max197_set_full_range(struct max197_data *data, int channel) 76 { 77 data->ctrl_bytes[channel] |= MAX197_RNG; 78 } 79 80 static inline bool max197_is_bipolar(struct max197_data *data, int channel) 81 { 82 return data->ctrl_bytes[channel] & MAX197_BIP; 83 } 84 85 static inline bool max197_is_full_range(struct max197_data *data, int channel) 86 { 87 return data->ctrl_bytes[channel] & MAX197_RNG; 88 } 89 90 /* Function called on read access on in{0,1,2,3,4,5,6,7}_{min,max} */ 91 static ssize_t max197_show_range(struct device *dev, 92 struct device_attribute *devattr, char *buf) 93 { 94 struct max197_data *data = dev_get_drvdata(dev); 95 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 96 int channel = attr->index; 97 bool is_min = attr->nr; 98 int range; 99 100 if (mutex_lock_interruptible(&data->lock)) 101 return -ERESTARTSYS; 102 103 range = max197_is_full_range(data, channel) ? 104 data->limit : data->limit / 2; 105 if (is_min) { 106 if (max197_is_bipolar(data, channel)) 107 range = -range; 108 else 109 range = 0; 110 } 111 112 mutex_unlock(&data->lock); 113 114 return sprintf(buf, "%d\n", range); 115 } 116 117 /* Function called on write access on in{0,1,2,3,4,5,6,7}_{min,max} */ 118 static ssize_t max197_store_range(struct device *dev, 119 struct device_attribute *devattr, 120 const char *buf, size_t count) 121 { 122 struct max197_data *data = dev_get_drvdata(dev); 123 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 124 int channel = attr->index; 125 bool is_min = attr->nr; 126 long value; 127 int half = data->limit / 2; 128 int full = data->limit; 129 130 if (kstrtol(buf, 10, &value)) 131 return -EINVAL; 132 133 if (is_min) { 134 if (value <= -full) 135 value = -full; 136 else if (value < 0) 137 value = -half; 138 else 139 value = 0; 140 } else { 141 if (value >= full) 142 value = full; 143 else 144 value = half; 145 } 146 147 if (mutex_lock_interruptible(&data->lock)) 148 return -ERESTARTSYS; 149 150 if (value == 0) { 151 /* We can deduce only the polarity */ 152 max197_set_unipolarity(data, channel); 153 } else if (value == -half) { 154 max197_set_bipolarity(data, channel); 155 max197_set_half_range(data, channel); 156 } else if (value == -full) { 157 max197_set_bipolarity(data, channel); 158 max197_set_full_range(data, channel); 159 } else if (value == half) { 160 /* We can deduce only the range */ 161 max197_set_half_range(data, channel); 162 } else if (value == full) { 163 /* We can deduce only the range */ 164 max197_set_full_range(data, channel); 165 } 166 167 mutex_unlock(&data->lock); 168 169 return count; 170 } 171 172 /* Function called on read access on in{0,1,2,3,4,5,6,7}_input */ 173 static ssize_t max197_show_input(struct device *dev, 174 struct device_attribute *devattr, 175 char *buf) 176 { 177 struct max197_data *data = dev_get_drvdata(dev); 178 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 179 int channel = attr->index; 180 s32 value; 181 int ret; 182 183 if (mutex_lock_interruptible(&data->lock)) 184 return -ERESTARTSYS; 185 186 ret = data->pdata->convert(data->ctrl_bytes[channel]); 187 if (ret < 0) { 188 dev_err(dev, "conversion failed\n"); 189 goto unlock; 190 } 191 value = ret; 192 193 /* 194 * Coefficient to apply on raw value. 195 * See Table 1. Full Scale and Zero Scale in the MAX197 datasheet. 196 */ 197 if (data->scale) { 198 value *= MAX197_SCALE; 199 if (max197_is_full_range(data, channel)) 200 value *= 2; 201 value /= 10000; 202 } 203 204 ret = sprintf(buf, "%d\n", value); 205 206 unlock: 207 mutex_unlock(&data->lock); 208 return ret; 209 } 210 211 static ssize_t name_show(struct device *dev, struct device_attribute *attr, 212 char *buf) 213 { 214 struct platform_device *pdev = to_platform_device(dev); 215 return sprintf(buf, "%s\n", pdev->name); 216 } 217 218 #define MAX197_SENSOR_DEVICE_ATTR_CH(chan) \ 219 static SENSOR_DEVICE_ATTR(in##chan##_input, S_IRUGO, \ 220 max197_show_input, NULL, chan); \ 221 static SENSOR_DEVICE_ATTR_2(in##chan##_min, S_IRUGO | S_IWUSR, \ 222 max197_show_range, \ 223 max197_store_range, \ 224 true, chan); \ 225 static SENSOR_DEVICE_ATTR_2(in##chan##_max, S_IRUGO | S_IWUSR, \ 226 max197_show_range, \ 227 max197_store_range, \ 228 false, chan) 229 230 #define MAX197_SENSOR_DEV_ATTR_IN(chan) \ 231 &sensor_dev_attr_in##chan##_input.dev_attr.attr, \ 232 &sensor_dev_attr_in##chan##_max.dev_attr.attr, \ 233 &sensor_dev_attr_in##chan##_min.dev_attr.attr 234 235 static DEVICE_ATTR_RO(name); 236 237 MAX197_SENSOR_DEVICE_ATTR_CH(0); 238 MAX197_SENSOR_DEVICE_ATTR_CH(1); 239 MAX197_SENSOR_DEVICE_ATTR_CH(2); 240 MAX197_SENSOR_DEVICE_ATTR_CH(3); 241 MAX197_SENSOR_DEVICE_ATTR_CH(4); 242 MAX197_SENSOR_DEVICE_ATTR_CH(5); 243 MAX197_SENSOR_DEVICE_ATTR_CH(6); 244 MAX197_SENSOR_DEVICE_ATTR_CH(7); 245 246 static const struct attribute_group max197_sysfs_group = { 247 .attrs = (struct attribute *[]) { 248 &dev_attr_name.attr, 249 MAX197_SENSOR_DEV_ATTR_IN(0), 250 MAX197_SENSOR_DEV_ATTR_IN(1), 251 MAX197_SENSOR_DEV_ATTR_IN(2), 252 MAX197_SENSOR_DEV_ATTR_IN(3), 253 MAX197_SENSOR_DEV_ATTR_IN(4), 254 MAX197_SENSOR_DEV_ATTR_IN(5), 255 MAX197_SENSOR_DEV_ATTR_IN(6), 256 MAX197_SENSOR_DEV_ATTR_IN(7), 257 NULL 258 }, 259 }; 260 261 static int max197_probe(struct platform_device *pdev) 262 { 263 int ch, ret; 264 struct max197_data *data; 265 struct max197_platform_data *pdata = dev_get_platdata(&pdev->dev); 266 enum max197_chips chip = platform_get_device_id(pdev)->driver_data; 267 268 if (pdata == NULL) { 269 dev_err(&pdev->dev, "no platform data supplied\n"); 270 return -EINVAL; 271 } 272 273 if (pdata->convert == NULL) { 274 dev_err(&pdev->dev, "no convert function supplied\n"); 275 return -EINVAL; 276 } 277 278 data = devm_kzalloc(&pdev->dev, sizeof(struct max197_data), GFP_KERNEL); 279 if (!data) 280 return -ENOMEM; 281 282 data->pdata = pdata; 283 mutex_init(&data->lock); 284 285 if (chip == max197) { 286 data->limit = MAX197_LIMIT; 287 data->scale = true; 288 } else { 289 data->limit = MAX199_LIMIT; 290 data->scale = false; 291 } 292 293 for (ch = 0; ch < MAX197_NUM_CH; ch++) 294 data->ctrl_bytes[ch] = (u8) ch; 295 296 platform_set_drvdata(pdev, data); 297 298 ret = sysfs_create_group(&pdev->dev.kobj, &max197_sysfs_group); 299 if (ret) { 300 dev_err(&pdev->dev, "sysfs create group failed\n"); 301 return ret; 302 } 303 304 data->hwmon_dev = hwmon_device_register(&pdev->dev); 305 if (IS_ERR(data->hwmon_dev)) { 306 ret = PTR_ERR(data->hwmon_dev); 307 dev_err(&pdev->dev, "hwmon device register failed\n"); 308 goto error; 309 } 310 311 return 0; 312 313 error: 314 sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group); 315 return ret; 316 } 317 318 static int max197_remove(struct platform_device *pdev) 319 { 320 struct max197_data *data = platform_get_drvdata(pdev); 321 322 hwmon_device_unregister(data->hwmon_dev); 323 sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group); 324 325 return 0; 326 } 327 328 static const struct platform_device_id max197_device_ids[] = { 329 { "max197", max197 }, 330 { "max199", max199 }, 331 { } 332 }; 333 MODULE_DEVICE_TABLE(platform, max197_device_ids); 334 335 static struct platform_driver max197_driver = { 336 .driver = { 337 .name = "max197", 338 }, 339 .probe = max197_probe, 340 .remove = max197_remove, 341 .id_table = max197_device_ids, 342 }; 343 module_platform_driver(max197_driver); 344 345 MODULE_LICENSE("GPL"); 346 MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>"); 347 MODULE_DESCRIPTION("Maxim MAX197 A/D Converter driver"); 348