aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
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
commit483db43e81f4958e3cd11a990112e8082a6a5261 (patch)
tree4f1f0081a8dedbb2ec9c2f264d40f03ae3772be7 /drivers/hwmon
parentc4458db3688a603a4cb4b1d01ca10ff0d58bc8eb (diff)
hwmon: (it87) Manage device specific features with table
This simplifies the code, improves runtime performance, reduces code size (about 280 bytes on x86_64), and makes it easier to add support for new devices. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/it87.c155
1 files changed, 81 insertions, 74 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 59c147b9b976..e8fdc438df0a 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
231struct 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
242static 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
232struct it87_sio_data { 289struct it87_sio_data {
233 enum chips type; 290 enum chips type;
@@ -251,7 +308,7 @@ struct it87_sio_data {
251struct it87_data { 308struct 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
296static 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
306static 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
316static 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
327static int adc_lsb(const struct it87_data *data, int nr) 353static 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
409static 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
427static 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
438static int it87_probe(struct platform_device *pdev); 435static int it87_probe(struct platform_device *pdev);
439static int it87_remove(struct platform_device *pdev); 436static 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)