summaryrefslogtreecommitdiff
path: root/drivers/misc/bcm4329_rfkill.c
diff options
context:
space:
mode:
authorAnantha Idapalapati <aidapalapati@nvidia.com>2010-12-29 13:15:11 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 01:06:21 -0700
commit528850b997b6728a6a9c781e21e23ddc4d451cf7 (patch)
tree19a25782935fd29d0cbaaeded7764b7b36c8d44d /drivers/misc/bcm4329_rfkill.c
parentd1b6edeb559806ece4d942a506d5a0ccfb222d1a (diff)
[bt/rfkill]: make either RST/SHUTDOWN GPIO usage optional.
the current BCM4329 rfkill driver assumes usage of 2 GPIOs known as RST and SHUTDOWN and the driver makes a particular GPIO mandatory. Some of the platforms does not define both GPIOs, instead a single either RST/SHUTDOWN GPIO is used to setup the chip. This change makes driver to consider any of the two GPIOs as optional and use any of the RST/SHUTDOWN GPIOs. Simultaneous usage of both GPIOs is also allowed. Original-Change-Id: Ib66ea350e78642082f639514ef7a9def6e460e28 Reviewed-on: http://git-master/r/14534 Reviewed-by: Anantha Idapalapati <aidapalapati@nvidia.com> Tested-by: Anantha Idapalapati <aidapalapati@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Rebase-Id: R0d885111030f3123aeeeb8331f4e2abf08c88c8b
Diffstat (limited to 'drivers/misc/bcm4329_rfkill.c')
-rw-r--r--drivers/misc/bcm4329_rfkill.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/drivers/misc/bcm4329_rfkill.c b/drivers/misc/bcm4329_rfkill.c
index f274c6c10ad2..34725bccd596 100644
--- a/drivers/misc/bcm4329_rfkill.c
+++ b/drivers/misc/bcm4329_rfkill.c
@@ -44,15 +44,19 @@ static struct bcm4329_rfkill_data *bcm4329_rfkill;
static int bcm4329_bt_rfkill_set_power(void *data, bool blocked)
{
if (blocked) {
- gpio_direction_output(bcm4329_rfkill->gpio_shutdown, 0);
- gpio_direction_output(bcm4329_rfkill->gpio_reset, 0);
+ if (bcm4329_rfkill->gpio_shutdown)
+ gpio_direction_output(bcm4329_rfkill->gpio_shutdown, 0);
+ if (bcm4329_rfkill->gpio_reset)
+ gpio_direction_output(bcm4329_rfkill->gpio_reset, 0);
if (bcm4329_rfkill->bt_32k_clk)
clk_disable(bcm4329_rfkill->bt_32k_clk);
} else {
if (bcm4329_rfkill->bt_32k_clk)
clk_enable(bcm4329_rfkill->bt_32k_clk);
- gpio_direction_output(bcm4329_rfkill->gpio_shutdown, 1);
- gpio_direction_output(bcm4329_rfkill->gpio_reset, 1);
+ if (bcm4329_rfkill->gpio_shutdown)
+ gpio_direction_output(bcm4329_rfkill->gpio_shutdown, 1);
+ if (bcm4329_rfkill->gpio_reset)
+ gpio_direction_output(bcm4329_rfkill->gpio_reset, 1);
}
return 0;
@@ -76,40 +80,43 @@ static int bcm4329_rfkill_probe(struct platform_device *pdev)
bcm4329_rfkill->bt_32k_clk = clk_get(&pdev->dev, "bcm4329_32k_clk");
if (IS_ERR(bcm4329_rfkill->bt_32k_clk)) {
- pr_warn("can't find bcm4329_32k_clk. assuming clock to chip\n");
+ pr_warn("%s: can't find bcm4329_32k_clk.\
+ assuming 32k clock to chip\n", __func__);
bcm4329_rfkill->bt_32k_clk = NULL;
}
res = platform_get_resource_byname(pdev, IORESOURCE_IO,
"bcm4329_nreset_gpio");
- if (!res) {
- pr_err("couldn't find reset gpio\n");
- goto free_bcm_32k_clk;
+ if (res) {
+ bcm4329_rfkill->gpio_reset = res->start;
+ ret = gpio_request(bcm4329_rfkill->gpio_reset,
+ "bcm4329_nreset_gpio");
+ } else {
+ pr_warn("%s : can't find reset gpio.\n", __func__);
+ bcm4329_rfkill->gpio_reset = 0;
}
- bcm4329_rfkill->gpio_reset = res->start;
- ret = gpio_request(bcm4329_rfkill->gpio_reset,
- "bcm4329_nreset_gpio");
- if (unlikely(ret))
- goto free_bcm_32k_clk;
res = platform_get_resource_byname(pdev, IORESOURCE_IO,
"bcm4329_nshutdown_gpio");
- if (!res) {
- pr_err("couldn't find shutdown gpio\n");
- gpio_free(bcm4329_rfkill->gpio_reset);
- goto free_bcm_32k_clk;
- }
- ret = gpio_request(bcm4329_rfkill->gpio_shutdown,
- "bcm4329_nshutdown_gpio");
- if (unlikely(ret)) {
- gpio_free(bcm4329_rfkill->gpio_reset);
- goto free_bcm_32k_clk;
+ if (res) {
+ bcm4329_rfkill->gpio_shutdown = res->start;
+ ret = gpio_request(bcm4329_rfkill->gpio_shutdown,
+ "bcm4329_nshutdown_gpio");
+ } else {
+ pr_warn("%s : can't find shutdown gpio.\n", __func__);
+ bcm4329_rfkill->gpio_shutdown = 0;
}
+ /* make sure at-least one of the GPIO is defined */
+ if (!bcm4329_rfkill->gpio_reset && !bcm4329_rfkill->gpio_shutdown)
+ goto free_bcm_res;
+
if (bcm4329_rfkill->bt_32k_clk && enable)
clk_enable(bcm4329_rfkill->bt_32k_clk);
- gpio_direction_output(bcm4329_rfkill->gpio_shutdown, enable);
- gpio_direction_output(bcm4329_rfkill->gpio_reset, enable);
+ if (bcm4329_rfkill->gpio_shutdown)
+ gpio_direction_output(bcm4329_rfkill->gpio_shutdown, enable);
+ if (bcm4329_rfkill->gpio_reset)
+ gpio_direction_output(bcm4329_rfkill->gpio_reset, enable);
bt_rfkill = rfkill_alloc("bcm4329 Bluetooth", &pdev->dev,
RFKILL_TYPE_BLUETOOTH, &bcm4329_bt_rfkill_ops,
@@ -131,9 +138,10 @@ static int bcm4329_rfkill_probe(struct platform_device *pdev)
return 0;
free_bcm_res:
- gpio_free(bcm4329_rfkill->gpio_shutdown);
- gpio_free(bcm4329_rfkill->gpio_reset);
-free_bcm_32k_clk:
+ if (bcm4329_rfkill->gpio_shutdown)
+ gpio_free(bcm4329_rfkill->gpio_shutdown);
+ if (bcm4329_rfkill->gpio_reset)
+ gpio_free(bcm4329_rfkill->gpio_reset);
if (bcm4329_rfkill->bt_32k_clk && enable)
clk_disable(bcm4329_rfkill->bt_32k_clk);
if (bcm4329_rfkill->bt_32k_clk)
@@ -150,8 +158,10 @@ static int bcm4329_rfkill_remove(struct platform_device *pdev)
clk_put(bcm4329_rfkill->bt_32k_clk);
rfkill_unregister(bt_rfkill);
rfkill_destroy(bt_rfkill);
- gpio_free(bcm4329_rfkill->gpio_shutdown);
- gpio_free(bcm4329_rfkill->gpio_reset);
+ if (bcm4329_rfkill->gpio_shutdown)
+ gpio_free(bcm4329_rfkill->gpio_shutdown);
+ if (bcm4329_rfkill->gpio_reset)
+ gpio_free(bcm4329_rfkill->gpio_reset);
kfree(bcm4329_rfkill);
return 0;