diff options
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap7000.c | 133 |
1 files changed, 102 insertions, 31 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index d152504f12b9..a9d9ec081e3d 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c | |||
@@ -1330,10 +1330,9 @@ out_free_pdev: | |||
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | /* -------------------------------------------------------------------- | 1332 | /* -------------------------------------------------------------------- |
1333 | * IDE | 1333 | * IDE / CompactFlash |
1334 | * -------------------------------------------------------------------- */ | 1334 | * -------------------------------------------------------------------- */ |
1335 | static struct ide_platform_data at32_ide0_data; | 1335 | static struct resource at32_smc_cs4_resource[] __initdata = { |
1336 | static struct resource at32_ide0_resource[] = { | ||
1337 | { | 1336 | { |
1338 | .start = 0x04000000, | 1337 | .start = 0x04000000, |
1339 | .end = 0x07ffffff, | 1338 | .end = 0x07ffffff, |
@@ -1341,45 +1340,63 @@ static struct resource at32_ide0_resource[] = { | |||
1341 | }, | 1340 | }, |
1342 | IRQ(~0UL), /* Magic IRQ will be overridden */ | 1341 | IRQ(~0UL), /* Magic IRQ will be overridden */ |
1343 | }; | 1342 | }; |
1344 | DEFINE_DEV_DATA(at32_ide, 0); | 1343 | static struct resource at32_smc_cs5_resource[] __initdata = { |
1344 | { | ||
1345 | .start = 0x20000000, | ||
1346 | .end = 0x23ffffff, | ||
1347 | .flags = IORESOURCE_MEM, | ||
1348 | }, | ||
1349 | IRQ(~0UL), /* Magic IRQ will be overridden */ | ||
1350 | }; | ||
1345 | 1351 | ||
1346 | struct platform_device *__init | 1352 | static int __init at32_init_ide_or_cf(struct platform_device *pdev, |
1347 | at32_add_device_ide(unsigned int id, unsigned int extint, | 1353 | unsigned int cs, unsigned int extint) |
1348 | struct ide_platform_data *data) | ||
1349 | { | 1354 | { |
1350 | struct platform_device *pdev; | 1355 | static unsigned int extint_pin_map[4] __initdata = { |
1356 | GPIO_PIN_PB(25), | ||
1357 | GPIO_PIN_PB(26), | ||
1358 | GPIO_PIN_PB(27), | ||
1359 | GPIO_PIN_PB(28), | ||
1360 | }; | ||
1361 | static bool common_pins_initialized __initdata = false; | ||
1351 | unsigned int extint_pin; | 1362 | unsigned int extint_pin; |
1363 | int ret; | ||
1352 | 1364 | ||
1353 | switch (extint) { | 1365 | if (extint >= ARRAY_SIZE(extint_pin_map)) |
1354 | case 0: | 1366 | return -EINVAL; |
1355 | extint_pin = GPIO_PIN_PB(25); | 1367 | extint_pin = extint_pin_map[extint]; |
1356 | break; | 1368 | |
1357 | case 1: | 1369 | switch (cs) { |
1358 | extint_pin = GPIO_PIN_PB(26); | 1370 | case 4: |
1359 | break; | 1371 | ret = platform_device_add_resources(pdev, |
1360 | case 2: | 1372 | at32_smc_cs4_resource, |
1361 | extint_pin = GPIO_PIN_PB(27); | 1373 | ARRAY_SIZE(at32_smc_cs4_resource)); |
1374 | if (ret) | ||
1375 | return ret; | ||
1376 | |||
1377 | select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */ | ||
1378 | set_ebi_sfr_bits(HMATRIX_BIT(CS4A)); | ||
1362 | break; | 1379 | break; |
1363 | case 3: | 1380 | case 5: |
1364 | extint_pin = GPIO_PIN_PB(28); | 1381 | ret = platform_device_add_resources(pdev, |
1382 | at32_smc_cs5_resource, | ||
1383 | ARRAY_SIZE(at32_smc_cs5_resource)); | ||
1384 | if (ret) | ||
1385 | return ret; | ||
1386 | |||
1387 | select_peripheral(PE(22), PERIPH_A, 0); /* NCS5 -> OE_N */ | ||
1388 | set_ebi_sfr_bits(HMATRIX_BIT(CS5A)); | ||
1365 | break; | 1389 | break; |
1366 | default: | 1390 | default: |
1367 | return NULL; | 1391 | return -EINVAL; |
1368 | } | 1392 | } |
1369 | 1393 | ||
1370 | switch (id) { | 1394 | if (!common_pins_initialized) { |
1371 | case 0: | ||
1372 | pdev = &at32_ide0_device; | ||
1373 | select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */ | 1395 | select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */ |
1374 | select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */ | 1396 | select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */ |
1375 | select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */ | ||
1376 | select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */ | 1397 | select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */ |
1377 | select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */ | 1398 | select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */ |
1378 | set_ebi_sfr_bits(HMATRIX_BIT(CS4A)); | 1399 | common_pins_initialized = true; |
1379 | data->cs = 4; | ||
1380 | break; | ||
1381 | default: | ||
1382 | return NULL; | ||
1383 | } | 1400 | } |
1384 | 1401 | ||
1385 | at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); | 1402 | at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); |
@@ -1387,11 +1404,65 @@ at32_add_device_ide(unsigned int id, unsigned int extint, | |||
1387 | pdev->resource[1].start = EIM_IRQ_BASE + extint; | 1404 | pdev->resource[1].start = EIM_IRQ_BASE + extint; |
1388 | pdev->resource[1].end = pdev->resource[1].start; | 1405 | pdev->resource[1].end = pdev->resource[1].start; |
1389 | 1406 | ||
1390 | memcpy(pdev->dev.platform_data, data, sizeof(struct ide_platform_data)); | 1407 | return 0; |
1408 | } | ||
1391 | 1409 | ||
1392 | platform_device_register(pdev); | 1410 | struct platform_device *__init |
1411 | at32_add_device_ide(unsigned int id, unsigned int extint, | ||
1412 | struct ide_platform_data *data) | ||
1413 | { | ||
1414 | struct platform_device *pdev; | ||
1415 | |||
1416 | pdev = platform_device_alloc("at32_ide", id); | ||
1417 | if (!pdev) | ||
1418 | goto fail; | ||
1419 | |||
1420 | if (platform_device_add_data(pdev, data, | ||
1421 | sizeof(struct ide_platform_data))) | ||
1422 | goto fail; | ||
1423 | |||
1424 | if (at32_init_ide_or_cf(pdev, data->cs, extint)) | ||
1425 | goto fail; | ||
1426 | |||
1427 | platform_device_add(pdev); | ||
1428 | return pdev; | ||
1429 | |||
1430 | fail: | ||
1431 | platform_device_put(pdev); | ||
1432 | return NULL; | ||
1433 | } | ||
1434 | |||
1435 | struct platform_device *__init | ||
1436 | at32_add_device_cf(unsigned int id, unsigned int extint, | ||
1437 | struct cf_platform_data *data) | ||
1438 | { | ||
1439 | struct platform_device *pdev; | ||
1440 | |||
1441 | pdev = platform_device_alloc("at32_cf", id); | ||
1442 | if (!pdev) | ||
1443 | goto fail; | ||
1393 | 1444 | ||
1445 | if (platform_device_add_data(pdev, data, | ||
1446 | sizeof(struct cf_platform_data))) | ||
1447 | goto fail; | ||
1448 | |||
1449 | if (at32_init_ide_or_cf(pdev, data->cs, extint)) | ||
1450 | goto fail; | ||
1451 | |||
1452 | if (data->detect_pin != GPIO_PIN_NONE) | ||
1453 | at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH); | ||
1454 | if (data->reset_pin != GPIO_PIN_NONE) | ||
1455 | at32_select_gpio(data->reset_pin, 0); | ||
1456 | if (data->vcc_pin != GPIO_PIN_NONE) | ||
1457 | at32_select_gpio(data->vcc_pin, 0); | ||
1458 | /* READY is used as extint, so we can't select it as gpio */ | ||
1459 | |||
1460 | platform_device_add(pdev); | ||
1394 | return pdev; | 1461 | return pdev; |
1462 | |||
1463 | fail: | ||
1464 | platform_device_put(pdev); | ||
1465 | return NULL; | ||
1395 | } | 1466 | } |
1396 | 1467 | ||
1397 | /* -------------------------------------------------------------------- | 1468 | /* -------------------------------------------------------------------- |