blob: 7a67c4b3366b6d9df886b3e5e55084fd62205f1f [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define DRIVER_AUTHOR "Archana Ramchandran <archanar@codeaurora.org>"
14#define DRIVER_NAME "radio-iris"
15#define DRIVER_CARD "Qualcomm FM Radio Transceiver"
16#define DRIVER_DESC "Driver for Qualcomm FM Radio Transceiver "
17
18#include <linux/version.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/uaccess.h>
22#include <linux/kfifo.h>
23#include <linux/param.h>
24#include <linux/interrupt.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/version.h>
28#include <linux/videodev2.h>
29#include <linux/mutex.h>
30#include <linux/unistd.h>
31#include <linux/atomic.h>
32#include <linux/platform_device.h>
33#include <linux/workqueue.h>
34#include <linux/slab.h>
35#include <media/v4l2-common.h>
36#include <media/v4l2-ioctl.h>
37#include <media/radio-iris.h>
38#include <asm/unaligned.h>
39
40static unsigned int rds_buf = 100;
41module_param(rds_buf, uint, 0);
42MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
43
44static void radio_hci_cmd_task(unsigned long arg);
45static void radio_hci_rx_task(unsigned long arg);
46static struct video_device *video_get_dev(void);
47static DEFINE_RWLOCK(hci_task_lock);
48
49struct iris_device {
50 struct device *dev;
51 struct kfifo data_buf[IRIS_BUF_MAX];
52
53 int pending_xfrs[IRIS_XFR_MAX];
54 int xfr_bytes_left;
55 int xfr_in_progress;
56 struct completion sync_xfr_start;
57 int tune_req;
58
59 struct video_device *videodev;
60
61 struct mutex lock;
62 spinlock_t buf_lock[IRIS_BUF_MAX];
63 wait_queue_head_t event_queue;
64 wait_queue_head_t read_queue;
65
66 struct radio_hci_dev *fm_hdev;
67
68 struct v4l2_capability *g_cap;
69 struct v4l2_control *g_ctl;
70
71 struct hci_fm_mute_mode_req mute_mode;
72 struct hci_fm_stereo_mode_req stereo_mode;
73 struct hci_fm_station_rsp fm_st_rsp;
74 struct hci_fm_search_station_req srch_st;
75 struct hci_fm_search_rds_station_req srch_rds;
76 struct hci_fm_search_station_list_req srch_st_list;
77 struct hci_fm_recv_conf_req recv_conf;
78 struct hci_fm_rds_grp_req rds_grp;
79 unsigned char g_search_mode;
80 unsigned char g_scan_time;
81 unsigned int g_antenna;
82 unsigned int g_rds_grp_proc_ps;
83 enum iris_region_t region;
84 struct hci_fm_dbg_param_rsp st_dbg_param;
85 struct hci_ev_srch_list_compl srch_st_result;
86};
87
88static struct video_device *priv_videodev;
89
90static struct v4l2_queryctrl iris_v4l2_queryctrl[] = {
91 {
92 .id = V4L2_CID_AUDIO_VOLUME,
93 .type = V4L2_CTRL_TYPE_INTEGER,
94 .name = "Volume",
95 .minimum = 0,
96 .maximum = 15,
97 .step = 1,
98 .default_value = 15,
99 },
100 {
101 .id = V4L2_CID_AUDIO_BALANCE,
102 .flags = V4L2_CTRL_FLAG_DISABLED,
103 },
104 {
105 .id = V4L2_CID_AUDIO_BASS,
106 .flags = V4L2_CTRL_FLAG_DISABLED,
107 },
108 {
109 .id = V4L2_CID_AUDIO_TREBLE,
110 .flags = V4L2_CTRL_FLAG_DISABLED,
111 },
112 {
113 .id = V4L2_CID_AUDIO_MUTE,
114 .type = V4L2_CTRL_TYPE_BOOLEAN,
115 .name = "Mute",
116 .minimum = 0,
117 .maximum = 1,
118 .step = 1,
119 .default_value = 1,
120 },
121 {
122 .id = V4L2_CID_AUDIO_LOUDNESS,
123 .flags = V4L2_CTRL_FLAG_DISABLED,
124 },
125 {
126 .id = V4L2_CID_PRIVATE_IRIS_SRCHMODE,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Search mode",
129 .minimum = 0,
130 .maximum = 7,
131 .step = 1,
132 .default_value = 0,
133 },
134 {
135 .id = V4L2_CID_PRIVATE_IRIS_SCANDWELL,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Search dwell time",
138 .minimum = 0,
139 .maximum = 7,
140 .step = 1,
141 .default_value = 0,
142 },
143 {
144 .id = V4L2_CID_PRIVATE_IRIS_SRCHON,
145 .type = V4L2_CTRL_TYPE_BOOLEAN,
146 .name = "Search on/off",
147 .minimum = 0,
148 .maximum = 1,
149 .step = 1,
150 .default_value = 1,
151
152 },
153 {
154 .id = V4L2_CID_PRIVATE_IRIS_STATE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "radio 0ff/rx/tx/reset",
157 .minimum = 0,
158 .maximum = 3,
159 .step = 1,
160 .default_value = 1,
161
162 },
163 {
164 .id = V4L2_CID_PRIVATE_IRIS_REGION,
165 .type = V4L2_CTRL_TYPE_INTEGER,
166 .name = "radio standard",
167 .minimum = 0,
168 .maximum = 2,
169 .step = 1,
170 .default_value = 0,
171 },
172 {
173 .id = V4L2_CID_PRIVATE_IRIS_SIGNAL_TH,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "Signal Threshold",
176 .minimum = 0x80,
177 .maximum = 0x7F,
178 .step = 1,
179 .default_value = 0,
180 },
181 {
182 .id = V4L2_CID_PRIVATE_IRIS_SRCH_PTY,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Search PTY",
185 .minimum = 0,
186 .maximum = 31,
187 .default_value = 0,
188 },
189 {
190 .id = V4L2_CID_PRIVATE_IRIS_SRCH_PI,
191 .type = V4L2_CTRL_TYPE_INTEGER,
192 .name = "Search PI",
193 .minimum = 0,
194 .maximum = 0xFF,
195 .default_value = 0,
196 },
197 {
198 .id = V4L2_CID_PRIVATE_IRIS_SRCH_CNT,
199 .type = V4L2_CTRL_TYPE_INTEGER,
200 .name = "Preset num",
201 .minimum = 0,
202 .maximum = 12,
203 .default_value = 0,
204 },
205 {
206 .id = V4L2_CID_PRIVATE_IRIS_EMPHASIS,
207 .type = V4L2_CTRL_TYPE_BOOLEAN,
208 .name = "Emphasis",
209 .minimum = 0,
210 .maximum = 1,
211 .default_value = 0,
212 },
213 {
214 .id = V4L2_CID_PRIVATE_IRIS_RDS_STD,
215 .type = V4L2_CTRL_TYPE_BOOLEAN,
216 .name = "RDS standard",
217 .minimum = 0,
218 .maximum = 1,
219 .default_value = 0,
220 },
221 {
222 .id = V4L2_CID_PRIVATE_IRIS_SPACING,
223 .type = V4L2_CTRL_TYPE_INTEGER,
224 .name = "Channel spacing",
225 .minimum = 0,
226 .maximum = 2,
227 .default_value = 0,
228 },
229 {
230 .id = V4L2_CID_PRIVATE_IRIS_RDSON,
231 .type = V4L2_CTRL_TYPE_BOOLEAN,
232 .name = "RDS on/off",
233 .minimum = 0,
234 .maximum = 1,
235 .default_value = 0,
236 },
237 {
238 .id = V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK,
239 .type = V4L2_CTRL_TYPE_INTEGER,
240 .name = "RDS group mask",
241 .minimum = 0,
242 .maximum = 0xFFFFFFFF,
243 .default_value = 0,
244 },
245 {
246 .id = V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC,
247 .type = V4L2_CTRL_TYPE_INTEGER,
248 .name = "RDS processing",
249 .minimum = 0,
250 .maximum = 0xFF,
251 .default_value = 0,
252 },
253 {
254 .id = V4L2_CID_PRIVATE_IRIS_RDSD_BUF,
255 .type = V4L2_CTRL_TYPE_INTEGER,
256 .name = "RDS data groups to buffer",
257 .minimum = 1,
258 .maximum = 21,
259 .default_value = 0,
260 },
261 {
262 .id = V4L2_CID_PRIVATE_IRIS_PSALL,
263 .type = V4L2_CTRL_TYPE_BOOLEAN,
264 .name = "pass all ps strings",
265 .minimum = 0,
266 .maximum = 1,
267 .default_value = 0,
268 },
269 {
270 .id = V4L2_CID_PRIVATE_IRIS_LP_MODE,
271 .type = V4L2_CTRL_TYPE_BOOLEAN,
272 .name = "Low power mode",
273 .minimum = 0,
274 .maximum = 1,
275 .default_value = 0,
276 },
277 {
278 .id = V4L2_CID_PRIVATE_IRIS_ANTENNA,
279 .type = V4L2_CTRL_TYPE_BOOLEAN,
280 .name = "headset/internal",
281 .minimum = 0,
282 .maximum = 1,
283 .default_value = 0,
284 },
285
286 {
287 .id = V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT,
288 .type = V4L2_CTRL_TYPE_INTEGER,
289 .name = "Set PS REPEATCOUNT",
290 .minimum = 0,
291 .maximum = 15,
292 },
293 {
294 .id = V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME,
295 .type = V4L2_CTRL_TYPE_BOOLEAN,
296 .name = "Stop PS NAME",
297 .minimum = 0,
298 .maximum = 1,
299 },
300 {
301 .id = V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT,
302 .type = V4L2_CTRL_TYPE_BOOLEAN,
303 .name = "Stop RT",
304 .minimum = 0,
305 .maximum = 1,
306 },
307
308};
309
310static void iris_q_event(struct iris_device *radio,
311 enum iris_evt_t event)
312{
313 struct kfifo *data_b = &radio->data_buf[IRIS_BUF_EVENTS];
314 unsigned char evt = event;
315 if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[IRIS_BUF_EVENTS]))
316 wake_up_interruptible(&radio->event_queue);
317}
318
319static int hci_send_frame(struct sk_buff *skb)
320{
321 struct radio_hci_dev *hdev = (struct radio_hci_dev *) skb->dev;
322
323 if (!hdev) {
324 kfree_skb(skb);
325 return -ENODEV;
326 }
327
328 __net_timestamp(skb);
329
330 skb_orphan(skb);
331 return hdev->send(skb);
332}
333
334static void radio_hci_cmd_task(unsigned long arg)
335{
336 struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
337 struct sk_buff *skb;
338 if (!(atomic_read(&hdev->cmd_cnt))
339 && time_after(jiffies, hdev->cmd_last_tx + HZ)) {
340 FMDERR("%s command tx timeout", hdev->name);
341 atomic_set(&hdev->cmd_cnt, 1);
342 }
343
344 skb = skb_dequeue(&hdev->cmd_q);
345 if (atomic_read(&hdev->cmd_cnt) && skb) {
346 kfree_skb(hdev->sent_cmd);
347 hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
348 if (hdev->sent_cmd) {
349 atomic_dec(&hdev->cmd_cnt);
350 hci_send_frame(skb);
351 hdev->cmd_last_tx = jiffies;
352 } else {
353 skb_queue_head(&hdev->cmd_q, skb);
354 tasklet_schedule(&hdev->cmd_task);
355 }
356 }
357
358}
359
360static void radio_hci_rx_task(unsigned long arg)
361{
362 struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
363 struct sk_buff *skb;
364
365 read_lock(&hci_task_lock);
366
367 skb = skb_dequeue(&hdev->rx_q);
368 radio_hci_event_packet(hdev, skb);
369
370 read_unlock(&hci_task_lock);
371}
372
373int radio_hci_register_dev(struct radio_hci_dev *hdev)
374{
375 struct iris_device *radio = video_get_drvdata(video_get_dev());
376 if (!radio) {
377 FMDERR(":radio is null");
378 return -EINVAL;
379 }
380
381 if (!hdev) {
382 FMDERR("hdev is null");
383 return -EINVAL;
384 }
385
386 hdev->flags = 0;
387
388 tasklet_init(&hdev->cmd_task, radio_hci_cmd_task, (unsigned long)
389 hdev);
390 tasklet_init(&hdev->rx_task, radio_hci_rx_task, (unsigned long)
391 hdev);
392
393 init_waitqueue_head(&hdev->req_wait_q);
394
395 skb_queue_head_init(&hdev->rx_q);
396 skb_queue_head_init(&hdev->cmd_q);
397 skb_queue_head_init(&hdev->raw_q);
398
399 if (!radio)
400 FMDERR(":radio is null");
401
402 radio->fm_hdev = hdev;
403
404 return 0;
405}
406EXPORT_SYMBOL(radio_hci_register_dev);
407
408int radio_hci_unregister_dev(struct radio_hci_dev *hdev)
409{
410 struct iris_device *radio = video_get_drvdata(video_get_dev());
411 if (!radio) {
412 FMDERR(":radio is null");
413 return -EINVAL;
414 }
415
416 tasklet_kill(&hdev->rx_task);
417 tasklet_kill(&hdev->cmd_task);
418 skb_queue_purge(&hdev->rx_q);
419 skb_queue_purge(&hdev->cmd_q);
420 skb_queue_purge(&hdev->raw_q);
421 kfree(radio->fm_hdev);
422 kfree(radio->videodev);
423
424 return 0;
425}
426EXPORT_SYMBOL(radio_hci_unregister_dev);
427
428int radio_hci_recv_frame(struct sk_buff *skb)
429{
430 struct radio_hci_dev *hdev = (struct radio_hci_dev *) skb->dev;
431 if (!hdev) {
432 FMDERR("%s hdev is null while receiving frame", hdev->name);
433 kfree_skb(skb);
434 return -ENXIO;
435 }
436
437 __net_timestamp(skb);
438
439 radio_hci_event_packet(hdev, skb);
440
441 return 0;
442}
443EXPORT_SYMBOL(radio_hci_recv_frame);
444
445int radio_hci_send_cmd(struct radio_hci_dev *hdev, __u16 opcode, __u32 plen,
446 void *param)
447{
448 int len = RADIO_HCI_COMMAND_HDR_SIZE + plen;
449 struct radio_hci_command_hdr *hdr;
450 struct sk_buff *skb;
451 int ret = 0;
452
453 skb = alloc_skb(len, GFP_ATOMIC);
454 if (!skb) {
455 FMDERR("%s no memory for command", hdev->name);
456 return -ENOMEM;
457 }
458
459 hdr = (struct radio_hci_command_hdr *) skb_put(skb,
460 RADIO_HCI_COMMAND_HDR_SIZE);
461 hdr->opcode = cpu_to_le16(opcode);
462 hdr->plen = plen;
463
464 if (plen)
465 memcpy(skb_put(skb, plen), param, plen);
466
467 skb->dev = (void *) hdev;
468
469 ret = hci_send_frame(skb);
470
471 return ret;
472}
473EXPORT_SYMBOL(radio_hci_send_cmd);
474
475static int hci_fm_enable_recv_req(struct radio_hci_dev *hdev,
476 unsigned long param)
477{
478 __u16 opcode = 0;
479
480 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
481 HCI_OCF_FM_ENABLE_RECV_REQ);
482 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
483}
484
485static int hci_fm_disable_recv_req(struct radio_hci_dev *hdev,
486 unsigned long param)
487{
488 __u16 opcode = 0;
489
490 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
491 HCI_OCF_FM_DISABLE_RECV_REQ);
492 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
493}
494
495static int hci_get_fm_recv_conf_req(struct radio_hci_dev *hdev,
496 unsigned long param)
497{
498 __u16 opcode = 0;
499
500 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
501 HCI_OCF_FM_GET_RECV_CONF_REQ);
502 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
503}
504
505static int hci_set_fm_recv_conf_req(struct radio_hci_dev *hdev,
506 unsigned long param)
507{
508 __u16 opcode = 0;
509
510 struct hci_fm_recv_conf_req *recv_conf_req =
511 (struct hci_fm_recv_conf_req *) param;
512
513 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
514 HCI_OCF_FM_SET_RECV_CONF_REQ);
515 return radio_hci_send_cmd(hdev, opcode, sizeof((*recv_conf_req)),
516 recv_conf_req);
517}
518
519static int hci_fm_get_station_param_req(struct radio_hci_dev *hdev,
520 unsigned long param)
521{
522 __u16 opcode = 0;
523
524 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
525 HCI_OCF_FM_GET_STATION_PARAM_REQ);
526 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
527}
528
529static int hci_set_fm_mute_mode_req(struct radio_hci_dev *hdev,
530 unsigned long param)
531{
532 __u16 opcode = 0;
533 struct hci_fm_mute_mode_req *mute_mode_req =
534 (struct hci_fm_mute_mode_req *) param;
535
536 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
537 HCI_OCF_FM_SET_MUTE_MODE_REQ);
538 return radio_hci_send_cmd(hdev, opcode, sizeof((*mute_mode_req)),
539 mute_mode_req);
540}
541
542static int hci_set_fm_stereo_mode_req(struct radio_hci_dev *hdev,
543 unsigned long param)
544{
545 __u16 opcode = 0;
546 struct hci_fm_stereo_mode_req *stereo_mode_req =
547 (struct hci_fm_stereo_mode_req *) param;
548 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
549 HCI_OCF_FM_SET_STEREO_MODE_REQ);
550 return radio_hci_send_cmd(hdev, opcode, sizeof((*stereo_mode_req)),
551 stereo_mode_req);
552}
553
554static int hci_fm_set_antenna_req(struct radio_hci_dev *hdev,
555 unsigned long param)
556{
557 __u16 opcode = 0;
558
559 __u8 antenna = param;
560
561 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
562 HCI_OCF_FM_SET_ANTENNA);
563 return radio_hci_send_cmd(hdev, opcode, sizeof(antenna), &antenna);
564}
565
566static int hci_fm_set_sig_threshold_req(struct radio_hci_dev *hdev,
567 unsigned long param)
568{
569 __u16 opcode = 0;
570
571 __u8 sig_threshold = param;
572
573 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
574 HCI_OCF_FM_SET_SIGNAL_THRESHOLD);
575 return radio_hci_send_cmd(hdev, opcode, sizeof(sig_threshold),
576 &sig_threshold);
577}
578
579static int hci_fm_get_sig_threshold_req(struct radio_hci_dev *hdev,
580 unsigned long param)
581{
582 __u16 opcode = 0;
583
584 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
585 HCI_OCF_FM_GET_SIGNAL_THRESHOLD);
586 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
587}
588
589static int hci_fm_get_program_service_req(struct radio_hci_dev *hdev,
590 unsigned long param)
591{
592 __u16 opcode = 0;
593
594 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
595 HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ);
596 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
597}
598
599static int hci_fm_get_radio_text_req(struct radio_hci_dev *hdev,
600 unsigned long param)
601{
602 __u16 opcode = 0;
603
604 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
605 HCI_OCF_FM_GET_RADIO_TEXT_REQ);
606 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
607}
608
609static int hci_fm_get_af_list_req(struct radio_hci_dev *hdev,
610 unsigned long param)
611{
612 __u16 opcode = 0;
613
614 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
615 HCI_OCF_FM_GET_AF_LIST_REQ);
616 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
617}
618
619static int hci_fm_search_stations_req(struct radio_hci_dev *hdev,
620 unsigned long param)
621{
622 __u16 opcode = 0;
623 struct hci_fm_search_station_req *srch_stations =
624 (struct hci_fm_search_station_req *) param;
625
626 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
627 HCI_OCF_FM_SEARCH_STATIONS);
628 return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
629 srch_stations);
630}
631
632static int hci_fm_srch_rds_stations_req(struct radio_hci_dev *hdev,
633 unsigned long param)
634{
635 __u16 opcode = 0;
636 struct hci_fm_search_rds_station_req *srch_stations =
637 (struct hci_fm_search_rds_station_req *) param;
638
639 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
640 HCI_OCF_FM_SEARCH_RDS_STATIONS);
641 return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
642 srch_stations);
643}
644
645static int hci_fm_srch_station_list_req(struct radio_hci_dev *hdev,
646 unsigned long param)
647{
648 __u16 opcode = 0;
649 struct hci_fm_search_station_list_req *srch_list =
650 (struct hci_fm_search_station_list_req *) param;
651
652 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
653 HCI_OCF_FM_SEARCH_STATIONS_LIST);
654 return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_list)),
655 srch_list);
656}
657
658static int hci_fm_cancel_search_req(struct radio_hci_dev *hdev,
659 unsigned long param)
660{
661 __u16 opcode = 0;
662
663 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
664 HCI_OCF_FM_CANCEL_SEARCH);
665 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
666}
667
668static int hci_fm_rds_grp_process_req(struct radio_hci_dev *hdev,
669 unsigned long param)
670{
671 __u16 opcode = 0;
672
673 __u32 fm_grps_process = param;
674
675 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
676 HCI_OCF_FM_RDS_GRP_PROCESS);
677 return radio_hci_send_cmd(hdev, opcode, sizeof(fm_grps_process),
678 &fm_grps_process);
679}
680
681static int hci_fm_tune_station_req(struct radio_hci_dev *hdev,
682 unsigned long param)
683{
684 __u16 opcode = 0;
685
686 __u32 tune_freq = param;
687
688 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
689 HCI_OCF_FM_TUNE_STATION_REQ);
690 return radio_hci_send_cmd(hdev, opcode, sizeof(tune_freq), &tune_freq);
691}
692
693static int hci_def_data_read_req(struct radio_hci_dev *hdev,
694 unsigned long param)
695{
696 __u16 opcode = 0;
697 struct hci_fm_def_data_rd_req *def_data_rd =
698 (struct hci_fm_def_data_rd_req *) param;
699
700 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
701 HCI_OCF_FM_DEFAULT_DATA_READ);
702 return radio_hci_send_cmd(hdev, opcode, sizeof((*def_data_rd)),
703 def_data_rd);
704}
705
706static int hci_def_data_write_req(struct radio_hci_dev *hdev,
707 unsigned long param)
708{
709 __u16 opcode = 0;
710 struct hci_fm_def_data_wr_req *def_data_wr =
711 (struct hci_fm_def_data_wr_req *) param;
712
713 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
714 HCI_OCF_FM_DEFAULT_DATA_WRITE);
715 return radio_hci_send_cmd(hdev, opcode, sizeof((*def_data_wr)),
716 def_data_wr);
717}
718
719static int hci_fm_reset_req(struct radio_hci_dev *hdev, unsigned long param)
720{
721 __u16 opcode = 0;
722
723 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
724 HCI_OCF_FM_RESET);
725 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
726}
727
728static int hci_fm_get_feature_lists_req(struct radio_hci_dev *hdev,
729 unsigned long param)
730{
731 __u16 opcode = 0;
732
733 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
734 HCI_OCF_FM_GET_FEATURE_LIST);
735 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
736}
737
738static int hci_fm_do_calibration_req(struct radio_hci_dev *hdev,
739 unsigned long param)
740{
741 __u16 opcode = 0;
742
743 __u8 mode = param;
744
745 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
746 HCI_OCF_FM_DO_CALIBRATION);
747 return radio_hci_send_cmd(hdev, opcode, sizeof(mode), &mode);
748}
749
750static int hci_read_grp_counters_req(struct radio_hci_dev *hdev,
751 unsigned long param)
752{
753 __u16 opcode = 0;
754
755 __u8 reset_counters = param;
756
757 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
758 HCI_OCF_FM_READ_GRP_COUNTERS);
759 return radio_hci_send_cmd(hdev, opcode, sizeof(reset_counters),
760 &reset_counters);
761}
762
763static int hci_peek_data_req(struct radio_hci_dev *hdev, unsigned long param)
764{
765 __u16 opcode = 0;
766 struct hci_fm_peek_req *peek_data = (struct hci_fm_peek_req *) param;
767
768 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
769 HCI_OCF_FM_PEEK_DATA);
770 return radio_hci_send_cmd(hdev, opcode, sizeof((*peek_data)),
771 peek_data);
772}
773
774static int hci_poke_data_req(struct radio_hci_dev *hdev, unsigned long param)
775{
776 __u16 opcode = 0;
777 struct hci_fm_poke_req *poke_data = (struct hci_fm_poke_req *) param;
778
779 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
780 HCI_OCF_FM_POKE_DATA);
781 return radio_hci_send_cmd(hdev, opcode, sizeof((*poke_data)),
782 poke_data);
783}
784
785static int hci_ssbi_peek_reg_req(struct radio_hci_dev *hdev,
786 unsigned long param)
787{
788 __u16 opcode = 0;
789 struct hci_fm_ssbi_req *ssbi_peek = (struct hci_fm_ssbi_req *) param;
790
791 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
792 HCI_OCF_FM_SSBI_PEEK_REG);
793 return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_peek)),
794 ssbi_peek);
795}
796
797static int hci_ssbi_poke_reg_req(struct radio_hci_dev *hdev,
798 unsigned long param)
799{
800 __u16 opcode = 0;
801 struct hci_fm_ssbi_req *ssbi_poke = (struct hci_fm_ssbi_req *) param;
802
803 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
804 HCI_OCF_FM_SSBI_POKE_REG);
805 return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_poke)),
806 ssbi_poke);
807}
808
809static int hci_fm_get_station_dbg_param_req(struct radio_hci_dev *hdev,
810 unsigned long param)
811{
812 __u16 opcode = 0;
813
814 opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
815 HCI_OCF_FM_STATION_DBG_PARAM);
816 return radio_hci_send_cmd(hdev, opcode, 0, NULL);
817}
818
819static int radio_hci_err(__u16 code)
820{
821 switch (code) {
822 case 0:
823 return 0;
824 case 0x01:
825 return -EBADRQC;
826 case 0x02:
827 return -ENOTCONN;
828 case 0x03:
829 return -EIO;
830 case 0x07:
831 return -ENOMEM;
832 case 0x0c:
833 return -EBUSY;
834 case 0x11:
835 return -EOPNOTSUPP;
836 case 0x12:
837 return -EINVAL;
838 default:
839 return -ENOSYS;
840 }
841}
842
843static int __radio_hci_request(struct radio_hci_dev *hdev,
844 int (*req)(struct radio_hci_dev *hdev,
845 unsigned long param),
846 unsigned long param, __u32 timeout)
847{
848 int err = 0;
849
850 DECLARE_WAITQUEUE(wait, current);
851
852 hdev->req_status = HCI_REQ_PEND;
853
854 add_wait_queue(&hdev->req_wait_q, &wait);
855 set_current_state(TASK_INTERRUPTIBLE);
856
857 err = req(hdev, param);
858
859 schedule_timeout(timeout);
860
861 remove_wait_queue(&hdev->req_wait_q, &wait);
862
863 if (signal_pending(current))
864 return -EINTR;
865
866 switch (hdev->req_status) {
867 case HCI_REQ_DONE:
868 case HCI_REQ_STATUS:
869 err = radio_hci_err(hdev->req_result);
870 break;
871
872 case HCI_REQ_CANCELED:
873 err = -hdev->req_result;
874 break;
875
876 default:
877 err = -ETIMEDOUT;
878 break;
879 }
880
881 hdev->req_status = hdev->req_result = 0;
882
883 return err;
884}
885
886static inline int radio_hci_request(struct radio_hci_dev *hdev,
887 int (*req)(struct
888 radio_hci_dev * hdev, unsigned long param),
889 unsigned long param, __u32 timeout)
890{
891 int ret = 0;
892
893 ret = __radio_hci_request(hdev, req, param, timeout);
894
895 return ret;
896}
897
898static int hci_set_fm_recv_conf(struct hci_fm_recv_conf_req *arg,
899 struct radio_hci_dev *hdev)
900{
901 int ret = 0;
902 struct hci_fm_recv_conf_req *set_recv_conf = arg;
903
904 ret = radio_hci_request(hdev, hci_set_fm_recv_conf_req, (unsigned
905 long)set_recv_conf, RADIO_HCI_TIMEOUT);
906
907 return ret;
908}
909
910static int hci_fm_tune_station(__u32 *arg, struct radio_hci_dev *hdev)
911{
912 int ret = 0;
913 __u32 tune_freq = *arg;
914
915 ret = radio_hci_request(hdev, hci_fm_tune_station_req, tune_freq,
916 RADIO_HCI_TIMEOUT);
917
918 return ret;
919}
920
921static int hci_set_fm_mute_mode(struct hci_fm_mute_mode_req *arg,
922 struct radio_hci_dev *hdev)
923{
924 int ret = 0;
925 struct hci_fm_mute_mode_req *set_mute_conf = arg;
926
927 ret = radio_hci_request(hdev, hci_set_fm_mute_mode_req, (unsigned
928 long)set_mute_conf, RADIO_HCI_TIMEOUT);
929
930 return ret;
931}
932
933static int hci_set_fm_stereo_mode(struct hci_fm_stereo_mode_req *arg,
934 struct radio_hci_dev *hdev)
935{
936 int ret = 0;
937 struct hci_fm_stereo_mode_req *set_stereo_conf = arg;
938
939 ret = radio_hci_request(hdev, hci_set_fm_stereo_mode_req, (unsigned
940 long)set_stereo_conf, RADIO_HCI_TIMEOUT);
941
942 return ret;
943}
944
945static int hci_fm_set_antenna(__u8 *arg, struct radio_hci_dev *hdev)
946{
947 int ret = 0;
948 __u8 antenna = *arg;
949
950 ret = radio_hci_request(hdev, hci_fm_set_antenna_req, antenna,
951 RADIO_HCI_TIMEOUT);
952
953 return ret;
954}
955
956static int hci_fm_set_signal_threshold(__u8 *arg,
957 struct radio_hci_dev *hdev)
958{
959 int ret = 0;
960 __u8 sig_threshold = *arg;
961
962 ret = radio_hci_request(hdev, hci_fm_set_sig_threshold_req,
963 sig_threshold, RADIO_HCI_TIMEOUT);
964
965 return ret;
966}
967
968static int hci_fm_search_stations(struct hci_fm_search_station_req *arg,
969 struct radio_hci_dev *hdev)
970{
971 int ret = 0;
972 struct hci_fm_search_station_req *srch_stations = arg;
973
974 ret = radio_hci_request(hdev, hci_fm_search_stations_req, (unsigned
975 long)srch_stations, RADIO_HCI_TIMEOUT);
976
977 return ret;
978}
979
980static int hci_fm_search_rds_stations(struct hci_fm_search_rds_station_req *arg,
981 struct radio_hci_dev *hdev)
982{
983 int ret = 0;
984 struct hci_fm_search_rds_station_req *srch_stations = arg;
985
986 ret = radio_hci_request(hdev, hci_fm_srch_rds_stations_req, (unsigned
987 long)srch_stations, RADIO_HCI_TIMEOUT);
988
989 return ret;
990}
991
992static int hci_fm_search_station_list
993 (struct hci_fm_search_station_list_req *arg,
994 struct radio_hci_dev *hdev)
995{
996 int ret = 0;
997 struct hci_fm_search_station_list_req *srch_list = arg;
998
999 ret = radio_hci_request(hdev, hci_fm_srch_station_list_req, (unsigned
1000 long)srch_list, RADIO_HCI_TIMEOUT);
1001
1002 return ret;
1003}
1004
1005static int hci_fm_rds_grp(struct hci_fm_rds_grp_req *arg,
1006 struct radio_hci_dev *hdev)
1007{
1008 return 0;
1009}
1010
1011static int hci_fm_rds_grps_process(__u32 *arg, struct radio_hci_dev *hdev)
1012{
1013 int ret = 0;
1014 __u32 fm_grps_process = *arg;
1015
1016 ret = radio_hci_request(hdev, hci_fm_rds_grp_process_req,
1017 fm_grps_process, RADIO_HCI_TIMEOUT);
1018
1019 return ret;
1020}
1021
1022int hci_def_data_read(struct hci_fm_def_data_rd_req *arg,
1023 struct radio_hci_dev *hdev)
1024{
1025 int ret = 0;
1026 struct hci_fm_def_data_rd_req *def_data_rd = arg;
1027
1028 ret = radio_hci_request(hdev, hci_def_data_read_req, (unsigned
1029 long)def_data_rd, RADIO_HCI_TIMEOUT);
1030
1031 return ret;
1032}
1033
1034int hci_def_data_write(struct hci_fm_def_data_wr_req *arg,
1035 struct radio_hci_dev *hdev)
1036{
1037 int ret = 0;
1038 struct hci_fm_def_data_wr_req *def_data_wr = arg;
1039
1040 ret = radio_hci_request(hdev, hci_def_data_write_req, (unsigned
1041 long)def_data_wr, RADIO_HCI_TIMEOUT);
1042
1043 return ret;
1044}
1045
1046int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev)
1047{
1048 int ret = 0;
1049 __u8 mode = *arg;
1050
1051 ret = radio_hci_request(hdev, hci_fm_do_calibration_req, mode,
1052 RADIO_HCI_TIMEOUT);
1053
1054 return ret;
1055}
1056
1057int hci_read_grp_counters(__u8 *arg, struct radio_hci_dev *hdev)
1058{
1059 int ret = 0;
1060 __u8 reset_counters = *arg;
1061
1062 ret = radio_hci_request(hdev, hci_read_grp_counters_req,
1063 reset_counters, RADIO_HCI_TIMEOUT);
1064
1065 return ret;
1066}
1067
1068int hci_peek_data(struct hci_fm_peek_req *arg, struct radio_hci_dev *hdev)
1069{
1070 int ret = 0;
1071 struct hci_fm_peek_req *peek_data = arg;
1072
1073 ret = radio_hci_request(hdev, hci_peek_data_req, (unsigned
1074 long)peek_data, RADIO_HCI_TIMEOUT);
1075
1076 return ret;
1077}
1078
1079int hci_poke_data(struct hci_fm_poke_req *arg, struct radio_hci_dev *hdev)
1080{
1081 int ret = 0;
1082 struct hci_fm_poke_req *poke_data = arg;
1083
1084 ret = radio_hci_request(hdev, hci_poke_data_req, (unsigned
1085 long)poke_data, RADIO_HCI_TIMEOUT);
1086
1087 return ret;
1088}
1089
1090int hci_ssbi_peek_reg(struct hci_fm_ssbi_req *arg,
1091 struct radio_hci_dev *hdev)
1092{
1093 int ret = 0;
1094 struct hci_fm_ssbi_req *ssbi_peek_reg = arg;
1095
1096 ret = radio_hci_request(hdev, hci_ssbi_peek_reg_req, (unsigned
1097 long)ssbi_peek_reg, RADIO_HCI_TIMEOUT);
1098
1099 return ret;
1100}
1101
1102int hci_ssbi_poke_reg(struct hci_fm_ssbi_req *arg, struct radio_hci_dev *hdev)
1103{
1104 int ret = 0;
1105 struct hci_fm_ssbi_req *ssbi_poke_reg = arg;
1106
1107 ret = radio_hci_request(hdev, hci_ssbi_poke_reg_req, (unsigned
1108 long)ssbi_poke_reg, RADIO_HCI_TIMEOUT);
1109
1110 return ret;
1111}
1112
1113static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev)
1114{
1115 int ret = 0;
1116 unsigned long arg = 0;
1117
1118 switch (cmd) {
1119 case HCI_FM_ENABLE_RECV_CMD:
1120 ret = radio_hci_request(hdev, hci_fm_enable_recv_req, arg,
1121 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1122 break;
1123
1124 case HCI_FM_DISABLE_RECV_CMD:
1125 ret = radio_hci_request(hdev, hci_fm_disable_recv_req, arg,
1126 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1127 break;
1128
1129 case HCI_FM_GET_RECV_CONF_CMD:
1130 ret = radio_hci_request(hdev, hci_get_fm_recv_conf_req, arg,
1131 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1132 break;
1133
1134 case HCI_FM_GET_STATION_PARAM_CMD:
1135 ret = radio_hci_request(hdev,
1136 hci_fm_get_station_param_req, arg,
1137 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1138 break;
1139
1140 case HCI_FM_GET_SIGNAL_TH_CMD:
1141 ret = radio_hci_request(hdev,
1142 hci_fm_get_sig_threshold_req, arg,
1143 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1144 break;
1145
1146 case HCI_FM_GET_PROGRAM_SERVICE_CMD:
1147 ret = radio_hci_request(hdev,
1148 hci_fm_get_program_service_req, arg,
1149 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1150 break;
1151
1152 case HCI_FM_GET_RADIO_TEXT_CMD:
1153 ret = radio_hci_request(hdev, hci_fm_get_radio_text_req, arg,
1154 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1155 break;
1156
1157 case HCI_FM_GET_AF_LIST_CMD:
1158 ret = radio_hci_request(hdev, hci_fm_get_af_list_req, arg,
1159 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1160 break;
1161
1162 case HCI_FM_CANCEL_SEARCH_CMD:
1163 ret = radio_hci_request(hdev, hci_fm_cancel_search_req, arg,
1164 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1165 break;
1166
1167 case HCI_FM_RESET_CMD:
1168 ret = radio_hci_request(hdev, hci_fm_reset_req, arg,
1169 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1170 break;
1171
1172 case HCI_FM_GET_FEATURES_CMD:
1173 ret = radio_hci_request(hdev,
1174 hci_fm_get_feature_lists_req, arg,
1175 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1176 break;
1177
1178 case HCI_FM_STATION_DBG_PARAM_CMD:
1179 ret = radio_hci_request(hdev,
1180 hci_fm_get_station_dbg_param_req, arg,
1181 msecs_to_jiffies(RADIO_HCI_TIMEOUT));
1182 break;
1183
1184 default:
1185 ret = -EINVAL;
1186 break;
1187 }
1188
1189 return ret;
1190}
1191
1192static void radio_hci_req_complete(struct radio_hci_dev *hdev, int result)
1193{
1194 hdev->req_result = result;
1195 hdev->req_status = HCI_REQ_DONE;
1196 wake_up_interruptible(&hdev->req_wait_q);
1197}
1198
1199static void radio_hci_status_complete(struct radio_hci_dev *hdev, int result)
1200{
1201 hdev->req_result = result;
1202 hdev->req_status = HCI_REQ_STATUS;
1203 wake_up_interruptible(&hdev->req_wait_q);
1204}
1205
1206static void hci_cc_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1207{
1208 __u8 status = *((__u8 *) skb->data);
1209
1210 if (status)
1211 return;
1212
1213 radio_hci_req_complete(hdev, status);
1214}
1215
1216static void hci_cc_fm_disable_rsp(struct radio_hci_dev *hdev,
1217 struct sk_buff *skb)
1218{
1219 __u8 status = *((__u8 *) skb->data);
1220 struct iris_device *radio = video_get_drvdata(video_get_dev());
1221
1222 if (status)
1223 return;
1224
1225 iris_q_event(radio, IRIS_EVT_RADIO_READY);
1226
1227 radio_hci_req_complete(hdev, status);
1228}
1229
1230static void hci_cc_conf_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1231{
1232 struct hci_fm_conf_rsp *rsp = (void *)skb->data;
1233 struct iris_device *radio = video_get_drvdata(video_get_dev());
1234
1235 if (rsp->status)
1236 return;
1237
1238 radio->recv_conf = rsp->recv_conf_rsp;
1239 radio_hci_req_complete(hdev, rsp->status);
1240}
1241
1242static void hci_cc_fm_enable_rsp(struct radio_hci_dev *hdev,
1243 struct sk_buff *skb)
1244{
1245 struct hci_fm_conf_rsp *rsp = (void *)skb->data;
1246 struct iris_device *radio = video_get_drvdata(video_get_dev());
1247
1248 if (rsp->status)
1249 return;
1250
1251 iris_q_event(radio, IRIS_EVT_RADIO_READY);
1252
1253 radio_hci_req_complete(hdev, rsp->status);
1254}
1255
1256static void hci_cc_sig_threshold_rsp(struct radio_hci_dev *hdev,
1257 struct sk_buff *skb)
1258{
1259 struct hci_fm_sig_threshold_rsp *rsp = (void *)skb->data;
1260 struct iris_device *radio = video_get_drvdata(video_get_dev());
1261 struct v4l2_control *v4l_ctl = radio->g_ctl;
1262
1263 if (rsp->status)
1264 return;
1265
1266 v4l_ctl->value = rsp->sig_threshold;
1267
1268 radio_hci_req_complete(hdev, rsp->status);
1269}
1270
1271static void hci_cc_station_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1272{
1273 struct iris_device *radio = video_get_drvdata(video_get_dev());
1274 struct hci_fm_station_rsp *rsp = (void *)skb->data;
1275 radio->fm_st_rsp = *(rsp);
1276
1277 /* Tune is always succesful */
1278 radio_hci_req_complete(hdev, 0);
1279}
1280
1281static void hci_cc_prg_srv_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1282{
1283 struct hci_fm_prgm_srv_rsp *rsp = (void *)skb->data;
1284
1285 if (rsp->status)
1286 return;
1287
1288 radio_hci_req_complete(hdev, rsp->status);
1289}
1290
1291static void hci_cc_rd_txt_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1292{
1293 struct hci_fm_radio_txt_rsp *rsp = (void *)skb->data;
1294
1295 if (rsp->status)
1296 return;
1297
1298 radio_hci_req_complete(hdev, rsp->status);
1299}
1300
1301static void hci_cc_af_list_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1302{
1303 struct hci_fm_af_list_rsp *rsp = (void *)skb->data;
1304
1305 if (rsp->status)
1306 return;
1307
1308 radio_hci_req_complete(hdev, rsp->status);
1309}
1310
1311static void hci_cc_data_rd_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
1312{
1313 struct hci_fm_data_rd_rsp *rsp = (void *)skb->data;
1314
1315 if (rsp->status)
1316 return;
1317
1318 radio_hci_req_complete(hdev, rsp->status);
1319}
1320
1321static void hci_cc_feature_list_rsp(struct radio_hci_dev *hdev,
1322 struct sk_buff *skb)
1323{
1324 struct hci_fm_feature_list_rsp *rsp = (void *)skb->data;
1325 struct iris_device *radio = video_get_drvdata(video_get_dev());
1326 struct v4l2_capability *v4l_cap = radio->g_cap;
1327
1328 if (rsp->status)
1329 return;
1330 v4l_cap->capabilities = (rsp->feature_mask & 0x000002) |
1331 (rsp->feature_mask & 0x000001);
1332
1333 radio_hci_req_complete(hdev, rsp->status);
1334}
1335
1336static void hci_cc_dbg_param_rsp(struct radio_hci_dev *hdev,
1337 struct sk_buff *skb)
1338{
1339 struct iris_device *radio = video_get_drvdata(video_get_dev());
1340 struct hci_fm_dbg_param_rsp *rsp = (void *)skb->data;
1341 radio->st_dbg_param = *(rsp);
1342
1343 if (radio->st_dbg_param.status)
1344 return;
1345
1346 radio_hci_req_complete(hdev, radio->st_dbg_param.status);
1347}
1348
1349static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev,
1350 struct sk_buff *skb)
1351{
1352 struct hci_ev_cmd_complete *cmd_compl_ev = (void *) skb->data;
1353 __u16 opcode;
1354
1355 skb_pull(skb, sizeof(*cmd_compl_ev));
1356
1357 opcode = __le16_to_cpu(cmd_compl_ev->cmd_opcode);
1358
1359 switch (opcode) {
1360 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_RECV_REQ):
1361 hci_cc_fm_enable_rsp(hdev, skb);
1362 break;
1363 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_RECV_CONF_REQ):
1364 hci_cc_conf_rsp(hdev, skb);
1365 break;
1366
1367 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_DISABLE_RECV_REQ):
1368 hci_cc_fm_disable_rsp(hdev, skb);
1369 break;
1370
1371 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_RECV_CONF_REQ):
1372 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_MUTE_MODE_REQ):
1373 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_STEREO_MODE_REQ):
1374 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_ANTENNA):
1375 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_SIGNAL_THRESHOLD):
1376 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_CANCEL_SEARCH):
1377 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP):
1378 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP_PROCESS):
1379 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL):
1380 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL):
1381 case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE):
1382 case hci_common_cmd_op_pack(HCI_OCF_FM_RESET):
1383 case hci_status_param_op_pack(HCI_OCF_FM_READ_GRP_COUNTERS):
1384 case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_POKE_DATA):
1385 case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_PEEK_REG):
1386 case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_POKE_REG):
1387 hci_cc_rsp(hdev, skb);
1388 break;
1389
1390 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_SIGNAL_THRESHOLD):
1391 hci_cc_sig_threshold_rsp(hdev, skb);
1392 break;
1393
1394 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_STATION_PARAM_REQ):
1395 hci_cc_station_rsp(hdev, skb);
1396 break;
1397
1398 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ):
1399 hci_cc_prg_srv_rsp(hdev, skb);
1400 break;
1401
1402 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_RADIO_TEXT_REQ):
1403 hci_cc_rd_txt_rsp(hdev, skb);
1404 break;
1405
1406 case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_AF_LIST_REQ):
1407 hci_cc_af_list_rsp(hdev, skb);
1408 break;
1409
1410 case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_READ):
1411 case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_PEEK_DATA):
1412 hci_cc_data_rd_rsp(hdev, skb);
1413 break;
1414
1415 case hci_common_cmd_op_pack(HCI_OCF_FM_GET_FEATURE_LIST):
1416 hci_cc_feature_list_rsp(hdev, skb);
1417 break;
1418
1419 case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_STATION_DBG_PARAM):
1420 hci_cc_dbg_param_rsp(hdev, skb);
1421 break;
1422
1423 default:
1424 FMDERR("%s opcode 0x%x", hdev->name, opcode);
1425 break;
1426 }
1427
1428}
1429
1430static inline void hci_cmd_status_event(struct radio_hci_dev *hdev,
1431 struct sk_buff *skb)
1432{
1433 struct hci_ev_cmd_status *ev = (void *) skb->data;
1434 radio_hci_status_complete(hdev, ev->status);
1435}
1436
1437static inline void hci_ev_tune_status(struct radio_hci_dev *hdev,
1438 struct sk_buff *skb)
1439{
1440 int i;
1441 int len;
1442
1443 struct iris_device *radio = video_get_drvdata(video_get_dev());
1444
1445 len = sizeof(struct hci_fm_station_rsp);
1446
1447 memcpy(&radio->fm_st_rsp.station_rsp, skb_pull(skb, len), len);
1448
1449 iris_q_event(radio, IRIS_EVT_TUNE_SUCC);
1450
1451 for (i = 0; i < IRIS_BUF_MAX; i++) {
1452 if (i >= IRIS_BUF_RT_RDS)
1453 kfifo_reset(&radio->data_buf[i]);
1454 }
1455
1456 if (radio->fm_st_rsp.station_rsp.rssi)
1457 iris_q_event(radio, IRIS_EVT_ABOVE_TH);
1458 else
1459 iris_q_event(radio, IRIS_EVT_BELOW_TH);
1460
1461 if (radio->fm_st_rsp.station_rsp.stereo_prg)
1462 iris_q_event(radio, IRIS_EVT_STEREO);
1463
1464 if (radio->fm_st_rsp.station_rsp.mute_mode)
1465 iris_q_event(radio, IRIS_EVT_MONO);
1466
1467 if (radio->fm_st_rsp.station_rsp.rds_sync_status)
1468 iris_q_event(radio, IRIS_EVT_RDS_AVAIL);
1469 else
1470 iris_q_event(radio, IRIS_EVT_RDS_NOT_AVAIL);
1471}
1472
1473static inline void hci_ev_search_compl(struct radio_hci_dev *hdev,
1474 struct sk_buff *skb)
1475{
1476 struct iris_device *radio = video_get_drvdata(video_get_dev());
1477 iris_q_event(radio, IRIS_EVT_SEEK_COMPLETE);
1478}
1479
Srinivasa Rao Uppala18fb80e2011-07-17 17:33:00 -07001480
1481static void iris_q_evt_data(struct iris_device *radio,
1482 char *data, int len, int event)
1483{
1484 struct kfifo *data_b = &radio->data_buf[event];
1485 if (kfifo_in_locked(data_b, data, len, &radio->buf_lock[event]))
1486 wake_up_interruptible(&radio->event_queue);
1487}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001488static inline void hci_ev_srch_st_list_compl(struct radio_hci_dev *hdev,
1489 struct sk_buff *skb)
1490{
1491 struct iris_device *radio = video_get_drvdata(video_get_dev());
Srinivasa Rao Uppala18fb80e2011-07-17 17:33:00 -07001492 struct hci_ev_srch_list_compl *ev ;
1493 int cnt;
1494 int stn_num;
1495 int rel_freq;
1496 int abs_freq;
1497 int len;
1498
1499 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1500 if (!ev) {
1501 FMDERR("Memory allocation failed");
1502 return ;
1503 }
1504
1505 ev->num_stations_found = skb->data[STN_NUM_OFFSET];
1506 len = ev->num_stations_found * PARAMS_PER_STATION + STN_FREQ_OFFSET;
1507
1508 for (cnt = STN_FREQ_OFFSET, stn_num = 0;
1509 (cnt < len) && (stn_num < ev->num_stations_found);
1510 cnt += PARAMS_PER_STATION, stn_num++) {
1511 abs_freq = *((int *)&skb->data[cnt]);
1512 rel_freq = abs_freq - radio->recv_conf.band_low_limit;
1513 rel_freq = (rel_freq * 20) / KHZ_TO_MHZ;
1514
1515 ev->rel_freq[stn_num].rel_freq_lsb = GET_LSB(rel_freq);
1516 ev->rel_freq[stn_num].rel_freq_msb = GET_MSB(rel_freq);
1517 }
1518
1519 len = ev->num_stations_found * 2 + sizeof(ev->num_stations_found);
1520 iris_q_event(radio, IRIS_EVT_NEW_SRCH_LIST);
1521 iris_q_evt_data(radio, (char *)ev, len, IRIS_BUF_SRCH_LIST);
1522 kfree(ev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001523}
1524
1525static inline void hci_ev_search_next(struct radio_hci_dev *hdev,
1526 struct sk_buff *skb)
1527{
1528 struct iris_device *radio = video_get_drvdata(video_get_dev());
1529 iris_q_event(radio, IRIS_EVT_SCAN_NEXT);
1530}
1531
1532static inline void hci_ev_stereo_status(struct radio_hci_dev *hdev,
1533 struct sk_buff *skb)
1534{
1535 struct iris_device *radio = video_get_drvdata(video_get_dev());
1536 __u8 st_status = *((__u8 *) skb->data);
1537 if (st_status)
1538 iris_q_event(radio, IRIS_EVT_STEREO);
1539 else
1540 iris_q_event(radio, IRIS_EVT_MONO);
1541}
1542
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001543
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001544static inline void hci_ev_program_service(struct radio_hci_dev *hdev,
1545 struct sk_buff *skb)
1546{
1547 struct iris_device *radio = video_get_drvdata(video_get_dev());
1548 int len;
1549 char *data;
1550
1551 len = (skb->data[RDS_PS_LENGTH_OFFSET] * RDS_STRING) + RDS_OFFSET;
1552 iris_q_event(radio, IRIS_EVT_NEW_PS_RDS);
1553 data = kmalloc(len, GFP_ATOMIC);
1554 if (!data) {
1555 FMDERR("Failed to allocate memory");
1556 return;
1557 }
1558
1559 data[0] = skb->data[RDS_PS_LENGTH_OFFSET];
1560 data[1] = skb->data[RDS_PTYPE];
1561 data[2] = skb->data[RDS_PID_LOWER];
1562 data[3] = skb->data[RDS_PID_HIGHER];
1563 data[4] = 0;
1564
1565 memcpy(data+RDS_OFFSET, &skb->data[RDS_PS_DATA_OFFSET], len-RDS_OFFSET);
1566
Srinivasa Rao Uppala18fb80e2011-07-17 17:33:00 -07001567 iris_q_evt_data(radio, data, len, IRIS_BUF_PS_RDS);
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001568
1569 kfree(data);
1570}
1571
1572
1573static inline void hci_ev_radio_text(struct radio_hci_dev *hdev,
1574 struct sk_buff *skb)
1575{
1576 struct iris_device *radio = video_get_drvdata(video_get_dev());
1577 int len = 0;
1578 char *data;
1579
1580 iris_q_event(radio, IRIS_EVT_NEW_RT_RDS);
1581
1582 while (skb->data[len+RDS_OFFSET] != 0x0d)
1583 len++;
1584 len++;
1585
1586 data = kmalloc(len+RDS_OFFSET, GFP_ATOMIC);
1587 if (!data) {
1588 FMDERR("Failed to allocate memory");
1589 return;
1590 }
1591
1592 data[0] = len;
1593 data[1] = skb->data[RDS_PTYPE];
1594 data[2] = skb->data[RDS_PID_LOWER];
1595 data[3] = skb->data[RDS_PID_HIGHER];
1596 data[4] = 0;
1597
1598 memcpy(data+RDS_OFFSET, &skb->data[RDS_OFFSET], len);
1599 data[len+RDS_OFFSET] = 0x00;
1600
Srinivasa Rao Uppala18fb80e2011-07-17 17:33:00 -07001601 iris_q_evt_data(radio, data, len+RDS_OFFSET, IRIS_BUF_RT_RDS);
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001602
1603 kfree(data);
1604}
1605
1606
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001607void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb)
1608{
1609 struct radio_hci_event_hdr *hdr = (void *) skb->data;
1610 __u8 event = hdr->evt;
1611
1612 skb_pull(skb, RADIO_HCI_EVENT_HDR_SIZE);
1613
1614 switch (event) {
1615 case HCI_EV_TUNE_STATUS:
1616 hci_ev_tune_status(hdev, skb);
1617 break;
1618 case HCI_EV_SEARCH_PROGRESS:
1619 case HCI_EV_SEARCH_RDS_PROGRESS:
1620 case HCI_EV_SEARCH_LIST_PROGRESS:
1621 hci_ev_search_next(hdev, skb);
1622 break;
1623 case HCI_EV_STEREO_STATUS:
1624 hci_ev_stereo_status(hdev, skb);
1625 break;
1626 case HCI_EV_RDS_LOCK_STATUS:
1627 case HCI_EV_SERVICE_AVAILABLE:
1628 case HCI_EV_RDS_RX_DATA:
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001629 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001630 case HCI_EV_PROGRAM_SERVICE:
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001631 hci_ev_program_service(hdev, skb);
1632 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001633 case HCI_EV_RADIO_TEXT:
Ankur Nandwani78a782b2011-07-07 21:11:21 -07001634 hci_ev_radio_text(hdev, skb);
1635 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001636 case HCI_EV_FM_AF_LIST:
1637 case HCI_EV_TX_RDS_GRP_COMPL:
1638 case HCI_EV_TX_RDS_CONT_GRP_COMPL:
1639 break;
1640
1641 case HCI_EV_CMD_COMPLETE:
1642 hci_cmd_complete_event(hdev, skb);
1643 break;
1644
1645 case HCI_EV_CMD_STATUS:
1646 hci_cmd_status_event(hdev, skb);
1647 break;
1648
1649 case HCI_EV_SEARCH_COMPLETE:
1650 case HCI_EV_SEARCH_RDS_COMPLETE:
1651 hci_ev_search_compl(hdev, skb);
1652 break;
1653
1654 case HCI_EV_SEARCH_LIST_COMPLETE:
Srinivasa Rao Uppala18fb80e2011-07-17 17:33:00 -07001655 hci_ev_srch_st_list_compl(hdev, skb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001656 break;
1657
1658 default:
1659 break;
1660 }
1661}
1662
1663/*
1664 * fops/IOCTL helper functions
1665 */
1666
1667static int iris_search(struct iris_device *radio, int on, int dir)
1668{
1669 int retval = 0;
1670 enum search_t srch = radio->g_search_mode & SRCH_MODE;
1671
1672 if (on) {
1673 switch (srch) {
1674 case SCAN_FOR_STRONG:
1675 case SCAN_FOR_WEAK:
1676 radio->srch_st_list.srch_list_dir = dir;
1677 radio->srch_st_list.srch_list_mode = srch;
1678 radio->srch_st_list.srch_list_max = 0;
1679 retval = hci_fm_search_station_list(
1680 &radio->srch_st_list, radio->fm_hdev);
1681 break;
1682 case RDS_SEEK_PTY:
1683 case RDS_SCAN_PTY:
1684 case RDS_SEEK_PI:
Srinivasa Rao Uppala7bb22102011-07-14 11:27:30 -07001685 srch = srch - SEARCH_RDS_STNS_MODE_OFFSET;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001686 radio->srch_rds.srch_station.srch_mode = srch;
1687 radio->srch_rds.srch_station.srch_dir = dir;
1688 radio->srch_rds.srch_station.scan_time =
1689 radio->g_scan_time;
1690 retval = hci_fm_search_rds_stations(&radio->srch_rds,
1691 radio->fm_hdev);
1692 break;
1693 default:
1694 radio->srch_st.srch_mode = srch;
1695 radio->srch_st.scan_time = radio->g_scan_time;
1696 radio->srch_st.srch_dir = dir;
1697 retval = hci_fm_search_stations(
1698 &radio->srch_st, radio->fm_hdev);
1699 break;
1700 }
1701
1702 } else {
1703 retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
1704 }
1705
1706 return retval;
1707}
1708
1709static int iris_set_region(struct iris_device *radio, int req_region)
1710{
1711 int retval;
1712 radio->region = req_region;
1713
1714 switch (radio->region) {
1715 case IRIS_REGION_US:
1716 {
1717 radio->recv_conf.band_low_limit = 88100;
1718 radio->recv_conf.band_high_limit = 108000;
1719 radio->recv_conf.emphasis = 0;
1720 radio->recv_conf.hlsi = 0;
1721 radio->recv_conf.ch_spacing = 0;
1722 radio->recv_conf.rds_std = 0;
1723 }
1724 break;
1725 case IRIS_REGION_EU:
1726 {
1727 radio->recv_conf.band_low_limit = 88100;
1728 radio->recv_conf.band_high_limit = 108000;
1729 radio->recv_conf.emphasis = 0;
1730 radio->recv_conf.hlsi = 0;
1731 radio->recv_conf.ch_spacing = 0;
1732 radio->recv_conf.rds_std = 0;
1733 }
1734 break;
1735 case IRIS_REGION_JAPAN:
1736 {
1737 radio->recv_conf.band_low_limit = 76000;
1738 radio->recv_conf.band_high_limit = 108000;
1739 radio->recv_conf.emphasis = 0;
1740 radio->recv_conf.hlsi = 0;
1741 radio->recv_conf.ch_spacing = 0;
1742 }
1743 break;
1744 default:
1745 {
1746 radio->recv_conf.emphasis = 0;
1747 radio->recv_conf.hlsi = 0;
1748 radio->recv_conf.ch_spacing = 0;
1749 radio->recv_conf.rds_std = 0;
1750 }
1751 break;
1752 }
1753
1754
1755 retval = hci_set_fm_recv_conf(
1756 &radio->recv_conf,
1757 radio->fm_hdev);
1758
1759 return retval;
1760}
1761
1762static int iris_set_freq(struct iris_device *radio, unsigned int freq)
1763{
1764
1765 int retval;
1766 retval = hci_fm_tune_station(&freq, radio->fm_hdev);
1767 if (retval < 0)
1768 FMDERR("Error while setting the frequency : %d\n", retval);
1769 return retval;
1770}
1771
1772
1773static int iris_vidioc_queryctrl(struct file *file, void *priv,
1774 struct v4l2_queryctrl *qc)
1775{
1776 unsigned char i;
1777 int retval = -EINVAL;
1778
1779 for (i = 0; i < ARRAY_SIZE(iris_v4l2_queryctrl); i++) {
1780 if (qc->id && qc->id == iris_v4l2_queryctrl[i].id) {
1781 memcpy(qc, &(iris_v4l2_queryctrl[i]), sizeof(*qc));
1782 retval = 0;
1783 break;
1784 }
1785 }
1786
1787 return retval;
1788}
1789
1790static int iris_vidioc_g_ctrl(struct file *file, void *priv,
1791 struct v4l2_control *ctrl)
1792{
1793 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1794 int retval = 0;
1795
1796 switch (ctrl->id) {
1797 case V4L2_CID_AUDIO_VOLUME:
1798 break;
1799 case V4L2_CID_AUDIO_MUTE:
1800 ctrl->value = radio->mute_mode.hard_mute;
1801 break;
1802 case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
1803 ctrl->value = radio->g_search_mode;
1804 break;
1805 case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
1806 ctrl->value = radio->g_scan_time;
1807 break;
1808 case V4L2_CID_PRIVATE_IRIS_SRCHON:
1809 break;
1810 case V4L2_CID_PRIVATE_IRIS_STATE:
1811 break;
1812 case V4L2_CID_PRIVATE_IRIS_IOVERC:
1813 retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
1814 if (retval < 0)
1815 return retval;
1816 ctrl->value = radio->st_dbg_param.io_verc;
1817 break;
1818 case V4L2_CID_PRIVATE_IRIS_INTDET:
1819 retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
1820 if (retval < 0)
1821 return retval;
1822 ctrl->value = radio->st_dbg_param.in_det_out;
1823 break;
1824 case V4L2_CID_PRIVATE_IRIS_REGION:
1825 ctrl->value = radio->region;
1826 break;
1827 case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
1828 retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
1829 break;
1830 case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
1831 break;
1832 case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
1833 break;
1834 case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
1835 break;
1836 case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
1837 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1838 radio->fm_hdev);
1839 if (retval < 0)
1840 FMDERR("Error get FM recv conf"
1841 " %d\n", retval);
1842 else
1843 ctrl->value = radio->recv_conf.emphasis;
1844 break;
1845 case V4L2_CID_PRIVATE_IRIS_RDS_STD:
1846 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1847 radio->fm_hdev);
1848 if (retval < 0)
1849 FMDERR("Error get FM recv conf"
1850 " %d\n", retval);
1851 else
1852 ctrl->value = radio->recv_conf.rds_std;
1853 break;
1854 case V4L2_CID_PRIVATE_IRIS_SPACING:
1855 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1856 radio->fm_hdev);
1857 if (retval < 0)
1858 FMDERR("Error get FM recv conf"
1859 " %d\n", retval);
1860 else
1861 ctrl->value = radio->recv_conf.ch_spacing;
1862 break;
1863 case V4L2_CID_PRIVATE_IRIS_RDSON:
1864 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1865 radio->fm_hdev);
1866 if (retval < 0)
1867 FMDERR("Error get FM recv conf"
1868 " %d\n", retval);
1869 else
1870 ctrl->value = radio->recv_conf.rds_std;
1871 break;
1872 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
1873 ctrl->value = radio->rds_grp.rds_grp_enable_mask;
1874 break;
1875 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
1876 break;
1877 case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
1878 ctrl->value = radio->rds_grp.rds_buf_size;
1879 break;
1880 case V4L2_CID_PRIVATE_IRIS_PSALL:
1881 ctrl->value = radio->g_rds_grp_proc_ps;
1882 break;
1883 case V4L2_CID_PRIVATE_IRIS_LP_MODE:
1884 break;
1885 case V4L2_CID_PRIVATE_IRIS_ANTENNA:
1886 ctrl->value = radio->g_antenna;
1887 break;
1888 default:
1889 retval = -EINVAL;
1890 }
1891 if (retval < 0)
1892 FMDERR("get control failed with %d, id: %d\n",
1893 retval, ctrl->id);
1894 return retval;
1895}
1896
1897static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
1898 struct v4l2_ext_controls *ctrl)
1899{
1900 return -ENOTSUPP;
1901}
1902
1903static int iris_vidioc_s_ctrl(struct file *file, void *priv,
1904 struct v4l2_control *ctrl)
1905{
1906 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1907 int retval = 0;
1908 unsigned int rds_grps_proc = 0;
1909 __u8 temp_val = 0;
1910 radio->recv_conf.emphasis = 0;
1911 radio->recv_conf.ch_spacing = 0;
1912 radio->recv_conf.hlsi = 0;
1913 radio->recv_conf.band_low_limit = 87500;
1914 radio->recv_conf.band_high_limit = 108000;
1915 radio->recv_conf.rds_std = 0;
1916
1917
1918 switch (ctrl->id) {
1919 case V4L2_CID_AUDIO_VOLUME:
1920 break;
1921 case V4L2_CID_AUDIO_MUTE:
1922 radio->mute_mode.hard_mute = ctrl->value;
1923 radio->mute_mode.soft_mute = IOC_SFT_MUTE;
1924 retval = hci_set_fm_mute_mode(
1925 &radio->mute_mode,
1926 radio->fm_hdev);
1927 if (retval < 0)
1928 FMDERR("Error while set FM hard mute"" %d\n",
1929 retval);
1930 break;
1931 case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
1932 radio->g_search_mode = ctrl->value;
1933 break;
1934 case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
1935 radio->g_scan_time = ctrl->value;
1936 break;
1937 case V4L2_CID_PRIVATE_IRIS_SRCHON:
1938 iris_search(radio, ctrl->value, SRCH_DIR_UP);
1939 break;
1940 case V4L2_CID_PRIVATE_IRIS_STATE:
1941 if (ctrl->value == FM_RECV) {
1942 retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
1943 radio->fm_hdev);
1944 } else {
1945 if (ctrl->value == FM_OFF) {
1946 retval = hci_cmd(
1947 HCI_FM_DISABLE_RECV_CMD,
1948 radio->fm_hdev);
1949 if (retval < 0)
1950 FMDERR("Error on disable FM"
1951 " %d\n", retval);
1952 }
1953 }
1954 break;
1955 case V4L2_CID_PRIVATE_IRIS_REGION:
1956 retval = iris_set_region(radio, ctrl->value);
1957 break;
1958 case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
1959 temp_val = ctrl->value;
1960 retval = hci_fm_set_signal_threshold(
1961 &temp_val,
1962 radio->fm_hdev);
1963 if (retval < 0) {
1964 FMDERR("Error while setting signal threshold\n");
1965 break;
1966 }
1967 break;
1968 case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
1969 radio->srch_rds.srch_pty = ctrl->value;
1970 radio->srch_st_list.srch_pty = ctrl->value;
1971 break;
1972 case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
1973 radio->srch_rds.srch_pi = ctrl->value;
1974 break;
1975 case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
1976 break;
1977 case V4L2_CID_PRIVATE_IRIS_SPACING:
1978 radio->recv_conf.ch_spacing = ctrl->value;
1979 break;
1980 case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
1981 radio->recv_conf.emphasis = ctrl->value;
1982 retval =
1983 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1984 break;
1985 case V4L2_CID_PRIVATE_IRIS_RDS_STD:
1986 radio->recv_conf.rds_std = ctrl->value;
1987 retval =
1988 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1989 break;
1990 case V4L2_CID_PRIVATE_IRIS_RDSON:
1991 radio->recv_conf.rds_std = ctrl->value;
1992 retval =
1993 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1994 break;
1995 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
1996 radio->rds_grp.rds_grp_enable_mask = ctrl->value;
1997 retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
1998 break;
1999 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
2000 rds_grps_proc = radio->g_rds_grp_proc_ps | ctrl->value;
2001 retval = hci_fm_rds_grps_process(
2002 &rds_grps_proc,
2003 radio->fm_hdev);
2004 break;
2005 case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
2006 radio->rds_grp.rds_buf_size = ctrl->value;
2007 break;
2008 case V4L2_CID_PRIVATE_IRIS_PSALL:
2009 radio->g_rds_grp_proc_ps = ctrl->value;
2010 break;
2011 case V4L2_CID_PRIVATE_IRIS_LP_MODE:
2012 break;
2013 case V4L2_CID_PRIVATE_IRIS_ANTENNA:
2014 temp_val = ctrl->value;
2015 retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
2016 break;
2017 case V4L2_CID_RDS_TX_PTY:
2018 break;
2019 case V4L2_CID_RDS_TX_PI:
2020 break;
2021 case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
2022 break;
2023 case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
2024 break;
2025 case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
2026 break;
2027 case V4L2_CID_TUNE_POWER_LEVEL:
2028 break;
2029 default:
2030 retval = -EINVAL;
2031 }
2032 return retval;
2033}
2034
2035static int iris_vidioc_g_tuner(struct file *file, void *priv,
2036 struct v4l2_tuner *tuner)
2037{
2038 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2039 int retval;
2040 if (tuner->index > 0)
2041 return -EINVAL;
2042
2043 retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
2044 if (retval < 0)
2045 return retval;
2046
2047 tuner->type = V4L2_TUNER_RADIO;
2048 tuner->rangelow = radio->recv_conf.band_low_limit * TUNE_PARAM;
2049 tuner->rangehigh = radio->recv_conf.band_high_limit * TUNE_PARAM;
2050 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
2051 tuner->capability = V4L2_TUNER_CAP_LOW;
2052 tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
2053 tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
2054 tuner->afc = 0;
2055
2056 return 0;
2057}
2058
2059static int iris_vidioc_s_tuner(struct file *file, void *priv,
2060 struct v4l2_tuner *tuner)
2061{
2062 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2063 int retval;
2064 if (tuner->index > 0)
2065 return -EINVAL;
2066
2067 radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
2068 radio->recv_conf.band_high_limit = tuner->rangehigh / TUNE_PARAM;
2069 if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
2070 radio->stereo_mode.stereo_mode = 0x01;
2071 retval = hci_set_fm_stereo_mode(
2072 &radio->stereo_mode,
2073 radio->fm_hdev);
2074 } else {
2075 radio->stereo_mode.stereo_mode = 0x00;
2076 retval = hci_set_fm_stereo_mode(
2077 &radio->stereo_mode,
2078 radio->fm_hdev);
2079 }
2080 if (retval < 0)
2081 FMDERR(": set tuner failed with %d\n", retval);
2082 return retval;
2083}
2084
2085static int iris_vidioc_g_frequency(struct file *file, void *priv,
2086 struct v4l2_frequency *freq)
2087{
2088 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2089 int retval;
2090
2091 freq->type = V4L2_TUNER_RADIO;
2092 retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
2093 if (retval < 0)
2094 FMDERR("get frequency failed %d\n", retval);
2095 else
2096 freq->frequency =
2097 radio->fm_st_rsp.station_rsp.station_freq * TUNE_PARAM;
2098 return retval;
2099}
2100
2101static int iris_vidioc_s_frequency(struct file *file, void *priv,
2102 struct v4l2_frequency *freq)
2103{
2104 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2105 int retval = -1;
2106 freq->frequency = freq->frequency / TUNE_PARAM;
2107
2108 if (freq->type != V4L2_TUNER_RADIO)
2109 return -EINVAL;
2110
2111 retval = iris_set_freq(radio, freq->frequency);
2112 if (retval < 0)
2113 FMDERR(" set frequency failed with %d\n", retval);
2114 return retval;
2115}
2116
2117static int iris_vidioc_dqbuf(struct file *file, void *priv,
2118 struct v4l2_buffer *buffer)
2119{
2120 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2121 enum iris_buf_t buf_type = buffer->index;
2122 struct kfifo *data_fifo;
2123 unsigned char *buf = (unsigned char *)buffer->m.userptr;
2124 unsigned int len = buffer->length;
2125 if (!access_ok(VERIFY_WRITE, buf, len))
2126 return -EFAULT;
2127 if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
2128 data_fifo = &radio->data_buf[buf_type];
2129 if (buf_type == IRIS_BUF_EVENTS)
2130 if (wait_event_interruptible(radio->event_queue,
2131 kfifo_len(data_fifo)) < 0)
2132 return -EINTR;
2133 } else {
2134 FMDERR("invalid buffer type\n");
2135 return -EINVAL;
2136 }
2137 buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
2138 &radio->buf_lock[buf_type]);
2139
2140 return 0;
2141}
2142
2143static int iris_vidioc_g_fmt_type_private(struct file *file, void *priv,
2144 struct v4l2_format *f)
2145{
2146 return 0;
2147
2148}
2149
2150static int iris_vidioc_s_hw_freq_seek(struct file *file, void *priv,
2151 struct v4l2_hw_freq_seek *seek)
2152{
2153 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2154 int dir;
2155 if (seek->seek_upward)
2156 dir = SRCH_DIR_UP;
2157 else
2158 dir = SRCH_DIR_DOWN;
2159 return iris_search(radio, CTRL_ON, dir);
2160}
2161
2162static int iris_vidioc_querycap(struct file *file, void *priv,
2163 struct v4l2_capability *capability)
2164{
2165 struct iris_device *radio;
2166 radio = video_get_drvdata(video_devdata(file));
2167 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
2168 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
2169 radio->g_cap = capability;
2170 return 0;
2171}
2172
2173
2174static const struct v4l2_ioctl_ops iris_ioctl_ops = {
2175 .vidioc_querycap = iris_vidioc_querycap,
2176 .vidioc_queryctrl = iris_vidioc_queryctrl,
2177 .vidioc_g_ctrl = iris_vidioc_g_ctrl,
2178 .vidioc_s_ctrl = iris_vidioc_s_ctrl,
2179 .vidioc_g_tuner = iris_vidioc_g_tuner,
2180 .vidioc_s_tuner = iris_vidioc_s_tuner,
2181 .vidioc_g_frequency = iris_vidioc_g_frequency,
2182 .vidioc_s_frequency = iris_vidioc_s_frequency,
2183 .vidioc_s_hw_freq_seek = iris_vidioc_s_hw_freq_seek,
2184 .vidioc_dqbuf = iris_vidioc_dqbuf,
2185 .vidioc_g_fmt_type_private = iris_vidioc_g_fmt_type_private,
2186 .vidioc_s_ext_ctrls = iris_vidioc_s_ext_ctrls,
2187};
2188
2189static const struct v4l2_file_operations iris_fops = {
2190 .owner = THIS_MODULE,
2191 .unlocked_ioctl = video_ioctl2,
2192};
2193
2194static struct video_device iris_viddev_template = {
2195 .fops = &iris_fops,
2196 .ioctl_ops = &iris_ioctl_ops,
2197 .name = DRIVER_NAME,
2198 .release = video_device_release,
2199};
2200
2201static struct video_device *video_get_dev(void)
2202{
2203 return priv_videodev;
2204}
2205
2206static int __init iris_probe(struct platform_device *pdev)
2207{
2208 struct iris_device *radio;
2209 int retval;
2210 int radio_nr = -1;
2211 int i;
2212
2213 if (!pdev) {
2214 FMDERR(": pdev is null\n");
2215 return -ENOMEM;
2216 }
2217
2218 radio = kzalloc(sizeof(struct iris_device), GFP_KERNEL);
2219 if (!radio) {
2220 FMDERR(": Could not allocate radio device\n");
2221 return -ENOMEM;
2222 }
2223
2224 radio->dev = &pdev->dev;
2225 platform_set_drvdata(pdev, radio);
2226
2227 radio->videodev = video_device_alloc();
2228 if (!radio->videodev) {
2229 FMDERR(": Could not allocate V4L device\n");
2230 kfree(radio);
2231 return -ENOMEM;
2232 }
2233
2234 memcpy(radio->videodev, &iris_viddev_template,
2235 sizeof(iris_viddev_template));
2236
2237 for (i = 0; i < IRIS_BUF_MAX; i++) {
2238 int kfifo_alloc_rc = 0;
2239 spin_lock_init(&radio->buf_lock[i]);
2240
2241 if (i == IRIS_BUF_RAW_RDS)
2242 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
2243 rds_buf*3, GFP_KERNEL);
2244 else
2245 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
2246 STD_BUF_SIZE, GFP_KERNEL);
2247
2248 if (kfifo_alloc_rc != 0) {
2249 FMDERR("failed allocating buffers %d\n",
2250 kfifo_alloc_rc);
2251 for (; i > -1; i--) {
2252 kfifo_free(&radio->data_buf[i]);
2253 kfree(radio);
2254 return -ENOMEM;
2255 }
2256 }
2257 }
2258
2259 mutex_init(&radio->lock);
2260 init_completion(&radio->sync_xfr_start);
2261 radio->tune_req = 0;
2262 init_waitqueue_head(&radio->event_queue);
2263 init_waitqueue_head(&radio->read_queue);
2264
2265 video_set_drvdata(radio->videodev, radio);
2266
2267 if (NULL == video_get_drvdata(radio->videodev))
2268 FMDERR(": video_get_drvdata failed\n");
2269
2270 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
2271 radio_nr);
2272 if (retval) {
2273 FMDERR(": Could not register video device\n");
2274 video_device_release(radio->videodev);
2275 for (; i > -1; i--)
2276 kfifo_free(&radio->data_buf[i]);
2277 kfree(radio);
2278 return retval;
2279 } else {
2280 priv_videodev = kzalloc(sizeof(struct video_device),
2281 GFP_KERNEL);
2282 memcpy(priv_videodev, radio->videodev,
2283 sizeof(struct video_device));
2284 }
2285 return 0;
2286}
2287
2288
2289static int __devexit iris_remove(struct platform_device *pdev)
2290{
2291 int i;
2292 struct iris_device *radio = platform_get_drvdata(pdev);
2293
2294 video_unregister_device(radio->videodev);
2295
2296 for (i = 0; i < IRIS_BUF_MAX; i++)
2297 kfifo_free(&radio->data_buf[i]);
2298
2299 kfree(radio);
2300
2301 platform_set_drvdata(pdev, NULL);
2302
2303 return 0;
2304}
2305
2306static struct platform_driver iris_driver = {
2307 .driver = {
2308 .owner = THIS_MODULE,
2309 .name = "iris_fm",
2310 },
2311 .remove = __devexit_p(iris_remove),
2312};
2313
2314static int __init iris_radio_init(void)
2315{
2316 return platform_driver_probe(&iris_driver, iris_probe);
2317}
2318module_init(iris_radio_init);
2319
2320static void __exit iris_radio_exit(void)
2321{
2322 platform_driver_unregister(&iris_driver);
2323}
2324module_exit(iris_radio_exit);
2325
2326MODULE_LICENSE("GPL v2");
2327MODULE_AUTHOR(DRIVER_AUTHOR);
2328MODULE_DESCRIPTION(DRIVER_DESC);