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