Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Bing Zhao and committed by
Gustavo Padovan
433a9389 3e4543ab

+18 -89
-4
drivers/bluetooth/btmrvl_drv.h
··· 23 23 #include <linux/bitops.h> 24 24 #include <linux/slab.h> 25 25 #include <net/bluetooth/bluetooth.h> 26 - #include <linux/ctype.h> 27 - #include <linux/firmware.h> 28 26 29 27 #define BTM_HEADER_LEN 4 30 28 #define BTM_UPLD_SIZE 2312 ··· 41 43 struct btmrvl_device { 42 44 void *card; 43 45 struct hci_dev *hcidev; 44 - struct device *dev; 45 - const char *cal_data; 46 46 47 47 u8 dev_type; 48 48
+17 -75
drivers/bluetooth/btmrvl_main.c
··· 19 19 **/ 20 20 21 21 #include <linux/module.h> 22 - 22 + #include <linux/of.h> 23 23 #include <net/bluetooth/bluetooth.h> 24 24 #include <net/bluetooth/hci_core.h> 25 25 ··· 414 414 return 0; 415 415 } 416 416 417 - /* 418 - * This function parses provided calibration data input. It should contain 419 - * hex bytes separated by space or new line character. Here is an example. 420 - * 00 1C 01 37 FF FF FF FF 02 04 7F 01 421 - * CE BA 00 00 00 2D C6 C0 00 00 00 00 422 - * 00 F0 00 00 423 - */ 424 - static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size) 425 - { 426 - const u8 *s = src; 427 - u8 *d = dst; 428 - int ret; 429 - u8 tmp[3]; 430 - 431 - tmp[2] = '\0'; 432 - while ((s - src) <= len - 2) { 433 - if (isspace(*s)) { 434 - s++; 435 - continue; 436 - } 437 - 438 - if (isxdigit(*s)) { 439 - if ((d - dst) >= dst_size) { 440 - BT_ERR("calibration data file too big!!!"); 441 - return -EINVAL; 442 - } 443 - 444 - memcpy(tmp, s, 2); 445 - 446 - ret = kstrtou8(tmp, 16, d++); 447 - if (ret < 0) 448 - return ret; 449 - 450 - s += 2; 451 - } else { 452 - return -EINVAL; 453 - } 454 - } 455 - if (d == dst) 456 - return -EINVAL; 457 - 458 - return 0; 459 - } 460 - 461 - static int btmrvl_load_cal_data(struct btmrvl_private *priv, 462 - u8 *config_data) 417 + static int btmrvl_download_cal_data(struct btmrvl_private *priv, 418 + u8 *config_data) 463 419 { 464 420 int i, ret; 465 421 u8 data[BT_CMD_DATA_SIZE]; ··· 443 487 return 0; 444 488 } 445 489 446 - static int 447 - btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size) 490 + static int btmrvl_cal_data_dt(struct btmrvl_private *priv) 448 491 { 492 + struct device_node *dt_node; 449 493 u8 cal_data[BT_CAL_DATA_SIZE]; 494 + const char name[] = "btmrvl_caldata"; 495 + const char property[] = "btmrvl,caldata"; 450 496 int ret; 451 497 452 - ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data)); 498 + dt_node = of_find_node_by_name(NULL, name); 499 + if (!dt_node) 500 + return -ENODEV; 501 + 502 + ret = of_property_read_u8_array(dt_node, property, cal_data, 503 + sizeof(cal_data)); 453 504 if (ret) 454 505 return ret; 455 506 456 - ret = btmrvl_load_cal_data(priv, cal_data); 507 + BT_DBG("Use cal data from device tree"); 508 + ret = btmrvl_download_cal_data(priv, cal_data); 457 509 if (ret) { 458 - BT_ERR("Fail to load calibrate data"); 510 + BT_ERR("Fail to download calibrate data"); 459 511 return ret; 460 512 } 461 513 462 514 return 0; 463 - } 464 - 465 - static int btmrvl_cal_data_config(struct btmrvl_private *priv) 466 - { 467 - const struct firmware *cfg; 468 - int ret; 469 - const char *cal_data = priv->btmrvl_dev.cal_data; 470 - 471 - if (!cal_data) 472 - return 0; 473 - 474 - ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev); 475 - if (ret < 0) { 476 - BT_DBG("Failed to get %s file, skipping cal data download", 477 - cal_data); 478 - return 0; 479 - } 480 - 481 - ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size); 482 - release_firmware(cfg); 483 - return ret; 484 515 } 485 516 486 517 static int btmrvl_setup(struct hci_dev *hdev) ··· 476 533 477 534 btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); 478 535 479 - if (btmrvl_cal_data_config(priv)) 480 - BT_ERR("Set cal data failed"); 536 + btmrvl_cal_data_dt(priv); 481 537 482 538 priv->btmrvl_dev.psmode = 1; 483 539 btmrvl_enable_ps(priv);
+1 -8
drivers/bluetooth/btmrvl_sdio.c
··· 18 18 * this warranty disclaimer. 19 19 **/ 20 20 21 + #include <linux/firmware.h> 21 22 #include <linux/slab.h> 22 23 23 24 #include <linux/mmc/sdio_ids.h> ··· 102 101 static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { 103 102 .helper = "mrvl/sd8688_helper.bin", 104 103 .firmware = "mrvl/sd8688.bin", 105 - .cal_data = NULL, 106 104 .reg = &btmrvl_reg_8688, 107 105 .sd_blksz_fw_dl = 64, 108 106 }; ··· 109 109 static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { 110 110 .helper = NULL, 111 111 .firmware = "mrvl/sd8787_uapsta.bin", 112 - .cal_data = NULL, 113 112 .reg = &btmrvl_reg_87xx, 114 113 .sd_blksz_fw_dl = 256, 115 114 }; ··· 116 117 static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { 117 118 .helper = NULL, 118 119 .firmware = "mrvl/sd8797_uapsta.bin", 119 - .cal_data = "mrvl/sd8797_caldata.conf", 120 120 .reg = &btmrvl_reg_87xx, 121 121 .sd_blksz_fw_dl = 256, 122 122 }; ··· 123 125 static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { 124 126 .helper = NULL, 125 127 .firmware = "mrvl/sd8897_uapsta.bin", 126 - .cal_data = NULL, 127 128 .reg = &btmrvl_reg_88xx, 128 129 .sd_blksz_fw_dl = 256, 129 130 }; ··· 1004 1007 struct btmrvl_sdio_device *data = (void *) id->driver_data; 1005 1008 card->helper = data->helper; 1006 1009 card->firmware = data->firmware; 1007 - card->cal_data = data->cal_data; 1008 1010 card->reg = data->reg; 1009 1011 card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; 1010 1012 } ··· 1032 1036 } 1033 1037 1034 1038 card->priv = priv; 1035 - priv->btmrvl_dev.dev = &card->func->dev; 1036 - priv->btmrvl_dev.cal_data = card->cal_data; 1037 1039 1038 1040 /* Initialize the interface specific function pointers */ 1039 1041 priv->hw_host_to_card = btmrvl_sdio_host_to_card; ··· 1214 1220 MODULE_FIRMWARE("mrvl/sd8688.bin"); 1215 1221 MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); 1216 1222 MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); 1217 - MODULE_FIRMWARE("mrvl/sd8797_caldata.conf"); 1218 1223 MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
-2
drivers/bluetooth/btmrvl_sdio.h
··· 85 85 u32 ioport; 86 86 const char *helper; 87 87 const char *firmware; 88 - const char *cal_data; 89 88 const struct btmrvl_sdio_card_reg *reg; 90 89 u16 sd_blksz_fw_dl; 91 90 u8 rx_unit; ··· 94 95 struct btmrvl_sdio_device { 95 96 const char *helper; 96 97 const char *firmware; 97 - const char *cal_data; 98 98 const struct btmrvl_sdio_card_reg *reg; 99 99 u16 sd_blksz_fw_dl; 100 100 };