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