1 /* tmp421.c 2 * 3 * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> 4 * Preliminary support by: 5 * Melvin Rook, Raymond Ng 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 /* 23 * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC. 24 * Supported models: TMP421, TMP422, TMP423 25 */ 26 27 #include <linux/module.h> 28 #include <linux/init.h> 29 #include <linux/slab.h> 30 #include <linux/jiffies.h> 31 #include <linux/i2c.h> 32 #include <linux/hwmon.h> 33 #include <linux/hwmon-sysfs.h> 34 #include <linux/err.h> 35 #include <linux/mutex.h> 36 #include <linux/sysfs.h> 37 38 /* Addresses to scan */ 39 static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, 40 I2C_CLIENT_END }; 41 42 /* Insmod parameters */ 43 I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423); 44 45 /* The TMP421 registers */ 46 #define TMP421_CONFIG_REG_1 0x09 47 #define TMP421_CONVERSION_RATE_REG 0x0B 48 #define TMP421_MANUFACTURER_ID_REG 0xFE 49 #define TMP421_DEVICE_ID_REG 0xFF 50 51 static const u8 TMP421_TEMP_MSB[4] = { 0x00, 0x01, 0x02, 0x03 }; 52 static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 }; 53 54 /* Flags */ 55 #define TMP421_CONFIG_SHUTDOWN 0x40 56 #define TMP421_CONFIG_RANGE 0x04 57 58 /* Manufacturer / Device ID's */ 59 #define TMP421_MANUFACTURER_ID 0x55 60 #define TMP421_DEVICE_ID 0x21 61 #define TMP422_DEVICE_ID 0x22 62 #define TMP423_DEVICE_ID 0x23 63 64 static const struct i2c_device_id tmp421_id[] = { 65 { "tmp421", tmp421 }, 66 { "tmp422", tmp422 }, 67 { "tmp423", tmp423 }, 68 { } 69 }; 70 MODULE_DEVICE_TABLE(i2c, tmp421_id); 71 72 struct tmp421_data { 73 struct device *hwmon_dev; 74 struct mutex update_lock; 75 char valid; 76 unsigned long last_updated; 77 int kind; 78 u8 config; 79 s16 temp[4]; 80 }; 81 82 static int temp_from_s16(s16 reg) 83 { 84 int temp = reg; 85 86 return (temp * 1000 + 128) / 256; 87 } 88 89 static int temp_from_u16(u16 reg) 90 { 91 int temp = reg; 92 93 /* Add offset for extended temperature range. */ 94 temp -= 64 * 256; 95 96 return (temp * 1000 + 128) / 256; 97 } 98 99 static struct tmp421_data *tmp421_update_device(struct device *dev) 100 { 101 struct i2c_client *client = to_i2c_client(dev); 102 struct tmp421_data *data = i2c_get_clientdata(client); 103 int i; 104 105 mutex_lock(&data->update_lock); 106 107 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { 108 data->config = i2c_smbus_read_byte_data(client, 109 TMP421_CONFIG_REG_1); 110 111 for (i = 0; i <= data->kind; i++) { 112 data->temp[i] = i2c_smbus_read_byte_data(client, 113 TMP421_TEMP_MSB[i]) << 8; 114 data->temp[i] |= i2c_smbus_read_byte_data(client, 115 TMP421_TEMP_LSB[i]); 116 } 117 data->last_updated = jiffies; 118 data->valid = 1; 119 } 120 121 mutex_unlock(&data->update_lock); 122 123 return data; 124 } 125 126 static ssize_t show_temp_value(struct device *dev, 127 struct device_attribute *devattr, char *buf) 128 { 129 int index = to_sensor_dev_attr(devattr)->index; 130 struct tmp421_data *data = tmp421_update_device(dev); 131 int temp; 132 133 mutex_lock(&data->update_lock); 134 if (data->config & TMP421_CONFIG_RANGE) 135 temp = temp_from_u16(data->temp[index]); 136 else 137 temp = temp_from_s16(data->temp[index]); 138 mutex_unlock(&data->update_lock); 139 140 return sprintf(buf, "%d\n", temp); 141 } 142 143 static ssize_t show_fault(struct device *dev, 144 struct device_attribute *devattr, char *buf) 145 { 146 int index = to_sensor_dev_attr(devattr)->index; 147 struct tmp421_data *data = tmp421_update_device(dev); 148 149 /* 150 * The OPEN bit signals a fault. This is bit 0 of the temperature 151 * register (low byte). 152 */ 153 if (data->temp[index] & 0x01) 154 return sprintf(buf, "1\n"); 155 else 156 return sprintf(buf, "0\n"); 157 } 158 159 static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, 160 int n) 161 { 162 struct device *dev = container_of(kobj, struct device, kobj); 163 struct tmp421_data *data = dev_get_drvdata(dev); 164 struct device_attribute *devattr; 165 unsigned int index; 166 167 devattr = container_of(a, struct device_attribute, attr); 168 index = to_sensor_dev_attr(devattr)->index; 169 170 if (data->kind > index) 171 return a->mode; 172 173 return 0; 174 } 175 176 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0); 177 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1); 178 static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1); 179 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2); 180 static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2); 181 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3); 182 static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3); 183 184 static struct attribute *tmp421_attr[] = { 185 &sensor_dev_attr_temp1_input.dev_attr.attr, 186 &sensor_dev_attr_temp2_input.dev_attr.attr, 187 &sensor_dev_attr_temp2_fault.dev_attr.attr, 188 &sensor_dev_attr_temp3_input.dev_attr.attr, 189 &sensor_dev_attr_temp3_fault.dev_attr.attr, 190 &sensor_dev_attr_temp4_input.dev_attr.attr, 191 &sensor_dev_attr_temp4_fault.dev_attr.attr, 192 NULL 193 }; 194 195 static const struct attribute_group tmp421_group = { 196 .attrs = tmp421_attr, 197 .is_visible = tmp421_is_visible, 198 }; 199 200 static int tmp421_init_client(struct i2c_client *client) 201 { 202 int config, config_orig; 203 204 /* Set the conversion rate to 2 Hz */ 205 i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05); 206 207 /* Start conversions (disable shutdown if necessary) */ 208 config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); 209 if (config < 0) { 210 dev_err(&client->dev, "Could not read configuration" 211 " register (%d)\n", config); 212 return -ENODEV; 213 } 214 215 config_orig = config; 216 config &= ~TMP421_CONFIG_SHUTDOWN; 217 218 if (config != config_orig) { 219 dev_info(&client->dev, "Enable monitoring chip\n"); 220 i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config); 221 } 222 223 return 0; 224 } 225 226 static int tmp421_detect(struct i2c_client *client, int kind, 227 struct i2c_board_info *info) 228 { 229 struct i2c_adapter *adapter = client->adapter; 230 const char *names[] = { "TMP421", "TMP422", "TMP423" }; 231 232 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 233 return -ENODEV; 234 235 if (kind <= 0) { 236 u8 reg; 237 238 reg = i2c_smbus_read_byte_data(client, 239 TMP421_MANUFACTURER_ID_REG); 240 if (reg != TMP421_MANUFACTURER_ID) 241 return -ENODEV; 242 243 reg = i2c_smbus_read_byte_data(client, 244 TMP421_DEVICE_ID_REG); 245 switch (reg) { 246 case TMP421_DEVICE_ID: 247 kind = tmp421; 248 break; 249 case TMP422_DEVICE_ID: 250 kind = tmp422; 251 break; 252 case TMP423_DEVICE_ID: 253 kind = tmp423; 254 break; 255 default: 256 return -ENODEV; 257 } 258 } 259 strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); 260 dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", 261 names[kind - 1], client->addr); 262 263 return 0; 264 } 265 266 static int tmp421_probe(struct i2c_client *client, 267 const struct i2c_device_id *id) 268 { 269 struct tmp421_data *data; 270 int err; 271 272 data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL); 273 if (!data) 274 return -ENOMEM; 275 276 i2c_set_clientdata(client, data); 277 mutex_init(&data->update_lock); 278 data->kind = id->driver_data; 279 280 err = tmp421_init_client(client); 281 if (err) 282 goto exit_free; 283 284 err = sysfs_create_group(&client->dev.kobj, &tmp421_group); 285 if (err) 286 goto exit_free; 287 288 data->hwmon_dev = hwmon_device_register(&client->dev); 289 if (IS_ERR(data->hwmon_dev)) { 290 err = PTR_ERR(data->hwmon_dev); 291 data->hwmon_dev = NULL; 292 goto exit_remove; 293 } 294 return 0; 295 296 exit_remove: 297 sysfs_remove_group(&client->dev.kobj, &tmp421_group); 298 299 exit_free: 300 i2c_set_clientdata(client, NULL); 301 kfree(data); 302 303 return err; 304 } 305 306 static int tmp421_remove(struct i2c_client *client) 307 { 308 struct tmp421_data *data = i2c_get_clientdata(client); 309 310 hwmon_device_unregister(data->hwmon_dev); 311 sysfs_remove_group(&client->dev.kobj, &tmp421_group); 312 313 i2c_set_clientdata(client, NULL); 314 kfree(data); 315 316 return 0; 317 } 318 319 static struct i2c_driver tmp421_driver = { 320 .class = I2C_CLASS_HWMON, 321 .driver = { 322 .name = "tmp421", 323 }, 324 .probe = tmp421_probe, 325 .remove = tmp421_remove, 326 .id_table = tmp421_id, 327 .detect = tmp421_detect, 328 .address_data = &addr_data, 329 }; 330 331 static int __init tmp421_init(void) 332 { 333 return i2c_add_driver(&tmp421_driver); 334 } 335 336 static void __exit tmp421_exit(void) 337 { 338 i2c_del_driver(&tmp421_driver); 339 } 340 341 MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); 342 MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" 343 " driver"); 344 MODULE_LICENSE("GPL"); 345 346 module_init(tmp421_init); 347 module_exit(tmp421_exit); 348