aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/thmc50.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/thmc50.c')
-rw-r--r--drivers/hwmon/thmc50.c68
1 files changed, 48 insertions, 20 deletions
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 9395b52d9b99..04dd7699b3ac 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -46,6 +46,11 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
46#define THMC50_REG_COMPANY_ID 0x3E 46#define THMC50_REG_COMPANY_ID 0x3E
47#define THMC50_REG_DIE_CODE 0x3F 47#define THMC50_REG_DIE_CODE 0x3F
48#define THMC50_REG_ANALOG_OUT 0x19 48#define THMC50_REG_ANALOG_OUT 0x19
49/*
50 * The mirror status register cannot be used as
51 * reading it does not clear alarms.
52 */
53#define THMC50_REG_INTR 0x41
49 54
50const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; 55const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
51const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; 56const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
@@ -56,7 +61,7 @@ const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
56/* Each client has this additional data */ 61/* Each client has this additional data */
57struct thmc50_data { 62struct thmc50_data {
58 struct i2c_client client; 63 struct i2c_client client;
59 struct class_device *class_dev; 64 struct device *hwmon_dev;
60 65
61 struct mutex update_lock; 66 struct mutex update_lock;
62 enum chips type; 67 enum chips type;
@@ -69,6 +74,7 @@ struct thmc50_data {
69 s8 temp_max[3]; 74 s8 temp_max[3];
70 s8 temp_min[3]; 75 s8 temp_min[3];
71 u8 analog_out; 76 u8 analog_out;
77 u8 alarms;
72}; 78};
73 79
74static int thmc50_attach_adapter(struct i2c_adapter *adapter); 80static int thmc50_attach_adapter(struct i2c_adapter *adapter);
@@ -180,6 +186,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
180 return count; 186 return count;
181} 187}
182 188
189static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
190 char *buf)
191{
192 int index = to_sensor_dev_attr(attr)->index;
193 struct thmc50_data *data = thmc50_update_device(dev);
194
195 return sprintf(buf, "%u\n", (data->alarms >> index) & 1);
196}
197
183#define temp_reg(offset) \ 198#define temp_reg(offset) \
184static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ 199static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \
185 NULL, offset - 1); \ 200 NULL, offset - 1); \
@@ -192,6 +207,12 @@ temp_reg(1);
192temp_reg(2); 207temp_reg(2);
193temp_reg(3); 208temp_reg(3);
194 209
210static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0);
211static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5);
212static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 1);
213static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 7);
214static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2);
215
195static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out, 216static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out,
196 set_analog_out, 0); 217 set_analog_out, 0);
197static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0); 218static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
@@ -200,9 +221,12 @@ static struct attribute *thmc50_attributes[] = {
200 &sensor_dev_attr_temp1_max.dev_attr.attr, 221 &sensor_dev_attr_temp1_max.dev_attr.attr,
201 &sensor_dev_attr_temp1_min.dev_attr.attr, 222 &sensor_dev_attr_temp1_min.dev_attr.attr,
202 &sensor_dev_attr_temp1_input.dev_attr.attr, 223 &sensor_dev_attr_temp1_input.dev_attr.attr,
224 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
203 &sensor_dev_attr_temp2_max.dev_attr.attr, 225 &sensor_dev_attr_temp2_max.dev_attr.attr,
204 &sensor_dev_attr_temp2_min.dev_attr.attr, 226 &sensor_dev_attr_temp2_min.dev_attr.attr,
205 &sensor_dev_attr_temp2_input.dev_attr.attr, 227 &sensor_dev_attr_temp2_input.dev_attr.attr,
228 &sensor_dev_attr_temp2_alarm.dev_attr.attr,
229 &sensor_dev_attr_temp2_fault.dev_attr.attr,
206 &sensor_dev_attr_pwm1.dev_attr.attr, 230 &sensor_dev_attr_pwm1.dev_attr.attr,
207 &sensor_dev_attr_pwm1_mode.dev_attr.attr, 231 &sensor_dev_attr_pwm1_mode.dev_attr.attr,
208 NULL 232 NULL
@@ -213,15 +237,17 @@ static const struct attribute_group thmc50_group = {
213}; 237};
214 238
215/* for ADM1022 3rd temperature mode */ 239/* for ADM1022 3rd temperature mode */
216static struct attribute *adm1022_attributes[] = { 240static struct attribute *temp3_attributes[] = {
217 &sensor_dev_attr_temp3_max.dev_attr.attr, 241 &sensor_dev_attr_temp3_max.dev_attr.attr,
218 &sensor_dev_attr_temp3_min.dev_attr.attr, 242 &sensor_dev_attr_temp3_min.dev_attr.attr,
219 &sensor_dev_attr_temp3_input.dev_attr.attr, 243 &sensor_dev_attr_temp3_input.dev_attr.attr,
244 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
245 &sensor_dev_attr_temp3_fault.dev_attr.attr,
220 NULL 246 NULL
221}; 247};
222 248
223static const struct attribute_group adm1022_group = { 249static const struct attribute_group temp3_group = {
224 .attrs = adm1022_attributes, 250 .attrs = temp3_attributes,
225}; 251};
226 252
227static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) 253static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
@@ -233,7 +259,7 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
233 struct thmc50_data *data; 259 struct thmc50_data *data;
234 struct device *dev; 260 struct device *dev;
235 int err = 0; 261 int err = 0;
236 const char *type_name = ""; 262 const char *type_name;
237 263
238 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 264 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
239 pr_debug("thmc50: detect failed, " 265 pr_debug("thmc50: detect failed, "
@@ -283,13 +309,9 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
283 pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n"); 309 pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
284 goto exit_free; 310 goto exit_free;
285 } 311 }
286 pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
287 type_name, (revision >> 4) - 0xc, revision & 0xf);
288 data->type = kind; 312 data->type = kind;
289 313
290 if (kind == thmc50) 314 if (kind == adm1022) {
291 type_name = "thmc50";
292 else if (kind == adm1022) {
293 int id = i2c_adapter_id(client->adapter); 315 int id = i2c_adapter_id(client->adapter);
294 int i; 316 int i;
295 317
@@ -302,7 +324,11 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
302 data->has_temp3 = 1; 324 data->has_temp3 = 1;
303 break; 325 break;
304 } 326 }
327 } else {
328 type_name = "thmc50";
305 } 329 }
330 pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
331 type_name, (revision >> 4) - 0xc, revision & 0xf);
306 332
307 /* Fill in the remaining client fields & put it into the global list */ 333 /* Fill in the remaining client fields & put it into the global list */
308 strlcpy(client->name, type_name, I2C_NAME_SIZE); 334 strlcpy(client->name, type_name, I2C_NAME_SIZE);
@@ -319,23 +345,23 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
319 goto exit_detach; 345 goto exit_detach;
320 346
321 /* Register ADM1022 sysfs hooks */ 347 /* Register ADM1022 sysfs hooks */
322 if (data->type == adm1022) 348 if (data->has_temp3)
323 if ((err = sysfs_create_group(&client->dev.kobj, 349 if ((err = sysfs_create_group(&client->dev.kobj,
324 &adm1022_group))) 350 &temp3_group)))
325 goto exit_remove_sysfs_thmc50; 351 goto exit_remove_sysfs_thmc50;
326 352
327 /* Register a new directory entry with module sensors */ 353 /* Register a new directory entry with module sensors */
328 data->class_dev = hwmon_device_register(&client->dev); 354 data->hwmon_dev = hwmon_device_register(&client->dev);
329 if (IS_ERR(data->class_dev)) { 355 if (IS_ERR(data->hwmon_dev)) {
330 err = PTR_ERR(data->class_dev); 356 err = PTR_ERR(data->hwmon_dev);
331 goto exit_remove_sysfs; 357 goto exit_remove_sysfs;
332 } 358 }
333 359
334 return 0; 360 return 0;
335 361
336exit_remove_sysfs: 362exit_remove_sysfs:
337 if (data->type == adm1022) 363 if (data->has_temp3)
338 sysfs_remove_group(&client->dev.kobj, &adm1022_group); 364 sysfs_remove_group(&client->dev.kobj, &temp3_group);
339exit_remove_sysfs_thmc50: 365exit_remove_sysfs_thmc50:
340 sysfs_remove_group(&client->dev.kobj, &thmc50_group); 366 sysfs_remove_group(&client->dev.kobj, &thmc50_group);
341exit_detach: 367exit_detach:
@@ -358,10 +384,10 @@ static int thmc50_detach_client(struct i2c_client *client)
358 struct thmc50_data *data = i2c_get_clientdata(client); 384 struct thmc50_data *data = i2c_get_clientdata(client);
359 int err; 385 int err;
360 386
361 hwmon_device_unregister(data->class_dev); 387 hwmon_device_unregister(data->hwmon_dev);
362 sysfs_remove_group(&client->dev.kobj, &thmc50_group); 388 sysfs_remove_group(&client->dev.kobj, &thmc50_group);
363 if (data->type == adm1022) 389 if (data->has_temp3)
364 sysfs_remove_group(&client->dev.kobj, &adm1022_group); 390 sysfs_remove_group(&client->dev.kobj, &temp3_group);
365 391
366 if ((err = i2c_detach_client(client))) 392 if ((err = i2c_detach_client(client)))
367 return err; 393 return err;
@@ -414,6 +440,8 @@ static struct thmc50_data *thmc50_update_device(struct device *dev)
414 } 440 }
415 data->analog_out = 441 data->analog_out =
416 i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); 442 i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
443 data->alarms =
444 i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
417 data->last_updated = jiffies; 445 data->last_updated = jiffies;
418 data->valid = 1; 446 data->valid = 1;
419 } 447 }