Texas instrument ' s Bluetooth Driver for Shared Transport notes

Source: Internet
Author: User

Bluetooth Driver acts as interface between HCI Core and TI Shared Transport Layer.

/DRIVERS/BLUETOOTH/BTWILINK.C:

#include <linux/platform_device.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_ core.h> #include <net/bluetooth/hci.h> #include <linux/ti_wilink_st.h> #include <linux/module.h > #define Debug#define VERSION               "1.0" #define Max_bt_chnl_ids3#define bt_register_timeout 6000
struct Ti_st {struct Hci_dev *hdev;char reg_status;long (*st_write) (struct sk_buff *); struct completion Wait_reg_complet Ion;};
struct Ti_st-module operation structure Body
@hdev: The HCI device pointer is bound to the Bluetooth module
@reg_status: ST Registration return status
@st_write: Write function used by send_frame
@wait_reg_completion end synchronization between-ti_st_open and ST_REG_COMPLETION_CB

static inline void Ti_st_tx_complete (struct ti_st *hst, int pkt_type) {struct Hci_dev *hdev = hst->hdev;/* Update HCI St At Counters */switch (pkt_type) {case Hci_command_pkt:hdev->stat.cmd_tx++;break;case hci_acldata_pkt:hdev-> Stat.acl_tx++;break;case Hci_scodata_pkt:hdev->stat.sco_tx++;break;}}
Pocket ID (Cmd,acl,sco) Count
static void St_reg_completion_cb (void *priv_data, char data) {struct Ti_st *lhst = priv_data;/* Save registration status fo R use in Ti_st_open () */lhst->reg_status = data;/* Complete the wait in Ti_st_open () */complete (&lhst->wait_reg_ completion);}
The Status.ti_st_open () function waits for the st_pending signal returned by the St_register ()

static long st_receive (void *priv_data, struct sk_buff *skb) {struct Ti_st *lhst = Priv_data;int err;if (!SKB) Return-efaul T;if (!lhst) {KFREE_SKB (SKB); return-efault;} Skb->dev = (void *) lhst->hdev;/* Forward SKB to HCI core layer */err = Hci_recv_frame (SKB); if (Err < 0) {Bt_err ( "Unable to push SKB to HCI core (%d)", err); return err;} Lhst->hdev->stat.byte_rx + = Skb->len;return 0;}
Called by the shared transport layer when data is received
static struct st_proto_s Ti_st_proto[max_bt_chnl_ids] = {{. chnl_id = hci_event_pkt,/* HCI Events */.hdr_len = sizeof (Stru CT Hci_event_hdr),. Offset_len_in_hdr = Offsetof (struct HCI_EVENT_HDR, Plen),. len_size = 1,/* sizeof (Plen) in struct hci_e  Vent_hdr */.reserve = 8,},{.chnl_id = hci_acldata_pkt,/* ACL */.hdr_len = sizeof (struct HCI_ACL_HDR),. Offset_len_in_hdr = Offsetof (struct HCI_ACL_HDR, Dlen),. len_size = 2,/* sizeof (dlen) in struct hci_acl_hdr */.reserve = 8,},{.chnl_id = hci_s CODATA_PKT,/* SCO */.hdr_len = sizeof (struct HCI_SCO_HDR),. Offset_len_in_hdr = Offsetof (struct HCI_SCO_HDR, Dlen),. Len_ Size = 1,/* sizeof (Dlen) in struct HCI_SCO_HDR */.reserve = 8,},};
interface of the HCI layer

Definition of struct st_proto_s:/include/linux/ti_wilink_st.h:

struct st_proto_s {
    enum proto_type type;
    long (*RECV) (void *, struct sk_buff *);
    unsigned char (*match_packet) (const unsigned char *data);
    void (*REG_COMPLETE_CB) (void *, char data);
    long (*write) (struct sk_buff *skb);
    void *priv_data;
    unsigned Char chnl_id;
    unsigned The size of the maximum frame max_frame_size; //can receive
    unsigned char Hdr_len;    //Head structure length
    unsigned char offset_len_in_hdr;   //provides length offset in the header structure
    unsigned char len_size;  //2 byte or 1 bytes
    unsigned Char reserve;   //st the number of bytes to swap};

static int Ti_st_open (struct Hci_dev *hdev) {unsigned long timeleft;struct ti_st *hst;int err, I; bt_dbg ("%s%p", Hdev->name, Hdev); if (Test_and_set_bit (hci_running, &hdev->flags)) return-ebusy;/* provide Contexts for callbacks from ST */hst = hdev->driver_data;for (i = 0; i < max_bt_chnl_ids; i++) {ti_st_proto[i].priv_ data = Hst;ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE;TI_ST_PROTO[I].RECV = St_receive;ti_st_proto[i].reg_ COMPLETE_CB = st_reg_completion_cb;/* Prepare wait-for-completion handler */init_completion (&hst->wait_reg_ completion);/* Reset ST Registration callback status Flag, * This value would be updated in * ST_REG_COMPLETION_CB () * func tion whenever it called from ST driver. */hst->reg_status =-einprogress;err = St_register (&ti_st_proto[i]), if (!err) goto done;if (Err! =-EINPROGRESS) { Clear_bit (hci_running, &hdev->flags); Bt_err ("St_register failed%d", err); return err;} /* ST is busy with either protocol * registration or firmwareDownload. */bt_dbg ("Waiting for Registration", "completion signal from ST"); timeleft = Wait_for_completion_timeout (&hst-> Wait_reg_completion, Msecs_to_jiffies (bt_register_timeout)); if (!timeleft) {clear_bit (hci_running, &hdev-> Flags); Bt_err ("Timeout (%d sec), didn ' t get reg" "Completion signal from ST", bt_register_timeout/1000); return-etimedout;} /* is ST registration callback * called with ERROR status? */if (Hst->reg_status! = 0) {clear_bit (hci_running, &hdev->flags); Bt_err ("ST registration completed with invalid" "Status%d", hst->reg_status); return-eagain;} Done:hst->st_write = Ti_st_proto[i].write;if (!hst->st_write) {bt_err ("Undefined st write function"); Clear_bit ( Hci_running, &hdev->flags); for (i = 0; i < max_bt_chnl_ids; i++) {/* Undo registration with ST */err = St_unregi Ster (&ti_st_proto[i]); if (err) Bt_err ("St_unregister () failed with" "Error%d", err); hst->st_write = NULL;} Return-eio;}} return 0;}
HCI Core invocation, initializing the device

static int ti_st_close (struct Hci_dev *hdev) {int err, i;struct ti_st *hst = hdev->driver_data;if (!test_and_clear_bit ( Hci_running, &hdev->flags)) return 0;for (i = max_bt_chnl_ids-1; I >= 0; i--) {err = St_unregister (&ti_st_pro To[i]); if (err) Bt_err ("St_unregister (%d) failed with error%d", ti_st_proto[i].chnl_id, err);} Hst->st_write = Null;return err;}
Turn off the device

static int ti_st_send_frame (struct sk_buff *skb) {struct Hci_dev *hdev;struct ti_st *hst;long len;hdev = (struct Hci_dev *) Skb->dev;if (!test_bit (hci_running, &hdev->flags)) Return-ebusy;hst = hdev->driver_data;/* Prepend SKB With frame type */memcpy (Skb_push (SKB, 1), &AMP;BT_CB (SKB)->pkt_type, 1);  bt_dbg ("%s:type%d len%d", Hdev->name, BT_CB (SKB)->pkt_type,skb->len);/* Insert SKB to shared transport layer ' s Transmit queue. * Freeing SKB memory is taken care on shared transport layer, * so don ' t free SKB memory here. */len = Hst->st_write (SKB), if (Len < 0) {KFREE_SKB (SKB); Bt_err ("ST Write Failed (%ld)", Len);/* Try Again, would only fail if UART have gone bad */return-eagain;} /* ST accepted our SKB. So, Go ahead and do rest */hdev->stat.byte_tx + = Len;ti_st_tx_complete (HST, BT_CB (SKB)->pkt_type); return 0;} static void Ti_st_destruct (struct Hci_dev *hdev) {bt_dbg ("%s", hdev->name);/* do nothing here, since platform remove * w Ould Free the Hdev->dRiver_data */} 
Send Frame

static int bt_ti_probe (struct platform_device *pdev) {static struct Ti_st *hst;struct hci_dev *hdev;int err;hst = Kzalloc (s  izeof (struct ti_st), Gfp_kernel), if (!hst) return-enomem;/* Expose "HCIX" device to user space */hdev = Hci_alloc_dev (); if (!hdev) {Kfree (HST); return-enomem;} bt_dbg ("Hdev%p", hdev); Hst->hdev = Hdev;hdev->bus = Hci_uart;hdev->driver_data = Hst;hdev->open = Ti_st_ Open;hdev->close = Ti_st_close;hdev->flush = Null;hdev->send = Ti_st_send_frame;hdev->destruct = Ti_st_ Destruct;hdev->owner = This_module;err = Hci_register_dev (Hdev), if (Err < 0) {Bt_err ("Can ' t register HCI device Erro R%d ", err); Kfree (HST); Hci_free_dev (Hdev); return err;} bt_dbg ("HCI device registered (Hdev%p)", Hdev);d ev_set_drvdata (&pdev->dev, HST); return err;}
Device detection

static int bt_ti_remove (struct platform_device *pdev) {struct Hci_dev *hdev;struct ti_st *hst = Dev_get_drvdata (& Pdev->dev); if (!hst) Return-efault; bt_dbg ("%s", hst->hdev->name); Hdev = Hst->hdev;ti_st_close (Hdev); Hci_unregister_dev (Hdev); Hci_free_dev ( Hdev); Kfree (HST);d ev_set_drvdata (&pdev->dev, NULL); return 0;}
Device Uninstall

static struct Platform_driver Btwilink_driver = {. Probe = Bt_ti_probe,.remove = Bt_ti_remove,.driver = {. Name = "Btwilink" ,. Owner = This_module,},};
Platform Driver

static int __init btwilink_init (void) {Bt_info ("Bluetooth Driver for TI wilink-version%s", Version); return Platform_driv Er_register (&btwilink_driver);} static void __exit btwilink_exit (void) {platform_driver_unregister (&btwilink_driver);} Module_init (Btwilink_init); Module_exit (Btwilink_exit);
Device Init and exit
Module_author ("Raja Mani <[email protected]>"); Module_description ("Bluetooth Driver for TI Shared Transport" VERSION); Module_version (VERSION); Module_license ("GPL");

Texas instrument ' s Bluetooth Driver for Shared Transport notes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.