blob: 47e23e5605088a10e54df1ab5e54c07563ae14ce [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:
1657 radio->srch_rds.srch_station.srch_mode = srch;
1658 radio->srch_rds.srch_station.srch_dir = dir;
1659 radio->srch_rds.srch_station.scan_time =
1660 radio->g_scan_time;
1661 retval = hci_fm_search_rds_stations(&radio->srch_rds,
1662 radio->fm_hdev);
1663 break;
1664 default:
1665 radio->srch_st.srch_mode = srch;
1666 radio->srch_st.scan_time = radio->g_scan_time;
1667 radio->srch_st.srch_dir = dir;
1668 retval = hci_fm_search_stations(
1669 &radio->srch_st, radio->fm_hdev);
1670 break;
1671 }
1672
1673 } else {
1674 retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
1675 }
1676
1677 return retval;
1678}
1679
1680static int iris_set_region(struct iris_device *radio, int req_region)
1681{
1682 int retval;
1683 radio->region = req_region;
1684
1685 switch (radio->region) {
1686 case IRIS_REGION_US:
1687 {
1688 radio->recv_conf.band_low_limit = 88100;
1689 radio->recv_conf.band_high_limit = 108000;
1690 radio->recv_conf.emphasis = 0;
1691 radio->recv_conf.hlsi = 0;
1692 radio->recv_conf.ch_spacing = 0;
1693 radio->recv_conf.rds_std = 0;
1694 }
1695 break;
1696 case IRIS_REGION_EU:
1697 {
1698 radio->recv_conf.band_low_limit = 88100;
1699 radio->recv_conf.band_high_limit = 108000;
1700 radio->recv_conf.emphasis = 0;
1701 radio->recv_conf.hlsi = 0;
1702 radio->recv_conf.ch_spacing = 0;
1703 radio->recv_conf.rds_std = 0;
1704 }
1705 break;
1706 case IRIS_REGION_JAPAN:
1707 {
1708 radio->recv_conf.band_low_limit = 76000;
1709 radio->recv_conf.band_high_limit = 108000;
1710 radio->recv_conf.emphasis = 0;
1711 radio->recv_conf.hlsi = 0;
1712 radio->recv_conf.ch_spacing = 0;
1713 }
1714 break;
1715 default:
1716 {
1717 radio->recv_conf.emphasis = 0;
1718 radio->recv_conf.hlsi = 0;
1719 radio->recv_conf.ch_spacing = 0;
1720 radio->recv_conf.rds_std = 0;
1721 }
1722 break;
1723 }
1724
1725
1726 retval = hci_set_fm_recv_conf(
1727 &radio->recv_conf,
1728 radio->fm_hdev);
1729
1730 return retval;
1731}
1732
1733static int iris_set_freq(struct iris_device *radio, unsigned int freq)
1734{
1735
1736 int retval;
1737 retval = hci_fm_tune_station(&freq, radio->fm_hdev);
1738 if (retval < 0)
1739 FMDERR("Error while setting the frequency : %d\n", retval);
1740 return retval;
1741}
1742
1743
1744static int iris_vidioc_queryctrl(struct file *file, void *priv,
1745 struct v4l2_queryctrl *qc)
1746{
1747 unsigned char i;
1748 int retval = -EINVAL;
1749
1750 for (i = 0; i < ARRAY_SIZE(iris_v4l2_queryctrl); i++) {
1751 if (qc->id && qc->id == iris_v4l2_queryctrl[i].id) {
1752 memcpy(qc, &(iris_v4l2_queryctrl[i]), sizeof(*qc));
1753 retval = 0;
1754 break;
1755 }
1756 }
1757
1758 return retval;
1759}
1760
1761static int iris_vidioc_g_ctrl(struct file *file, void *priv,
1762 struct v4l2_control *ctrl)
1763{
1764 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1765 int retval = 0;
1766
1767 switch (ctrl->id) {
1768 case V4L2_CID_AUDIO_VOLUME:
1769 break;
1770 case V4L2_CID_AUDIO_MUTE:
1771 ctrl->value = radio->mute_mode.hard_mute;
1772 break;
1773 case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
1774 ctrl->value = radio->g_search_mode;
1775 break;
1776 case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
1777 ctrl->value = radio->g_scan_time;
1778 break;
1779 case V4L2_CID_PRIVATE_IRIS_SRCHON:
1780 break;
1781 case V4L2_CID_PRIVATE_IRIS_STATE:
1782 break;
1783 case V4L2_CID_PRIVATE_IRIS_IOVERC:
1784 retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
1785 if (retval < 0)
1786 return retval;
1787 ctrl->value = radio->st_dbg_param.io_verc;
1788 break;
1789 case V4L2_CID_PRIVATE_IRIS_INTDET:
1790 retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
1791 if (retval < 0)
1792 return retval;
1793 ctrl->value = radio->st_dbg_param.in_det_out;
1794 break;
1795 case V4L2_CID_PRIVATE_IRIS_REGION:
1796 ctrl->value = radio->region;
1797 break;
1798 case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
1799 retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
1800 break;
1801 case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
1802 break;
1803 case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
1804 break;
1805 case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
1806 break;
1807 case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
1808 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1809 radio->fm_hdev);
1810 if (retval < 0)
1811 FMDERR("Error get FM recv conf"
1812 " %d\n", retval);
1813 else
1814 ctrl->value = radio->recv_conf.emphasis;
1815 break;
1816 case V4L2_CID_PRIVATE_IRIS_RDS_STD:
1817 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1818 radio->fm_hdev);
1819 if (retval < 0)
1820 FMDERR("Error get FM recv conf"
1821 " %d\n", retval);
1822 else
1823 ctrl->value = radio->recv_conf.rds_std;
1824 break;
1825 case V4L2_CID_PRIVATE_IRIS_SPACING:
1826 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1827 radio->fm_hdev);
1828 if (retval < 0)
1829 FMDERR("Error get FM recv conf"
1830 " %d\n", retval);
1831 else
1832 ctrl->value = radio->recv_conf.ch_spacing;
1833 break;
1834 case V4L2_CID_PRIVATE_IRIS_RDSON:
1835 retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
1836 radio->fm_hdev);
1837 if (retval < 0)
1838 FMDERR("Error get FM recv conf"
1839 " %d\n", retval);
1840 else
1841 ctrl->value = radio->recv_conf.rds_std;
1842 break;
1843 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
1844 ctrl->value = radio->rds_grp.rds_grp_enable_mask;
1845 break;
1846 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
1847 break;
1848 case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
1849 ctrl->value = radio->rds_grp.rds_buf_size;
1850 break;
1851 case V4L2_CID_PRIVATE_IRIS_PSALL:
1852 ctrl->value = radio->g_rds_grp_proc_ps;
1853 break;
1854 case V4L2_CID_PRIVATE_IRIS_LP_MODE:
1855 break;
1856 case V4L2_CID_PRIVATE_IRIS_ANTENNA:
1857 ctrl->value = radio->g_antenna;
1858 break;
1859 default:
1860 retval = -EINVAL;
1861 }
1862 if (retval < 0)
1863 FMDERR("get control failed with %d, id: %d\n",
1864 retval, ctrl->id);
1865 return retval;
1866}
1867
1868static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
1869 struct v4l2_ext_controls *ctrl)
1870{
1871 return -ENOTSUPP;
1872}
1873
1874static int iris_vidioc_s_ctrl(struct file *file, void *priv,
1875 struct v4l2_control *ctrl)
1876{
1877 struct iris_device *radio = video_get_drvdata(video_devdata(file));
1878 int retval = 0;
1879 unsigned int rds_grps_proc = 0;
1880 __u8 temp_val = 0;
1881 radio->recv_conf.emphasis = 0;
1882 radio->recv_conf.ch_spacing = 0;
1883 radio->recv_conf.hlsi = 0;
1884 radio->recv_conf.band_low_limit = 87500;
1885 radio->recv_conf.band_high_limit = 108000;
1886 radio->recv_conf.rds_std = 0;
1887
1888
1889 switch (ctrl->id) {
1890 case V4L2_CID_AUDIO_VOLUME:
1891 break;
1892 case V4L2_CID_AUDIO_MUTE:
1893 radio->mute_mode.hard_mute = ctrl->value;
1894 radio->mute_mode.soft_mute = IOC_SFT_MUTE;
1895 retval = hci_set_fm_mute_mode(
1896 &radio->mute_mode,
1897 radio->fm_hdev);
1898 if (retval < 0)
1899 FMDERR("Error while set FM hard mute"" %d\n",
1900 retval);
1901 break;
1902 case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
1903 radio->g_search_mode = ctrl->value;
1904 break;
1905 case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
1906 radio->g_scan_time = ctrl->value;
1907 break;
1908 case V4L2_CID_PRIVATE_IRIS_SRCHON:
1909 iris_search(radio, ctrl->value, SRCH_DIR_UP);
1910 break;
1911 case V4L2_CID_PRIVATE_IRIS_STATE:
1912 if (ctrl->value == FM_RECV) {
1913 retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
1914 radio->fm_hdev);
1915 } else {
1916 if (ctrl->value == FM_OFF) {
1917 retval = hci_cmd(
1918 HCI_FM_DISABLE_RECV_CMD,
1919 radio->fm_hdev);
1920 if (retval < 0)
1921 FMDERR("Error on disable FM"
1922 " %d\n", retval);
1923 }
1924 }
1925 break;
1926 case V4L2_CID_PRIVATE_IRIS_REGION:
1927 retval = iris_set_region(radio, ctrl->value);
1928 break;
1929 case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
1930 temp_val = ctrl->value;
1931 retval = hci_fm_set_signal_threshold(
1932 &temp_val,
1933 radio->fm_hdev);
1934 if (retval < 0) {
1935 FMDERR("Error while setting signal threshold\n");
1936 break;
1937 }
1938 break;
1939 case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
1940 radio->srch_rds.srch_pty = ctrl->value;
1941 radio->srch_st_list.srch_pty = ctrl->value;
1942 break;
1943 case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
1944 radio->srch_rds.srch_pi = ctrl->value;
1945 break;
1946 case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
1947 break;
1948 case V4L2_CID_PRIVATE_IRIS_SPACING:
1949 radio->recv_conf.ch_spacing = ctrl->value;
1950 break;
1951 case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
1952 radio->recv_conf.emphasis = ctrl->value;
1953 retval =
1954 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1955 break;
1956 case V4L2_CID_PRIVATE_IRIS_RDS_STD:
1957 radio->recv_conf.rds_std = ctrl->value;
1958 retval =
1959 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1960 break;
1961 case V4L2_CID_PRIVATE_IRIS_RDSON:
1962 radio->recv_conf.rds_std = ctrl->value;
1963 retval =
1964 hci_set_fm_recv_conf(&radio->recv_conf, radio->fm_hdev);
1965 break;
1966 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
1967 radio->rds_grp.rds_grp_enable_mask = ctrl->value;
1968 retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
1969 break;
1970 case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
1971 rds_grps_proc = radio->g_rds_grp_proc_ps | ctrl->value;
1972 retval = hci_fm_rds_grps_process(
1973 &rds_grps_proc,
1974 radio->fm_hdev);
1975 break;
1976 case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
1977 radio->rds_grp.rds_buf_size = ctrl->value;
1978 break;
1979 case V4L2_CID_PRIVATE_IRIS_PSALL:
1980 radio->g_rds_grp_proc_ps = ctrl->value;
1981 break;
1982 case V4L2_CID_PRIVATE_IRIS_LP_MODE:
1983 break;
1984 case V4L2_CID_PRIVATE_IRIS_ANTENNA:
1985 temp_val = ctrl->value;
1986 retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
1987 break;
1988 case V4L2_CID_RDS_TX_PTY:
1989 break;
1990 case V4L2_CID_RDS_TX_PI:
1991 break;
1992 case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
1993 break;
1994 case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
1995 break;
1996 case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
1997 break;
1998 case V4L2_CID_TUNE_POWER_LEVEL:
1999 break;
2000 default:
2001 retval = -EINVAL;
2002 }
2003 return retval;
2004}
2005
2006static int iris_vidioc_g_tuner(struct file *file, void *priv,
2007 struct v4l2_tuner *tuner)
2008{
2009 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2010 int retval;
2011 if (tuner->index > 0)
2012 return -EINVAL;
2013
2014 retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
2015 if (retval < 0)
2016 return retval;
2017
2018 tuner->type = V4L2_TUNER_RADIO;
2019 tuner->rangelow = radio->recv_conf.band_low_limit * TUNE_PARAM;
2020 tuner->rangehigh = radio->recv_conf.band_high_limit * TUNE_PARAM;
2021 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
2022 tuner->capability = V4L2_TUNER_CAP_LOW;
2023 tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
2024 tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
2025 tuner->afc = 0;
2026
2027 return 0;
2028}
2029
2030static int iris_vidioc_s_tuner(struct file *file, void *priv,
2031 struct v4l2_tuner *tuner)
2032{
2033 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2034 int retval;
2035 if (tuner->index > 0)
2036 return -EINVAL;
2037
2038 radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
2039 radio->recv_conf.band_high_limit = tuner->rangehigh / TUNE_PARAM;
2040 if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
2041 radio->stereo_mode.stereo_mode = 0x01;
2042 retval = hci_set_fm_stereo_mode(
2043 &radio->stereo_mode,
2044 radio->fm_hdev);
2045 } else {
2046 radio->stereo_mode.stereo_mode = 0x00;
2047 retval = hci_set_fm_stereo_mode(
2048 &radio->stereo_mode,
2049 radio->fm_hdev);
2050 }
2051 if (retval < 0)
2052 FMDERR(": set tuner failed with %d\n", retval);
2053 return retval;
2054}
2055
2056static int iris_vidioc_g_frequency(struct file *file, void *priv,
2057 struct v4l2_frequency *freq)
2058{
2059 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2060 int retval;
2061
2062 freq->type = V4L2_TUNER_RADIO;
2063 retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
2064 if (retval < 0)
2065 FMDERR("get frequency failed %d\n", retval);
2066 else
2067 freq->frequency =
2068 radio->fm_st_rsp.station_rsp.station_freq * TUNE_PARAM;
2069 return retval;
2070}
2071
2072static int iris_vidioc_s_frequency(struct file *file, void *priv,
2073 struct v4l2_frequency *freq)
2074{
2075 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2076 int retval = -1;
2077 freq->frequency = freq->frequency / TUNE_PARAM;
2078
2079 if (freq->type != V4L2_TUNER_RADIO)
2080 return -EINVAL;
2081
2082 retval = iris_set_freq(radio, freq->frequency);
2083 if (retval < 0)
2084 FMDERR(" set frequency failed with %d\n", retval);
2085 return retval;
2086}
2087
2088static int iris_vidioc_dqbuf(struct file *file, void *priv,
2089 struct v4l2_buffer *buffer)
2090{
2091 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2092 enum iris_buf_t buf_type = buffer->index;
2093 struct kfifo *data_fifo;
2094 unsigned char *buf = (unsigned char *)buffer->m.userptr;
2095 unsigned int len = buffer->length;
2096 if (!access_ok(VERIFY_WRITE, buf, len))
2097 return -EFAULT;
2098 if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
2099 data_fifo = &radio->data_buf[buf_type];
2100 if (buf_type == IRIS_BUF_EVENTS)
2101 if (wait_event_interruptible(radio->event_queue,
2102 kfifo_len(data_fifo)) < 0)
2103 return -EINTR;
2104 } else {
2105 FMDERR("invalid buffer type\n");
2106 return -EINVAL;
2107 }
2108 buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
2109 &radio->buf_lock[buf_type]);
2110
2111 return 0;
2112}
2113
2114static int iris_vidioc_g_fmt_type_private(struct file *file, void *priv,
2115 struct v4l2_format *f)
2116{
2117 return 0;
2118
2119}
2120
2121static int iris_vidioc_s_hw_freq_seek(struct file *file, void *priv,
2122 struct v4l2_hw_freq_seek *seek)
2123{
2124 struct iris_device *radio = video_get_drvdata(video_devdata(file));
2125 int dir;
2126 if (seek->seek_upward)
2127 dir = SRCH_DIR_UP;
2128 else
2129 dir = SRCH_DIR_DOWN;
2130 return iris_search(radio, CTRL_ON, dir);
2131}
2132
2133static int iris_vidioc_querycap(struct file *file, void *priv,
2134 struct v4l2_capability *capability)
2135{
2136 struct iris_device *radio;
2137 radio = video_get_drvdata(video_devdata(file));
2138 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
2139 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
2140 radio->g_cap = capability;
2141 return 0;
2142}
2143
2144
2145static const struct v4l2_ioctl_ops iris_ioctl_ops = {
2146 .vidioc_querycap = iris_vidioc_querycap,
2147 .vidioc_queryctrl = iris_vidioc_queryctrl,
2148 .vidioc_g_ctrl = iris_vidioc_g_ctrl,
2149 .vidioc_s_ctrl = iris_vidioc_s_ctrl,
2150 .vidioc_g_tuner = iris_vidioc_g_tuner,
2151 .vidioc_s_tuner = iris_vidioc_s_tuner,
2152 .vidioc_g_frequency = iris_vidioc_g_frequency,
2153 .vidioc_s_frequency = iris_vidioc_s_frequency,
2154 .vidioc_s_hw_freq_seek = iris_vidioc_s_hw_freq_seek,
2155 .vidioc_dqbuf = iris_vidioc_dqbuf,
2156 .vidioc_g_fmt_type_private = iris_vidioc_g_fmt_type_private,
2157 .vidioc_s_ext_ctrls = iris_vidioc_s_ext_ctrls,
2158};
2159
2160static const struct v4l2_file_operations iris_fops = {
2161 .owner = THIS_MODULE,
2162 .unlocked_ioctl = video_ioctl2,
2163};
2164
2165static struct video_device iris_viddev_template = {
2166 .fops = &iris_fops,
2167 .ioctl_ops = &iris_ioctl_ops,
2168 .name = DRIVER_NAME,
2169 .release = video_device_release,
2170};
2171
2172static struct video_device *video_get_dev(void)
2173{
2174 return priv_videodev;
2175}
2176
2177static int __init iris_probe(struct platform_device *pdev)
2178{
2179 struct iris_device *radio;
2180 int retval;
2181 int radio_nr = -1;
2182 int i;
2183
2184 if (!pdev) {
2185 FMDERR(": pdev is null\n");
2186 return -ENOMEM;
2187 }
2188
2189 radio = kzalloc(sizeof(struct iris_device), GFP_KERNEL);
2190 if (!radio) {
2191 FMDERR(": Could not allocate radio device\n");
2192 return -ENOMEM;
2193 }
2194
2195 radio->dev = &pdev->dev;
2196 platform_set_drvdata(pdev, radio);
2197
2198 radio->videodev = video_device_alloc();
2199 if (!radio->videodev) {
2200 FMDERR(": Could not allocate V4L device\n");
2201 kfree(radio);
2202 return -ENOMEM;
2203 }
2204
2205 memcpy(radio->videodev, &iris_viddev_template,
2206 sizeof(iris_viddev_template));
2207
2208 for (i = 0; i < IRIS_BUF_MAX; i++) {
2209 int kfifo_alloc_rc = 0;
2210 spin_lock_init(&radio->buf_lock[i]);
2211
2212 if (i == IRIS_BUF_RAW_RDS)
2213 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
2214 rds_buf*3, GFP_KERNEL);
2215 else
2216 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
2217 STD_BUF_SIZE, GFP_KERNEL);
2218
2219 if (kfifo_alloc_rc != 0) {
2220 FMDERR("failed allocating buffers %d\n",
2221 kfifo_alloc_rc);
2222 for (; i > -1; i--) {
2223 kfifo_free(&radio->data_buf[i]);
2224 kfree(radio);
2225 return -ENOMEM;
2226 }
2227 }
2228 }
2229
2230 mutex_init(&radio->lock);
2231 init_completion(&radio->sync_xfr_start);
2232 radio->tune_req = 0;
2233 init_waitqueue_head(&radio->event_queue);
2234 init_waitqueue_head(&radio->read_queue);
2235
2236 video_set_drvdata(radio->videodev, radio);
2237
2238 if (NULL == video_get_drvdata(radio->videodev))
2239 FMDERR(": video_get_drvdata failed\n");
2240
2241 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
2242 radio_nr);
2243 if (retval) {
2244 FMDERR(": Could not register video device\n");
2245 video_device_release(radio->videodev);
2246 for (; i > -1; i--)
2247 kfifo_free(&radio->data_buf[i]);
2248 kfree(radio);
2249 return retval;
2250 } else {
2251 priv_videodev = kzalloc(sizeof(struct video_device),
2252 GFP_KERNEL);
2253 memcpy(priv_videodev, radio->videodev,
2254 sizeof(struct video_device));
2255 }
2256 return 0;
2257}
2258
2259
2260static int __devexit iris_remove(struct platform_device *pdev)
2261{
2262 int i;
2263 struct iris_device *radio = platform_get_drvdata(pdev);
2264
2265 video_unregister_device(radio->videodev);
2266
2267 for (i = 0; i < IRIS_BUF_MAX; i++)
2268 kfifo_free(&radio->data_buf[i]);
2269
2270 kfree(radio);
2271
2272 platform_set_drvdata(pdev, NULL);
2273
2274 return 0;
2275}
2276
2277static struct platform_driver iris_driver = {
2278 .driver = {
2279 .owner = THIS_MODULE,
2280 .name = "iris_fm",
2281 },
2282 .remove = __devexit_p(iris_remove),
2283};
2284
2285static int __init iris_radio_init(void)
2286{
2287 return platform_driver_probe(&iris_driver, iris_probe);
2288}
2289module_init(iris_radio_init);
2290
2291static void __exit iris_radio_exit(void)
2292{
2293 platform_driver_unregister(&iris_driver);
2294}
2295module_exit(iris_radio_exit);
2296
2297MODULE_LICENSE("GPL v2");
2298MODULE_AUTHOR(DRIVER_AUTHOR);
2299MODULE_DESCRIPTION(DRIVER_DESC);