aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.h22
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c72
-rw-r--r--drivers/mmc/host/atmel-mci-regs.h6
-rw-r--r--drivers/mmc/host/atmel-mci.c24
8 files changed, 137 insertions, 36 deletions
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index b8286f1ce854..f3085208959f 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -53,8 +53,11 @@ static struct spi_board_info spi0_board_info[] __initdata = {
53}; 53};
54 54
55static struct mci_platform_data __initdata mci0_data = { 55static struct mci_platform_data __initdata mci0_data = {
56 .detect_pin = GPIO_PIN_PC(25), 56 .slot[0] = {
57 .wp_pin = GPIO_PIN_PE(0), 57 .bus_width = 4,
58 .detect_pin = GPIO_PIN_PC(25),
59 .wp_pin = GPIO_PIN_PE(0),
60 },
58}; 61};
59 62
60/* 63/*
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index dfc3443e23aa..4fedbc4488de 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 50a5273e5916..d6a2d02f0329 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, 0); 153 fbmem_start, fbmem_size, 0);
diff --git a/arch/avr32/include/asm/atmel-mci.h b/arch/avr32/include/asm/atmel-mci.h
index c2ea6e1c9aa1..d38c64ca41e8 100644
--- a/arch/avr32/include/asm/atmel-mci.h
+++ b/arch/avr32/include/asm/atmel-mci.h
@@ -1,9 +1,29 @@
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/**
5 * struct mci_slot_pdata - board-specific per-slot configuration
6 * @bus_width: Number of data lines wired up the slot
7 * @detect_pin: GPIO pin wired to the card detect switch
8 * @wp_pin: GPIO pin wired to the write protect sensor
9 *
10 * If a given slot is not present on the board, @bus_width should be
11 * set to 0. The other fields are ignored in this case.
12 *
13 * Any pins that aren't available should be set to a negative value.
14 */
15struct mci_slot_pdata {
16 unsigned int bus_width;
5 int detect_pin; 17 int detect_pin;
6 int wp_pin; 18 int wp_pin;
7}; 19};
8 20
21/**
22 * struct mci_platform_data - board-specific MMC/SDcard configuration
23 * @slot: Per-slot configuration data.
24 */
25struct mci_platform_data {
26 struct mci_slot_pdata slot[2];
27};
28
9#endif /* __ASM_AVR32_ATMEL_MCI_H */ 29#endif /* __ASM_AVR32_ATMEL_MCI_H */
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index e01dbe4ebb40..9967d5a3b6eb 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1272,10 +1272,13 @@ 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;
1277 1276
1278 if (id != 0) 1277 if (id != 0 || !data)
1278 return NULL;
1279
1280 /* Must have at least one usable slot */
1281 if (!data->slot[0].bus_width && !data->slot[1].bus_width)
1279 return NULL; 1282 return NULL;
1280 1283
1281 pdev = platform_device_alloc("atmel_mci", id); 1284 pdev = platform_device_alloc("atmel_mci", id);
@@ -1286,28 +1289,61 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
1286 ARRAY_SIZE(atmel_mci0_resource))) 1289 ARRAY_SIZE(atmel_mci0_resource)))
1287 goto fail; 1290 goto fail;
1288 1291
1289 if (!data) {
1290 data = &_data;
1291 memset(data, -1, sizeof(struct mci_platform_data));
1292 data->detect_pin = GPIO_PIN_NONE;
1293 data->wp_pin = GPIO_PIN_NONE;
1294 }
1295 1292
1296 if (platform_device_add_data(pdev, data, 1293 if (platform_device_add_data(pdev, data,
1297 sizeof(struct mci_platform_data))) 1294 sizeof(struct mci_platform_data)))
1298 goto fail; 1295 goto fail;
1299 1296
1300 select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ 1297 /* CLK line is common to both slots */
1301 select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ 1298 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 1299
1307 if (gpio_is_valid(data->detect_pin)) 1300 switch (data->slot[0].bus_width) {
1308 at32_select_gpio(data->detect_pin, 0); 1301 case 4:
1309 if (gpio_is_valid(data->wp_pin)) 1302 select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
1310 at32_select_gpio(data->wp_pin, 0); 1303 select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
1304 select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
1305 /* fall through */
1306 case 1:
1307 select_peripheral(PA(11), PERIPH_A, 0); /* CMD */
1308 select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
1309
1310 if (gpio_is_valid(data->slot[0].detect_pin))
1311 at32_select_gpio(data->slot[0].detect_pin, 0);
1312 if (gpio_is_valid(data->slot[0].wp_pin))
1313 at32_select_gpio(data->slot[0].wp_pin, 0);
1314 break;
1315 case 0:
1316 /* Slot is unused */
1317 break;
1318 default:
1319 goto fail;
1320 }
1321
1322 switch (data->slot[1].bus_width) {
1323 case 4:
1324 select_peripheral(PB(8), PERIPH_B, 0); /* DATA1 */
1325 select_peripheral(PB(9), PERIPH_B, 0); /* DATA2 */
1326 select_peripheral(PB(10), PERIPH_B, 0); /* DATA3 */
1327 /* fall through */
1328 case 1:
1329 select_peripheral(PB(6), PERIPH_B, 0); /* CMD */
1330 select_peripheral(PB(7), PERIPH_B, 0); /* DATA0 */
1331
1332 if (gpio_is_valid(data->slot[1].detect_pin))
1333 at32_select_gpio(data->slot[1].detect_pin, 0);
1334 if (gpio_is_valid(data->slot[1].wp_pin))
1335 at32_select_gpio(data->slot[1].wp_pin, 0);
1336 break;
1337 case 0:
1338 /* Slot is unused */
1339 break;
1340 default:
1341 if (!data->slot[0].bus_width)
1342 goto fail;
1343
1344 data->slot[1].bus_width = 0;
1345 break;
1346 }
1311 1347
1312 atmel_mci0_pclk.dev = &pdev->dev; 1348 atmel_mci0_pclk.dev = &pdev->dev;
1313 1349
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
index 26bd80e65031..b58364ed6bba 100644
--- a/drivers/mmc/host/atmel-mci-regs.h
+++ b/drivers/mmc/host/atmel-mci-regs.h
@@ -25,8 +25,10 @@
25#define MCI_SDCR 0x000c /* SD Card / SDIO */ 25#define MCI_SDCR 0x000c /* SD Card / SDIO */
26# define MCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */ 26# define MCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */
27# define MCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */ 27# define MCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */
28# define MCI_SDCBUS_1BIT ( 0 << 7) /* 1-bit data bus */ 28# define MCI_SDCSEL_MASK ( 3 << 0)
29# define MCI_SDCBUS_4BIT ( 1 << 7) /* 4-bit data bus */ 29# define MCI_SDCBUS_1BIT ( 0 << 6) /* 1-bit data bus */
30# define MCI_SDCBUS_4BIT ( 2 << 6) /* 4-bit data bus */
31# define MCI_SDCBUS_MASK ( 3 << 6)
30#define MCI_ARGR 0x0010 /* Command Argument */ 32#define MCI_ARGR 0x0010 /* Command Argument */
31#define MCI_CMDR 0x0014 /* Command */ 33#define MCI_CMDR 0x0014 /* Command */
32# define MCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */ 34# define MCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 14ab28da7fa8..8170905a0401 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -508,9 +508,10 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
508{ 508{
509 struct atmel_mci *host = mmc_priv(mmc); 509 struct atmel_mci *host = mmc_priv(mmc);
510 510
511 host->sdc_reg &= ~MCI_SDCBUS_MASK;
511 switch (ios->bus_width) { 512 switch (ios->bus_width) {
512 case MMC_BUS_WIDTH_1: 513 case MMC_BUS_WIDTH_1:
513 host->sdc_reg = 0; 514 host->sdc_reg |= MCI_SDCBUS_1BIT;
514 break; 515 break;
515 case MMC_BUS_WIDTH_4: 516 case MMC_BUS_WIDTH_4:
516 host->sdc_reg = MCI_SDCBUS_4BIT; 517 host->sdc_reg = MCI_SDCBUS_4BIT;
@@ -1014,9 +1015,11 @@ static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id)
1014static int __init atmci_probe(struct platform_device *pdev) 1015static int __init atmci_probe(struct platform_device *pdev)
1015{ 1016{
1016 struct mci_platform_data *pdata; 1017 struct mci_platform_data *pdata;
1018 struct mci_slot_pdata *slot;
1017 struct atmel_mci *host; 1019 struct atmel_mci *host;
1018 struct mmc_host *mmc; 1020 struct mmc_host *mmc;
1019 struct resource *regs; 1021 struct resource *regs;
1022 u32 sdc_reg;
1020 int irq; 1023 int irq;
1021 int ret; 1024 int ret;
1022 1025
@@ -1030,6 +1033,17 @@ static int __init atmci_probe(struct platform_device *pdev)
1030 if (irq < 0) 1033 if (irq < 0)
1031 return irq; 1034 return irq;
1032 1035
1036 /* TODO: Allow using several slots at once */
1037 if (pdata->slot[0].bus_width) {
1038 sdc_reg = MCI_SDCSEL_SLOT_A;
1039 slot = &pdata->slot[0];
1040 } else if (pdata->slot[1].bus_width) {
1041 sdc_reg = MCI_SDCSEL_SLOT_B;
1042 slot = &pdata->slot[1];
1043 } else {
1044 return -EINVAL;
1045 }
1046
1033 mmc = mmc_alloc_host(sizeof(struct atmel_mci), &pdev->dev); 1047 mmc = mmc_alloc_host(sizeof(struct atmel_mci), &pdev->dev);
1034 if (!mmc) 1048 if (!mmc)
1035 return -ENOMEM; 1049 return -ENOMEM;
@@ -1037,8 +1051,9 @@ static int __init atmci_probe(struct platform_device *pdev)
1037 host = mmc_priv(mmc); 1051 host = mmc_priv(mmc);
1038 host->pdev = pdev; 1052 host->pdev = pdev;
1039 host->mmc = mmc; 1053 host->mmc = mmc;
1040 host->detect_pin = pdata->detect_pin; 1054 host->detect_pin = slot->detect_pin;
1041 host->wp_pin = pdata->wp_pin; 1055 host->wp_pin = slot->wp_pin;
1056 host->sdc_reg = sdc_reg;
1042 1057
1043 host->mck = clk_get(&pdev->dev, "mci_clk"); 1058 host->mck = clk_get(&pdev->dev, "mci_clk");
1044 if (IS_ERR(host->mck)) { 1059 if (IS_ERR(host->mck)) {
@@ -1062,7 +1077,8 @@ static int __init atmci_probe(struct platform_device *pdev)
1062 mmc->f_min = (host->bus_hz + 511) / 512; 1077 mmc->f_min = (host->bus_hz + 511) / 512;
1063 mmc->f_max = host->bus_hz / 2; 1078 mmc->f_max = host->bus_hz / 2;
1064 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 1079 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1065 mmc->caps |= MMC_CAP_4_BIT_DATA; 1080 if (slot->bus_width >= 4)
1081 mmc->caps |= MMC_CAP_4_BIT_DATA;
1066 1082
1067 mmc->max_hw_segs = 64; 1083 mmc->max_hw_segs = 64;
1068 mmc->max_phys_segs = 64; 1084 mmc->max_phys_segs = 64;