From ff065137154478940de641255d24e473aa94ce10 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 6 Feb 2012 10:23:07 +0000 Subject: [PATCH] hwmon: backport IT8728F support for linux 3.3. svn path=/dists/trunk/linux-2.6/; revision=18669 --- debian/changelog | 7 + .../all/hwmon-it87-Add-IT8728F-support.patch | 270 ++++++++++++++++++ debian/patches/series/base | 2 + 3 files changed, 279 insertions(+) create mode 100644 debian/patches/features/all/hwmon-it87-Add-IT8728F-support.patch diff --git a/debian/changelog b/debian/changelog index c9da3b61c..d0ff367b0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +linux-2.6 (3.2.4-2) UNRELEASED; urgency=low + + [ Aurelien Jarno ] + * hwmon: backport IT8728F support for linux 3.3. + + -- Bastian Blank Mon, 06 Feb 2012 11:22:07 +0100 + linux-2.6 (3.2.4-1) unstable; urgency=low * New upstream stable update: diff --git a/debian/patches/features/all/hwmon-it87-Add-IT8728F-support.patch b/debian/patches/features/all/hwmon-it87-Add-IT8728F-support.patch new file mode 100644 index 000000000..97def2c89 --- /dev/null +++ b/debian/patches/features/all/hwmon-it87-Add-IT8728F-support.patch @@ -0,0 +1,270 @@ +From: Jean Delvare +Date: Mon, 16 Jan 2012 22:51:48 +0100 +Subject: [PATCH] hwmon: (it87) Add IT8728F support + +commit 16b5dda22e3798e61bb008d2329d4f4d90ef764e upstream. + +Until we get a datasheet for the IT8728F, treat it as fully compatible +with the IT8721F, as it seems to work reasonably well. + +This closes kernel bug #27262. + +Signed-off-by: Jean Delvare +Acked-by: Guenter Roeck +--- + Documentation/hwmon/it87 | 13 +++++++-- + drivers/hwmon/Kconfig | 4 +- + drivers/hwmon/it87.c | 61 ++++++++++++++++++++++++++++++++++----------- + 3 files changed, 58 insertions(+), 20 deletions(-) + +diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 +index 6f496a5..23b7def 100644 +--- a/Documentation/hwmon/it87 ++++ b/Documentation/hwmon/it87 +@@ -26,6 +26,10 @@ Supported chips: + Prefix: 'it8721' + Addresses scanned: from Super I/O config space (8 I/O ports) + Datasheet: Not publicly available ++ * IT8728F ++ Prefix: 'it8728' ++ Addresses scanned: from Super I/O config space (8 I/O ports) ++ Datasheet: Not publicly available + * SiS950 [clone of IT8705F] + Prefix: 'it87' + Addresses scanned: from Super I/O config space (8 I/O ports) +@@ -71,7 +75,7 @@ Description + ----------- + + This driver implements support for the IT8705F, IT8712F, IT8716F, +-IT8718F, IT8720F, IT8721F, IT8726F, IT8758E and SiS950 chips. ++IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E and SiS950 chips. + + These chips are 'Super I/O chips', supporting floppy disks, infrared ports, + joysticks and other miscellaneous stuff. For hardware monitoring, they +@@ -105,6 +109,9 @@ The IT8726F is just bit enhanced IT8716F with additional hardware + for AMD power sequencing. Therefore the chip will appear as IT8716F + to userspace applications. + ++The IT8728F is considered compatible with the IT8721F, until a datasheet ++becomes available (hopefully.) ++ + Temperatures are measured in degrees Celsius. An alarm is triggered once + when the Overtemperature Shutdown limit is crossed. + +@@ -121,8 +128,8 @@ alarm is triggered if the voltage has crossed a programmable minimum or + maximum limit. Note that minimum in this case always means 'closest to + zero'; this is important for negative voltage measurements. All voltage + inputs can measure voltages between 0 and 4.08 volts, with a resolution of +-0.016 volt (except IT8721F/IT8758E: 0.012 volt.) The battery voltage in8 does +-not have limit registers. ++0.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery ++voltage in8 does not have limit registers. + + On the IT8721F/IT8758E, some voltage inputs are internal and scaled inside + the chip (in7, in8 and optionally in3). The driver handles this transparently +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index f468bbb..0226040 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -474,8 +474,8 @@ config SENSORS_IT87 + select HWMON_VID + help + If you say yes here you get support for ITE IT8705F, IT8712F, +- IT8716F, IT8718F, IT8720F, IT8721F, IT8726F and IT8758E sensor +- chips, and the SiS960 clone. ++ IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F and IT8758E ++ sensor chips, and the SiS960 clone. + + This driver can also be built as a module. If so, the module + will be called it87. +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index 603ef2a..0054d6f 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -17,6 +17,7 @@ + * IT8720F Super I/O chip w/LPC interface + * IT8721F Super I/O chip w/LPC interface + * IT8726F Super I/O chip w/LPC interface ++ * IT8728F Super I/O chip w/LPC interface + * IT8758E Super I/O chip w/LPC interface + * Sis950 A clone of the IT8705F + * +@@ -58,7 +59,7 @@ + + #define DRVNAME "it87" + +-enum chips { it87, it8712, it8716, it8718, it8720, it8721 }; ++enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728 }; + + static unsigned short force_id; + module_param(force_id, ushort, 0); +@@ -135,6 +136,7 @@ static inline void superio_exit(void) + #define IT8720F_DEVID 0x8720 + #define IT8721F_DEVID 0x8721 + #define IT8726F_DEVID 0x8726 ++#define IT8728F_DEVID 0x8728 + #define IT87_ACT_REG 0x30 + #define IT87_BASE_REG 0x60 + +@@ -274,11 +276,31 @@ struct it87_data { + s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ + }; + ++static inline int has_12mv_adc(const struct it87_data *data) ++{ ++ /* ++ * IT8721F and later have a 12 mV ADC, also with internal scaling ++ * on selected inputs. ++ */ ++ return data->type == it8721 ++ || data->type == it8728; ++} ++ ++static inline int has_newer_autopwm(const struct it87_data *data) ++{ ++ /* ++ * IT8721F and later have separate registers for the temperature ++ * mapping and the manual duty cycle. ++ */ ++ return data->type == it8721 ++ || data->type == it8728; ++} ++ + static u8 in_to_reg(const struct it87_data *data, int nr, long val) + { + long lsb; + +- if (data->type == it8721) { ++ if (has_12mv_adc(data)) { + if (data->in_scaled & (1 << nr)) + lsb = 24; + else +@@ -292,7 +314,7 @@ static u8 in_to_reg(const struct it87_data *data, int nr, long val) + + static int in_from_reg(const struct it87_data *data, int nr, int val) + { +- if (data->type == it8721) { ++ if (has_12mv_adc(data)) { + if (data->in_scaled & (1 << nr)) + return val * 24; + else +@@ -329,7 +351,7 @@ static inline u16 FAN16_TO_REG(long rpm) + + static u8 pwm_to_reg(const struct it87_data *data, long val) + { +- if (data->type == it8721) ++ if (has_newer_autopwm(data)) + return val; + else + return val >> 1; +@@ -337,7 +359,7 @@ static u8 pwm_to_reg(const struct it87_data *data, long val) + + static int pwm_from_reg(const struct it87_data *data, u8 reg) + { +- if (data->type == it8721) ++ if (has_newer_autopwm(data)) + return reg; + else + return (reg & 0x7f) << 1; +@@ -374,7 +396,8 @@ static inline int has_16bit_fans(const struct it87_data *data) + || data->type == it8716 + || data->type == it8718 + || data->type == it8720 +- || data->type == it8721; ++ || data->type == it8721 ++ || data->type == it8728; + } + + static inline int has_old_autopwm(const struct it87_data *data) +@@ -842,7 +865,7 @@ static ssize_t set_pwm_enable(struct device *dev, + data->fan_main_ctrl); + } else { + if (val == 1) /* Manual mode */ +- data->pwm_ctrl[nr] = data->type == it8721 ? ++ data->pwm_ctrl[nr] = has_newer_autopwm(data) ? + data->pwm_temp_map[nr] : + data->pwm_duty[nr]; + else /* Automatic mode */ +@@ -870,7 +893,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, + return -EINVAL; + + mutex_lock(&data->update_lock); +- if (data->type == it8721) { ++ if (has_newer_autopwm(data)) { + /* If we are in automatic mode, the PWM duty cycle register + * is read-only so we can't write the value */ + if (data->pwm_ctrl[nr] & 0x80) { +@@ -1311,8 +1334,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr, + struct it87_data *data = dev_get_drvdata(dev); + int nr = to_sensor_dev_attr(attr)->index; + +- return sprintf(buf, "%s\n", data->type == it8721 ? labels_it8721[nr] +- : labels[nr]); ++ return sprintf(buf, "%s\n", has_12mv_adc(data) ? labels_it8721[nr] ++ : labels[nr]); + } + static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); + static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); +@@ -1605,6 +1628,9 @@ static int __init it87_find(unsigned short *address, + case IT8721F_DEVID: + sio_data->type = it8721; + break; ++ case IT8728F_DEVID: ++ sio_data->type = it8728; ++ break; + case 0xffff: /* No device at all */ + goto exit; + default: +@@ -1646,8 +1672,11 @@ static int __init it87_find(unsigned short *address, + superio_select(GPIO); + + reg = superio_inb(IT87_SIO_GPIO3_REG); +- if (sio_data->type == it8721) { +- /* The IT8721F/IT8758E doesn't have VID pins at all */ ++ if (sio_data->type == it8721 || sio_data->type == it8728) { ++ /* ++ * The IT8721F/IT8758E doesn't have VID pins at all, ++ * not sure about the IT8728F. ++ */ + sio_data->skip_vid = 1; + } else { + /* We need at least 4 VID pins */ +@@ -1692,7 +1721,8 @@ static int __init it87_find(unsigned short *address, + } + if (reg & (1 << 0)) + sio_data->internal |= (1 << 0); +- if ((reg & (1 << 1)) || sio_data->type == it8721) ++ if ((reg & (1 << 1)) || sio_data->type == it8721 || ++ sio_data->type == it8728) + sio_data->internal |= (1 << 1); + + sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; +@@ -1770,6 +1800,7 @@ static int __devinit it87_probe(struct platform_device *pdev) + "it8718", + "it8720", + "it8721", ++ "it8728", + }; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); +@@ -1807,7 +1838,7 @@ static int __devinit it87_probe(struct platform_device *pdev) + enable_pwm_interface = it87_check_pwm(dev); + + /* Starting with IT8721F, we handle scaling of internal voltages */ +- if (data->type == it8721) { ++ if (has_12mv_adc(data)) { + if (sio_data->internal & (1 << 0)) + data->in_scaled |= (1 << 3); /* in3 is AVCC */ + if (sio_data->internal & (1 << 1)) +@@ -2093,7 +2124,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) + static void it87_update_pwm_ctrl(struct it87_data *data, int nr) + { + data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); +- if (data->type == it8721) { ++ if (has_newer_autopwm(data)) { + data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; + data->pwm_duty[nr] = it87_read_value(data, + IT87_REG_PWM_DUTY(nr)); +-- +1.7.9 + diff --git a/debian/patches/series/base b/debian/patches/series/base index ce7a538e1..d8884c2b0 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -74,3 +74,5 @@ + bugfix/x86/KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch + bugfix/x86/KVM-x86-fix-missing-checks-in-syscall-emulation.patch + bugfix/all/pci-rework-aspm-disable-code.patch + ++ features/all/hwmon-it87-Add-IT8728F-support.patch