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)