summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2019-06-01 21:04:16 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-07-06 07:00:04 -0400
commita3cb6d602a7a948f0b4ff77b6a087f9c25038d52 (patch)
tree1235513c96ec8eef5d4a34a38c47c14d64481a17 /drivers/bluetooth
parent14e3ed84d77e78fbf386006d3e5a0c20150681f5 (diff)
Bluetooth: btmtkuart: add an implementation for boot-gpios property
Not every platform has the pinctrl device integrates the GPIO the function such as MT7621 whose pinctrl and GPIO are separate hardware so the driver adds additional boot-gpios to let the MT766[3,8]U can enter the proper boot mode by gpiod for such platform. Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btmtkuart.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c
index f5dbeec8e274..1257149cfdc4 100644
--- a/drivers/bluetooth/btmtkuart.c
+++ b/drivers/bluetooth/btmtkuart.c
@@ -119,6 +119,7 @@ struct btmtkuart_dev {
119 119
120 struct regulator *vcc; 120 struct regulator *vcc;
121 struct gpio_desc *reset; 121 struct gpio_desc *reset;
122 struct gpio_desc *boot;
122 struct pinctrl *pinctrl; 123 struct pinctrl *pinctrl;
123 struct pinctrl_state *pins_runtime; 124 struct pinctrl_state *pins_runtime;
124 struct pinctrl_state *pins_boot; 125 struct pinctrl_state *pins_boot;
@@ -911,6 +912,13 @@ static int btmtkuart_parse_dt(struct serdev_device *serdev)
911 return err; 912 return err;
912 } 913 }
913 914
915 bdev->boot = devm_gpiod_get_optional(&serdev->dev, "boot",
916 GPIOD_OUT_LOW);
917 if (IS_ERR(bdev->boot)) {
918 err = PTR_ERR(bdev->boot);
919 return err;
920 }
921
914 bdev->pinctrl = devm_pinctrl_get(&serdev->dev); 922 bdev->pinctrl = devm_pinctrl_get(&serdev->dev);
915 if (IS_ERR(bdev->pinctrl)) { 923 if (IS_ERR(bdev->pinctrl)) {
916 err = PTR_ERR(bdev->pinctrl); 924 err = PTR_ERR(bdev->pinctrl);
@@ -919,8 +927,10 @@ static int btmtkuart_parse_dt(struct serdev_device *serdev)
919 927
920 bdev->pins_boot = pinctrl_lookup_state(bdev->pinctrl, 928 bdev->pins_boot = pinctrl_lookup_state(bdev->pinctrl,
921 "default"); 929 "default");
922 if (IS_ERR(bdev->pins_boot)) { 930 if (IS_ERR(bdev->pins_boot) && !bdev->boot) {
923 err = PTR_ERR(bdev->pins_boot); 931 err = PTR_ERR(bdev->pins_boot);
932 dev_err(&serdev->dev,
933 "Should assign RXD to LOW at boot stage\n");
924 return err; 934 return err;
925 } 935 }
926 936
@@ -996,8 +1006,14 @@ static int btmtkuart_probe(struct serdev_device *serdev)
996 set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); 1006 set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
997 1007
998 if (btmtkuart_is_standalone(bdev)) { 1008 if (btmtkuart_is_standalone(bdev)) {
999 /* Switch to the specific pin state for the booting requires */ 1009 if (bdev->boot) {
1000 pinctrl_select_state(bdev->pinctrl, bdev->pins_boot); 1010 gpiod_set_value_cansleep(bdev->boot, 1);
1011 } else {
1012 /* Switch to the specific pin state for the booting
1013 * requires.
1014 */
1015 pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
1016 }
1001 1017
1002 /* Power on */ 1018 /* Power on */
1003 err = regulator_enable(bdev->vcc); 1019 err = regulator_enable(bdev->vcc);
@@ -1017,6 +1033,10 @@ static int btmtkuart_probe(struct serdev_device *serdev)
1017 * mode the device requires for UART transfers. 1033 * mode the device requires for UART transfers.
1018 */ 1034 */
1019 msleep(50); 1035 msleep(50);
1036
1037 if (bdev->boot)
1038 devm_gpiod_put(&serdev->dev, bdev->boot);
1039
1020 pinctrl_select_state(bdev->pinctrl, bdev->pins_runtime); 1040 pinctrl_select_state(bdev->pinctrl, bdev->pins_runtime);
1021 1041
1022 /* A standalone device doesn't depends on power domain on SoC, 1042 /* A standalone device doesn't depends on power domain on SoC,
@@ -1037,10 +1057,8 @@ static int btmtkuart_probe(struct serdev_device *serdev)
1037 return 0; 1057 return 0;
1038 1058
1039err_regulator_disable: 1059err_regulator_disable:
1040 if (btmtkuart_is_standalone(bdev)) { 1060 if (btmtkuart_is_standalone(bdev))
1041 pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
1042 regulator_disable(bdev->vcc); 1061 regulator_disable(bdev->vcc);
1043 }
1044 1062
1045 return err; 1063 return err;
1046} 1064}
@@ -1050,10 +1068,8 @@ static void btmtkuart_remove(struct serdev_device *serdev)
1050 struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); 1068 struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
1051 struct hci_dev *hdev = bdev->hdev; 1069 struct hci_dev *hdev = bdev->hdev;
1052 1070
1053 if (btmtkuart_is_standalone(bdev)) { 1071 if (btmtkuart_is_standalone(bdev))
1054 pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
1055 regulator_disable(bdev->vcc); 1072 regulator_disable(bdev->vcc);
1056 }
1057 1073
1058 hci_unregister_dev(hdev); 1074 hci_unregister_dev(hdev);
1059 hci_free_dev(hdev); 1075 hci_free_dev(hdev);