/* Recv data */ static int ath_recv(struct hci_uart *hu, void *data, int count) { struct ath_struct *ath = hu->priv; unsigned int type; BT_DBG(""); if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) BT_ERR("Frame Reassembly Failed"); if (count & test_bit(BT_SLEEPCMD, &flags)) { struct sk_buff *skb = hu->hdev->reassembly[0]; if (!skb) { struct { char type; } *pkt; /* Start of the frame */ pkt = data; type = pkt->type; } else type = bt_cb(skb)->pkt_type; if (type == HCI_EVENT_PKT) { clear_bit(BT_SLEEPCMD, &flags); BT_INFO("cur_sleep:%d\n", ath->cur_sleep); if (ath->cur_sleep == 1) set_bit(BT_SLEEPENABLE, &flags); else clear_bit(BT_SLEEPENABLE, &flags); } if (test_bit(BT_SLEEPENABLE, &flags)) modify_timer_task(); } return count; }
/* Initialize protocol */ static int ath_open(struct hci_uart *hu) { struct ath_struct *ath; BT_DBG("hu %p, bsi %p", hu, bsi); if (!bsi) return -EIO; ath = kzalloc(sizeof(*ath), GFP_ATOMIC); if (!ath) return -ENOMEM; skb_queue_head_init(&ath->txq); hu->priv = ath; ath->hu = hu; if (ath_bluesleep_gpio_config(ath, 1) < 0) { BT_ERR("HCIATH3K GPIO Config failed"); hu->priv = NULL; kfree(ath); return -EIO; } ath->cur_sleep = enableuartsleep; if (ath->cur_sleep == 1) { set_bit(BT_SLEEPENABLE, &flags); modify_timer_task(); } INIT_WORK(&ath->ctxtsw, ath_hci_uart_work); INIT_WORK(&ath->ws_sleep, wakeup_host_work); return 0; }
static void wakeup_host_work(struct work_struct *work) { BT_DBG("wake up host"); if (test_bit(BT_SLEEPENABLE, &flags)) { if (test_bit(BT_TXEXPIRED, &flags)) hsuart_serial_clock_on(bsi->uport); } if (!is_lpm_enabled) modify_timer_task(); }
static void wakeup_host_work(struct work_struct *work) { struct ath_struct *ath = container_of(work, struct ath_struct, ws_sleep); BT_INFO("wake up host"); if (test_bit(BT_SLEEPENABLE, &flags)) { if (test_bit(BT_TXEXPIRED, &flags)) hsuart_serial_clock_on(ath->hu->tty); } modify_timer_task(); }
static int ath_wakeup_ar3k(struct tty_struct *tty) { int status = 0; if (test_bit(BT_TXEXPIRED, &flags)) { BT_INFO("wakeup device\n"); gpio_set_value(bsi->ext_wake, 0); msleep(20); gpio_set_value(bsi->ext_wake, 1); } modify_timer_task(); return status; }
static int ath_wakeup_ar3k(void) { int status = 0; if (test_bit(BT_TXEXPIRED, &flags)) { hsuart_serial_clock_on(bsi->uport); BT_DBG("wakeup device\n"); gpio_set_value(bsi->ext_wake, 0); msleep(20); gpio_set_value(bsi->ext_wake, 1); } if (!is_lpm_enabled) modify_timer_task(); return status; }
/* Initialize protocol */ static int ath_open(struct hci_uart *hu) { struct ath_struct *ath; struct uart_state *state; BT_DBG("hu %p, bsi %p", hu, bsi); if (!bsi) { BT_ERR("HCIATH3K bluesleep info does not exist"); return -EIO; } ath = kzalloc(sizeof(*ath), GFP_ATOMIC); if (!ath) { BT_ERR("HCIATH3K Memory not enough to init driver"); return -ENOMEM; } skb_queue_head_init(&ath->txq); hu->priv = ath; ath->hu = hu; state = hu->tty->driver_data; if (!state) { BT_ERR("HCIATH3K tty driver data does not exist"); return -ENXIO; } bsi->uport = state->uart_port; if (ath_bluesleep_gpio_config(1) < 0) { BT_ERR("HCIATH3K GPIO Config failed"); hu->priv = NULL; kfree(ath); return -EIO; } ath->cur_sleep = enableuartsleep; if (ath->cur_sleep == 1) { set_bit(BT_SLEEPENABLE, &flags); modify_timer_task(); } INIT_WORK(&ath->ctxtsw, ath_hci_uart_work); INIT_WORK(&ws_sleep, wakeup_host_work); return 0; }