Commit 2f407966 authored by Linus Walleij's avatar Linus Walleij Committed by Marcel Holtmann
Browse files

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: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 7820ee1c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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;