diff options
author | Abhishek Pandit-Subedi <abhishekpandit@chromium.org> | 2019-11-26 08:17:30 +0100 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2020-07-10 17:48:18 +0900 |
commit | ee02e9fc57a1b624f59d18cdf7ef9e729c479789 (patch) | |
tree | 773ed57bfc850a53b1ab3474d2e53a06d0bf1de9 | |
parent | 07bd7ab686f5032f237e1504126a95789826af7b (diff) | |
download | linux-rpi-ee02e9fc57a1b624f59d18cdf7ef9e729c479789.tar.gz linux-rpi-ee02e9fc57a1b624f59d18cdf7ef9e729c479789.tar.bz2 linux-rpi-ee02e9fc57a1b624f59d18cdf7ef9e729c479789.zip |
Bluetooth: btbcm: Support pcm configuration
commit 528379902337102b0264fe5343eafb3d6c59fa45 upstream.
Add BCM vendor specific command to configure PCM parameters. The new
vendor opcode allows us to set the sco routing, the pcm interface rate,
and a few other pcm specific options (frame sync, sync mode, and clock
mode). See broadcom-bluetooth.txt in Documentation for more information
about valid values for those settings.
Here is an example trace where this opcode was used to configure
a BCM4354:
< HCI Command: Vendor (0x3f|0x001c) plen 5
01 02 00 01 01
> HCI Event: Command Complete (0x0e) plen 4
Vendor (0x3f|0x001c) ncmd 1
Status: Success (0x00)
We can read back the values as well with ocf 0x001d to confirm the
values that were set:
$ hcitool cmd 0x3f 0x001d
< HCI Command: ogf 0x3f, ocf 0x001d, plen 0
> HCI Event: 0x0e plen 9
01 1D FC 00 01 02 00 01 01
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r-- | drivers/bluetooth/btbcm.c | 46 | ||||
-rw-r--r-- | drivers/bluetooth/btbcm.h | 16 |
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 15b7cafde0f7..5b0f8a0b87f2 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -105,6 +105,52 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) } EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); +int btbcm_read_pcm_int_params(struct hci_dev *hdev, + struct bcm_set_pcm_int_params *params) +{ + struct sk_buff *skb; + int err = 0; + + skb = __hci_cmd_sync(hdev, 0xfc1d, 0, NULL, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "BCM: Read PCM int params failed (%d)", err); + return err; + } + + if (skb->len != 6 || skb->data[0]) { + bt_dev_err(hdev, "BCM: Read PCM int params length mismatch"); + kfree_skb(skb); + return -EIO; + } + + if (params) + memcpy(params, skb->data + 1, 5); + + kfree_skb(skb); + + return 0; +} +EXPORT_SYMBOL_GPL(btbcm_read_pcm_int_params); + +int btbcm_write_pcm_int_params(struct hci_dev *hdev, + const struct bcm_set_pcm_int_params *params) +{ + struct sk_buff *skb; + int err; + + skb = __hci_cmd_sync(hdev, 0xfc1c, 5, params, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "BCM: Write PCM int params failed (%d)", err); + return err; + } + kfree_skb(skb); + + return 0; +} +EXPORT_SYMBOL_GPL(btbcm_write_pcm_int_params); + int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) { const struct hci_command_hdr *cmd; diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index d204be8a84bf..3c7dd0765837 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h @@ -54,6 +54,10 @@ struct bcm_set_pcm_format_params { int btbcm_check_bdaddr(struct hci_dev *hdev); int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw); +int btbcm_read_pcm_int_params(struct hci_dev *hdev, + struct bcm_set_pcm_int_params *params); +int btbcm_write_pcm_int_params(struct hci_dev *hdev, + const struct bcm_set_pcm_int_params *params); int btbcm_setup_patchram(struct hci_dev *hdev); int btbcm_setup_apple(struct hci_dev *hdev); @@ -74,6 +78,18 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) return -EOPNOTSUPP; } +int btbcm_read_pcm_int_params(struct hci_dev *hdev, + struct bcm_set_pcm_int_params *params) +{ + return -EOPNOTSUPP; +} + +int btbcm_write_pcm_int_params(struct hci_dev *hdev, + const struct bcm_set_pcm_int_params *params) +{ + return -EOPNOTSUPP; +} + static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) { return -EOPNOTSUPP; |