18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * OMAP16xx specific gpio init 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Author: 78c2ecf20Sopenharmony_ci * Charulatha V <charu@ti.com> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or 108c2ecf20Sopenharmony_ci * modify it under the terms of the GNU General Public License as 118c2ecf20Sopenharmony_ci * published by the Free Software Foundation version 2. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * This program is distributed "as is" WITHOUT ANY WARRANTY of any 148c2ecf20Sopenharmony_ci * kind, whether express or implied; without even the implied warranty 158c2ecf20Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 168c2ecf20Sopenharmony_ci * GNU General Public License for more details. 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include <linux/gpio.h> 208c2ecf20Sopenharmony_ci#include <linux/platform_data/gpio-omap.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <mach/irqs.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include "soc.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define OMAP1610_GPIO1_BASE 0xfffbe400 278c2ecf20Sopenharmony_ci#define OMAP1610_GPIO2_BASE 0xfffbec00 288c2ecf20Sopenharmony_ci#define OMAP1610_GPIO3_BASE 0xfffbb400 298c2ecf20Sopenharmony_ci#define OMAP1610_GPIO4_BASE 0xfffbbc00 308c2ecf20Sopenharmony_ci#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* smart idle, enable wakeup */ 338c2ecf20Sopenharmony_ci#define SYSCONFIG_WORD 0x14 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* mpu gpio */ 368c2ecf20Sopenharmony_cistatic struct resource omap16xx_mpu_gpio_resources[] = { 378c2ecf20Sopenharmony_ci { 388c2ecf20Sopenharmony_ci .start = OMAP1_MPUIO_VBASE, 398c2ecf20Sopenharmony_ci .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, 408c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 418c2ecf20Sopenharmony_ci }, 428c2ecf20Sopenharmony_ci { 438c2ecf20Sopenharmony_ci .start = INT_MPUIO, 448c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 458c2ecf20Sopenharmony_ci }, 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic struct omap_gpio_reg_offs omap16xx_mpuio_regs = { 498c2ecf20Sopenharmony_ci .revision = USHRT_MAX, 508c2ecf20Sopenharmony_ci .direction = OMAP_MPUIO_IO_CNTL, 518c2ecf20Sopenharmony_ci .datain = OMAP_MPUIO_INPUT_LATCH, 528c2ecf20Sopenharmony_ci .dataout = OMAP_MPUIO_OUTPUT, 538c2ecf20Sopenharmony_ci .irqstatus = OMAP_MPUIO_GPIO_INT, 548c2ecf20Sopenharmony_ci .irqenable = OMAP_MPUIO_GPIO_MASKIT, 558c2ecf20Sopenharmony_ci .irqenable_inv = true, 568c2ecf20Sopenharmony_ci .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic struct omap_gpio_platform_data omap16xx_mpu_gpio_config = { 608c2ecf20Sopenharmony_ci .is_mpuio = true, 618c2ecf20Sopenharmony_ci .bank_width = 16, 628c2ecf20Sopenharmony_ci .bank_stride = 1, 638c2ecf20Sopenharmony_ci .regs = &omap16xx_mpuio_regs, 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic struct platform_device omap16xx_mpu_gpio = { 678c2ecf20Sopenharmony_ci .name = "omap_gpio", 688c2ecf20Sopenharmony_ci .id = 0, 698c2ecf20Sopenharmony_ci .dev = { 708c2ecf20Sopenharmony_ci .platform_data = &omap16xx_mpu_gpio_config, 718c2ecf20Sopenharmony_ci }, 728c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources), 738c2ecf20Sopenharmony_ci .resource = omap16xx_mpu_gpio_resources, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* gpio1 */ 778c2ecf20Sopenharmony_cistatic struct resource omap16xx_gpio1_resources[] = { 788c2ecf20Sopenharmony_ci { 798c2ecf20Sopenharmony_ci .start = OMAP1610_GPIO1_BASE, 808c2ecf20Sopenharmony_ci .end = OMAP1610_GPIO1_BASE + SZ_2K - 1, 818c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 828c2ecf20Sopenharmony_ci }, 838c2ecf20Sopenharmony_ci { 848c2ecf20Sopenharmony_ci .start = INT_GPIO_BANK1, 858c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 868c2ecf20Sopenharmony_ci }, 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic struct omap_gpio_reg_offs omap16xx_gpio_regs = { 908c2ecf20Sopenharmony_ci .revision = OMAP1610_GPIO_REVISION, 918c2ecf20Sopenharmony_ci .direction = OMAP1610_GPIO_DIRECTION, 928c2ecf20Sopenharmony_ci .set_dataout = OMAP1610_GPIO_SET_DATAOUT, 938c2ecf20Sopenharmony_ci .clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT, 948c2ecf20Sopenharmony_ci .datain = OMAP1610_GPIO_DATAIN, 958c2ecf20Sopenharmony_ci .dataout = OMAP1610_GPIO_DATAOUT, 968c2ecf20Sopenharmony_ci .irqstatus = OMAP1610_GPIO_IRQSTATUS1, 978c2ecf20Sopenharmony_ci .irqenable = OMAP1610_GPIO_IRQENABLE1, 988c2ecf20Sopenharmony_ci .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, 998c2ecf20Sopenharmony_ci .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, 1008c2ecf20Sopenharmony_ci .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, 1018c2ecf20Sopenharmony_ci .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1, 1028c2ecf20Sopenharmony_ci .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic struct omap_gpio_platform_data omap16xx_gpio1_config = { 1068c2ecf20Sopenharmony_ci .bank_width = 16, 1078c2ecf20Sopenharmony_ci .regs = &omap16xx_gpio_regs, 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic struct platform_device omap16xx_gpio1 = { 1118c2ecf20Sopenharmony_ci .name = "omap_gpio", 1128c2ecf20Sopenharmony_ci .id = 1, 1138c2ecf20Sopenharmony_ci .dev = { 1148c2ecf20Sopenharmony_ci .platform_data = &omap16xx_gpio1_config, 1158c2ecf20Sopenharmony_ci }, 1168c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources), 1178c2ecf20Sopenharmony_ci .resource = omap16xx_gpio1_resources, 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* gpio2 */ 1218c2ecf20Sopenharmony_cistatic struct resource omap16xx_gpio2_resources[] = { 1228c2ecf20Sopenharmony_ci { 1238c2ecf20Sopenharmony_ci .start = OMAP1610_GPIO2_BASE, 1248c2ecf20Sopenharmony_ci .end = OMAP1610_GPIO2_BASE + SZ_2K - 1, 1258c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1268c2ecf20Sopenharmony_ci }, 1278c2ecf20Sopenharmony_ci { 1288c2ecf20Sopenharmony_ci .start = INT_1610_GPIO_BANK2, 1298c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1308c2ecf20Sopenharmony_ci }, 1318c2ecf20Sopenharmony_ci}; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic struct omap_gpio_platform_data omap16xx_gpio2_config = { 1348c2ecf20Sopenharmony_ci .bank_width = 16, 1358c2ecf20Sopenharmony_ci .regs = &omap16xx_gpio_regs, 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic struct platform_device omap16xx_gpio2 = { 1398c2ecf20Sopenharmony_ci .name = "omap_gpio", 1408c2ecf20Sopenharmony_ci .id = 2, 1418c2ecf20Sopenharmony_ci .dev = { 1428c2ecf20Sopenharmony_ci .platform_data = &omap16xx_gpio2_config, 1438c2ecf20Sopenharmony_ci }, 1448c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources), 1458c2ecf20Sopenharmony_ci .resource = omap16xx_gpio2_resources, 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* gpio3 */ 1498c2ecf20Sopenharmony_cistatic struct resource omap16xx_gpio3_resources[] = { 1508c2ecf20Sopenharmony_ci { 1518c2ecf20Sopenharmony_ci .start = OMAP1610_GPIO3_BASE, 1528c2ecf20Sopenharmony_ci .end = OMAP1610_GPIO3_BASE + SZ_2K - 1, 1538c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1548c2ecf20Sopenharmony_ci }, 1558c2ecf20Sopenharmony_ci { 1568c2ecf20Sopenharmony_ci .start = INT_1610_GPIO_BANK3, 1578c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1588c2ecf20Sopenharmony_ci }, 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic struct omap_gpio_platform_data omap16xx_gpio3_config = { 1628c2ecf20Sopenharmony_ci .bank_width = 16, 1638c2ecf20Sopenharmony_ci .regs = &omap16xx_gpio_regs, 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic struct platform_device omap16xx_gpio3 = { 1678c2ecf20Sopenharmony_ci .name = "omap_gpio", 1688c2ecf20Sopenharmony_ci .id = 3, 1698c2ecf20Sopenharmony_ci .dev = { 1708c2ecf20Sopenharmony_ci .platform_data = &omap16xx_gpio3_config, 1718c2ecf20Sopenharmony_ci }, 1728c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources), 1738c2ecf20Sopenharmony_ci .resource = omap16xx_gpio3_resources, 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/* gpio4 */ 1778c2ecf20Sopenharmony_cistatic struct resource omap16xx_gpio4_resources[] = { 1788c2ecf20Sopenharmony_ci { 1798c2ecf20Sopenharmony_ci .start = OMAP1610_GPIO4_BASE, 1808c2ecf20Sopenharmony_ci .end = OMAP1610_GPIO4_BASE + SZ_2K - 1, 1818c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1828c2ecf20Sopenharmony_ci }, 1838c2ecf20Sopenharmony_ci { 1848c2ecf20Sopenharmony_ci .start = INT_1610_GPIO_BANK4, 1858c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1868c2ecf20Sopenharmony_ci }, 1878c2ecf20Sopenharmony_ci}; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic struct omap_gpio_platform_data omap16xx_gpio4_config = { 1908c2ecf20Sopenharmony_ci .bank_width = 16, 1918c2ecf20Sopenharmony_ci .regs = &omap16xx_gpio_regs, 1928c2ecf20Sopenharmony_ci}; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cistatic struct platform_device omap16xx_gpio4 = { 1958c2ecf20Sopenharmony_ci .name = "omap_gpio", 1968c2ecf20Sopenharmony_ci .id = 4, 1978c2ecf20Sopenharmony_ci .dev = { 1988c2ecf20Sopenharmony_ci .platform_data = &omap16xx_gpio4_config, 1998c2ecf20Sopenharmony_ci }, 2008c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources), 2018c2ecf20Sopenharmony_ci .resource = omap16xx_gpio4_resources, 2028c2ecf20Sopenharmony_ci}; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic struct platform_device *omap16xx_gpio_dev[] __initdata = { 2058c2ecf20Sopenharmony_ci &omap16xx_mpu_gpio, 2068c2ecf20Sopenharmony_ci &omap16xx_gpio1, 2078c2ecf20Sopenharmony_ci &omap16xx_gpio2, 2088c2ecf20Sopenharmony_ci &omap16xx_gpio3, 2098c2ecf20Sopenharmony_ci &omap16xx_gpio4, 2108c2ecf20Sopenharmony_ci}; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci/* 2138c2ecf20Sopenharmony_ci * omap16xx_gpio_init needs to be done before 2148c2ecf20Sopenharmony_ci * machine_init functions access gpio APIs. 2158c2ecf20Sopenharmony_ci * Hence omap16xx_gpio_init is a postcore_initcall. 2168c2ecf20Sopenharmony_ci */ 2178c2ecf20Sopenharmony_cistatic int __init omap16xx_gpio_init(void) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci int i; 2208c2ecf20Sopenharmony_ci void __iomem *base; 2218c2ecf20Sopenharmony_ci struct resource *res; 2228c2ecf20Sopenharmony_ci struct platform_device *pdev; 2238c2ecf20Sopenharmony_ci struct omap_gpio_platform_data *pdata; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci if (!cpu_is_omap16xx()) 2268c2ecf20Sopenharmony_ci return -EINVAL; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci /* 2298c2ecf20Sopenharmony_ci * Enable system clock for GPIO module. 2308c2ecf20Sopenharmony_ci * The CAM_CLK_CTRL *is* really the right place. 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_ci omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, 2338c2ecf20Sopenharmony_ci ULPD_CAM_CLK_CTRL); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) { 2368c2ecf20Sopenharmony_ci pdev = omap16xx_gpio_dev[i]; 2378c2ecf20Sopenharmony_ci pdata = pdev->dev.platform_data; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2408c2ecf20Sopenharmony_ci if (unlikely(!res)) { 2418c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Invalid mem resource.\n"); 2428c2ecf20Sopenharmony_ci return -ENODEV; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci base = ioremap(res->start, resource_size(res)); 2468c2ecf20Sopenharmony_ci if (unlikely(!base)) { 2478c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "ioremap failed.\n"); 2488c2ecf20Sopenharmony_ci return -ENOMEM; 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG); 2528c2ecf20Sopenharmony_ci iounmap(base); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci platform_device_register(omap16xx_gpio_dev[i]); 2558c2ecf20Sopenharmony_ci } 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci return 0; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_cipostcore_initcall(omap16xx_gpio_init); 260