Lines Matching +full:fw +full:- +full:init +full:- +full:baudrate

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright 2023-2025 NXP
109 /* Set Auto-Sleep mode */
113 /* Set operational baudrate */
117 /* Bluetooth vendor command: Trigger FW dump */
192 const struct firmware *fw; member
232 #define NXP_HDR_RX_TIMEOUT BIT(3) /* FW Header chunk not received */
233 #define NXP_DATA_RX_TIMEOUT BIT(4) /* FW Data chunk not received */
297 #define INIT 0x00000001 macro
346 /* FW dump */
378 struct ps_data *psdata = &nxpdev->psdata; in nxp_drv_send_cmd()
384 psdata->driver_sent_cmd = true; in nxp_drv_send_cmd()
394 psdata->driver_sent_cmd = false; in nxp_drv_send_cmd()
401 if (schedule_work(&nxpdev->tx_work)) in btnxpuart_tx_wakeup()
402 set_bit(BTNXPUART_TX_STATE_ACTIVE, &nxpdev->tx_state); in btnxpuart_tx_wakeup()
408 struct ps_data *psdata = &nxpdev->psdata; in ps_start_timer()
413 if (psdata->cur_psmode == PS_MODE_ENABLE) in ps_start_timer()
414 mod_timer(&psdata->ps_timer, jiffies + msecs_to_jiffies(psdata->h2c_ps_interval)); in ps_start_timer()
416 if (psdata->ps_state == PS_STATE_AWAKE && psdata->ps_cmd == PS_CMD_ENTER_PS) in ps_start_timer()
417 cancel_work_sync(&psdata->work); in ps_start_timer()
422 struct ps_data *psdata = &nxpdev->psdata; in ps_cancel_timer()
424 flush_work(&psdata->work); in ps_cancel_timer()
425 timer_shutdown_sync(&psdata->ps_timer); in ps_cancel_timer()
431 struct ps_data *psdata = &nxpdev->psdata; in ps_control()
434 if (psdata->ps_state == ps_state || in ps_control()
435 !test_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state)) in ps_control()
438 mutex_lock(&psdata->ps_lock); in ps_control()
439 switch (psdata->cur_h2c_wakeupmode) { in ps_control()
442 gpiod_set_value_cansleep(psdata->h2c_ps_gpio, 0); in ps_control()
444 gpiod_set_value_cansleep(psdata->h2c_ps_gpio, 1); in ps_control()
450 status = serdev_device_set_tiocm(nxpdev->serdev, TIOCM_DTR, 0); in ps_control()
452 status = serdev_device_set_tiocm(nxpdev->serdev, 0, TIOCM_DTR); in ps_control()
457 status = serdev_device_break_ctl(nxpdev->serdev, 0); in ps_control()
459 status = serdev_device_break_ctl(nxpdev->serdev, -1); in ps_control()
460 msleep(20); /* Allow chip to detect UART-break and enter sleep */ in ps_control()
466 psdata->ps_state = ps_state; in ps_control()
467 mutex_unlock(&psdata->ps_lock); in ps_control()
477 if (data->ps_cmd == PS_CMD_ENTER_PS && data->cur_psmode == PS_MODE_ENABLE) in ps_work_func()
478 ps_control(data->hdev, PS_STATE_SLEEP); in ps_work_func()
479 else if (data->ps_cmd == PS_CMD_EXIT_PS) in ps_work_func()
480 ps_control(data->hdev, PS_STATE_AWAKE); in ps_work_func()
486 struct hci_dev *hdev = data->hdev; in ps_timeout_func()
489 if (test_bit(BTNXPUART_TX_STATE_ACTIVE, &nxpdev->tx_state)) { in ps_timeout_func()
492 data->ps_cmd = PS_CMD_ENTER_PS; in ps_timeout_func()
493 schedule_work(&data->work); in ps_timeout_func()
501 bt_dev_dbg(nxpdev->hdev, "Host wakeup interrupt"); in ps_host_wakeup_irq_handler()
507 struct serdev_device *serdev = nxpdev->serdev; in ps_setup()
508 struct ps_data *psdata = &nxpdev->psdata; in ps_setup()
511 /* Out-Of-Band Device Wakeup */ in ps_setup()
512 psdata->h2c_ps_gpio = devm_gpiod_get_optional(&serdev->dev, "device-wakeup", in ps_setup()
514 if (IS_ERR(psdata->h2c_ps_gpio)) { in ps_setup()
515 bt_dev_err(hdev, "Error fetching device-wakeup-gpios: %ld", in ps_setup()
516 PTR_ERR(psdata->h2c_ps_gpio)); in ps_setup()
517 return PTR_ERR(psdata->h2c_ps_gpio); in ps_setup()
520 if (device_property_read_u8(&serdev->dev, "nxp,wakein-pin", &psdata->h2c_wakeup_gpio)) { in ps_setup()
521 psdata->h2c_wakeup_gpio = 0xff; /* 0xff: use default pin/gpio */ in ps_setup()
522 } else if (!psdata->h2c_ps_gpio) { in ps_setup()
523 bt_dev_warn(hdev, "nxp,wakein-pin property without device-wakeup-gpios"); in ps_setup()
524 psdata->h2c_wakeup_gpio = 0xff; in ps_setup()
527 /* Out-Of-Band Host Wakeup */ in ps_setup()
528 if (of_property_read_bool(serdev->dev.of_node, "wakeup-source")) { in ps_setup()
529 psdata->irq_handler = of_irq_get_byname(serdev->dev.of_node, "wakeup"); in ps_setup()
530 bt_dev_info(nxpdev->hdev, "irq_handler: %d", psdata->irq_handler); in ps_setup()
531 if (psdata->irq_handler > 0) in ps_setup()
532 psdata->wakeup_source = true; in ps_setup()
535 if (device_property_read_u8(&serdev->dev, "nxp,wakeout-pin", &psdata->c2h_wakeup_gpio)) { in ps_setup()
536 psdata->c2h_wakeup_gpio = 0xff; in ps_setup()
537 if (psdata->wakeup_source) { in ps_setup()
538 bt_dev_warn(hdev, "host wakeup interrupt without nxp,wakeout-pin"); in ps_setup()
539 psdata->wakeup_source = false; in ps_setup()
541 } else if (!psdata->wakeup_source) { in ps_setup()
542 bt_dev_warn(hdev, "nxp,wakeout-pin property without host wakeup interrupt"); in ps_setup()
543 psdata->c2h_wakeup_gpio = 0xff; in ps_setup()
546 if (psdata->wakeup_source) { in ps_setup()
547 ret = devm_request_threaded_irq(&serdev->dev, psdata->irq_handler, in ps_setup()
550 dev_name(&serdev->dev), nxpdev); in ps_setup()
553 disable_irq(psdata->irq_handler); in ps_setup()
554 device_init_wakeup(&serdev->dev, true); in ps_setup()
557 psdata->hdev = hdev; in ps_setup()
558 INIT_WORK(&psdata->work, ps_work_func); in ps_setup()
559 mutex_init(&psdata->ps_lock); in ps_setup()
560 timer_setup(&psdata->ps_timer, ps_timeout_func, 0); in ps_setup()
567 struct ps_data *psdata = &nxpdev->psdata; in ps_wakeup()
570 mutex_lock(&psdata->ps_lock); in ps_wakeup()
571 ps_state = psdata->ps_state; in ps_wakeup()
572 mutex_unlock(&psdata->ps_lock); in ps_wakeup()
575 psdata->ps_cmd = PS_CMD_EXIT_PS; in ps_wakeup()
576 schedule_work(&psdata->work); in ps_wakeup()
584 struct ps_data *psdata = &nxpdev->psdata; in ps_cleanup()
587 mutex_lock(&psdata->ps_lock); in ps_cleanup()
588 ps_state = psdata->ps_state; in ps_cleanup()
589 mutex_unlock(&psdata->ps_lock); in ps_cleanup()
592 ps_control(psdata->hdev, PS_STATE_AWAKE); in ps_cleanup()
595 cancel_work_sync(&psdata->work); in ps_cleanup()
596 mutex_destroy(&psdata->ps_lock); in ps_cleanup()
602 struct ps_data *psdata = &nxpdev->psdata; in send_ps_cmd()
607 if (psdata->target_ps_mode == PS_MODE_ENABLE) in send_ps_cmd()
611 pcmd.c2h_ps_interval = __cpu_to_le16(psdata->c2h_ps_interval); in send_ps_cmd()
623 psdata->cur_psmode = psdata->target_ps_mode; in send_ps_cmd()
625 psdata->target_ps_mode = psdata->cur_psmode; in send_ps_cmd()
626 if (psdata->cur_psmode == PS_MODE_ENABLE) in send_ps_cmd()
631 *status, psdata->cur_psmode); in send_ps_cmd()
641 struct ps_data *psdata = &nxpdev->psdata; in send_wakeup_method_cmd()
646 pcmd.c2h_wakeupmode = psdata->c2h_wakeupmode; in send_wakeup_method_cmd()
647 pcmd.c2h_wakeup_gpio = psdata->c2h_wakeup_gpio; in send_wakeup_method_cmd()
649 switch (psdata->h2c_wakeupmode) { in send_wakeup_method_cmd()
652 pcmd.h2c_wakeup_gpio = psdata->h2c_wakeup_gpio; in send_wakeup_method_cmd()
666 bt_dev_err(hdev, "Setting wake-up method failed (%ld)", PTR_ERR(skb)); in send_wakeup_method_cmd()
673 psdata->cur_h2c_wakeupmode = psdata->h2c_wakeupmode; in send_wakeup_method_cmd()
675 psdata->h2c_wakeupmode = psdata->cur_h2c_wakeupmode; in send_wakeup_method_cmd()
677 *status, psdata->cur_h2c_wakeupmode); in send_wakeup_method_cmd()
687 struct ps_data *psdata = &nxpdev->psdata; in ps_init()
690 serdev_device_set_tiocm(nxpdev->serdev, 0, TIOCM_RTS); in ps_init()
692 serdev_device_set_tiocm(nxpdev->serdev, TIOCM_RTS, 0); in ps_init()
695 psdata->ps_state = PS_STATE_AWAKE; in ps_init()
697 if (psdata->c2h_wakeup_gpio != 0xff) in ps_init()
698 psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_GPIO; in ps_init()
700 psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_NONE; in ps_init()
702 psdata->cur_h2c_wakeupmode = WAKEUP_METHOD_INVALID; in ps_init()
703 if (psdata->h2c_ps_gpio) in ps_init()
706 psdata->h2c_ps_interval = PS_DEFAULT_TIMEOUT_PERIOD_MS; in ps_init()
710 psdata->h2c_wakeupmode = WAKEUP_METHOD_GPIO; in ps_init()
711 gpiod_set_value_cansleep(psdata->h2c_ps_gpio, 0); in ps_init()
715 psdata->h2c_wakeupmode = WAKEUP_METHOD_DTR; in ps_init()
716 serdev_device_set_tiocm(nxpdev->serdev, 0, TIOCM_DTR); in ps_init()
717 serdev_device_set_tiocm(nxpdev->serdev, TIOCM_DTR, 0); in ps_init()
721 psdata->h2c_wakeupmode = WAKEUP_METHOD_BREAK; in ps_init()
722 serdev_device_break_ctl(nxpdev->serdev, -1); in ps_init()
724 serdev_device_break_ctl(nxpdev->serdev, 0); in ps_init()
729 psdata->cur_psmode = PS_MODE_DISABLE; in ps_init()
730 psdata->target_ps_mode = DEFAULT_PS_MODE; in ps_init()
739 nxpdev->fw_dnld_v1_offset = 0; in nxp_download_firmware()
740 nxpdev->fw_v1_sent_bytes = 0; in nxp_download_firmware()
741 nxpdev->fw_v1_expected_len = HDR_LEN; in nxp_download_firmware()
742 nxpdev->boot_reg_offset = 0; in nxp_download_firmware()
743 nxpdev->fw_dnld_v3_offset = 0; in nxp_download_firmware()
744 nxpdev->fw_v3_offset_correction = 0; in nxp_download_firmware()
745 nxpdev->baudrate_changed = not_changed; in nxp_download_firmware()
746 nxpdev->timeout_changed = not_changed; in nxp_download_firmware()
747 nxpdev->helper_downloaded = false; in nxp_download_firmware()
749 serdev_device_set_baudrate(nxpdev->serdev, HCI_NXP_PRI_BAUDRATE); in nxp_download_firmware()
750 serdev_device_set_flow_control(nxpdev->serdev, false); in nxp_download_firmware()
751 nxpdev->current_baudrate = HCI_NXP_PRI_BAUDRATE; in nxp_download_firmware()
753 /* Wait till FW is downloaded */ in nxp_download_firmware()
754 err = wait_event_interruptible_timeout(nxpdev->fw_dnld_done_wait_q, in nxp_download_firmware()
756 &nxpdev->tx_state), in nxp_download_firmware()
759 if (nxpdev->fw && strlen(nxpdev->fw_name)) { in nxp_download_firmware()
760 release_firmware(nxpdev->fw); in nxp_download_firmware()
761 memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name)); in nxp_download_firmware()
765 bt_dev_err(hdev, "FW Download Timeout. offset: %d", in nxp_download_firmware()
766 nxpdev->fw_dnld_v1_offset ? in nxp_download_firmware()
767 nxpdev->fw_dnld_v1_offset : in nxp_download_firmware()
768 nxpdev->fw_dnld_v3_offset); in nxp_download_firmware()
769 return -ETIMEDOUT; in nxp_download_firmware()
771 if (test_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state)) { in nxp_download_firmware()
772 bt_dev_err(hdev, "FW Download Aborted"); in nxp_download_firmware()
773 return -EINTR; in nxp_download_firmware()
776 serdev_device_set_flow_control(nxpdev->serdev, true); in nxp_download_firmware()
778 /* Allow the downloaded FW to initialize */ in nxp_download_firmware()
795 serdev_device_write_buf(nxpdev->serdev, ack_nak, len); in nxp_send_ack()
803 u32 clkdivaddr = CLKDIVADDR - nxpdev->boot_reg_offset; in nxp_fw_change_baudrate()
804 u32 uartdivaddr = UARTDIVADDR - nxpdev->boot_reg_offset; in nxp_fw_change_baudrate()
805 u32 uartmcraddr = UARTMCRADDR - nxpdev->boot_reg_offset; in nxp_fw_change_baudrate()
806 u32 uartreinitaddr = UARTREINITADDR - nxpdev->boot_reg_offset; in nxp_fw_change_baudrate()
807 u32 uarticraddr = UARTICRADDR - nxpdev->boot_reg_offset; in nxp_fw_change_baudrate()
808 u32 uartfcraddr = UARTFCRADDR - nxpdev->boot_reg_offset; in nxp_fw_change_baudrate()
814 /* FW expects swapped CRC bytes */ in nxp_fw_change_baudrate()
816 sizeof(nxp_cmd5) - 4)); in nxp_fw_change_baudrate()
818 serdev_device_write_buf(nxpdev->serdev, (u8 *)&nxp_cmd5, sizeof(nxp_cmd5)); in nxp_fw_change_baudrate()
819 nxpdev->fw_v3_offset_correction += req_len; in nxp_fw_change_baudrate()
822 if (nxpdev->new_baudrate == HCI_NXP_SEC_BAUDRATE_4M) in nxp_fw_change_baudrate()
831 uart_config.re_init.value = __cpu_to_le32(INIT); in nxp_fw_change_baudrate()
836 /* FW expects swapped CRC bytes */ in nxp_fw_change_baudrate()
838 sizeof(uart_config) - 4)); in nxp_fw_change_baudrate()
840 serdev_device_write_buf(nxpdev->serdev, (u8 *)&uart_config, sizeof(uart_config)); in nxp_fw_change_baudrate()
841 serdev_device_wait_until_sent(nxpdev->serdev, 0); in nxp_fw_change_baudrate()
842 nxpdev->fw_v3_offset_correction += req_len; in nxp_fw_change_baudrate()
859 /* FW expects swapped CRC bytes */ in nxp_fw_change_timeout()
861 sizeof(nxp_cmd7) - 4)); in nxp_fw_change_timeout()
862 serdev_device_write_buf(nxpdev->serdev, (u8 *)&nxp_cmd7, sizeof(nxp_cmd7)); in nxp_fw_change_timeout()
863 serdev_device_wait_until_sent(nxpdev->serdev, 0); in nxp_fw_change_timeout()
864 nxpdev->fw_v3_offset_correction += req_len; in nxp_fw_change_timeout()
872 return __le32_to_cpu(hdr->payload_len); in nxp_get_data_len()
877 return test_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in is_fw_downloading()
882 return test_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state); in ind_reset_in_progress()
887 return test_bit(BTNXPUART_FW_DUMP_IN_PROGRESS, &nxpdev->tx_state); in fw_dump_in_progress()
892 if (test_bit(BTNXPUART_CHECK_BOOT_SIGNATURE, &nxpdev->tx_state)) { in process_boot_signature()
893 clear_bit(BTNXPUART_CHECK_BOOT_SIGNATURE, &nxpdev->tx_state); in process_boot_signature()
894 wake_up_interruptible(&nxpdev->check_boot_sign_wait_q); in process_boot_signature()
908 return -ENOENT; in nxp_request_firmware()
910 if (!strlen(nxpdev->fw_name)) { in nxp_request_firmware()
912 !device_property_read_string(&nxpdev->serdev->dev, in nxp_request_firmware()
913 "firmware-name", in nxp_request_firmware()
916 snprintf(nxpdev->fw_name, MAX_FW_FILE_NAME_LEN, "nxp/%s", fw_name); in nxp_request_firmware()
917 err = request_firmware_direct(&nxpdev->fw, nxpdev->fw_name, &hdev->dev); in nxp_request_firmware()
919 snprintf(nxpdev->fw_name, MAX_FW_FILE_NAME_LEN, "nxp/%s", fw_name_old); in nxp_request_firmware()
920 err = request_firmware_direct(&nxpdev->fw, nxpdev->fw_name, &hdev->dev); in nxp_request_firmware()
923 bt_dev_info(hdev, "Request Firmware: %s", nxpdev->fw_name); in nxp_request_firmware()
925 bt_dev_err(hdev, "Firmware file %s not found", nxpdev->fw_name); in nxp_request_firmware()
926 clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_request_firmware()
943 chip_id = le16_to_cpu(req->chip_id ^ req->chip_id_comp); in nxp_recv_chip_ver_v1()
944 if (chip_id == 0xffff && nxpdev->fw_dnld_v1_offset) { in nxp_recv_chip_ver_v1()
945 nxpdev->fw_dnld_v1_offset = 0; in nxp_recv_chip_ver_v1()
946 nxpdev->fw_v1_sent_bytes = 0; in nxp_recv_chip_ver_v1()
947 nxpdev->fw_v1_expected_len = HDR_LEN; in nxp_recv_chip_ver_v1()
948 release_firmware(nxpdev->fw); in nxp_recv_chip_ver_v1()
949 memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name)); in nxp_recv_chip_ver_v1()
961 struct btnxpuart_data *nxp_data = nxpdev->nxp_data; in nxp_recv_fw_req_v1()
972 len = __le16_to_cpu(req->len ^ req->len_comp); in nxp_recv_fw_req_v1()
980 len = __le16_to_cpu(req->len); in nxp_recv_fw_req_v1()
982 if (!nxp_data->helper_fw_name) { in nxp_recv_fw_req_v1()
983 if (nxpdev->timeout_changed != changed) { in nxp_recv_fw_req_v1()
985 nxpdev->timeout_changed = changed; in nxp_recv_fw_req_v1()
988 if (nxpdev->baudrate_changed != changed) { in nxp_recv_fw_req_v1()
989 nxpdev->new_baudrate = nxpdev->secondary_baudrate; in nxp_recv_fw_req_v1()
991 nxpdev->baudrate_changed = changed; in nxp_recv_fw_req_v1()
992 serdev_device_set_baudrate(nxpdev->serdev, in nxp_recv_fw_req_v1()
993 nxpdev->secondary_baudrate); in nxp_recv_fw_req_v1()
994 serdev_device_set_flow_control(nxpdev->serdev, true); in nxp_recv_fw_req_v1()
995 nxpdev->current_baudrate = nxpdev->secondary_baudrate; in nxp_recv_fw_req_v1()
1001 if (!nxp_data->helper_fw_name || nxpdev->helper_downloaded) { in nxp_recv_fw_req_v1()
1002 if (nxp_request_firmware(hdev, nxp_data->fw_name, nxp_data->fw_name_old)) in nxp_recv_fw_req_v1()
1004 } else if (nxp_data->helper_fw_name && !nxpdev->helper_downloaded) { in nxp_recv_fw_req_v1()
1005 if (nxp_request_firmware(hdev, nxp_data->helper_fw_name, NULL)) in nxp_recv_fw_req_v1()
1010 bt_dev_info(hdev, "FW Download Complete: %zu bytes", in nxp_recv_fw_req_v1()
1011 nxpdev->fw->size); in nxp_recv_fw_req_v1()
1012 if (nxp_data->helper_fw_name && !nxpdev->helper_downloaded) { in nxp_recv_fw_req_v1()
1013 nxpdev->helper_downloaded = true; in nxp_recv_fw_req_v1()
1014 serdev_device_wait_until_sent(nxpdev->serdev, 0); in nxp_recv_fw_req_v1()
1015 serdev_device_set_baudrate(nxpdev->serdev, in nxp_recv_fw_req_v1()
1017 serdev_device_set_flow_control(nxpdev->serdev, true); in nxp_recv_fw_req_v1()
1019 clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_recv_fw_req_v1()
1020 wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); in nxp_recv_fw_req_v1()
1028 len = nxpdev->fw_v1_sent_bytes; in nxp_recv_fw_req_v1()
1029 bt_dev_dbg(hdev, "CRC error. Resend %d bytes of FW.", len); in nxp_recv_fw_req_v1()
1031 nxpdev->fw_dnld_v1_offset += nxpdev->fw_v1_sent_bytes; in nxp_recv_fw_req_v1()
1033 /* The FW bin file is made up of many blocks of in nxp_recv_fw_req_v1()
1035 * FW has requested a header, read the payload length in nxp_recv_fw_req_v1()
1037 * In the next iteration, the FW should request the in nxp_recv_fw_req_v1()
1040 * mismatch, clearly the driver and FW are out of sync, in nxp_recv_fw_req_v1()
1041 * and we need to re-send the previous header again. in nxp_recv_fw_req_v1()
1043 if (len == nxpdev->fw_v1_expected_len) { in nxp_recv_fw_req_v1()
1045 nxpdev->fw_v1_expected_len = nxp_get_data_len(nxpdev->fw->data + in nxp_recv_fw_req_v1()
1046 nxpdev->fw_dnld_v1_offset); in nxp_recv_fw_req_v1()
1048 nxpdev->fw_v1_expected_len = HDR_LEN; in nxp_recv_fw_req_v1()
1050 /* FW download out of sync. Send previous chunk again */ in nxp_recv_fw_req_v1()
1051 nxpdev->fw_dnld_v1_offset -= nxpdev->fw_v1_sent_bytes; in nxp_recv_fw_req_v1()
1052 nxpdev->fw_v1_expected_len = HDR_LEN; in nxp_recv_fw_req_v1()
1056 if (nxpdev->fw_dnld_v1_offset + len <= nxpdev->fw->size) in nxp_recv_fw_req_v1()
1057 serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data + in nxp_recv_fw_req_v1()
1058 nxpdev->fw_dnld_v1_offset, len); in nxp_recv_fw_req_v1()
1059 nxpdev->fw_v1_sent_bytes = len; in nxp_recv_fw_req_v1()
1084 nxpdev->boot_reg_offset = 1; in nxp_get_fw_name_from_chipid()
1152 chip_id = le16_to_cpu(req->chip_id); in nxp_recv_chip_ver_v3()
1153 loader_ver = req->loader_ver; in nxp_recv_chip_ver_v3()
1168 __u32 offset = __le32_to_cpu(req->offset); in nxp_handle_fw_download_error()
1169 __u16 err = __le16_to_cpu(req->error); in nxp_handle_fw_download_error()
1176 sizeof(crc_nak_buf) - 1, 0xff); in nxp_handle_fw_download_error()
1177 serdev_device_write_buf(nxpdev->serdev, crc_nak_buf.buf, in nxp_handle_fw_download_error()
1185 sizeof(timeout_nak_buf) - 1, 0xff); in nxp_handle_fw_download_error()
1186 serdev_device_write_buf(nxpdev->serdev, timeout_nak_buf.buf, in nxp_handle_fw_download_error()
1205 if (!req || !nxpdev->fw) in nxp_recv_fw_req_v3()
1208 err = __le16_to_cpu(req->error); in nxp_recv_fw_req_v3()
1212 if (nxpdev->timeout_changed == cmd_sent) in nxp_recv_fw_req_v3()
1213 nxpdev->timeout_changed = changed; in nxp_recv_fw_req_v3()
1214 if (nxpdev->baudrate_changed == cmd_sent) in nxp_recv_fw_req_v3()
1215 nxpdev->baudrate_changed = changed; in nxp_recv_fw_req_v3()
1218 if (nxpdev->timeout_changed == cmd_sent && in nxp_recv_fw_req_v3()
1220 nxpdev->fw_v3_offset_correction -= nxpdev->fw_v3_prev_sent; in nxp_recv_fw_req_v3()
1221 nxpdev->timeout_changed = not_changed; in nxp_recv_fw_req_v3()
1223 if (nxpdev->baudrate_changed == cmd_sent && in nxp_recv_fw_req_v3()
1225 nxpdev->fw_v3_offset_correction -= nxpdev->fw_v3_prev_sent; in nxp_recv_fw_req_v3()
1226 nxpdev->baudrate_changed = not_changed; in nxp_recv_fw_req_v3()
1231 len = __le16_to_cpu(req->len); in nxp_recv_fw_req_v3()
1233 if (nxpdev->timeout_changed != changed) { in nxp_recv_fw_req_v3()
1235 nxpdev->timeout_changed = cmd_sent; in nxp_recv_fw_req_v3()
1239 if (nxpdev->baudrate_changed != changed) { in nxp_recv_fw_req_v3()
1240 nxpdev->new_baudrate = nxpdev->secondary_baudrate; in nxp_recv_fw_req_v3()
1242 nxpdev->baudrate_changed = cmd_sent; in nxp_recv_fw_req_v3()
1243 serdev_device_set_baudrate(nxpdev->serdev, in nxp_recv_fw_req_v3()
1244 nxpdev->secondary_baudrate); in nxp_recv_fw_req_v3()
1245 serdev_device_set_flow_control(nxpdev->serdev, true); in nxp_recv_fw_req_v3()
1246 nxpdev->current_baudrate = nxpdev->secondary_baudrate; in nxp_recv_fw_req_v3()
1251 if (req->len == 0) { in nxp_recv_fw_req_v3()
1252 bt_dev_info(hdev, "FW Download Complete: %zu bytes", in nxp_recv_fw_req_v3()
1253 nxpdev->fw->size); in nxp_recv_fw_req_v3()
1254 clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_recv_fw_req_v3()
1255 wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); in nxp_recv_fw_req_v3()
1259 offset = __le32_to_cpu(req->offset); in nxp_recv_fw_req_v3()
1260 if (offset < nxpdev->fw_v3_offset_correction) { in nxp_recv_fw_req_v3()
1262 * FW is out of sync and needs a power cycle. in nxp_recv_fw_req_v3()
1264 bt_dev_err(hdev, "Something went wrong during FW download"); in nxp_recv_fw_req_v3()
1269 nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction; in nxp_recv_fw_req_v3()
1270 serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data + in nxp_recv_fw_req_v3()
1271 nxpdev->fw_dnld_v3_offset, len); in nxp_recv_fw_req_v3()
1274 nxpdev->fw_v3_prev_sent = len; in nxp_recv_fw_req_v3()
1282 __le32 new_baudrate = __cpu_to_le32(nxpdev->new_baudrate); in nxp_set_baudrate_cmd()
1283 struct ps_data *psdata = &nxpdev->psdata; in nxp_set_baudrate_cmd()
1293 bt_dev_err(hdev, "Setting baudrate failed (%ld)", PTR_ERR(skb)); in nxp_set_baudrate_cmd()
1300 serdev_device_set_baudrate(nxpdev->serdev, nxpdev->new_baudrate); in nxp_set_baudrate_cmd()
1301 nxpdev->current_baudrate = nxpdev->new_baudrate; in nxp_set_baudrate_cmd()
1303 bt_dev_dbg(hdev, "Set baudrate response: status=%d, baudrate=%d", in nxp_set_baudrate_cmd()
1304 *status, nxpdev->new_baudrate); in nxp_set_baudrate_cmd()
1313 serdev_device_set_baudrate(nxpdev->serdev, HCI_NXP_PRI_BAUDRATE); in nxp_check_boot_sign()
1315 serdev_device_set_flow_control(nxpdev->serdev, false); in nxp_check_boot_sign()
1317 serdev_device_set_flow_control(nxpdev->serdev, true); in nxp_check_boot_sign()
1318 set_bit(BTNXPUART_CHECK_BOOT_SIGNATURE, &nxpdev->tx_state); in nxp_check_boot_sign()
1320 return wait_event_interruptible_timeout(nxpdev->check_boot_sign_wait_q, in nxp_check_boot_sign()
1322 &nxpdev->tx_state), in nxp_check_boot_sign()
1334 return -ENOMEM; in nxp_set_ind_reset()
1351 bt_dev_err(hdev, "Failed to trigger FW Dump. (%ld)", PTR_ERR(skb)); in nxp_coredump()
1358 /* Nothing to be added in FW dump header */ in nxp_coredump_hdr()
1365 struct nxp_fw_dump_hdr *fw_dump_hdr = (struct nxp_fw_dump_hdr *)skb->data; in nxp_process_fw_dump()
1367 __u16 seq_num = __le16_to_cpu(fw_dump_hdr->seq_num); in nxp_process_fw_dump()
1368 __u16 buf_len = __le16_to_cpu(fw_dump_hdr->buf_len); in nxp_process_fw_dump()
1372 if (test_and_set_bit(BTNXPUART_FW_DUMP_IN_PROGRESS, &nxpdev->tx_state)) { in nxp_process_fw_dump()
1373 bt_dev_err(hdev, "FW dump already in progress"); in nxp_process_fw_dump()
1376 bt_dev_warn(hdev, "==== Start FW dump ==="); in nxp_process_fw_dump()
1381 schedule_delayed_work(&hdev->dump.dump_timeout, in nxp_process_fw_dump()
1390 bt_dev_warn(hdev, "==== FW dump complete ==="); in nxp_process_fw_dump()
1402 __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle); in nxp_recv_acl_pkt()
1404 /* FW dump chunks are ACL packets with conn handle 0xfff */ in nxp_recv_acl_pkt()
1425 "Reset before setting local-bd-addr failed (%d)", in nxp_set_bdaddr()
1444 struct serdev_device *serdev = nxpdev->serdev; in nxp_setup()
1451 bt_dev_dbg(hdev, "Need FW Download."); in nxp_setup()
1456 bt_dev_info(hdev, "FW already running."); in nxp_setup()
1457 clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_setup()
1460 snprintf(device_string, 30, "BTNXPUART_DEV=%s", dev_name(&serdev->dev)); in nxp_setup()
1464 kobject_uevent_env(&serdev->dev.kobj, KOBJ_CHANGE, envp); in nxp_setup()
1466 serdev_device_set_baudrate(nxpdev->serdev, nxpdev->fw_init_baudrate); in nxp_setup()
1467 nxpdev->current_baudrate = nxpdev->fw_init_baudrate; in nxp_setup()
1471 if (test_and_clear_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state)) in nxp_setup()
1480 struct ps_data *psdata = &nxpdev->psdata; in nxp_post_init()
1482 if (nxpdev->current_baudrate != nxpdev->secondary_baudrate) { in nxp_post_init()
1483 nxpdev->new_baudrate = nxpdev->secondary_baudrate; in nxp_post_init()
1486 if (psdata->cur_h2c_wakeupmode != psdata->h2c_wakeupmode) in nxp_post_init()
1488 if (psdata->cur_psmode != psdata->target_ps_mode) in nxp_post_init()
1499 set_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state); in nxp_hw_err()
1515 &nxpdev->tx_state)) in nxp_shutdown()
1521 serdev_device_set_flow_control(nxpdev->serdev, false); in nxp_shutdown()
1522 set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_shutdown()
1534 struct ps_data *psdata = &nxpdev->psdata; in nxp_wakeup()
1536 if (psdata->c2h_wakeupmode != BT_HOST_WAKEUP_METHOD_NONE) in nxp_wakeup()
1558 skb_queue_tail(&nxpdev->txq, skb); in btnxpuart_queue_skb()
1566 struct ps_data *psdata = &nxpdev->psdata; in nxp_enqueue()
1573 return -EBUSY; in nxp_enqueue()
1576 * driver flags accordingly and ask driver to re-send the command to FW. in nxp_enqueue()
1581 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT && !psdata->driver_sent_cmd) { in nxp_enqueue()
1582 hdr = (struct hci_command_hdr *)skb->data; in nxp_enqueue()
1583 if (hdr->plen != (skb->len - HCI_COMMAND_HDR_SIZE)) in nxp_enqueue()
1586 switch (__le16_to_cpu(hdr->opcode)) { in nxp_enqueue()
1588 if (hdr->plen == sizeof(ps_parm)) { in nxp_enqueue()
1589 memcpy(&ps_parm, skb->data + HCI_COMMAND_HDR_SIZE, hdr->plen); in nxp_enqueue()
1591 psdata->target_ps_mode = PS_MODE_ENABLE; in nxp_enqueue()
1593 psdata->target_ps_mode = PS_MODE_DISABLE; in nxp_enqueue()
1594 psdata->c2h_ps_interval = __le16_to_cpu(ps_parm.c2h_ps_interval); in nxp_enqueue()
1600 if (hdr->plen == sizeof(wakeup_parm)) { in nxp_enqueue()
1601 memcpy(&wakeup_parm, skb->data + HCI_COMMAND_HDR_SIZE, hdr->plen); in nxp_enqueue()
1602 psdata->c2h_wakeupmode = wakeup_parm.c2h_wakeupmode; in nxp_enqueue()
1603 psdata->c2h_wakeup_gpio = wakeup_parm.c2h_wakeup_gpio; in nxp_enqueue()
1604 psdata->h2c_wakeup_gpio = wakeup_parm.h2c_wakeup_gpio; in nxp_enqueue()
1607 psdata->h2c_wakeupmode = WAKEUP_METHOD_GPIO; in nxp_enqueue()
1610 psdata->h2c_wakeupmode = WAKEUP_METHOD_DTR; in nxp_enqueue()
1614 psdata->h2c_wakeupmode = WAKEUP_METHOD_BREAK; in nxp_enqueue()
1622 if (hdr->plen == sizeof(baudrate_parm)) { in nxp_enqueue()
1623 memcpy(&baudrate_parm, skb->data + HCI_COMMAND_HDR_SIZE, hdr->plen); in nxp_enqueue()
1624 nxpdev->new_baudrate = __le32_to_cpu(baudrate_parm); in nxp_enqueue()
1630 if (hdr->plen == 1) { in nxp_enqueue()
1652 return skb_dequeue(&nxpdev->txq); in nxp_dequeue()
1660 struct serdev_device *serdev = nxpdev->serdev; in btnxpuart_tx_work()
1661 struct hci_dev *hdev = nxpdev->hdev; in btnxpuart_tx_work()
1669 len = serdev_device_write_buf(serdev, skb->data, skb->len); in btnxpuart_tx_work()
1670 hdev->stat.byte_tx += len; in btnxpuart_tx_work()
1673 if (skb->len > 0) { in btnxpuart_tx_work()
1674 skb_queue_head(&nxpdev->txq, skb); in btnxpuart_tx_work()
1680 hdev->stat.cmd_tx++; in btnxpuart_tx_work()
1683 hdev->stat.acl_tx++; in btnxpuart_tx_work()
1686 hdev->stat.sco_tx++; in btnxpuart_tx_work()
1692 clear_bit(BTNXPUART_TX_STATE_ACTIVE, &nxpdev->tx_state); in btnxpuart_tx_work()
1700 err = serdev_device_open(nxpdev->serdev); in btnxpuart_open()
1703 dev_name(&nxpdev->serdev->dev)); in btnxpuart_open()
1705 set_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state); in btnxpuart_open()
1714 serdev_device_close(nxpdev->serdev); in btnxpuart_close()
1715 skb_queue_purge(&nxpdev->txq); in btnxpuart_close()
1716 if (!IS_ERR_OR_NULL(nxpdev->rx_skb)) { in btnxpuart_close()
1717 kfree_skb(nxpdev->rx_skb); in btnxpuart_close()
1718 nxpdev->rx_skb = NULL; in btnxpuart_close()
1720 clear_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state); in btnxpuart_close()
1729 serdev_device_write_flush(nxpdev->serdev); in btnxpuart_flush()
1730 skb_queue_purge(&nxpdev->txq); in btnxpuart_flush()
1732 cancel_work_sync(&nxpdev->tx_work); in btnxpuart_flush()
1734 if (!IS_ERR_OR_NULL(nxpdev->rx_skb)) { in btnxpuart_flush()
1735 kfree_skb(nxpdev->rx_skb); in btnxpuart_flush()
1736 nxpdev->rx_skb = NULL; in btnxpuart_flush()
1760 nxpdev->rx_skb = h4_recv_buf(&nxpdev->hu, nxpdev->rx_skb, data, count, in btnxpuart_receive_buf()
1762 if (IS_ERR(nxpdev->rx_skb)) { in btnxpuart_receive_buf()
1763 int err = PTR_ERR(nxpdev->rx_skb); in btnxpuart_receive_buf()
1764 /* Safe to ignore out-of-sync bootloader signatures */ in btnxpuart_receive_buf()
1767 bt_dev_err(nxpdev->hdev, "Frame reassembly failed (%d)", err); in btnxpuart_receive_buf()
1772 nxpdev->hdev->stat.byte_rx += count; in btnxpuart_receive_buf()
1789 struct serdev_device *serdev = nxpdev->serdev; in nxp_coredump_notify()
1794 snprintf(device_string, 30, "BTNXPUART_DEV=%s", dev_name(&serdev->dev)); in nxp_coredump_notify()
1812 kobject_uevent_env(&serdev->dev.kobj, KOBJ_CHANGE, envp); in nxp_coredump_notify()
1822 nxpdev = devm_kzalloc(&serdev->dev, sizeof(*nxpdev), GFP_KERNEL); in nxp_serdev_probe()
1824 return -ENOMEM; in nxp_serdev_probe()
1826 nxpdev->nxp_data = (struct btnxpuart_data *)device_get_match_data(&serdev->dev); in nxp_serdev_probe()
1828 nxpdev->serdev = serdev; in nxp_serdev_probe()
1833 INIT_WORK(&nxpdev->tx_work, btnxpuart_tx_work); in nxp_serdev_probe()
1834 skb_queue_head_init(&nxpdev->txq); in nxp_serdev_probe()
1836 init_waitqueue_head(&nxpdev->fw_dnld_done_wait_q); in nxp_serdev_probe()
1837 init_waitqueue_head(&nxpdev->check_boot_sign_wait_q); in nxp_serdev_probe()
1839 device_property_read_u32(&nxpdev->serdev->dev, "fw-init-baudrate", in nxp_serdev_probe()
1840 &nxpdev->fw_init_baudrate); in nxp_serdev_probe()
1841 if (!nxpdev->fw_init_baudrate) in nxp_serdev_probe()
1842 nxpdev->fw_init_baudrate = FW_INIT_BAUDRATE; in nxp_serdev_probe()
1844 device_property_read_u32(&nxpdev->serdev->dev, "max-speed", in nxp_serdev_probe()
1845 &nxpdev->secondary_baudrate); in nxp_serdev_probe()
1846 if (!nxpdev->secondary_baudrate || in nxp_serdev_probe()
1847 (nxpdev->secondary_baudrate != HCI_NXP_SEC_BAUDRATE_3M && in nxp_serdev_probe()
1848 nxpdev->secondary_baudrate != HCI_NXP_SEC_BAUDRATE_4M)) { in nxp_serdev_probe()
1849 if (nxpdev->secondary_baudrate) in nxp_serdev_probe()
1850 dev_err(&serdev->dev, in nxp_serdev_probe()
1851 "Invalid max-speed. Using default 3000000."); in nxp_serdev_probe()
1852 nxpdev->secondary_baudrate = HCI_NXP_SEC_BAUDRATE_3M; in nxp_serdev_probe()
1855 set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_serdev_probe()
1859 nxpdev->pdn = devm_reset_control_get_optional_shared(&serdev->dev, NULL); in nxp_serdev_probe()
1860 if (IS_ERR(nxpdev->pdn)) in nxp_serdev_probe()
1861 return PTR_ERR(nxpdev->pdn); in nxp_serdev_probe()
1863 err = devm_regulator_get_enable(&serdev->dev, "vcc"); in nxp_serdev_probe()
1865 dev_err(&serdev->dev, "Failed to enable vcc regulator\n"); in nxp_serdev_probe()
1872 dev_err(&serdev->dev, "Can't allocate HCI device\n"); in nxp_serdev_probe()
1873 return -ENOMEM; in nxp_serdev_probe()
1876 reset_control_deassert(nxpdev->pdn); in nxp_serdev_probe()
1878 nxpdev->hdev = hdev; in nxp_serdev_probe()
1879 nxpdev->hu.hdev = hdev; in nxp_serdev_probe()
1881 hdev->bus = HCI_UART; in nxp_serdev_probe()
1884 hdev->manufacturer = MANUFACTURER_NXP; in nxp_serdev_probe()
1885 hdev->open = btnxpuart_open; in nxp_serdev_probe()
1886 hdev->close = btnxpuart_close; in nxp_serdev_probe()
1887 hdev->flush = btnxpuart_flush; in nxp_serdev_probe()
1888 hdev->setup = nxp_setup; in nxp_serdev_probe()
1889 hdev->post_init = nxp_post_init; in nxp_serdev_probe()
1890 hdev->send = nxp_enqueue; in nxp_serdev_probe()
1891 hdev->hw_error = nxp_hw_err; in nxp_serdev_probe()
1892 hdev->shutdown = nxp_shutdown; in nxp_serdev_probe()
1893 hdev->wakeup = nxp_wakeup; in nxp_serdev_probe()
1894 hdev->reset = nxp_reset; in nxp_serdev_probe()
1895 hdev->set_bdaddr = nxp_set_bdaddr; in nxp_serdev_probe()
1896 SET_HCIDEV_DEV(hdev, &serdev->dev); in nxp_serdev_probe()
1898 device_property_read_u8_array(&nxpdev->serdev->dev, in nxp_serdev_probe()
1899 "local-bd-address", in nxp_serdev_probe()
1905 dev_err(&serdev->dev, "Can't register HCI device\n"); in nxp_serdev_probe()
1918 reset_control_assert(nxpdev->pdn); in nxp_serdev_probe()
1920 return -ENODEV; in nxp_serdev_probe()
1926 struct hci_dev *hdev = nxpdev->hdev; in nxp_serdev_remove()
1929 set_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state); in nxp_serdev_remove()
1930 clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); in nxp_serdev_remove()
1931 wake_up_interruptible(&nxpdev->check_boot_sign_wait_q); in nxp_serdev_remove()
1932 wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); in nxp_serdev_remove()
1934 /* Restore FW baudrate to fw_init_baudrate if changed. in nxp_serdev_remove()
1935 * This will ensure FW baudrate is in sync with in nxp_serdev_remove()
1936 * driver baudrate in case this driver is re-inserted. in nxp_serdev_remove()
1938 if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) { in nxp_serdev_remove()
1939 nxpdev->new_baudrate = nxpdev->fw_init_baudrate; in nxp_serdev_remove()
1946 reset_control_assert(nxpdev->pdn); in nxp_serdev_remove()
1954 struct ps_data *psdata = &nxpdev->psdata; in nxp_serdev_suspend()
1956 ps_control(psdata->hdev, PS_STATE_SLEEP); in nxp_serdev_suspend()
1958 if (psdata->wakeup_source) { in nxp_serdev_suspend()
1959 enable_irq_wake(psdata->irq_handler); in nxp_serdev_suspend()
1960 enable_irq(psdata->irq_handler); in nxp_serdev_suspend()
1968 struct ps_data *psdata = &nxpdev->psdata; in nxp_serdev_resume()
1970 if (psdata->wakeup_source) { in nxp_serdev_resume()
1971 disable_irq(psdata->irq_handler); in nxp_serdev_resume()
1972 disable_irq_wake(psdata->irq_handler); in nxp_serdev_resume()
1975 ps_control(psdata->hdev, PS_STATE_AWAKE); in nxp_serdev_resume()
1984 struct hci_dev *hdev = nxpdev->hdev; in nxp_serdev_coredump()
1986 if (hdev->dump.coredump) in nxp_serdev_coredump()
1987 hdev->dump.coredump(hdev); in nxp_serdev_coredump()
2004 { .compatible = "nxp,88w8987-bt", .data = &w8987_data },
2005 { .compatible = "nxp,88w8997-bt", .data = &w8997_data },