summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_ll.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/hci_ll.c')
-rw-r--r--drivers/bluetooth/hci_ll.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index adc444f309a3..c982943f0747 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -48,6 +48,7 @@
#include <linux/serdev.h>
#include <linux/skbuff.h>
#include <linux/ti_wilink_st.h>
+#include <linux/clk.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -84,6 +85,7 @@ struct ll_device {
struct hci_uart hu;
struct serdev_device *serdev;
struct gpio_desc *enable_gpio;
+ struct clk *ext_clk;
};
struct ll_struct {
@@ -118,7 +120,7 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
}
/* prepare packet */
- hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
+ hcill_packet = skb_put(skb, 1);
hcill_packet->cmd = cmd;
/* send packet */
@@ -146,8 +148,12 @@ static int ll_open(struct hci_uart *hu)
hu->priv = ll;
- if (hu->serdev)
+ if (hu->serdev) {
+ struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
serdev_device_open(hu->serdev);
+ if (!IS_ERR(lldev->ext_clk))
+ clk_prepare_enable(lldev->ext_clk);
+ }
return 0;
}
@@ -181,6 +187,8 @@ static int ll_close(struct hci_uart *hu)
struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
gpiod_set_value_cansleep(lldev->enable_gpio, 0);
+ clk_disable_unprepare(lldev->ext_clk);
+
serdev_device_close(hu->serdev);
}
@@ -405,7 +413,7 @@ static int ll_recv(struct hci_uart *hu, const void *data, int count)
while (count) {
if (ll->rx_count) {
len = min_t(unsigned int, ll->rx_count, count);
- memcpy(skb_put(ll->rx_skb, len), ptr, len);
+ skb_put_data(ll->rx_skb, ptr, len);
ll->rx_count -= len; count -= len; ptr += len;
if (ll->rx_count)
@@ -624,6 +632,7 @@ static int download_firmware(struct ll_device *lldev)
skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
bt_dev_err(lldev->hu.hdev, "send command failed\n");
+ err = PTR_ERR(skb);
goto out_rel_fw;
}
kfree_skb(skb);
@@ -720,6 +729,10 @@ static int hci_ti_probe(struct serdev_device *serdev)
if (IS_ERR(lldev->enable_gpio))
return PTR_ERR(lldev->enable_gpio);
+ lldev->ext_clk = devm_clk_get(&serdev->dev, "ext_clock");
+ if (IS_ERR(lldev->ext_clk) && PTR_ERR(lldev->ext_clk) != -ENOENT)
+ return PTR_ERR(lldev->ext_clk);
+
of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed);
hci_uart_set_speeds(hu, 115200, max_speed);
@@ -740,6 +753,14 @@ static void hci_ti_remove(struct serdev_device *serdev)
}
static const struct of_device_id hci_ti_of_match[] = {
+ { .compatible = "ti,wl1271-st" },
+ { .compatible = "ti,wl1273-st" },
+ { .compatible = "ti,wl1281-st" },
+ { .compatible = "ti,wl1283-st" },
+ { .compatible = "ti,wl1285-st" },
+ { .compatible = "ti,wl1801-st" },
+ { .compatible = "ti,wl1805-st" },
+ { .compatible = "ti,wl1807-st" },
{ .compatible = "ti,wl1831-st" },
{ .compatible = "ti,wl1835-st" },
{ .compatible = "ti,wl1837-st" },