Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * GPIO driver for Fintek Super-I/O F71869, F71869A, F71882, F71889 and F81866
0004  *
0005  * Copyright (C) 2010-2013 LaCie
0006  *
0007  * Author: Simon Guinot <simon.guinot@sequanux.org>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/io.h>
0014 #include <linux/gpio/driver.h>
0015 #include <linux/bitops.h>
0016 
0017 #define DRVNAME "gpio-f7188x"
0018 
0019 /*
0020  * Super-I/O registers
0021  */
0022 #define SIO_LDSEL       0x07    /* Logical device select */
0023 #define SIO_DEVID       0x20    /* Device ID (2 bytes) */
0024 #define SIO_DEVREV      0x22    /* Device revision */
0025 #define SIO_MANID       0x23    /* Fintek ID (2 bytes) */
0026 
0027 #define SIO_LD_GPIO     0x06    /* GPIO logical device */
0028 #define SIO_UNLOCK_KEY      0x87    /* Key to enable Super-I/O */
0029 #define SIO_LOCK_KEY        0xAA    /* Key to disable Super-I/O */
0030 
0031 #define SIO_FINTEK_ID       0x1934  /* Manufacturer ID */
0032 #define SIO_F71869_ID       0x0814  /* F71869 chipset ID */
0033 #define SIO_F71869A_ID      0x1007  /* F71869A chipset ID */
0034 #define SIO_F71882_ID       0x0541  /* F71882 chipset ID */
0035 #define SIO_F71889_ID       0x0909  /* F71889 chipset ID */
0036 #define SIO_F71889A_ID      0x1005  /* F71889A chipset ID */
0037 #define SIO_F81866_ID       0x1010  /* F81866 chipset ID */
0038 #define SIO_F81804_ID       0x1502  /* F81804 chipset ID, same for f81966 */
0039 #define SIO_F81865_ID       0x0704  /* F81865 chipset ID */
0040 
0041 
0042 enum chips {
0043     f71869,
0044     f71869a,
0045     f71882fg,
0046     f71889a,
0047     f71889f,
0048     f81866,
0049     f81804,
0050     f81865,
0051 };
0052 
0053 static const char * const f7188x_names[] = {
0054     "f71869",
0055     "f71869a",
0056     "f71882fg",
0057     "f71889a",
0058     "f71889f",
0059     "f81866",
0060     "f81804",
0061     "f81865",
0062 };
0063 
0064 struct f7188x_sio {
0065     int addr;
0066     enum chips type;
0067 };
0068 
0069 struct f7188x_gpio_bank {
0070     struct gpio_chip chip;
0071     unsigned int regbase;
0072     struct f7188x_gpio_data *data;
0073 };
0074 
0075 struct f7188x_gpio_data {
0076     struct f7188x_sio *sio;
0077     int nr_bank;
0078     struct f7188x_gpio_bank *bank;
0079 };
0080 
0081 /*
0082  * Super-I/O functions.
0083  */
0084 
0085 static inline int superio_inb(int base, int reg)
0086 {
0087     outb(reg, base);
0088     return inb(base + 1);
0089 }
0090 
0091 static int superio_inw(int base, int reg)
0092 {
0093     int val;
0094 
0095     outb(reg++, base);
0096     val = inb(base + 1) << 8;
0097     outb(reg, base);
0098     val |= inb(base + 1);
0099 
0100     return val;
0101 }
0102 
0103 static inline void superio_outb(int base, int reg, int val)
0104 {
0105     outb(reg, base);
0106     outb(val, base + 1);
0107 }
0108 
0109 static inline int superio_enter(int base)
0110 {
0111     /* Don't step on other drivers' I/O space by accident. */
0112     if (!request_muxed_region(base, 2, DRVNAME)) {
0113         pr_err(DRVNAME "I/O address 0x%04x already in use\n", base);
0114         return -EBUSY;
0115     }
0116 
0117     /* According to the datasheet the key must be send twice. */
0118     outb(SIO_UNLOCK_KEY, base);
0119     outb(SIO_UNLOCK_KEY, base);
0120 
0121     return 0;
0122 }
0123 
0124 static inline void superio_select(int base, int ld)
0125 {
0126     outb(SIO_LDSEL, base);
0127     outb(ld, base + 1);
0128 }
0129 
0130 static inline void superio_exit(int base)
0131 {
0132     outb(SIO_LOCK_KEY, base);
0133     release_region(base, 2);
0134 }
0135 
0136 /*
0137  * GPIO chip.
0138  */
0139 
0140 static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset);
0141 static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset);
0142 static int f7188x_gpio_get(struct gpio_chip *chip, unsigned offset);
0143 static int f7188x_gpio_direction_out(struct gpio_chip *chip,
0144                      unsigned offset, int value);
0145 static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value);
0146 static int f7188x_gpio_set_config(struct gpio_chip *chip, unsigned offset,
0147                   unsigned long config);
0148 
0149 #define F7188X_GPIO_BANK(_base, _ngpio, _regbase)           \
0150     {                               \
0151         .chip = {                       \
0152             .label            = DRVNAME,            \
0153             .owner            = THIS_MODULE,        \
0154             .get_direction    = f7188x_gpio_get_direction,  \
0155             .direction_input  = f7188x_gpio_direction_in,   \
0156             .get              = f7188x_gpio_get,        \
0157             .direction_output = f7188x_gpio_direction_out,  \
0158             .set              = f7188x_gpio_set,        \
0159             .set_config   = f7188x_gpio_set_config, \
0160             .base             = _base,          \
0161             .ngpio            = _ngpio,         \
0162             .can_sleep        = true,           \
0163         },                          \
0164         .regbase = _regbase,                    \
0165     }
0166 
0167 #define gpio_dir(base) (base + 0)
0168 #define gpio_data_out(base) (base + 1)
0169 #define gpio_data_in(base) (base + 2)
0170 /* Output mode register (0:open drain 1:push-pull). */
0171 #define gpio_out_mode(base) (base + 3)
0172 
0173 static struct f7188x_gpio_bank f71869_gpio_bank[] = {
0174     F7188X_GPIO_BANK(0, 6, 0xF0),
0175     F7188X_GPIO_BANK(10, 8, 0xE0),
0176     F7188X_GPIO_BANK(20, 8, 0xD0),
0177     F7188X_GPIO_BANK(30, 8, 0xC0),
0178     F7188X_GPIO_BANK(40, 8, 0xB0),
0179     F7188X_GPIO_BANK(50, 5, 0xA0),
0180     F7188X_GPIO_BANK(60, 6, 0x90),
0181 };
0182 
0183 static struct f7188x_gpio_bank f71869a_gpio_bank[] = {
0184     F7188X_GPIO_BANK(0, 6, 0xF0),
0185     F7188X_GPIO_BANK(10, 8, 0xE0),
0186     F7188X_GPIO_BANK(20, 8, 0xD0),
0187     F7188X_GPIO_BANK(30, 8, 0xC0),
0188     F7188X_GPIO_BANK(40, 8, 0xB0),
0189     F7188X_GPIO_BANK(50, 5, 0xA0),
0190     F7188X_GPIO_BANK(60, 8, 0x90),
0191     F7188X_GPIO_BANK(70, 8, 0x80),
0192 };
0193 
0194 static struct f7188x_gpio_bank f71882_gpio_bank[] = {
0195     F7188X_GPIO_BANK(0, 8, 0xF0),
0196     F7188X_GPIO_BANK(10, 8, 0xE0),
0197     F7188X_GPIO_BANK(20, 8, 0xD0),
0198     F7188X_GPIO_BANK(30, 4, 0xC0),
0199     F7188X_GPIO_BANK(40, 4, 0xB0),
0200 };
0201 
0202 static struct f7188x_gpio_bank f71889a_gpio_bank[] = {
0203     F7188X_GPIO_BANK(0, 7, 0xF0),
0204     F7188X_GPIO_BANK(10, 7, 0xE0),
0205     F7188X_GPIO_BANK(20, 8, 0xD0),
0206     F7188X_GPIO_BANK(30, 8, 0xC0),
0207     F7188X_GPIO_BANK(40, 8, 0xB0),
0208     F7188X_GPIO_BANK(50, 5, 0xA0),
0209     F7188X_GPIO_BANK(60, 8, 0x90),
0210     F7188X_GPIO_BANK(70, 8, 0x80),
0211 };
0212 
0213 static struct f7188x_gpio_bank f71889_gpio_bank[] = {
0214     F7188X_GPIO_BANK(0, 7, 0xF0),
0215     F7188X_GPIO_BANK(10, 7, 0xE0),
0216     F7188X_GPIO_BANK(20, 8, 0xD0),
0217     F7188X_GPIO_BANK(30, 8, 0xC0),
0218     F7188X_GPIO_BANK(40, 8, 0xB0),
0219     F7188X_GPIO_BANK(50, 5, 0xA0),
0220     F7188X_GPIO_BANK(60, 8, 0x90),
0221     F7188X_GPIO_BANK(70, 8, 0x80),
0222 };
0223 
0224 static struct f7188x_gpio_bank f81866_gpio_bank[] = {
0225     F7188X_GPIO_BANK(0, 8, 0xF0),
0226     F7188X_GPIO_BANK(10, 8, 0xE0),
0227     F7188X_GPIO_BANK(20, 8, 0xD0),
0228     F7188X_GPIO_BANK(30, 8, 0xC0),
0229     F7188X_GPIO_BANK(40, 8, 0xB0),
0230     F7188X_GPIO_BANK(50, 8, 0xA0),
0231     F7188X_GPIO_BANK(60, 8, 0x90),
0232     F7188X_GPIO_BANK(70, 8, 0x80),
0233     F7188X_GPIO_BANK(80, 8, 0x88),
0234 };
0235 
0236 
0237 static struct f7188x_gpio_bank f81804_gpio_bank[] = {
0238     F7188X_GPIO_BANK(0, 8, 0xF0),
0239     F7188X_GPIO_BANK(10, 8, 0xE0),
0240     F7188X_GPIO_BANK(20, 8, 0xD0),
0241     F7188X_GPIO_BANK(50, 8, 0xA0),
0242     F7188X_GPIO_BANK(60, 8, 0x90),
0243     F7188X_GPIO_BANK(70, 8, 0x80),
0244     F7188X_GPIO_BANK(90, 8, 0x98),
0245 };
0246 
0247 static struct f7188x_gpio_bank f81865_gpio_bank[] = {
0248     F7188X_GPIO_BANK(0, 8, 0xF0),
0249     F7188X_GPIO_BANK(10, 8, 0xE0),
0250     F7188X_GPIO_BANK(20, 8, 0xD0),
0251     F7188X_GPIO_BANK(30, 8, 0xC0),
0252     F7188X_GPIO_BANK(40, 8, 0xB0),
0253     F7188X_GPIO_BANK(50, 8, 0xA0),
0254     F7188X_GPIO_BANK(60, 5, 0x90),
0255 };
0256 
0257 static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
0258 {
0259     int err;
0260     struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
0261     struct f7188x_sio *sio = bank->data->sio;
0262     u8 dir;
0263 
0264     err = superio_enter(sio->addr);
0265     if (err)
0266         return err;
0267     superio_select(sio->addr, SIO_LD_GPIO);
0268 
0269     dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
0270 
0271     superio_exit(sio->addr);
0272 
0273     if (dir & 1 << offset)
0274         return GPIO_LINE_DIRECTION_OUT;
0275 
0276     return GPIO_LINE_DIRECTION_IN;
0277 }
0278 
0279 static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
0280 {
0281     int err;
0282     struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
0283     struct f7188x_sio *sio = bank->data->sio;
0284     u8 dir;
0285 
0286     err = superio_enter(sio->addr);
0287     if (err)
0288         return err;
0289     superio_select(sio->addr, SIO_LD_GPIO);
0290 
0291     dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
0292     dir &= ~BIT(offset);
0293     superio_outb(sio->addr, gpio_dir(bank->regbase), dir);
0294 
0295     superio_exit(sio->addr);
0296 
0297     return 0;
0298 }
0299 
0300 static int f7188x_gpio_get(struct gpio_chip *chip, unsigned offset)
0301 {
0302     int err;
0303     struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
0304     struct f7188x_sio *sio = bank->data->sio;
0305     u8 dir, data;
0306 
0307     err = superio_enter(sio->addr);
0308     if (err)
0309         return err;
0310     superio_select(sio->addr, SIO_LD_GPIO);
0311 
0312     dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
0313     dir = !!(dir & BIT(offset));
0314     if (dir)
0315         data = superio_inb(sio->addr, gpio_data_out(bank->regbase));
0316     else
0317         data = superio_inb(sio->addr, gpio_data_in(bank->regbase));
0318 
0319     superio_exit(sio->addr);
0320 
0321     return !!(data & BIT(offset));
0322 }
0323 
0324 static int f7188x_gpio_direction_out(struct gpio_chip *chip,
0325                      unsigned offset, int value)
0326 {
0327     int err;
0328     struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
0329     struct f7188x_sio *sio = bank->data->sio;
0330     u8 dir, data_out;
0331 
0332     err = superio_enter(sio->addr);
0333     if (err)
0334         return err;
0335     superio_select(sio->addr, SIO_LD_GPIO);
0336 
0337     data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase));
0338     if (value)
0339         data_out |= BIT(offset);
0340     else
0341         data_out &= ~BIT(offset);
0342     superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out);
0343 
0344     dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
0345     dir |= BIT(offset);
0346     superio_outb(sio->addr, gpio_dir(bank->regbase), dir);
0347 
0348     superio_exit(sio->addr);
0349 
0350     return 0;
0351 }
0352 
0353 static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
0354 {
0355     int err;
0356     struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
0357     struct f7188x_sio *sio = bank->data->sio;
0358     u8 data_out;
0359 
0360     err = superio_enter(sio->addr);
0361     if (err)
0362         return;
0363     superio_select(sio->addr, SIO_LD_GPIO);
0364 
0365     data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase));
0366     if (value)
0367         data_out |= BIT(offset);
0368     else
0369         data_out &= ~BIT(offset);
0370     superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out);
0371 
0372     superio_exit(sio->addr);
0373 }
0374 
0375 static int f7188x_gpio_set_config(struct gpio_chip *chip, unsigned offset,
0376                   unsigned long config)
0377 {
0378     int err;
0379     enum pin_config_param param = pinconf_to_config_param(config);
0380     struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
0381     struct f7188x_sio *sio = bank->data->sio;
0382     u8 data;
0383 
0384     if (param != PIN_CONFIG_DRIVE_OPEN_DRAIN &&
0385         param != PIN_CONFIG_DRIVE_PUSH_PULL)
0386         return -ENOTSUPP;
0387 
0388     err = superio_enter(sio->addr);
0389     if (err)
0390         return err;
0391     superio_select(sio->addr, SIO_LD_GPIO);
0392 
0393     data = superio_inb(sio->addr, gpio_out_mode(bank->regbase));
0394     if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
0395         data &= ~BIT(offset);
0396     else
0397         data |= BIT(offset);
0398     superio_outb(sio->addr, gpio_out_mode(bank->regbase), data);
0399 
0400     superio_exit(sio->addr);
0401     return 0;
0402 }
0403 
0404 /*
0405  * Platform device and driver.
0406  */
0407 
0408 static int f7188x_gpio_probe(struct platform_device *pdev)
0409 {
0410     int err;
0411     int i;
0412     struct f7188x_sio *sio = dev_get_platdata(&pdev->dev);
0413     struct f7188x_gpio_data *data;
0414 
0415     data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
0416     if (!data)
0417         return -ENOMEM;
0418 
0419     switch (sio->type) {
0420     case f71869:
0421         data->nr_bank = ARRAY_SIZE(f71869_gpio_bank);
0422         data->bank = f71869_gpio_bank;
0423         break;
0424     case f71869a:
0425         data->nr_bank = ARRAY_SIZE(f71869a_gpio_bank);
0426         data->bank = f71869a_gpio_bank;
0427         break;
0428     case f71882fg:
0429         data->nr_bank = ARRAY_SIZE(f71882_gpio_bank);
0430         data->bank = f71882_gpio_bank;
0431         break;
0432     case f71889a:
0433         data->nr_bank = ARRAY_SIZE(f71889a_gpio_bank);
0434         data->bank = f71889a_gpio_bank;
0435         break;
0436     case f71889f:
0437         data->nr_bank = ARRAY_SIZE(f71889_gpio_bank);
0438         data->bank = f71889_gpio_bank;
0439         break;
0440     case f81866:
0441         data->nr_bank = ARRAY_SIZE(f81866_gpio_bank);
0442         data->bank = f81866_gpio_bank;
0443         break;
0444     case  f81804:
0445         data->nr_bank = ARRAY_SIZE(f81804_gpio_bank);
0446         data->bank = f81804_gpio_bank;
0447         break;
0448     case f81865:
0449         data->nr_bank = ARRAY_SIZE(f81865_gpio_bank);
0450         data->bank = f81865_gpio_bank;
0451         break;
0452     default:
0453         return -ENODEV;
0454     }
0455     data->sio = sio;
0456 
0457     platform_set_drvdata(pdev, data);
0458 
0459     /* For each GPIO bank, register a GPIO chip. */
0460     for (i = 0; i < data->nr_bank; i++) {
0461         struct f7188x_gpio_bank *bank = &data->bank[i];
0462 
0463         bank->chip.parent = &pdev->dev;
0464         bank->data = data;
0465 
0466         err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
0467         if (err) {
0468             dev_err(&pdev->dev,
0469                 "Failed to register gpiochip %d: %d\n",
0470                 i, err);
0471             return err;
0472         }
0473     }
0474 
0475     return 0;
0476 }
0477 
0478 static int __init f7188x_find(int addr, struct f7188x_sio *sio)
0479 {
0480     int err;
0481     u16 devid;
0482 
0483     err = superio_enter(addr);
0484     if (err)
0485         return err;
0486 
0487     err = -ENODEV;
0488     devid = superio_inw(addr, SIO_MANID);
0489     if (devid != SIO_FINTEK_ID) {
0490         pr_debug(DRVNAME ": Not a Fintek device at 0x%08x\n", addr);
0491         goto err;
0492     }
0493 
0494     devid = superio_inw(addr, SIO_DEVID);
0495     switch (devid) {
0496     case SIO_F71869_ID:
0497         sio->type = f71869;
0498         break;
0499     case SIO_F71869A_ID:
0500         sio->type = f71869a;
0501         break;
0502     case SIO_F71882_ID:
0503         sio->type = f71882fg;
0504         break;
0505     case SIO_F71889A_ID:
0506         sio->type = f71889a;
0507         break;
0508     case SIO_F71889_ID:
0509         sio->type = f71889f;
0510         break;
0511     case SIO_F81866_ID:
0512         sio->type = f81866;
0513         break;
0514     case SIO_F81804_ID:
0515         sio->type = f81804;
0516         break;
0517     case SIO_F81865_ID:
0518         sio->type = f81865;
0519         break;
0520     default:
0521         pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid);
0522         goto err;
0523     }
0524     sio->addr = addr;
0525     err = 0;
0526 
0527     pr_info(DRVNAME ": Found %s at %#x, revision %d\n",
0528         f7188x_names[sio->type],
0529         (unsigned int) addr,
0530         (int) superio_inb(addr, SIO_DEVREV));
0531 
0532 err:
0533     superio_exit(addr);
0534     return err;
0535 }
0536 
0537 static struct platform_device *f7188x_gpio_pdev;
0538 
0539 static int __init
0540 f7188x_gpio_device_add(const struct f7188x_sio *sio)
0541 {
0542     int err;
0543 
0544     f7188x_gpio_pdev = platform_device_alloc(DRVNAME, -1);
0545     if (!f7188x_gpio_pdev)
0546         return -ENOMEM;
0547 
0548     err = platform_device_add_data(f7188x_gpio_pdev,
0549                        sio, sizeof(*sio));
0550     if (err) {
0551         pr_err(DRVNAME "Platform data allocation failed\n");
0552         goto err;
0553     }
0554 
0555     err = platform_device_add(f7188x_gpio_pdev);
0556     if (err) {
0557         pr_err(DRVNAME "Device addition failed\n");
0558         goto err;
0559     }
0560 
0561     return 0;
0562 
0563 err:
0564     platform_device_put(f7188x_gpio_pdev);
0565 
0566     return err;
0567 }
0568 
0569 /*
0570  * Try to match a supported Fintek device by reading the (hard-wired)
0571  * configuration I/O ports. If available, then register both the platform
0572  * device and driver to support the GPIOs.
0573  */
0574 
0575 static struct platform_driver f7188x_gpio_driver = {
0576     .driver = {
0577         .name   = DRVNAME,
0578     },
0579     .probe      = f7188x_gpio_probe,
0580 };
0581 
0582 static int __init f7188x_gpio_init(void)
0583 {
0584     int err;
0585     struct f7188x_sio sio;
0586 
0587     if (f7188x_find(0x2e, &sio) &&
0588         f7188x_find(0x4e, &sio))
0589         return -ENODEV;
0590 
0591     err = platform_driver_register(&f7188x_gpio_driver);
0592     if (!err) {
0593         err = f7188x_gpio_device_add(&sio);
0594         if (err)
0595             platform_driver_unregister(&f7188x_gpio_driver);
0596     }
0597 
0598     return err;
0599 }
0600 subsys_initcall(f7188x_gpio_init);
0601 
0602 static void __exit f7188x_gpio_exit(void)
0603 {
0604     platform_device_unregister(f7188x_gpio_pdev);
0605     platform_driver_unregister(&f7188x_gpio_driver);
0606 }
0607 module_exit(f7188x_gpio_exit);
0608 
0609 MODULE_DESCRIPTION("GPIO driver for Super-I/O chips F71869, F71869A, F71882FG, F71889A, F71889F and F81866");
0610 MODULE_AUTHOR("Simon Guinot <simon.guinot@sequanux.org>");
0611 MODULE_LICENSE("GPL");