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
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source