radio: iris: Added code for search station list response
This patch adds support to handle the search station list
response event
Signed-off-by: Srinivasa Rao Uppala <uppalas@codeaurora.org>
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 347b113..7a67c4b 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1477,12 +1477,49 @@
iris_q_event(radio, IRIS_EVT_SEEK_COMPLETE);
}
+
+static void iris_q_evt_data(struct iris_device *radio,
+ char *data, int len, int event)
+{
+ struct kfifo *data_b = &radio->data_buf[event];
+ if (kfifo_in_locked(data_b, data, len, &radio->buf_lock[event]))
+ wake_up_interruptible(&radio->event_queue);
+}
static inline void hci_ev_srch_st_list_compl(struct radio_hci_dev *hdev,
struct sk_buff *skb)
{
struct iris_device *radio = video_get_drvdata(video_get_dev());
- struct hci_ev_srch_list_compl *ev = (void *) skb->data;
- radio->srch_st_result = *ev;
+ struct hci_ev_srch_list_compl *ev ;
+ int cnt;
+ int stn_num;
+ int rel_freq;
+ int abs_freq;
+ int len;
+
+ ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev) {
+ FMDERR("Memory allocation failed");
+ return ;
+ }
+
+ ev->num_stations_found = skb->data[STN_NUM_OFFSET];
+ len = ev->num_stations_found * PARAMS_PER_STATION + STN_FREQ_OFFSET;
+
+ for (cnt = STN_FREQ_OFFSET, stn_num = 0;
+ (cnt < len) && (stn_num < ev->num_stations_found);
+ cnt += PARAMS_PER_STATION, stn_num++) {
+ abs_freq = *((int *)&skb->data[cnt]);
+ rel_freq = abs_freq - radio->recv_conf.band_low_limit;
+ rel_freq = (rel_freq * 20) / KHZ_TO_MHZ;
+
+ ev->rel_freq[stn_num].rel_freq_lsb = GET_LSB(rel_freq);
+ ev->rel_freq[stn_num].rel_freq_msb = GET_MSB(rel_freq);
+ }
+
+ len = ev->num_stations_found * 2 + sizeof(ev->num_stations_found);
+ iris_q_event(radio, IRIS_EVT_NEW_SRCH_LIST);
+ iris_q_evt_data(radio, (char *)ev, len, IRIS_BUF_SRCH_LIST);
+ kfree(ev);
}
static inline void hci_ev_search_next(struct radio_hci_dev *hdev,
@@ -1504,16 +1541,6 @@
}
-static void iris_q_rds_data(struct iris_device *radio,
- char *data, int len, int event)
-{
- struct kfifo *data_b = &radio->data_buf[event];
-
- if (kfifo_in_locked(data_b, data, len, &radio->buf_lock[event]))
- wake_up_interruptible(&radio->event_queue);
-}
-
-
static inline void hci_ev_program_service(struct radio_hci_dev *hdev,
struct sk_buff *skb)
{
@@ -1537,7 +1564,7 @@
memcpy(data+RDS_OFFSET, &skb->data[RDS_PS_DATA_OFFSET], len-RDS_OFFSET);
- iris_q_rds_data(radio, data, len, IRIS_BUF_PS_RDS);
+ iris_q_evt_data(radio, data, len, IRIS_BUF_PS_RDS);
kfree(data);
}
@@ -1571,7 +1598,7 @@
memcpy(data+RDS_OFFSET, &skb->data[RDS_OFFSET], len);
data[len+RDS_OFFSET] = 0x00;
- iris_q_rds_data(radio, data, len+RDS_OFFSET, IRIS_BUF_RT_RDS);
+ iris_q_evt_data(radio, data, len+RDS_OFFSET, IRIS_BUF_RT_RDS);
kfree(data);
}
@@ -1625,6 +1652,7 @@
break;
case HCI_EV_SEARCH_LIST_COMPLETE:
+ hci_ev_srch_st_list_compl(hdev, skb);
break;
default:
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index c482fec..845a7c5 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -343,10 +343,14 @@
__le16 status_opcode;
} __packed;
+struct hci_ev_rel_freq {
+ __u8 rel_freq_msb;
+ __u8 rel_freq_lsb;
+
+} __packed;
struct hci_ev_srch_list_compl {
- __u8 status;
__u8 num_stations_found;
- struct hci_ev_srch_st srch_st[20];
+ struct hci_ev_rel_freq rel_freq[20];
} __packed;
/* ----- HCI Event Response ----- */
@@ -551,6 +555,15 @@
/*Search RDS stations*/
#define SEARCH_RDS_STNS_MODE_OFFSET 4
+
+/*Search Station list */
+#define PARAMS_PER_STATION 0x07
+#define STN_NUM_OFFSET 0x01
+#define STN_FREQ_OFFSET 0x02
+#define KHZ_TO_MHZ 1000
+#define GET_MSB(x)((x >> 8) & 0xFF)
+#define GET_LSB(x)((x) & 0xFF)
+
/* control options */
#define CTRL_ON (1)
#define CTRL_OFF (0)