• Home
  • Raw
  • Download

Lines Matching +full:llp +full:- +full:based

9  *  Written by Ohad Ben-Cohen <ohad@bencohen.org>
12 * This file is based on hci_h4.c, which was written
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
56 #include <linux/nvmem-consumer.h>
60 /* Vendor-specific HCI commands */
102 struct ll_struct *ll = hu->priv; in send_hcill_cmd()
110 err = -ENOMEM; in send_hcill_cmd()
118 skb_queue_tail(&ll->txq, skb); in send_hcill_cmd()
132 return -ENOMEM; in ll_open()
134 skb_queue_head_init(&ll->txq); in ll_open()
135 skb_queue_head_init(&ll->tx_wait_q); in ll_open()
136 spin_lock_init(&ll->hcill_lock); in ll_open()
138 ll->hcill_state = HCILL_AWAKE; in ll_open()
140 hu->priv = ll; in ll_open()
142 if (hu->serdev) { in ll_open()
143 struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev); in ll_open()
144 if (!IS_ERR(lldev->ext_clk)) in ll_open()
145 clk_prepare_enable(lldev->ext_clk); in ll_open()
154 struct ll_struct *ll = hu->priv; in ll_flush()
158 skb_queue_purge(&ll->tx_wait_q); in ll_flush()
159 skb_queue_purge(&ll->txq); in ll_flush()
167 struct ll_struct *ll = hu->priv; in ll_close()
171 skb_queue_purge(&ll->tx_wait_q); in ll_close()
172 skb_queue_purge(&ll->txq); in ll_close()
174 kfree_skb(ll->rx_skb); in ll_close()
176 if (hu->serdev) { in ll_close()
177 struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev); in ll_close()
178 gpiod_set_value_cansleep(lldev->enable_gpio, 0); in ll_close()
180 clk_disable_unprepare(lldev->ext_clk); in ll_close()
183 hu->priv = NULL; in ll_close()
201 while ((skb = skb_dequeue(&ll->tx_wait_q))) in __ll_do_awake()
202 skb_queue_tail(&ll->txq, skb); in __ll_do_awake()
204 ll->hcill_state = HCILL_AWAKE; in __ll_do_awake()
208 * Called upon a wake-up-indication from the device
213 struct ll_struct *ll = hu->priv; in ll_device_want_to_wakeup()
218 spin_lock_irqsave(&ll->hcill_lock, flags); in ll_device_want_to_wakeup()
220 switch (ll->hcill_state) { in ll_device_want_to_wakeup()
224 * have simultaneously sent a wake-up-indication packet. in ll_device_want_to_wakeup()
225 * Traditionally, in this case, receiving a wake-up-indication in ll_device_want_to_wakeup()
226 * was enough and an additional wake-up-ack wasn't needed. in ll_device_want_to_wakeup()
228 * explicit wake-up-ack. Other BRF versions, which do not in ll_device_want_to_wakeup()
232 BT_DBG("dual wake-up-indication"); in ll_device_want_to_wakeup()
243 BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state); in ll_device_want_to_wakeup()
251 spin_unlock_irqrestore(&ll->hcill_lock, flags); in ll_device_want_to_wakeup()
258 * Called upon a sleep-indication from the device
263 struct ll_struct *ll = hu->priv; in ll_device_want_to_sleep()
268 spin_lock_irqsave(&ll->hcill_lock, flags); in ll_device_want_to_sleep()
271 if (ll->hcill_state != HCILL_AWAKE) in ll_device_want_to_sleep()
272 BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state); in ll_device_want_to_sleep()
281 ll->hcill_state = HCILL_ASLEEP; in ll_device_want_to_sleep()
284 spin_unlock_irqrestore(&ll->hcill_lock, flags); in ll_device_want_to_sleep()
291 * Called upon wake-up-acknowledgement from the device
296 struct ll_struct *ll = hu->priv; in ll_device_woke_up()
301 spin_lock_irqsave(&ll->hcill_lock, flags); in ll_device_woke_up()
304 if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE) in ll_device_woke_up()
305 BT_ERR("received HCILL_WAKE_UP_ACK in state %ld", ll->hcill_state); in ll_device_woke_up()
310 spin_unlock_irqrestore(&ll->hcill_lock, flags); in ll_device_woke_up()
321 struct ll_struct *ll = hu->priv; in ll_enqueue()
329 spin_lock_irqsave(&ll->hcill_lock, flags); in ll_enqueue()
332 switch (ll->hcill_state) { in ll_enqueue()
335 skb_queue_tail(&ll->txq, skb); in ll_enqueue()
340 skb_queue_tail(&ll->tx_wait_q, skb); in ll_enqueue()
346 ll->hcill_state = HCILL_ASLEEP_TO_AWAKE; in ll_enqueue()
351 skb_queue_tail(&ll->tx_wait_q, skb); in ll_enqueue()
354 BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state); in ll_enqueue()
359 spin_unlock_irqrestore(&ll->hcill_lock, flags); in ll_enqueue()
367 struct ll_struct *ll = hu->priv; in ll_recv_frame()
377 ll->hcill_state); in ll_recv_frame()
434 struct ll_struct *ll = hu->priv; in ll_recv()
436 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) in ll_recv()
437 return -EUNATCH; in ll_recv()
439 ll->rx_skb = h4_recv_buf(hu->hdev, ll->rx_skb, data, count, in ll_recv()
441 if (IS_ERR(ll->rx_skb)) { in ll_recv()
442 int err = PTR_ERR(ll->rx_skb); in ll_recv()
443 bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); in ll_recv()
444 ll->rx_skb = NULL; in ll_recv()
453 struct ll_struct *ll = hu->priv; in ll_dequeue()
454 return skb_dequeue(&ll->txq); in ll_dequeue()
471 if (skb->len != sizeof(*ver)) { in read_local_version()
472 err = -EILSEQ; in read_local_version()
476 ver = (struct hci_rp_read_local_version *)skb->data; in read_local_version()
477 if (le16_to_cpu(ver->manufacturer) != 13) { in read_local_version()
478 err = -ENODEV; in read_local_version()
482 version = le16_to_cpu(ver->lmp_subver); in read_local_version()
491 * download_firmware -
505 version = read_local_version(lldev->hu.hdev); in download_firmware()
516 "ti-connectivity/TIInit_%d.%d.%d.bts", in download_firmware()
519 err = request_firmware(&fw, bts_scr_name, &lldev->serdev->dev); in download_firmware()
520 if (err || !fw->data || !fw->size) { in download_firmware()
521 bt_dev_err(lldev->hu.hdev, "request_firmware failed(errno %d) for %s", in download_firmware()
523 return -EINVAL; in download_firmware()
525 ptr = (void *)fw->data; in download_firmware()
526 len = fw->size; in download_firmware()
531 len -= sizeof(struct bts_header); in download_firmware()
534 bt_dev_dbg(lldev->hu.hdev, " action size %d, type %d ", in download_firmware()
535 ((struct bts_action *)ptr)->size, in download_firmware()
536 ((struct bts_action *)ptr)->type); in download_firmware()
538 action_ptr = &(((struct bts_action *)ptr)->data[0]); in download_firmware()
540 switch (((struct bts_action *)ptr)->type) { in download_firmware()
542 bt_dev_dbg(lldev->hu.hdev, "S"); in download_firmware()
544 if (cmd->opcode == HCI_VS_UPDATE_UART_HCI_BAUDRATE) { in download_firmware()
548 bt_dev_warn(lldev->hu.hdev, "change remote baud rate command in firmware"); in download_firmware()
551 if (cmd->prefix != 1) in download_firmware()
552 bt_dev_dbg(lldev->hu.hdev, "command type %d", cmd->prefix); in download_firmware()
554 skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT); in download_firmware()
556 bt_dev_err(lldev->hu.hdev, "send command failed"); in download_firmware()
564 bt_dev_dbg(lldev->hu.hdev, "W"); in download_firmware()
567 bt_dev_info(lldev->hu.hdev, "sleep command in scr"); in download_firmware()
568 msleep(((struct bts_action_delay *)action_ptr)->msec); in download_firmware()
571 len -= (sizeof(struct bts_action) + in download_firmware()
572 ((struct bts_action *)ptr)->size); in download_firmware()
574 ((struct bts_action *)ptr)->size; in download_firmware()
605 struct serdev_device *serdev = hu->serdev; in ll_setup()
613 hu->hdev->set_bdaddr = ll_set_bdaddr; in ll_setup()
619 gpiod_set_value_cansleep(lldev->enable_gpio, 0); in ll_setup()
621 gpiod_set_value_cansleep(lldev->enable_gpio, 1); in ll_setup()
624 bt_dev_err(hu->hdev, "Failed to get CTS"); in ll_setup()
633 bt_dev_err(hu->hdev, "download firmware failed, retrying..."); in ll_setup()
634 } while (retry--); in ll_setup()
640 if (!bacmp(&lldev->bdaddr, BDADDR_NONE)) { in ll_setup()
644 set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks); in ll_setup()
645 } else if (bacmp(&lldev->bdaddr, BDADDR_ANY)) { in ll_setup()
646 err = ll_set_bdaddr(hu->hdev, &lldev->bdaddr); in ll_setup()
648 set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks); in ll_setup()
652 if (hu->oper_speed) in ll_setup()
653 speed = hu->oper_speed; in ll_setup()
654 else if (hu->proto->oper_speed) in ll_setup()
655 speed = hu->proto->oper_speed; in ll_setup()
663 skb = __hci_cmd_sync(hu->hdev, HCI_VS_UPDATE_UART_HCI_BAUDRATE, in ll_setup()
675 static const struct hci_uart_proto llp; variable
684 lldev = devm_kzalloc(&serdev->dev, sizeof(struct ll_device), GFP_KERNEL); in hci_ti_probe()
686 return -ENOMEM; in hci_ti_probe()
687 hu = &lldev->hu; in hci_ti_probe()
690 lldev->serdev = hu->serdev = serdev; in hci_ti_probe()
692 lldev->enable_gpio = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); in hci_ti_probe()
693 if (IS_ERR(lldev->enable_gpio)) in hci_ti_probe()
694 return PTR_ERR(lldev->enable_gpio); in hci_ti_probe()
696 lldev->ext_clk = devm_clk_get(&serdev->dev, "ext_clock"); in hci_ti_probe()
697 if (IS_ERR(lldev->ext_clk) && PTR_ERR(lldev->ext_clk) != -ENOENT) in hci_ti_probe()
698 return PTR_ERR(lldev->ext_clk); in hci_ti_probe()
700 of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed); in hci_ti_probe()
704 bdaddr_cell = nvmem_cell_get(&serdev->dev, "bd-address"); in hci_ti_probe()
708 if (err == -EPROBE_DEFER) in hci_ti_probe()
714 if (err != -ENOENT && err != -ENOSYS) { in hci_ti_probe()
720 dev_warn(&serdev->dev, in hci_ti_probe()
721 "Failed to get \"bd-address\" nvmem cell (%d)\n", in hci_ti_probe()
723 bacpy(&lldev->bdaddr, BDADDR_NONE); in hci_ti_probe()
732 dev_err(&serdev->dev, "Failed to read nvmem bd-address\n"); in hci_ti_probe()
736 dev_err(&serdev->dev, "Invalid nvmem bd-address length\n"); in hci_ti_probe()
738 return -EINVAL; in hci_ti_probe()
745 baswap(&lldev->bdaddr, bdaddr); in hci_ti_probe()
749 return hci_uart_register_device(hu, &llp); in hci_ti_probe()
756 hci_uart_unregister_device(&lldev->hu); in hci_ti_remove()
761 { .compatible = "ti,wl1271-st" },
762 { .compatible = "ti,wl1273-st" },
763 { .compatible = "ti,wl1281-st" },
764 { .compatible = "ti,wl1283-st" },
765 { .compatible = "ti,wl1285-st" },
766 { .compatible = "ti,wl1801-st" },
767 { .compatible = "ti,wl1805-st" },
768 { .compatible = "ti,wl1807-st" },
769 { .compatible = "ti,wl1831-st" },
770 { .compatible = "ti,wl1835-st" },
771 { .compatible = "ti,wl1837-st" },
778 .name = "hci-ti",
788 static const struct hci_uart_proto llp = { variable
804 return hci_uart_register_proto(&llp); in ll_init()
811 return hci_uart_unregister_proto(&llp); in ll_deinit()