aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-19 16:17:02 -0500
committerJean Delvare <khali@endymion.delvare>2012-12-19 16:17:02 -0500
commit19529784785d8fd164079e1008c8b1970d6062ee (patch)
tree457dc84c7b33647b7a74e72d0dbea70249e486a3 /drivers/hwmon/it87.c
parent5d8d2f2bdbd0812dfad05ca37e4b28912fca7e33 (diff)
hwmon: (it87) Support PECI for additional chips
Extend support for reporting and selecting PECI temperature sensors to IT8718, IT8720, IT8782, and IT8783. For IT8721, report the sensor type for temp2 as Intel PECI (6) if the chip is configured to report the PCH temperature. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 3827aa9aa11e..117d66fcded6 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -231,7 +231,8 @@ static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
231struct it87_devices { 231struct it87_devices {
232 const char *name; 232 const char *name;
233 u16 features; 233 u16 features;
234 u16 peci_mask; 234 u8 peci_mask;
235 u8 old_peci_mask;
235}; 236};
236 237
237#define FEAT_12MV_ADC (1 << 0) 238#define FEAT_12MV_ADC (1 << 0)
@@ -240,6 +241,7 @@ struct it87_devices {
240#define FEAT_16BIT_FANS (1 << 3) 241#define FEAT_16BIT_FANS (1 << 3)
241#define FEAT_TEMP_OFFSET (1 << 4) 242#define FEAT_TEMP_OFFSET (1 << 4)
242#define FEAT_TEMP_PECI (1 << 5) 243#define FEAT_TEMP_PECI (1 << 5)
244#define FEAT_TEMP_OLD_PECI (1 << 6)
243 245
244static const struct it87_devices it87_devices[] = { 246static const struct it87_devices it87_devices[] = {
245 [it87] = { 247 [it87] = {
@@ -256,17 +258,22 @@ static const struct it87_devices it87_devices[] = {
256 }, 258 },
257 [it8718] = { 259 [it8718] = {
258 .name = "it8718", 260 .name = "it8718",
259 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, 261 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
262 | FEAT_TEMP_OLD_PECI,
263 .old_peci_mask = 0x4,
260 }, 264 },
261 [it8720] = { 265 [it8720] = {
262 .name = "it8720", 266 .name = "it8720",
263 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, 267 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
268 | FEAT_TEMP_OLD_PECI,
269 .old_peci_mask = 0x4,
264 }, 270 },
265 [it8721] = { 271 [it8721] = {
266 .name = "it8721", 272 .name = "it8721",
267 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS 273 .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
268 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI, 274 | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI,
269 .peci_mask = 0x05, 275 .peci_mask = 0x05,
276 .old_peci_mask = 0x02, /* Actually reports PCH */
270 }, 277 },
271 [it8728] = { 278 [it8728] = {
272 .name = "it8728", 279 .name = "it8728",
@@ -276,11 +283,15 @@ static const struct it87_devices it87_devices[] = {
276 }, 283 },
277 [it8782] = { 284 [it8782] = {
278 .name = "it8782", 285 .name = "it8782",
279 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, 286 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
287 | FEAT_TEMP_OLD_PECI,
288 .old_peci_mask = 0x4,
280 }, 289 },
281 [it8783] = { 290 [it8783] = {
282 .name = "it8783", 291 .name = "it8783",
283 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, 292 .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
293 | FEAT_TEMP_OLD_PECI,
294 .old_peci_mask = 0x4,
284 }, 295 },
285}; 296};
286 297
@@ -291,6 +302,9 @@ static const struct it87_devices it87_devices[] = {
291#define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET) 302#define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET)
292#define has_temp_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \ 303#define has_temp_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \
293 ((data)->peci_mask & (1 << nr))) 304 ((data)->peci_mask & (1 << nr)))
305#define has_temp_old_peci(data, nr) \
306 (((data)->features & FEAT_TEMP_OLD_PECI) && \
307 ((data)->old_peci_mask & (1 << nr)))
294 308
295struct it87_sio_data { 309struct it87_sio_data {
296 enum chips type; 310 enum chips type;
@@ -315,7 +329,8 @@ struct it87_data {
315 struct device *hwmon_dev; 329 struct device *hwmon_dev;
316 enum chips type; 330 enum chips type;
317 u16 features; 331 u16 features;
318 u16 peci_mask; 332 u8 peci_mask;
333 u8 old_peci_mask;
319 334
320 unsigned short addr; 335 unsigned short addr;
321 const char *name; 336 const char *name;
@@ -329,7 +344,8 @@ struct it87_data {
329 u16 fan[5][2]; /* Register values, [nr][0]=fan, [1]=min */ 344 u16 fan[5][2]; /* Register values, [nr][0]=fan, [1]=min */
330 u8 has_temp; /* Bitfield, temp sensors enabled */ 345 u8 has_temp; /* Bitfield, temp sensors enabled */
331 s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ 346 s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
332 u8 sensor; /* Register value */ 347 u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */
348 u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */
333 u8 fan_div[3]; /* Register encoding, shifted right */ 349 u8 fan_div[3]; /* Register encoding, shifted right */
334 u8 vid; /* Register encoding, combined */ 350 u8 vid; /* Register encoding, combined */
335 u8 vrm; 351 u8 vrm;
@@ -623,8 +639,10 @@ static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
623 int nr = sensor_attr->index; 639 int nr = sensor_attr->index;
624 struct it87_data *data = it87_update_device(dev); 640 struct it87_data *data = it87_update_device(dev);
625 u8 reg = data->sensor; /* In case value is updated while used */ 641 u8 reg = data->sensor; /* In case value is updated while used */
642 u8 extra = data->extra;
626 643
627 if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1)) 644 if ((has_temp_peci(data, nr) && (reg >> 6 == nr + 1))
645 || (has_temp_old_peci(data, nr) && (extra & 0x80)))
628 return sprintf(buf, "6\n"); /* Intel PECI */ 646 return sprintf(buf, "6\n"); /* Intel PECI */
629 if (reg & (1 << nr)) 647 if (reg & (1 << nr))
630 return sprintf(buf, "3\n"); /* thermal diode */ 648 return sprintf(buf, "3\n"); /* thermal diode */
@@ -641,7 +659,7 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
641 659
642 struct it87_data *data = dev_get_drvdata(dev); 660 struct it87_data *data = dev_get_drvdata(dev);
643 long val; 661 long val;
644 u8 reg; 662 u8 reg, extra;
645 663
646 if (kstrtol(buf, 10, &val) < 0) 664 if (kstrtol(buf, 10, &val) < 0)
647 return -EINVAL; 665 return -EINVAL;
@@ -651,6 +669,9 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
651 reg &= ~(8 << nr); 669 reg &= ~(8 << nr);
652 if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1 || val == 6)) 670 if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1 || val == 6))
653 reg &= 0x3f; 671 reg &= 0x3f;
672 extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
673 if (has_temp_old_peci(data, nr) && ((extra & 0x80) || val == 6))
674 extra &= 0x7f;
654 if (val == 2) { /* backwards compatibility */ 675 if (val == 2) { /* backwards compatibility */
655 dev_warn(dev, 676 dev_warn(dev,
656 "Sensor type 2 is deprecated, please use 4 instead\n"); 677 "Sensor type 2 is deprecated, please use 4 instead\n");
@@ -663,12 +684,17 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
663 reg |= 8 << nr; 684 reg |= 8 << nr;
664 else if (has_temp_peci(data, nr) && val == 6) 685 else if (has_temp_peci(data, nr) && val == 6)
665 reg |= (nr + 1) << 6; 686 reg |= (nr + 1) << 6;
687 else if (has_temp_old_peci(data, nr) && val == 6)
688 extra |= 0x80;
666 else if (val != 0) 689 else if (val != 0)
667 return -EINVAL; 690 return -EINVAL;
668 691
669 mutex_lock(&data->update_lock); 692 mutex_lock(&data->update_lock);
670 data->sensor = reg; 693 data->sensor = reg;
694 data->extra = extra;
671 it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); 695 it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
696 if (has_temp_old_peci(data, nr))
697 it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
672 data->valid = 0; /* Force cache refresh */ 698 data->valid = 0; /* Force cache refresh */
673 mutex_unlock(&data->update_lock); 699 mutex_unlock(&data->update_lock);
674 return count; 700 return count;
@@ -1980,6 +2006,7 @@ static int it87_probe(struct platform_device *pdev)
1980 data->type = sio_data->type; 2006 data->type = sio_data->type;
1981 data->features = it87_devices[sio_data->type].features; 2007 data->features = it87_devices[sio_data->type].features;
1982 data->peci_mask = it87_devices[sio_data->type].peci_mask; 2008 data->peci_mask = it87_devices[sio_data->type].peci_mask;
2009 data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
1983 data->name = it87_devices[sio_data->type].name; 2010 data->name = it87_devices[sio_data->type].name;
1984 /* 2011 /*
1985 * IT8705F Datasheet 0.4.1, 3h == Version G. 2012 * IT8705F Datasheet 0.4.1, 3h == Version G.
@@ -2461,6 +2488,7 @@ static struct it87_data *it87_update_device(struct device *dev)
2461 it87_update_pwm_ctrl(data, i); 2488 it87_update_pwm_ctrl(data, i);
2462 2489
2463 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 2490 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
2491 data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
2464 /* 2492 /*
2465 * The IT8705F does not have VID capability. 2493 * The IT8705F does not have VID capability.
2466 * The IT8718F and later don't use IT87_REG_VID for the 2494 * The IT8718F and later don't use IT87_REG_VID for the