summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2019-06-01 21:04:17 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-07-06 07:00:04 -0400
commit055825614c6b4da8c931fe1dea2f2920553f7a67 (patch)
tree9afaece4ec99d4278dcf364bc2a17ffe480ced02 /drivers/bluetooth
parenta3cb6d602a7a948f0b4ff77b6a087f9c25038d52 (diff)
Bluetooth: btmtkuart: add an implementation for clock osc property
Some board requires explicitily control external osscilator via GPIO. So, add an implementation of a clock property for an external oscillator to the device. 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.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c
index 1257149cfdc4..e11169ad8247 100644
--- a/drivers/bluetooth/btmtkuart.c
+++ b/drivers/bluetooth/btmtkuart.c
@@ -115,8 +115,9 @@ struct btmtk_hci_wmt_params {
115struct btmtkuart_dev { 115struct btmtkuart_dev {
116 struct hci_dev *hdev; 116 struct hci_dev *hdev;
117 struct serdev_device *serdev; 117 struct serdev_device *serdev;
118 struct clk *clk;
119 118
119 struct clk *clk;
120 struct clk *osc;
120 struct regulator *vcc; 121 struct regulator *vcc;
121 struct gpio_desc *reset; 122 struct gpio_desc *reset;
122 struct gpio_desc *boot; 123 struct gpio_desc *boot;
@@ -912,6 +913,12 @@ static int btmtkuart_parse_dt(struct serdev_device *serdev)
912 return err; 913 return err;
913 } 914 }
914 915
916 bdev->osc = devm_clk_get_optional(&serdev->dev, "osc");
917 if (IS_ERR(bdev->osc)) {
918 err = PTR_ERR(bdev->osc);
919 return err;
920 }
921
915 bdev->boot = devm_gpiod_get_optional(&serdev->dev, "boot", 922 bdev->boot = devm_gpiod_get_optional(&serdev->dev, "boot",
916 GPIOD_OUT_LOW); 923 GPIOD_OUT_LOW);
917 if (IS_ERR(bdev->boot)) { 924 if (IS_ERR(bdev->boot)) {
@@ -1006,6 +1013,10 @@ static int btmtkuart_probe(struct serdev_device *serdev)
1006 set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); 1013 set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
1007 1014
1008 if (btmtkuart_is_standalone(bdev)) { 1015 if (btmtkuart_is_standalone(bdev)) {
1016 err = clk_prepare_enable(bdev->osc);
1017 if (err < 0)
1018 return err;
1019
1009 if (bdev->boot) { 1020 if (bdev->boot) {
1010 gpiod_set_value_cansleep(bdev->boot, 1); 1021 gpiod_set_value_cansleep(bdev->boot, 1);
1011 } else { 1022 } else {
@@ -1017,8 +1028,10 @@ static int btmtkuart_probe(struct serdev_device *serdev)
1017 1028
1018 /* Power on */ 1029 /* Power on */
1019 err = regulator_enable(bdev->vcc); 1030 err = regulator_enable(bdev->vcc);
1020 if (err < 0) 1031 if (err < 0) {
1032 clk_disable_unprepare(bdev->osc);
1021 return err; 1033 return err;
1034 }
1022 1035
1023 /* Reset if the reset-gpios is available otherwise the board 1036 /* Reset if the reset-gpios is available otherwise the board
1024 * -level design should be guaranteed. 1037 * -level design should be guaranteed.
@@ -1068,8 +1081,10 @@ static void btmtkuart_remove(struct serdev_device *serdev)
1068 struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); 1081 struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
1069 struct hci_dev *hdev = bdev->hdev; 1082 struct hci_dev *hdev = bdev->hdev;
1070 1083
1071 if (btmtkuart_is_standalone(bdev)) 1084 if (btmtkuart_is_standalone(bdev)) {
1072 regulator_disable(bdev->vcc); 1085 regulator_disable(bdev->vcc);
1086 clk_disable_unprepare(bdev->osc);
1087 }
1073 1088
1074 hci_unregister_dev(hdev); 1089 hci_unregister_dev(hdev);
1075 hci_free_dev(hdev); 1090 hci_free_dev(hdev);