diff options
33 files changed, 1282 insertions, 548 deletions
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c index ab9ee5820c48..409fa56d0a87 100644 --- a/arch/arm/mach-omap1/board-h2-mmc.c +++ b/arch/arm/mach-omap1/board-h2-mmc.c | |||
| @@ -12,90 +12,68 @@ | |||
| 12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | |||
| 17 | #include <linux/i2c/tps65010.h> | ||
| 18 | |||
| 15 | #include <mach/mmc.h> | 19 | #include <mach/mmc.h> |
| 16 | #include <mach/gpio.h> | 20 | #include <mach/gpio.h> |
| 17 | 21 | ||
| 18 | #ifdef CONFIG_MMC_OMAP | 22 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
| 19 | static int slot_cover_open; | ||
| 20 | static struct device *mmc_device; | ||
| 21 | 23 | ||
| 22 | static int h2_mmc_set_power(struct device *dev, int slot, int power_on, | 24 | static int mmc_set_power(struct device *dev, int slot, int power_on, |
| 23 | int vdd) | 25 | int vdd) |
| 24 | { | 26 | { |
| 25 | #ifdef CONFIG_MMC_DEBUG | 27 | if (power_on) |
| 26 | dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1, | 28 | gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1); |
| 27 | power_on ? "on" : "off", vdd); | 29 | else |
| 28 | #endif | 30 | gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0); |
| 29 | if (slot != 0) { | ||
| 30 | dev_err(dev, "No such slot %d\n", slot + 1); | ||
| 31 | return -ENODEV; | ||
| 32 | } | ||
| 33 | 31 | ||
| 34 | return 0; | 32 | return 0; |
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | static int h2_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode) | 35 | static int mmc_late_init(struct device *dev) |
| 38 | { | 36 | { |
| 39 | #ifdef CONFIG_MMC_DEBUG | 37 | int ret; |
| 40 | dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1, | ||
| 41 | bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull"); | ||
| 42 | #endif | ||
| 43 | if (slot != 0) { | ||
| 44 | dev_err(dev, "No such slot %d\n", slot + 1); | ||
| 45 | return -ENODEV; | ||
| 46 | } | ||
| 47 | 38 | ||
| 48 | return 0; | 39 | ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power"); |
| 49 | } | 40 | if (ret < 0) |
| 41 | return ret; | ||
| 50 | 42 | ||
| 51 | static int h2_mmc_get_cover_state(struct device *dev, int slot) | 43 | gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0); |
| 52 | { | ||
| 53 | BUG_ON(slot != 0); | ||
| 54 | |||
| 55 | return slot_cover_open; | ||
| 56 | } | ||
| 57 | |||
| 58 | void h2_mmc_slot_cover_handler(void *arg, int state) | ||
| 59 | { | ||
| 60 | if (mmc_device == NULL) | ||
| 61 | return; | ||
| 62 | |||
| 63 | slot_cover_open = state; | ||
| 64 | omap_mmc_notify_cover_event(mmc_device, 0, state); | ||
| 65 | } | ||
| 66 | |||
| 67 | static int h2_mmc_late_init(struct device *dev) | ||
| 68 | { | ||
| 69 | int ret = 0; | ||
| 70 | |||
| 71 | mmc_device = dev; | ||
| 72 | 44 | ||
| 73 | return ret; | 45 | return ret; |
| 74 | } | 46 | } |
| 75 | 47 | ||
| 76 | static void h2_mmc_cleanup(struct device *dev) | 48 | static void mmc_shutdown(struct device *dev) |
| 77 | { | 49 | { |
| 50 | gpio_free(H2_TPS_GPIO_MMC_PWR_EN); | ||
| 78 | } | 51 | } |
| 79 | 52 | ||
| 80 | static struct omap_mmc_platform_data h2_mmc_data = { | 53 | /* |
| 54 | * H2 could use the following functions tested: | ||
| 55 | * - mmc_get_cover_state that uses OMAP_MPUIO(1) | ||
| 56 | * - mmc_get_wp that uses OMAP_MPUIO(3) | ||
| 57 | */ | ||
| 58 | static struct omap_mmc_platform_data mmc1_data = { | ||
| 81 | .nr_slots = 1, | 59 | .nr_slots = 1, |
| 82 | .switch_slot = NULL, | 60 | .init = mmc_late_init, |
| 83 | .init = h2_mmc_late_init, | 61 | .shutdown = mmc_shutdown, |
| 84 | .cleanup = h2_mmc_cleanup, | 62 | .dma_mask = 0xffffffff, |
| 85 | .slots[0] = { | 63 | .slots[0] = { |
| 86 | .set_power = h2_mmc_set_power, | 64 | .set_power = mmc_set_power, |
| 87 | .set_bus_mode = h2_mmc_set_bus_mode, | ||
| 88 | .get_ro = NULL, | ||
| 89 | .get_cover_state = h2_mmc_get_cover_state, | ||
| 90 | .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | | 65 | .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | |
| 91 | MMC_VDD_32_33 | MMC_VDD_33_34, | 66 | MMC_VDD_32_33 | MMC_VDD_33_34, |
| 92 | .name = "mmcblk", | 67 | .name = "mmcblk", |
| 93 | }, | 68 | }, |
| 94 | }; | 69 | }; |
| 95 | 70 | ||
| 71 | static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; | ||
| 72 | |||
| 96 | void __init h2_mmc_init(void) | 73 | void __init h2_mmc_init(void) |
| 97 | { | 74 | { |
| 98 | omap_set_mmc_info(1, &h2_mmc_data); | 75 | mmc_data[0] = &mmc1_data; |
| 76 | omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC); | ||
| 99 | } | 77 | } |
| 100 | 78 | ||
| 101 | #else | 79 | #else |
| @@ -104,7 +82,4 @@ void __init h2_mmc_init(void) | |||
| 104 | { | 82 | { |
| 105 | } | 83 | } |
| 106 | 84 | ||
| 107 | void h2_mmc_slot_cover_handler(void *arg, int state) | ||
| 108 | { | ||
| 109 | } | ||
| 110 | #endif | 85 | #endif |
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index c5b4a3b718cf..b240c5f861da 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
| @@ -345,10 +345,25 @@ static void __init h2_init_smc91x(void) | |||
| 345 | } | 345 | } |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static int tps_setup(struct i2c_client *client, void *context) | ||
| 349 | { | ||
| 350 | tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | | ||
| 351 | TPS_LDO1_ENABLE | TPS_VLDO1_3_0V); | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | static struct tps65010_board tps_board = { | ||
| 357 | .base = H2_TPS_GPIO_BASE, | ||
| 358 | .outmask = 0x0f, | ||
| 359 | .setup = tps_setup, | ||
| 360 | }; | ||
| 361 | |||
| 348 | static struct i2c_board_info __initdata h2_i2c_board_info[] = { | 362 | static struct i2c_board_info __initdata h2_i2c_board_info[] = { |
| 349 | { | 363 | { |
| 350 | I2C_BOARD_INFO("tps65010", 0x48), | 364 | I2C_BOARD_INFO("tps65010", 0x48), |
| 351 | .irq = OMAP_GPIO_IRQ(58), | 365 | .irq = OMAP_GPIO_IRQ(58), |
| 366 | .platform_data = &tps_board, | ||
| 352 | }, { | 367 | }, { |
| 353 | I2C_BOARD_INFO("isp1301_omap", 0x2d), | 368 | I2C_BOARD_INFO("isp1301_omap", 0x2d), |
| 354 | .irq = OMAP_GPIO_IRQ(2), | 369 | .irq = OMAP_GPIO_IRQ(2), |
| @@ -378,15 +393,6 @@ static struct omap_usb_config h2_usb_config __initdata = { | |||
| 378 | .pins[1] = 3, | 393 | .pins[1] = 3, |
| 379 | }; | 394 | }; |
| 380 | 395 | ||
| 381 | static struct omap_mmc_config h2_mmc_config __initdata = { | ||
| 382 | .mmc[0] = { | ||
| 383 | .enabled = 1, | ||
| 384 | .wire4 = 1, | ||
| 385 | }, | ||
| 386 | }; | ||
| 387 | |||
| 388 | extern struct omap_mmc_platform_data h2_mmc_data; | ||
| 389 | |||
| 390 | static struct omap_uart_config h2_uart_config __initdata = { | 396 | static struct omap_uart_config h2_uart_config __initdata = { |
| 391 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 397 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 392 | }; | 398 | }; |
| @@ -397,7 +403,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = { | |||
| 397 | 403 | ||
| 398 | static struct omap_board_config_kernel h2_config[] __initdata = { | 404 | static struct omap_board_config_kernel h2_config[] __initdata = { |
| 399 | { OMAP_TAG_USB, &h2_usb_config }, | 405 | { OMAP_TAG_USB, &h2_usb_config }, |
| 400 | { OMAP_TAG_MMC, &h2_mmc_config }, | ||
| 401 | { OMAP_TAG_UART, &h2_uart_config }, | 406 | { OMAP_TAG_UART, &h2_uart_config }, |
| 402 | { OMAP_TAG_LCD, &h2_lcd_config }, | 407 | { OMAP_TAG_LCD, &h2_lcd_config }, |
| 403 | }; | 408 | }; |
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c index 36085819098c..fdfe793d56f2 100644 --- a/arch/arm/mach-omap1/board-h3-mmc.c +++ b/arch/arm/mach-omap1/board-h3-mmc.c | |||
| @@ -12,94 +12,55 @@ | |||
| 12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | |||
| 17 | #include <linux/i2c/tps65010.h> | ||
| 18 | |||
| 15 | #include <mach/mmc.h> | 19 | #include <mach/mmc.h> |
| 16 | #include <mach/gpio.h> | 20 | #include <mach/gpio.h> |
| 17 | 21 | ||
| 18 | #ifdef CONFIG_MMC_OMAP | 22 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
| 19 | static int slot_cover_open; | ||
| 20 | static struct device *mmc_device; | ||
| 21 | 23 | ||
| 22 | static int h3_mmc_set_power(struct device *dev, int slot, int power_on, | 24 | static int mmc_set_power(struct device *dev, int slot, int power_on, |
| 23 | int vdd) | 25 | int vdd) |
| 24 | { | 26 | { |
| 25 | #ifdef CONFIG_MMC_DEBUG | 27 | if (power_on) |
| 26 | dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1, | 28 | gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1); |
| 27 | power_on ? "on" : "off", vdd); | 29 | else |
| 28 | #endif | 30 | gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0); |
| 29 | if (slot != 0) { | ||
| 30 | dev_err(dev, "No such slot %d\n", slot + 1); | ||
| 31 | return -ENODEV; | ||
| 32 | } | ||
| 33 | 31 | ||
| 34 | return 0; | 32 | return 0; |
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | static int h3_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode) | 35 | /* |
| 38 | { | 36 | * H3 could use the following functions tested: |
| 39 | int ret = 0; | 37 | * - mmc_get_cover_state that uses OMAP_MPUIO(1) |
| 40 | 38 | * - mmc_get_wp that maybe uses OMAP_MPUIO(3) | |
| 41 | #ifdef CONFIG_MMC_DEBUG | 39 | */ |
| 42 | dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1, | 40 | static struct omap_mmc_platform_data mmc1_data = { |
| 43 | bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull"); | ||
| 44 | #endif | ||
| 45 | if (slot != 0) { | ||
| 46 | dev_err(dev, "No such slot %d\n", slot + 1); | ||
| 47 | return -ENODEV; | ||
| 48 | } | ||
| 49 | |||
| 50 | /* Treated on upper level */ | ||
| 51 | |||
| 52 | return bus_mode; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int h3_mmc_get_cover_state(struct device *dev, int slot) | ||
| 56 | { | ||
| 57 | BUG_ON(slot != 0); | ||
| 58 | |||
| 59 | return slot_cover_open; | ||
| 60 | } | ||
| 61 | |||
| 62 | void h3_mmc_slot_cover_handler(void *arg, int state) | ||
| 63 | { | ||
| 64 | if (mmc_device == NULL) | ||
| 65 | return; | ||
| 66 | |||
| 67 | slot_cover_open = state; | ||
| 68 | omap_mmc_notify_cover_event(mmc_device, 0, state); | ||
| 69 | } | ||
| 70 | |||
| 71 | static int h3_mmc_late_init(struct device *dev) | ||
| 72 | { | ||
| 73 | int ret = 0; | ||
| 74 | |||
| 75 | mmc_device = dev; | ||
| 76 | |||
| 77 | return ret; | ||
| 78 | } | ||
| 79 | |||
| 80 | static void h3_mmc_cleanup(struct device *dev) | ||
| 81 | { | ||
| 82 | } | ||
| 83 | |||
| 84 | static struct omap_mmc_platform_data h3_mmc_data = { | ||
| 85 | .nr_slots = 1, | 41 | .nr_slots = 1, |
| 86 | .switch_slot = NULL, | 42 | .dma_mask = 0xffffffff, |
| 87 | .init = h3_mmc_late_init, | ||
| 88 | .cleanup = h3_mmc_cleanup, | ||
| 89 | .slots[0] = { | 43 | .slots[0] = { |
| 90 | .set_power = h3_mmc_set_power, | 44 | .set_power = mmc_set_power, |
| 91 | .set_bus_mode = h3_mmc_set_bus_mode, | ||
| 92 | .get_ro = NULL, | ||
| 93 | .get_cover_state = h3_mmc_get_cover_state, | ||
| 94 | .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | | 45 | .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | |
| 95 | MMC_VDD_32_33 | MMC_VDD_33_34, | 46 | MMC_VDD_32_33 | MMC_VDD_33_34, |
| 96 | .name = "mmcblk", | 47 | .name = "mmcblk", |
| 97 | }, | 48 | }, |
| 98 | }; | 49 | }; |
| 99 | 50 | ||
| 51 | static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; | ||
| 52 | |||
| 100 | void __init h3_mmc_init(void) | 53 | void __init h3_mmc_init(void) |
| 101 | { | 54 | { |
| 102 | omap_set_mmc_info(1, &h3_mmc_data); | 55 | int ret; |
| 56 | |||
| 57 | ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power"); | ||
| 58 | if (ret < 0) | ||
| 59 | return; | ||
| 60 | gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0); | ||
| 61 | |||
| 62 | mmc_data[0] = &mmc1_data; | ||
| 63 | omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC); | ||
| 103 | } | 64 | } |
| 104 | 65 | ||
| 105 | #else | 66 | #else |
| @@ -108,7 +69,4 @@ void __init h3_mmc_init(void) | |||
| 108 | { | 69 | { |
| 109 | } | 70 | } |
| 110 | 71 | ||
| 111 | void h3_mmc_slot_cover_handler(void *arg, int state) | ||
| 112 | { | ||
| 113 | } | ||
| 114 | #endif | 72 | #endif |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 0332203bd53d..5157eea9be35 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
| @@ -447,15 +447,6 @@ static struct omap_usb_config h3_usb_config __initdata = { | |||
| 447 | .pins[1] = 3, | 447 | .pins[1] = 3, |
| 448 | }; | 448 | }; |
| 449 | 449 | ||
| 450 | static struct omap_mmc_config h3_mmc_config __initdata = { | ||
| 451 | .mmc[0] = { | ||
| 452 | .enabled = 1, | ||
| 453 | .wire4 = 1, | ||
| 454 | }, | ||
| 455 | }; | ||
| 456 | |||
| 457 | extern struct omap_mmc_platform_data h3_mmc_data; | ||
| 458 | |||
| 459 | static struct omap_uart_config h3_uart_config __initdata = { | 450 | static struct omap_uart_config h3_uart_config __initdata = { |
| 460 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 451 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 461 | }; | 452 | }; |
| @@ -466,7 +457,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = { | |||
| 466 | 457 | ||
| 467 | static struct omap_board_config_kernel h3_config[] __initdata = { | 458 | static struct omap_board_config_kernel h3_config[] __initdata = { |
| 468 | { OMAP_TAG_USB, &h3_usb_config }, | 459 | { OMAP_TAG_USB, &h3_usb_config }, |
| 469 | { OMAP_TAG_MMC, &h3_mmc_config }, | ||
| 470 | { OMAP_TAG_UART, &h3_uart_config }, | 460 | { OMAP_TAG_UART, &h3_uart_config }, |
| 471 | { OMAP_TAG_LCD, &h3_lcd_config }, | 461 | { OMAP_TAG_LCD, &h3_lcd_config }, |
| 472 | }; | 462 | }; |
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index a21e365a7a87..af2fb9070083 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <mach/common.h> | 39 | #include <mach/common.h> |
| 40 | #include <mach/mcbsp.h> | 40 | #include <mach/mcbsp.h> |
| 41 | #include <mach/omap-alsa.h> | 41 | #include <mach/omap-alsa.h> |
| 42 | #include <mach/mmc.h> | ||
| 42 | 43 | ||
| 43 | static int innovator_keymap[] = { | 44 | static int innovator_keymap[] = { |
| 44 | KEY(0, 0, KEY_F1), | 45 | KEY(0, 0, KEY_F1), |
| @@ -360,16 +361,49 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = { | |||
| 360 | }; | 361 | }; |
| 361 | #endif | 362 | #endif |
| 362 | 363 | ||
| 363 | static struct omap_mmc_config innovator_mmc_config __initdata = { | 364 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
| 364 | .mmc [0] = { | 365 | |
| 365 | .enabled = 1, | 366 | static int mmc_set_power(struct device *dev, int slot, int power_on, |
| 366 | .wire4 = 1, | 367 | int vdd) |
| 367 | .wp_pin = OMAP_MPUIO(3), | 368 | { |
| 368 | .power_pin = -1, /* FPGA F3 UIO42 */ | 369 | if (power_on) |
| 369 | .switch_pin = -1, /* FPGA F4 UIO43 */ | 370 | fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), |
| 371 | OMAP1510_FPGA_POWER); | ||
| 372 | else | ||
| 373 | fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), | ||
| 374 | OMAP1510_FPGA_POWER); | ||
| 375 | |||
| 376 | return 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | /* | ||
| 380 | * Innovator could use the following functions tested: | ||
| 381 | * - mmc_get_wp that uses OMAP_MPUIO(3) | ||
| 382 | * - mmc_get_cover_state that uses FPGA F4 UIO43 | ||
| 383 | */ | ||
| 384 | static struct omap_mmc_platform_data mmc1_data = { | ||
| 385 | .nr_slots = 1, | ||
| 386 | .slots[0] = { | ||
| 387 | .set_power = mmc_set_power, | ||
| 388 | .wires = 4, | ||
| 389 | .name = "mmcblk", | ||
| 370 | }, | 390 | }, |
| 371 | }; | 391 | }; |
| 372 | 392 | ||
| 393 | static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; | ||
| 394 | |||
| 395 | void __init innovator_mmc_init(void) | ||
| 396 | { | ||
| 397 | mmc_data[0] = &mmc1_data; | ||
| 398 | omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC); | ||
| 399 | } | ||
| 400 | |||
| 401 | #else | ||
| 402 | static inline void innovator_mmc_init(void) | ||
| 403 | { | ||
| 404 | } | ||
| 405 | #endif | ||
| 406 | |||
| 373 | static struct omap_uart_config innovator_uart_config __initdata = { | 407 | static struct omap_uart_config innovator_uart_config __initdata = { |
| 374 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 408 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 375 | }; | 409 | }; |
| @@ -377,7 +411,6 @@ static struct omap_uart_config innovator_uart_config __initdata = { | |||
| 377 | static struct omap_board_config_kernel innovator_config[] = { | 411 | static struct omap_board_config_kernel innovator_config[] = { |
| 378 | { OMAP_TAG_USB, NULL }, | 412 | { OMAP_TAG_USB, NULL }, |
| 379 | { OMAP_TAG_LCD, NULL }, | 413 | { OMAP_TAG_LCD, NULL }, |
| 380 | { OMAP_TAG_MMC, &innovator_mmc_config }, | ||
| 381 | { OMAP_TAG_UART, &innovator_uart_config }, | 414 | { OMAP_TAG_UART, &innovator_uart_config }, |
| 382 | }; | 415 | }; |
| 383 | 416 | ||
| @@ -412,6 +445,7 @@ static void __init innovator_init(void) | |||
| 412 | omap_board_config_size = ARRAY_SIZE(innovator_config); | 445 | omap_board_config_size = ARRAY_SIZE(innovator_config); |
| 413 | omap_serial_init(); | 446 | omap_serial_init(); |
| 414 | omap_register_i2c_bus(1, 100, NULL, 0); | 447 | omap_register_i2c_bus(1, 100, NULL, 0); |
| 448 | innovator_mmc_init(); | ||
| 415 | } | 449 | } |
| 416 | 450 | ||
| 417 | static void __init innovator_map_io(void) | 451 | static void __init innovator_map_io(void) |
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index b26782471e59..4970c402a594 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <mach/aic23.h> | 35 | #include <mach/aic23.h> |
| 36 | #include <mach/omapfb.h> | 36 | #include <mach/omapfb.h> |
| 37 | #include <mach/lcd_mipid.h> | 37 | #include <mach/lcd_mipid.h> |
| 38 | #include <mach/mmc.h> | ||
| 38 | 39 | ||
| 39 | #define ADS7846_PENDOWN_GPIO 15 | 40 | #define ADS7846_PENDOWN_GPIO 15 |
| 40 | 41 | ||
| @@ -173,26 +174,68 @@ static struct omap_usb_config nokia770_usb_config __initdata = { | |||
| 173 | .pins[0] = 6, | 174 | .pins[0] = 6, |
| 174 | }; | 175 | }; |
| 175 | 176 | ||
| 176 | static struct omap_mmc_config nokia770_mmc_config __initdata = { | 177 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
| 177 | .mmc[0] = { | 178 | |
| 178 | .enabled = 0, | 179 | #define NOKIA770_GPIO_MMC_POWER 41 |
| 179 | .wire4 = 0, | 180 | #define NOKIA770_GPIO_MMC_SWITCH 23 |
| 180 | .wp_pin = -1, | 181 | |
| 181 | .power_pin = -1, | 182 | static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on, |
| 182 | .switch_pin = -1, | 183 | int vdd) |
| 183 | }, | 184 | { |
| 184 | .mmc[1] = { | 185 | if (power_on) |
| 185 | .enabled = 0, | 186 | gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1); |
| 186 | .wire4 = 0, | 187 | else |
| 187 | .wp_pin = -1, | 188 | gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0); |
| 188 | .power_pin = -1, | 189 | |
| 189 | .switch_pin = -1, | 190 | return 0; |
| 191 | } | ||
| 192 | |||
| 193 | static int nokia770_mmc_get_cover_state(struct device *dev, int slot) | ||
| 194 | { | ||
| 195 | return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH); | ||
| 196 | } | ||
| 197 | |||
| 198 | static struct omap_mmc_platform_data nokia770_mmc2_data = { | ||
| 199 | .nr_slots = 1, | ||
| 200 | .dma_mask = 0xffffffff, | ||
| 201 | .slots[0] = { | ||
| 202 | .set_power = nokia770_mmc_set_power, | ||
| 203 | .get_cover_state = nokia770_mmc_get_cover_state, | ||
| 204 | .name = "mmcblk", | ||
| 190 | }, | 205 | }, |
| 191 | }; | 206 | }; |
| 192 | 207 | ||
| 208 | static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC]; | ||
| 209 | |||
| 210 | static void __init nokia770_mmc_init(void) | ||
| 211 | { | ||
| 212 | int ret; | ||
| 213 | |||
| 214 | ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power"); | ||
| 215 | if (ret < 0) | ||
| 216 | return; | ||
| 217 | gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0); | ||
| 218 | |||
| 219 | ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover"); | ||
| 220 | if (ret < 0) { | ||
| 221 | gpio_free(NOKIA770_GPIO_MMC_POWER); | ||
| 222 | return; | ||
| 223 | } | ||
| 224 | gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH); | ||
| 225 | |||
| 226 | /* Only the second MMC controller is used */ | ||
| 227 | nokia770_mmc_data[1] = &nokia770_mmc2_data; | ||
| 228 | omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC); | ||
| 229 | } | ||
| 230 | |||
| 231 | #else | ||
| 232 | static inline void nokia770_mmc_init(void) | ||
| 233 | { | ||
| 234 | } | ||
| 235 | #endif | ||
| 236 | |||
| 193 | static struct omap_board_config_kernel nokia770_config[] __initdata = { | 237 | static struct omap_board_config_kernel nokia770_config[] __initdata = { |
| 194 | { OMAP_TAG_USB, NULL }, | 238 | { OMAP_TAG_USB, NULL }, |
| 195 | { OMAP_TAG_MMC, &nokia770_mmc_config }, | ||
| 196 | }; | 239 | }; |
| 197 | 240 | ||
| 198 | #if defined(CONFIG_OMAP_DSP) | 241 | #if defined(CONFIG_OMAP_DSP) |
| @@ -335,6 +378,7 @@ static void __init omap_nokia770_init(void) | |||
| 335 | omap_dsp_init(); | 378 | omap_dsp_init(); |
| 336 | ads7846_dev_init(); | 379 | ads7846_dev_init(); |
| 337 | mipid_dev_init(); | 380 | mipid_dev_init(); |
| 381 | nokia770_mmc_init(); | ||
| 338 | } | 382 | } |
| 339 | 383 | ||
| 340 | static void __init omap_nokia770_map_io(void) | 384 | static void __init omap_nokia770_map_io(void) |
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 4141e3917d7c..75e32d35afd9 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c | |||
| @@ -316,7 +316,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery) | |||
| 316 | 316 | ||
| 317 | static struct omap_board_config_kernel palmte_config[] __initdata = { | 317 | static struct omap_board_config_kernel palmte_config[] __initdata = { |
| 318 | { OMAP_TAG_USB, &palmte_usb_config }, | 318 | { OMAP_TAG_USB, &palmte_usb_config }, |
| 319 | { OMAP_TAG_MMC, &palmte_mmc_config }, | ||
| 320 | { OMAP_TAG_LCD, &palmte_lcd_config }, | 319 | { OMAP_TAG_LCD, &palmte_lcd_config }, |
| 321 | { OMAP_TAG_UART, &palmte_uart_config }, | 320 | { OMAP_TAG_UART, &palmte_uart_config }, |
| 322 | }; | 321 | }; |
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 801fb5f62ed7..cc05257eb1cd 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c | |||
| @@ -267,16 +267,6 @@ static struct omap_usb_config palmz71_usb_config __initdata = { | |||
| 267 | .pins[0] = 2, | 267 | .pins[0] = 2, |
| 268 | }; | 268 | }; |
| 269 | 269 | ||
| 270 | static struct omap_mmc_config palmz71_mmc_config __initdata = { | ||
| 271 | .mmc[0] = { | ||
| 272 | .enabled = 1, | ||
| 273 | .wire4 = 0, | ||
| 274 | .wp_pin = PALMZ71_MMC_WP_GPIO, | ||
| 275 | .power_pin = -1, | ||
| 276 | .switch_pin = PALMZ71_MMC_IN_GPIO, | ||
| 277 | }, | ||
| 278 | }; | ||
| 279 | |||
| 280 | static struct omap_lcd_config palmz71_lcd_config __initdata = { | 270 | static struct omap_lcd_config palmz71_lcd_config __initdata = { |
| 281 | .ctrl_name = "internal", | 271 | .ctrl_name = "internal", |
| 282 | }; | 272 | }; |
| @@ -287,7 +277,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = { | |||
| 287 | 277 | ||
| 288 | static struct omap_board_config_kernel palmz71_config[] __initdata = { | 278 | static struct omap_board_config_kernel palmz71_config[] __initdata = { |
| 289 | {OMAP_TAG_USB, &palmz71_usb_config}, | 279 | {OMAP_TAG_USB, &palmz71_usb_config}, |
| 290 | {OMAP_TAG_MMC, &palmz71_mmc_config}, | ||
| 291 | {OMAP_TAG_LCD, &palmz71_lcd_config}, | 280 | {OMAP_TAG_LCD, &palmz71_lcd_config}, |
| 292 | {OMAP_TAG_UART, &palmz71_uart_config}, | 281 | {OMAP_TAG_UART, &palmz71_uart_config}, |
| 293 | }; | 282 | }; |
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c index 0be4ebaa2842..66a4d7d5255d 100644 --- a/arch/arm/mach-omap1/board-sx1-mmc.c +++ b/arch/arm/mach-omap1/board-sx1-mmc.c | |||
| @@ -12,30 +12,20 @@ | |||
| 12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | |||
| 15 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
| 16 | #include <mach/mmc.h> | 18 | #include <mach/mmc.h> |
| 17 | #include <mach/gpio.h> | 19 | #include <mach/gpio.h> |
| 18 | 20 | ||
| 19 | #ifdef CONFIG_MMC_OMAP | 21 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
| 20 | static int slot_cover_open; | ||
| 21 | static struct device *mmc_device; | ||
| 22 | 22 | ||
| 23 | static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, | 23 | static int mmc_set_power(struct device *dev, int slot, int power_on, |
| 24 | int vdd) | 24 | int vdd) |
| 25 | { | 25 | { |
| 26 | int err; | 26 | int err; |
| 27 | u8 dat = 0; | 27 | u8 dat = 0; |
| 28 | 28 | ||
| 29 | #ifdef CONFIG_MMC_DEBUG | ||
| 30 | dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1, | ||
| 31 | power_on ? "on" : "off", vdd); | ||
| 32 | #endif | ||
| 33 | |||
| 34 | if (slot != 0) { | ||
| 35 | dev_err(dev, "No such slot %d\n", slot + 1); | ||
| 36 | return -ENODEV; | ||
| 37 | } | ||
| 38 | |||
| 39 | err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); | 29 | err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); |
| 40 | if (err < 0) | 30 | if (err < 0) |
| 41 | return err; | 31 | return err; |
| @@ -48,68 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, | |||
| 48 | return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); | 38 | return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); |
| 49 | } | 39 | } |
| 50 | 40 | ||
| 51 | static int sx1_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode) | 41 | /* Cover switch is at OMAP_MPUIO(3) */ |
| 52 | { | 42 | static struct omap_mmc_platform_data mmc1_data = { |
| 53 | #ifdef CONFIG_MMC_DEBUG | ||
| 54 | dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1, | ||
| 55 | bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull"); | ||
| 56 | #endif | ||
| 57 | if (slot != 0) { | ||
| 58 | dev_err(dev, "No such slot %d\n", slot + 1); | ||
| 59 | return -ENODEV; | ||
| 60 | } | ||
| 61 | |||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int sx1_mmc_get_cover_state(struct device *dev, int slot) | ||
| 66 | { | ||
| 67 | BUG_ON(slot != 0); | ||
| 68 | |||
| 69 | return slot_cover_open; | ||
| 70 | } | ||
| 71 | |||
| 72 | void sx1_mmc_slot_cover_handler(void *arg, int state) | ||
| 73 | { | ||
| 74 | if (mmc_device == NULL) | ||
| 75 | return; | ||
| 76 | |||
| 77 | slot_cover_open = state; | ||
| 78 | omap_mmc_notify_cover_event(mmc_device, 0, state); | ||
| 79 | } | ||
| 80 | |||
| 81 | static int sx1_mmc_late_init(struct device *dev) | ||
| 82 | { | ||
| 83 | int ret = 0; | ||
| 84 | |||
| 85 | mmc_device = dev; | ||
| 86 | |||
| 87 | return ret; | ||
| 88 | } | ||
| 89 | |||
| 90 | static void sx1_mmc_cleanup(struct device *dev) | ||
| 91 | { | ||
| 92 | } | ||
| 93 | |||
| 94 | static struct omap_mmc_platform_data sx1_mmc_data = { | ||
| 95 | .nr_slots = 1, | 43 | .nr_slots = 1, |
| 96 | .switch_slot = NULL, | ||
| 97 | .init = sx1_mmc_late_init, | ||
| 98 | .cleanup = sx1_mmc_cleanup, | ||
| 99 | .slots[0] = { | 44 | .slots[0] = { |
| 100 | .set_power = sx1_mmc_set_power, | 45 | .set_power = mmc_set_power, |
| 101 | .set_bus_mode = sx1_mmc_set_bus_mode, | ||
| 102 | .get_ro = NULL, | ||
| 103 | .get_cover_state = sx1_mmc_get_cover_state, | ||
| 104 | .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | | 46 | .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | |
| 105 | MMC_VDD_32_33 | MMC_VDD_33_34, | 47 | MMC_VDD_32_33 | MMC_VDD_33_34, |
| 106 | .name = "mmcblk", | 48 | .name = "mmcblk", |
| 107 | }, | 49 | }, |
| 108 | }; | 50 | }; |
| 109 | 51 | ||
| 52 | static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC]; | ||
| 53 | |||
| 110 | void __init sx1_mmc_init(void) | 54 | void __init sx1_mmc_init(void) |
| 111 | { | 55 | { |
| 112 | omap_set_mmc_info(1, &sx1_mmc_data); | 56 | mmc_data[0] = &mmc1_data; |
| 57 | omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC); | ||
| 113 | } | 58 | } |
| 114 | 59 | ||
| 115 | #else | 60 | #else |
| @@ -118,7 +63,4 @@ void __init sx1_mmc_init(void) | |||
| 118 | { | 63 | { |
| 119 | } | 64 | } |
| 120 | 65 | ||
| 121 | void sx1_mmc_slot_cover_handler(void *arg, int state) | ||
| 122 | { | ||
| 123 | } | ||
| 124 | #endif | 66 | #endif |
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 93bd395b9972..8171fe0ca082 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c | |||
| @@ -378,15 +378,6 @@ static struct omap_usb_config sx1_usb_config __initdata = { | |||
| 378 | .pins[2] = 0, | 378 | .pins[2] = 0, |
| 379 | }; | 379 | }; |
| 380 | 380 | ||
| 381 | /*----------- MMC -------------------------*/ | ||
| 382 | |||
| 383 | static struct omap_mmc_config sx1_mmc_config __initdata = { | ||
| 384 | .mmc [0] = { | ||
| 385 | .enabled = 1, | ||
| 386 | .wire4 = 0, | ||
| 387 | }, | ||
| 388 | }; | ||
| 389 | |||
| 390 | /*----------- LCD -------------------------*/ | 381 | /*----------- LCD -------------------------*/ |
| 391 | 382 | ||
| 392 | static struct platform_device sx1_lcd_device = { | 383 | static struct platform_device sx1_lcd_device = { |
| @@ -414,7 +405,6 @@ static struct omap_uart_config sx1_uart_config __initdata = { | |||
| 414 | 405 | ||
| 415 | static struct omap_board_config_kernel sx1_config[] __initdata = { | 406 | static struct omap_board_config_kernel sx1_config[] __initdata = { |
| 416 | { OMAP_TAG_USB, &sx1_usb_config }, | 407 | { OMAP_TAG_USB, &sx1_usb_config }, |
| 417 | { OMAP_TAG_MMC, &sx1_mmc_config }, | ||
| 418 | { OMAP_TAG_LCD, &sx1_lcd_config }, | 408 | { OMAP_TAG_LCD, &sx1_lcd_config }, |
| 419 | { OMAP_TAG_UART, &sx1_uart_config }, | 409 | { OMAP_TAG_UART, &sx1_uart_config }, |
| 420 | }; | 410 | }; |
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 92c9de1090a9..c224f3c64235 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/irq.h> | ||
| 18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 20 | #include <linux/notifier.h> | 21 | #include <linux/notifier.h> |
| @@ -140,21 +141,12 @@ static struct omap_usb_config voiceblue_usb_config __initdata = { | |||
| 140 | .pins[2] = 6, | 141 | .pins[2] = 6, |
| 141 | }; | 142 | }; |
| 142 | 143 | ||
| 143 | static struct omap_mmc_config voiceblue_mmc_config __initdata = { | ||
| 144 | .mmc[0] = { | ||
| 145 | .enabled = 1, | ||
| 146 | .power_pin = 2, | ||
| 147 | .switch_pin = -1, | ||
| 148 | }, | ||
| 149 | }; | ||
| 150 | |||
| 151 | static struct omap_uart_config voiceblue_uart_config __initdata = { | 144 | static struct omap_uart_config voiceblue_uart_config __initdata = { |
| 152 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 145 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 153 | }; | 146 | }; |
| 154 | 147 | ||
| 155 | static struct omap_board_config_kernel voiceblue_config[] = { | 148 | static struct omap_board_config_kernel voiceblue_config[] = { |
| 156 | { OMAP_TAG_USB, &voiceblue_usb_config }, | 149 | { OMAP_TAG_USB, &voiceblue_usb_config }, |
| 157 | { OMAP_TAG_MMC, &voiceblue_mmc_config }, | ||
| 158 | { OMAP_TAG_UART, &voiceblue_uart_config }, | 150 | { OMAP_TAG_UART, &voiceblue_uart_config }, |
| 159 | }; | 151 | }; |
| 160 | 152 | ||
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 5635b511ab6f..c1dcdf18d8dd 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h | |||
| @@ -705,7 +705,6 @@ static struct clk bclk_16xx = { | |||
| 705 | 705 | ||
| 706 | static struct clk mmc1_ck = { | 706 | static struct clk mmc1_ck = { |
| 707 | .name = "mmc_ck", | 707 | .name = "mmc_ck", |
| 708 | .id = 1, | ||
| 709 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | 708 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ |
| 710 | .parent = &armper_ck.clk, | 709 | .parent = &armper_ck.clk, |
| 711 | .rate = 48000000, | 710 | .rate = 48000000, |
| @@ -720,7 +719,7 @@ static struct clk mmc1_ck = { | |||
| 720 | 719 | ||
| 721 | static struct clk mmc2_ck = { | 720 | static struct clk mmc2_ck = { |
| 722 | .name = "mmc_ck", | 721 | .name = "mmc_ck", |
| 723 | .id = 2, | 722 | .id = 1, |
| 724 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | 723 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ |
| 725 | .parent = &armper_ck.clk, | 724 | .parent = &armper_ck.clk, |
| 726 | .rate = 48000000, | 725 | .rate = 48000000, |
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index e382b438c64e..77382d8b6b2f 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <mach/board.h> | 22 | #include <mach/board.h> |
| 23 | #include <mach/mux.h> | 23 | #include <mach/mux.h> |
| 24 | #include <mach/gpio.h> | 24 | #include <mach/gpio.h> |
| 25 | #include <mach/mmc.h> | ||
| 25 | 26 | ||
| 26 | /*-------------------------------------------------------------------------*/ | 27 | /*-------------------------------------------------------------------------*/ |
| 27 | 28 | ||
| @@ -99,6 +100,95 @@ static inline void omap_init_mbox(void) | |||
| 99 | static inline void omap_init_mbox(void) { } | 100 | static inline void omap_init_mbox(void) { } |
| 100 | #endif | 101 | #endif |
| 101 | 102 | ||
| 103 | /*-------------------------------------------------------------------------*/ | ||
| 104 | |||
| 105 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) | ||
| 106 | |||
| 107 | static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | ||
| 108 | int controller_nr) | ||
| 109 | { | ||
| 110 | if (controller_nr == 0) { | ||
| 111 | omap_cfg_reg(MMC_CMD); | ||
| 112 | omap_cfg_reg(MMC_CLK); | ||
| 113 | omap_cfg_reg(MMC_DAT0); | ||
| 114 | if (cpu_is_omap1710()) { | ||
| 115 | omap_cfg_reg(M15_1710_MMC_CLKI); | ||
| 116 | omap_cfg_reg(P19_1710_MMC_CMDDIR); | ||
| 117 | omap_cfg_reg(P20_1710_MMC_DATDIR0); | ||
| 118 | } | ||
| 119 | if (mmc_controller->slots[0].wires == 4) { | ||
| 120 | omap_cfg_reg(MMC_DAT1); | ||
| 121 | /* NOTE: DAT2 can be on W10 (here) or M15 */ | ||
| 122 | if (!mmc_controller->slots[0].nomux) | ||
| 123 | omap_cfg_reg(MMC_DAT2); | ||
| 124 | omap_cfg_reg(MMC_DAT3); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | /* Block 2 is on newer chips, and has many pinout options */ | ||
| 129 | if (cpu_is_omap16xx() && controller_nr == 1) { | ||
| 130 | if (!mmc_controller->slots[1].nomux) { | ||
| 131 | omap_cfg_reg(Y8_1610_MMC2_CMD); | ||
| 132 | omap_cfg_reg(Y10_1610_MMC2_CLK); | ||
| 133 | omap_cfg_reg(R18_1610_MMC2_CLKIN); | ||
| 134 | omap_cfg_reg(W8_1610_MMC2_DAT0); | ||
| 135 | if (mmc_controller->slots[1].wires == 4) { | ||
| 136 | omap_cfg_reg(V8_1610_MMC2_DAT1); | ||
| 137 | omap_cfg_reg(W15_1610_MMC2_DAT2); | ||
| 138 | omap_cfg_reg(R10_1610_MMC2_DAT3); | ||
| 139 | } | ||
| 140 | |||
| 141 | /* These are needed for the level shifter */ | ||
| 142 | omap_cfg_reg(V9_1610_MMC2_CMDDIR); | ||
| 143 | omap_cfg_reg(V5_1610_MMC2_DATDIR0); | ||
| 144 | omap_cfg_reg(W19_1610_MMC2_DATDIR1); | ||
| 145 | } | ||
| 146 | |||
| 147 | /* Feedback clock must be set on OMAP-1710 MMC2 */ | ||
| 148 | if (cpu_is_omap1710()) | ||
| 149 | omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), | ||
| 150 | MOD_CONF_CTRL_1); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, | ||
| 155 | int nr_controllers) | ||
| 156 | { | ||
| 157 | int i; | ||
| 158 | |||
| 159 | for (i = 0; i < nr_controllers; i++) { | ||
| 160 | unsigned long base, size; | ||
| 161 | unsigned int irq = 0; | ||
| 162 | |||
| 163 | if (!mmc_data[i]) | ||
| 164 | continue; | ||
| 165 | |||
| 166 | omap1_mmc_mux(mmc_data[i], i); | ||
| 167 | |||
| 168 | switch (i) { | ||
| 169 | case 0: | ||
| 170 | base = OMAP1_MMC1_BASE; | ||
| 171 | irq = INT_MMC; | ||
| 172 | break; | ||
| 173 | case 1: | ||
| 174 | if (!cpu_is_omap16xx()) | ||
| 175 | return; | ||
| 176 | base = OMAP1_MMC2_BASE; | ||
| 177 | irq = INT_1610_MMC2; | ||
| 178 | break; | ||
| 179 | default: | ||
| 180 | continue; | ||
| 181 | } | ||
| 182 | size = OMAP1_MMC_SIZE; | ||
| 183 | |||
| 184 | omap_mmc_add(i, base, size, irq, mmc_data[i]); | ||
| 185 | }; | ||
| 186 | } | ||
| 187 | |||
| 188 | #endif | ||
| 189 | |||
| 190 | /*-------------------------------------------------------------------------*/ | ||
| 191 | |||
| 102 | #if defined(CONFIG_OMAP_STI) | 192 | #if defined(CONFIG_OMAP_STI) |
| 103 | 193 | ||
| 104 | #define OMAP1_STI_BASE 0xfffea000 | 194 | #define OMAP1_STI_BASE 0xfffea000 |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index f12c43e4932f..bbd12bc10fdc 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
| @@ -27,10 +27,15 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o | |||
| 27 | # Specific board support | 27 | # Specific board support |
| 28 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o | 28 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o |
| 29 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o | 29 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o |
| 30 | obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o | 30 | obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \ |
| 31 | mmc-twl4030.o | ||
| 31 | obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o | 32 | obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o |
| 32 | obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o | 33 | obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ |
| 33 | obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o | 34 | mmc-twl4030.o |
| 34 | obj-$(CONFIG_MACH_OVERO) += board-overo.o | 35 | obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \ |
| 35 | obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o | 36 | mmc-twl4030.o |
| 37 | obj-$(CONFIG_MACH_OVERO) += board-overo.o \ | ||
| 38 | mmc-twl4030.o | ||
| 39 | obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ | ||
| 40 | mmc-twl4030.o | ||
| 36 | 41 | ||
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 6748de6e19a8..83fa37211d77 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/mtd/mtd.h> | 19 | #include <linux/mtd/mtd.h> |
| 20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/i2c/twl4030.h> | ||
| 22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
| 23 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| 24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| @@ -35,6 +36,7 @@ | |||
| 35 | #include <mach/common.h> | 36 | #include <mach/common.h> |
| 36 | #include <mach/gpmc.h> | 37 | #include <mach/gpmc.h> |
| 37 | 38 | ||
| 39 | #include "mmc-twl4030.h" | ||
| 38 | 40 | ||
| 39 | #define SDP2430_FLASH_CS 0 | 41 | #define SDP2430_FLASH_CS 0 |
| 40 | #define SDP2430_SMC91X_CS 5 | 42 | #define SDP2430_SMC91X_CS 5 |
| @@ -197,12 +199,58 @@ static struct omap_board_config_kernel sdp2430_config[] = { | |||
| 197 | {OMAP_TAG_UART, &sdp2430_uart_config}, | 199 | {OMAP_TAG_UART, &sdp2430_uart_config}, |
| 198 | }; | 200 | }; |
| 199 | 201 | ||
| 202 | |||
| 203 | static struct twl4030_gpio_platform_data sdp2430_gpio_data = { | ||
| 204 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
| 205 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
| 206 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
| 207 | }; | ||
| 208 | |||
| 209 | static struct twl4030_platform_data sdp2430_twldata = { | ||
| 210 | .irq_base = TWL4030_IRQ_BASE, | ||
| 211 | .irq_end = TWL4030_IRQ_END, | ||
| 212 | |||
| 213 | /* platform_data for children goes here */ | ||
| 214 | .gpio = &sdp2430_gpio_data, | ||
| 215 | }; | ||
| 216 | |||
| 217 | static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { | ||
| 218 | { | ||
| 219 | I2C_BOARD_INFO("twl4030", 0x48), | ||
| 220 | .flags = I2C_CLIENT_WAKE, | ||
| 221 | .irq = INT_24XX_SYS_NIRQ, | ||
| 222 | .platform_data = &sdp2430_twldata, | ||
| 223 | }, | ||
| 224 | }; | ||
| 225 | |||
| 226 | static int __init omap2430_i2c_init(void) | ||
| 227 | { | ||
| 228 | omap_register_i2c_bus(1, 400, NULL, 0); | ||
| 229 | omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo, | ||
| 230 | ARRAY_SIZE(sdp2430_i2c_boardinfo)); | ||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
| 235 | { | ||
| 236 | .mmc = 1, | ||
| 237 | .wires = 4, | ||
| 238 | .gpio_cd = -EINVAL, | ||
| 239 | .gpio_wp = -EINVAL, | ||
| 240 | .ext_clock = 1, | ||
| 241 | }, | ||
| 242 | {} /* Terminator */ | ||
| 243 | }; | ||
| 244 | |||
| 200 | static void __init omap_2430sdp_init(void) | 245 | static void __init omap_2430sdp_init(void) |
| 201 | { | 246 | { |
| 247 | omap2430_i2c_init(); | ||
| 248 | |||
| 202 | platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); | 249 | platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); |
| 203 | omap_board_config = sdp2430_config; | 250 | omap_board_config = sdp2430_config; |
| 204 | omap_board_config_size = ARRAY_SIZE(sdp2430_config); | 251 | omap_board_config_size = ARRAY_SIZE(sdp2430_config); |
| 205 | omap_serial_init(); | 252 | omap_serial_init(); |
| 253 | twl4030_mmc_init(mmc); | ||
| 206 | } | 254 | } |
| 207 | 255 | ||
| 208 | static void __init omap_2430sdp_map_io(void) | 256 | static void __init omap_2430sdp_map_io(void) |
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index d83035b436d5..bf1e5d32c2a3 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c | |||
| @@ -261,16 +261,6 @@ static struct omap_uart_config apollon_uart_config __initdata = { | |||
| 261 | .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), | 261 | .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), |
| 262 | }; | 262 | }; |
| 263 | 263 | ||
| 264 | static struct omap_mmc_config apollon_mmc_config __initdata = { | ||
| 265 | .mmc [0] = { | ||
| 266 | .enabled = 1, | ||
| 267 | .wire4 = 1, | ||
| 268 | .wp_pin = -1, | ||
| 269 | .power_pin = -1, | ||
| 270 | .switch_pin = -1, | ||
| 271 | }, | ||
| 272 | }; | ||
| 273 | |||
| 274 | static struct omap_usb_config apollon_usb_config __initdata = { | 264 | static struct omap_usb_config apollon_usb_config __initdata = { |
| 275 | .register_dev = 1, | 265 | .register_dev = 1, |
| 276 | .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ | 266 | .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ |
| @@ -284,7 +274,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = { | |||
| 284 | 274 | ||
| 285 | static struct omap_board_config_kernel apollon_config[] = { | 275 | static struct omap_board_config_kernel apollon_config[] = { |
| 286 | { OMAP_TAG_UART, &apollon_uart_config }, | 276 | { OMAP_TAG_UART, &apollon_uart_config }, |
| 287 | { OMAP_TAG_MMC, &apollon_mmc_config }, | ||
| 288 | { OMAP_TAG_USB, &apollon_usb_config }, | 277 | { OMAP_TAG_USB, &apollon_usb_config }, |
| 289 | { OMAP_TAG_LCD, &apollon_lcd_config }, | 278 | { OMAP_TAG_LCD, &apollon_lcd_config }, |
| 290 | }; | 279 | }; |
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 9ba097868e72..3b34c20d1df4 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
| @@ -41,19 +41,8 @@ static struct omap_uart_config generic_uart_config __initdata = { | |||
| 41 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 41 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | static struct omap_mmc_config generic_mmc_config __initdata = { | ||
| 45 | .mmc [0] = { | ||
| 46 | .enabled = 0, | ||
| 47 | .wire4 = 0, | ||
| 48 | .wp_pin = -1, | ||
| 49 | .power_pin = -1, | ||
| 50 | .switch_pin = -1, | ||
| 51 | }, | ||
| 52 | }; | ||
| 53 | |||
| 54 | static struct omap_board_config_kernel generic_config[] = { | 44 | static struct omap_board_config_kernel generic_config[] = { |
| 55 | { OMAP_TAG_UART, &generic_uart_config }, | 45 | { OMAP_TAG_UART, &generic_uart_config }, |
| 56 | { OMAP_TAG_MMC, &generic_mmc_config }, | ||
| 57 | }; | 46 | }; |
| 58 | 47 | ||
| 59 | static void __init omap_generic_init(void) | 48 | static void __init omap_generic_init(void) |
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 7de0506e1e29..5e9b14675b1e 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
| @@ -373,23 +373,12 @@ static struct omap_uart_config h4_uart_config __initdata = { | |||
| 373 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 373 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 374 | }; | 374 | }; |
| 375 | 375 | ||
| 376 | static struct omap_mmc_config h4_mmc_config __initdata = { | ||
| 377 | .mmc [0] = { | ||
| 378 | .enabled = 1, | ||
| 379 | .wire4 = 1, | ||
| 380 | .wp_pin = -1, | ||
| 381 | .power_pin = -1, | ||
| 382 | .switch_pin = -1, | ||
| 383 | }, | ||
| 384 | }; | ||
| 385 | |||
| 386 | static struct omap_lcd_config h4_lcd_config __initdata = { | 376 | static struct omap_lcd_config h4_lcd_config __initdata = { |
| 387 | .ctrl_name = "internal", | 377 | .ctrl_name = "internal", |
| 388 | }; | 378 | }; |
| 389 | 379 | ||
| 390 | static struct omap_board_config_kernel h4_config[] = { | 380 | static struct omap_board_config_kernel h4_config[] = { |
| 391 | { OMAP_TAG_UART, &h4_uart_config }, | 381 | { OMAP_TAG_UART, &h4_uart_config }, |
| 392 | { OMAP_TAG_MMC, &h4_mmc_config }, | ||
| 393 | { OMAP_TAG_LCD, &h4_lcd_config }, | 382 | { OMAP_TAG_LCD, &h4_lcd_config }, |
| 394 | }; | 383 | }; |
| 395 | 384 | ||
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 43c7ac4b7f8f..aa6972781e4a 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 22 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
| 23 | #include <linux/spi/ads7846.h> | 23 | #include <linux/spi/ads7846.h> |
| 24 | #include <linux/i2c/twl4030.h> | ||
| 24 | 25 | ||
| 25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
| 26 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
| @@ -38,6 +39,8 @@ | |||
| 38 | #include <asm/delay.h> | 39 | #include <asm/delay.h> |
| 39 | #include <mach/control.h> | 40 | #include <mach/control.h> |
| 40 | 41 | ||
| 42 | #include "mmc-twl4030.h" | ||
| 43 | |||
| 41 | #define SDP3430_SMC91X_CS 3 | 44 | #define SDP3430_SMC91X_CS 3 |
| 42 | 45 | ||
| 43 | static struct resource ldp_smc911x_resources[] = { | 46 | static struct resource ldp_smc911x_resources[] = { |
| @@ -109,14 +112,48 @@ static struct omap_board_config_kernel ldp_config[] __initdata = { | |||
| 109 | { OMAP_TAG_UART, &ldp_uart_config }, | 112 | { OMAP_TAG_UART, &ldp_uart_config }, |
| 110 | }; | 113 | }; |
| 111 | 114 | ||
| 115 | static struct twl4030_gpio_platform_data ldp_gpio_data = { | ||
| 116 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
| 117 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
| 118 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct twl4030_platform_data ldp_twldata = { | ||
| 122 | .irq_base = TWL4030_IRQ_BASE, | ||
| 123 | .irq_end = TWL4030_IRQ_END, | ||
| 124 | |||
| 125 | /* platform_data for children goes here */ | ||
| 126 | .gpio = &ldp_gpio_data, | ||
| 127 | }; | ||
| 128 | |||
| 129 | static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = { | ||
| 130 | { | ||
| 131 | I2C_BOARD_INFO("twl4030", 0x48), | ||
| 132 | .flags = I2C_CLIENT_WAKE, | ||
| 133 | .irq = INT_34XX_SYS_NIRQ, | ||
| 134 | .platform_data = &ldp_twldata, | ||
| 135 | }, | ||
| 136 | }; | ||
| 137 | |||
| 112 | static int __init omap_i2c_init(void) | 138 | static int __init omap_i2c_init(void) |
| 113 | { | 139 | { |
| 114 | omap_register_i2c_bus(1, 2600, NULL, 0); | 140 | omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo, |
| 141 | ARRAY_SIZE(ldp_i2c_boardinfo)); | ||
| 115 | omap_register_i2c_bus(2, 400, NULL, 0); | 142 | omap_register_i2c_bus(2, 400, NULL, 0); |
| 116 | omap_register_i2c_bus(3, 400, NULL, 0); | 143 | omap_register_i2c_bus(3, 400, NULL, 0); |
| 117 | return 0; | 144 | return 0; |
| 118 | } | 145 | } |
| 119 | 146 | ||
| 147 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
| 148 | { | ||
| 149 | .mmc = 1, | ||
| 150 | .wires = 4, | ||
| 151 | .gpio_cd = -EINVAL, | ||
| 152 | .gpio_wp = -EINVAL, | ||
| 153 | }, | ||
| 154 | {} /* Terminator */ | ||
| 155 | }; | ||
| 156 | |||
| 120 | static void __init omap_ldp_init(void) | 157 | static void __init omap_ldp_init(void) |
| 121 | { | 158 | { |
| 122 | omap_i2c_init(); | 159 | omap_i2c_init(); |
| @@ -124,6 +161,7 @@ static void __init omap_ldp_init(void) | |||
| 124 | omap_board_config = ldp_config; | 161 | omap_board_config = ldp_config; |
| 125 | omap_board_config_size = ARRAY_SIZE(ldp_config); | 162 | omap_board_config_size = ARRAY_SIZE(ldp_config); |
| 126 | omap_serial_init(); | 163 | omap_serial_init(); |
| 164 | twl4030_mmc_init(mmc); | ||
| 127 | } | 165 | } |
| 128 | 166 | ||
| 129 | static void __init omap_ldp_map_io(void) | 167 | static void __init omap_ldp_map_io(void) |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index baa79674e9d5..9e5ada01b5fa 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
| @@ -38,7 +38,9 @@ | |||
| 38 | #include <mach/common.h> | 38 | #include <mach/common.h> |
| 39 | #include <mach/gpmc.h> | 39 | #include <mach/gpmc.h> |
| 40 | #include <mach/nand.h> | 40 | #include <mach/nand.h> |
| 41 | #include <mach/mux.h> | ||
| 41 | 42 | ||
| 43 | #include "mmc-twl4030.h" | ||
| 42 | 44 | ||
| 43 | #define GPMC_CS0_BASE 0x60 | 45 | #define GPMC_CS0_BASE 0x60 |
| 44 | #define GPMC_CS_SIZE 0x30 | 46 | #define GPMC_CS_SIZE 0x30 |
| @@ -103,6 +105,78 @@ static struct omap_uart_config omap3_beagle_uart_config __initdata = { | |||
| 103 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 105 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 104 | }; | 106 | }; |
| 105 | 107 | ||
| 108 | static struct twl4030_hsmmc_info mmc[] = { | ||
| 109 | { | ||
| 110 | .mmc = 1, | ||
| 111 | .wires = 8, | ||
| 112 | .gpio_wp = 29, | ||
| 113 | }, | ||
| 114 | {} /* Terminator */ | ||
| 115 | }; | ||
| 116 | |||
| 117 | static struct gpio_led gpio_leds[]; | ||
| 118 | |||
| 119 | static int beagle_twl_gpio_setup(struct device *dev, | ||
| 120 | unsigned gpio, unsigned ngpio) | ||
| 121 | { | ||
| 122 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ | ||
| 123 | |||
| 124 | /* REVISIT: need ehci-omap hooks for external VBUS | ||
| 125 | * power switch and overcurrent detect | ||
| 126 | */ | ||
| 127 | |||
| 128 | gpio_request(gpio + 1, "EHCI_nOC"); | ||
| 129 | gpio_direction_input(gpio + 1); | ||
| 130 | |||
| 131 | /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ | ||
| 132 | gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); | ||
| 133 | gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); | ||
| 134 | |||
| 135 | /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ | ||
| 136 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | static struct twl4030_gpio_platform_data beagle_gpio_data = { | ||
| 142 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
| 143 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
| 144 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
| 145 | .use_leds = true, | ||
| 146 | .pullups = BIT(1), | ||
| 147 | .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) | ||
| 148 | | BIT(15) | BIT(16) | BIT(17), | ||
| 149 | .setup = beagle_twl_gpio_setup, | ||
| 150 | }; | ||
| 151 | |||
| 152 | static struct twl4030_platform_data beagle_twldata = { | ||
| 153 | .irq_base = TWL4030_IRQ_BASE, | ||
| 154 | .irq_end = TWL4030_IRQ_END, | ||
| 155 | |||
| 156 | /* platform_data for children goes here */ | ||
| 157 | .gpio = &beagle_gpio_data, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { | ||
| 161 | { | ||
| 162 | I2C_BOARD_INFO("twl4030", 0x48), | ||
| 163 | .flags = I2C_CLIENT_WAKE, | ||
| 164 | .irq = INT_34XX_SYS_NIRQ, | ||
| 165 | .platform_data = &beagle_twldata, | ||
| 166 | }, | ||
| 167 | }; | ||
| 168 | |||
| 169 | static int __init omap3_beagle_i2c_init(void) | ||
| 170 | { | ||
| 171 | omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, | ||
| 172 | ARRAY_SIZE(beagle_i2c_boardinfo)); | ||
| 173 | #ifdef CONFIG_I2C2_OMAP_BEAGLE | ||
| 174 | omap_register_i2c_bus(2, 400, NULL, 0); | ||
| 175 | #endif | ||
| 176 | omap_register_i2c_bus(3, 400, NULL, 0); | ||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 106 | static void __init omap3_beagle_init_irq(void) | 180 | static void __init omap3_beagle_init_irq(void) |
| 107 | { | 181 | { |
| 108 | omap2_init_common_hw(); | 182 | omap2_init_common_hw(); |
| @@ -130,6 +204,11 @@ static struct gpio_led gpio_leds[] = { | |||
| 130 | .default_trigger = "mmc0", | 204 | .default_trigger = "mmc0", |
| 131 | .gpio = 149, | 205 | .gpio = 149, |
| 132 | }, | 206 | }, |
| 207 | { | ||
| 208 | .name = "beagleboard::pmu_stat", | ||
| 209 | .gpio = -EINVAL, /* gets replaced */ | ||
| 210 | .active_low = true, | ||
| 211 | }, | ||
| 133 | }; | 212 | }; |
| 134 | 213 | ||
| 135 | static struct gpio_led_platform_data gpio_led_info = { | 214 | static struct gpio_led_platform_data gpio_led_info = { |
| @@ -218,11 +297,22 @@ static void __init omap3beagle_flash_init(void) | |||
| 218 | 297 | ||
| 219 | static void __init omap3_beagle_init(void) | 298 | static void __init omap3_beagle_init(void) |
| 220 | { | 299 | { |
| 300 | omap3_beagle_i2c_init(); | ||
| 221 | platform_add_devices(omap3_beagle_devices, | 301 | platform_add_devices(omap3_beagle_devices, |
| 222 | ARRAY_SIZE(omap3_beagle_devices)); | 302 | ARRAY_SIZE(omap3_beagle_devices)); |
| 223 | omap_board_config = omap3_beagle_config; | 303 | omap_board_config = omap3_beagle_config; |
| 224 | omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); | 304 | omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); |
| 225 | omap_serial_init(); | 305 | omap_serial_init(); |
| 306 | |||
| 307 | omap_cfg_reg(AH8_34XX_GPIO29); | ||
| 308 | mmc[0].gpio_cd = gpio + 0; | ||
| 309 | twl4030_mmc_init(mmc); | ||
| 310 | |||
| 311 | omap_cfg_reg(J25_34XX_GPIO170); | ||
| 312 | gpio_request(170, "DVI_nPD"); | ||
| 313 | /* REVISIT leave DVI powered down until it's needed ... */ | ||
| 314 | gpio_direction_output(170, true); | ||
| 315 | |||
| 226 | omap3beagle_flash_init(); | 316 | omap3beagle_flash_init(); |
| 227 | } | 317 | } |
| 228 | 318 | ||
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 7236c7be05b3..b3196107afdb 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
| @@ -35,16 +35,48 @@ | |||
| 35 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
| 36 | #include <mach/mcspi.h> | 36 | #include <mach/mcspi.h> |
| 37 | 37 | ||
| 38 | #include "mmc-twl4030.h" | ||
| 39 | |||
| 38 | #define OMAP3_PANDORA_TS_GPIO 94 | 40 | #define OMAP3_PANDORA_TS_GPIO 94 |
| 39 | 41 | ||
| 42 | static struct twl4030_hsmmc_info omap3pandora_mmc[] = { | ||
| 43 | { | ||
| 44 | .mmc = 1, | ||
| 45 | .wires = 4, | ||
| 46 | .gpio_cd = -EINVAL, | ||
| 47 | .gpio_wp = 126, | ||
| 48 | .ext_clock = 0, | ||
| 49 | }, | ||
| 50 | { | ||
| 51 | .mmc = 2, | ||
| 52 | .wires = 4, | ||
| 53 | .gpio_cd = -EINVAL, | ||
| 54 | .gpio_wp = 127, | ||
| 55 | .ext_clock = 1, | ||
| 56 | }, | ||
| 57 | {} /* Terminator */ | ||
| 58 | }; | ||
| 59 | |||
| 40 | static struct omap_uart_config omap3pandora_uart_config __initdata = { | 60 | static struct omap_uart_config omap3pandora_uart_config __initdata = { |
| 41 | .enabled_uarts = (1 << 2), /* UART3 */ | 61 | .enabled_uarts = (1 << 2), /* UART3 */ |
| 42 | }; | 62 | }; |
| 43 | 63 | ||
| 64 | static int omap3pandora_twl_gpio_setup(struct device *dev, | ||
| 65 | unsigned gpio, unsigned ngpio) | ||
| 66 | { | ||
| 67 | /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ | ||
| 68 | omap3pandora_mmc[0].gpio_cd = gpio + 0; | ||
| 69 | omap3pandora_mmc[1].gpio_cd = gpio + 1; | ||
| 70 | twl4030_mmc_init(omap3pandora_mmc); | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 44 | static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { | 75 | static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { |
| 45 | .gpio_base = OMAP_MAX_GPIO_LINES, | 76 | .gpio_base = OMAP_MAX_GPIO_LINES, |
| 46 | .irq_base = TWL4030_GPIO_IRQ_BASE, | 77 | .irq_base = TWL4030_GPIO_IRQ_BASE, |
| 47 | .irq_end = TWL4030_GPIO_IRQ_END, | 78 | .irq_end = TWL4030_GPIO_IRQ_END, |
| 79 | .setup = omap3pandora_twl_gpio_setup, | ||
| 48 | }; | 80 | }; |
| 49 | 81 | ||
| 50 | static struct twl4030_usb_data omap3pandora_usb_data = { | 82 | static struct twl4030_usb_data omap3pandora_usb_data = { |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index e09aa59a399c..82b3dc557c96 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| 27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/i2c/twl4030.h> | ||
| 29 | 30 | ||
| 30 | #include <linux/mtd/mtd.h> | 31 | #include <linux/mtd/mtd.h> |
| 31 | #include <linux/mtd/nand.h> | 32 | #include <linux/mtd/nand.h> |
| @@ -44,6 +45,8 @@ | |||
| 44 | #include <mach/hardware.h> | 45 | #include <mach/hardware.h> |
| 45 | #include <mach/nand.h> | 46 | #include <mach/nand.h> |
| 46 | 47 | ||
| 48 | #include "mmc-twl4030.h" | ||
| 49 | |||
| 47 | #define NAND_BLOCK_SIZE SZ_128K | 50 | #define NAND_BLOCK_SIZE SZ_128K |
| 48 | #define GPMC_CS0_BASE 0x60 | 51 | #define GPMC_CS0_BASE 0x60 |
| 49 | #define GPMC_CS_SIZE 0x30 | 52 | #define GPMC_CS_SIZE 0x30 |
| @@ -139,8 +142,31 @@ static struct omap_uart_config overo_uart_config __initdata = { | |||
| 139 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 142 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
| 140 | }; | 143 | }; |
| 141 | 144 | ||
| 145 | static struct twl4030_gpio_platform_data overo_gpio_data = { | ||
| 146 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
| 147 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
| 148 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
| 149 | }; | ||
| 150 | |||
| 151 | static struct twl4030_platform_data overo_twldata = { | ||
| 152 | .irq_base = TWL4030_IRQ_BASE, | ||
| 153 | .irq_end = TWL4030_IRQ_END, | ||
| 154 | .gpio = &overo_gpio_data, | ||
| 155 | }; | ||
| 156 | |||
| 157 | static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { | ||
| 158 | { | ||
| 159 | I2C_BOARD_INFO("twl4030", 0x48), | ||
| 160 | .flags = I2C_CLIENT_WAKE, | ||
| 161 | .irq = INT_34XX_SYS_NIRQ, | ||
| 162 | .platform_data = &overo_twldata, | ||
| 163 | }, | ||
| 164 | }; | ||
| 165 | |||
| 142 | static int __init overo_i2c_init(void) | 166 | static int __init overo_i2c_init(void) |
| 143 | { | 167 | { |
| 168 | omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo, | ||
| 169 | ARRAY_SIZE(overo_i2c_boardinfo)); | ||
| 144 | /* i2c2 pins are used for gpio */ | 170 | /* i2c2 pins are used for gpio */ |
| 145 | omap_register_i2c_bus(3, 400, NULL, 0); | 171 | omap_register_i2c_bus(3, 400, NULL, 0); |
| 146 | return 0; | 172 | return 0; |
| @@ -171,6 +197,22 @@ static struct platform_device *overo_devices[] __initdata = { | |||
| 171 | &overo_lcd_device, | 197 | &overo_lcd_device, |
| 172 | }; | 198 | }; |
| 173 | 199 | ||
| 200 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
| 201 | { | ||
| 202 | .mmc = 1, | ||
| 203 | .wires = 4, | ||
| 204 | .gpio_cd = -EINVAL, | ||
| 205 | .gpio_wp = -EINVAL, | ||
| 206 | }, | ||
| 207 | { | ||
| 208 | .mmc = 2, | ||
| 209 | .wires = 4, | ||
| 210 | .gpio_cd = -EINVAL, | ||
| 211 | .gpio_wp = -EINVAL, | ||
| 212 | }, | ||
| 213 | {} /* Terminator */ | ||
| 214 | }; | ||
| 215 | |||
| 174 | static void __init overo_init(void) | 216 | static void __init overo_init(void) |
| 175 | { | 217 | { |
| 176 | overo_i2c_init(); | 218 | overo_i2c_init(); |
| @@ -178,6 +220,7 @@ static void __init overo_init(void) | |||
| 178 | omap_board_config = overo_config; | 220 | omap_board_config = overo_config; |
| 179 | omap_board_config_size = ARRAY_SIZE(overo_config); | 221 | omap_board_config_size = ARRAY_SIZE(overo_config); |
| 180 | omap_serial_init(); | 222 | omap_serial_init(); |
| 223 | twl4030_mmc_init(mmc); | ||
| 181 | overo_flash_init(); | 224 | overo_flash_init(); |
| 182 | 225 | ||
| 183 | if ((gpio_request(OVERO_GPIO_W2W_NRESET, | 226 | if ((gpio_request(OVERO_GPIO_W2W_NRESET, |
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h index 242a19d86ccd..ff6cd14d254d 100644 --- a/arch/arm/mach-omap2/clock24xx.h +++ b/arch/arm/mach-omap2/clock24xx.h | |||
| @@ -2522,7 +2522,6 @@ static struct clk usbhs_ick = { | |||
| 2522 | 2522 | ||
| 2523 | static struct clk mmchs1_ick = { | 2523 | static struct clk mmchs1_ick = { |
| 2524 | .name = "mmchs_ick", | 2524 | .name = "mmchs_ick", |
| 2525 | .id = 1, | ||
| 2526 | .parent = &l4_ck, | 2525 | .parent = &l4_ck, |
| 2527 | .flags = CLOCK_IN_OMAP243X, | 2526 | .flags = CLOCK_IN_OMAP243X, |
| 2528 | .clkdm_name = "core_l4_clkdm", | 2527 | .clkdm_name = "core_l4_clkdm", |
| @@ -2533,7 +2532,6 @@ static struct clk mmchs1_ick = { | |||
| 2533 | 2532 | ||
| 2534 | static struct clk mmchs1_fck = { | 2533 | static struct clk mmchs1_fck = { |
| 2535 | .name = "mmchs_fck", | 2534 | .name = "mmchs_fck", |
| 2536 | .id = 1, | ||
| 2537 | .parent = &func_96m_ck, | 2535 | .parent = &func_96m_ck, |
| 2538 | .flags = CLOCK_IN_OMAP243X, | 2536 | .flags = CLOCK_IN_OMAP243X, |
| 2539 | .clkdm_name = "core_l3_clkdm", | 2537 | .clkdm_name = "core_l3_clkdm", |
| @@ -2544,7 +2542,7 @@ static struct clk mmchs1_fck = { | |||
| 2544 | 2542 | ||
| 2545 | static struct clk mmchs2_ick = { | 2543 | static struct clk mmchs2_ick = { |
| 2546 | .name = "mmchs_ick", | 2544 | .name = "mmchs_ick", |
| 2547 | .id = 2, | 2545 | .id = 1, |
| 2548 | .parent = &l4_ck, | 2546 | .parent = &l4_ck, |
| 2549 | .flags = CLOCK_IN_OMAP243X, | 2547 | .flags = CLOCK_IN_OMAP243X, |
| 2550 | .clkdm_name = "core_l4_clkdm", | 2548 | .clkdm_name = "core_l4_clkdm", |
| @@ -2555,7 +2553,7 @@ static struct clk mmchs2_ick = { | |||
| 2555 | 2553 | ||
| 2556 | static struct clk mmchs2_fck = { | 2554 | static struct clk mmchs2_fck = { |
| 2557 | .name = "mmchs_fck", | 2555 | .name = "mmchs_fck", |
| 2558 | .id = 2, | 2556 | .id = 1, |
| 2559 | .parent = &func_96m_ck, | 2557 | .parent = &func_96m_ck, |
| 2560 | .flags = CLOCK_IN_OMAP243X, | 2558 | .flags = CLOCK_IN_OMAP243X, |
| 2561 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), | 2559 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), |
| @@ -2595,7 +2593,6 @@ static struct clk mdm_intc_ick = { | |||
| 2595 | 2593 | ||
| 2596 | static struct clk mmchsdb1_fck = { | 2594 | static struct clk mmchsdb1_fck = { |
| 2597 | .name = "mmchsdb_fck", | 2595 | .name = "mmchsdb_fck", |
| 2598 | .id = 1, | ||
| 2599 | .parent = &func_32k_ck, | 2596 | .parent = &func_32k_ck, |
| 2600 | .flags = CLOCK_IN_OMAP243X, | 2597 | .flags = CLOCK_IN_OMAP243X, |
| 2601 | .clkdm_name = "core_l4_clkdm", | 2598 | .clkdm_name = "core_l4_clkdm", |
| @@ -2606,7 +2603,7 @@ static struct clk mmchsdb1_fck = { | |||
| 2606 | 2603 | ||
| 2607 | static struct clk mmchsdb2_fck = { | 2604 | static struct clk mmchsdb2_fck = { |
| 2608 | .name = "mmchsdb_fck", | 2605 | .name = "mmchsdb_fck", |
| 2609 | .id = 2, | 2606 | .id = 1, |
| 2610 | .parent = &func_32k_ck, | 2607 | .parent = &func_32k_ck, |
| 2611 | .flags = CLOCK_IN_OMAP243X, | 2608 | .flags = CLOCK_IN_OMAP243X, |
| 2612 | .clkdm_name = "core_l4_clkdm", | 2609 | .clkdm_name = "core_l4_clkdm", |
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 7217a0824ec4..a826094d89b5 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
| @@ -1374,7 +1374,7 @@ static struct clk core_96m_fck = { | |||
| 1374 | 1374 | ||
| 1375 | static struct clk mmchs3_fck = { | 1375 | static struct clk mmchs3_fck = { |
| 1376 | .name = "mmchs_fck", | 1376 | .name = "mmchs_fck", |
| 1377 | .id = 3, | 1377 | .id = 2, |
| 1378 | .parent = &core_96m_fck, | 1378 | .parent = &core_96m_fck, |
| 1379 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1379 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
| 1380 | .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, | 1380 | .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, |
| @@ -1385,7 +1385,7 @@ static struct clk mmchs3_fck = { | |||
| 1385 | 1385 | ||
| 1386 | static struct clk mmchs2_fck = { | 1386 | static struct clk mmchs2_fck = { |
| 1387 | .name = "mmchs_fck", | 1387 | .name = "mmchs_fck", |
| 1388 | .id = 2, | 1388 | .id = 1, |
| 1389 | .parent = &core_96m_fck, | 1389 | .parent = &core_96m_fck, |
| 1390 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1390 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
| 1391 | .enable_bit = OMAP3430_EN_MMC2_SHIFT, | 1391 | .enable_bit = OMAP3430_EN_MMC2_SHIFT, |
| @@ -1406,7 +1406,6 @@ static struct clk mspro_fck = { | |||
| 1406 | 1406 | ||
| 1407 | static struct clk mmchs1_fck = { | 1407 | static struct clk mmchs1_fck = { |
| 1408 | .name = "mmchs_fck", | 1408 | .name = "mmchs_fck", |
| 1409 | .id = 1, | ||
| 1410 | .parent = &core_96m_fck, | 1409 | .parent = &core_96m_fck, |
| 1411 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1410 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
| 1412 | .enable_bit = OMAP3430_EN_MMC1_SHIFT, | 1411 | .enable_bit = OMAP3430_EN_MMC1_SHIFT, |
| @@ -1722,7 +1721,7 @@ static struct clk usbtll_ick = { | |||
| 1722 | 1721 | ||
| 1723 | static struct clk mmchs3_ick = { | 1722 | static struct clk mmchs3_ick = { |
| 1724 | .name = "mmchs_ick", | 1723 | .name = "mmchs_ick", |
| 1725 | .id = 3, | 1724 | .id = 2, |
| 1726 | .parent = &core_l4_ick, | 1725 | .parent = &core_l4_ick, |
| 1727 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1726 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
| 1728 | .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, | 1727 | .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, |
| @@ -1774,7 +1773,7 @@ static struct clk des2_ick = { | |||
| 1774 | 1773 | ||
| 1775 | static struct clk mmchs2_ick = { | 1774 | static struct clk mmchs2_ick = { |
| 1776 | .name = "mmchs_ick", | 1775 | .name = "mmchs_ick", |
| 1777 | .id = 2, | 1776 | .id = 1, |
| 1778 | .parent = &core_l4_ick, | 1777 | .parent = &core_l4_ick, |
| 1779 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1778 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
| 1780 | .enable_bit = OMAP3430_EN_MMC2_SHIFT, | 1779 | .enable_bit = OMAP3430_EN_MMC2_SHIFT, |
| @@ -1785,7 +1784,6 @@ static struct clk mmchs2_ick = { | |||
| 1785 | 1784 | ||
| 1786 | static struct clk mmchs1_ick = { | 1785 | static struct clk mmchs1_ick = { |
| 1787 | .name = "mmchs_ick", | 1786 | .name = "mmchs_ick", |
| 1788 | .id = 1, | ||
| 1789 | .parent = &core_l4_ick, | 1787 | .parent = &core_l4_ick, |
| 1790 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1788 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
| 1791 | .enable_bit = OMAP3430_EN_MMC1_SHIFT, | 1789 | .enable_bit = OMAP3430_EN_MMC1_SHIFT, |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 90af2ac469aa..9d7216ff6c9f 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
| @@ -14,16 +14,19 @@ | |||
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/clk.h> | ||
| 17 | 18 | ||
| 18 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
| 19 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
| 20 | #include <asm/mach/map.h> | 21 | #include <asm/mach/map.h> |
| 21 | 22 | ||
| 23 | #include <mach/control.h> | ||
| 22 | #include <mach/tc.h> | 24 | #include <mach/tc.h> |
| 23 | #include <mach/board.h> | 25 | #include <mach/board.h> |
| 24 | #include <mach/mux.h> | 26 | #include <mach/mux.h> |
| 25 | #include <mach/gpio.h> | 27 | #include <mach/gpio.h> |
| 26 | #include <mach/eac.h> | 28 | #include <mach/eac.h> |
| 29 | #include <mach/mmc.h> | ||
| 27 | 30 | ||
| 28 | #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) | 31 | #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) |
| 29 | #define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) | 32 | #define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) |
| @@ -295,6 +298,171 @@ static void omap_init_sha1_md5(void) | |||
| 295 | static inline void omap_init_sha1_md5(void) { } | 298 | static inline void omap_init_sha1_md5(void) { } |
| 296 | #endif | 299 | #endif |
| 297 | 300 | ||
| 301 | /*-------------------------------------------------------------------------*/ | ||
| 302 | |||
| 303 | #ifdef CONFIG_ARCH_OMAP3 | ||
| 304 | |||
| 305 | #define MMCHS_SYSCONFIG 0x0010 | ||
| 306 | #define MMCHS_SYSCONFIG_SWRESET (1 << 1) | ||
| 307 | #define MMCHS_SYSSTATUS 0x0014 | ||
| 308 | #define MMCHS_SYSSTATUS_RESETDONE (1 << 0) | ||
| 309 | |||
| 310 | static struct platform_device dummy_pdev = { | ||
| 311 | .dev = { | ||
| 312 | .bus = &platform_bus_type, | ||
| 313 | }, | ||
| 314 | }; | ||
| 315 | |||
| 316 | /** | ||
| 317 | * omap_hsmmc_reset() - Full reset of each HS-MMC controller | ||
| 318 | * | ||
| 319 | * Ensure that each MMC controller is fully reset. Controllers | ||
| 320 | * left in an unknown state (by bootloader) may prevent retention | ||
| 321 | * or OFF-mode. This is especially important in cases where the | ||
| 322 | * MMC driver is not enabled, _or_ built as a module. | ||
| 323 | * | ||
| 324 | * In order for reset to work, interface, functional and debounce | ||
| 325 | * clocks must be enabled. The debounce clock comes from func_32k_clk | ||
| 326 | * and is not under SW control, so we only enable i- and f-clocks. | ||
| 327 | **/ | ||
| 328 | static void __init omap_hsmmc_reset(void) | ||
| 329 | { | ||
| 330 | u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC : | ||
| 331 | OMAP24XX_NR_MMC; | ||
| 332 | |||
| 333 | for (i = 0; i < nr_controllers; i++) { | ||
| 334 | u32 v, base = 0; | ||
| 335 | struct clk *iclk, *fclk; | ||
| 336 | struct device *dev = &dummy_pdev.dev; | ||
| 337 | |||
| 338 | switch (i) { | ||
| 339 | case 0: | ||
| 340 | base = OMAP2_MMC1_BASE; | ||
| 341 | break; | ||
| 342 | case 1: | ||
| 343 | base = OMAP2_MMC2_BASE; | ||
| 344 | break; | ||
| 345 | case 2: | ||
| 346 | base = OMAP3_MMC3_BASE; | ||
| 347 | break; | ||
| 348 | } | ||
| 349 | |||
| 350 | dummy_pdev.id = i; | ||
| 351 | iclk = clk_get(dev, "mmchs_ick"); | ||
| 352 | if (iclk && clk_enable(iclk)) | ||
| 353 | iclk = NULL; | ||
| 354 | |||
| 355 | fclk = clk_get(dev, "mmchs_fck"); | ||
| 356 | if (fclk && clk_enable(fclk)) | ||
| 357 | fclk = NULL; | ||
| 358 | |||
| 359 | if (!iclk || !fclk) { | ||
| 360 | printk(KERN_WARNING | ||
| 361 | "%s: Unable to enable clocks for MMC%d, " | ||
| 362 | "cannot reset.\n", __func__, i); | ||
| 363 | break; | ||
| 364 | } | ||
| 365 | |||
| 366 | omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG); | ||
| 367 | v = omap_readl(base + MMCHS_SYSSTATUS); | ||
| 368 | while (!(omap_readl(base + MMCHS_SYSSTATUS) & | ||
| 369 | MMCHS_SYSSTATUS_RESETDONE)) | ||
| 370 | cpu_relax(); | ||
| 371 | |||
| 372 | if (fclk) { | ||
| 373 | clk_disable(fclk); | ||
| 374 | clk_put(fclk); | ||
| 375 | } | ||
| 376 | if (iclk) { | ||
| 377 | clk_disable(iclk); | ||
| 378 | clk_put(iclk); | ||
| 379 | } | ||
| 380 | } | ||
| 381 | } | ||
| 382 | #else | ||
| 383 | static inline void omap_hsmmc_reset(void) {} | ||
| 384 | #endif | ||
| 385 | |||
| 386 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ | ||
| 387 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) | ||
| 388 | |||
| 389 | static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | ||
| 390 | int controller_nr) | ||
| 391 | { | ||
| 392 | if (cpu_is_omap2420() && controller_nr == 0) { | ||
| 393 | omap_cfg_reg(H18_24XX_MMC_CMD); | ||
| 394 | omap_cfg_reg(H15_24XX_MMC_CLKI); | ||
| 395 | omap_cfg_reg(G19_24XX_MMC_CLKO); | ||
| 396 | omap_cfg_reg(F20_24XX_MMC_DAT0); | ||
| 397 | omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); | ||
| 398 | omap_cfg_reg(G18_24XX_MMC_CMD_DIR); | ||
| 399 | if (mmc_controller->slots[0].wires == 4) { | ||
| 400 | omap_cfg_reg(H14_24XX_MMC_DAT1); | ||
| 401 | omap_cfg_reg(E19_24XX_MMC_DAT2); | ||
| 402 | omap_cfg_reg(D19_24XX_MMC_DAT3); | ||
| 403 | omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); | ||
| 404 | omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); | ||
| 405 | omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); | ||
| 406 | } | ||
| 407 | |||
| 408 | /* | ||
| 409 | * Use internal loop-back in MMC/SDIO Module Input Clock | ||
| 410 | * selection | ||
| 411 | */ | ||
| 412 | if (mmc_controller->slots[0].internal_clock) { | ||
| 413 | u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
| 414 | v |= (1 << 24); | ||
| 415 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | ||
| 416 | } | ||
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 420 | void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | ||
| 421 | int nr_controllers) | ||
| 422 | { | ||
| 423 | int i; | ||
| 424 | |||
| 425 | for (i = 0; i < nr_controllers; i++) { | ||
| 426 | unsigned long base, size; | ||
| 427 | unsigned int irq = 0; | ||
| 428 | |||
| 429 | if (!mmc_data[i]) | ||
| 430 | continue; | ||
| 431 | |||
| 432 | omap2_mmc_mux(mmc_data[i], i); | ||
| 433 | |||
| 434 | switch (i) { | ||
| 435 | case 0: | ||
| 436 | base = OMAP2_MMC1_BASE; | ||
| 437 | irq = INT_24XX_MMC_IRQ; | ||
| 438 | break; | ||
| 439 | case 1: | ||
| 440 | base = OMAP2_MMC2_BASE; | ||
| 441 | irq = INT_24XX_MMC2_IRQ; | ||
| 442 | break; | ||
| 443 | case 2: | ||
| 444 | if (!cpu_is_omap34xx()) | ||
| 445 | return; | ||
| 446 | base = OMAP3_MMC3_BASE; | ||
| 447 | irq = INT_34XX_MMC3_IRQ; | ||
| 448 | break; | ||
| 449 | default: | ||
| 450 | continue; | ||
| 451 | } | ||
| 452 | |||
| 453 | if (cpu_is_omap2420()) | ||
| 454 | size = OMAP2420_MMC_SIZE; | ||
| 455 | else | ||
| 456 | size = HSMMC_SIZE; | ||
| 457 | |||
| 458 | omap_mmc_add(i, base, size, irq, mmc_data[i]); | ||
| 459 | }; | ||
| 460 | } | ||
| 461 | |||
| 462 | #endif | ||
| 463 | |||
| 464 | /*-------------------------------------------------------------------------*/ | ||
| 465 | |||
| 298 | #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) | 466 | #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) |
| 299 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | 467 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) |
| 300 | #define OMAP_HDQ_BASE 0x480B2000 | 468 | #define OMAP_HDQ_BASE 0x480B2000 |
| @@ -334,6 +502,7 @@ static int __init omap2_init_devices(void) | |||
| 334 | /* please keep these calls, and their implementations above, | 502 | /* please keep these calls, and their implementations above, |
| 335 | * in alphabetical order so they're easier to sort through. | 503 | * in alphabetical order so they're easier to sort through. |
| 336 | */ | 504 | */ |
| 505 | omap_hsmmc_reset(); | ||
| 337 | omap_init_mbox(); | 506 | omap_init_mbox(); |
| 338 | omap_init_mcspi(); | 507 | omap_init_mcspi(); |
| 339 | omap_hdq_init(); | 508 | omap_hdq_init(); |
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c new file mode 100644 index 000000000000..437f52073f6e --- /dev/null +++ b/arch/arm/mach-omap2/mmc-twl4030.c | |||
| @@ -0,0 +1,408 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-omap2/mmc-twl4030.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007-2008 Texas Instruments | ||
| 5 | * Copyright (C) 2008 Nokia Corporation | ||
| 6 | * Author: Texas Instruments | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/i2c/twl4030.h> | ||
| 20 | |||
| 21 | #include <mach/hardware.h> | ||
| 22 | #include <mach/control.h> | ||
| 23 | #include <mach/mmc.h> | ||
| 24 | #include <mach/board.h> | ||
| 25 | |||
| 26 | #include "mmc-twl4030.h" | ||
| 27 | |||
| 28 | #if defined(CONFIG_TWL4030_CORE) && \ | ||
| 29 | (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) | ||
| 30 | |||
| 31 | #define LDO_CLR 0x00 | ||
| 32 | #define VSEL_S2_CLR 0x40 | ||
| 33 | |||
| 34 | #define VMMC1_DEV_GRP 0x27 | ||
| 35 | #define VMMC1_CLR 0x00 | ||
| 36 | #define VMMC1_315V 0x03 | ||
| 37 | #define VMMC1_300V 0x02 | ||
| 38 | #define VMMC1_285V 0x01 | ||
| 39 | #define VMMC1_185V 0x00 | ||
| 40 | #define VMMC1_DEDICATED 0x2A | ||
| 41 | |||
| 42 | #define VMMC2_DEV_GRP 0x2B | ||
| 43 | #define VMMC2_CLR 0x40 | ||
| 44 | #define VMMC2_315V 0x0c | ||
| 45 | #define VMMC2_300V 0x0b | ||
| 46 | #define VMMC2_285V 0x0a | ||
| 47 | #define VMMC2_260V 0x08 | ||
| 48 | #define VMMC2_185V 0x06 | ||
| 49 | #define VMMC2_DEDICATED 0x2E | ||
| 50 | |||
| 51 | #define VMMC_DEV_GRP_P1 0x20 | ||
| 52 | |||
| 53 | static u16 control_pbias_offset; | ||
| 54 | static u16 control_devconf1_offset; | ||
| 55 | |||
| 56 | #define HSMMC_NAME_LEN 9 | ||
| 57 | |||
| 58 | static struct twl_mmc_controller { | ||
| 59 | struct omap_mmc_platform_data *mmc; | ||
| 60 | u8 twl_vmmc_dev_grp; | ||
| 61 | u8 twl_mmc_dedicated; | ||
| 62 | char name[HSMMC_NAME_LEN]; | ||
| 63 | } hsmmc[] = { | ||
| 64 | { | ||
| 65 | .twl_vmmc_dev_grp = VMMC1_DEV_GRP, | ||
| 66 | .twl_mmc_dedicated = VMMC1_DEDICATED, | ||
| 67 | }, | ||
| 68 | { | ||
| 69 | .twl_vmmc_dev_grp = VMMC2_DEV_GRP, | ||
| 70 | .twl_mmc_dedicated = VMMC2_DEDICATED, | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static int twl_mmc_card_detect(int irq) | ||
| 75 | { | ||
| 76 | unsigned i; | ||
| 77 | |||
| 78 | for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { | ||
| 79 | struct omap_mmc_platform_data *mmc; | ||
| 80 | |||
| 81 | mmc = hsmmc[i].mmc; | ||
| 82 | if (!mmc) | ||
| 83 | continue; | ||
| 84 | if (irq != mmc->slots[0].card_detect_irq) | ||
| 85 | continue; | ||
| 86 | |||
| 87 | /* NOTE: assumes card detect signal is active-low */ | ||
| 88 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
| 89 | } | ||
| 90 | return -ENOSYS; | ||
| 91 | } | ||
| 92 | |||
| 93 | static int twl_mmc_get_ro(struct device *dev, int slot) | ||
| 94 | { | ||
| 95 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 96 | |||
| 97 | /* NOTE: assumes write protect signal is active-high */ | ||
| 98 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | ||
| 99 | } | ||
| 100 | |||
| 101 | /* | ||
| 102 | * MMC Slot Initialization. | ||
| 103 | */ | ||
| 104 | static int twl_mmc_late_init(struct device *dev) | ||
| 105 | { | ||
| 106 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 107 | int ret = 0; | ||
| 108 | int i; | ||
| 109 | |||
| 110 | ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); | ||
| 111 | if (ret) | ||
| 112 | goto done; | ||
| 113 | ret = gpio_direction_input(mmc->slots[0].switch_pin); | ||
| 114 | if (ret) | ||
| 115 | goto err; | ||
| 116 | |||
| 117 | for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { | ||
| 118 | if (hsmmc[i].name == mmc->slots[0].name) { | ||
| 119 | hsmmc[i].mmc = mmc; | ||
| 120 | break; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | |||
| 126 | err: | ||
| 127 | gpio_free(mmc->slots[0].switch_pin); | ||
| 128 | done: | ||
| 129 | mmc->slots[0].card_detect_irq = 0; | ||
| 130 | mmc->slots[0].card_detect = NULL; | ||
| 131 | |||
| 132 | dev_err(dev, "err %d configuring card detect\n", ret); | ||
| 133 | return ret; | ||
| 134 | } | ||
| 135 | |||
| 136 | static void twl_mmc_cleanup(struct device *dev) | ||
| 137 | { | ||
| 138 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 139 | |||
| 140 | gpio_free(mmc->slots[0].switch_pin); | ||
| 141 | } | ||
| 142 | |||
| 143 | #ifdef CONFIG_PM | ||
| 144 | |||
| 145 | static int twl_mmc_suspend(struct device *dev, int slot) | ||
| 146 | { | ||
| 147 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 148 | |||
| 149 | disable_irq(mmc->slots[0].card_detect_irq); | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | static int twl_mmc_resume(struct device *dev, int slot) | ||
| 154 | { | ||
| 155 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 156 | |||
| 157 | enable_irq(mmc->slots[0].card_detect_irq); | ||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | |||
| 161 | #else | ||
| 162 | #define twl_mmc_suspend NULL | ||
| 163 | #define twl_mmc_resume NULL | ||
| 164 | #endif | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Sets the MMC voltage in twl4030 | ||
| 168 | */ | ||
| 169 | static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd) | ||
| 170 | { | ||
| 171 | int ret; | ||
| 172 | u8 vmmc, dev_grp_val; | ||
| 173 | |||
| 174 | switch (1 << vdd) { | ||
| 175 | case MMC_VDD_35_36: | ||
| 176 | case MMC_VDD_34_35: | ||
| 177 | case MMC_VDD_33_34: | ||
| 178 | case MMC_VDD_32_33: | ||
| 179 | case MMC_VDD_31_32: | ||
| 180 | case MMC_VDD_30_31: | ||
| 181 | if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) | ||
| 182 | vmmc = VMMC1_315V; | ||
| 183 | else | ||
| 184 | vmmc = VMMC2_315V; | ||
| 185 | break; | ||
| 186 | case MMC_VDD_29_30: | ||
| 187 | if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) | ||
| 188 | vmmc = VMMC1_315V; | ||
| 189 | else | ||
| 190 | vmmc = VMMC2_300V; | ||
| 191 | break; | ||
| 192 | case MMC_VDD_27_28: | ||
| 193 | case MMC_VDD_26_27: | ||
| 194 | if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) | ||
| 195 | vmmc = VMMC1_285V; | ||
| 196 | else | ||
| 197 | vmmc = VMMC2_285V; | ||
| 198 | break; | ||
| 199 | case MMC_VDD_25_26: | ||
| 200 | case MMC_VDD_24_25: | ||
| 201 | case MMC_VDD_23_24: | ||
| 202 | case MMC_VDD_22_23: | ||
| 203 | case MMC_VDD_21_22: | ||
| 204 | case MMC_VDD_20_21: | ||
| 205 | if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) | ||
| 206 | vmmc = VMMC1_285V; | ||
| 207 | else | ||
| 208 | vmmc = VMMC2_260V; | ||
| 209 | break; | ||
| 210 | case MMC_VDD_165_195: | ||
| 211 | if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) | ||
| 212 | vmmc = VMMC1_185V; | ||
| 213 | else | ||
| 214 | vmmc = VMMC2_185V; | ||
| 215 | break; | ||
| 216 | default: | ||
| 217 | vmmc = 0; | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | |||
| 221 | if (vmmc) | ||
| 222 | dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */ | ||
| 223 | else | ||
| 224 | dev_grp_val = LDO_CLR; /* Power down */ | ||
| 225 | |||
| 226 | ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, | ||
| 227 | dev_grp_val, c->twl_vmmc_dev_grp); | ||
| 228 | if (ret) | ||
| 229 | return ret; | ||
| 230 | |||
| 231 | ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, | ||
| 232 | vmmc, c->twl_mmc_dedicated); | ||
| 233 | |||
| 234 | return ret; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | ||
| 238 | int vdd) | ||
| 239 | { | ||
| 240 | u32 reg; | ||
| 241 | int ret = 0; | ||
| 242 | struct twl_mmc_controller *c = &hsmmc[0]; | ||
| 243 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 244 | |||
| 245 | if (power_on) { | ||
| 246 | if (cpu_is_omap2430()) { | ||
| 247 | reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1); | ||
| 248 | if ((1 << vdd) >= MMC_VDD_30_31) | ||
| 249 | reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE; | ||
| 250 | else | ||
| 251 | reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE; | ||
| 252 | omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); | ||
| 253 | } | ||
| 254 | |||
| 255 | if (mmc->slots[0].internal_clock) { | ||
| 256 | reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
| 257 | reg |= OMAP2_MMCSDIO1ADPCLKISEL; | ||
| 258 | omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); | ||
| 259 | } | ||
| 260 | |||
| 261 | reg = omap_ctrl_readl(control_pbias_offset); | ||
| 262 | reg |= OMAP2_PBIASSPEEDCTRL0; | ||
| 263 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | ||
| 264 | omap_ctrl_writel(reg, control_pbias_offset); | ||
| 265 | |||
| 266 | ret = twl_mmc_set_voltage(c, vdd); | ||
| 267 | |||
| 268 | /* 100ms delay required for PBIAS configuration */ | ||
| 269 | msleep(100); | ||
| 270 | reg = omap_ctrl_readl(control_pbias_offset); | ||
| 271 | reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); | ||
| 272 | if ((1 << vdd) <= MMC_VDD_165_195) | ||
| 273 | reg &= ~OMAP2_PBIASLITEVMODE0; | ||
| 274 | else | ||
| 275 | reg |= OMAP2_PBIASLITEVMODE0; | ||
| 276 | omap_ctrl_writel(reg, control_pbias_offset); | ||
| 277 | } else { | ||
| 278 | reg = omap_ctrl_readl(control_pbias_offset); | ||
| 279 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | ||
| 280 | omap_ctrl_writel(reg, control_pbias_offset); | ||
| 281 | |||
| 282 | ret = twl_mmc_set_voltage(c, 0); | ||
| 283 | |||
| 284 | /* 100ms delay required for PBIAS configuration */ | ||
| 285 | msleep(100); | ||
| 286 | reg = omap_ctrl_readl(control_pbias_offset); | ||
| 287 | reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | | ||
| 288 | OMAP2_PBIASLITEVMODE0); | ||
| 289 | omap_ctrl_writel(reg, control_pbias_offset); | ||
| 290 | } | ||
| 291 | |||
| 292 | return ret; | ||
| 293 | } | ||
| 294 | |||
| 295 | static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd) | ||
| 296 | { | ||
| 297 | int ret; | ||
| 298 | struct twl_mmc_controller *c = &hsmmc[1]; | ||
| 299 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
| 300 | |||
| 301 | if (power_on) { | ||
| 302 | if (mmc->slots[0].internal_clock) { | ||
| 303 | u32 reg; | ||
| 304 | |||
| 305 | reg = omap_ctrl_readl(control_devconf1_offset); | ||
| 306 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; | ||
| 307 | omap_ctrl_writel(reg, control_devconf1_offset); | ||
| 308 | } | ||
| 309 | ret = twl_mmc_set_voltage(c, vdd); | ||
| 310 | } else { | ||
| 311 | ret = twl_mmc_set_voltage(c, 0); | ||
| 312 | } | ||
| 313 | |||
| 314 | return ret; | ||
| 315 | } | ||
| 316 | |||
| 317 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; | ||
| 318 | |||
| 319 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | ||
| 320 | { | ||
| 321 | struct twl4030_hsmmc_info *c; | ||
| 322 | int nr_hsmmc = ARRAY_SIZE(hsmmc_data); | ||
| 323 | |||
| 324 | if (cpu_is_omap2430()) { | ||
| 325 | control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; | ||
| 326 | control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; | ||
| 327 | nr_hsmmc = 2; | ||
| 328 | } else { | ||
| 329 | control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; | ||
| 330 | control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; | ||
| 331 | } | ||
| 332 | |||
| 333 | for (c = controllers; c->mmc; c++) { | ||
| 334 | struct twl_mmc_controller *twl = hsmmc + c->mmc - 1; | ||
| 335 | struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; | ||
| 336 | |||
| 337 | if (!c->mmc || c->mmc > nr_hsmmc) { | ||
| 338 | pr_debug("MMC%d: no such controller\n", c->mmc); | ||
| 339 | continue; | ||
| 340 | } | ||
| 341 | if (mmc) { | ||
| 342 | pr_debug("MMC%d: already configured\n", c->mmc); | ||
| 343 | continue; | ||
| 344 | } | ||
| 345 | |||
| 346 | mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); | ||
| 347 | if (!mmc) { | ||
| 348 | pr_err("Cannot allocate memory for mmc device!\n"); | ||
| 349 | return; | ||
| 350 | } | ||
| 351 | |||
| 352 | sprintf(twl->name, "mmc%islot%i", c->mmc, 1); | ||
| 353 | mmc->slots[0].name = twl->name; | ||
| 354 | mmc->nr_slots = 1; | ||
| 355 | mmc->slots[0].ocr_mask = MMC_VDD_165_195 | | ||
| 356 | MMC_VDD_26_27 | MMC_VDD_27_28 | | ||
| 357 | MMC_VDD_29_30 | | ||
| 358 | MMC_VDD_30_31 | MMC_VDD_31_32; | ||
| 359 | mmc->slots[0].wires = c->wires; | ||
| 360 | mmc->slots[0].internal_clock = !c->ext_clock; | ||
| 361 | mmc->dma_mask = 0xffffffff; | ||
| 362 | |||
| 363 | /* note: twl4030 card detect GPIOs normally switch VMMCx ... */ | ||
| 364 | if (gpio_is_valid(c->gpio_cd)) { | ||
| 365 | mmc->init = twl_mmc_late_init; | ||
| 366 | mmc->cleanup = twl_mmc_cleanup; | ||
| 367 | mmc->suspend = twl_mmc_suspend; | ||
| 368 | mmc->resume = twl_mmc_resume; | ||
| 369 | |||
| 370 | mmc->slots[0].switch_pin = c->gpio_cd; | ||
| 371 | mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); | ||
| 372 | mmc->slots[0].card_detect = twl_mmc_card_detect; | ||
| 373 | } else | ||
| 374 | mmc->slots[0].switch_pin = -EINVAL; | ||
| 375 | |||
| 376 | /* write protect normally uses an OMAP gpio */ | ||
| 377 | if (gpio_is_valid(c->gpio_wp)) { | ||
| 378 | gpio_request(c->gpio_wp, "mmc_wp"); | ||
| 379 | gpio_direction_input(c->gpio_wp); | ||
| 380 | |||
| 381 | mmc->slots[0].gpio_wp = c->gpio_wp; | ||
| 382 | mmc->slots[0].get_ro = twl_mmc_get_ro; | ||
| 383 | } else | ||
| 384 | mmc->slots[0].gpio_wp = -EINVAL; | ||
| 385 | |||
| 386 | /* NOTE: we assume OMAP's MMC1 and MMC2 use | ||
| 387 | * the TWL4030's VMMC1 and VMMC2, respectively; | ||
| 388 | * and that OMAP's MMC3 isn't used. | ||
| 389 | */ | ||
| 390 | |||
| 391 | switch (c->mmc) { | ||
| 392 | case 1: | ||
| 393 | mmc->slots[0].set_power = twl_mmc1_set_power; | ||
| 394 | break; | ||
| 395 | case 2: | ||
| 396 | mmc->slots[0].set_power = twl_mmc2_set_power; | ||
| 397 | break; | ||
| 398 | default: | ||
| 399 | pr_err("MMC%d configuration not supported!\n", c->mmc); | ||
| 400 | continue; | ||
| 401 | } | ||
| 402 | hsmmc_data[c->mmc - 1] = mmc; | ||
| 403 | } | ||
| 404 | |||
| 405 | omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); | ||
| 406 | } | ||
| 407 | |||
| 408 | #endif | ||
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h new file mode 100644 index 000000000000..e1c8076400ca --- /dev/null +++ b/arch/arm/mach-omap2/mmc-twl4030.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * MMC definitions for OMAP2 | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | struct twl4030_hsmmc_info { | ||
| 10 | u8 mmc; /* controller 1/2/3 */ | ||
| 11 | u8 wires; /* 1/4/8 wires */ | ||
| 12 | int gpio_cd; /* or -EINVAL */ | ||
| 13 | int gpio_wp; /* or -EINVAL */ | ||
| 14 | int ext_clock:1; /* use external pin for input clock */ | ||
| 15 | }; | ||
| 16 | |||
| 17 | #if defined(CONFIG_TWL4030_CORE) && \ | ||
| 18 | (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ | ||
| 19 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) | ||
| 20 | |||
| 21 | void twl4030_mmc_init(struct twl4030_hsmmc_info *); | ||
| 22 | |||
| 23 | #else | ||
| 24 | |||
| 25 | static inline void twl4030_mmc_init(struct twl4030_hsmmc_info *info) | ||
| 26 | { | ||
| 27 | } | ||
| 28 | |||
| 29 | #endif | ||
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 0cb2b22388e9..ac15c23fd5da 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
| @@ -192,202 +192,48 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, | |||
| 192 | 192 | ||
| 193 | /*-------------------------------------------------------------------------*/ | 193 | /*-------------------------------------------------------------------------*/ |
| 194 | 194 | ||
| 195 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ | 195 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ |
| 196 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) | 196 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) |
| 197 | 197 | ||
| 198 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 198 | #define OMAP_MMC_NR_RES 2 |
| 199 | #define OMAP_MMC1_BASE 0x4809c000 | ||
| 200 | #define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc) | ||
| 201 | #define OMAP_MMC1_INT INT_24XX_MMC_IRQ | ||
| 202 | 199 | ||
| 203 | #define OMAP_MMC2_BASE 0x480b4000 | 200 | /* |
| 204 | #define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc) | 201 | * Register MMC devices. Called from mach-omap1 and mach-omap2 device init. |
| 205 | #define OMAP_MMC2_INT INT_24XX_MMC2_IRQ | 202 | */ |
| 206 | 203 | int __init omap_mmc_add(int id, unsigned long base, unsigned long size, | |
| 207 | #else | 204 | unsigned int irq, struct omap_mmc_platform_data *data) |
| 208 | |||
| 209 | #define OMAP_MMC1_BASE 0xfffb7800 | ||
| 210 | #define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f) | ||
| 211 | #define OMAP_MMC1_INT INT_MMC | ||
| 212 | |||
| 213 | #define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ | ||
| 214 | #define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f) | ||
| 215 | #define OMAP_MMC2_INT INT_1610_MMC2 | ||
| 216 | |||
| 217 | #endif | ||
| 218 | |||
| 219 | static struct omap_mmc_platform_data mmc1_data; | ||
| 220 | |||
| 221 | static u64 mmc1_dmamask = 0xffffffff; | ||
| 222 | |||
| 223 | static struct resource mmc1_resources[] = { | ||
| 224 | { | ||
| 225 | .start = OMAP_MMC1_BASE, | ||
| 226 | .end = OMAP_MMC1_END, | ||
| 227 | .flags = IORESOURCE_MEM, | ||
| 228 | }, | ||
| 229 | { | ||
| 230 | .start = OMAP_MMC1_INT, | ||
| 231 | .flags = IORESOURCE_IRQ, | ||
| 232 | }, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static struct platform_device mmc_omap_device1 = { | ||
| 236 | .name = "mmci-omap", | ||
| 237 | .id = 1, | ||
| 238 | .dev = { | ||
| 239 | .dma_mask = &mmc1_dmamask, | ||
| 240 | .platform_data = &mmc1_data, | ||
| 241 | }, | ||
| 242 | .num_resources = ARRAY_SIZE(mmc1_resources), | ||
| 243 | .resource = mmc1_resources, | ||
| 244 | }; | ||
| 245 | |||
| 246 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ | ||
| 247 | defined(CONFIG_ARCH_OMAP34XX) | ||
| 248 | |||
| 249 | static struct omap_mmc_platform_data mmc2_data; | ||
| 250 | |||
| 251 | static u64 mmc2_dmamask = 0xffffffff; | ||
| 252 | |||
| 253 | static struct resource mmc2_resources[] = { | ||
| 254 | { | ||
| 255 | .start = OMAP_MMC2_BASE, | ||
| 256 | .end = OMAP_MMC2_END, | ||
| 257 | .flags = IORESOURCE_MEM, | ||
| 258 | }, | ||
| 259 | { | ||
| 260 | .start = OMAP_MMC2_INT, | ||
| 261 | .flags = IORESOURCE_IRQ, | ||
| 262 | }, | ||
| 263 | }; | ||
| 264 | |||
| 265 | static struct platform_device mmc_omap_device2 = { | ||
| 266 | .name = "mmci-omap", | ||
| 267 | .id = 2, | ||
| 268 | .dev = { | ||
| 269 | .dma_mask = &mmc2_dmamask, | ||
| 270 | .platform_data = &mmc2_data, | ||
| 271 | }, | ||
| 272 | .num_resources = ARRAY_SIZE(mmc2_resources), | ||
| 273 | .resource = mmc2_resources, | ||
| 274 | }; | ||
| 275 | #endif | ||
| 276 | |||
| 277 | static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf) | ||
| 278 | { | ||
| 279 | if (cpu_is_omap2430() || cpu_is_omap34xx()) | ||
| 280 | return; | ||
| 281 | |||
| 282 | if (mmc_conf->mmc[0].enabled) { | ||
| 283 | if (cpu_is_omap24xx()) { | ||
| 284 | omap_cfg_reg(H18_24XX_MMC_CMD); | ||
| 285 | omap_cfg_reg(H15_24XX_MMC_CLKI); | ||
| 286 | omap_cfg_reg(G19_24XX_MMC_CLKO); | ||
| 287 | omap_cfg_reg(F20_24XX_MMC_DAT0); | ||
| 288 | omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); | ||
| 289 | omap_cfg_reg(G18_24XX_MMC_CMD_DIR); | ||
| 290 | } else { | ||
| 291 | omap_cfg_reg(MMC_CMD); | ||
| 292 | omap_cfg_reg(MMC_CLK); | ||
| 293 | omap_cfg_reg(MMC_DAT0); | ||
| 294 | if (cpu_is_omap1710()) { | ||
| 295 | omap_cfg_reg(M15_1710_MMC_CLKI); | ||
| 296 | omap_cfg_reg(P19_1710_MMC_CMDDIR); | ||
| 297 | omap_cfg_reg(P20_1710_MMC_DATDIR0); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | if (mmc_conf->mmc[0].wire4) { | ||
| 301 | if (cpu_is_omap24xx()) { | ||
| 302 | omap_cfg_reg(H14_24XX_MMC_DAT1); | ||
| 303 | omap_cfg_reg(E19_24XX_MMC_DAT2); | ||
| 304 | omap_cfg_reg(D19_24XX_MMC_DAT3); | ||
| 305 | omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); | ||
| 306 | omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); | ||
| 307 | omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); | ||
| 308 | } else { | ||
| 309 | omap_cfg_reg(MMC_DAT1); | ||
| 310 | /* NOTE: DAT2 can be on W10 (here) or M15 */ | ||
| 311 | if (!mmc_conf->mmc[0].nomux) | ||
| 312 | omap_cfg_reg(MMC_DAT2); | ||
| 313 | omap_cfg_reg(MMC_DAT3); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | #ifdef CONFIG_ARCH_OMAP16XX | ||
| 319 | /* block 2 is on newer chips, and has many pinout options */ | ||
| 320 | if (mmc_conf->mmc[1].enabled) { | ||
| 321 | if (!mmc_conf->mmc[1].nomux) { | ||
| 322 | omap_cfg_reg(Y8_1610_MMC2_CMD); | ||
| 323 | omap_cfg_reg(Y10_1610_MMC2_CLK); | ||
| 324 | omap_cfg_reg(R18_1610_MMC2_CLKIN); | ||
| 325 | omap_cfg_reg(W8_1610_MMC2_DAT0); | ||
| 326 | if (mmc_conf->mmc[1].wire4) { | ||
| 327 | omap_cfg_reg(V8_1610_MMC2_DAT1); | ||
| 328 | omap_cfg_reg(W15_1610_MMC2_DAT2); | ||
| 329 | omap_cfg_reg(R10_1610_MMC2_DAT3); | ||
| 330 | } | ||
| 331 | |||
| 332 | /* These are needed for the level shifter */ | ||
| 333 | omap_cfg_reg(V9_1610_MMC2_CMDDIR); | ||
| 334 | omap_cfg_reg(V5_1610_MMC2_DATDIR0); | ||
| 335 | omap_cfg_reg(W19_1610_MMC2_DATDIR1); | ||
| 336 | } | ||
| 337 | |||
| 338 | /* Feedback clock must be set on OMAP-1710 MMC2 */ | ||
| 339 | if (cpu_is_omap1710()) | ||
| 340 | omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), | ||
| 341 | MOD_CONF_CTRL_1); | ||
| 342 | } | ||
| 343 | #endif | ||
| 344 | } | ||
| 345 | |||
| 346 | static void __init omap_init_mmc(void) | ||
| 347 | { | 205 | { |
| 348 | const struct omap_mmc_config *mmc_conf; | 206 | struct platform_device *pdev; |
| 349 | 207 | struct resource res[OMAP_MMC_NR_RES]; | |
| 350 | /* NOTE: assumes MMC was never (wrongly) enabled */ | 208 | int ret; |
| 351 | mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); | 209 | |
| 352 | if (!mmc_conf) | 210 | pdev = platform_device_alloc("mmci-omap", id); |
| 353 | return; | 211 | if (!pdev) |
| 354 | 212 | return -ENOMEM; | |
| 355 | omap_init_mmc_conf(mmc_conf); | 213 | |
| 356 | 214 | memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource)); | |
| 357 | if (mmc_conf->mmc[0].enabled) { | 215 | res[0].start = base; |
| 358 | mmc1_data.conf = mmc_conf->mmc[0]; | 216 | res[0].end = base + size - 1; |
| 359 | (void) platform_device_register(&mmc_omap_device1); | 217 | res[0].flags = IORESOURCE_MEM; |
| 360 | } | 218 | res[1].start = res[1].end = irq; |
| 361 | 219 | res[1].flags = IORESOURCE_IRQ; | |
| 362 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ | 220 | |
| 363 | defined(CONFIG_ARCH_OMAP34XX) | 221 | ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); |
| 364 | if (mmc_conf->mmc[1].enabled) { | 222 | if (ret == 0) |
| 365 | mmc2_data.conf = mmc_conf->mmc[1]; | 223 | ret = platform_device_add_data(pdev, data, sizeof(*data)); |
| 366 | (void) platform_device_register(&mmc_omap_device2); | 224 | if (ret) |
| 367 | } | 225 | goto fail; |
| 368 | #endif | 226 | |
| 369 | } | 227 | ret = platform_device_add(pdev); |
| 228 | if (ret) | ||
| 229 | goto fail; | ||
| 230 | return 0; | ||
| 370 | 231 | ||
| 371 | void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) | 232 | fail: |
| 372 | { | 233 | platform_device_put(pdev); |
| 373 | switch (host) { | 234 | return ret; |
| 374 | case 1: | ||
| 375 | mmc1_data = *info; | ||
| 376 | break; | ||
| 377 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \ | ||
| 378 | defined(CONFIG_ARCH_OMAP34XX) | ||
| 379 | case 2: | ||
| 380 | mmc2_data = *info; | ||
| 381 | break; | ||
| 382 | #endif | ||
| 383 | default: | ||
| 384 | BUG(); | ||
| 385 | } | ||
| 386 | } | 235 | } |
| 387 | 236 | ||
| 388 | #else | ||
| 389 | static inline void omap_init_mmc(void) {} | ||
| 390 | void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {} | ||
| 391 | #endif | 237 | #endif |
| 392 | 238 | ||
| 393 | /*-------------------------------------------------------------------------*/ | 239 | /*-------------------------------------------------------------------------*/ |
| @@ -532,7 +378,6 @@ static int __init omap_init_devices(void) | |||
| 532 | */ | 378 | */ |
| 533 | omap_init_dsp(); | 379 | omap_init_dsp(); |
| 534 | omap_init_kp(); | 380 | omap_init_kp(); |
| 535 | omap_init_mmc(); | ||
| 536 | omap_init_uwire(); | 381 | omap_init_uwire(); |
| 537 | omap_init_wdt(); | 382 | omap_init_wdt(); |
| 538 | omap_init_rng(); | 383 | omap_init_rng(); |
diff --git a/arch/arm/plat-omap/include/mach/board-h2.h b/arch/arm/plat-omap/include/mach/board-h2.h index 2a050e9be65f..15531c8dc0e6 100644 --- a/arch/arm/plat-omap/include/mach/board-h2.h +++ b/arch/arm/plat-omap/include/mach/board-h2.h | |||
| @@ -29,13 +29,13 @@ | |||
| 29 | #ifndef __ASM_ARCH_OMAP_H2_H | 29 | #ifndef __ASM_ARCH_OMAP_H2_H |
| 30 | #define __ASM_ARCH_OMAP_H2_H | 30 | #define __ASM_ARCH_OMAP_H2_H |
| 31 | 31 | ||
| 32 | /* Placeholder for H2 specific defines */ | ||
| 33 | |||
| 34 | /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ | 32 | /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ |
| 35 | #define OMAP1610_ETHR_START 0x04000300 | 33 | #define OMAP1610_ETHR_START 0x04000300 |
| 36 | 34 | ||
| 35 | #define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */) | ||
| 36 | # define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3) | ||
| 37 | |||
| 37 | extern void h2_mmc_init(void); | 38 | extern void h2_mmc_init(void); |
| 38 | extern void h2_mmc_slot_cover_handler(void *arg, int state); | ||
| 39 | 39 | ||
| 40 | #endif /* __ASM_ARCH_OMAP_H2_H */ | 40 | #endif /* __ASM_ARCH_OMAP_H2_H */ |
| 41 | 41 | ||
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h index c23c12ccb353..9466772fc7c8 100644 --- a/arch/arm/plat-omap/include/mach/board.h +++ b/arch/arm/plat-omap/include/mach/board.h | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | 16 | ||
| 17 | /* Different peripheral ids */ | 17 | /* Different peripheral ids */ |
| 18 | #define OMAP_TAG_CLOCK 0x4f01 | 18 | #define OMAP_TAG_CLOCK 0x4f01 |
| 19 | #define OMAP_TAG_MMC 0x4f02 | ||
| 20 | #define OMAP_TAG_SERIAL_CONSOLE 0x4f03 | 19 | #define OMAP_TAG_SERIAL_CONSOLE 0x4f03 |
| 21 | #define OMAP_TAG_USB 0x4f04 | 20 | #define OMAP_TAG_USB 0x4f04 |
| 22 | #define OMAP_TAG_LCD 0x4f05 | 21 | #define OMAP_TAG_LCD 0x4f05 |
| @@ -35,27 +34,6 @@ struct omap_clock_config { | |||
| 35 | u8 system_clock_type; | 34 | u8 system_clock_type; |
| 36 | }; | 35 | }; |
| 37 | 36 | ||
| 38 | struct omap_mmc_conf { | ||
| 39 | unsigned enabled:1; | ||
| 40 | /* nomux means "standard" muxing is wrong on this board, and that | ||
| 41 | * board-specific code handled it before common init logic. | ||
| 42 | */ | ||
| 43 | unsigned nomux:1; | ||
| 44 | /* switch pin can be for card detect (default) or card cover */ | ||
| 45 | unsigned cover:1; | ||
| 46 | /* 4 wire signaling is optional, and is only used for SD/SDIO */ | ||
| 47 | unsigned wire4:1; | ||
| 48 | /* use the internal clock */ | ||
| 49 | unsigned internal_clock:1; | ||
| 50 | s16 power_pin; | ||
| 51 | s16 switch_pin; | ||
| 52 | s16 wp_pin; | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct omap_mmc_config { | ||
| 56 | struct omap_mmc_conf mmc[2]; | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct omap_serial_console_config { | 37 | struct omap_serial_console_config { |
| 60 | u8 console_uart; | 38 | u8 console_uart; |
| 61 | u32 console_speed; | 39 | u32 console_speed; |
diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h index dc9886760577..269147f3836f 100644 --- a/arch/arm/plat-omap/include/mach/control.h +++ b/arch/arm/plat-omap/include/mach/control.h | |||
| @@ -74,6 +74,7 @@ | |||
| 74 | #define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) | 74 | #define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) |
| 75 | #define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) | 75 | #define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) |
| 76 | #define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198) | 76 | #define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198) |
| 77 | #define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230) | ||
| 77 | 78 | ||
| 78 | /* 24xx-only CONTROL_GENERAL register offsets */ | 79 | /* 24xx-only CONTROL_GENERAL register offsets */ |
| 79 | #define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000) | 80 | #define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000) |
| @@ -140,6 +141,7 @@ | |||
| 140 | #define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) | 141 | #define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) |
| 141 | #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) | 142 | #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) |
| 142 | #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) | 143 | #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) |
| 144 | #define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0) | ||
| 143 | #define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) | 145 | #define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) |
| 144 | 146 | ||
| 145 | /* | 147 | /* |
| @@ -154,11 +156,14 @@ | |||
| 154 | * and the security mode (secure, non-secure, don't care) | 156 | * and the security mode (secure, non-secure, don't care) |
| 155 | */ | 157 | */ |
| 156 | /* CONTROL_DEVCONF0 bits */ | 158 | /* CONTROL_DEVCONF0 bits */ |
| 159 | #define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */ | ||
| 157 | #define OMAP24XX_USBSTANDBYCTRL (1 << 15) | 160 | #define OMAP24XX_USBSTANDBYCTRL (1 << 15) |
| 158 | #define OMAP2_MCBSP2_CLKS_MASK (1 << 6) | 161 | #define OMAP2_MCBSP2_CLKS_MASK (1 << 6) |
| 159 | #define OMAP2_MCBSP1_CLKS_MASK (1 << 2) | 162 | #define OMAP2_MCBSP1_CLKS_MASK (1 << 2) |
| 160 | 163 | ||
| 161 | /* CONTROL_DEVCONF1 bits */ | 164 | /* CONTROL_DEVCONF1 bits */ |
| 165 | #define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31) | ||
| 166 | #define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6) /* MMC2 loop back clock */ | ||
| 162 | #define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */ | 167 | #define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */ |
| 163 | #define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */ | 168 | #define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */ |
| 164 | #define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */ | 169 | #define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */ |
| @@ -172,6 +177,18 @@ | |||
| 172 | #define OMAP2_SYSBOOT_1_MASK (1 << 1) | 177 | #define OMAP2_SYSBOOT_1_MASK (1 << 1) |
| 173 | #define OMAP2_SYSBOOT_0_MASK (1 << 0) | 178 | #define OMAP2_SYSBOOT_0_MASK (1 << 0) |
| 174 | 179 | ||
| 180 | /* CONTROL_PBIAS_LITE bits */ | ||
| 181 | #define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15) | ||
| 182 | #define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11) | ||
| 183 | #define OMAP343X_PBIASSPEEDCTRL1 (1 << 10) | ||
| 184 | #define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9) | ||
| 185 | #define OMAP343X_PBIASLITEVMODE1 (1 << 8) | ||
| 186 | #define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7) | ||
| 187 | #define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3) | ||
| 188 | #define OMAP2_PBIASSPEEDCTRL0 (1 << 2) | ||
| 189 | #define OMAP2_PBIASLITEPWRDNZ0 (1 << 1) | ||
| 190 | #define OMAP2_PBIASLITEVMODE0 (1 << 0) | ||
| 191 | |||
| 175 | #ifndef __ASSEMBLY__ | 192 | #ifndef __ASSEMBLY__ |
| 176 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 193 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
| 177 | extern void __iomem *omap_ctrl_base_get(void); | 194 | extern void __iomem *omap_ctrl_base_get(void); |
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h index fc15d13058fc..031250f02805 100644 --- a/arch/arm/plat-omap/include/mach/mmc.h +++ b/arch/arm/plat-omap/include/mach/mmc.h | |||
| @@ -17,12 +17,28 @@ | |||
| 17 | 17 | ||
| 18 | #include <mach/board.h> | 18 | #include <mach/board.h> |
| 19 | 19 | ||
| 20 | #define OMAP15XX_NR_MMC 1 | ||
| 21 | #define OMAP16XX_NR_MMC 2 | ||
| 22 | #define OMAP1_MMC_SIZE 0x080 | ||
| 23 | #define OMAP1_MMC1_BASE 0xfffb7800 | ||
| 24 | #define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */ | ||
| 25 | |||
| 26 | #define OMAP24XX_NR_MMC 2 | ||
| 27 | #define OMAP34XX_NR_MMC 3 | ||
| 28 | #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE | ||
| 29 | #define HSMMC_SIZE 0x200 | ||
| 30 | #define OMAP2_MMC1_BASE 0x4809c000 | ||
| 31 | #define OMAP2_MMC2_BASE 0x480b4000 | ||
| 32 | #define OMAP3_MMC3_BASE 0x480ad000 | ||
| 33 | #define HSMMC3 (1 << 2) | ||
| 34 | #define HSMMC2 (1 << 1) | ||
| 35 | #define HSMMC1 (1 << 0) | ||
| 36 | |||
| 20 | #define OMAP_MMC_MAX_SLOTS 2 | 37 | #define OMAP_MMC_MAX_SLOTS 2 |
| 21 | 38 | ||
| 22 | struct omap_mmc_platform_data { | 39 | struct omap_mmc_platform_data { |
| 23 | struct omap_mmc_conf conf; | ||
| 24 | 40 | ||
| 25 | /* number of slots on board */ | 41 | /* number of slots per controller */ |
| 26 | unsigned nr_slots:2; | 42 | unsigned nr_slots:2; |
| 27 | 43 | ||
| 28 | /* set if your board has components or wiring that limits the | 44 | /* set if your board has components or wiring that limits the |
| @@ -41,7 +57,31 @@ struct omap_mmc_platform_data { | |||
| 41 | int (*suspend)(struct device *dev, int slot); | 57 | int (*suspend)(struct device *dev, int slot); |
| 42 | int (*resume)(struct device *dev, int slot); | 58 | int (*resume)(struct device *dev, int slot); |
| 43 | 59 | ||
| 60 | u64 dma_mask; | ||
| 61 | |||
| 44 | struct omap_mmc_slot_data { | 62 | struct omap_mmc_slot_data { |
| 63 | |||
| 64 | /* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC; | ||
| 65 | * 8 wire signaling is also optional, and is used with HSMMC | ||
| 66 | */ | ||
| 67 | u8 wires; | ||
| 68 | |||
| 69 | /* | ||
| 70 | * nomux means "standard" muxing is wrong on this board, and | ||
| 71 | * that board-specific code handled it before common init logic. | ||
| 72 | */ | ||
| 73 | unsigned nomux:1; | ||
| 74 | |||
| 75 | /* switch pin can be for card detect (default) or card cover */ | ||
| 76 | unsigned cover:1; | ||
| 77 | |||
| 78 | /* use the internal clock */ | ||
| 79 | unsigned internal_clock:1; | ||
| 80 | s16 power_pin; | ||
| 81 | |||
| 82 | int switch_pin; /* gpio (card detect) */ | ||
| 83 | int gpio_wp; /* gpio (write protect) */ | ||
| 84 | |||
| 45 | int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); | 85 | int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); |
| 46 | int (* set_power)(struct device *dev, int slot, int power_on, int vdd); | 86 | int (* set_power)(struct device *dev, int slot, int power_on, int vdd); |
| 47 | int (* get_ro)(struct device *dev, int slot); | 87 | int (* get_ro)(struct device *dev, int slot); |
| @@ -49,8 +89,8 @@ struct omap_mmc_platform_data { | |||
| 49 | /* return MMC cover switch state, can be NULL if not supported. | 89 | /* return MMC cover switch state, can be NULL if not supported. |
| 50 | * | 90 | * |
| 51 | * possible return values: | 91 | * possible return values: |
| 52 | * 0 - open | 92 | * 0 - closed |
| 53 | * 1 - closed | 93 | * 1 - open |
| 54 | */ | 94 | */ |
| 55 | int (* get_cover_state)(struct device *dev, int slot); | 95 | int (* get_cover_state)(struct device *dev, int slot); |
| 56 | 96 | ||
| @@ -66,9 +106,31 @@ struct omap_mmc_platform_data { | |||
| 66 | } slots[OMAP_MMC_MAX_SLOTS]; | 106 | } slots[OMAP_MMC_MAX_SLOTS]; |
| 67 | }; | 107 | }; |
| 68 | 108 | ||
| 69 | extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info); | ||
| 70 | |||
| 71 | /* called from board-specific card detection service routine */ | 109 | /* called from board-specific card detection service routine */ |
| 72 | extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); | 110 | extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); |
| 73 | 111 | ||
| 112 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ | ||
| 113 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) | ||
| 114 | void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, | ||
| 115 | int nr_controllers); | ||
| 116 | void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | ||
| 117 | int nr_controllers); | ||
| 118 | int omap_mmc_add(int id, unsigned long base, unsigned long size, | ||
| 119 | unsigned int irq, struct omap_mmc_platform_data *data); | ||
| 120 | #else | ||
| 121 | static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, | ||
| 122 | int nr_controllers) | ||
| 123 | { | ||
| 124 | } | ||
| 125 | static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | ||
| 126 | int nr_controllers) | ||
| 127 | { | ||
| 128 | } | ||
| 129 | static inline int omap_mmc_add(int id, unsigned long base, unsigned long size, | ||
| 130 | unsigned int irq, struct omap_mmc_platform_data *data) | ||
| 131 | { | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | #endif | ||
| 74 | #endif | 136 | #endif |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 1b9fc3c6b875..67d7b7fef084 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
| @@ -1015,7 +1015,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data | |||
| 1015 | } | 1015 | } |
| 1016 | 1016 | ||
| 1017 | if (is_read) { | 1017 | if (is_read) { |
| 1018 | if (host->id == 1) { | 1018 | if (host->id == 0) { |
| 1019 | sync_dev = OMAP_DMA_MMC_RX; | 1019 | sync_dev = OMAP_DMA_MMC_RX; |
| 1020 | dma_dev_name = "MMC1 read"; | 1020 | dma_dev_name = "MMC1 read"; |
| 1021 | } else { | 1021 | } else { |
| @@ -1023,7 +1023,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data | |||
| 1023 | dma_dev_name = "MMC2 read"; | 1023 | dma_dev_name = "MMC2 read"; |
| 1024 | } | 1024 | } |
| 1025 | } else { | 1025 | } else { |
| 1026 | if (host->id == 1) { | 1026 | if (host->id == 0) { |
| 1027 | sync_dev = OMAP_DMA_MMC_TX; | 1027 | sync_dev = OMAP_DMA_MMC_TX; |
| 1028 | dma_dev_name = "MMC1 write"; | 1028 | dma_dev_name = "MMC1 write"; |
| 1029 | } else { | 1029 | } else { |
| @@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) | |||
| 1317 | host->slots[id] = slot; | 1317 | host->slots[id] = slot; |
| 1318 | 1318 | ||
| 1319 | mmc->caps = 0; | 1319 | mmc->caps = 0; |
| 1320 | if (host->pdata->conf.wire4) | 1320 | if (host->pdata->slots[id].wires >= 4) |
| 1321 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 1321 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 1322 | 1322 | ||
| 1323 | mmc->ops = &mmc_omap_ops; | 1323 | mmc->ops = &mmc_omap_ops; |
| @@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev) | |||
| 1451 | host->irq = irq; | 1451 | host->irq = irq; |
| 1452 | 1452 | ||
| 1453 | host->use_dma = 1; | 1453 | host->use_dma = 1; |
| 1454 | host->dev->dma_mask = &pdata->dma_mask; | ||
| 1454 | host->dma_ch = -1; | 1455 | host->dma_ch = -1; |
| 1455 | 1456 | ||
| 1456 | host->irq = irq; | 1457 | host->irq = irq; |
