From 062be972a7c74270e8e08303973a20ce88a4140b Mon Sep 17 00:00:00 2001 From: Mangesh Malusare Date: Fri, 21 Aug 2020 01:07:35 +0530 Subject: [PATCH] SPI Host driver: Handle INIT event from SPI slave device Signed-off-by: Mangesh Malusare --- .../network_adapter/main/app_main.c | 1 - .../network_adapter/main/spi_slave_api.c | 2 +- host/linux/host_driver/esp32/esp.h | 1 + host/linux/host_driver/esp32/esp_bt.c | 9 +- host/linux/host_driver/esp32/sdio/esp_sdio.c | 2 + host/linux/host_driver/esp32/spi/esp_spi.c | 92 +++++++++++++++++-- 6 files changed, 95 insertions(+), 12 deletions(-) diff --git a/esp/esp_driver/network_adapter/main/app_main.c b/esp/esp_driver/network_adapter/main/app_main.c index b7f23d7..18e2436 100644 --- a/esp/esp_driver/network_adapter/main/app_main.c +++ b/esp/esp_driver/network_adapter/main/app_main.c @@ -646,7 +646,6 @@ void app_main() assert(from_host_queue != NULL); ESP_ERROR_CHECK(ret); - sleep(3); xTaskCreate(recv_task , "recv_task" , 4096 , NULL , 18 , NULL); xTaskCreate(send_task , "send_task" , 4096 , NULL , 18 , NULL); diff --git a/esp/esp_driver/network_adapter/main/spi_slave_api.c b/esp/esp_driver/network_adapter/main/spi_slave_api.c index 815dfb4..7bea1d9 100644 --- a/esp/esp_driver/network_adapter/main/spi_slave_api.c +++ b/esp/esp_driver/network_adapter/main/spi_slave_api.c @@ -318,7 +318,7 @@ static interface_handle_t * esp_spi_init(uint8_t capabilities) generate_startup_event(capabilities); - usleep(200); + usleep(500); xTaskCreate(spi_transaction_task , "spi_task" , 4096 , NULL , 18 , NULL); return &if_handle_g; diff --git a/host/linux/host_driver/esp32/esp.h b/host/linux/host_driver/esp32/esp.h index d590c15..9390684 100644 --- a/host/linux/host_driver/esp32/esp.h +++ b/host/linux/host_driver/esp32/esp.h @@ -28,6 +28,7 @@ #include "adapter.h" #define ESP_IF_TYPE_SDIO 1 +#define ESP_IF_TYPE_SPI 2 /* Network link status */ #define ESP_LINK_DOWN 0 diff --git a/host/linux/host_driver/esp32/esp_bt.c b/host/linux/host_driver/esp32/esp_bt.c index e947518..0759963 100644 --- a/host/linux/host_driver/esp32/esp_bt.c +++ b/host/linux/host_driver/esp32/esp_bt.c @@ -135,6 +135,9 @@ int esp_deinit_bt(struct esp_adapter *adapter) { struct hci_dev *hdev = NULL; + if (!adapter || !adapter->hcidev) + return 0; + hdev = adapter->hcidev; hci_unregister_dev(hdev); @@ -168,7 +171,11 @@ int esp_init_bt(struct esp_adapter *adapter) adapter->hcidev = hdev; hci_set_drvdata(hdev, adapter); - hdev->bus = HCI_SDIO; + if (adapter->if_type == ESP_IF_TYPE_SDIO) + hdev->bus = HCI_SDIO; + else if (adapter->if_type == ESP_IF_TYPE_SPI) + hdev->bus = HCI_SPI; + hdev->open = esp_bt_open; hdev->close = esp_bt_close; hdev->flush = esp_bt_flush; diff --git a/host/linux/host_driver/esp32/sdio/esp_sdio.c b/host/linux/host_driver/esp32/sdio/esp_sdio.c index c40eb66..5969bf3 100644 --- a/host/linux/host_driver/esp32/sdio/esp_sdio.c +++ b/host/linux/host_driver/esp32/sdio/esp_sdio.c @@ -293,6 +293,8 @@ static int init_context(struct esp_sdio_context *context) if (!context->adapter) printk (KERN_ERR "%s: Failed to get adapter\n", __func__); + context->adapter->if_type = ESP_IF_TYPE_SDIO; + return ret; } diff --git a/host/linux/host_driver/esp32/spi/esp_spi.c b/host/linux/host_driver/esp32/spi/esp_spi.c index a3ac374..1cbe6b9 100644 --- a/host/linux/host_driver/esp32/spi/esp_spi.c +++ b/host/linux/host_driver/esp32/spi/esp_spi.c @@ -126,6 +126,78 @@ static int write_packet(struct esp_adapter *adapter, u8 *buf, u32 size) return 0; } +static void process_capabilities(u8 cap) +{ + printk (KERN_INFO "ESP32 capabilities: 0x%x", cap); + + /* Reset BT */ + esp_deinit_bt(spi_context.adapter); + + if ((cap & ESP_BT_SPI_SUPPORT) || (cap & ESP_BT_SDIO_SUPPORT)) { + msleep(200); + esp_init_bt(spi_context.adapter); + } +} + +static void process_init_event(u8 *evt_buf, u8 len) +{ + u8 len_left = len, tag_len; + u8 *pos; + + if (!evt_buf) + return; + + pos = evt_buf; + + while (len_left) { + tag_len = *(pos + 1); + if (*pos == ESP_PRIV_CAPABILITY) { + process_capabilities(*(pos + 2)); + } else { + printk (KERN_WARNING "Unsupported tag in event"); + } + len_left = len_left - (tag_len + 2); + } +} + +static void process_event(u8 *evt_buf, u16 len) +{ + struct esp_priv_event *event; + + if (!evt_buf || !len) + return; + + event = (struct esp_priv_event *) evt_buf; + + if (event->event_type == ESP_PRIV_EVENT_INIT) { + printk (KERN_INFO "Received INIT event from esp32"); + process_init_event(event->event_data, event->event_len); + } else { + printk (KERN_WARNING "Drop unknown event"); + } +} + +static void process_priv_communication(struct sk_buff *skb) +{ + struct esp_payload_header *header; + u8 *payload; + u16 len; + + if (!skb || !skb->data) + return; + + header = (struct esp_payload_header *) skb->data; + + payload = skb->data + le16_to_cpu(header->offset); + len = le16_to_cpu(header->len); + + if (header->priv_pkt_type == ESP_PACKET_TYPE_EVENT) { + process_event(payload, len); + } + + dev_kfree_skb(skb); +} + static int process_rx_buf(struct sk_buff *skb) { struct esp_payload_header *header; @@ -155,6 +227,14 @@ static int process_rx_buf(struct sk_buff *skb) /* Trim SKB to actual size */ skb_trim(skb, len); + if (header->if_type == ESP_PRIV_IF) { + process_priv_communication(skb); + return 0; + } + + if (!data_path) + return -EPERM; + /* enqueue skb for read_packet to pick it */ skb_queue_tail(&spi_context.rx_q, skb); @@ -207,7 +287,7 @@ static void esp_spi_work(struct work_struct *work) } /* Free rx_skb if received data is not valid */ - if (!data_path || process_rx_buf(rx_skb)) { + if (process_rx_buf(rx_skb)) { dev_kfree_skb(rx_skb); } @@ -224,7 +304,7 @@ static int spi_init(void) strlcpy(esp_board.modalias, "esp_spi", sizeof(esp_board.modalias)); esp_board.mode = SPI_MODE_3; /* 10MHz */ - esp_board.max_speed_hz = 10000000; + esp_board.max_speed_hz = 8000000; esp_board.bus_num = 0; esp_board.chip_select = 0; @@ -311,13 +391,6 @@ static int spi_init(void) return status; } - status = esp_init_bt(spi_context.adapter); - if (status) { - spi_exit(); - printk (KERN_ERR "Failed to init BT\n"); - return status; - } - msleep(200); return status; @@ -362,6 +435,7 @@ int esp_init_interface_layer(struct esp_adapter *adapter) adapter->if_context = &spi_context; adapter->if_ops = &if_ops; + adapter->if_type = ESP_IF_TYPE_SPI; spi_context.adapter = adapter; return spi_init(); -- 2.42.0