diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2021-03-05 19:37:36 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2021-03-08 10:25:49 +0100 |
commit | 2f40796671f03c0eb193f44c7d4a6855ab9b30f6 (patch) | |
tree | d063d4d684e7eb60b700a524b8ad226d61a44989 /drivers/bluetooth | |
parent | 7820ee1c4757d888c2255b8eb7f74b8d1e5ac555 (diff) |
Bluetooth: btbcm: Obtain and handle reset GPIO
Obtain and drive the optional reset GPIO line if this is
not hardwired in the platform. This is needed on the
Samsung GT-I9070 mobile phone.
The invers of power is used, this should be OK to apply
simultaneously as the power signal according to
figures 47-51 on pages 159-161 in the BCM4330 datasheet.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/hci_bcm.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 3764ceb6fa0d..93a4c03a8787 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -68,6 +68,8 @@ struct bcm_device_data { * deassert = Bluetooth device may sleep when sleep criteria are met * @shutdown: BT_REG_ON pin, * power up or power down Bluetooth device internal regulators + * @reset: BT_RST_N pin, + * active low resets the Bluetooth logic core * @set_device_wakeup: callback to toggle BT_WAKE pin * either by accessing @device_wakeup or by calling @btlp * @set_shutdown: callback to toggle BT_REG_ON pin @@ -101,6 +103,7 @@ struct bcm_device { const char *name; struct gpio_desc *device_wakeup; struct gpio_desc *shutdown; + struct gpio_desc *reset; int (*set_device_wakeup)(struct bcm_device *, bool); int (*set_shutdown)(struct bcm_device *, bool); #ifdef CONFIG_ACPI @@ -985,6 +988,15 @@ static int bcm_gpio_set_device_wakeup(struct bcm_device *dev, bool awake) static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered) { gpiod_set_value_cansleep(dev->shutdown, powered); + if (dev->reset) + /* + * The reset line is asserted on powerdown and deasserted + * on poweron so the inverse of powered is used. Notice + * that the GPIO line BT_RST_N needs to be specified as + * active low in the device tree or similar system + * description. + */ + gpiod_set_value_cansleep(dev->reset, !powered); return 0; } @@ -1050,6 +1062,11 @@ static int bcm_get_resources(struct bcm_device *dev) if (IS_ERR(dev->shutdown)) return PTR_ERR(dev->shutdown); + dev->reset = devm_gpiod_get_optional(dev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(dev->reset)) + return PTR_ERR(dev->reset); + dev->set_device_wakeup = bcm_gpio_set_device_wakeup; dev->set_shutdown = bcm_gpio_set_shutdown; |