diff options
author | Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> | 2011-05-25 23:22:35 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 15:15:22 +0200 |
commit | 7f31e53a216a3713fe921e6684bed37511765d3b (patch) | |
tree | 5b181cc9c2b5f760f49bf32775550b27aac5169d | |
parent | 63ca006d40cbbaa434f5e287f2a9f6b0ae5374b4 (diff) |
cw1200: Add regulator support
Add regulator support needed on Snowball HW.
Change-Id: I12a88e7f968e00de256c7f331f5baede2d410ab7
Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/25139
Reviewed-by: Robert MARKLUND <robert.marklund@stericsson.com>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-wlan.c | 44 | ||||
-rw-r--r-- | drivers/staging/cw1200/cw1200_plat.h | 5 | ||||
-rw-r--r-- | drivers/staging/cw1200/cw1200_sdio.c | 29 |
3 files changed, 66 insertions, 12 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-wlan.c b/arch/arm/mach-ux500/board-mop500-wlan.c index 90b17e70e23..e73a35e7c76 100644 --- a/arch/arm/mach-ux500/board-mop500-wlan.c +++ b/arch/arm/mach-ux500/board-mop500-wlan.c @@ -6,7 +6,9 @@ */ #include <linux/kernel.h> +#include <linux/err.h> #include <linux/platform_device.h> +#include <linux/regulator/consumer.h> #include <asm/mach-types.h> #include <mach/irqs-board-mop500.h> #include <plat/pincfg.h> @@ -14,6 +16,8 @@ #include "../drivers/staging/cw1200/cw1200_plat.h" static void cw1200_release(struct device *dev); +static int cw1200_power_ctrl(const struct cw1200_platform_data *pdata, + bool enable); static struct resource cw1200_href_resources[] = { { @@ -49,16 +53,14 @@ static struct resource cw1200_href60_resources[] = { #endif /* CONFIG_CW1200_USE_GPIO_IRQ */ }; -static struct cw1200_platform_data cw1200_platform_data = { - .regulator_vdd = "vdd", - .regulator_vio = "vio", -}; +static struct cw1200_platform_data cw1200_platform_data = { 0 }; static struct platform_device cw1200_device = { - .name = "cw1200", + .name = "cw1200_wlan", .dev = { .platform_data = &cw1200_platform_data, .release = cw1200_release, + .init_name = "cw1200_wlan", }, }; @@ -95,6 +97,36 @@ static int cw1200_pins_enable(bool enable) return ret; } +static int cw1200_power_ctrl(const struct cw1200_platform_data *pdata, + bool enable) +{ + static const char *vdd_name = "vdd"; + struct regulator *vdd; + int ret = 0; + + vdd = regulator_get(&cw1200_device.dev, vdd_name); + if (IS_ERR(vdd)) { + ret = PTR_ERR(vdd); + dev_warn(&cw1200_device.dev, + "%s: Failed to get regulator '%s': %d\n", + __func__, vdd_name, ret); + } else { + if (enable) + ret = regulator_enable(vdd); + else + ret = regulator_disable(vdd); + + if (ret) { + dev_warn(&cw1200_device.dev, + "%s: Failed to %s regulator '%s': %d\n", + __func__, enable ? "enable" : "disable", + vdd_name, ret); + } + regulator_put(vdd); + } + return ret; +} + int __init mop500_wlan_init(void) { int ret; @@ -128,6 +160,8 @@ int __init mop500_wlan_init(void) #endif /* #ifdef CONFIG_CW1200_USE_GPIO_IRQ */ cw1200_device.dev.release = cw1200_release; + if (machine_is_snowball()) + cw1200_platform_data.power_ctrl = cw1200_power_ctrl; ret = cw1200_pins_enable(true); if (WARN_ON(ret)) diff --git a/drivers/staging/cw1200/cw1200_plat.h b/drivers/staging/cw1200/cw1200_plat.h index 3b6acaff305..573bc06ac7f 100644 --- a/drivers/staging/cw1200/cw1200_plat.h +++ b/drivers/staging/cw1200/cw1200_plat.h @@ -8,11 +8,12 @@ #include <linux/ioport.h> struct cw1200_platform_data { - const char *regulator_vdd; - const char *regulator_vio; + struct platform_device *device; const char *mmc_id; const struct resource *irq; const struct resource *reset; + int (*power_ctrl)(const struct cw1200_platform_data *pdata, + bool enable); }; /* Declaration only. Should be implemented in arch/xxx/mach-yyy */ diff --git a/drivers/staging/cw1200/cw1200_sdio.c b/drivers/staging/cw1200/cw1200_sdio.c index 2b7d0a1eaf7..235ac67cb75 100644 --- a/drivers/staging/cw1200/cw1200_sdio.c +++ b/drivers/staging/cw1200/cw1200_sdio.c @@ -28,7 +28,7 @@ MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>"); MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SDIO driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("cw1200"); +MODULE_ALIAS("cw1200_wlan"); struct sbus_priv { struct sdio_func *func; @@ -259,6 +259,9 @@ static int cw1200_sdio_on(const struct cw1200_platform_data *pdata) const struct resource *reset = pdata->reset; gpio_request(reset->start, reset->name); gpio_direction_output(reset->start, 1); + msleep(100); + gpio_set_value(reset->start, 0); + msleep(100); gpio_set_value(reset->start, 1); cw1200_detect_card(pdata); return 0; @@ -267,7 +270,7 @@ static int cw1200_sdio_on(const struct cw1200_platform_data *pdata) static int cw1200_sdio_reset(struct sbus_priv *self) { cw1200_sdio_off(self->pdata); - mdelay(1000); + msleep(1000); cw1200_sdio_on(self->pdata); return 0; } @@ -350,7 +353,7 @@ static void cw1200_sdio_disconnect(struct sdio_func *func) } static struct sdio_driver sdio_driver = { - .name = "cw1200", + .name = "cw1200_wlan", .id_table = if_sdio_ids, .probe = cw1200_sdio_probe, .remove = cw1200_sdio_disconnect, @@ -359,19 +362,31 @@ static struct sdio_driver sdio_driver = { /* Init Module function -> Called by insmod */ static int __init cw1200_sdio_init(void) { + const struct cw1200_platform_data *pdata; int ret; + pdata = cw1200_get_platform_data(); + ret = sdio_register_driver(&sdio_driver); if (ret) goto err_reg; - ret = cw1200_sdio_on(cw1200_get_platform_data()); + if (pdata->power_ctrl) { + ret = pdata->power_ctrl(pdata, true); + if (ret) + goto err_power; + } + + ret = cw1200_sdio_on(pdata); if (ret) goto err_on; return 0; err_on: + if (pdata->power_ctrl) + pdata->power_ctrl(pdata, false); +err_power: sdio_unregister_driver(&sdio_driver); err_reg: return ret; @@ -380,8 +395,12 @@ err_reg: /* Called at Driver Unloading */ static void __exit cw1200_sdio_exit(void) { + const struct cw1200_platform_data *pdata; + pdata = cw1200_get_platform_data(); sdio_unregister_driver(&sdio_driver); - cw1200_sdio_off(cw1200_get_platform_data()); + cw1200_sdio_off(pdata); + if (pdata->power_ctrl) + pdata->power_ctrl(pdata, false); } |