• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

hardware/broadcom/libbt


Commit MetaInfo

Revisión78e7dccc08db81cc95810dc928d956ecf7199853 (tree)
Tiempo2012-10-23 15:59:52
AutorYK Jeffrey Chao <jechao@broa...>
CommiterMatthew Xie

Log Message

Add new user-to-kernel interface for Bluetooth low power mode control (1/2)

The bluesleep kernel module was used in Tegra3 platform to perform Bluetooth
low power wakelock and interrup control. Add new user-to-kernel interface
through proc fs nodes for Bluedroid to feed bluesleep with the HCI_DEV events
which bluesleep was monitoring on.

bug 7347413

Change-Id: I791be1042d5573e5207aa81e3d59fa418134f9fe

Conflicts:
libbt/include/vnd_manta.txt

Cambiar Resumen

Diferencia incremental

--- a/include/bt_vendor_brcm.h
+++ b/include/bt_vendor_brcm.h
@@ -202,6 +202,13 @@
202202 #define BT_WAKE_VIA_USERIAL_IOCTL FALSE
203203 #endif
204204
205+/* BT_WAKE_VIA_PROC
206+
207+ LPM & BT_WAKE control through PROC nodes
208+*/
209+#ifndef BT_WAKE_VIA_PROC
210+#define BT_WAKE_VIA_PROC FALSE
211+#endif
205212
206213 /* SCO_CFG_INCLUDED
207214
--- a/include/upio.h
+++ b/include/upio.h
@@ -38,6 +38,7 @@
3838 enum {
3939 UPIO_BT_WAKE = 0,
4040 UPIO_HOST_WAKE,
41+ UPIO_LPM_MODE,
4142 UPIO_MAX_COUNT
4243 };
4344
--- a/include/vnd_crespo.txt
+++ b/include/vnd_crespo.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/s3c2410_serial0"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_PCM_IF_CLOCK_RATE = 0
65 BTVND_DBG = FALSE
--- a/include/vnd_crespo4g.txt
+++ b/include/vnd_crespo4g.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/s3c2410_serial0"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_PCM_IF_CLOCK_RATE = 0
65 BTVND_DBG = FALSE
--- a/include/vnd_generic.txt
+++ b/include/vnd_generic.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_USE_I2S_INTERFACE = TRUE
65 BTVND_DBG = FALSE
--- a/include/vnd_generic_x86.txt
+++ b/include/vnd_generic_x86.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_USE_I2S_INTERFACE = TRUE
65 BTVND_DBG = FALSE
--- a/include/vnd_grouper.txt
+++ b/include/vnd_grouper.txt
@@ -1,6 +1,6 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
22 FW_PATCHFILE_LOCATION = "/etc/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
3+BT_WAKE_VIA_PROC = TRUE
44 LPM_IDLE_TIMEOUT_MULTIPLE = 5
55 BTVND_DBG = FALSE
66 BTHW_DBG = TRUE
--- a/include/vnd_maguro.txt
+++ b/include/vnd_maguro.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_USE_I2S_INTERFACE = TRUE
65 BTVND_DBG = FALSE
--- a/include/vnd_mako.txt
+++ b/include/vnd_mako.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_USE_I2S_INTERFACE = TRUE
65 BTVND_DBG = FALSE
--- a/include/vnd_manta.txt
+++ b/include/vnd_manta.txt
@@ -1,7 +1,6 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttySAC0"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
33 UART_TARGET_BAUD_RATE = 921600
4-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
54 LPM_IDLE_TIMEOUT_MULTIPLE = 5
65 SCO_USE_I2S_INTERFACE = TRUE
76 SCO_I2SPCM_IF_ROLE = 0
--- a/include/vnd_phantasm.txt
+++ b/include/vnd_phantasm.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
22 FW_PATCHFILE_LOCATION = "/vendor/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 SCO_USE_I2S_INTERFACE = TRUE
65 BTVND_DBG = FALSE
--- a/include/vnd_stingray.txt
+++ b/include/vnd_stingray.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
22 FW_PATCHFILE_LOCATION = "/etc/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 BTVND_DBG = FALSE
65 BTHW_DBG = TRUE
--- a/include/vnd_tilapia.txt
+++ b/include/vnd_tilapia.txt
@@ -1,6 +1,6 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
22 FW_PATCHFILE_LOCATION = "/etc/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
3+BT_WAKE_VIA_PROC = TRUE
44 LPM_IDLE_TIMEOUT_MULTIPLE = 5
55 BTVND_DBG = FALSE
66 BTHW_DBG = TRUE
--- a/include/vnd_wingray.txt
+++ b/include/vnd_wingray.txt
@@ -1,6 +1,5 @@
11 BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
22 FW_PATCHFILE_LOCATION = "/etc/firmware/"
3-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
43 LPM_IDLE_TIMEOUT_MULTIPLE = 5
54 BTVND_DBG = FALSE
65 BTHW_DBG = TRUE
--- a/src/bt_vendor_brcm.c
+++ b/src/bt_vendor_brcm.c
@@ -197,7 +197,7 @@ static int op(bt_vendor_opcode_t opcode, void *param)
197197 case BT_VND_OP_LPM_WAKE_SET_STATE:
198198 {
199199 uint8_t *state = (uint8_t *) param;
200- uint8_t wake_assert = (state == BT_VND_LPM_WAKE_ASSERT) ? \
200+ uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
201201 TRUE : FALSE;
202202
203203 hw_lpm_set_wake_state(wake_assert);
--- a/src/hardware.c
+++ b/src/hardware.c
@@ -1045,10 +1045,12 @@ uint8_t hw_lpm_enable(uint8_t turn_on)
10451045 if (turn_on)
10461046 {
10471047 memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE);
1048+ upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0);
10481049 }
10491050 else
10501051 {
10511052 memset(p, 0, LPM_CMD_PARAM_SIZE);
1053+ upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
10521054 }
10531055
10541056 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \
--- a/src/upio.c
+++ b/src/upio.c
@@ -54,6 +54,39 @@
5454 ** Local type definitions
5555 ******************************************************************************/
5656
57+#if (BT_WAKE_VIA_PROC == TRUE)
58+
59+/* proc fs node for enable/disable lpm mode */
60+#ifndef VENDOR_LPM_PROC_NODE
61+#define VENDOR_LPM_PROC_NODE "/proc/bluetooth/sleep/lpm"
62+#endif
63+
64+/* proc fs node for notifying write request */
65+#ifndef VENDOR_BTWRITE_PROC_NODE
66+#define VENDOR_BTWRITE_PROC_NODE "/proc/bluetooth/sleep/btwrite"
67+#endif
68+
69+/*
70+ * Maximum btwrite assertion holding time without consecutive btwrite kicking.
71+ * This value is correlative(shorter) to the in-activity timeout period set in
72+ * the bluesleep LPM code. The current value used in bluesleep is 10sec.
73+ */
74+#ifndef PROC_BTWRITE_TIMER_TIMEOUT_MS
75+#define PROC_BTWRITE_TIMER_TIMEOUT_MS 8000
76+#endif
77+
78+/* lpm proc control block */
79+typedef struct
80+{
81+ uint8_t btwrite_active;
82+ uint8_t timer_created;
83+ timer_t timer_id;
84+ uint32_t timeout_ms;
85+} vnd_lpm_proc_cb_t;
86+
87+static vnd_lpm_proc_cb_t lpm_proc_cb;
88+#endif
89+
5790 /******************************************************************************
5891 ** Static variables
5992 ******************************************************************************/
@@ -68,6 +101,12 @@ static char *rfkill_state_path = NULL;
68101 ******************************************************************************/
69102
70103 /* for friendly debugging outpout string */
104+static char *lpm_mode[] = {
105+ "UNKNOWN",
106+ "disabled",
107+ "enabled"
108+};
109+
71110 static char *lpm_state[] = {
72111 "UNKNOWN",
73112 "de-asserted",
@@ -141,6 +180,23 @@ static int init_rfkill()
141180 ** LPM Static Functions
142181 *****************************************************************************/
143182
183+#if (BT_WAKE_VIA_PROC == TRUE)
184+/*******************************************************************************
185+**
186+** Function proc_btwrite_timeout
187+**
188+** Description Timeout thread of proc/.../btwrite assertion holding timer
189+**
190+** Returns None
191+**
192+*******************************************************************************/
193+static void proc_btwrite_timeout(union sigval arg)
194+{
195+ UPIODBG("..%s..", __FUNCTION__);
196+ lpm_proc_cb.btwrite_active = FALSE;
197+}
198+#endif
199+
144200 /*****************************************************************************
145201 ** UPIO Interface Functions
146202 *****************************************************************************/
@@ -157,6 +213,9 @@ static int init_rfkill()
157213 void upio_init(void)
158214 {
159215 memset(upio_state, UPIO_UNKNOWN, UPIO_MAX_COUNT);
216+#if (BT_WAKE_VIA_PROC == TRUE)
217+ memset(&lpm_proc_cb, 0, sizeof(vnd_lpm_proc_cb_t));
218+#endif
160219 }
161220
162221 /*******************************************************************************
@@ -170,6 +229,12 @@ void upio_init(void)
170229 *******************************************************************************/
171230 void upio_cleanup(void)
172231 {
232+#if (BT_WAKE_VIA_PROC == TRUE)
233+ if (lpm_proc_cb.timer_created == TRUE)
234+ timer_delete(lpm_proc_cb.timer_id);
235+
236+ lpm_proc_cb.timer_created = FALSE;
237+#endif
173238 }
174239
175240 /*******************************************************************************
@@ -260,33 +325,157 @@ int upio_set_bluetooth_power(int on)
260325 void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
261326 {
262327 int rc;
328+#if (BT_WAKE_VIA_PROC == TRUE)
329+ int fd = -1;
330+ char buffer;
331+#endif
263332
264333 switch (pio)
265334 {
266- case UPIO_BT_WAKE:
335+ case UPIO_LPM_MODE:
336+ if (upio_state[UPIO_LPM_MODE] == action)
337+ {
338+ UPIODBG("LPM is %s already", lpm_mode[action]);
339+ return;
340+ }
341+
342+ upio_state[UPIO_LPM_MODE] = action;
343+
344+#if (BT_WAKE_VIA_PROC == TRUE)
345+ fd = open(VENDOR_LPM_PROC_NODE, O_WRONLY);
346+
347+ if (fd < 0)
348+ {
349+ ALOGE("upio_set : open(%s) for write failed: %s (%d)",
350+ VENDOR_LPM_PROC_NODE, strerror(errno), errno);
351+ return;
352+ }
353+
354+ if (action == UPIO_ASSERT)
355+ {
356+ buffer = '1';
357+ }
358+ else
359+ {
360+ buffer = '0';
361+
362+ // delete btwrite assertion holding timer
363+ if (lpm_proc_cb.timer_created == TRUE)
364+ {
365+ timer_delete(lpm_proc_cb.timer_id);
366+ lpm_proc_cb.timer_created = FALSE;
367+ }
368+ }
369+
370+ if (write(fd, &buffer, 1) < 0)
371+ {
372+ ALOGE("upio_set : write(%s) failed: %s (%d)",
373+ VENDOR_LPM_PROC_NODE, strerror(errno),errno);
374+ }
375+ else
376+ {
377+ if (action == UPIO_ASSERT)
378+ {
379+ // create btwrite assertion holding timer
380+ if (lpm_proc_cb.timer_created == FALSE)
381+ {
382+ int status;
383+ struct sigevent se;
384+
385+ se.sigev_notify = SIGEV_THREAD;
386+ se.sigev_value.sival_ptr = &lpm_proc_cb.timer_id;
387+ se.sigev_notify_function = proc_btwrite_timeout;
388+ se.sigev_notify_attributes = NULL;
389+
390+ status = timer_create(CLOCK_MONOTONIC, &se,
391+ &lpm_proc_cb.timer_id);
392+
393+ if (status == 0)
394+ lpm_proc_cb.timer_created = TRUE;
395+ }
396+ }
397+ }
267398
399+ if (fd >= 0)
400+ close(fd);
401+#endif
402+ break;
403+
404+ case UPIO_BT_WAKE:
268405 if (upio_state[UPIO_BT_WAKE] == action)
269406 {
270407 UPIODBG("BT_WAKE is %s already", lpm_state[action]);
408+
409+#if (BT_WAKE_VIA_PROC == TRUE)
410+ if (lpm_proc_cb.btwrite_active == TRUE)
411+ /*
412+ * The proc btwrite node could have not been updated for
413+ * certain time already due to heavy downstream path flow.
414+ * In this case, we want to explicity touch proc btwrite
415+ * node to keep the bt_wake assertion in the LPM kernel
416+ * driver. The current kernel bluesleep LPM code starts
417+ * a 10sec internal in-activity timeout timer before it
418+ * attempts to deassert BT_WAKE line.
419+ */
420+#endif
271421 return;
272422 }
273423
274424 upio_state[UPIO_BT_WAKE] = action;
275425
276- /****************************************
277- * !!! TODO !!!
278- *
279- * === Custom Porting Required ===
280- *
281- * Platform dependent user-to-kernel
282- * interface is required to set output
283- * state of physical BT_WAKE pin.
284- ****************************************/
285426 #if (BT_WAKE_VIA_USERIAL_IOCTL == TRUE)
427+
286428 userial_vendor_ioctl( ( (action==UPIO_ASSERT) ? \
287429 USERIAL_OP_ASSERT_BT_WAKE : USERIAL_OP_DEASSERT_BT_WAKE),\
288430 NULL);
431+
432+#elif (BT_WAKE_VIA_PROC == TRUE)
433+
434+ /*
435+ * Kick proc btwrite node only at UPIO_ASSERT
436+ */
437+ if (action == UPIO_DEASSERT)
438+ return;
439+
440+ fd = open(VENDOR_BTWRITE_PROC_NODE, O_WRONLY);
441+
442+ if (fd < 0)
443+ {
444+ ALOGE("upio_set : open(%s) for write failed: %s (%d)",
445+ VENDOR_BTWRITE_PROC_NODE, strerror(errno), errno);
446+ return;
447+ }
448+
449+ buffer = '1';
450+
451+ if (write(fd, &buffer, 1) < 0)
452+ {
453+ ALOGE("upio_set : write(%s) failed: %s (%d)",
454+ VENDOR_BTWRITE_PROC_NODE, strerror(errno),errno);
455+ }
456+ else
457+ {
458+ lpm_proc_cb.btwrite_active = TRUE;
459+
460+ if (lpm_proc_cb.timer_created == TRUE)
461+ {
462+ struct itimerspec ts;
463+
464+ ts.it_value.tv_sec = PROC_BTWRITE_TIMER_TIMEOUT_MS/1000;
465+ ts.it_value.tv_nsec = 1000*(PROC_BTWRITE_TIMER_TIMEOUT_MS%1000);
466+ ts.it_interval.tv_sec = 0;
467+ ts.it_interval.tv_nsec = 0;
468+
469+ timer_settime(lpm_proc_cb.timer_id, 0, &ts, 0);
470+ }
471+ }
472+
473+ UPIODBG("proc btwrite assertion");
474+
475+ if (fd >= 0)
476+ close(fd);
289477 #endif
478+
290479 break;
291480
292481 case UPIO_HOST_WAKE: