static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; superio_enter(); id = superio_inb(SUPERIO_REG_DEVID); if ((id != 0x6f) && (id != 0x81)) { superio_exit(); return -ENODEV; } rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); printk(KERN_INFO "smsc47b397: found SMSC %s " "(base address 0x%04x, revision %u)\n", id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); superio_exit(); return 0; }
static ssize_t intrusion0_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nct6683_data *data = dev_get_drvdata(dev); int ret; u8 reg; mutex_lock(&data->update_lock); ret = superio_enter(data->sioreg); if (ret) goto error; superio_select(data->sioreg, NCT6683_LD_ACPI); reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN); superio_exit(data->sioreg); mutex_unlock(&data->update_lock); return sprintf(buf, "%u\n", !(reg & NCT6683_CR_CASEOPEN_MASK)); error: mutex_unlock(&data->update_lock); return ret; }
static int f7188x_gpio_direction_out(struct gpio_chip *chip, unsigned offset, int value) { int err; struct f7188x_gpio_bank *bank = container_of(chip, struct f7188x_gpio_bank, chip); struct f7188x_sio *sio = bank->data->sio; u8 dir, data_out; err = superio_enter(sio->addr); if (err) return err; superio_select(sio->addr, SIO_LD_GPIO); data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase)); if (value) data_out |= (1 << offset); else data_out &= ~(1 << offset); superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out); dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); dir |= (1 << offset); superio_outb(sio->addr, gpio_dir(bank->regbase), dir); superio_exit(sio->addr); return 0; }
static ssize_t beep_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct nct6683_data *data = dev_get_drvdata(dev); unsigned long val; u8 reg; int ret; if (kstrtoul(buf, 10, &val) || (val != 0 && val != 1)) return -EINVAL; mutex_lock(&data->update_lock); ret = superio_enter(data->sioreg); if (ret) { count = ret; goto error; } superio_select(data->sioreg, NCT6683_LD_HWM); reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP); if (val) reg |= NCT6683_CR_BEEP_MASK; else reg &= ~NCT6683_CR_BEEP_MASK; superio_outb(data->sioreg, NCT6683_REG_CR_BEEP, reg); superio_exit(data->sioreg); error: mutex_unlock(&data->update_lock); return count; }
static int __init smsc47m1_find(unsigned short *addr, struct smsc47m1_sio_data *sio_data) { u8 val; superio_enter(); val = superio_inb(SUPERIO_REG_DEVID); /* * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x * (device id 0x5F) and LPC47B27x (device id 0x51) have fan control. * The LPC47M15x and LPC47M192 chips "with hardware monitoring block" * can do much more besides (device id 0x60). * The LPC47M997 is undocumented, but seems to be compatible with * the LPC47M192, and has the same device id. * The LPC47M292 (device id 0x6B) is somewhat compatible, but it * supports a 3rd fan, and the pin configuration registers are * unfortunately different. */ switch (val) { case 0x51: pr_info(DRVNAME ": Found SMSC LPC47B27x\n"); sio_data->type = smsc47m1; break; case 0x59: pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n"); sio_data->type = smsc47m1; break; case 0x5F: pr_info(DRVNAME ": Found SMSC LPC47M14x\n"); sio_data->type = smsc47m1; break; case 0x60: pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n"); sio_data->type = smsc47m1; break; case 0x6B: pr_info(DRVNAME ": Found SMSC LPC47M292\n"); sio_data->type = smsc47m2; break; default: superio_exit(); return -ENODEV; } superio_select(); *addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); val = superio_inb(SUPERIO_REG_ACT); if (*addr == 0 || (val & 0x01) == 0) { pr_info(DRVNAME ": Device is disabled, will not use\n"); superio_exit(); return -ENODEV; } superio_exit(); return 0; }
/* * The Nuvoton NCT6102D starts per default after reset with both, * the internal watchdog and the internal legacy UART enabled. This * code provides a function to disable the watchdog. */ int nct6102d_wdt_disable(void) { superio_enter(); /* Select logical device for WDT */ superio_select(NCT6102D_LD_WDT); superio_outb(NCT6102D_WDT_TIMEOUT, 0x00); superio_exit(); return 0; }
static int __init f7188x_find(int addr, struct f7188x_sio *sio) { int err; u16 devid; err = superio_enter(addr); if (err) return err; err = -ENODEV; devid = superio_inw(addr, SIO_MANID); if (devid != SIO_FINTEK_ID) { pr_debug(DRVNAME ": Not a Fintek device at 0x%08x\n", addr); goto err; } devid = superio_inw(addr, SIO_DEVID); switch (devid) { case SIO_F71808E_ID: sio->type = f71808e; break; case SIO_F71869_ID: sio->type = f71869; break; case SIO_F71869A_ID: sio->type = f71869a; break; case SIO_F71882_ID: sio->type = f71882fg; break; case SIO_F71889_ID: sio->type = f71889f; break; case SIO_F81866_ID: sio->type = f81866; break; default: pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid); goto err; } sio->addr = addr; err = 0; pr_info(DRVNAME ": Found %s at %#x, revision %d\n", f7188x_names[sio->type], (unsigned int) addr, (int) superio_inb(addr, SIO_DEVREV)); err: superio_exit(addr); return err; }
static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data) { int addr; u16 val; int err; err = superio_enter(sioaddr); if (err) return err; val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | superio_inb(sioaddr, SIO_REG_DEVID + 1); switch (val & SIO_ID_MASK) { case SIO_NCT6683_ID: sio_data->kind = nct6683; break; default: if (val != 0xffff) pr_debug("unsupported chip ID: 0x%04x\n", val); goto fail; } /* We have a known chip, find the HWM I/O address */ superio_select(sioaddr, NCT6683_LD_HWM); val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) | superio_inb(sioaddr, SIO_REG_ADDR + 1); addr = val & IOREGION_ALIGNMENT; if (addr == 0) { pr_err("EC base I/O port unconfigured\n"); goto fail; } /* Activate logical device if needed */ val = superio_inb(sioaddr, SIO_REG_ENABLE); if (!(val & 0x01)) { pr_warn("Forcibly enabling EC access. Data may be unusable.\n"); superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); } superio_exit(sioaddr); pr_info("Found %s or compatible chip at %#x:%#x\n", nct6683_chip_names[sio_data->kind], sioaddr, addr); sio_data->sioreg = sioaddr; return addr; fail: superio_exit(sioaddr); return -ENODEV; }
static int wdt_set_time(unsigned int timeout) { int ret; ret = superio_enter(); if (ret) return ret; superio_select(W83627HF_LD_WDT); superio_outb(cr_wdt_timeout, timeout); superio_exit(); return 0; }
static unsigned int wdt_get_time(struct watchdog_device *wdog) { unsigned int timeleft; int ret; ret = superio_enter(); if (ret) return 0; superio_select(W83627HF_LD_WDT); timeleft = superio_inb(cr_wdt_timeout); superio_exit(); return timeleft; }
static void wdt_stop(void) { unsigned long flags; spin_lock_irqsave(&spinlock, flags); superio_enter(); superio_select(GPIO); superio_outb(0x00, WDTCTRL); superio_outb(WDT_TOV1, WDTCFG); superio_outb(0x00, WDTVALMSB); superio_outb(0x00, WDTVALLSB); superio_exit(); spin_unlock_irqrestore(&spinlock, flags); }
static int __init qnap_gpio_button_init(void) { u16 chip_type; u8 chip_rev; unsigned long flags; int err = -ENODEV; int tmp; spin_lock_irqsave(&spinlock, flags); superio_enter(); chip_type = superio_inw(SIO_CHIP_ID); chip_rev = superio_inb(SIO_CHIP_REV) & 0x0f; if (chip_type != SIO_IT8718_ID) goto exit; superio_select(SIO_GPIO_LDN); gpio_base_address = superio_inw(GPIO_ADDR_MSB_REG); // GP16 GP17 tmp = superio_inb(GPIO_SET1_SEL_REG); superio_outb(GPIO_SET1_SEL_REG, tmp | 0xc0); //select GPIO Set1 function tmp = superio_inb(GPIO_SET1_ENABLE_REG); superio_outb(GPIO_SET1_ENABLE_REG, tmp | 0xc0); //enable simple IO function tmp = superio_inb(GPIO_SET1_OUTPUT_EN_REG); superio_outb(GPIO_SET1_OUTPUT_EN_REG, tmp & 0x3f); //enable input direction superio_outb(GPIO_DBOUNCE_SEL_REG, 0x03); // set De-Bounce tmp = superio_inb(GPIO_SMI_STATUS_REG); superio_outb(GPIO_SMI_STATUS_REG, tmp | 0xc0); /* reset panel button de-bounce status */ superio_outb(GPIO_BTN0_MAPPING_REG, 0x4e); /* GP16 = 001110 */ superio_outb(GPIO_BTN1_MAPPING_REG, 0x4f); /* GP17 = 001111 */ err = 0; exit: superio_exit(); spin_unlock_irqrestore(&spinlock, flags); return err; }
static int wdt_set_timeout(int t) { unsigned long flags; if (t < 1 || t > 65535) return -EINVAL; timeout = t; spin_lock_irqsave(&spinlock, flags); if (test_bit(WDTS_TIMER_RUN, &wdt_status)) { superio_enter(); superio_select(GPIO); superio_outb(t>>8, WDTVALMSB); superio_outb(t, WDTVALLSB); superio_exit(); }
static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { int err; struct f7188x_gpio_bank *bank = gpiochip_get_data(chip); struct f7188x_sio *sio = bank->data->sio; u8 dir; err = superio_enter(sio->addr); if (err) return err; superio_select(sio->addr, SIO_LD_GPIO); dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); dir &= ~(1 << offset); superio_outb(sio->addr, gpio_dir(bank->regbase), dir); superio_exit(sio->addr); return 0; }
static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { int err; struct f7188x_gpio_bank *bank = gpiochip_get_data(chip); struct f7188x_sio *sio = bank->data->sio; u8 data_out; err = superio_enter(sio->addr); if (err) return; superio_select(sio->addr, SIO_LD_GPIO); data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase)); if (value) data_out |= (1 << offset); else data_out &= ~(1 << offset); superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out); superio_exit(sio->addr); }
static int __init f71805f_find(int sioaddr, unsigned short *address) { int err = -ENODEV; u16 devid; superio_enter(sioaddr); devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) goto exit; devid = superio_inw(sioaddr, SIO_REG_DEVID); if (devid != SIO_F71805F_ID) { printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " "skipping\n"); goto exit; } superio_select(sioaddr, F71805F_LD_HWM); if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { printk(KERN_WARNING DRVNAME ": Device not activated, " "skipping\n"); goto exit; } *address = superio_inw(sioaddr, SIO_REG_ADDR); if (*address == 0) { printk(KERN_WARNING DRVNAME ": Base address not set, " "skipping\n"); goto exit; } err = 0; printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", *address, superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); return err; }
static void wdt_start(void) { unsigned long flags; spin_lock_irqsave(&spinlock, flags); superio_enter(); superio_select(GPIO); if (test_bit(WDTS_USE_GP, &wdt_status)) superio_outb(WDT_GAMEPORT, WDTCTRL); else superio_outb(WDT_CIRINT, WDTCTRL); if (!testmode) superio_outb(WDT_TOV1 | WDT_KRST | WDT_PWROK, WDTCFG); else superio_outb(WDT_TOV1, WDTCFG); superio_outb(timeout>>8, WDTVALMSB); superio_outb(timeout, WDTVALLSB); superio_exit(); spin_unlock_irqrestore(&spinlock, flags); }
static void qnap_timer(unsigned long data) { int tmp; unsigned long flags; struct input_dev *qnap_input = (struct input_dev *) data; spin_lock_irqsave(&spinlock, flags); superio_enter(); superio_select(SIO_GPIO_LDN); tmp = inb(gpio_base_address); input_report_key(qnap_input, KEY_ARCHIVE, (tmp & 0x40) >> 6 ); /* USB Copy Button */ input_report_key(qnap_input, KEY_RESTART, (tmp & 0x80) >> 7 ); /* RESET Button */ input_sync(qnap_input); superio_outb(GPIO_SMI_STATUS_REG, tmp | 0xc0); superio_exit(); spin_unlock_irqrestore(&spinlock, flags); }
static ssize_t intrusion0_alarm_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct nct6683_data *data = dev_get_drvdata(dev); unsigned long val; u8 reg; int ret; if (kstrtoul(buf, 10, &val) || val != 0) return -EINVAL; mutex_lock(&data->update_lock); /* * Use CR registers to clear caseopen status. * Caseopen is activ low, clear by writing 1 into the register. */ ret = superio_enter(data->sioreg); if (ret) { count = ret; goto error; } superio_select(data->sioreg, NCT6683_LD_ACPI); reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN); reg |= NCT6683_CR_CASEOPEN_MASK; superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg); reg &= ~NCT6683_CR_CASEOPEN_MASK; superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg); superio_exit(data->sioreg); data->valid = false; /* Force cache refresh */ error: mutex_unlock(&data->update_lock); return count; }
static int f7188x_gpio_get(struct gpio_chip *chip, unsigned offset) { int err; struct f7188x_gpio_bank *bank = gpiochip_get_data(chip); struct f7188x_sio *sio = bank->data->sio; u8 dir, data; err = superio_enter(sio->addr); if (err) return err; superio_select(sio->addr, SIO_LD_GPIO); dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); dir = !!(dir & (1 << offset)); if (dir) data = superio_inb(sio->addr, gpio_data_out(bank->regbase)); else data = superio_inb(sio->addr, gpio_data_in(bank->regbase)); superio_exit(sio->addr); return !!(data & 1 << offset); }
static int __init smsc47b397_device_add(unsigned short address) { struct resource res = { .start = address, .end = address + SMSC_EXTENT - 1, .name = DRVNAME, .flags = IORESOURCE_IO, }; int err; pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } err = platform_device_add_resources(pdev, &res, 1); if (err) { printk(KERN_ERR DRVNAME ": Device resource addition failed " "(%d)\n", err); goto exit_device_put; } err = platform_device_add(pdev); if (err) { printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", err); goto exit_device_put; } return 0; exit_device_put: platform_device_put(pdev); exit: return err; } static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; char *name; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); switch(id) { case 0x81: name = "SCH5307-NS"; break; case 0x6f: name = "LPC47B397-NC"; break; case 0x85: case 0x8c: name = "SCH5317"; break; default: superio_exit(); return -ENODEV; } rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); printk(KERN_INFO DRVNAME ": found SMSC %s " "(base address 0x%04x, revision %u)\n", name, *addr, rev); superio_exit(); return 0; }
static int wdt_find(int addr) { u8 val; int ret; cr_wdt_timeout = W83627HF_WDT_TIMEOUT; cr_wdt_control = W83627HF_WDT_CONTROL; cr_wdt_csr = W836X7HF_WDT_CSR; ret = superio_enter(); if (ret) return ret; superio_select(W83627HF_LD_WDT); val = superio_inb(0x20); switch (val) { case W83627HF_ID: ret = w83627hf; break; case W83627S_ID: ret = w83627s; break; case W83697HF_ID: ret = w83697hf; cr_wdt_timeout = W83697HF_WDT_TIMEOUT; cr_wdt_control = W83697HF_WDT_CONTROL; break; case W83697UG_ID: ret = w83697ug; cr_wdt_timeout = W83697HF_WDT_TIMEOUT; cr_wdt_control = W83697HF_WDT_CONTROL; break; case W83637HF_ID: ret = w83637hf; break; case W83627THF_ID: ret = w83627thf; break; case W83687THF_ID: ret = w83687thf; break; case W83627EHF_ID: ret = w83627ehf; break; case W83627DHG_ID: ret = w83627dhg; break; case W83627DHG_P_ID: ret = w83627dhg_p; break; case W83627UHG_ID: ret = w83627uhg; break; case W83667HG_ID: ret = w83667hg; break; case W83667HG_B_ID: ret = w83667hg_b; break; case NCT6775_ID: ret = nct6775; break; case NCT6776_ID: ret = nct6776; break; case NCT6779_ID: ret = nct6779; break; case NCT6791_ID: ret = nct6791; break; case NCT6792_ID: ret = nct6792; break; case NCT6793_ID: ret = nct6793; break; case NCT6795_ID: ret = nct6795; break; case NCT6102_ID: ret = nct6102; cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; cr_wdt_control = NCT6102D_WDT_CONTROL; cr_wdt_csr = NCT6102D_WDT_CSR; break; case 0xff: ret = -ENODEV; break; default: ret = -ENODEV; pr_err("Unsupported chip ID: 0x%02x\n", val); break; } superio_exit(); return ret; }
static int __init f71805f_device_add(unsigned short address) { struct resource res = { .start = address, .end = address + REGION_LENGTH - 1, .flags = IORESOURCE_IO, }; int err; pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } res.name = pdev->name; err = platform_device_add_resources(pdev, &res, 1); if (err) { printk(KERN_ERR DRVNAME ": Device resource addition failed " "(%d)\n", err); goto exit_device_put; } err = platform_device_add(pdev); if (err) { printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", err); goto exit_device_put; } return 0; exit_device_put: platform_device_put(pdev); exit: return err; } static int __init f71805f_find(int sioaddr, unsigned short *address) { int err = -ENODEV; u16 devid; superio_enter(sioaddr); devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) goto exit; devid = superio_inw(sioaddr, SIO_REG_DEVID); if (devid != SIO_F71805F_ID) { printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " "skipping\n"); goto exit; } superio_select(sioaddr, F71805F_LD_HWM); if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { printk(KERN_WARNING DRVNAME ": Device not activated, " "skipping\n"); goto exit; } *address = superio_inw(sioaddr, SIO_REG_ADDR); if (*address == 0) { printk(KERN_WARNING DRVNAME ": Base address not set, " "skipping\n"); goto exit; } err = 0; printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", *address, superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); return err; }
static int __init f71805f_device_add(unsigned short address, const struct f71805f_sio_data *sio_data) { struct resource res = { .start = address, .end = address + REGION_LENGTH - 1, .flags = IORESOURCE_IO, }; int err; pdev = platform_device_alloc(DRVNAME, address); if (!pdev) { err = -ENOMEM; printk(KERN_ERR DRVNAME ": Device allocation failed\n"); goto exit; } res.name = pdev->name; err = acpi_check_resource_conflict(&res); if (err) goto exit_device_put; err = platform_device_add_resources(pdev, &res, 1); if (err) { printk(KERN_ERR DRVNAME ": Device resource addition failed " "(%d)\n", err); goto exit_device_put; } err = platform_device_add_data(pdev, sio_data, sizeof(struct f71805f_sio_data)); if (err) { printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); goto exit_device_put; } err = platform_device_add(pdev); if (err) { printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", err); goto exit_device_put; } return 0; exit_device_put: platform_device_put(pdev); exit: return err; } static int __init f71805f_find(int sioaddr, unsigned short *address, struct f71805f_sio_data *sio_data) { int err = -ENODEV; u16 devid; static const char *names[] = { "F71805F/FG", "F71872F/FG or F71806F/FG", }; superio_enter(sioaddr); devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) goto exit; devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); switch (devid) { case SIO_F71805F_ID: sio_data->kind = f71805f; break; case SIO_F71872F_ID: sio_data->kind = f71872f; sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1); break; default: printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " "skipping\n"); goto exit; } superio_select(sioaddr, F71805F_LD_HWM); if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { printk(KERN_WARNING DRVNAME ": Device not activated, " "skipping\n"); goto exit; } *address = superio_inw(sioaddr, SIO_REG_ADDR); if (*address == 0) { printk(KERN_WARNING DRVNAME ": Base address not set, " "skipping\n"); goto exit; } *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ err = 0; printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n", names[sio_data->kind], *address, superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); return err; }
static int w83627hf_init(struct watchdog_device *wdog, enum chips chip) { int ret; unsigned char t; ret = superio_enter(); if (ret) return ret; superio_select(W83627HF_LD_WDT); /* set CR30 bit 0 to activate GPIO2 */ t = superio_inb(0x30); if (!(t & 0x01)) superio_outb(0x30, t | 0x01); switch (chip) { case w83627hf: case w83627s: t = superio_inb(0x2B) & ~0x10; superio_outb(0x2B, t); /* set GPIO24 to WDT0 */ break; case w83697hf: /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ t = superio_inb(0x29) & ~0x60; t |= 0x20; superio_outb(0x29, t); break; case w83697ug: /* Set pin 118 to WDTO# mode */ t = superio_inb(0x2b) & ~0x04; superio_outb(0x2b, t); break; case w83627thf: t = (superio_inb(0x2B) & ~0x08) | 0x04; superio_outb(0x2B, t); /* set GPIO3 to WDT0 */ break; case w83627dhg: case w83627dhg_p: t = superio_inb(0x2D) & ~0x01; /* PIN77 -> WDT0# */ superio_outb(0x2D, t); /* set GPIO5 to WDT0 */ t = superio_inb(cr_wdt_control); t |= 0x02; /* enable the WDTO# output low pulse * to the KBRST# pin */ superio_outb(cr_wdt_control, t); break; case w83637hf: break; case w83687thf: t = superio_inb(0x2C) & ~0x80; /* PIN47 -> WDT0# */ superio_outb(0x2C, t); break; case w83627ehf: case w83627uhg: case w83667hg: case w83667hg_b: case nct6775: case nct6776: case nct6779: /* * These chips have a fixed WDTO# output pin (W83627UHG), * or support more than one WDTO# output pin. * Don't touch its configuration, and hope the BIOS * does the right thing. */ t = superio_inb(cr_wdt_control); t |= 0x02; /* enable the WDTO# output low pulse * to the KBRST# pin */ superio_outb(cr_wdt_control, t); break; default: break; } t = superio_inb(cr_wdt_timeout); if (t != 0) { pr_info("Watchdog already running. Resetting timeout to %d sec\n", wdog->timeout); superio_outb(cr_wdt_timeout, wdog->timeout); } /* set second mode & disable keyboard turning off watchdog */ t = superio_inb(cr_wdt_control) & ~0x0C; superio_outb(cr_wdt_control, t); /* reset trigger, disable keyboard & mouse turning off watchdog */ t = superio_inb(0xF7) & ~0xD0; superio_outb(0xF7, t); superio_exit(); return 0; }