From ac79f96435637ec7b82382123ba6c1dd39fcfe61 Mon Sep 17 00:00:00 2001 From: Par-Gunnar Hjalmdahl Date: Fri, 2 Sep 2011 15:59:16 +0530 Subject: cg2900: Set WLAN_PMU_EN for startup This patch changes startup behavior of CG2900 so that WLAN_PMU_EN is controlled separately. ST-Ericsson Linux next: Not tested, ER 326583 ST-Ericsson ID: 326583 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Iac4aac30835b93c16ceaaf2aa0e601b293cc0cbb Signed-off-by: Par-Gunnar Hjalmdahl Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23839 Reviewed-by: Lukasz RYMANOWSKI Reviewed-by: QATEST Reviewed-by: Jonas ABERG Reviewed-by: Srinidhi KASAGAR Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30040 Reviewed-by: Virupax SADASHIVPETIMATH Tested-by: Virupax SADASHIVPETIMATH --- drivers/staging/cg2900/board-mop500-cg2900.c | 7 +++ drivers/staging/cg2900/devices-cg2900-u8500.c | 71 ++++++++++++++++++++++----- drivers/staging/cg2900/devices-cg2900.c | 8 ++- drivers/staging/cg2900/devices-cg2900.h | 4 +- 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/drivers/staging/cg2900/board-mop500-cg2900.c b/drivers/staging/cg2900/board-mop500-cg2900.c index f1bc070c0a1..4c010a1287e 100644 --- a/drivers/staging/cg2900/board-mop500-cg2900.c +++ b/drivers/staging/cg2900/board-mop500-cg2900.c @@ -28,6 +28,7 @@ #define CG2900_BT_ENABLE_GPIO 170 #define CG2900_GBF_ENA_RESET_GPIO 171 +#define WLAN_PMU_EN_GPIO 226 #define CG2900_BT_CTS_GPIO 0 enum cg2900_gpio_pull_sleep cg2900_sleep_gpio[21] = { @@ -119,6 +120,12 @@ static struct resource cg2900_uart_resources[] = { .flags = IORESOURCE_IO, .name = "gbf_ena_reset", }, + { + .start = WLAN_PMU_EN_GPIO, + .end = WLAN_PMU_EN_GPIO, + .flags = IORESOURCE_IO, + .name = "pmu_en", + }, { .start = CG2900_BT_CTS_GPIO, .end = CG2900_BT_CTS_GPIO, diff --git a/drivers/staging/cg2900/devices-cg2900-u8500.c b/drivers/staging/cg2900/devices-cg2900-u8500.c index cbadeee248d..f7ca62d5c68 100644 --- a/drivers/staging/cg2900/devices-cg2900-u8500.c +++ b/drivers/staging/cg2900/devices-cg2900-u8500.c @@ -37,7 +37,7 @@ void dcg2900_enable_chip(struct cg2900_chip_dev *dev) /* * Due to a bug in CG2900 we cannot just set GPIO high to enable - * the chip. We must wait more than 100 msecs before enbling the + * the chip. We must wait more than 100 msecs before enabling the * chip. * - Set PDB to low. * - Wait for 100 msecs @@ -46,6 +46,16 @@ void dcg2900_enable_chip(struct cg2900_chip_dev *dev) gpio_set_value(info->gbf_gpio, 0); schedule_timeout_uninterruptible(msecs_to_jiffies( CHIP_ENABLE_PDB_LOW_TIMEOUT)); + + if (info->pmuen_gpio != -1) { + /* + * We must first set PMU_EN pin high and then wait 300 us before + * setting the GBF_EN high. + */ + gpio_set_value(info->pmuen_gpio, 1); + udelay(CHIP_ENABLE_PMU_EN_TIMEOUT); + } + gpio_set_value(info->gbf_gpio, 1); } @@ -55,6 +65,8 @@ void dcg2900_disable_chip(struct cg2900_chip_dev *dev) if (info->gbf_gpio != -1) gpio_set_value(info->gbf_gpio, 0); + if (info->pmuen_gpio != -1) + gpio_set_value(info->pmuen_gpio, 0); } int dcg2900_setup(struct cg2900_chip_dev *dev, @@ -64,6 +76,7 @@ int dcg2900_setup(struct cg2900_chip_dev *dev, struct resource *resource; const char *gbf_name; const char *bt_name = NULL; + const char *pmuen_name = NULL; resource = platform_get_resource_byname(dev->pdev, IORESOURCE_IO, "gbf_ena_reset"); @@ -84,35 +97,64 @@ int dcg2900_setup(struct cg2900_chip_dev *dev, bt_name = resource->name; } + resource = platform_get_resource_byname(dev->pdev, IORESOURCE_IO, + "pmu_en"); + /* PMU_EN GPIO may not exist */ + if (resource) { + info->pmuen_gpio = resource->start; + pmuen_name = resource->name; + } + /* Now setup the GPIOs */ err = gpio_request(info->gbf_gpio, gbf_name); if (err < 0) { - dev_err(dev->dev, "gpio_request failed with err: %d\n", err); + dev_err(dev->dev, "gpio_request %s failed with err: %d\n", + gbf_name, err); goto err_handling; } err = gpio_direction_output(info->gbf_gpio, 0); if (err < 0) { - dev_err(dev->dev, "gpio_direction_output failed with err: %d\n", - err); + dev_err(dev->dev, + "gpio_direction_output %s failed with err: %d\n", + gbf_name, err); goto err_handling_free_gpio_gbf; } - if (!bt_name) { - info->bt_gpio = -1; - goto finished; + if (!pmuen_name) + goto set_bt_gpio; + + err = gpio_request(info->pmuen_gpio, pmuen_name); + if (err < 0) { + dev_err(dev->dev, "gpio_request %s failed with err: %d\n", + pmuen_name, err); + goto err_handling_free_gpio_gbf; + } + + err = gpio_direction_output(info->pmuen_gpio, 0); + if (err < 0) { + dev_err(dev->dev, + "gpio_direction_output %s failed with err: %d\n", + pmuen_name, err); + goto err_handling_free_gpio_pmuen; } +set_bt_gpio: + if (!bt_name) + goto finished; + err = gpio_request(info->bt_gpio, bt_name); if (err < 0) { - dev_err(dev->dev, "gpio_request failed with err: %d\n", err); - goto err_handling_free_gpio_gbf; + dev_err(dev->dev, "gpio_request %s failed with err: %d\n", + bt_name, err); + goto err_handling_free_gpio_pmuen; } err = gpio_direction_output(info->bt_gpio, 1); if (err < 0) { - dev_err(dev->dev, "gpio_direction_output failed with err: %d\n", - err); + dev_err(dev->dev, + "gpio_direction_output %s failed with err: %d\n", + bt_name, err); goto err_handling_free_gpio_bt; } @@ -122,8 +164,15 @@ finished: err_handling_free_gpio_bt: gpio_free(info->bt_gpio); + info->bt_gpio = -1; +err_handling_free_gpio_pmuen: + if (info->pmuen_gpio != -1) { + gpio_free(info->pmuen_gpio); + info->pmuen_gpio = -1; + } err_handling_free_gpio_gbf: gpio_free(info->gbf_gpio); + info->gbf_gpio = -1; err_handling: return err; diff --git a/drivers/staging/cg2900/devices-cg2900.c b/drivers/staging/cg2900/devices-cg2900.c index 689235989d9..8f342a4a1fc 100644 --- a/drivers/staging/cg2900/devices-cg2900.c +++ b/drivers/staging/cg2900/devices-cg2900.c @@ -149,10 +149,12 @@ static int dcg2900_init(struct cg2900_chip_dev *dev) return -ENOMEM; } + info->gbf_gpio = -1; + info->pmuen_gpio = -1; + info->bt_gpio = -1; + if (!dev->pdev->num_resources) { dev_dbg(dev->dev, "No resources available\n"); - info->gbf_gpio = -1; - info->bt_gpio = -1; goto finished; } @@ -218,6 +220,8 @@ static void dcg2900_exit(struct cg2900_chip_dev *dev) dcg2900_disable_chip(dev); if (info->bt_gpio != -1) gpio_free(info->bt_gpio); + if (info->pmuen_gpio != -1) + gpio_free(info->pmuen_gpio); if (info->gbf_gpio != -1) gpio_free(info->gbf_gpio); kfree(info); diff --git a/drivers/staging/cg2900/devices-cg2900.h b/drivers/staging/cg2900/devices-cg2900.h index c4dc060e22e..5feeb84901c 100644 --- a/drivers/staging/cg2900/devices-cg2900.h +++ b/drivers/staging/cg2900/devices-cg2900.h @@ -11,10 +11,12 @@ #include "cg2900.h" #include -#define CHIP_ENABLE_PDB_LOW_TIMEOUT 100 /* ms */ +#define CHIP_ENABLE_PDB_LOW_TIMEOUT 100 /* ms */ +#define CHIP_ENABLE_PMU_EN_TIMEOUT 300 /* us */ struct dcg2900_info { int gbf_gpio; + int pmuen_gpio; int bt_gpio; bool sleep_gpio_set; u8 gpio_0_7_pull_up; -- cgit v1.2.3