diff options
author | Anantha Idapalapati <aidapalapati@nvidia.com> | 2010-12-29 13:15:11 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 01:06:21 -0700 |
commit | 528850b997b6728a6a9c781e21e23ddc4d451cf7 (patch) | |
tree | 19a25782935fd29d0cbaaeded7764b7b36c8d44d /drivers | |
parent | d1b6edeb559806ece4d942a506d5a0ccfb222d1a (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')
-rw-r--r-- | drivers/misc/bcm4329_rfkill.c | 70 |
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; |