diff options
| -rw-r--r-- | arch/avr32/mach-at32ap/at32ap7000.c | 133 | ||||
| -rw-r--r-- | include/asm-avr32/arch-at32ap/board.h | 11 |
2 files changed, 113 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 | /* -------------------------------------------------------------------- |
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index 946378a1b6b5..d6993a6b6473 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h | |||
| @@ -70,4 +70,15 @@ struct platform_device *at32_add_device_mci(unsigned int id); | |||
| 70 | struct platform_device *at32_add_device_ac97c(unsigned int id); | 70 | struct platform_device *at32_add_device_ac97c(unsigned int id); |
| 71 | struct platform_device *at32_add_device_abdac(unsigned int id); | 71 | struct platform_device *at32_add_device_abdac(unsigned int id); |
| 72 | 72 | ||
| 73 | struct cf_platform_data { | ||
| 74 | int detect_pin; | ||
| 75 | int reset_pin; | ||
| 76 | int vcc_pin; | ||
| 77 | int ready_pin; | ||
| 78 | u8 cs; | ||
| 79 | }; | ||
| 80 | struct platform_device * | ||
| 81 | at32_add_device_cf(unsigned int id, unsigned int extint, | ||
| 82 | struct cf_platform_data *data); | ||
| 83 | |||
| 73 | #endif /* __ASM_ARCH_BOARD_H */ | 84 | #endif /* __ASM_ARCH_BOARD_H */ |
