in gpio-it87.c [272:395]
static int __init it87_gpio_init(void)
{
int rc = 0, i;
u16 chip_type;
u8 chip_rev, gpio_ba_reg;
char *labels, **labels_table;
struct it87_gpio *it87_gpio = &it87_gpio_chip;
rc = superio_enter();
if (rc)
return rc;
chip_type = superio_inw(CHIPID);
chip_rev = superio_inb(CHIPREV) & 0x0f;
superio_exit();
it87_gpio->chip = it87_template_chip;
switch (chip_type) {
case IT8613_ID:
gpio_ba_reg = 0x62;
it87_gpio->io_size = 8; /* it8613 only needs 6, use 8 for alignment */
it87_gpio->output_base = 0xc8;
it87_gpio->simple_base = 0xc0;
it87_gpio->simple_size = 6;
it87_gpio->chip.ngpio = 64; /* has 48, use 64 for convenient calc */
break;
case IT8620_ID:
case IT8628_ID:
gpio_ba_reg = 0x62;
it87_gpio->io_size = 11;
it87_gpio->output_base = 0xc8;
it87_gpio->simple_size = 0;
it87_gpio->chip.ngpio = 64;
break;
case IT8718_ID:
case IT8728_ID:
case IT8732_ID:
case IT8772_ID:
case IT8786_ID:
gpio_ba_reg = 0x62;
it87_gpio->io_size = 8;
it87_gpio->output_base = 0xc8;
it87_gpio->simple_base = 0xc0;
it87_gpio->simple_size = 5;
it87_gpio->chip.ngpio = 64;
break;
case IT8761_ID:
gpio_ba_reg = 0x60;
it87_gpio->io_size = 4;
it87_gpio->output_base = 0xf0;
it87_gpio->simple_size = 0;
it87_gpio->chip.ngpio = 16;
break;
case NO_DEV_ID:
pr_err("no device\n");
return -ENODEV;
default:
pr_err("Unknown Chip found, Chip %04x Revision %x\n",
chip_type, chip_rev);
return -ENODEV;
}
rc = superio_enter();
if (rc)
return rc;
superio_select(GPIO);
/* fetch GPIO base address */
it87_gpio->io_base = superio_inw(gpio_ba_reg);
superio_exit();
pr_info("Found Chip IT%04x rev %x. %u GPIO lines starting at %04xh\n",
chip_type, chip_rev, it87_gpio->chip.ngpio,
it87_gpio->io_base);
if (!request_region(it87_gpio->io_base, it87_gpio->io_size,
KBUILD_MODNAME))
return -EBUSY;
/* Set up aliases for the GPIO connection.
*
* ITE documentation for recent chips such as the IT8728F
* refers to the GPIO lines as GPxy, with a coordinates system
* where x is the GPIO group (starting from 1) and y is the
* bit within the group.
*
* By creating these aliases, we make it easier to understand
* to which GPIO pin we're referring to.
*/
labels = kcalloc(it87_gpio->chip.ngpio, sizeof("it87_gpXY"),
GFP_KERNEL);
labels_table = kcalloc(it87_gpio->chip.ngpio, sizeof(const char *),
GFP_KERNEL);
if (!labels || !labels_table) {
rc = -ENOMEM;
goto labels_free;
}
for (i = 0; i < it87_gpio->chip.ngpio; i++) {
char *label = &labels[i * sizeof("it87_gpXY")];
sprintf(label, "it87_gp%u%u", 1+(i/8), i%8);
labels_table[i] = label;
}
it87_gpio->chip.names = (const char *const*)labels_table;
rc = gpiochip_add_data(&it87_gpio->chip, it87_gpio);
if (rc)
goto labels_free;
return 0;
labels_free:
kfree(labels_table);
kfree(labels);
release_region(it87_gpio->io_base, it87_gpio->io_size);
return rc;
}