Loading drivers/bluetooth/ath3k.c +4 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x300b) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE005) }, { USB_DEVICE(0x0CF3, 0xE005) }, Loading @@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x0cf3, 0x3121) }, { USB_DEVICE(0x0cf3, 0x3121) }, { USB_DEVICE(0x0cf3, 0xe003) }, { USB_DEVICE(0x0cf3, 0xe003) }, { USB_DEVICE(0x0489, 0xe05f) }, /* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, { USB_DEVICE(0x0489, 0xE02C) }, Loading Loading @@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, Loading @@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, Loading drivers/bluetooth/btmrvl_drv.h +12 −13 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -90,12 +86,12 @@ struct btmrvl_private { #define MRVL_VENDOR_PKT 0xFE #define MRVL_VENDOR_PKT 0xFE /* Bluetooth commands */ /* Vendor specific Bluetooth commands */ #define BT_CMD_AUTO_SLEEP_MODE 0x23 #define BT_CMD_AUTO_SLEEP_MODE 0xFC23 #define BT_CMD_HOST_SLEEP_CONFIG 0x59 #define BT_CMD_HOST_SLEEP_CONFIG 0xFC59 #define BT_CMD_HOST_SLEEP_ENABLE 0x5A #define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A #define BT_CMD_MODULE_CFG_REQ 0x5B #define BT_CMD_MODULE_CFG_REQ 0xFC5B #define BT_CMD_LOAD_CONFIG_DATA 0x61 #define BT_CMD_LOAD_CONFIG_DATA 0xFC61 /* Sub-commands: Module Bringup/Shutdown Request/Response */ /* Sub-commands: Module Bringup/Shutdown Request/Response */ #define MODULE_BRINGUP_REQ 0xF1 #define MODULE_BRINGUP_REQ 0xF1 Loading @@ -104,6 +100,11 @@ struct btmrvl_private { #define MODULE_SHUTDOWN_REQ 0xF2 #define MODULE_SHUTDOWN_REQ 0xF2 /* Vendor specific Bluetooth events */ #define BT_EVENT_AUTO_SLEEP_MODE 0x23 #define BT_EVENT_HOST_SLEEP_CONFIG 0x59 #define BT_EVENT_HOST_SLEEP_ENABLE 0x5A #define BT_EVENT_MODULE_CFG_REQ 0x5B #define BT_EVENT_POWER_STATE 0x20 #define BT_EVENT_POWER_STATE 0x20 /* Bluetooth Power States */ /* Bluetooth Power States */ Loading @@ -111,8 +112,6 @@ struct btmrvl_private { #define BT_PS_DISABLE 0x03 #define BT_PS_DISABLE 0x03 #define BT_PS_SLEEP 0x01 #define BT_PS_SLEEP 0x01 #define OGF 0x3F /* Host Sleep states */ /* Host Sleep states */ #define HS_ACTIVATED 0x01 #define HS_ACTIVATED 0x01 #define HS_DEACTIVATED 0x00 #define HS_DEACTIVATED 0x00 Loading @@ -121,7 +120,7 @@ struct btmrvl_private { #define PS_SLEEP 0x01 #define PS_SLEEP 0x01 #define PS_AWAKE 0x00 #define PS_AWAKE 0x00 #define BT_CMD_DATA_SIZE 32 #define BT_CAL_HDR_LEN 4 #define BT_CAL_DATA_SIZE 28 #define BT_CAL_DATA_SIZE 28 struct btmrvl_event { struct btmrvl_event { Loading drivers/bluetooth/btmrvl_main.c +31 −99 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) if (hdr->evt == HCI_EV_CMD_COMPLETE) { if (hdr->evt == HCI_EV_CMD_COMPLETE) { struct hci_ev_cmd_complete *ec; struct hci_ev_cmd_complete *ec; u16 opcode, ocf, ogf; u16 opcode; ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); ogf = hci_opcode_ogf(opcode); if (priv->btmrvl_dev.sendcmdflag) { if (priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->btmrvl_dev.sendcmdflag = false; Loading @@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) wake_up_interruptible(&priv->adapter->cmd_wait_q); wake_up_interruptible(&priv->adapter->cmd_wait_q); } } if (ogf == OGF) { if (hci_opcode_ogf(opcode) == 0x3F) { BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x", BT_DBG("vendor event skipped: opcode=%#4.4x", opcode); ogf, ocf); kfree_skb(skb); kfree_skb(skb); return false; return false; } } Loading @@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } switch (event->data[0]) { switch (event->data[0]) { case BT_CMD_AUTO_SLEEP_MODE: case BT_EVENT_AUTO_SLEEP_MODE: if (!event->data[2]) { if (!event->data[2]) { if (event->data[1] == BT_PS_ENABLE) if (event->data[1] == BT_PS_ENABLE) adapter->psmode = 1; adapter->psmode = 1; Loading @@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } break; break; case BT_CMD_HOST_SLEEP_CONFIG: case BT_EVENT_HOST_SLEEP_CONFIG: if (!event->data[3]) if (!event->data[3]) BT_DBG("gpio=%x, gap=%x", event->data[1], BT_DBG("gpio=%x, gap=%x", event->data[1], event->data[2]); event->data[2]); Loading @@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) BT_DBG("HSCFG command failed"); BT_DBG("HSCFG command failed"); break; break; case BT_CMD_HOST_SLEEP_ENABLE: case BT_EVENT_HOST_SLEEP_ENABLE: if (!event->data[1]) { if (!event->data[1]) { adapter->hs_state = HS_ACTIVATED; adapter->hs_state = HS_ACTIVATED; if (adapter->psmode) if (adapter->psmode) Loading @@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } break; break; case BT_CMD_MODULE_CFG_REQ: case BT_EVENT_MODULE_CFG_REQ: if (priv->btmrvl_dev.sendcmdflag && if (priv->btmrvl_dev.sendcmdflag && event->data[1] == MODULE_BRINGUP_REQ) { event->data[1] == MODULE_BRINGUP_REQ) { BT_DBG("EVENT:%s", BT_DBG("EVENT:%s", Loading Loading @@ -166,7 +163,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } EXPORT_SYMBOL_GPL(btmrvl_process_event); EXPORT_SYMBOL_GPL(btmrvl_process_event); static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode, const void *param, u8 len) const void *param, u8 len) { { struct sk_buff *skb; struct sk_buff *skb; Loading @@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, } } hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no)); hdr->opcode = cpu_to_le16(opcode); hdr->plen = len; hdr->plen = len; if (len) if (len) Loading Loading @@ -417,127 +414,62 @@ 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 *data, int len) * 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; 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; u8 data[BT_CMD_DATA_SIZE]; data[0] = 0x00; data[0] = 0x00; data[1] = 0x00; data[1] = 0x00; data[2] = 0x00; data[2] = 0x00; data[3] = BT_CMD_DATA_SIZE - 4; data[3] = len; /* Swap cal-data bytes. Each four bytes are swapped. Considering 4 * byte SDIO header offset, mapping of input and output bytes will be * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4}, * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */ for (i = 4; i < BT_CMD_DATA_SIZE; i++) data[i] = config_data[(i / 4) * 8 - 1 - i]; print_hex_dump_bytes("Calibration data: ", print_hex_dump_bytes("Calibration data: ", DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE); DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len); ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data, ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data, BT_CMD_DATA_SIZE); BT_CAL_HDR_LEN + len); if (ret) if (ret) BT_ERR("Failed to download caibration data\n"); BT_ERR("Failed to download caibration data\n"); 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) { { u8 cal_data[BT_CAL_DATA_SIZE]; struct device_node *dt_node; u8 cal_data[BT_CAL_HDR_LEN + 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 + BT_CAL_HDR_LEN, BT_CAL_DATA_SIZE); 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, BT_CAL_DATA_SIZE); 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); Loading drivers/bluetooth/btmrvl_sdio.c +1 −8 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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, }; }; Loading @@ -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, }; }; Loading @@ -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, }; }; Loading @@ -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, }; }; Loading Loading @@ -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; } } Loading Loading @@ -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; Loading Loading @@ -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"); drivers/bluetooth/btmrvl_sdio.h +0 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading
drivers/bluetooth/ath3k.c +4 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x300b) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE005) }, { USB_DEVICE(0x0CF3, 0xE005) }, Loading @@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x0cf3, 0x3121) }, { USB_DEVICE(0x0cf3, 0x3121) }, { USB_DEVICE(0x0cf3, 0xe003) }, { USB_DEVICE(0x0cf3, 0xe003) }, { USB_DEVICE(0x0489, 0xe05f) }, /* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, { USB_DEVICE(0x0489, 0xE02C) }, Loading Loading @@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, Loading @@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, Loading
drivers/bluetooth/btmrvl_drv.h +12 −13 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -90,12 +86,12 @@ struct btmrvl_private { #define MRVL_VENDOR_PKT 0xFE #define MRVL_VENDOR_PKT 0xFE /* Bluetooth commands */ /* Vendor specific Bluetooth commands */ #define BT_CMD_AUTO_SLEEP_MODE 0x23 #define BT_CMD_AUTO_SLEEP_MODE 0xFC23 #define BT_CMD_HOST_SLEEP_CONFIG 0x59 #define BT_CMD_HOST_SLEEP_CONFIG 0xFC59 #define BT_CMD_HOST_SLEEP_ENABLE 0x5A #define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A #define BT_CMD_MODULE_CFG_REQ 0x5B #define BT_CMD_MODULE_CFG_REQ 0xFC5B #define BT_CMD_LOAD_CONFIG_DATA 0x61 #define BT_CMD_LOAD_CONFIG_DATA 0xFC61 /* Sub-commands: Module Bringup/Shutdown Request/Response */ /* Sub-commands: Module Bringup/Shutdown Request/Response */ #define MODULE_BRINGUP_REQ 0xF1 #define MODULE_BRINGUP_REQ 0xF1 Loading @@ -104,6 +100,11 @@ struct btmrvl_private { #define MODULE_SHUTDOWN_REQ 0xF2 #define MODULE_SHUTDOWN_REQ 0xF2 /* Vendor specific Bluetooth events */ #define BT_EVENT_AUTO_SLEEP_MODE 0x23 #define BT_EVENT_HOST_SLEEP_CONFIG 0x59 #define BT_EVENT_HOST_SLEEP_ENABLE 0x5A #define BT_EVENT_MODULE_CFG_REQ 0x5B #define BT_EVENT_POWER_STATE 0x20 #define BT_EVENT_POWER_STATE 0x20 /* Bluetooth Power States */ /* Bluetooth Power States */ Loading @@ -111,8 +112,6 @@ struct btmrvl_private { #define BT_PS_DISABLE 0x03 #define BT_PS_DISABLE 0x03 #define BT_PS_SLEEP 0x01 #define BT_PS_SLEEP 0x01 #define OGF 0x3F /* Host Sleep states */ /* Host Sleep states */ #define HS_ACTIVATED 0x01 #define HS_ACTIVATED 0x01 #define HS_DEACTIVATED 0x00 #define HS_DEACTIVATED 0x00 Loading @@ -121,7 +120,7 @@ struct btmrvl_private { #define PS_SLEEP 0x01 #define PS_SLEEP 0x01 #define PS_AWAKE 0x00 #define PS_AWAKE 0x00 #define BT_CMD_DATA_SIZE 32 #define BT_CAL_HDR_LEN 4 #define BT_CAL_DATA_SIZE 28 #define BT_CAL_DATA_SIZE 28 struct btmrvl_event { struct btmrvl_event { Loading
drivers/bluetooth/btmrvl_main.c +31 −99 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) if (hdr->evt == HCI_EV_CMD_COMPLETE) { if (hdr->evt == HCI_EV_CMD_COMPLETE) { struct hci_ev_cmd_complete *ec; struct hci_ev_cmd_complete *ec; u16 opcode, ocf, ogf; u16 opcode; ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); ogf = hci_opcode_ogf(opcode); if (priv->btmrvl_dev.sendcmdflag) { if (priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->btmrvl_dev.sendcmdflag = false; Loading @@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) wake_up_interruptible(&priv->adapter->cmd_wait_q); wake_up_interruptible(&priv->adapter->cmd_wait_q); } } if (ogf == OGF) { if (hci_opcode_ogf(opcode) == 0x3F) { BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x", BT_DBG("vendor event skipped: opcode=%#4.4x", opcode); ogf, ocf); kfree_skb(skb); kfree_skb(skb); return false; return false; } } Loading @@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } switch (event->data[0]) { switch (event->data[0]) { case BT_CMD_AUTO_SLEEP_MODE: case BT_EVENT_AUTO_SLEEP_MODE: if (!event->data[2]) { if (!event->data[2]) { if (event->data[1] == BT_PS_ENABLE) if (event->data[1] == BT_PS_ENABLE) adapter->psmode = 1; adapter->psmode = 1; Loading @@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } break; break; case BT_CMD_HOST_SLEEP_CONFIG: case BT_EVENT_HOST_SLEEP_CONFIG: if (!event->data[3]) if (!event->data[3]) BT_DBG("gpio=%x, gap=%x", event->data[1], BT_DBG("gpio=%x, gap=%x", event->data[1], event->data[2]); event->data[2]); Loading @@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) BT_DBG("HSCFG command failed"); BT_DBG("HSCFG command failed"); break; break; case BT_CMD_HOST_SLEEP_ENABLE: case BT_EVENT_HOST_SLEEP_ENABLE: if (!event->data[1]) { if (!event->data[1]) { adapter->hs_state = HS_ACTIVATED; adapter->hs_state = HS_ACTIVATED; if (adapter->psmode) if (adapter->psmode) Loading @@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } break; break; case BT_CMD_MODULE_CFG_REQ: case BT_EVENT_MODULE_CFG_REQ: if (priv->btmrvl_dev.sendcmdflag && if (priv->btmrvl_dev.sendcmdflag && event->data[1] == MODULE_BRINGUP_REQ) { event->data[1] == MODULE_BRINGUP_REQ) { BT_DBG("EVENT:%s", BT_DBG("EVENT:%s", Loading Loading @@ -166,7 +163,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) } } EXPORT_SYMBOL_GPL(btmrvl_process_event); EXPORT_SYMBOL_GPL(btmrvl_process_event); static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode, const void *param, u8 len) const void *param, u8 len) { { struct sk_buff *skb; struct sk_buff *skb; Loading @@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, } } hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no)); hdr->opcode = cpu_to_le16(opcode); hdr->plen = len; hdr->plen = len; if (len) if (len) Loading Loading @@ -417,127 +414,62 @@ 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 *data, int len) * 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; 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; u8 data[BT_CMD_DATA_SIZE]; data[0] = 0x00; data[0] = 0x00; data[1] = 0x00; data[1] = 0x00; data[2] = 0x00; data[2] = 0x00; data[3] = BT_CMD_DATA_SIZE - 4; data[3] = len; /* Swap cal-data bytes. Each four bytes are swapped. Considering 4 * byte SDIO header offset, mapping of input and output bytes will be * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4}, * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */ for (i = 4; i < BT_CMD_DATA_SIZE; i++) data[i] = config_data[(i / 4) * 8 - 1 - i]; print_hex_dump_bytes("Calibration data: ", print_hex_dump_bytes("Calibration data: ", DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE); DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len); ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data, ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data, BT_CMD_DATA_SIZE); BT_CAL_HDR_LEN + len); if (ret) if (ret) BT_ERR("Failed to download caibration data\n"); BT_ERR("Failed to download caibration data\n"); 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) { { u8 cal_data[BT_CAL_DATA_SIZE]; struct device_node *dt_node; u8 cal_data[BT_CAL_HDR_LEN + 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 + BT_CAL_HDR_LEN, BT_CAL_DATA_SIZE); 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, BT_CAL_DATA_SIZE); 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); Loading
drivers/bluetooth/btmrvl_sdio.c +1 −8 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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, }; }; Loading @@ -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, }; }; Loading @@ -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, }; }; Loading @@ -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, }; }; Loading Loading @@ -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; } } Loading Loading @@ -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; Loading Loading @@ -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");
drivers/bluetooth/btmrvl_sdio.h +0 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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