blob: ced5a0c65432c033da91324a6734be0bd5ec945e [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;
Anantha Krishnana02ef212011-06-28 00:57:25 +05301243 unsigned int rdsMask = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001244 unsigned char xfr_buf[XFR_REG_NUM];
1245 unsigned char value;
1246 unsigned int spacing = 0.100 * FREQ_MUL;
1247 unsigned int band_low, band_high;
1248 unsigned int low_band_limit = 76.0 * FREQ_MUL;
1249 enum tavarua_region_t region = req_region;
Anantha Krishnana02ef212011-06-28 00:57:25 +05301250 unsigned char adie_type_bahma;
1251
1252 adie_type_bahma = is_bahama();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001253
1254 /* Set freq band */
1255 switch (region) {
1256 case TAVARUA_REGION_US:
1257 case TAVARUA_REGION_EU:
1258 case TAVARUA_REGION_JAPAN_WIDE:
1259 SET_REG_FIELD(radio->registers[RDCTRL], 0,
1260 RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
1261 break;
1262 case TAVARUA_REGION_JAPAN:
1263 SET_REG_FIELD(radio->registers[RDCTRL], 1,
1264 RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
1265 break;
1266 default:
1267 retval = sync_read_xfr(radio, RADIO_CONFIG, xfr_buf);
1268 if (retval < 0) {
1269 FMDERR("failed to get RADIO_CONFIG\n");
1270 return retval;
1271 }
1272 band_low = (radio->region_params.band_low -
1273 low_band_limit) / spacing;
1274 band_high = (radio->region_params.band_high -
1275 low_band_limit) / spacing;
1276 FMDBG("low_band: %x, high_band: %x\n", band_low, band_high);
1277 xfr_buf[0] = band_low >> 8;
1278 xfr_buf[1] = band_low & 0xFF;
1279 xfr_buf[2] = band_high >> 8;
1280 xfr_buf[3] = band_high & 0xFF;
1281 retval = sync_write_xfr(radio, RADIO_CONFIG, xfr_buf);
1282 if (retval < 0) {
1283 FMDERR("Could not set regional settings\n");
1284 return retval;
1285 }
1286 break;
1287 }
1288
Anantha Krishnana02ef212011-06-28 00:57:25 +05301289 /* Enable/Disable the 200KHz enforcer for respectiver regions */
1290 switch (region) {
1291 case TAVARUA_REGION_US:
1292 if (adie_type_bahma) {
1293 FMDBG("Adie type : Bahama\n");
1294 /*Enable the 200KHz enforcer*/
1295 retval = tavarua_read_registers(radio,
1296 ADVCTRL, 1);
1297 if (retval >= 0) {
1298 rdsMask = radio->registers[ADVCTRL];
1299 SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
1300 SRCH200KHZ_OFFSET, SRCH_MASK);
1301 msleep(TAVARUA_DELAY);
1302 retval = tavarua_write_register(radio,
1303 ADVCTRL, rdsMask);
1304 } else
1305 return retval;
1306 } /* if Marimba do nothing */
1307 break;
1308 case TAVARUA_REGION_EU:
1309 case TAVARUA_REGION_JAPAN:
1310 case TAVARUA_REGION_JAPAN_WIDE:
1311 default:
1312 if (adie_type_bahma) {
1313 FMDBG("Adie type : Bahama\n");
1314 /*
1315 Disable 200KHz enforcer for all 100/50 KHz
1316 spaced regions.
1317 */
1318 retval = tavarua_read_registers(radio,
1319 ADVCTRL, 1);
1320 if (retval >= 0) {
1321 rdsMask = radio->registers[ADVCTRL];
1322 SET_REG_FIELD(rdsMask, NO_SRCH200khz,
1323 SRCH200KHZ_OFFSET, SRCH_MASK);
1324 msleep(TAVARUA_DELAY);
1325 retval = tavarua_write_register(radio,
1326 ADVCTRL, rdsMask);
1327 } else
1328 return retval;
1329 } /* if Marimba do nothing */
1330 break;
1331 }
1332
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001333 /* Set channel spacing */
1334 switch (region) {
1335 case TAVARUA_REGION_US:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301336 if (adie_type_bahma) {
1337 FMDBG("Adie type : Bahama\n");
1338 /*
1339 Configuring all 200KHZ spaced regions as
1340 100KHz due to change in the new Bahma
1341 FM SoC search algorithm.
1342 */
1343 value = FM_CH_SPACE_100KHZ;
1344 } else {
1345 FMDBG("Adie type : Marimba\n");
1346 value = FM_CH_SPACE_200KHZ;
1347 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001348 break;
Anantha Krishnana02ef212011-06-28 00:57:25 +05301349 case TAVARUA_REGION_EU:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001350 case TAVARUA_REGION_JAPAN:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301351 value = FM_CH_SPACE_100KHZ;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001352 break;
1353 case TAVARUA_REGION_JAPAN_WIDE:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301354 value = FM_CH_SPACE_50KHZ;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001355 break;
1356 default:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301357 /*
1358 Set the channel spacing as configured from
1359 the upper layers.
1360 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001361 value = radio->region_params.spacing;
Anantha Krishnana02ef212011-06-28 00:57:25 +05301362 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001363 }
1364
1365 SET_REG_FIELD(radio->registers[RDCTRL], value,
1366 RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
1367
1368 /* Set De-emphasis and soft band range*/
1369 switch (region) {
1370 case TAVARUA_REGION_US:
1371 case TAVARUA_REGION_JAPAN:
1372 case TAVARUA_REGION_JAPAN_WIDE:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301373 value = EMP_75;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001374 break;
1375 case TAVARUA_REGION_EU:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301376 value = EMP_50;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001377 break;
1378 default:
1379 value = radio->region_params.emphasis;
1380 }
1381
1382 SET_REG_FIELD(radio->registers[RDCTRL], value,
1383 RDCTRL_DEEMPHASIS_OFFSET, RDCTRL_DEEMPHASIS_MASK);
1384
1385 /* set RDS standard */
1386 switch (region) {
1387 default:
1388 value = radio->region_params.rds_std;
1389 break;
1390 case TAVARUA_REGION_US:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301391 value = RBDS_STD;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001392 break;
1393 case TAVARUA_REGION_EU:
Anantha Krishnana02ef212011-06-28 00:57:25 +05301394 value = RDS_STD;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001395 break;
1396 }
1397 SET_REG_FIELD(radio->registers[RDSCTRL], value,
1398 RDSCTRL_STANDARD_OFFSET, RDSCTRL_STANDARD_MASK);
1399
1400 FMDBG("RDSCTRLL %x\n", radio->registers[RDSCTRL]);
1401 retval = tavarua_write_register(radio, RDSCTRL,
1402 radio->registers[RDSCTRL]);
1403 if (retval < 0)
1404 return retval;
1405
1406 FMDBG("RDCTRL: %x\n", radio->registers[RDCTRL]);
1407 retval = tavarua_write_register(radio, RDCTRL,
1408 radio->registers[RDCTRL]);
1409 if (retval < 0) {
1410 FMDERR("Could not set region in rdctrl\n");
1411 return retval;
1412 }
1413
1414 /* setting soft band */
1415 switch (region) {
1416 case TAVARUA_REGION_US:
1417 case TAVARUA_REGION_EU:
1418 radio->region_params.band_low = 87.5 * FREQ_MUL;
1419 radio->region_params.band_high = 108 * FREQ_MUL;
1420 break;
1421 case TAVARUA_REGION_JAPAN:
1422 radio->region_params.band_low = 76 * FREQ_MUL;
1423 radio->region_params.band_high = 90 * FREQ_MUL;
1424 break;
1425 case TAVARUA_REGION_JAPAN_WIDE:
1426 radio->region_params.band_low = 90 * FREQ_MUL;
1427 radio->region_params.band_high = 108 * FREQ_MUL;
1428 break;
1429 default:
1430 break;
1431 }
1432 radio->region_params.region = region;
1433 return retval;
1434}
1435
1436/*=============================================================================
1437FUNCTION: tavarua_get_freq
1438=============================================================================*/
1439/**
1440 This interface gets the current frequency.
1441
1442 @param radio: structure pointer passed by client.
1443 @param freq: struct v4l2_frequency. This will be set to the resultant
1444 frequency in units of 62.5 kHz on success.
1445
1446 NOTE:
1447 To get the current tuner or modulator radio frequency applications set the
1448 tuner field of a struct v4l2_frequency to the respective tuner or modulator
1449 number (only input devices have tuners, only output devices have modulators),
1450 zero out the reserved array and call the VIDIOC_G_FREQUENCY ioctl with a
1451 pointer to this structure. The driver stores the current frequency in the
1452 frequency field.
1453
1454 Tuning frequency is in units of 62.5 kHz, or if the struct v4l2_tuner or
1455 struct v4l2_modulator capabilities flag V4L2_TUNER_CAP_LOW is set, in
1456 units of 62.5 Hz.
1457
1458 @return => 0 if successful.
1459 @return < 0 if failure.
1460*/
1461static int tavarua_get_freq(struct tavarua_device *radio,
1462 struct v4l2_frequency *freq)
1463{
1464 int retval;
1465 unsigned short chan;
1466 unsigned int band_bottom;
1467 unsigned int spacing;
1468 band_bottom = radio->region_params.band_low;
1469 spacing = 0.100 * FREQ_MUL;
1470 /* read channel */
1471 retval = tavarua_read_registers(radio, FREQ, 2);
1472 chan = radio->registers[FREQ];
1473
1474 /* Frequency (MHz) = 100 (kHz) x Channel + Bottom of Band (MHz) */
1475 freq->frequency = spacing * chan + band_bottom;
1476 if (radio->registers[TUNECTRL] & ADD_OFFSET)
1477 freq->frequency += 800;
1478 return retval;
1479}
1480
1481/*=============================================================================
1482FUNCTION: tavarua_set_freq
1483=============================================================================*/
1484/**
1485 This interface sets the current frequency.
1486
1487 @param radio: structure pointer passed by client.
1488 @param freq: desired frequency sent by the client in 62.5 kHz units.
1489
1490 NOTE:
1491 To change the current tuner or modulator radio frequency, applications
1492 initialize the tuner, type and frequency fields, and the reserved array of a
1493 struct v4l2_frequency and call the VIDIOC_S_FREQUENCY ioctl with a pointer to
1494 this structure. When the requested frequency is not possible the driver
1495 assumes the closest possible value. However VIDIOC_S_FREQUENCY is a
1496 write-only ioctl, it does not return the actual new frequency.
1497
1498 Tuning frequency is in units of 62.5 kHz, or if the struct v4l2_tuner
1499 or struct v4l2_modulator capabilities flag V4L2_TUNER_CAP_LOW is set,
1500 in units of 62.5 Hz.
1501
1502 @return => 0 if successful.
1503 @return < 0 if failure.
1504*/
1505static int tavarua_set_freq(struct tavarua_device *radio, unsigned int freq)
1506{
1507
1508 unsigned int band_bottom;
1509 unsigned char chan;
1510 unsigned char cmd[] = {0x00, 0x00};
1511 unsigned int spacing;
1512 int retval;
1513 band_bottom = radio->region_params.band_low;
1514 spacing = 0.100 * FREQ_MUL;
1515 if ((freq % 1600) == 800) {
1516 cmd[1] = ADD_OFFSET;
1517 freq -= 800;
1518 }
1519 /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / 100 (kHz) */
1520 chan = (freq - band_bottom) / spacing;
1521
1522 cmd[0] = chan;
1523 cmd[1] |= TUNE_STATION;
1524 radio->tune_req = 1;
1525 retval = tavarua_write_registers(radio, FREQ, cmd, 2);
1526 if (retval < 0)
1527 radio->tune_req = 0;
1528 return retval;
1529
1530}
1531
1532/**************************************************************************
1533 * File Operations Interface
1534 *************************************************************************/
1535
1536/*=============================================================================
1537FUNCTION: tavarua_fops_read
1538=============================================================================*/
1539/**
1540 This function is called when a process, which already opened the dev file,
1541 attempts to read from it.
1542
1543 In case of tavarua driver, it is called to read RDS data.
1544
1545 @param file: file descriptor.
1546 @param buf: The buffer to fill with data.
1547 @param count: The length of the buffer in bytes.
1548 @param ppos: Our offset in the file.
1549
1550 @return The number of bytes put into the buffer on sucess.
1551 -EFAULT if there is no access to user buffer
1552*/
1553static ssize_t tavarua_fops_read(struct file *file, char __user *buf,
1554 size_t count, loff_t *ppos)
1555{
1556 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1557 struct kfifo *rds_buf = &radio->data_buf[TAVARUA_BUF_RAW_RDS];
1558
1559 /* block if no new data available */
1560 while (!kfifo_len(rds_buf)) {
1561 if (file->f_flags & O_NONBLOCK)
1562 return -EWOULDBLOCK;
1563 if (wait_event_interruptible(radio->read_queue,
1564 kfifo_len(rds_buf)) < 0)
1565 return -EINTR;
1566 }
1567
1568 /* calculate block count from byte count */
1569 count /= BYTES_PER_BLOCK;
1570
1571
1572 /* check if we can write to the user buffer */
1573 if (!access_ok(VERIFY_WRITE, buf, count*BYTES_PER_BLOCK))
1574 return -EFAULT;
1575
1576 /* copy RDS block out of internal buffer and to user buffer */
1577 return kfifo_out_locked(rds_buf, buf, count*BYTES_PER_BLOCK,
1578 &radio->buf_lock[TAVARUA_BUF_RAW_RDS]);
1579}
1580
1581/*=============================================================================
1582FUNCTION: tavarua_fops_write
1583=============================================================================*/
1584/**
1585 This function is called when a process, which already opened the dev file,
1586 attempts to write to it.
1587
1588 In case of tavarua driver, it is called to write RDS data to host.
1589
1590 @param file: file descriptor.
1591 @param buf: The buffer which has data to write.
1592 @param count: The length of the buffer.
1593 @param ppos: Our offset in the file.
1594
1595 @return The number of bytes written from the buffer.
1596*/
1597static ssize_t tavarua_fops_write(struct file *file, const char __user *data,
1598 size_t count, loff_t *ppos)
1599{
1600 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1601 int retval = 0;
1602 int bytes_to_copy;
1603 int bytes_copied = 0;
1604 int bytes_left;
1605 int chunk_index = 0;
1606 unsigned char tx_data[XFR_REG_NUM];
1607 /* Disable TX of this type first */
1608 switch (radio->tx_mode) {
1609 case TAVARUA_TX_RT:
1610 bytes_left = min((int)count, MAX_RT_LENGTH);
1611 tx_data[1] = 0;
1612 break;
1613 case TAVARUA_TX_PS:
1614 bytes_left = min((int)count, MAX_PS_LENGTH);
1615 tx_data[4] = 0;
1616 break;
1617 default:
1618 FMDERR("%s: Unknown TX mode\n", __func__);
1619 return -1;
1620 }
1621 retval = sync_write_xfr(radio, radio->tx_mode, tx_data);
1622 if (retval < 0)
1623 return retval;
1624
1625 /* send payload to FM hardware */
1626 while (bytes_left) {
1627 chunk_index++;
1628 bytes_to_copy = min(bytes_left, XFR_REG_NUM);
1629 if (copy_from_user(tx_data, data + bytes_copied, bytes_to_copy))
1630 return -EFAULT;
1631 retval = sync_write_xfr(radio, radio->tx_mode +
1632 chunk_index, tx_data);
1633 if (retval < 0)
1634 return retval;
1635
1636 bytes_copied += bytes_to_copy;
1637 bytes_left -= bytes_to_copy;
1638 }
1639
1640 /* send the header */
1641 switch (radio->tx_mode) {
1642 case TAVARUA_TX_RT:
1643 FMDBG("Writing RT header\n");
1644 tx_data[0] = bytes_copied;
1645 tx_data[1] = TX_ON | 0x03; /* on | PTY */
1646 tx_data[2] = 0x12; /* PI high */
1647 tx_data[3] = 0x34; /* PI low */
1648 break;
1649 case TAVARUA_TX_PS:
1650 FMDBG("Writing PS header\n");
1651 tx_data[0] = chunk_index;
1652 tx_data[1] = 0x03; /* PTY */
1653 tx_data[2] = 0x12; /* PI high */
1654 tx_data[3] = 0x34; /* PI low */
1655 tx_data[4] = TX_ON | 0x01;
1656 break;
1657 default:
1658 FMDERR("%s: Unknown TX mode\n", __func__);
1659 return -1;
1660 }
1661 retval = sync_write_xfr(radio, radio->tx_mode, tx_data);
1662 if (retval < 0)
1663 return retval;
1664 FMDBG("done writing: %d\n", retval);
1665 return bytes_copied;
1666}
1667
1668/*=============================================================================
1669FUNCTION: tavarua_fops_open
1670=============================================================================*/
1671/**
1672 This function is called when a process tries to open the device file, like
1673 "cat /dev/mycharfile"
1674
1675 @param file: file descriptor.
1676
1677 @return => 0 if successful.
1678 @return < 0 if failure.
1679*/
1680static int tavarua_fops_open(struct file *file)
1681{
1682 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1683 int retval = -ENODEV;
1684 unsigned char value;
1685 /* FM core bring up */
1686 int i = 0;
1687 char fm_ctl0_part1[] = { 0xCA, 0xCE, 0xD6 };
1688 char fm_ctl1[] = { 0x03 };
1689 char fm_ctl0_part2[] = { 0xB6, 0xB7 };
1690 char buffer[] = {0x00, 0x48, 0x8A, 0x8E, 0x97, 0xB7};
1691 int bahama_present = -ENODEV;
1692
1693 mutex_lock(&radio->lock);
1694 if (radio->users) {
1695 mutex_unlock(&radio->lock);
1696 return -EBUSY;
1697 } else {
1698 radio->users++;
1699 }
1700 mutex_unlock(&radio->lock);
1701
1702 /* initial gpio pin config & Power up */
1703 retval = radio->pdata->fm_setup(radio->pdata);
1704 if (retval) {
1705 printk(KERN_ERR "%s: failed config gpio & pmic\n", __func__);
1706 goto open_err_setup;
1707 }
1708 if (radio->pdata->config_i2s_gpio != NULL) {
1709 retval = radio->pdata->config_i2s_gpio(FM_I2S_ON);
1710 if (retval) {
1711 printk(KERN_ERR "%s: failed config gpio\n", __func__);
1712 goto config_i2s_err;
1713 }
1714 }
1715 /* enable irq */
1716 retval = tavarua_request_irq(radio);
1717 if (retval < 0) {
1718 printk(KERN_ERR "%s: failed to request irq\n", __func__);
1719 goto open_err_req_irq;
1720 }
1721 /* call top level marimba interface here to enable FM core */
1722 FMDBG("initializing SoC\n");
1723
1724 bahama_present = is_bahama();
1725
1726 if (bahama_present == -ENODEV)
1727 return -ENODEV;
1728
1729 if (bahama_present)
1730 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1731 else
1732 radio->marimba->mod_id = MARIMBA_SLAVE_ID_MARIMBA;
1733
1734 value = FM_ENABLE;
1735 retval = marimba_write_bit_mask(radio->marimba,
1736 MARIMBA_XO_BUFF_CNTRL, &value, 1, value);
1737 if (retval < 0) {
1738 printk(KERN_ERR "%s:XO_BUFF_CNTRL write failed\n",
1739 __func__);
1740 goto open_err_all;
1741 }
1742
1743
1744 /* Bring up FM core */
1745 if (bahama_present) {
1746
1747 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1748 /* Read the Bahama version*/
1749 retval = marimba_read_bit_mask(radio->marimba,
1750 0x00, &bahama_version, 1, 0x1F);
1751 if (retval < 0) {
1752 printk(KERN_ERR "%s: version read failed",
1753 __func__);
1754 goto open_err_all;
1755 }
Rahul Kashyapc88b6e32011-07-07 10:52:16 +05301756
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001757 /* Check for Bahama V2 variant*/
1758 if (bahama_version == 0x09) {
1759
1760 /* In case of Bahama v2, forcefully enable the
1761 * internal analog and digital voltage controllers
1762 */
1763 value = 0x06;
1764 /* value itself used as mask in these writes*/
1765 retval = marimba_write_bit_mask(radio->marimba,
1766 BAHAMA_LDO_DREG_CTL0, &value, 1, value);
1767 if (retval < 0) {
1768 printk(KERN_ERR "%s:0xF0 write failed\n",
1769 __func__);
1770 goto open_err_all;
1771 }
1772 value = 0x86;
1773 retval = marimba_write_bit_mask(radio->marimba,
1774 BAHAMA_LDO_AREG_CTL0, &value, 1, value);
1775 if (retval < 0) {
1776 printk(KERN_ERR "%s:0xF4 write failed\n",
1777 __func__);
1778 goto open_err_all;
1779 }
1780 }
1781
1782 /*write FM mode*/
1783 retval = tavarua_write_register(radio, BAHAMA_FM_MODE_REG,
1784 BAHAMA_FM_MODE_NORMAL);
1785 if (retval < 0) {
1786 printk(KERN_ERR "failed to set the FM mode: %d\n",
1787 retval);
1788 goto open_err_all;
1789 }
1790 /*Write first sequence of bytes to FM_CTL0*/
1791 for (i = 0; i < 3; i++) {
1792 retval = tavarua_write_register(radio,
1793 BAHAMA_FM_CTL0_REG, fm_ctl0_part1[i]);
1794 if (retval < 0) {
1795 printk(KERN_ERR "FM_CTL0:set-1 failure: %d\n",
1796 retval);
1797 goto open_err_all;
1798 }
1799 }
1800 /*Write the FM_CTL1 sequence*/
1801 for (i = 0; i < 1; i++) {
1802 retval = tavarua_write_register(radio,
1803 BAHAMA_FM_CTL1_REG, fm_ctl1[i]);
1804 if (retval < 0) {
1805 printk(KERN_ERR "FM_CTL1 write failure: %d\n",
1806 retval);
1807 goto open_err_all;
1808 }
1809 }
1810 /*Write second sequence of bytes to FM_CTL0*/
1811 for (i = 0; i < 2; i++) {
1812 retval = tavarua_write_register(radio,
1813 BAHAMA_FM_CTL0_REG, fm_ctl0_part2[i]);
1814 if (retval < 0) {
1815 printk(KERN_ERR "FM_CTL0:set-2 failure: %d\n",
1816 retval);
1817 goto open_err_all;
1818 }
1819 }
1820 } else {
1821 retval = tavarua_write_registers(radio, LEAKAGE_CNTRL,
1822 buffer, 6);
1823 if (retval < 0) {
1824 printk(KERN_ERR "%s: failed to bring up FM Core\n",
1825 __func__);
1826 goto open_err_all;
1827 }
1828 }
1829 /* Wait for interrupt i.e. complete(&radio->sync_req_done); call */
1830 /*Initialize the completion variable for
1831 for the proper behavior*/
1832 init_completion(&radio->sync_req_done);
1833 if (!wait_for_completion_timeout(&radio->sync_req_done,
1834 msecs_to_jiffies(wait_timeout))) {
1835 retval = -1;
1836 FMDERR("Timeout waiting for initialization\n");
1837 }
1838
1839 /* get Chip ID */
1840 retval = tavarua_write_register(radio, XFRCTRL, CHIPID);
1841 if (retval < 0)
1842 goto open_err_all;
1843 msleep(TAVARUA_DELAY);
1844 tavarua_read_registers(radio, XFRCTRL, XFR_REG_NUM+1);
1845 if (radio->registers[XFRCTRL] != CHIPID)
1846 goto open_err_all;
1847
1848 radio->chipID = (radio->registers[XFRCTRL+2] << 24) |
1849 (radio->registers[XFRCTRL+5] << 16) |
1850 (radio->registers[XFRCTRL+6] << 8) |
1851 (radio->registers[XFRCTRL+7]);
1852
1853 printk(KERN_WARNING DRIVER_NAME ": Chip ID %x\n", radio->chipID);
1854 if (radio->chipID == MARIMBA_A0) {
1855 printk(KERN_WARNING DRIVER_NAME ": Unsupported hardware: %x\n",
1856 radio->chipID);
1857 retval = -1;
1858 goto open_err_all;
1859 }
1860
1861 radio->handle_irq = 0;
1862 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1863 marimba_set_fm_status(radio->marimba, true);
1864 return 0;
1865
1866
1867open_err_all:
1868 /*Disable FM in case of error*/
1869 value = 0x00;
1870 marimba_write_bit_mask(radio->marimba, MARIMBA_XO_BUFF_CNTRL,
1871 &value, 1, value);
1872 tavarua_disable_irq(radio);
1873open_err_req_irq:
1874 if (radio->pdata->config_i2s_gpio != NULL)
1875 radio->pdata->config_i2s_gpio(FM_I2S_OFF);
1876config_i2s_err:
1877 radio->pdata->fm_shutdown(radio->pdata);
1878open_err_setup:
1879 radio->handle_irq = 1;
1880 radio->users = 0;
1881 return retval;
1882}
1883
1884/*=============================================================================
1885FUNCTION: tavarua_fops_release
1886=============================================================================*/
1887/**
1888 This function is called when a process closes the device file.
1889
1890 @param file: file descriptor.
1891
1892 @return => 0 if successful.
1893 @return < 0 if failure.
1894*/
1895static int tavarua_fops_release(struct file *file)
1896{
1897 int retval;
1898 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
1899 unsigned char value;
1900 int i = 0;
1901 /*FM Core shutdown sequence for Bahama*/
1902 char fm_ctl0_part1[] = { 0xB7 };
1903 char fm_ctl1[] = { 0x03 };
1904 char fm_ctl0_part2[] = { 0x9F, 0x48, 0x02 };
1905 int bahama_present = -ENODEV;
1906 /*FM Core shutdown sequence for Marimba*/
1907 char buffer[] = {0x18, 0xB7, 0x48};
1908 bool bt_status = false;
1909 int index;
1910 /* internal regulator controllers DREG_CTL0, AREG_CTL0
1911 * has to be kept in the valid state based on the bt status.
1912 * 1st row is the state when no clients are active,
1913 * and the second when bt is in on state.
1914 */
1915 char internal_vreg_ctl[2][2] = {
1916 { 0x04, 0x84 },
1917 { 0x00, 0x80 }
1918 };
1919
1920 if (!radio)
1921 return -ENODEV;
1922 FMDBG("In %s", __func__);
1923
1924 /* disable radio ctrl */
1925 retval = tavarua_write_register(radio, RDCTRL, 0x00);
1926
1927 FMDBG("%s, Disable IRQs\n", __func__);
1928 /* disable irq */
1929 retval = tavarua_disable_irq(radio);
1930 if (retval < 0) {
1931 printk(KERN_ERR "%s: failed to disable irq\n", __func__);
1932 return retval;
1933 }
1934
1935 bahama_present = is_bahama();
1936
1937 if (bahama_present == -ENODEV)
1938 return -ENODEV;
1939
1940 if (bahama_present) {
1941 /*Write first sequence of bytes to FM_CTL0*/
1942 for (i = 0; i < 1; i++) {
1943 retval = tavarua_write_register(radio,
1944 BAHAMA_FM_CTL0_REG, fm_ctl0_part1[i]);
1945 if (retval < 0) {
1946 printk(KERN_ERR "FM_CTL0:Set-1 failure: %d\n",
1947 retval);
1948 break;
1949 }
1950 }
1951 /*Write the FM_CTL1 sequence*/
1952 for (i = 0; i < 1; i++) {
1953 retval = tavarua_write_register(radio,
1954 BAHAMA_FM_CTL1_REG, fm_ctl1[i]);
1955 if (retval < 0) {
1956 printk(KERN_ERR "FM_CTL1 failure: %d\n",
1957 retval);
1958 break;
1959 }
1960 }
1961 /*Write second sequence of bytes to FM_CTL0*/
1962 for (i = 0; i < 3; i++) {
1963 retval = tavarua_write_register(radio,
1964 BAHAMA_FM_CTL0_REG, fm_ctl0_part2[i]);
1965 if (retval < 0) {
1966 printk(KERN_ERR "FM_CTL0:Set-2 failure: %d\n",
1967 retval);
1968 break;
1969 }
1970 }
1971 } else {
1972
1973 retval = tavarua_write_registers(radio, FM_CTL0,
1974 buffer, sizeof(buffer)/sizeof(buffer[0]));
1975 if (retval < 0) {
1976 printk(KERN_ERR "%s: failed to bring down the FM Core\n",
1977 __func__);
1978 return retval;
1979 }
1980 }
1981 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1982 bt_status = marimba_get_bt_status(radio->marimba);
1983 /* Set the index based on the bt status*/
1984 index = bt_status ? 1 : 0;
1985 /* Check for Bahama's existance and Bahama V2 variant*/
1986 if (bahama_present && (bahama_version == 0x09)) {
1987 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
1988 /* actual value itself used as mask*/
1989 retval = marimba_write_bit_mask(radio->marimba,
1990 BAHAMA_LDO_DREG_CTL0, &internal_vreg_ctl[bt_status][0],
1991 1, internal_vreg_ctl[index][0]);
1992 if (retval < 0) {
1993 printk(KERN_ERR "%s:0xF0 write failed\n", __func__);
1994 return retval;
1995 }
1996 /* actual value itself used as mask*/
1997 retval = marimba_write_bit_mask(radio->marimba,
1998 BAHAMA_LDO_AREG_CTL0, &internal_vreg_ctl[bt_status][1],
1999 1, internal_vreg_ctl[index][1]);
2000 if (retval < 0) {
2001 printk(KERN_ERR "%s:0xF4 write failed\n", __func__);
2002 return retval;
2003 }
2004 } else {
2005 /* disable fm core */
2006 radio->marimba->mod_id = MARIMBA_SLAVE_ID_MARIMBA;
2007 }
2008
2009 value = 0x00;
2010 retval = marimba_write_bit_mask(radio->marimba, MARIMBA_XO_BUFF_CNTRL,
2011 &value, 1, FM_ENABLE);
2012 if (retval < 0) {
2013 printk(KERN_ERR "%s:XO_BUFF_CNTRL write failed\n", __func__);
2014 return retval;
2015 }
2016 FMDBG("%s, Calling fm_shutdown\n", __func__);
2017 /* teardown gpio and pmic */
Rahul Kashyapc88b6e32011-07-07 10:52:16 +05302018
2019 marimba_set_fm_status(radio->marimba, false);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002020 radio->pdata->fm_shutdown(radio->pdata);
2021 if (radio->pdata->config_i2s_gpio != NULL)
2022 radio->pdata->config_i2s_gpio(FM_I2S_OFF);
2023 radio->handle_irq = 1;
2024 radio->users = 0;
2025 radio->marimba->mod_id = SLAVE_ID_BAHAMA;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002026 return 0;
2027}
2028
2029/*
2030 * tavarua_fops - file operations interface
2031 */
2032static const struct v4l2_file_operations tavarua_fops = {
2033 .owner = THIS_MODULE,
2034 .read = tavarua_fops_read,
2035 .write = tavarua_fops_write,
2036 .ioctl = video_ioctl2,
2037 .open = tavarua_fops_open,
2038 .release = tavarua_fops_release,
2039};
2040
2041/*************************************************************************
2042 * Video4Linux Interface
2043 *************************************************************************/
2044
2045/*
2046 * tavarua_v4l2_queryctrl - query control
2047 */
2048static struct v4l2_queryctrl tavarua_v4l2_queryctrl[] = {
2049 {
2050 .id = V4L2_CID_AUDIO_VOLUME,
2051 .type = V4L2_CTRL_TYPE_INTEGER,
2052 .name = "Volume",
2053 .minimum = 0,
2054 .maximum = 15,
2055 .step = 1,
2056 .default_value = 15,
2057 },
2058 {
2059 .id = V4L2_CID_AUDIO_BALANCE,
2060 .flags = V4L2_CTRL_FLAG_DISABLED,
2061 },
2062 {
2063 .id = V4L2_CID_AUDIO_BASS,
2064 .flags = V4L2_CTRL_FLAG_DISABLED,
2065 },
2066 {
2067 .id = V4L2_CID_AUDIO_TREBLE,
2068 .flags = V4L2_CTRL_FLAG_DISABLED,
2069 },
2070 {
2071 .id = V4L2_CID_AUDIO_MUTE,
2072 .type = V4L2_CTRL_TYPE_BOOLEAN,
2073 .name = "Mute",
2074 .minimum = 0,
2075 .maximum = 1,
2076 .step = 1,
2077 .default_value = 1,
2078 },
2079 {
2080 .id = V4L2_CID_AUDIO_LOUDNESS,
2081 .flags = V4L2_CTRL_FLAG_DISABLED,
2082 },
2083 {
2084 .id = V4L2_CID_PRIVATE_TAVARUA_SRCHMODE,
2085 .type = V4L2_CTRL_TYPE_INTEGER,
2086 .name = "Search mode",
2087 .minimum = 0,
2088 .maximum = 7,
2089 .step = 1,
2090 .default_value = 0,
2091 },
2092 {
2093 .id = V4L2_CID_PRIVATE_TAVARUA_SCANDWELL,
2094 .type = V4L2_CTRL_TYPE_INTEGER,
2095 .name = "Search dwell time",
2096 .minimum = 0,
2097 .maximum = 7,
2098 .step = 1,
2099 .default_value = 0,
2100 },
2101 {
2102 .id = V4L2_CID_PRIVATE_TAVARUA_SRCHON,
2103 .type = V4L2_CTRL_TYPE_BOOLEAN,
2104 .name = "Search on/off",
2105 .minimum = 0,
2106 .maximum = 1,
2107 .step = 1,
2108 .default_value = 1,
2109
2110 },
2111 {
2112 .id = V4L2_CID_PRIVATE_TAVARUA_STATE,
2113 .type = V4L2_CTRL_TYPE_INTEGER,
2114 .name = "radio 0ff/rx/tx/reset",
2115 .minimum = 0,
2116 .maximum = 3,
2117 .step = 1,
2118 .default_value = 1,
2119
2120 },
2121 {
2122 .id = V4L2_CID_PRIVATE_TAVARUA_REGION,
2123 .type = V4L2_CTRL_TYPE_INTEGER,
2124 .name = "radio standard",
2125 .minimum = 0,
2126 .maximum = 2,
2127 .step = 1,
2128 .default_value = 0,
2129 },
2130 {
2131 .id = V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH,
2132 .type = V4L2_CTRL_TYPE_INTEGER,
2133 .name = "Signal Threshold",
2134 .minimum = 0x80,
2135 .maximum = 0x7F,
2136 .step = 1,
2137 .default_value = 0,
2138 },
2139 {
2140 .id = V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY,
2141 .type = V4L2_CTRL_TYPE_INTEGER,
2142 .name = "Search PTY",
2143 .minimum = 0,
2144 .maximum = 31,
2145 .default_value = 0,
2146 },
2147 {
2148 .id = V4L2_CID_PRIVATE_TAVARUA_SRCH_PI,
2149 .type = V4L2_CTRL_TYPE_INTEGER,
2150 .name = "Search PI",
2151 .minimum = 0,
2152 .maximum = 0xFF,
2153 .default_value = 0,
2154 },
2155 {
2156 .id = V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT,
2157 .type = V4L2_CTRL_TYPE_INTEGER,
2158 .name = "Preset num",
2159 .minimum = 0,
2160 .maximum = 12,
2161 .default_value = 0,
2162 },
2163 {
2164 .id = V4L2_CID_PRIVATE_TAVARUA_EMPHASIS,
2165 .type = V4L2_CTRL_TYPE_BOOLEAN,
2166 .name = "Emphasis",
2167 .minimum = 0,
2168 .maximum = 1,
2169 .default_value = 0,
2170 },
2171 {
2172 .id = V4L2_CID_PRIVATE_TAVARUA_RDS_STD,
2173 .type = V4L2_CTRL_TYPE_BOOLEAN,
2174 .name = "RDS standard",
2175 .minimum = 0,
2176 .maximum = 1,
2177 .default_value = 0,
2178 },
2179 {
2180 .id = V4L2_CID_PRIVATE_TAVARUA_SPACING,
2181 .type = V4L2_CTRL_TYPE_INTEGER,
2182 .name = "Channel spacing",
2183 .minimum = 0,
2184 .maximum = 2,
2185 .default_value = 0,
2186 },
2187 {
2188 .id = V4L2_CID_PRIVATE_TAVARUA_RDSON,
2189 .type = V4L2_CTRL_TYPE_BOOLEAN,
2190 .name = "RDS on/off",
2191 .minimum = 0,
2192 .maximum = 1,
2193 .default_value = 0,
2194 },
2195 {
2196 .id = V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK,
2197 .type = V4L2_CTRL_TYPE_INTEGER,
2198 .name = "RDS group mask",
2199 .minimum = 0,
2200 .maximum = 0xFFFFFFFF,
2201 .default_value = 0,
2202 },
2203 {
2204 .id = V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC,
2205 .type = V4L2_CTRL_TYPE_INTEGER,
2206 .name = "RDS processing",
2207 .minimum = 0,
2208 .maximum = 0xFF,
2209 .default_value = 0,
2210 },
2211 {
2212 .id = V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF,
2213 .type = V4L2_CTRL_TYPE_INTEGER,
2214 .name = "RDS data groups to buffer",
2215 .minimum = 1,
2216 .maximum = 21,
2217 .default_value = 0,
2218 },
2219 {
2220 .id = V4L2_CID_PRIVATE_TAVARUA_PSALL,
2221 .type = V4L2_CTRL_TYPE_BOOLEAN,
2222 .name = "pass all ps strings",
2223 .minimum = 0,
2224 .maximum = 1,
2225 .default_value = 0,
2226 },
2227 {
2228 .id = V4L2_CID_PRIVATE_TAVARUA_LP_MODE,
2229 .type = V4L2_CTRL_TYPE_BOOLEAN,
2230 .name = "Low power mode",
2231 .minimum = 0,
2232 .maximum = 1,
2233 .default_value = 0,
2234 },
2235 {
2236 .id = V4L2_CID_PRIVATE_TAVARUA_ANTENNA,
2237 .type = V4L2_CTRL_TYPE_BOOLEAN,
2238 .name = "headset/internal",
2239 .minimum = 0,
2240 .maximum = 1,
2241 .default_value = 0,
2242 },
2243 /* Private controls for FM TX*/
2244 {
2245 .id = V4L2_CID_PRIVATE_TAVARUA_TX_SETPSREPEATCOUNT,
2246 .type = V4L2_CTRL_TYPE_INTEGER,
2247 .name = "Set PS REPEATCOUNT",
2248 .minimum = 0,
2249 .maximum = 15,
2250 },
2251 {
2252 .id = V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_PS_NAME,
2253 .type = V4L2_CTRL_TYPE_BOOLEAN,
2254 .name = "Stop PS NAME",
2255 .minimum = 0,
2256 .maximum = 1,
2257 },
2258 {
2259 .id = V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_RT,
2260 .type = V4L2_CTRL_TYPE_BOOLEAN,
2261 .name = "Stop RT",
2262 .minimum = 0,
2263 .maximum = 1,
2264 },
2265
2266};
2267
2268/*=============================================================================
2269FUNCTION: tavarua_vidioc_querycap
2270=============================================================================*/
2271/**
2272 This function is called to query device capabilities.
2273
2274 NOTE:
2275 All V4L2 devices support the VIDIOC_QUERYCAP ioctl. It is used to identify
2276 kernel devices compatible with this specification and to obtain information
2277 about driver and hardware capabilities. The ioctl takes a pointer to a struct
2278 v4l2_capability which is filled by the driver. When the driver is not
2279 compatible with this specification the ioctl returns an EINVAL error code.
2280
2281 @param file: File descriptor returned by open().
2282 @param capability: pointer to struct v4l2_capability.
2283
2284 @return On success 0 is returned, else error code.
2285 @return EINVAL: The device is not compatible with this specification.
2286*/
2287static int tavarua_vidioc_querycap(struct file *file, void *priv,
2288 struct v4l2_capability *capability)
2289{
2290 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2291
2292 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
2293 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
2294 sprintf(capability->bus_info, "I2C");
2295 capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
2296
2297 capability->version = radio->chipID;
2298
2299 return 0;
2300}
2301
2302/*=============================================================================
2303FUNCTION: tavarua_vidioc_queryctrl
2304=============================================================================*/
2305/**
2306 This function is called to query the device and driver for supported video
2307 controls (enumerate control items).
2308
2309 NOTE:
2310 To query the attributes of a control, the applications set the id field of
2311 a struct v4l2_queryctrl and call the VIDIOC_QUERYCTRL ioctl with a pointer
2312 to this structure. The driver fills the rest of the structure or returns an
2313 EINVAL error code when the id is invalid.
2314
2315 @param file: File descriptor returned by open().
2316 @param qc: pointer to struct v4l2_queryctrl.
2317
2318 @return On success 0 is returned, else error code.
2319 @return EINVAL: The struct v4l2_queryctrl id is invalid.
2320*/
2321static int tavarua_vidioc_queryctrl(struct file *file, void *priv,
2322 struct v4l2_queryctrl *qc)
2323{
2324 unsigned char i;
2325 int retval = -EINVAL;
2326
2327 for (i = 0; i < ARRAY_SIZE(tavarua_v4l2_queryctrl); i++) {
2328 if (qc->id && qc->id == tavarua_v4l2_queryctrl[i].id) {
2329 memcpy(qc, &(tavarua_v4l2_queryctrl[i]), sizeof(*qc));
2330 retval = 0;
2331 break;
2332 }
2333 }
2334 if (retval < 0)
2335 printk(KERN_WARNING DRIVER_NAME
2336 ": query conv4ltrol failed with %d\n", retval);
2337
2338 return retval;
2339}
2340static int peek_MPX_DCC(struct tavarua_device *radio)
2341{
2342 int retval = 0;
2343 unsigned char xfr_buf[XFR_REG_NUM];
2344 int MPX_DCC[] = { 0 };
2345 int DCC = 0;
2346 int ct = 0;
2347 unsigned char size = 0;
2348
2349 /*
2350 Poking the MPX_DCC_BYPASS register to freeze the
2351 value of MPX_DCC from changing while we access it
2352 */
2353
2354 /*Poking the MPX_DCC_BYPASS register : 0x88C0 */
2355 size = 0x01;
2356 xfr_buf[0] = (XFR_POKE_MODE | (size << 1));
2357 xfr_buf[1] = MPX_DCC_BYPASS_POKE_MSB;
2358 xfr_buf[2] = MPX_DCC_BYPASS_POKE_LSB;
2359 xfr_buf[3] = 0x01;
2360
2361 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 4);
2362 if (retval < 0) {
2363 FMDBG("Failed to write\n");
2364 return retval;
2365 }
2366 /*Wait for the XFR interrupt */
2367 msleep(TAVARUA_DELAY*15);
2368
2369 for (ct = 0; ct < 5; ct++)
2370 xfr_buf[ct] = 0;
2371
2372 /* Peeking Regs 0x88C2-0x88C4 */
2373 size = 0x03;
2374 xfr_buf[0] = (XFR_PEEK_MODE | (size << 1));
2375 xfr_buf[1] = MPX_DCC_PEEK_MSB_REG1;
2376 xfr_buf[2] = MPX_DCC_PEEK_LSB_REG1;
2377 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 3);
2378 if (retval < 0) {
2379 FMDBG("Failed to write\n");
2380 return retval;
2381 }
2382 /*Wait for the XFR interrupt */
2383 msleep(TAVARUA_DELAY*10);
2384 retval = tavarua_read_registers(radio, XFRDAT0, 3);
2385 if (retval < 0) {
2386 printk(KERN_INFO "INT_DET: Read failure\n");
2387 return retval;
2388 }
2389 MPX_DCC[0] = (int)radio->registers[XFRDAT0];
2390 MPX_DCC[1] = (int)radio->registers[XFRDAT1];
2391 MPX_DCC[2] = (int)radio->registers[XFRDAT2];
2392
2393 /*
2394 Form the final MPX_DCC parameter
2395 MPX_DCC[0] will form the LSB part
2396 MPX_DCC[1] will be the middle part and 4 bits of
2397 MPX_DCC[2] will be the MSB par of the 20-bit signed MPX_DCC
2398 */
2399
2400 DCC = ((int)MPX_DCC[2] << 16) | ((int)MPX_DCC[1] << 8) |
2401 ((int)MPX_DCC[0]);
2402
2403 /*
2404 if bit-19 is '1',set remaining bits to '1' & make it -tive
2405 */
2406 if (DCC & 0x00080000) {
2407 FMDBG(KERN_INFO "bit-19 is '1'\n");
2408 DCC |= 0xFFF00000;
2409 }
2410
2411 /*
2412 Poking the MPX_DCC_BYPASS register to be back to normal
2413 */
2414
2415 /*Poking the MPX_DCC_BYPASS register : 0x88C0 */
2416 size = 0x01;
2417 xfr_buf[0] = (XFR_POKE_MODE | (size << 1));
2418 xfr_buf[1] = MPX_DCC_BYPASS_POKE_MSB;
2419 xfr_buf[2] = MPX_DCC_BYPASS_POKE_LSB;
2420 xfr_buf[3] = 0x00;
2421
2422 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 4);
2423 if (retval < 0) {
2424 FMDBG("Failed to write\n");
2425 return retval;
2426 }
2427 /*Wait for the XFR interrupt */
2428 msleep(TAVARUA_DELAY*10);
2429
2430 return DCC;
2431}
2432/*=============================================================================
2433FUNCTION: tavarua_vidioc_g_ctrl
2434=============================================================================*/
2435/**
2436 This function is called to get the value of a control.
2437
2438 NOTE:
2439 To get the current value of a control, applications initialize the id field
2440 of a struct v4l2_control and call the VIDIOC_G_CTRL ioctl with a pointer to
2441 this structure.
2442
2443 When the id is invalid drivers return an EINVAL error code. When the value is
2444 out of bounds drivers can choose to take the closest valid value or return an
2445 ERANGE error code, whatever seems more appropriate.
2446
2447 @param file: File descriptor returned by open().
2448 @param ctrl: pointer to struct v4l2_control.
2449
2450 @return On success 0 is returned, else error code.
2451 @return EINVAL: The struct v4l2_control id is invalid.
2452 @return ERANGE: The struct v4l2_control value is out of bounds.
2453 @return EBUSY: The control is temporarily not changeable, possibly because
2454 another applications took over control of the device function this control
2455 belongs to.
2456*/
2457static int tavarua_vidioc_g_ctrl(struct file *file, void *priv,
2458 struct v4l2_control *ctrl)
2459{
2460 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2461 int retval = 0;
2462 unsigned char xfr_buf[XFR_REG_NUM];
2463 signed char cRmssiThreshold;
2464 signed char ioc;
2465 unsigned char size = 0;
2466
2467 switch (ctrl->id) {
2468 case V4L2_CID_AUDIO_VOLUME:
2469 break;
2470 case V4L2_CID_AUDIO_MUTE:
2471 ctrl->value = radio->registers[IOCTRL] & 0x03 ;
2472 break;
2473 case V4L2_CID_PRIVATE_TAVARUA_SRCHMODE:
2474 ctrl->value = radio->registers[SRCHCTRL] & SRCH_MODE;
2475 break;
2476 case V4L2_CID_PRIVATE_TAVARUA_SCANDWELL:
2477 ctrl->value = (radio->registers[SRCHCTRL] & SCAN_DWELL) >> 4;
2478 break;
2479 case V4L2_CID_PRIVATE_TAVARUA_SRCHON:
2480 ctrl->value = (radio->registers[SRCHCTRL] & SRCH_ON) >> 7 ;
2481 break;
2482 case V4L2_CID_PRIVATE_TAVARUA_STATE:
2483 ctrl->value = (radio->registers[RDCTRL] & 0x03);
2484 break;
2485 case V4L2_CID_PRIVATE_TAVARUA_IOVERC:
2486 retval = tavarua_read_registers(radio, IOVERC, 1);
2487 if (retval < 0)
2488 return retval;
2489 ioc = radio->registers[IOVERC];
2490 ctrl->value = ioc;
2491 break;
2492 case V4L2_CID_PRIVATE_TAVARUA_INTDET:
2493 size = 0x1;
2494 xfr_buf[0] = (XFR_PEEK_MODE | (size << 1));
2495 xfr_buf[1] = INTDET_PEEK_MSB;
2496 xfr_buf[2] = INTDET_PEEK_LSB;
2497 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 3);
2498 if (retval < 0) {
2499 FMDBG("Failed to write\n");
2500 return retval;
2501 }
2502 FMDBG("INT_DET:Sync write success\n");
2503 /*Wait for the XFR interrupt */
2504 msleep(TAVARUA_DELAY*10);
2505 /* Read the XFRDAT0 register populated by FM SoC */
2506 retval = tavarua_read_registers(radio, XFRDAT0, 3);
2507 if (retval < 0) {
2508 FMDBG("INT_DET: Read failure\n");
2509 return retval;
2510 }
2511 ctrl->value = radio->registers[XFRDAT0];
2512 break;
2513 case V4L2_CID_PRIVATE_TAVARUA_MPX_DCC:
2514 ctrl->value = peek_MPX_DCC(radio);
2515 break;
2516 case V4L2_CID_PRIVATE_TAVARUA_REGION:
2517 ctrl->value = radio->region_params.region;
2518 break;
2519 case V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH:
2520 retval = sync_read_xfr(radio, RX_CONFIG, xfr_buf);
2521 if (retval < 0) {
2522 FMDBG("[G IOCTL=V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH]\n");
2523 FMDBG("sync_read_xfr error: [retval=%d]\n", retval);
2524 break;
2525 }
2526 /* Since RMSSI Threshold is signed value */
2527 cRmssiThreshold = (signed char)xfr_buf[0];
2528 ctrl->value = cRmssiThreshold;
2529 FMDBG("cRmssiThreshold: %d\n", cRmssiThreshold);
2530 break;
2531 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY:
2532 ctrl->value = radio->srch_params.srch_pty;
2533 break;
2534 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PI:
2535 ctrl->value = radio->srch_params.srch_pi;
2536 break;
2537 case V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT:
2538 ctrl->value = radio->srch_params.preset_num;
2539 break;
2540 case V4L2_CID_PRIVATE_TAVARUA_EMPHASIS:
2541 ctrl->value = radio->region_params.emphasis;
2542 break;
2543 case V4L2_CID_PRIVATE_TAVARUA_RDS_STD:
2544 ctrl->value = radio->region_params.rds_std;
2545 break;
2546 case V4L2_CID_PRIVATE_TAVARUA_SPACING:
2547 ctrl->value = radio->region_params.spacing;
2548 break;
2549 case V4L2_CID_PRIVATE_TAVARUA_RDSON:
2550 ctrl->value = radio->registers[RDSCTRL] & RDS_ON;
2551 break;
2552 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK:
2553 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2554 if (retval > -1)
2555 ctrl->value = (xfr_buf[8] << 24) |
2556 (xfr_buf[9] << 16) |
2557 (xfr_buf[10] << 8) |
2558 xfr_buf[11];
2559 break;
2560 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC:
2561 retval = tavarua_read_registers(radio, ADVCTRL, 1);
2562 if (retval > -1)
2563 ctrl->value = radio->registers[ADVCTRL];
Anantha Krishnane46ef6f2011-06-29 23:56:03 +05302564 msleep(TAVARUA_DELAY*5);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002565 break;
2566 case V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF:
2567 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2568 if (retval > -1)
2569 ctrl->value = xfr_buf[1];
2570 break;
2571 case V4L2_CID_PRIVATE_TAVARUA_PSALL:
2572 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2573 if (retval > -1)
2574 ctrl->value = xfr_buf[12] & RDS_CONFIG_PSALL;
2575 break;
2576 case V4L2_CID_PRIVATE_TAVARUA_LP_MODE:
2577 ctrl->value = radio->lp_mode;
2578 break;
2579 case V4L2_CID_PRIVATE_TAVARUA_ANTENNA:
2580 ctrl->value = GET_REG_FIELD(radio->registers[IOCTRL],
2581 IOC_ANTENNA_OFFSET, IOC_ANTENNA_MASK);
2582 break;
2583 default:
2584 retval = -EINVAL;
2585 }
2586 if (retval < 0)
2587 printk(KERN_WARNING DRIVER_NAME
2588 ": get control failed with %d, id: %d\n", retval, ctrl->id);
2589
2590 return retval;
2591}
2592
2593static int tavarua_vidioc_s_ext_ctrls(struct file *file, void *priv,
2594 struct v4l2_ext_controls *ctrl)
2595{
2596 int retval = 0;
2597 int bytes_to_copy;
2598 int bytes_copied = 0;
2599 int bytes_left = 0;
2600 int chunk_index = 0;
2601 char tx_data[XFR_REG_NUM];
2602 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2603 char *data = NULL;
2604 int extra_name_byte = 0;
2605 int name_bytes = 0;
2606
2607 switch ((ctrl->controls[0]).id) {
2608 case V4L2_CID_RDS_TX_PS_NAME: {
2609 FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
2610 /*Pass a sample PS string */
2611
2612 chunk_index = 0;
2613 bytes_copied = 0;
2614 bytes_left = min((int)(ctrl->controls[0]).size,
2615 MAX_PS_LENGTH);
2616 data = (ctrl->controls[0]).string;
2617
2618 /* send payload to FM hardware */
2619 while (bytes_left) {
2620 chunk_index++;
2621 FMDBG("chunk is %d", chunk_index);
2622 bytes_to_copy = min(bytes_left, XFR_REG_NUM);
2623 /*Clear the tx_data */
2624 memset(tx_data, 0, XFR_REG_NUM);
2625 if (copy_from_user(tx_data,
2626 data + bytes_copied, bytes_to_copy))
2627 return -EFAULT;
2628 retval = sync_write_xfr(radio,
2629 RDS_PS_0 + chunk_index, tx_data);
2630 if (retval < 0) {
2631 FMDBG("sync_write_xfr: %d", retval);
2632 return retval;
2633 }
2634 bytes_copied += bytes_to_copy;
2635 bytes_left -= bytes_to_copy;
2636 }
2637 memset(tx_data, 0, XFR_REG_NUM);
2638 /*Write the PS Header*/
2639 FMDBG("Writing PS header\n");
2640 extra_name_byte = (bytes_copied%8) ? 1 : 0;
2641 name_bytes = (bytes_copied/8) + extra_name_byte;
2642 /*8 bytes are grouped as 1 name */
2643 tx_data[0] = (name_bytes) & MASK_TXREPCOUNT;
2644 tx_data[1] = radio->pty & MASK_PTY; /* PTY */
2645 tx_data[2] = ((radio->pi & MASK_PI_MSB) >> 8);
2646 tx_data[3] = radio->pi & MASK_PI_LSB;
2647 /* TX ctrl + repeatCount*/
2648 tx_data[4] = TX_ON |
2649 (radio->ps_repeatcount & MASK_TXREPCOUNT);
2650 retval = sync_write_xfr(radio, RDS_PS_0, tx_data);
2651 if (retval < 0) {
2652 FMDBG("sync_write_xfr returned %d", retval);
2653 return retval;
2654 }
2655 } break;
2656 case V4L2_CID_RDS_TX_RADIO_TEXT: {
2657 chunk_index = 0;
2658 bytes_copied = 0;
2659 FMDBG("In V4L2_CID_RDS_TX_RADIO_TEXT\n");
2660 /*Pass a sample PS string */
2661 FMDBG("Passed RT String : %s\n",
2662 (ctrl->controls[0]).string);
2663 bytes_left =
2664 min((int)(ctrl->controls[0]).size, MAX_RT_LENGTH);
2665 data = (ctrl->controls[0]).string;
2666 /* send payload to FM hardware */
2667 while (bytes_left) {
2668 chunk_index++;
2669 bytes_to_copy = min(bytes_left, XFR_REG_NUM);
2670 memset(tx_data, 0, XFR_REG_NUM);
2671 if (copy_from_user(tx_data,
2672 data + bytes_copied, bytes_to_copy))
2673 return -EFAULT;
2674 retval = sync_write_xfr(radio,
2675 RDS_RT_0 + chunk_index, tx_data);
2676 if (retval < 0)
2677 return retval;
2678 bytes_copied += bytes_to_copy;
2679 bytes_left -= bytes_to_copy;
2680 }
2681 /*Write the RT Header */
2682 tx_data[0] = bytes_copied;
2683 /* PTY */
2684 tx_data[1] = TX_ON | ((radio->pty & MASK_PTY) >> 8);
2685 /* PI high */
2686 tx_data[2] = ((radio->pi & MASK_PI_MSB) >> 8);
2687 /* PI low */
2688 tx_data[3] = radio->pi & MASK_PI_LSB;
2689 retval = sync_write_xfr(radio, RDS_RT_0 , tx_data);
2690 if (retval < 0)
2691 return retval;
2692 FMDBG("done RT writing: %d\n", retval);
2693 } break;
2694 default:
2695 {
2696 FMDBG("Shouldn't reach here\n");
2697 retval = -1;
2698 }
2699 }
2700 return retval;
2701}
2702
2703/*=============================================================================
2704FUNCTION: tavarua_vidioc_s_ctrl
2705=============================================================================*/
2706/**
2707 This function is called to set the value of a control.
2708
2709 NOTE:
2710 To change the value of a control, applications initialize the id and value
2711 fields of a struct v4l2_control and call the VIDIOC_S_CTRL ioctl.
2712
2713 When the id is invalid drivers return an EINVAL error code. When the value is
2714 out of bounds drivers can choose to take the closest valid value or return an
2715 ERANGE error code, whatever seems more appropriate.
2716
2717 @param file: File descriptor returned by open().
2718 @param ctrl: pointer to struct v4l2_control.
2719
2720 @return On success 0 is returned, else error code.
2721 @return EINVAL: The struct v4l2_control id is invalid.
2722 @return ERANGE: The struct v4l2_control value is out of bounds.
2723 @return EBUSY: The control is temporarily not changeable, possibly because
2724 another applications took over control of the device function this control
2725 belongs to.
2726*/
2727static int tavarua_vidioc_s_ctrl(struct file *file, void *priv,
2728 struct v4l2_control *ctrl)
2729{
2730 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
2731 int retval = 0;
2732 unsigned char value;
2733 unsigned char xfr_buf[XFR_REG_NUM];
2734 unsigned char tx_data[XFR_REG_NUM];
2735
2736 switch (ctrl->id) {
2737 case V4L2_CID_AUDIO_VOLUME:
2738 break;
2739 case V4L2_CID_AUDIO_MUTE:
2740 value = (radio->registers[IOCTRL] & ~IOC_HRD_MUTE) |
2741 (ctrl->value & 0x03);
2742 retval = tavarua_write_register(radio, IOCTRL, value);
2743 break;
2744 case V4L2_CID_PRIVATE_TAVARUA_SRCHMODE:
2745 value = (radio->registers[SRCHCTRL] & ~SRCH_MODE) |
2746 ctrl->value;
2747 radio->registers[SRCHCTRL] = value;
2748 break;
2749 case V4L2_CID_PRIVATE_TAVARUA_SCANDWELL:
2750 value = (radio->registers[SRCHCTRL] & ~SCAN_DWELL) |
2751 (ctrl->value << 4);
2752 radio->registers[SRCHCTRL] = value;
2753 break;
2754 /* start/stop search */
2755 case V4L2_CID_PRIVATE_TAVARUA_SRCHON:
2756 FMDBG("starting search\n");
2757 tavarua_search(radio, ctrl->value, SRCH_DIR_UP);
2758 break;
2759 case V4L2_CID_PRIVATE_TAVARUA_STATE:
2760 /* check if already on */
2761 radio->handle_irq = 1;
2762 if (((ctrl->value == FM_RECV) || (ctrl->value == FM_TRANS))
2763 && !(radio->registers[RDCTRL] &
2764 ctrl->value)) {
2765 FMDBG("clearing flags\n");
2766 init_completion(&radio->sync_xfr_start);
2767 init_completion(&radio->sync_req_done);
2768 radio->xfr_in_progress = 0;
2769 radio->xfr_bytes_left = 0;
2770 FMDBG("turning on ..\n");
2771 retval = tavarua_start(radio, ctrl->value);
2772 if (retval >= 0) {
2773 FMDBG("Setting audio path ...\n");
2774 retval = tavarua_set_audio_path(
2775 TAVARUA_AUDIO_OUT_DIGITAL_ON,
2776 TAVARUA_AUDIO_OUT_ANALOG_OFF);
2777 if (retval < 0) {
2778 FMDERR("Error in tavarua_set_audio_path"
2779 " %d\n", retval);
2780 }
2781 /* Enabling 'SoftMute' and 'SignalBlending' features */
2782 value = (radio->registers[IOCTRL] |
2783 IOC_SFT_MUTE | IOC_SIG_BLND);
2784 retval = tavarua_write_register(radio, IOCTRL, value);
2785 if (retval < 0)
2786 FMDBG("SMute and SBlending not enabled\n");
2787 }
2788 }
2789 /* check if off */
2790 else if ((ctrl->value == FM_OFF) && radio->registers[RDCTRL]) {
2791 FMDBG("turning off...\n");
2792 retval = tavarua_write_register(radio, RDCTRL,
2793 ctrl->value);
2794 /*Make it synchronous
2795 Block it till READY interrupt
2796 Wait for interrupt i.e.
2797 complete(&radio->sync_req_done)
2798 */
2799
2800 if (retval >= 0) {
2801
2802 if (!wait_for_completion_timeout(
2803 &radio->sync_req_done,
2804 msecs_to_jiffies(wait_timeout)))
2805 FMDBG("turning off timedout...\n");
2806 }
2807 }
2808 break;
2809 case V4L2_CID_PRIVATE_TAVARUA_REGION:
2810 retval = tavarua_set_region(radio, ctrl->value);
2811 break;
2812 case V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH:
2813 retval = sync_read_xfr(radio, RX_CONFIG, xfr_buf);
2814 if (retval < 0) {
2815 FMDERR("V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH]\n");
2816 FMDERR("sync_read_xfr [retval=%d]\n", retval);
2817 break;
2818 }
2819 /* RMSSI Threshold is a signed 8 bit value */
2820 xfr_buf[0] = (unsigned char)ctrl->value;
2821 xfr_buf[1] = (unsigned char)ctrl->value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002822 retval = sync_write_xfr(radio, RX_CONFIG, xfr_buf);
2823 if (retval < 0) {
2824 FMDERR("V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH]\n");
2825 FMDERR("sync_write_xfr [retval=%d]\n", retval);
2826 break;
2827 }
2828 break;
2829 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY:
2830 radio->srch_params.srch_pty = ctrl->value;
2831 break;
2832 case V4L2_CID_PRIVATE_TAVARUA_SRCH_PI:
2833 radio->srch_params.srch_pi = ctrl->value;
2834 break;
2835 case V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT:
2836 radio->srch_params.preset_num = ctrl->value;
2837 break;
2838 case V4L2_CID_PRIVATE_TAVARUA_EMPHASIS:
2839 radio->region_params.emphasis = ctrl->value;
2840 break;
2841 case V4L2_CID_PRIVATE_TAVARUA_RDS_STD:
2842 radio->region_params.rds_std = ctrl->value;
2843 break;
2844 case V4L2_CID_PRIVATE_TAVARUA_SPACING:
2845 radio->region_params.spacing = ctrl->value;
2846 break;
2847 case V4L2_CID_PRIVATE_TAVARUA_RDSON:
2848 retval = 0;
2849 if (ctrl->value != (radio->registers[RDSCTRL] & RDS_ON)) {
2850 value = radio->registers[RDSCTRL] | ctrl->value;
2851 retval = tavarua_write_register(radio, RDSCTRL, value);
2852 }
2853 break;
2854 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK:
2855 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2856 if (retval < 0)
2857 break;
2858 xfr_buf[8] = (ctrl->value & 0xFF000000) >> 24;
2859 xfr_buf[9] = (ctrl->value & 0x00FF0000) >> 16;
2860 xfr_buf[10] = (ctrl->value & 0x0000FF00) >> 8;
2861 xfr_buf[11] = (ctrl->value & 0x000000FF);
2862 retval = sync_write_xfr(radio, RDS_CONFIG, xfr_buf);
2863 break;
2864 case V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC:
Anantha Krishnane46ef6f2011-06-29 23:56:03 +05302865 value = radio->registers[ADVCTRL] | ctrl->value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002866 retval = tavarua_write_register(radio, ADVCTRL, value);
2867 break;
Anantha Krishnane46ef6f2011-06-29 23:56:03 +05302868 case V4L2_CID_PRIVATE_TAVARUA_AF_JUMP:
2869 retval = tavarua_read_registers(radio, ADVCTRL, 1);
2870 SET_REG_FIELD(radio->registers[ADVCTRL], ctrl->value,
2871 RDSAF_OFFSET, RDSAF_MASK);
2872 msleep(TAVARUA_DELAY*5);
2873 retval = tavarua_write_register(radio,
2874 ADVCTRL, radio->registers[ADVCTRL]);
2875 msleep(TAVARUA_DELAY*5);
2876 break;
Anantha Krishnan3b44cd42011-07-06 12:36:15 +05302877 case V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA:
2878 retval = sync_read_xfr(radio, RX_CONFIG, xfr_buf);
2879 if (retval < 0) {
2880 FMDERR("V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA]\n");
2881 FMDERR("sync_read_xfr [retval=%d]\n", retval);
2882 break;
2883 }
2884 xfr_buf[4] = (unsigned char)ctrl->value;
2885 retval = sync_write_xfr(radio, RX_CONFIG, xfr_buf);
2886 if (retval < 0) {
2887 FMDERR("V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA]\n");
2888 FMDERR("sync_write_xfr [retval=%d]\n", retval);
2889 break;
2890 }
2891 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002892 case V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF:
2893 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2894 if (retval < 0)
2895 break;
2896 xfr_buf[1] = ctrl->value;
2897 retval = sync_write_xfr(radio, RDS_CONFIG, xfr_buf);
2898 break;
2899 case V4L2_CID_PRIVATE_TAVARUA_PSALL:
2900 retval = sync_read_xfr(radio, RDS_CONFIG, xfr_buf);
2901 value = ctrl->value & RDS_CONFIG_PSALL;
2902 if (retval < 0)
2903 break;
2904 xfr_buf[12] &= ~RDS_CONFIG_PSALL;
2905 xfr_buf[12] |= value;
2906 retval = sync_write_xfr(radio, RDS_CONFIG, xfr_buf);
2907 break;
2908 case V4L2_CID_PRIVATE_TAVARUA_LP_MODE:
2909 retval = 0;
2910 if (ctrl->value == radio->lp_mode)
2911 break;
2912 if (ctrl->value) {
2913 FMDBG("going into low power mode\n");
2914 retval = tavarua_disable_interrupts(radio);
2915 } else {
2916 FMDBG("going into normal power mode\n");
2917 tavarua_setup_interrupts(radio,
2918 (radio->registers[RDCTRL] & 0x03));
2919 }
2920 break;
2921 case V4L2_CID_PRIVATE_TAVARUA_ANTENNA:
2922 SET_REG_FIELD(radio->registers[IOCTRL], ctrl->value,
2923 IOC_ANTENNA_OFFSET, IOC_ANTENNA_MASK);
2924 break;
2925 /* TX Controls */
2926
2927 case V4L2_CID_RDS_TX_PTY: {
2928 radio->pty = ctrl->value;
2929 } break;
2930 case V4L2_CID_RDS_TX_PI: {
2931 radio->pi = ctrl->value;
2932 } break;
2933 case V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_PS_NAME: {
2934 FMDBG("In STOP_RDS_TX_PS_NAME\n");
2935 /*Pass a sample PS string */
2936 memset(tx_data, '0', XFR_REG_NUM);
2937 FMDBG("Writing PS header\n");
2938 retval = sync_write_xfr(radio, RDS_PS_0, tx_data);
2939 FMDBG("retval of PS Header write: %d", retval);
2940
2941 } break;
2942
2943 case V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_RT: {
2944 memset(tx_data, '0', XFR_REG_NUM);
2945 FMDBG("Writing RT header\n");
2946 retval = sync_write_xfr(radio, RDS_RT_0, tx_data);
2947 FMDBG("retval of Header write: %d", retval);
2948
2949 } break;
2950
2951 case V4L2_CID_PRIVATE_TAVARUA_TX_SETPSREPEATCOUNT: {
2952 radio->ps_repeatcount = ctrl->value;
2953 } break;
2954 case V4L2_CID_TUNE_POWER_LEVEL: {
2955 unsigned char tx_power_lvl_config[FM_TX_PWR_LVL_MAX+1] = {
2956 0x85, /* tx_da<5:3> = 0 lpf<2:0> = 5*/
2957 0x95, /* tx_da<5:3> = 2 lpf<2:0> = 5*/
2958 0x9D, /* tx_da<5:3> = 3 lpf<2:0> = 5*/
2959 0xA5, /* tx_da<5:3> = 4 lpf<2:0> = 5*/
2960 0xAD, /* tx_da<5:3> = 5 lpf<2:0> = 5*/
2961 0xB5, /* tx_da<5:3> = 6 lpf<2:0> = 5*/
2962 0xBD, /* tx_da<5:3> = 7 lpf<2:0> = 5*/
2963 0xBF /* tx_da<5:3> = 7 lpf<2:0> = 7*/
2964 };
2965 if (ctrl->value > FM_TX_PWR_LVL_MAX)
2966 ctrl->value = FM_TX_PWR_LVL_MAX;
2967 if (ctrl->value < FM_TX_PWR_LVL_0)
2968 ctrl->value = FM_TX_PWR_LVL_0;
2969 retval = sync_read_xfr(radio, PHY_TXGAIN, xfr_buf);
2970 FMDBG("return for PHY_TXGAIN is %d", retval);
2971 if (retval < 0) {
2972 FMDBG("read failed");
2973 break;
2974 }
2975 xfr_buf[2] = tx_power_lvl_config[ctrl->value];
2976 retval = sync_write_xfr(radio, PHY_TXGAIN, xfr_buf);
2977 FMDBG("return for write PHY_TXGAIN is %d", retval);
2978 if (retval < 0)
2979 FMDBG("write failed");
2980 } break;
2981
2982 default:
2983 retval = -EINVAL;
2984 }
2985 if (retval < 0)
2986 printk(KERN_WARNING DRIVER_NAME
2987 ": set control failed with %d, id : %d\n", retval, ctrl->id);
2988
2989 return retval;
2990}
2991
2992/*=============================================================================
2993FUNCTION: tavarua_vidioc_g_tuner
2994=============================================================================*/
2995/**
2996 This function is called to get tuner attributes.
2997
2998 NOTE:
2999 To query the attributes of a tuner, applications initialize the index field
3000 and zero out the reserved array of a struct v4l2_tuner and call the
3001 VIDIOC_G_TUNER ioctl with a pointer to this structure. Drivers fill the rest
3002 of the structure or return an EINVAL error code when the index is out of
3003 bounds. To enumerate all tuners applications shall begin at index zero,
3004 incrementing by one until the driver returns EINVAL.
3005
3006 @param file: File descriptor returned by open().
3007 @param tuner: pointer to struct v4l2_tuner.
3008
3009 @return On success 0 is returned, else error code.
3010 @return EINVAL: The struct v4l2_tuner index is out of bounds.
3011*/
3012static int tavarua_vidioc_g_tuner(struct file *file, void *priv,
3013 struct v4l2_tuner *tuner)
3014{
3015 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3016 int retval;
3017 unsigned char xfr_buf[XFR_REG_NUM];
3018 char rmssi = 0;
3019 unsigned char size = 0;
3020
3021 if (tuner->index > 0)
3022 return -EINVAL;
3023
3024 /* read status rssi */
3025 retval = tavarua_read_registers(radio, IOCTRL, 1);
3026 if (retval < 0)
3027 return retval;
3028 /* read RMSSI */
3029 size = 0x1;
3030 xfr_buf[0] = (XFR_PEEK_MODE | (size << 1));
3031 xfr_buf[1] = RMSSI_PEEK_MSB;
3032 xfr_buf[2] = RMSSI_PEEK_LSB;
3033 retval = tavarua_write_registers(radio, XFRCTRL, xfr_buf, 3);
3034 msleep(TAVARUA_DELAY*10);
3035 retval = tavarua_read_registers(radio, XFRDAT0, 3);
3036 rmssi = radio->registers[XFRDAT0];
3037 tuner->signal = rmssi;
3038
3039 strcpy(tuner->name, "FM");
3040 tuner->type = V4L2_TUNER_RADIO;
3041 tuner->rangelow = radio->region_params.band_low;
3042 tuner->rangehigh = radio->region_params.band_high;
3043 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
3044 tuner->capability = V4L2_TUNER_CAP_LOW;
3045
3046 /* Stereo indicator == Stereo (instead of Mono) */
3047 if (radio->registers[IOCTRL] & IOC_MON_STR)
3048 tuner->audmode = V4L2_TUNER_MODE_STEREO;
3049 else
3050 tuner->audmode = V4L2_TUNER_MODE_MONO;
3051
3052 /* automatic frequency control: -1: freq to low, 1 freq to high */
3053 tuner->afc = 0;
3054
3055 return 0;
3056}
3057
3058/*=============================================================================
3059FUNCTION: tavarua_vidioc_s_tuner
3060=============================================================================*/
3061/**
3062 This function is called to set tuner attributes. Used to set mono/stereo mode.
3063
3064 NOTE:
3065 Tuners have two writable properties, the audio mode and the radio frequency.
3066 To change the audio mode, applications initialize the index, audmode and
3067 reserved fields and call the VIDIOC_S_TUNER ioctl. This will not change the
3068 current tuner, which is determined by the current video input. Drivers may
3069 choose a different audio mode if the requested mode is invalid or unsupported.
3070 Since this is a write-only ioctl, it does not return the actually selected
3071 audio mode.
3072
3073 To change the radio frequency the VIDIOC_S_FREQUENCY ioctl is available.
3074
3075 @param file: File descriptor returned by open().
3076 @param tuner: pointer to struct v4l2_tuner.
3077
3078 @return On success 0 is returned, else error code.
3079 @return -EINVAL: The struct v4l2_tuner index is out of bounds.
3080*/
3081static int tavarua_vidioc_s_tuner(struct file *file, void *priv,
3082 struct v4l2_tuner *tuner)
3083{
3084 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3085 int retval;
3086 int audmode;
3087 if (tuner->index > 0)
3088 return -EINVAL;
3089
3090 FMDBG("%s: set low to %d\n", __func__, tuner->rangelow);
3091 radio->region_params.band_low = tuner->rangelow;
3092 radio->region_params.band_high = tuner->rangehigh;
3093 if (tuner->audmode == V4L2_TUNER_MODE_MONO)
3094 /* Mono */
3095 audmode = (radio->registers[IOCTRL] | IOC_MON_STR);
3096 else
3097 /* Stereo */
3098 audmode = (radio->registers[IOCTRL] & ~IOC_MON_STR);
3099 retval = tavarua_write_register(radio, IOCTRL, audmode);
3100 if (retval < 0)
3101 printk(KERN_WARNING DRIVER_NAME
3102 ": set tuner failed with %d\n", retval);
3103
3104 return retval;
3105}
3106
3107/*=============================================================================
3108FUNCTION: tavarua_vidioc_g_frequency
3109=============================================================================*/
3110/**
3111 This function is called to get tuner or modulator radio frequency.
3112
3113 NOTE:
3114 To get the current tuner or modulator radio frequency applications set the
3115 tuner field of a struct v4l2_frequency to the respective tuner or modulator
3116 number (only input devices have tuners, only output devices have modulators),
3117 zero out the reserved array and call the VIDIOC_G_FREQUENCY ioctl with a
3118 pointer to this structure. The driver stores the current frequency in the
3119 frequency field.
3120
3121 @param file: File descriptor returned by open().
3122 @param freq: pointer to struct v4l2_frequency. This will be set to the
3123 resultant
3124 frequency in 62.5 khz on success.
3125
3126 @return On success 0 is returned, else error code.
3127 @return EINVAL: The tuner index is out of bounds or the value in the type
3128 field is wrong.
3129*/
3130static int tavarua_vidioc_g_frequency(struct file *file, void *priv,
3131 struct v4l2_frequency *freq)
3132{
3133 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3134 freq->type = V4L2_TUNER_RADIO;
3135 return tavarua_get_freq(radio, freq);
3136
3137}
3138
3139/*=============================================================================
3140FUNCTION: tavarua_vidioc_s_frequency
3141=============================================================================*/
3142/**
3143 This function is called to set tuner or modulator radio frequency.
3144
3145 NOTE:
3146 To change the current tuner or modulator radio frequency applications
3147 initialize the tuner, type and frequency fields, and the reserved array of
3148 a struct v4l2_frequency and call the VIDIOC_S_FREQUENCY ioctl with a pointer
3149 to this structure. When the requested frequency is not possible the driver
3150 assumes the closest possible value. However VIDIOC_S_FREQUENCY is a
3151 write-only ioctl, it does not return the actual new frequency.
3152
3153 @param file: File descriptor returned by open().
3154 @param freq: pointer to struct v4l2_frequency.
3155
3156 @return On success 0 is returned, else error code.
3157 @return EINVAL: The tuner index is out of bounds or the value in the type
3158 field is wrong.
3159*/
3160static int tavarua_vidioc_s_frequency(struct file *file, void *priv,
3161 struct v4l2_frequency *freq)
3162{
3163 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3164 int retval = -1;
3165 struct v4l2_frequency getFreq;
3166
3167 FMDBG("%s\n", __func__);
3168
3169 if (freq->type != V4L2_TUNER_RADIO)
3170 return -EINVAL;
3171
3172 FMDBG("Calling tavarua_set_freq\n");
3173
3174 INIT_COMPLETION(radio->sync_req_done);
3175 retval = tavarua_set_freq(radio, freq->frequency);
3176 if (retval < 0) {
3177 printk(KERN_WARNING DRIVER_NAME
3178 ": set frequency failed with %d\n", retval);
3179 } else {
3180 /* Wait for interrupt i.e. complete
3181 (&radio->sync_req_done); call */
3182 if (!wait_for_completion_timeout(&radio->sync_req_done,
3183 msecs_to_jiffies(wait_timeout))) {
3184 FMDERR("Timeout: No Tune response");
3185 retval = tavarua_get_freq(radio, &getFreq);
3186 radio->tune_req = 0;
3187 if (retval > 0) {
3188 if (getFreq.frequency == freq->frequency) {
3189 /** This is success, queut the event*/
3190 tavarua_q_event(radio,
3191 TAVARUA_EVT_TUNE_SUCC);
3192 return 0;
3193 } else {
3194 return -EIO;
3195 }
3196 }
3197 }
3198 }
3199 radio->tune_req = 0;
3200 return retval;
3201}
3202
3203/*=============================================================================
3204FUNCTION: tavarua_vidioc_dqbuf
3205=============================================================================*/
3206/**
3207 This function is called to exchange a buffer with the driver.
3208 This is main buffer function, in essense its equivalent to a blocking
3209 read call.
3210
3211 Applications call the VIDIOC_DQBUF ioctl to dequeue a filled (capturing) or
3212 displayed (output) buffer from the driver's outgoing queue. They just set
3213 the type and memory fields of a struct v4l2_buffer as above, when VIDIOC_DQBUF
3214 is called with a pointer to this structure the driver fills the remaining
3215 fields or returns an error code.
3216
3217 NOTE:
3218 By default VIDIOC_DQBUF blocks when no buffer is in the outgoing queue.
3219 When the O_NONBLOCK flag was given to the open() function, VIDIOC_DQBUF
3220 returns immediately with an EAGAIN error code when no buffer is available.
3221
3222 @param file: File descriptor returned by open().
3223 @param buffer: pointer to struct v4l2_buffer.
3224
3225 @return On success 0 is returned, else error code.
3226 @return EAGAIN: Non-blocking I/O has been selected using O_NONBLOCK and no
3227 buffer was in the outgoing queue.
3228 @return EINVAL: The buffer type is not supported, or the index is out of
3229 bounds, or no buffers have been allocated yet, or the userptr or length are
3230 invalid.
3231 @return ENOMEM: Not enough physical or virtual memory was available to enqueue
3232 a user pointer buffer.
3233 @return EIO: VIDIOC_DQBUF failed due to an internal error. Can also indicate
3234 temporary problems like signal loss. Note the driver might dequeue an (empty)
3235 buffer despite returning an error, or even stop capturing.
3236*/
3237static int tavarua_vidioc_dqbuf(struct file *file, void *priv,
3238 struct v4l2_buffer *buffer)
3239{
3240
3241 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3242 enum tavarua_buf_t buf_type = buffer->index;
3243 struct kfifo *data_fifo;
3244 unsigned char *buf = (unsigned char *)buffer->m.userptr;
3245 unsigned int len = buffer->length;
3246 FMDBG("%s: requesting buffer %d\n", __func__, buf_type);
3247 /* check if we can access the user buffer */
3248 if (!access_ok(VERIFY_WRITE, buf, len))
3249 return -EFAULT;
3250 if ((buf_type < TAVARUA_BUF_MAX) && (buf_type >= 0)) {
3251 data_fifo = &radio->data_buf[buf_type];
3252 if (buf_type == TAVARUA_BUF_EVENTS) {
3253 if (wait_event_interruptible(radio->event_queue,
3254 kfifo_len(data_fifo)) < 0) {
3255 return -EINTR;
3256 }
3257 }
3258 } else {
3259 FMDERR("invalid buffer type\n");
3260 return -EINVAL;
3261 }
3262 buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
3263 &radio->buf_lock[buf_type]);
3264
3265 return 0;
3266}
3267
3268/*=============================================================================
3269FUNCTION: tavarua_vidioc_g_fmt_type_private
3270=============================================================================*/
3271/**
3272 This function is here to make the v4l2 framework happy.
3273 We cannot use private buffers without it.
3274
3275 @param file: File descriptor returned by open().
3276 @param f: pointer to struct v4l2_format.
3277
3278 @return On success 0 is returned, else error code.
3279 @return EINVAL: The tuner index is out of bounds or the value in the type
3280 field is wrong.
3281*/
3282static int tavarua_vidioc_g_fmt_type_private(struct file *file, void *priv,
3283 struct v4l2_format *f)
3284{
3285 return 0;
3286
3287}
3288
3289/*=============================================================================
3290FUNCTION: tavarua_vidioc_s_hw_freq_seek
3291=============================================================================*/
3292/**
3293 This function is called to perform a hardware frequency seek.
3294
3295 Start a hardware frequency seek from the current frequency. To do this
3296 applications initialize the tuner, type, seek_upward and wrap_around fields,
3297 and zero out the reserved array of a struct v4l2_hw_freq_seek and call the
3298 VIDIOC_S_HW_FREQ_SEEK ioctl with a pointer to this structure.
3299
3300 This ioctl is supported if the V4L2_CAP_HW_FREQ_SEEK capability is set.
3301
3302 @param file: File descriptor returned by open().
3303 @param seek: pointer to struct v4l2_hw_freq_seek.
3304
3305 @return On success 0 is returned, else error code.
3306 @return EINVAL: The tuner index is out of bounds or the value in the type
3307 field is wrong.
3308 @return EAGAIN: The ioctl timed-out. Try again.
3309*/
3310static int tavarua_vidioc_s_hw_freq_seek(struct file *file, void *priv,
3311 struct v4l2_hw_freq_seek *seek)
3312{
3313 struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
3314 int dir;
3315 if (seek->seek_upward)
3316 dir = SRCH_DIR_UP;
3317 else
3318 dir = SRCH_DIR_DOWN;
3319 FMDBG("starting search\n");
3320 return tavarua_search(radio, CTRL_ON, dir);
3321}
3322
3323/*
3324 * tavarua_viddev_tamples - video device interface
3325 */
3326static const struct v4l2_ioctl_ops tavarua_ioctl_ops = {
3327 .vidioc_querycap = tavarua_vidioc_querycap,
3328 .vidioc_queryctrl = tavarua_vidioc_queryctrl,
3329 .vidioc_g_ctrl = tavarua_vidioc_g_ctrl,
3330 .vidioc_s_ctrl = tavarua_vidioc_s_ctrl,
3331 .vidioc_g_tuner = tavarua_vidioc_g_tuner,
3332 .vidioc_s_tuner = tavarua_vidioc_s_tuner,
3333 .vidioc_g_frequency = tavarua_vidioc_g_frequency,
3334 .vidioc_s_frequency = tavarua_vidioc_s_frequency,
3335 .vidioc_s_hw_freq_seek = tavarua_vidioc_s_hw_freq_seek,
3336 .vidioc_dqbuf = tavarua_vidioc_dqbuf,
3337 .vidioc_g_fmt_type_private = tavarua_vidioc_g_fmt_type_private,
3338 .vidioc_s_ext_ctrls = tavarua_vidioc_s_ext_ctrls,
3339};
3340
3341static struct video_device tavarua_viddev_template = {
3342 .fops = &tavarua_fops,
3343 .ioctl_ops = &tavarua_ioctl_ops,
3344 .name = DRIVER_NAME,
3345 .release = video_device_release,
3346};
3347
3348/*==============================================================
3349FUNCTION: FmQSocCom_EnableInterrupts
3350==============================================================*/
3351/**
3352 This function enable interrupts.
3353
3354 @param radio: structure pointer passed by client.
3355 @param state: FM radio state (receiver/transmitter/off/reset).
3356
3357 @return => 0 if successful.
3358 @return < 0 if failure.
3359*/
3360static int tavarua_setup_interrupts(struct tavarua_device *radio,
3361 enum radio_state_t state)
3362{
3363 int retval;
3364 unsigned char int_ctrl[XFR_REG_NUM];
3365
3366 if (!radio->lp_mode)
3367 return 0;
3368
3369 int_ctrl[STATUS_REG1] = READY | TUNE | SEARCH | SCANNEXT |
3370 SIGNAL | INTF | SYNC | AUDIO;
3371 if (state == FM_RECV)
3372 int_ctrl[STATUS_REG2] = RDSDAT | RDSRT | RDSPS | RDSAF;
3373 else
3374 int_ctrl[STATUS_REG2] = TXRDSDAT | TXRDSDONE;
3375
3376 int_ctrl[STATUS_REG3] = TRANSFER | ERROR;
3377
3378 /* use xfr for interrupt setup */
3379 if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
3380 || radio->chipID == BAHAMA_2_0) {
3381 FMDBG("Setting interrupts\n");
3382 retval = sync_write_xfr(radio, INT_CTRL, int_ctrl);
3383 /* use register write to setup interrupts */
3384 } else {
3385 retval = tavarua_write_register(radio,
3386 STATUS_REG1, int_ctrl[STATUS_REG1]);
3387 if (retval < 0)
3388 return retval;
3389
3390 retval = tavarua_write_register(radio,
3391 STATUS_REG2, int_ctrl[STATUS_REG2]);
3392 if (retval < 0)
3393 return retval;
3394
3395 retval = tavarua_write_register(radio,
3396 STATUS_REG3, int_ctrl[STATUS_REG3]);
3397 if (retval < 0)
3398 return retval;
3399 }
3400
3401 radio->lp_mode = 0;
3402 /* tavarua_handle_interrupts force reads all the interrupt status
3403 * registers and it is not valid for MBA 2.1
3404 */
3405 if ((radio->chipID != MARIMBA_2_1) && (radio->chipID != BAHAMA_1_0)
3406 && (radio->chipID != BAHAMA_2_0))
3407 tavarua_handle_interrupts(radio);
3408
3409 return retval;
3410
3411}
3412
3413/*==============================================================
3414FUNCTION: tavarua_disable_interrupts
3415==============================================================*/
3416/**
3417 This function disables interrupts.
3418
3419 @param radio: structure pointer passed by client.
3420
3421 @return => 0 if successful.
3422 @return < 0 if failure.
3423*/
3424static int tavarua_disable_interrupts(struct tavarua_device *radio)
3425{
3426 unsigned char lpm_buf[XFR_REG_NUM];
3427 int retval;
3428 if (radio->lp_mode)
3429 return 0;
3430 FMDBG("%s\n", __func__);
3431 /* In Low power mode, disable all the interrupts that are not being
3432 waited by the Application */
3433 lpm_buf[STATUS_REG1] = TUNE | SEARCH | SCANNEXT;
3434 lpm_buf[STATUS_REG2] = 0x00;
3435 lpm_buf[STATUS_REG3] = TRANSFER;
3436 /* use xfr for interrupt setup */
3437 wait_timeout = 100;
3438 if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
3439 || radio->chipID == BAHAMA_2_0)
3440 retval = sync_write_xfr(radio, INT_CTRL, lpm_buf);
3441 /* use register write to setup interrupts */
3442 else
3443 retval = tavarua_write_registers(radio, STATUS_REG1, lpm_buf,
3444 ARRAY_SIZE(lpm_buf));
3445
3446 /*INT_CTL writes may fail with TIME_OUT as all the
3447 interrupts have been disabled
3448 */
3449 if (retval > -1 || retval == -ETIME) {
3450 radio->lp_mode = 1;
3451 /*Consider timeout as a valid case here*/
3452 retval = 0;
3453 }
3454 wait_timeout = WAIT_TIMEOUT;
3455 return retval;
3456
3457}
3458
3459/*==============================================================
3460FUNCTION: tavarua_start
3461==============================================================*/
3462/**
3463 Starts/enables the device (FM radio).
3464
3465 @param radio: structure pointer passed by client.
3466 @param state: FM radio state (receiver/transmitter/off/reset).
3467
3468 @return On success 0 is returned, else error code.
3469*/
3470static int tavarua_start(struct tavarua_device *radio,
3471 enum radio_state_t state)
3472{
3473
3474 int retval;
3475 FMDBG("%s <%d>\n", __func__, state);
3476 /* set geographic region */
3477 radio->region_params.region = TAVARUA_REGION_US;
3478
3479 /* set radio mode */
3480 retval = tavarua_write_register(radio, RDCTRL, state);
3481 if (retval < 0)
3482 return retval;
3483 /* wait for radio to init */
3484 msleep(RADIO_INIT_TIME);
3485 /* enable interrupts */
3486 tavarua_setup_interrupts(radio, state);
3487 /* default region is US */
3488 radio->region_params.band_low = US_LOW_BAND * FREQ_MUL;
3489 radio->region_params.band_high = US_HIGH_BAND * FREQ_MUL;
3490
3491 return 0;
3492}
3493
3494/*==============================================================
3495FUNCTION: tavarua_suspend
3496==============================================================*/
3497/**
3498 Save state and stop all devices in system.
3499
3500 @param pdev: platform device to be suspended.
3501 @param state: Power state to put each device in.
3502
3503 @return On success 0 is returned, else error code.
3504*/
3505static int tavarua_suspend(struct platform_device *pdev, pm_message_t state)
3506{
3507 struct tavarua_device *radio = platform_get_drvdata(pdev);
3508 int retval;
3509 int users = 0;
3510 printk(KERN_INFO DRIVER_NAME "%s: radio suspend\n\n", __func__);
3511 if (radio) {
3512 mutex_lock(&radio->lock);
3513 users = radio->users;
3514 mutex_unlock(&radio->lock);
3515 if (users) {
3516 retval = tavarua_disable_interrupts(radio);
3517 if (retval < 0) {
3518 printk(KERN_INFO DRIVER_NAME
3519 "tavarua_suspend error %d\n", retval);
3520 return -EIO;
3521 }
3522 }
3523 }
3524 return 0;
3525}
3526
3527/*==============================================================
3528FUNCTION: tavarua_resume
3529==============================================================*/
3530/**
3531 Restore state of each device in system.
3532
3533 @param pdev: platform device to be resumed.
3534
3535 @return On success 0 is returned, else error code.
3536*/
3537static int tavarua_resume(struct platform_device *pdev)
3538{
3539
3540 struct tavarua_device *radio = platform_get_drvdata(pdev);
3541 int retval;
3542 int users = 0;
3543 printk(KERN_INFO DRIVER_NAME "%s: radio resume\n\n", __func__);
3544 if (radio) {
3545 mutex_lock(&radio->lock);
3546 users = radio->users;
3547 mutex_unlock(&radio->lock);
3548
3549 if (users) {
3550 retval = tavarua_setup_interrupts(radio,
3551 (radio->registers[RDCTRL] & 0x03));
3552 if (retval < 0) {
3553 printk(KERN_INFO DRIVER_NAME "Error in \
3554 tavarua_resume %d\n", retval);
3555 return -EIO;
3556 }
3557 }
3558 }
3559 return 0;
3560}
3561
3562/*==============================================================
3563FUNCTION: tavarua_set_audio_path
3564==============================================================*/
3565/**
3566 This function will configure the audio path to and from the
3567 FM core.
3568
3569 This interface is expected to be called from the multimedia
3570 driver's thread. This interface should only be called when
3571 the FM hardware is enabled. If the FM hardware is not
3572 currently enabled, this interface will return an error.
3573
3574 @param digital_on: Digital audio from the FM core should be enabled/disbled.
3575 @param analog_on: Analog audio from the FM core should be enabled/disbled.
3576
3577 @return On success 0 is returned, else error code.
3578*/
3579int tavarua_set_audio_path(int digital_on, int analog_on)
3580{
3581 struct tavarua_device *radio = private_data;
3582 int rx_on = radio->registers[RDCTRL] & FM_RECV;
3583 if (!radio)
3584 return -ENOMEM;
3585 /* RX */
3586 FMDBG("%s: digital: %d analog: %d\n", __func__, digital_on, analog_on);
3587 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3588 ((rx_on && analog_on) ? 1 : 0),
3589 AUDIORX_ANALOG_OFFSET,
3590 AUDIORX_ANALOG_MASK);
3591 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3592 ((rx_on && digital_on) ? 1 : 0),
3593 AUDIORX_DIGITAL_OFFSET,
3594 AUDIORX_DIGITAL_MASK);
3595 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3596 (rx_on ? 0 : 1),
3597 AUDIOTX_OFFSET,
3598 AUDIOTX_MASK);
3599 /*
3600
3601 I2S Master/Slave configuration:
3602 Setting the FM SoC as I2S Master/Slave
3603 'false' - FM SoC is I2S Slave
3604 'true' - FM SoC is I2S Master
3605
3606 We get this infomation from the respective target's board file :
3607 MSM7x30 - FM SoC is I2S Slave
3608 MSM8x60 - FM SoC is I2S Slave
3609 MSM7x27A - FM SoC is I2S Master
3610 */
3611
3612 if (!radio->pdata->is_fm_soc_i2s_master) {
3613 FMDBG("FM SoC is I2S Slave\n");
3614 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3615 (0),
3616 I2SCTRL_OFFSET,
3617 I2SCTRL_MASK);
3618 } else {
3619 FMDBG("FM SoC is I2S Master\n");
3620 SET_REG_FIELD(radio->registers[AUDIOCTRL],
3621 (1),
3622 I2SCTRL_OFFSET,
3623 I2SCTRL_MASK);
3624 }
3625 FMDBG("%s: %x\n", __func__, radio->registers[AUDIOCTRL]);
3626 return tavarua_write_register(radio, AUDIOCTRL,
3627 radio->registers[AUDIOCTRL]);
3628
3629}
3630
3631/*==============================================================
3632FUNCTION: tavarua_probe
3633==============================================================*/
3634/**
3635 Once called this functions initiates, allocates resources and registers video
3636 tuner device with the v4l2 framework.
3637
3638 NOTE:
3639 probe() should verify that the specified device hardware
3640 actually exists; sometimes platform setup code can't be sure. The probing
3641 can use device resources, including clocks, and device platform_data.
3642
3643 @param pdev: platform device to be probed.
3644
3645 @return On success 0 is returned, else error code.
3646 -ENOMEM in low memory cases
3647*/
3648static int __init tavarua_probe(struct platform_device *pdev)
3649{
3650
3651 struct marimba_fm_platform_data *tavarua_pdata;
3652 struct tavarua_device *radio;
3653 int retval;
3654 int i;
3655 FMDBG("%s: probe called\n", __func__);
3656 /* private data allocation */
3657 radio = kzalloc(sizeof(struct tavarua_device), GFP_KERNEL);
3658 if (!radio) {
3659 retval = -ENOMEM;
3660 goto err_initial;
3661 }
3662
3663 radio->marimba = platform_get_drvdata(pdev);
3664 tavarua_pdata = pdev->dev.platform_data;
3665 radio->pdata = tavarua_pdata;
3666 radio->dev = &pdev->dev;
3667 platform_set_drvdata(pdev, radio);
3668
3669 /* video device allocation */
3670 radio->videodev = video_device_alloc();
3671 if (!radio->videodev)
3672 goto err_radio;
3673
3674 /* initial configuration */
3675 memcpy(radio->videodev, &tavarua_viddev_template,
3676 sizeof(tavarua_viddev_template));
3677
3678 /*allocate internal buffers for decoded rds and event buffer*/
3679 for (i = 0; i < TAVARUA_BUF_MAX; i++) {
3680 int kfifo_alloc_rc=0;
3681 spin_lock_init(&radio->buf_lock[i]);
3682
3683 if (i == TAVARUA_BUF_RAW_RDS)
3684 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
3685 rds_buf*3, GFP_KERNEL);
3686 else
3687 kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
3688 STD_BUF_SIZE, GFP_KERNEL);
3689
3690 if (kfifo_alloc_rc!=0) {
3691 printk(KERN_ERR "%s: failed allocating buffers %d\n",
3692 __func__, kfifo_alloc_rc);
3693 goto err_bufs;
3694 }
3695 }
3696 /* init xfr status */
3697 radio->users = 0;
3698 radio->xfr_in_progress = 0;
3699 radio->xfr_bytes_left = 0;
3700 for (i = 0; i < TAVARUA_XFR_MAX; i++)
3701 radio->pending_xfrs[i] = 0;
3702
3703 /* init transmit data */
3704 radio->tx_mode = TAVARUA_TX_RT;
3705 /* Init RT and PS Tx datas*/
3706 radio->pty = 0;
3707 radio->pi = 0;
3708 radio->ps_repeatcount = 0;
3709 /* init search params */
3710 radio->srch_params.srch_pty = 0;
3711 radio->srch_params.srch_pi = 0;
3712 radio->srch_params.preset_num = 0;
3713 radio->srch_params.get_list = 0;
3714 /* radio initializes to low power mode */
3715 radio->lp_mode = 1;
3716 radio->handle_irq = 1;
3717 /* init lock */
3718 mutex_init(&radio->lock);
3719 /* init completion flags */
3720 init_completion(&radio->sync_xfr_start);
3721 init_completion(&radio->sync_req_done);
3722 radio->tune_req = 0;
3723 /* initialize wait queue for event read */
3724 init_waitqueue_head(&radio->event_queue);
3725 /* initialize wait queue for raw rds read */
3726 init_waitqueue_head(&radio->read_queue);
3727
3728 video_set_drvdata(radio->videodev, radio);
3729 /*Start the worker thread for event handling and register read_int_stat
3730 as worker function*/
3731 INIT_DELAYED_WORK(&radio->work, read_int_stat);
3732
3733 /* register video device */
3734 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
3735 printk(KERN_WARNING DRIVER_NAME
3736 ": Could not register video device\n");
3737 goto err_all;
3738 }
3739 private_data = radio;
3740 return 0;
3741
3742err_all:
3743 video_device_release(radio->videodev);
3744err_bufs:
3745 for (; i > -1; i--)
3746 kfifo_free(&radio->data_buf[i]);
3747err_radio:
3748 kfree(radio);
3749err_initial:
3750 return retval;
3751}
3752
3753/*==============================================================
3754FUNCTION: tavarua_remove
3755==============================================================*/
3756/**
3757 Removes the device.
3758
3759 @param pdev: platform device to be removed.
3760
3761 @return On success 0 is returned, else error code.
3762*/
3763static int __devexit tavarua_remove(struct platform_device *pdev)
3764{
3765 int i;
3766 struct tavarua_device *radio = platform_get_drvdata(pdev);
3767
3768 /* disable irq */
3769 tavarua_disable_irq(radio);
3770
3771 video_unregister_device(radio->videodev);
3772
3773 /* free internal buffers */
3774 for (i = 0; i < TAVARUA_BUF_MAX; i++)
3775 kfifo_free(&radio->data_buf[i]);
3776
3777 /* free state struct */
3778 kfree(radio);
3779
3780 platform_set_drvdata(pdev, NULL);
3781
3782 return 0;
3783}
3784
3785/*
3786 Platform drivers follow the standard driver model convention, where
3787 discovery/enumeration is handled outside the drivers, and drivers
3788 provide probe() and remove() methods. They support power management
3789 and shutdown notifications using the standard conventions.
3790*/
3791static struct platform_driver tavarua_driver = {
3792 .driver = {
3793 .owner = THIS_MODULE,
3794 .name = "marimba_fm",
3795 },
3796 .remove = __devexit_p(tavarua_remove),
3797 .suspend = tavarua_suspend,
3798 .resume = tavarua_resume,
3799}; /* platform device we're adding */
3800
3801
3802/*************************************************************************
3803 * Module Interface
3804 ************************************************************************/
3805
3806/*==============================================================
3807FUNCTION: radio_module_init
3808==============================================================*/
3809/**
3810 Module entry - add a platform-level device.
3811
3812 @return Returns zero if the driver registered and bound to a device, else
3813 returns a negative error code when the driver not registered.
3814*/
3815static int __init radio_module_init(void)
3816{
3817 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
3818 return platform_driver_probe(&tavarua_driver, tavarua_probe);
3819}
3820
3821/*==============================================================
3822FUNCTION: radio_module_exit
3823==============================================================*/
3824/**
3825 Module exit - removes a platform-level device.
3826
3827 NOTE:
3828 Note that this function will also release all memory- and port-based
3829 resources owned by the device (dev->resource).
3830
3831 @return none.
3832*/
3833static void __exit radio_module_exit(void)
3834{
3835 platform_driver_unregister(&tavarua_driver);
3836}
3837
3838MODULE_LICENSE("GPL v2");
3839MODULE_AUTHOR(DRIVER_AUTHOR);
3840MODULE_DESCRIPTION(DRIVER_DESC);
3841MODULE_VERSION(DRIVER_VERSION);
3842
3843module_init(radio_module_init);
3844module_exit(radio_module_exit);
3845