diff --git a/arch/arm64/boot/dts/amlogic/g12a_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_skt.dts index 038fc60121c2..e65f555dbffc 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_skt.dts @@ -234,6 +234,7 @@ dev_name = "bt-dev"; status = "okay"; gpio_reset = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + gpio_hostwake = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>; }; wifi{ diff --git a/drivers/amlogic/bluetooth/bt_device.c b/drivers/amlogic/bluetooth/bt_device.c index c18a676790ea..af0ea21812e7 100644 --- a/drivers/amlogic/bluetooth/bt_device.c +++ b/drivers/amlogic/bluetooth/bt_device.c @@ -57,6 +57,17 @@ static void bt_device_init(struct bt_dev_data *pdata) if (pdata->gpio_en > 0) gpio_request(pdata->gpio_en, BT_RFKILL); + if (pdata->gpio_hostwake > 0) { + gpio_request(pdata->gpio_hostwake, BT_RFKILL); + + if ((pdata->power_on_pin_OD) && (!pdata->power_low_level)) { + gpio_direction_input(pdata->gpio_hostwake); + } else { + gpio_direction_output(pdata->gpio_hostwake, + !pdata->power_low_level); + } + } + } static void bt_device_deinit(struct bt_dev_data *pdata) @@ -67,6 +78,9 @@ static void bt_device_deinit(struct bt_dev_data *pdata) if (pdata->gpio_en > 0) gpio_free(pdata->gpio_en); + if (pdata->gpio_hostwake > 0) + gpio_free(pdata->gpio_hostwake); + } static void bt_device_on(struct bt_dev_data *pdata) @@ -133,6 +147,7 @@ static void bt_device_off(struct bt_dev_data *pdata) set_usb_bt_power(0); } } + msleep(20); } @@ -143,10 +158,10 @@ static int bt_set_block(void *data, bool blocked) pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on"); if (!blocked) { - pr_info("BCM_BT: going ON\n"); + pr_info("AML_BT: going ON\n"); bt_device_on(pdata); } else { - pr_info("BCM_BT: going OFF\n"); + pr_info("AML_BT: going OFF\n"); bt_device_off(pdata); } return 0; @@ -205,7 +220,7 @@ static int bt_probe(struct platform_device *pdev) pdata->gpio_reset = desc_to_gpio(desc); } - ret = of_property_read_string(pdev->dev.of_node, + ret = of_property_read_string(pdev->dev.of_node, "gpio_en", &str); if (ret) { pr_warn("not get gpio_en\n"); @@ -215,6 +230,16 @@ static int bt_probe(struct platform_device *pdev) "gpio_en", 0, NULL); pdata->gpio_en = desc_to_gpio(desc); } + ret = of_property_read_string(pdev->dev.of_node, + "gpio_hostwake", &str); + if (ret) { + pr_warn("not get gpio_hostwake\n"); + pdata->gpio_hostwake = 0; + } else { + desc = of_get_named_gpiod_flags(pdev->dev.of_node, + "gpio_hostwake", 0, NULL); + pdata->gpio_hostwake = desc_to_gpio(desc); + } prop = of_get_property(pdev->dev.of_node, "power_low_level", NULL); diff --git a/include/linux/amlogic/bt_device.h b/include/linux/amlogic/bt_device.h index e0c6de19c55b..f233dbe71dfa 100644 --- a/include/linux/amlogic/bt_device.h +++ b/include/linux/amlogic/bt_device.h @@ -21,6 +21,7 @@ struct bt_dev_data { int gpio_reset; int gpio_en; + int gpio_hostwake; int power_low_level; int power_on_pin_OD; };