blob: 56c9241ee7fb9666d5b9b2025ba2a4f6ec76e0cf [file] [log] [blame]
Eduardo Valentin02bee892009-08-08 08:46:53 -03001/*
2 * drivers/media/radio/si4713-i2c.c
3 *
4 * Silicon Labs Si4713 FM Radio Transmitter I2C commands.
5 *
6 * Copyright (c) 2009 Nokia Corporation
7 * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
Eduardo Valentin02bee892009-08-08 08:46:53 -030024#include <linux/completion.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/i2c.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090028#include <linux/slab.h>
Jarkko Nikula00df0552010-10-29 11:31:39 -030029#include <linux/gpio.h>
30#include <linux/regulator/consumer.h>
Paul Gortmaker7a707b82011-07-03 14:03:12 -040031#include <linux/module.h>
Eduardo Valentin02bee892009-08-08 08:46:53 -030032#include <media/v4l2-device.h>
33#include <media/v4l2-ioctl.h>
34#include <media/v4l2-common.h>
35
36#include "si4713-i2c.h"
37
38/* module parameters */
39static int debug;
40module_param(debug, int, S_IRUGO | S_IWUSR);
41MODULE_PARM_DESC(debug, "Debug level (0 - 2)");
42
43MODULE_LICENSE("GPL");
44MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
45MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
46MODULE_VERSION("0.0.1");
47
Jarkko Nikula00df0552010-10-29 11:31:39 -030048static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = {
49 "vio",
50 "vdd",
51};
52
Eduardo Valentin02bee892009-08-08 08:46:53 -030053#define DEFAULT_RDS_PI 0x00
54#define DEFAULT_RDS_PTY 0x00
55#define DEFAULT_RDS_PS_NAME ""
56#define DEFAULT_RDS_RADIO_TEXT DEFAULT_RDS_PS_NAME
57#define DEFAULT_RDS_DEVIATION 0x00C8
58#define DEFAULT_RDS_PS_REPEAT_COUNT 0x0003
59#define DEFAULT_LIMITER_RTIME 0x1392
60#define DEFAULT_LIMITER_DEV 0x102CA
61#define DEFAULT_PILOT_FREQUENCY 0x4A38
62#define DEFAULT_PILOT_DEVIATION 0x1A5E
63#define DEFAULT_ACOMP_ATIME 0x0000
64#define DEFAULT_ACOMP_RTIME 0xF4240L
65#define DEFAULT_ACOMP_GAIN 0x0F
66#define DEFAULT_ACOMP_THRESHOLD (-0x28)
67#define DEFAULT_MUTE 0x01
68#define DEFAULT_POWER_LEVEL 88
69#define DEFAULT_FREQUENCY 8800
70#define DEFAULT_PREEMPHASIS FMPE_EU
71#define DEFAULT_TUNE_RNL 0xFF
72
73#define to_si4713_device(sd) container_of(sd, struct si4713_device, sd)
74
75/* frequency domain transformation (using times 10 to avoid floats) */
76#define FREQDEV_UNIT 100000
77#define FREQV4L2_MULTI 625
78#define si4713_to_v4l2(f) ((f * FREQDEV_UNIT) / FREQV4L2_MULTI)
79#define v4l2_to_si4713(f) ((f * FREQV4L2_MULTI) / FREQDEV_UNIT)
80#define FREQ_RANGE_LOW 7600
81#define FREQ_RANGE_HIGH 10800
82
83#define MAX_ARGS 7
84
85#define RDS_BLOCK 8
86#define RDS_BLOCK_CLEAR 0x03
87#define RDS_BLOCK_LOAD 0x04
88#define RDS_RADIOTEXT_2A 0x20
89#define RDS_RADIOTEXT_BLK_SIZE 4
90#define RDS_RADIOTEXT_INDEX_MAX 0x0F
91#define RDS_CARRIAGE_RETURN 0x0D
92
93#define rds_ps_nblocks(len) ((len / RDS_BLOCK) + (len % RDS_BLOCK ? 1 : 0))
94
95#define get_status_bit(p, b, m) (((p) & (m)) >> (b))
96#define set_bits(p, v, b, m) (((p) & ~(m)) | ((v) << (b)))
97
98#define ATTACK_TIME_UNIT 500
99
100#define POWER_OFF 0x00
101#define POWER_ON 0x01
102
103#define msb(x) ((u8)((u16) x >> 8))
104#define lsb(x) ((u8)((u16) x & 0x00FF))
105#define compose_u16(msb, lsb) (((u16)msb << 8) | lsb)
106#define check_command_failed(status) (!(status & SI4713_CTS) || \
107 (status & SI4713_ERR))
108/* mute definition */
109#define set_mute(p) ((p & 1) | ((p & 1) << 1));
110#define get_mute(p) (p & 0x01)
111
112#ifdef DEBUG
113#define DBG_BUFFER(device, message, buffer, size) \
114 { \
115 int i; \
116 char str[(size)*5]; \
117 for (i = 0; i < size; i++) \
118 sprintf(str + i * 5, " 0x%02x", buffer[i]); \
119 v4l2_dbg(2, debug, device, "%s:%s\n", message, str); \
120 }
121#else
122#define DBG_BUFFER(device, message, buffer, size)
123#endif
124
125/*
126 * Values for limiter release time (sorted by second column)
127 * device release
128 * value time (us)
129 */
130static long limiter_times[] = {
131 2000, 250,
132 1000, 500,
133 510, 1000,
134 255, 2000,
135 170, 3000,
136 127, 4020,
137 102, 5010,
138 85, 6020,
139 73, 7010,
140 64, 7990,
141 57, 8970,
142 51, 10030,
143 25, 20470,
144 17, 30110,
145 13, 39380,
146 10, 51190,
147 8, 63690,
148 7, 73140,
149 6, 85330,
150 5, 102390,
151};
152
153/*
154 * Values for audio compression release time (sorted by second column)
155 * device release
156 * value time (us)
157 */
158static unsigned long acomp_rtimes[] = {
159 0, 100000,
160 1, 200000,
161 2, 350000,
162 3, 525000,
163 4, 1000000,
164};
165
166/*
167 * Values for preemphasis (sorted by second column)
168 * device preemphasis
169 * value value (v4l2)
170 */
171static unsigned long preemphasis_values[] = {
172 FMPE_DISABLED, V4L2_PREEMPHASIS_DISABLED,
173 FMPE_EU, V4L2_PREEMPHASIS_50_uS,
174 FMPE_USA, V4L2_PREEMPHASIS_75_uS,
175};
176
177static int usecs_to_dev(unsigned long usecs, unsigned long const array[],
178 int size)
179{
180 int i;
181 int rval = -EINVAL;
182
183 for (i = 0; i < size / 2; i++)
184 if (array[(i * 2) + 1] >= usecs) {
185 rval = array[i * 2];
186 break;
187 }
188
189 return rval;
190}
191
192static unsigned long dev_to_usecs(int value, unsigned long const array[],
193 int size)
194{
195 int i;
196 int rval = -EINVAL;
197
198 for (i = 0; i < size / 2; i++)
199 if (array[i * 2] == value) {
200 rval = array[(i * 2) + 1];
201 break;
202 }
203
204 return rval;
205}
206
207/* si4713_handler: IRQ handler, just complete work */
208static irqreturn_t si4713_handler(int irq, void *dev)
209{
210 struct si4713_device *sdev = dev;
211
212 v4l2_dbg(2, debug, &sdev->sd,
213 "%s: sending signal to completion work.\n", __func__);
214 complete(&sdev->work);
215
216 return IRQ_HANDLED;
217}
218
219/*
220 * si4713_send_command - sends a command to si4713 and waits its response
221 * @sdev: si4713_device structure for the device we are communicating
222 * @command: command id
223 * @args: command arguments we are sending (up to 7)
224 * @argn: actual size of @args
225 * @response: buffer to place the expected response from the device (up to 15)
226 * @respn: actual size of @response
227 * @usecs: amount of time to wait before reading the response (in usecs)
228 */
229static int si4713_send_command(struct si4713_device *sdev, const u8 command,
230 const u8 args[], const int argn,
231 u8 response[], const int respn, const int usecs)
232{
233 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
234 u8 data1[MAX_ARGS + 1];
235 int err;
236
237 if (!client->adapter)
238 return -ENODEV;
239
240 /* First send the command and its arguments */
241 data1[0] = command;
242 memcpy(data1 + 1, args, argn);
243 DBG_BUFFER(&sdev->sd, "Parameters", data1, argn + 1);
244
245 err = i2c_master_send(client, data1, argn + 1);
246 if (err != argn + 1) {
247 v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
248 command);
249 return (err > 0) ? -EIO : err;
250 }
251
252 /* Wait response from interrupt */
253 if (!wait_for_completion_timeout(&sdev->work,
254 usecs_to_jiffies(usecs) + 1))
255 v4l2_warn(&sdev->sd,
256 "(%s) Device took too much time to answer.\n",
257 __func__);
258
259 /* Then get the response */
260 err = i2c_master_recv(client, response, respn);
261 if (err != respn) {
262 v4l2_err(&sdev->sd,
263 "Error while reading response for command 0x%02x\n",
264 command);
265 return (err > 0) ? -EIO : err;
266 }
267
268 DBG_BUFFER(&sdev->sd, "Response", response, respn);
269 if (check_command_failed(response[0]))
270 return -EBUSY;
271
272 return 0;
273}
274
275/*
276 * si4713_read_property - reads a si4713 property
277 * @sdev: si4713_device structure for the device we are communicating
278 * @prop: property identification number
279 * @pv: property value to be returned on success
280 */
281static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv)
282{
283 int err;
284 u8 val[SI4713_GET_PROP_NRESP];
285 /*
286 * .First byte = 0
287 * .Second byte = property's MSB
288 * .Third byte = property's LSB
289 */
290 const u8 args[SI4713_GET_PROP_NARGS] = {
291 0x00,
292 msb(prop),
293 lsb(prop),
294 };
295
296 err = si4713_send_command(sdev, SI4713_CMD_GET_PROPERTY,
297 args, ARRAY_SIZE(args), val,
298 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
299
300 if (err < 0)
301 return err;
302
303 *pv = compose_u16(val[2], val[3]);
304
305 v4l2_dbg(1, debug, &sdev->sd,
306 "%s: property=0x%02x value=0x%02x status=0x%02x\n",
307 __func__, prop, *pv, val[0]);
308
309 return err;
310}
311
312/*
313 * si4713_write_property - modifies a si4713 property
314 * @sdev: si4713_device structure for the device we are communicating
315 * @prop: property identification number
316 * @val: new value for that property
317 */
318static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val)
319{
320 int rval;
321 u8 resp[SI4713_SET_PROP_NRESP];
322 /*
323 * .First byte = 0
324 * .Second byte = property's MSB
325 * .Third byte = property's LSB
326 * .Fourth byte = value's MSB
327 * .Fifth byte = value's LSB
328 */
329 const u8 args[SI4713_SET_PROP_NARGS] = {
330 0x00,
331 msb(prop),
332 lsb(prop),
333 msb(val),
334 lsb(val),
335 };
336
337 rval = si4713_send_command(sdev, SI4713_CMD_SET_PROPERTY,
338 args, ARRAY_SIZE(args),
339 resp, ARRAY_SIZE(resp),
340 DEFAULT_TIMEOUT);
341
342 if (rval < 0)
343 return rval;
344
345 v4l2_dbg(1, debug, &sdev->sd,
346 "%s: property=0x%02x value=0x%02x status=0x%02x\n",
347 __func__, prop, val, resp[0]);
348
349 /*
350 * As there is no command response for SET_PROPERTY,
351 * wait Tcomp time to finish before proceed, in order
352 * to have property properly set.
353 */
354 msleep(TIMEOUT_SET_PROPERTY);
355
356 return rval;
357}
358
359/*
360 * si4713_powerup - Powers the device up
361 * @sdev: si4713_device structure for the device we are communicating
362 */
363static int si4713_powerup(struct si4713_device *sdev)
364{
365 int err;
366 u8 resp[SI4713_PWUP_NRESP];
367 /*
368 * .First byte = Enabled interrupts and boot function
369 * .Second byte = Input operation mode
370 */
371 const u8 args[SI4713_PWUP_NARGS] = {
372 SI4713_PWUP_CTSIEN | SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX,
373 SI4713_PWUP_OPMOD_ANALOG,
374 };
375
376 if (sdev->power_state)
377 return 0;
378
Jarkko Nikula00df0552010-10-29 11:31:39 -0300379 err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies),
380 sdev->supplies);
381 if (err) {
382 v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err);
383 return err;
384 }
385 if (gpio_is_valid(sdev->gpio_reset)) {
386 udelay(50);
387 gpio_set_value(sdev->gpio_reset, 1);
388 }
389
Eduardo Valentin02bee892009-08-08 08:46:53 -0300390 err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
391 args, ARRAY_SIZE(args),
392 resp, ARRAY_SIZE(resp),
393 TIMEOUT_POWER_UP);
394
395 if (!err) {
396 v4l2_dbg(1, debug, &sdev->sd, "Powerup response: 0x%02x\n",
397 resp[0]);
398 v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n");
399 sdev->power_state = POWER_ON;
400
401 err = si4713_write_property(sdev, SI4713_GPO_IEN,
402 SI4713_STC_INT | SI4713_CTS);
403 } else {
Jarkko Nikula00df0552010-10-29 11:31:39 -0300404 if (gpio_is_valid(sdev->gpio_reset))
405 gpio_set_value(sdev->gpio_reset, 0);
406 err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
407 sdev->supplies);
408 if (err)
409 v4l2_err(&sdev->sd,
410 "Failed to disable supplies: %d\n", err);
Eduardo Valentin02bee892009-08-08 08:46:53 -0300411 }
412
413 return err;
414}
415
416/*
417 * si4713_powerdown - Powers the device down
418 * @sdev: si4713_device structure for the device we are communicating
419 */
420static int si4713_powerdown(struct si4713_device *sdev)
421{
422 int err;
423 u8 resp[SI4713_PWDN_NRESP];
424
425 if (!sdev->power_state)
426 return 0;
427
428 err = si4713_send_command(sdev, SI4713_CMD_POWER_DOWN,
429 NULL, 0,
430 resp, ARRAY_SIZE(resp),
431 DEFAULT_TIMEOUT);
432
433 if (!err) {
434 v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
435 resp[0]);
436 v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
Jarkko Nikula00df0552010-10-29 11:31:39 -0300437 if (gpio_is_valid(sdev->gpio_reset))
438 gpio_set_value(sdev->gpio_reset, 0);
439 err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
440 sdev->supplies);
441 if (err)
442 v4l2_err(&sdev->sd,
443 "Failed to disable supplies: %d\n", err);
Eduardo Valentin02bee892009-08-08 08:46:53 -0300444 sdev->power_state = POWER_OFF;
445 }
446
447 return err;
448}
449
450/*
451 * si4713_checkrev - Checks if we are treating a device with the correct rev.
452 * @sdev: si4713_device structure for the device we are communicating
453 */
454static int si4713_checkrev(struct si4713_device *sdev)
455{
456 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
457 int rval;
458 u8 resp[SI4713_GETREV_NRESP];
459
Eduardo Valentin02bee892009-08-08 08:46:53 -0300460 rval = si4713_send_command(sdev, SI4713_CMD_GET_REV,
461 NULL, 0,
462 resp, ARRAY_SIZE(resp),
463 DEFAULT_TIMEOUT);
464
465 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300466 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -0300467
468 if (resp[1] == SI4713_PRODUCT_NUMBER) {
469 v4l2_info(&sdev->sd, "chip found @ 0x%02x (%s)\n",
470 client->addr << 1, client->adapter->name);
471 } else {
472 v4l2_err(&sdev->sd, "Invalid product number\n");
473 rval = -EINVAL;
474 }
Eduardo Valentin02bee892009-08-08 08:46:53 -0300475 return rval;
476}
477
478/*
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300479 * si4713_wait_stc - Waits STC interrupt and clears status bits. Useful
Eduardo Valentin02bee892009-08-08 08:46:53 -0300480 * for TX_TUNE_POWER, TX_TUNE_FREQ and TX_TUNE_MEAS
481 * @sdev: si4713_device structure for the device we are communicating
482 * @usecs: timeout to wait for STC interrupt signal
483 */
484static int si4713_wait_stc(struct si4713_device *sdev, const int usecs)
485{
486 int err;
487 u8 resp[SI4713_GET_STATUS_NRESP];
488
489 /* Wait response from STC interrupt */
490 if (!wait_for_completion_timeout(&sdev->work,
491 usecs_to_jiffies(usecs) + 1))
492 v4l2_warn(&sdev->sd,
493 "%s: device took too much time to answer (%d usec).\n",
494 __func__, usecs);
495
496 /* Clear status bits */
497 err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS,
498 NULL, 0,
499 resp, ARRAY_SIZE(resp),
500 DEFAULT_TIMEOUT);
501
502 if (err < 0)
503 goto exit;
504
505 v4l2_dbg(1, debug, &sdev->sd,
506 "%s: status bits: 0x%02x\n", __func__, resp[0]);
507
508 if (!(resp[0] & SI4713_STC_INT))
509 err = -EIO;
510
511exit:
512 return err;
513}
514
515/*
516 * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning
517 * frequency between 76 and 108 MHz in 10 kHz units and
518 * steps of 50 kHz.
519 * @sdev: si4713_device structure for the device we are communicating
520 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
521 */
522static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
523{
524 int err;
525 u8 val[SI4713_TXFREQ_NRESP];
526 /*
527 * .First byte = 0
528 * .Second byte = frequency's MSB
529 * .Third byte = frequency's LSB
530 */
531 const u8 args[SI4713_TXFREQ_NARGS] = {
532 0x00,
533 msb(frequency),
534 lsb(frequency),
535 };
536
537 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_FREQ,
538 args, ARRAY_SIZE(args), val,
539 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
540
541 if (err < 0)
542 return err;
543
544 v4l2_dbg(1, debug, &sdev->sd,
545 "%s: frequency=0x%02x status=0x%02x\n", __func__,
546 frequency, val[0]);
547
548 err = si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
549 if (err < 0)
550 return err;
551
552 return compose_u16(args[1], args[2]);
553}
554
555/*
556 * si4713_tx_tune_power - Sets the RF voltage level between 88 and 115 dBuV in
557 * 1 dB units. A value of 0x00 indicates off. The command
558 * also sets the antenna tuning capacitance. A value of 0
559 * indicates autotuning, and a value of 1 - 191 indicates
560 * a manual override, which results in a tuning
561 * capacitance of 0.25 pF x @antcap.
562 * @sdev: si4713_device structure for the device we are communicating
563 * @power: tuning power (88 - 115 dBuV, unit/step 1 dB)
564 * @antcap: value of antenna tuning capacitor (0 - 191)
565 */
566static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
567 u8 antcap)
568{
569 int err;
570 u8 val[SI4713_TXPWR_NRESP];
571 /*
572 * .First byte = 0
573 * .Second byte = 0
574 * .Third byte = power
575 * .Fourth byte = antcap
576 */
577 const u8 args[SI4713_TXPWR_NARGS] = {
578 0x00,
579 0x00,
580 power,
581 antcap,
582 };
583
584 if (((power > 0) && (power < SI4713_MIN_POWER)) ||
585 power > SI4713_MAX_POWER || antcap > SI4713_MAX_ANTCAP)
586 return -EDOM;
587
588 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
589 args, ARRAY_SIZE(args), val,
590 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
591
592 if (err < 0)
593 return err;
594
595 v4l2_dbg(1, debug, &sdev->sd,
596 "%s: power=0x%02x antcap=0x%02x status=0x%02x\n",
597 __func__, power, antcap, val[0]);
598
599 return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE_POWER);
600}
601
602/*
603 * si4713_tx_tune_measure - Enters receive mode and measures the received noise
604 * level in units of dBuV on the selected frequency.
605 * The Frequency must be between 76 and 108 MHz in 10 kHz
606 * units and steps of 50 kHz. The command also sets the
607 * antenna tuning capacitance. A value of 0 means
608 * autotuning, and a value of 1 to 191 indicates manual
609 * override.
610 * @sdev: si4713_device structure for the device we are communicating
611 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
612 * @antcap: value of antenna tuning capacitor (0 - 191)
613 */
614static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency,
615 u8 antcap)
616{
617 int err;
618 u8 val[SI4713_TXMEA_NRESP];
619 /*
620 * .First byte = 0
621 * .Second byte = frequency's MSB
622 * .Third byte = frequency's LSB
623 * .Fourth byte = antcap
624 */
625 const u8 args[SI4713_TXMEA_NARGS] = {
626 0x00,
627 msb(frequency),
628 lsb(frequency),
629 antcap,
630 };
631
632 sdev->tune_rnl = DEFAULT_TUNE_RNL;
633
634 if (antcap > SI4713_MAX_ANTCAP)
635 return -EDOM;
636
637 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_MEASURE,
638 args, ARRAY_SIZE(args), val,
639 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
640
641 if (err < 0)
642 return err;
643
644 v4l2_dbg(1, debug, &sdev->sd,
645 "%s: frequency=0x%02x antcap=0x%02x status=0x%02x\n",
646 __func__, frequency, antcap, val[0]);
647
648 return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
649}
650
651/*
652 * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or
653 * tx_tune_power commands. This command return the current
654 * frequency, output voltage in dBuV, the antenna tunning
655 * capacitance value and the received noise level. The
656 * command also clears the stcint interrupt bit when the
657 * first bit of its arguments is high.
658 * @sdev: si4713_device structure for the device we are communicating
659 * @intack: 0x01 to clear the seek/tune complete interrupt status indicator.
660 * @frequency: returned frequency
661 * @power: returned power
662 * @antcap: returned antenna capacitance
663 * @noise: returned noise level
664 */
665static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack,
666 u16 *frequency, u8 *power,
667 u8 *antcap, u8 *noise)
668{
669 int err;
670 u8 val[SI4713_TXSTATUS_NRESP];
671 /*
672 * .First byte = intack bit
673 */
674 const u8 args[SI4713_TXSTATUS_NARGS] = {
675 intack & SI4713_INTACK_MASK,
676 };
677
678 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_STATUS,
679 args, ARRAY_SIZE(args), val,
680 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
681
682 if (!err) {
683 v4l2_dbg(1, debug, &sdev->sd,
684 "%s: status=0x%02x\n", __func__, val[0]);
685 *frequency = compose_u16(val[2], val[3]);
686 sdev->frequency = *frequency;
687 *power = val[5];
688 *antcap = val[6];
689 *noise = val[7];
690 v4l2_dbg(1, debug, &sdev->sd, "%s: response: %d x 10 kHz "
691 "(power %d, antcap %d, rnl %d)\n", __func__,
692 *frequency, *power, *antcap, *noise);
693 }
694
695 return err;
696}
697
698/*
699 * si4713_tx_rds_buff - Loads the RDS group buffer FIFO or circular buffer.
700 * @sdev: si4713_device structure for the device we are communicating
701 * @mode: the buffer operation mode.
702 * @rdsb: RDS Block B
703 * @rdsc: RDS Block C
704 * @rdsd: RDS Block D
705 * @cbleft: returns the number of available circular buffer blocks minus the
706 * number of used circular buffer blocks.
707 */
708static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb,
709 u16 rdsc, u16 rdsd, s8 *cbleft)
710{
711 int err;
712 u8 val[SI4713_RDSBUFF_NRESP];
713
714 const u8 args[SI4713_RDSBUFF_NARGS] = {
715 mode & SI4713_RDSBUFF_MODE_MASK,
716 msb(rdsb),
717 lsb(rdsb),
718 msb(rdsc),
719 lsb(rdsc),
720 msb(rdsd),
721 lsb(rdsd),
722 };
723
724 err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_BUFF,
725 args, ARRAY_SIZE(args), val,
726 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
727
728 if (!err) {
729 v4l2_dbg(1, debug, &sdev->sd,
730 "%s: status=0x%02x\n", __func__, val[0]);
731 *cbleft = (s8)val[2] - val[3];
732 v4l2_dbg(1, debug, &sdev->sd, "%s: response: interrupts"
733 " 0x%02x cb avail: %d cb used %d fifo avail"
734 " %d fifo used %d\n", __func__, val[1],
735 val[2], val[3], val[4], val[5]);
736 }
737
738 return err;
739}
740
741/*
742 * si4713_tx_rds_ps - Loads the program service buffer.
743 * @sdev: si4713_device structure for the device we are communicating
744 * @psid: program service id to be loaded.
745 * @pschar: assumed 4 size char array to be loaded into the program service
746 */
747static int si4713_tx_rds_ps(struct si4713_device *sdev, u8 psid,
748 unsigned char *pschar)
749{
750 int err;
751 u8 val[SI4713_RDSPS_NRESP];
752
753 const u8 args[SI4713_RDSPS_NARGS] = {
754 psid & SI4713_RDSPS_PSID_MASK,
755 pschar[0],
756 pschar[1],
757 pschar[2],
758 pschar[3],
759 };
760
761 err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_PS,
762 args, ARRAY_SIZE(args), val,
763 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
764
765 if (err < 0)
766 return err;
767
768 v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]);
769
770 return err;
771}
772
773static int si4713_set_power_state(struct si4713_device *sdev, u8 value)
774{
Eduardo Valentin02bee892009-08-08 08:46:53 -0300775 if (value)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300776 return si4713_powerup(sdev);
777 return si4713_powerdown(sdev);
Eduardo Valentin02bee892009-08-08 08:46:53 -0300778}
779
780static int si4713_set_mute(struct si4713_device *sdev, u16 mute)
781{
782 int rval = 0;
783
784 mute = set_mute(mute);
785
Eduardo Valentin02bee892009-08-08 08:46:53 -0300786 if (sdev->power_state)
787 rval = si4713_write_property(sdev,
788 SI4713_TX_LINE_INPUT_MUTE, mute);
789
790 if (rval >= 0)
791 sdev->mute = get_mute(mute);
792
Eduardo Valentin02bee892009-08-08 08:46:53 -0300793 return rval;
794}
795
796static int si4713_set_rds_ps_name(struct si4713_device *sdev, char *ps_name)
797{
798 int rval = 0, i;
799 u8 len = 0;
800
801 /* We want to clear the whole thing */
802 if (!strlen(ps_name))
803 memset(ps_name, 0, MAX_RDS_PS_NAME + 1);
804
Eduardo Valentin02bee892009-08-08 08:46:53 -0300805 if (sdev->power_state) {
806 /* Write the new ps name and clear the padding */
807 for (i = 0; i < MAX_RDS_PS_NAME; i += (RDS_BLOCK / 2)) {
808 rval = si4713_tx_rds_ps(sdev, (i / (RDS_BLOCK / 2)),
809 ps_name + i);
810 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300811 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -0300812 }
813
814 /* Setup the size to be sent */
815 if (strlen(ps_name))
816 len = strlen(ps_name) - 1;
817 else
818 len = 1;
819
820 rval = si4713_write_property(sdev,
821 SI4713_TX_RDS_PS_MESSAGE_COUNT,
822 rds_ps_nblocks(len));
823 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300824 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -0300825
826 rval = si4713_write_property(sdev,
827 SI4713_TX_RDS_PS_REPEAT_COUNT,
828 DEFAULT_RDS_PS_REPEAT_COUNT * 2);
829 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300830 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -0300831 }
832
833 strncpy(sdev->rds_info.ps_name, ps_name, MAX_RDS_PS_NAME);
Eduardo Valentin02bee892009-08-08 08:46:53 -0300834 return rval;
835}
836
837static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt)
838{
839 int rval = 0, i;
840 u16 t_index = 0;
841 u8 b_index = 0, cr_inserted = 0;
842 s8 left;
843
Eduardo Valentin02bee892009-08-08 08:46:53 -0300844 if (!sdev->power_state)
845 goto copy;
846
847 rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_CLEAR, 0, 0, 0, &left);
848 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300849 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -0300850
851 if (!strlen(rt))
852 goto copy;
853
854 do {
855 /* RDS spec says that if the last block isn't used,
856 * then apply a carriage return
857 */
858 if (t_index < (RDS_RADIOTEXT_INDEX_MAX *
859 RDS_RADIOTEXT_BLK_SIZE)) {
860 for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) {
861 if (!rt[t_index + i] || rt[t_index + i] ==
862 RDS_CARRIAGE_RETURN) {
863 rt[t_index + i] = RDS_CARRIAGE_RETURN;
864 cr_inserted = 1;
865 break;
866 }
867 }
868 }
869
870 rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_LOAD,
871 compose_u16(RDS_RADIOTEXT_2A, b_index++),
872 compose_u16(rt[t_index], rt[t_index + 1]),
873 compose_u16(rt[t_index + 2], rt[t_index + 3]),
874 &left);
875 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -0300876 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -0300877
878 t_index += RDS_RADIOTEXT_BLK_SIZE;
879
880 if (cr_inserted)
881 break;
882 } while (left > 0);
883
884copy:
885 strncpy(sdev->rds_info.radio_text, rt, MAX_RDS_RADIO_TEXT);
Eduardo Valentin02bee892009-08-08 08:46:53 -0300886 return rval;
887}
888
889static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
890 u32 **shadow, s32 *bit, s32 *mask, u16 *property, int *mul,
891 unsigned long **table, int *size)
892{
893 s32 rval = 0;
894
895 switch (id) {
896 /* FM_TX class controls */
897 case V4L2_CID_RDS_TX_PI:
898 *property = SI4713_TX_RDS_PI;
899 *mul = 1;
900 *shadow = &sdev->rds_info.pi;
901 break;
902 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
903 *property = SI4713_TX_ACOMP_THRESHOLD;
904 *mul = 1;
905 *shadow = &sdev->acomp_info.threshold;
906 break;
907 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
908 *property = SI4713_TX_ACOMP_GAIN;
909 *mul = 1;
910 *shadow = &sdev->acomp_info.gain;
911 break;
912 case V4L2_CID_PILOT_TONE_FREQUENCY:
913 *property = SI4713_TX_PILOT_FREQUENCY;
914 *mul = 1;
915 *shadow = &sdev->pilot_info.frequency;
916 break;
917 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
918 *property = SI4713_TX_ACOMP_ATTACK_TIME;
919 *mul = ATTACK_TIME_UNIT;
920 *shadow = &sdev->acomp_info.attack_time;
921 break;
922 case V4L2_CID_PILOT_TONE_DEVIATION:
923 *property = SI4713_TX_PILOT_DEVIATION;
924 *mul = 10;
925 *shadow = &sdev->pilot_info.deviation;
926 break;
927 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
928 *property = SI4713_TX_AUDIO_DEVIATION;
929 *mul = 10;
930 *shadow = &sdev->limiter_info.deviation;
931 break;
932 case V4L2_CID_RDS_TX_DEVIATION:
933 *property = SI4713_TX_RDS_DEVIATION;
934 *mul = 1;
935 *shadow = &sdev->rds_info.deviation;
936 break;
937
938 case V4L2_CID_RDS_TX_PTY:
939 *property = SI4713_TX_RDS_PS_MISC;
940 *bit = 5;
941 *mask = 0x1F << 5;
942 *shadow = &sdev->rds_info.pty;
943 break;
944 case V4L2_CID_AUDIO_LIMITER_ENABLED:
945 *property = SI4713_TX_ACOMP_ENABLE;
946 *bit = 1;
947 *mask = 1 << 1;
948 *shadow = &sdev->limiter_info.enabled;
949 break;
950 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
951 *property = SI4713_TX_ACOMP_ENABLE;
952 *bit = 0;
953 *mask = 1 << 0;
954 *shadow = &sdev->acomp_info.enabled;
955 break;
956 case V4L2_CID_PILOT_TONE_ENABLED:
957 *property = SI4713_TX_COMPONENT_ENABLE;
958 *bit = 0;
959 *mask = 1 << 0;
960 *shadow = &sdev->pilot_info.enabled;
961 break;
962
963 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
964 *property = SI4713_TX_LIMITER_RELEASE_TIME;
965 *table = limiter_times;
966 *size = ARRAY_SIZE(limiter_times);
967 *shadow = &sdev->limiter_info.release_time;
968 break;
969 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
970 *property = SI4713_TX_ACOMP_RELEASE_TIME;
971 *table = acomp_rtimes;
972 *size = ARRAY_SIZE(acomp_rtimes);
973 *shadow = &sdev->acomp_info.release_time;
974 break;
975 case V4L2_CID_TUNE_PREEMPHASIS:
976 *property = SI4713_TX_PREEMPHASIS;
977 *table = preemphasis_values;
978 *size = ARRAY_SIZE(preemphasis_values);
979 *shadow = &sdev->preemphasis;
980 break;
981
982 default:
983 rval = -EINVAL;
Peter Senna Tschudincb9e40f2012-09-06 12:09:11 -0300984 }
Eduardo Valentin02bee892009-08-08 08:46:53 -0300985
986 return rval;
987}
988
989static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
990
991/* write string property */
992static int si4713_write_econtrol_string(struct si4713_device *sdev,
993 struct v4l2_ext_control *control)
994{
995 struct v4l2_queryctrl vqc;
996 int len;
997 s32 rval = 0;
998
999 vqc.id = control->id;
1000 rval = si4713_queryctrl(&sdev->sd, &vqc);
1001 if (rval < 0)
1002 goto exit;
1003
1004 switch (control->id) {
1005 case V4L2_CID_RDS_TX_PS_NAME: {
1006 char ps_name[MAX_RDS_PS_NAME + 1];
1007
1008 len = control->size - 1;
Mauro Carvalho Chehabdc6b8452011-07-17 00:24:37 -03001009 if (len < 0 || len > MAX_RDS_PS_NAME) {
Eduardo Valentin02bee892009-08-08 08:46:53 -03001010 rval = -ERANGE;
1011 goto exit;
1012 }
1013 rval = copy_from_user(ps_name, control->string, len);
Dan Carpenteraac870a2010-06-04 07:34:40 -03001014 if (rval) {
1015 rval = -EFAULT;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001016 goto exit;
Dan Carpenteraac870a2010-06-04 07:34:40 -03001017 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001018 ps_name[len] = '\0';
1019
1020 if (strlen(ps_name) % vqc.step) {
1021 rval = -ERANGE;
1022 goto exit;
1023 }
1024
1025 rval = si4713_set_rds_ps_name(sdev, ps_name);
1026 }
1027 break;
1028
1029 case V4L2_CID_RDS_TX_RADIO_TEXT: {
1030 char radio_text[MAX_RDS_RADIO_TEXT + 1];
1031
1032 len = control->size - 1;
Mauro Carvalho Chehabdc6b8452011-07-17 00:24:37 -03001033 if (len < 0 || len > MAX_RDS_RADIO_TEXT) {
Eduardo Valentin02bee892009-08-08 08:46:53 -03001034 rval = -ERANGE;
1035 goto exit;
1036 }
1037 rval = copy_from_user(radio_text, control->string, len);
Dan Carpenteraac870a2010-06-04 07:34:40 -03001038 if (rval) {
1039 rval = -EFAULT;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001040 goto exit;
Dan Carpenteraac870a2010-06-04 07:34:40 -03001041 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001042 radio_text[len] = '\0';
1043
1044 if (strlen(radio_text) % vqc.step) {
1045 rval = -ERANGE;
1046 goto exit;
1047 }
1048
1049 rval = si4713_set_rds_radio_text(sdev, radio_text);
1050 }
1051 break;
1052
1053 default:
1054 rval = -EINVAL;
1055 break;
Peter Senna Tschudincb9e40f2012-09-06 12:09:11 -03001056 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001057
1058exit:
1059 return rval;
1060}
1061
1062static int validate_range(struct v4l2_subdev *sd,
1063 struct v4l2_ext_control *control)
1064{
1065 struct v4l2_queryctrl vqc;
1066 int rval;
1067
1068 vqc.id = control->id;
1069 rval = si4713_queryctrl(sd, &vqc);
1070 if (rval < 0)
1071 goto exit;
1072
1073 if (control->value < vqc.minimum || control->value > vqc.maximum)
1074 rval = -ERANGE;
1075
1076exit:
1077 return rval;
1078}
1079
1080/* properties which use tx_tune_power*/
1081static int si4713_write_econtrol_tune(struct si4713_device *sdev,
1082 struct v4l2_ext_control *control)
1083{
1084 s32 rval = 0;
1085 u8 power, antcap;
1086
1087 rval = validate_range(&sdev->sd, control);
1088 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001089 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001090
1091 switch (control->id) {
1092 case V4L2_CID_TUNE_POWER_LEVEL:
1093 power = control->value;
1094 antcap = sdev->antenna_capacitor;
1095 break;
1096 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1097 power = sdev->power_level;
1098 antcap = control->value;
1099 break;
1100 default:
Hans Verkuil55b2a312013-04-08 06:31:30 -03001101 return -EINVAL;
Peter Senna Tschudincb9e40f2012-09-06 12:09:11 -03001102 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001103
1104 if (sdev->power_state)
1105 rval = si4713_tx_tune_power(sdev, power, antcap);
1106
1107 if (rval == 0) {
1108 sdev->power_level = power;
1109 sdev->antenna_capacitor = antcap;
1110 }
1111
Eduardo Valentin02bee892009-08-08 08:46:53 -03001112 return rval;
1113}
1114
1115static int si4713_write_econtrol_integers(struct si4713_device *sdev,
1116 struct v4l2_ext_control *control)
1117{
1118 s32 rval;
1119 u32 *shadow = NULL, val = 0;
1120 s32 bit = 0, mask = 0;
1121 u16 property = 0;
1122 int mul = 0;
1123 unsigned long *table = NULL;
1124 int size = 0;
1125
1126 rval = validate_range(&sdev->sd, control);
1127 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001128 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001129
1130 rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
1131 &mask, &property, &mul, &table, &size);
1132 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001133 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001134
1135 val = control->value;
1136 if (mul) {
1137 val = control->value / mul;
1138 } else if (table) {
1139 rval = usecs_to_dev(control->value, table, size);
1140 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001141 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001142 val = rval;
1143 rval = 0;
1144 }
1145
Eduardo Valentin02bee892009-08-08 08:46:53 -03001146 if (sdev->power_state) {
1147 if (mask) {
1148 rval = si4713_read_property(sdev, property, &val);
1149 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001150 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001151 val = set_bits(val, control->value, bit, mask);
1152 }
1153
1154 rval = si4713_write_property(sdev, property, val);
1155 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001156 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001157 if (mask)
1158 val = control->value;
1159 }
1160
1161 if (mul) {
1162 *shadow = val * mul;
1163 } else if (table) {
1164 rval = dev_to_usecs(val, table, size);
1165 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001166 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001167 *shadow = rval;
1168 rval = 0;
1169 } else {
1170 *shadow = val;
1171 }
1172
Eduardo Valentin02bee892009-08-08 08:46:53 -03001173 return rval;
1174}
1175
Hans Verkuilb530a442013-03-19 04:09:26 -03001176static int si4713_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *f);
Hans Verkuil3f70e1f2012-09-04 12:08:47 -03001177static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulator *);
Eduardo Valentin02bee892009-08-08 08:46:53 -03001178/*
1179 * si4713_setup - Sets the device up with current configuration.
1180 * @sdev: si4713_device structure for the device we are communicating
1181 */
1182static int si4713_setup(struct si4713_device *sdev)
1183{
1184 struct v4l2_ext_control ctrl;
1185 struct v4l2_frequency f;
1186 struct v4l2_modulator vm;
1187 struct si4713_device *tmp;
1188 int rval = 0;
1189
1190 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
1191 if (!tmp)
1192 return -ENOMEM;
1193
1194 /* Get a local copy to avoid race */
Eduardo Valentin02bee892009-08-08 08:46:53 -03001195 memcpy(tmp, sdev, sizeof(*sdev));
Eduardo Valentin02bee892009-08-08 08:46:53 -03001196
1197 ctrl.id = V4L2_CID_RDS_TX_PI;
1198 ctrl.value = tmp->rds_info.pi;
1199 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1200
1201 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_THRESHOLD;
1202 ctrl.value = tmp->acomp_info.threshold;
1203 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1204
1205 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_GAIN;
1206 ctrl.value = tmp->acomp_info.gain;
1207 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1208
1209 ctrl.id = V4L2_CID_PILOT_TONE_FREQUENCY;
1210 ctrl.value = tmp->pilot_info.frequency;
1211 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1212
1213 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME;
1214 ctrl.value = tmp->acomp_info.attack_time;
1215 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1216
1217 ctrl.id = V4L2_CID_PILOT_TONE_DEVIATION;
1218 ctrl.value = tmp->pilot_info.deviation;
1219 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1220
1221 ctrl.id = V4L2_CID_AUDIO_LIMITER_DEVIATION;
1222 ctrl.value = tmp->limiter_info.deviation;
1223 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1224
1225 ctrl.id = V4L2_CID_RDS_TX_DEVIATION;
1226 ctrl.value = tmp->rds_info.deviation;
1227 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1228
1229 ctrl.id = V4L2_CID_RDS_TX_PTY;
1230 ctrl.value = tmp->rds_info.pty;
1231 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1232
1233 ctrl.id = V4L2_CID_AUDIO_LIMITER_ENABLED;
1234 ctrl.value = tmp->limiter_info.enabled;
1235 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1236
1237 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ENABLED;
1238 ctrl.value = tmp->acomp_info.enabled;
1239 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1240
1241 ctrl.id = V4L2_CID_PILOT_TONE_ENABLED;
1242 ctrl.value = tmp->pilot_info.enabled;
1243 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1244
1245 ctrl.id = V4L2_CID_AUDIO_LIMITER_RELEASE_TIME;
1246 ctrl.value = tmp->limiter_info.release_time;
1247 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1248
1249 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME;
1250 ctrl.value = tmp->acomp_info.release_time;
1251 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1252
1253 ctrl.id = V4L2_CID_TUNE_PREEMPHASIS;
1254 ctrl.value = tmp->preemphasis;
1255 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1256
1257 ctrl.id = V4L2_CID_RDS_TX_PS_NAME;
1258 rval |= si4713_set_rds_ps_name(sdev, tmp->rds_info.ps_name);
1259
1260 ctrl.id = V4L2_CID_RDS_TX_RADIO_TEXT;
1261 rval |= si4713_set_rds_radio_text(sdev, tmp->rds_info.radio_text);
1262
1263 /* Device procedure needs to set frequency first */
Hans Verkuilb3877542013-04-08 17:25:05 -03001264 f.tuner = 0;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001265 f.frequency = tmp->frequency ? tmp->frequency : DEFAULT_FREQUENCY;
1266 f.frequency = si4713_to_v4l2(f.frequency);
1267 rval |= si4713_s_frequency(&sdev->sd, &f);
1268
1269 ctrl.id = V4L2_CID_TUNE_POWER_LEVEL;
1270 ctrl.value = tmp->power_level;
1271 rval |= si4713_write_econtrol_tune(sdev, &ctrl);
1272
1273 ctrl.id = V4L2_CID_TUNE_ANTENNA_CAPACITOR;
1274 ctrl.value = tmp->antenna_capacitor;
1275 rval |= si4713_write_econtrol_tune(sdev, &ctrl);
1276
1277 vm.index = 0;
1278 if (tmp->stereo)
1279 vm.txsubchans = V4L2_TUNER_SUB_STEREO;
1280 else
1281 vm.txsubchans = V4L2_TUNER_SUB_MONO;
1282 if (tmp->rds_info.enabled)
1283 vm.txsubchans |= V4L2_TUNER_SUB_RDS;
1284 si4713_s_modulator(&sdev->sd, &vm);
1285
1286 kfree(tmp);
1287
1288 return rval;
1289}
1290
1291/*
1292 * si4713_initialize - Sets the device up with default configuration.
1293 * @sdev: si4713_device structure for the device we are communicating
1294 */
1295static int si4713_initialize(struct si4713_device *sdev)
1296{
1297 int rval;
1298
1299 rval = si4713_set_power_state(sdev, POWER_ON);
1300 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001301 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001302
1303 rval = si4713_checkrev(sdev);
1304 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001305 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001306
1307 rval = si4713_set_power_state(sdev, POWER_OFF);
1308 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001309 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001310
1311 sdev->rds_info.pi = DEFAULT_RDS_PI;
1312 sdev->rds_info.pty = DEFAULT_RDS_PTY;
1313 sdev->rds_info.deviation = DEFAULT_RDS_DEVIATION;
1314 strlcpy(sdev->rds_info.ps_name, DEFAULT_RDS_PS_NAME, MAX_RDS_PS_NAME);
1315 strlcpy(sdev->rds_info.radio_text, DEFAULT_RDS_RADIO_TEXT,
1316 MAX_RDS_RADIO_TEXT);
1317 sdev->rds_info.enabled = 1;
1318
1319 sdev->limiter_info.release_time = DEFAULT_LIMITER_RTIME;
1320 sdev->limiter_info.deviation = DEFAULT_LIMITER_DEV;
1321 sdev->limiter_info.enabled = 1;
1322
1323 sdev->pilot_info.deviation = DEFAULT_PILOT_DEVIATION;
1324 sdev->pilot_info.frequency = DEFAULT_PILOT_FREQUENCY;
1325 sdev->pilot_info.enabled = 1;
1326
1327 sdev->acomp_info.release_time = DEFAULT_ACOMP_RTIME;
1328 sdev->acomp_info.attack_time = DEFAULT_ACOMP_ATIME;
1329 sdev->acomp_info.threshold = DEFAULT_ACOMP_THRESHOLD;
1330 sdev->acomp_info.gain = DEFAULT_ACOMP_GAIN;
1331 sdev->acomp_info.enabled = 1;
1332
1333 sdev->frequency = DEFAULT_FREQUENCY;
1334 sdev->preemphasis = DEFAULT_PREEMPHASIS;
1335 sdev->mute = DEFAULT_MUTE;
1336 sdev->power_level = DEFAULT_POWER_LEVEL;
1337 sdev->antenna_capacitor = 0;
1338 sdev->stereo = 1;
1339 sdev->tune_rnl = DEFAULT_TUNE_RNL;
1340
Eduardo Valentin02bee892009-08-08 08:46:53 -03001341 return rval;
1342}
1343
1344/* read string property */
1345static int si4713_read_econtrol_string(struct si4713_device *sdev,
1346 struct v4l2_ext_control *control)
1347{
1348 s32 rval = 0;
1349
1350 switch (control->id) {
1351 case V4L2_CID_RDS_TX_PS_NAME:
1352 if (strlen(sdev->rds_info.ps_name) + 1 > control->size) {
1353 control->size = MAX_RDS_PS_NAME + 1;
1354 rval = -ENOSPC;
1355 goto exit;
1356 }
1357 rval = copy_to_user(control->string, sdev->rds_info.ps_name,
1358 strlen(sdev->rds_info.ps_name) + 1);
Dan Carpenteraac870a2010-06-04 07:34:40 -03001359 if (rval)
1360 rval = -EFAULT;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001361 break;
1362
1363 case V4L2_CID_RDS_TX_RADIO_TEXT:
1364 if (strlen(sdev->rds_info.radio_text) + 1 > control->size) {
1365 control->size = MAX_RDS_RADIO_TEXT + 1;
1366 rval = -ENOSPC;
1367 goto exit;
1368 }
1369 rval = copy_to_user(control->string, sdev->rds_info.radio_text,
1370 strlen(sdev->rds_info.radio_text) + 1);
Dan Carpenteraac870a2010-06-04 07:34:40 -03001371 if (rval)
1372 rval = -EFAULT;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001373 break;
1374
1375 default:
1376 rval = -EINVAL;
1377 break;
Peter Senna Tschudincb9e40f2012-09-06 12:09:11 -03001378 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001379
1380exit:
1381 return rval;
1382}
1383
1384/*
1385 * si4713_update_tune_status - update properties from tx_tune_status
Hans Verkuil55b2a312013-04-08 06:31:30 -03001386 * command.
Eduardo Valentin02bee892009-08-08 08:46:53 -03001387 * @sdev: si4713_device structure for the device we are communicating
1388 */
1389static int si4713_update_tune_status(struct si4713_device *sdev)
1390{
1391 int rval;
1392 u16 f = 0;
1393 u8 p = 0, a = 0, n = 0;
1394
1395 rval = si4713_tx_tune_status(sdev, 0x00, &f, &p, &a, &n);
1396
1397 if (rval < 0)
1398 goto exit;
1399
1400 sdev->power_level = p;
1401 sdev->antenna_capacitor = a;
1402 sdev->tune_rnl = n;
1403
1404exit:
1405 return rval;
1406}
1407
1408/* properties which use tx_tune_status */
1409static int si4713_read_econtrol_tune(struct si4713_device *sdev,
1410 struct v4l2_ext_control *control)
1411{
1412 s32 rval = 0;
1413
Eduardo Valentin02bee892009-08-08 08:46:53 -03001414 if (sdev->power_state) {
1415 rval = si4713_update_tune_status(sdev);
1416 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001417 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001418 }
1419
1420 switch (control->id) {
1421 case V4L2_CID_TUNE_POWER_LEVEL:
1422 control->value = sdev->power_level;
1423 break;
1424 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1425 control->value = sdev->antenna_capacitor;
1426 break;
1427 default:
Hans Verkuil55b2a312013-04-08 06:31:30 -03001428 return -EINVAL;
Peter Senna Tschudincb9e40f2012-09-06 12:09:11 -03001429 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001430
Eduardo Valentin02bee892009-08-08 08:46:53 -03001431 return rval;
1432}
1433
1434static int si4713_read_econtrol_integers(struct si4713_device *sdev,
1435 struct v4l2_ext_control *control)
1436{
1437 s32 rval;
1438 u32 *shadow = NULL, val = 0;
1439 s32 bit = 0, mask = 0;
1440 u16 property = 0;
1441 int mul = 0;
1442 unsigned long *table = NULL;
1443 int size = 0;
1444
1445 rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
1446 &mask, &property, &mul, &table, &size);
1447 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001448 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001449
1450 if (sdev->power_state) {
1451 rval = si4713_read_property(sdev, property, &val);
1452 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001453 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001454
1455 /* Keep negative values for threshold */
1456 if (control->id == V4L2_CID_AUDIO_COMPRESSION_THRESHOLD)
1457 *shadow = (s16)val;
1458 else if (mask)
1459 *shadow = get_status_bit(val, bit, mask);
1460 else if (mul)
1461 *shadow = val * mul;
1462 else
1463 *shadow = dev_to_usecs(val, table, size);
1464 }
1465
1466 control->value = *shadow;
1467
Eduardo Valentin02bee892009-08-08 08:46:53 -03001468 return rval;
1469}
1470
1471/*
1472 * Video4Linux Subdev Interface
1473 */
1474/* si4713_s_ext_ctrls - set extended controls value */
1475static int si4713_s_ext_ctrls(struct v4l2_subdev *sd,
1476 struct v4l2_ext_controls *ctrls)
1477{
1478 struct si4713_device *sdev = to_si4713_device(sd);
1479 int i;
1480
1481 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
1482 return -EINVAL;
1483
1484 for (i = 0; i < ctrls->count; i++) {
1485 int err;
1486
1487 switch ((ctrls->controls + i)->id) {
1488 case V4L2_CID_RDS_TX_PS_NAME:
1489 case V4L2_CID_RDS_TX_RADIO_TEXT:
1490 err = si4713_write_econtrol_string(sdev,
1491 ctrls->controls + i);
1492 break;
1493 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1494 case V4L2_CID_TUNE_POWER_LEVEL:
1495 err = si4713_write_econtrol_tune(sdev,
1496 ctrls->controls + i);
1497 break;
1498 default:
1499 err = si4713_write_econtrol_integers(sdev,
1500 ctrls->controls + i);
1501 }
1502
1503 if (err < 0) {
1504 ctrls->error_idx = i;
1505 return err;
1506 }
1507 }
1508
1509 return 0;
1510}
1511
1512/* si4713_g_ext_ctrls - get extended controls value */
1513static int si4713_g_ext_ctrls(struct v4l2_subdev *sd,
1514 struct v4l2_ext_controls *ctrls)
1515{
1516 struct si4713_device *sdev = to_si4713_device(sd);
1517 int i;
1518
1519 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
1520 return -EINVAL;
1521
1522 for (i = 0; i < ctrls->count; i++) {
1523 int err;
1524
1525 switch ((ctrls->controls + i)->id) {
1526 case V4L2_CID_RDS_TX_PS_NAME:
1527 case V4L2_CID_RDS_TX_RADIO_TEXT:
1528 err = si4713_read_econtrol_string(sdev,
1529 ctrls->controls + i);
1530 break;
1531 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1532 case V4L2_CID_TUNE_POWER_LEVEL:
1533 err = si4713_read_econtrol_tune(sdev,
1534 ctrls->controls + i);
1535 break;
1536 default:
1537 err = si4713_read_econtrol_integers(sdev,
1538 ctrls->controls + i);
1539 }
1540
1541 if (err < 0) {
1542 ctrls->error_idx = i;
1543 return err;
1544 }
1545 }
1546
1547 return 0;
1548}
1549
1550/* si4713_queryctrl - enumerate control items */
1551static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1552{
1553 int rval = 0;
1554
1555 switch (qc->id) {
1556 /* User class controls */
1557 case V4L2_CID_AUDIO_MUTE:
1558 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, DEFAULT_MUTE);
1559 break;
1560 /* FM_TX class controls */
1561 case V4L2_CID_RDS_TX_PI:
1562 rval = v4l2_ctrl_query_fill(qc, 0, 0xFFFF, 1, DEFAULT_RDS_PI);
1563 break;
1564 case V4L2_CID_RDS_TX_PTY:
1565 rval = v4l2_ctrl_query_fill(qc, 0, 31, 1, DEFAULT_RDS_PTY);
1566 break;
1567 case V4L2_CID_RDS_TX_DEVIATION:
1568 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_DEVIATION,
1569 10, DEFAULT_RDS_DEVIATION);
1570 break;
1571 case V4L2_CID_RDS_TX_PS_NAME:
1572 /*
1573 * Report step as 8. From RDS spec, psname
1574 * should be 8. But there are receivers which scroll strings
1575 * sized as 8xN.
1576 */
1577 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_PS_NAME, 8, 0);
1578 break;
1579 case V4L2_CID_RDS_TX_RADIO_TEXT:
1580 /*
1581 * Report step as 32 (2A block). From RDS spec,
1582 * radio text should be 32 for 2A block. But there are receivers
1583 * which scroll strings sized as 32xN. Setting default to 32.
1584 */
1585 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_RADIO_TEXT, 32, 0);
1586 break;
1587
1588 case V4L2_CID_AUDIO_LIMITER_ENABLED:
1589 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1590 break;
1591 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
1592 rval = v4l2_ctrl_query_fill(qc, 250, MAX_LIMITER_RELEASE_TIME,
1593 50, DEFAULT_LIMITER_RTIME);
1594 break;
1595 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
1596 rval = v4l2_ctrl_query_fill(qc, 0, MAX_LIMITER_DEVIATION,
1597 10, DEFAULT_LIMITER_DEV);
1598 break;
1599
1600 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
1601 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1602 break;
1603 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
1604 rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_GAIN, 1,
1605 DEFAULT_ACOMP_GAIN);
1606 break;
1607 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
1608 rval = v4l2_ctrl_query_fill(qc, MIN_ACOMP_THRESHOLD,
1609 MAX_ACOMP_THRESHOLD, 1,
1610 DEFAULT_ACOMP_THRESHOLD);
1611 break;
1612 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
1613 rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_ATTACK_TIME,
1614 500, DEFAULT_ACOMP_ATIME);
1615 break;
1616 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
1617 rval = v4l2_ctrl_query_fill(qc, 100000, MAX_ACOMP_RELEASE_TIME,
1618 100000, DEFAULT_ACOMP_RTIME);
1619 break;
1620
1621 case V4L2_CID_PILOT_TONE_ENABLED:
1622 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1623 break;
1624 case V4L2_CID_PILOT_TONE_DEVIATION:
1625 rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_DEVIATION,
1626 10, DEFAULT_PILOT_DEVIATION);
1627 break;
1628 case V4L2_CID_PILOT_TONE_FREQUENCY:
1629 rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_FREQUENCY,
1630 1, DEFAULT_PILOT_FREQUENCY);
1631 break;
1632
1633 case V4L2_CID_TUNE_PREEMPHASIS:
1634 rval = v4l2_ctrl_query_fill(qc, V4L2_PREEMPHASIS_DISABLED,
1635 V4L2_PREEMPHASIS_75_uS, 1,
1636 V4L2_PREEMPHASIS_50_uS);
1637 break;
1638 case V4L2_CID_TUNE_POWER_LEVEL:
1639 rval = v4l2_ctrl_query_fill(qc, 0, 120, 1, DEFAULT_POWER_LEVEL);
1640 break;
1641 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1642 rval = v4l2_ctrl_query_fill(qc, 0, 191, 1, 0);
1643 break;
1644 default:
1645 rval = -EINVAL;
1646 break;
Peter Senna Tschudincb9e40f2012-09-06 12:09:11 -03001647 }
Eduardo Valentin02bee892009-08-08 08:46:53 -03001648
1649 return rval;
1650}
1651
1652/* si4713_g_ctrl - get the value of a control */
1653static int si4713_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1654{
1655 struct si4713_device *sdev = to_si4713_device(sd);
1656 int rval = 0;
1657
1658 if (!sdev)
1659 return -ENODEV;
1660
Eduardo Valentin02bee892009-08-08 08:46:53 -03001661 if (sdev->power_state) {
1662 rval = si4713_read_property(sdev, SI4713_TX_LINE_INPUT_MUTE,
1663 &sdev->mute);
1664
1665 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001666 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001667 }
1668
1669 switch (ctrl->id) {
1670 case V4L2_CID_AUDIO_MUTE:
1671 ctrl->value = get_mute(sdev->mute);
1672 break;
1673 }
1674
Eduardo Valentin02bee892009-08-08 08:46:53 -03001675 return rval;
1676}
1677
1678/* si4713_s_ctrl - set the value of a control */
1679static int si4713_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1680{
1681 struct si4713_device *sdev = to_si4713_device(sd);
1682 int rval = 0;
1683
1684 if (!sdev)
1685 return -ENODEV;
1686
1687 switch (ctrl->id) {
1688 case V4L2_CID_AUDIO_MUTE:
1689 if (ctrl->value) {
1690 rval = si4713_set_mute(sdev, ctrl->value);
1691 if (rval < 0)
1692 goto exit;
1693
1694 rval = si4713_set_power_state(sdev, POWER_DOWN);
1695 } else {
1696 rval = si4713_set_power_state(sdev, POWER_UP);
1697 if (rval < 0)
1698 goto exit;
1699
1700 rval = si4713_setup(sdev);
1701 if (rval < 0)
1702 goto exit;
1703
1704 rval = si4713_set_mute(sdev, ctrl->value);
1705 }
1706 break;
1707 }
1708
1709exit:
1710 return rval;
1711}
1712
1713/* si4713_ioctl - deal with private ioctls (only rnl for now) */
Mauro Carvalho Chehab0dec8682012-10-27 18:35:46 -02001714static long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
Eduardo Valentin02bee892009-08-08 08:46:53 -03001715{
1716 struct si4713_device *sdev = to_si4713_device(sd);
1717 struct si4713_rnl *rnl = arg;
1718 u16 frequency;
1719 int rval = 0;
1720
1721 if (!arg)
1722 return -EINVAL;
1723
Eduardo Valentin02bee892009-08-08 08:46:53 -03001724 switch (cmd) {
1725 case SI4713_IOC_MEASURE_RNL:
1726 frequency = v4l2_to_si4713(rnl->frequency);
1727
1728 if (sdev->power_state) {
1729 /* Set desired measurement frequency */
1730 rval = si4713_tx_tune_measure(sdev, frequency, 0);
1731 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001732 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001733 /* get results from tune status */
1734 rval = si4713_update_tune_status(sdev);
1735 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001736 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001737 }
1738 rnl->rnl = sdev->tune_rnl;
1739 break;
1740
1741 default:
1742 /* nothing */
1743 rval = -ENOIOCTLCMD;
1744 }
1745
Eduardo Valentin02bee892009-08-08 08:46:53 -03001746 return rval;
1747}
1748
1749static const struct v4l2_subdev_core_ops si4713_subdev_core_ops = {
1750 .queryctrl = si4713_queryctrl,
1751 .g_ext_ctrls = si4713_g_ext_ctrls,
1752 .s_ext_ctrls = si4713_s_ext_ctrls,
1753 .g_ctrl = si4713_g_ctrl,
1754 .s_ctrl = si4713_s_ctrl,
1755 .ioctl = si4713_ioctl,
1756};
1757
1758/* si4713_g_modulator - get modulator attributes */
1759static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1760{
1761 struct si4713_device *sdev = to_si4713_device(sd);
1762 int rval = 0;
1763
Hans Verkuil55b2a312013-04-08 06:31:30 -03001764 if (!sdev)
1765 return -ENODEV;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001766
Hans Verkuil55b2a312013-04-08 06:31:30 -03001767 if (vm->index > 0)
1768 return -EINVAL;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001769
1770 strncpy(vm->name, "FM Modulator", 32);
1771 vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW |
Matti Aaltonencb0ed222010-10-18 06:54:14 -03001772 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001773
1774 /* Report current frequency range limits */
1775 vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW);
1776 vm->rangehigh = si4713_to_v4l2(FREQ_RANGE_HIGH);
1777
Eduardo Valentin02bee892009-08-08 08:46:53 -03001778 if (sdev->power_state) {
1779 u32 comp_en = 0;
1780
1781 rval = si4713_read_property(sdev, SI4713_TX_COMPONENT_ENABLE,
1782 &comp_en);
1783 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001784 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001785
1786 sdev->stereo = get_status_bit(comp_en, 1, 1 << 1);
1787 sdev->rds_info.enabled = get_status_bit(comp_en, 2, 1 << 2);
1788 }
1789
1790 /* Report current audio mode: mono or stereo */
1791 if (sdev->stereo)
1792 vm->txsubchans = V4L2_TUNER_SUB_STEREO;
1793 else
1794 vm->txsubchans = V4L2_TUNER_SUB_MONO;
1795
1796 /* Report rds feature status */
1797 if (sdev->rds_info.enabled)
1798 vm->txsubchans |= V4L2_TUNER_SUB_RDS;
1799 else
1800 vm->txsubchans &= ~V4L2_TUNER_SUB_RDS;
1801
Eduardo Valentin02bee892009-08-08 08:46:53 -03001802 return rval;
1803}
1804
1805/* si4713_s_modulator - set modulator attributes */
Hans Verkuil3f70e1f2012-09-04 12:08:47 -03001806static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulator *vm)
Eduardo Valentin02bee892009-08-08 08:46:53 -03001807{
1808 struct si4713_device *sdev = to_si4713_device(sd);
1809 int rval = 0;
1810 u16 stereo, rds;
1811 u32 p;
1812
Hans Verkuila65f3152009-08-31 17:21:04 -03001813 if (!sdev)
1814 return -ENODEV;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001815
Hans Verkuila65f3152009-08-31 17:21:04 -03001816 if (vm->index > 0)
1817 return -EINVAL;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001818
1819 /* Set audio mode: mono or stereo */
1820 if (vm->txsubchans & V4L2_TUNER_SUB_STEREO)
1821 stereo = 1;
1822 else if (vm->txsubchans & V4L2_TUNER_SUB_MONO)
1823 stereo = 0;
1824 else
Hans Verkuila65f3152009-08-31 17:21:04 -03001825 return -EINVAL;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001826
1827 rds = !!(vm->txsubchans & V4L2_TUNER_SUB_RDS);
1828
Eduardo Valentin02bee892009-08-08 08:46:53 -03001829 if (sdev->power_state) {
1830 rval = si4713_read_property(sdev,
1831 SI4713_TX_COMPONENT_ENABLE, &p);
1832 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001833 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001834
1835 p = set_bits(p, stereo, 1, 1 << 1);
1836 p = set_bits(p, rds, 2, 1 << 2);
1837
1838 rval = si4713_write_property(sdev,
1839 SI4713_TX_COMPONENT_ENABLE, p);
1840 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001841 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001842 }
1843
1844 sdev->stereo = stereo;
1845 sdev->rds_info.enabled = rds;
1846
Eduardo Valentin02bee892009-08-08 08:46:53 -03001847 return rval;
1848}
1849
1850/* si4713_g_frequency - get tuner or modulator radio frequency */
1851static int si4713_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
1852{
1853 struct si4713_device *sdev = to_si4713_device(sd);
1854 int rval = 0;
1855
Hans Verkuilb3877542013-04-08 17:25:05 -03001856 if (f->tuner)
1857 return -EINVAL;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001858
Eduardo Valentin02bee892009-08-08 08:46:53 -03001859 if (sdev->power_state) {
1860 u16 freq;
1861 u8 p, a, n;
1862
1863 rval = si4713_tx_tune_status(sdev, 0x00, &freq, &p, &a, &n);
1864 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001865 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001866
1867 sdev->frequency = freq;
1868 }
1869
1870 f->frequency = si4713_to_v4l2(sdev->frequency);
1871
Eduardo Valentin02bee892009-08-08 08:46:53 -03001872 return rval;
1873}
1874
1875/* si4713_s_frequency - set tuner or modulator radio frequency */
Hans Verkuilb530a442013-03-19 04:09:26 -03001876static int si4713_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *f)
Eduardo Valentin02bee892009-08-08 08:46:53 -03001877{
1878 struct si4713_device *sdev = to_si4713_device(sd);
1879 int rval = 0;
1880 u16 frequency = v4l2_to_si4713(f->frequency);
1881
Hans Verkuilb3877542013-04-08 17:25:05 -03001882 if (f->tuner)
1883 return -EINVAL;
1884
Eduardo Valentin02bee892009-08-08 08:46:53 -03001885 /* Check frequency range */
Hans Verkuilb3877542013-04-08 17:25:05 -03001886 frequency = clamp_t(u16, frequency, FREQ_RANGE_LOW, FREQ_RANGE_HIGH);
Eduardo Valentin02bee892009-08-08 08:46:53 -03001887
Eduardo Valentin02bee892009-08-08 08:46:53 -03001888 if (sdev->power_state) {
1889 rval = si4713_tx_tune_freq(sdev, frequency);
1890 if (rval < 0)
Hans Verkuil55b2a312013-04-08 06:31:30 -03001891 return rval;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001892 frequency = rval;
1893 rval = 0;
1894 }
1895 sdev->frequency = frequency;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001896
Eduardo Valentin02bee892009-08-08 08:46:53 -03001897 return rval;
1898}
1899
1900static const struct v4l2_subdev_tuner_ops si4713_subdev_tuner_ops = {
1901 .g_frequency = si4713_g_frequency,
1902 .s_frequency = si4713_s_frequency,
1903 .g_modulator = si4713_g_modulator,
1904 .s_modulator = si4713_s_modulator,
1905};
1906
1907static const struct v4l2_subdev_ops si4713_subdev_ops = {
1908 .core = &si4713_subdev_core_ops,
1909 .tuner = &si4713_subdev_tuner_ops,
1910};
1911
1912/*
1913 * I2C driver interface
1914 */
1915/* si4713_probe - probe for the device */
1916static int si4713_probe(struct i2c_client *client,
1917 const struct i2c_device_id *id)
1918{
1919 struct si4713_device *sdev;
Jarkko Nikula00df0552010-10-29 11:31:39 -03001920 struct si4713_platform_data *pdata = client->dev.platform_data;
1921 int rval, i;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001922
1923 sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
1924 if (!sdev) {
1925 dev_err(&client->dev, "Failed to alloc video device.\n");
1926 rval = -ENOMEM;
1927 goto exit;
1928 }
1929
Jarkko Nikula00df0552010-10-29 11:31:39 -03001930 sdev->gpio_reset = -1;
1931 if (pdata && gpio_is_valid(pdata->gpio_reset)) {
1932 rval = gpio_request(pdata->gpio_reset, "si4713 reset");
1933 if (rval) {
1934 dev_err(&client->dev,
1935 "Failed to request gpio: %d\n", rval);
1936 goto free_sdev;
1937 }
1938 sdev->gpio_reset = pdata->gpio_reset;
1939 gpio_direction_output(sdev->gpio_reset, 0);
1940 }
1941
1942 for (i = 0; i < ARRAY_SIZE(sdev->supplies); i++)
1943 sdev->supplies[i].supply = si4713_supply_names[i];
1944
1945 rval = regulator_bulk_get(&client->dev, ARRAY_SIZE(sdev->supplies),
1946 sdev->supplies);
1947 if (rval) {
1948 dev_err(&client->dev, "Cannot get regulators: %d\n", rval);
1949 goto free_gpio;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001950 }
1951
1952 v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
1953
Eduardo Valentin02bee892009-08-08 08:46:53 -03001954 init_completion(&sdev->work);
1955
1956 if (client->irq) {
1957 rval = request_irq(client->irq,
1958 si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
1959 client->name, sdev);
1960 if (rval < 0) {
1961 v4l2_err(&sdev->sd, "Could not request IRQ\n");
Jarkko Nikula00df0552010-10-29 11:31:39 -03001962 goto put_reg;
Eduardo Valentin02bee892009-08-08 08:46:53 -03001963 }
1964 v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
1965 } else {
1966 v4l2_warn(&sdev->sd, "IRQ not configured. Using timeouts.\n");
1967 }
1968
1969 rval = si4713_initialize(sdev);
1970 if (rval < 0) {
1971 v4l2_err(&sdev->sd, "Failed to probe device information.\n");
1972 goto free_irq;
1973 }
1974
1975 return 0;
1976
1977free_irq:
1978 if (client->irq)
1979 free_irq(client->irq, sdev);
Jarkko Nikula00df0552010-10-29 11:31:39 -03001980put_reg:
1981 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
1982free_gpio:
1983 if (gpio_is_valid(sdev->gpio_reset))
1984 gpio_free(sdev->gpio_reset);
Eduardo Valentin02bee892009-08-08 08:46:53 -03001985free_sdev:
1986 kfree(sdev);
1987exit:
1988 return rval;
1989}
1990
1991/* si4713_remove - remove the device */
1992static int si4713_remove(struct i2c_client *client)
1993{
1994 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1995 struct si4713_device *sdev = to_si4713_device(sd);
1996
1997 if (sdev->power_state)
1998 si4713_set_power_state(sdev, POWER_DOWN);
1999
2000 if (client->irq > 0)
2001 free_irq(client->irq, sdev);
2002
2003 v4l2_device_unregister_subdev(sd);
Jarkko Nikula00df0552010-10-29 11:31:39 -03002004 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
2005 if (gpio_is_valid(sdev->gpio_reset))
2006 gpio_free(sdev->gpio_reset);
Eduardo Valentin02bee892009-08-08 08:46:53 -03002007 kfree(sdev);
2008
2009 return 0;
2010}
2011
2012/* si4713_i2c_driver - i2c driver interface */
2013static const struct i2c_device_id si4713_id[] = {
2014 { "si4713" , 0 },
2015 { },
2016};
2017MODULE_DEVICE_TABLE(i2c, si4713_id);
2018
2019static struct i2c_driver si4713_i2c_driver = {
2020 .driver = {
2021 .name = "si4713",
2022 },
2023 .probe = si4713_probe,
2024 .remove = si4713_remove,
2025 .id_table = si4713_id,
2026};
2027
Axel Linc6e8d862012-02-12 06:56:32 -03002028module_i2c_driver(si4713_i2c_driver);