I recently was presented with a Thinkpad T430s containing a Broadcom BCM20702 bluetooth chip, and bluetooth wouldn't work at all on it.
Bus 003 Device 009: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
On boot, I saw this in /var/log/syslog:
Nov 24 13:37:35 liberty kernel: bluetooth hci0: Direct firmware load for brcm/BCM20702A1-0a5c-21e6.hcd failed with error -2
Sure enough, /lib/firmware/brcm/BCM20702A1-0a5c-21e6.hcd did not exist.
After a bit of research, I determined that nobody had already written clear instructions on just how to obtain the needed firmware. There were a few results with links to different firmware that someone had already obtained from some mysterious source, and vague references about "get it from your Windows system" and such, but well, I don't have a Windows system.
I went to the Lenovo support site, downloaded the bluetooth driver file (currently located at https://download.lenovo.com/ibmdl/pub/pc/pccbbs/mobiles/g4wb12ww.exe but of course, this link will not always be valid), and poked around a bit in its contents. To do that, you'll first need to get innoextract (see http://constexpr.org/innoextract/ or search SlackBuilds.org for it).
root@liberty:~/fw# innoextract g4wb12ww.exe
...lots of output, all extracted to an "app/" directory...
Now to see if we can find the important bits in here... I notice that the firmware expected to be loaded has "0a5c-21e6" in the name, and the usb ID of the bluetooth hardware is "0a5c:21e6" so let's poke around and see if we can find anything with that name:
find app/ -name "*0a5c*" -o -name "*0A5C*"
Hmm, no output. Okay.
root@liberty:~/fw#grep -Eir 0a5c.*21e6 .
Binary file ./app/Win64/BTW.msi matches
./app/Win64/bcbtums-win7x64-brcm.inf:%BRCM20702Thinkpad.DeviceDesc%=RAMUSB21E6, USB\VID_0A5C&PID_21E6 ; 20702 non-UHE Lenovo Japan
Binary file ./app/Win32/BTW.msi matches
./app/Win32/bcbtums-win7x86-brcm.inf:%BRCM20702Thinkpad.DeviceDesc%=RAMUSB21E6, USB\VID_0A5C&PID_21E6 ; 20702 non-UHE Lenovo Japan
Well, I don't want to poke around in binary files too much, but I know that .inf are plaintext files, so let's look in there. That "DeviceDesc" looks important, so we'll search for that in the .inf file once we get it opened. I use vi, but hopefully you know your editor well enough to do the equivalent, and you'll find something like this:
%BRCM20702Thinkpad.DeviceDesc%=RAMUSB21E6, USB\VID_0A5C&PID_21E6 ; 20702 non-UHE Lenovo Japan
HKR,,LowerFilters, 0x00010000, "bcbtums"
I happen to know from my research that the firmware files are .hex file, so this line is awesome to see:
Copy that file out of the directory structure into a place that's easier to work with:
root@liberty:~/fw# cp app/Win64/BCM20702A1_001.002.014.0449.0462.hex .
BCM20702A1_001.002.014.0449.0462.hex app/ g4wb12ww.exe
Now we need to put this in a form that the linux kernel expects, so that's where hex2hcd comes in:
root@liberty:~/fw# git clone git://github.com/jessesung/hex2hcd.git
Cloning into 'hex2hcd'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 8 (delta 1), reused 8 (delta 1), pack-reused 0
Receiving objects: 100% (8/8), 8.71 KiB | 0 bytes/s, done.
Resolving deltas: 100% (1/1), done.
Checking connectivity... done.
root@liberty:~/fw# cd hex2hcd/
gcc -O2 -march=native hex2hcd.c -o hex2hcd
Now we use hex2hcd:
root@liberty:~/fw/hex2hcd# ./hex2hcd ../BCM20702A1_001.002.014.0449.0462.hex ../BCM20702A1-0a5c-21e6.hcd
... lots of text and binary data ...
Finally, let's back up a directory, make sure what think is there is actually there, and copy it into place:
root@liberty:~/fw/hex2hcd# cd ..
BCM20702A1-0a5c-21e6.hcd BCM20702A1_001.002.014.0449.0462.hex app/ g4wb12ww.exe hex2hcd/
root@liberty:~/fw# cp BCM20702A1-0a5c-21e6.hcd /lib/firmware/brcm/
The first person who finds this useful is expected to clean up the formatting and such. :-) Enjoy! -RW