diff options
Diffstat (limited to 'drivers/hwmon/tmp421.c')
-rw-r--r-- | drivers/hwmon/tmp421.c | 74 |
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 @@ | |||
39 | static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, | 39 | static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, |
40 | I2C_CLIENT_END }; | 40 | I2C_CLIENT_END }; |
41 | 41 | ||
42 | /* Insmod parameters */ | 42 | enum chips { tmp421, tmp422, tmp423 }; |
43 | I2C_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 | ||
64 | static const struct i2c_device_id tmp421_id[] = { | 63 | static 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 | }; |
70 | MODULE_DEVICE_TABLE(i2c, tmp421_id); | 69 | MODULE_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 | ||
82 | static int temp_from_s16(s16 reg) | 81 | static 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 | ||
89 | static int temp_from_u16(u16 reg) | 89 | static 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 | ||
226 | static int tmp421_detect(struct i2c_client *client, int kind, | 227 | static 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 | ||
331 | static int __init tmp421_init(void) | 329 | static int __init tmp421_init(void) |