aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btbcm.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-04-06 01:52:19 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-04-07 12:47:45 -0400
commit9a0bb57d2d08f1923aeef3af1877ec0b6f3209ba (patch)
treed9cf9701ddca6ec3af8d0519406c19a75ecbae7b /drivers/bluetooth/btbcm.c
parentbdd8818e05da187cd028f64ef2c0a2a6a582bcb1 (diff)
Bluetooth: btbcm: Add firmware table for UART based devices
The Broadcom UART based devices seem to use a little bit different firmare naming prefix. So add a separate table for these devices. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'drivers/bluetooth/btbcm.c')
-rw-r--r--drivers/bluetooth/btbcm.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index c90401261ab4..d0741f3ed7ec 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -174,7 +174,15 @@ static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
174static const struct { 174static const struct {
175 u16 subver; 175 u16 subver;
176 const char *name; 176 const char *name;
177} bcm_subver_table[] = { 177} bcm_uart_subver_table[] = {
178 { 0x410e, "BCM43341B0" }, /* 002.001.014 */
179 { }
180};
181
182static const struct {
183 u16 subver;
184 const char *name;
185} bcm_usb_subver_table[] = {
178 { 0x210b, "BCM43142A0" }, /* 001.001.011 */ 186 { 0x210b, "BCM43142A0" }, /* 001.001.011 */
179 { 0x2112, "BCM4314A0" }, /* 001.001.018 */ 187 { 0x2112, "BCM4314A0" }, /* 001.001.018 */
180 { 0x2118, "BCM20702A0" }, /* 001.001.024 */ 188 { 0x2118, "BCM20702A0" }, /* 001.001.024 */
@@ -224,29 +232,47 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
224 BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]); 232 BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
225 kfree_skb(skb); 233 kfree_skb(skb);
226 234
227 /* Read USB Product Info */ 235 switch ((rev & 0xf000) >> 12) {
228 skb = btbcm_read_usb_product(hdev); 236 case 0:
229 if (IS_ERR(skb)) 237 for (i = 0; bcm_uart_subver_table[i].name; i++) {
230 return PTR_ERR(skb); 238 if (subver == bcm_uart_subver_table[i].subver) {
239 hw_name = bcm_uart_subver_table[i].name;
240 break;
241 }
242 }
231 243
232 vid = get_unaligned_le16(skb->data + 1); 244 snprintf(fw_name, sizeof(fw_name), "brcm/%s.hcd",
233 pid = get_unaligned_le16(skb->data + 3); 245 hw_name ? : "BCM");
234 kfree_skb(skb); 246 break;
247 case 1:
248 case 2:
249 /* Read USB Product Info */
250 skb = btbcm_read_usb_product(hdev);
251 if (IS_ERR(skb))
252 return PTR_ERR(skb);
253
254 vid = get_unaligned_le16(skb->data + 1);
255 pid = get_unaligned_le16(skb->data + 3);
256 kfree_skb(skb);
235 257
236 for (i = 0; bcm_subver_table[i].name; i++) { 258 for (i = 0; bcm_usb_subver_table[i].name; i++) {
237 if (subver == bcm_subver_table[i].subver) { 259 if (subver == bcm_usb_subver_table[i].subver) {
238 hw_name = bcm_subver_table[i].name; 260 hw_name = bcm_usb_subver_table[i].name;
239 break; 261 break;
262 }
240 } 263 }
264
265 snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
266 hw_name ? : "BCM", vid, pid);
267 break;
268 default:
269 return 0;
241 } 270 }
242 271
243 BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, 272 BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
244 hw_name ? : "BCM", (subver & 0x7000) >> 13, 273 hw_name ? : "BCM", (subver & 0x7000) >> 13,
245 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); 274 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
246 275
247 snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
248 hw_name ? : "BCM", vid, pid);
249
250 err = request_firmware(&fw, fw_name, &hdev->dev); 276 err = request_firmware(&fw, fw_name, &hdev->dev);
251 if (err < 0) { 277 if (err < 0) {
252 BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name); 278 BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);