1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * OMAP16xx specific gpio init 4 * 5 * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ 6 * 7 * Author: 8 * Charulatha V <charu@ti.com> 9 */ 10 11 #include <linux/gpio.h> 12 #include <linux/platform_data/gpio-omap.h> 13 #include <linux/soc/ti/omap1-io.h> 14 15 #include "hardware.h" 16 #include "irqs.h" 17 #include "soc.h" 18 19 #define OMAP1610_GPIO1_BASE 0xfffbe400 20 #define OMAP1610_GPIO2_BASE 0xfffbec00 21 #define OMAP1610_GPIO3_BASE 0xfffbb400 22 #define OMAP1610_GPIO4_BASE 0xfffbbc00 23 #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE 24 25 /* smart idle, enable wakeup */ 26 #define SYSCONFIG_WORD 0x14 27 28 /* mpu gpio */ 29 static struct resource omap16xx_mpu_gpio_resources[] = { 30 { 31 .start = OMAP1_MPUIO_VBASE, 32 .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, 33 .flags = IORESOURCE_MEM, 34 }, 35 { 36 .start = INT_MPUIO, 37 .flags = IORESOURCE_IRQ, 38 }, 39 }; 40 41 static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { 42 .revision = USHRT_MAX, 43 .direction = OMAP_MPUIO_IO_CNTL, 44 .datain = OMAP_MPUIO_INPUT_LATCH, 45 .dataout = OMAP_MPUIO_OUTPUT, 46 .irqstatus = OMAP_MPUIO_GPIO_INT, 47 .irqenable = OMAP_MPUIO_GPIO_MASKIT, 48 .irqenable_inv = true, 49 .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, 50 }; 51 52 static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = { 53 .is_mpuio = true, 54 .bank_width = 16, 55 .bank_stride = 1, 56 .regs = &omap16xx_mpuio_regs, 57 }; 58 59 static struct platform_device omap16xx_mpu_gpio = { 60 .name = "omap_gpio", 61 .id = 0, 62 .dev = { 63 .platform_data = &omap16xx_mpu_gpio_config, 64 }, 65 .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources), 66 .resource = omap16xx_mpu_gpio_resources, 67 }; 68 69 /* gpio1 */ 70 static struct resource omap16xx_gpio1_resources[] = { 71 { 72 .start = OMAP1610_GPIO1_BASE, 73 .end = OMAP1610_GPIO1_BASE + SZ_2K - 1, 74 .flags = IORESOURCE_MEM, 75 }, 76 { 77 .start = INT_GPIO_BANK1, 78 .flags = IORESOURCE_IRQ, 79 }, 80 }; 81 82 static struct omap_gpio_reg_offs omap16xx_gpio_regs = { 83 .revision = OMAP1610_GPIO_REVISION, 84 .direction = OMAP1610_GPIO_DIRECTION, 85 .set_dataout = OMAP1610_GPIO_SET_DATAOUT, 86 .clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT, 87 .datain = OMAP1610_GPIO_DATAIN, 88 .dataout = OMAP1610_GPIO_DATAOUT, 89 .irqstatus = OMAP1610_GPIO_IRQSTATUS1, 90 .irqenable = OMAP1610_GPIO_IRQENABLE1, 91 .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, 92 .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, 93 .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, 94 .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1, 95 .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, 96 }; 97 98 static struct omap_gpio_platform_data omap16xx_gpio1_config = { 99 .bank_width = 16, 100 .regs = &omap16xx_gpio_regs, 101 }; 102 103 static struct platform_device omap16xx_gpio1 = { 104 .name = "omap_gpio", 105 .id = 1, 106 .dev = { 107 .platform_data = &omap16xx_gpio1_config, 108 }, 109 .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources), 110 .resource = omap16xx_gpio1_resources, 111 }; 112 113 /* gpio2 */ 114 static struct resource omap16xx_gpio2_resources[] = { 115 { 116 .start = OMAP1610_GPIO2_BASE, 117 .end = OMAP1610_GPIO2_BASE + SZ_2K - 1, 118 .flags = IORESOURCE_MEM, 119 }, 120 { 121 .start = INT_1610_GPIO_BANK2, 122 .flags = IORESOURCE_IRQ, 123 }, 124 }; 125 126 static struct omap_gpio_platform_data omap16xx_gpio2_config = { 127 .bank_width = 16, 128 .regs = &omap16xx_gpio_regs, 129 }; 130 131 static struct platform_device omap16xx_gpio2 = { 132 .name = "omap_gpio", 133 .id = 2, 134 .dev = { 135 .platform_data = &omap16xx_gpio2_config, 136 }, 137 .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources), 138 .resource = omap16xx_gpio2_resources, 139 }; 140 141 /* gpio3 */ 142 static struct resource omap16xx_gpio3_resources[] = { 143 { 144 .start = OMAP1610_GPIO3_BASE, 145 .end = OMAP1610_GPIO3_BASE + SZ_2K - 1, 146 .flags = IORESOURCE_MEM, 147 }, 148 { 149 .start = INT_1610_GPIO_BANK3, 150 .flags = IORESOURCE_IRQ, 151 }, 152 }; 153 154 static struct omap_gpio_platform_data omap16xx_gpio3_config = { 155 .bank_width = 16, 156 .regs = &omap16xx_gpio_regs, 157 }; 158 159 static struct platform_device omap16xx_gpio3 = { 160 .name = "omap_gpio", 161 .id = 3, 162 .dev = { 163 .platform_data = &omap16xx_gpio3_config, 164 }, 165 .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources), 166 .resource = omap16xx_gpio3_resources, 167 }; 168 169 /* gpio4 */ 170 static struct resource omap16xx_gpio4_resources[] = { 171 { 172 .start = OMAP1610_GPIO4_BASE, 173 .end = OMAP1610_GPIO4_BASE + SZ_2K - 1, 174 .flags = IORESOURCE_MEM, 175 }, 176 { 177 .start = INT_1610_GPIO_BANK4, 178 .flags = IORESOURCE_IRQ, 179 }, 180 }; 181 182 static struct omap_gpio_platform_data omap16xx_gpio4_config = { 183 .bank_width = 16, 184 .regs = &omap16xx_gpio_regs, 185 }; 186 187 static struct platform_device omap16xx_gpio4 = { 188 .name = "omap_gpio", 189 .id = 4, 190 .dev = { 191 .platform_data = &omap16xx_gpio4_config, 192 }, 193 .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources), 194 .resource = omap16xx_gpio4_resources, 195 }; 196 197 static struct platform_device *omap16xx_gpio_dev[] __initdata = { 198 &omap16xx_mpu_gpio, 199 &omap16xx_gpio1, 200 &omap16xx_gpio2, 201 &omap16xx_gpio3, 202 &omap16xx_gpio4, 203 }; 204 205 /* 206 * omap16xx_gpio_init needs to be done before 207 * machine_init functions access gpio APIs. 208 * Hence omap16xx_gpio_init is a postcore_initcall. 209 */ 210 static int __init omap16xx_gpio_init(void) 211 { 212 int i; 213 void __iomem *base; 214 struct resource *res; 215 struct platform_device *pdev; 216 struct omap_gpio_platform_data *pdata; 217 218 if (!cpu_is_omap16xx()) 219 return -EINVAL; 220 221 /* 222 * Enable system clock for GPIO module. 223 * The CAM_CLK_CTRL *is* really the right place. 224 */ 225 omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, 226 ULPD_CAM_CLK_CTRL); 227 228 for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) { 229 pdev = omap16xx_gpio_dev[i]; 230 pdata = pdev->dev.platform_data; 231 232 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 233 if (unlikely(!res)) { 234 dev_err(&pdev->dev, "Invalid mem resource.\n"); 235 return -ENODEV; 236 } 237 238 base = ioremap(res->start, resource_size(res)); 239 if (unlikely(!base)) { 240 dev_err(&pdev->dev, "ioremap failed.\n"); 241 return -ENOMEM; 242 } 243 244 __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG); 245 iounmap(base); 246 247 platform_device_register(omap16xx_gpio_dev[i]); 248 } 249 250 return 0; 251 } 252 postcore_initcall(omap16xx_gpio_init); 253