diff options
30 files changed, 2192 insertions, 627 deletions
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index aa53ee22438f..513d6abec1f5 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * arch/arm/mach-u300/core.c | 3 | * arch/arm/mach-u300/core.c |
| 4 | * | 4 | * |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2007-2010 ST-Ericsson AB | 6 | * Copyright (C) 2007-2010 ST-Ericsson SA |
| 7 | * License terms: GNU General Public License (GPL) version 2 | 7 | * License terms: GNU General Public License (GPL) version 2 |
| 8 | * Core platform support, IRQ handling and device definitions. | 8 | * Core platform support, IRQ handling and device definitions. |
| 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
| @@ -16,7 +16,9 @@ | |||
| 16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/termios.h> | 18 | #include <linux/termios.h> |
| 19 | #include <linux/dmaengine.h> | ||
| 19 | #include <linux/amba/bus.h> | 20 | #include <linux/amba/bus.h> |
| 21 | #include <linux/amba/serial.h> | ||
| 20 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 21 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
| 22 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| @@ -96,10 +98,20 @@ void __init u300_map_io(void) | |||
| 96 | * Declaration of devices found on the U300 board and | 98 | * Declaration of devices found on the U300 board and |
| 97 | * their respective memory locations. | 99 | * their respective memory locations. |
| 98 | */ | 100 | */ |
| 101 | |||
| 102 | static struct amba_pl011_data uart0_plat_data = { | ||
| 103 | #ifdef CONFIG_COH901318 | ||
| 104 | .dma_filter = coh901318_filter_id, | ||
| 105 | .dma_rx_param = (void *) U300_DMA_UART0_RX, | ||
| 106 | .dma_tx_param = (void *) U300_DMA_UART0_TX, | ||
| 107 | #endif | ||
| 108 | }; | ||
| 109 | |||
| 99 | static struct amba_device uart0_device = { | 110 | static struct amba_device uart0_device = { |
| 100 | .dev = { | 111 | .dev = { |
| 112 | .coherent_dma_mask = ~0, | ||
| 101 | .init_name = "uart0", /* Slow device at 0x3000 offset */ | 113 | .init_name = "uart0", /* Slow device at 0x3000 offset */ |
| 102 | .platform_data = NULL, | 114 | .platform_data = &uart0_plat_data, |
| 103 | }, | 115 | }, |
| 104 | .res = { | 116 | .res = { |
| 105 | .start = U300_UART0_BASE, | 117 | .start = U300_UART0_BASE, |
| @@ -111,10 +123,19 @@ static struct amba_device uart0_device = { | |||
| 111 | 123 | ||
| 112 | /* The U335 have an additional UART1 on the APP CPU */ | 124 | /* The U335 have an additional UART1 on the APP CPU */ |
| 113 | #ifdef CONFIG_MACH_U300_BS335 | 125 | #ifdef CONFIG_MACH_U300_BS335 |
| 126 | static struct amba_pl011_data uart1_plat_data = { | ||
| 127 | #ifdef CONFIG_COH901318 | ||
| 128 | .dma_filter = coh901318_filter_id, | ||
| 129 | .dma_rx_param = (void *) U300_DMA_UART1_RX, | ||
| 130 | .dma_tx_param = (void *) U300_DMA_UART1_TX, | ||
| 131 | #endif | ||
| 132 | }; | ||
| 133 | |||
| 114 | static struct amba_device uart1_device = { | 134 | static struct amba_device uart1_device = { |
| 115 | .dev = { | 135 | .dev = { |
| 136 | .coherent_dma_mask = ~0, | ||
| 116 | .init_name = "uart1", /* Fast device at 0x7000 offset */ | 137 | .init_name = "uart1", /* Fast device at 0x7000 offset */ |
| 117 | .platform_data = NULL, | 138 | .platform_data = &uart1_plat_data, |
| 118 | }, | 139 | }, |
| 119 | .res = { | 140 | .res = { |
| 120 | .start = U300_UART1_BASE, | 141 | .start = U300_UART1_BASE, |
| @@ -960,42 +981,37 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
| 960 | .priority_high = 0, | 981 | .priority_high = 0, |
| 961 | .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220, | 982 | .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220, |
| 962 | }, | 983 | }, |
| 984 | /* | ||
| 985 | * Don't set up device address, burst count or size of src | ||
| 986 | * or dst bus for this peripheral - handled by PrimeCell | ||
| 987 | * DMA extension. | ||
| 988 | */ | ||
| 963 | { | 989 | { |
| 964 | .number = U300_DMA_MMCSD_RX_TX, | 990 | .number = U300_DMA_MMCSD_RX_TX, |
| 965 | .name = "MMCSD RX TX", | 991 | .name = "MMCSD RX TX", |
| 966 | .priority_high = 0, | 992 | .priority_high = 0, |
| 967 | .dev_addr = U300_MMCSD_BASE + 0x080, | ||
| 968 | .param.config = COH901318_CX_CFG_CH_DISABLE | | 993 | .param.config = COH901318_CX_CFG_CH_DISABLE | |
| 969 | COH901318_CX_CFG_LCR_DISABLE | | 994 | COH901318_CX_CFG_LCR_DISABLE | |
| 970 | COH901318_CX_CFG_TC_IRQ_ENABLE | | 995 | COH901318_CX_CFG_TC_IRQ_ENABLE | |
| 971 | COH901318_CX_CFG_BE_IRQ_ENABLE, | 996 | COH901318_CX_CFG_BE_IRQ_ENABLE, |
| 972 | .param.ctrl_lli_chained = 0 | | 997 | .param.ctrl_lli_chained = 0 | |
| 973 | COH901318_CX_CTRL_TC_ENABLE | | 998 | COH901318_CX_CTRL_TC_ENABLE | |
| 974 | COH901318_CX_CTRL_BURST_COUNT_32_BYTES | | ||
| 975 | COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | | ||
| 976 | COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | | ||
| 977 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 999 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
| 978 | COH901318_CX_CTRL_TCP_ENABLE | | 1000 | COH901318_CX_CTRL_TCP_ENABLE | |
| 979 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1001 | COH901318_CX_CTRL_TC_IRQ_DISABLE | |
| 980 | COH901318_CX_CTRL_HSP_ENABLE | | 1002 | COH901318_CX_CTRL_HSP_ENABLE | |
| 981 | COH901318_CX_CTRL_HSS_DISABLE | | 1003 | COH901318_CX_CTRL_HSS_DISABLE | |
| 982 | COH901318_CX_CTRL_DDMA_LEGACY, | 1004 | COH901318_CX_CTRL_DDMA_LEGACY, |
| 983 | .param.ctrl_lli = 0 | | 1005 | .param.ctrl_lli = 0 | |
| 984 | COH901318_CX_CTRL_TC_ENABLE | | 1006 | COH901318_CX_CTRL_TC_ENABLE | |
| 985 | COH901318_CX_CTRL_BURST_COUNT_32_BYTES | | ||
| 986 | COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | | ||
| 987 | COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | | ||
| 988 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 1007 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
| 989 | COH901318_CX_CTRL_TCP_ENABLE | | 1008 | COH901318_CX_CTRL_TCP_ENABLE | |
| 990 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1009 | COH901318_CX_CTRL_TC_IRQ_DISABLE | |
| 991 | COH901318_CX_CTRL_HSP_ENABLE | | 1010 | COH901318_CX_CTRL_HSP_ENABLE | |
| 992 | COH901318_CX_CTRL_HSS_DISABLE | | 1011 | COH901318_CX_CTRL_HSS_DISABLE | |
| 993 | COH901318_CX_CTRL_DDMA_LEGACY, | 1012 | COH901318_CX_CTRL_DDMA_LEGACY, |
| 994 | .param.ctrl_lli_last = 0 | | 1013 | .param.ctrl_lli_last = 0 | |
| 995 | COH901318_CX_CTRL_TC_ENABLE | | 1014 | COH901318_CX_CTRL_TC_ENABLE | |
| 996 | COH901318_CX_CTRL_BURST_COUNT_32_BYTES | | ||
| 997 | COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | | ||
| 998 | COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | | ||
| 999 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 1015 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
| 1000 | COH901318_CX_CTRL_TCP_DISABLE | | 1016 | COH901318_CX_CTRL_TCP_DISABLE | |
| 1001 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1017 | COH901318_CX_CTRL_TC_IRQ_ENABLE | |
| @@ -1014,15 +1030,76 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
| 1014 | .name = "MSPRO RX", | 1030 | .name = "MSPRO RX", |
| 1015 | .priority_high = 0, | 1031 | .priority_high = 0, |
| 1016 | }, | 1032 | }, |
| 1033 | /* | ||
| 1034 | * Don't set up device address, burst count or size of src | ||
| 1035 | * or dst bus for this peripheral - handled by PrimeCell | ||
| 1036 | * DMA extension. | ||
| 1037 | */ | ||
| 1017 | { | 1038 | { |
| 1018 | .number = U300_DMA_UART0_TX, | 1039 | .number = U300_DMA_UART0_TX, |
| 1019 | .name = "UART0 TX", | 1040 | .name = "UART0 TX", |
| 1020 | .priority_high = 0, | 1041 | .priority_high = 0, |
| 1042 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
| 1043 | COH901318_CX_CFG_LCR_DISABLE | | ||
| 1044 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
| 1045 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
| 1046 | .param.ctrl_lli_chained = 0 | | ||
| 1047 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1048 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1049 | COH901318_CX_CTRL_TCP_ENABLE | | ||
| 1050 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
| 1051 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1052 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1053 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1054 | .param.ctrl_lli = 0 | | ||
| 1055 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1056 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1057 | COH901318_CX_CTRL_TCP_ENABLE | | ||
| 1058 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1059 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1060 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1061 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1062 | .param.ctrl_lli_last = 0 | | ||
| 1063 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1064 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1065 | COH901318_CX_CTRL_TCP_ENABLE | | ||
| 1066 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1067 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1068 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1069 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1021 | }, | 1070 | }, |
| 1022 | { | 1071 | { |
| 1023 | .number = U300_DMA_UART0_RX, | 1072 | .number = U300_DMA_UART0_RX, |
| 1024 | .name = "UART0 RX", | 1073 | .name = "UART0 RX", |
| 1025 | .priority_high = 0, | 1074 | .priority_high = 0, |
| 1075 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
| 1076 | COH901318_CX_CFG_LCR_DISABLE | | ||
| 1077 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
| 1078 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
| 1079 | .param.ctrl_lli_chained = 0 | | ||
| 1080 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1081 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1082 | COH901318_CX_CTRL_TCP_ENABLE | | ||
| 1083 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
| 1084 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1085 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1086 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1087 | .param.ctrl_lli = 0 | | ||
| 1088 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1089 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1090 | COH901318_CX_CTRL_TCP_ENABLE | | ||
| 1091 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1092 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1093 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1094 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1095 | .param.ctrl_lli_last = 0 | | ||
| 1096 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1097 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1098 | COH901318_CX_CTRL_TCP_ENABLE | | ||
| 1099 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1100 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1101 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1102 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1026 | }, | 1103 | }, |
| 1027 | { | 1104 | { |
| 1028 | .number = U300_DMA_APEX_TX, | 1105 | .number = U300_DMA_APEX_TX, |
| @@ -1080,7 +1157,7 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
| 1080 | COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | | 1157 | COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | |
| 1081 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 1158 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
| 1082 | COH901318_CX_CTRL_TCP_ENABLE | | 1159 | COH901318_CX_CTRL_TCP_ENABLE | |
| 1083 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1160 | COH901318_CX_CTRL_TC_IRQ_DISABLE | |
| 1084 | COH901318_CX_CTRL_HSP_ENABLE | | 1161 | COH901318_CX_CTRL_HSP_ENABLE | |
| 1085 | COH901318_CX_CTRL_HSS_DISABLE | | 1162 | COH901318_CX_CTRL_HSS_DISABLE | |
| 1086 | COH901318_CX_CTRL_DDMA_LEGACY | | 1163 | COH901318_CX_CTRL_DDMA_LEGACY | |
| @@ -1252,15 +1329,77 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
| 1252 | .name = "XGAM PDI", | 1329 | .name = "XGAM PDI", |
| 1253 | .priority_high = 0, | 1330 | .priority_high = 0, |
| 1254 | }, | 1331 | }, |
| 1332 | /* | ||
| 1333 | * Don't set up device address, burst count or size of src | ||
| 1334 | * or dst bus for this peripheral - handled by PrimeCell | ||
| 1335 | * DMA extension. | ||
| 1336 | */ | ||
| 1255 | { | 1337 | { |
| 1256 | .number = U300_DMA_SPI_TX, | 1338 | .number = U300_DMA_SPI_TX, |
| 1257 | .name = "SPI TX", | 1339 | .name = "SPI TX", |
| 1258 | .priority_high = 0, | 1340 | .priority_high = 0, |
| 1341 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
| 1342 | COH901318_CX_CFG_LCR_DISABLE | | ||
| 1343 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
| 1344 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
| 1345 | .param.ctrl_lli_chained = 0 | | ||
| 1346 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1347 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1348 | COH901318_CX_CTRL_TCP_DISABLE | | ||
| 1349 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
| 1350 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1351 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1352 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1353 | .param.ctrl_lli = 0 | | ||
| 1354 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1355 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1356 | COH901318_CX_CTRL_TCP_DISABLE | | ||
| 1357 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1358 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1359 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1360 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1361 | .param.ctrl_lli_last = 0 | | ||
| 1362 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1363 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1364 | COH901318_CX_CTRL_TCP_DISABLE | | ||
| 1365 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1366 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1367 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1368 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1259 | }, | 1369 | }, |
| 1260 | { | 1370 | { |
| 1261 | .number = U300_DMA_SPI_RX, | 1371 | .number = U300_DMA_SPI_RX, |
| 1262 | .name = "SPI RX", | 1372 | .name = "SPI RX", |
| 1263 | .priority_high = 0, | 1373 | .priority_high = 0, |
| 1374 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
| 1375 | COH901318_CX_CFG_LCR_DISABLE | | ||
| 1376 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
| 1377 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
| 1378 | .param.ctrl_lli_chained = 0 | | ||
| 1379 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1380 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1381 | COH901318_CX_CTRL_TCP_DISABLE | | ||
| 1382 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
| 1383 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1384 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1385 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1386 | .param.ctrl_lli = 0 | | ||
| 1387 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1388 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1389 | COH901318_CX_CTRL_TCP_DISABLE | | ||
| 1390 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1391 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1392 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1393 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1394 | .param.ctrl_lli_last = 0 | | ||
| 1395 | COH901318_CX_CTRL_TC_ENABLE | | ||
| 1396 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
| 1397 | COH901318_CX_CTRL_TCP_DISABLE | | ||
| 1398 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
| 1399 | COH901318_CX_CTRL_HSP_ENABLE | | ||
| 1400 | COH901318_CX_CTRL_HSS_DISABLE | | ||
| 1401 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
| 1402 | |||
| 1264 | }, | 1403 | }, |
| 1265 | { | 1404 | { |
| 1266 | .number = U300_DMA_GENERAL_PURPOSE_0, | 1405 | .number = U300_DMA_GENERAL_PURPOSE_0, |
| @@ -1617,7 +1756,7 @@ static void __init u300_init_check_chip(void) | |||
| 1617 | #endif | 1756 | #endif |
| 1618 | #ifdef CONFIG_MACH_U300_BS335 | 1757 | #ifdef CONFIG_MACH_U300_BS335 |
| 1619 | if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { | 1758 | if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { |
| 1620 | printk(KERN_ERR "Platform configured for BS365 " \ | 1759 | printk(KERN_ERR "Platform configured for BS335 " \ |
| 1621 | " with DB3350 but %s detected, expect problems!", | 1760 | " with DB3350 but %s detected, expect problems!", |
| 1622 | chipname); | 1761 | chipname); |
| 1623 | } | 1762 | } |
| @@ -1692,12 +1831,12 @@ void __init u300_init_devices(void) | |||
| 1692 | /* Register subdevices on the I2C buses */ | 1831 | /* Register subdevices on the I2C buses */ |
| 1693 | u300_i2c_register_board_devices(); | 1832 | u300_i2c_register_board_devices(); |
| 1694 | 1833 | ||
| 1695 | /* Register subdevices on the SPI bus */ | ||
| 1696 | u300_spi_register_board_devices(); | ||
| 1697 | |||
| 1698 | /* Register the platform devices */ | 1834 | /* Register the platform devices */ |
| 1699 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 1835 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
| 1700 | 1836 | ||
| 1837 | /* Register subdevices on the SPI bus */ | ||
| 1838 | u300_spi_register_board_devices(); | ||
| 1839 | |||
| 1701 | #ifndef CONFIG_MACH_U300_SEMI_IS_SHARED | 1840 | #ifndef CONFIG_MACH_U300_SEMI_IS_SHARED |
| 1702 | /* | 1841 | /* |
| 1703 | * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when | 1842 | * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when |
diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 6193aaa47794..7c3b2b2d25b6 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h | |||
| @@ -102,6 +102,7 @@ struct coh901318_platform { | |||
| 102 | const int max_channels; | 102 | const int max_channels; |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | #ifdef CONFIG_COH901318 | ||
| 105 | /** | 106 | /** |
| 106 | * coh901318_filter_id() - DMA channel filter function | 107 | * coh901318_filter_id() - DMA channel filter function |
| 107 | * @chan: dma channel handle | 108 | * @chan: dma channel handle |
| @@ -110,6 +111,12 @@ struct coh901318_platform { | |||
| 110 | * In dma_request_channel() it specifies what channel id to be requested | 111 | * In dma_request_channel() it specifies what channel id to be requested |
| 111 | */ | 112 | */ |
| 112 | bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); | 113 | bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); |
| 114 | #else | ||
| 115 | static inline bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) | ||
| 116 | { | ||
| 117 | return false; | ||
| 118 | } | ||
| 119 | #endif | ||
| 113 | 120 | ||
| 114 | /* | 121 | /* |
| 115 | * DMA Controller - this access the static mappings of the coh901318 dma. | 122 | * DMA Controller - this access the static mappings of the coh901318 dma. |
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index de1ac9ad2213..677ccef5cd32 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c | |||
| @@ -3,159 +3,52 @@ | |||
| 3 | * arch/arm/mach-u300/mmc.c | 3 | * arch/arm/mach-u300/mmc.c |
| 4 | * | 4 | * |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2009 ST-Ericsson AB | 6 | * Copyright (C) 2009 ST-Ericsson SA |
| 7 | * License terms: GNU General Public License (GPL) version 2 | 7 | * License terms: GNU General Public License (GPL) version 2 |
| 8 | * | 8 | * |
| 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
| 10 | * Author: Johan Lundin <johan.lundin@stericsson.com> | 10 | * Author: Johan Lundin |
| 11 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | 11 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> |
| 12 | */ | 12 | */ |
| 13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
| 14 | #include <linux/amba/bus.h> | 14 | #include <linux/amba/bus.h> |
| 15 | #include <linux/mmc/host.h> | 15 | #include <linux/mmc/host.h> |
| 16 | #include <linux/input.h> | ||
| 17 | #include <linux/workqueue.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/regulator/consumer.h> | ||
| 20 | #include <linux/regulator/machine.h> | ||
| 21 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
| 17 | #include <linux/dmaengine.h> | ||
| 22 | #include <linux/amba/mmci.h> | 18 | #include <linux/amba/mmci.h> |
| 23 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <mach/coh901318.h> | ||
| 21 | #include <mach/dma_channels.h> | ||
| 24 | 22 | ||
| 25 | #include "mmc.h" | 23 | #include "mmc.h" |
| 26 | #include "padmux.h" | 24 | #include "padmux.h" |
| 27 | 25 | ||
| 28 | struct mmci_card_event { | 26 | static struct mmci_platform_data mmc0_plat_data = { |
| 29 | struct input_dev *mmc_input; | 27 | /* |
| 30 | int mmc_inserted; | 28 | * Do not set ocr_mask or voltage translation function, |
| 31 | struct work_struct workq; | 29 | * we have a regulator we can control instead. |
| 32 | struct mmci_platform_data mmc0_plat_data; | 30 | */ |
| 31 | /* Nominally 2.85V on our platform */ | ||
| 32 | .f_max = 24000000, | ||
| 33 | .gpio_wp = -1, | ||
| 34 | .gpio_cd = U300_GPIO_PIN_MMC_CD, | ||
| 35 | .cd_invert = true, | ||
| 36 | .capabilities = MMC_CAP_MMC_HIGHSPEED | | ||
| 37 | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, | ||
| 38 | #ifdef CONFIG_COH901318 | ||
| 39 | .dma_filter = coh901318_filter_id, | ||
| 40 | .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX, | ||
| 41 | /* Don't specify a TX channel, this RX channel is bidirectional */ | ||
| 42 | #endif | ||
| 33 | }; | 43 | }; |
| 34 | 44 | ||
| 35 | static unsigned int mmc_status(struct device *dev) | ||
| 36 | { | ||
| 37 | struct mmci_card_event *mmci_card = container_of( | ||
| 38 | dev->platform_data, | ||
| 39 | struct mmci_card_event, mmc0_plat_data); | ||
| 40 | |||
| 41 | return mmci_card->mmc_inserted; | ||
| 42 | } | ||
| 43 | |||
| 44 | static int mmci_callback(void *data) | ||
| 45 | { | ||
| 46 | struct mmci_card_event *mmci_card = data; | ||
| 47 | |||
| 48 | disable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD); | ||
| 49 | schedule_work(&mmci_card->workq); | ||
| 50 | |||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | |||
| 55 | static ssize_t gpio_show(struct device *dev, struct device_attribute *attr, | ||
| 56 | char *buf) | ||
| 57 | { | ||
| 58 | struct mmci_card_event *mmci_card = container_of( | ||
| 59 | dev->platform_data, | ||
| 60 | struct mmci_card_event, mmc0_plat_data); | ||
| 61 | |||
| 62 | |||
| 63 | return sprintf(buf, "%d\n", !mmci_card->mmc_inserted); | ||
| 64 | } | ||
| 65 | |||
| 66 | static DEVICE_ATTR(mmc_inserted, S_IRUGO, gpio_show, NULL); | ||
| 67 | |||
| 68 | static void _mmci_callback(struct work_struct *ws) | ||
| 69 | { | ||
| 70 | |||
| 71 | struct mmci_card_event *mmci_card = container_of( | ||
| 72 | ws, | ||
| 73 | struct mmci_card_event, workq); | ||
| 74 | |||
| 75 | mdelay(20); | ||
| 76 | |||
| 77 | mmci_card->mmc_inserted = !gpio_get_value(U300_GPIO_PIN_MMC_CD); | ||
| 78 | |||
| 79 | input_report_switch(mmci_card->mmc_input, KEY_INSERT, | ||
| 80 | mmci_card->mmc_inserted); | ||
| 81 | input_sync(mmci_card->mmc_input); | ||
| 82 | |||
| 83 | pr_debug("MMC/SD card was %s\n", | ||
| 84 | mmci_card->mmc_inserted ? "inserted" : "removed"); | ||
| 85 | |||
| 86 | enable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD, mmci_card->mmc_inserted); | ||
| 87 | } | ||
| 88 | |||
| 89 | int __devinit mmc_init(struct amba_device *adev) | 45 | int __devinit mmc_init(struct amba_device *adev) |
| 90 | { | 46 | { |
| 91 | struct mmci_card_event *mmci_card; | ||
| 92 | struct device *mmcsd_device = &adev->dev; | 47 | struct device *mmcsd_device = &adev->dev; |
| 93 | struct pmx *pmx; | 48 | struct pmx *pmx; |
| 94 | int ret = 0; | 49 | int ret = 0; |
| 95 | 50 | ||
| 96 | mmci_card = kzalloc(sizeof(struct mmci_card_event), GFP_KERNEL); | 51 | mmcsd_device->platform_data = &mmc0_plat_data; |
| 97 | if (!mmci_card) | ||
| 98 | return -ENOMEM; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Do not set ocr_mask or voltage translation function, | ||
| 102 | * we have a regulator we can control instead. | ||
| 103 | */ | ||
| 104 | /* Nominally 2.85V on our platform */ | ||
| 105 | mmci_card->mmc0_plat_data.f_max = 24000000; | ||
| 106 | mmci_card->mmc0_plat_data.status = mmc_status; | ||
| 107 | mmci_card->mmc0_plat_data.gpio_wp = -1; | ||
| 108 | mmci_card->mmc0_plat_data.gpio_cd = -1; | ||
| 109 | mmci_card->mmc0_plat_data.capabilities = MMC_CAP_MMC_HIGHSPEED | | ||
| 110 | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; | ||
| 111 | |||
| 112 | mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; | ||
| 113 | |||
| 114 | INIT_WORK(&mmci_card->workq, _mmci_callback); | ||
| 115 | |||
| 116 | ret = gpio_request(U300_GPIO_PIN_MMC_CD, "MMC card detection"); | ||
| 117 | if (ret) { | ||
| 118 | printk(KERN_CRIT "Could not allocate MMC card detection " \ | ||
| 119 | "GPIO pin\n"); | ||
| 120 | goto out; | ||
| 121 | } | ||
| 122 | |||
| 123 | ret = gpio_direction_input(U300_GPIO_PIN_MMC_CD); | ||
| 124 | if (ret) { | ||
| 125 | printk(KERN_CRIT "Invalid GPIO pin requested\n"); | ||
| 126 | goto out; | ||
| 127 | } | ||
| 128 | |||
| 129 | ret = sysfs_create_file(&mmcsd_device->kobj, | ||
| 130 | &dev_attr_mmc_inserted.attr); | ||
| 131 | if (ret) | ||
| 132 | goto out; | ||
| 133 | |||
| 134 | mmci_card->mmc_input = input_allocate_device(); | ||
| 135 | if (!mmci_card->mmc_input) { | ||
| 136 | printk(KERN_CRIT "Could not allocate MMC input device\n"); | ||
| 137 | return -ENOMEM; | ||
| 138 | } | ||
| 139 | |||
| 140 | mmci_card->mmc_input->name = "MMC insert notification"; | ||
| 141 | mmci_card->mmc_input->id.bustype = BUS_HOST; | ||
| 142 | mmci_card->mmc_input->id.vendor = 0; | ||
| 143 | mmci_card->mmc_input->id.product = 0; | ||
| 144 | mmci_card->mmc_input->id.version = 0x0100; | ||
| 145 | mmci_card->mmc_input->dev.parent = mmcsd_device; | ||
| 146 | input_set_capability(mmci_card->mmc_input, EV_SW, KEY_INSERT); | ||
| 147 | |||
| 148 | /* | ||
| 149 | * Since this must always be compiled into the kernel, this input | ||
| 150 | * is never unregistered or free:ed. | ||
| 151 | */ | ||
| 152 | ret = input_register_device(mmci_card->mmc_input); | ||
| 153 | if (ret) { | ||
| 154 | input_free_device(mmci_card->mmc_input); | ||
| 155 | goto out; | ||
| 156 | } | ||
| 157 | |||
| 158 | input_set_drvdata(mmci_card->mmc_input, mmci_card); | ||
| 159 | 52 | ||
| 160 | /* | 53 | /* |
| 161 | * Setup padmuxing for MMC. Since this must always be | 54 | * Setup padmuxing for MMC. Since this must always be |
| @@ -171,12 +64,5 @@ int __devinit mmc_init(struct amba_device *adev) | |||
| 171 | pr_warning("Could not activate padmuxing\n"); | 64 | pr_warning("Could not activate padmuxing\n"); |
| 172 | } | 65 | } |
| 173 | 66 | ||
| 174 | ret = gpio_register_callback(U300_GPIO_PIN_MMC_CD, mmci_callback, | ||
| 175 | mmci_card); | ||
| 176 | |||
| 177 | schedule_work(&mmci_card->workq); | ||
| 178 | |||
| 179 | printk(KERN_INFO "Registered MMC insert/remove notification\n"); | ||
| 180 | out: | ||
| 181 | return ret; | 67 | return ret; |
| 182 | } | 68 | } |
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c index 00869def5420..5767208f1c1d 100644 --- a/arch/arm/mach-u300/spi.c +++ b/arch/arm/mach-u300/spi.c | |||
| @@ -11,6 +11,9 @@ | |||
| 11 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
| 12 | #include <linux/amba/pl022.h> | 12 | #include <linux/amba/pl022.h> |
| 13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 14 | #include <mach/coh901318.h> | ||
| 15 | #include <mach/dma_channels.h> | ||
| 16 | |||
| 14 | #include "padmux.h" | 17 | #include "padmux.h" |
| 15 | 18 | ||
| 16 | /* | 19 | /* |
| @@ -30,11 +33,8 @@ static void select_dummy_chip(u32 chipselect) | |||
| 30 | } | 33 | } |
| 31 | 34 | ||
| 32 | struct pl022_config_chip dummy_chip_info = { | 35 | struct pl022_config_chip dummy_chip_info = { |
| 33 | /* | 36 | /* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */ |
| 34 | * available POLLING_TRANSFER and INTERRUPT_TRANSFER, | 37 | .com_mode = DMA_TRANSFER, |
| 35 | * DMA_TRANSFER does not work | ||
| 36 | */ | ||
| 37 | .com_mode = INTERRUPT_TRANSFER, | ||
| 38 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | 38 | .iface = SSP_INTERFACE_MOTOROLA_SPI, |
| 39 | /* We can only act as master but SSP_SLAVE is possible in theory */ | 39 | /* We can only act as master but SSP_SLAVE is possible in theory */ |
| 40 | .hierarchy = SSP_MASTER, | 40 | .hierarchy = SSP_MASTER, |
| @@ -75,8 +75,6 @@ static struct spi_board_info u300_spi_devices[] = { | |||
| 75 | static struct pl022_ssp_controller ssp_platform_data = { | 75 | static struct pl022_ssp_controller ssp_platform_data = { |
| 76 | /* If you have several SPI buses this varies, we have only bus 0 */ | 76 | /* If you have several SPI buses this varies, we have only bus 0 */ |
| 77 | .bus_id = 0, | 77 | .bus_id = 0, |
| 78 | /* Set this to 1 when we think we got DMA working */ | ||
| 79 | .enable_dma = 0, | ||
| 80 | /* | 78 | /* |
| 81 | * On the APP CPU GPIO 4, 5 and 6 are connected as generic | 79 | * On the APP CPU GPIO 4, 5 and 6 are connected as generic |
| 82 | * chip selects for SPI. (Same on U330, U335 and U365.) | 80 | * chip selects for SPI. (Same on U330, U335 and U365.) |
| @@ -84,6 +82,14 @@ static struct pl022_ssp_controller ssp_platform_data = { | |||
| 84 | * and do padmuxing accordingly too. | 82 | * and do padmuxing accordingly too. |
| 85 | */ | 83 | */ |
| 86 | .num_chipselect = 3, | 84 | .num_chipselect = 3, |
| 85 | #ifdef CONFIG_COH901318 | ||
| 86 | .enable_dma = 1, | ||
| 87 | .dma_filter = coh901318_filter_id, | ||
| 88 | .dma_rx_param = (void *) U300_DMA_SPI_RX, | ||
| 89 | .dma_tx_param = (void *) U300_DMA_SPI_TX, | ||
| 90 | #else | ||
| 91 | .enable_dma = 0, | ||
| 92 | #endif | ||
| 87 | }; | 93 | }; |
| 88 | 94 | ||
| 89 | 95 | ||
| @@ -109,6 +115,7 @@ void __init u300_spi_init(struct amba_device *adev) | |||
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | } | 117 | } |
| 118 | |||
| 112 | void __init u300_spi_register_board_devices(void) | 119 | void __init u300_spi_register_board_devices(void) |
| 113 | { | 120 | { |
| 114 | /* Register any SPI devices */ | 121 | /* Register any SPI devices */ |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 53ebb429e971..b549a8fb4231 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
| @@ -3,16 +3,18 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := clock.o cpu.o devices.o devices-common.o \ | 5 | obj-y := clock.o cpu.o devices.o devices-common.o \ |
| 6 | id.o | 6 | id.o usb.o |
| 7 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o | 7 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o |
| 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o | 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o |
| 9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ | 9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ |
| 10 | board-mop500-keypads.o | 10 | board-mop500-regulators.o \ |
| 11 | board-mop500-uib.o board-mop500-stuib.o \ | ||
| 12 | board-mop500-u8500uib.o \ | ||
| 13 | board-mop500-pins.o | ||
| 11 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o | 14 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o |
| 12 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 15 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
| 13 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 16 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
| 14 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 17 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o |
| 15 | obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o | ||
| 16 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o | 18 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o |
| 17 | obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o | 19 | obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o |
| 18 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | 20 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o |
diff --git a/arch/arm/mach-ux500/board-mop500-keypads.c b/arch/arm/mach-ux500/board-mop500-keypads.c deleted file mode 100644 index 70318c354d32..000000000000 --- a/arch/arm/mach-ux500/board-mop500-keypads.c +++ /dev/null | |||
| @@ -1,229 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * License Terms: GNU General Public License v2 | ||
| 5 | * | ||
| 6 | * Keypad layouts for various boards | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/i2c.h> | ||
| 10 | #include <linux/gpio.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/mfd/stmpe.h> | ||
| 14 | #include <linux/mfd/tc3589x.h> | ||
| 15 | #include <linux/input/matrix_keypad.h> | ||
| 16 | |||
| 17 | #include <plat/pincfg.h> | ||
| 18 | #include <plat/ske.h> | ||
| 19 | |||
| 20 | #include <mach/devices.h> | ||
| 21 | #include <mach/hardware.h> | ||
| 22 | |||
| 23 | #include "devices-db8500.h" | ||
| 24 | #include "board-mop500.h" | ||
| 25 | |||
| 26 | /* STMPE/SKE keypad use this key layout */ | ||
| 27 | static const unsigned int mop500_keymap[] = { | ||
| 28 | KEY(2, 5, KEY_END), | ||
| 29 | KEY(4, 1, KEY_POWER), | ||
| 30 | KEY(3, 5, KEY_VOLUMEDOWN), | ||
| 31 | KEY(1, 3, KEY_3), | ||
| 32 | KEY(5, 2, KEY_RIGHT), | ||
| 33 | KEY(5, 0, KEY_9), | ||
| 34 | |||
| 35 | KEY(0, 5, KEY_MENU), | ||
| 36 | KEY(7, 6, KEY_ENTER), | ||
| 37 | KEY(4, 5, KEY_0), | ||
| 38 | KEY(6, 7, KEY_2), | ||
| 39 | KEY(3, 4, KEY_UP), | ||
| 40 | KEY(3, 3, KEY_DOWN), | ||
| 41 | |||
| 42 | KEY(6, 4, KEY_SEND), | ||
| 43 | KEY(6, 2, KEY_BACK), | ||
| 44 | KEY(4, 2, KEY_VOLUMEUP), | ||
| 45 | KEY(5, 5, KEY_1), | ||
| 46 | KEY(4, 3, KEY_LEFT), | ||
| 47 | KEY(3, 2, KEY_7), | ||
| 48 | }; | ||
| 49 | |||
| 50 | static const struct matrix_keymap_data mop500_keymap_data = { | ||
| 51 | .keymap = mop500_keymap, | ||
| 52 | .keymap_size = ARRAY_SIZE(mop500_keymap), | ||
| 53 | }; | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Nomadik SKE keypad | ||
| 57 | */ | ||
| 58 | #define ROW_PIN_I0 164 | ||
| 59 | #define ROW_PIN_I1 163 | ||
| 60 | #define ROW_PIN_I2 162 | ||
| 61 | #define ROW_PIN_I3 161 | ||
| 62 | #define ROW_PIN_I4 156 | ||
| 63 | #define ROW_PIN_I5 155 | ||
| 64 | #define ROW_PIN_I6 154 | ||
| 65 | #define ROW_PIN_I7 153 | ||
| 66 | #define COL_PIN_O0 168 | ||
| 67 | #define COL_PIN_O1 167 | ||
| 68 | #define COL_PIN_O2 166 | ||
| 69 | #define COL_PIN_O3 165 | ||
| 70 | #define COL_PIN_O4 160 | ||
| 71 | #define COL_PIN_O5 159 | ||
| 72 | #define COL_PIN_O6 158 | ||
| 73 | #define COL_PIN_O7 157 | ||
| 74 | |||
| 75 | #define SKE_KPD_MAX_ROWS 8 | ||
| 76 | #define SKE_KPD_MAX_COLS 8 | ||
| 77 | |||
| 78 | static int ske_kp_rows[] = { | ||
| 79 | ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, | ||
| 80 | ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7, | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* | ||
| 84 | * ske_set_gpio_row: request and set gpio rows | ||
| 85 | */ | ||
| 86 | static int ske_set_gpio_row(int gpio) | ||
| 87 | { | ||
| 88 | int ret; | ||
| 89 | |||
| 90 | ret = gpio_request(gpio, "ske-kp"); | ||
| 91 | if (ret < 0) { | ||
| 92 | pr_err("ske_set_gpio_row: gpio request failed\n"); | ||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | |||
| 96 | ret = gpio_direction_output(gpio, 1); | ||
| 97 | if (ret < 0) { | ||
| 98 | pr_err("ske_set_gpio_row: gpio direction failed\n"); | ||
| 99 | gpio_free(gpio); | ||
| 100 | } | ||
| 101 | |||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | |||
| 105 | /* | ||
| 106 | * ske_kp_init - enable the gpio configuration | ||
| 107 | */ | ||
| 108 | static int ske_kp_init(void) | ||
| 109 | { | ||
| 110 | int ret, i; | ||
| 111 | |||
| 112 | for (i = 0; i < SKE_KPD_MAX_ROWS; i++) { | ||
| 113 | ret = ske_set_gpio_row(ske_kp_rows[i]); | ||
| 114 | if (ret < 0) { | ||
| 115 | pr_err("ske_kp_init: failed init\n"); | ||
| 116 | return ret; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | static struct ske_keypad_platform_data ske_keypad_board = { | ||
| 124 | .init = ske_kp_init, | ||
| 125 | .keymap_data = &mop500_keymap_data, | ||
| 126 | .no_autorepeat = true, | ||
| 127 | .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */ | ||
| 128 | .kcol = SKE_KPD_MAX_COLS, | ||
| 129 | .debounce_ms = 40, /* in millisecs */ | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * STMPE1601 | ||
| 134 | */ | ||
| 135 | static struct stmpe_keypad_platform_data stmpe1601_keypad_data = { | ||
| 136 | .debounce_ms = 64, | ||
| 137 | .scan_count = 8, | ||
| 138 | .no_autorepeat = true, | ||
| 139 | .keymap_data = &mop500_keymap_data, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static struct stmpe_platform_data stmpe1601_data = { | ||
| 143 | .id = 1, | ||
| 144 | .blocks = STMPE_BLOCK_KEYPAD, | ||
| 145 | .irq_trigger = IRQF_TRIGGER_FALLING, | ||
| 146 | .irq_base = MOP500_STMPE1601_IRQ(0), | ||
| 147 | .keypad = &stmpe1601_keypad_data, | ||
| 148 | .autosleep = true, | ||
| 149 | .autosleep_timeout = 1024, | ||
| 150 | }; | ||
| 151 | |||
| 152 | static struct i2c_board_info mop500_i2c0_devices_stuib[] = { | ||
| 153 | { | ||
| 154 | I2C_BOARD_INFO("stmpe1601", 0x40), | ||
| 155 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
| 156 | .platform_data = &stmpe1601_data, | ||
| 157 | .flags = I2C_CLIENT_WAKE, | ||
| 158 | }, | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* | ||
| 162 | * TC35893 | ||
| 163 | */ | ||
| 164 | |||
| 165 | static const unsigned int uib_keymap[] = { | ||
| 166 | KEY(3, 1, KEY_END), | ||
| 167 | KEY(4, 1, KEY_POWER), | ||
| 168 | KEY(6, 4, KEY_VOLUMEDOWN), | ||
| 169 | KEY(4, 2, KEY_EMAIL), | ||
| 170 | KEY(3, 3, KEY_RIGHT), | ||
| 171 | KEY(2, 5, KEY_BACKSPACE), | ||
| 172 | |||
| 173 | KEY(6, 7, KEY_MENU), | ||
| 174 | KEY(5, 0, KEY_ENTER), | ||
| 175 | KEY(4, 3, KEY_0), | ||
| 176 | KEY(3, 4, KEY_DOT), | ||
| 177 | KEY(5, 2, KEY_UP), | ||
| 178 | KEY(3, 5, KEY_DOWN), | ||
| 179 | |||
| 180 | KEY(4, 5, KEY_SEND), | ||
| 181 | KEY(0, 5, KEY_BACK), | ||
| 182 | KEY(6, 2, KEY_VOLUMEUP), | ||
| 183 | KEY(1, 3, KEY_SPACE), | ||
| 184 | KEY(7, 6, KEY_LEFT), | ||
| 185 | KEY(5, 5, KEY_SEARCH), | ||
| 186 | }; | ||
| 187 | |||
| 188 | static struct matrix_keymap_data uib_keymap_data = { | ||
| 189 | .keymap = uib_keymap, | ||
| 190 | .keymap_size = ARRAY_SIZE(uib_keymap), | ||
| 191 | }; | ||
| 192 | |||
| 193 | static struct tc3589x_keypad_platform_data tc35893_data = { | ||
| 194 | .krow = TC_KPD_ROWS, | ||
| 195 | .kcol = TC_KPD_COLUMNS, | ||
| 196 | .debounce_period = TC_KPD_DEBOUNCE_PERIOD, | ||
| 197 | .settle_time = TC_KPD_SETTLE_TIME, | ||
| 198 | .irqtype = IRQF_TRIGGER_FALLING, | ||
| 199 | .enable_wakeup = true, | ||
| 200 | .keymap_data = &uib_keymap_data, | ||
| 201 | .no_autorepeat = true, | ||
| 202 | }; | ||
| 203 | |||
| 204 | static struct tc3589x_platform_data tc3589x_keypad_data = { | ||
| 205 | .block = TC3589x_BLOCK_KEYPAD, | ||
| 206 | .keypad = &tc35893_data, | ||
| 207 | .irq_base = MOP500_EGPIO_IRQ_BASE, | ||
| 208 | }; | ||
| 209 | |||
| 210 | static struct i2c_board_info mop500_i2c0_devices_uib[] = { | ||
| 211 | { | ||
| 212 | I2C_BOARD_INFO("tc3589x", 0x44), | ||
| 213 | .platform_data = &tc3589x_keypad_data, | ||
| 214 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
| 215 | .flags = I2C_CLIENT_WAKE, | ||
| 216 | }, | ||
| 217 | }; | ||
| 218 | |||
| 219 | void mop500_keypad_init(void) | ||
| 220 | { | ||
| 221 | db8500_add_ske_keypad(&ske_keypad_board); | ||
| 222 | |||
| 223 | i2c_register_board_info(0, mop500_i2c0_devices_stuib, | ||
| 224 | ARRAY_SIZE(mop500_i2c0_devices_stuib)); | ||
| 225 | |||
| 226 | i2c_register_board_info(0, mop500_i2c0_devices_uib, | ||
| 227 | ARRAY_SIZE(mop500_i2c0_devices_uib)); | ||
| 228 | |||
| 229 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c new file mode 100644 index 000000000000..fd4cf1ca5efd --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-pins.c | |||
| @@ -0,0 +1,241 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * License terms: GNU General Public License (GPL) version 2 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <linux/gpio.h> | ||
| 10 | |||
| 11 | #include <asm/mach-types.h> | ||
| 12 | #include <plat/pincfg.h> | ||
| 13 | #include <mach/hardware.h> | ||
| 14 | |||
| 15 | #include "pins-db8500.h" | ||
| 16 | |||
| 17 | static pin_cfg_t mop500_pins_common[] = { | ||
| 18 | /* I2C */ | ||
| 19 | GPIO147_I2C0_SCL, | ||
| 20 | GPIO148_I2C0_SDA, | ||
| 21 | GPIO16_I2C1_SCL, | ||
| 22 | GPIO17_I2C1_SDA, | ||
| 23 | GPIO10_I2C2_SDA, | ||
| 24 | GPIO11_I2C2_SCL, | ||
| 25 | GPIO229_I2C3_SDA, | ||
| 26 | GPIO230_I2C3_SCL, | ||
| 27 | |||
| 28 | /* MSP0 */ | ||
| 29 | GPIO12_MSP0_TXD, | ||
| 30 | GPIO13_MSP0_TFS, | ||
| 31 | GPIO14_MSP0_TCK, | ||
| 32 | GPIO15_MSP0_RXD, | ||
| 33 | |||
| 34 | /* MSP2: HDMI */ | ||
| 35 | GPIO193_MSP2_TXD, | ||
| 36 | GPIO194_MSP2_TCK, | ||
| 37 | GPIO195_MSP2_TFS, | ||
| 38 | GPIO196_MSP2_RXD | PIN_OUTPUT_LOW, | ||
| 39 | |||
| 40 | /* Touch screen INTERFACE */ | ||
| 41 | GPIO84_GPIO | PIN_INPUT_PULLUP, /* TOUCH_INT1 */ | ||
| 42 | |||
| 43 | /* STMPE1601/tc35893 keypad IRQ */ | ||
| 44 | GPIO218_GPIO | PIN_INPUT_PULLUP, | ||
| 45 | |||
| 46 | /* MMC0 (MicroSD card) */ | ||
| 47 | GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH, | ||
| 48 | GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH, | ||
| 49 | GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH, | ||
| 50 | |||
| 51 | GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL, | ||
| 52 | GPIO23_MC0_CLK | PIN_OUTPUT_LOW, | ||
| 53 | GPIO24_MC0_CMD | PIN_INPUT_PULLUP, | ||
| 54 | GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP, | ||
| 55 | GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP, | ||
| 56 | GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP, | ||
| 57 | GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP, | ||
| 58 | |||
| 59 | /* SDI1 (SDIO) */ | ||
| 60 | GPIO208_MC1_CLK | PIN_OUTPUT_LOW, | ||
| 61 | GPIO209_MC1_FBCLK | PIN_INPUT_NOPULL, | ||
| 62 | GPIO210_MC1_CMD | PIN_INPUT_PULLUP, | ||
| 63 | GPIO211_MC1_DAT0 | PIN_INPUT_PULLUP, | ||
| 64 | GPIO212_MC1_DAT1 | PIN_INPUT_PULLUP, | ||
| 65 | GPIO213_MC1_DAT2 | PIN_INPUT_PULLUP, | ||
| 66 | GPIO214_MC1_DAT3 | PIN_INPUT_PULLUP, | ||
| 67 | |||
| 68 | /* MMC2 (On-board DATA INTERFACE eMMC) */ | ||
| 69 | GPIO128_MC2_CLK | PIN_OUTPUT_LOW, | ||
| 70 | GPIO129_MC2_CMD | PIN_INPUT_PULLUP, | ||
| 71 | GPIO130_MC2_FBCLK | PIN_INPUT_NOPULL, | ||
| 72 | GPIO131_MC2_DAT0 | PIN_INPUT_PULLUP, | ||
| 73 | GPIO132_MC2_DAT1 | PIN_INPUT_PULLUP, | ||
| 74 | GPIO133_MC2_DAT2 | PIN_INPUT_PULLUP, | ||
| 75 | GPIO134_MC2_DAT3 | PIN_INPUT_PULLUP, | ||
| 76 | GPIO135_MC2_DAT4 | PIN_INPUT_PULLUP, | ||
| 77 | GPIO136_MC2_DAT5 | PIN_INPUT_PULLUP, | ||
| 78 | GPIO137_MC2_DAT6 | PIN_INPUT_PULLUP, | ||
| 79 | GPIO138_MC2_DAT7 | PIN_INPUT_PULLUP, | ||
| 80 | |||
| 81 | /* MMC4 (On-board STORAGE INTERFACE eMMC) */ | ||
| 82 | GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP, | ||
| 83 | GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP, | ||
| 84 | GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP, | ||
| 85 | GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP, | ||
| 86 | GPIO201_MC4_CMD | PIN_INPUT_PULLUP, | ||
| 87 | GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL, | ||
| 88 | GPIO203_MC4_CLK | PIN_OUTPUT_LOW, | ||
| 89 | GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP, | ||
| 90 | GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP, | ||
| 91 | GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP, | ||
| 92 | GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP, | ||
| 93 | |||
| 94 | /* SKE keypad */ | ||
| 95 | GPIO153_KP_I7, | ||
| 96 | GPIO154_KP_I6, | ||
| 97 | GPIO155_KP_I5, | ||
| 98 | GPIO156_KP_I4, | ||
| 99 | GPIO157_KP_O7, | ||
| 100 | GPIO158_KP_O6, | ||
| 101 | GPIO159_KP_O5, | ||
| 102 | GPIO160_KP_O4, | ||
| 103 | GPIO161_KP_I3, | ||
| 104 | GPIO162_KP_I2, | ||
| 105 | GPIO163_KP_I1, | ||
| 106 | GPIO164_KP_I0, | ||
| 107 | GPIO165_KP_O3, | ||
| 108 | GPIO166_KP_O2, | ||
| 109 | GPIO167_KP_O1, | ||
| 110 | GPIO168_KP_O0, | ||
| 111 | |||
| 112 | /* UART */ | ||
| 113 | GPIO0_U0_CTSn | PIN_INPUT_PULLUP, | ||
| 114 | GPIO1_U0_RTSn | PIN_OUTPUT_HIGH, | ||
| 115 | GPIO2_U0_RXD | PIN_INPUT_PULLUP, | ||
| 116 | GPIO3_U0_TXD | PIN_OUTPUT_HIGH, | ||
| 117 | |||
| 118 | GPIO29_U2_RXD | PIN_INPUT_PULLUP, | ||
| 119 | GPIO30_U2_TXD | PIN_OUTPUT_HIGH, | ||
| 120 | GPIO31_U2_CTSn | PIN_INPUT_PULLUP, | ||
| 121 | GPIO32_U2_RTSn | PIN_OUTPUT_HIGH, | ||
| 122 | |||
| 123 | /* Display & HDMI HW sync */ | ||
| 124 | GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP, | ||
| 125 | GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static pin_cfg_t mop500_pins_default[] = { | ||
| 129 | /* SSP0 */ | ||
| 130 | GPIO143_SSP0_CLK, | ||
| 131 | GPIO144_SSP0_FRM, | ||
| 132 | GPIO145_SSP0_RXD | PIN_PULL_DOWN, | ||
| 133 | GPIO146_SSP0_TXD, | ||
| 134 | |||
| 135 | |||
| 136 | GPIO217_GPIO | PIN_INPUT_PULLUP, /* TC35892 IRQ */ | ||
| 137 | |||
| 138 | /* SDI0 (MicroSD card) */ | ||
| 139 | GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH, | ||
| 140 | |||
| 141 | /* UART */ | ||
| 142 | GPIO4_U1_RXD | PIN_INPUT_PULLUP, | ||
| 143 | GPIO5_U1_TXD | PIN_OUTPUT_HIGH, | ||
| 144 | GPIO6_U1_CTSn | PIN_INPUT_PULLUP, | ||
| 145 | GPIO7_U1_RTSn | PIN_OUTPUT_HIGH, | ||
| 146 | }; | ||
| 147 | |||
| 148 | static pin_cfg_t mop500_pins_hrefv60[] = { | ||
| 149 | /* WLAN */ | ||
| 150 | GPIO4_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */ | ||
| 151 | GPIO85_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */ | ||
| 152 | |||
| 153 | /* XENON Flashgun INTERFACE */ | ||
| 154 | GPIO6_IP_GPIO0 | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */ | ||
| 155 | GPIO7_IP_GPIO1 | PIN_INPUT_PULLUP,/* XENON_READY */ | ||
| 156 | GPIO170_GPIO | PIN_OUTPUT_LOW, /* XENON_CHARGE */ | ||
| 157 | |||
| 158 | /* Assistant LED INTERFACE */ | ||
| 159 | GPIO21_GPIO | PIN_OUTPUT_LOW, /* XENON_EN1 */ | ||
| 160 | GPIO64_IP_GPIO4 | PIN_OUTPUT_LOW, /* XENON_EN2 */ | ||
| 161 | |||
| 162 | /* Magnetometer */ | ||
| 163 | GPIO31_GPIO | PIN_INPUT_PULLUP, /* magnetometer_INT */ | ||
| 164 | GPIO32_GPIO | PIN_INPUT_PULLDOWN, /* Magnetometer DRDY */ | ||
| 165 | |||
| 166 | /* Display Interface */ | ||
| 167 | GPIO65_GPIO | PIN_OUTPUT_LOW, /* DISP1 RST */ | ||
| 168 | GPIO66_GPIO | PIN_OUTPUT_LOW, /* DISP2 RST */ | ||
| 169 | |||
| 170 | /* Touch screen INTERFACE */ | ||
| 171 | GPIO143_GPIO | PIN_OUTPUT_LOW,/*TOUCH_RST1 */ | ||
| 172 | |||
| 173 | /* Touch screen INTERFACE 2 */ | ||
| 174 | GPIO67_GPIO | PIN_INPUT_PULLUP, /* TOUCH_INT2 */ | ||
| 175 | GPIO146_GPIO | PIN_OUTPUT_LOW,/*TOUCH_RST2 */ | ||
| 176 | |||
| 177 | /* ETM_PTM_TRACE INTERFACE */ | ||
| 178 | GPIO70_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA23 */ | ||
| 179 | GPIO71_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA22 */ | ||
| 180 | GPIO72_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA21 */ | ||
| 181 | GPIO73_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA20 */ | ||
| 182 | GPIO74_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA19 */ | ||
| 183 | |||
| 184 | /* NAHJ INTERFACE */ | ||
| 185 | GPIO76_GPIO | PIN_OUTPUT_LOW,/* NAHJ_CTRL */ | ||
| 186 | GPIO216_GPIO | PIN_OUTPUT_HIGH,/* NAHJ_CTRL_INV */ | ||
| 187 | |||
| 188 | /* NFC INTERFACE */ | ||
| 189 | GPIO77_GPIO | PIN_OUTPUT_LOW, /* NFC_ENA */ | ||
| 190 | GPIO144_GPIO | PIN_INPUT_PULLDOWN, /* NFC_IRQ */ | ||
| 191 | GPIO142_GPIO | PIN_OUTPUT_LOW, /* NFC_RESET */ | ||
| 192 | |||
| 193 | /* Keyboard MATRIX INTERFACE */ | ||
| 194 | GPIO90_MC5_CMD | PIN_OUTPUT_LOW, /* KP_O_1 */ | ||
| 195 | GPIO87_MC5_DAT1 | PIN_OUTPUT_LOW, /* KP_O_2 */ | ||
| 196 | GPIO86_MC5_DAT0 | PIN_OUTPUT_LOW, /* KP_O_3 */ | ||
| 197 | GPIO96_KP_O6 | PIN_OUTPUT_LOW, /* KP_O_6 */ | ||
| 198 | GPIO94_KP_O7 | PIN_OUTPUT_LOW, /* KP_O_7 */ | ||
| 199 | GPIO93_MC5_DAT4 | PIN_INPUT_PULLUP, /* KP_I_0 */ | ||
| 200 | GPIO89_MC5_DAT3 | PIN_INPUT_PULLUP, /* KP_I_2 */ | ||
| 201 | GPIO88_MC5_DAT2 | PIN_INPUT_PULLUP, /* KP_I_3 */ | ||
| 202 | GPIO91_GPIO | PIN_INPUT_PULLUP, /* FORCE_SENSING_INT */ | ||
| 203 | GPIO92_GPIO | PIN_OUTPUT_LOW, /* FORCE_SENSING_RST */ | ||
| 204 | GPIO97_GPIO | PIN_OUTPUT_LOW, /* FORCE_SENSING_WU */ | ||
| 205 | |||
| 206 | /* DiPro Sensor Interface */ | ||
| 207 | GPIO139_GPIO | PIN_INPUT_PULLUP, /* DIPRO_INT */ | ||
| 208 | |||
| 209 | /* HAL SWITCH INTERFACE */ | ||
| 210 | GPIO145_GPIO | PIN_INPUT_PULLDOWN,/* HAL_SW */ | ||
| 211 | |||
| 212 | /* Audio Amplifier Interface */ | ||
| 213 | GPIO149_GPIO | PIN_OUTPUT_LOW, /* VAUDIO_HF_EN */ | ||
| 214 | |||
| 215 | /* GBF INTERFACE */ | ||
| 216 | GPIO171_GPIO | PIN_OUTPUT_LOW, /* GBF_ENA_RESET */ | ||
| 217 | |||
| 218 | /* MSP : HDTV INTERFACE */ | ||
| 219 | GPIO192_GPIO | PIN_INPUT_PULLDOWN, | ||
| 220 | |||
| 221 | /* ACCELEROMETER_INTERFACE */ | ||
| 222 | GPIO82_GPIO | PIN_INPUT_PULLUP, /* ACC_INT1 */ | ||
| 223 | GPIO83_GPIO | PIN_INPUT_PULLUP, /* ACC_INT2 */ | ||
| 224 | |||
| 225 | /* Proximity Sensor */ | ||
| 226 | GPIO217_GPIO | PIN_INPUT_PULLUP, | ||
| 227 | |||
| 228 | |||
| 229 | }; | ||
| 230 | |||
| 231 | void __init mop500_pins_init(void) | ||
| 232 | { | ||
| 233 | nmk_config_pins(mop500_pins_common, | ||
| 234 | ARRAY_SIZE(mop500_pins_common)); | ||
| 235 | if (machine_is_hrefv60()) | ||
| 236 | nmk_config_pins(mop500_pins_hrefv60, | ||
| 237 | ARRAY_SIZE(mop500_pins_hrefv60)); | ||
| 238 | else | ||
| 239 | nmk_config_pins(mop500_pins_default, | ||
| 240 | ARRAY_SIZE(mop500_pins_default)); | ||
| 241 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 533967c2d095..875c91b2f8a4 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c | |||
| @@ -11,6 +11,56 @@ | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/regulator/machine.h> | 12 | #include <linux/regulator/machine.h> |
| 13 | #include <linux/regulator/ab8500.h> | 13 | #include <linux/regulator/ab8500.h> |
| 14 | #include "board-mop500-regulators.h" | ||
| 15 | |||
| 16 | static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { | ||
| 17 | /* External displays, connector on board 2v5 power supply */ | ||
| 18 | REGULATOR_SUPPLY("vaux12v5", "mcde.0"), | ||
| 19 | /* SFH7741 proximity sensor */ | ||
| 20 | REGULATOR_SUPPLY("vcc", "gpio-keys.0"), | ||
| 21 | /* BH1780GLS ambient light sensor */ | ||
| 22 | REGULATOR_SUPPLY("vcc", "2-0029"), | ||
| 23 | /* lsm303dlh accelerometer */ | ||
| 24 | REGULATOR_SUPPLY("vdd", "3-0018"), | ||
| 25 | /* lsm303dlh magnetometer */ | ||
| 26 | REGULATOR_SUPPLY("vdd", "3-001e"), | ||
| 27 | /* Rohm BU21013 Touchscreen devices */ | ||
| 28 | REGULATOR_SUPPLY("avdd", "3-005c"), | ||
| 29 | REGULATOR_SUPPLY("avdd", "3-005d"), | ||
| 30 | /* Synaptics RMI4 Touchscreen device */ | ||
| 31 | REGULATOR_SUPPLY("vdd", "3-004b"), | ||
| 32 | }; | ||
| 33 | |||
| 34 | static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { | ||
| 35 | /* On-board eMMC power */ | ||
| 36 | REGULATOR_SUPPLY("vmmc", "sdi4"), | ||
| 37 | /* AB8500 audio codec */ | ||
| 38 | REGULATOR_SUPPLY("vcc-N2158", "ab8500-codec.0"), | ||
| 39 | }; | ||
| 40 | |||
| 41 | static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { | ||
| 42 | /* External MMC slot power */ | ||
| 43 | REGULATOR_SUPPLY("vmmc", "sdi0"), | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { | ||
| 47 | /* TV-out DENC supply */ | ||
| 48 | REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"), | ||
| 49 | /* Internal general-purpose ADC */ | ||
| 50 | REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), | ||
| 51 | }; | ||
| 52 | |||
| 53 | static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { | ||
| 54 | /* SoC core supply, no device */ | ||
| 55 | REGULATOR_SUPPLY("v-intcore", NULL), | ||
| 56 | /* USB Transciever */ | ||
| 57 | REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"), | ||
| 58 | }; | ||
| 59 | |||
| 60 | static struct regulator_consumer_supply ab8500_vana_consumers[] = { | ||
| 61 | /* External displays, connector on board, 1v8 power supply */ | ||
| 62 | REGULATOR_SUPPLY("vsmps2", "mcde.0"), | ||
| 63 | }; | ||
| 14 | 64 | ||
| 15 | /* AB8500 regulators */ | 65 | /* AB8500 regulators */ |
| 16 | struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | 66 | struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { |
| @@ -23,6 +73,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
| 23 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | 73 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
| 24 | REGULATOR_CHANGE_STATUS, | 74 | REGULATOR_CHANGE_STATUS, |
| 25 | }, | 75 | }, |
| 76 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), | ||
| 77 | .consumer_supplies = ab8500_vaux1_consumers, | ||
| 26 | }, | 78 | }, |
| 27 | /* supplies to the on-board eMMC */ | 79 | /* supplies to the on-board eMMC */ |
| 28 | [AB8500_LDO_AUX2] = { | 80 | [AB8500_LDO_AUX2] = { |
| @@ -33,6 +85,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
| 33 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | 85 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
| 34 | REGULATOR_CHANGE_STATUS, | 86 | REGULATOR_CHANGE_STATUS, |
| 35 | }, | 87 | }, |
| 88 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), | ||
| 89 | .consumer_supplies = ab8500_vaux2_consumers, | ||
| 36 | }, | 90 | }, |
| 37 | /* supply for VAUX3, supplies to SDcard slots */ | 91 | /* supply for VAUX3, supplies to SDcard slots */ |
| 38 | [AB8500_LDO_AUX3] = { | 92 | [AB8500_LDO_AUX3] = { |
| @@ -43,6 +97,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
| 43 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | 97 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
| 44 | REGULATOR_CHANGE_STATUS, | 98 | REGULATOR_CHANGE_STATUS, |
| 45 | }, | 99 | }, |
| 100 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), | ||
| 101 | .consumer_supplies = ab8500_vaux3_consumers, | ||
| 46 | }, | 102 | }, |
| 47 | /* supply for tvout, gpadc, TVOUT LDO */ | 103 | /* supply for tvout, gpadc, TVOUT LDO */ |
| 48 | [AB8500_LDO_TVOUT] = { | 104 | [AB8500_LDO_TVOUT] = { |
| @@ -50,6 +106,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
| 50 | .name = "V-TVOUT", | 106 | .name = "V-TVOUT", |
| 51 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 107 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
| 52 | }, | 108 | }, |
| 109 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vtvout_consumers), | ||
| 110 | .consumer_supplies = ab8500_vtvout_consumers, | ||
| 53 | }, | 111 | }, |
| 54 | /* supply for ab8500-vaudio, VAUDIO LDO */ | 112 | /* supply for ab8500-vaudio, VAUDIO LDO */ |
| 55 | [AB8500_LDO_AUDIO] = { | 113 | [AB8500_LDO_AUDIO] = { |
| @@ -85,6 +143,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
| 85 | .name = "V-INTCORE", | 143 | .name = "V-INTCORE", |
| 86 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 144 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
| 87 | }, | 145 | }, |
| 146 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), | ||
| 147 | .consumer_supplies = ab8500_vintcore_consumers, | ||
| 88 | }, | 148 | }, |
| 89 | /* supply for U8500 CSI/DSI, VANA LDO */ | 149 | /* supply for U8500 CSI/DSI, VANA LDO */ |
| 90 | [AB8500_LDO_ANA] = { | 150 | [AB8500_LDO_ANA] = { |
| @@ -92,5 +152,7 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
| 92 | .name = "V-CSI/DSI", | 152 | .name = "V-CSI/DSI", |
| 93 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 153 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
| 94 | }, | 154 | }, |
| 155 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), | ||
| 156 | .consumer_supplies = ab8500_vana_consumers, | ||
| 95 | }, | 157 | }, |
| 96 | }; | 158 | }; |
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 4b996676594e..bf0b02414e5b 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
| @@ -12,56 +12,14 @@ | |||
| 12 | #include <linux/mmc/host.h> | 12 | #include <linux/mmc/host.h> |
| 13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 14 | 14 | ||
| 15 | #include <plat/pincfg.h> | 15 | #include <asm/mach-types.h> |
| 16 | #include <plat/ste_dma40.h> | ||
| 16 | #include <mach/devices.h> | 17 | #include <mach/devices.h> |
| 17 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> |
| 18 | 19 | ||
| 19 | #include "devices-db8500.h" | 20 | #include "devices-db8500.h" |
| 20 | #include "pins-db8500.h" | ||
| 21 | #include "board-mop500.h" | 21 | #include "board-mop500.h" |
| 22 | 22 | #include "ste-dma40-db8500.h" | |
| 23 | static pin_cfg_t mop500_sdi_pins[] = { | ||
| 24 | /* SDI0 (MicroSD slot) */ | ||
| 25 | GPIO18_MC0_CMDDIR, | ||
| 26 | GPIO19_MC0_DAT0DIR, | ||
| 27 | GPIO20_MC0_DAT2DIR, | ||
| 28 | GPIO21_MC0_DAT31DIR, | ||
| 29 | GPIO22_MC0_FBCLK, | ||
| 30 | GPIO23_MC0_CLK, | ||
| 31 | GPIO24_MC0_CMD, | ||
| 32 | GPIO25_MC0_DAT0, | ||
| 33 | GPIO26_MC0_DAT1, | ||
| 34 | GPIO27_MC0_DAT2, | ||
| 35 | GPIO28_MC0_DAT3, | ||
| 36 | |||
| 37 | /* SDI4 (on-board eMMC) */ | ||
| 38 | GPIO197_MC4_DAT3, | ||
| 39 | GPIO198_MC4_DAT2, | ||
| 40 | GPIO199_MC4_DAT1, | ||
| 41 | GPIO200_MC4_DAT0, | ||
| 42 | GPIO201_MC4_CMD, | ||
| 43 | GPIO202_MC4_FBCLK, | ||
| 44 | GPIO203_MC4_CLK, | ||
| 45 | GPIO204_MC4_DAT7, | ||
| 46 | GPIO205_MC4_DAT6, | ||
| 47 | GPIO206_MC4_DAT5, | ||
| 48 | GPIO207_MC4_DAT4, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static pin_cfg_t mop500_sdi2_pins[] = { | ||
| 52 | /* SDI2 (POP eMMC) */ | ||
| 53 | GPIO128_MC2_CLK, | ||
| 54 | GPIO129_MC2_CMD, | ||
| 55 | GPIO130_MC2_FBCLK, | ||
| 56 | GPIO131_MC2_DAT0, | ||
| 57 | GPIO132_MC2_DAT1, | ||
| 58 | GPIO133_MC2_DAT2, | ||
| 59 | GPIO134_MC2_DAT3, | ||
| 60 | GPIO135_MC2_DAT4, | ||
| 61 | GPIO136_MC2_DAT5, | ||
| 62 | GPIO137_MC2_DAT6, | ||
| 63 | GPIO138_MC2_DAT7, | ||
| 64 | }; | ||
| 65 | 23 | ||
| 66 | /* | 24 | /* |
| 67 | * SDI 0 (MicroSD slot) | 25 | * SDI 0 (MicroSD slot) |
| @@ -86,48 +44,134 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | |||
| 86 | MCI_DATA2DIREN | MCI_DATA31DIREN; | 44 | MCI_DATA2DIREN | MCI_DATA31DIREN; |
| 87 | } | 45 | } |
| 88 | 46 | ||
| 47 | #ifdef CONFIG_STE_DMA40 | ||
| 48 | struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { | ||
| 49 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 50 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 51 | .src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX, | ||
| 52 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 53 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 54 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { | ||
| 58 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 59 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 60 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 61 | .dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX, | ||
| 62 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 63 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 64 | }; | ||
| 65 | #endif | ||
| 66 | |||
| 89 | static struct mmci_platform_data mop500_sdi0_data = { | 67 | static struct mmci_platform_data mop500_sdi0_data = { |
| 90 | .vdd_handler = mop500_sdi0_vdd_handler, | 68 | .vdd_handler = mop500_sdi0_vdd_handler, |
| 91 | .ocr_mask = MMC_VDD_29_30, | 69 | .ocr_mask = MMC_VDD_29_30, |
| 92 | .f_max = 100000000, | 70 | .f_max = 100000000, |
| 93 | .capabilities = MMC_CAP_4_BIT_DATA, | 71 | .capabilities = MMC_CAP_4_BIT_DATA, |
| 94 | .gpio_cd = GPIO_SDMMC_CD, | ||
| 95 | .gpio_wp = -1, | 72 | .gpio_wp = -1, |
| 73 | #ifdef CONFIG_STE_DMA40 | ||
| 74 | .dma_filter = stedma40_filter, | ||
| 75 | .dma_rx_param = &mop500_sdi0_dma_cfg_rx, | ||
| 76 | .dma_tx_param = &mop500_sdi0_dma_cfg_tx, | ||
| 77 | #endif | ||
| 96 | }; | 78 | }; |
| 97 | 79 | ||
| 98 | void mop500_sdi_tc35892_init(void) | 80 | /* GPIO pins used by the sdi0 level shifter */ |
| 81 | static int sdi0_en = -1; | ||
| 82 | static int sdi0_vsel = -1; | ||
| 83 | |||
| 84 | static void sdi0_configure(void) | ||
| 99 | { | 85 | { |
| 100 | int ret; | 86 | int ret; |
| 101 | 87 | ||
| 102 | ret = gpio_request(GPIO_SDMMC_EN, "SDMMC_EN"); | 88 | ret = gpio_request(sdi0_en, "level shifter enable"); |
| 103 | if (!ret) | 89 | if (!ret) |
| 104 | ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL, | 90 | ret = gpio_request(sdi0_vsel, |
| 105 | "GPIO_SDMMC_1V8_3V_SEL"); | 91 | "level shifter 1v8-3v select"); |
| 106 | if (ret) | 92 | |
| 93 | if (ret) { | ||
| 94 | pr_warning("unable to config sdi0 gpios for level shifter.\n"); | ||
| 107 | return; | 95 | return; |
| 96 | } | ||
| 108 | 97 | ||
| 109 | gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1); | 98 | /* Select the default 2.9V and enable level shifter */ |
| 110 | gpio_direction_output(GPIO_SDMMC_EN, 0); | 99 | gpio_direction_output(sdi0_vsel, 0); |
| 100 | gpio_direction_output(sdi0_en, 1); | ||
| 111 | 101 | ||
| 102 | /* Add the device */ | ||
| 112 | db8500_add_sdi0(&mop500_sdi0_data); | 103 | db8500_add_sdi0(&mop500_sdi0_data); |
| 113 | } | 104 | } |
| 114 | 105 | ||
| 106 | void mop500_sdi_tc35892_init(void) | ||
| 107 | { | ||
| 108 | mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD; | ||
| 109 | sdi0_en = GPIO_SDMMC_EN; | ||
| 110 | sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL; | ||
| 111 | sdi0_configure(); | ||
| 112 | } | ||
| 113 | |||
| 115 | /* | 114 | /* |
| 116 | * SDI 2 (POP eMMC, not on DB8500ed) | 115 | * SDI 2 (POP eMMC, not on DB8500ed) |
| 117 | */ | 116 | */ |
| 118 | 117 | ||
| 118 | #ifdef CONFIG_STE_DMA40 | ||
| 119 | struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { | ||
| 120 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 121 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 122 | .src_dev_type = DB8500_DMA_DEV28_SD_MM2_RX, | ||
| 123 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 124 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 125 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { | ||
| 129 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 130 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 131 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 132 | .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX, | ||
| 133 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 134 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 135 | }; | ||
| 136 | #endif | ||
| 137 | |||
| 119 | static struct mmci_platform_data mop500_sdi2_data = { | 138 | static struct mmci_platform_data mop500_sdi2_data = { |
| 120 | .ocr_mask = MMC_VDD_165_195, | 139 | .ocr_mask = MMC_VDD_165_195, |
| 121 | .f_max = 100000000, | 140 | .f_max = 100000000, |
| 122 | .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, | 141 | .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, |
| 123 | .gpio_cd = -1, | 142 | .gpio_cd = -1, |
| 124 | .gpio_wp = -1, | 143 | .gpio_wp = -1, |
| 144 | #ifdef CONFIG_STE_DMA40 | ||
| 145 | .dma_filter = stedma40_filter, | ||
| 146 | .dma_rx_param = &mop500_sdi2_dma_cfg_rx, | ||
| 147 | .dma_tx_param = &mop500_sdi2_dma_cfg_tx, | ||
| 148 | #endif | ||
| 125 | }; | 149 | }; |
| 126 | 150 | ||
| 127 | /* | 151 | /* |
| 128 | * SDI 4 (on-board eMMC) | 152 | * SDI 4 (on-board eMMC) |
| 129 | */ | 153 | */ |
| 130 | 154 | ||
| 155 | #ifdef CONFIG_STE_DMA40 | ||
| 156 | struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { | ||
| 157 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 158 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 159 | .src_dev_type = DB8500_DMA_DEV42_SD_MM4_RX, | ||
| 160 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 161 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 162 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 163 | }; | ||
| 164 | |||
| 165 | static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { | ||
| 166 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 167 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 168 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 169 | .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX, | ||
| 170 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 171 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 172 | }; | ||
| 173 | #endif | ||
| 174 | |||
| 131 | static struct mmci_platform_data mop500_sdi4_data = { | 175 | static struct mmci_platform_data mop500_sdi4_data = { |
| 132 | .ocr_mask = MMC_VDD_29_30, | 176 | .ocr_mask = MMC_VDD_29_30, |
| 133 | .f_max = 100000000, | 177 | .f_max = 100000000, |
| @@ -135,26 +179,32 @@ static struct mmci_platform_data mop500_sdi4_data = { | |||
| 135 | MMC_CAP_MMC_HIGHSPEED, | 179 | MMC_CAP_MMC_HIGHSPEED, |
| 136 | .gpio_cd = -1, | 180 | .gpio_cd = -1, |
| 137 | .gpio_wp = -1, | 181 | .gpio_wp = -1, |
| 182 | #ifdef CONFIG_STE_DMA40 | ||
| 183 | .dma_filter = stedma40_filter, | ||
| 184 | .dma_rx_param = &mop500_sdi4_dma_cfg_rx, | ||
| 185 | .dma_tx_param = &mop500_sdi4_dma_cfg_tx, | ||
| 186 | #endif | ||
| 138 | }; | 187 | }; |
| 139 | 188 | ||
| 140 | void __init mop500_sdi_init(void) | 189 | void __init mop500_sdi_init(void) |
| 141 | { | 190 | { |
| 142 | nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins)); | 191 | /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ |
| 192 | if (!cpu_is_u8500v10()) | ||
| 193 | mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; | ||
| 194 | db8500_add_sdi2(&mop500_sdi2_data); | ||
| 195 | |||
| 196 | /* On-board eMMC */ | ||
| 197 | db8500_add_sdi4(&mop500_sdi4_data); | ||
| 143 | 198 | ||
| 199 | if (machine_is_hrefv60()) { | ||
| 200 | mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; | ||
| 201 | sdi0_en = HREFV60_SDMMC_EN_GPIO; | ||
| 202 | sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; | ||
| 203 | sdi0_configure(); | ||
| 204 | } | ||
| 144 | /* | 205 | /* |
| 145 | * sdi0 will finally be added when the TC35892 initializes and calls | 206 | * On boards with the TC35892 GPIO expander, sdi0 will finally |
| 207 | * be added when the TC35892 initializes and calls | ||
| 146 | * mop500_sdi_tc35892_init() above. | 208 | * mop500_sdi_tc35892_init() above. |
| 147 | */ | 209 | */ |
| 148 | |||
| 149 | /* PoP:ed eMMC */ | ||
| 150 | if (!cpu_is_u8500ed()) { | ||
| 151 | nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins)); | ||
| 152 | /* POP eMMC on v1.0 has problems with high speed */ | ||
| 153 | if (!cpu_is_u8500v10()) | ||
| 154 | mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; | ||
| 155 | db8500_add_sdi2(&mop500_sdi2_data); | ||
| 156 | } | ||
| 157 | |||
| 158 | /* On-board eMMC */ | ||
| 159 | db8500_add_sdi4(&mop500_sdi4_data); | ||
| 160 | } | 210 | } |
diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c new file mode 100644 index 000000000000..8c979770d872 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-stuib.c | |||
| @@ -0,0 +1,205 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * License terms: GNU General Public License (GPL), version 2 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <linux/mfd/stmpe.h> | ||
| 10 | #include <linux/input/bu21013.h> | ||
| 11 | #include <linux/gpio.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/i2c.h> | ||
| 14 | #include <linux/input/matrix_keypad.h> | ||
| 15 | #include <asm/mach-types.h> | ||
| 16 | |||
| 17 | #include "board-mop500.h" | ||
| 18 | |||
| 19 | /* STMPE/SKE keypad use this key layout */ | ||
| 20 | static const unsigned int mop500_keymap[] = { | ||
| 21 | KEY(2, 5, KEY_END), | ||
| 22 | KEY(4, 1, KEY_POWER), | ||
| 23 | KEY(3, 5, KEY_VOLUMEDOWN), | ||
| 24 | KEY(1, 3, KEY_3), | ||
| 25 | KEY(5, 2, KEY_RIGHT), | ||
| 26 | KEY(5, 0, KEY_9), | ||
| 27 | |||
| 28 | KEY(0, 5, KEY_MENU), | ||
| 29 | KEY(7, 6, KEY_ENTER), | ||
| 30 | KEY(4, 5, KEY_0), | ||
| 31 | KEY(6, 7, KEY_2), | ||
| 32 | KEY(3, 4, KEY_UP), | ||
| 33 | KEY(3, 3, KEY_DOWN), | ||
| 34 | |||
| 35 | KEY(6, 4, KEY_SEND), | ||
| 36 | KEY(6, 2, KEY_BACK), | ||
| 37 | KEY(4, 2, KEY_VOLUMEUP), | ||
| 38 | KEY(5, 5, KEY_1), | ||
| 39 | KEY(4, 3, KEY_LEFT), | ||
| 40 | KEY(3, 2, KEY_7), | ||
| 41 | }; | ||
| 42 | |||
| 43 | static const struct matrix_keymap_data mop500_keymap_data = { | ||
| 44 | .keymap = mop500_keymap, | ||
| 45 | .keymap_size = ARRAY_SIZE(mop500_keymap), | ||
| 46 | }; | ||
| 47 | /* | ||
| 48 | * STMPE1601 | ||
| 49 | */ | ||
| 50 | static struct stmpe_keypad_platform_data stmpe1601_keypad_data = { | ||
| 51 | .debounce_ms = 64, | ||
| 52 | .scan_count = 8, | ||
| 53 | .no_autorepeat = true, | ||
| 54 | .keymap_data = &mop500_keymap_data, | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct stmpe_platform_data stmpe1601_data = { | ||
| 58 | .id = 1, | ||
| 59 | .blocks = STMPE_BLOCK_KEYPAD, | ||
| 60 | .irq_trigger = IRQF_TRIGGER_FALLING, | ||
| 61 | .irq_base = MOP500_STMPE1601_IRQ(0), | ||
| 62 | .keypad = &stmpe1601_keypad_data, | ||
| 63 | .autosleep = true, | ||
| 64 | .autosleep_timeout = 1024, | ||
| 65 | }; | ||
| 66 | |||
| 67 | static struct i2c_board_info __initdata mop500_i2c0_devices_stuib[] = { | ||
| 68 | { | ||
| 69 | I2C_BOARD_INFO("stmpe1601", 0x40), | ||
| 70 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
| 71 | .platform_data = &stmpe1601_data, | ||
| 72 | .flags = I2C_CLIENT_WAKE, | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * BU21013 ROHM touchscreen interface on the STUIBs | ||
| 78 | */ | ||
| 79 | |||
| 80 | /* tracks number of bu21013 devices being enabled */ | ||
| 81 | static int bu21013_devices; | ||
| 82 | |||
| 83 | #define TOUCH_GPIO_PIN 84 | ||
| 84 | |||
| 85 | #define TOUCH_XMAX 384 | ||
| 86 | #define TOUCH_YMAX 704 | ||
| 87 | |||
| 88 | #define PRCMU_CLOCK_OCR 0x1CC | ||
| 89 | #define TSC_EXT_CLOCK_9_6MHZ 0x840000 | ||
| 90 | |||
| 91 | /** | ||
| 92 | * bu21013_gpio_board_init : configures the touch panel. | ||
| 93 | * @reset_pin: reset pin number | ||
| 94 | * This function can be used to configures | ||
| 95 | * the voltage and reset the touch panel controller. | ||
| 96 | */ | ||
| 97 | static int bu21013_gpio_board_init(int reset_pin) | ||
| 98 | { | ||
| 99 | int retval = 0; | ||
| 100 | |||
| 101 | bu21013_devices++; | ||
| 102 | if (bu21013_devices == 1) { | ||
| 103 | retval = gpio_request(reset_pin, "touchp_reset"); | ||
| 104 | if (retval) { | ||
| 105 | printk(KERN_ERR "Unable to request gpio reset_pin"); | ||
| 106 | return retval; | ||
| 107 | } | ||
| 108 | retval = gpio_direction_output(reset_pin, 1); | ||
| 109 | if (retval < 0) { | ||
| 110 | printk(KERN_ERR "%s: gpio direction failed\n", | ||
| 111 | __func__); | ||
| 112 | return retval; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | return retval; | ||
| 117 | } | ||
| 118 | |||
| 119 | /** | ||
| 120 | * bu21013_gpio_board_exit : deconfigures the touch panel controller | ||
| 121 | * @reset_pin: reset pin number | ||
| 122 | * This function can be used to deconfigures the chip selection | ||
| 123 | * for touch panel controller. | ||
| 124 | */ | ||
| 125 | static int bu21013_gpio_board_exit(int reset_pin) | ||
| 126 | { | ||
| 127 | int retval = 0; | ||
| 128 | |||
| 129 | if (bu21013_devices == 1) { | ||
| 130 | retval = gpio_direction_output(reset_pin, 0); | ||
| 131 | if (retval < 0) { | ||
| 132 | printk(KERN_ERR "%s: gpio direction failed\n", | ||
| 133 | __func__); | ||
| 134 | return retval; | ||
| 135 | } | ||
| 136 | gpio_set_value(reset_pin, 0); | ||
| 137 | } | ||
| 138 | bu21013_devices--; | ||
| 139 | |||
| 140 | return retval; | ||
| 141 | } | ||
| 142 | |||
| 143 | /** | ||
| 144 | * bu21013_read_pin_val : get the interrupt pin value | ||
| 145 | * This function can be used to get the interrupt pin value for touch panel | ||
| 146 | * controller. | ||
| 147 | */ | ||
| 148 | static int bu21013_read_pin_val(void) | ||
| 149 | { | ||
| 150 | return gpio_get_value(TOUCH_GPIO_PIN); | ||
| 151 | } | ||
| 152 | |||
| 153 | static struct bu21013_platform_device tsc_plat_device = { | ||
| 154 | .cs_en = bu21013_gpio_board_init, | ||
| 155 | .cs_dis = bu21013_gpio_board_exit, | ||
| 156 | .irq_read_val = bu21013_read_pin_val, | ||
| 157 | .irq = NOMADIK_GPIO_TO_IRQ(TOUCH_GPIO_PIN), | ||
| 158 | .touch_x_max = TOUCH_XMAX, | ||
| 159 | .touch_y_max = TOUCH_YMAX, | ||
| 160 | .ext_clk = false, | ||
| 161 | .x_flip = false, | ||
| 162 | .y_flip = true, | ||
| 163 | }; | ||
| 164 | |||
| 165 | static struct bu21013_platform_device tsc_plat2_device = { | ||
| 166 | .cs_en = bu21013_gpio_board_init, | ||
| 167 | .cs_dis = bu21013_gpio_board_exit, | ||
| 168 | .irq_read_val = bu21013_read_pin_val, | ||
| 169 | .irq = NOMADIK_GPIO_TO_IRQ(TOUCH_GPIO_PIN), | ||
| 170 | .touch_x_max = TOUCH_XMAX, | ||
| 171 | .touch_y_max = TOUCH_YMAX, | ||
| 172 | .ext_clk = false, | ||
| 173 | .x_flip = false, | ||
| 174 | .y_flip = true, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static struct i2c_board_info __initdata u8500_i2c3_devices_stuib[] = { | ||
| 178 | { | ||
| 179 | I2C_BOARD_INFO("bu21013_tp", 0x5C), | ||
| 180 | .platform_data = &tsc_plat_device, | ||
| 181 | }, | ||
| 182 | { | ||
| 183 | I2C_BOARD_INFO("bu21013_tp", 0x5D), | ||
| 184 | .platform_data = &tsc_plat2_device, | ||
| 185 | }, | ||
| 186 | |||
| 187 | }; | ||
| 188 | |||
| 189 | void __init mop500_stuib_init(void) | ||
| 190 | { | ||
| 191 | if (machine_is_hrefv60()) { | ||
| 192 | tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO; | ||
| 193 | tsc_plat2_device.cs_pin = HREFV60_TOUCH_RST_GPIO; | ||
| 194 | } else { | ||
| 195 | tsc_plat_device.cs_pin = GPIO_BU21013_CS; | ||
| 196 | tsc_plat2_device.cs_pin = GPIO_BU21013_CS; | ||
| 197 | |||
| 198 | } | ||
| 199 | |||
| 200 | mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib, | ||
| 201 | ARRAY_SIZE(mop500_i2c0_devices_stuib)); | ||
| 202 | |||
| 203 | mop500_uib_i2c_add(3, u8500_i2c3_devices_stuib, | ||
| 204 | ARRAY_SIZE(u8500_i2c3_devices_stuib)); | ||
| 205 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c new file mode 100644 index 000000000000..d8a8734a0eba --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * Board data for the U8500 UIB, also known as the New UIB | ||
| 5 | * License terms: GNU General Public License (GPL), version 2 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/i2c.h> | ||
| 11 | #include <linux/gpio.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/mfd/tc3589x.h> | ||
| 14 | #include <linux/input/matrix_keypad.h> | ||
| 15 | #include <../drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h> | ||
| 16 | |||
| 17 | #include <mach/gpio.h> | ||
| 18 | #include <mach/irqs.h> | ||
| 19 | |||
| 20 | #include "board-mop500.h" | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Synaptics RMI4 touchscreen interface on the U8500 UIB | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Descriptor structure. | ||
| 28 | * Describes the number of i2c devices on the bus that speak RMI. | ||
| 29 | */ | ||
| 30 | static struct synaptics_rmi4_platform_data rmi4_i2c_dev_platformdata = { | ||
| 31 | .irq_number = NOMADIK_GPIO_TO_IRQ(84), | ||
| 32 | .irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED), | ||
| 33 | .x_flip = false, | ||
| 34 | .y_flip = true, | ||
| 35 | .regulator_en = false, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = { | ||
| 39 | { | ||
| 40 | I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B), | ||
| 41 | .platform_data = &rmi4_i2c_dev_platformdata, | ||
| 42 | }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /* | ||
| 46 | * TC35893 | ||
| 47 | */ | ||
| 48 | static const unsigned int u8500_keymap[] = { | ||
| 49 | KEY(3, 1, KEY_END), | ||
| 50 | KEY(4, 1, KEY_POWER), | ||
| 51 | KEY(6, 4, KEY_VOLUMEDOWN), | ||
| 52 | KEY(4, 2, KEY_EMAIL), | ||
| 53 | KEY(3, 3, KEY_RIGHT), | ||
| 54 | KEY(2, 5, KEY_BACKSPACE), | ||
| 55 | |||
| 56 | KEY(6, 7, KEY_MENU), | ||
| 57 | KEY(5, 0, KEY_ENTER), | ||
| 58 | KEY(4, 3, KEY_0), | ||
| 59 | KEY(3, 4, KEY_DOT), | ||
| 60 | KEY(5, 2, KEY_UP), | ||
| 61 | KEY(3, 5, KEY_DOWN), | ||
| 62 | |||
| 63 | KEY(4, 5, KEY_SEND), | ||
| 64 | KEY(0, 5, KEY_BACK), | ||
| 65 | KEY(6, 2, KEY_VOLUMEUP), | ||
| 66 | KEY(1, 3, KEY_SPACE), | ||
| 67 | KEY(7, 6, KEY_LEFT), | ||
| 68 | KEY(5, 5, KEY_SEARCH), | ||
| 69 | }; | ||
| 70 | |||
| 71 | static struct matrix_keymap_data u8500_keymap_data = { | ||
| 72 | .keymap = u8500_keymap, | ||
| 73 | .keymap_size = ARRAY_SIZE(u8500_keymap), | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct tc3589x_keypad_platform_data tc35893_data = { | ||
| 77 | .krow = TC_KPD_ROWS, | ||
| 78 | .kcol = TC_KPD_COLUMNS, | ||
| 79 | .debounce_period = TC_KPD_DEBOUNCE_PERIOD, | ||
| 80 | .settle_time = TC_KPD_SETTLE_TIME, | ||
| 81 | .irqtype = IRQF_TRIGGER_FALLING, | ||
| 82 | .enable_wakeup = true, | ||
| 83 | .keymap_data = &u8500_keymap_data, | ||
| 84 | .no_autorepeat = true, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static struct tc3589x_platform_data tc3589x_keypad_data = { | ||
| 88 | .block = TC3589x_BLOCK_KEYPAD, | ||
| 89 | .keypad = &tc35893_data, | ||
| 90 | .irq_base = MOP500_EGPIO_IRQ_BASE, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct i2c_board_info __initdata mop500_i2c0_devices_u8500[] = { | ||
| 94 | { | ||
| 95 | I2C_BOARD_INFO("tc3589x", 0x44), | ||
| 96 | .platform_data = &tc3589x_keypad_data, | ||
| 97 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
| 98 | .flags = I2C_CLIENT_WAKE, | ||
| 99 | }, | ||
| 100 | }; | ||
| 101 | |||
| 102 | |||
| 103 | void __init mop500_u8500uib_init(void) | ||
| 104 | { | ||
| 105 | mop500_uib_i2c_add(3, mop500_i2c3_devices_u8500, | ||
| 106 | ARRAY_SIZE(mop500_i2c3_devices_u8500)); | ||
| 107 | |||
| 108 | mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, | ||
| 109 | ARRAY_SIZE(mop500_i2c0_devices_u8500)); | ||
| 110 | |||
| 111 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c new file mode 100644 index 000000000000..69cce41f602a --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-uib.c | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
| 5 | * License terms: GNU General Public License (GPL), version 2 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define pr_fmt(fmt) "mop500-uib: " fmt | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/i2c.h> | ||
| 13 | |||
| 14 | #include <mach/hardware.h> | ||
| 15 | #include "board-mop500.h" | ||
| 16 | |||
| 17 | enum mop500_uib { | ||
| 18 | STUIB, | ||
| 19 | U8500UIB, | ||
| 20 | }; | ||
| 21 | |||
| 22 | struct uib { | ||
| 23 | const char *name; | ||
| 24 | const char *option; | ||
| 25 | void (*init)(void); | ||
| 26 | }; | ||
| 27 | |||
| 28 | static struct __initdata uib mop500_uibs[] = { | ||
| 29 | [STUIB] = { | ||
| 30 | .name = "ST-UIB", | ||
| 31 | .option = "stuib", | ||
| 32 | .init = mop500_stuib_init, | ||
| 33 | }, | ||
| 34 | [U8500UIB] = { | ||
| 35 | .name = "U8500-UIB", | ||
| 36 | .option = "u8500uib", | ||
| 37 | .init = mop500_u8500uib_init, | ||
| 38 | }, | ||
| 39 | }; | ||
| 40 | |||
| 41 | static struct uib *mop500_uib; | ||
| 42 | |||
| 43 | static int __init mop500_uib_setup(char *str) | ||
| 44 | { | ||
| 45 | int i; | ||
| 46 | |||
| 47 | for (i = 0; i < ARRAY_SIZE(mop500_uibs); i++) { | ||
| 48 | struct uib *uib = &mop500_uibs[i]; | ||
| 49 | |||
| 50 | if (!strcmp(str, uib->option)) { | ||
| 51 | mop500_uib = uib; | ||
| 52 | break; | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | if (i == ARRAY_SIZE(mop500_uibs)) | ||
| 57 | pr_err("invalid uib= option (%s)\n", str); | ||
| 58 | |||
| 59 | return 1; | ||
| 60 | } | ||
| 61 | __setup("uib=", mop500_uib_setup); | ||
| 62 | |||
| 63 | /* | ||
| 64 | * The UIBs are detected after the I2C host controllers are registered, so | ||
| 65 | * i2c_register_board_info() can't be used. | ||
| 66 | */ | ||
| 67 | void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, | ||
| 68 | unsigned n) | ||
| 69 | { | ||
| 70 | struct i2c_adapter *adap; | ||
| 71 | struct i2c_client *client; | ||
| 72 | int i; | ||
| 73 | |||
| 74 | adap = i2c_get_adapter(busnum); | ||
| 75 | if (!adap) { | ||
| 76 | pr_err("failed to get adapter i2c%d\n", busnum); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | for (i = 0; i < n; i++) { | ||
| 81 | client = i2c_new_device(adap, &info[i]); | ||
| 82 | if (!client) | ||
| 83 | pr_err("failed to register %s to i2c%d\n", | ||
| 84 | info[i].type, busnum); | ||
| 85 | } | ||
| 86 | |||
| 87 | i2c_put_adapter(adap); | ||
| 88 | } | ||
| 89 | |||
| 90 | static void __init __mop500_uib_init(struct uib *uib, const char *why) | ||
| 91 | { | ||
| 92 | pr_info("%s (%s)\n", uib->name, why); | ||
| 93 | uib->init(); | ||
| 94 | } | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Detect the UIB attached based on the presence or absence of i2c devices. | ||
| 98 | */ | ||
| 99 | static int __init mop500_uib_init(void) | ||
| 100 | { | ||
| 101 | struct uib *uib = mop500_uib; | ||
| 102 | struct i2c_adapter *i2c0; | ||
| 103 | int ret; | ||
| 104 | |||
| 105 | if (!cpu_is_u8500()) | ||
| 106 | return -ENODEV; | ||
| 107 | |||
| 108 | if (uib) { | ||
| 109 | __mop500_uib_init(uib, "from uib= boot argument"); | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | i2c0 = i2c_get_adapter(0); | ||
| 114 | if (!i2c0) { | ||
| 115 | __mop500_uib_init(&mop500_uibs[STUIB], | ||
| 116 | "fallback, could not get i2c0"); | ||
| 117 | return -ENODEV; | ||
| 118 | } | ||
| 119 | |||
| 120 | /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */ | ||
| 121 | ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0, | ||
| 122 | I2C_SMBUS_QUICK, NULL); | ||
| 123 | i2c_put_adapter(i2c0); | ||
| 124 | |||
| 125 | if (ret == 0) | ||
| 126 | uib = &mop500_uibs[U8500UIB]; | ||
| 127 | else | ||
| 128 | uib = &mop500_uibs[STUIB]; | ||
| 129 | |||
| 130 | __mop500_uib_init(uib, "detected"); | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | module_init(mop500_uib_init); | ||
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a393f57ed2a8..8790d984cac8 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
| @@ -17,68 +17,30 @@ | |||
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
| 18 | #include <linux/amba/bus.h> | 18 | #include <linux/amba/bus.h> |
| 19 | #include <linux/amba/pl022.h> | 19 | #include <linux/amba/pl022.h> |
| 20 | #include <linux/amba/serial.h> | ||
| 20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 21 | #include <linux/mfd/ab8500.h> | 22 | #include <linux/mfd/ab8500.h> |
| 22 | #include <linux/mfd/tc3589x.h> | 23 | #include <linux/mfd/tc3589x.h> |
| 24 | #include <linux/leds-lp5521.h> | ||
| 25 | #include <linux/input.h> | ||
| 26 | #include <linux/gpio_keys.h> | ||
| 23 | 27 | ||
| 24 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
| 25 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
| 26 | 30 | ||
| 27 | #include <plat/pincfg.h> | ||
| 28 | #include <plat/i2c.h> | 31 | #include <plat/i2c.h> |
| 32 | #include <plat/ste_dma40.h> | ||
| 29 | 33 | ||
| 30 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
| 31 | #include <mach/setup.h> | 35 | #include <mach/setup.h> |
| 32 | #include <mach/devices.h> | 36 | #include <mach/devices.h> |
| 33 | #include <mach/irqs.h> | 37 | #include <mach/irqs.h> |
| 34 | 38 | ||
| 39 | #include "ste-dma40-db8500.h" | ||
| 35 | #include "devices-db8500.h" | 40 | #include "devices-db8500.h" |
| 36 | #include "pins-db8500.h" | ||
| 37 | #include "board-mop500.h" | 41 | #include "board-mop500.h" |
| 38 | #include "board-mop500-regulators.h" | 42 | #include "board-mop500-regulators.h" |
| 39 | 43 | ||
| 40 | static pin_cfg_t mop500_pins[] = { | ||
| 41 | /* SSP0 */ | ||
| 42 | GPIO143_SSP0_CLK, | ||
| 43 | GPIO144_SSP0_FRM, | ||
| 44 | GPIO145_SSP0_RXD, | ||
| 45 | GPIO146_SSP0_TXD, | ||
| 46 | |||
| 47 | /* I2C */ | ||
| 48 | GPIO147_I2C0_SCL, | ||
| 49 | GPIO148_I2C0_SDA, | ||
| 50 | GPIO16_I2C1_SCL, | ||
| 51 | GPIO17_I2C1_SDA, | ||
| 52 | GPIO10_I2C2_SDA, | ||
| 53 | GPIO11_I2C2_SCL, | ||
| 54 | GPIO229_I2C3_SDA, | ||
| 55 | GPIO230_I2C3_SCL, | ||
| 56 | |||
| 57 | /* SKE keypad */ | ||
| 58 | GPIO153_KP_I7, | ||
| 59 | GPIO154_KP_I6, | ||
| 60 | GPIO155_KP_I5, | ||
| 61 | GPIO156_KP_I4, | ||
| 62 | GPIO157_KP_O7, | ||
| 63 | GPIO158_KP_O6, | ||
| 64 | GPIO159_KP_O5, | ||
| 65 | GPIO160_KP_O4, | ||
| 66 | GPIO161_KP_I3, | ||
| 67 | GPIO162_KP_I2, | ||
| 68 | GPIO163_KP_I1, | ||
| 69 | GPIO164_KP_I0, | ||
| 70 | GPIO165_KP_O3, | ||
| 71 | GPIO166_KP_O2, | ||
| 72 | GPIO167_KP_O1, | ||
| 73 | GPIO168_KP_O0, | ||
| 74 | |||
| 75 | /* GPIO_EXP_INT */ | ||
| 76 | GPIO217_GPIO, | ||
| 77 | |||
| 78 | /* STMPE1601 IRQ */ | ||
| 79 | GPIO218_GPIO | PIN_INPUT_PULLUP, | ||
| 80 | }; | ||
| 81 | |||
| 82 | static struct ab8500_platform_data ab8500_platdata = { | 44 | static struct ab8500_platform_data ab8500_platdata = { |
| 83 | .irq_base = MOP500_AB8500_IRQ_BASE, | 45 | .irq_base = MOP500_AB8500_IRQ_BASE, |
| 84 | .regulator = ab8500_regulators, | 46 | .regulator = ab8500_regulators, |
| @@ -103,16 +65,6 @@ struct platform_device ab8500_device = { | |||
| 103 | .resource = ab8500_resources, | 65 | .resource = ab8500_resources, |
| 104 | }; | 66 | }; |
| 105 | 67 | ||
| 106 | static struct pl022_ssp_controller ssp0_platform_data = { | ||
| 107 | .bus_id = 0, | ||
| 108 | /* pl022 not yet supports dma */ | ||
| 109 | .enable_dma = 0, | ||
| 110 | /* on this platform, gpio 31,142,144,214 & | ||
| 111 | * 224 are connected as chip selects | ||
| 112 | */ | ||
| 113 | .num_chipselect = 5, | ||
| 114 | }; | ||
| 115 | |||
| 116 | /* | 68 | /* |
| 117 | * TC35892 | 69 | * TC35892 |
| 118 | */ | 70 | */ |
| @@ -133,14 +85,81 @@ static struct tc3589x_platform_data mop500_tc35892_data = { | |||
| 133 | .irq_base = MOP500_EGPIO_IRQ_BASE, | 85 | .irq_base = MOP500_EGPIO_IRQ_BASE, |
| 134 | }; | 86 | }; |
| 135 | 87 | ||
| 88 | static struct lp5521_led_config lp5521_pri_led[] = { | ||
| 89 | [0] = { | ||
| 90 | .chan_nr = 0, | ||
| 91 | .led_current = 0x2f, | ||
| 92 | .max_current = 0x5f, | ||
| 93 | }, | ||
| 94 | [1] = { | ||
| 95 | .chan_nr = 1, | ||
| 96 | .led_current = 0x2f, | ||
| 97 | .max_current = 0x5f, | ||
| 98 | }, | ||
| 99 | [2] = { | ||
| 100 | .chan_nr = 2, | ||
| 101 | .led_current = 0x2f, | ||
| 102 | .max_current = 0x5f, | ||
| 103 | }, | ||
| 104 | }; | ||
| 105 | |||
| 106 | static struct lp5521_platform_data __initdata lp5521_pri_data = { | ||
| 107 | .label = "lp5521_pri", | ||
| 108 | .led_config = &lp5521_pri_led[0], | ||
| 109 | .num_channels = 3, | ||
| 110 | .clock_mode = LP5521_CLOCK_EXT, | ||
| 111 | }; | ||
| 112 | |||
| 113 | static struct lp5521_led_config lp5521_sec_led[] = { | ||
| 114 | [0] = { | ||
| 115 | .chan_nr = 0, | ||
| 116 | .led_current = 0x2f, | ||
| 117 | .max_current = 0x5f, | ||
| 118 | }, | ||
| 119 | [1] = { | ||
| 120 | .chan_nr = 1, | ||
| 121 | .led_current = 0x2f, | ||
| 122 | .max_current = 0x5f, | ||
| 123 | }, | ||
| 124 | [2] = { | ||
| 125 | .chan_nr = 2, | ||
| 126 | .led_current = 0x2f, | ||
| 127 | .max_current = 0x5f, | ||
| 128 | }, | ||
| 129 | }; | ||
| 130 | |||
| 131 | static struct lp5521_platform_data __initdata lp5521_sec_data = { | ||
| 132 | .label = "lp5521_sec", | ||
| 133 | .led_config = &lp5521_sec_led[0], | ||
| 134 | .num_channels = 3, | ||
| 135 | .clock_mode = LP5521_CLOCK_EXT, | ||
| 136 | }; | ||
| 137 | |||
| 136 | static struct i2c_board_info mop500_i2c0_devices[] = { | 138 | static struct i2c_board_info mop500_i2c0_devices[] = { |
| 137 | { | 139 | { |
| 138 | I2C_BOARD_INFO("tc3589x", 0x42), | 140 | I2C_BOARD_INFO("tc3589x", 0x42), |
| 139 | .irq = NOMADIK_GPIO_TO_IRQ(217), | 141 | .irq = NOMADIK_GPIO_TO_IRQ(217), |
| 140 | .platform_data = &mop500_tc35892_data, | 142 | .platform_data = &mop500_tc35892_data, |
| 141 | }, | 143 | }, |
| 142 | }; | 144 | }; |
| 143 | 145 | ||
| 146 | static struct i2c_board_info __initdata mop500_i2c2_devices[] = { | ||
| 147 | { | ||
| 148 | /* lp5521 LED driver, 1st device */ | ||
| 149 | I2C_BOARD_INFO("lp5521", 0x33), | ||
| 150 | .platform_data = &lp5521_pri_data, | ||
| 151 | }, | ||
| 152 | { | ||
| 153 | /* lp5521 LED driver, 2st device */ | ||
| 154 | I2C_BOARD_INFO("lp5521", 0x34), | ||
| 155 | .platform_data = &lp5521_sec_data, | ||
| 156 | }, | ||
| 157 | { | ||
| 158 | /* Light sensor Rohm BH1780GLI */ | ||
| 159 | I2C_BOARD_INFO("bh1780", 0x29), | ||
| 160 | }, | ||
| 161 | }; | ||
| 162 | |||
| 144 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ | 163 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ |
| 145 | static struct nmk_i2c_controller u8500_i2c##id##_data = { \ | 164 | static struct nmk_i2c_controller u8500_i2c##id##_data = { \ |
| 146 | /* \ | 165 | /* \ |
| @@ -178,8 +197,93 @@ static void __init mop500_i2c_init(void) | |||
| 178 | db8500_add_i2c3(&u8500_i2c3_data); | 197 | db8500_add_i2c3(&u8500_i2c3_data); |
| 179 | } | 198 | } |
| 180 | 199 | ||
| 200 | static struct gpio_keys_button mop500_gpio_keys[] = { | ||
| 201 | { | ||
| 202 | .desc = "SFH7741 Proximity Sensor", | ||
| 203 | .type = EV_SW, | ||
| 204 | .code = SW_FRONT_PROXIMITY, | ||
| 205 | .active_low = 0, | ||
| 206 | .can_disable = 1, | ||
| 207 | } | ||
| 208 | }; | ||
| 209 | |||
| 210 | static struct regulator *prox_regulator; | ||
| 211 | static int mop500_prox_activate(struct device *dev); | ||
| 212 | static void mop500_prox_deactivate(struct device *dev); | ||
| 213 | |||
| 214 | static struct gpio_keys_platform_data mop500_gpio_keys_data = { | ||
| 215 | .buttons = mop500_gpio_keys, | ||
| 216 | .nbuttons = ARRAY_SIZE(mop500_gpio_keys), | ||
| 217 | .enable = mop500_prox_activate, | ||
| 218 | .disable = mop500_prox_deactivate, | ||
| 219 | }; | ||
| 220 | |||
| 221 | static struct platform_device mop500_gpio_keys_device = { | ||
| 222 | .name = "gpio-keys", | ||
| 223 | .id = 0, | ||
| 224 | .dev = { | ||
| 225 | .platform_data = &mop500_gpio_keys_data, | ||
| 226 | }, | ||
| 227 | }; | ||
| 228 | |||
| 229 | static int mop500_prox_activate(struct device *dev) | ||
| 230 | { | ||
| 231 | prox_regulator = regulator_get(&mop500_gpio_keys_device.dev, | ||
| 232 | "vcc"); | ||
| 233 | if (IS_ERR(prox_regulator)) { | ||
| 234 | dev_err(&mop500_gpio_keys_device.dev, | ||
| 235 | "no regulator\n"); | ||
| 236 | return PTR_ERR(prox_regulator); | ||
| 237 | } | ||
| 238 | regulator_enable(prox_regulator); | ||
| 239 | return 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | static void mop500_prox_deactivate(struct device *dev) | ||
| 243 | { | ||
| 244 | regulator_disable(prox_regulator); | ||
| 245 | regulator_put(prox_regulator); | ||
| 246 | } | ||
| 247 | |||
| 181 | /* add any platform devices here - TODO */ | 248 | /* add any platform devices here - TODO */ |
| 182 | static struct platform_device *platform_devs[] __initdata = { | 249 | static struct platform_device *platform_devs[] __initdata = { |
| 250 | &mop500_gpio_keys_device, | ||
| 251 | }; | ||
| 252 | |||
| 253 | #ifdef CONFIG_STE_DMA40 | ||
| 254 | static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { | ||
| 255 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 256 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 257 | .src_dev_type = DB8500_DMA_DEV8_SSP0_RX, | ||
| 258 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 259 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 260 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 261 | }; | ||
| 262 | |||
| 263 | static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { | ||
| 264 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 265 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 266 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 267 | .dst_dev_type = DB8500_DMA_DEV8_SSP0_TX, | ||
| 268 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 269 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 270 | }; | ||
| 271 | #endif | ||
| 272 | |||
| 273 | static struct pl022_ssp_controller ssp0_platform_data = { | ||
| 274 | .bus_id = 0, | ||
| 275 | #ifdef CONFIG_STE_DMA40 | ||
| 276 | .enable_dma = 1, | ||
| 277 | .dma_filter = stedma40_filter, | ||
| 278 | .dma_rx_param = &ssp0_dma_cfg_rx, | ||
| 279 | .dma_tx_param = &ssp0_dma_cfg_tx, | ||
| 280 | #else | ||
| 281 | .enable_dma = 0, | ||
| 282 | #endif | ||
| 283 | /* on this platform, gpio 31,142,144,214 & | ||
| 284 | * 224 are connected as chip selects | ||
| 285 | */ | ||
| 286 | .num_chipselect = 5, | ||
| 183 | }; | 287 | }; |
| 184 | 288 | ||
| 185 | static void __init mop500_spi_init(void) | 289 | static void __init mop500_spi_init(void) |
| @@ -187,18 +291,108 @@ static void __init mop500_spi_init(void) | |||
| 187 | db8500_add_ssp0(&ssp0_platform_data); | 291 | db8500_add_ssp0(&ssp0_platform_data); |
| 188 | } | 292 | } |
| 189 | 293 | ||
| 294 | #ifdef CONFIG_STE_DMA40 | ||
| 295 | static struct stedma40_chan_cfg uart0_dma_cfg_rx = { | ||
| 296 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 297 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 298 | .src_dev_type = DB8500_DMA_DEV13_UART0_RX, | ||
| 299 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 300 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 301 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 302 | }; | ||
| 303 | |||
| 304 | static struct stedma40_chan_cfg uart0_dma_cfg_tx = { | ||
| 305 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 306 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 307 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 308 | .dst_dev_type = DB8500_DMA_DEV13_UART0_TX, | ||
| 309 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 310 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 311 | }; | ||
| 312 | |||
| 313 | static struct stedma40_chan_cfg uart1_dma_cfg_rx = { | ||
| 314 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 315 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 316 | .src_dev_type = DB8500_DMA_DEV12_UART1_RX, | ||
| 317 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 318 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 319 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 320 | }; | ||
| 321 | |||
| 322 | static struct stedma40_chan_cfg uart1_dma_cfg_tx = { | ||
| 323 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 324 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 325 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 326 | .dst_dev_type = DB8500_DMA_DEV12_UART1_TX, | ||
| 327 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 328 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 329 | }; | ||
| 330 | |||
| 331 | static struct stedma40_chan_cfg uart2_dma_cfg_rx = { | ||
| 332 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 333 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 334 | .src_dev_type = DB8500_DMA_DEV11_UART2_RX, | ||
| 335 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 336 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 337 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 338 | }; | ||
| 339 | |||
| 340 | static struct stedma40_chan_cfg uart2_dma_cfg_tx = { | ||
| 341 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 342 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 343 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 344 | .dst_dev_type = DB8500_DMA_DEV11_UART2_TX, | ||
| 345 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 346 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
| 347 | }; | ||
| 348 | #endif | ||
| 349 | |||
| 350 | static struct amba_pl011_data uart0_plat = { | ||
| 351 | #ifdef CONFIG_STE_DMA40 | ||
| 352 | .dma_filter = stedma40_filter, | ||
| 353 | .dma_rx_param = &uart0_dma_cfg_rx, | ||
| 354 | .dma_tx_param = &uart0_dma_cfg_tx, | ||
| 355 | #endif | ||
| 356 | }; | ||
| 357 | |||
| 358 | static struct amba_pl011_data uart1_plat = { | ||
| 359 | #ifdef CONFIG_STE_DMA40 | ||
| 360 | .dma_filter = stedma40_filter, | ||
| 361 | .dma_rx_param = &uart1_dma_cfg_rx, | ||
| 362 | .dma_tx_param = &uart1_dma_cfg_tx, | ||
| 363 | #endif | ||
| 364 | }; | ||
| 365 | |||
| 366 | static struct amba_pl011_data uart2_plat = { | ||
| 367 | #ifdef CONFIG_STE_DMA40 | ||
| 368 | .dma_filter = stedma40_filter, | ||
| 369 | .dma_rx_param = &uart2_dma_cfg_rx, | ||
| 370 | .dma_tx_param = &uart2_dma_cfg_tx, | ||
| 371 | #endif | ||
| 372 | }; | ||
| 373 | |||
| 190 | static void __init mop500_uart_init(void) | 374 | static void __init mop500_uart_init(void) |
| 191 | { | 375 | { |
| 192 | db8500_add_uart0(); | 376 | db8500_add_uart0(&uart0_plat); |
| 193 | db8500_add_uart1(); | 377 | db8500_add_uart1(&uart1_plat); |
| 194 | db8500_add_uart2(); | 378 | db8500_add_uart2(&uart2_plat); |
| 195 | } | 379 | } |
| 196 | 380 | ||
| 197 | static void __init u8500_init_machine(void) | 381 | static void __init mop500_init_machine(void) |
| 198 | { | 382 | { |
| 383 | /* | ||
| 384 | * The HREFv60 board removed a GPIO expander and routed | ||
| 385 | * all these GPIO pins to the internal GPIO controller | ||
| 386 | * instead. | ||
| 387 | */ | ||
| 388 | if (machine_is_hrefv60()) | ||
| 389 | mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; | ||
| 390 | else | ||
| 391 | mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; | ||
| 392 | |||
| 199 | u8500_init_devices(); | 393 | u8500_init_devices(); |
| 200 | 394 | ||
| 201 | nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins)); | 395 | mop500_pins_init(); |
| 202 | 396 | ||
| 203 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 397 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
| 204 | 398 | ||
| @@ -207,12 +401,12 @@ static void __init u8500_init_machine(void) | |||
| 207 | mop500_spi_init(); | 401 | mop500_spi_init(); |
| 208 | mop500_uart_init(); | 402 | mop500_uart_init(); |
| 209 | 403 | ||
| 210 | mop500_keypad_init(); | ||
| 211 | |||
| 212 | platform_device_register(&ab8500_device); | 404 | platform_device_register(&ab8500_device); |
| 213 | 405 | ||
| 214 | i2c_register_board_info(0, mop500_i2c0_devices, | 406 | i2c_register_board_info(0, mop500_i2c0_devices, |
| 215 | ARRAY_SIZE(mop500_i2c0_devices)); | 407 | ARRAY_SIZE(mop500_i2c0_devices)); |
| 408 | i2c_register_board_info(2, mop500_i2c2_devices, | ||
| 409 | ARRAY_SIZE(mop500_i2c2_devices)); | ||
| 216 | } | 410 | } |
| 217 | 411 | ||
| 218 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | 412 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") |
| @@ -222,5 +416,13 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | |||
| 222 | .init_irq = ux500_init_irq, | 416 | .init_irq = ux500_init_irq, |
| 223 | /* we re-use nomadik timer here */ | 417 | /* we re-use nomadik timer here */ |
| 224 | .timer = &ux500_timer, | 418 | .timer = &ux500_timer, |
| 225 | .init_machine = u8500_init_machine, | 419 | .init_machine = mop500_init_machine, |
| 420 | MACHINE_END | ||
| 421 | |||
| 422 | MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") | ||
| 423 | .boot_params = 0x100, | ||
| 424 | .map_io = u8500_map_io, | ||
| 425 | .init_irq = ux500_init_irq, | ||
| 426 | .timer = &ux500_timer, | ||
| 427 | .init_machine = mop500_init_machine, | ||
| 226 | MACHINE_END | 428 | MACHINE_END |
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 3104ae2a02c2..56722f4be71b 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h | |||
| @@ -7,15 +7,36 @@ | |||
| 7 | #ifndef __BOARD_MOP500_H | 7 | #ifndef __BOARD_MOP500_H |
| 8 | #define __BOARD_MOP500_H | 8 | #define __BOARD_MOP500_H |
| 9 | 9 | ||
| 10 | #define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) | 10 | /* HREFv60-specific GPIO assignments, this board has no GPIO expander */ |
| 11 | #define HREFV60_TOUCH_RST_GPIO 143 | ||
| 12 | #define HREFV60_PROX_SENSE_GPIO 217 | ||
| 13 | #define HREFV60_HAL_SW_GPIO 145 | ||
| 14 | #define HREFV60_SDMMC_EN_GPIO 169 | ||
| 15 | #define HREFV60_SDMMC_1V8_3V_GPIO 5 | ||
| 16 | #define HREFV60_SDMMC_CD_GPIO 95 | ||
| 17 | #define HREFV60_ACCEL_INT1_GPIO 82 | ||
| 18 | #define HREFV60_ACCEL_INT2_GPIO 83 | ||
| 19 | #define HREFV60_MAGNET_DRDY_GPIO 32 | ||
| 20 | #define HREFV60_DISP1_RST_GPIO 65 | ||
| 21 | #define HREFV60_DISP2_RST_GPIO 66 | ||
| 11 | 22 | ||
| 12 | /* GPIOs on the TC35892 expander */ | 23 | /* GPIOs on the TC35892 expander */ |
| 24 | #define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) | ||
| 13 | #define GPIO_SDMMC_CD MOP500_EGPIO(3) | 25 | #define GPIO_SDMMC_CD MOP500_EGPIO(3) |
| 26 | #define GPIO_PROX_SENSOR MOP500_EGPIO(7) | ||
| 27 | #define GPIO_BU21013_CS MOP500_EGPIO(13) | ||
| 14 | #define GPIO_SDMMC_EN MOP500_EGPIO(17) | 28 | #define GPIO_SDMMC_EN MOP500_EGPIO(17) |
| 15 | #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) | 29 | #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) |
| 16 | 30 | ||
| 31 | struct i2c_board_info; | ||
| 32 | |||
| 17 | extern void mop500_sdi_init(void); | 33 | extern void mop500_sdi_init(void); |
| 18 | extern void mop500_sdi_tc35892_init(void); | 34 | extern void mop500_sdi_tc35892_init(void); |
| 19 | extern void mop500_keypad_init(void); | 35 | void __init mop500_u8500uib_init(void); |
| 36 | void __init mop500_stuib_init(void); | ||
| 37 | void __init mop500_pins_init(void); | ||
| 38 | |||
| 39 | void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, | ||
| 40 | unsigned n); | ||
| 20 | 41 | ||
| 21 | #endif | 42 | #endif |
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c index 54712acc0394..739fb4c5b160 100644 --- a/arch/arm/mach-ux500/board-u5500-sdi.c +++ b/arch/arm/mach-ux500/board-u5500-sdi.c | |||
| @@ -31,6 +31,26 @@ static pin_cfg_t u5500_sdi_pins[] = { | |||
| 31 | GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW, | 31 | GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW, |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | #ifdef CONFIG_STE_DMA40 | ||
| 35 | struct stedma40_chan_cfg u5500_sdi0_dma_cfg_rx = { | ||
| 36 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 37 | .dir = STEDMA40_PERIPH_TO_MEM, | ||
| 38 | .src_dev_type = DB5500_DMA_DEV24_SDMMC0_RX, | ||
| 39 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, | ||
| 40 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 41 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct stedma40_chan_cfg u5500_sdi0_dma_cfg_tx = { | ||
| 45 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 46 | .dir = STEDMA40_MEM_TO_PERIPH, | ||
| 47 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, | ||
| 48 | .dst_dev_type = DB5500_DMA_DEV24_SDMMC0_TX, | ||
| 49 | .src_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 50 | .dst_info.data_width = STEDMA40_WORD_WIDTH, | ||
| 51 | }; | ||
| 52 | #endif | ||
| 53 | |||
| 34 | static struct mmci_platform_data u5500_sdi0_data = { | 54 | static struct mmci_platform_data u5500_sdi0_data = { |
| 35 | .ocr_mask = MMC_VDD_165_195, | 55 | .ocr_mask = MMC_VDD_165_195, |
| 36 | .f_max = 50000000, | 56 | .f_max = 50000000, |
| @@ -39,6 +59,11 @@ static struct mmci_platform_data u5500_sdi0_data = { | |||
| 39 | MMC_CAP_MMC_HIGHSPEED, | 59 | MMC_CAP_MMC_HIGHSPEED, |
| 40 | .gpio_cd = -1, | 60 | .gpio_cd = -1, |
| 41 | .gpio_wp = -1, | 61 | .gpio_wp = -1, |
| 62 | #ifdef CONFIG_STE_DMA40 | ||
| 63 | .dma_filter = stedma40_filter, | ||
| 64 | .dma_rx_param = &u5500_sdi0_dma_cfg_rx, | ||
| 65 | .dma_tx_param = &u5500_sdi0_dma_cfg_tx, | ||
| 66 | #endif | ||
| 42 | }; | 67 | }; |
| 43 | 68 | ||
| 44 | void __init u5500_sdi_init(void) | 69 | void __init u5500_sdi_init(void) |
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 39d370c1f3b4..44fd3b5c33ec 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c | |||
| @@ -22,9 +22,9 @@ | |||
| 22 | 22 | ||
| 23 | static void __init u5500_uart_init(void) | 23 | static void __init u5500_uart_init(void) |
| 24 | { | 24 | { |
| 25 | db5500_add_uart0(); | 25 | db5500_add_uart0(NULL); |
| 26 | db5500_add_uart1(); | 26 | db5500_add_uart1(NULL); |
| 27 | db5500_add_uart2(); | 27 | db5500_add_uart2(NULL); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | static void __init u5500_init_machine(void) | 30 | static void __init u5500_init_machine(void) |
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index b2b0a3b9be8f..32ce90840ee1 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c | |||
| @@ -313,7 +313,7 @@ static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000); | |||
| 313 | static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK); | 313 | static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK); |
| 314 | static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */ | 314 | static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */ |
| 315 | static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000); | 315 | static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000); |
| 316 | static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 50000000); | 316 | static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000); |
| 317 | static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK); | 317 | static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK); |
| 318 | static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK); | 318 | static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK); |
| 319 | static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK); | 319 | static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK); |
| @@ -520,7 +520,7 @@ static struct clk_lookup u8500_ed_clks[] = { | |||
| 520 | CLK(ssp0_ed, "ssp0", NULL), | 520 | CLK(ssp0_ed, "ssp0", NULL), |
| 521 | 521 | ||
| 522 | /* Peripheral Cluster #5 */ | 522 | /* Peripheral Cluster #5 */ |
| 523 | CLK(usb_ed, "musb_hdrc.0", "usb"), | 523 | CLK(usb_ed, "musb-ux500.0", "usb"), |
| 524 | 524 | ||
| 525 | /* Peripheral Cluster #6 */ | 525 | /* Peripheral Cluster #6 */ |
| 526 | CLK(dmc_ed, "dmc", NULL), | 526 | CLK(dmc_ed, "dmc", NULL), |
| @@ -561,7 +561,7 @@ static struct clk_lookup u8500_v1_clks[] = { | |||
| 561 | CLK(ssp0_v1, "ssp0", NULL), | 561 | CLK(ssp0_v1, "ssp0", NULL), |
| 562 | 562 | ||
| 563 | /* Peripheral Cluster #5 */ | 563 | /* Peripheral Cluster #5 */ |
| 564 | CLK(usb_v1, "musb_hdrc.0", "usb"), | 564 | CLK(usb_v1, "musb-ux500.0", "usb"), |
| 565 | 565 | ||
| 566 | /* Peripheral Cluster #6 */ | 566 | /* Peripheral Cluster #6 */ |
| 567 | CLK(mtu1_v1, "mtu1", NULL), | 567 | CLK(mtu1_v1, "mtu1", NULL), |
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index af04e0891a78..c9dc2eff3cb2 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
| 12 | 12 | ||
| 13 | #include <asm/mach/map.h> | 13 | #include <asm/mach/map.h> |
| 14 | #include <asm/pmu.h> | ||
| 14 | 15 | ||
| 15 | #include <plat/gpio.h> | 16 | #include <plat/gpio.h> |
| 16 | 17 | ||
| @@ -18,8 +19,10 @@ | |||
| 18 | #include <mach/devices.h> | 19 | #include <mach/devices.h> |
| 19 | #include <mach/setup.h> | 20 | #include <mach/setup.h> |
| 20 | #include <mach/irqs.h> | 21 | #include <mach/irqs.h> |
| 22 | #include <mach/usb.h> | ||
| 21 | 23 | ||
| 22 | #include "devices-db5500.h" | 24 | #include "devices-db5500.h" |
| 25 | #include "ste-dma40-db5500.h" | ||
| 23 | 26 | ||
| 24 | static struct map_desc u5500_uart_io_desc[] __initdata = { | 27 | static struct map_desc u5500_uart_io_desc[] __initdata = { |
| 25 | __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K), | 28 | __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K), |
| @@ -43,6 +46,26 @@ static struct map_desc u5500_io_desc[] __initdata = { | |||
| 43 | __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), | 46 | __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), |
| 44 | }; | 47 | }; |
| 45 | 48 | ||
| 49 | static struct resource db5500_pmu_resources[] = { | ||
| 50 | [0] = { | ||
| 51 | .start = IRQ_DB5500_PMU0, | ||
| 52 | .end = IRQ_DB5500_PMU0, | ||
| 53 | .flags = IORESOURCE_IRQ, | ||
| 54 | }, | ||
| 55 | [1] = { | ||
| 56 | .start = IRQ_DB5500_PMU1, | ||
| 57 | .end = IRQ_DB5500_PMU1, | ||
| 58 | .flags = IORESOURCE_IRQ, | ||
| 59 | }, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static struct platform_device db5500_pmu_device = { | ||
| 63 | .name = "arm-pmu", | ||
| 64 | .id = ARM_PMU_DEVICE_CPU, | ||
| 65 | .num_resources = ARRAY_SIZE(db5500_pmu_resources), | ||
| 66 | .resource = db5500_pmu_resources, | ||
| 67 | }; | ||
| 68 | |||
| 46 | static struct resource mbox0_resources[] = { | 69 | static struct resource mbox0_resources[] = { |
| 47 | { | 70 | { |
| 48 | .name = "mbox_peer", | 71 | .name = "mbox_peer", |
| @@ -127,7 +150,8 @@ static struct platform_device mbox2_device = { | |||
| 127 | .num_resources = ARRAY_SIZE(mbox2_resources), | 150 | .num_resources = ARRAY_SIZE(mbox2_resources), |
| 128 | }; | 151 | }; |
| 129 | 152 | ||
| 130 | static struct platform_device *u5500_platform_devs[] __initdata = { | 153 | static struct platform_device *db5500_platform_devs[] __initdata = { |
| 154 | &db5500_pmu_device, | ||
| 131 | &mbox0_device, | 155 | &mbox0_device, |
| 132 | &mbox1_device, | 156 | &mbox1_device, |
| 133 | &mbox2_device, | 157 | &mbox2_device, |
| @@ -166,12 +190,35 @@ void __init u5500_map_io(void) | |||
| 166 | iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); | 190 | iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); |
| 167 | } | 191 | } |
| 168 | 192 | ||
| 193 | static int usb_db5500_rx_dma_cfg[] = { | ||
| 194 | DB5500_DMA_DEV4_USB_OTG_IEP_1_9, | ||
| 195 | DB5500_DMA_DEV5_USB_OTG_IEP_2_10, | ||
| 196 | DB5500_DMA_DEV6_USB_OTG_IEP_3_11, | ||
| 197 | DB5500_DMA_DEV20_USB_OTG_IEP_4_12, | ||
| 198 | DB5500_DMA_DEV21_USB_OTG_IEP_5_13, | ||
| 199 | DB5500_DMA_DEV22_USB_OTG_IEP_6_14, | ||
| 200 | DB5500_DMA_DEV23_USB_OTG_IEP_7_15, | ||
| 201 | DB5500_DMA_DEV38_USB_OTG_IEP_8 | ||
| 202 | }; | ||
| 203 | |||
| 204 | static int usb_db5500_tx_dma_cfg[] = { | ||
| 205 | DB5500_DMA_DEV4_USB_OTG_OEP_1_9, | ||
| 206 | DB5500_DMA_DEV5_USB_OTG_OEP_2_10, | ||
| 207 | DB5500_DMA_DEV6_USB_OTG_OEP_3_11, | ||
| 208 | DB5500_DMA_DEV20_USB_OTG_OEP_4_12, | ||
| 209 | DB5500_DMA_DEV21_USB_OTG_OEP_5_13, | ||
| 210 | DB5500_DMA_DEV22_USB_OTG_OEP_6_14, | ||
| 211 | DB5500_DMA_DEV23_USB_OTG_OEP_7_15, | ||
| 212 | DB5500_DMA_DEV38_USB_OTG_OEP_8 | ||
| 213 | }; | ||
| 214 | |||
| 169 | void __init u5500_init_devices(void) | 215 | void __init u5500_init_devices(void) |
| 170 | { | 216 | { |
| 171 | db5500_add_gpios(); | 217 | db5500_add_gpios(); |
| 172 | db5500_dma_init(); | 218 | db5500_dma_init(); |
| 173 | db5500_add_rtc(); | 219 | db5500_add_rtc(); |
| 220 | db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); | ||
| 174 | 221 | ||
| 175 | platform_add_devices(u5500_platform_devs, | 222 | platform_add_devices(db5500_platform_devs, |
| 176 | ARRAY_SIZE(u5500_platform_devs)); | 223 | ARRAY_SIZE(db5500_platform_devs)); |
| 177 | } | 224 | } |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 5c0fabf5fa01..516126cb357d 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
| @@ -23,8 +23,10 @@ | |||
| 23 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
| 24 | #include <mach/setup.h> | 24 | #include <mach/setup.h> |
| 25 | #include <mach/devices.h> | 25 | #include <mach/devices.h> |
| 26 | #include <mach/usb.h> | ||
| 26 | 27 | ||
| 27 | #include "devices-db8500.h" | 28 | #include "devices-db8500.h" |
| 29 | #include "ste-dma40-db8500.h" | ||
| 28 | 30 | ||
| 29 | /* minimum static i/o mapping required to boot U8500 platforms */ | 31 | /* minimum static i/o mapping required to boot U8500 platforms */ |
| 30 | static struct map_desc u8500_uart_io_desc[] __initdata = { | 32 | static struct map_desc u8500_uart_io_desc[] __initdata = { |
| @@ -154,6 +156,28 @@ static void __init db8500_add_gpios(void) | |||
| 154 | IRQ_DB8500_GPIO0, &pdata); | 156 | IRQ_DB8500_GPIO0, &pdata); |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 159 | static int usb_db8500_rx_dma_cfg[] = { | ||
| 160 | DB8500_DMA_DEV38_USB_OTG_IEP_1_9, | ||
| 161 | DB8500_DMA_DEV37_USB_OTG_IEP_2_10, | ||
| 162 | DB8500_DMA_DEV36_USB_OTG_IEP_3_11, | ||
| 163 | DB8500_DMA_DEV19_USB_OTG_IEP_4_12, | ||
| 164 | DB8500_DMA_DEV18_USB_OTG_IEP_5_13, | ||
| 165 | DB8500_DMA_DEV17_USB_OTG_IEP_6_14, | ||
| 166 | DB8500_DMA_DEV16_USB_OTG_IEP_7_15, | ||
| 167 | DB8500_DMA_DEV39_USB_OTG_IEP_8 | ||
| 168 | }; | ||
| 169 | |||
| 170 | static int usb_db8500_tx_dma_cfg[] = { | ||
| 171 | DB8500_DMA_DEV38_USB_OTG_OEP_1_9, | ||
| 172 | DB8500_DMA_DEV37_USB_OTG_OEP_2_10, | ||
| 173 | DB8500_DMA_DEV36_USB_OTG_OEP_3_11, | ||
| 174 | DB8500_DMA_DEV19_USB_OTG_OEP_4_12, | ||
| 175 | DB8500_DMA_DEV18_USB_OTG_OEP_5_13, | ||
| 176 | DB8500_DMA_DEV17_USB_OTG_OEP_6_14, | ||
| 177 | DB8500_DMA_DEV16_USB_OTG_OEP_7_15, | ||
| 178 | DB8500_DMA_DEV39_USB_OTG_OEP_8 | ||
| 179 | }; | ||
| 180 | |||
| 157 | /* | 181 | /* |
| 158 | * This function is called from the board init | 182 | * This function is called from the board init |
| 159 | */ | 183 | */ |
| @@ -164,6 +188,7 @@ void __init u8500_init_devices(void) | |||
| 164 | 188 | ||
| 165 | db8500_add_rtc(); | 189 | db8500_add_rtc(); |
| 166 | db8500_add_gpios(); | 190 | db8500_add_gpios(); |
| 191 | db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); | ||
| 167 | 192 | ||
| 168 | platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); | 193 | platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); |
| 169 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 194 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index fe69f5fac1bb..13a4ce046ae5 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c | |||
| @@ -139,6 +139,7 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq, | |||
| 139 | for (i = 0; i < num; i++, first += 32, irq++) { | 139 | for (i = 0; i < num; i++, first += 32, irq++) { |
| 140 | pdata->first_gpio = first; | 140 | pdata->first_gpio = first; |
| 141 | pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); | 141 | pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); |
| 142 | pdata->num_gpio = 32; | ||
| 142 | 143 | ||
| 143 | dbx500_add_gpio(i, base[i], irq, pdata); | 144 | dbx500_add_gpio(i, base[i], irq, pdata); |
| 144 | } | 145 | } |
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index cbadc117d2db..c719b5a1d913 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h | |||
| @@ -42,10 +42,13 @@ dbx500_add_sdi(const char *name, resource_size_t base, int irq, | |||
| 42 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | 42 | return dbx500_add_amba_device(name, base, irq, pdata, 0); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | struct amba_pl011_data; | ||
| 46 | |||
| 45 | static inline struct amba_device * | 47 | static inline struct amba_device * |
| 46 | dbx500_add_uart(const char *name, resource_size_t base, int irq) | 48 | dbx500_add_uart(const char *name, resource_size_t base, int irq, |
| 49 | struct amba_pl011_data *pdata) | ||
| 47 | { | 50 | { |
| 48 | return dbx500_add_amba_device(name, base, irq, NULL, 0); | 51 | return dbx500_add_amba_device(name, base, irq, pdata, 0); |
| 49 | } | 52 | } |
| 50 | 53 | ||
| 51 | struct nmk_i2c_controller; | 54 | struct nmk_i2c_controller; |
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h index c8d7901c1f2d..94627f7783b0 100644 --- a/arch/arm/mach-ux500/devices-db5500.h +++ b/arch/arm/mach-ux500/devices-db5500.h | |||
| @@ -34,6 +34,9 @@ | |||
| 34 | #define db5500_add_rtc() \ | 34 | #define db5500_add_rtc() \ |
| 35 | dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); | 35 | dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); |
| 36 | 36 | ||
| 37 | #define db5500_add_usb(rx_cfg, tx_cfg) \ | ||
| 38 | ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) | ||
| 39 | |||
| 37 | #define db5500_add_sdi0(pdata) \ | 40 | #define db5500_add_sdi0(pdata) \ |
| 38 | dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata) | 41 | dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata) |
| 39 | #define db5500_add_sdi1(pdata) \ | 42 | #define db5500_add_sdi1(pdata) \ |
| @@ -54,13 +57,13 @@ | |||
| 54 | #define db5500_add_spi3(pdata) \ | 57 | #define db5500_add_spi3(pdata) \ |
| 55 | dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata) | 58 | dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata) |
| 56 | 59 | ||
| 57 | #define db5500_add_uart0() \ | 60 | #define db5500_add_uart0(plat) \ |
| 58 | dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0) | 61 | dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat) |
| 59 | #define db5500_add_uart1() \ | 62 | #define db5500_add_uart1(plat) \ |
| 60 | dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1) | 63 | dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat) |
| 61 | #define db5500_add_uart2() \ | 64 | #define db5500_add_uart2(plat) \ |
| 62 | dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2) | 65 | dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat) |
| 63 | #define db5500_add_uart3() \ | 66 | #define db5500_add_uart3(plat) \ |
| 64 | dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3) | 67 | dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat) |
| 65 | 68 | ||
| 66 | #endif | 69 | #endif |
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 23c695d54977..73b17404b194 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
| 12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
| 13 | #include <linux/amba/bus.h> | 13 | #include <linux/amba/bus.h> |
| 14 | #include <linux/amba/pl022.h> | ||
| 14 | 15 | ||
| 15 | #include <plat/ste_dma40.h> | 16 | #include <plat/ste_dma40.h> |
| 16 | 17 | ||
| @@ -67,12 +68,72 @@ struct stedma40_chan_cfg dma40_memcpy_conf_log = { | |||
| 67 | 68 | ||
| 68 | /* | 69 | /* |
| 69 | * Mapping between destination event lines and physical device address. | 70 | * Mapping between destination event lines and physical device address. |
| 70 | * The event line is tied to a device and therefor the address is constant. | 71 | * The event line is tied to a device and therefore the address is constant. |
| 72 | * When the address comes from a primecell it will be configured in runtime | ||
| 73 | * and we set the address to -1 as a placeholder. | ||
| 71 | */ | 74 | */ |
| 72 | static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV]; | 75 | static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = { |
| 76 | /* MUSB - these will be runtime-reconfigured */ | ||
| 77 | [DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1, | ||
| 78 | [DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1, | ||
| 79 | [DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1, | ||
| 80 | [DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1, | ||
| 81 | [DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1, | ||
| 82 | [DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1, | ||
| 83 | [DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1, | ||
| 84 | [DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1, | ||
| 85 | /* PrimeCells - run-time configured */ | ||
| 86 | [DB8500_DMA_DEV0_SPI0_TX] = -1, | ||
| 87 | [DB8500_DMA_DEV1_SD_MMC0_TX] = -1, | ||
| 88 | [DB8500_DMA_DEV2_SD_MMC1_TX] = -1, | ||
| 89 | [DB8500_DMA_DEV3_SD_MMC2_TX] = -1, | ||
| 90 | [DB8500_DMA_DEV8_SSP0_TX] = -1, | ||
| 91 | [DB8500_DMA_DEV9_SSP1_TX] = -1, | ||
| 92 | [DB8500_DMA_DEV11_UART2_TX] = -1, | ||
| 93 | [DB8500_DMA_DEV12_UART1_TX] = -1, | ||
| 94 | [DB8500_DMA_DEV13_UART0_TX] = -1, | ||
| 95 | [DB8500_DMA_DEV28_SD_MM2_TX] = -1, | ||
| 96 | [DB8500_DMA_DEV29_SD_MM0_TX] = -1, | ||
| 97 | [DB8500_DMA_DEV32_SD_MM1_TX] = -1, | ||
| 98 | [DB8500_DMA_DEV33_SPI2_TX] = -1, | ||
| 99 | [DB8500_DMA_DEV35_SPI1_TX] = -1, | ||
| 100 | [DB8500_DMA_DEV40_SPI3_TX] = -1, | ||
| 101 | [DB8500_DMA_DEV41_SD_MM3_TX] = -1, | ||
| 102 | [DB8500_DMA_DEV42_SD_MM4_TX] = -1, | ||
| 103 | [DB8500_DMA_DEV43_SD_MM5_TX] = -1, | ||
| 104 | }; | ||
| 73 | 105 | ||
| 74 | /* Mapping between source event lines and physical device address */ | 106 | /* Mapping between source event lines and physical device address */ |
| 75 | static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV]; | 107 | static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { |
| 108 | /* MUSB - these will be runtime-reconfigured */ | ||
| 109 | [DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1, | ||
| 110 | [DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1, | ||
| 111 | [DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1, | ||
| 112 | [DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1, | ||
| 113 | [DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1, | ||
| 114 | [DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1, | ||
| 115 | [DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1, | ||
| 116 | [DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1, | ||
| 117 | /* PrimeCells */ | ||
| 118 | [DB8500_DMA_DEV0_SPI0_RX] = -1, | ||
| 119 | [DB8500_DMA_DEV1_SD_MMC0_RX] = -1, | ||
| 120 | [DB8500_DMA_DEV2_SD_MMC1_RX] = -1, | ||
| 121 | [DB8500_DMA_DEV3_SD_MMC2_RX] = -1, | ||
| 122 | [DB8500_DMA_DEV8_SSP0_RX] = -1, | ||
| 123 | [DB8500_DMA_DEV9_SSP1_RX] = -1, | ||
| 124 | [DB8500_DMA_DEV11_UART2_RX] = -1, | ||
| 125 | [DB8500_DMA_DEV12_UART1_RX] = -1, | ||
| 126 | [DB8500_DMA_DEV13_UART0_RX] = -1, | ||
| 127 | [DB8500_DMA_DEV28_SD_MM2_RX] = -1, | ||
| 128 | [DB8500_DMA_DEV29_SD_MM0_RX] = -1, | ||
| 129 | [DB8500_DMA_DEV32_SD_MM1_RX] = -1, | ||
| 130 | [DB8500_DMA_DEV33_SPI2_RX] = -1, | ||
| 131 | [DB8500_DMA_DEV35_SPI1_RX] = -1, | ||
| 132 | [DB8500_DMA_DEV40_SPI3_RX] = -1, | ||
| 133 | [DB8500_DMA_DEV41_SD_MM3_RX] = -1, | ||
| 134 | [DB8500_DMA_DEV42_SD_MM4_RX] = -1, | ||
| 135 | [DB8500_DMA_DEV43_SD_MM5_RX] = -1, | ||
| 136 | }; | ||
| 76 | 137 | ||
| 77 | /* Reserved event lines for memcpy only */ | 138 | /* Reserved event lines for memcpy only */ |
| 78 | static int dma40_memcpy_event[] = { | 139 | static int dma40_memcpy_event[] = { |
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index 3a770c756979..9cc6f8f5d3e6 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h | |||
| @@ -61,6 +61,9 @@ db8500_add_ssp(const char *name, resource_size_t base, int irq, | |||
| 61 | #define db8500_add_rtc() \ | 61 | #define db8500_add_rtc() \ |
| 62 | dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); | 62 | dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); |
| 63 | 63 | ||
| 64 | #define db8500_add_usb(rx_cfg, tx_cfg) \ | ||
| 65 | ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) | ||
| 66 | |||
| 64 | #define db8500_add_sdi0(pdata) \ | 67 | #define db8500_add_sdi0(pdata) \ |
| 65 | dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata) | 68 | dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata) |
| 66 | #define db8500_add_sdi1(pdata) \ | 69 | #define db8500_add_sdi1(pdata) \ |
| @@ -88,11 +91,11 @@ db8500_add_ssp(const char *name, resource_size_t base, int irq, | |||
| 88 | #define db8500_add_spi3(pdata) \ | 91 | #define db8500_add_spi3(pdata) \ |
| 89 | dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata) | 92 | dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata) |
| 90 | 93 | ||
| 91 | #define db8500_add_uart0() \ | 94 | #define db8500_add_uart0(pdata) \ |
| 92 | dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0) | 95 | dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata) |
| 93 | #define db8500_add_uart1() \ | 96 | #define db8500_add_uart1(pdata) \ |
| 94 | dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1) | 97 | dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata) |
| 95 | #define db8500_add_uart2() \ | 98 | #define db8500_add_uart2(pdata) \ |
| 96 | dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2) | 99 | dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata) |
| 97 | 100 | ||
| 98 | #endif | 101 | #endif |
diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c index 32a061f8a95b..1cfab68ae417 100644 --- a/arch/arm/mach-ux500/dma-db5500.c +++ b/arch/arm/mach-ux500/dma-db5500.c | |||
| @@ -73,11 +73,27 @@ static struct stedma40_chan_cfg dma40_memcpy_conf_log = { | |||
| 73 | */ | 73 | */ |
| 74 | static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = { | 74 | static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = { |
| 75 | [DB5500_DMA_DEV24_SDMMC0_RX] = -1, | 75 | [DB5500_DMA_DEV24_SDMMC0_RX] = -1, |
| 76 | [DB5500_DMA_DEV38_USB_OTG_IEP_8] = -1, | ||
| 77 | [DB5500_DMA_DEV23_USB_OTG_IEP_7_15] = -1, | ||
| 78 | [DB5500_DMA_DEV22_USB_OTG_IEP_6_14] = -1, | ||
| 79 | [DB5500_DMA_DEV21_USB_OTG_IEP_5_13] = -1, | ||
| 80 | [DB5500_DMA_DEV20_USB_OTG_IEP_4_12] = -1, | ||
| 81 | [DB5500_DMA_DEV6_USB_OTG_IEP_3_11] = -1, | ||
| 82 | [DB5500_DMA_DEV5_USB_OTG_IEP_2_10] = -1, | ||
| 83 | [DB5500_DMA_DEV4_USB_OTG_IEP_1_9] = -1, | ||
| 76 | }; | 84 | }; |
| 77 | 85 | ||
| 78 | /* Mapping between destination event lines and physical device address */ | 86 | /* Mapping between destination event lines and physical device address */ |
| 79 | static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = { | 87 | static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = { |
| 80 | [DB5500_DMA_DEV24_SDMMC0_TX] = -1, | 88 | [DB5500_DMA_DEV24_SDMMC0_TX] = -1, |
| 89 | [DB5500_DMA_DEV38_USB_OTG_OEP_8] = -1, | ||
| 90 | [DB5500_DMA_DEV23_USB_OTG_OEP_7_15] = -1, | ||
| 91 | [DB5500_DMA_DEV22_USB_OTG_OEP_6_14] = -1, | ||
| 92 | [DB5500_DMA_DEV21_USB_OTG_OEP_5_13] = -1, | ||
| 93 | [DB5500_DMA_DEV20_USB_OTG_OEP_4_12] = -1, | ||
| 94 | [DB5500_DMA_DEV6_USB_OTG_OEP_3_11] = -1, | ||
| 95 | [DB5500_DMA_DEV5_USB_OTG_OEP_2_10] = -1, | ||
| 96 | [DB5500_DMA_DEV4_USB_OTG_OEP_1_9] = -1, | ||
| 81 | }; | 97 | }; |
| 82 | 98 | ||
| 83 | static int dma40_memcpy_event[] = { | 99 | static int dma40_memcpy_event[] = { |
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h index 9a6614c6808e..ab0fe1432fae 100644 --- a/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/arch/arm/mach-ux500/include/mach/uncompress.h | |||
| @@ -50,7 +50,11 @@ static void flush(void) | |||
| 50 | 50 | ||
| 51 | static inline void arch_decomp_setup(void) | 51 | static inline void arch_decomp_setup(void) |
| 52 | { | 52 | { |
| 53 | if (machine_is_u8500()) | 53 | /* Check in run time if we run on an U8500 or U5500 */ |
| 54 | if (machine_is_u8500() || | ||
| 55 | machine_is_svp8500v1() || | ||
| 56 | machine_is_svp8500v2() || | ||
| 57 | machine_is_hrefv60()) | ||
| 54 | ux500_uart_base = U8500_UART2_BASE; | 58 | ux500_uart_base = U8500_UART2_BASE; |
| 55 | else if (machine_is_u5500()) | 59 | else if (machine_is_u5500()) |
| 56 | ux500_uart_base = U5500_UART0_BASE; | 60 | ux500_uart_base = U5500_UART0_BASE; |
diff --git a/arch/arm/mach-ux500/include/mach/usb.h b/arch/arm/mach-ux500/include/mach/usb.h new file mode 100644 index 000000000000..d3739d418813 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/usb.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2011 | ||
| 3 | * | ||
| 4 | * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | ||
| 5 | * License terms: GNU General Public License (GPL) version 2 | ||
| 6 | */ | ||
| 7 | #ifndef __ASM_ARCH_USB_H | ||
| 8 | #define __ASM_ARCH_USB_H | ||
| 9 | |||
| 10 | #include <linux/dmaengine.h> | ||
| 11 | |||
| 12 | #define UX500_MUSB_DMA_NUM_RX_CHANNELS 8 | ||
| 13 | #define UX500_MUSB_DMA_NUM_TX_CHANNELS 8 | ||
| 14 | |||
| 15 | struct ux500_musb_board_data { | ||
| 16 | void **dma_rx_param_array; | ||
| 17 | void **dma_tx_param_array; | ||
| 18 | u32 num_rx_channels; | ||
| 19 | u32 num_tx_channels; | ||
| 20 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | ||
| 21 | }; | ||
| 22 | |||
| 23 | void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, | ||
| 24 | int *dma_tx_cfg); | ||
| 25 | #endif | ||
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c new file mode 100644 index 000000000000..82e535953fd9 --- /dev/null +++ b/arch/arm/mach-ux500/usb.c | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2011 | ||
| 3 | * | ||
| 4 | * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | ||
| 5 | * License terms: GNU General Public License (GPL) version 2 | ||
| 6 | */ | ||
| 7 | #include <linux/platform_device.h> | ||
| 8 | #include <linux/usb/musb.h> | ||
| 9 | #include <plat/ste_dma40.h> | ||
| 10 | #include <mach/hardware.h> | ||
| 11 | #include <mach/usb.h> | ||
| 12 | |||
| 13 | #define MUSB_DMA40_RX_CH { \ | ||
| 14 | .mode = STEDMA40_MODE_LOGICAL, \ | ||
| 15 | .dir = STEDMA40_PERIPH_TO_MEM, \ | ||
| 16 | .dst_dev_type = STEDMA40_DEV_DST_MEMORY, \ | ||
| 17 | .src_info.data_width = STEDMA40_WORD_WIDTH, \ | ||
| 18 | .dst_info.data_width = STEDMA40_WORD_WIDTH, \ | ||
| 19 | .src_info.psize = STEDMA40_PSIZE_LOG_16, \ | ||
| 20 | .dst_info.psize = STEDMA40_PSIZE_LOG_16, \ | ||
| 21 | } | ||
| 22 | |||
| 23 | #define MUSB_DMA40_TX_CH { \ | ||
| 24 | .mode = STEDMA40_MODE_LOGICAL, \ | ||
| 25 | .dir = STEDMA40_MEM_TO_PERIPH, \ | ||
| 26 | .src_dev_type = STEDMA40_DEV_SRC_MEMORY, \ | ||
| 27 | .src_info.data_width = STEDMA40_WORD_WIDTH, \ | ||
| 28 | .dst_info.data_width = STEDMA40_WORD_WIDTH, \ | ||
| 29 | .src_info.psize = STEDMA40_PSIZE_LOG_16, \ | ||
| 30 | .dst_info.psize = STEDMA40_PSIZE_LOG_16, \ | ||
| 31 | } | ||
| 32 | |||
| 33 | static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] | ||
| 34 | = { | ||
| 35 | MUSB_DMA40_RX_CH, | ||
| 36 | MUSB_DMA40_RX_CH, | ||
| 37 | MUSB_DMA40_RX_CH, | ||
| 38 | MUSB_DMA40_RX_CH, | ||
| 39 | MUSB_DMA40_RX_CH, | ||
| 40 | MUSB_DMA40_RX_CH, | ||
| 41 | MUSB_DMA40_RX_CH, | ||
| 42 | MUSB_DMA40_RX_CH | ||
| 43 | }; | ||
| 44 | |||
| 45 | static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] | ||
| 46 | = { | ||
| 47 | MUSB_DMA40_TX_CH, | ||
| 48 | MUSB_DMA40_TX_CH, | ||
| 49 | MUSB_DMA40_TX_CH, | ||
| 50 | MUSB_DMA40_TX_CH, | ||
| 51 | MUSB_DMA40_TX_CH, | ||
| 52 | MUSB_DMA40_TX_CH, | ||
| 53 | MUSB_DMA40_TX_CH, | ||
| 54 | MUSB_DMA40_TX_CH, | ||
| 55 | }; | ||
| 56 | |||
| 57 | static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { | ||
| 58 | &musb_dma_rx_ch[0], | ||
| 59 | &musb_dma_rx_ch[1], | ||
| 60 | &musb_dma_rx_ch[2], | ||
| 61 | &musb_dma_rx_ch[3], | ||
| 62 | &musb_dma_rx_ch[4], | ||
| 63 | &musb_dma_rx_ch[5], | ||
| 64 | &musb_dma_rx_ch[6], | ||
| 65 | &musb_dma_rx_ch[7] | ||
| 66 | }; | ||
| 67 | |||
| 68 | static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { | ||
| 69 | &musb_dma_tx_ch[0], | ||
| 70 | &musb_dma_tx_ch[1], | ||
| 71 | &musb_dma_tx_ch[2], | ||
| 72 | &musb_dma_tx_ch[3], | ||
| 73 | &musb_dma_tx_ch[4], | ||
| 74 | &musb_dma_tx_ch[5], | ||
| 75 | &musb_dma_tx_ch[6], | ||
| 76 | &musb_dma_tx_ch[7] | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct ux500_musb_board_data musb_board_data = { | ||
| 80 | .dma_rx_param_array = ux500_dma_rx_param_array, | ||
| 81 | .dma_tx_param_array = ux500_dma_tx_param_array, | ||
| 82 | .num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS, | ||
| 83 | .num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS, | ||
| 84 | .dma_filter = stedma40_filter, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static u64 ux500_musb_dmamask = DMA_BIT_MASK(32); | ||
| 88 | |||
| 89 | static struct musb_hdrc_config musb_hdrc_config = { | ||
| 90 | .multipoint = true, | ||
| 91 | .dyn_fifo = true, | ||
| 92 | .num_eps = 16, | ||
| 93 | .ram_bits = 16, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static struct musb_hdrc_platform_data musb_platform_data = { | ||
| 97 | #if defined(CONFIG_USB_MUSB_OTG) | ||
| 98 | .mode = MUSB_OTG, | ||
| 99 | #elif defined(CONFIG_USB_MUSB_PERIPHERAL) | ||
| 100 | .mode = MUSB_PERIPHERAL, | ||
| 101 | #else /* defined(CONFIG_USB_MUSB_HOST) */ | ||
| 102 | .mode = MUSB_HOST, | ||
| 103 | #endif | ||
| 104 | .config = &musb_hdrc_config, | ||
| 105 | .board_data = &musb_board_data, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static struct resource usb_resources[] = { | ||
| 109 | [0] = { | ||
| 110 | .name = "usb-mem", | ||
| 111 | .flags = IORESOURCE_MEM, | ||
| 112 | }, | ||
| 113 | |||
| 114 | [1] = { | ||
| 115 | .name = "mc", /* hard-coded in musb */ | ||
| 116 | .flags = IORESOURCE_IRQ, | ||
| 117 | }, | ||
| 118 | }; | ||
| 119 | |||
| 120 | struct platform_device ux500_musb_device = { | ||
| 121 | .name = "musb-ux500", | ||
| 122 | .id = 0, | ||
| 123 | .dev = { | ||
| 124 | .platform_data = &musb_platform_data, | ||
| 125 | .dma_mask = &ux500_musb_dmamask, | ||
| 126 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 127 | }, | ||
| 128 | .num_resources = ARRAY_SIZE(usb_resources), | ||
| 129 | .resource = usb_resources, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static inline void ux500_usb_dma_update_rx_ch_config(int *src_dev_type) | ||
| 133 | { | ||
| 134 | u32 idx; | ||
| 135 | |||
| 136 | for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++) | ||
| 137 | musb_dma_rx_ch[idx].src_dev_type = src_dev_type[idx]; | ||
| 138 | } | ||
| 139 | |||
| 140 | static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type) | ||
| 141 | { | ||
| 142 | u32 idx; | ||
| 143 | |||
| 144 | for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++) | ||
| 145 | musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx]; | ||
| 146 | } | ||
| 147 | |||
| 148 | void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, | ||
| 149 | int *dma_tx_cfg) | ||
| 150 | { | ||
| 151 | ux500_musb_device.resource[0].start = base; | ||
| 152 | ux500_musb_device.resource[0].end = base + SZ_64K - 1; | ||
| 153 | ux500_musb_device.resource[1].start = irq; | ||
| 154 | ux500_musb_device.resource[1].end = irq; | ||
| 155 | |||
| 156 | ux500_usb_dma_update_rx_ch_config(dma_rx_cfg); | ||
| 157 | ux500_usb_dma_update_tx_ch_config(dma_tx_cfg); | ||
| 158 | |||
| 159 | platform_device_register(&ux500_musb_device); | ||
| 160 | } | ||
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 1e88ecb846d1..70620426ee55 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
| @@ -30,23 +30,39 @@ | |||
| 30 | /* | 30 | /* |
| 31 | * The GPIO module in the Nomadik family of Systems-on-Chip is an | 31 | * The GPIO module in the Nomadik family of Systems-on-Chip is an |
| 32 | * AMBA device, managing 32 pins and alternate functions. The logic block | 32 | * AMBA device, managing 32 pins and alternate functions. The logic block |
| 33 | * is currently only used in the Nomadik. | 33 | * is currently used in the Nomadik and ux500. |
| 34 | * | 34 | * |
| 35 | * Symbols in this file are called "nmk_gpio" for "nomadik gpio" | 35 | * Symbols in this file are called "nmk_gpio" for "nomadik gpio" |
| 36 | */ | 36 | */ |
| 37 | 37 | ||
| 38 | #define NMK_GPIO_PER_CHIP 32 | 38 | #define NMK_GPIO_PER_CHIP 32 |
| 39 | |||
| 39 | struct nmk_gpio_chip { | 40 | struct nmk_gpio_chip { |
| 40 | struct gpio_chip chip; | 41 | struct gpio_chip chip; |
| 41 | void __iomem *addr; | 42 | void __iomem *addr; |
| 42 | struct clk *clk; | 43 | struct clk *clk; |
| 44 | unsigned int bank; | ||
| 43 | unsigned int parent_irq; | 45 | unsigned int parent_irq; |
| 46 | int secondary_parent_irq; | ||
| 47 | u32 (*get_secondary_status)(unsigned int bank); | ||
| 48 | void (*set_ioforce)(bool enable); | ||
| 44 | spinlock_t lock; | 49 | spinlock_t lock; |
| 45 | /* Keep track of configured edges */ | 50 | /* Keep track of configured edges */ |
| 46 | u32 edge_rising; | 51 | u32 edge_rising; |
| 47 | u32 edge_falling; | 52 | u32 edge_falling; |
| 53 | u32 real_wake; | ||
| 54 | u32 rwimsc; | ||
| 55 | u32 fwimsc; | ||
| 56 | u32 slpm; | ||
| 48 | }; | 57 | }; |
| 49 | 58 | ||
| 59 | static struct nmk_gpio_chip * | ||
| 60 | nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)]; | ||
| 61 | |||
| 62 | static DEFINE_SPINLOCK(nmk_gpio_slpm_lock); | ||
| 63 | |||
| 64 | #define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips) | ||
| 65 | |||
| 50 | static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, | 66 | static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip, |
| 51 | unsigned offset, int gpio_mode) | 67 | unsigned offset, int gpio_mode) |
| 52 | { | 68 | { |
| @@ -118,8 +134,35 @@ static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | |||
| 118 | __nmk_gpio_set_output(nmk_chip, offset, val); | 134 | __nmk_gpio_set_output(nmk_chip, offset, val); |
| 119 | } | 135 | } |
| 120 | 136 | ||
| 137 | static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip, | ||
| 138 | unsigned offset, int gpio_mode, | ||
| 139 | bool glitch) | ||
| 140 | { | ||
| 141 | u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 142 | u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 143 | |||
| 144 | if (glitch && nmk_chip->set_ioforce) { | ||
| 145 | u32 bit = BIT(offset); | ||
| 146 | |||
| 147 | /* Prevent spurious wakeups */ | ||
| 148 | writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 149 | writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 150 | |||
| 151 | nmk_chip->set_ioforce(true); | ||
| 152 | } | ||
| 153 | |||
| 154 | __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode); | ||
| 155 | |||
| 156 | if (glitch && nmk_chip->set_ioforce) { | ||
| 157 | nmk_chip->set_ioforce(false); | ||
| 158 | |||
| 159 | writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 160 | writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 164 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
| 122 | pin_cfg_t cfg, bool sleep) | 165 | pin_cfg_t cfg, bool sleep, unsigned int *slpmregs) |
| 123 | { | 166 | { |
| 124 | static const char *afnames[] = { | 167 | static const char *afnames[] = { |
| 125 | [NMK_GPIO_ALT_GPIO] = "GPIO", | 168 | [NMK_GPIO_ALT_GPIO] = "GPIO", |
| @@ -144,6 +187,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
| 144 | int slpm = PIN_SLPM(cfg); | 187 | int slpm = PIN_SLPM(cfg); |
| 145 | int output = PIN_DIR(cfg); | 188 | int output = PIN_DIR(cfg); |
| 146 | int val = PIN_VAL(cfg); | 189 | int val = PIN_VAL(cfg); |
| 190 | bool glitch = af == NMK_GPIO_ALT_C; | ||
| 147 | 191 | ||
| 148 | dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", | 192 | dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", |
| 149 | pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], | 193 | pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], |
| @@ -155,6 +199,8 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
| 155 | int slpm_output = PIN_SLPM_DIR(cfg); | 199 | int slpm_output = PIN_SLPM_DIR(cfg); |
| 156 | int slpm_val = PIN_SLPM_VAL(cfg); | 200 | int slpm_val = PIN_SLPM_VAL(cfg); |
| 157 | 201 | ||
| 202 | af = NMK_GPIO_ALT_GPIO; | ||
| 203 | |||
| 158 | /* | 204 | /* |
| 159 | * The SLPM_* values are normal values + 1 to allow zero to | 205 | * The SLPM_* values are normal values + 1 to allow zero to |
| 160 | * mean "same as normal". | 206 | * mean "same as normal". |
| @@ -180,8 +226,116 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
| 180 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | 226 | __nmk_gpio_set_pull(nmk_chip, offset, pull); |
| 181 | } | 227 | } |
| 182 | 228 | ||
| 183 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); | 229 | /* |
| 184 | __nmk_gpio_set_mode(nmk_chip, offset, af); | 230 | * If we've backed up the SLPM registers (glitch workaround), modify |
| 231 | * the backups since they will be restored. | ||
| 232 | */ | ||
| 233 | if (slpmregs) { | ||
| 234 | if (slpm == NMK_GPIO_SLPM_NOCHANGE) | ||
| 235 | slpmregs[nmk_chip->bank] |= BIT(offset); | ||
| 236 | else | ||
| 237 | slpmregs[nmk_chip->bank] &= ~BIT(offset); | ||
| 238 | } else | ||
| 239 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); | ||
| 240 | |||
| 241 | __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch); | ||
| 242 | } | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Safe sequence used to switch IOs between GPIO and Alternate-C mode: | ||
| 246 | * - Save SLPM registers | ||
| 247 | * - Set SLPM=0 for the IOs you want to switch and others to 1 | ||
| 248 | * - Configure the GPIO registers for the IOs that are being switched | ||
| 249 | * - Set IOFORCE=1 | ||
| 250 | * - Modify the AFLSA/B registers for the IOs that are being switched | ||
| 251 | * - Set IOFORCE=0 | ||
| 252 | * - Restore SLPM registers | ||
| 253 | * - Any spurious wake up event during switch sequence to be ignored and | ||
| 254 | * cleared | ||
| 255 | */ | ||
| 256 | static void nmk_gpio_glitch_slpm_init(unsigned int *slpm) | ||
| 257 | { | ||
| 258 | int i; | ||
| 259 | |||
| 260 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 261 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 262 | unsigned int temp = slpm[i]; | ||
| 263 | |||
| 264 | if (!chip) | ||
| 265 | break; | ||
| 266 | |||
| 267 | slpm[i] = readl(chip->addr + NMK_GPIO_SLPC); | ||
| 268 | writel(temp, chip->addr + NMK_GPIO_SLPC); | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 272 | static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm) | ||
| 273 | { | ||
| 274 | int i; | ||
| 275 | |||
| 276 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 277 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 278 | |||
| 279 | if (!chip) | ||
| 280 | break; | ||
| 281 | |||
| 282 | writel(slpm[i], chip->addr + NMK_GPIO_SLPC); | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) | ||
| 287 | { | ||
| 288 | static unsigned int slpm[NUM_BANKS]; | ||
| 289 | unsigned long flags; | ||
| 290 | bool glitch = false; | ||
| 291 | int ret = 0; | ||
| 292 | int i; | ||
| 293 | |||
| 294 | for (i = 0; i < num; i++) { | ||
| 295 | if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) { | ||
| 296 | glitch = true; | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | ||
| 302 | |||
| 303 | if (glitch) { | ||
| 304 | memset(slpm, 0xff, sizeof(slpm)); | ||
| 305 | |||
| 306 | for (i = 0; i < num; i++) { | ||
| 307 | int pin = PIN_NUM(cfgs[i]); | ||
| 308 | int offset = pin % NMK_GPIO_PER_CHIP; | ||
| 309 | |||
| 310 | if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) | ||
| 311 | slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset); | ||
| 312 | } | ||
| 313 | |||
| 314 | nmk_gpio_glitch_slpm_init(slpm); | ||
| 315 | } | ||
| 316 | |||
| 317 | for (i = 0; i < num; i++) { | ||
| 318 | struct nmk_gpio_chip *nmk_chip; | ||
| 319 | int pin = PIN_NUM(cfgs[i]); | ||
| 320 | |||
| 321 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(pin)); | ||
| 322 | if (!nmk_chip) { | ||
| 323 | ret = -EINVAL; | ||
| 324 | break; | ||
| 325 | } | ||
| 326 | |||
| 327 | spin_lock(&nmk_chip->lock); | ||
| 328 | __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base, | ||
| 329 | cfgs[i], sleep, glitch ? slpm : NULL); | ||
| 330 | spin_unlock(&nmk_chip->lock); | ||
| 331 | } | ||
| 332 | |||
| 333 | if (glitch) | ||
| 334 | nmk_gpio_glitch_slpm_restore(slpm); | ||
| 335 | |||
| 336 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 337 | |||
| 338 | return ret; | ||
| 185 | } | 339 | } |
| 186 | 340 | ||
| 187 | /** | 341 | /** |
| @@ -200,19 +354,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
| 200 | */ | 354 | */ |
| 201 | int nmk_config_pin(pin_cfg_t cfg, bool sleep) | 355 | int nmk_config_pin(pin_cfg_t cfg, bool sleep) |
| 202 | { | 356 | { |
| 203 | struct nmk_gpio_chip *nmk_chip; | 357 | return __nmk_config_pins(&cfg, 1, sleep); |
| 204 | int gpio = PIN_NUM(cfg); | ||
| 205 | unsigned long flags; | ||
| 206 | |||
| 207 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 208 | if (!nmk_chip) | ||
| 209 | return -EINVAL; | ||
| 210 | |||
| 211 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 212 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg, sleep); | ||
| 213 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | 358 | } |
| 217 | EXPORT_SYMBOL(nmk_config_pin); | 359 | EXPORT_SYMBOL(nmk_config_pin); |
| 218 | 360 | ||
| @@ -226,31 +368,13 @@ EXPORT_SYMBOL(nmk_config_pin); | |||
| 226 | */ | 368 | */ |
| 227 | int nmk_config_pins(pin_cfg_t *cfgs, int num) | 369 | int nmk_config_pins(pin_cfg_t *cfgs, int num) |
| 228 | { | 370 | { |
| 229 | int ret = 0; | 371 | return __nmk_config_pins(cfgs, num, false); |
| 230 | int i; | ||
| 231 | |||
| 232 | for (i = 0; i < num; i++) { | ||
| 233 | ret = nmk_config_pin(cfgs[i], false); | ||
| 234 | if (ret) | ||
| 235 | break; | ||
| 236 | } | ||
| 237 | |||
| 238 | return ret; | ||
| 239 | } | 372 | } |
| 240 | EXPORT_SYMBOL(nmk_config_pins); | 373 | EXPORT_SYMBOL(nmk_config_pins); |
| 241 | 374 | ||
| 242 | int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) | 375 | int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) |
| 243 | { | 376 | { |
| 244 | int ret = 0; | 377 | return __nmk_config_pins(cfgs, num, true); |
| 245 | int i; | ||
| 246 | |||
| 247 | for (i = 0; i < num; i++) { | ||
| 248 | ret = nmk_config_pin(cfgs[i], true); | ||
| 249 | if (ret) | ||
| 250 | break; | ||
| 251 | } | ||
| 252 | |||
| 253 | return ret; | ||
| 254 | } | 378 | } |
| 255 | EXPORT_SYMBOL(nmk_config_pins_sleep); | 379 | EXPORT_SYMBOL(nmk_config_pins_sleep); |
| 256 | 380 | ||
| @@ -277,9 +401,13 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | |||
| 277 | if (!nmk_chip) | 401 | if (!nmk_chip) |
| 278 | return -EINVAL; | 402 | return -EINVAL; |
| 279 | 403 | ||
| 280 | spin_lock_irqsave(&nmk_chip->lock, flags); | 404 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
| 405 | spin_lock(&nmk_chip->lock); | ||
| 406 | |||
| 281 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode); | 407 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode); |
| 282 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 408 | |
| 409 | spin_unlock(&nmk_chip->lock); | ||
| 410 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 283 | 411 | ||
| 284 | return 0; | 412 | return 0; |
| 285 | } | 413 | } |
| @@ -314,6 +442,15 @@ int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull) | |||
| 314 | } | 442 | } |
| 315 | 443 | ||
| 316 | /* Mode functions */ | 444 | /* Mode functions */ |
| 445 | /** | ||
| 446 | * nmk_gpio_set_mode() - set the mux mode of a gpio pin | ||
| 447 | * @gpio: pin number | ||
| 448 | * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A, | ||
| 449 | * NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C | ||
| 450 | * | ||
| 451 | * Sets the mode of the specified pin to one of the alternate functions or | ||
| 452 | * plain GPIO. | ||
| 453 | */ | ||
| 317 | int nmk_gpio_set_mode(int gpio, int gpio_mode) | 454 | int nmk_gpio_set_mode(int gpio, int gpio_mode) |
| 318 | { | 455 | { |
| 319 | struct nmk_gpio_chip *nmk_chip; | 456 | struct nmk_gpio_chip *nmk_chip; |
| @@ -401,8 +538,20 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, | |||
| 401 | } | 538 | } |
| 402 | } | 539 | } |
| 403 | 540 | ||
| 404 | static int nmk_gpio_irq_modify(struct irq_data *d, enum nmk_gpio_irq_type which, | 541 | static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, |
| 405 | bool enable) | 542 | int gpio, bool on) |
| 543 | { | ||
| 544 | #ifdef CONFIG_ARCH_U8500 | ||
| 545 | if (cpu_is_u8500v2()) { | ||
| 546 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, | ||
| 547 | on ? NMK_GPIO_SLPM_WAKEUP_ENABLE | ||
| 548 | : NMK_GPIO_SLPM_WAKEUP_DISABLE); | ||
| 549 | } | ||
| 550 | #endif | ||
| 551 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); | ||
| 552 | } | ||
| 553 | |||
| 554 | static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) | ||
| 406 | { | 555 | { |
| 407 | int gpio; | 556 | int gpio; |
| 408 | struct nmk_gpio_chip *nmk_chip; | 557 | struct nmk_gpio_chip *nmk_chip; |
| @@ -415,44 +564,58 @@ static int nmk_gpio_irq_modify(struct irq_data *d, enum nmk_gpio_irq_type which, | |||
| 415 | if (!nmk_chip) | 564 | if (!nmk_chip) |
| 416 | return -EINVAL; | 565 | return -EINVAL; |
| 417 | 566 | ||
| 418 | spin_lock_irqsave(&nmk_chip->lock, flags); | 567 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
| 419 | __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable); | 568 | spin_lock(&nmk_chip->lock); |
| 420 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 569 | |
| 570 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, enable); | ||
| 571 | |||
| 572 | if (!(nmk_chip->real_wake & bitmask)) | ||
| 573 | __nmk_gpio_set_wake(nmk_chip, gpio, enable); | ||
| 574 | |||
| 575 | spin_unlock(&nmk_chip->lock); | ||
| 576 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 421 | 577 | ||
| 422 | return 0; | 578 | return 0; |
| 423 | } | 579 | } |
| 424 | 580 | ||
| 425 | static void nmk_gpio_irq_mask(struct irq_data *d) | 581 | static void nmk_gpio_irq_mask(struct irq_data *d) |
| 426 | { | 582 | { |
| 427 | nmk_gpio_irq_modify(d, NORMAL, false); | 583 | nmk_gpio_irq_maskunmask(d, false); |
| 428 | } | 584 | } |
| 429 | 585 | ||
| 430 | static void nmk_gpio_irq_unmask(struct irq_data *d) | 586 | static void nmk_gpio_irq_unmask(struct irq_data *d) |
| 431 | { | 587 | { |
| 432 | nmk_gpio_irq_modify(d, NORMAL, true); | 588 | nmk_gpio_irq_maskunmask(d, true); |
| 433 | } | 589 | } |
| 434 | 590 | ||
| 435 | static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | 591 | static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) |
| 436 | { | 592 | { |
| 593 | struct irq_desc *desc = irq_to_desc(d->irq); | ||
| 594 | bool enabled = !(desc->status & IRQ_DISABLED); | ||
| 437 | struct nmk_gpio_chip *nmk_chip; | 595 | struct nmk_gpio_chip *nmk_chip; |
| 438 | unsigned long flags; | 596 | unsigned long flags; |
| 597 | u32 bitmask; | ||
| 439 | int gpio; | 598 | int gpio; |
| 440 | 599 | ||
| 441 | gpio = NOMADIK_IRQ_TO_GPIO(d->irq); | 600 | gpio = NOMADIK_IRQ_TO_GPIO(d->irq); |
| 442 | nmk_chip = irq_data_get_irq_chip_data(d); | 601 | nmk_chip = irq_data_get_irq_chip_data(d); |
| 443 | if (!nmk_chip) | 602 | if (!nmk_chip) |
| 444 | return -EINVAL; | 603 | return -EINVAL; |
| 604 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 445 | 605 | ||
| 446 | spin_lock_irqsave(&nmk_chip->lock, flags); | 606 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
| 447 | #ifdef CONFIG_ARCH_U8500 | 607 | spin_lock(&nmk_chip->lock); |
| 448 | if (cpu_is_u8500v2()) { | 608 | |
| 449 | __nmk_gpio_set_slpm(nmk_chip, gpio, | 609 | if (!enabled) |
| 450 | on ? NMK_GPIO_SLPM_WAKEUP_ENABLE | 610 | __nmk_gpio_set_wake(nmk_chip, gpio, on); |
| 451 | : NMK_GPIO_SLPM_WAKEUP_DISABLE); | 611 | |
| 452 | } | 612 | if (on) |
| 453 | #endif | 613 | nmk_chip->real_wake |= bitmask; |
| 454 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); | 614 | else |
| 455 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 615 | nmk_chip->real_wake &= ~bitmask; |
| 616 | |||
| 617 | spin_unlock(&nmk_chip->lock); | ||
| 618 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | ||
| 456 | 619 | ||
| 457 | return 0; | 620 | return 0; |
| 458 | } | 621 | } |
| @@ -483,7 +646,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
| 483 | if (enabled) | 646 | if (enabled) |
| 484 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false); | 647 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false); |
| 485 | 648 | ||
| 486 | if (wake) | 649 | if (enabled || wake) |
| 487 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false); | 650 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false); |
| 488 | 651 | ||
| 489 | nmk_chip->edge_rising &= ~bitmask; | 652 | nmk_chip->edge_rising &= ~bitmask; |
| @@ -497,7 +660,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
| 497 | if (enabled) | 660 | if (enabled) |
| 498 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true); | 661 | __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true); |
| 499 | 662 | ||
| 500 | if (wake) | 663 | if (enabled || wake) |
| 501 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); | 664 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); |
| 502 | 665 | ||
| 503 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 666 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
| @@ -514,12 +677,11 @@ static struct irq_chip nmk_gpio_irq_chip = { | |||
| 514 | .irq_set_wake = nmk_gpio_irq_set_wake, | 677 | .irq_set_wake = nmk_gpio_irq_set_wake, |
| 515 | }; | 678 | }; |
| 516 | 679 | ||
| 517 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 680 | static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, |
| 681 | u32 status) | ||
| 518 | { | 682 | { |
| 519 | struct nmk_gpio_chip *nmk_chip; | 683 | struct nmk_gpio_chip *nmk_chip; |
| 520 | struct irq_chip *host_chip = get_irq_chip(irq); | 684 | struct irq_chip *host_chip = get_irq_chip(irq); |
| 521 | unsigned int gpio_irq; | ||
| 522 | u32 pending; | ||
| 523 | unsigned int first_irq; | 685 | unsigned int first_irq; |
| 524 | 686 | ||
| 525 | if (host_chip->irq_mask_ack) | 687 | if (host_chip->irq_mask_ack) |
| @@ -532,29 +694,56 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 532 | 694 | ||
| 533 | nmk_chip = get_irq_data(irq); | 695 | nmk_chip = get_irq_data(irq); |
| 534 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | 696 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); |
| 535 | while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { | 697 | while (status) { |
| 536 | gpio_irq = first_irq + __ffs(pending); | 698 | int bit = __ffs(status); |
| 537 | generic_handle_irq(gpio_irq); | 699 | |
| 700 | generic_handle_irq(first_irq + bit); | ||
| 701 | status &= ~BIT(bit); | ||
| 538 | } | 702 | } |
| 539 | 703 | ||
| 540 | host_chip->irq_unmask(&desc->irq_data); | 704 | host_chip->irq_unmask(&desc->irq_data); |
| 541 | } | 705 | } |
| 542 | 706 | ||
| 707 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 708 | { | ||
| 709 | struct nmk_gpio_chip *nmk_chip = get_irq_data(irq); | ||
| 710 | u32 status = readl(nmk_chip->addr + NMK_GPIO_IS); | ||
| 711 | |||
| 712 | __nmk_gpio_irq_handler(irq, desc, status); | ||
| 713 | } | ||
| 714 | |||
| 715 | static void nmk_gpio_secondary_irq_handler(unsigned int irq, | ||
| 716 | struct irq_desc *desc) | ||
| 717 | { | ||
| 718 | struct nmk_gpio_chip *nmk_chip = get_irq_data(irq); | ||
| 719 | u32 status = nmk_chip->get_secondary_status(nmk_chip->bank); | ||
| 720 | |||
| 721 | __nmk_gpio_irq_handler(irq, desc, status); | ||
| 722 | } | ||
| 723 | |||
| 543 | static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) | 724 | static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) |
| 544 | { | 725 | { |
| 545 | unsigned int first_irq; | 726 | unsigned int first_irq; |
| 546 | int i; | 727 | int i; |
| 547 | 728 | ||
| 548 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | 729 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); |
| 549 | for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) { | 730 | for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) { |
| 550 | set_irq_chip(i, &nmk_gpio_irq_chip); | 731 | set_irq_chip(i, &nmk_gpio_irq_chip); |
| 551 | set_irq_handler(i, handle_edge_irq); | 732 | set_irq_handler(i, handle_edge_irq); |
| 552 | set_irq_flags(i, IRQF_VALID); | 733 | set_irq_flags(i, IRQF_VALID); |
| 553 | set_irq_chip_data(i, nmk_chip); | 734 | set_irq_chip_data(i, nmk_chip); |
| 554 | set_irq_type(i, IRQ_TYPE_EDGE_FALLING); | 735 | set_irq_type(i, IRQ_TYPE_EDGE_FALLING); |
| 555 | } | 736 | } |
| 737 | |||
| 556 | set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); | 738 | set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); |
| 557 | set_irq_data(nmk_chip->parent_irq, nmk_chip); | 739 | set_irq_data(nmk_chip->parent_irq, nmk_chip); |
| 740 | |||
| 741 | if (nmk_chip->secondary_parent_irq >= 0) { | ||
| 742 | set_irq_chained_handler(nmk_chip->secondary_parent_irq, | ||
| 743 | nmk_gpio_secondary_irq_handler); | ||
| 744 | set_irq_data(nmk_chip->secondary_parent_irq, nmk_chip); | ||
| 745 | } | ||
| 746 | |||
| 558 | return 0; | 747 | return 0; |
| 559 | } | 748 | } |
| 560 | 749 | ||
| @@ -605,6 +794,97 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 605 | return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset; | 794 | return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset; |
| 606 | } | 795 | } |
| 607 | 796 | ||
| 797 | #ifdef CONFIG_DEBUG_FS | ||
| 798 | |||
| 799 | #include <linux/seq_file.h> | ||
| 800 | |||
| 801 | static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
| 802 | { | ||
| 803 | int mode; | ||
| 804 | unsigned i; | ||
| 805 | unsigned gpio = chip->base; | ||
| 806 | int is_out; | ||
| 807 | struct nmk_gpio_chip *nmk_chip = | ||
| 808 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 809 | const char *modes[] = { | ||
| 810 | [NMK_GPIO_ALT_GPIO] = "gpio", | ||
| 811 | [NMK_GPIO_ALT_A] = "altA", | ||
| 812 | [NMK_GPIO_ALT_B] = "altB", | ||
| 813 | [NMK_GPIO_ALT_C] = "altC", | ||
| 814 | }; | ||
| 815 | |||
| 816 | for (i = 0; i < chip->ngpio; i++, gpio++) { | ||
| 817 | const char *label = gpiochip_is_requested(chip, i); | ||
| 818 | bool pull; | ||
| 819 | u32 bit = 1 << i; | ||
| 820 | |||
| 821 | if (!label) | ||
| 822 | continue; | ||
| 823 | |||
| 824 | is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit; | ||
| 825 | pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); | ||
| 826 | mode = nmk_gpio_get_mode(gpio); | ||
| 827 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", | ||
| 828 | gpio, label, | ||
| 829 | is_out ? "out" : "in ", | ||
| 830 | chip->get | ||
| 831 | ? (chip->get(chip, i) ? "hi" : "lo") | ||
| 832 | : "? ", | ||
| 833 | (mode < 0) ? "unknown" : modes[mode], | ||
| 834 | pull ? "pull" : "none"); | ||
| 835 | |||
| 836 | if (!is_out) { | ||
| 837 | int irq = gpio_to_irq(gpio); | ||
| 838 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 839 | |||
| 840 | /* This races with request_irq(), set_irq_type(), | ||
| 841 | * and set_irq_wake() ... but those are "rare". | ||
| 842 | * | ||
| 843 | * More significantly, trigger type flags aren't | ||
| 844 | * currently maintained by genirq. | ||
| 845 | */ | ||
| 846 | if (irq >= 0 && desc->action) { | ||
| 847 | char *trigger; | ||
| 848 | |||
| 849 | switch (desc->status & IRQ_TYPE_SENSE_MASK) { | ||
| 850 | case IRQ_TYPE_NONE: | ||
| 851 | trigger = "(default)"; | ||
| 852 | break; | ||
| 853 | case IRQ_TYPE_EDGE_FALLING: | ||
| 854 | trigger = "edge-falling"; | ||
| 855 | break; | ||
| 856 | case IRQ_TYPE_EDGE_RISING: | ||
| 857 | trigger = "edge-rising"; | ||
| 858 | break; | ||
| 859 | case IRQ_TYPE_EDGE_BOTH: | ||
| 860 | trigger = "edge-both"; | ||
| 861 | break; | ||
| 862 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 863 | trigger = "level-high"; | ||
| 864 | break; | ||
| 865 | case IRQ_TYPE_LEVEL_LOW: | ||
| 866 | trigger = "level-low"; | ||
| 867 | break; | ||
| 868 | default: | ||
| 869 | trigger = "?trigger?"; | ||
| 870 | break; | ||
| 871 | } | ||
| 872 | |||
| 873 | seq_printf(s, " irq-%d %s%s", | ||
| 874 | irq, trigger, | ||
| 875 | (desc->status & IRQ_WAKEUP) | ||
| 876 | ? " wakeup" : ""); | ||
| 877 | } | ||
| 878 | } | ||
| 879 | |||
| 880 | seq_printf(s, "\n"); | ||
| 881 | } | ||
| 882 | } | ||
| 883 | |||
| 884 | #else | ||
| 885 | #define nmk_gpio_dbg_show NULL | ||
| 886 | #endif | ||
| 887 | |||
| 608 | /* This structure is replicated for each GPIO block allocated at probe time */ | 888 | /* This structure is replicated for each GPIO block allocated at probe time */ |
| 609 | static struct gpio_chip nmk_gpio_template = { | 889 | static struct gpio_chip nmk_gpio_template = { |
| 610 | .direction_input = nmk_gpio_make_input, | 890 | .direction_input = nmk_gpio_make_input, |
| @@ -612,10 +892,64 @@ static struct gpio_chip nmk_gpio_template = { | |||
| 612 | .direction_output = nmk_gpio_make_output, | 892 | .direction_output = nmk_gpio_make_output, |
| 613 | .set = nmk_gpio_set_output, | 893 | .set = nmk_gpio_set_output, |
| 614 | .to_irq = nmk_gpio_to_irq, | 894 | .to_irq = nmk_gpio_to_irq, |
| 615 | .ngpio = NMK_GPIO_PER_CHIP, | 895 | .dbg_show = nmk_gpio_dbg_show, |
| 616 | .can_sleep = 0, | 896 | .can_sleep = 0, |
| 617 | }; | 897 | }; |
| 618 | 898 | ||
| 899 | /* | ||
| 900 | * Called from the suspend/resume path to only keep the real wakeup interrupts | ||
| 901 | * (those that have had set_irq_wake() called on them) as wakeup interrupts, | ||
| 902 | * and not the rest of the interrupts which we needed to have as wakeups for | ||
| 903 | * cpuidle. | ||
| 904 | * | ||
| 905 | * PM ops are not used since this needs to be done at the end, after all the | ||
| 906 | * other drivers are done with their suspend callbacks. | ||
| 907 | */ | ||
| 908 | void nmk_gpio_wakeups_suspend(void) | ||
| 909 | { | ||
| 910 | int i; | ||
| 911 | |||
| 912 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 913 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 914 | |||
| 915 | if (!chip) | ||
| 916 | break; | ||
| 917 | |||
| 918 | chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC); | ||
| 919 | chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC); | ||
| 920 | |||
| 921 | writel(chip->rwimsc & chip->real_wake, | ||
| 922 | chip->addr + NMK_GPIO_RWIMSC); | ||
| 923 | writel(chip->fwimsc & chip->real_wake, | ||
| 924 | chip->addr + NMK_GPIO_FWIMSC); | ||
| 925 | |||
| 926 | if (cpu_is_u8500v2()) { | ||
| 927 | chip->slpm = readl(chip->addr + NMK_GPIO_SLPC); | ||
| 928 | |||
| 929 | /* 0 -> wakeup enable */ | ||
| 930 | writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC); | ||
| 931 | } | ||
| 932 | } | ||
| 933 | } | ||
| 934 | |||
| 935 | void nmk_gpio_wakeups_resume(void) | ||
| 936 | { | ||
| 937 | int i; | ||
| 938 | |||
| 939 | for (i = 0; i < NUM_BANKS; i++) { | ||
| 940 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
| 941 | |||
| 942 | if (!chip) | ||
| 943 | break; | ||
| 944 | |||
| 945 | writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC); | ||
| 946 | writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC); | ||
| 947 | |||
| 948 | if (cpu_is_u8500v2()) | ||
| 949 | writel(chip->slpm, chip->addr + NMK_GPIO_SLPC); | ||
| 950 | } | ||
| 951 | } | ||
| 952 | |||
| 619 | static int __devinit nmk_gpio_probe(struct platform_device *dev) | 953 | static int __devinit nmk_gpio_probe(struct platform_device *dev) |
| 620 | { | 954 | { |
| 621 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; | 955 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; |
| @@ -623,6 +957,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
| 623 | struct gpio_chip *chip; | 957 | struct gpio_chip *chip; |
| 624 | struct resource *res; | 958 | struct resource *res; |
| 625 | struct clk *clk; | 959 | struct clk *clk; |
| 960 | int secondary_irq; | ||
| 626 | int irq; | 961 | int irq; |
| 627 | int ret; | 962 | int ret; |
| 628 | 963 | ||
| @@ -641,6 +976,12 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
| 641 | goto out; | 976 | goto out; |
| 642 | } | 977 | } |
| 643 | 978 | ||
| 979 | secondary_irq = platform_get_irq(dev, 1); | ||
| 980 | if (secondary_irq >= 0 && !pdata->get_secondary_status) { | ||
| 981 | ret = -EINVAL; | ||
| 982 | goto out; | ||
| 983 | } | ||
| 984 | |||
| 644 | if (request_mem_region(res->start, resource_size(res), | 985 | if (request_mem_region(res->start, resource_size(res), |
| 645 | dev_name(&dev->dev)) == NULL) { | 986 | dev_name(&dev->dev)) == NULL) { |
| 646 | ret = -EBUSY; | 987 | ret = -EBUSY; |
| @@ -664,14 +1005,19 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
| 664 | * The virt address in nmk_chip->addr is in the nomadik register space, | 1005 | * The virt address in nmk_chip->addr is in the nomadik register space, |
| 665 | * so we can simply convert the resource address, without remapping | 1006 | * so we can simply convert the resource address, without remapping |
| 666 | */ | 1007 | */ |
| 1008 | nmk_chip->bank = dev->id; | ||
| 667 | nmk_chip->clk = clk; | 1009 | nmk_chip->clk = clk; |
| 668 | nmk_chip->addr = io_p2v(res->start); | 1010 | nmk_chip->addr = io_p2v(res->start); |
| 669 | nmk_chip->chip = nmk_gpio_template; | 1011 | nmk_chip->chip = nmk_gpio_template; |
| 670 | nmk_chip->parent_irq = irq; | 1012 | nmk_chip->parent_irq = irq; |
| 1013 | nmk_chip->secondary_parent_irq = secondary_irq; | ||
| 1014 | nmk_chip->get_secondary_status = pdata->get_secondary_status; | ||
| 1015 | nmk_chip->set_ioforce = pdata->set_ioforce; | ||
| 671 | spin_lock_init(&nmk_chip->lock); | 1016 | spin_lock_init(&nmk_chip->lock); |
| 672 | 1017 | ||
| 673 | chip = &nmk_chip->chip; | 1018 | chip = &nmk_chip->chip; |
| 674 | chip->base = pdata->first_gpio; | 1019 | chip->base = pdata->first_gpio; |
| 1020 | chip->ngpio = pdata->num_gpio; | ||
| 675 | chip->label = pdata->name ?: dev_name(&dev->dev); | 1021 | chip->label = pdata->name ?: dev_name(&dev->dev); |
| 676 | chip->dev = &dev->dev; | 1022 | chip->dev = &dev->dev; |
| 677 | chip->owner = THIS_MODULE; | 1023 | chip->owner = THIS_MODULE; |
| @@ -680,6 +1026,9 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
| 680 | if (ret) | 1026 | if (ret) |
| 681 | goto out_free; | 1027 | goto out_free; |
| 682 | 1028 | ||
| 1029 | BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips)); | ||
| 1030 | |||
| 1031 | nmk_gpio_chips[nmk_chip->bank] = nmk_chip; | ||
| 683 | platform_set_drvdata(dev, nmk_chip); | 1032 | platform_set_drvdata(dev, nmk_chip); |
| 684 | 1033 | ||
| 685 | nmk_gpio_init_irq(nmk_chip); | 1034 | nmk_gpio_init_irq(nmk_chip); |
| @@ -705,10 +1054,8 @@ static struct platform_driver nmk_gpio_driver = { | |||
| 705 | .driver = { | 1054 | .driver = { |
| 706 | .owner = THIS_MODULE, | 1055 | .owner = THIS_MODULE, |
| 707 | .name = "gpio", | 1056 | .name = "gpio", |
| 708 | }, | 1057 | }, |
| 709 | .probe = nmk_gpio_probe, | 1058 | .probe = nmk_gpio_probe, |
| 710 | .suspend = NULL, /* to be done */ | ||
| 711 | .resume = NULL, | ||
| 712 | }; | 1059 | }; |
| 713 | 1060 | ||
| 714 | static int __init nmk_gpio_init(void) | 1061 | static int __init nmk_gpio_init(void) |
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h index 67b113d639d8..1b9f6f0843d1 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio.h +++ b/arch/arm/plat-nomadik/include/plat/gpio.h | |||
| @@ -75,6 +75,9 @@ extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull); | |||
| 75 | extern int nmk_gpio_set_mode(int gpio, int gpio_mode); | 75 | extern int nmk_gpio_set_mode(int gpio, int gpio_mode); |
| 76 | extern int nmk_gpio_get_mode(int gpio); | 76 | extern int nmk_gpio_get_mode(int gpio); |
| 77 | 77 | ||
| 78 | extern void nmk_gpio_wakeups_suspend(void); | ||
| 79 | extern void nmk_gpio_wakeups_resume(void); | ||
| 80 | |||
| 78 | /* | 81 | /* |
| 79 | * Platform data to register a block: only the initial gpio/irq number. | 82 | * Platform data to register a block: only the initial gpio/irq number. |
| 80 | */ | 83 | */ |
| @@ -82,6 +85,9 @@ struct nmk_gpio_platform_data { | |||
| 82 | char *name; | 85 | char *name; |
| 83 | int first_gpio; | 86 | int first_gpio; |
| 84 | int first_irq; | 87 | int first_irq; |
| 88 | int num_gpio; | ||
| 89 | u32 (*get_secondary_status)(unsigned int bank); | ||
| 90 | void (*set_ioforce)(bool enable); | ||
| 85 | }; | 91 | }; |
| 86 | 92 | ||
| 87 | #endif /* __ASM_PLAT_GPIO_H */ | 93 | #endif /* __ASM_PLAT_GPIO_H */ |
