AnsweredAssumed Answered

Bluetooth Serial Communication Problem with IMX6DL + WL1835

Question asked by Danny Pickford on Feb 18, 2015
Latest reply on Dec 22, 2015 by eduard gavin
Branched to a new discussion

I've been working on integrating the freescale IMX6DL & bluetooth on the TI WL1835 WILINK8 card on our custom board for the last month or so, and have been running into issues.  We have the 802.11 wireless working well but cannot bring up bluetooth.

Primary issue is that I can't seem to get the TI WL1835 to communicate back to the driver the information about the hardware so it can then load the firmware.

The second issue is that I cannot get ldisc to enumerate a 3,000,000 bluetooth speed (prior to loading the firmware) and I have working around this by setting it to 115200.

Working with our hardware engineer we've looped the serial interface all the way back to the input pins on the WL1835 chip itself to valid the pins in the hardware layout and believe we are correct in our device tree pin settings.

I'm working with a yocto project 3.10 & 3.14 kernel, with various TI supplied patches to add device tree support to shared transport, and are using the UIM mechanism to initialize the bluetooth hardware (apparently tested by TI on the imx6sl solo; we're working with the dualite). Our patches are primarily comprised from the work done by Iian Hunter and a few additional patches cherry picked from the ti-wilink kernel.

We're using 4 UARTS on the platform and are only having issues with UART2 currently; which is hooked up to the bluetooth interface on the WL1835.

cat /proc/tty/driver/IMX-uart
serinfo:1.0 driver revision:
0: uart:IMX mmio:0x02020000 irq:58 tx:41063 rx:647 RTS|DTR|DSR|CD
1: uart:IMX mmio:0x021E8000 irq:59 tx:0 rx:0 DSR|CD
2: uart:IMX mmio:0x021EC000 irq:60 tx:1 rx:2234 RTS|DTR|DSR|CD
3: uart:IMX mmio:0x021F0000 irq:61 tx:0 rx:0 CTS|DSR|CD

We're running UIM and are using the shared transport mechanism. Initializing bluetooth via bootup and hciconfig toggles the enable GPIO as expected, but we then receive this shared transport error.

I've included some relevant output below; if anyone has any suggestions it would be greatly appreciated.

GPIO Toggle:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:
gpio-64 (sysfs ) out lo
gpio-83 (brcm_reg ) out hi
gpio-86 (usb_otg_vbus ) out lo
gpio-90 (kim ) out hi
gpio-95 (sysfs ) out hi

Shared Transport Failure Log:

(stc): st_tty_open (stk) :line discipline installed
(stk) : waiting for ver info- timed out (stk) :kim: failed to read local ver
(stk) :download firmware failed(stk) :ldisc_install = 0
(stc): st_tty_close Bluetooth: st_register failed -22
Can't init device hci0: Input/output error (5)

Relevant DTB snippets:

kim {
compatible = "kim";
nshutdown_gpio = <90>; // GPIO3_26
dev_name = "/dev/ttymxc1";
flow_cntrl = <1>;
baud_rate = <115200>; //<3000000>
//Ran into issues with ldisc connecting at 3M, reverted to chip default 115200.

};

btwilink {
compatible = "btwilink";
};

pinctrl_elarm_uart2: elarm-uart2 {
fsl,pins = <
MX6QDL_PAD_SD4_DAT5__UART2_CTS_B 0x1b0b1
MX6QDL_PAD_SD4_DAT6__UART2_RTS_B 0x1b0b1
MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
>;
};

uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_elarm_uart2>;
fsl,uart-has-rtscts;
//fsl,dte-mode;
status = "okay";
};

This error appears to be related to the following code snippet which indicates the driver can't get the version information from the chip so it can send up the appropriate firmware to the device.

/drivers/misc/ti-st/st_kim.c

long st_kim_start(void *kim_data)
{
long err = 0;
long retry = POR_RETRY_COUNT;
struct ti_st_plat_data *pdata;
struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;

pr_info(" %s", __func__);
if (kim_gdata->kim_pdev->dev.of_node) {
pr_debug("use device tree data");
pdata = dt_pdata;
} else {
pdata = kim_gdata->kim_pdev->dev.platform_data;
}

do {
/* platform specific enabling code here */
if (pdata->chip_enable)
pdata->chip_enable(kim_gdata);

/* Configure BT nShutdown to HIGH state */
gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
mdelay(5); /* FIXME: a proper toggle */
gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
mdelay(100);
/* re-initialize the completion */
reinit_completion(&kim_gdata->ldisc_installed);
/* send notification to UIM */
kim_gdata->ldisc_install = 1;
pr_info("ldisc_install = 1");
sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
NULL, "install");
/* wait for ldisc to be installed */
err = wait_for_completion_interruptible_timeout(
&kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME));
if (!err) {
/* ldisc installation timeout,
* flush uart, power cycle BT_EN */
pr_err("ldisc installation timeout");
err = st_kim_stop(kim_gdata);
continue;
} else {
/* ldisc installed now */
pr_info("line discipline installed");
err = download_firmware(kim_gdata);
if (err != 0) {
/* ldisc installed but fw download failed,
* flush uart & power cycle BT_EN */
pr_err("download firmware failed");
err = st_kim_stop(kim_gdata);
continue;
} else { /* on success don't retry */
break;
}
}
} while (retry--);
return err;
}

Outcomes