1 /* 2 ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC 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 <steve@linuxrealtime.co.uk> 8 9 Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 2 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 */ 25 26 #include <linux/module.h> 27 #include <linux/init.h> 28 #include <linux/slab.h> 29 #include <linux/jiffies.h> 30 #include <linux/i2c.h> 31 #include <linux/hwmon.h> 32 #include <linux/hwmon-sysfs.h> 33 #include <linux/err.h> 34 #include <linux/mutex.h> 35 36 /* The ADS7828 registers */ 37 #define ADS7828_NCH 8 /* 8 channels of 12-bit A-D supported */ 38 #define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */ 39 #define ADS7828_CMD_SD_DIFF 0x00 /* Differential inputs */ 40 #define ADS7828_CMD_PD0 0x0 /* Power Down between A-D conversions */ 41 #define ADS7828_CMD_PD1 0x04 /* Internal ref OFF && A-D ON */ 42 #define ADS7828_CMD_PD2 0x08 /* Internal ref ON && A-D OFF */ 43 #define ADS7828_CMD_PD3 0x0C /* Internal ref ON && A-D ON */ 44 #define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */ 45 46 /* Addresses to scan */ 47 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 48 I2C_CLIENT_END }; 49 50 /* Insmod parameters */ 51 I2C_CLIENT_INSMOD_1(ads7828); 52 53 /* Other module parameters */ 54 static int se_input = 1; /* Default is SE, 0 == diff */ 55 static int int_vref = 1; /* Default is internal ref ON */ 56 static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */ 57 module_param(se_input, bool, S_IRUGO); 58 module_param(int_vref, bool, S_IRUGO); 59 module_param(vref_mv, int, S_IRUGO); 60 61 /* Global Variables */ 62 static u8 ads7828_cmd_byte; /* cmd byte without channel bits */ 63 static unsigned int ads7828_lsb_resol; /* resolution of the ADC sample lsb */ 64 65 /* Each client has this additional data */ 66 struct ads7828_data { 67 struct device *hwmon_dev; 68 struct mutex update_lock; /* mutex protect updates */ 69 char valid; /* !=0 if following fields are valid */ 70 unsigned long last_updated; /* In jiffies */ 71 u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH 12-bit samples */ 72 }; 73 74 /* Function declaration - necessary due to function dependencies */ 75 static int ads7828_detect(struct i2c_client *client, int kind, 76 struct i2c_board_info *info); 77 static int ads7828_probe(struct i2c_client *client, 78 const struct i2c_device_id *id); 79 80 /* The ADS7828 returns the 12-bit sample in two bytes, 81 these are read as a word then byte-swapped */ 82 static u16 ads7828_read_value(struct i2c_client *client, u8 reg) 83 { 84 return swab16(i2c_smbus_read_word_data(client, reg)); 85 } 86 87 static inline u8 channel_cmd_byte(int ch) 88 { 89 /* cmd byte C2,C1,C0 - see datasheet */ 90 u8 cmd = (((ch>>1) | (ch&0x01)<<2)<<4); 91 cmd |= ads7828_cmd_byte; 92 return cmd; 93 } 94 95 /* Update data for the device (all 8 channels) */ 96 static struct ads7828_data *ads7828_update_device(struct device *dev) 97 { 98 struct i2c_client *client = to_i2c_client(dev); 99 struct ads7828_data *data = i2c_get_clientdata(client); 100 101 mutex_lock(&data->update_lock); 102 103 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 104 || !data->valid) { 105 unsigned int ch; 106 dev_dbg(&client->dev, "Starting ads7828 update\n"); 107 108 for (ch = 0; ch < ADS7828_NCH; ch++) { 109 u8 cmd = channel_cmd_byte(ch); 110 data->adc_input[ch] = ads7828_read_value(client, cmd); 111 } 112 data->last_updated = jiffies; 113 data->valid = 1; 114 } 115 116 mutex_unlock(&data->update_lock); 117 118 return data; 119 } 120 121 /* sysfs callback function */ 122 static ssize_t show_in(struct device *dev, struct device_attribute *da, 123 char *buf) 124 { 125 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 126 struct ads7828_data *data = ads7828_update_device(dev); 127 /* Print value (in mV as specified in sysfs-interface documentation) */ 128 return sprintf(buf, "%d\n", (data->adc_input[attr->index] * 129 ads7828_lsb_resol)/1000); 130 } 131 132 #define in_reg(offset)\ 133 static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in,\ 134 NULL, offset) 135 136 in_reg(0); 137 in_reg(1); 138 in_reg(2); 139 in_reg(3); 140 in_reg(4); 141 in_reg(5); 142 in_reg(6); 143 in_reg(7); 144 145 static struct attribute *ads7828_attributes[] = { 146 &sensor_dev_attr_in0_input.dev_attr.attr, 147 &sensor_dev_attr_in1_input.dev_attr.attr, 148 &sensor_dev_attr_in2_input.dev_attr.attr, 149 &sensor_dev_attr_in3_input.dev_attr.attr, 150 &sensor_dev_attr_in4_input.dev_attr.attr, 151 &sensor_dev_attr_in5_input.dev_attr.attr, 152 &sensor_dev_attr_in6_input.dev_attr.attr, 153 &sensor_dev_attr_in7_input.dev_attr.attr, 154 NULL 155 }; 156 157 static const struct attribute_group ads7828_group = { 158 .attrs = ads7828_attributes, 159 }; 160 161 static int ads7828_remove(struct i2c_client *client) 162 { 163 struct ads7828_data *data = i2c_get_clientdata(client); 164 hwmon_device_unregister(data->hwmon_dev); 165 sysfs_remove_group(&client->dev.kobj, &ads7828_group); 166 kfree(i2c_get_clientdata(client)); 167 return 0; 168 } 169 170 static const struct i2c_device_id ads7828_id[] = { 171 { "ads7828", ads7828 }, 172 { } 173 }; 174 MODULE_DEVICE_TABLE(i2c, ads7828_id); 175 176 /* This is the driver that will be inserted */ 177 static struct i2c_driver ads7828_driver = { 178 .class = I2C_CLASS_HWMON, 179 .driver = { 180 .name = "ads7828", 181 }, 182 .probe = ads7828_probe, 183 .remove = ads7828_remove, 184 .id_table = ads7828_id, 185 .detect = ads7828_detect, 186 .address_data = &addr_data, 187 }; 188 189 /* Return 0 if detection is successful, -ENODEV otherwise */ 190 static int ads7828_detect(struct i2c_client *client, int kind, 191 struct i2c_board_info *info) 192 { 193 struct i2c_adapter *adapter = client->adapter; 194 195 /* Check we have a valid client */ 196 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) 197 return -ENODEV; 198 199 /* Now, we do the remaining detection. There is no identification 200 dedicated register so attempt to sanity check using knowledge of 201 the chip 202 - Read from the 8 channel addresses 203 - Check the top 4 bits of each result are not set (12 data bits) 204 */ 205 if (kind < 0) { 206 int ch; 207 for (ch = 0; ch < ADS7828_NCH; ch++) { 208 u16 in_data; 209 u8 cmd = channel_cmd_byte(ch); 210 in_data = ads7828_read_value(client, cmd); 211 if (in_data & 0xF000) { 212 printk(KERN_DEBUG 213 "%s : Doesn't look like an ads7828 device\n", 214 __func__); 215 return -ENODEV; 216 } 217 } 218 } 219 strlcpy(info->type, "ads7828", I2C_NAME_SIZE); 220 221 return 0; 222 } 223 224 static int ads7828_probe(struct i2c_client *client, 225 const struct i2c_device_id *id) 226 { 227 struct ads7828_data *data; 228 int err; 229 230 data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL); 231 if (!data) { 232 err = -ENOMEM; 233 goto exit; 234 } 235 236 i2c_set_clientdata(client, data); 237 mutex_init(&data->update_lock); 238 239 /* Register sysfs hooks */ 240 err = sysfs_create_group(&client->dev.kobj, &ads7828_group); 241 if (err) 242 goto exit_free; 243 244 data->hwmon_dev = hwmon_device_register(&client->dev); 245 if (IS_ERR(data->hwmon_dev)) { 246 err = PTR_ERR(data->hwmon_dev); 247 goto exit_remove; 248 } 249 250 return 0; 251 252 exit_remove: 253 sysfs_remove_group(&client->dev.kobj, &ads7828_group); 254 exit_free: 255 kfree(data); 256 exit: 257 return err; 258 } 259 260 static int __init sensors_ads7828_init(void) 261 { 262 /* Initialize the command byte according to module parameters */ 263 ads7828_cmd_byte = se_input ? 264 ADS7828_CMD_SD_SE : ADS7828_CMD_SD_DIFF; 265 ads7828_cmd_byte |= int_vref ? 266 ADS7828_CMD_PD3 : ADS7828_CMD_PD1; 267 268 /* Calculate the LSB resolution */ 269 ads7828_lsb_resol = (vref_mv*1000)/4096; 270 271 return i2c_add_driver(&ads7828_driver); 272 } 273 274 static void __exit sensors_ads7828_exit(void) 275 { 276 i2c_del_driver(&ads7828_driver); 277 } 278 279 MODULE_AUTHOR("Steve Hardy <steve@linuxrealtime.co.uk>"); 280 MODULE_DESCRIPTION("ADS7828 driver"); 281 MODULE_LICENSE("GPL"); 282 283 module_init(sensors_ads7828_init); 284 module_exit(sensors_ads7828_exit); 285