diff options
| -rw-r--r-- | drivers/hwmon/it87.c | 155 |
1 files changed, 81 insertions, 74 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 59c147b9b97..e8fdc438df0 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -228,6 +228,63 @@ static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; | |||
| 228 | #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i)) | 228 | #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i)) |
| 229 | #define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i)) | 229 | #define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i)) |
| 230 | 230 | ||
| 231 | struct it87_devices { | ||
| 232 | const char *name; | ||
| 233 | u16 features; | ||
| 234 | }; | ||
| 235 | |||
| 236 | #define FEAT_12MV_ADC (1 << 0) | ||
| 237 | #define FEAT_NEWER_AUTOPWM (1 << 1) | ||
| 238 | #define FEAT_OLD_AUTOPWM (1 << 2) | ||
| 239 | #define FEAT_16BIT_FANS (1 << 3) | ||
| 240 | #define FEAT_TEMP_OFFSET (1 << 4) | ||
| 241 | |||
| 242 | static const struct it87_devices it87_devices[] = { | ||
| 243 | [it87] = { | ||
| 244 | .name = "it87", | ||
| 245 | .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ | ||
| 246 | }, | ||
| 247 | [it8712] = { | ||
| 248 | .name = "it8712", | ||
| 249 | .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ | ||
| 250 | }, | ||
| 251 | [it8716] = { | ||
| 252 | .name = "it8716", | ||
| 253 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, | ||
| 254 | }, | ||
| 255 | [it8718] = { | ||
| 256 | .name = "it8718", | ||
| 257 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, | ||
| 258 | }, | ||
| 259 | [it8720] = { | ||
| 260 | .name = "it8720", | ||
| 261 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, | ||
| 262 | }, | ||
| 263 | [it8721] = { | ||
| 264 | .name = "it8721", | ||
| 265 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | ||
| 266 | | FEAT_TEMP_OFFSET, | ||
| 267 | }, | ||
| 268 | [it8728] = { | ||
| 269 | .name = "it8728", | ||
| 270 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | ||
| 271 | | FEAT_TEMP_OFFSET, | ||
| 272 | }, | ||
| 273 | [it8782] = { | ||
| 274 | .name = "it8782", | ||
| 275 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, | ||
| 276 | }, | ||
| 277 | [it8783] = { | ||
| 278 | .name = "it8783", | ||
| 279 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, | ||
| 280 | }, | ||
| 281 | }; | ||
| 282 | |||
| 283 | #define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS) | ||
| 284 | #define has_12mv_adc(data) ((data)->features & FEAT_12MV_ADC) | ||
| 285 | #define has_newer_autopwm(data) ((data)->features & FEAT_NEWER_AUTOPWM) | ||
| 286 | #define has_old_autopwm(data) ((data)->features & FEAT_OLD_AUTOPWM) | ||
| 287 | #define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET) | ||
| 231 | 288 | ||
| 232 | struct it87_sio_data { | 289 | struct it87_sio_data { |
| 233 | enum chips type; | 290 | enum chips type; |
| @@ -251,7 +308,7 @@ struct it87_sio_data { | |||
| 251 | struct it87_data { | 308 | struct it87_data { |
| 252 | struct device *hwmon_dev; | 309 | struct device *hwmon_dev; |
| 253 | enum chips type; | 310 | enum chips type; |
| 254 | u8 revision; | 311 | u16 features; |
| 255 | 312 | ||
| 256 | unsigned short addr; | 313 | unsigned short addr; |
| 257 | const char *name; | 314 | const char *name; |
| @@ -293,37 +350,6 @@ struct it87_data { | |||
| 293 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ | 350 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ |
| 294 | }; | 351 | }; |
| 295 | 352 | ||
| 296 | static inline int has_12mv_adc(const struct it87_data *data) | ||
| 297 | { | ||
| 298 | /* | ||
| 299 | * IT8721F and later have a 12 mV ADC, also with internal scaling | ||
| 300 | * on selected inputs. | ||
| 301 | */ | ||
| 302 | return data->type == it8721 | ||
| 303 | || data->type == it8728; | ||
| 304 | } | ||
| 305 | |||
| 306 | static inline int has_newer_autopwm(const struct it87_data *data) | ||
| 307 | { | ||
| 308 | /* | ||
| 309 | * IT8721F and later have separate registers for the temperature | ||
| 310 | * mapping and the manual duty cycle. | ||
| 311 | */ | ||
| 312 | return data->type == it8721 | ||
| 313 | || data->type == it8728; | ||
| 314 | } | ||
| 315 | |||
| 316 | static inline int has_temp_offset(const struct it87_data *data) | ||
| 317 | { | ||
| 318 | return data->type == it8716 | ||
| 319 | || data->type == it8718 | ||
| 320 | || data->type == it8720 | ||
| 321 | || data->type == it8721 | ||
| 322 | || data->type == it8728 | ||
| 323 | || data->type == it8782 | ||
| 324 | || data->type == it8783; | ||
| 325 | } | ||
| 326 | |||
| 327 | static int adc_lsb(const struct it87_data *data, int nr) | 353 | static int adc_lsb(const struct it87_data *data, int nr) |
| 328 | { | 354 | { |
| 329 | int lsb = has_12mv_adc(data) ? 12 : 16; | 355 | int lsb = has_12mv_adc(data) ? 12 : 16; |
| @@ -406,35 +432,6 @@ static const unsigned int pwm_freq[8] = { | |||
| 406 | 750000 / 128, | 432 | 750000 / 128, |
| 407 | }; | 433 | }; |
| 408 | 434 | ||
| 409 | static inline int has_16bit_fans(const struct it87_data *data) | ||
| 410 | { | ||
| 411 | /* | ||
| 412 | * IT8705F Datasheet 0.4.1, 3h == Version G. | ||
| 413 | * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
| 414 | * These are the first revisions with 16-bit tachometer support. | ||
| 415 | */ | ||
| 416 | return (data->type == it87 && data->revision >= 0x03) | ||
| 417 | || (data->type == it8712 && data->revision >= 0x08) | ||
| 418 | || data->type == it8716 | ||
| 419 | || data->type == it8718 | ||
| 420 | || data->type == it8720 | ||
| 421 | || data->type == it8721 | ||
| 422 | || data->type == it8728 | ||
| 423 | || data->type == it8782 | ||
| 424 | || data->type == it8783; | ||
| 425 | } | ||
| 426 | |||
| 427 | static inline int has_old_autopwm(const struct it87_data *data) | ||
| 428 | { | ||
| 429 | /* | ||
| 430 | * The old automatic fan speed control interface is implemented | ||
| 431 | * by IT8705F chips up to revision F and IT8712F chips up to | ||
| 432 | * revision G. | ||
| 433 | */ | ||
| 434 | return (data->type == it87 && data->revision < 0x03) | ||
| 435 | || (data->type == it8712 && data->revision < 0x08); | ||
| 436 | } | ||
| 437 | |||
| 438 | static int it87_probe(struct platform_device *pdev); | 435 | static int it87_probe(struct platform_device *pdev); |
| 439 | static int it87_remove(struct platform_device *pdev); | 436 | static int it87_remove(struct platform_device *pdev); |
| 440 | 437 | ||
| @@ -1952,17 +1949,6 @@ static int it87_probe(struct platform_device *pdev) | |||
| 1952 | int err = 0, i; | 1949 | int err = 0, i; |
| 1953 | int enable_pwm_interface; | 1950 | int enable_pwm_interface; |
| 1954 | int fan_beep_need_rw; | 1951 | int fan_beep_need_rw; |
| 1955 | static const char * const names[] = { | ||
| 1956 | "it87", | ||
| 1957 | "it8712", | ||
| 1958 | "it8716", | ||
| 1959 | "it8718", | ||
| 1960 | "it8720", | ||
| 1961 | "it8721", | ||
| 1962 | "it8728", | ||
| 1963 | "it8782", | ||
| 1964 | "it8783", | ||
| 1965 | }; | ||
| 1966 | 1952 | ||
| 1967 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1953 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 1968 | if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT, | 1954 | if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT, |
| @@ -1979,8 +1965,29 @@ static int it87_probe(struct platform_device *pdev) | |||
| 1979 | 1965 | ||
| 1980 | data->addr = res->start; | 1966 | data->addr = res->start; |
| 1981 | data->type = sio_data->type; | 1967 | data->type = sio_data->type; |
| 1982 | data->revision = sio_data->revision; | 1968 | data->features = it87_devices[sio_data->type].features; |
| 1983 | data->name = names[sio_data->type]; | 1969 | data->name = it87_devices[sio_data->type].name; |
| 1970 | /* | ||
| 1971 | * IT8705F Datasheet 0.4.1, 3h == Version G. | ||
| 1972 | * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
| 1973 | * These are the first revisions with 16-bit tachometer support. | ||
| 1974 | */ | ||
| 1975 | switch (data->type) { | ||
| 1976 | case it87: | ||
| 1977 | if (sio_data->revision >= 0x03) { | ||
| 1978 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
| 1979 | data->features |= FEAT_16BIT_FANS; | ||
| 1980 | } | ||
| 1981 | break; | ||
| 1982 | case it8712: | ||
| 1983 | if (sio_data->revision >= 0x08) { | ||
| 1984 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
| 1985 | data->features |= FEAT_16BIT_FANS; | ||
| 1986 | } | ||
| 1987 | break; | ||
| 1988 | default: | ||
| 1989 | break; | ||
| 1990 | } | ||
| 1984 | 1991 | ||
| 1985 | /* Now, we do the remaining detection. */ | 1992 | /* Now, we do the remaining detection. */ |
| 1986 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) | 1993 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) |
