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 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 __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 __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; }