1 /* 2 * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs. 3 * 4 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 5 * Copyright (C) 2009 Sascha Hauer, Pengutronix 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * this program; if not, write to the Free Software Foundation, Inc., 51 18 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <linux/mfd/mc13xxx.h> 22 #include <linux/platform_device.h> 23 #include <linux/hwmon-sysfs.h> 24 #include <linux/kernel.h> 25 #include <linux/module.h> 26 #include <linux/hwmon.h> 27 #include <linux/slab.h> 28 #include <linux/init.h> 29 #include <linux/err.h> 30 31 #define DRIVER_NAME "mc13783-adc" 32 33 /* platform device id driver data */ 34 #define MC13783_ADC_16CHANS 1 35 #define MC13783_ADC_BPDIV2 2 36 37 struct mc13783_adc_priv { 38 struct mc13xxx *mc13xxx; 39 struct device *hwmon_dev; 40 char name[PLATFORM_NAME_SIZE]; 41 }; 42 43 static ssize_t name_show(struct device *dev, struct device_attribute *devattr, 44 char *buf) 45 { 46 struct mc13783_adc_priv *priv = dev_get_drvdata(dev); 47 48 return sprintf(buf, "%s\n", priv->name); 49 } 50 51 static int mc13783_adc_read(struct device *dev, 52 struct device_attribute *devattr, unsigned int *val) 53 { 54 struct mc13783_adc_priv *priv = dev_get_drvdata(dev); 55 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 56 unsigned int channel = attr->index; 57 unsigned int sample[4]; 58 int ret; 59 60 ret = mc13xxx_adc_do_conversion(priv->mc13xxx, 61 MC13XXX_ADC_MODE_MULT_CHAN, 62 channel, 0, 0, sample); 63 if (ret) 64 return ret; 65 66 channel &= 0x7; 67 68 *val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff; 69 70 return 0; 71 } 72 73 static ssize_t mc13783_adc_read_bp(struct device *dev, 74 struct device_attribute *devattr, char *buf) 75 { 76 unsigned val; 77 struct platform_device *pdev = to_platform_device(dev); 78 kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; 79 int ret = mc13783_adc_read(dev, devattr, &val); 80 81 if (ret) 82 return ret; 83 84 if (driver_data & MC13783_ADC_BPDIV2) 85 val = DIV_ROUND_CLOSEST(val * 9, 2); 86 else 87 /* 88 * BP (channel 2) reports with offset 2.4V to the actual value 89 * to fit the input range of the ADC. unit = 2.25mV = 9/4 mV. 90 */ 91 val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400; 92 93 return sprintf(buf, "%u\n", val); 94 } 95 96 static ssize_t mc13783_adc_read_gp(struct device *dev, 97 struct device_attribute *devattr, char *buf) 98 { 99 unsigned val; 100 int ret = mc13783_adc_read(dev, devattr, &val); 101 102 if (ret) 103 return ret; 104 105 /* 106 * input range is [0, 2.3V], val has 10 bits, so each bit 107 * is worth 9/4 mV. 108 */ 109 val = DIV_ROUND_CLOSEST(val * 9, 4); 110 111 return sprintf(buf, "%u\n", val); 112 } 113 114 static DEVICE_ATTR_RO(name); 115 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, mc13783_adc_read_bp, NULL, 2); 116 static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, mc13783_adc_read_gp, NULL, 5); 117 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, mc13783_adc_read_gp, NULL, 6); 118 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, mc13783_adc_read_gp, NULL, 7); 119 static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, mc13783_adc_read_gp, NULL, 8); 120 static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, mc13783_adc_read_gp, NULL, 9); 121 static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, mc13783_adc_read_gp, NULL, 10); 122 static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, mc13783_adc_read_gp, NULL, 11); 123 static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, mc13783_adc_read_gp, NULL, 12); 124 static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13); 125 static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14); 126 static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15); 127 128 static struct attribute *mc13783_attr_base[] = { 129 &dev_attr_name.attr, 130 &sensor_dev_attr_in2_input.dev_attr.attr, 131 &sensor_dev_attr_in5_input.dev_attr.attr, 132 &sensor_dev_attr_in6_input.dev_attr.attr, 133 &sensor_dev_attr_in7_input.dev_attr.attr, 134 NULL 135 }; 136 137 static const struct attribute_group mc13783_group_base = { 138 .attrs = mc13783_attr_base, 139 }; 140 141 /* these are only used if MC13783_ADC_16CHANS is provided in driver data */ 142 static struct attribute *mc13783_attr_16chans[] = { 143 &sensor_dev_attr_in8_input.dev_attr.attr, 144 &sensor_dev_attr_in9_input.dev_attr.attr, 145 &sensor_dev_attr_in10_input.dev_attr.attr, 146 &sensor_dev_attr_in11_input.dev_attr.attr, 147 NULL 148 }; 149 150 static const struct attribute_group mc13783_group_16chans = { 151 .attrs = mc13783_attr_16chans, 152 }; 153 154 /* last four channels may be occupied by the touchscreen */ 155 static struct attribute *mc13783_attr_ts[] = { 156 &sensor_dev_attr_in12_input.dev_attr.attr, 157 &sensor_dev_attr_in13_input.dev_attr.attr, 158 &sensor_dev_attr_in14_input.dev_attr.attr, 159 &sensor_dev_attr_in15_input.dev_attr.attr, 160 NULL 161 }; 162 163 static const struct attribute_group mc13783_group_ts = { 164 .attrs = mc13783_attr_ts, 165 }; 166 167 static int mc13783_adc_use_touchscreen(struct platform_device *pdev) 168 { 169 struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); 170 unsigned flags = mc13xxx_get_flags(priv->mc13xxx); 171 172 return flags & MC13XXX_USE_TOUCHSCREEN; 173 } 174 175 static int __init mc13783_adc_probe(struct platform_device *pdev) 176 { 177 struct mc13783_adc_priv *priv; 178 int ret; 179 const struct platform_device_id *id = platform_get_device_id(pdev); 180 char *dash; 181 182 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 183 if (!priv) 184 return -ENOMEM; 185 186 priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); 187 snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name); 188 dash = strchr(priv->name, '-'); 189 if (dash) 190 *dash = '\0'; 191 192 platform_set_drvdata(pdev, priv); 193 194 /* Register sysfs hooks */ 195 ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base); 196 if (ret) 197 return ret; 198 199 if (id->driver_data & MC13783_ADC_16CHANS) { 200 ret = sysfs_create_group(&pdev->dev.kobj, 201 &mc13783_group_16chans); 202 if (ret) 203 goto out_err_create_16chans; 204 } 205 206 if (!mc13783_adc_use_touchscreen(pdev)) { 207 ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts); 208 if (ret) 209 goto out_err_create_ts; 210 } 211 212 priv->hwmon_dev = hwmon_device_register(&pdev->dev); 213 if (IS_ERR(priv->hwmon_dev)) { 214 ret = PTR_ERR(priv->hwmon_dev); 215 dev_err(&pdev->dev, 216 "hwmon_device_register failed with %d.\n", ret); 217 goto out_err_register; 218 } 219 220 return 0; 221 222 out_err_register: 223 224 if (!mc13783_adc_use_touchscreen(pdev)) 225 sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); 226 out_err_create_ts: 227 228 if (id->driver_data & MC13783_ADC_16CHANS) 229 sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); 230 out_err_create_16chans: 231 232 sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); 233 return ret; 234 } 235 236 static int mc13783_adc_remove(struct platform_device *pdev) 237 { 238 struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); 239 kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; 240 241 hwmon_device_unregister(priv->hwmon_dev); 242 243 if (!mc13783_adc_use_touchscreen(pdev)) 244 sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); 245 246 if (driver_data & MC13783_ADC_16CHANS) 247 sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); 248 249 sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); 250 251 return 0; 252 } 253 254 static const struct platform_device_id mc13783_adc_idtable[] = { 255 { 256 .name = "mc13783-adc", 257 .driver_data = MC13783_ADC_16CHANS, 258 }, { 259 .name = "mc13892-adc", 260 .driver_data = MC13783_ADC_BPDIV2, 261 }, { 262 /* sentinel */ 263 } 264 }; 265 MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable); 266 267 static struct platform_driver mc13783_adc_driver = { 268 .remove = mc13783_adc_remove, 269 .driver = { 270 .name = DRIVER_NAME, 271 }, 272 .id_table = mc13783_adc_idtable, 273 }; 274 275 module_platform_driver_probe(mc13783_adc_driver, mc13783_adc_probe); 276 277 MODULE_DESCRIPTION("MC13783 ADC driver"); 278 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); 279 MODULE_LICENSE("GPL"); 280