aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/tmp421.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/tmp421.c')
-rw-r--r--drivers/hwmon/tmp421.c74
1 files changed, 36 insertions, 38 deletions
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 20924343431b..738c472ece27 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -39,8 +39,7 @@
39static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, 39static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
40 I2C_CLIENT_END }; 40 I2C_CLIENT_END };
41 41
42/* Insmod parameters */ 42enum chips { tmp421, tmp422, tmp423 };
43I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423);
44 43
45/* The TMP421 registers */ 44/* The TMP421 registers */
46#define TMP421_CONFIG_REG_1 0x09 45#define TMP421_CONFIG_REG_1 0x09
@@ -62,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 };
62#define TMP423_DEVICE_ID 0x23 61#define TMP423_DEVICE_ID 0x23
63 62
64static const struct i2c_device_id tmp421_id[] = { 63static const struct i2c_device_id tmp421_id[] = {
65 { "tmp421", tmp421 }, 64 { "tmp421", 2 },
66 { "tmp422", tmp422 }, 65 { "tmp422", 3 },
67 { "tmp423", tmp423 }, 66 { "tmp423", 4 },
68 { } 67 { }
69}; 68};
70MODULE_DEVICE_TABLE(i2c, tmp421_id); 69MODULE_DEVICE_TABLE(i2c, tmp421_id);
@@ -74,21 +73,23 @@ struct tmp421_data {
74 struct mutex update_lock; 73 struct mutex update_lock;
75 char valid; 74 char valid;
76 unsigned long last_updated; 75 unsigned long last_updated;
77 int kind; 76 int channels;
78 u8 config; 77 u8 config;
79 s16 temp[4]; 78 s16 temp[4];
80}; 79};
81 80
82static int temp_from_s16(s16 reg) 81static int temp_from_s16(s16 reg)
83{ 82{
84 int temp = reg; 83 /* Mask out status bits */
84 int temp = reg & ~0xf;
85 85
86 return (temp * 1000 + 128) / 256; 86 return (temp * 1000 + 128) / 256;
87} 87}
88 88
89static int temp_from_u16(u16 reg) 89static int temp_from_u16(u16 reg)
90{ 90{
91 int temp = reg; 91 /* Mask out status bits */
92 int temp = reg & ~0xf;
92 93
93 /* Add offset for extended temperature range. */ 94 /* Add offset for extended temperature range. */
94 temp -= 64 * 256; 95 temp -= 64 * 256;
@@ -108,7 +109,7 @@ static struct tmp421_data *tmp421_update_device(struct device *dev)
108 data->config = i2c_smbus_read_byte_data(client, 109 data->config = i2c_smbus_read_byte_data(client,
109 TMP421_CONFIG_REG_1); 110 TMP421_CONFIG_REG_1);
110 111
111 for (i = 0; i <= data->kind; i++) { 112 for (i = 0; i < data->channels; i++) {
112 data->temp[i] = i2c_smbus_read_byte_data(client, 113 data->temp[i] = i2c_smbus_read_byte_data(client,
113 TMP421_TEMP_MSB[i]) << 8; 114 TMP421_TEMP_MSB[i]) << 8;
114 data->temp[i] |= i2c_smbus_read_byte_data(client, 115 data->temp[i] |= i2c_smbus_read_byte_data(client,
@@ -167,7 +168,7 @@ static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
167 devattr = container_of(a, struct device_attribute, attr); 168 devattr = container_of(a, struct device_attribute, attr);
168 index = to_sensor_dev_attr(devattr)->index; 169 index = to_sensor_dev_attr(devattr)->index;
169 170
170 if (data->kind > index) 171 if (index < data->channels)
171 return a->mode; 172 return a->mode;
172 173
173 return 0; 174 return 0;
@@ -223,42 +224,39 @@ static int tmp421_init_client(struct i2c_client *client)
223 return 0; 224 return 0;
224} 225}
225 226
226static int tmp421_detect(struct i2c_client *client, int kind, 227static int tmp421_detect(struct i2c_client *client,
227 struct i2c_board_info *info) 228 struct i2c_board_info *info)
228{ 229{
230 enum chips kind;
229 struct i2c_adapter *adapter = client->adapter; 231 struct i2c_adapter *adapter = client->adapter;
230 const char *names[] = { "TMP421", "TMP422", "TMP423" }; 232 const char *names[] = { "TMP421", "TMP422", "TMP423" };
233 u8 reg;
231 234
232 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 235 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
233 return -ENODEV; 236 return -ENODEV;
234 237
235 if (kind <= 0) { 238 reg = i2c_smbus_read_byte_data(client, TMP421_MANUFACTURER_ID_REG);
236 u8 reg; 239 if (reg != TMP421_MANUFACTURER_ID)
237 240 return -ENODEV;
238 reg = i2c_smbus_read_byte_data(client, 241
239 TMP421_MANUFACTURER_ID_REG); 242 reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
240 if (reg != TMP421_MANUFACTURER_ID) 243 switch (reg) {
241 return -ENODEV; 244 case TMP421_DEVICE_ID:
242 245 kind = tmp421;
243 reg = i2c_smbus_read_byte_data(client, 246 break;
244 TMP421_DEVICE_ID_REG); 247 case TMP422_DEVICE_ID:
245 switch (reg) { 248 kind = tmp422;
246 case TMP421_DEVICE_ID: 249 break;
247 kind = tmp421; 250 case TMP423_DEVICE_ID:
248 break; 251 kind = tmp423;
249 case TMP422_DEVICE_ID: 252 break;
250 kind = tmp422; 253 default:
251 break; 254 return -ENODEV;
252 case TMP423_DEVICE_ID:
253 kind = tmp423;
254 break;
255 default:
256 return -ENODEV;
257 }
258 } 255 }
259 strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); 256
257 strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
260 dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", 258 dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
261 names[kind - 1], client->addr); 259 names[kind], client->addr);
262 260
263 return 0; 261 return 0;
264} 262}
@@ -275,7 +273,7 @@ static int tmp421_probe(struct i2c_client *client,
275 273
276 i2c_set_clientdata(client, data); 274 i2c_set_clientdata(client, data);
277 mutex_init(&data->update_lock); 275 mutex_init(&data->update_lock);
278 data->kind = id->driver_data; 276 data->channels = id->driver_data;
279 277
280 err = tmp421_init_client(client); 278 err = tmp421_init_client(client);
281 if (err) 279 if (err)
@@ -325,7 +323,7 @@ static struct i2c_driver tmp421_driver = {
325 .remove = tmp421_remove, 323 .remove = tmp421_remove,
326 .id_table = tmp421_id, 324 .id_table = tmp421_id,
327 .detect = tmp421_detect, 325 .detect = tmp421_detect,
328 .address_data = &addr_data, 326 .address_list = normal_i2c,
329}; 327};
330 328
331static int __init tmp421_init(void) 329static int __init tmp421_init(void)