diff options
author | Sean Wang <sean.wang@mediatek.com> | 2019-06-01 21:04:17 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2019-07-06 07:00:04 -0400 |
commit | 055825614c6b4da8c931fe1dea2f2920553f7a67 (patch) | |
tree | 9afaece4ec99d4278dcf364bc2a17ffe480ced02 /drivers/bluetooth | |
parent | a3cb6d602a7a948f0b4ff77b6a087f9c25038d52 (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.c | 21 |
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 { | |||
115 | struct btmtkuart_dev { | 115 | struct 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); |