[bt/rfkill]: make either RST/SHUTDOWN GPIO usage optional.
Anantha Idapalapati [Wed, 29 Dec 2010 07:45:11 +0000 (12:45 +0530)]
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

drivers/misc/bcm4329_rfkill.c

index eeb4047..c266195 100644 (file)
@@ -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,42 +80,45 @@ 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;
+               tegra_gpio_enable(bcm4329_rfkill->gpio_reset);
+               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;
-       tegra_gpio_enable(bcm4329_rfkill->gpio_reset);
-       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;
-       }
-       tegra_gpio_enable(bcm4329_rfkill->gpio_shutdown);
-       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;
+               tegra_gpio_enable(bcm4329_rfkill->gpio_shutdown);
+               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,
@@ -133,9 +140,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)
@@ -152,8 +160,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;