Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Maxim MAX197 A/D Converter driver
0004  *
0005  * Copyright (c) 2012 Savoir-faire Linux Inc.
0006  *          Vivien Didelot <vivien.didelot@savoirfairelinux.com>
0007  *
0008  * For further information, see the Documentation/hwmon/max197.rst file.
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/mod_devicetable.h>
0014 #include <linux/init.h>
0015 #include <linux/err.h>
0016 #include <linux/slab.h>
0017 #include <linux/mutex.h>
0018 #include <linux/device.h>
0019 #include <linux/sysfs.h>
0020 #include <linux/hwmon.h>
0021 #include <linux/hwmon-sysfs.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/platform_data/max197.h>
0024 
0025 #define MAX199_LIMIT    4000        /* 4V */
0026 #define MAX197_LIMIT    10000       /* 10V */
0027 
0028 #define MAX197_NUM_CH   8       /* 8 Analog Input Channels */
0029 
0030 /* Control byte format */
0031 #define MAX197_BIP  (1 << 3)    /* Bipolarity */
0032 #define MAX197_RNG  (1 << 4)    /* Full range */
0033 
0034 #define MAX197_SCALE    12207       /* Scale coefficient for raw data */
0035 
0036 /* List of supported chips */
0037 enum max197_chips { max197, max199 };
0038 
0039 /**
0040  * struct max197_data - device instance specific data
0041  * @pdata:      Platform data.
0042  * @hwmon_dev:      The hwmon device.
0043  * @lock:       Read/Write mutex.
0044  * @limit:      Max range value (10V for MAX197, 4V for MAX199).
0045  * @scale:      Need to scale.
0046  * @ctrl_bytes:     Channels control byte.
0047  */
0048 struct max197_data {
0049     struct max197_platform_data *pdata;
0050     struct device *hwmon_dev;
0051     struct mutex lock;
0052     int limit;
0053     bool scale;
0054     u8 ctrl_bytes[MAX197_NUM_CH];
0055 };
0056 
0057 static inline void max197_set_unipolarity(struct max197_data *data, int channel)
0058 {
0059     data->ctrl_bytes[channel] &= ~MAX197_BIP;
0060 }
0061 
0062 static inline void max197_set_bipolarity(struct max197_data *data, int channel)
0063 {
0064     data->ctrl_bytes[channel] |= MAX197_BIP;
0065 }
0066 
0067 static inline void max197_set_half_range(struct max197_data *data, int channel)
0068 {
0069     data->ctrl_bytes[channel] &= ~MAX197_RNG;
0070 }
0071 
0072 static inline void max197_set_full_range(struct max197_data *data, int channel)
0073 {
0074     data->ctrl_bytes[channel] |= MAX197_RNG;
0075 }
0076 
0077 static inline bool max197_is_bipolar(struct max197_data *data, int channel)
0078 {
0079     return data->ctrl_bytes[channel] & MAX197_BIP;
0080 }
0081 
0082 static inline bool max197_is_full_range(struct max197_data *data, int channel)
0083 {
0084     return data->ctrl_bytes[channel] & MAX197_RNG;
0085 }
0086 
0087 /* Function called on read access on in{0,1,2,3,4,5,6,7}_{min,max} */
0088 static ssize_t max197_show_range(struct device *dev,
0089                  struct device_attribute *devattr, char *buf)
0090 {
0091     struct max197_data *data = dev_get_drvdata(dev);
0092     struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
0093     int channel = attr->index;
0094     bool is_min = attr->nr;
0095     int range;
0096 
0097     if (mutex_lock_interruptible(&data->lock))
0098         return -ERESTARTSYS;
0099 
0100     range = max197_is_full_range(data, channel) ?
0101         data->limit : data->limit / 2;
0102     if (is_min) {
0103         if (max197_is_bipolar(data, channel))
0104             range = -range;
0105         else
0106             range = 0;
0107     }
0108 
0109     mutex_unlock(&data->lock);
0110 
0111     return sprintf(buf, "%d\n", range);
0112 }
0113 
0114 /* Function called on write access on in{0,1,2,3,4,5,6,7}_{min,max} */
0115 static ssize_t max197_store_range(struct device *dev,
0116                   struct device_attribute *devattr,
0117                   const char *buf, size_t count)
0118 {
0119     struct max197_data *data = dev_get_drvdata(dev);
0120     struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
0121     int channel = attr->index;
0122     bool is_min = attr->nr;
0123     long value;
0124     int half = data->limit / 2;
0125     int full = data->limit;
0126 
0127     if (kstrtol(buf, 10, &value))
0128         return -EINVAL;
0129 
0130     if (is_min) {
0131         if (value <= -full)
0132             value = -full;
0133         else if (value < 0)
0134             value = -half;
0135         else
0136             value = 0;
0137     } else {
0138         if (value >= full)
0139             value = full;
0140         else
0141             value = half;
0142     }
0143 
0144     if (mutex_lock_interruptible(&data->lock))
0145         return -ERESTARTSYS;
0146 
0147     if (value == 0) {
0148         /* We can deduce only the polarity */
0149         max197_set_unipolarity(data, channel);
0150     } else if (value == -half) {
0151         max197_set_bipolarity(data, channel);
0152         max197_set_half_range(data, channel);
0153     } else if (value == -full) {
0154         max197_set_bipolarity(data, channel);
0155         max197_set_full_range(data, channel);
0156     } else if (value == half) {
0157         /* We can deduce only the range */
0158         max197_set_half_range(data, channel);
0159     } else if (value == full) {
0160         /* We can deduce only the range */
0161         max197_set_full_range(data, channel);
0162     }
0163 
0164     mutex_unlock(&data->lock);
0165 
0166     return count;
0167 }
0168 
0169 /* Function called on read access on in{0,1,2,3,4,5,6,7}_input */
0170 static ssize_t max197_show_input(struct device *dev,
0171                  struct device_attribute *devattr,
0172                  char *buf)
0173 {
0174     struct max197_data *data = dev_get_drvdata(dev);
0175     struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
0176     int channel = attr->index;
0177     s32 value;
0178     int ret;
0179 
0180     if (mutex_lock_interruptible(&data->lock))
0181         return -ERESTARTSYS;
0182 
0183     ret = data->pdata->convert(data->ctrl_bytes[channel]);
0184     if (ret < 0) {
0185         dev_err(dev, "conversion failed\n");
0186         goto unlock;
0187     }
0188     value = ret;
0189 
0190     /*
0191      * Coefficient to apply on raw value.
0192      * See Table 1. Full Scale and Zero Scale in the MAX197 datasheet.
0193      */
0194     if (data->scale) {
0195         value *= MAX197_SCALE;
0196         if (max197_is_full_range(data, channel))
0197             value *= 2;
0198         value /= 10000;
0199     }
0200 
0201     ret = sprintf(buf, "%d\n", value);
0202 
0203 unlock:
0204     mutex_unlock(&data->lock);
0205     return ret;
0206 }
0207 
0208 static ssize_t name_show(struct device *dev, struct device_attribute *attr,
0209              char *buf)
0210 {
0211     struct platform_device *pdev = to_platform_device(dev);
0212     return sprintf(buf, "%s\n", pdev->name);
0213 }
0214 
0215 #define MAX197_SENSOR_DEVICE_ATTR_CH(chan)              \
0216     static SENSOR_DEVICE_ATTR(in##chan##_input, S_IRUGO,        \
0217                   max197_show_input, NULL, chan);   \
0218     static SENSOR_DEVICE_ATTR_2(in##chan##_min, S_IRUGO | S_IWUSR,  \
0219                     max197_show_range,          \
0220                     max197_store_range,         \
0221                     true, chan);            \
0222     static SENSOR_DEVICE_ATTR_2(in##chan##_max, S_IRUGO | S_IWUSR,  \
0223                     max197_show_range,          \
0224                     max197_store_range,         \
0225                     false, chan)
0226 
0227 #define MAX197_SENSOR_DEV_ATTR_IN(chan)                 \
0228     &sensor_dev_attr_in##chan##_input.dev_attr.attr,        \
0229     &sensor_dev_attr_in##chan##_max.dev_attr.attr,          \
0230     &sensor_dev_attr_in##chan##_min.dev_attr.attr
0231 
0232 static DEVICE_ATTR_RO(name);
0233 
0234 MAX197_SENSOR_DEVICE_ATTR_CH(0);
0235 MAX197_SENSOR_DEVICE_ATTR_CH(1);
0236 MAX197_SENSOR_DEVICE_ATTR_CH(2);
0237 MAX197_SENSOR_DEVICE_ATTR_CH(3);
0238 MAX197_SENSOR_DEVICE_ATTR_CH(4);
0239 MAX197_SENSOR_DEVICE_ATTR_CH(5);
0240 MAX197_SENSOR_DEVICE_ATTR_CH(6);
0241 MAX197_SENSOR_DEVICE_ATTR_CH(7);
0242 
0243 static const struct attribute_group max197_sysfs_group = {
0244     .attrs = (struct attribute *[]) {
0245         &dev_attr_name.attr,
0246         MAX197_SENSOR_DEV_ATTR_IN(0),
0247         MAX197_SENSOR_DEV_ATTR_IN(1),
0248         MAX197_SENSOR_DEV_ATTR_IN(2),
0249         MAX197_SENSOR_DEV_ATTR_IN(3),
0250         MAX197_SENSOR_DEV_ATTR_IN(4),
0251         MAX197_SENSOR_DEV_ATTR_IN(5),
0252         MAX197_SENSOR_DEV_ATTR_IN(6),
0253         MAX197_SENSOR_DEV_ATTR_IN(7),
0254         NULL
0255     },
0256 };
0257 
0258 static int max197_probe(struct platform_device *pdev)
0259 {
0260     int ch, ret;
0261     struct max197_data *data;
0262     struct max197_platform_data *pdata = dev_get_platdata(&pdev->dev);
0263     enum max197_chips chip = platform_get_device_id(pdev)->driver_data;
0264 
0265     if (pdata == NULL) {
0266         dev_err(&pdev->dev, "no platform data supplied\n");
0267         return -EINVAL;
0268     }
0269 
0270     if (pdata->convert == NULL) {
0271         dev_err(&pdev->dev, "no convert function supplied\n");
0272         return -EINVAL;
0273     }
0274 
0275     data = devm_kzalloc(&pdev->dev, sizeof(struct max197_data), GFP_KERNEL);
0276     if (!data)
0277         return -ENOMEM;
0278 
0279     data->pdata = pdata;
0280     mutex_init(&data->lock);
0281 
0282     if (chip == max197) {
0283         data->limit = MAX197_LIMIT;
0284         data->scale = true;
0285     } else {
0286         data->limit = MAX199_LIMIT;
0287         data->scale = false;
0288     }
0289 
0290     for (ch = 0; ch < MAX197_NUM_CH; ch++)
0291         data->ctrl_bytes[ch] = (u8) ch;
0292 
0293     platform_set_drvdata(pdev, data);
0294 
0295     ret = sysfs_create_group(&pdev->dev.kobj, &max197_sysfs_group);
0296     if (ret) {
0297         dev_err(&pdev->dev, "sysfs create group failed\n");
0298         return ret;
0299     }
0300 
0301     data->hwmon_dev = hwmon_device_register(&pdev->dev);
0302     if (IS_ERR(data->hwmon_dev)) {
0303         ret = PTR_ERR(data->hwmon_dev);
0304         dev_err(&pdev->dev, "hwmon device register failed\n");
0305         goto error;
0306     }
0307 
0308     return 0;
0309 
0310 error:
0311     sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group);
0312     return ret;
0313 }
0314 
0315 static int max197_remove(struct platform_device *pdev)
0316 {
0317     struct max197_data *data = platform_get_drvdata(pdev);
0318 
0319     hwmon_device_unregister(data->hwmon_dev);
0320     sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group);
0321 
0322     return 0;
0323 }
0324 
0325 static const struct platform_device_id max197_device_ids[] = {
0326     { "max197", max197 },
0327     { "max199", max199 },
0328     { }
0329 };
0330 MODULE_DEVICE_TABLE(platform, max197_device_ids);
0331 
0332 static struct platform_driver max197_driver = {
0333     .driver = {
0334         .name = "max197",
0335     },
0336     .probe = max197_probe,
0337     .remove = max197_remove,
0338     .id_table = max197_device_ids,
0339 };
0340 module_platform_driver(max197_driver);
0341 
0342 MODULE_LICENSE("GPL");
0343 MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
0344 MODULE_DESCRIPTION("Maxim MAX197 A/D Converter driver");