Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Driver for GE FPGA based GPIO
0003  *
0004  * Author: Martyn Welch <martyn.welch@ge.com>
0005  *
0006  * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc.
0007  *
0008  * This file is licensed under the terms of the GNU General Public License
0009  * version 2.  This program is licensed "as is" without any warranty of any
0010  * kind, whether express or implied.
0011  */
0012 
0013 /* TODO
0014  *
0015  * Configuration of output modes (totem-pole/open-drain)
0016  * Interrupt configuration - interrupts are always generated the FPGA relies on
0017  * the I/O interrupt controllers mask to stop them propergating
0018  */
0019 
0020 #include <linux/kernel.h>
0021 #include <linux/io.h>
0022 #include <linux/slab.h>
0023 #include <linux/of_device.h>
0024 #include <linux/of_address.h>
0025 #include <linux/module.h>
0026 #include <linux/gpio/driver.h>
0027 
0028 #define GEF_GPIO_DIRECT     0x00
0029 #define GEF_GPIO_IN     0x04
0030 #define GEF_GPIO_OUT        0x08
0031 #define GEF_GPIO_TRIG       0x0C
0032 #define GEF_GPIO_POLAR_A    0x10
0033 #define GEF_GPIO_POLAR_B    0x14
0034 #define GEF_GPIO_INT_STAT   0x18
0035 #define GEF_GPIO_OVERRUN    0x1C
0036 #define GEF_GPIO_MODE       0x20
0037 
0038 static const struct of_device_id gef_gpio_ids[] = {
0039     {
0040         .compatible = "gef,sbc610-gpio",
0041         .data       = (void *)19,
0042     }, {
0043         .compatible = "gef,sbc310-gpio",
0044         .data       = (void *)6,
0045     }, {
0046         .compatible = "ge,imp3a-gpio",
0047         .data       = (void *)16,
0048     },
0049     { }
0050 };
0051 MODULE_DEVICE_TABLE(of, gef_gpio_ids);
0052 
0053 static int __init gef_gpio_probe(struct platform_device *pdev)
0054 {
0055     struct gpio_chip *gc;
0056     void __iomem *regs;
0057     int ret;
0058 
0059     gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
0060     if (!gc)
0061         return -ENOMEM;
0062 
0063     regs = of_iomap(pdev->dev.of_node, 0);
0064     if (!regs)
0065         return -ENOMEM;
0066 
0067     ret = bgpio_init(gc, &pdev->dev, 4, regs + GEF_GPIO_IN,
0068              regs + GEF_GPIO_OUT, NULL, NULL,
0069              regs + GEF_GPIO_DIRECT, BGPIOF_BIG_ENDIAN_BYTE_ORDER);
0070     if (ret) {
0071         dev_err(&pdev->dev, "bgpio_init failed\n");
0072         goto err0;
0073     }
0074 
0075     /* Setup pointers to chip functions */
0076     gc->label = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
0077     if (!gc->label) {
0078         ret = -ENOMEM;
0079         goto err0;
0080     }
0081 
0082     gc->base = -1;
0083     gc->ngpio = (u16)(uintptr_t)of_device_get_match_data(&pdev->dev);
0084     gc->of_gpio_n_cells = 2;
0085 
0086     /* This function adds a memory mapped GPIO chip */
0087     ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL);
0088     if (ret)
0089         goto err0;
0090 
0091     return 0;
0092 err0:
0093     iounmap(regs);
0094     pr_err("%pOF: GPIO chip registration failed\n", pdev->dev.of_node);
0095     return ret;
0096 };
0097 
0098 static struct platform_driver gef_gpio_driver = {
0099     .driver = {
0100         .name       = "gef-gpio",
0101         .of_match_table = gef_gpio_ids,
0102     },
0103 };
0104 module_platform_driver_probe(gef_gpio_driver, gef_gpio_probe);
0105 
0106 MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
0107 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
0108 MODULE_LICENSE("GPL");