Commit 71461ca5 authored by Tony Lindgren's avatar Tony Lindgren

HSMMC: Improve the interface for hsmmc_init()

Improve the interface for hsmmc_init()

Based on earlier code snippet and patch by
David Brownell <dbrownell@users.sourceforge.net>.
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>

parent fc492663
......@@ -387,6 +387,15 @@ static int __init omap2430_i2c_init(void)
return 0;
}
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 4,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
static void __init omap_2430sdp_init(void)
{
omap2430_i2c_init();
......@@ -404,7 +413,7 @@ static void __init omap_2430sdp_init(void)
spi_register_board_info(sdp2430_spi_board_info,
ARRAY_SIZE(sdp2430_spi_board_info));
ads7846_dev_init();
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
/* turn off secondary LCD backlight */
omap_set_gpio_direction(SECONDARY_LCD_GPIO, 0);
......
......@@ -46,6 +46,7 @@
#include <mach/control.h>
#include "sdram-qimonda-hyb18m512160af-6.h"
#include "mmc-twl4030.h"
#define CONFIG_DISABLE_HFCLK 1
......@@ -444,6 +445,20 @@ static int __init omap3430_i2c_init(void)
return 0;
}
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 8,
.gpio_cd = -EINVAL,
},
{
.mmc = 2,
.wires = 8,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
extern void __init sdp3430_flash_init(void);
static void __init omap_3430sdp_init(void)
......@@ -465,7 +480,7 @@ static void __init omap_3430sdp_init(void)
omap_serial_init();
usb_musb_init();
usb_ehci_init();
hsmmc_init(HSMMC1 | HSMMC2);
hsmmc_init(mmc);
}
static void __init omap_3430sdp_map_io(void)
......
......@@ -68,7 +68,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.cleanup = apollon_mmc_cleanup,
.dma_mask = 0xffffffff,
.slots[0] = {
.wire4 = 1,
.wires = 4,
/*
* Use internal loop-back in MMC/SDIO Module Input Clock
......
......@@ -231,7 +231,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.cleanup = h4_mmc_cleanup,
.dma_mask = 0xffffffff,
.slots[0] = {
.wire4 = 1,
.wires = 4,
.set_power = h4_mmc_set_power,
.set_bus_mode = h4_mmc_set_bus_mode,
.get_cover_state= h4_mmc_slot1_cover_state,
......@@ -241,7 +241,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.name = "slot1",
},
.slots[1] = {
.wire4 = 1,
.wires = 4,
.set_power = h4_mmc_set_power,
.set_bus_mode = h4_mmc_set_bus_mode,
.get_cover_state= h4_mmc_slot2_cover_state,
......
......@@ -338,6 +338,15 @@ static int __init omap_i2c_init(void)
return 0;
}
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 4,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
static void __init omap_ldp_init(void)
{
omap_i2c_init();
......@@ -352,7 +361,7 @@ static void __init omap_ldp_init(void)
ads7846_dev_init();
omap_serial_init();
usb_musb_init();
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
}
static void __init omap_ldp_map_io(void)
......
......@@ -308,7 +308,7 @@ static struct omap_mmc_platform_data mmc1_data = {
.max_freq = 24000000,
.dma_mask = 0xffffffff,
.slots[0] = {
.wire4 = 1,
.wires = 4,
.set_power = n800_mmc_set_power,
.set_bus_mode = n800_mmc_set_bus_mode,
.get_cover_state= n800_mmc_get_cover_state,
......
......@@ -337,6 +337,15 @@ static struct platform_device *omap2_evm_devices[] __initdata = {
&omap2evm_smc911x_device,
};
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 4,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
static void __init omap2_evm_init(void)
{
omap2_evm_i2c_init();
......@@ -347,7 +356,7 @@ static void __init omap2_evm_init(void)
spi_register_board_info(omap2evm_spi_board_info,
ARRAY_SIZE(omap2evm_spi_board_info));
omap_serial_init();
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
omap2evm_flash_init();
ads7846_dev_init();
}
......
......@@ -297,6 +297,15 @@ static void __init omap3beagle_flash_init(void)
}
}
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 8,
.gpio_cd = TWL4030_GPIO_IRQ_NO(0),
},
{} /* Terminator */
};
static void __init omap3_beagle_init(void)
{
omap3_beagle_i2c_init();
......@@ -309,7 +318,7 @@ static void __init omap3_beagle_init(void)
omap_cfg_reg(AH8_34XX_GPIO29);
gpio_request(29, "mmc0_wp");
gpio_direction_input(29);
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
omap_cfg_reg(J25_34XX_GPIO170);
gpio_request(170, "DVI_nPD");
......
......@@ -233,6 +233,15 @@ static struct platform_device *omap3_evm_devices[] __initdata = {
&omap3evm_smc911x_device,
};
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 4,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
static void __init omap3_evm_init(void)
{
omap3_evm_i2c_init();
......@@ -245,7 +254,7 @@ static void __init omap3_evm_init(void)
ARRAY_SIZE(omap3evm_spi_board_info));
omap_serial_init();
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
usb_musb_init();
usb_ehci_init();
omap3evm_flash_init();
......
......@@ -201,6 +201,15 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
&omap3pandora_lcd_device,
};
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 4,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
static void __init omap3pandora_init(void)
{
omap3pandora_i2c_init();
......@@ -208,7 +217,7 @@ static void __init omap3pandora_init(void)
omap_board_config = omap3pandora_config;
omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
omap_serial_init();
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
usb_musb_init();
usb_ehci_init();
omap3pandora_flash_init();
......
......@@ -50,6 +50,7 @@
#include "sdram-micron-mt46h32m32lf-6.h"
#include "twl4030-generic-scripts.h"
#include "mmc-twl4030.h"
#define NAND_BLOCK_SIZE SZ_128K
#define GPMC_CS0_BASE 0x60
......@@ -207,6 +208,20 @@ static struct platform_device *overo_devices[] __initdata = {
&overo_lcd_device,
};
static struct twl4030_hsmmc_info mmc[] __initdata = {
{
.mmc = 1,
.wires = 4,
.gpio_cd = -EINVAL,
},
{
.mmc = 2,
.wires = 4,
.gpio_cd = -EINVAL,
},
{} /* Terminator */
};
static void __init overo_init(void)
{
overo_i2c_init();
......@@ -214,7 +229,7 @@ static void __init overo_init(void)
omap_board_config = overo_config;
omap_board_config_size = ARRAY_SIZE(overo_config);
omap_serial_init();
hsmmc_init(HSMMC1);
hsmmc_init(mmc);
usb_musb_init();
usb_ehci_init();
overo_flash_init();
......
......@@ -371,7 +371,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
omap_cfg_reg(F20_24XX_MMC_DAT0);
omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
if (mmc_controller->slots[0].wire4) {
if (mmc_controller->slots[0].wires == 4) {
omap_cfg_reg(H14_24XX_MMC_DAT1);
omap_cfg_reg(E19_24XX_MMC_DAT2);
omap_cfg_reg(D19_24XX_MMC_DAT3);
......
......@@ -23,6 +23,8 @@
#include <mach/mmc.h>
#include <mach/board.h>
#include "mmc-twl4030.h"
#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
#define TWL_GPIO_IMR1A 0x1C
......@@ -149,7 +151,7 @@ static int hsmmc1_suspend(struct device *dev, int slot)
{
int ret = 0;
disable_irq(TWL4030_GPIO_IRQ_NO(0));
disable_irq(hsmmc[0].card_detect_gpio);
ret = mask_cd_interrupt(1);
return ret;
......@@ -159,12 +161,15 @@ static int hsmmc1_resume(struct device *dev, int slot)
{
int ret = 0;
enable_irq(TWL4030_GPIO_IRQ_NO(0));
enable_irq(hsmmc[0].card_detect_gpio);
ret = mask_cd_interrupt(0);
return ret;
}
#else
#define hsmmc1_suspend NULL
#define hsmmc1_resume NULL
#endif
/*
......@@ -316,42 +321,14 @@ static int hsmmc2_set_power(struct device *dev, int slot, int power_on, int vdd)
return ret;
}
static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
.init = hsmmc1_late_init,
.cleanup = hsmmc1_cleanup,
#ifdef CONFIG_PM
.suspend = hsmmc1_suspend,
.resume = hsmmc1_resume,
#endif
.dma_mask = 0xffffffff,
.slots[0] = {
.wire4 = 1,
.set_power = hsmmc1_set_power,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34 |
MMC_VDD_165_195,
.name = "first slot",
.card_detect_irq = TWL4030_GPIO_IRQ_NO(0),
.card_detect = hsmmc1_card_detect,
},
};
static struct omap_mmc_platform_data mmc2_data = {
.nr_slots = 1,
.slots[0] = {
.set_power = hsmmc2_set_power,
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 |
MMC_VDD_29_30 | MMC_VDD_30_31 |
MMC_VDD_31_32 | MMC_VDD_32_33,
.name = "second slot",
},
};
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC];
void __init hsmmc_init(int controller_mask)
#define HSMMC_NAME_LEN 9
void __init hsmmc_init(struct twl4030_hsmmc_info *controllers)
{
struct twl4030_hsmmc_info *c;
if (cpu_is_omap2430()) {
control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
hsmmc[1].control_devconf_offset = OMAP243X_CONTROL_DEVCONF1;
......@@ -360,12 +337,55 @@ void __init hsmmc_init(int controller_mask)
hsmmc[1].control_devconf_offset = OMAP343X_CONTROL_DEVCONF1;
}
if (controller_mask & HSMMC1)
hsmmc_data[0] = &mmc1_data;
if (controller_mask & HSMMC2)
hsmmc_data[1] = &mmc2_data;
if (controller_mask & HSMMC3)
pr_err("HSMMC: Unknown configuration for controller 3\n");
for (c = controllers; c->mmc; c++) {
struct omap_mmc_platform_data *mmc;
char *name;
mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
if (!mmc) {
pr_err("Cannot allocate memory for mmc device!\n");
return;
}
name = kzalloc(HSMMC_NAME_LEN, GFP_KERNEL);
if (!name) {
kfree(mmc);
pr_err("Cannot allocate memory for mmc name!\n");
return;
}
sprintf(name, "mmc%islot%i", c->mmc, 1);
mmc->slots[0].name = name;
mmc->nr_slots = 1;
mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
MMC_VDD_26_27 | MMC_VDD_27_28 |
MMC_VDD_29_30 |
MMC_VDD_30_31 | MMC_VDD_31_32;
mmc->slots[0].wires = c->wires;
if (c->gpio_cd != -EINVAL)
mmc->slots[0].card_detect_irq = c->gpio_cd;
mmc->dma_mask = 0xffffffff;
switch (c->mmc) {
case 1:
mmc->init = hsmmc1_late_init;
mmc->cleanup = hsmmc1_cleanup;
mmc->suspend = hsmmc1_suspend;
mmc->resume = hsmmc1_resume;
mmc->slots[0].set_power = hsmmc1_set_power;
mmc->slots[0].card_detect = hsmmc1_card_detect;
hsmmc_data[0] = mmc;
break;
case 2:
mmc->slots[0].set_power = hsmmc2_set_power;
hsmmc_data[1] = mmc;
break;
default:
pr_err("Unknown MMC configuration!\n");
return;
}
}
omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
}
......
/*
* MMC definitions for OMAP2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
struct twl4030_hsmmc_info {
u8 mmc; /* controller 1/2/3 */
u8 wires; /* 1/4/8 wires */
int gpio_cd; /* or -EINVAL */
};
void hsmmc_init(struct twl4030_hsmmc_info *);
#else
static inline void hsmmc_init(struct twl4030_hsmmc_info *)
{
}
#endif
......@@ -71,7 +71,7 @@ struct omap_mmc_platform_data {
unsigned cover:1;
/* 4 wire signaling is optional, and is only used for SD/SDIO */
unsigned wire4:1;
u8 wires;
/* use the internal clock */
unsigned internal_clock:1;
......@@ -111,7 +111,6 @@ void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers);
void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers);
void hsmmc_init(int controller_mask);
int omap_mmc_add(int id, unsigned long base, unsigned long size,
unsigned int irq, struct omap_mmc_platform_data *data);
#else
......@@ -123,9 +122,6 @@ static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers)
{
}
static inline void hsmmc_init(int controller_mask)
{
}
static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
unsigned int irq, struct omap_mmc_platform_data *data)
{
......
......@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
host->slots[id] = slot;
mmc->caps = 0;
if (host->pdata->slots[id].wire4)
if (host->pdata->slots[id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
mmc->ops = &mmc_omap_ops;
......
......@@ -936,7 +936,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
mmc->ocr_avail = mmc_slot(host).ocr_mask;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
if (pdata->slots[host->slot_id].wire4)
if (pdata->slots[host->slot_id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
/* Only MMC1 supports 3.0V */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment