BCM chips may require configuration of PCM to operate correctly and there is a vendor specific HCI command to do this. Add support in the hci_bcm driver to parse this from devicetree and configure the chip. Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@xxxxxxxxxxxx> --- drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 4fe66e52927d..e94908a7e407 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -79,6 +79,7 @@ * @hu: pointer to HCI UART controller struct, * used to disable flow control during runtime suspend and system sleep * @is_suspended: whether flow control is currently disabled + * @pcm_params: Bytestring of pcm int and format params. */ struct bcm_device { /* Must be the first member, hci_serdev.c expects this. */ @@ -112,6 +113,9 @@ struct bcm_device { struct hci_uart *hu; bool is_suspended; #endif + + bool has_pcm_params; + u8 pcm_params[BCM_PCM_PARAMS_COUNT]; }; /* generic bcm uart resources */ @@ -529,6 +533,8 @@ static int bcm_setup(struct hci_uart *hu) const struct firmware *fw; unsigned int speed; int err; + struct bcm_set_pcm_int_params int_params; + struct bcm_set_pcm_format_params format_params; bt_dev_dbg(hu->hdev, "hu %p", hu); @@ -576,6 +582,23 @@ static int bcm_setup(struct hci_uart *hu) host_set_baudrate(hu, speed); } + /* PCM parameters if any*/ + if (bcm->dev && bcm->dev->has_pcm_params) { + memcpy(&int_params, &(bcm->dev->pcm_params[0]), + sizeof(int_params)); + memcpy(&format_params, &(bcm->dev->pcm_params[5]), + sizeof(format_params)); + + err = btbcm_set_pcm_params(hu->hdev, &int_params, + &format_params); + + if (err) { + bt_dev_info(hu->hdev, "BCM: Set pcm params failed (%d)", + err); + } + + } + finalize: release_firmware(fw); @@ -1112,7 +1135,15 @@ static int bcm_acpi_probe(struct bcm_device *dev) static int bcm_of_probe(struct bcm_device *bdev) { + int plen; + device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed); + plen = device_property_read_u8_array(bdev->dev, "pcm-parameters", + bdev->pcm_params, + BCM_PCM_PARAMS_COUNT); + if (plen == 0) + bdev->has_pcm_params = true; + return 0; } -- 2.24.0.rc1.363.gb1bccd3e3d-goog