1 /* 2 * ads7828.c - driver for TI ADS7828 8-channel A/D converter and compatibles 3 * (C) 2007 EADS Astrium 4 * 5 * This driver is based on the lm75 and other lm_sensors/hwmon drivers 6 * 7 * Written by Steve Hardy <shardy@redhat.com> 8 * 9 * ADS7830 support, by Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> 10 * 11 * For further information, see the Documentation/hwmon/ads7828 file. 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 */ 27 28 #include <linux/err.h> 29 #include <linux/hwmon.h> 30 #include <linux/hwmon-sysfs.h> 31 #include <linux/i2c.h> 32 #include <linux/init.h> 33 #include <linux/module.h> 34 #include <linux/of_device.h> 35 #include <linux/platform_data/ads7828.h> 36 #include <linux/regmap.h> 37 #include <linux/slab.h> 38 #include <linux/regulator/consumer.h> 39 40 /* The ADS7828 registers */ 41 #define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */ 42 #define ADS7828_CMD_PD1 0x04 /* Internal vref OFF && A/D ON */ 43 #define ADS7828_CMD_PD3 0x0C /* Internal vref ON && A/D ON */ 44 #define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */ 45 #define ADS7828_EXT_VREF_MV_MIN 50 /* External vref min value 0.05V */ 46 #define ADS7828_EXT_VREF_MV_MAX 5250 /* External vref max value 5.25V */ 47 48 /* List of supported devices */ 49 enum ads7828_chips { ads7828, ads7830 }; 50 51 /* Client specific data */ 52 struct ads7828_data { 53 struct regmap *regmap; 54 u8 cmd_byte; /* Command byte without channel bits */ 55 unsigned int lsb_resol; /* Resolution of the ADC sample LSB */ 56 }; 57 58 /* Command byte C2,C1,C0 - see datasheet */ 59 static inline u8 ads7828_cmd_byte(u8 cmd, int ch) 60 { 61 return cmd | (((ch >> 1) | (ch & 0x01) << 2) << 4); 62 } 63 64 /* sysfs callback function */ 65 static ssize_t ads7828_show_in(struct device *dev, struct device_attribute *da, 66 char *buf) 67 { 68 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 69 struct ads7828_data *data = dev_get_drvdata(dev); 70 u8 cmd = ads7828_cmd_byte(data->cmd_byte, attr->index); 71 unsigned int regval; 72 int err; 73 74 err = regmap_read(data->regmap, cmd, ®val); 75 if (err < 0) 76 return err; 77 78 return sprintf(buf, "%d\n", 79 DIV_ROUND_CLOSEST(regval * data->lsb_resol, 1000)); 80 } 81 82 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ads7828_show_in, NULL, 0); 83 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ads7828_show_in, NULL, 1); 84 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ads7828_show_in, NULL, 2); 85 static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ads7828_show_in, NULL, 3); 86 static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ads7828_show_in, NULL, 4); 87 static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ads7828_show_in, NULL, 5); 88 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6); 89 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7); 90 91 static struct attribute *ads7828_attrs[] = { 92 &sensor_dev_attr_in0_input.dev_attr.attr, 93 &sensor_dev_attr_in1_input.dev_attr.attr, 94 &sensor_dev_attr_in2_input.dev_attr.attr, 95 &sensor_dev_attr_in3_input.dev_attr.attr, 96 &sensor_dev_attr_in4_input.dev_attr.attr, 97 &sensor_dev_attr_in5_input.dev_attr.attr, 98 &sensor_dev_attr_in6_input.dev_attr.attr, 99 &sensor_dev_attr_in7_input.dev_attr.attr, 100 NULL 101 }; 102 103 ATTRIBUTE_GROUPS(ads7828); 104 105 static const struct regmap_config ads2828_regmap_config = { 106 .reg_bits = 8, 107 .val_bits = 16, 108 }; 109 110 static const struct regmap_config ads2830_regmap_config = { 111 .reg_bits = 8, 112 .val_bits = 8, 113 }; 114 115 static int ads7828_probe(struct i2c_client *client, 116 const struct i2c_device_id *id) 117 { 118 struct device *dev = &client->dev; 119 struct ads7828_platform_data *pdata = dev_get_platdata(dev); 120 struct ads7828_data *data; 121 struct device *hwmon_dev; 122 unsigned int vref_mv = ADS7828_INT_VREF_MV; 123 unsigned int vref_uv; 124 bool diff_input = false; 125 bool ext_vref = false; 126 unsigned int regval; 127 enum ads7828_chips chip; 128 struct regulator *reg; 129 130 data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL); 131 if (!data) 132 return -ENOMEM; 133 134 if (pdata) { 135 diff_input = pdata->diff_input; 136 ext_vref = pdata->ext_vref; 137 if (ext_vref && pdata->vref_mv) 138 vref_mv = pdata->vref_mv; 139 } else if (dev->of_node) { 140 diff_input = of_property_read_bool(dev->of_node, 141 "ti,differential-input"); 142 reg = devm_regulator_get_optional(dev, "vref"); 143 if (!IS_ERR(reg)) { 144 vref_uv = regulator_get_voltage(reg); 145 vref_mv = DIV_ROUND_CLOSEST(vref_uv, 1000); 146 if (vref_mv < ADS7828_EXT_VREF_MV_MIN || 147 vref_mv > ADS7828_EXT_VREF_MV_MAX) 148 return -EINVAL; 149 ext_vref = true; 150 } 151 } 152 153 if (client->dev.of_node) 154 chip = (enum ads7828_chips) 155 of_device_get_match_data(&client->dev); 156 else 157 chip = id->driver_data; 158 159 /* Bound Vref with min/max values */ 160 vref_mv = clamp_val(vref_mv, ADS7828_EXT_VREF_MV_MIN, 161 ADS7828_EXT_VREF_MV_MAX); 162 163 /* ADS7828 uses 12-bit samples, while ADS7830 is 8-bit */ 164 if (chip == ads7828) { 165 data->lsb_resol = DIV_ROUND_CLOSEST(vref_mv * 1000, 4096); 166 data->regmap = devm_regmap_init_i2c(client, 167 &ads2828_regmap_config); 168 } else { 169 data->lsb_resol = DIV_ROUND_CLOSEST(vref_mv * 1000, 256); 170 data->regmap = devm_regmap_init_i2c(client, 171 &ads2830_regmap_config); 172 } 173 174 if (IS_ERR(data->regmap)) 175 return PTR_ERR(data->regmap); 176 177 data->cmd_byte = ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3; 178 if (!diff_input) 179 data->cmd_byte |= ADS7828_CMD_SD_SE; 180 181 /* 182 * Datasheet specifies internal reference voltage is disabled by 183 * default. The internal reference voltage needs to be enabled and 184 * voltage needs to settle before getting valid ADC data. So perform a 185 * dummy read to enable the internal reference voltage. 186 */ 187 if (!ext_vref) 188 regmap_read(data->regmap, data->cmd_byte, ®val); 189 190 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 191 data, 192 ads7828_groups); 193 return PTR_ERR_OR_ZERO(hwmon_dev); 194 } 195 196 static const struct i2c_device_id ads7828_device_ids[] = { 197 { "ads7828", ads7828 }, 198 { "ads7830", ads7830 }, 199 { } 200 }; 201 MODULE_DEVICE_TABLE(i2c, ads7828_device_ids); 202 203 static const struct of_device_id ads7828_of_match[] = { 204 { 205 .compatible = "ti,ads7828", 206 .data = (void *)ads7828 207 }, 208 { 209 .compatible = "ti,ads7830", 210 .data = (void *)ads7830 211 }, 212 { }, 213 }; 214 MODULE_DEVICE_TABLE(of, ads7828_of_match); 215 216 static struct i2c_driver ads7828_driver = { 217 .driver = { 218 .name = "ads7828", 219 .of_match_table = of_match_ptr(ads7828_of_match), 220 }, 221 222 .id_table = ads7828_device_ids, 223 .probe = ads7828_probe, 224 }; 225 226 module_i2c_driver(ads7828_driver); 227 228 MODULE_LICENSE("GPL"); 229 MODULE_AUTHOR("Steve Hardy <shardy@redhat.com>"); 230 MODULE_DESCRIPTION("Driver for TI ADS7828 A/D converter and compatibles"); 231