Message ID | 1310074390-4277-6-git-send-email-ido@wizery.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, On Fri, Jul 08, 2011 at 02:39:32PM +0400, Sergei Shtylyov wrote: > Hello. > > On 08-07-2011 1:33, Ido Yariv wrote: > > >The DA850 supports an optional wl12xx based expansion board, adding WLAN > >& BT capabilities. The wl12xx is a 4-wire, 1.8V, embedded SDIO WLAN > >device with an external IRQ line and is power-controlled by a GPIO-based > >fixed regulator. > > >This patch adds support for the WLAN capabilities of this expansion > >board. > > >Signed-off-by: Ido Yariv<ido@wizery.com> > >--- > > arch/arm/mach-davinci/Kconfig | 31 +++++++ > > arch/arm/mach-davinci/board-da850-evm.c | 128 ++++++++++++++++++++++++++++++ > > arch/arm/mach-davinci/da850.c | 9 ++ > > arch/arm/mach-davinci/include/mach/mux.h | 10 +++ > > 4 files changed, 178 insertions(+), 0 deletions(-) > > >diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig > >index c0deaca..1a9149c 100644 > >--- a/arch/arm/mach-davinci/Kconfig > >+++ b/arch/arm/mach-davinci/Kconfig > >@@ -192,6 +192,37 @@ config DA850_UI_RMII > > > > endchoice > > > >+config DA850_WL12XX > >+ bool "DA850 wl12xx expansion board" > >+ depends on MACH_DAVINCI_DA850_EVM > >+ ---help--- > >+ Say Y if you want to use a wl12xx expansion board connected to the > >+ DA850 EVM. > > If I don't mistake, this expansion board is rather used with AM180x EVM? I'm actually not sure about the compatibility between the two, so yes, it might be a good idea to rename the configuration option and description. [...] > >+config DA850_WL12XX_FREF_19_2 > >+ bool "19.2MHz" > >+config DA850_WL12XX_FREF_26 > >+ bool "26MHz" > >+config DA850_WL12XX_FREF_38_4 > >+ bool "38.4MHz" > >+config DA850_WL12XX_FREF_52 > >+ bool "52MHz" > >+config DA850_WL12XX_FREF_XTAL_26 > >+ bool "XTAL 26MHz" > >+config DA850_WL12XX_FREF_XTAL_38_4 > >+ bool "XTAL 38MHz" > > Could you add emoty lines between items? Sure. [...] > >+static int da850_wl12xx_fref = -1; > >+ > >+static int __init setup_da850_wl12xx_fref(char *fref) > >+{ > >+ if (!strcmp(fref, "19.2")) > >+ da850_wl12xx_fref = WL12XX_REFCLOCK_19; > >+ else if (!strcmp(fref, "26")) > >+ da850_wl12xx_fref = WL12XX_REFCLOCK_26; > >+ else if (!strcmp(fref, "38.4")) > >+ da850_wl12xx_fref = WL12XX_REFCLOCK_38; > >+ else if (!strcmp(fref, "52")) > >+ da850_wl12xx_fref = WL12XX_REFCLOCK_52; > >+ else if (!strcmp(fref, "XTAL26")) > >+ da850_wl12xx_fref = WL12XX_REFCLOCK_26_XTAL; > >+ else if (!strcmp(fref, "XTAL38.4")) > >+ da850_wl12xx_fref = WL12XX_REFCLOCK_38_XTAL; > >+ else > >+ pr_info("da850_wl12xx_fref is invalid. Valid options: " > >+ "19.2, 26, 38.4, 52, XTAL26 or XTAL38.4\n"); > >+ return 0; > >+} > >+__setup("da850_wl12xx_fref=", setup_da850_wl12xx_fref); > > Why then also have a Kconfig 'choice' for that? We could choose a default value arbitrarily, but AFAIK there isn't a good one. The two currently available expansion boards use different reference clocks, so one of them will not work out of the box. Having it configurable by a boot argument can be handy when switching between expansion boards during development. Naturally, it's not a must. > >+static void wl12xx_set_power(int slot, bool power_on) > >+{ > >+ static bool power_state; > >+ > >+ pr_debug("Powering %s wl12xx", (power_on ? "on" : "off")); > > Parens not needed around ?:. Sure, will be fixed. > > >+ if (power_on) { > >+ /* Power up sequence required for wl127x devices */ > >+ gpio_set_value(DA850_WLAN_EN, 1); > >+ mdelay(15); > >+ gpio_set_value(DA850_WLAN_EN, 0); > >+ mdelay(1); > >+ gpio_set_value(DA850_WLAN_EN, 1); > >+ mdelay(70); > > Perhaps msleep()? Sure, will be fixed. > >+static void da850_wl12xx_init(void) > >+{ > >+ int ret; > >+ > >+ ret = davinci_cfg_reg_list(da850_evm_mmc_wl12xx_pins); > >+ if (ret) > >+ pr_warning("da850_evm_init: wl12xx/mmc mux setup failed:" > >+ " %d\n", ret); > >+ > >+ ret = da850_register_mmcsd1(&da850_mmc_wl12xx_config); > >+ if (ret) > >+ pr_warning("da850_evm_init: wl12xx/mmc registration failed:" > >+ " %d\n", ret); > > If these fail, does it makse sense to continue? I doubt it... Right, will be fixed. > > >+ if (gpio_request(DA850_WLAN_EN, "wl12xx_en") || > >+ gpio_direction_output(DA850_WLAN_EN, 0)) > > Use gpio_request_one() instead of this pair. > > >+ pr_err("Error initializing the wl12xx enable gpio\n"); > >+ > >+ if (gpio_request(DA850_WLAN_IRQ, "wl12xx_irq") || > >+ gpio_direction_input(DA850_WLAN_IRQ)) > > Same here. Sure, will be fixed. > >diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > >index 133aac4..bfe9b71 100644 > >--- a/arch/arm/mach-davinci/da850.c > >+++ b/arch/arm/mach-davinci/da850.c > >@@ -525,6 +525,13 @@ static const struct mux_config da850_pins[] = { > > MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false) > > MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false) > > MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false) > >+ /* MMC/SD1 function */ > >+ MUX_CFG(DA850, MMCSD1_DAT_0, 18, 8, 15, 2, false) > >+ MUX_CFG(DA850, MMCSD1_DAT_1, 19, 16, 15, 2, false) > >+ MUX_CFG(DA850, MMCSD1_DAT_2, 19, 12, 15, 2, false) > >+ MUX_CFG(DA850, MMCSD1_DAT_3, 19, 8, 15, 2, false) > >+ MUX_CFG(DA850, MMCSD1_CLK, 18, 12, 15, 2, false) > >+ MUX_CFG(DA850, MMCSD1_CMD, 18, 16, 15, 2, false) > > /* EMIF2.5/EMIFA function */ > > MUX_CFG(DA850, EMA_D_7, 9, 0, 15, 1, false) > > MUX_CFG(DA850, EMA_D_6, 9, 4, 15, 1, false) > >@@ -583,6 +590,8 @@ static const struct mux_config da850_pins[] = { > > MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) > > MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) > > MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) > >+ MUX_CFG(DA850, GPIO6_9, 13, 24, 15, 8, false) > >+ MUX_CFG(DA850, GPIO6_10, 13, 20, 15, 8, false) > > MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) > > MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) > > #endif > > >diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h > >index 5d4e0fe..a7e92fc 100644 > >--- a/arch/arm/mach-davinci/include/mach/mux.h > >+++ b/arch/arm/mach-davinci/include/mach/mux.h > >@@ -857,6 +857,14 @@ enum davinci_da850_index { > > DA850_MMCSD0_CLK, > > DA850_MMCSD0_CMD, > > > >+ /* MMC/SD1 function */ > >+ DA850_MMCSD1_DAT_0, > >+ DA850_MMCSD1_DAT_1, > >+ DA850_MMCSD1_DAT_2, > >+ DA850_MMCSD1_DAT_3, > >+ DA850_MMCSD1_CLK, > >+ DA850_MMCSD1_CMD, > >+ > > /* EMIF2.5/EMIFA function */ > > DA850_EMA_D_7, > > DA850_EMA_D_6, > >@@ -916,6 +924,8 @@ enum davinci_da850_index { > > DA850_GPIO3_13, > > DA850_GPIO4_0, > > DA850_GPIO4_1, > >+ DA850_GPIO6_9, > >+ DA850_GPIO6_10, > > DA850_GPIO6_13, > > DA850_RTC_ALARM, > > }; > > Please modify these 2 files a sperate patch. Maybe even 2 > patches: one for MMC1 pins and one for GPIO pins... Sure, will be fixed. Thanks for your review, Ido. -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index c0deaca..1a9149c 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -192,6 +192,37 @@ config DA850_UI_RMII endchoice +config DA850_WL12XX + bool "DA850 wl12xx expansion board" + depends on MACH_DAVINCI_DA850_EVM + ---help--- + Say Y if you want to use a wl12xx expansion board connected to the + DA850 EVM. + +choice + prompt "FREF reference clock used by the wl12XX expansion board" + default DA850_WL12XX_FREF_38_4 + depends on DA850_WL12XX + help + There are currently two kinds of such daughter boards, one made by + Mistral and another by LS Research. These (and perhaps others) use + different FREF reference clocks. Select the correct one according to + the daughter board's type. + +config DA850_WL12XX_FREF_19_2 + bool "19.2MHz" +config DA850_WL12XX_FREF_26 + bool "26MHz" +config DA850_WL12XX_FREF_38_4 + bool "38.4MHz" +config DA850_WL12XX_FREF_52 + bool "52MHz" +config DA850_WL12XX_FREF_XTAL_26 + bool "XTAL 26MHz" +config DA850_WL12XX_FREF_XTAL_38_4 + bool "XTAL 38MHz" +endchoice + config GPIO_PCA953X default MACH_DAVINCI_DA850_EVM diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index a7b41bf..a567379 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -31,6 +31,8 @@ #include <linux/input/tps6507x-ts.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <linux/delay.h> +#include <linux/wl12xx.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -49,6 +51,9 @@ #define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0) #define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1) +#define DA850_WLAN_EN GPIO_TO_PIN(6, 9) +#define DA850_WLAN_IRQ GPIO_TO_PIN(6, 10) + #define DA850_MII_MDIO_CLKEN_PIN GPIO_TO_PIN(2, 6) static struct mtd_partition da850evm_spiflash_part[] = { @@ -1117,6 +1122,127 @@ static __init int da850_evm_init_cpufreq(void) static __init int da850_evm_init_cpufreq(void) { return 0; } #endif +#ifdef CONFIG_DA850_WL12XX + +static int da850_wl12xx_fref = -1; + +static int __init setup_da850_wl12xx_fref(char *fref) +{ + if (!strcmp(fref, "19.2")) + da850_wl12xx_fref = WL12XX_REFCLOCK_19; + else if (!strcmp(fref, "26")) + da850_wl12xx_fref = WL12XX_REFCLOCK_26; + else if (!strcmp(fref, "38.4")) + da850_wl12xx_fref = WL12XX_REFCLOCK_38; + else if (!strcmp(fref, "52")) + da850_wl12xx_fref = WL12XX_REFCLOCK_52; + else if (!strcmp(fref, "XTAL26")) + da850_wl12xx_fref = WL12XX_REFCLOCK_26_XTAL; + else if (!strcmp(fref, "XTAL38.4")) + da850_wl12xx_fref = WL12XX_REFCLOCK_38_XTAL; + else + pr_info("da850_wl12xx_fref is invalid. Valid options: " + "19.2, 26, 38.4, 52, XTAL26 or XTAL38.4\n"); + return 0; +} +__setup("da850_wl12xx_fref=", setup_da850_wl12xx_fref); + +static void wl12xx_set_power(int slot, bool power_on) +{ + static bool power_state; + + pr_debug("Powering %s wl12xx", (power_on ? "on" : "off")); + + if (power_on == power_state) + return; + power_state = power_on; + + if (power_on) { + /* Power up sequence required for wl127x devices */ + gpio_set_value(DA850_WLAN_EN, 1); + mdelay(15); + gpio_set_value(DA850_WLAN_EN, 0); + mdelay(1); + gpio_set_value(DA850_WLAN_EN, 1); + mdelay(70); + } else { + gpio_set_value(DA850_WLAN_EN, 0); + } +} + +static struct davinci_mmc_config da850_mmc_wl12xx_config = { + .get_ro = NULL, + .get_cd = NULL, + .set_power = wl12xx_set_power, + .wires = 4, + .max_freq = 25000000, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE | + MMC_CAP_POWER_OFF_CARD, + .version = MMC_CTLR_VERSION_2, +}; + +static const short da850_evm_mmc_wl12xx_pins[] __initconst = { + DA850_MMCSD1_DAT_0, DA850_MMCSD1_DAT_1, DA850_MMCSD1_DAT_2, + DA850_MMCSD1_DAT_3, DA850_MMCSD1_CLK, DA850_MMCSD1_CMD, + DA850_GPIO6_9, DA850_GPIO6_10, + -1 +}; + +static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = { + .irq = -1, +#ifdef CONFIG_DA850_WL12XX_FREF_19_2 + .board_ref_clock = WL12XX_REFCLOCK_19, +#elif defined CONFIG_DA850_WL12XX_FREF_26 + .board_ref_clock = WL12XX_REFCLOCK_26, +#elif defined CONFIG_DA850_WL12XX_FREF_38_4 + .board_ref_clock = WL12XX_REFCLOCK_38, +#elif defined CONFIG_DA850_WL12XX_FREF_52 + .board_ref_clock = WL12XX_REFCLOCK_52, +#elif defined CONFIG_DA850_WL12XX_FREF_XTAL_26 + .board_ref_clock = WL12XX_REFCLOCK_26_XTAL, +#elif defined CONFIG_DA850_WL12XX_FREF_XTAL_38_4 + .board_ref_clock = WL12XX_REFCLOCK_38_XTAL, +#endif + .platform_quirks = WL12XX_PLATFORM_QUIRK_EDGE_IRQ, +}; + +static void da850_wl12xx_init(void) +{ + int ret; + + ret = davinci_cfg_reg_list(da850_evm_mmc_wl12xx_pins); + if (ret) + pr_warning("da850_evm_init: wl12xx/mmc mux setup failed:" + " %d\n", ret); + + ret = da850_register_mmcsd1(&da850_mmc_wl12xx_config); + if (ret) + pr_warning("da850_evm_init: wl12xx/mmc registration failed:" + " %d\n", ret); + + if (gpio_request(DA850_WLAN_EN, "wl12xx_en") || + gpio_direction_output(DA850_WLAN_EN, 0)) + pr_err("Error initializing the wl12xx enable gpio\n"); + + if (gpio_request(DA850_WLAN_IRQ, "wl12xx_irq") || + gpio_direction_input(DA850_WLAN_IRQ)) + pr_err("Error initializing the wl12xx irq gpio\n"); + else + da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ); + + if (da850_wl12xx_fref != -1) + da850_wl12xx_wlan_data.board_ref_clock = da850_wl12xx_fref; + + if (wl12xx_set_platform_data(&da850_wl12xx_wlan_data)) + pr_err("Error setting wl12xx data\n"); +} + +#else /* CONFIG_DA850_WL12XX */ + +static void da850_wl12xx_init(void) { } + +#endif /* CONFIG_DA850_WL12XX */ + static __init void da850_evm_init(void) { int ret; @@ -1169,6 +1295,8 @@ static __init void da850_evm_init(void) if (ret) pr_warning("da850_evm_init: mmcsd0 registration failed:" " %d\n", ret); + + da850_wl12xx_init(); } davinci_serial_init(&da850_evm_uart_config); diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 133aac4..bfe9b71 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -525,6 +525,13 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false) MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false) MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false) + /* MMC/SD1 function */ + MUX_CFG(DA850, MMCSD1_DAT_0, 18, 8, 15, 2, false) + MUX_CFG(DA850, MMCSD1_DAT_1, 19, 16, 15, 2, false) + MUX_CFG(DA850, MMCSD1_DAT_2, 19, 12, 15, 2, false) + MUX_CFG(DA850, MMCSD1_DAT_3, 19, 8, 15, 2, false) + MUX_CFG(DA850, MMCSD1_CLK, 18, 12, 15, 2, false) + MUX_CFG(DA850, MMCSD1_CMD, 18, 16, 15, 2, false) /* EMIF2.5/EMIFA function */ MUX_CFG(DA850, EMA_D_7, 9, 0, 15, 1, false) MUX_CFG(DA850, EMA_D_6, 9, 4, 15, 1, false) @@ -583,6 +590,8 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_9, 13, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_10, 13, 20, 15, 8, false) MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 5d4e0fe..a7e92fc 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -857,6 +857,14 @@ enum davinci_da850_index { DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + /* MMC/SD1 function */ + DA850_MMCSD1_DAT_0, + DA850_MMCSD1_DAT_1, + DA850_MMCSD1_DAT_2, + DA850_MMCSD1_DAT_3, + DA850_MMCSD1_CLK, + DA850_MMCSD1_CMD, + /* EMIF2.5/EMIFA function */ DA850_EMA_D_7, DA850_EMA_D_6, @@ -916,6 +924,8 @@ enum davinci_da850_index { DA850_GPIO3_13, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO6_9, + DA850_GPIO6_10, DA850_GPIO6_13, DA850_RTC_ALARM, };
The DA850 supports an optional wl12xx based expansion board, adding WLAN & BT capabilities. The wl12xx is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line and is power-controlled by a GPIO-based fixed regulator. This patch adds support for the WLAN capabilities of this expansion board. Signed-off-by: Ido Yariv <ido@wizery.com> --- arch/arm/mach-davinci/Kconfig | 31 +++++++ arch/arm/mach-davinci/board-da850-evm.c | 128 ++++++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 9 ++ arch/arm/mach-davinci/include/mach/mux.h | 10 +++ 4 files changed, 178 insertions(+), 0 deletions(-)