aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-08-07 08:08:49 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-05 14:39:21 -0400
commit6b918657b7431e4c5c953b8222ae2f4fc1b2576a (patch)
treebb3bb53d91501064821ea860a490dc1b3633df52 /arch/avr32/mach-at32ap
parent945533b538c6c6185afc77ba4a81eeba8f6ef8dd (diff)
atmel-mci: Platform code for supporting multiple mmc slots
Add the necessary platform infrastructure to support multiple mmc/sdcard slots all at once through a single controller. Currently, the driver will use the first valid slot it finds and stick with that, but later patches will add support for switching between several slots on the fly. Extend the platform data structure with per-slot information: MMC/SDcard bus width and card detect/write protect pins. This will affect the pin muxing as well as the capabilities announced to the mmc core. Note that board code is now required to supply a mci_platform_data struct to at32_add_device_mci(). Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c72
1 files changed, 54 insertions, 18 deletions
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