Bluetooth: hci_qca: Load customized NVM based on the device property

QCA BTSOC NVM is a customized firmware file and different vendors may
want to have different BTSOC configuration (e.g. Configure SCO over PCM
or I2S, Setting Tx power, etc.) via this file. This patch will allow
vendors to download different NVM firmware file by reading a device
property "firmware-name".

Signed-off-by: Rocky Liao <rjliao@codeaurora.org>
Tested-by: Harish Bandi <c-hbandi@codeaurora.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Rocky Liao
2019-06-06 17:40:30 +08:00
committad av Marcel Holtmann
förälder be70e5e774
incheckning 99c905c6a1
3 ändrade filer med 27 tillägg och 5 borttagningar

Visa fil

@@ -159,6 +159,7 @@ struct qca_serdev {
struct qca_power *bt_power;
u32 init_speed;
u32 oper_speed;
const char *firmware_name;
};
static int qca_power_setup(struct hci_uart *hu, bool on);
@@ -180,6 +181,17 @@ static enum qca_btsoc_type qca_soc_type(struct hci_uart *hu)
return soc_type;
}
static const char *qca_get_firmware_name(struct hci_uart *hu)
{
if (hu->serdev) {
struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
return qsd->firmware_name;
} else {
return NULL;
}
}
static void __serial_clock_on(struct tty_struct *tty)
{
/* TODO: Some chipset requires to enable UART clock on client
@@ -1235,6 +1247,7 @@ static int qca_setup(struct hci_uart *hu)
struct qca_data *qca = hu->priv;
unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
const char *firmware_name = qca_get_firmware_name(hu);
int ret;
int soc_ver = 0;
@@ -1285,7 +1298,8 @@ static int qca_setup(struct hci_uart *hu)
bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
/* Setup patch / NVM configurations */
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver);
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
firmware_name);
if (!ret) {
set_bit(QCA_IBS_ENABLED, &qca->flags);
qca_debugfs_init(hdev);
@@ -1479,6 +1493,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
qcadev->serdev_hu.serdev = serdev;
data = of_device_get_match_data(&serdev->dev);
serdev_device_set_drvdata(serdev, qcadev);
device_property_read_string(&serdev->dev, "firmware-name",
&qcadev->firmware_name);
if (data && qca_is_wcn399x(data->soc_type)) {
qcadev->btsoc_type = data->soc_type;
qcadev->bt_power = devm_kzalloc(&serdev->dev,