blob: f04dfe5f4dd6c059329c619a151a3e3ef96d8651 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009-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/*
14 * Qualcomm Tavarua FM core driver
15 */
16
17/* driver definitions */
18#define DRIVER_AUTHOR "Qualcomm"
19#define DRIVER_NAME "radio-tavarua"
20#define DRIVER_CARD "Qualcomm FM Radio Transceiver"
21#define DRIVER_DESC "I2C radio driver for Qualcomm FM Radio Transceiver "
22#define DRIVER_VERSION "1.0.0"
23
24#include <linux/version.h>
25#include <linux/init.h> /* Initdata */
26#include <linux/delay.h> /* udelay */
27#include <linux/uaccess.h> /* copy to/from user */
28#include <linux/kfifo.h> /* lock free circular buffer */
29#include <linux/param.h>
30#include <linux/i2c.h>
31#include <linux/irq.h>
32#include <linux/interrupt.h>
33
34/* kernel includes */
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/version.h>
38#include <linux/videodev2.h>
39#include <linux/mutex.h>
40#include <media/v4l2-common.h>
41#include <asm/unaligned.h>
42#include <media/v4l2-ioctl.h>
43#include <linux/unistd.h>
44#include <asm/atomic.h>
45#include <media/tavarua.h>
46#include <linux/mfd/marimba.h>
47#include <linux/platform_device.h>
48#include <linux/workqueue.h>
49#include <linux/slab.h>
50/*
51regional parameters for radio device
52*/
53struct region_params_t {
54 enum tavarua_region_t region;
55 unsigned int band_high;
56 unsigned int band_low;
57 char emphasis;
58 char rds_std;
59 char spacing;
60};
61
62struct srch_params_t {
63 unsigned short srch_pi;
64 unsigned char srch_pty;
65 unsigned int preset_num;
66 int get_list;
67};
68
69/* Main radio device structure,
70acts as a shadow copy of the
71actual tavaura registers */
72struct tavarua_device {
73 struct video_device *videodev;
74 /* driver management */
75 int users;
76 /* top level driver data */
77 struct marimba *marimba;
78 struct device *dev;
79 /* platform specific functionality */
80 struct marimba_fm_platform_data *pdata;
81 unsigned int chipID;
82 /*RDS buffers + Radio event buffer*/
83 struct kfifo data_buf[TAVARUA_BUF_MAX];
84 /* search paramters */
85 struct srch_params_t srch_params;
86 /* keep track of pending xfrs */
87 int pending_xfrs[TAVARUA_XFR_MAX];
88 int xfr_bytes_left;
89 int xfr_in_progress;
90 /* Transmit data */
91 enum tavarua_xfr_ctrl_t tx_mode;
92 /* synchrnous xfr data */
93 unsigned char sync_xfr_regs[XFR_REG_NUM];
94 struct completion sync_xfr_start;
95 struct completion sync_req_done;
96 int tune_req;
97 /* internal register status */
98 unsigned char registers[RADIO_REGISTERS];
99 /* regional settings */
100 struct region_params_t region_params;
101 /* power mode */
102 int lp_mode;
103 int handle_irq;
104 /* global lock */
105 struct mutex lock;
106 /* buffer locks*/
107 spinlock_t buf_lock[TAVARUA_BUF_MAX];
108 /* work queue */
109 struct workqueue_struct *wqueue;
110 struct delayed_work work;
111 /* wait queue for blocking event read */
112 wait_queue_head_t event_queue;
113 /* wait queue for raw rds read */
114 wait_queue_head_t read_queue;
115 /* PTY for FM Tx */
116 int pty;
117 /* PI for FM TX */
118 int pi;
119 /*PS repeatcount for PS Tx */
120 int ps_repeatcount;
121};
122
123/**************************************************************************
124 * Module Parameters
125 **************************************************************************/
126
127/* Radio Nr */
128static int radio_nr = -1;
129module_param(radio_nr, int, 0);
130MODULE_PARM_DESC(radio_nr, "Radio Nr");
131static int wait_timeout = WAIT_TIMEOUT;
132/* Bahama's version*/
133static u8 bahama_version;
134/* RDS buffer blocks */
135static unsigned int rds_buf = 100;
136module_param(rds_buf, uint, 0);
137MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
138/* static variables */
139static struct tavarua_device *private_data;
140/* forward declerations */
141static int tavarua_disable_interrupts(struct tavarua_device *radio);
142static int tavarua_setup_interrupts(struct tavarua_device *radio,
143 enum radio_state_t state);
144static int tavarua_start(struct tavarua_device *radio,
145 enum radio_state_t state);
146static int tavarua_request_irq(struct tavarua_device *radio);
147static void start_pending_xfr(struct tavarua_device *radio);
148/* work function */
149static void read_int_stat(struct work_struct *work);
150
151static int is_bahama(void)
152{
153 int id = 0;
154
155 switch (id = adie_get_detected_connectivity_type()) {
156 case BAHAMA_ID:
157 FMDBG("It is Bahama\n");
158 return 1;
159
160 case MARIMBA_ID:
161 FMDBG("It is Marimba\n");
162 return 0;
163 default:
164 printk(KERN_ERR "%s: unexpected adie connectivity type: %d\n",
165 __func__, id);
166 return -ENODEV;
167 }
168}
169
170static int set_fm_slave_id(struct tavarua_device *radio)
171{
172 int bahama_present = is_bahama();
173
174 if (bahama_present == -ENODEV)
175 return -ENODEV;
176
177 if (bahama_present)
178 radio->marimba->mod_id = SLAVE_ID_BAHAMA_FM;
179 else
180 radio->marimba->mod_id = MARIMBA_SLAVE_ID_FM;
181
182 return 0;
183}
184
185/*=============================================================================
186FUNCTION: tavarua_isr
187=============================================================================*/
188/**
189 This function is called when GPIO is toggled. This functions queues the event
190 to interrupt queue, which is later handled by isr handling funcion.
191 i.e. INIT_DELAYED_WORK(&radio->work, read_int_stat);
192
193 @param irq: irq that is toggled.
194 @param dev_id: structure pointer passed by client.
195
196 @return IRQ_HANDLED.
197*/
198static irqreturn_t tavarua_isr(int irq, void *dev_id)
199{
200 struct tavarua_device *radio = dev_id;
201 /* schedule a tasklet to handle host intr */
202 /* The call to queue_delayed_work ensures that a minimum delay (in jiffies)
203 * passes before the work is actually executed. The return value from the
204 * function is nonzero if the work_struct was actually added to queue
205 * (otherwise, it may have already been there and will not be added a second
206 * time).
207 */
208 queue_delayed_work(radio->wqueue, &radio->work,
209 msecs_to_jiffies(TAVARUA_DELAY));
210 return IRQ_HANDLED;
211}
212
213/**************************************************************************
214 * Interface to radio internal registers over top level marimba driver
215 *************************************************************************/
216
217/*=============================================================================
218FUNCTION: tavarua_read_registers
219=============================================================================*/
220/**
221 This function is called to read a number of bytes from an I2C interface.
222 The bytes read are stored in internal register status (shadow copy).
223
224 @param radio: structure pointer passed by client.
225 @param offset: register offset.
226 @param len: num of bytes.
227
228 @return => 0 if successful.
229 @return < 0 if failure.
230*/
231static int tavarua_read_registers(struct tavarua_device *radio,
232 unsigned char offset, int len)
233{
234 int retval = 0, i = 0;
235 retval = set_fm_slave_id(radio);
236
237 if (retval == -ENODEV)
238 return retval;
239
240 FMDBG_I2C("I2C Slave: %x, Read Offset(%x): Data [",
241 radio->marimba->mod_id,
242 offset);
243
244 retval = marimba_read(radio->marimba, offset,
245 &radio->registers[offset], len);
246
247 if (retval > 0) {
248 for (i = 0; i < len; i++)
249 FMDBG_I2C("%02x ", radio->registers[offset+i]);
250 FMDBG_I2C(" ]\n");
251
252 }
253 return retval;
254}
255
256/*=============================================================================
257FUNCTION: tavarua_write_register
258=============================================================================*/
259/**
260 This function is called to write a byte over the I2C interface.
261 The corresponding shadow copy is stored in internal register status.
262
263 @param radio: structure pointer passed by client.
264 @param offset: register offset.
265 @param value: buffer to be written to the registers.
266
267 @return => 0 if successful.
268 @return < 0 if failure.
269*/
270static int tavarua_write_register(struct tavarua_device *radio,
271 unsigned char offset, unsigned char value)
272{
273 int retval;
274 retval = set_fm_slave_id(radio);
275
276 if (retval == -ENODEV)
277 return retval;
278
279 FMDBG_I2C("I2C Slave: %x, Write Offset(%x): Data[",
280 radio->marimba->mod_id,
281 offset);
282 retval = marimba_write(radio->marimba, offset, &value, 1);
283 if (retval > 0) {
284 if (offset < RADIO_REGISTERS) {
285 radio->registers[offset] = value;
286 FMDBG_I2C("%02x ", radio->registers[offset]);
287 }
288 FMDBG_I2C(" ]\n");
289 }
290 return retval;
291}
292
293/*=============================================================================
294FUNCTION: tavarua_write_registers
295=============================================================================*/
296/**
297 This function is called to write a number of bytes over the I2C interface.
298 The corresponding shadow copy is stored in internal register status.
299
300 @param radio: structure pointer passed by client.
301 @param offset: register offset.
302 @param buf: buffer to be written to the registers.
303 @param len: num of bytes.
304
305 @return => 0 if successful.
306 @return < 0 if failure.
307*/
308static int tavarua_write_registers(struct tavarua_device *radio,
309 unsigned char offset, unsigned char *buf, int len)
310{
311
312 int i;
313 int retval;
314 retval = set_fm_slave_id(radio);
315
316 if (retval == -ENODEV)
317 return retval;
318
319 FMDBG_I2C("I2C Slave: %x, Write Offset(%x): Data[",
320 radio->marimba->mod_id,
321 offset);
322 retval = marimba_write(radio->marimba, offset, buf, len);
323 if (retval > 0) { /* if write successful, update internal state too */
324 for (i = 0; i < len; i++) {
325 if ((offset+i) < RADIO_REGISTERS) {
326 radio->registers[offset+i] = buf[i];
327 FMDBG_I2C("%x ", radio->registers[offset+i]);
328 }
329 }
330 FMDBG_I2C(" ]\n");
331 }
332 return retval;
333}
334
335/*=============================================================================
336FUNCTION: read_data_blocks
337=============================================================================*/
338/**
339 This function reads Raw RDS blocks from Core regs to driver
340 internal regs (shadow copy).
341
342 @param radio: structure pointer passed by client.
343 @param offset: register offset.
344
345 @return => 0 if successful.
346 @return < 0 if failure.
347*/
348static int read_data_blocks(struct tavarua_device *radio, unsigned char offset)
349{
350 /* read all 3 RDS blocks */
351 return tavarua_read_registers(radio, offset, RDS_BLOCK*4);
352}
353
354/*=============================================================================
355FUNCTION: tavarua_rds_read
356=============================================================================*/
357/**
358 This is a rds processing function reads that reads Raw RDS blocks from Core
359 regs to driver internal regs (shadow copy). It then fills the V4L2 RDS buffer,
360 which is read by App using JNI interface.
361
362 @param radio: structure pointer passed by client.
363
364 @return None.
365*/
366static void tavarua_rds_read(struct tavarua_device *radio)
367{
368 struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
369 unsigned char blocknum;
370 unsigned char tmp[3];
371
372 if (read_data_blocks(radio, RAW_RDS) < 0)
373 return;
374 /* copy all four RDS blocks to internal buffer */
375 for (blocknum = 0; blocknum < RDS_BLOCKS_NUM; blocknum++) {
376 /* Fill the V4L2 RDS buffer */
377 put_unaligned(cpu_to_le16(radio->registers[RAW_RDS +
378 blocknum*RDS_BLOCK]), (unsigned short *) tmp);
379 tmp[2] = blocknum; /* offset name */
380 tmp[2] |= blocknum << 3; /* received offset */
381 tmp[2] |= 0x40; /* corrected error(s) */
382
383 /* copy RDS block to internal buffer */
384 kfifo_in_locked(rds_buf, tmp, 3, &radio->buf_lock[TAVARUA_BUF_RAW_RDS]);
385 }
386 /* wake up read queue */
387 if (kfifo_len(rds_buf))
388 wake_up_interruptible(&radio->read_queue);
389
390}
391
392/*=============================================================================
393FUNCTION: request_read_xfr
394=============================================================================*/
395/**
396 This function sets the desired MODE in the XFRCTRL register and also sets the
397 CTRL field to read.
398 This is an asynchronous way of reading the XFR registers. Client would request
399 by setting the desired mode in the XFRCTRL register and then would initiate
400 the actual data register read by calling copy_from_xfr up on SOC signals
401 success.
402
403 NOTE:
404
405 The Data Transfer (XFR) registers are used to pass various data and
406 configuration parameters between the Core and host processor.
407
408 To read from the XFR registers, the host processor must set the desired MODE
409 in the XFRCTRL register and set the CTRL field to read. The Core will then
410 populate the XFRDAT0 - XFRDAT15 registers with the defined mode bytes. The
411 Core will set the TRANSFER interrupt status bit and interrupt the host if the
412 TRANSFERCTRL interrupt control bit is set. The host can then extract the XFR
413 mode bytes once it detects that the Core has updated the registers.
414
415 @param radio: structure pointer passed by client.
416
417 @return Always returns 0.
418*/
419static int request_read_xfr(struct tavarua_device *radio,
420 enum tavarua_xfr_ctrl_t mode){
421
422 tavarua_write_register(radio, XFRCTRL, mode);
423 msleep(TAVARUA_DELAY);
424 return 0;
425}
426
427/*=============================================================================
428FUNCTION: copy_from_xfr
429=============================================================================*/
430/**
431 This function is used to read XFR mode bytes once it detects that the Core
432 has updated the registers. It also updates XFR regs to the appropriate
433 internal buffer n bytes.
434
435 NOTE:
436
437 This function should be used in conjuction with request_read_xfr. Refer
438 request_read_xfr for XFR mode transaction details.
439
440 @param radio: structure pointer passed by client.
441 @param buf_type: Index into RDS/Radio event buffer to use.
442 @param len: num of bytes.
443
444 @return Always returns 0.
445*/
446static int copy_from_xfr(struct tavarua_device *radio,
447 enum tavarua_buf_t buf_type, unsigned int n){
448
449 struct kfifo *data_fifo = &radio->data_buf[buf_type];
450 unsigned char *xfr_regs = &radio->registers[XFRCTRL+1];
451 kfifo_in_locked(data_fifo, xfr_regs, n, &radio->buf_lock[buf_type]);
452 return 0;
453}
454
455/*=============================================================================
456FUNCTION: write_to_xfr
457=============================================================================*/
458/**
459 This function sets the desired MODE in the XFRCTRL register and it also sets
460 the CTRL field and data to write.
461 This also writes all the XFRDATx registers with the desired input buffer.
462
463 NOTE:
464
465 The Data Transfer (XFR) registers are used to pass various data and
466 configuration parameters between the Core and host processor.
467
468 To write data to the Core, the host processor updates XFRDAT0 - XFRDAT15 with
469 the appropriate mode bytes. The host processor must then set the desired MODE
470 in the XFRCTRL register and set the CTRL field to write. The core will detect
471 that the XFRCTRL register was written to and will read the XFR mode bytes.
472 After reading all the mode bytes, the Core will set the TRANSFER interrupt
473 status bit and interrupt the host if the TRANSFERCTRL interrupt control bit
474 is set.
475
476 @param radio: structure pointer passed by client.
477 @param mode: XFR mode to write in XFRCTRL register.
478 @param buf: buffer to be written to the registers.
479 @param len: num of bytes.
480
481 @return => 0 if successful.
482 @return < 0 if failure.
483*/
484static int write_to_xfr(struct tavarua_device *radio, unsigned char mode,
485 char *buf, int len)
486{
487 char buffer[len+1];
488 memcpy(buffer+1, buf, len);
489 /* buffer[0] corresponds to XFRCTRL register
490 set the CTRL bit to 1 for write mode
491 */
492 buffer[0] = ((1<<7) | mode);
493 return tavarua_write_registers(radio, XFRCTRL, buffer, sizeof(buffer));
494}
495
496/*=============================================================================
497FUNCTION: xfr_intf_own
498=============================================================================*/
499/**
500 This function is used to check if there is any pending XFR mode operation.
501 If yes, wait for it to complete, else update the flag to indicate XFR
502 operation is in progress
503
504 @param radio: structure pointer passed by client.
505
506 @return 0 on success.
507 -ETIME on timeout.
508*/
509static int xfr_intf_own(struct tavarua_device *radio)
510{
511
512 mutex_lock(&radio->lock);
513 if (radio->xfr_in_progress) {
514 radio->pending_xfrs[TAVARUA_XFR_SYNC] = 1;
515 mutex_unlock(&radio->lock);
516 if (!wait_for_completion_timeout(&radio->sync_xfr_start,
517 msecs_to_jiffies(wait_timeout)))
518 return -ETIME;
519 } else {
520 FMDBG("gained ownership of xfr\n");
521 radio->xfr_in_progress = 1;
522 mutex_unlock(&radio->lock);
523 }
524 return 0;
525}
526
527/*=============================================================================
528FUNCTION: sync_read_xfr
529=============================================================================*/
530/**
531 This function is used to do synchronous XFR read operation.
532
533 @param radio: structure pointer passed by client.
534 @param xfr_type: XFR mode to write in XFRCTRL register.
535 @param buf: buffer to be read from the core.
536
537 @return => 0 if successful.
538 @return < 0 if failure.
539*/
540static int sync_read_xfr(struct tavarua_device *radio,
541 enum tavarua_xfr_ctrl_t xfr_type, unsigned char *buf)
542{
543 int retval;
544 retval = xfr_intf_own(radio);
545 if (retval < 0)
546 return retval;
547 retval = tavarua_write_register(radio, XFRCTRL, xfr_type);
548
549 if (retval >= 0) {
550 /* Wait for interrupt i.e. complete
551 (&radio->sync_req_done); call */
552 if (!wait_for_completion_timeout(&radio->sync_req_done,
553 msecs_to_jiffies(wait_timeout)) || (retval < 0)) {
554 retval = -ETIME;
555 } else {
556 memcpy(buf, radio->sync_xfr_regs, XFR_REG_NUM);
557 }
558 }
559 radio->xfr_in_progress = 0;
560 start_pending_xfr(radio);
561 FMDBG("%s: %d\n", __func__, retval);
562 return retval;
563}
564
565/*=============================================================================
566FUNCTION: sync_write_xfr
567=============================================================================*/
568/**
569 This function is used to do synchronous XFR write operation.
570
571 @param radio: structure pointer passed by client.
572 @param xfr_type: XFR mode to write in XFRCTRL register.
573 @param buf: buffer to be written to the core.
574
575 @return => 0 if successful.
576 @return < 0 if failure.
577*/
578static int sync_write_xfr(struct tavarua_device *radio,
579 enum tavarua_xfr_ctrl_t xfr_type, unsigned char *buf)
580{
581 int retval;
582 retval = xfr_intf_own(radio);
583 if (retval < 0)
584 return retval;
585 retval = write_to_xfr(radio, xfr_type, buf, XFR_REG_NUM);
586
587 if (retval >= 0) {
588 /* Wait for interrupt i.e. complete
589 (&radio->sync_req_done); call */
590 if (!wait_for_completion_timeout(&radio->sync_req_done,
591 msecs_to_jiffies(wait_timeout)) || (retval < 0)) {
592 FMDBG("Write xfr timeout");
593 }
594 }
595 radio->xfr_in_progress = 0;
596 start_pending_xfr(radio);
597 FMDBG("%s: %d\n", __func__, retval);
598 return retval;
599}
600
601
602/*=============================================================================
603FUNCTION: start_pending_xfr
604=============================================================================*/
605/**
606 This function checks if their are any pending xfr interrupts and if
607 the interrupts are either RDS PS, RDS RT, RDS AF, SCANNEXT, SEARCH or SYNC
608 then initiates corresponding read operation. Preference is given to RAW RDS
609 data (SYNC) over processed data (PS, RT, AF, etc) from core.
610
611 @param radio: structure pointer passed by client.
612
613 @return None.
614*/
615static void start_pending_xfr(struct tavarua_device *radio)
616{
617 int i;
618 enum tavarua_xfr_t xfr;
619 for (i = 0; i < TAVARUA_XFR_MAX; i++) {
620 if (radio->pending_xfrs[i]) {
621 radio->xfr_in_progress = 1;
622 xfr = (enum tavarua_xfr_t)i;
623 switch (xfr) {
624 /* priority given to synchronous xfrs */
625 case TAVARUA_XFR_SYNC:
626 complete(&radio->sync_xfr_start);
627 break;
628 /* asynchrnous xfrs */
629 case TAVARUA_XFR_SRCH_LIST:
630 request_read_xfr(radio, RX_STATIONS_0);
631 break;
632 case TAVARUA_XFR_RT_RDS:
633 request_read_xfr(radio, RDS_RT_0);
634 break;
635 case TAVARUA_XFR_PS_RDS:
636 request_read_xfr(radio, RDS_PS_0);
637 break;
638 case TAVARUA_XFR_AF_LIST:
639 request_read_xfr(radio, RDS_AF_0);
640 break;
641 default:
642 FMDERR("%s: Unsupported XFR %d\n",
643 __func__, xfr);
644 }
645 radio->pending_xfrs[i] = 0;
646 FMDBG("resurrect xfr %d\n", i);
647 }
648 }
649 return;
650}
651
652/*=============================================================================
653FUNCTION: tavarua_q_event
654=============================================================================*/
655/**
656 This function is called to queue an event for user.
657
658 NOTE:
659 Applications call the VIDIOC_QBUF ioctl to enqueue an empty (capturing) or
660 filled (output) buffer in the driver's incoming queue.
661
662 Pleaes refer tavarua_probe where we register different ioctl's for FM.
663
664 @param radio: structure pointer passed by client.
665 @param event: event to be queued.
666
667 @return None.
668*/
669static void tavarua_q_event(struct tavarua_device *radio,
670 enum tavarua_evt_t event)
671{
672
673 struct kfifo *data_b = &radio->data_buf[TAVARUA_BUF_EVENTS];
674 unsigned char evt = event;
675 FMDBG("updating event_q with event %x\n", event);
676 if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[TAVARUA_BUF_EVENTS]))
677 wake_up_interruptible(&radio->event_queue);
678}
679
680/*=============================================================================
681FUNCTION: tavarua_start_xfr
682=============================================================================*/
683/**
684 This function is called to process interrupts which require multiple XFR
685 operations (RDS search, RDS PS, RDS RT, etc). if any XFR operation is
686 already in progress we store information about pending interrupt, which
687 will be processed in future when current pending operation is done.
688
689 @param radio: structure pointer passed by client.
690 @param pending_id: XFR operation (which requires multiple XFR operations in
691 steps) to start.
692 @param xfr_id: XFR mode to write in XFRCTRL register.
693
694 @return None.
695*/
696static void tavarua_start_xfr(struct tavarua_device *radio,
697 enum tavarua_xfr_t pending_id, enum tavarua_xfr_ctrl_t xfr_id)
698{
699 if (radio->xfr_in_progress)
700 radio->pending_xfrs[pending_id] = 1;
701 else {
702 radio->xfr_in_progress = 1;
703 request_read_xfr(radio, xfr_id);
704 }
705}
706
707/*=============================================================================
708FUNCTION: tavarua_handle_interrupts
709=============================================================================*/
710/**
711 This function processes the interrupts.
712
713 NOTE:
714 tavarua_q_event is used to queue events in App buffer. i.e. App calls the
715 VIDIOC_QBUF ioctl to enqueue an empty (capturing) buffer, which is filled
716 by tavarua_q_event call.
717
718 Any async event that requires multiple steps, i.e. search, RT, PS, etc is
719 handled one at a time. (We preserve other interrupts when processing one).
720 Sync interrupts are given priority.
721
722 @param radio: structure pointer passed by client.
723
724 @return None.
725*/
726static void tavarua_handle_interrupts(struct tavarua_device *radio)
727{
728 int i;
729 int retval;
730 unsigned char xfr_status;
731 if (!radio->handle_irq) {
732 FMDBG("IRQ happend, but I wont handle it\n");
733 return;
734 }
735 mutex_lock(&radio->lock);
736 tavarua_read_registers(radio, STATUS_REG1, STATUS_REG_NUM);
737
738 FMDBG("INTSTAT1 <%x>\n", radio->registers[STATUS_REG1]);
739 FMDBG("INTSTAT2 <%x>\n", radio->registers[STATUS_REG2]);
740 FMDBG("INTSTAT3 <%x>\n", radio->registers[STATUS_REG3]);
741
742 if (radio->registers[STATUS_REG1] & READY) {
743 complete(&radio->sync_req_done);
744 tavarua_q_event(radio, TAVARUA_EVT_RADIO_READY);
745 }
746
747 /* Tune completed */
748 if (radio->registers[STATUS_REG1] & TUNE) {
749 if (radio->tune_req) {
750 complete(&radio->sync_req_done);
751 radio->tune_req = 0;
752 }
753 tavarua_q_event(radio, TAVARUA_EVT_TUNE_SUCC);
754 if (radio->srch_params.get_list) {
755 tavarua_start_xfr(radio, TAVARUA_XFR_SRCH_LIST,
756 RX_STATIONS_0);
757 }
758 radio->srch_params.get_list = 0;
759 radio->xfr_in_progress = 0;
760 radio->xfr_bytes_left = 0;
761 for (i = 0; i < TAVARUA_BUF_MAX; i++) {
762 if (i >= TAVARUA_BUF_RT_RDS)
763 kfifo_reset(&radio->data_buf[i]);
764 }
765 for (i = 0; i < TAVARUA_XFR_MAX; i++) {
766 if (i >= TAVARUA_XFR_RT_RDS)
767 radio->pending_xfrs[i] = 0;
768 }
769 retval = tavarua_read_registers(radio, TUNECTRL, 1);
770 /* send to user station parameters */
771 if (retval > -1) {
772 /* Signal strength */
773 if (!(radio->registers[TUNECTRL] & SIGSTATE))
774 tavarua_q_event(radio, TAVARUA_EVT_BELOW_TH);
775 else
776 tavarua_q_event(radio, TAVARUA_EVT_ABOVE_TH);
777 /* mono/stereo */
778 if ((radio->registers[TUNECTRL] & MOSTSTATE))
779 tavarua_q_event(radio, TAVARUA_EVT_STEREO);
780 else
781 tavarua_q_event(radio, TAVARUA_EVT_MONO);
782 /* is RDS available */
783 if ((radio->registers[TUNECTRL] & RDSSYNC))
784 tavarua_q_event(radio, TAVARUA_EVT_RDS_AVAIL);
785 else
786 tavarua_q_event(radio,
787 TAVARUA_EVT_RDS_NOT_AVAIL);
788 }
789
790 } else {
791 if (radio->tune_req) {
792 FMDERR("Tune INT is pending\n");
793 mutex_unlock(&radio->lock);
794 return;
795 }
796 }
797 /* Search completed (read FREQ) */
798 if (radio->registers[STATUS_REG1] & SEARCH)
799 tavarua_q_event(radio, TAVARUA_EVT_SEEK_COMPLETE);
800
801 /* Scanning for next station */
802 if (radio->registers[STATUS_REG1] & SCANNEXT)
803 tavarua_q_event(radio, TAVARUA_EVT_SCAN_NEXT);
804
805 /* Signal indicator change (read SIGSTATE) */
806 if (radio->registers[STATUS_REG1] & SIGNAL) {
807 retval = tavarua_read_registers(radio, TUNECTRL, 1);
808 if (retval > -1) {
809 if (!(radio->registers[TUNECTRL] & SIGSTATE))
810 tavarua_q_event(radio, TAVARUA_EVT_BELOW_TH);
811 else
812 tavarua_q_event(radio, TAVARUA_EVT_ABOVE_TH);
813 }
814 }
815
816 /* RDS synchronization state change (read RDSSYNC) */
817 if (radio->registers[STATUS_REG1] & SYNC) {
818 retval = tavarua_read_registers(radio, TUNECTRL, 1);
819 if (retval > -1) {
820 if ((radio->registers[TUNECTRL] & RDSSYNC))
821 tavarua_q_event(radio, TAVARUA_EVT_RDS_AVAIL);
822 else
823 tavarua_q_event(radio,
824 TAVARUA_EVT_RDS_NOT_AVAIL);
825 }
826 }
827
828 /* Audio Control indicator (read AUDIOIND) */
829 if (radio->registers[STATUS_REG1] & AUDIO) {
830 retval = tavarua_read_registers(radio, AUDIOIND, 1);
831 if (retval > -1) {
832 if ((radio->registers[AUDIOIND] & 0x01))
833 tavarua_q_event(radio, TAVARUA_EVT_STEREO);
834 else
835 tavarua_q_event(radio, TAVARUA_EVT_MONO);
836 }
837 }
838
839 /* interrupt register 2 */
840
841 /* New unread RDS data group available */
842 if (radio->registers[STATUS_REG2] & RDSDAT) {
843 FMDBG("Raw RDS Available\n");
844 tavarua_rds_read(radio);
845 tavarua_q_event(radio, TAVARUA_EVT_NEW_RAW_RDS);
846 }
847
848 /* New RDS Program Service Table available */
849 if (radio->registers[STATUS_REG2] & RDSPS) {
850 FMDBG("New PS RDS\n");
851 tavarua_start_xfr(radio, TAVARUA_XFR_PS_RDS, RDS_PS_0);
852 }
853
854 /* New RDS Radio Text available */
855 if (radio->registers[STATUS_REG2] & RDSRT) {
856 FMDBG("New RT RDS\n");
857 tavarua_start_xfr(radio, TAVARUA_XFR_RT_RDS, RDS_RT_0);
858 }
859
860 /* New RDS Radio Text available */
861 if (radio->registers[STATUS_REG2] & RDSAF) {
862 FMDBG("New AF RDS\n");
863 tavarua_start_xfr(radio, TAVARUA_XFR_AF_LIST, RDS_AF_0);
864 }
865 /* Trasmitter an RDS Group */
866 if (radio->registers[STATUS_REG2] & TXRDSDAT) {
867 FMDBG("New TXRDSDAT\n");
868 tavarua_q_event(radio, TAVARUA_EVT_TXRDSDAT);
869 }
870
871 /* Complete RDS buffer is available for transmission */
872 if (radio->registers[STATUS_REG2] & TXRDSDONE) {
873 FMDBG("New TXRDSDAT\n");
874 tavarua_q_event(radio, TAVARUA_EVT_TXRDSDONE);
875 }
876 /* interrupt register 3 */
877
878 /* Data transfer (XFR) completed */
879 if (radio->registers[STATUS_REG3] & TRANSFER) {
880 FMDBG("XFR Interrupt\n");
881 tavarua_read_registers(radio, XFRCTRL, XFR_REG_NUM+1);
882 FMDBG("XFRCTRL IS: %x\n", radio->registers[XFRCTRL]);
883 xfr_status = radio->registers[XFRCTRL];
884 switch (xfr_status) {
885 case RDS_PS_0:
886 FMDBG("PS Header\n");
887 copy_from_xfr(radio, TAVARUA_BUF_PS_RDS, 5);
888 radio->xfr_bytes_left = (radio->registers[XFRCTRL+1] &
889 0x0F) * 8;
890 FMDBG("PS RDS Length: %d\n", radio->xfr_bytes_left);
891 if ((radio->xfr_bytes_left > 0) &&
892 (radio->xfr_bytes_left < 97))
893 request_read_xfr(radio, RDS_PS_1);
894 else
895 radio->xfr_in_progress = 0;
896 break;
897 case RDS_PS_1:
898 case RDS_PS_2:
899 case RDS_PS_3:
900 case RDS_PS_4:
901 case RDS_PS_5:
902 case RDS_PS_6:
903 FMDBG("PS Data\n");
904 copy_from_xfr(radio, TAVARUA_BUF_PS_RDS, XFR_REG_NUM);
905 radio->xfr_bytes_left -= XFR_REG_NUM;
906 if (radio->xfr_bytes_left > 0) {
907 if ((xfr_status + 1) > RDS_PS_6)
908 request_read_xfr(radio, RDS_PS_6);
909 else
910 request_read_xfr(radio, xfr_status+1);
911 } else {
912 radio->xfr_in_progress = 0;
913 tavarua_q_event(radio, TAVARUA_EVT_NEW_PS_RDS);
914 }
915 break;
916 case RDS_RT_0:
917 FMDBG("RT Header\n");
918 copy_from_xfr(radio, TAVARUA_BUF_RT_RDS, 5);
919 radio->xfr_bytes_left = radio->registers[XFRCTRL+1]
920 & 0x7F;
921 FMDBG("RT RDS Length: %d\n", radio->xfr_bytes_left);
922 /*RT_1 to RT_4 16 byte registers so 64 bytes */
923 if ((radio->xfr_bytes_left > 0)
924 && (radio->xfr_bytes_left < 65))
925 request_read_xfr(radio, RDS_RT_1);
926 break;
927 case RDS_RT_1:
928 case RDS_RT_2:
929 case RDS_RT_3:
930 case RDS_RT_4:
931 FMDBG("xfr interrupt RT data\n");
932 copy_from_xfr(radio, TAVARUA_BUF_RT_RDS, XFR_REG_NUM);
933 radio->xfr_bytes_left -= XFR_REG_NUM;
934 if (radio->xfr_bytes_left > 0)
935 request_read_xfr(radio, xfr_status+1);
936 else {
937 radio->xfr_in_progress = 0;
938 tavarua_q_event(radio, TAVARUA_EVT_NEW_RT_RDS);
939 }
940 break;
941 case RDS_AF_0:
942 copy_from_xfr(radio, TAVARUA_BUF_AF_LIST,
943 XFR_REG_NUM);
944 radio->xfr_bytes_left = radio->registers[XFRCTRL+5]-11;
945 if (radio->xfr_bytes_left > 0)
946 request_read_xfr(radio, RDS_AF_1);
947 else
948 radio->xfr_in_progress = 0;
949 break;
950 case RDS_AF_1:
951 copy_from_xfr(radio, TAVARUA_BUF_AF_LIST,
952 radio->xfr_bytes_left);
953 tavarua_q_event(radio, TAVARUA_EVT_NEW_AF_LIST);
954 radio->xfr_in_progress = 0;
955 break;
956 case RX_CONFIG:
957 case RADIO_CONFIG:
958 case RDS_CONFIG:
959 memcpy(radio->sync_xfr_regs,
960 &radio->registers[XFRCTRL+1], XFR_REG_NUM);
961 complete(&radio->sync_req_done);
962 break;
963 case RX_STATIONS_0:
964 FMDBG("Search list has %d stations\n",
965 radio->registers[XFRCTRL+1]);
966 radio->xfr_bytes_left = radio->registers[XFRCTRL+1]*2;
967 if (radio->xfr_bytes_left > 14) {
968 copy_from_xfr(radio, TAVARUA_BUF_SRCH_LIST,
969 XFR_REG_NUM);
970 request_read_xfr(radio, RX_STATIONS_1);
971 } else if (radio->xfr_bytes_left) {
972 FMDBG("In else RX_STATIONS_0\n");
973 copy_from_xfr(radio, TAVARUA_BUF_SRCH_LIST,
974 radio->xfr_bytes_left+1);
975 tavarua_q_event(radio,
976 TAVARUA_EVT_NEW_SRCH_LIST);
977 radio->xfr_in_progress = 0;
978 }
979 break;
980 case RX_STATIONS_1:
981 FMDBG("In RX_STATIONS_1");
982 copy_from_xfr(radio, TAVARUA_BUF_SRCH_LIST,
983 radio->xfr_bytes_left);
984 tavarua_q_event(radio, TAVARUA_EVT_NEW_SRCH_LIST);
985 radio->xfr_in_progress = 0;
986 break;
987 case PHY_TXGAIN:
988 FMDBG("read PHY_TXGAIN is successful");
989 complete(&radio->sync_req_done);
990 break;
991 case (0x80 | RX_CONFIG):
992 case (0x80 | RADIO_CONFIG):
993 case (0x80 | RDS_CONFIG):
994 case (0x80 | INT_CTRL):
995 complete(&radio->sync_req_done);
996 break;
997 case (0x80 | RDS_RT_0):
998 FMDBG("RT Header Sent\n");
999 complete(&radio->sync_req_done);
1000 break;
1001 case (0x80 | RDS_RT_1):
1002 case (0x80 | RDS_RT_2):
1003 case (0x80 | RDS_RT_3):
1004 case (0x80 | RDS_RT_4):
1005 FMDBG("xfr interrupt RT data Sent\n");
1006 complete(&radio->sync_req_done);
1007 break;
1008 /*TX Specific transfer */
1009 case (0x80 | RDS_PS_0):
1010 FMDBG("PS Header Sent\n");
1011 complete(&radio->sync_req_done);
1012 break;
1013 case (0x80 | RDS_PS_1):
1014 case (0x80 | RDS_PS_2):
1015 case (0x80 | RDS_PS_3):
1016 case (0x80 | RDS_PS_4):
1017 case (0x80 | RDS_PS_5):
1018 case (0x80 | RDS_PS_6):
1019 FMDBG("xfr interrupt PS data Sent\n");
1020 complete(&radio->sync_req_done);
1021 break;
1022 case (0x80 | PHY_TXGAIN):
1023 FMDBG("write PHY_TXGAIN is successful");
1024 complete(&radio->sync_req_done);
1025 break;
1026 default:
1027 FMDERR("UNKNOWN XFR = %d\n", xfr_status);
1028 }
1029 if (!radio->xfr_in_progress)
1030 start_pending_xfr(radio);
1031
1032 }
1033
1034 /* Error occurred. Read ERRCODE to determine cause */
1035 if (radio->registers[STATUS_REG3] & ERROR) {
1036#ifdef FM_DEBUG
1037 unsigned char xfr_buf[XFR_REG_NUM];
1038 int retval = sync_read_xfr(radio, ERROR_CODE, xfr_buf);
1039 FMDBG("retval of ERROR_CODE read : %d\n", retval);
1040#endif
1041 FMDERR("ERROR STATE\n");
1042 }
1043
1044 mutex_unlock(&radio->lock);
1045 FMDBG("Work is done\n");
1046
1047}
1048
1049/*=============================================================================
1050FUNCTION: read_int_stat
1051=============================================================================*/
1052/**
1053 This function is scheduled whenever there is an interrupt pending in interrupt
1054 queue. i.e. kfmradio.
1055
1056 Whenever there is a GPIO interrupt, a delayed work will be queued in to the
1057 'kfmradio' work queue. Upon execution of this work in the queue, a a call
1058 to read_int_stat function will be made , which would in turn handle the
1059 interrupts by reading the INTSTATx registers.
1060 NOTE:
1061 Tasks to be run out of a workqueue need to be packaged in a struct
1062 work_struct structure.
1063
1064 @param work: work_struct structure.
1065
1066 @return None.
1067*/
1068static void read_int_stat(struct work_struct *work)
1069{
1070 struct tavarua_device *radio = container_of(work,
1071 struct tavarua_device, work.work);
1072 tavarua_handle_interrupts(radio);
1073}
1074
1075/*************************************************************************
1076 * irq helper functions
1077 ************************************************************************/
1078
1079/*=============================================================================
1080FUNCTION: tavarua_request_irq
1081=============================================================================*/
1082/**
1083 This function is called to acquire a FM GPIO and enable FM interrupts.
1084
1085 @param radio: structure pointer passed by client.
1086
1087 @return 0 if success else otherwise.
1088*/
1089static int tavarua_request_irq(struct tavarua_device *radio)
1090{
1091 int retval;
1092 int irq = radio->pdata->irq;
1093 if (radio == NULL)
1094 return -EINVAL;
1095
1096 /* A workqueue created with create_workqueue() will have one worker thread
1097 * for each CPU on the system; create_singlethread_workqueue(), instead,
1098 * creates a workqueue with a single worker process. The name of the queue
1099 * is limited to ten characters; it is only used for generating the "command"
1100 * for the kernel thread(s) (which can be seen in ps or top).
1101 */
1102 radio->wqueue = create_singlethread_workqueue("kfmradio");
1103 if (!radio->wqueue)
1104 return -ENOMEM;
1105 /* allocate an interrupt line */
1106 /* On success, request_irq() returns 0 if everything goes as
1107 planned. Your interrupt handler will start receiving its
1108 interrupts immediately. On failure, request_irq()
1109 returns:
1110 -EINVAL
1111 The IRQ number you requested was either
1112 invalid or reserved, or your passed a NULL
1113 pointer for the handler() parameter.
1114
1115 -EBUSY The IRQ you requested is already being
1116 handled, and the IRQ cannot be shared.
1117
1118 -ENXIO The m68k returns this value for an invalid
1119 IRQ number.
1120 */
1121 /* Use request_any_context_irq, So that it might work for nested or
1122 nested interrupts. in MSM8x60, FM is connected to PMIC GPIO and it
1123 is a nested interrupt*/
1124 retval = request_any_context_irq(irq, tavarua_isr,
1125 IRQ_TYPE_EDGE_FALLING, "fm interrupt", radio);
1126 if (retval < 0) {
1127 FMDERR("Couldn't acquire FM gpio %d\n", irq);
1128 return retval;
1129 } else {
1130 FMDBG("FM GPIO %d registered\n", irq);
1131 }
1132 retval = enable_irq_wake(irq);
1133 if (retval < 0) {
1134 FMDERR("Could not enable FM interrupt\n ");
1135 free_irq(irq , radio);
1136 }
1137 return retval;
1138}
1139
1140/*=============================================================================
1141FUNCTION: tavarua_disable_irq
1142=============================================================================*/
1143/**
1144 This function is called to disable FM irq and free up FM interrupt handling
1145 resources.
1146
1147 @param radio: structure pointer passed by client.
1148
1149 @return 0 if success else otherwise.
1150*/
1151static int tavarua_disable_irq(struct tavarua_device *radio)
1152{
1153 int irq;
1154 if (!radio)
1155 return -EINVAL;
1156 irq = radio->pdata->irq;
1157 disable_irq_wake(irq);
1158 cancel_delayed_work_sync(&radio->work);
1159 flush_workqueue(radio->wqueue);
1160 free_irq(irq, radio);
1161 destroy_workqueue(radio->wqueue);
1162 return 0;
1163}
1164
1165/*************************************************************************
1166 * fops/IOCTL helper functions
1167 ************************************************************************/
1168
1169/*=============================================================================
1170FUNCTION: tavarua_search
1171=============================================================================*/
1172/**
1173 This interface sets the search control features.
1174
1175 @param radio: structure pointer passed by client.
1176 @param on: The value of a control.
1177 @param dir: FM search direction.
1178
1179 @return => 0 if successful.
1180 @return < 0 if failure.
1181*/
1182static int tavarua_search(struct tavarua_device *radio, int on, int dir)
1183{
1184 enum search_t srch = radio->registers[SRCHCTRL] & SRCH_MODE;
1185
1186 FMDBG("In tavarua_search\n");
1187 if (on) {
1188 radio->registers[SRCHRDS1] = 0x00;
1189 radio->registers[SRCHRDS2] = 0x00;
1190 /* Set freq band */
1191 switch (srch) {
1192 case SCAN_FOR_STRONG:
1193 case SCAN_FOR_WEAK:
1194 radio->srch_params.get_list = 1;
1195 radio->registers[SRCHRDS2] =
1196 radio->srch_params.preset_num;
1197 break;
1198 case RDS_SEEK_PTY:
1199 case RDS_SCAN_PTY:
1200 radio->registers[SRCHRDS2] =
1201 radio->srch_params.srch_pty;
1202 break;
1203 case RDS_SEEK_PI:
1204 radio->registers[SRCHRDS1] =
1205 (radio->srch_params.srch_pi & 0xFF00) >> 8;
1206 radio->registers[SRCHRDS2] =
1207 (radio->srch_params.srch_pi & 0x00FF);
1208 break;
1209 default:
1210 break;
1211 }
1212 radio->registers[SRCHCTRL] |= SRCH_ON;
1213 } else {
1214 radio->registers[SRCHCTRL] &= ~SRCH_ON;
1215 radio->srch_params.get_list = 0;
1216 }
1217 radio->registers[SRCHCTRL] = (dir << 3) |
1218 (radio->registers[SRCHCTRL] & 0xF7);
1219
1220 FMDBG("SRCHCTRL <%x>\n", radio->registers[SRCHCTRL]);
1221 FMDBG("Search Started\n");
1222 return tavarua_write_registers(radio, SRCHRDS1,
1223 &radio->registers[SRCHRDS1], 3);
1224}
1225
1226/*=============================================================================
1227FUNCTION: tavarua_set_region
1228=============================================================================*/
1229/**
1230 This interface configures the FM radio.
1231
1232 @param radio: structure pointer passed by client.
1233 @param req_region: FM band types. These types defines the FM band minimum and
1234 maximum frequencies in the FM band.
1235
1236 @return => 0 if successful.
1237 @return < 0 if failure.
1238*/
1239static int tavarua_set_region(struct tavarua_device *radio,
1240 int req_region)
1241{
1242 int retval = 0;
1243 unsigned char xfr_buf[XFR_REG_NUM];
1244 unsigned char value;
1245 unsigned int spacing = 0.100 * FREQ_MUL;
1246 unsigned int band_low, band_high;
1247 unsigned int low_band_limit = 76.0 * FREQ_MUL;
1248 enum tavarua_region_t region = req_region;
1249
1250 /* Set freq band */
1251 switch (region) {
1252 case TAVARUA_REGION_US:
1253 case TAVARUA_REGION_EU:
1254 case TAVARUA_REGION_JAPAN_WIDE:
1255 SET_REG_FIELD(radio->registers[RDCTRL], 0,
1256 RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
1257 break;
1258 case TAVARUA_REGION_JAPAN:
1259 SET_REG_FIELD(radio->registers[RDCTRL], 1,
1260 RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
1261 break;
1262 default:
1263 retval = sync_read_xfr(radio, RADIO_CONFIG, xfr_buf);
1264 if (retval < 0) {
1265 FMDERR("failed to get RADIO_CONFIG\n");
1266 return retval;
1267 }
1268 band_low = (radio->region_params.band_low -
1269 low_band_limit) / spacing;
1270 band_high = (radio->region_params.band_high -
1271 low_band_limit) / spacing;
1272 FMDBG("low_band: %x, high_band: %x\n", band_low, band_high);
1273 xfr_buf[0] = band_low >> 8;
1274 xfr_buf[1] = band_low & 0xFF;
1275 xfr_buf[2] = band_high >> 8;
1276 xfr_buf[3] = band_high & 0xFF;
1277 retval = sync_write_xfr(radio, RADIO_CONFIG, xfr_buf);
1278 if (retval < 0) {
1279 FMDERR("Could not set regional settings\n");
1280 return retval;
1281 }
1282 break;
1283 }
1284
1285 /* Set channel spacing */
1286 switch (region) {
1287 case TAVARUA_REGION_US:
1288 case TAVARUA_REGION_EU:
1289 value = 0;
1290 break;
1291 case TAVARUA_REGION_JAPAN:
1292 value = 1;
1293 break;
1294 case TAVARUA_REGION_JAPAN_WIDE:
1295 value = 2;
1296 break;
1297 default:
1298 value = radio->region_params.spacing;
1299 }
1300
1301 SET_REG_FIELD(radio->registers[RDCTRL], value,
1302 RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
1303
1304 /* Set De-emphasis and soft band range*/
1305 switch (region) {
1306 case TAVARUA_REGION_US:
1307 case TAVARUA_REGION_JAPAN:
1308 case TAVARUA_REGION_JAPAN_WIDE:
1309 value = 0;
1310 break;
1311 case TAVARUA_REGION_EU:
1312 value = 1;
1313 break;
1314 default:
1315 value = radio->region_params.emphasis;
1316 }
1317
1318 SET_REG_FIELD(radio->registers[RDCTRL], value,
1319 RDCTRL_DEEMPHASIS_OFFSET, RDCTRL_DEEMPHASIS_MASK);
1320
1321 /* set RDS standard */
1322 switch (region) {
1323 default:
1324 value = radio->region_params.rds_std;
1325 break;
1326 case TAVARUA_REGION_US:
1327 value = 0;
1328 break;
1329 case TAVARUA_REGION_EU:
1330 value = 1;
1331 break;
1332 }
1333 SET_REG_FIELD(radio->registers[RDSCTRL], value,
1334 RDSCTRL_STANDARD_OFFSET, RDSCTRL_STANDARD_MASK);
1335
1336 FMDBG("RDSCTRLL %x\n", radio->registers[RDSCTRL]);
1337 retval = tavarua_write_register(radio, RDSCTRL,
1338 radio->registers[RDSCTRL]);
1339 if (retval < 0)
1340 return retval;
1341
1342 FMDBG("RDCTRL: %x\n", radio->registers[RDCTRL]);
1343 retval = tavarua_write_register(radio, RDCTRL,
1344 radio->registers[RDCTRL]);
1345 if (retval < 0) {
1346 FMDERR("Could not set region in rdctrl\n");
1347 return retval;
1348 }
1349
1350 /* setting soft band */
1351 switch (region) {
1352 case TAVARUA_REGION_US:
1353 case TAVARUA_REGION_EU:
1354 radio->region_params.band_low = 87.5 * FREQ_MUL;
1355 radio->region_params.band_high = 108 * FREQ_MUL;
1356 break;
1357 case TAVARUA_REGION_JAPAN:
1358 radio->region_params.band_low = 76 * FREQ_MUL;
1359 radio->region_params.band_high = 90 * FREQ_MUL;
1360 break;
1361 case TAVARUA_REGION_JAPAN_WIDE:
1362 radio->region_params.band_low = 90 * FREQ_MUL;
1363 radio->region_params.band_high = 108 * FREQ_MUL;
1364 break;
1365 default:
1366 break;
1367 }
1368 radio->region_params.region = region;
1369 return retval;
1370}
1371
1372/*=============================================================================
1373FUNCTION: tavarua_get_freq
1374=============================================================================*/
1375/**
1376 This interface gets the current frequency.
1377
1378 @param radio: structure pointer passed by client.
1379 @param freq: struct v4l2_frequency. This will be set to the resultant
1380 frequency in units of 62.5 kHz on success.
1381
1382 NOTE:
1383 To get the current tuner or modulator radio frequency applications set the
1384 tuner field of a struct v4l2_frequency to the respective tuner or modulator
1385 number (only input devices have tuners, only output devices have modulators),
1386 zero out the reserved array and call the VIDIOC_G_FREQUENCY ioctl with a
1387 pointer to this structure. The driver stores the current frequency in the
1388 frequency field.
1389
1390 Tuning frequency is in units of 62.5 kHz, or if the struct v4l2_tuner or
1391 struct v4l2_modulator capabilities flag V4L2_TUNER_CAP_LOW is set, in
1392 units of 62.5 Hz.
1393
1394 @return => 0 if successful.
1395 @return < 0 if failure.
1396*/
1397static int tavarua_get_freq(struct tavarua_device *radio,
1398 struct v4l2_frequency *freq)
1399{
1400 int retval;
1401 unsigned short chan;
1402 unsigned int band_bottom;
1403 unsigned int spacing;
1404 band_bottom = radio->region_params.band_low;
1405 spacing = 0.100 * FREQ_MUL;
1406 /* read channel */
1407 retval = tavarua_read_registers(radio, FREQ, 2);
1408 chan = radio->registers[FREQ];
1409
1410 /* Frequency (MHz) = 100 (kHz) x Channel + Bottom of Band (MHz) */
1411 freq->frequency = spacing * chan + band_bottom;
1412 if (radio->registers[TUNECTRL] & ADD_OFFSET)
1413 freq->frequency += 800;
1414 return retval;
1415}
1416
1417/*=============================================================================
1418FUNCTION: tavarua_set_freq
1419=============================================================================*/
1420/**
1421 This interface sets the current frequency.
1422
1423 @param radio: structure pointer passed by client.
1424 @param freq: desired frequency sent by the client in 62.5 kHz units.
1425
1426 NOTE:
1427 To change the current tuner or modulator radio frequency, applications
1428 initialize the tuner, type and frequency fields, and the reserved array of a
1429 struct v4l2_frequency and call the VIDIOC_S_FREQUENCY ioctl with a pointer to
1430 this structure. When the requested frequency is not possible the driver
1431 assumes the closest possible value. However VIDIOC_S_FREQUENCY is a
1432 write-only ioctl, it does not return the actual new frequency.
1433
1434 Tuning frequency is in units of 62.5 kHz, or if the struct v4l2_tuner
1435 or struct v4l2_modulator capabilities flag V4L2_TUNER_CAP_LOW is set,
1436 in units of 62.5 Hz.
1437
1438 @return => 0 if successful.
1439 @return < 0 if failure.
1440*/
1441static int tavarua_set_freq(struct tavarua_device *radio, unsigned int freq)
1442{
1443
1444 unsigned int band_bottom;
1445 unsigned char chan;
1446 unsigned char cmd[] = {0x00, 0x00};
1447 unsigned int spacing;
1448 int retval;
1449 band_bottom = radio->region_params.band_low;
1450 spacing = 0.100 * FREQ_MUL;
1451 if ((freq % 1600) == 800) {
1452 cmd[1] = ADD_OFFSET;
1453 freq -= 800;
1454 }
1455 /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / 100 (kHz) */
1456 chan = (freq - band_bottom) / spacing;
1457
1458 cmd[0] = chan;
1459 cmd[1] |= TUNE_STATION;
1460 radio->tune_req = 1;
1461 retval = tavarua_write_registers(radio, FREQ, cmd, 2);
1462 if (retval < 0)
1463 radio->tune_req = 0;
1464 return retval;
1465
1466}
1467
1468/**************************************************************************
1469 * File Operations Interface
1470 *************************************************************************/
1471
1472/*=============================================================================
1473FUNCTION: tavarua_fops_read
1474=============================================================================*/
1475/**
1476 This function is called when a process, which already opened the dev file,
1477 attempts to read from it.
1478
1479 In case of tavarua driver, it is called to read RDS data.
1480
1481 @param file: file descriptor.
1482 @param buf: The buffer to fill with data.
1483 @param count: The length of the buffer in bytes.
1484 @param ppos: Our offset in the file.
1485
1486 @return The number of bytes put into the buffer on sucess.
1487 -EFAULT if there is no access to user buffer
1488*/
1489static ssize_t tavarua_fops_read(struct file *file, char __user *buf,
1490 size_t count, loff_t *ppos)
1491{
1492 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1493 struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
1494
1495 /* block if no new data available */
1496 while (!kfifo_len(rds_buf)) {
1497 if (file->f_flags & O_NONBLOCK)
1498 return -EWOULDBLOCK;
1499 if (wait_event_interruptible(radio->read_queue,
1500 kfifo_len(rds_buf)) < 0)
1501 return -EINTR;
1502 }
1503
1504 /* calculate block count from byte count */
1505 count /= BYTES_PER_BLOCK;
1506
1507
1508 /* check if we can write to the user buffer */
1509 if (!access_ok(VERIFY_WRITE, buf, count*BYTES_PER_BLOCK))
1510 return -EFAULT;
1511
1512 /* copy RDS block out of internal buffer and to user buffer */
1513 return kfifo_out_locked(rds_buf, buf, count*BYTES_PER_BLOCK,
1514 &radio->buf_lock[TAVARUA_BUF_RAW_RDS]);
1515}
1516
1517/*=============================================================================
1518FUNCTION: tavarua_fops_write
1519=============================================================================*/
1520/**
1521 This function is called when a process, which already opened the dev file,
1522 attempts to write to it.
1523
1524 In case of tavarua driver, it is called to write RDS data to host.
1525
1526 @param file: file descriptor.
1527 @param buf: The buffer which has data to write.
1528 @param count: The length of the buffer.
1529 @param ppos: Our offset in the file.
1530
1531 @return The number of bytes written from the buffer.
1532*/
1533static ssize_t tavarua_fops_write(struct file *file, const char __user *data,
1534 size_t count, loff_t *ppos)
1535{
1536 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1537 int retval = 0;
1538 int bytes_to_copy;
1539 int bytes_copied = 0;
1540 int bytes_left;
1541 int chunk_index = 0;
1542 unsigned char tx_data[XFR_REG_NUM];
1543 /* Disable TX of this type first */
1544 switch (radio->tx_mode) {
1545 case TAVARUA_TX_RT:
1546 bytes_left = min((int)count, MAX_RT_LENGTH);
1547 tx_data[1] = 0;
1548 break;
1549 case TAVARUA_TX_PS:
1550 bytes_left = min((int)count, MAX_PS_LENGTH);
1551 tx_data[4] = 0;
1552 break;
1553 default:
1554 FMDERR("%s: Unknown TX mode\n", __func__);
1555 return -1;
1556 }
1557 retval = sync_write_xfr(radio, radio->tx_mode, tx_data);
1558 if (retval < 0)
1559 return retval;
1560
1561 /* send payload to FM hardware */
1562 while (bytes_left) {
1563 chunk_index++;
1564 bytes_to_copy = min(bytes_left, XFR_REG_NUM);
1565 if (copy_from_user(tx_data, data + bytes_copied, bytes_to_copy))
1566 return -EFAULT;
1567 retval = sync_write_xfr(radio, radio->tx_mode +
1568 chunk_index, tx_data);
1569 if (retval < 0)
1570 return retval;
1571
1572 bytes_copied += bytes_to_copy;
1573 bytes_left -= bytes_to_copy;
1574 }
1575
1576 /* send the header */
1577 switch (radio->tx_mode) {
1578 case TAVARUA_TX_RT:
1579 FMDBG("Writing RT header\n");
1580 tx_data[0] = bytes_copied;
1581 tx_data[1] = TX_ON | 0x03; /* on | PTY */
1582 tx_data[2] = 0x12; /* PI high */
1583 tx_data[3] = 0x34; /* PI low */
1584 break;
1585 case TAVARUA_TX_PS:
1586 FMDBG("Writing PS header\n");
1587 tx_data[0] = chunk_index;
1588 tx_data[1] = 0x03; /* PTY */
1589 tx_data[2] = 0x12; /* PI high */
1590 tx_data[3] = 0x34; /* PI low */
1591 tx_data[4] = TX_ON | 0x01;
1592 break;
1593 default:
1594 FMDERR("%s: Unknown TX mode\n", __func__);
1595 return -1;
1596 }
1597 retval = sync_write_xfr(radio, radio->tx_mode, tx_data);
1598 if (retval < 0)
1599 return retval;
1600 FMDBG("done writing: %d\n", retval);
1601 return bytes_copied;
1602}
1603
1604/*=============================================================================
1605FUNCTION: tavarua_fops_open
1606=============================================================================*/
1607/**
1608 This function is called when a process tries to open the device file, like
1609 "cat /dev/mycharfile"
1610
1611 @param file: file descriptor.
1612
1613 @return => 0 if successful.
1614 @return < 0 if failure.
1615*/
1616static int tavarua_fops_open(struct file *file)
1617{
1618 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1619 int retval = -ENODEV;
1620 unsigned char value;
1621 /* FM core bring up */
1622 int i = 0;
1623 char fm_ctl0_part1[] = { 0xCA, 0xCE, 0xD6 };
1624 char fm_ctl1[] = { 0x03 };
1625 char fm_ctl0_part2[] = { 0xB6, 0xB7 };
1626 char buffer[] = {0x00, 0x48, 0x8A, 0x8E, 0x97, 0xB7};
1627 int bahama_present = -ENODEV;
1628
1629 mutex_lock(&radio->lock);
1630 if (radio->users) {
1631 mutex_unlock(&radio->lock);
1632 return -EBUSY;
1633 } else {
1634 radio->users++;
1635 }
1636 mutex_unlock(&radio->lock);
1637
1638 /* initial gpio pin config & Power up */
1639 retval = radio->pdata->fm_setup(radio->pdata);
1640 if (retval) {
1641 printk(KERN_ERR "%s: failed config gpio & pmic\n", __func__);
1642 goto open_err_setup;
1643 }
1644 if (radio->pdata->config_i2s_gpio != NULL) {
1645 retval = radio->pdata->config_i2s_gpio(FM_I2S_ON);
1646 if (retval) {
1647 printk(KERN_ERR "%s: failed config gpio\n", __func__);
1648 goto config_i2s_err;
1649 }
1650 }
1651 /* enable irq */
1652 retval = tavarua_request_irq(radio);
1653 if (retval < 0) {
1654 printk(KERN_ERR "%s: failed to request irq\n", __func__);
1655 goto open_err_req_irq;
1656 }
1657 /* call top level marimba interface here to enable FM core */
1658 FMDBG("initializing SoC\n");
1659
1660 bahama_present = is_bahama();
1661
1662 if (bahama_present == -ENODEV)
1663 return -ENODEV;
1664
1665 if (bahama_present)
1666 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1667 else
1668 radio->marimba->mod_id = MARIMBA_SLAVE_ID_MARIMBA;
1669
1670 value = FM_ENABLE;
1671 retval = marimba_write_bit_mask(radio->marimba,
1672 MARIMBA_XO_BUFF_CNTRL, &value, 1, value);
1673 if (retval < 0) {
1674 printk(KERN_ERR "%s:XO_BUFF_CNTRL write failed\n",
1675 __func__);
1676 goto open_err_all;
1677 }
1678
1679
1680 /* Bring up FM core */
1681 if (bahama_present) {
1682
1683 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1684 /* Read the Bahama version*/
1685 retval = marimba_read_bit_mask(radio->marimba,
1686 0x00, &bahama_version, 1, 0x1F);
1687 if (retval < 0) {
1688 printk(KERN_ERR "%s: version read failed",
1689 __func__);
1690 goto open_err_all;
1691 }
1692 /* Check for Bahama V2 variant*/
1693 if (bahama_version == 0x09) {
1694
1695 /* In case of Bahama v2, forcefully enable the
1696 * internal analog and digital voltage controllers
1697 */
1698 value = 0x06;
1699 /* value itself used as mask in these writes*/
1700 retval = marimba_write_bit_mask(radio->marimba,
1701 BAHAMA_LDO_DREG_CTL0, &value, 1, value);
1702 if (retval < 0) {
1703 printk(KERN_ERR "%s:0xF0 write failed\n",
1704 __func__);
1705 goto open_err_all;
1706 }
1707 value = 0x86;
1708 retval = marimba_write_bit_mask(radio->marimba,
1709 BAHAMA_LDO_AREG_CTL0, &value, 1, value);
1710 if (retval < 0) {
1711 printk(KERN_ERR "%s:0xF4 write failed\n",
1712 __func__);
1713 goto open_err_all;
1714 }
1715 }
1716
1717 /*write FM mode*/
1718 retval = tavarua_write_register(radio, BAHAMA_FM_MODE_REG,
1719 BAHAMA_FM_MODE_NORMAL);
1720 if (retval < 0) {
1721 printk(KERN_ERR "failed to set the FM mode: %d\n",
1722 retval);
1723 goto open_err_all;
1724 }
1725 /*Write first sequence of bytes to FM_CTL0*/
1726 for (i = 0; i < 3; i++) {
1727 retval = tavarua_write_register(radio,
1728 BAHAMA_FM_CTL0_REG, fm_ctl0_part1[i]);
1729 if (retval < 0) {
1730 printk(KERN_ERR "FM_CTL0:set-1 failure: %d\n",
1731 retval);
1732 goto open_err_all;
1733 }
1734 }
1735 /*Write the FM_CTL1 sequence*/
1736 for (i = 0; i < 1; i++) {
1737 retval = tavarua_write_register(radio,
1738 BAHAMA_FM_CTL1_REG, fm_ctl1[i]);
1739 if (retval < 0) {
1740 printk(KERN_ERR "FM_CTL1 write failure: %d\n",
1741 retval);
1742 goto open_err_all;
1743 }
1744 }
1745 /*Write second sequence of bytes to FM_CTL0*/
1746 for (i = 0; i < 2; i++) {
1747 retval = tavarua_write_register(radio,
1748 BAHAMA_FM_CTL0_REG, fm_ctl0_part2[i]);
1749 if (retval < 0) {
1750 printk(KERN_ERR "FM_CTL0:set-2 failure: %d\n",
1751 retval);
1752 goto open_err_all;
1753 }
1754 }
1755 } else {
1756 retval = tavarua_write_registers(radio, LEAKAGE_CNTRL,
1757 buffer, 6);
1758 if (retval < 0) {
1759 printk(KERN_ERR "%s: failed to bring up FM Core\n",
1760 __func__);
1761 goto open_err_all;
1762 }
1763 }
1764 /* Wait for interrupt i.e. complete(&radio->sync_req_done); call */
1765 /*Initialize the completion variable for
1766 for the proper behavior*/
1767 init_completion(&radio->sync_req_done);
1768 if (!wait_for_completion_timeout(&radio->sync_req_done,
1769 msecs_to_jiffies(wait_timeout))) {
1770 retval = -1;
1771 FMDERR("Timeout waiting for initialization\n");
1772 }
1773
1774 /* get Chip ID */
1775 retval = tavarua_write_register(radio, XFRCTRL, CHIPID);
1776 if (retval < 0)
1777 goto open_err_all;
1778 msleep(TAVARUA_DELAY);
1779 tavarua_read_registers(radio, XFRCTRL, XFR_REG_NUM+1);
1780 if (radio->registers[XFRCTRL] != CHIPID)
1781 goto open_err_all;
1782
1783 radio->chipID = (radio->registers[XFRCTRL+2] << 24) |
1784 (radio->registers[XFRCTRL+5] << 16) |
1785 (radio->registers[XFRCTRL+6] << 8) |
1786 (radio->registers[XFRCTRL+7]);
1787
1788 printk(KERN_WARNING DRIVER_NAME ": Chip ID %x\n", radio->chipID);
1789 if (radio->chipID == MARIMBA_A0) {
1790 printk(KERN_WARNING DRIVER_NAME ": Unsupported hardware: %x\n",
1791 radio->chipID);
1792 retval = -1;
1793 goto open_err_all;
1794 }
1795
1796 radio->handle_irq = 0;
1797 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1798 marimba_set_fm_status(radio->marimba, true);
1799 return 0;
1800
1801
1802open_err_all:
1803 /*Disable FM in case of error*/
1804 value = 0x00;
1805 marimba_write_bit_mask(radio->marimba, MARIMBA_XO_BUFF_CNTRL,
1806 &value, 1, value);
1807 tavarua_disable_irq(radio);
1808open_err_req_irq:
1809 if (radio->pdata->config_i2s_gpio != NULL)
1810 radio->pdata->config_i2s_gpio(FM_I2S_OFF);
1811config_i2s_err:
1812 radio->pdata->fm_shutdown(radio->pdata);
1813open_err_setup:
1814 radio->handle_irq = 1;
1815 radio->users = 0;
1816 return retval;
1817}
1818
1819/*=============================================================================
1820FUNCTION: tavarua_fops_release
1821=============================================================================*/
1822/**
1823 This function is called when a process closes the device file.
1824
1825 @param file: file descriptor.
1826
1827 @return => 0 if successful.
1828 @return < 0 if failure.
1829*/
1830static int tavarua_fops_release(struct file *file)
1831{
1832 int retval;
1833 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1834 unsigned char value;
1835 int i = 0;
1836 /*FM Core shutdown sequence for Bahama*/
1837 char fm_ctl0_part1[] = { 0xB7 };
1838 char fm_ctl1[] = { 0x03 };
1839 char fm_ctl0_part2[] = { 0x9F, 0x48, 0x02 };
1840 int bahama_present = -ENODEV;
1841 /*FM Core shutdown sequence for Marimba*/
1842 char buffer[] = {0x18, 0xB7, 0x48};
1843 bool bt_status = false;
1844 int index;
1845 /* internal regulator controllers DREG_CTL0, AREG_CTL0
1846 * has to be kept in the valid state based on the bt status.
1847 * 1st row is the state when no clients are active,
1848 * and the second when bt is in on state.
1849 */
1850 char internal_vreg_ctl[2][2] = {
1851 { 0x04, 0x84 },
1852 { 0x00, 0x80 }
1853 };
1854
1855 if (!radio)
1856 return -ENODEV;
1857 FMDBG("In %s", __func__);
1858
1859 /* disable radio ctrl */
1860 retval = tavarua_write_register(radio, RDCTRL, 0x00);
1861
1862 FMDBG("%s, Disable IRQs\n", __func__);
1863 /* disable irq */
1864 retval = tavarua_disable_irq(radio);
1865 if (retval < 0) {
1866 printk(KERN_ERR "%s: failed to disable irq\n", __func__);
1867 return retval;
1868 }
1869
1870 bahama_present = is_bahama();
1871
1872 if (bahama_present == -ENODEV)
1873 return -ENODEV;
1874
1875 if (bahama_present) {
1876 /*Write first sequence of bytes to FM_CTL0*/
1877 for (i = 0; i < 1; i++) {
1878 retval = tavarua_write_register(radio,
1879 BAHAMA_FM_CTL0_REG, fm_ctl0_part1[i]);
1880 if (retval < 0) {
1881 printk(KERN_ERR "FM_CTL0:Set-1 failure: %d\n",
1882 retval);
1883 break;
1884 }
1885 }
1886 /*Write the FM_CTL1 sequence*/
1887 for (i = 0; i < 1; i++) {
1888 retval = tavarua_write_register(radio,
1889 BAHAMA_FM_CTL1_REG, fm_ctl1[i]);
1890 if (retval < 0) {
1891 printk(KERN_ERR "FM_CTL1 failure: %d\n",
1892 retval);
1893 break;
1894 }
1895 }
1896 /*Write second sequence of bytes to FM_CTL0*/
1897 for (i = 0; i < 3; i++) {
1898 retval = tavarua_write_register(radio,
1899 BAHAMA_FM_CTL0_REG, fm_ctl0_part2[i]);
1900 if (retval < 0) {
1901 printk(KERN_ERR "FM_CTL0:Set-2 failure: %d\n",
1902 retval);
1903 break;
1904 }
1905 }
1906 } else {
1907
1908 retval = tavarua_write_registers(radio, FM_CTL0,
1909 buffer, sizeof(buffer)/sizeof(buffer[0]));
1910 if (retval < 0) {
1911 printk(KERN_ERR "%s: failed to bring down the FM Core\n",
1912 __func__);
1913 return retval;
1914 }
1915 }
1916 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1917 bt_status = marimba_get_bt_status(radio->marimba);
1918 /* Set the index based on the bt status*/
1919 index = bt_status ? 1 : 0;
1920 /* Check for Bahama's existance and Bahama V2 variant*/
1921 if (bahama_present && (bahama_version == 0x09)) {
1922 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1923 /* actual value itself used as mask*/
1924 retval = marimba_write_bit_mask(radio->marimba,
1925 BAHAMA_LDO_DREG_CTL0, &internal_vreg_ctl[bt_status][0],
1926 1, internal_vreg_ctl[index][0]);
1927 if (retval < 0) {
1928 printk(KERN_ERR "%s:0xF0 write failed\n", __func__);
1929 return retval;
1930 }
1931 /* actual value itself used as mask*/
1932 retval = marimba_write_bit_mask(radio->marimba,
1933 BAHAMA_LDO_AREG_CTL0, &internal_vreg_ctl[bt_status][1],
1934 1, internal_vreg_ctl[index][1]);
1935 if (retval < 0) {
1936 printk(KERN_ERR "%s:0xF4 write failed\n", __func__);
1937 return retval;
1938 }
1939 } else {
1940 /* disable fm core */
1941 radio->marimba->mod_id = MARIMBA_SLAVE_ID_MARIMBA;
1942 }
1943
1944 value = 0x00;
1945 retval = marimba_write_bit_mask(radio->marimba, MARIMBA_XO_BUFF_CNTRL,
1946 &value, 1, FM_ENABLE);
1947 if (retval < 0) {
1948 printk(KERN_ERR "%s:XO_BUFF_CNTRL write failed\n", __func__);
1949 return retval;
1950 }
1951 FMDBG("%s, Calling fm_shutdown\n", __func__);
1952 /* teardown gpio and pmic */
1953 radio->pdata->fm_shutdown(radio->pdata);
1954 if (radio->pdata->config_i2s_gpio != NULL)
1955 radio->pdata->config_i2s_gpio(FM_I2S_OFF);
1956 radio->handle_irq = 1;
1957 radio->users = 0;
1958 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1959 marimba_set_fm_status(radio->marimba, false);
1960 return 0;
1961}
1962
1963/*
1964 * tavarua_fops - file operations interface
1965 */
1966static const struct v4l2_file_operations tavarua_fops = {
1967 .owner = THIS_MODULE,
1968 .read = tavarua_fops_read,
1969 .write = tavarua_fops_write,
1970 .ioctl = video_ioctl2,
1971 .open = tavarua_fops_open,
1972 .release = tavarua_fops_release,
1973};
1974
1975/*************************************************************************
1976 * Video4Linux Interface
1977 *************************************************************************/
1978
1979/*
1980 * tavarua_v4l2_queryctrl - query control
1981 */
1982static struct v4l2_queryctrl tavarua_v4l2_queryctrl[] = {
1983 {
1984 .id = V4L2_CID_AUDIO_VOLUME,
1985 .type = V4L2_CTRL_TYPE_INTEGER,
1986 .name = "Volume",
1987 .minimum = 0,
1988 .maximum = 15,
1989 .step = 1,
1990 .default_value = 15,
1991 },
1992 {
1993 .id = V4L2_CID_AUDIO_BALANCE,
1994 .flags = V4L2_CTRL_FLAG_DISABLED,
1995 },
1996 {
1997 .id = V4L2_CID_AUDIO_BASS,
1998 .flags = V4L2_CTRL_FLAG_DISABLED,
1999 },
2000 {
2001 .id = V4L2_CID_AUDIO_TREBLE,
2002 .flags = V4L2_CTRL_FLAG_DISABLED,
2003 },
2004 {
2005 .id = V4L2_CID_AUDIO_MUTE,
2006 .type = V4L2_CTRL_TYPE_BOOLEAN,
2007 .name = "Mute",
2008 .minimum = 0,
2009 .maximum = 1,
2010 .step = 1,
2011 .default_value = 1,
2012 },
2013 {
2014 .id = V4L2_CID_AUDIO_LOUDNESS,
2015 .flags = V4L2_CTRL_FLAG_DISABLED,
2016 },
2017 {
2018 .id = V4L2_CID_PRIVATE_TAVARUA_SRCHMODE,
2019 .type = V4L2_CTRL_TYPE_INTEGER,
2020 .name = "Search mode",
2021 .minimum = 0,
2022 .maximum = 7,
2023 .step = 1,
2024 .default_value = 0,
2025 },
2026 {
2027 .id = V4L2_CID_PRIVATE_TAVARUA_SCANDWELL,
2028 .type = V4L2_CTRL_TYPE_INTEGER,
2029 .name = "Search dwell time",
2030 .minimum = 0,
2031 .maximum = 7,
2032 .step = 1,
2033 .default_value = 0,
2034 },
2035 {
2036 .id = V4L2_CID_PRIVATE_TAVARUA_SRCHON,
2037 .type = V4L2_CTRL_TYPE_BOOLEAN,
2038 .name = "Search on/off",
2039 .minimum = 0,
2040 .maximum = 1,
2041 .step = 1,
2042 .default_value = 1,
2043
2044 },
2045 {
2046 .id = V4L2_CID_PRIVATE_TAVARUA_STATE,
2047 .type = V4L2_CTRL_TYPE_INTEGER,
2048 .name = "radio 0ff/rx/tx/reset",
2049 .minimum = 0,
2050 .maximum = 3,
2051 .step = 1,
2052 .default_value = 1,
2053
2054 },
2055 {
2056 .id = V4L2_CID_PRIVATE_TAVARUA_REGION,
2057 .type = V4L2_CTRL_TYPE_INTEGER,
2058 .name = "radio standard",
2059 .minimum = 0,
2060 .maximum = 2,
2061 .step = 1,
2062 .default_value = 0,
2063 },
2064 {
2065 .id = V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH,
2066 .type = V4L2_CTRL_TYPE_INTEGER,
2067 .name = "Signal Threshold",
2068 .minimum = 0x80,
2069 .maximum = 0x7F,
2070 .step = 1,
2071 .default_value = 0,
2072 },
2073 {
2074 .id = V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY,
2075 .type = V4L2_CTRL_TYPE_INTEGER,
2076 .name = "Search PTY",
2077 .minimum = 0,
2078 .maximum = 31,
2079 .default_value = 0,
2080 },
2081 {
2082 .id = V4L2_CID_PRIVATE_TAVARUA_SRCH_PI,
2083 .type = V4L2_CTRL_TYPE_INTEGER,
2084 .name = "Search PI",
2085 .minimum = 0,
2086 .maximum = 0xFF,
2087 .default_value = 0,
2088 },
2089 {
2090 .id = V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT,
2091 .type = V4L2_CTRL_TYPE_INTEGER,
2092 .name = "Preset num",
2093 .minimum = 0,
2094 .maximum = 12,
2095 .default_value = 0,
2096 },
2097 {
2098 .id = V4L2_CID_PRIVATE_TAVARUA_EMPHASIS,
2099 .type = V4L2_CTRL_TYPE_BOOLEAN,
2100 .name = "Emphasis",
2101 .minimum = 0,
2102 .maximum = 1,
2103 .default_value = 0,
2104 },
2105 {
2106 .id = V4L2_CID_PRIVATE_TAVARUA_RDS_STD,
2107 .type = V4L2_CTRL_TYPE_BOOLEAN,
2108 .name = "RDS standard",
2109 .minimum = 0,
2110 .maximum = 1,
2111 .default_value = 0,
2112 },
2113 {
2114 .id = V4L2_CID_PRIVATE_TAVARUA_SPACING,
2115 .type = V4L2_CTRL_TYPE_INTEGER,
2116 .name = "Channel spacing",
2117 .minimum = 0,
2118 .maximum = 2,
2119 .default_value = 0,
2120 },
2121 {
2122 .id = V4L2_CID_PRIVATE_TAVARUA_RDSON,
2123 .type = V4L2_CTRL_TYPE_BOOLEAN,
2124 .name = "RDS on/off",
2125 .minimum = 0,
2126 .maximum = 1,
2127 .default_value = 0,
2128 },
2129 {
2130 .id = V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK,
2131 .type = V4L2_CTRL_TYPE_INTEGER,
2132 .name = "RDS group mask",
2133 .minimum = 0,
2134 .maximum = 0xFFFFFFFF,
2135 .default_value = 0,
2136 },
2137 {
2138 .id = V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC,
2139 .type = V4L2_CTRL_TYPE_INTEGER,
2140 .name = "RDS processing",
2141 .minimum = 0,
2142 .maximum = 0xFF,
2143 .default_value = 0,
2144 },
2145 {
2146 .id = V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF,
2147 .type = V4L2_CTRL_TYPE_INTEGER,
2148 .name = "RDS data groups to buffer",
2149 .minimum = 1,
2150 .maximum = 21,
2151 .default_value = 0,
2152 },
2153 {
2154 .id = V4L2_CID_PRIVATE_TAVARUA_PSALL,
2155 .type = V4L2_CTRL_TYPE_BOOLEAN,
2156 .name = "pass all ps strings",
2157 .minimum = 0,
2158 .maximum = 1,
2159 .default_value = 0,
2160 },
2161 {
2162 .id = V4L2_CID_PRIVATE_TAVARUA_LP_MODE,
2163 .type = V4L2_CTRL_TYPE_BOOLEAN,
2164 .name = "Low power mode",
2165 .minimum = 0,
2166 .maximum = 1,
2167 .default_value = 0,
2168 },
2169 {
2170 .id = V4L2_CID_PRIVATE_TAVARUA_ANTENNA,
2171 .type = V4L2_CTRL_TYPE_BOOLEAN,
2172 .name = "headset/internal",
2173 .minimum = 0,
2174 .maximum = 1,
2175 .default_value = 0,
2176 },
2177 /* Private controls for FM TX*/
2178 {
2179 .id = V4L2_CID_PRIVATE_TAVARUA_TX_SETPSREPEATCOUNT,
2180 .type = V4L2_CTRL_TYPE_INTEGER,
2181 .name = "Set PS REPEATCOUNT",
2182 .minimum = 0,
2183 .maximum = 15,
2184 },
2185 {
2186 .id = V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_PS_NAME,
2187 .type = V4L2_CTRL_TYPE_BOOLEAN,
2188 .name = "Stop PS NAME",
2189 .minimum = 0,
2190 .maximum = 1,
2191 },
2192 {
2193 .id = V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_RT,
2194 .type = V4L2_CTRL_TYPE_BOOLEAN,
2195 .name = "Stop RT",
2196 .minimum = 0,
2197 .maximum = 1,
2198 },
2199
2200};
2201
2202/*=============================================================================
2203FUNCTION: tavarua_vidioc_querycap
2204=============================================================================*/
2205/**
2206 This function is called to query device capabilities.
2207
2208 NOTE:
2209 All V4L2 devices support the VIDIOC_QUERYCAP ioctl. It is used to identify
2210 kernel devices compatible with this specification and to obtain information
2211 about driver and hardware capabilities. The ioctl takes a pointer to a struct
2212 v4l2_capability which is filled by the driver. When the driver is not
2213 compatible with this specification the ioctl returns an EINVAL error code.
2214
2215 @param file: File descriptor returned by open().
2216 @param capability: pointer to struct v4l2_capability.
2217
2218 @return On success 0 is returned, else error code.
2219 @return EINVAL: The device is not compatible with this specification.
2220*/
2221static int tavarua_vidioc_querycap(struct file *file, void *priv,
2222 struct v4l2_capability *capability)
2223{
2224 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2225
2226 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
2227 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
2228 sprintf(capability->bus_info, "I2C");
2229 capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
2230
2231 capability->version = radio->chipID;
2232
2233 return 0;
2234}
2235
2236/*=============================================================================
2237FUNCTION: tavarua_vidioc_queryctrl
2238=============================================================================*/
2239/**
2240 This function is called to query the device and driver for supported video
2241 controls (enumerate control items).
2242
2243 NOTE:
2244 To query the attributes of a control, the applications set the id field of
2245 a struct v4l2_queryctrl and call the VIDIOC_QUERYCTRL ioctl with a pointer
2246 to this structure. The driver fills the rest of the structure or returns an
2247 EINVAL error code when the id is invalid.
2248
2249 @param file: File descriptor returned by open().
2250 @param qc: pointer to struct v4l2_queryctrl.
2251
2252 @return On success 0 is returned, else error code.
2253 @return EINVAL: The struct v4l2_queryctrl id is invalid.
2254*/
2255static int tavarua_vidioc_queryctrl(struct file *file, void *priv,
2256 struct v4l2_queryctrl *qc)
2257{
2258 unsigned char i;
2259 int retval = -EINVAL;
2260
2261 for (i = 0; i < ARRAY_SIZE(tavarua_v4l2_queryctrl); i++) {
2262 if (qc->id && qc->id == tavarua_v4l2_queryctrl[i].id) {
2263 memcpy(qc, &(tavarua_v4l2_queryctrl[i]), sizeof(*qc));
2264 retval = 0;
2265 break;
2266 }
2267 }
2268 if (retval < 0)
2269 printk(KERN_WARNING DRIVER_NAME
2270 ": query conv4ltrol failed with %d\n", retval);
2271
2272 return retval;
2273}
2274static int peek_MPX_DCC(struct tavarua_device *radio)
2275{
2276 int retval = 0;
2277 unsigned char xfr_buf[XFR_REG_NUM];
2278 int MPX_DCC[] = { 0 };
2279 int DCC = 0;
2280 int ct = 0;
2281 unsigned char size = 0;
2282
2283 /*
2284 Poking the MPX_DCC_BYPASS register to freeze the
2285 value of MPX_DCC from changing while we access it
2286 */
2287
2288 /*Poking the MPX_DCC_BYPASS register : 0x88C0 */
2289 size = 0x01;
2290 xfr_buf[0] = (XFR_POKE_MODE | (size << 1));
2291 xfr_buf[1] = MPX_DCC_BYPASS_POKE_MSB;
2292 xfr_buf[2] = MPX_DCC_BYPASS_POKE_LSB;
2293 xfr_buf[3] = 0x01;
2294
2295 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 4);
2296 if (retval < 0) {
2297 FMDBG("Failed to write\n");
2298 return retval;
2299 }
2300 /*Wait for the XFR interrupt */
2301 msleep(TAVARUA_DELAY*15);
2302
2303 for (ct = 0; ct < 5; ct++)
2304 xfr_buf[ct] = 0;
2305
2306 /* Peeking Regs 0x88C2-0x88C4 */
2307 size = 0x03;
2308 xfr_buf[0] = (XFR_PEEK_MODE | (size << 1));
2309 xfr_buf[1] = MPX_DCC_PEEK_MSB_REG1;
2310 xfr_buf[2] = MPX_DCC_PEEK_LSB_REG1;
2311 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 3);
2312 if (retval < 0) {
2313 FMDBG("Failed to write\n");
2314 return retval;
2315 }
2316 /*Wait for the XFR interrupt */
2317 msleep(TAVARUA_DELAY*10);
2318 retval = tavarua_read_registers(radio, XFRDAT0, 3);
2319 if (retval < 0) {
2320 printk(KERN_INFO "INT_DET: Read failure\n");
2321 return retval;
2322 }
2323 MPX_DCC[0] = (int)radio->registers[XFRDAT0];
2324 MPX_DCC[1] = (int)radio->registers[XFRDAT1];
2325 MPX_DCC[2] = (int)radio->registers[XFRDAT2];
2326
2327 /*
2328 Form the final MPX_DCC parameter
2329 MPX_DCC[0] will form the LSB part
2330 MPX_DCC[1] will be the middle part and 4 bits of
2331 MPX_DCC[2] will be the MSB par of the 20-bit signed MPX_DCC
2332 */
2333
2334 DCC = ((int)MPX_DCC[2] << 16) | ((int)MPX_DCC[1] << 8) |
2335 ((int)MPX_DCC[0]);
2336
2337 /*
2338 if bit-19 is '1',set remaining bits to '1' & make it -tive
2339 */
2340 if (DCC & 0x00080000) {
2341 FMDBG(KERN_INFO "bit-19 is '1'\n");
2342 DCC |= 0xFFF00000;
2343 }
2344
2345 /*
2346 Poking the MPX_DCC_BYPASS register to be back to normal
2347 */
2348
2349 /*Poking the MPX_DCC_BYPASS register : 0x88C0 */
2350 size = 0x01;
2351 xfr_buf[0] = (XFR_POKE_MODE | (size << 1));
2352 xfr_buf[1] = MPX_DCC_BYPASS_POKE_MSB;
2353 xfr_buf[2] = MPX_DCC_BYPASS_POKE_LSB;
2354 xfr_buf[3] = 0x00;
2355
2356 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 4);
2357 if (retval < 0) {
2358 FMDBG("Failed to write\n");
2359 return retval;
2360 }
2361 /*Wait for the XFR interrupt */
2362 msleep(TAVARUA_DELAY*10);
2363
2364 return DCC;
2365}
2366/*=============================================================================
2367FUNCTION: tavarua_vidioc_g_ctrl
2368=============================================================================*/
2369/**
2370 This function is called to get the value of a control.
2371
2372 NOTE:
2373 To get the current value of a control, applications initialize the id field
2374 of a struct v4l2_control and call the VIDIOC_G_CTRL ioctl with a pointer to
2375 this structure.
2376
2377 When the id is invalid drivers return an EINVAL error code. When the value is
2378 out of bounds drivers can choose to take the closest valid value or return an
2379 ERANGE error code, whatever seems more appropriate.
2380
2381 @param file: File descriptor returned by open().
2382 @param ctrl: pointer to struct v4l2_control.
2383
2384 @return On success 0 is returned, else error code.
2385 @return EINVAL: The struct v4l2_control id is invalid.
2386 @return ERANGE: The struct v4l2_control value is out of bounds.
2387 @return EBUSY: The control is temporarily not changeable, possibly because
2388 another applications took over control of the device function this control
2389 belongs to.
2390*/
2391static int tavarua_vidioc_g_ctrl(struct file *file, void *priv,
2392 struct v4l2_control *ctrl)
2393{
2394 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2395 int retval = 0;
2396 unsigned char xfr_buf[XFR_REG_NUM];
2397 signed char cRmssiThreshold;
2398 signed char ioc;
2399 unsigned char size = 0;
2400
2401 switch (ctrl->id) {
2402 case V4L2_CID_AUDIO_VOLUME:
2403 break;
2404 case V4L2_CID_AUDIO_MUTE:
2405 ctrl->value = radio->registers[IOCTRL] & 0x03 ;
2406 break;
2407 case V4L2_CID_PRIVATE_TAVARUA_SRCHMODE:
2408 ctrl->value = radio->registers[SRCHCTRL] & SRCH_MODE;
2409 break;
2410 case V4L2_CID_PRIVATE_TAVARUA_SCANDWELL:
2411 ctrl->value = (radio->registers[SRCHCTRL] & SCAN_DWELL) >> 4;
2412 break;
2413 case V4L2_CID_PRIVATE_TAVARUA_SRCHON:
2414 ctrl->value = (radio->registers[SRCHCTRL] & SRCH_ON) >> 7 ;
2415 break;
2416 case V4L2_CID_PRIVATE_TAVARUA_STATE:
2417 ctrl->value = (radio->registers[RDCTRL] & 0x03);
2418 break;
2419 case V4L2_CID_PRIVATE_TAVARUA_IOVERC:
2420 retval = tavarua_read_registers(radio, IOVERC, 1);
2421 if (retval < 0)
2422 return retval;
2423 ioc = radio->registers[IOVERC];
2424 ctrl->value = ioc;
2425 break;
2426 case V4L2_CID_PRIVATE_TAVARUA_INTDET:
2427 size = 0x1;
2428 xfr_buf[0] = (XFR_PEEK_MODE | (size << 1));
2429 xfr_buf[1] = INTDET_PEEK_MSB;
2430 xfr_buf[2] = INTDET_PEEK_LSB;
2431 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 3);
2432 if (retval < 0) {
2433 FMDBG("Failed to write\n");
2434 return retval;
2435 }
2436 FMDBG("INT_DET:Sync write success\n");
2437 /*Wait for the XFR interrupt */
2438 msleep(TAVARUA_DELAY*10);
2439 /* Read the XFRDAT0 register populated by FM SoC */
2440 retval = tavarua_read_registers(radio, XFRDAT0, 3);
2441 if (retval < 0) {
2442 FMDBG("INT_DET: Read failure\n");
2443 return retval;
2444 }
2445 ctrl->value = radio->registers[XFRDAT0];
2446 break;
2447 case V4L2_CID_PRIVATE_TAVARUA_MPX_DCC:
2448 ctrl->value = peek_MPX_DCC(radio);
2449 break;
2450 case V4L2_CID_PRIVATE_TAVARUA_REGION:
2451 ctrl->value = radio->region_params.region;
2452 break;
2453 case V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH:
2454 retval = sync_read_xfr(radio, RX_CONFIG, xfr_buf);
2455 if (retval < 0) {
2456 FMDBG("[G IOCTL=V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH]\n");
2457 FMDBG("sync_read_xfr error: [retval=%d]\n", retval);
2458 break;
2459 }
2460 /* Since RMSSI Threshold is signed value */
2461 cRmssiThreshold = (signed char)xfr_buf[0];
2462 ctrl->value = cRmssiThreshold;
2463 FMDBG("cRmssiThreshold: %d\n", cRmssiThreshold);
2464 break;
2465 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY:
2466 ctrl->value = radio->srch_params.srch_pty;
2467 break;
2468 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PI:
2469 ctrl->value = radio->srch_params.srch_pi;
2470 break;
2471 case V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT:
2472 ctrl->value = radio->srch_params.preset_num;
2473 break;
2474 case V4L2_CID_PRIVATE_TAVARUA_EMPHASIS:
2475 ctrl->value = radio->region_params.emphasis;
2476 break;
2477 case V4L2_CID_PRIVATE_TAVARUA_RDS_STD:
2478 ctrl->value = radio->region_params.rds_std;
2479 break;
2480 case V4L2_CID_PRIVATE_TAVARUA_SPACING:
2481 ctrl->value = radio->region_params.spacing;
2482 break;
2483 case V4L2_CID_PRIVATE_TAVARUA_RDSON:
2484 ctrl->value = radio->registers[RDSCTRL] & RDS_ON;
2485 break;
2486 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK:
2487 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2488 if (retval > -1)
2489 ctrl->value = (xfr_buf[8] << 24) |
2490 (xfr_buf[9] << 16) |
2491 (xfr_buf[10] << 8) |
2492 xfr_buf[11];
2493 break;
2494 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC:
2495 retval = tavarua_read_registers(radio, ADVCTRL, 1);
2496 if (retval > -1)
2497 ctrl->value = radio->registers[ADVCTRL];
2498 break;
2499 case V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF:
2500 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2501 if (retval > -1)
2502 ctrl->value = xfr_buf[1];
2503 break;
2504 case V4L2_CID_PRIVATE_TAVARUA_PSALL:
2505 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2506 if (retval > -1)
2507 ctrl->value = xfr_buf[12] & RDS_CONFIG_PSALL;
2508 break;
2509 case V4L2_CID_PRIVATE_TAVARUA_LP_MODE:
2510 ctrl->value = radio->lp_mode;
2511 break;
2512 case V4L2_CID_PRIVATE_TAVARUA_ANTENNA:
2513 ctrl->value = GET_REG_FIELD(radio->registers[IOCTRL],
2514 IOC_ANTENNA_OFFSET, IOC_ANTENNA_MASK);
2515 break;
2516 default:
2517 retval = -EINVAL;
2518 }
2519 if (retval < 0)
2520 printk(KERN_WARNING DRIVER_NAME
2521 ": get control failed with %d, id: %d\n", retval, ctrl->id);
2522
2523 return retval;
2524}
2525
2526static int tavarua_vidioc_s_ext_ctrls(struct file *file, void *priv,
2527 struct v4l2_ext_controls *ctrl)
2528{
2529 int retval = 0;
2530 int bytes_to_copy;
2531 int bytes_copied = 0;
2532 int bytes_left = 0;
2533 int chunk_index = 0;
2534 char tx_data[XFR_REG_NUM];
2535 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2536 char *data = NULL;
2537 int extra_name_byte = 0;
2538 int name_bytes = 0;
2539
2540 switch ((ctrl->controls[0]).id) {
2541 case V4L2_CID_RDS_TX_PS_NAME: {
2542 FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
2543 /*Pass a sample PS string */
2544
2545 chunk_index = 0;
2546 bytes_copied = 0;
2547 bytes_left = min((int)(ctrl->controls[0]).size,
2548 MAX_PS_LENGTH);
2549 data = (ctrl->controls[0]).string;
2550
2551 /* send payload to FM hardware */
2552 while (bytes_left) {
2553 chunk_index++;
2554 FMDBG("chunk is %d", chunk_index);
2555 bytes_to_copy = min(bytes_left, XFR_REG_NUM);
2556 /*Clear the tx_data */
2557 memset(tx_data, 0, XFR_REG_NUM);
2558 if (copy_from_user(tx_data,
2559 data + bytes_copied, bytes_to_copy))
2560 return -EFAULT;
2561 retval = sync_write_xfr(radio,
2562 RDS_PS_0 + chunk_index, tx_data);
2563 if (retval < 0) {
2564 FMDBG("sync_write_xfr: %d", retval);
2565 return retval;
2566 }
2567 bytes_copied += bytes_to_copy;
2568 bytes_left -= bytes_to_copy;
2569 }
2570 memset(tx_data, 0, XFR_REG_NUM);
2571 /*Write the PS Header*/
2572 FMDBG("Writing PS header\n");
2573 extra_name_byte = (bytes_copied%8) ? 1 : 0;
2574 name_bytes = (bytes_copied/8) + extra_name_byte;
2575 /*8 bytes are grouped as 1 name */
2576 tx_data[0] = (name_bytes) & MASK_TXREPCOUNT;
2577 tx_data[1] = radio->pty & MASK_PTY; /* PTY */
2578 tx_data[2] = ((radio->pi & MASK_PI_MSB) >> 8);
2579 tx_data[3] = radio->pi & MASK_PI_LSB;
2580 /* TX ctrl + repeatCount*/
2581 tx_data[4] = TX_ON |
2582 (radio->ps_repeatcount & MASK_TXREPCOUNT);
2583 retval = sync_write_xfr(radio, RDS_PS_0, tx_data);
2584 if (retval < 0) {
2585 FMDBG("sync_write_xfr returned %d", retval);
2586 return retval;
2587 }
2588 } break;
2589 case V4L2_CID_RDS_TX_RADIO_TEXT: {
2590 chunk_index = 0;
2591 bytes_copied = 0;
2592 FMDBG("In V4L2_CID_RDS_TX_RADIO_TEXT\n");
2593 /*Pass a sample PS string */
2594 FMDBG("Passed RT String : %s\n",
2595 (ctrl->controls[0]).string);
2596 bytes_left =
2597 min((int)(ctrl->controls[0]).size, MAX_RT_LENGTH);
2598 data = (ctrl->controls[0]).string;
2599 /* send payload to FM hardware */
2600 while (bytes_left) {
2601 chunk_index++;
2602 bytes_to_copy = min(bytes_left, XFR_REG_NUM);
2603 memset(tx_data, 0, XFR_REG_NUM);
2604 if (copy_from_user(tx_data,
2605 data + bytes_copied, bytes_to_copy))
2606 return -EFAULT;
2607 retval = sync_write_xfr(radio,
2608 RDS_RT_0 + chunk_index, tx_data);
2609 if (retval < 0)
2610 return retval;
2611 bytes_copied += bytes_to_copy;
2612 bytes_left -= bytes_to_copy;
2613 }
2614 /*Write the RT Header */
2615 tx_data[0] = bytes_copied;
2616 /* PTY */
2617 tx_data[1] = TX_ON | ((radio->pty & MASK_PTY) >> 8);
2618 /* PI high */
2619 tx_data[2] = ((radio->pi & MASK_PI_MSB) >> 8);
2620 /* PI low */
2621 tx_data[3] = radio->pi & MASK_PI_LSB;
2622 retval = sync_write_xfr(radio, RDS_RT_0 , tx_data);
2623 if (retval < 0)
2624 return retval;
2625 FMDBG("done RT writing: %d\n", retval);
2626 } break;
2627 default:
2628 {
2629 FMDBG("Shouldn't reach here\n");
2630 retval = -1;
2631 }
2632 }
2633 return retval;
2634}
2635
2636/*=============================================================================
2637FUNCTION: tavarua_vidioc_s_ctrl
2638=============================================================================*/
2639/**
2640 This function is called to set the value of a control.
2641
2642 NOTE:
2643 To change the value of a control, applications initialize the id and value
2644 fields of a struct v4l2_control and call the VIDIOC_S_CTRL ioctl.
2645
2646 When the id is invalid drivers return an EINVAL error code. When the value is
2647 out of bounds drivers can choose to take the closest valid value or return an
2648 ERANGE error code, whatever seems more appropriate.
2649
2650 @param file: File descriptor returned by open().
2651 @param ctrl: pointer to struct v4l2_control.
2652
2653 @return On success 0 is returned, else error code.
2654 @return EINVAL: The struct v4l2_control id is invalid.
2655 @return ERANGE: The struct v4l2_control value is out of bounds.
2656 @return EBUSY: The control is temporarily not changeable, possibly because
2657 another applications took over control of the device function this control
2658 belongs to.
2659*/
2660static int tavarua_vidioc_s_ctrl(struct file *file, void *priv,
2661 struct v4l2_control *ctrl)
2662{
2663 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2664 int retval = 0;
2665 unsigned char value;
2666 unsigned char xfr_buf[XFR_REG_NUM];
2667 unsigned char tx_data[XFR_REG_NUM];
2668
2669 switch (ctrl->id) {
2670 case V4L2_CID_AUDIO_VOLUME:
2671 break;
2672 case V4L2_CID_AUDIO_MUTE:
2673 value = (radio->registers[IOCTRL] & ~IOC_HRD_MUTE) |
2674 (ctrl->value & 0x03);
2675 retval = tavarua_write_register(radio, IOCTRL, value);
2676 break;
2677 case V4L2_CID_PRIVATE_TAVARUA_SRCHMODE:
2678 value = (radio->registers[SRCHCTRL] & ~SRCH_MODE) |
2679 ctrl->value;
2680 radio->registers[SRCHCTRL] = value;
2681 break;
2682 case V4L2_CID_PRIVATE_TAVARUA_SCANDWELL:
2683 value = (radio->registers[SRCHCTRL] & ~SCAN_DWELL) |
2684 (ctrl->value << 4);
2685 radio->registers[SRCHCTRL] = value;
2686 break;
2687 /* start/stop search */
2688 case V4L2_CID_PRIVATE_TAVARUA_SRCHON:
2689 FMDBG("starting search\n");
2690 tavarua_search(radio, ctrl->value, SRCH_DIR_UP);
2691 break;
2692 case V4L2_CID_PRIVATE_TAVARUA_STATE:
2693 /* check if already on */
2694 radio->handle_irq = 1;
2695 if (((ctrl->value == FM_RECV) || (ctrl->value == FM_TRANS))
2696 && !(radio->registers[RDCTRL] &
2697 ctrl->value)) {
2698 FMDBG("clearing flags\n");
2699 init_completion(&radio->sync_xfr_start);
2700 init_completion(&radio->sync_req_done);
2701 radio->xfr_in_progress = 0;
2702 radio->xfr_bytes_left = 0;
2703 FMDBG("turning on ..\n");
2704 retval = tavarua_start(radio, ctrl->value);
2705 if (retval >= 0) {
2706 FMDBG("Setting audio path ...\n");
2707 retval = tavarua_set_audio_path(
2708 TAVARUA_AUDIO_OUT_DIGITAL_ON,
2709 TAVARUA_AUDIO_OUT_ANALOG_OFF);
2710 if (retval < 0) {
2711 FMDERR("Error in tavarua_set_audio_path"
2712 " %d\n", retval);
2713 }
2714 /* Enabling 'SoftMute' and 'SignalBlending' features */
2715 value = (radio->registers[IOCTRL] |
2716 IOC_SFT_MUTE | IOC_SIG_BLND);
2717 retval = tavarua_write_register(radio, IOCTRL, value);
2718 if (retval < 0)
2719 FMDBG("SMute and SBlending not enabled\n");
2720 }
2721 }
2722 /* check if off */
2723 else if ((ctrl->value == FM_OFF) && radio->registers[RDCTRL]) {
2724 FMDBG("turning off...\n");
2725 retval = tavarua_write_register(radio, RDCTRL,
2726 ctrl->value);
2727 /*Make it synchronous
2728 Block it till READY interrupt
2729 Wait for interrupt i.e.
2730 complete(&radio->sync_req_done)
2731 */
2732
2733 if (retval >= 0) {
2734
2735 if (!wait_for_completion_timeout(
2736 &radio->sync_req_done,
2737 msecs_to_jiffies(wait_timeout)))
2738 FMDBG("turning off timedout...\n");
2739 }
2740 }
2741 break;
2742 case V4L2_CID_PRIVATE_TAVARUA_REGION:
2743 retval = tavarua_set_region(radio, ctrl->value);
2744 break;
2745 case V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH:
2746 retval = sync_read_xfr(radio, RX_CONFIG, xfr_buf);
2747 if (retval < 0) {
2748 FMDERR("V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH]\n");
2749 FMDERR("sync_read_xfr [retval=%d]\n", retval);
2750 break;
2751 }
2752 /* RMSSI Threshold is a signed 8 bit value */
2753 xfr_buf[0] = (unsigned char)ctrl->value;
2754 xfr_buf[1] = (unsigned char)ctrl->value;
2755 xfr_buf[4] = 0x01;
2756 retval = sync_write_xfr(radio, RX_CONFIG, xfr_buf);
2757 if (retval < 0) {
2758 FMDERR("V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH]\n");
2759 FMDERR("sync_write_xfr [retval=%d]\n", retval);
2760 break;
2761 }
2762 break;
2763 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY:
2764 radio->srch_params.srch_pty = ctrl->value;
2765 break;
2766 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PI:
2767 radio->srch_params.srch_pi = ctrl->value;
2768 break;
2769 case V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT:
2770 radio->srch_params.preset_num = ctrl->value;
2771 break;
2772 case V4L2_CID_PRIVATE_TAVARUA_EMPHASIS:
2773 radio->region_params.emphasis = ctrl->value;
2774 break;
2775 case V4L2_CID_PRIVATE_TAVARUA_RDS_STD:
2776 radio->region_params.rds_std = ctrl->value;
2777 break;
2778 case V4L2_CID_PRIVATE_TAVARUA_SPACING:
2779 radio->region_params.spacing = ctrl->value;
2780 break;
2781 case V4L2_CID_PRIVATE_TAVARUA_RDSON:
2782 retval = 0;
2783 if (ctrl->value != (radio->registers[RDSCTRL] & RDS_ON)) {
2784 value = radio->registers[RDSCTRL] | ctrl->value;
2785 retval = tavarua_write_register(radio, RDSCTRL, value);
2786 }
2787 break;
2788 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK:
2789 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2790 if (retval < 0)
2791 break;
2792 xfr_buf[8] = (ctrl->value & 0xFF000000) >> 24;
2793 xfr_buf[9] = (ctrl->value & 0x00FF0000) >> 16;
2794 xfr_buf[10] = (ctrl->value & 0x0000FF00) >> 8;
2795 xfr_buf[11] = (ctrl->value & 0x000000FF);
2796 retval = sync_write_xfr(radio, RDS_CONFIG, xfr_buf);
2797 break;
2798 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC:
2799 value = radio->registers[ADVCTRL] | ctrl->value ;
2800 retval = tavarua_write_register(radio, ADVCTRL, value);
2801 break;
2802 case V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF:
2803 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2804 if (retval < 0)
2805 break;
2806 xfr_buf[1] = ctrl->value;
2807 retval = sync_write_xfr(radio, RDS_CONFIG, xfr_buf);
2808 break;
2809 case V4L2_CID_PRIVATE_TAVARUA_PSALL:
2810 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2811 value = ctrl->value & RDS_CONFIG_PSALL;
2812 if (retval < 0)
2813 break;
2814 xfr_buf[12] &= ~RDS_CONFIG_PSALL;
2815 xfr_buf[12] |= value;
2816 retval = sync_write_xfr(radio, RDS_CONFIG, xfr_buf);
2817 break;
2818 case V4L2_CID_PRIVATE_TAVARUA_LP_MODE:
2819 retval = 0;
2820 if (ctrl->value == radio->lp_mode)
2821 break;
2822 if (ctrl->value) {
2823 FMDBG("going into low power mode\n");
2824 retval = tavarua_disable_interrupts(radio);
2825 } else {
2826 FMDBG("going into normal power mode\n");
2827 tavarua_setup_interrupts(radio,
2828 (radio->registers[RDCTRL] & 0x03));
2829 }
2830 break;
2831 case V4L2_CID_PRIVATE_TAVARUA_ANTENNA:
2832 SET_REG_FIELD(radio->registers[IOCTRL], ctrl->value,
2833 IOC_ANTENNA_OFFSET, IOC_ANTENNA_MASK);
2834 break;
2835 /* TX Controls */
2836
2837 case V4L2_CID_RDS_TX_PTY: {
2838 radio->pty = ctrl->value;
2839 } break;
2840 case V4L2_CID_RDS_TX_PI: {
2841 radio->pi = ctrl->value;
2842 } break;
2843 case V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_PS_NAME: {
2844 FMDBG("In STOP_RDS_TX_PS_NAME\n");
2845 /*Pass a sample PS string */
2846 memset(tx_data, '0', XFR_REG_NUM);
2847 FMDBG("Writing PS header\n");
2848 retval = sync_write_xfr(radio, RDS_PS_0, tx_data);
2849 FMDBG("retval of PS Header write: %d", retval);
2850
2851 } break;
2852
2853 case V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_RT: {
2854 memset(tx_data, '0', XFR_REG_NUM);
2855 FMDBG("Writing RT header\n");
2856 retval = sync_write_xfr(radio, RDS_RT_0, tx_data);
2857 FMDBG("retval of Header write: %d", retval);
2858
2859 } break;
2860
2861 case V4L2_CID_PRIVATE_TAVARUA_TX_SETPSREPEATCOUNT: {
2862 radio->ps_repeatcount = ctrl->value;
2863 } break;
2864 case V4L2_CID_TUNE_POWER_LEVEL: {
2865 unsigned char tx_power_lvl_config[FM_TX_PWR_LVL_MAX+1] = {
2866 0x85, /* tx_da<5:3> = 0 lpf<2:0> = 5*/
2867 0x95, /* tx_da<5:3> = 2 lpf<2:0> = 5*/
2868 0x9D, /* tx_da<5:3> = 3 lpf<2:0> = 5*/
2869 0xA5, /* tx_da<5:3> = 4 lpf<2:0> = 5*/
2870 0xAD, /* tx_da<5:3> = 5 lpf<2:0> = 5*/
2871 0xB5, /* tx_da<5:3> = 6 lpf<2:0> = 5*/
2872 0xBD, /* tx_da<5:3> = 7 lpf<2:0> = 5*/
2873 0xBF /* tx_da<5:3> = 7 lpf<2:0> = 7*/
2874 };
2875 if (ctrl->value > FM_TX_PWR_LVL_MAX)
2876 ctrl->value = FM_TX_PWR_LVL_MAX;
2877 if (ctrl->value < FM_TX_PWR_LVL_0)
2878 ctrl->value = FM_TX_PWR_LVL_0;
2879 retval = sync_read_xfr(radio, PHY_TXGAIN, xfr_buf);
2880 FMDBG("return for PHY_TXGAIN is %d", retval);
2881 if (retval < 0) {
2882 FMDBG("read failed");
2883 break;
2884 }
2885 xfr_buf[2] = tx_power_lvl_config[ctrl->value];
2886 retval = sync_write_xfr(radio, PHY_TXGAIN, xfr_buf);
2887 FMDBG("return for write PHY_TXGAIN is %d", retval);
2888 if (retval < 0)
2889 FMDBG("write failed");
2890 } break;
2891
2892 default:
2893 retval = -EINVAL;
2894 }
2895 if (retval < 0)
2896 printk(KERN_WARNING DRIVER_NAME
2897 ": set control failed with %d, id : %d\n", retval, ctrl->id);
2898
2899 return retval;
2900}
2901
2902/*=============================================================================
2903FUNCTION: tavarua_vidioc_g_tuner
2904=============================================================================*/
2905/**
2906 This function is called to get tuner attributes.
2907
2908 NOTE:
2909 To query the attributes of a tuner, applications initialize the index field
2910 and zero out the reserved array of a struct v4l2_tuner and call the
2911 VIDIOC_G_TUNER ioctl with a pointer to this structure. Drivers fill the rest
2912 of the structure or return an EINVAL error code when the index is out of
2913 bounds. To enumerate all tuners applications shall begin at index zero,
2914 incrementing by one until the driver returns EINVAL.
2915
2916 @param file: File descriptor returned by open().
2917 @param tuner: pointer to struct v4l2_tuner.
2918
2919 @return On success 0 is returned, else error code.
2920 @return EINVAL: The struct v4l2_tuner index is out of bounds.
2921*/
2922static int tavarua_vidioc_g_tuner(struct file *file, void *priv,
2923 struct v4l2_tuner *tuner)
2924{
2925 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2926 int retval;
2927 unsigned char xfr_buf[XFR_REG_NUM];
2928 char rmssi = 0;
2929 unsigned char size = 0;
2930
2931 if (tuner->index > 0)
2932 return -EINVAL;
2933
2934 /* read status rssi */
2935 retval = tavarua_read_registers(radio, IOCTRL, 1);
2936 if (retval < 0)
2937 return retval;
2938 /* read RMSSI */
2939 size = 0x1;
2940 xfr_buf[0] = (XFR_PEEK_MODE | (size << 1));
2941 xfr_buf[1] = RMSSI_PEEK_MSB;
2942 xfr_buf[2] = RMSSI_PEEK_LSB;
2943 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 3);
2944 msleep(TAVARUA_DELAY*10);
2945 retval = tavarua_read_registers(radio, XFRDAT0, 3);
2946 rmssi = radio->registers[XFRDAT0];
2947 tuner->signal = rmssi;
2948
2949 strcpy(tuner->name, "FM");
2950 tuner->type = V4L2_TUNER_RADIO;
2951 tuner->rangelow = radio->region_params.band_low;
2952 tuner->rangehigh = radio->region_params.band_high;
2953 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
2954 tuner->capability = V4L2_TUNER_CAP_LOW;
2955
2956 /* Stereo indicator == Stereo (instead of Mono) */
2957 if (radio->registers[IOCTRL] & IOC_MON_STR)
2958 tuner->audmode = V4L2_TUNER_MODE_STEREO;
2959 else
2960 tuner->audmode = V4L2_TUNER_MODE_MONO;
2961
2962 /* automatic frequency control: -1: freq to low, 1 freq to high */
2963 tuner->afc = 0;
2964
2965 return 0;
2966}
2967
2968/*=============================================================================
2969FUNCTION: tavarua_vidioc_s_tuner
2970=============================================================================*/
2971/**
2972 This function is called to set tuner attributes. Used to set mono/stereo mode.
2973
2974 NOTE:
2975 Tuners have two writable properties, the audio mode and the radio frequency.
2976 To change the audio mode, applications initialize the index, audmode and
2977 reserved fields and call the VIDIOC_S_TUNER ioctl. This will not change the
2978 current tuner, which is determined by the current video input. Drivers may
2979 choose a different audio mode if the requested mode is invalid or unsupported.
2980 Since this is a write-only ioctl, it does not return the actually selected
2981 audio mode.
2982
2983 To change the radio frequency the VIDIOC_S_FREQUENCY ioctl is available.
2984
2985 @param file: File descriptor returned by open().
2986 @param tuner: pointer to struct v4l2_tuner.
2987
2988 @return On success 0 is returned, else error code.
2989 @return -EINVAL: The struct v4l2_tuner index is out of bounds.
2990*/
2991static int tavarua_vidioc_s_tuner(struct file *file, void *priv,
2992 struct v4l2_tuner *tuner)
2993{
2994 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2995 int retval;
2996 int audmode;
2997 if (tuner->index > 0)
2998 return -EINVAL;
2999
3000 FMDBG("%s: set low to %d\n", __func__, tuner->rangelow);
3001 radio->region_params.band_low = tuner->rangelow;
3002 radio->region_params.band_high = tuner->rangehigh;
3003 if (tuner->audmode == V4L2_TUNER_MODE_MONO)
3004 /* Mono */
3005 audmode = (radio->registers[IOCTRL] | IOC_MON_STR);
3006 else
3007 /* Stereo */
3008 audmode = (radio->registers[IOCTRL] & ~IOC_MON_STR);
3009 retval = tavarua_write_register(radio, IOCTRL, audmode);
3010 if (retval < 0)
3011 printk(KERN_WARNING DRIVER_NAME
3012 ": set tuner failed with %d\n", retval);
3013
3014 return retval;
3015}
3016
3017/*=============================================================================
3018FUNCTION: tavarua_vidioc_g_frequency
3019=============================================================================*/
3020/**
3021 This function is called to get tuner or modulator radio frequency.
3022
3023 NOTE:
3024 To get the current tuner or modulator radio frequency applications set the
3025 tuner field of a struct v4l2_frequency to the respective tuner or modulator
3026 number (only input devices have tuners, only output devices have modulators),
3027 zero out the reserved array and call the VIDIOC_G_FREQUENCY ioctl with a
3028 pointer to this structure. The driver stores the current frequency in the
3029 frequency field.
3030
3031 @param file: File descriptor returned by open().
3032 @param freq: pointer to struct v4l2_frequency. This will be set to the
3033 resultant
3034 frequency in 62.5 khz on success.
3035
3036 @return On success 0 is returned, else error code.
3037 @return EINVAL: The tuner index is out of bounds or the value in the type
3038 field is wrong.
3039*/
3040static int tavarua_vidioc_g_frequency(struct file *file, void *priv,
3041 struct v4l2_frequency *freq)
3042{
3043 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3044 freq->type = V4L2_TUNER_RADIO;
3045 return tavarua_get_freq(radio, freq);
3046
3047}
3048
3049/*=============================================================================
3050FUNCTION: tavarua_vidioc_s_frequency
3051=============================================================================*/
3052/**
3053 This function is called to set tuner or modulator radio frequency.
3054
3055 NOTE:
3056 To change the current tuner or modulator radio frequency applications
3057 initialize the tuner, type and frequency fields, and the reserved array of
3058 a struct v4l2_frequency and call the VIDIOC_S_FREQUENCY ioctl with a pointer
3059 to this structure. When the requested frequency is not possible the driver
3060 assumes the closest possible value. However VIDIOC_S_FREQUENCY is a
3061 write-only ioctl, it does not return the actual new frequency.
3062
3063 @param file: File descriptor returned by open().
3064 @param freq: pointer to struct v4l2_frequency.
3065
3066 @return On success 0 is returned, else error code.
3067 @return EINVAL: The tuner index is out of bounds or the value in the type
3068 field is wrong.
3069*/
3070static int tavarua_vidioc_s_frequency(struct file *file, void *priv,
3071 struct v4l2_frequency *freq)
3072{
3073 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3074 int retval = -1;
3075 struct v4l2_frequency getFreq;
3076
3077 FMDBG("%s\n", __func__);
3078
3079 if (freq->type != V4L2_TUNER_RADIO)
3080 return -EINVAL;
3081
3082 FMDBG("Calling tavarua_set_freq\n");
3083
3084 INIT_COMPLETION(radio->sync_req_done);
3085 retval = tavarua_set_freq(radio, freq->frequency);
3086 if (retval < 0) {
3087 printk(KERN_WARNING DRIVER_NAME
3088 ": set frequency failed with %d\n", retval);
3089 } else {
3090 /* Wait for interrupt i.e. complete
3091 (&radio->sync_req_done); call */
3092 if (!wait_for_completion_timeout(&radio->sync_req_done,
3093 msecs_to_jiffies(wait_timeout))) {
3094 FMDERR("Timeout: No Tune response");
3095 retval = tavarua_get_freq(radio, &getFreq);
3096 radio->tune_req = 0;
3097 if (retval > 0) {
3098 if (getFreq.frequency == freq->frequency) {
3099 /** This is success, queut the event*/
3100 tavarua_q_event(radio,
3101 TAVARUA_EVT_TUNE_SUCC);
3102 return 0;
3103 } else {
3104 return -EIO;
3105 }
3106 }
3107 }
3108 }
3109 radio->tune_req = 0;
3110 return retval;
3111}
3112
3113/*=============================================================================
3114FUNCTION: tavarua_vidioc_dqbuf
3115=============================================================================*/
3116/**
3117 This function is called to exchange a buffer with the driver.
3118 This is main buffer function, in essense its equivalent to a blocking
3119 read call.
3120
3121 Applications call the VIDIOC_DQBUF ioctl to dequeue a filled (capturing) or
3122 displayed (output) buffer from the driver's outgoing queue. They just set
3123 the type and memory fields of a struct v4l2_buffer as above, when VIDIOC_DQBUF
3124 is called with a pointer to this structure the driver fills the remaining
3125 fields or returns an error code.
3126
3127 NOTE:
3128 By default VIDIOC_DQBUF blocks when no buffer is in the outgoing queue.
3129 When the O_NONBLOCK flag was given to the open() function, VIDIOC_DQBUF
3130 returns immediately with an EAGAIN error code when no buffer is available.
3131
3132 @param file: File descriptor returned by open().
3133 @param buffer: pointer to struct v4l2_buffer.
3134
3135 @return On success 0 is returned, else error code.
3136 @return EAGAIN: Non-blocking I/O has been selected using O_NONBLOCK and no
3137 buffer was in the outgoing queue.
3138 @return EINVAL: The buffer type is not supported, or the index is out of
3139 bounds, or no buffers have been allocated yet, or the userptr or length are
3140 invalid.
3141 @return ENOMEM: Not enough physical or virtual memory was available to enqueue
3142 a user pointer buffer.
3143 @return EIO: VIDIOC_DQBUF failed due to an internal error. Can also indicate
3144 temporary problems like signal loss. Note the driver might dequeue an (empty)
3145 buffer despite returning an error, or even stop capturing.
3146*/
3147static int tavarua_vidioc_dqbuf(struct file *file, void *priv,
3148 struct v4l2_buffer *buffer)
3149{
3150
3151 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3152 enum tavarua_buf_t buf_type = buffer->index;
3153 struct kfifo *data_fifo;
3154 unsigned char *buf = (unsigned char *)buffer->m.userptr;
3155 unsigned int len = buffer->length;
3156 FMDBG("%s: requesting buffer %d\n", __func__, buf_type);
3157 /* check if we can access the user buffer */
3158 if (!access_ok(VERIFY_WRITE, buf, len))
3159 return -EFAULT;
3160 if ((buf_type < TAVARUA_BUF_MAX) && (buf_type >= 0)) {
3161 data_fifo = &radio->data_buf[buf_type];
3162 if (buf_type == TAVARUA_BUF_EVENTS) {
3163 if (wait_event_interruptible(radio->event_queue,
3164 kfifo_len(data_fifo)) < 0) {
3165 return -EINTR;
3166 }
3167 }
3168 } else {
3169 FMDERR("invalid buffer type\n");
3170 return -EINVAL;
3171 }
3172 buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
3173 &radio->buf_lock[buf_type]);
3174
3175 return 0;
3176}
3177
3178/*=============================================================================
3179FUNCTION: tavarua_vidioc_g_fmt_type_private
3180=============================================================================*/
3181/**
3182 This function is here to make the v4l2 framework happy.
3183 We cannot use private buffers without it.
3184
3185 @param file: File descriptor returned by open().
3186 @param f: pointer to struct v4l2_format.
3187
3188 @return On success 0 is returned, else error code.
3189 @return EINVAL: The tuner index is out of bounds or the value in the type
3190 field is wrong.
3191*/
3192static int tavarua_vidioc_g_fmt_type_private(struct file *file, void *priv,
3193 struct v4l2_format *f)
3194{
3195 return 0;
3196
3197}
3198
3199/*=============================================================================
3200FUNCTION: tavarua_vidioc_s_hw_freq_seek
3201=============================================================================*/
3202/**
3203 This function is called to perform a hardware frequency seek.
3204
3205 Start a hardware frequency seek from the current frequency. To do this
3206 applications initialize the tuner, type, seek_upward and wrap_around fields,
3207 and zero out the reserved array of a struct v4l2_hw_freq_seek and call the
3208 VIDIOC_S_HW_FREQ_SEEK ioctl with a pointer to this structure.
3209
3210 This ioctl is supported if the V4L2_CAP_HW_FREQ_SEEK capability is set.
3211
3212 @param file: File descriptor returned by open().
3213 @param seek: pointer to struct v4l2_hw_freq_seek.
3214
3215 @return On success 0 is returned, else error code.
3216 @return EINVAL: The tuner index is out of bounds or the value in the type
3217 field is wrong.
3218 @return EAGAIN: The ioctl timed-out. Try again.
3219*/
3220static int tavarua_vidioc_s_hw_freq_seek(struct file *file, void *priv,
3221 struct v4l2_hw_freq_seek *seek)
3222{
3223 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3224 int dir;
3225 if (seek->seek_upward)
3226 dir = SRCH_DIR_UP;
3227 else
3228 dir = SRCH_DIR_DOWN;
3229 FMDBG("starting search\n");
3230 return tavarua_search(radio, CTRL_ON, dir);
3231}
3232
3233/*
3234 * tavarua_viddev_tamples - video device interface
3235 */
3236static const struct v4l2_ioctl_ops tavarua_ioctl_ops = {
3237 .vidioc_querycap = tavarua_vidioc_querycap,
3238 .vidioc_queryctrl = tavarua_vidioc_queryctrl,
3239 .vidioc_g_ctrl = tavarua_vidioc_g_ctrl,
3240 .vidioc_s_ctrl = tavarua_vidioc_s_ctrl,
3241 .vidioc_g_tuner = tavarua_vidioc_g_tuner,
3242 .vidioc_s_tuner = tavarua_vidioc_s_tuner,
3243 .vidioc_g_frequency = tavarua_vidioc_g_frequency,
3244 .vidioc_s_frequency = tavarua_vidioc_s_frequency,
3245 .vidioc_s_hw_freq_seek = tavarua_vidioc_s_hw_freq_seek,
3246 .vidioc_dqbuf = tavarua_vidioc_dqbuf,
3247 .vidioc_g_fmt_type_private = tavarua_vidioc_g_fmt_type_private,
3248 .vidioc_s_ext_ctrls = tavarua_vidioc_s_ext_ctrls,
3249};
3250
3251static struct video_device tavarua_viddev_template = {
3252 .fops = &tavarua_fops,
3253 .ioctl_ops = &tavarua_ioctl_ops,
3254 .name = DRIVER_NAME,
3255 .release = video_device_release,
3256};
3257
3258/*==============================================================
3259FUNCTION: FmQSocCom_EnableInterrupts
3260==============================================================*/
3261/**
3262 This function enable interrupts.
3263
3264 @param radio: structure pointer passed by client.
3265 @param state: FM radio state (receiver/transmitter/off/reset).
3266
3267 @return => 0 if successful.
3268 @return < 0 if failure.
3269*/
3270static int tavarua_setup_interrupts(struct tavarua_device *radio,
3271 enum radio_state_t state)
3272{
3273 int retval;
3274 unsigned char int_ctrl[XFR_REG_NUM];
3275
3276 if (!radio->lp_mode)
3277 return 0;
3278
3279 int_ctrl[STATUS_REG1] = READY | TUNE | SEARCH | SCANNEXT |
3280 SIGNAL | INTF | SYNC | AUDIO;
3281 if (state == FM_RECV)
3282 int_ctrl[STATUS_REG2] = RDSDAT | RDSRT | RDSPS | RDSAF;
3283 else
3284 int_ctrl[STATUS_REG2] = TXRDSDAT | TXRDSDONE;
3285
3286 int_ctrl[STATUS_REG3] = TRANSFER | ERROR;
3287
3288 /* use xfr for interrupt setup */
3289 if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
3290 || radio->chipID == BAHAMA_2_0) {
3291 FMDBG("Setting interrupts\n");
3292 retval = sync_write_xfr(radio, INT_CTRL, int_ctrl);
3293 /* use register write to setup interrupts */
3294 } else {
3295 retval = tavarua_write_register(radio,
3296 STATUS_REG1, int_ctrl[STATUS_REG1]);
3297 if (retval < 0)
3298 return retval;
3299
3300 retval = tavarua_write_register(radio,
3301 STATUS_REG2, int_ctrl[STATUS_REG2]);
3302 if (retval < 0)
3303 return retval;
3304
3305 retval = tavarua_write_register(radio,
3306 STATUS_REG3, int_ctrl[STATUS_REG3]);
3307 if (retval < 0)
3308 return retval;
3309 }
3310
3311 radio->lp_mode = 0;
3312 /* tavarua_handle_interrupts force reads all the interrupt status
3313 * registers and it is not valid for MBA 2.1
3314 */
3315 if ((radio->chipID != MARIMBA_2_1) && (radio->chipID != BAHAMA_1_0)
3316 && (radio->chipID != BAHAMA_2_0))
3317 tavarua_handle_interrupts(radio);
3318
3319 return retval;
3320
3321}
3322
3323/*==============================================================
3324FUNCTION: tavarua_disable_interrupts
3325==============================================================*/
3326/**
3327 This function disables interrupts.
3328
3329 @param radio: structure pointer passed by client.
3330
3331 @return => 0 if successful.
3332 @return < 0 if failure.
3333*/
3334static int tavarua_disable_interrupts(struct tavarua_device *radio)
3335{
3336 unsigned char lpm_buf[XFR_REG_NUM];
3337 int retval;
3338 if (radio->lp_mode)
3339 return 0;
3340 FMDBG("%s\n", __func__);
3341 /* In Low power mode, disable all the interrupts that are not being
3342 waited by the Application */
3343 lpm_buf[STATUS_REG1] = TUNE | SEARCH | SCANNEXT;
3344 lpm_buf[STATUS_REG2] = 0x00;
3345 lpm_buf[STATUS_REG3] = TRANSFER;
3346 /* use xfr for interrupt setup */
3347 wait_timeout = 100;
3348 if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
3349 || radio->chipID == BAHAMA_2_0)
3350 retval = sync_write_xfr(radio, INT_CTRL, lpm_buf);
3351 /* use register write to setup interrupts */
3352 else
3353 retval = tavarua_write_registers(radio, STATUS_REG1, lpm_buf,
3354 ARRAY_SIZE(lpm_buf));
3355
3356 /*INT_CTL writes may fail with TIME_OUT as all the
3357 interrupts have been disabled
3358 */
3359 if (retval > -1 || retval == -ETIME) {
3360 radio->lp_mode = 1;
3361 /*Consider timeout as a valid case here*/
3362 retval = 0;
3363 }
3364 wait_timeout = WAIT_TIMEOUT;
3365 return retval;
3366
3367}
3368
3369/*==============================================================
3370FUNCTION: tavarua_start
3371==============================================================*/
3372/**
3373 Starts/enables the device (FM radio).
3374
3375 @param radio: structure pointer passed by client.
3376 @param state: FM radio state (receiver/transmitter/off/reset).
3377
3378 @return On success 0 is returned, else error code.
3379*/
3380static int tavarua_start(struct tavarua_device *radio,
3381 enum radio_state_t state)
3382{
3383
3384 int retval;
3385 FMDBG("%s <%d>\n", __func__, state);
3386 /* set geographic region */
3387 radio->region_params.region = TAVARUA_REGION_US;
3388
3389 /* set radio mode */
3390 retval = tavarua_write_register(radio, RDCTRL, state);
3391 if (retval < 0)
3392 return retval;
3393 /* wait for radio to init */
3394 msleep(RADIO_INIT_TIME);
3395 /* enable interrupts */
3396 tavarua_setup_interrupts(radio, state);
3397 /* default region is US */
3398 radio->region_params.band_low = US_LOW_BAND * FREQ_MUL;
3399 radio->region_params.band_high = US_HIGH_BAND * FREQ_MUL;
3400
3401 return 0;
3402}
3403
3404/*==============================================================
3405FUNCTION: tavarua_suspend
3406==============================================================*/
3407/**
3408 Save state and stop all devices in system.
3409
3410 @param pdev: platform device to be suspended.
3411 @param state: Power state to put each device in.
3412
3413 @return On success 0 is returned, else error code.
3414*/
3415static int tavarua_suspend(struct platform_device *pdev, pm_message_t state)
3416{
3417 struct tavarua_device *radio = platform_get_drvdata(pdev);
3418 int retval;
3419 int users = 0;
3420 printk(KERN_INFO DRIVER_NAME "%s: radio suspend\n\n", __func__);
3421 if (radio) {
3422 mutex_lock(&radio->lock);
3423 users = radio->users;
3424 mutex_unlock(&radio->lock);
3425 if (users) {
3426 retval = tavarua_disable_interrupts(radio);
3427 if (retval < 0) {
3428 printk(KERN_INFO DRIVER_NAME
3429 "tavarua_suspend error %d\n", retval);
3430 return -EIO;
3431 }
3432 }
3433 }
3434 return 0;
3435}
3436
3437/*==============================================================
3438FUNCTION: tavarua_resume
3439==============================================================*/
3440/**
3441 Restore state of each device in system.
3442
3443 @param pdev: platform device to be resumed.
3444
3445 @return On success 0 is returned, else error code.
3446*/
3447static int tavarua_resume(struct platform_device *pdev)
3448{
3449
3450 struct tavarua_device *radio = platform_get_drvdata(pdev);
3451 int retval;
3452 int users = 0;
3453 printk(KERN_INFO DRIVER_NAME "%s: radio resume\n\n", __func__);
3454 if (radio) {
3455 mutex_lock(&radio->lock);
3456 users = radio->users;
3457 mutex_unlock(&radio->lock);
3458
3459 if (users) {
3460 retval = tavarua_setup_interrupts(radio,
3461 (radio->registers[RDCTRL] & 0x03));
3462 if (retval < 0) {
3463 printk(KERN_INFO DRIVER_NAME "Error in \
3464 tavarua_resume %d\n", retval);
3465 return -EIO;
3466 }
3467 }
3468 }
3469 return 0;
3470}
3471
3472/*==============================================================
3473FUNCTION: tavarua_set_audio_path
3474==============================================================*/
3475/**
3476 This function will configure the audio path to and from the
3477 FM core.
3478
3479 This interface is expected to be called from the multimedia
3480 driver's thread. This interface should only be called when
3481 the FM hardware is enabled. If the FM hardware is not
3482 currently enabled, this interface will return an error.
3483
3484 @param digital_on: Digital audio from the FM core should be enabled/disbled.
3485 @param analog_on: Analog audio from the FM core should be enabled/disbled.
3486
3487 @return On success 0 is returned, else error code.
3488*/
3489int tavarua_set_audio_path(int digital_on, int analog_on)
3490{
3491 struct tavarua_device *radio = private_data;
3492 int rx_on = radio->registers[RDCTRL] & FM_RECV;
3493 if (!radio)
3494 return -ENOMEM;
3495 /* RX */
3496 FMDBG("%s: digital: %d analog: %d\n", __func__, digital_on, analog_on);
3497 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3498 ((rx_on && analog_on) ? 1 : 0),
3499 AUDIORX_ANALOG_OFFSET,
3500 AUDIORX_ANALOG_MASK);
3501 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3502 ((rx_on && digital_on) ? 1 : 0),
3503 AUDIORX_DIGITAL_OFFSET,
3504 AUDIORX_DIGITAL_MASK);
3505 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3506 (rx_on ? 0 : 1),
3507 AUDIOTX_OFFSET,
3508 AUDIOTX_MASK);
3509 /*
3510
3511 I2S Master/Slave configuration:
3512 Setting the FM SoC as I2S Master/Slave
3513 'false' - FM SoC is I2S Slave
3514 'true' - FM SoC is I2S Master
3515
3516 We get this infomation from the respective target's board file :
3517 MSM7x30 - FM SoC is I2S Slave
3518 MSM8x60 - FM SoC is I2S Slave
3519 MSM7x27A - FM SoC is I2S Master
3520 */
3521
3522 if (!radio->pdata->is_fm_soc_i2s_master) {
3523 FMDBG("FM SoC is I2S Slave\n");
3524 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3525 (0),
3526 I2SCTRL_OFFSET,
3527 I2SCTRL_MASK);
3528 } else {
3529 FMDBG("FM SoC is I2S Master\n");
3530 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3531 (1),
3532 I2SCTRL_OFFSET,
3533 I2SCTRL_MASK);
3534 }
3535 FMDBG("%s: %x\n", __func__, radio->registers[AUDIOCTRL]);
3536 return tavarua_write_register(radio, AUDIOCTRL,
3537 radio->registers[AUDIOCTRL]);
3538
3539}
3540
3541/*==============================================================
3542FUNCTION: tavarua_probe
3543==============================================================*/
3544/**
3545 Once called this functions initiates, allocates resources and registers video
3546 tuner device with the v4l2 framework.
3547
3548 NOTE:
3549 probe() should verify that the specified device hardware
3550 actually exists; sometimes platform setup code can't be sure. The probing
3551 can use device resources, including clocks, and device platform_data.
3552
3553 @param pdev: platform device to be probed.
3554
3555 @return On success 0 is returned, else error code.
3556 -ENOMEM in low memory cases
3557*/
3558static int __init tavarua_probe(struct platform_device *pdev)
3559{
3560
3561 struct marimba_fm_platform_data *tavarua_pdata;
3562 struct tavarua_device *radio;
3563 int retval;
3564 int i;
3565 FMDBG("%s: probe called\n", __func__);
3566 /* private data allocation */
3567 radio = kzalloc(sizeof(struct tavarua_device), GFP_KERNEL);
3568 if (!radio) {
3569 retval = -ENOMEM;
3570 goto err_initial;
3571 }
3572
3573 radio->marimba = platform_get_drvdata(pdev);
3574 tavarua_pdata = pdev->dev.platform_data;
3575 radio->pdata = tavarua_pdata;
3576 radio->dev = &pdev->dev;
3577 platform_set_drvdata(pdev, radio);
3578
3579 /* video device allocation */
3580 radio->videodev = video_device_alloc();
3581 if (!radio->videodev)
3582 goto err_radio;
3583
3584 /* initial configuration */
3585 memcpy(radio->videodev, &tavarua_viddev_template,
3586 sizeof(tavarua_viddev_template));
3587
3588 /*allocate internal buffers for decoded rds and event buffer*/
3589 for (i = 0; i < TAVARUA_BUF_MAX; i++) {
3590 int kfifo_alloc_rc=0;
3591 spin_lock_init(&radio->buf_lock[i]);
3592
3593 if (i == TAVARUA_BUF_RAW_RDS)
3594 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
3595 rds_buf*3, GFP_KERNEL);
3596 else
3597 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
3598 STD_BUF_SIZE, GFP_KERNEL);
3599
3600 if (kfifo_alloc_rc!=0) {
3601 printk(KERN_ERR "%s: failed allocating buffers %d\n",
3602 __func__, kfifo_alloc_rc);
3603 goto err_bufs;
3604 }
3605 }
3606 /* init xfr status */
3607 radio->users = 0;
3608 radio->xfr_in_progress = 0;
3609 radio->xfr_bytes_left = 0;
3610 for (i = 0; i < TAVARUA_XFR_MAX; i++)
3611 radio->pending_xfrs[i] = 0;
3612
3613 /* init transmit data */
3614 radio->tx_mode = TAVARUA_TX_RT;
3615 /* Init RT and PS Tx datas*/
3616 radio->pty = 0;
3617 radio->pi = 0;
3618 radio->ps_repeatcount = 0;
3619 /* init search params */
3620 radio->srch_params.srch_pty = 0;
3621 radio->srch_params.srch_pi = 0;
3622 radio->srch_params.preset_num = 0;
3623 radio->srch_params.get_list = 0;
3624 /* radio initializes to low power mode */
3625 radio->lp_mode = 1;
3626 radio->handle_irq = 1;
3627 /* init lock */
3628 mutex_init(&radio->lock);
3629 /* init completion flags */
3630 init_completion(&radio->sync_xfr_start);
3631 init_completion(&radio->sync_req_done);
3632 radio->tune_req = 0;
3633 /* initialize wait queue for event read */
3634 init_waitqueue_head(&radio->event_queue);
3635 /* initialize wait queue for raw rds read */
3636 init_waitqueue_head(&radio->read_queue);
3637
3638 video_set_drvdata(radio->videodev, radio);
3639 /*Start the worker thread for event handling and register read_int_stat
3640 as worker function*/
3641 INIT_DELAYED_WORK(&radio->work, read_int_stat);
3642
3643 /* register video device */
3644 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
3645 printk(KERN_WARNING DRIVER_NAME
3646 ": Could not register video device\n");
3647 goto err_all;
3648 }
3649 private_data = radio;
3650 return 0;
3651
3652err_all:
3653 video_device_release(radio->videodev);
3654err_bufs:
3655 for (; i > -1; i--)
3656 kfifo_free(&radio->data_buf[i]);
3657err_radio:
3658 kfree(radio);
3659err_initial:
3660 return retval;
3661}
3662
3663/*==============================================================
3664FUNCTION: tavarua_remove
3665==============================================================*/
3666/**
3667 Removes the device.
3668
3669 @param pdev: platform device to be removed.
3670
3671 @return On success 0 is returned, else error code.
3672*/
3673static int __devexit tavarua_remove(struct platform_device *pdev)
3674{
3675 int i;
3676 struct tavarua_device *radio = platform_get_drvdata(pdev);
3677
3678 /* disable irq */
3679 tavarua_disable_irq(radio);
3680
3681 video_unregister_device(radio->videodev);
3682
3683 /* free internal buffers */
3684 for (i = 0; i < TAVARUA_BUF_MAX; i++)
3685 kfifo_free(&radio->data_buf[i]);
3686
3687 /* free state struct */
3688 kfree(radio);
3689
3690 platform_set_drvdata(pdev, NULL);
3691
3692 return 0;
3693}
3694
3695/*
3696 Platform drivers follow the standard driver model convention, where
3697 discovery/enumeration is handled outside the drivers, and drivers
3698 provide probe() and remove() methods. They support power management
3699 and shutdown notifications using the standard conventions.
3700*/
3701static struct platform_driver tavarua_driver = {
3702 .driver = {
3703 .owner = THIS_MODULE,
3704 .name = "marimba_fm",
3705 },
3706 .remove = __devexit_p(tavarua_remove),
3707 .suspend = tavarua_suspend,
3708 .resume = tavarua_resume,
3709}; /* platform device we're adding */
3710
3711
3712/*************************************************************************
3713 * Module Interface
3714 ************************************************************************/
3715
3716/*==============================================================
3717FUNCTION: radio_module_init
3718==============================================================*/
3719/**
3720 Module entry - add a platform-level device.
3721
3722 @return Returns zero if the driver registered and bound to a device, else
3723 returns a negative error code when the driver not registered.
3724*/
3725static int __init radio_module_init(void)
3726{
3727 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
3728 return platform_driver_probe(&tavarua_driver, tavarua_probe);
3729}
3730
3731/*==============================================================
3732FUNCTION: radio_module_exit
3733==============================================================*/
3734/**
3735 Module exit - removes a platform-level device.
3736
3737 NOTE:
3738 Note that this function will also release all memory- and port-based
3739 resources owned by the device (dev->resource).
3740
3741 @return none.
3742*/
3743static void __exit radio_module_exit(void)
3744{
3745 platform_driver_unregister(&tavarua_driver);
3746}
3747
3748MODULE_LICENSE("GPL v2");
3749MODULE_AUTHOR(DRIVER_AUTHOR);
3750MODULE_DESCRIPTION(DRIVER_DESC);
3751MODULE_VERSION(DRIVER_VERSION);
3752
3753module_init(radio_module_init);
3754module_exit(radio_module_exit);
3755