blob: fe53ca8df74fa21ba731e2efb1b5df4a2989a2d1 [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
1480static inline void hci_ev_srch_st_list_compl(struct radio_hci_dev *hdev,
1481 struct sk_buff *skb)
1482{
1483 struct iris_device *radio = video_get_drvdata(video_get_dev());
1484 struct hci_ev_srch_list_compl *ev = (void *) skb->data;
1485 radio->srch_st_result = *ev;
1486}
1487
1488static inline void hci_ev_search_next(struct radio_hci_dev *hdev,
1489 struct sk_buff *skb)
1490{
1491 struct iris_device *radio = video_get_drvdata(video_get_dev());
1492 iris_q_event(radio, IRIS_EVT_SCAN_NEXT);
1493}
1494
1495static inline void hci_ev_stereo_status(struct radio_hci_dev *hdev,
1496 struct sk_buff *skb)
1497{
1498 struct iris_device *radio = video_get_drvdata(video_get_dev());
1499 __u8 st_status = *((__u8 *) skb->data);
1500 if (st_status)
1501 iris_q_event(radio, IRIS_EVT_STEREO);
1502 else
1503 iris_q_event(radio, IRIS_EVT_MONO);
1504}
1505
1506void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb)
1507{
1508 struct radio_hci_event_hdr *hdr = (void *) skb->data;
1509 __u8 event = hdr->evt;
1510
1511 skb_pull(skb, RADIO_HCI_EVENT_HDR_SIZE);
1512
1513 switch (event) {
1514 case HCI_EV_TUNE_STATUS:
1515 hci_ev_tune_status(hdev, skb);
1516 break;
1517 case HCI_EV_SEARCH_PROGRESS:
1518 case HCI_EV_SEARCH_RDS_PROGRESS:
1519 case HCI_EV_SEARCH_LIST_PROGRESS:
1520 hci_ev_search_next(hdev, skb);
1521 break;
1522 case HCI_EV_STEREO_STATUS:
1523 hci_ev_stereo_status(hdev, skb);
1524 break;
1525 case HCI_EV_RDS_LOCK_STATUS:
1526 case HCI_EV_SERVICE_AVAILABLE:
1527 case HCI_EV_RDS_RX_DATA:
1528 case HCI_EV_PROGRAM_SERVICE:
1529 case HCI_EV_RADIO_TEXT:
1530 case HCI_EV_FM_AF_LIST:
1531 case HCI_EV_TX_RDS_GRP_COMPL:
1532 case HCI_EV_TX_RDS_CONT_GRP_COMPL:
1533 break;
1534
1535 case HCI_EV_CMD_COMPLETE:
1536 hci_cmd_complete_event(hdev, skb);
1537 break;
1538
1539 case HCI_EV_CMD_STATUS:
1540 hci_cmd_status_event(hdev, skb);
1541 break;
1542
1543 case HCI_EV_SEARCH_COMPLETE:
1544 case HCI_EV_SEARCH_RDS_COMPLETE:
1545 hci_ev_search_compl(hdev, skb);
1546 break;
1547
1548 case HCI_EV_SEARCH_LIST_COMPLETE:
1549 break;
1550
1551 default:
1552 break;
1553 }
1554}
1555
1556/*
1557 * fops/IOCTL helper functions
1558 */
1559
1560static int iris_search(struct iris_device *radio, int on, int dir)
1561{
1562 int retval = 0;
1563 enum search_t srch = radio->g_search_mode & SRCH_MODE;
1564
1565 if (on) {
1566 switch (srch) {
1567 case SCAN_FOR_STRONG:
1568 case SCAN_FOR_WEAK:
1569 radio->srch_st_list.srch_list_dir = dir;
1570 radio->srch_st_list.srch_list_mode = srch;
1571 radio->srch_st_list.srch_list_max = 0;
1572 retval = hci_fm_search_station_list(
1573 &radio->srch_st_list, radio->fm_hdev);
1574 break;
1575 case RDS_SEEK_PTY:
1576 case RDS_SCAN_PTY:
1577 case RDS_SEEK_PI:
1578 radio->srch_rds.srch_station.srch_mode = srch;
1579 radio->srch_rds.srch_station.srch_dir = dir;
1580 radio->srch_rds.srch_station.scan_time =
1581 radio->g_scan_time;
1582 retval = hci_fm_search_rds_stations(&radio->srch_rds,
1583 radio->fm_hdev);
1584 break;
1585 default:
1586 radio->srch_st.srch_mode = srch;
1587 radio->srch_st.scan_time = radio->g_scan_time;
1588 radio->srch_st.srch_dir = dir;
1589 retval = hci_fm_search_stations(
1590 &radio->srch_st, radio->fm_hdev);
1591 break;
1592 }
1593
1594 } else {
1595 retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
1596 }
1597
1598 return retval;
1599}
1600
1601static int iris_set_region(struct iris_device *radio, int req_region)
1602{
1603 int retval;
1604 radio->region = req_region;
1605
1606 switch (radio->region) {
1607 case IRIS_REGION_US:
1608 {
1609 radio->recv_conf.band_low_limit = 88100;
1610 radio->recv_conf.band_high_limit = 108000;
1611 radio->recv_conf.emphasis = 0;
1612 radio->recv_conf.hlsi = 0;
1613 radio->recv_conf.ch_spacing = 0;
1614 radio->recv_conf.rds_std = 0;
1615 }
1616 break;
1617 case IRIS_REGION_EU:
1618 {
1619 radio->recv_conf.band_low_limit = 88100;
1620 radio->recv_conf.band_high_limit = 108000;
1621 radio->recv_conf.emphasis = 0;
1622 radio->recv_conf.hlsi = 0;
1623 radio->recv_conf.ch_spacing = 0;
1624 radio->recv_conf.rds_std = 0;
1625 }
1626 break;
1627 case IRIS_REGION_JAPAN:
1628 {
1629 radio->recv_conf.band_low_limit = 76000;
1630 radio->recv_conf.band_high_limit = 108000;
1631 radio->recv_conf.emphasis = 0;
1632 radio->recv_conf.hlsi = 0;
1633 radio->recv_conf.ch_spacing = 0;
1634 }
1635 break;
1636 default:
1637 {
1638 radio->recv_conf.emphasis = 0;
1639 radio->recv_conf.hlsi = 0;
1640 radio->recv_conf.ch_spacing = 0;
1641 radio->recv_conf.rds_std = 0;
1642 }
1643 break;
1644 }
1645
1646
1647 retval = hci_set_fm_recv_conf(
1648 &radio->recv_conf,
1649 radio->fm_hdev);
1650
1651 return retval;
1652}
1653
1654static int iris_set_freq(struct iris_device *radio, unsigned int freq)
1655{
1656
1657 int retval;
1658 retval = hci_fm_tune_station(&freq, radio->fm_hdev);
1659 if (retval < 0)
1660 FMDERR("Error while setting the frequency : %d\n", retval);
1661 return retval;
1662}
1663
1664
1665static int iris_vidioc_queryctrl(struct file *file, void *priv,
1666 struct v4l2_queryctrl *qc)
1667{
1668 unsigned char i;
1669 int retval = -EINVAL;
1670
1671 for (i = 0; i < ARRAY_SIZE(iris_v4l2_queryctrl); i++) {
1672 if (qc->id && qc->id == iris_v4l2_queryctrl[i].id) {
1673 memcpy(qc, &(iris_v4l2_queryctrl[i]), sizeof(*qc));
1674 retval = 0;
1675 break;
1676 }
1677 }
1678
1679 return retval;
1680}
1681
1682static int iris_vidioc_g_ctrl(struct file *file, void *priv,
1683 struct v4l2_control *ctrl)
1684{
1685 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1686 int retval = 0;
1687
1688 switch (ctrl->id) {
1689 case V4L2_CID_AUDIO_VOLUME:
1690 break;
1691 case V4L2_CID_AUDIO_MUTE:
1692 ctrl->value = radio->mute_mode.hard_mute;
1693 break;
1694 case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
1695 ctrl->value = radio->g_search_mode;
1696 break;
1697 case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
1698 ctrl->value = radio->g_scan_time;
1699 break;
1700 case V4L2_CID_PRIVATE_IRIS_SRCHON:
1701 break;
1702 case V4L2_CID_PRIVATE_IRIS_STATE:
1703 break;
1704 case V4L2_CID_PRIVATE_IRIS_IOVERC:
1705 retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
1706 if (retval < 0)
1707 return retval;
1708 ctrl->value = radio->st_dbg_param.io_verc;
1709 break;
1710 case V4L2_CID_PRIVATE_IRIS_INTDET:
1711 retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
1712 if (retval < 0)
1713 return retval;
1714 ctrl->value = radio->st_dbg_param.in_det_out;
1715 break;
1716 case V4L2_CID_PRIVATE_IRIS_REGION:
1717 ctrl->value = radio->region;
1718 break;
1719 case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
1720 retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
1721 break;
1722 case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
1723 break;
1724 case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
1725 break;
1726 case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
1727 break;
1728 case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
1729 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1730 radio->fm_hdev);
1731 if (retval < 0)
1732 FMDERR("Error get FM recv conf"
1733 " %d\n", retval);
1734 else
1735 ctrl->value = radio->recv_conf.emphasis;
1736 break;
1737 case V4L2_CID_PRIVATE_IRIS_RDS_STD:
1738 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1739 radio->fm_hdev);
1740 if (retval < 0)
1741 FMDERR("Error get FM recv conf"
1742 " %d\n", retval);
1743 else
1744 ctrl->value = radio->recv_conf.rds_std;
1745 break;
1746 case V4L2_CID_PRIVATE_IRIS_SPACING:
1747 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1748 radio->fm_hdev);
1749 if (retval < 0)
1750 FMDERR("Error get FM recv conf"
1751 " %d\n", retval);
1752 else
1753 ctrl->value = radio->recv_conf.ch_spacing;
1754 break;
1755 case V4L2_CID_PRIVATE_IRIS_RDSON:
1756 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1757 radio->fm_hdev);
1758 if (retval < 0)
1759 FMDERR("Error get FM recv conf"
1760 " %d\n", retval);
1761 else
1762 ctrl->value = radio->recv_conf.rds_std;
1763 break;
1764 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
1765 ctrl->value = radio->rds_grp.rds_grp_enable_mask;
1766 break;
1767 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
1768 break;
1769 case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
1770 ctrl->value = radio->rds_grp.rds_buf_size;
1771 break;
1772 case V4L2_CID_PRIVATE_IRIS_PSALL:
1773 ctrl->value = radio->g_rds_grp_proc_ps;
1774 break;
1775 case V4L2_CID_PRIVATE_IRIS_LP_MODE:
1776 break;
1777 case V4L2_CID_PRIVATE_IRIS_ANTENNA:
1778 ctrl->value = radio->g_antenna;
1779 break;
1780 default:
1781 retval = -EINVAL;
1782 }
1783 if (retval < 0)
1784 FMDERR("get control failed with %d, id: %d\n",
1785 retval, ctrl->id);
1786 return retval;
1787}
1788
1789static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
1790 struct v4l2_ext_controls *ctrl)
1791{
1792 return -ENOTSUPP;
1793}
1794
1795static int iris_vidioc_s_ctrl(struct file *file, void *priv,
1796 struct v4l2_control *ctrl)
1797{
1798 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1799 int retval = 0;
1800 unsigned int rds_grps_proc = 0;
1801 __u8 temp_val = 0;
1802 radio->recv_conf.emphasis = 0;
1803 radio->recv_conf.ch_spacing = 0;
1804 radio->recv_conf.hlsi = 0;
1805 radio->recv_conf.band_low_limit = 87500;
1806 radio->recv_conf.band_high_limit = 108000;
1807 radio->recv_conf.rds_std = 0;
1808
1809
1810 switch (ctrl->id) {
1811 case V4L2_CID_AUDIO_VOLUME:
1812 break;
1813 case V4L2_CID_AUDIO_MUTE:
1814 radio->mute_mode.hard_mute = ctrl->value;
1815 radio->mute_mode.soft_mute = IOC_SFT_MUTE;
1816 retval = hci_set_fm_mute_mode(
1817 &radio->mute_mode,
1818 radio->fm_hdev);
1819 if (retval < 0)
1820 FMDERR("Error while set FM hard mute"" %d\n",
1821 retval);
1822 break;
1823 case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
1824 radio->g_search_mode = ctrl->value;
1825 break;
1826 case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
1827 radio->g_scan_time = ctrl->value;
1828 break;
1829 case V4L2_CID_PRIVATE_IRIS_SRCHON:
1830 iris_search(radio, ctrl->value, SRCH_DIR_UP);
1831 break;
1832 case V4L2_CID_PRIVATE_IRIS_STATE:
1833 if (ctrl->value == FM_RECV) {
1834 retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
1835 radio->fm_hdev);
1836 } else {
1837 if (ctrl->value == FM_OFF) {
1838 retval = hci_cmd(
1839 HCI_FM_DISABLE_RECV_CMD,
1840 radio->fm_hdev);
1841 if (retval < 0)
1842 FMDERR("Error on disable FM"
1843 " %d\n", retval);
1844 }
1845 }
1846 break;
1847 case V4L2_CID_PRIVATE_IRIS_REGION:
1848 retval = iris_set_region(radio, ctrl->value);
1849 break;
1850 case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
1851 temp_val = ctrl->value;
1852 retval = hci_fm_set_signal_threshold(
1853 &temp_val,
1854 radio->fm_hdev);
1855 if (retval < 0) {
1856 FMDERR("Error while setting signal threshold\n");
1857 break;
1858 }
1859 break;
1860 case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
1861 radio->srch_rds.srch_pty = ctrl->value;
1862 radio->srch_st_list.srch_pty = ctrl->value;
1863 break;
1864 case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
1865 radio->srch_rds.srch_pi = ctrl->value;
1866 break;
1867 case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
1868 break;
1869 case V4L2_CID_PRIVATE_IRIS_SPACING:
1870 radio->recv_conf.ch_spacing = ctrl->value;
1871 break;
1872 case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
1873 radio->recv_conf.emphasis = ctrl->value;
1874 retval =
1875 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1876 break;
1877 case V4L2_CID_PRIVATE_IRIS_RDS_STD:
1878 radio->recv_conf.rds_std = ctrl->value;
1879 retval =
1880 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1881 break;
1882 case V4L2_CID_PRIVATE_IRIS_RDSON:
1883 radio->recv_conf.rds_std = ctrl->value;
1884 retval =
1885 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1886 break;
1887 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
1888 radio->rds_grp.rds_grp_enable_mask = ctrl->value;
1889 retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
1890 break;
1891 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
1892 rds_grps_proc = radio->g_rds_grp_proc_ps | ctrl->value;
1893 retval = hci_fm_rds_grps_process(
1894 &rds_grps_proc,
1895 radio->fm_hdev);
1896 break;
1897 case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
1898 radio->rds_grp.rds_buf_size = ctrl->value;
1899 break;
1900 case V4L2_CID_PRIVATE_IRIS_PSALL:
1901 radio->g_rds_grp_proc_ps = ctrl->value;
1902 break;
1903 case V4L2_CID_PRIVATE_IRIS_LP_MODE:
1904 break;
1905 case V4L2_CID_PRIVATE_IRIS_ANTENNA:
1906 temp_val = ctrl->value;
1907 retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
1908 break;
1909 case V4L2_CID_RDS_TX_PTY:
1910 break;
1911 case V4L2_CID_RDS_TX_PI:
1912 break;
1913 case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
1914 break;
1915 case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
1916 break;
1917 case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
1918 break;
1919 case V4L2_CID_TUNE_POWER_LEVEL:
1920 break;
1921 default:
1922 retval = -EINVAL;
1923 }
1924 return retval;
1925}
1926
1927static int iris_vidioc_g_tuner(struct file *file, void *priv,
1928 struct v4l2_tuner *tuner)
1929{
1930 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1931 int retval;
1932 if (tuner->index > 0)
1933 return -EINVAL;
1934
1935 retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
1936 if (retval < 0)
1937 return retval;
1938
1939 tuner->type = V4L2_TUNER_RADIO;
1940 tuner->rangelow = radio->recv_conf.band_low_limit * TUNE_PARAM;
1941 tuner->rangehigh = radio->recv_conf.band_high_limit * TUNE_PARAM;
1942 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
1943 tuner->capability = V4L2_TUNER_CAP_LOW;
1944 tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
1945 tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
1946 tuner->afc = 0;
1947
1948 return 0;
1949}
1950
1951static int iris_vidioc_s_tuner(struct file *file, void *priv,
1952 struct v4l2_tuner *tuner)
1953{
1954 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1955 int retval;
1956 if (tuner->index > 0)
1957 return -EINVAL;
1958
1959 radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
1960 radio->recv_conf.band_high_limit = tuner->rangehigh / TUNE_PARAM;
1961 if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
1962 radio->stereo_mode.stereo_mode = 0x01;
1963 retval = hci_set_fm_stereo_mode(
1964 &radio->stereo_mode,
1965 radio->fm_hdev);
1966 } else {
1967 radio->stereo_mode.stereo_mode = 0x00;
1968 retval = hci_set_fm_stereo_mode(
1969 &radio->stereo_mode,
1970 radio->fm_hdev);
1971 }
1972 if (retval < 0)
1973 FMDERR(": set tuner failed with %d\n", retval);
1974 return retval;
1975}
1976
1977static int iris_vidioc_g_frequency(struct file *file, void *priv,
1978 struct v4l2_frequency *freq)
1979{
1980 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1981 int retval;
1982
1983 freq->type = V4L2_TUNER_RADIO;
1984 retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
1985 if (retval < 0)
1986 FMDERR("get frequency failed %d\n", retval);
1987 else
1988 freq->frequency =
1989 radio->fm_st_rsp.station_rsp.station_freq * TUNE_PARAM;
1990 return retval;
1991}
1992
1993static int iris_vidioc_s_frequency(struct file *file, void *priv,
1994 struct v4l2_frequency *freq)
1995{
1996 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1997 int retval = -1;
1998 freq->frequency = freq->frequency / TUNE_PARAM;
1999
2000 if (freq->type != V4L2_TUNER_RADIO)
2001 return -EINVAL;
2002
2003 retval = iris_set_freq(radio, freq->frequency);
2004 if (retval < 0)
2005 FMDERR(" set frequency failed with %d\n", retval);
2006 return retval;
2007}
2008
2009static int iris_vidioc_dqbuf(struct file *file, void *priv,
2010 struct v4l2_buffer *buffer)
2011{
2012 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2013 enum iris_buf_t buf_type = buffer->index;
2014 struct kfifo *data_fifo;
2015 unsigned char *buf = (unsigned char *)buffer->m.userptr;
2016 unsigned int len = buffer->length;
2017 if (!access_ok(VERIFY_WRITE, buf, len))
2018 return -EFAULT;
2019 if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
2020 data_fifo = &radio->data_buf[buf_type];
2021 if (buf_type == IRIS_BUF_EVENTS)
2022 if (wait_event_interruptible(radio->event_queue,
2023 kfifo_len(data_fifo)) < 0)
2024 return -EINTR;
2025 } else {
2026 FMDERR("invalid buffer type\n");
2027 return -EINVAL;
2028 }
2029 buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
2030 &radio->buf_lock[buf_type]);
2031
2032 return 0;
2033}
2034
2035static int iris_vidioc_g_fmt_type_private(struct file *file, void *priv,
2036 struct v4l2_format *f)
2037{
2038 return 0;
2039
2040}
2041
2042static int iris_vidioc_s_hw_freq_seek(struct file *file, void *priv,
2043 struct v4l2_hw_freq_seek *seek)
2044{
2045 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2046 int dir;
2047 if (seek->seek_upward)
2048 dir = SRCH_DIR_UP;
2049 else
2050 dir = SRCH_DIR_DOWN;
2051 return iris_search(radio, CTRL_ON, dir);
2052}
2053
2054static int iris_vidioc_querycap(struct file *file, void *priv,
2055 struct v4l2_capability *capability)
2056{
2057 struct iris_device *radio;
2058 radio = video_get_drvdata(video_devdata(file));
2059 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
2060 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
2061 radio->g_cap = capability;
2062 return 0;
2063}
2064
2065
2066static const struct v4l2_ioctl_ops iris_ioctl_ops = {
2067 .vidioc_querycap = iris_vidioc_querycap,
2068 .vidioc_queryctrl = iris_vidioc_queryctrl,
2069 .vidioc_g_ctrl = iris_vidioc_g_ctrl,
2070 .vidioc_s_ctrl = iris_vidioc_s_ctrl,
2071 .vidioc_g_tuner = iris_vidioc_g_tuner,
2072 .vidioc_s_tuner = iris_vidioc_s_tuner,
2073 .vidioc_g_frequency = iris_vidioc_g_frequency,
2074 .vidioc_s_frequency = iris_vidioc_s_frequency,
2075 .vidioc_s_hw_freq_seek = iris_vidioc_s_hw_freq_seek,
2076 .vidioc_dqbuf = iris_vidioc_dqbuf,
2077 .vidioc_g_fmt_type_private = iris_vidioc_g_fmt_type_private,
2078 .vidioc_s_ext_ctrls = iris_vidioc_s_ext_ctrls,
2079};
2080
2081static const struct v4l2_file_operations iris_fops = {
2082 .owner = THIS_MODULE,
2083 .unlocked_ioctl = video_ioctl2,
2084};
2085
2086static struct video_device iris_viddev_template = {
2087 .fops = &iris_fops,
2088 .ioctl_ops = &iris_ioctl_ops,
2089 .name = DRIVER_NAME,
2090 .release = video_device_release,
2091};
2092
2093static struct video_device *video_get_dev(void)
2094{
2095 return priv_videodev;
2096}
2097
2098static int __init iris_probe(struct platform_device *pdev)
2099{
2100 struct iris_device *radio;
2101 int retval;
2102 int radio_nr = -1;
2103 int i;
2104
2105 if (!pdev) {
2106 FMDERR(": pdev is null\n");
2107 return -ENOMEM;
2108 }
2109
2110 radio = kzalloc(sizeof(struct iris_device), GFP_KERNEL);
2111 if (!radio) {
2112 FMDERR(": Could not allocate radio device\n");
2113 return -ENOMEM;
2114 }
2115
2116 radio->dev = &pdev->dev;
2117 platform_set_drvdata(pdev, radio);
2118
2119 radio->videodev = video_device_alloc();
2120 if (!radio->videodev) {
2121 FMDERR(": Could not allocate V4L device\n");
2122 kfree(radio);
2123 return -ENOMEM;
2124 }
2125
2126 memcpy(radio->videodev, &iris_viddev_template,
2127 sizeof(iris_viddev_template));
2128
2129 for (i = 0; i < IRIS_BUF_MAX; i++) {
2130 int kfifo_alloc_rc = 0;
2131 spin_lock_init(&radio->buf_lock[i]);
2132
2133 if (i == IRIS_BUF_RAW_RDS)
2134 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
2135 rds_buf*3, GFP_KERNEL);
2136 else
2137 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
2138 STD_BUF_SIZE, GFP_KERNEL);
2139
2140 if (kfifo_alloc_rc != 0) {
2141 FMDERR("failed allocating buffers %d\n",
2142 kfifo_alloc_rc);
2143 for (; i > -1; i--) {
2144 kfifo_free(&radio->data_buf[i]);
2145 kfree(radio);
2146 return -ENOMEM;
2147 }
2148 }
2149 }
2150
2151 mutex_init(&radio->lock);
2152 init_completion(&radio->sync_xfr_start);
2153 radio->tune_req = 0;
2154 init_waitqueue_head(&radio->event_queue);
2155 init_waitqueue_head(&radio->read_queue);
2156
2157 video_set_drvdata(radio->videodev, radio);
2158
2159 if (NULL == video_get_drvdata(radio->videodev))
2160 FMDERR(": video_get_drvdata failed\n");
2161
2162 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
2163 radio_nr);
2164 if (retval) {
2165 FMDERR(": Could not register video device\n");
2166 video_device_release(radio->videodev);
2167 for (; i > -1; i--)
2168 kfifo_free(&radio->data_buf[i]);
2169 kfree(radio);
2170 return retval;
2171 } else {
2172 priv_videodev = kzalloc(sizeof(struct video_device),
2173 GFP_KERNEL);
2174 memcpy(priv_videodev, radio->videodev,
2175 sizeof(struct video_device));
2176 }
2177 return 0;
2178}
2179
2180
2181static int __devexit iris_remove(struct platform_device *pdev)
2182{
2183 int i;
2184 struct iris_device *radio = platform_get_drvdata(pdev);
2185
2186 video_unregister_device(radio->videodev);
2187
2188 for (i = 0; i < IRIS_BUF_MAX; i++)
2189 kfifo_free(&radio->data_buf[i]);
2190
2191 kfree(radio);
2192
2193 platform_set_drvdata(pdev, NULL);
2194
2195 return 0;
2196}
2197
2198static struct platform_driver iris_driver = {
2199 .driver = {
2200 .owner = THIS_MODULE,
2201 .name = "iris_fm",
2202 },
2203 .remove = __devexit_p(iris_remove),
2204};
2205
2206static int __init iris_radio_init(void)
2207{
2208 return platform_driver_probe(&iris_driver, iris_probe);
2209}
2210module_init(iris_radio_init);
2211
2212static void __exit iris_radio_exit(void)
2213{
2214 platform_driver_unregister(&iris_driver);
2215}
2216module_exit(iris_radio_exit);
2217
2218MODULE_LICENSE("GPL v2");
2219MODULE_AUTHOR(DRIVER_AUTHOR);
2220MODULE_DESCRIPTION(DRIVER_DESC);