Commit 5c88b021 authored by Pavan Savoy's avatar Pavan Savoy Committed by Greg Kroah-Hartman

drivers:misc: ti-st: register with channel IDs

The architecture of shared transport had begun with individual
protocols like bluetooth, fm and gps telling the shared transport
what sort of protocol they are and then expecting the ST driver
to parse the incoming data from chip and forward data only
relevant to the protocol drivers.

This change would mean each protocol drivers would also send
information to ST driver as to how to intrepret their protocol
data coming out of the chip.
Signed-off-by: default avatarPavan Savoy <pavan_savoy@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6d6a49e9
This diff is collapsed.
......@@ -32,11 +32,7 @@
#include <linux/sched.h>
#include <linux/rfkill.h>
/* understand BT events for fw response */
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci.h>
#include <linux/skbuff.h>
#include <linux/ti_wilink_st.h>
......@@ -134,7 +130,7 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len)
/* Packet header has non-zero payload length and
* we have enough space in created skb. Lets read
* payload data */
kim_gdata->rx_state = ST_BT_W4_DATA;
kim_gdata->rx_state = ST_W4_DATA;
kim_gdata->rx_count = len;
return len;
}
......@@ -158,8 +154,8 @@ void kim_int_recv(struct kim_data_s *kim_gdata,
const unsigned char *data, long count)
{
const unsigned char *ptr;
struct hci_event_hdr *eh;
int len = 0, type = 0;
unsigned char *plen;
pr_debug("%s", __func__);
/* Decode received bytes here */
......@@ -183,29 +179,27 @@ void kim_int_recv(struct kim_data_s *kim_gdata,
/* Check ST RX state machine , where are we? */
switch (kim_gdata->rx_state) {
/* Waiting for complete packet ? */
case ST_BT_W4_DATA:
case ST_W4_DATA:
pr_debug("Complete pkt received");
validate_firmware_response(kim_gdata);
kim_gdata->rx_state = ST_W4_PACKET_TYPE;
kim_gdata->rx_skb = NULL;
continue;
/* Waiting for Bluetooth event header ? */
case ST_BT_W4_EVENT_HDR:
eh = (struct hci_event_hdr *)kim_gdata->
rx_skb->data;
pr_debug("Event header: evt 0x%2.2x"
"plen %d", eh->evt, eh->plen);
kim_check_data_len(kim_gdata, eh->plen);
case ST_W4_HEADER:
plen =
(unsigned char *)&kim_gdata->rx_skb->data[1];
pr_debug("event hdr: plen 0x%02x\n", *plen);
kim_check_data_len(kim_gdata, *plen);
continue;
} /* end of switch */
} /* end of if rx_state */
switch (*ptr) {
/* Bluetooth event packet? */
case HCI_EVENT_PKT:
pr_info("Event packet");
kim_gdata->rx_state = ST_BT_W4_EVENT_HDR;
kim_gdata->rx_count = HCI_EVENT_HDR_SIZE;
type = HCI_EVENT_PKT;
case 0x04:
kim_gdata->rx_state = ST_W4_HEADER;
kim_gdata->rx_count = 2;
type = *ptr;
break;
default:
pr_info("unknown packet");
......@@ -216,16 +210,18 @@ void kim_int_recv(struct kim_data_s *kim_gdata,
ptr++;
count--;
kim_gdata->rx_skb =
bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
alloc_skb(1024+8, GFP_ATOMIC);
if (!kim_gdata->rx_skb) {
pr_err("can't allocate mem for new packet");
kim_gdata->rx_state = ST_W4_PACKET_TYPE;
kim_gdata->rx_count = 0;
return;
}
bt_cb(kim_gdata->rx_skb)->pkt_type = type;
skb_reserve(kim_gdata->rx_skb, 8);
kim_gdata->rx_skb->cb[0] = 4;
kim_gdata->rx_skb->cb[1] = 0;
}
pr_info("done %s", __func__);
return;
}
......@@ -398,7 +394,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW);
break;
case ST_MAX:
case ST_MAX_CHANNELS:
default:
break;
}
......@@ -416,7 +412,6 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count)
struct st_data_s *st_gdata = (struct st_data_s *)disc_data;
struct kim_data_s *kim_gdata = st_gdata->kim_data;
pr_info(" %s ", __func__);
/* copy to local buffer */
if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
/* must be the read_ver_cmd */
......@@ -578,7 +573,7 @@ static int kim_toggle_radio(void *data, bool blocked)
else
st_kim_chip_toggle(type, KIM_GPIO_ACTIVE);
break;
case ST_MAX:
case ST_MAX_CHANNELS:
pr_err(" wrong proto type ");
break;
}
......@@ -664,12 +659,13 @@ static int kim_probe(struct platform_device *pdev)
/* refer to itself */
kim_gdata->core_data->kim_data = kim_gdata;
for (proto = 0; proto < ST_MAX; proto++) {
for (proto = 0; proto < ST_MAX_CHANNELS; proto++) {
kim_gdata->gpios[proto] = gpios[proto];
pr_info(" %ld gpio to be requested", gpios[proto]);
}
for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
for (proto = 0; (proto < ST_MAX_CHANNELS)
&& (gpios[proto] != -1); proto++) {
/* Claim the Bluetooth/FM/GPIO
* nShutdown gpio from the system
*/
......@@ -704,7 +700,8 @@ static int kim_probe(struct platform_device *pdev)
init_completion(&kim_gdata->kim_rcvd);
init_completion(&kim_gdata->ldisc_installed);
for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
for (proto = 0; (proto < ST_MAX_CHANNELS)
&& (gpios[proto] != -1); proto++) {
/* TODO: should all types be rfkill_type_bt ? */
kim_gdata->rf_protos[proto] = proto;
kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto],
......@@ -752,7 +749,8 @@ static int kim_remove(struct platform_device *pdev)
kim_gdata = dev_get_drvdata(&pdev->dev);
for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
for (proto = 0; (proto < ST_MAX_CHANNELS)
&& (gpios[proto] != -1); proto++) {
/* Claim the Bluetooth/FM/GPIO
* nShutdown gpio from the system
*/
......
......@@ -42,7 +42,7 @@ enum proto_type {
ST_BT,
ST_FM,
ST_GPS,
ST_MAX,
ST_MAX_CHANNELS = 16,
};
/**
......@@ -62,6 +62,17 @@ enum proto_type {
* @priv_data: privdate data holder for the protocol drivers, sent
* from the protocol drivers during registration, and sent back on
* reg_complete_cb and recv.
* @chnl_id: channel id the protocol driver is interested in, the channel
* id is nothing but the 1st byte of the packet in UART frame.
* @max_frame_size: size of the largest frame the protocol can receive.
* @hdr_len: length of the header structure of the protocol.
* @offset_len_in_hdr: this provides the offset of the length field in the
* header structure of the protocol header, to assist ST to know
* how much to receive, if the data is split across UART frames.
* @len_size: whether the length field inside the header is 2 bytes
* or 1 byte.
* @reserve: the number of bytes ST needs to reserve in the skb being
* prepared for the protocol driver.
*/
struct st_proto_s {
enum proto_type type;
......@@ -70,10 +81,17 @@ struct st_proto_s {
void (*reg_complete_cb) (void *, char data);
long (*write) (struct sk_buff *skb);
void *priv_data;
unsigned char chnl_id;
unsigned short max_frame_size;
unsigned char hdr_len;
unsigned char offset_len_in_hdr;
unsigned char len_size;
unsigned char reserve;
};
extern long st_register(struct st_proto_s *);
extern long st_unregister(enum proto_type);
extern long st_unregister(struct st_proto_s *);
/*
......@@ -114,6 +132,7 @@ extern long st_unregister(enum proto_type);
* @rx_skb: the skb where all data for a protocol gets accumulated,
* since tty might not call receive when a complete event packet
* is received, the states, count and the skb needs to be maintained.
* @rx_chnl: the channel ID for which the data is getting accumalated for.
* @txq: the list of skbs which needs to be sent onto the TTY.
* @tx_waitq: if the chip is not in AWAKE state, the skbs needs to be queued
* up in here, PM(WAKEUP_IND) data needs to be sent and then the skbs
......@@ -135,10 +154,11 @@ struct st_data_s {
#define ST_TX_SENDING 1
#define ST_TX_WAKEUP 2
unsigned long tx_state;
struct st_proto_s *list[ST_MAX];
struct st_proto_s *list[ST_MAX_CHANNELS];
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
unsigned char rx_chnl;
struct sk_buff_head txq, tx_waitq;
spinlock_t lock;
unsigned char protos_registered;
......@@ -243,12 +263,12 @@ struct kim_data_s {
struct completion kim_rcvd, ldisc_installed;
char resp_buffer[30];
const struct firmware *fw_entry;
long gpios[ST_MAX];
long gpios[ST_MAX_CHANNELS];
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
struct rfkill *rfkill[ST_MAX];
enum proto_type rf_protos[ST_MAX];
struct rfkill *rfkill[ST_MAX_CHANNELS];
enum proto_type rf_protos[ST_MAX_CHANNELS];
struct st_data_s *core_data;
struct chip_version version;
};
......@@ -338,12 +358,8 @@ struct hci_command {
/* ST LL receiver states */
#define ST_W4_PACKET_TYPE 0
#define ST_BT_W4_EVENT_HDR 1
#define ST_BT_W4_ACL_HDR 2
#define ST_BT_W4_SCO_HDR 3
#define ST_BT_W4_DATA 4
#define ST_FM_W4_EVENT_HDR 5
#define ST_GPS_W4_EVENT_HDR 6
#define ST_W4_HEADER 1
#define ST_W4_DATA 2
/* ST LL state machines */
#define ST_LL_ASLEEP 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment