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