Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * OMAP16xx specific gpio init
0004  *
0005  * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
0006  *
0007  * Author:
0008  *  Charulatha V <charu@ti.com>
0009  */
0010 
0011 #include <linux/gpio.h>
0012 #include <linux/platform_data/gpio-omap.h>
0013 #include <linux/soc/ti/omap1-io.h>
0014 
0015 #include "hardware.h"
0016 #include "irqs.h"
0017 #include "soc.h"
0018 
0019 #define OMAP1610_GPIO1_BASE     0xfffbe400
0020 #define OMAP1610_GPIO2_BASE     0xfffbec00
0021 #define OMAP1610_GPIO3_BASE     0xfffbb400
0022 #define OMAP1610_GPIO4_BASE     0xfffbbc00
0023 #define OMAP1_MPUIO_VBASE       OMAP1_MPUIO_BASE
0024 
0025 /* smart idle, enable wakeup */
0026 #define SYSCONFIG_WORD          0x14
0027 
0028 /* mpu gpio */
0029 static struct resource omap16xx_mpu_gpio_resources[] = {
0030     {
0031         .start  = OMAP1_MPUIO_VBASE,
0032         .end    = OMAP1_MPUIO_VBASE + SZ_2K - 1,
0033         .flags  = IORESOURCE_MEM,
0034     },
0035     {
0036         .start  = INT_MPUIO,
0037         .flags  = IORESOURCE_IRQ,
0038     },
0039 };
0040 
0041 static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {
0042     .revision       = USHRT_MAX,
0043     .direction  = OMAP_MPUIO_IO_CNTL,
0044     .datain     = OMAP_MPUIO_INPUT_LATCH,
0045     .dataout    = OMAP_MPUIO_OUTPUT,
0046     .irqstatus  = OMAP_MPUIO_GPIO_INT,
0047     .irqenable  = OMAP_MPUIO_GPIO_MASKIT,
0048     .irqenable_inv  = true,
0049     .irqctrl    = OMAP_MPUIO_GPIO_INT_EDGE,
0050 };
0051 
0052 static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = {
0053     .is_mpuio       = true,
0054     .bank_width     = 16,
0055     .bank_stride        = 1,
0056     .regs                   = &omap16xx_mpuio_regs,
0057 };
0058 
0059 static struct platform_device omap16xx_mpu_gpio = {
0060     .name           = "omap_gpio",
0061     .id             = 0,
0062     .dev            = {
0063         .platform_data = &omap16xx_mpu_gpio_config,
0064     },
0065     .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
0066     .resource = omap16xx_mpu_gpio_resources,
0067 };
0068 
0069 /* gpio1 */
0070 static struct resource omap16xx_gpio1_resources[] = {
0071     {
0072         .start  = OMAP1610_GPIO1_BASE,
0073         .end    = OMAP1610_GPIO1_BASE + SZ_2K - 1,
0074         .flags  = IORESOURCE_MEM,
0075     },
0076     {
0077         .start  = INT_GPIO_BANK1,
0078         .flags  = IORESOURCE_IRQ,
0079     },
0080 };
0081 
0082 static struct omap_gpio_reg_offs omap16xx_gpio_regs = {
0083     .revision       = OMAP1610_GPIO_REVISION,
0084     .direction  = OMAP1610_GPIO_DIRECTION,
0085     .set_dataout    = OMAP1610_GPIO_SET_DATAOUT,
0086     .clr_dataout    = OMAP1610_GPIO_CLEAR_DATAOUT,
0087     .datain     = OMAP1610_GPIO_DATAIN,
0088     .dataout    = OMAP1610_GPIO_DATAOUT,
0089     .irqstatus  = OMAP1610_GPIO_IRQSTATUS1,
0090     .irqenable  = OMAP1610_GPIO_IRQENABLE1,
0091     .set_irqenable  = OMAP1610_GPIO_SET_IRQENABLE1,
0092     .clr_irqenable  = OMAP1610_GPIO_CLEAR_IRQENABLE1,
0093     .wkup_en    = OMAP1610_GPIO_WAKEUPENABLE,
0094     .edgectrl1  = OMAP1610_GPIO_EDGE_CTRL1,
0095     .edgectrl2  = OMAP1610_GPIO_EDGE_CTRL2,
0096 };
0097 
0098 static struct omap_gpio_platform_data omap16xx_gpio1_config = {
0099     .bank_width     = 16,
0100     .regs                   = &omap16xx_gpio_regs,
0101 };
0102 
0103 static struct platform_device omap16xx_gpio1 = {
0104     .name           = "omap_gpio",
0105     .id             = 1,
0106     .dev            = {
0107         .platform_data = &omap16xx_gpio1_config,
0108     },
0109     .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
0110     .resource = omap16xx_gpio1_resources,
0111 };
0112 
0113 /* gpio2 */
0114 static struct resource omap16xx_gpio2_resources[] = {
0115     {
0116         .start  = OMAP1610_GPIO2_BASE,
0117         .end    = OMAP1610_GPIO2_BASE + SZ_2K - 1,
0118         .flags  = IORESOURCE_MEM,
0119     },
0120     {
0121         .start  = INT_1610_GPIO_BANK2,
0122         .flags  = IORESOURCE_IRQ,
0123     },
0124 };
0125 
0126 static struct omap_gpio_platform_data omap16xx_gpio2_config = {
0127     .bank_width     = 16,
0128     .regs                   = &omap16xx_gpio_regs,
0129 };
0130 
0131 static struct platform_device omap16xx_gpio2 = {
0132     .name           = "omap_gpio",
0133     .id             = 2,
0134     .dev            = {
0135         .platform_data = &omap16xx_gpio2_config,
0136     },
0137     .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
0138     .resource = omap16xx_gpio2_resources,
0139 };
0140 
0141 /* gpio3 */
0142 static struct resource omap16xx_gpio3_resources[] = {
0143     {
0144         .start  = OMAP1610_GPIO3_BASE,
0145         .end    = OMAP1610_GPIO3_BASE + SZ_2K - 1,
0146         .flags  = IORESOURCE_MEM,
0147     },
0148     {
0149         .start  = INT_1610_GPIO_BANK3,
0150         .flags  = IORESOURCE_IRQ,
0151     },
0152 };
0153 
0154 static struct omap_gpio_platform_data omap16xx_gpio3_config = {
0155     .bank_width     = 16,
0156     .regs                   = &omap16xx_gpio_regs,
0157 };
0158 
0159 static struct platform_device omap16xx_gpio3 = {
0160     .name           = "omap_gpio",
0161     .id             = 3,
0162     .dev            = {
0163         .platform_data = &omap16xx_gpio3_config,
0164     },
0165     .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
0166     .resource = omap16xx_gpio3_resources,
0167 };
0168 
0169 /* gpio4 */
0170 static struct resource omap16xx_gpio4_resources[] = {
0171     {
0172         .start  = OMAP1610_GPIO4_BASE,
0173         .end    = OMAP1610_GPIO4_BASE + SZ_2K - 1,
0174         .flags  = IORESOURCE_MEM,
0175     },
0176     {
0177         .start  = INT_1610_GPIO_BANK4,
0178         .flags  = IORESOURCE_IRQ,
0179     },
0180 };
0181 
0182 static struct omap_gpio_platform_data omap16xx_gpio4_config = {
0183     .bank_width     = 16,
0184     .regs                   = &omap16xx_gpio_regs,
0185 };
0186 
0187 static struct platform_device omap16xx_gpio4 = {
0188     .name           = "omap_gpio",
0189     .id             = 4,
0190     .dev            = {
0191         .platform_data = &omap16xx_gpio4_config,
0192     },
0193     .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
0194     .resource = omap16xx_gpio4_resources,
0195 };
0196 
0197 static struct platform_device *omap16xx_gpio_dev[] __initdata = {
0198     &omap16xx_mpu_gpio,
0199     &omap16xx_gpio1,
0200     &omap16xx_gpio2,
0201     &omap16xx_gpio3,
0202     &omap16xx_gpio4,
0203 };
0204 
0205 /*
0206  * omap16xx_gpio_init needs to be done before
0207  * machine_init functions access gpio APIs.
0208  * Hence omap16xx_gpio_init is a postcore_initcall.
0209  */
0210 static int __init omap16xx_gpio_init(void)
0211 {
0212     int i;
0213     void __iomem *base;
0214     struct resource *res;
0215     struct platform_device *pdev;
0216     struct omap_gpio_platform_data *pdata;
0217 
0218     if (!cpu_is_omap16xx())
0219         return -EINVAL;
0220 
0221     /*
0222      * Enable system clock for GPIO module.
0223      * The CAM_CLK_CTRL *is* really the right place.
0224      */
0225     omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
0226                     ULPD_CAM_CLK_CTRL);
0227 
0228     for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
0229         pdev = omap16xx_gpio_dev[i];
0230         pdata = pdev->dev.platform_data;
0231 
0232         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0233         if (unlikely(!res)) {
0234             dev_err(&pdev->dev, "Invalid mem resource.\n");
0235             return -ENODEV;
0236         }
0237 
0238         base = ioremap(res->start, resource_size(res));
0239         if (unlikely(!base)) {
0240             dev_err(&pdev->dev, "ioremap failed.\n");
0241             return -ENOMEM;
0242         }
0243 
0244         __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG);
0245         iounmap(base);
0246 
0247         platform_device_register(omap16xx_gpio_dev[i]);
0248     }
0249 
0250     return 0;
0251 }
0252 postcore_initcall(omap16xx_gpio_init);