summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>2011-05-25 23:22:35 +0200
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:15:22 +0200
commit7f31e53a216a3713fe921e6684bed37511765d3b (patch)
tree5b181cc9c2b5f760f49bf32775550b27aac5169d
parent63ca006d40cbbaa434f5e287f2a9f6b0ae5374b4 (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.c44
-rw-r--r--drivers/staging/cw1200/cw1200_plat.h5
-rw-r--r--drivers/staging/cw1200/cw1200_sdio.c29
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);
}