Merge tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / drivers / gpio / gpio-ge.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for GE FPGA based GPIO
4  *
5  * Author: Martyn Welch <martyn.welch@ge.com>
6  *
7  * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc.
8  */
9
10 /*
11  * TODO:
12  *
13  * Configuration of output modes (totem-pole/open-drain).
14  * Interrupt configuration - interrupts are always generated, the FPGA relies
15  * on the I/O interrupt controllers mask to stop them from being propagated.
16  */
17
18 #include <linux/gpio/driver.h>
19 #include <linux/io.h>
20 #include <linux/kernel.h>
21 #include <linux/mod_devicetable.h>
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/property.h>
25 #include <linux/slab.h>
26
27 #define GEF_GPIO_DIRECT         0x00
28 #define GEF_GPIO_IN             0x04
29 #define GEF_GPIO_OUT            0x08
30 #define GEF_GPIO_TRIG           0x0C
31 #define GEF_GPIO_POLAR_A        0x10
32 #define GEF_GPIO_POLAR_B        0x14
33 #define GEF_GPIO_INT_STAT       0x18
34 #define GEF_GPIO_OVERRUN        0x1C
35 #define GEF_GPIO_MODE           0x20
36
37 static const struct of_device_id gef_gpio_ids[] = {
38         {
39                 .compatible     = "gef,sbc610-gpio",
40                 .data           = (void *)19,
41         }, {
42                 .compatible     = "gef,sbc310-gpio",
43                 .data           = (void *)6,
44         }, {
45                 .compatible     = "ge,imp3a-gpio",
46                 .data           = (void *)16,
47         },
48         { }
49 };
50 MODULE_DEVICE_TABLE(of, gef_gpio_ids);
51
52 static int __init gef_gpio_probe(struct platform_device *pdev)
53 {
54         struct device *dev = &pdev->dev;
55         struct gpio_chip *gc;
56         void __iomem *regs;
57         int ret;
58
59         gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
60         if (!gc)
61                 return -ENOMEM;
62
63         regs = devm_platform_ioremap_resource(pdev, 0);
64         if (IS_ERR(regs))
65                 return PTR_ERR(regs);
66
67         ret = bgpio_init(gc, dev, 4, regs + GEF_GPIO_IN, regs + GEF_GPIO_OUT,
68                          NULL, NULL, regs + GEF_GPIO_DIRECT,
69                          BGPIOF_BIG_ENDIAN_BYTE_ORDER);
70         if (ret)
71                 return dev_err_probe(dev, ret, "bgpio_init failed\n");
72
73         /* Setup pointers to chip functions */
74         gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", dev_fwnode(dev));
75         if (!gc->label)
76                 return -ENOMEM;
77
78         gc->base = -1;
79         gc->ngpio = (uintptr_t)device_get_match_data(dev);
80
81         /* This function adds a memory mapped GPIO chip */
82         ret = devm_gpiochip_add_data(dev, gc, NULL);
83         if (ret)
84                 return dev_err_probe(dev, ret, "GPIO chip registration failed\n");
85
86         return 0;
87 };
88
89 static struct platform_driver gef_gpio_driver = {
90         .driver = {
91                 .name           = "gef-gpio",
92                 .of_match_table = gef_gpio_ids,
93         },
94 };
95 module_platform_driver_probe(gef_gpio_driver, gef_gpio_probe);
96
97 MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
98 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
99 MODULE_LICENSE("GPL");