gpio-f7188x: switch over to using pr_fmt
[linux-2.6-block.git] / drivers / gpio / gpio-f7188x.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
6c17aa01 2/*
1920906f 3 * GPIO driver for Fintek Super-I/O F71869, F71869A, F71882, F71889 and F81866
6c17aa01
SG
4 *
5 * Copyright (C) 2010-2013 LaCie
6 *
7 * Author: Simon Guinot <simon.guinot@sequanux.org>
6c17aa01
SG
8 */
9
821d9e1d
HS
10#define DRVNAME "gpio-f7188x"
11#define pr_fmt(fmt) DRVNAME ": " fmt
12
6c17aa01
SG
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/io.h>
148c8642
LW
17#include <linux/gpio/driver.h>
18#include <linux/bitops.h>
6c17aa01 19
6c17aa01
SG
20/*
21 * Super-I/O registers
22 */
23#define SIO_LDSEL 0x07 /* Logical device select */
24#define SIO_DEVID 0x20 /* Device ID (2 bytes) */
25#define SIO_DEVREV 0x22 /* Device revision */
26#define SIO_MANID 0x23 /* Fintek ID (2 bytes) */
27
28#define SIO_LD_GPIO 0x06 /* GPIO logical device */
29#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
30#define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */
31
32#define SIO_FINTEK_ID 0x1934 /* Manufacturer ID */
24ccef35 33#define SIO_F71869_ID 0x0814 /* F71869 chipset ID */
7e960363 34#define SIO_F71869A_ID 0x1007 /* F71869A chipset ID */
6c17aa01
SG
35#define SIO_F71882_ID 0x0541 /* F71882 chipset ID */
36#define SIO_F71889_ID 0x0909 /* F71889 chipset ID */
d69843e4 37#define SIO_F71889A_ID 0x1005 /* F71889A chipset ID */
1920906f 38#define SIO_F81866_ID 0x1010 /* F81866 chipset ID */
b0c3e54e 39#define SIO_F81804_ID 0x1502 /* F81804 chipset ID, same for f81966 */
17f96ee2
PJ
40#define SIO_F81865_ID 0x0704 /* F81865 chipset ID */
41
42
43enum chips {
44 f71869,
45 f71869a,
46 f71882fg,
47 f71889a,
48 f71889f,
49 f81866,
50 f81804,
51 f81865,
52};
6c17aa01
SG
53
54static const char * const f7188x_names[] = {
24ccef35 55 "f71869",
7e960363 56 "f71869a",
6c17aa01 57 "f71882fg",
d69843e4 58 "f71889a",
6c17aa01 59 "f71889f",
1920906f 60 "f81866",
b0c3e54e 61 "f81804",
17f96ee2 62 "f81865",
6c17aa01
SG
63};
64
65struct f7188x_sio {
66 int addr;
67 enum chips type;
68};
69
70struct f7188x_gpio_bank {
71 struct gpio_chip chip;
72 unsigned int regbase;
73 struct f7188x_gpio_data *data;
74};
75
76struct f7188x_gpio_data {
77 struct f7188x_sio *sio;
78 int nr_bank;
79 struct f7188x_gpio_bank *bank;
80};
81
82/*
83 * Super-I/O functions.
84 */
85
86static inline int superio_inb(int base, int reg)
87{
88 outb(reg, base);
89 return inb(base + 1);
90}
91
92static int superio_inw(int base, int reg)
93{
94 int val;
95
96 outb(reg++, base);
97 val = inb(base + 1) << 8;
98 outb(reg, base);
99 val |= inb(base + 1);
100
101 return val;
102}
103
104static inline void superio_outb(int base, int reg, int val)
105{
106 outb(reg, base);
107 outb(val, base + 1);
108}
109
110static inline int superio_enter(int base)
111{
112 /* Don't step on other drivers' I/O space by accident. */
113 if (!request_muxed_region(base, 2, DRVNAME)) {
821d9e1d 114 pr_err("I/O address 0x%04x already in use\n", base);
6c17aa01
SG
115 return -EBUSY;
116 }
117
118 /* According to the datasheet the key must be send twice. */
119 outb(SIO_UNLOCK_KEY, base);
120 outb(SIO_UNLOCK_KEY, base);
121
122 return 0;
123}
124
125static inline void superio_select(int base, int ld)
126{
127 outb(SIO_LDSEL, base);
128 outb(ld, base + 1);
129}
130
131static inline void superio_exit(int base)
132{
133 outb(SIO_LOCK_KEY, base);
134 release_region(base, 2);
135}
136
137/*
138 * GPIO chip.
139 */
140
107cdd2d 141static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset);
6c17aa01
SG
142static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset);
143static int f7188x_gpio_get(struct gpio_chip *chip, unsigned offset);
144static int f7188x_gpio_direction_out(struct gpio_chip *chip,
145 unsigned offset, int value);
146static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value);
2956b5d9
MW
147static int f7188x_gpio_set_config(struct gpio_chip *chip, unsigned offset,
148 unsigned long config);
6c17aa01
SG
149
150#define F7188X_GPIO_BANK(_base, _ngpio, _regbase) \
151 { \
152 .chip = { \
153 .label = DRVNAME, \
154 .owner = THIS_MODULE, \
107cdd2d 155 .get_direction = f7188x_gpio_get_direction, \
6c17aa01
SG
156 .direction_input = f7188x_gpio_direction_in, \
157 .get = f7188x_gpio_get, \
158 .direction_output = f7188x_gpio_direction_out, \
159 .set = f7188x_gpio_set, \
2956b5d9 160 .set_config = f7188x_gpio_set_config, \
6c17aa01
SG
161 .base = _base, \
162 .ngpio = _ngpio, \
aeccc1b4 163 .can_sleep = true, \
6c17aa01
SG
164 }, \
165 .regbase = _regbase, \
166 }
167
168#define gpio_dir(base) (base + 0)
169#define gpio_data_out(base) (base + 1)
170#define gpio_data_in(base) (base + 2)
171/* Output mode register (0:open drain 1:push-pull). */
172#define gpio_out_mode(base) (base + 3)
173
24ccef35
AB
174static struct f7188x_gpio_bank f71869_gpio_bank[] = {
175 F7188X_GPIO_BANK(0, 6, 0xF0),
176 F7188X_GPIO_BANK(10, 8, 0xE0),
177 F7188X_GPIO_BANK(20, 8, 0xD0),
178 F7188X_GPIO_BANK(30, 8, 0xC0),
179 F7188X_GPIO_BANK(40, 8, 0xB0),
180 F7188X_GPIO_BANK(50, 5, 0xA0),
181 F7188X_GPIO_BANK(60, 6, 0x90),
182};
183
7e960363
AB
184static struct f7188x_gpio_bank f71869a_gpio_bank[] = {
185 F7188X_GPIO_BANK(0, 6, 0xF0),
186 F7188X_GPIO_BANK(10, 8, 0xE0),
187 F7188X_GPIO_BANK(20, 8, 0xD0),
188 F7188X_GPIO_BANK(30, 8, 0xC0),
189 F7188X_GPIO_BANK(40, 8, 0xB0),
190 F7188X_GPIO_BANK(50, 5, 0xA0),
191 F7188X_GPIO_BANK(60, 8, 0x90),
192 F7188X_GPIO_BANK(70, 8, 0x80),
193};
194
6c17aa01 195static struct f7188x_gpio_bank f71882_gpio_bank[] = {
38e003f4 196 F7188X_GPIO_BANK(0, 8, 0xF0),
6c17aa01
SG
197 F7188X_GPIO_BANK(10, 8, 0xE0),
198 F7188X_GPIO_BANK(20, 8, 0xD0),
199 F7188X_GPIO_BANK(30, 4, 0xC0),
200 F7188X_GPIO_BANK(40, 4, 0xB0),
201};
202
d69843e4
MP
203static struct f7188x_gpio_bank f71889a_gpio_bank[] = {
204 F7188X_GPIO_BANK(0, 7, 0xF0),
205 F7188X_GPIO_BANK(10, 7, 0xE0),
206 F7188X_GPIO_BANK(20, 8, 0xD0),
207 F7188X_GPIO_BANK(30, 8, 0xC0),
208 F7188X_GPIO_BANK(40, 8, 0xB0),
209 F7188X_GPIO_BANK(50, 5, 0xA0),
210 F7188X_GPIO_BANK(60, 8, 0x90),
211 F7188X_GPIO_BANK(70, 8, 0x80),
212};
213
6c17aa01 214static struct f7188x_gpio_bank f71889_gpio_bank[] = {
38e003f4 215 F7188X_GPIO_BANK(0, 7, 0xF0),
6c17aa01
SG
216 F7188X_GPIO_BANK(10, 7, 0xE0),
217 F7188X_GPIO_BANK(20, 8, 0xD0),
218 F7188X_GPIO_BANK(30, 8, 0xC0),
219 F7188X_GPIO_BANK(40, 8, 0xB0),
220 F7188X_GPIO_BANK(50, 5, 0xA0),
221 F7188X_GPIO_BANK(60, 8, 0x90),
222 F7188X_GPIO_BANK(70, 8, 0x80),
223};
224
1920906f
PH
225static struct f7188x_gpio_bank f81866_gpio_bank[] = {
226 F7188X_GPIO_BANK(0, 8, 0xF0),
227 F7188X_GPIO_BANK(10, 8, 0xE0),
228 F7188X_GPIO_BANK(20, 8, 0xD0),
229 F7188X_GPIO_BANK(30, 8, 0xC0),
230 F7188X_GPIO_BANK(40, 8, 0xB0),
231 F7188X_GPIO_BANK(50, 8, 0xA0),
232 F7188X_GPIO_BANK(60, 8, 0x90),
233 F7188X_GPIO_BANK(70, 8, 0x80),
234 F7188X_GPIO_BANK(80, 8, 0x88),
235};
236
b0c3e54e
SK
237
238static struct f7188x_gpio_bank f81804_gpio_bank[] = {
239 F7188X_GPIO_BANK(0, 8, 0xF0),
240 F7188X_GPIO_BANK(10, 8, 0xE0),
241 F7188X_GPIO_BANK(20, 8, 0xD0),
242 F7188X_GPIO_BANK(50, 8, 0xA0),
243 F7188X_GPIO_BANK(60, 8, 0x90),
244 F7188X_GPIO_BANK(70, 8, 0x80),
245 F7188X_GPIO_BANK(90, 8, 0x98),
246};
247
17f96ee2
PJ
248static struct f7188x_gpio_bank f81865_gpio_bank[] = {
249 F7188X_GPIO_BANK(0, 8, 0xF0),
250 F7188X_GPIO_BANK(10, 8, 0xE0),
251 F7188X_GPIO_BANK(20, 8, 0xD0),
252 F7188X_GPIO_BANK(30, 8, 0xC0),
253 F7188X_GPIO_BANK(40, 8, 0xB0),
254 F7188X_GPIO_BANK(50, 8, 0xA0),
255 F7188X_GPIO_BANK(60, 5, 0x90),
256};
b0c3e54e 257
107cdd2d 258static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
259{
260 int err;
35a26144 261 struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
107cdd2d 262 struct f7188x_sio *sio = bank->data->sio;
263 u8 dir;
264
265 err = superio_enter(sio->addr);
266 if (err)
267 return err;
268 superio_select(sio->addr, SIO_LD_GPIO);
269
270 dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
271
272 superio_exit(sio->addr);
273
e42615ec
MV
274 if (dir & 1 << offset)
275 return GPIO_LINE_DIRECTION_OUT;
276
277 return GPIO_LINE_DIRECTION_IN;
107cdd2d 278}
279
6c17aa01
SG
280static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
281{
282 int err;
f372d5f5 283 struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
6c17aa01
SG
284 struct f7188x_sio *sio = bank->data->sio;
285 u8 dir;
286
287 err = superio_enter(sio->addr);
288 if (err)
289 return err;
290 superio_select(sio->addr, SIO_LD_GPIO);
291
292 dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
148c8642 293 dir &= ~BIT(offset);
6c17aa01
SG
294 superio_outb(sio->addr, gpio_dir(bank->regbase), dir);
295
296 superio_exit(sio->addr);
297
298 return 0;
299}
300
301static int f7188x_gpio_get(struct gpio_chip *chip, unsigned offset)
302{
303 int err;
f372d5f5 304 struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
6c17aa01
SG
305 struct f7188x_sio *sio = bank->data->sio;
306 u8 dir, data;
307
308 err = superio_enter(sio->addr);
309 if (err)
310 return err;
311 superio_select(sio->addr, SIO_LD_GPIO);
312
313 dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
148c8642 314 dir = !!(dir & BIT(offset));
6c17aa01
SG
315 if (dir)
316 data = superio_inb(sio->addr, gpio_data_out(bank->regbase));
317 else
318 data = superio_inb(sio->addr, gpio_data_in(bank->regbase));
319
320 superio_exit(sio->addr);
321
148c8642 322 return !!(data & BIT(offset));
6c17aa01
SG
323}
324
325static int f7188x_gpio_direction_out(struct gpio_chip *chip,
326 unsigned offset, int value)
327{
328 int err;
f372d5f5 329 struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
6c17aa01
SG
330 struct f7188x_sio *sio = bank->data->sio;
331 u8 dir, data_out;
332
333 err = superio_enter(sio->addr);
334 if (err)
335 return err;
336 superio_select(sio->addr, SIO_LD_GPIO);
337
338 data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase));
339 if (value)
148c8642 340 data_out |= BIT(offset);
6c17aa01 341 else
148c8642 342 data_out &= ~BIT(offset);
6c17aa01
SG
343 superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out);
344
345 dir = superio_inb(sio->addr, gpio_dir(bank->regbase));
148c8642 346 dir |= BIT(offset);
6c17aa01
SG
347 superio_outb(sio->addr, gpio_dir(bank->regbase), dir);
348
349 superio_exit(sio->addr);
350
351 return 0;
352}
353
354static void f7188x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
355{
356 int err;
f372d5f5 357 struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
6c17aa01
SG
358 struct f7188x_sio *sio = bank->data->sio;
359 u8 data_out;
360
361 err = superio_enter(sio->addr);
362 if (err)
363 return;
364 superio_select(sio->addr, SIO_LD_GPIO);
365
366 data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase));
367 if (value)
148c8642 368 data_out |= BIT(offset);
6c17aa01 369 else
148c8642 370 data_out &= ~BIT(offset);
6c17aa01
SG
371 superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out);
372
373 superio_exit(sio->addr);
374}
375
2956b5d9
MW
376static int f7188x_gpio_set_config(struct gpio_chip *chip, unsigned offset,
377 unsigned long config)
f90c6bdb
LW
378{
379 int err;
2956b5d9 380 enum pin_config_param param = pinconf_to_config_param(config);
f90c6bdb
LW
381 struct f7188x_gpio_bank *bank = gpiochip_get_data(chip);
382 struct f7188x_sio *sio = bank->data->sio;
383 u8 data;
384
2956b5d9
MW
385 if (param != PIN_CONFIG_DRIVE_OPEN_DRAIN &&
386 param != PIN_CONFIG_DRIVE_PUSH_PULL)
f90c6bdb
LW
387 return -ENOTSUPP;
388
389 err = superio_enter(sio->addr);
390 if (err)
391 return err;
392 superio_select(sio->addr, SIO_LD_GPIO);
393
394 data = superio_inb(sio->addr, gpio_out_mode(bank->regbase));
2956b5d9 395 if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
f90c6bdb
LW
396 data &= ~BIT(offset);
397 else
398 data |= BIT(offset);
327819d1 399 superio_outb(sio->addr, gpio_out_mode(bank->regbase), data);
f90c6bdb
LW
400
401 superio_exit(sio->addr);
402 return 0;
403}
404
6c17aa01
SG
405/*
406 * Platform device and driver.
407 */
408
409static int f7188x_gpio_probe(struct platform_device *pdev)
410{
411 int err;
412 int i;
ab128afc 413 struct f7188x_sio *sio = dev_get_platdata(&pdev->dev);
6c17aa01
SG
414 struct f7188x_gpio_data *data;
415
416 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
417 if (!data)
418 return -ENOMEM;
419
420 switch (sio->type) {
24ccef35
AB
421 case f71869:
422 data->nr_bank = ARRAY_SIZE(f71869_gpio_bank);
423 data->bank = f71869_gpio_bank;
424 break;
7e960363
AB
425 case f71869a:
426 data->nr_bank = ARRAY_SIZE(f71869a_gpio_bank);
427 data->bank = f71869a_gpio_bank;
428 break;
6c17aa01
SG
429 case f71882fg:
430 data->nr_bank = ARRAY_SIZE(f71882_gpio_bank);
431 data->bank = f71882_gpio_bank;
432 break;
d69843e4
MP
433 case f71889a:
434 data->nr_bank = ARRAY_SIZE(f71889a_gpio_bank);
435 data->bank = f71889a_gpio_bank;
b86c86aa 436 break;
6c17aa01
SG
437 case f71889f:
438 data->nr_bank = ARRAY_SIZE(f71889_gpio_bank);
439 data->bank = f71889_gpio_bank;
440 break;
1920906f
PH
441 case f81866:
442 data->nr_bank = ARRAY_SIZE(f81866_gpio_bank);
443 data->bank = f81866_gpio_bank;
444 break;
b0c3e54e
SK
445 case f81804:
446 data->nr_bank = ARRAY_SIZE(f81804_gpio_bank);
447 data->bank = f81804_gpio_bank;
448 break;
17f96ee2
PJ
449 case f81865:
450 data->nr_bank = ARRAY_SIZE(f81865_gpio_bank);
451 data->bank = f81865_gpio_bank;
452 break;
6c17aa01
SG
453 default:
454 return -ENODEV;
455 }
456 data->sio = sio;
457
458 platform_set_drvdata(pdev, data);
459
460 /* For each GPIO bank, register a GPIO chip. */
461 for (i = 0; i < data->nr_bank; i++) {
462 struct f7188x_gpio_bank *bank = &data->bank[i];
463
58383c78 464 bank->chip.parent = &pdev->dev;
6c17aa01
SG
465 bank->data = data;
466
330f4e56 467 err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
6c17aa01
SG
468 if (err) {
469 dev_err(&pdev->dev,
470 "Failed to register gpiochip %d: %d\n",
471 i, err);
330f4e56 472 return err;
6c17aa01
SG
473 }
474 }
475
6c17aa01
SG
476 return 0;
477}
478
479static int __init f7188x_find(int addr, struct f7188x_sio *sio)
480{
481 int err;
482 u16 devid;
483
484 err = superio_enter(addr);
485 if (err)
486 return err;
487
488 err = -ENODEV;
489 devid = superio_inw(addr, SIO_MANID);
490 if (devid != SIO_FINTEK_ID) {
821d9e1d 491 pr_debug("Not a Fintek device at 0x%08x\n", addr);
6c17aa01
SG
492 goto err;
493 }
494
495 devid = superio_inw(addr, SIO_DEVID);
496 switch (devid) {
24ccef35
AB
497 case SIO_F71869_ID:
498 sio->type = f71869;
499 break;
7e960363
AB
500 case SIO_F71869A_ID:
501 sio->type = f71869a;
502 break;
6c17aa01
SG
503 case SIO_F71882_ID:
504 sio->type = f71882fg;
505 break;
d69843e4
MP
506 case SIO_F71889A_ID:
507 sio->type = f71889a;
508 break;
6c17aa01
SG
509 case SIO_F71889_ID:
510 sio->type = f71889f;
511 break;
1920906f
PH
512 case SIO_F81866_ID:
513 sio->type = f81866;
514 break;
b0c3e54e
SK
515 case SIO_F81804_ID:
516 sio->type = f81804;
517 break;
17f96ee2
PJ
518 case SIO_F81865_ID:
519 sio->type = f81865;
520 break;
6c17aa01 521 default:
821d9e1d 522 pr_info("Unsupported Fintek device 0x%04x\n", devid);
6c17aa01
SG
523 goto err;
524 }
525 sio->addr = addr;
526 err = 0;
527
821d9e1d 528 pr_info("Found %s at %#x, revision %d\n",
6c17aa01
SG
529 f7188x_names[sio->type],
530 (unsigned int) addr,
531 (int) superio_inb(addr, SIO_DEVREV));
532
533err:
534 superio_exit(addr);
535 return err;
536}
537
538static struct platform_device *f7188x_gpio_pdev;
539
540static int __init
541f7188x_gpio_device_add(const struct f7188x_sio *sio)
542{
543 int err;
544
545 f7188x_gpio_pdev = platform_device_alloc(DRVNAME, -1);
546 if (!f7188x_gpio_pdev)
547 return -ENOMEM;
548
549 err = platform_device_add_data(f7188x_gpio_pdev,
550 sio, sizeof(*sio));
551 if (err) {
821d9e1d 552 pr_err("Platform data allocation failed\n");
6c17aa01
SG
553 goto err;
554 }
555
556 err = platform_device_add(f7188x_gpio_pdev);
557 if (err) {
821d9e1d 558 pr_err("Device addition failed\n");
6c17aa01
SG
559 goto err;
560 }
561
562 return 0;
563
564err:
565 platform_device_put(f7188x_gpio_pdev);
566
567 return err;
568}
569
570/*
3f8f4f19 571 * Try to match a supported Fintek device by reading the (hard-wired)
6c17aa01
SG
572 * configuration I/O ports. If available, then register both the platform
573 * device and driver to support the GPIOs.
574 */
575
576static struct platform_driver f7188x_gpio_driver = {
577 .driver = {
6c17aa01
SG
578 .name = DRVNAME,
579 },
580 .probe = f7188x_gpio_probe,
6c17aa01
SG
581};
582
583static int __init f7188x_gpio_init(void)
584{
585 int err;
586 struct f7188x_sio sio;
587
588 if (f7188x_find(0x2e, &sio) &&
589 f7188x_find(0x4e, &sio))
590 return -ENODEV;
591
592 err = platform_driver_register(&f7188x_gpio_driver);
593 if (!err) {
594 err = f7188x_gpio_device_add(&sio);
595 if (err)
596 platform_driver_unregister(&f7188x_gpio_driver);
597 }
598
599 return err;
600}
601subsys_initcall(f7188x_gpio_init);
602
603static void __exit f7188x_gpio_exit(void)
604{
605 platform_device_unregister(f7188x_gpio_pdev);
606 platform_driver_unregister(&f7188x_gpio_driver);
607}
608module_exit(f7188x_gpio_exit);
609
d69843e4 610MODULE_DESCRIPTION("GPIO driver for Super-I/O chips F71869, F71869A, F71882FG, F71889A, F71889F and F81866");
6c17aa01
SG
611MODULE_AUTHOR("Simon Guinot <simon.guinot@sequanux.org>");
612MODULE_LICENSE("GPL");