From: David Brownell <[EMAIL PROTECTED]> Support card detect and writeprotect switches on DM355 EVM.
Signed-off-by: David Brownell <[EMAIL PROTECTED]> --- Grr, this is the bugfixed version ... forgot to add the right base to the gpio range passed from dm355evm_msp. And news on the "MMC1 partially works" front: disable DMA in the davinci_mmc code, and the various cards that it's able to enumerate will read and write just fine. A clue!! ;) arch/arm/mach-davinci/board-dm355-evm.c | 46 ++++++++++++++++++++++++++++-- drivers/mfd/dm355evm_msp.c | 10 ++++++ 2 files changed, 53 insertions(+), 3 deletions(-) --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -37,8 +37,26 @@ static struct davinci_i2c_platform_data .bus_delay = 0 /* usec */, }; +static int dm355evm_mmc_gpios = -EINVAL; + +static void dm355evm_mmcsd_gpios(unsigned gpio) +{ + gpio_request(gpio + 0, "mmc0_ro"); + gpio_request(gpio + 1, "mmc0_cd"); + gpio_request(gpio + 2, "mmc1_ro"); + gpio_request(gpio + 3, "mmc1_cd"); + + /* we "know" these are input-only so we don't + * need to call gpio_direction_input() + */ + + dm355evm_mmc_gpios = gpio; +} + static struct i2c_board_info dm355evm_i2c_info[] = { - { I2C_BOARD_INFO("dm355evm_msp", 0x25), /* plus irq */ }, + { I2C_BOARD_INFO("dm355evm_msp", 0x25), + .platform_data = dm355evm_mmcsd_gpios, + /* plus irq */ }, /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */ /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */ }; @@ -96,6 +114,28 @@ static void __init dm355_evm_map_io(void davinci_map_common_io(); } +static int dm355evm_mmc_get_cd(int module) +{ + if (!gpio_is_valid(dm355evm_mmc_gpios)) + return -ENXIO; + /* low == card present */ + return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1); +} + +static int dm355evm_mmc_get_ro(int module) +{ + if (!gpio_is_valid(dm355evm_mmc_gpios)) + return -ENXIO; + /* high == card's write protect switch active */ + return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0); +} + +static struct davinci_mmc_config dm355evm_mmc_config = { + .get_cd = dm355evm_mmc_get_cd, + .get_ro = dm355evm_mmc_get_ro, + .wires = 4, +}; + static __init void dm355_evm_init(void) { davinci_psc_init(); @@ -111,8 +151,8 @@ static __init void dm355_evm_init(void) davinci_board_config_size = ARRAY_SIZE(davinci_evm_config); davinci_serial_init(); - davinci_setup_mmc(0, NULL); - davinci_setup_mmc(1, NULL); + davinci_setup_mmc(0, &dm355evm_mmc_config); + davinci_setup_mmc(1, &dm355evm_mmc_config); } static __init void dm355_evm_irq_init(void) --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c @@ -107,6 +107,9 @@ static const u8 msp_gpios[] = { MSP_GPIO(0, SWITCH1), MSP_GPIO(1, SWITCH1), MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1), MSP_GPIO(4, SWITCH1), + /* switches on MMC/SD sockets */ + MSP_GPIO(1, SDMMC), MSP_GPIO(2, SDMMC), /* mmc0 WP, nCD */ + MSP_GPIO(3, SDMMC), MSP_GPIO(4, SDMMC), /* mmc1 WP, nCD */ }; #define MSP_GPIO_REG(offset) (msp_gpios[(offset)] >> 3) @@ -304,6 +307,13 @@ static int add_children(struct i2c_clien gpio_export(gpio, false); } + /* MMC/SD inputs -- right after the last config input */ + if (client->dev.platform_data) { + void (*mmcsd_setup)(unsigned) = client->dev.platform_data; + + mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5); + } + /* RTC is a 32 bit counter, no alarm */ if (msp_has_rtc()) { child = add_child(client, "rtc-dm355evm", _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source