Lines Matching +full:reg +full:- +full:names

2  * f71805f.c - driver for the Fintek F71805F/FG and F71872F/FG Super-I/O
4 * Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org>
6 * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
39 #include <linux/hwmon-sysfs.h>
57 * Super-I/O constants and functions
75 superio_inb(int base, int reg) in superio_inb() argument
77 outb(reg, base); in superio_inb()
82 superio_inw(int base, int reg) in superio_inw() argument
85 outb(reg++, base); in superio_inw()
87 outb(reg, base); in superio_inw()
124 /* in nr from 0 to 10 (8-bit values) */
128 /* fan nr from 0 to 2 (12-bit values, two registers) */
135 /* temp nr from 0 to 2 (8-bit values) */
141 /* map Fintek numbers to our numbers as follows: 9->0, 5->1, 1->2 */
143 (0xA0 + 0x10 * (pwmnr) + (2 - (apnr)))
146 2 * (2 - (apnr)))
203 static inline long in_from_reg(u8 reg) in in_from_reg() argument
205 return (reg * 8); in in_from_reg()
219 static inline long in0_from_reg(u8 reg) in in0_from_reg() argument
221 return (reg * 16); in in0_from_reg()
234 static inline long fan_from_reg(u16 reg) in fan_from_reg() argument
236 reg &= 0xfff; in fan_from_reg()
237 if (!reg || reg == 0xfff) in fan_from_reg()
239 return (1500000 / reg); in fan_from_reg()
245 store the largest possible 12-bit value in the registers, in fan_to_reg()
252 static inline unsigned long pwm_freq_from_reg(u8 reg) in pwm_freq_from_reg() argument
254 unsigned long clock = (reg & 0x80) ? 48000000UL : 1000000UL; in pwm_freq_from_reg()
256 reg &= 0x7f; in pwm_freq_from_reg()
257 if (reg == 0) in pwm_freq_from_reg()
258 reg++; in pwm_freq_from_reg()
259 return clock / (reg << 8); in pwm_freq_from_reg()
274 static inline int pwm_mode_from_reg(u8 reg) in pwm_mode_from_reg() argument
276 return !(reg & FAN_CTRL_DC_MODE); in pwm_mode_from_reg()
279 static inline long temp_from_reg(u8 reg) in temp_from_reg() argument
281 return (reg * 1000); in temp_from_reg()
297 /* Must be called with data->update_lock held, except during initialization */
298 static u8 f71805f_read8(struct f71805f_data *data, u8 reg) in f71805f_read8() argument
300 outb(reg, data->addr + ADDR_REG_OFFSET); in f71805f_read8()
301 return inb(data->addr + DATA_REG_OFFSET); in f71805f_read8()
304 /* Must be called with data->update_lock held, except during initialization */
305 static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) in f71805f_write8() argument
307 outb(reg, data->addr + ADDR_REG_OFFSET); in f71805f_write8()
308 outb(val, data->addr + DATA_REG_OFFSET); in f71805f_write8()
313 Must be called with data->update_lock held, except during initialization */
314 static u16 f71805f_read16(struct f71805f_data *data, u8 reg) in f71805f_read16() argument
318 outb(reg, data->addr + ADDR_REG_OFFSET); in f71805f_read16()
319 val = inb(data->addr + DATA_REG_OFFSET) << 8; in f71805f_read16()
320 outb(++reg, data->addr + ADDR_REG_OFFSET); in f71805f_read16()
321 val |= inb(data->addr + DATA_REG_OFFSET); in f71805f_read16()
326 /* Must be called with data->update_lock held, except during initialization */
327 static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) in f71805f_write16() argument
329 outb(reg, data->addr + ADDR_REG_OFFSET); in f71805f_write16()
330 outb(val >> 8, data->addr + DATA_REG_OFFSET); in f71805f_write16()
331 outb(++reg, data->addr + ADDR_REG_OFFSET); in f71805f_write16()
332 outb(val & 0xff, data->addr + DATA_REG_OFFSET); in f71805f_write16()
340 mutex_lock(&data->update_lock); in f71805f_update_device()
343 if (time_after(jiffies, data->last_updated + 60 * HZ) in f71805f_update_device()
344 || !data->valid) { in f71805f_update_device()
346 if (!(data->has_in & (1 << nr))) in f71805f_update_device()
348 data->in_high[nr] = f71805f_read8(data, in f71805f_update_device()
350 data->in_low[nr] = f71805f_read8(data, in f71805f_update_device()
354 data->fan_low[nr] = f71805f_read16(data, in f71805f_update_device()
356 data->fan_target[nr] = f71805f_read16(data, in f71805f_update_device()
358 data->pwm_freq[nr] = f71805f_read8(data, in f71805f_update_device()
362 data->temp_high[nr] = f71805f_read8(data, in f71805f_update_device()
364 data->temp_hyst[nr] = f71805f_read8(data, in f71805f_update_device()
367 data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); in f71805f_update_device()
370 data->auto_points[nr].temp[apnr] = in f71805f_update_device()
374 data->auto_points[nr].fan[apnr] = in f71805f_update_device()
381 data->last_limits = jiffies; in f71805f_update_device()
385 if (time_after(jiffies, data->last_updated + HZ) in f71805f_update_device()
386 || !data->valid) { in f71805f_update_device()
388 if (!(data->has_in & (1 << nr))) in f71805f_update_device()
390 data->in[nr] = f71805f_read8(data, in f71805f_update_device()
394 data->fan[nr] = f71805f_read16(data, in f71805f_update_device()
396 data->fan_ctrl[nr] = f71805f_read8(data, in f71805f_update_device()
398 data->pwm[nr] = f71805f_read8(data, in f71805f_update_device()
402 data->temp[nr] = f71805f_read8(data, in f71805f_update_device()
405 data->alarms = f71805f_read8(data, F71805F_REG_STATUS(0)) in f71805f_update_device()
409 data->last_updated = jiffies; in f71805f_update_device()
410 data->valid = 1; in f71805f_update_device()
413 mutex_unlock(&data->update_lock); in f71805f_update_device()
427 int nr = attr->index; in show_in0()
429 return sprintf(buf, "%ld\n", in0_from_reg(data->in[nr])); in show_in0()
437 int nr = attr->index; in show_in0_max()
439 return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[nr])); in show_in0_max()
447 int nr = attr->index; in show_in0_min()
449 return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[nr])); in show_in0_min()
457 int nr = attr->index; in set_in0_max()
460 mutex_lock(&data->update_lock); in set_in0_max()
461 data->in_high[nr] = in0_to_reg(val); in set_in0_max()
462 f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); in set_in0_max()
463 mutex_unlock(&data->update_lock); in set_in0_max()
473 int nr = attr->index; in set_in0_min()
476 mutex_lock(&data->update_lock); in set_in0_min()
477 data->in_low[nr] = in0_to_reg(val); in set_in0_min()
478 f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); in set_in0_min()
479 mutex_unlock(&data->update_lock); in set_in0_min()
489 int nr = attr->index; in show_in()
491 return sprintf(buf, "%ld\n", in_from_reg(data->in[nr])); in show_in()
499 int nr = attr->index; in show_in_max()
501 return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr])); in show_in_max()
509 int nr = attr->index; in show_in_min()
511 return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr])); in show_in_min()
519 int nr = attr->index; in set_in_max()
522 mutex_lock(&data->update_lock); in set_in_max()
523 data->in_high[nr] = in_to_reg(val); in set_in_max()
524 f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); in set_in_max()
525 mutex_unlock(&data->update_lock); in set_in_max()
535 int nr = attr->index; in set_in_min()
538 mutex_lock(&data->update_lock); in set_in_min()
539 data->in_low[nr] = in_to_reg(val); in set_in_min()
540 f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); in set_in_min()
541 mutex_unlock(&data->update_lock); in set_in_min()
551 int nr = attr->index; in show_fan()
553 return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr])); in show_fan()
561 int nr = attr->index; in show_fan_min()
563 return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); in show_fan_min()
571 int nr = attr->index; in show_fan_target()
573 return sprintf(buf, "%ld\n", fan_from_reg(data->fan_target[nr])); in show_fan_target()
581 int nr = attr->index; in set_fan_min()
584 mutex_lock(&data->update_lock); in set_fan_min()
585 data->fan_low[nr] = fan_to_reg(val); in set_fan_min()
586 f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); in set_fan_min()
587 mutex_unlock(&data->update_lock); in set_fan_min()
597 int nr = attr->index; in set_fan_target()
600 mutex_lock(&data->update_lock); in set_fan_target()
601 data->fan_target[nr] = fan_to_reg(val); in set_fan_target()
603 data->fan_target[nr]); in set_fan_target()
604 mutex_unlock(&data->update_lock); in set_fan_target()
614 int nr = attr->index; in show_pwm()
616 return sprintf(buf, "%d\n", (int)data->pwm[nr]); in show_pwm()
624 int nr = attr->index; in show_pwm_enable()
627 switch (data->fan_ctrl[nr] & FAN_CTRL_MODE_MASK) { in show_pwm_enable()
646 int nr = attr->index; in show_pwm_freq()
648 return sprintf(buf, "%lu\n", pwm_freq_from_reg(data->pwm_freq[nr])); in show_pwm_freq()
656 int nr = attr->index; in show_pwm_mode()
658 return sprintf(buf, "%d\n", pwm_mode_from_reg(data->fan_ctrl[nr])); in show_pwm_mode()
666 int nr = attr->index; in set_pwm()
670 return -EINVAL; in set_pwm()
672 mutex_lock(&data->update_lock); in set_pwm()
673 data->pwm[nr] = val; in set_pwm()
674 f71805f_write8(data, F71805F_REG_PWM_DUTY(nr), data->pwm[nr]); in set_pwm()
675 mutex_unlock(&data->update_lock); in set_pwm()
687 int nr = attr->index; in set_pwm_enable()
689 u8 reg; in set_pwm_enable() local
692 return -EINVAL; in set_pwm_enable()
695 if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr], in set_pwm_enable()
697 dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1); in set_pwm_enable()
700 mutex_lock(&data->update_lock); in set_pwm_enable()
701 reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr)) in set_pwm_enable()
705 reg |= FAN_CTRL_MODE_MANUAL; in set_pwm_enable()
708 reg |= FAN_CTRL_MODE_TEMPERATURE; in set_pwm_enable()
711 reg |= FAN_CTRL_MODE_SPEED; in set_pwm_enable()
714 data->fan_ctrl[nr] = reg; in set_pwm_enable()
715 f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg); in set_pwm_enable()
716 mutex_unlock(&data->update_lock); in set_pwm_enable()
719 if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr], in set_pwm_enable()
732 int nr = attr->index; in set_pwm_freq()
735 mutex_lock(&data->update_lock); in set_pwm_freq()
736 data->pwm_freq[nr] = pwm_freq_to_reg(val); in set_pwm_freq()
737 f71805f_write8(data, F71805F_REG_PWM_FREQ(nr), data->pwm_freq[nr]); in set_pwm_freq()
738 mutex_unlock(&data->update_lock); in set_pwm_freq()
749 int pwmnr = attr->nr; in show_pwm_auto_point_temp()
750 int apnr = attr->index; in show_pwm_auto_point_temp()
753 temp_from_reg(data->auto_points[pwmnr].temp[apnr])); in show_pwm_auto_point_temp()
762 int pwmnr = attr->nr; in set_pwm_auto_point_temp()
763 int apnr = attr->index; in set_pwm_auto_point_temp()
766 mutex_lock(&data->update_lock); in set_pwm_auto_point_temp()
767 data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val); in set_pwm_auto_point_temp()
769 data->auto_points[pwmnr].temp[apnr]); in set_pwm_auto_point_temp()
770 mutex_unlock(&data->update_lock); in set_pwm_auto_point_temp()
781 int pwmnr = attr->nr; in show_pwm_auto_point_fan()
782 int apnr = attr->index; in show_pwm_auto_point_fan()
785 fan_from_reg(data->auto_points[pwmnr].fan[apnr])); in show_pwm_auto_point_fan()
794 int pwmnr = attr->nr; in set_pwm_auto_point_fan()
795 int apnr = attr->index; in set_pwm_auto_point_fan()
798 mutex_lock(&data->update_lock); in set_pwm_auto_point_fan()
799 data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val); in set_pwm_auto_point_fan()
801 data->auto_points[pwmnr].fan[apnr]); in set_pwm_auto_point_fan()
802 mutex_unlock(&data->update_lock); in set_pwm_auto_point_fan()
812 int nr = attr->index; in show_temp()
814 return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr])); in show_temp()
822 int nr = attr->index; in show_temp_max()
824 return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr])); in show_temp_max()
832 int nr = attr->index; in show_temp_hyst()
834 return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr])); in show_temp_hyst()
842 int nr = attr->index; in show_temp_type()
845 return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4); in show_temp_type()
853 int nr = attr->index; in set_temp_max()
856 mutex_lock(&data->update_lock); in set_temp_max()
857 data->temp_high[nr] = temp_to_reg(val); in set_temp_max()
858 f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]); in set_temp_max()
859 mutex_unlock(&data->update_lock); in set_temp_max()
869 int nr = attr->index; in set_temp_hyst()
872 mutex_lock(&data->update_lock); in set_temp_hyst()
873 data->temp_hyst[nr] = temp_to_reg(val); in set_temp_hyst()
874 f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]); in set_temp_hyst()
875 mutex_unlock(&data->update_lock); in set_temp_hyst()
885 return sprintf(buf, "%lu\n", data->alarms & 0x7ff); in show_alarms_in()
893 return sprintf(buf, "%lu\n", (data->alarms >> 16) & 0x07); in show_alarms_fan()
901 return sprintf(buf, "%lu\n", (data->alarms >> 11) & 0x07); in show_alarms_temp()
909 int bitnr = attr->index; in show_alarm()
911 return sprintf(buf, "%lu\n", (data->alarms >> bitnr) & 1); in show_alarm()
919 return sprintf(buf, "%s\n", data->name); in show_name()
1013 /* pwm (value) files are created read-only, write permission is
1275 u8 reg; in f71805f_init_device() local
1278 reg = f71805f_read8(data, F71805F_REG_START); in f71805f_init_device()
1279 if ((reg & 0x41) != 0x01) { in f71805f_init_device()
1282 f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); in f71805f_init_device()
1288 data->fan_ctrl[i] = f71805f_read8(data, in f71805f_init_device()
1292 if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) { in f71805f_init_device()
1293 data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL; in f71805f_init_device()
1295 data->fan_ctrl[i]); in f71805f_init_device()
1302 struct f71805f_sio_data *sio_data = pdev->dev.platform_data; in f71805f_probe()
1307 static const char *names[] = { in f71805f_probe() local
1313 err = -ENOMEM; in f71805f_probe()
1319 if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) { in f71805f_probe()
1320 err = -EBUSY; in f71805f_probe()
1321 dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", in f71805f_probe()
1322 (unsigned long)(res->start + ADDR_REG_OFFSET), in f71805f_probe()
1323 (unsigned long)(res->start + ADDR_REG_OFFSET + 1)); in f71805f_probe()
1326 data->addr = res->start; in f71805f_probe()
1327 data->name = names[sio_data->kind]; in f71805f_probe()
1328 mutex_init(&data->update_lock); in f71805f_probe()
1333 switch (sio_data->kind) { in f71805f_probe()
1335 data->has_in = 0x1ff; in f71805f_probe()
1338 data->has_in = 0x6ef; in f71805f_probe()
1339 if (sio_data->fnsel1 & 0x01) in f71805f_probe()
1340 data->has_in |= (1 << 4); /* in4 */ in f71805f_probe()
1341 if (sio_data->fnsel1 & 0x02) in f71805f_probe()
1342 data->has_in |= (1 << 8); /* in8 */ in f71805f_probe()
1350 if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) in f71805f_probe()
1352 if (data->has_in & (1 << 4)) { /* in4 */ in f71805f_probe()
1353 if ((err = sysfs_create_group(&pdev->dev.kobj, in f71805f_probe()
1357 if (data->has_in & (1 << 8)) { /* in8 */ in f71805f_probe()
1358 if ((err = sysfs_create_group(&pdev->dev.kobj, in f71805f_probe()
1362 if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */ in f71805f_probe()
1363 if ((err = sysfs_create_group(&pdev->dev.kobj, in f71805f_probe()
1367 if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */ in f71805f_probe()
1368 if ((err = sysfs_create_group(&pdev->dev.kobj, in f71805f_probe()
1374 if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) { in f71805f_probe()
1375 if ((err = sysfs_create_file(&pdev->dev.kobj, in f71805f_probe()
1380 if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) { in f71805f_probe()
1381 if ((err = sysfs_chmod_file(&pdev->dev.kobj, in f71805f_probe()
1384 dev_err(&pdev->dev, "chmod +w pwm%d failed\n", in f71805f_probe()
1391 data->hwmon_dev = hwmon_device_register(&pdev->dev); in f71805f_probe()
1392 if (IS_ERR(data->hwmon_dev)) { in f71805f_probe()
1393 err = PTR_ERR(data->hwmon_dev); in f71805f_probe()
1394 dev_err(&pdev->dev, "Class registration failed (%d)\n", err); in f71805f_probe()
1401 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); in f71805f_probe()
1403 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); in f71805f_probe()
1404 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); in f71805f_probe()
1406 release_region(res->start + ADDR_REG_OFFSET, 2); in f71805f_probe()
1420 hwmon_device_unregister(data->hwmon_dev); in f71805f_remove()
1421 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); in f71805f_remove()
1423 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); in f71805f_remove()
1424 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); in f71805f_remove()
1429 release_region(res->start + ADDR_REG_OFFSET, 2); in f71805f_remove()
1448 .end = address + REGION_LENGTH - 1, in f71805f_device_add()
1455 err = -ENOMEM; in f71805f_device_add()
1460 res.name = pdev->name; in f71805f_device_add()
1495 int err = -ENODEV; in f71805f_find()
1498 static const char *names[] = { in f71805f_find() local
1512 sio_data->kind = f71805f; in f71805f_find()
1515 sio_data->kind = f71872f; in f71805f_find()
1516 sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1); in f71805f_find()
1534 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ in f71805f_find()
1538 names[sio_data->kind], *address, in f71805f_find()
1554 return -ENODEV; in f71805f_init()
1579 MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");