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 enum chips { tmp421, tmp422, tmp423 }; 43 44 /* The TMP421 registers */ 45 #define TMP421_CONFIG_REG_1 0x09 46 #define TMP421_CONVERSION_RATE_REG 0x0B 47 #define TMP421_MANUFACTURER_ID_REG 0xFE 48 #define TMP421_DEVICE_ID_REG 0xFF 49 50 static const u8 TMP421_TEMP_MSB[4] = { 0x00, 0x01, 0x02, 0x03 }; 51 static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 }; 52 53 /* Flags */ 54 #define TMP421_CONFIG_SHUTDOWN 0x40 55 #define TMP421_CONFIG_RANGE 0x04 56 57 /* Manufacturer / Device ID's */ 58 #define TMP421_MANUFACTURER_ID 0x55 59 #define TMP421_DEVICE_ID 0x21 60 #define TMP422_DEVICE_ID 0x22 61 #define TMP423_DEVICE_ID 0x23 62 63 static const struct i2c_device_id tmp421_id[] = { 64 { "tmp421", tmp421 }, 65 { "tmp422", tmp422 }, 66 { "tmp423", tmp423 }, 67 { } 68 }; 69 MODULE_DEVICE_TABLE(i2c, tmp421_id); 70 71 struct tmp421_data { 72 struct device *hwmon_dev; 73 struct mutex update_lock; 74 char valid; 75 unsigned long last_updated; 76 int kind; 77 u8 config; 78 s16 temp[4]; 79 }; 80 81 static int temp_from_s16(s16 reg) 82 { 83 int temp = reg; 84 85 return (temp * 1000 + 128) / 256; 86 } 87 88 static int temp_from_u16(u16 reg) 89 { 90 int temp = reg; 91 92 /* Add offset for extended temperature range. */ 93 temp -= 64 * 256; 94 95 return (temp * 1000 + 128) / 256; 96 } 97 98 static struct tmp421_data *tmp421_update_device(struct device *dev) 99 { 100 struct i2c_client *client = to_i2c_client(dev); 101 struct tmp421_data *data = i2c_get_clientdata(client); 102 int i; 103 104 mutex_lock(&data->update_lock); 105 106 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { 107 data->config = i2c_smbus_read_byte_data(client, 108 TMP421_CONFIG_REG_1); 109 110 for (i = 0; i <= data->kind; i++) { 111 data->temp[i] = i2c_smbus_read_byte_data(client, 112 TMP421_TEMP_MSB[i]) << 8; 113 data->temp[i] |= i2c_smbus_read_byte_data(client, 114 TMP421_TEMP_LSB[i]); 115 } 116 data->last_updated = jiffies; 117 data->valid = 1; 118 } 119 120 mutex_unlock(&data->update_lock); 121 122 return data; 123 } 124 125 static ssize_t show_temp_value(struct device *dev, 126 struct device_attribute *devattr, char *buf) 127 { 128 int index = to_sensor_dev_attr(devattr)->index; 129 struct tmp421_data *data = tmp421_update_device(dev); 130 int temp; 131 132 mutex_lock(&data->update_lock); 133 if (data->config & TMP421_CONFIG_RANGE) 134 temp = temp_from_u16(data->temp[index]); 135 else 136 temp = temp_from_s16(data->temp[index]); 137 mutex_unlock(&data->update_lock); 138 139 return sprintf(buf, "%d\n", temp); 140 } 141 142 static ssize_t show_fault(struct device *dev, 143 struct device_attribute *devattr, char *buf) 144 { 145 int index = to_sensor_dev_attr(devattr)->index; 146 struct tmp421_data *data = tmp421_update_device(dev); 147 148 /* 149 * The OPEN bit signals a fault. This is bit 0 of the temperature 150 * register (low byte). 151 */ 152 if (data->temp[index] & 0x01) 153 return sprintf(buf, "1\n"); 154 else 155 return sprintf(buf, "0\n"); 156 } 157 158 static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, 159 int n) 160 { 161 struct device *dev = container_of(kobj, struct device, kobj); 162 struct tmp421_data *data = dev_get_drvdata(dev); 163 struct device_attribute *devattr; 164 unsigned int index; 165 166 devattr = container_of(a, struct device_attribute, attr); 167 index = to_sensor_dev_attr(devattr)->index; 168 169 if (data->kind > index) 170 return a->mode; 171 172 return 0; 173 } 174 175 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0); 176 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1); 177 static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1); 178 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2); 179 static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2); 180 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3); 181 static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3); 182 183 static struct attribute *tmp421_attr[] = { 184 &sensor_dev_attr_temp1_input.dev_attr.attr, 185 &sensor_dev_attr_temp2_input.dev_attr.attr, 186 &sensor_dev_attr_temp2_fault.dev_attr.attr, 187 &sensor_dev_attr_temp3_input.dev_attr.attr, 188 &sensor_dev_attr_temp3_fault.dev_attr.attr, 189 &sensor_dev_attr_temp4_input.dev_attr.attr, 190 &sensor_dev_attr_temp4_fault.dev_attr.attr, 191 NULL 192 }; 193 194 static const struct attribute_group tmp421_group = { 195 .attrs = tmp421_attr, 196 .is_visible = tmp421_is_visible, 197 }; 198 199 static int tmp421_init_client(struct i2c_client *client) 200 { 201 int config, config_orig; 202 203 /* Set the conversion rate to 2 Hz */ 204 i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05); 205 206 /* Start conversions (disable shutdown if necessary) */ 207 config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); 208 if (config < 0) { 209 dev_err(&client->dev, "Could not read configuration" 210 " register (%d)\n", config); 211 return -ENODEV; 212 } 213 214 config_orig = config; 215 config &= ~TMP421_CONFIG_SHUTDOWN; 216 217 if (config != config_orig) { 218 dev_info(&client->dev, "Enable monitoring chip\n"); 219 i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config); 220 } 221 222 return 0; 223 } 224 225 static int tmp421_detect(struct i2c_client *client, 226 struct i2c_board_info *info) 227 { 228 enum chips kind; 229 struct i2c_adapter *adapter = client->adapter; 230 const char *names[] = { "TMP421", "TMP422", "TMP423" }; 231 u8 reg; 232 233 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 234 return -ENODEV; 235 236 reg = i2c_smbus_read_byte_data(client, TMP421_MANUFACTURER_ID_REG); 237 if (reg != TMP421_MANUFACTURER_ID) 238 return -ENODEV; 239 240 reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG); 241 switch (reg) { 242 case TMP421_DEVICE_ID: 243 kind = tmp421; 244 break; 245 case TMP422_DEVICE_ID: 246 kind = tmp422; 247 break; 248 case TMP423_DEVICE_ID: 249 kind = tmp423; 250 break; 251 default: 252 return -ENODEV; 253 } 254 255 strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); 256 dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", 257 names[kind - 1], client->addr); 258 259 return 0; 260 } 261 262 static int tmp421_probe(struct i2c_client *client, 263 const struct i2c_device_id *id) 264 { 265 struct tmp421_data *data; 266 int err; 267 268 data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL); 269 if (!data) 270 return -ENOMEM; 271 272 i2c_set_clientdata(client, data); 273 mutex_init(&data->update_lock); 274 data->kind = id->driver_data; 275 276 err = tmp421_init_client(client); 277 if (err) 278 goto exit_free; 279 280 err = sysfs_create_group(&client->dev.kobj, &tmp421_group); 281 if (err) 282 goto exit_free; 283 284 data->hwmon_dev = hwmon_device_register(&client->dev); 285 if (IS_ERR(data->hwmon_dev)) { 286 err = PTR_ERR(data->hwmon_dev); 287 data->hwmon_dev = NULL; 288 goto exit_remove; 289 } 290 return 0; 291 292 exit_remove: 293 sysfs_remove_group(&client->dev.kobj, &tmp421_group); 294 295 exit_free: 296 i2c_set_clientdata(client, NULL); 297 kfree(data); 298 299 return err; 300 } 301 302 static int tmp421_remove(struct i2c_client *client) 303 { 304 struct tmp421_data *data = i2c_get_clientdata(client); 305 306 hwmon_device_unregister(data->hwmon_dev); 307 sysfs_remove_group(&client->dev.kobj, &tmp421_group); 308 309 i2c_set_clientdata(client, NULL); 310 kfree(data); 311 312 return 0; 313 } 314 315 static struct i2c_driver tmp421_driver = { 316 .class = I2C_CLASS_HWMON, 317 .driver = { 318 .name = "tmp421", 319 }, 320 .probe = tmp421_probe, 321 .remove = tmp421_remove, 322 .id_table = tmp421_id, 323 .detect = tmp421_detect, 324 .address_list = normal_i2c, 325 }; 326 327 static int __init tmp421_init(void) 328 { 329 return i2c_add_driver(&tmp421_driver); 330 } 331 332 static void __exit tmp421_exit(void) 333 { 334 i2c_del_driver(&tmp421_driver); 335 } 336 337 MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); 338 MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" 339 " driver"); 340 MODULE_LICENSE("GPL"); 341 342 module_init(tmp421_init); 343 module_exit(tmp421_exit); 344