clk: bcm: dvp: drop a variable that is assigned to only
[linux-2.6-microblaze.git] / drivers / gpio / gpio-sch311x.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * GPIO driver for the SMSC SCH311x Super-I/O chips
4  *
5  * Copyright (C) 2013 Bruno Randolf <br1@einfach.org>
6  *
7  * SuperIO functions and chip detection:
8  * (c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>.
9  */
10
11 #include <linux/ioport.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/gpio/driver.h>
17 #include <linux/bitops.h>
18 #include <linux/io.h>
19
20 #define DRV_NAME                        "gpio-sch311x"
21
22 #define SCH311X_GPIO_CONF_DIR           BIT(0)
23 #define SCH311X_GPIO_CONF_INVERT        BIT(1)
24 #define SCH311X_GPIO_CONF_OPEN_DRAIN    BIT(7)
25
26 #define SIO_CONFIG_KEY_ENTER            0x55
27 #define SIO_CONFIG_KEY_EXIT             0xaa
28
29 #define GP1                             0x4b
30
31 static int sch311x_ioports[] = { 0x2e, 0x4e, 0x162e, 0x164e };
32
33 static struct platform_device *sch311x_gpio_pdev;
34
35 struct sch311x_pdev_data {              /* platform device data */
36         unsigned short runtime_reg;     /* runtime register base address */
37 };
38
39 struct sch311x_gpio_block {             /* one GPIO block runtime data */
40         struct gpio_chip chip;
41         unsigned short data_reg;        /* from definition below */
42         unsigned short *config_regs;    /* pointer to definition below */
43         unsigned short runtime_reg;     /* runtime register */
44         spinlock_t lock;                /* lock for this GPIO block */
45 };
46
47 struct sch311x_gpio_priv {              /* driver private data */
48         struct sch311x_gpio_block blocks[6];
49 };
50
51 struct sch311x_gpio_block_def {         /* register address definitions */
52         unsigned short data_reg;
53         unsigned short config_regs[8];
54         unsigned short base;
55 };
56
57 /* Note: some GPIOs are not available, these are marked with 0x00 */
58
59 static struct sch311x_gpio_block_def sch311x_gpio_blocks[] = {
60         {
61                 .data_reg = 0x4b,       /* GP1 */
62                 .config_regs = {0x23, 0x24, 0x25, 0x26, 0x27, 0x29, 0x2a, 0x2b},
63                 .base = 10,
64         },
65         {
66                 .data_reg = 0x4c,       /* GP2 */
67                 .config_regs = {0x00, 0x2c, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x32},
68                 .base = 20,
69         },
70         {
71                 .data_reg = 0x4d,       /* GP3 */
72                 .config_regs = {0x33, 0x34, 0x35, 0x36, 0x37, 0x00, 0x39, 0x3a},
73                 .base = 30,
74         },
75         {
76                 .data_reg = 0x4e,       /* GP4 */
77                 .config_regs = {0x3b, 0x00, 0x3d, 0x00, 0x6e, 0x6f, 0x72, 0x73},
78                 .base = 40,
79         },
80         {
81                 .data_reg = 0x4f,       /* GP5 */
82                 .config_regs = {0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46},
83                 .base = 50,
84         },
85         {
86                 .data_reg = 0x50,       /* GP6 */
87                 .config_regs = {0x47, 0x48, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59},
88                 .base = 60,
89         },
90 };
91
92 /*
93  *      Super-IO functions
94  */
95
96 static inline int sch311x_sio_enter(int sio_config_port)
97 {
98         /* Don't step on other drivers' I/O space by accident. */
99         if (!request_muxed_region(sio_config_port, 2, DRV_NAME)) {
100                 pr_err(DRV_NAME "I/O address 0x%04x already in use\n",
101                        sio_config_port);
102                 return -EBUSY;
103         }
104
105         outb(SIO_CONFIG_KEY_ENTER, sio_config_port);
106         return 0;
107 }
108
109 static inline void sch311x_sio_exit(int sio_config_port)
110 {
111         outb(SIO_CONFIG_KEY_EXIT, sio_config_port);
112         release_region(sio_config_port, 2);
113 }
114
115 static inline int sch311x_sio_inb(int sio_config_port, int reg)
116 {
117         outb(reg, sio_config_port);
118         return inb(sio_config_port + 1);
119 }
120
121 static inline void sch311x_sio_outb(int sio_config_port, int reg, int val)
122 {
123         outb(reg, sio_config_port);
124         outb(val, sio_config_port + 1);
125 }
126
127
128 /*
129  *      GPIO functions
130  */
131
132 static int sch311x_gpio_request(struct gpio_chip *chip, unsigned offset)
133 {
134         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
135
136         if (block->config_regs[offset] == 0) /* GPIO is not available */
137                 return -ENODEV;
138
139         if (!request_region(block->runtime_reg + block->config_regs[offset],
140                             1, DRV_NAME)) {
141                 dev_err(chip->parent, "Failed to request region 0x%04x.\n",
142                         block->runtime_reg + block->config_regs[offset]);
143                 return -EBUSY;
144         }
145         return 0;
146 }
147
148 static void sch311x_gpio_free(struct gpio_chip *chip, unsigned offset)
149 {
150         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
151
152         if (block->config_regs[offset] == 0) /* GPIO is not available */
153                 return;
154
155         release_region(block->runtime_reg + block->config_regs[offset], 1);
156 }
157
158 static int sch311x_gpio_get(struct gpio_chip *chip, unsigned offset)
159 {
160         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
161         u8 data;
162
163         spin_lock(&block->lock);
164         data = inb(block->runtime_reg + block->data_reg);
165         spin_unlock(&block->lock);
166
167         return !!(data & BIT(offset));
168 }
169
170 static void __sch311x_gpio_set(struct sch311x_gpio_block *block,
171                                unsigned offset, int value)
172 {
173         u8 data = inb(block->runtime_reg + block->data_reg);
174         if (value)
175                 data |= BIT(offset);
176         else
177                 data &= ~BIT(offset);
178         outb(data, block->runtime_reg + block->data_reg);
179 }
180
181 static void sch311x_gpio_set(struct gpio_chip *chip, unsigned offset,
182                              int value)
183 {
184         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
185
186         spin_lock(&block->lock);
187         __sch311x_gpio_set(block, offset, value);
188         spin_unlock(&block->lock);
189 }
190
191 static int sch311x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
192 {
193         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
194         u8 data;
195
196         spin_lock(&block->lock);
197         data = inb(block->runtime_reg + block->config_regs[offset]);
198         data |= SCH311X_GPIO_CONF_DIR;
199         outb(data, block->runtime_reg + block->config_regs[offset]);
200         spin_unlock(&block->lock);
201
202         return 0;
203 }
204
205 static int sch311x_gpio_direction_out(struct gpio_chip *chip, unsigned offset,
206                                       int value)
207 {
208         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
209         u8 data;
210
211         spin_lock(&block->lock);
212
213         data = inb(block->runtime_reg + block->config_regs[offset]);
214         data &= ~SCH311X_GPIO_CONF_DIR;
215         outb(data, block->runtime_reg + block->config_regs[offset]);
216         __sch311x_gpio_set(block, offset, value);
217
218         spin_unlock(&block->lock);
219         return 0;
220 }
221
222 static int sch311x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
223 {
224         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
225         u8 data;
226
227         spin_lock(&block->lock);
228         data = inb(block->runtime_reg + block->config_regs[offset]);
229         spin_unlock(&block->lock);
230
231         if (data & SCH311X_GPIO_CONF_DIR)
232                 return GPIO_LINE_DIRECTION_IN;
233
234         return GPIO_LINE_DIRECTION_OUT;
235 }
236
237 static int sch311x_gpio_set_config(struct gpio_chip *chip, unsigned offset,
238                                    unsigned long config)
239 {
240         struct sch311x_gpio_block *block = gpiochip_get_data(chip);
241         enum pin_config_param param = pinconf_to_config_param(config);
242         u8 data;
243
244         switch (param) {
245         case PIN_CONFIG_DRIVE_OPEN_DRAIN:
246                 spin_lock(&block->lock);
247                 data = inb(block->runtime_reg + block->config_regs[offset]);
248                 data |= SCH311X_GPIO_CONF_OPEN_DRAIN;
249                 outb(data, block->runtime_reg + block->config_regs[offset]);
250                 spin_unlock(&block->lock);
251                 return 0;
252         case PIN_CONFIG_DRIVE_PUSH_PULL:
253                 spin_lock(&block->lock);
254                 data = inb(block->runtime_reg + block->config_regs[offset]);
255                 data &= ~SCH311X_GPIO_CONF_OPEN_DRAIN;
256                 outb(data, block->runtime_reg + block->config_regs[offset]);
257                 spin_unlock(&block->lock);
258                 return 0;
259         default:
260                 break;
261         }
262         return -ENOTSUPP;
263 }
264
265 static int sch311x_gpio_probe(struct platform_device *pdev)
266 {
267         struct sch311x_pdev_data *pdata = dev_get_platdata(&pdev->dev);
268         struct sch311x_gpio_priv *priv;
269         struct sch311x_gpio_block *block;
270         int err, i;
271
272         /* we can register all GPIO data registers at once */
273         if (!devm_request_region(&pdev->dev, pdata->runtime_reg + GP1, 6,
274                 DRV_NAME)) {
275                 dev_err(&pdev->dev, "Failed to request region 0x%04x-0x%04x.\n",
276                         pdata->runtime_reg + GP1, pdata->runtime_reg + GP1 + 5);
277                 return -EBUSY;
278         }
279
280         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
281         if (!priv)
282                 return -ENOMEM;
283
284         platform_set_drvdata(pdev, priv);
285
286         for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) {
287                 block = &priv->blocks[i];
288
289                 spin_lock_init(&block->lock);
290
291                 block->chip.label = DRV_NAME;
292                 block->chip.owner = THIS_MODULE;
293                 block->chip.request = sch311x_gpio_request;
294                 block->chip.free = sch311x_gpio_free;
295                 block->chip.direction_input = sch311x_gpio_direction_in;
296                 block->chip.direction_output = sch311x_gpio_direction_out;
297                 block->chip.get_direction = sch311x_gpio_get_direction;
298                 block->chip.set_config = sch311x_gpio_set_config;
299                 block->chip.get = sch311x_gpio_get;
300                 block->chip.set = sch311x_gpio_set;
301                 block->chip.ngpio = 8;
302                 block->chip.parent = &pdev->dev;
303                 block->chip.base = sch311x_gpio_blocks[i].base;
304                 block->config_regs = sch311x_gpio_blocks[i].config_regs;
305                 block->data_reg = sch311x_gpio_blocks[i].data_reg;
306                 block->runtime_reg = pdata->runtime_reg;
307
308                 err = gpiochip_add_data(&block->chip, block);
309                 if (err < 0) {
310                         dev_err(&pdev->dev,
311                                 "Could not register gpiochip, %d\n", err);
312                         goto exit_err;
313                 }
314                 dev_info(&pdev->dev,
315                          "SMSC SCH311x GPIO block %d registered.\n", i);
316         }
317
318         return 0;
319
320 exit_err:
321         /* release already registered chips */
322         for (--i; i >= 0; i--)
323                 gpiochip_remove(&priv->blocks[i].chip);
324         return err;
325 }
326
327 static int sch311x_gpio_remove(struct platform_device *pdev)
328 {
329         struct sch311x_gpio_priv *priv = platform_get_drvdata(pdev);
330         int i;
331
332         for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) {
333                 gpiochip_remove(&priv->blocks[i].chip);
334                 dev_info(&pdev->dev,
335                          "SMSC SCH311x GPIO block %d unregistered.\n", i);
336         }
337         return 0;
338 }
339
340 static struct platform_driver sch311x_gpio_driver = {
341         .driver.name    = DRV_NAME,
342         .probe          = sch311x_gpio_probe,
343         .remove         = sch311x_gpio_remove,
344 };
345
346
347 /*
348  *      Init & exit routines
349  */
350
351 static int __init sch311x_detect(int sio_config_port, unsigned short *addr)
352 {
353         int err = 0, reg;
354         unsigned short base_addr;
355         u8 dev_id;
356
357         err = sch311x_sio_enter(sio_config_port);
358         if (err)
359                 return err;
360
361         /* Check device ID. */
362         reg = sch311x_sio_inb(sio_config_port, 0x20);
363         switch (reg) {
364         case 0x7c: /* SCH3112 */
365                 dev_id = 2;
366                 break;
367         case 0x7d: /* SCH3114 */
368                 dev_id = 4;
369                 break;
370         case 0x7f: /* SCH3116 */
371                 dev_id = 6;
372                 break;
373         default:
374                 err = -ENODEV;
375                 goto exit;
376         }
377
378         /* Select logical device A (runtime registers) */
379         sch311x_sio_outb(sio_config_port, 0x07, 0x0a);
380
381         /* Check if Logical Device Register is currently active */
382         if ((sch311x_sio_inb(sio_config_port, 0x30) & 0x01) == 0)
383                 pr_info("Seems that LDN 0x0a is not active...\n");
384
385         /* Get the base address of the runtime registers */
386         base_addr = (sch311x_sio_inb(sio_config_port, 0x60) << 8) |
387                            sch311x_sio_inb(sio_config_port, 0x61);
388         if (!base_addr) {
389                 pr_err("Base address not set\n");
390                 err = -ENODEV;
391                 goto exit;
392         }
393         *addr = base_addr;
394
395         pr_info("Found an SMSC SCH311%d chip at 0x%04x\n", dev_id, base_addr);
396
397 exit:
398         sch311x_sio_exit(sio_config_port);
399         return err;
400 }
401
402 static int __init sch311x_gpio_pdev_add(const unsigned short addr)
403 {
404         struct sch311x_pdev_data pdata;
405         int err;
406
407         pdata.runtime_reg = addr;
408
409         sch311x_gpio_pdev = platform_device_alloc(DRV_NAME, -1);
410         if (!sch311x_gpio_pdev)
411                 return -ENOMEM;
412
413         err = platform_device_add_data(sch311x_gpio_pdev,
414                                        &pdata, sizeof(pdata));
415         if (err) {
416                 pr_err(DRV_NAME "Platform data allocation failed\n");
417                 goto err;
418         }
419
420         err = platform_device_add(sch311x_gpio_pdev);
421         if (err) {
422                 pr_err(DRV_NAME "Device addition failed\n");
423                 goto err;
424         }
425         return 0;
426
427 err:
428         platform_device_put(sch311x_gpio_pdev);
429         return err;
430 }
431
432 static int __init sch311x_gpio_init(void)
433 {
434         int err, i;
435         unsigned short addr = 0;
436
437         for (i = 0; i < ARRAY_SIZE(sch311x_ioports); i++)
438                 if (sch311x_detect(sch311x_ioports[i], &addr) == 0)
439                         break;
440
441         if (!addr)
442                 return -ENODEV;
443
444         err = platform_driver_register(&sch311x_gpio_driver);
445         if (err)
446                 return err;
447
448         err = sch311x_gpio_pdev_add(addr);
449         if (err)
450                 goto unreg_platform_driver;
451
452         return 0;
453
454 unreg_platform_driver:
455         platform_driver_unregister(&sch311x_gpio_driver);
456         return err;
457 }
458
459 static void __exit sch311x_gpio_exit(void)
460 {
461         platform_device_unregister(sch311x_gpio_pdev);
462         platform_driver_unregister(&sch311x_gpio_driver);
463 }
464
465 module_init(sch311x_gpio_init);
466 module_exit(sch311x_gpio_exit);
467
468 MODULE_AUTHOR("Bruno Randolf <br1@einfach.org>");
469 MODULE_DESCRIPTION("SMSC SCH311x GPIO Driver");
470 MODULE_LICENSE("GPL");
471 MODULE_ALIAS("platform:gpio-sch311x");