mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
Bluetooth: btmrvl: use cal-data from device-tree instead of conf file
Some ARM versions of Chromebook need to download a new calibration data from host driver to firmware. They do have EEPROM but still need a piece of new calibration data in test mode. The cal-data is platform dependent. It's simpler and more feasible to use device tree based cal-data instead of configuration file based cal-data. This patch remove configuration file based cal-data downloading and replace it using cal-data from device tree. When CONFIG_OF is not selected, or the specific property is not present in the device tree, the calibration downloading will not happen. Cc: Mike Frysinger <vapier@chromium.org> Cc: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: Hyuckjoo Lee <hyuckjoo.lee@samsung.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
3e4543abf9
commit
433a9389a1
@ -23,8 +23,6 @@
|
|||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <linux/ctype.h>
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
|
|
||||||
#define BTM_HEADER_LEN 4
|
#define BTM_HEADER_LEN 4
|
||||||
#define BTM_UPLD_SIZE 2312
|
#define BTM_UPLD_SIZE 2312
|
||||||
@ -43,8 +41,6 @@ struct btmrvl_thread {
|
|||||||
struct btmrvl_device {
|
struct btmrvl_device {
|
||||||
void *card;
|
void *card;
|
||||||
struct hci_dev *hcidev;
|
struct hci_dev *hcidev;
|
||||||
struct device *dev;
|
|
||||||
const char *cal_data;
|
|
||||||
|
|
||||||
u8 dev_type;
|
u8 dev_type;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
@ -414,52 +414,8 @@ static int btmrvl_open(struct hci_dev *hdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int btmrvl_download_cal_data(struct btmrvl_private *priv,
|
||||||
* This function parses provided calibration data input. It should contain
|
u8 *config_data)
|
||||||
* hex bytes separated by space or new line character. Here is an example.
|
|
||||||
* 00 1C 01 37 FF FF FF FF 02 04 7F 01
|
|
||||||
* CE BA 00 00 00 2D C6 C0 00 00 00 00
|
|
||||||
* 00 F0 00 00
|
|
||||||
*/
|
|
||||||
static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
|
|
||||||
{
|
|
||||||
const u8 *s = src;
|
|
||||||
u8 *d = dst;
|
|
||||||
int ret;
|
|
||||||
u8 tmp[3];
|
|
||||||
|
|
||||||
tmp[2] = '\0';
|
|
||||||
while ((s - src) <= len - 2) {
|
|
||||||
if (isspace(*s)) {
|
|
||||||
s++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isxdigit(*s)) {
|
|
||||||
if ((d - dst) >= dst_size) {
|
|
||||||
BT_ERR("calibration data file too big!!!");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(tmp, s, 2);
|
|
||||||
|
|
||||||
ret = kstrtou8(tmp, 16, d++);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
s += 2;
|
|
||||||
} else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (d == dst)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int btmrvl_load_cal_data(struct btmrvl_private *priv,
|
|
||||||
u8 *config_data)
|
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
u8 data[BT_CMD_DATA_SIZE];
|
u8 data[BT_CMD_DATA_SIZE];
|
||||||
@ -487,54 +443,40 @@ static int btmrvl_load_cal_data(struct btmrvl_private *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
|
||||||
btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
|
|
||||||
{
|
{
|
||||||
|
struct device_node *dt_node;
|
||||||
u8 cal_data[BT_CAL_DATA_SIZE];
|
u8 cal_data[BT_CAL_DATA_SIZE];
|
||||||
|
const char name[] = "btmrvl_caldata";
|
||||||
|
const char property[] = "btmrvl,caldata";
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
|
dt_node = of_find_node_by_name(NULL, name);
|
||||||
|
if (!dt_node)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = of_property_read_u8_array(dt_node, property, cal_data,
|
||||||
|
sizeof(cal_data));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = btmrvl_load_cal_data(priv, cal_data);
|
BT_DBG("Use cal data from device tree");
|
||||||
|
ret = btmrvl_download_cal_data(priv, cal_data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
BT_ERR("Fail to load calibrate data");
|
BT_ERR("Fail to download calibrate data");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btmrvl_cal_data_config(struct btmrvl_private *priv)
|
|
||||||
{
|
|
||||||
const struct firmware *cfg;
|
|
||||||
int ret;
|
|
||||||
const char *cal_data = priv->btmrvl_dev.cal_data;
|
|
||||||
|
|
||||||
if (!cal_data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
|
|
||||||
if (ret < 0) {
|
|
||||||
BT_DBG("Failed to get %s file, skipping cal data download",
|
|
||||||
cal_data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
|
|
||||||
release_firmware(cfg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int btmrvl_setup(struct hci_dev *hdev)
|
static int btmrvl_setup(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
struct btmrvl_private *priv = hci_get_drvdata(hdev);
|
struct btmrvl_private *priv = hci_get_drvdata(hdev);
|
||||||
|
|
||||||
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
|
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
|
||||||
|
|
||||||
if (btmrvl_cal_data_config(priv))
|
btmrvl_cal_data_dt(priv);
|
||||||
BT_ERR("Set cal data failed");
|
|
||||||
|
|
||||||
priv->btmrvl_dev.psmode = 1;
|
priv->btmrvl_dev.psmode = 1;
|
||||||
btmrvl_enable_ps(priv);
|
btmrvl_enable_ps(priv);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
* this warranty disclaimer.
|
* this warranty disclaimer.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <linux/firmware.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <linux/mmc/sdio_ids.h>
|
#include <linux/mmc/sdio_ids.h>
|
||||||
@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
|
|||||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
||||||
.helper = "mrvl/sd8688_helper.bin",
|
.helper = "mrvl/sd8688_helper.bin",
|
||||||
.firmware = "mrvl/sd8688.bin",
|
.firmware = "mrvl/sd8688.bin",
|
||||||
.cal_data = NULL,
|
|
||||||
.reg = &btmrvl_reg_8688,
|
.reg = &btmrvl_reg_8688,
|
||||||
.sd_blksz_fw_dl = 64,
|
.sd_blksz_fw_dl = 64,
|
||||||
};
|
};
|
||||||
@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
|||||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
|
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
|
||||||
.helper = NULL,
|
.helper = NULL,
|
||||||
.firmware = "mrvl/sd8787_uapsta.bin",
|
.firmware = "mrvl/sd8787_uapsta.bin",
|
||||||
.cal_data = NULL,
|
|
||||||
.reg = &btmrvl_reg_87xx,
|
.reg = &btmrvl_reg_87xx,
|
||||||
.sd_blksz_fw_dl = 256,
|
.sd_blksz_fw_dl = 256,
|
||||||
};
|
};
|
||||||
@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
|
|||||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
|
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
|
||||||
.helper = NULL,
|
.helper = NULL,
|
||||||
.firmware = "mrvl/sd8797_uapsta.bin",
|
.firmware = "mrvl/sd8797_uapsta.bin",
|
||||||
.cal_data = "mrvl/sd8797_caldata.conf",
|
|
||||||
.reg = &btmrvl_reg_87xx,
|
.reg = &btmrvl_reg_87xx,
|
||||||
.sd_blksz_fw_dl = 256,
|
.sd_blksz_fw_dl = 256,
|
||||||
};
|
};
|
||||||
@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
|
|||||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
|
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
|
||||||
.helper = NULL,
|
.helper = NULL,
|
||||||
.firmware = "mrvl/sd8897_uapsta.bin",
|
.firmware = "mrvl/sd8897_uapsta.bin",
|
||||||
.cal_data = NULL,
|
|
||||||
.reg = &btmrvl_reg_88xx,
|
.reg = &btmrvl_reg_88xx,
|
||||||
.sd_blksz_fw_dl = 256,
|
.sd_blksz_fw_dl = 256,
|
||||||
};
|
};
|
||||||
@ -1007,7 +1004,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
|
|||||||
struct btmrvl_sdio_device *data = (void *) id->driver_data;
|
struct btmrvl_sdio_device *data = (void *) id->driver_data;
|
||||||
card->helper = data->helper;
|
card->helper = data->helper;
|
||||||
card->firmware = data->firmware;
|
card->firmware = data->firmware;
|
||||||
card->cal_data = data->cal_data;
|
|
||||||
card->reg = data->reg;
|
card->reg = data->reg;
|
||||||
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
|
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
|
||||||
}
|
}
|
||||||
@ -1036,8 +1032,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
|
|||||||
}
|
}
|
||||||
|
|
||||||
card->priv = priv;
|
card->priv = priv;
|
||||||
priv->btmrvl_dev.dev = &card->func->dev;
|
|
||||||
priv->btmrvl_dev.cal_data = card->cal_data;
|
|
||||||
|
|
||||||
/* Initialize the interface specific function pointers */
|
/* Initialize the interface specific function pointers */
|
||||||
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
|
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
|
||||||
@ -1220,5 +1214,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
|
|||||||
MODULE_FIRMWARE("mrvl/sd8688.bin");
|
MODULE_FIRMWARE("mrvl/sd8688.bin");
|
||||||
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
||||||
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
|
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
|
||||||
MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
|
|
||||||
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
|
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
|
||||||
|
@ -85,7 +85,6 @@ struct btmrvl_sdio_card {
|
|||||||
u32 ioport;
|
u32 ioport;
|
||||||
const char *helper;
|
const char *helper;
|
||||||
const char *firmware;
|
const char *firmware;
|
||||||
const char *cal_data;
|
|
||||||
const struct btmrvl_sdio_card_reg *reg;
|
const struct btmrvl_sdio_card_reg *reg;
|
||||||
u16 sd_blksz_fw_dl;
|
u16 sd_blksz_fw_dl;
|
||||||
u8 rx_unit;
|
u8 rx_unit;
|
||||||
@ -95,7 +94,6 @@ struct btmrvl_sdio_card {
|
|||||||
struct btmrvl_sdio_device {
|
struct btmrvl_sdio_device {
|
||||||
const char *helper;
|
const char *helper;
|
||||||
const char *firmware;
|
const char *firmware;
|
||||||
const char *cal_data;
|
|
||||||
const struct btmrvl_sdio_card_reg *reg;
|
const struct btmrvl_sdio_card_reg *reg;
|
||||||
u16 sd_blksz_fw_dl;
|
u16 sd_blksz_fw_dl;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user