0001
0002
0003
0004
0005
0006
0007
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
0021
0022 #define SIO_LDSEL 0x07
0023 #define SIO_DEVID 0x20
0024 #define SIO_DEVREV 0x22
0025 #define SIO_MANID 0x23
0026
0027 #define SIO_LD_GPIO 0x06
0028 #define SIO_UNLOCK_KEY 0x87
0029 #define SIO_LOCK_KEY 0xAA
0030
0031 #define SIO_FINTEK_ID 0x1934
0032 #define SIO_F71869_ID 0x0814
0033 #define SIO_F71869A_ID 0x1007
0034 #define SIO_F71882_ID 0x0541
0035 #define SIO_F71889_ID 0x0909
0036 #define SIO_F71889A_ID 0x1005
0037 #define SIO_F81866_ID 0x1010
0038 #define SIO_F81804_ID 0x1502
0039 #define SIO_F81865_ID 0x0704
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
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
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
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
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
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
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
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
0571
0572
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");