aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-12 09:44:33 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-12 09:44:33 -0400
commit0d62950125241a6e6db8e8f14271f098ec7a2da4 (patch)
tree8cdd9e17f6a6ff4cb6166ad12a4d3ed1d45b2dc9 /arch/avr32
parentb3bc2c5562f06ca34b30f61c5714e96490946c81 (diff)
parent5e7184ae0dd49456387e8b1cdebc6b2c92fc6d51 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/atmel-mci-2.6.28
Diffstat (limited to 'arch/avr32')
-rw-r--r--arch/avr32/boards/atngw100/setup.c7
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c18
-rw-r--r--arch/avr32/boards/atstk1000/atstk1003.c12
-rw-r--r--arch/avr32/boards/atstk1000/atstk1004.c12
-rw-r--r--arch/avr32/include/asm/atmel-mci.h32
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c88
6 files changed, 139 insertions, 30 deletions
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index abcb0d9559b1..65db3d266965 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -54,8 +54,11 @@ static struct spi_board_info spi0_board_info[] __initdata = {
54}; 54};
55 55
56static struct mci_platform_data __initdata mci0_data = { 56static struct mci_platform_data __initdata mci0_data = {
57 .detect_pin = GPIO_PIN_PC(25), 57 .slot[0] = {
58 .wp_pin = GPIO_PIN_PE(0), 58 .bus_width = 4,
59 .detect_pin = GPIO_PIN_PC(25),
60 .wp_pin = GPIO_PIN_PE(0),
61 },
59}; 62};
60 63
61/* 64/*
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index cccca241fae9..32aceec0ae72 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -264,16 +264,20 @@ void __init setup_board(void)
264 264
265#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM 265#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
266 266
267static struct mci_platform_data __initdata mci0_data = {
268 .slot[0] = {
269 .bus_width = 4,
270
267/* MMC card detect requires MACB0 *NOT* be used */ 271/* MMC card detect requires MACB0 *NOT* be used */
268#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM 272#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
269static struct mci_platform_data __initdata mci0_data = { 273 .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */
270 .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ 274 .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */
271 .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */
272};
273#define MCI_PDATA &mci0_data
274#else 275#else
275#define MCI_PDATA NULL 276 .detect_pin = -ENODEV,
277 .wp_pin = -ENODEV,
276#endif /* SW6 for sd{cd,wp} routing */ 278#endif /* SW6 for sd{cd,wp} routing */
279 },
280};
277 281
278#endif /* SW2 for MMC signal routing */ 282#endif /* SW2 for MMC signal routing */
279 283
@@ -326,7 +330,7 @@ static int __init atstk1002_init(void)
326 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); 330 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
327#endif 331#endif
328#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM 332#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
329 at32_add_device_mci(0, MCI_PDATA); 333 at32_add_device_mci(0, &mci0_pdata);
330#endif 334#endif
331#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM 335#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
332 set_hw_addr(at32_add_device_eth(1, &eth_data[1])); 336 set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c
index 0cf664174c17..acc61235b895 100644
--- a/arch/avr32/boards/atstk1000/atstk1003.c
+++ b/arch/avr32/boards/atstk1000/atstk1003.c
@@ -66,6 +66,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { {
66} }; 66} };
67#endif 67#endif
68 68
69#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
70static struct mci_platform_data __initdata mci0_data = {
71 .slot[0] = {
72 .bus_width = 4,
73 .detect_pin = -ENODEV,
74 .wp_pin = -ENODEV,
75 },
76};
77#endif
78
69#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC 79#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
70static void __init atstk1003_setup_extdac(void) 80static void __init atstk1003_setup_extdac(void)
71{ 81{
@@ -154,7 +164,7 @@ static int __init atstk1003_init(void)
154 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); 164 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
155#endif 165#endif
156#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM 166#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
157 at32_add_device_mci(0, NULL); 167 at32_add_device_mci(0, &mci0_data);
158#endif 168#endif
159 at32_add_device_usba(0, NULL); 169 at32_add_device_usba(0, NULL);
160#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM 170#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c
index 2c072cd0c22e..949c13ec51ed 100644
--- a/arch/avr32/boards/atstk1000/atstk1004.c
+++ b/arch/avr32/boards/atstk1000/atstk1004.c
@@ -71,6 +71,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { {
71} }; 71} };
72#endif 72#endif
73 73
74#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
75static struct mci_platform_data __initdata mci0_data = {
76 .slot[0] = {
77 .bus_width = 4,
78 .detect_pin = -ENODEV,
79 .wp_pin = -ENODEV,
80 },
81};
82#endif
83
74#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC 84#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
75static void __init atstk1004_setup_extdac(void) 85static void __init atstk1004_setup_extdac(void)
76{ 86{
@@ -137,7 +147,7 @@ static int __init atstk1004_init(void)
137 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); 147 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
138#endif 148#endif
139#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM 149#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
140 at32_add_device_mci(0, NULL); 150 at32_add_device_mci(0, &mci0_data);
141#endif 151#endif
142 at32_add_device_lcdc(0, &atstk1000_lcdc_data, 152 at32_add_device_lcdc(0, &atstk1000_lcdc_data,
143 fbmem_start, fbmem_size, 153 fbmem_start, fbmem_size,
diff --git a/arch/avr32/include/asm/atmel-mci.h b/arch/avr32/include/asm/atmel-mci.h
index c2ea6e1c9aa1..59f3fadd0b68 100644
--- a/arch/avr32/include/asm/atmel-mci.h
+++ b/arch/avr32/include/asm/atmel-mci.h
@@ -1,9 +1,39 @@
1#ifndef __ASM_AVR32_ATMEL_MCI_H 1#ifndef __ASM_AVR32_ATMEL_MCI_H
2#define __ASM_AVR32_ATMEL_MCI_H 2#define __ASM_AVR32_ATMEL_MCI_H
3 3
4struct mci_platform_data { 4#define ATMEL_MCI_MAX_NR_SLOTS 2
5
6struct dma_slave;
7
8/**
9 * struct mci_slot_pdata - board-specific per-slot configuration
10 * @bus_width: Number of data lines wired up the slot
11 * @detect_pin: GPIO pin wired to the card detect switch
12 * @wp_pin: GPIO pin wired to the write protect sensor
13 *
14 * If a given slot is not present on the board, @bus_width should be
15 * set to 0. The other fields are ignored in this case.
16 *
17 * Any pins that aren't available should be set to a negative value.
18 *
19 * Note that support for multiple slots is experimental -- some cards
20 * might get upset if we don't get the clock management exactly right.
21 * But in most cases, it should work just fine.
22 */
23struct mci_slot_pdata {
24 unsigned int bus_width;
5 int detect_pin; 25 int detect_pin;
6 int wp_pin; 26 int wp_pin;
7}; 27};
8 28
29/**
30 * struct mci_platform_data - board-specific MMC/SDcard configuration
31 * @dma_slave: DMA slave interface to use in data transfers, or NULL.
32 * @slot: Per-slot configuration data.
33 */
34struct mci_platform_data {
35 struct dma_slave *dma_slave;
36 struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS];
37};
38
9#endif /* __ASM_AVR32_ATMEL_MCI_H */ 39#endif /* __ASM_AVR32_ATMEL_MCI_H */
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index fd306c49194b..5d00bb8d3cc2 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1272,10 +1272,14 @@ static struct clk atmel_mci0_pclk = {
1272struct platform_device *__init 1272struct platform_device *__init
1273at32_add_device_mci(unsigned int id, struct mci_platform_data *data) 1273at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
1274{ 1274{
1275 struct mci_platform_data _data;
1276 struct platform_device *pdev; 1275 struct platform_device *pdev;
1276 struct dw_dma_slave *dws;
1277 1277
1278 if (id != 0) 1278 if (id != 0 || !data)
1279 return NULL;
1280
1281 /* Must have at least one usable slot */
1282 if (!data->slot[0].bus_width && !data->slot[1].bus_width)
1279 return NULL; 1283 return NULL;
1280 1284
1281 pdev = platform_device_alloc("atmel_mci", id); 1285 pdev = platform_device_alloc("atmel_mci", id);
@@ -1286,28 +1290,76 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
1286 ARRAY_SIZE(atmel_mci0_resource))) 1290 ARRAY_SIZE(atmel_mci0_resource)))
1287 goto fail; 1291 goto fail;
1288 1292
1289 if (!data) { 1293 if (data->dma_slave)
1290 data = &_data; 1294 dws = kmemdup(to_dw_dma_slave(data->dma_slave),
1291 memset(data, -1, sizeof(struct mci_platform_data)); 1295 sizeof(struct dw_dma_slave), GFP_KERNEL);
1292 data->detect_pin = GPIO_PIN_NONE; 1296 else
1293 data->wp_pin = GPIO_PIN_NONE; 1297 dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
1294 } 1298
1299 dws->slave.dev = &pdev->dev;
1300 dws->slave.dma_dev = &dw_dmac0_device.dev;
1301 dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT;
1302 dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
1303 | DWC_CFGH_DST_PER(1));
1304 dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
1305 | DWC_CFGL_HS_SRC_POL);
1306
1307 data->dma_slave = &dws->slave;
1295 1308
1296 if (platform_device_add_data(pdev, data, 1309 if (platform_device_add_data(pdev, data,
1297 sizeof(struct mci_platform_data))) 1310 sizeof(struct mci_platform_data)))
1298 goto fail; 1311 goto fail;
1299 1312
1300 select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ 1313 /* CLK line is common to both slots */
1301 select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ 1314 select_peripheral(PA(10), PERIPH_A, 0);
1302 select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
1303 select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
1304 select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
1305 select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
1306 1315
1307 if (gpio_is_valid(data->detect_pin)) 1316 switch (data->slot[0].bus_width) {
1308 at32_select_gpio(data->detect_pin, 0); 1317 case 4:
1309 if (gpio_is_valid(data->wp_pin)) 1318 select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
1310 at32_select_gpio(data->wp_pin, 0); 1319 select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
1320 select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
1321 /* fall through */
1322 case 1:
1323 select_peripheral(PA(11), PERIPH_A, 0); /* CMD */
1324 select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
1325
1326 if (gpio_is_valid(data->slot[0].detect_pin))
1327 at32_select_gpio(data->slot[0].detect_pin, 0);
1328 if (gpio_is_valid(data->slot[0].wp_pin))
1329 at32_select_gpio(data->slot[0].wp_pin, 0);
1330 break;
1331 case 0:
1332 /* Slot is unused */
1333 break;
1334 default:
1335 goto fail;
1336 }
1337
1338 switch (data->slot[1].bus_width) {
1339 case 4:
1340 select_peripheral(PB(8), PERIPH_B, 0); /* DATA1 */
1341 select_peripheral(PB(9), PERIPH_B, 0); /* DATA2 */
1342 select_peripheral(PB(10), PERIPH_B, 0); /* DATA3 */
1343 /* fall through */
1344 case 1:
1345 select_peripheral(PB(6), PERIPH_B, 0); /* CMD */
1346 select_peripheral(PB(7), PERIPH_B, 0); /* DATA0 */
1347
1348 if (gpio_is_valid(data->slot[1].detect_pin))
1349 at32_select_gpio(data->slot[1].detect_pin, 0);
1350 if (gpio_is_valid(data->slot[1].wp_pin))
1351 at32_select_gpio(data->slot[1].wp_pin, 0);
1352 break;
1353 case 0:
1354 /* Slot is unused */
1355 break;
1356 default:
1357 if (!data->slot[0].bus_width)
1358 goto fail;
1359
1360 data->slot[1].bus_width = 0;
1361 break;
1362 }
1311 1363
1312 atmel_mci0_pclk.dev = &pdev->dev; 1364 atmel_mci0_pclk.dev = &pdev->dev;
1313 1365