Lines Matching +full:full +full:- +full:hd

1 // SPDX-License-Identifier: GPL-2.0
15 #include <linux/crc-ccitt.h>
43 * struct gb_beagleplay - BeaglePlay Greybus driver
53 * @tx_crc: hdlc transmit crc-ccitt fcs
98 * struct hdlc_payload - Structure to represent part of HDCL frame payload data.
109 * struct hdlc_greybus_frame - Structure to represent greybus HDLC frame payload
131 * @COMMAND_BANK_ERASE: Performs an erase of all of the customer-accessible
168 * @checksum: 8-bit checksum excluding len
178 (U8_MAX - sizeof(struct cc1352_bootloader_packet))
207 u16 cport_id = le16_to_cpu(gb_frame->cport); in hdlc_rx_greybus_frame()
208 u16 gb_msg_len = le16_to_cpu(gb_frame->hdr.size); in hdlc_rx_greybus_frame()
210 dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", in hdlc_rx_greybus_frame()
211 gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); in hdlc_rx_greybus_frame()
213 greybus_data_rcvd(bg->gb_hd, cport_id, (u8 *)&gb_frame->hdr, gb_msg_len); in hdlc_rx_greybus_frame()
218 dev_dbg(&bg->sd->dev, "CC1352 Log: %.*s", (int)len, buf); in hdlc_rx_dbg_frame()
222 * hdlc_write() - Consume HDLC Buffer.
231 int head = smp_load_acquire(&bg->tx_circ_buf.head); in hdlc_write()
232 int tail = bg->tx_circ_buf.tail; in hdlc_write()
234 const unsigned char *buf = &bg->tx_circ_buf.buf[tail]; in hdlc_write()
237 written = serdev_device_write_buf(bg->sd, buf, count); in hdlc_write()
240 smp_store_release(&bg->tx_circ_buf.tail, (tail + written) & (TX_CIRC_BUF_SIZE - 1)); in hdlc_write()
245 * hdlc_append() - Queue HDLC data for sending.
253 int tail, head = bg->tx_circ_buf.head; in hdlc_append()
256 tail = READ_ONCE(bg->tx_circ_buf.tail); in hdlc_append()
259 bg->tx_circ_buf.buf[head] = value; in hdlc_append()
262 smp_store_release(&bg->tx_circ_buf.head, in hdlc_append()
263 (head + 1) & (TX_CIRC_BUF_SIZE - 1)); in hdlc_append()
266 dev_warn(&bg->sd->dev, "Tx circ buf full"); in hdlc_append()
282 bg->tx_crc = 0xFFFF; in hdlc_append_tx_frame()
288 bg->tx_crc = crc_ccitt(bg->tx_crc, &value, 1); in hdlc_append_tx_u8()
302 bg->tx_crc ^= 0xffff; in hdlc_append_tx_crc()
303 hdlc_append_escaped(bg, bg->tx_crc & 0xff); in hdlc_append_tx_crc()
304 hdlc_append_escaped(bg, (bg->tx_crc >> 8) & 0xff); in hdlc_append_tx_crc()
311 spin_lock_bh(&bg->tx_consumer_lock); in hdlc_transmit()
313 spin_unlock_bh(&bg->tx_consumer_lock); in hdlc_transmit()
321 spin_lock(&bg->tx_producer_lock); in hdlc_tx_frames()
333 spin_unlock(&bg->tx_producer_lock); in hdlc_tx_frames()
335 schedule_work(&bg->tx_work); in hdlc_tx_frames()
340 hdlc_tx_frames(bg, bg->rx_buffer[0], (bg->rx_buffer[1] >> 1) & 0x7, NULL, 0); in hdlc_tx_s_frame_ack()
347 u8 address = bg->rx_buffer[0]; in hdlc_rx_frame()
349 crc = crc_ccitt(0xffff, bg->rx_buffer, bg->rx_buffer_len); in hdlc_rx_frame()
351 dev_warn_ratelimited(&bg->sd->dev, "CRC failed from %02x: 0x%04x", address, crc); in hdlc_rx_frame()
355 ctrl = bg->rx_buffer[1]; in hdlc_rx_frame()
356 buf = &bg->rx_buffer[2]; in hdlc_rx_frame()
357 len = bg->rx_buffer_len - 4; in hdlc_rx_frame()
359 /* I-Frame, send S-Frame ACK */ in hdlc_rx_frame()
371 dev_warn_ratelimited(&bg->sd->dev, "unknown frame %u", address); in hdlc_rx_frame()
385 if (bg->rx_buffer_len) in hdlc_rx()
388 bg->rx_buffer_len = 0; in hdlc_rx()
391 bg->rx_in_esc = true; in hdlc_rx()
394 if (bg->rx_in_esc) { in hdlc_rx()
396 bg->rx_in_esc = false; in hdlc_rx()
399 if (bg->rx_buffer_len < MAX_RX_HDLC) { in hdlc_rx()
400 bg->rx_buffer[bg->rx_buffer_len] = c; in hdlc_rx()
401 bg->rx_buffer_len++; in hdlc_rx()
403 dev_err_ratelimited(&bg->sd->dev, "RX Buffer Overflow"); in hdlc_rx()
404 bg->rx_buffer_len = 0; in hdlc_rx()
414 INIT_WORK(&bg->tx_work, hdlc_transmit); in hdlc_init()
415 spin_lock_init(&bg->tx_producer_lock); in hdlc_init()
416 spin_lock_init(&bg->tx_consumer_lock); in hdlc_init()
417 bg->tx_circ_buf.head = 0; in hdlc_init()
418 bg->tx_circ_buf.tail = 0; in hdlc_init()
420 bg->tx_circ_buf.buf = devm_kmalloc(&bg->sd->dev, TX_CIRC_BUF_SIZE, GFP_KERNEL); in hdlc_init()
421 if (!bg->tx_circ_buf.buf) in hdlc_init()
422 return -ENOMEM; in hdlc_init()
424 bg->rx_buffer_len = 0; in hdlc_init()
425 bg->rx_in_esc = false; in hdlc_init()
432 flush_work(&bg->tx_work); in hdlc_deinit()
436 * csum8: Calculate 8-bit checksum on data
438 * @data: bytes to calculate 8-bit checksum of
457 serdev_device_write_buf(bg->sd, ack, sizeof(ack)); in cc1352_bootloader_send_ack()
464 serdev_device_write_buf(bg->sd, nack, sizeof(nack)); in cc1352_bootloader_send_nack()
487 * 5. Send an acknowledge byte or a not-acknowledge byte to the device to
501 WRITE_ONCE(bg->fwl_ack, data[0]); in cc1352_bootloader_pkt_rx()
502 complete(&bg->fwl_ack_com); in cc1352_bootloader_pkt_rx()
508 WRITE_ONCE(bg->fwl_cmd_response, (u32)data[2]); in cc1352_bootloader_pkt_rx()
514 WRITE_ONCE(bg->fwl_cmd_response, get_unaligned_be32(&data[2])); in cc1352_bootloader_pkt_rx()
517 return -EINVAL; in cc1352_bootloader_pkt_rx()
522 complete(&bg->fwl_cmd_response_com); in cc1352_bootloader_pkt_rx()
524 dev_warn(&bg->sd->dev, in cc1352_bootloader_pkt_rx()
538 memcpy(bg->rx_buffer + bg->rx_buffer_len, data, count); in cc1352_bootloader_rx()
539 bg->rx_buffer_len += count; in cc1352_bootloader_rx()
542 ret = cc1352_bootloader_pkt_rx(bg, bg->rx_buffer + off, in cc1352_bootloader_rx()
543 bg->rx_buffer_len - off); in cc1352_bootloader_rx()
545 return dev_err_probe(&bg->sd->dev, ret, in cc1352_bootloader_rx()
550 bg->rx_buffer_len -= off; in cc1352_bootloader_rx()
551 memmove(bg->rx_buffer, bg->rx_buffer + off, bg->rx_buffer_len); in cc1352_bootloader_rx()
561 if (READ_ONCE(bg->flashing_mode)) in gb_tty_receive()
571 if (!READ_ONCE(bg->flashing_mode)) in gb_tty_wakeup()
572 schedule_work(&bg->tx_work); in gb_tty_wakeup()
581 * gb_message_send() - Send greybus message using HDLC over UART
583 * @hd: pointer to greybus host device
593 static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) in gb_message_send() argument
595 struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); in gb_message_send()
599 dev_dbg(&hd->dev, "Sending greybus message with Operation %u, Type: %X on Cport %u", in gb_message_send()
600 msg->header->operation_id, msg->header->type, cport); in gb_message_send()
602 if (le16_to_cpu(msg->header->size) > RX_HDLC_PAYLOAD) in gb_message_send()
603 return dev_err_probe(&hd->dev, -E2BIG, "Greybus message too big"); in gb_message_send()
607 payloads[1].buf = msg->header; in gb_message_send()
608 payloads[1].len = sizeof(*msg->header); in gb_message_send()
609 payloads[2].buf = msg->payload; in gb_message_send()
610 payloads[2].len = msg->payload_size; in gb_message_send()
613 greybus_message_sent(bg->gb_hd, msg, 0); in gb_message_send()
646 &bg->fwl_ack_com, msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); in cc1352_bootloader_wait_for_ack()
648 return dev_err_probe(&bg->sd->dev, ret, in cc1352_bootloader_wait_for_ack()
651 switch (READ_ONCE(bg->fwl_ack)) { in cc1352_bootloader_wait_for_ack()
655 return -EAGAIN; in cc1352_bootloader_wait_for_ack()
657 return -EINVAL; in cc1352_bootloader_wait_for_ack()
665 serdev_device_write_buf(bg->sd, sync_bytes, sizeof(sync_bytes)); in cc1352_bootloader_sync()
678 serdev_device_write_buf(bg->sd, (const u8 *)&pkt, sizeof(pkt)); in cc1352_bootloader_get_status()
684 &bg->fwl_cmd_response_com, in cc1352_bootloader_get_status()
687 return dev_err_probe(&bg->sd->dev, ret, in cc1352_bootloader_get_status()
690 switch (READ_ONCE(bg->fwl_cmd_response)) { in cc1352_bootloader_get_status()
694 return -EINVAL; in cc1352_bootloader_get_status()
709 serdev_device_write_buf(bg->sd, (const u8 *)&pkt, sizeof(pkt)); in cc1352_bootloader_erase()
726 serdev_device_write_buf(bg->sd, (const u8 *)&pkt, sizeof(pkt)); in cc1352_bootloader_reset()
760 serdev_device_write_buf(bg->sd, (const u8 *)&pkt, sizeof(pkt)); in cc1352_bootloader_crc32()
761 serdev_device_write_buf(bg->sd, (const u8 *)&cmd_data, in cc1352_bootloader_crc32()
769 &bg->fwl_cmd_response_com, in cc1352_bootloader_crc32()
772 return dev_err_probe(&bg->sd->dev, ret, in cc1352_bootloader_crc32()
775 *crc32 = READ_ONCE(bg->fwl_cmd_response); in cc1352_bootloader_crc32()
795 serdev_device_write_buf(bg->sd, (const u8 *)&pkt, sizeof(pkt)); in cc1352_bootloader_download()
796 serdev_device_write_buf(bg->sd, (const u8 *)&cmd_data, in cc1352_bootloader_download()
816 serdev_device_write_buf(bg->sd, (const u8 *)&pkt, sizeof(pkt)); in cc1352_bootloader_send_data()
817 serdev_device_write_buf(bg->sd, data, rem); in cc1352_bootloader_send_data()
832 gb_hd_del(bg->gb_hd); in gb_greybus_deinit()
833 gb_hd_put(bg->gb_hd); in gb_greybus_deinit()
840 bg->gb_hd = gb_hd_create(&gb_hdlc_driver, &bg->sd->dev, TX_CIRC_BUF_SIZE, GB_MAX_CPORTS); in gb_greybus_init()
841 if (IS_ERR(bg->gb_hd)) { in gb_greybus_init()
842 dev_err(&bg->sd->dev, "Failed to create greybus host device"); in gb_greybus_init()
843 return PTR_ERR(bg->gb_hd); in gb_greybus_init()
846 ret = gb_hd_add(bg->gb_hd); in gb_greybus_init()
848 dev_err(&bg->sd->dev, "Failed to add greybus host device"); in gb_greybus_init()
851 dev_set_drvdata(&bg->gb_hd->dev, bg); in gb_greybus_init()
865 struct gb_beagleplay *bg = fw_upload->dd_handle; in cc1352_prepare()
867 dev_info(&bg->sd->dev, "CC1352 Start Flashing..."); in cc1352_prepare()
878 flush_work(&bg->tx_work); in cc1352_prepare()
880 serdev_device_wait_until_sent(bg->sd, CC1352_BOOTLOADER_TIMEOUT); in cc1352_prepare()
882 WRITE_ONCE(bg->flashing_mode, true); in cc1352_prepare()
884 gpiod_direction_output(bg->bootloader_backdoor_gpio, 0); in cc1352_prepare()
885 gpiod_direction_output(bg->rst_gpio, 0); in cc1352_prepare()
888 gpiod_set_value(bg->rst_gpio, 1); in cc1352_prepare()
891 gpiod_set_value(bg->bootloader_backdoor_gpio, 1); in cc1352_prepare()
894 gpiod_direction_input(bg->bootloader_backdoor_gpio); in cc1352_prepare()
895 gpiod_direction_input(bg->rst_gpio); in cc1352_prepare()
899 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_HW_ERROR, in cc1352_prepare()
904 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_HW_ERROR, in cc1352_prepare()
907 bg->fwl_crc32 = crc32(0xffffffff, data, size) ^ 0xffffffff; in cc1352_prepare()
910 if (bg->fwl_crc32 == curr_crc32) { in cc1352_prepare()
911 dev_warn(&bg->sd->dev, "Skipping reflashing same image"); in cc1352_prepare()
913 WRITE_ONCE(bg->flashing_mode, false); in cc1352_prepare()
916 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_RW_ERROR, in cc1352_prepare()
924 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_HW_ERROR, in cc1352_prepare()
927 bg->fwl_reset_addr = true; in cc1352_prepare()
934 struct gb_beagleplay *bg = fw_upload->dd_handle; in cc1352_cleanup()
936 WRITE_ONCE(bg->flashing_mode, false); in cc1352_cleanup()
945 struct gb_beagleplay *bg = fw_upload->dd_handle; in cc1352_write()
950 bg->fwl_reset_addr = true; in cc1352_write()
955 if (bg->fwl_reset_addr) { in cc1352_write()
958 return dev_err_probe(&bg->sd->dev, in cc1352_write()
962 bg->fwl_reset_addr = false; in cc1352_write()
967 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_HW_ERROR, in cc1352_write()
977 struct gb_beagleplay *bg = fw_upload->dd_handle; in cc1352_poll_complete()
980 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_HW_ERROR, in cc1352_poll_complete()
983 if (bg->fwl_crc32 != curr_crc32) in cc1352_poll_complete()
984 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_FW_INVALID, in cc1352_poll_complete()
988 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_HW_ERROR, in cc1352_poll_complete()
991 dev_info(&bg->sd->dev, "CC1352 Flashing Successful"); in cc1352_poll_complete()
992 WRITE_ONCE(bg->flashing_mode, false); in cc1352_poll_complete()
996 return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_RW_ERROR, in cc1352_poll_complete()
1006 struct gb_beagleplay *bg = fw_upload->dd_handle; in cc1352_cancel()
1008 dev_info(&bg->sd->dev, "CC1352 Bootloader Cancel"); in cc1352_cancel()
1015 serdev_device_close(bg->sd); in gb_serdev_deinit()
1022 serdev_device_set_drvdata(bg->sd, bg); in gb_serdev_init()
1023 serdev_device_set_client_ops(bg->sd, &gb_beagleplay_ops); in gb_serdev_init()
1024 ret = serdev_device_open(bg->sd); in gb_serdev_init()
1026 return dev_err_probe(&bg->sd->dev, ret, "Unable to open serial device"); in gb_serdev_init()
1028 serdev_device_set_baudrate(bg->sd, 115200); in gb_serdev_init()
1029 serdev_device_set_flow_control(bg->sd, false); in gb_serdev_init()
1051 bg->fwl = NULL; in gb_fw_init()
1052 bg->bootloader_backdoor_gpio = NULL; in gb_fw_init()
1053 bg->rst_gpio = NULL; in gb_fw_init()
1054 bg->flashing_mode = false; in gb_fw_init()
1055 bg->fwl_cmd_response = 0; in gb_fw_init()
1056 bg->fwl_ack = 0; in gb_fw_init()
1057 init_completion(&bg->fwl_ack_com); in gb_fw_init()
1058 init_completion(&bg->fwl_cmd_response_com); in gb_fw_init()
1060 desc = devm_gpiod_get(&bg->sd->dev, "bootloader-backdoor", GPIOD_IN); in gb_fw_init()
1063 bg->bootloader_backdoor_gpio = desc; in gb_fw_init()
1065 desc = devm_gpiod_get(&bg->sd->dev, "reset", GPIOD_IN); in gb_fw_init()
1068 bg->rst_gpio = desc; in gb_fw_init()
1070 fwl = firmware_upload_register(THIS_MODULE, &bg->sd->dev, "cc1352p7", in gb_fw_init()
1074 bg->fwl = fwl; in gb_fw_init()
1081 firmware_upload_unregister(bg->fwl); in gb_fw_deinit()
1089 bg = devm_kmalloc(&serdev->dev, sizeof(*bg), GFP_KERNEL); in gb_beagleplay_probe()
1091 return -ENOMEM; in gb_beagleplay_probe()
1093 bg->sd = serdev; in gb_beagleplay_probe()