Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[deliverable/linux.git] / drivers / staging / media / bcm2048 / radio-bcm2048.c
CommitLineData
899127b6
HV
1/*
2 * drivers/staging/media/radio-bcm2048.c
3 *
4 * Driver for I2C Broadcom BCM2048 FM Radio Receiver:
5 *
6 * Copyright (C) Nokia Corporation
7 * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
8 *
9 * Copyright (C) Nils Faerber <nils.faerber@kernelconcepts.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26/*
27 * History:
28 * Eero Nurkkala <ext-eero.nurkkala@nokia.com>
29 * Version 0.0.1
30 * - Initial implementation
31 * 2010-02-21 Nils Faerber <nils.faerber@kernelconcepts.de>
32 * Version 0.0.2
33 * - Add support for interrupt driven rds data reading
34 */
35
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/init.h>
39#include <linux/version.h>
40#include <linux/interrupt.h>
41#include <linux/sysfs.h>
42#include <linux/completion.h>
43#include <linux/delay.h>
44#include <linux/i2c.h>
45#include <linux/videodev2.h>
46#include <linux/mutex.h>
47#include <linux/slab.h>
48#include <media/v4l2-common.h>
49#include <media/v4l2-ioctl.h>
50#include "radio-bcm2048.h"
51
52/* driver definitions */
53#define BCM2048_DRIVER_AUTHOR "Eero Nurkkala <ext-eero.nurkkala@nokia.com>"
54#define BCM2048_DRIVER_NAME BCM2048_NAME
55#define BCM2048_DRIVER_VERSION KERNEL_VERSION(0, 0, 1)
56#define BCM2048_DRIVER_CARD "Broadcom bcm2048 FM Radio Receiver"
57#define BCM2048_DRIVER_DESC "I2C driver for BCM2048 FM Radio Receiver"
58
59/* I2C Control Registers */
60#define BCM2048_I2C_FM_RDS_SYSTEM 0x00
61#define BCM2048_I2C_FM_CTRL 0x01
62#define BCM2048_I2C_RDS_CTRL0 0x02
63#define BCM2048_I2C_RDS_CTRL1 0x03
64#define BCM2048_I2C_FM_AUDIO_PAUSE 0x04
65#define BCM2048_I2C_FM_AUDIO_CTRL0 0x05
66#define BCM2048_I2C_FM_AUDIO_CTRL1 0x06
67#define BCM2048_I2C_FM_SEARCH_CTRL0 0x07
68#define BCM2048_I2C_FM_SEARCH_CTRL1 0x08
69#define BCM2048_I2C_FM_SEARCH_TUNE_MODE 0x09
70#define BCM2048_I2C_FM_FREQ0 0x0a
71#define BCM2048_I2C_FM_FREQ1 0x0b
72#define BCM2048_I2C_FM_AF_FREQ0 0x0c
73#define BCM2048_I2C_FM_AF_FREQ1 0x0d
74#define BCM2048_I2C_FM_CARRIER 0x0e
75#define BCM2048_I2C_FM_RSSI 0x0f
76#define BCM2048_I2C_FM_RDS_MASK0 0x10
77#define BCM2048_I2C_FM_RDS_MASK1 0x11
78#define BCM2048_I2C_FM_RDS_FLAG0 0x12
79#define BCM2048_I2C_FM_RDS_FLAG1 0x13
80#define BCM2048_I2C_RDS_WLINE 0x14
81#define BCM2048_I2C_RDS_BLKB_MATCH0 0x16
82#define BCM2048_I2C_RDS_BLKB_MATCH1 0x17
83#define BCM2048_I2C_RDS_BLKB_MASK0 0x18
84#define BCM2048_I2C_RDS_BLKB_MASK1 0x19
85#define BCM2048_I2C_RDS_PI_MATCH0 0x1a
86#define BCM2048_I2C_RDS_PI_MATCH1 0x1b
87#define BCM2048_I2C_RDS_PI_MASK0 0x1c
88#define BCM2048_I2C_RDS_PI_MASK1 0x1d
89#define BCM2048_I2C_SPARE1 0x20
90#define BCM2048_I2C_SPARE2 0x21
91#define BCM2048_I2C_FM_RDS_REV 0x28
92#define BCM2048_I2C_SLAVE_CONFIGURATION 0x29
93#define BCM2048_I2C_RDS_DATA 0x80
94#define BCM2048_I2C_FM_BEST_TUNE_MODE 0x90
95
96/* BCM2048_I2C_FM_RDS_SYSTEM */
97#define BCM2048_FM_ON 0x01
98#define BCM2048_RDS_ON 0x02
99
100/* BCM2048_I2C_FM_CTRL */
101#define BCM2048_BAND_SELECT 0x01
102#define BCM2048_STEREO_MONO_AUTO_SELECT 0x02
103#define BCM2048_STEREO_MONO_MANUAL_SELECT 0x04
104#define BCM2048_STEREO_MONO_BLEND_SWITCH 0x08
105#define BCM2048_HI_LO_INJECTION 0x10
106
107/* BCM2048_I2C_RDS_CTRL0 */
108#define BCM2048_RBDS_RDS_SELECT 0x01
109#define BCM2048_FLUSH_FIFO 0x02
110
111/* BCM2048_I2C_FM_AUDIO_PAUSE */
112#define BCM2048_AUDIO_PAUSE_RSSI_TRESH 0x0f
113#define BCM2048_AUDIO_PAUSE_DURATION 0xf0
114
115/* BCM2048_I2C_FM_AUDIO_CTRL0 */
116#define BCM2048_RF_MUTE 0x01
117#define BCM2048_MANUAL_MUTE 0x02
118#define BCM2048_DAC_OUTPUT_LEFT 0x04
119#define BCM2048_DAC_OUTPUT_RIGHT 0x08
120#define BCM2048_AUDIO_ROUTE_DAC 0x10
121#define BCM2048_AUDIO_ROUTE_I2S 0x20
122#define BCM2048_DE_EMPHASIS_SELECT 0x40
123#define BCM2048_AUDIO_BANDWIDTH_SELECT 0x80
124
125/* BCM2048_I2C_FM_SEARCH_CTRL0 */
126#define BCM2048_SEARCH_RSSI_THRESHOLD 0x7f
127#define BCM2048_SEARCH_DIRECTION 0x80
128
129/* BCM2048_I2C_FM_SEARCH_TUNE_MODE */
130#define BCM2048_FM_AUTO_SEARCH 0x03
131
132/* BCM2048_I2C_FM_RSSI */
133#define BCM2048_RSSI_VALUE 0xff
134
135/* BCM2048_I2C_FM_RDS_MASK0 */
136/* BCM2048_I2C_FM_RDS_MASK1 */
137#define BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED 0x01
138#define BCM2048_FM_FLAG_SEARCH_TUNE_FAIL 0x02
139#define BCM2048_FM_FLAG_RSSI_LOW 0x04
140#define BCM2048_FM_FLAG_CARRIER_ERROR_HIGH 0x08
141#define BCM2048_FM_FLAG_AUDIO_PAUSE_INDICATION 0x10
142#define BCM2048_FLAG_STEREO_DETECTED 0x20
143#define BCM2048_FLAG_STEREO_ACTIVE 0x40
144
145/* BCM2048_I2C_RDS_DATA */
146#define BCM2048_SLAVE_ADDRESS 0x3f
147#define BCM2048_SLAVE_ENABLE 0x80
148
149/* BCM2048_I2C_FM_BEST_TUNE_MODE */
150#define BCM2048_BEST_TUNE_MODE 0x80
151
152#define BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED 0x01
153#define BCM2048_FM_FLAG_SEARCH_TUNE_FAIL 0x02
154#define BCM2048_FM_FLAG_RSSI_LOW 0x04
155#define BCM2048_FM_FLAG_CARRIER_ERROR_HIGH 0x08
156#define BCM2048_FM_FLAG_AUDIO_PAUSE_INDICATION 0x10
157#define BCM2048_FLAG_STEREO_DETECTED 0x20
158#define BCM2048_FLAG_STEREO_ACTIVE 0x40
159
160#define BCM2048_RDS_FLAG_FIFO_WLINE 0x02
161#define BCM2048_RDS_FLAG_B_BLOCK_MATCH 0x08
162#define BCM2048_RDS_FLAG_SYNC_LOST 0x10
163#define BCM2048_RDS_FLAG_PI_MATCH 0x20
164
165#define BCM2048_RDS_MARK_END_BYTE0 0x7C
166#define BCM2048_RDS_MARK_END_BYTEN 0xFF
167
168#define BCM2048_FM_FLAGS_ALL (FM_FLAG_SEARCH_TUNE_FINISHED | \
169 FM_FLAG_SEARCH_TUNE_FAIL | \
170 FM_FLAG_RSSI_LOW | \
171 FM_FLAG_CARRIER_ERROR_HIGH | \
172 FM_FLAG_AUDIO_PAUSE_INDICATION | \
173 FLAG_STEREO_DETECTED | FLAG_STEREO_ACTIVE)
174
175#define BCM2048_RDS_FLAGS_ALL (RDS_FLAG_FIFO_WLINE | \
176 RDS_FLAG_B_BLOCK_MATCH | \
177 RDS_FLAG_SYNC_LOST | RDS_FLAG_PI_MATCH)
178
179#define BCM2048_DEFAULT_TIMEOUT 1500
180#define BCM2048_AUTO_SEARCH_TIMEOUT 3000
181
899127b6
HV
182#define BCM2048_FREQDEV_UNIT 10000
183#define BCM2048_FREQV4L2_MULTI 625
184#define dev_to_v4l2(f) ((f * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI)
185#define v4l2_to_dev(f) ((f * BCM2048_FREQV4L2_MULTI) / BCM2048_FREQDEV_UNIT)
186
cf2f3408
AG
187#define msb(x) ((u8)((u16)x >> 8))
188#define lsb(x) ((u8)((u16)x & 0x00FF))
899127b6
HV
189#define compose_u16(msb, lsb) (((u16)msb << 8) | lsb)
190
191#define BCM2048_DEFAULT_POWERING_DELAY 20
192#define BCM2048_DEFAULT_REGION 0x02
193#define BCM2048_DEFAULT_MUTE 0x01
194#define BCM2048_DEFAULT_RSSI_THRESHOLD 0x64
195#define BCM2048_DEFAULT_RDS_WLINE 0x7E
196
197#define BCM2048_FM_SEARCH_INACTIVE 0x00
198#define BCM2048_FM_PRE_SET_MODE 0x01
199#define BCM2048_FM_AUTO_SEARCH_MODE 0x02
200#define BCM2048_FM_AF_JUMP_MODE 0x03
201
202#define BCM2048_FREQUENCY_BASE 64000
203
204#define BCM2048_POWER_ON 0x01
205#define BCM2048_POWER_OFF 0x00
206
207#define BCM2048_ITEM_ENABLED 0x01
208#define BCM2048_SEARCH_DIRECTION_UP 0x01
209
210#define BCM2048_DE_EMPHASIS_75us 75
211#define BCM2048_DE_EMPHASIS_50us 50
212
213#define BCM2048_SCAN_FAIL 0x00
214#define BCM2048_SCAN_OK 0x01
215
216#define BCM2048_FREQ_ERROR_FLOOR -20
217#define BCM2048_FREQ_ERROR_ROOF 20
218
69e98df7 219/* -60 dB is reported as full signal strength */
899127b6
HV
220#define BCM2048_RSSI_LEVEL_BASE -60
221#define BCM2048_RSSI_LEVEL_ROOF -100
222#define BCM2048_RSSI_LEVEL_ROOF_NEG 100
223#define BCM2048_SIGNAL_MULTIPLIER (0xFFFF / \
224 (BCM2048_RSSI_LEVEL_ROOF_NEG + \
225 BCM2048_RSSI_LEVEL_BASE))
226
227#define BCM2048_RDS_FIFO_DUPLE_SIZE 0x03
228#define BCM2048_RDS_CRC_MASK 0x0F
229#define BCM2048_RDS_CRC_NONE 0x00
230#define BCM2048_RDS_CRC_MAX_2BITS 0x04
231#define BCM2048_RDS_CRC_LEAST_2BITS 0x08
232#define BCM2048_RDS_CRC_UNRECOVARABLE 0x0C
233
234#define BCM2048_RDS_BLOCK_MASK 0xF0
235#define BCM2048_RDS_BLOCK_A 0x00
236#define BCM2048_RDS_BLOCK_B 0x10
237#define BCM2048_RDS_BLOCK_C 0x20
238#define BCM2048_RDS_BLOCK_D 0x30
239#define BCM2048_RDS_BLOCK_C_SCORED 0x40
240#define BCM2048_RDS_BLOCK_E 0x60
241
242#define BCM2048_RDS_RT 0x20
243#define BCM2048_RDS_PS 0x00
244
245#define BCM2048_RDS_GROUP_AB_MASK 0x08
246#define BCM2048_RDS_GROUP_A 0x00
247#define BCM2048_RDS_GROUP_B 0x08
248
249#define BCM2048_RDS_RT_AB_MASK 0x10
250#define BCM2048_RDS_RT_A 0x00
251#define BCM2048_RDS_RT_B 0x10
252#define BCM2048_RDS_RT_INDEX 0x0F
253
254#define BCM2048_RDS_PS_INDEX 0x03
255
256struct rds_info {
257 u16 rds_pi;
258#define BCM2048_MAX_RDS_RT (64 + 1)
259 u8 rds_rt[BCM2048_MAX_RDS_RT];
260 u8 rds_rt_group_b;
261 u8 rds_rt_ab;
262#define BCM2048_MAX_RDS_PS (8 + 1)
263 u8 rds_ps[BCM2048_MAX_RDS_PS];
264 u8 rds_ps_group;
265 u8 rds_ps_group_cnt;
266#define BCM2048_MAX_RDS_RADIO_TEXT 255
267 u8 radio_text[BCM2048_MAX_RDS_RADIO_TEXT + 3];
268 u8 text_len;
269};
270
271struct region_info {
272 u32 bottom_frequency;
273 u32 top_frequency;
274 u8 deemphasis;
275 u8 channel_spacing;
276 u8 region;
277};
278
279struct bcm2048_device {
280 struct i2c_client *client;
54ad7b9d 281 struct video_device videodev;
899127b6
HV
282 struct work_struct work;
283 struct completion compl;
284 struct mutex mutex;
285 struct bcm2048_platform_data *platform_data;
286 struct rds_info rds_info;
287 struct region_info region_info;
288 u16 frequency;
289 u8 cache_fm_rds_system;
290 u8 cache_fm_ctrl;
291 u8 cache_fm_audio_ctrl0;
292 u8 cache_fm_search_ctrl0;
293 u8 power_state;
294 u8 rds_state;
295 u8 fifo_size;
296 u8 scan_state;
297 u8 mute_state;
298
299 /* for rds data device read */
300 wait_queue_head_t read_queue;
301 unsigned int users;
302 unsigned char rds_data_available;
303 unsigned int rd_index;
304};
305
306static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */
307module_param(radio_nr, int, 0);
308MODULE_PARM_DESC(radio_nr,
309 "Minor number for radio device (-1 ==> auto assign)");
310
b05a4fa6 311static const struct region_info region_configs[] = {
899127b6
HV
312 /* USA */
313 {
314 .channel_spacing = 20,
315 .bottom_frequency = 87500,
316 .top_frequency = 108000,
317 .deemphasis = 75,
318 .region = 0,
319 },
320 /* Australia */
321 {
322 .channel_spacing = 20,
323 .bottom_frequency = 87500,
324 .top_frequency = 108000,
325 .deemphasis = 50,
326 .region = 1,
327 },
328 /* Europe */
329 {
330 .channel_spacing = 10,
331 .bottom_frequency = 87500,
332 .top_frequency = 108000,
333 .deemphasis = 50,
334 .region = 2,
335 },
336 /* Japan */
337 {
338 .channel_spacing = 10,
339 .bottom_frequency = 76000,
340 .top_frequency = 90000,
341 .deemphasis = 50,
342 .region = 3,
343 },
899127b6
HV
344};
345
346/*
347 * I2C Interface read / write
348 */
349static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg,
925b6578 350 unsigned int value)
899127b6
HV
351{
352 struct i2c_client *client = bdev->client;
353 u8 data[2];
354
355 if (!bdev->power_state) {
356 dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
357 return -EIO;
358 }
359
360 data[0] = reg & 0xff;
361 data[1] = value & 0xff;
362
b317d0f5 363 if (i2c_master_send(client, data, 2) == 2)
899127b6 364 return 0;
b317d0f5
LH
365
366 dev_err(&bdev->client->dev, "BCM I2C error!\n");
367 dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
368 return -EIO;
899127b6
HV
369}
370
371static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg,
925b6578 372 u8 *value)
899127b6
HV
373{
374 struct i2c_client *client = bdev->client;
375
376 if (!bdev->power_state) {
377 dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
378 return -EIO;
379 }
380
381 value[0] = i2c_smbus_read_byte_data(client, reg & 0xff);
382
383 return 0;
384}
385
386static int bcm2048_recv_duples(struct bcm2048_device *bdev, unsigned int reg,
925b6578 387 u8 *value, u8 duples)
899127b6
HV
388{
389 struct i2c_client *client = bdev->client;
390 struct i2c_adapter *adap = client->adapter;
391 struct i2c_msg msg[2];
392 u8 buf;
393
394 if (!bdev->power_state) {
395 dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
396 return -EIO;
397 }
398
399 buf = reg & 0xff;
400
401 msg[0].addr = client->addr;
402 msg[0].flags = client->flags & I2C_M_TEN;
403 msg[0].len = 1;
404 msg[0].buf = &buf;
405
406 msg[1].addr = client->addr;
407 msg[1].flags = client->flags & I2C_M_TEN;
408 msg[1].flags |= I2C_M_RD;
409 msg[1].len = duples;
410 msg[1].buf = value;
411
412 return i2c_transfer(adap, msg, 2);
413}
414
415/*
416 * BCM2048 - I2C register programming helpers
417 */
418static int bcm2048_set_power_state(struct bcm2048_device *bdev, u8 power)
419{
420 int err = 0;
421
422 mutex_lock(&bdev->mutex);
423
424 if (power) {
425 bdev->power_state = BCM2048_POWER_ON;
426 bdev->cache_fm_rds_system |= BCM2048_FM_ON;
427 } else {
428 bdev->cache_fm_rds_system &= ~BCM2048_FM_ON;
429 }
430
431 /*
432 * Warning! FM cannot be turned off because then
433 * the I2C communications get ruined!
434 * Comment off the "if (power)" when the chip works!
435 */
436 if (power)
437 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
925b6578 438 bdev->cache_fm_rds_system);
899127b6
HV
439 msleep(BCM2048_DEFAULT_POWERING_DELAY);
440
441 if (!power)
442 bdev->power_state = BCM2048_POWER_OFF;
443
444 mutex_unlock(&bdev->mutex);
445 return err;
446}
447
448static int bcm2048_get_power_state(struct bcm2048_device *bdev)
449{
450 int err;
451 u8 value;
452
453 mutex_lock(&bdev->mutex);
454
455 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, &value);
456
457 mutex_unlock(&bdev->mutex);
458
459 if (!err && (value & BCM2048_FM_ON))
460 return BCM2048_POWER_ON;
461
462 return err;
463}
464
465static int bcm2048_set_rds_no_lock(struct bcm2048_device *bdev, u8 rds_on)
466{
467 int err;
468 u8 flags;
469
470 bdev->cache_fm_rds_system &= ~BCM2048_RDS_ON;
471
472 if (rds_on) {
473 bdev->cache_fm_rds_system |= BCM2048_RDS_ON;
474 bdev->rds_state = BCM2048_RDS_ON;
475 flags = BCM2048_RDS_FLAG_FIFO_WLINE;
476 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
925b6578 477 flags);
899127b6
HV
478 } else {
479 flags = 0;
480 bdev->rds_state = 0;
481 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
925b6578 482 flags);
899127b6
HV
483 memset(&bdev->rds_info, 0, sizeof(bdev->rds_info));
484 }
485
486 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
925b6578 487 bdev->cache_fm_rds_system);
899127b6
HV
488
489 return err;
490}
491
492static int bcm2048_get_rds_no_lock(struct bcm2048_device *bdev)
493{
494 int err;
495 u8 value;
496
497 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, &value);
498
499 if (!err && (value & BCM2048_RDS_ON))
500 return BCM2048_ITEM_ENABLED;
501
502 return err;
503}
504
505static int bcm2048_set_rds(struct bcm2048_device *bdev, u8 rds_on)
506{
507 int err;
508
509 mutex_lock(&bdev->mutex);
510
511 err = bcm2048_set_rds_no_lock(bdev, rds_on);
512
513 mutex_unlock(&bdev->mutex);
514 return err;
515}
516
517static int bcm2048_get_rds(struct bcm2048_device *bdev)
518{
519 int err;
520
521 mutex_lock(&bdev->mutex);
522
523 err = bcm2048_get_rds_no_lock(bdev);
524
525 mutex_unlock(&bdev->mutex);
526 return err;
527}
528
529static int bcm2048_get_rds_pi(struct bcm2048_device *bdev)
530{
531 return bdev->rds_info.rds_pi;
532}
533
534static int bcm2048_set_fm_automatic_stereo_mono(struct bcm2048_device *bdev,
535 u8 enabled)
536{
537 int err;
538
539 mutex_lock(&bdev->mutex);
540
541 bdev->cache_fm_ctrl &= ~BCM2048_STEREO_MONO_AUTO_SELECT;
542
543 if (enabled)
544 bdev->cache_fm_ctrl |= BCM2048_STEREO_MONO_AUTO_SELECT;
545
546 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
925b6578 547 bdev->cache_fm_ctrl);
899127b6
HV
548
549 mutex_unlock(&bdev->mutex);
550 return err;
551}
552
553static int bcm2048_set_fm_hi_lo_injection(struct bcm2048_device *bdev,
925b6578 554 u8 hi_lo)
899127b6
HV
555{
556 int err;
557
558 mutex_lock(&bdev->mutex);
559
560 bdev->cache_fm_ctrl &= ~BCM2048_HI_LO_INJECTION;
561
562 if (hi_lo)
563 bdev->cache_fm_ctrl |= BCM2048_HI_LO_INJECTION;
564
565 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
925b6578 566 bdev->cache_fm_ctrl);
899127b6
HV
567
568 mutex_unlock(&bdev->mutex);
569 return err;
570}
571
572static int bcm2048_get_fm_hi_lo_injection(struct bcm2048_device *bdev)
573{
574 int err;
575 u8 value;
576
577 mutex_lock(&bdev->mutex);
578
579 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_CTRL, &value);
580
581 mutex_unlock(&bdev->mutex);
582
583 if (!err && (value & BCM2048_HI_LO_INJECTION))
584 return BCM2048_ITEM_ENABLED;
585
586 return err;
587}
588
589static int bcm2048_set_fm_frequency(struct bcm2048_device *bdev, u32 frequency)
590{
591 int err;
592
593 if (frequency < bdev->region_info.bottom_frequency ||
925b6578 594 frequency > bdev->region_info.top_frequency)
899127b6
HV
595 return -EDOM;
596
597 frequency -= BCM2048_FREQUENCY_BASE;
598
599 mutex_lock(&bdev->mutex);
600
601 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ0, lsb(frequency));
602 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ1,
925b6578 603 msb(frequency));
899127b6
HV
604
605 if (!err)
606 bdev->frequency = frequency;
607
608 mutex_unlock(&bdev->mutex);
609 return err;
610}
611
612static int bcm2048_get_fm_frequency(struct bcm2048_device *bdev)
613{
614 int err;
a1f8c0cf 615 u8 lsb = 0, msb = 0;
899127b6
HV
616
617 mutex_lock(&bdev->mutex);
618
619 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_FREQ0, &lsb);
620 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_FREQ1, &msb);
621
622 mutex_unlock(&bdev->mutex);
623
624 if (err)
625 return err;
626
627 err = compose_u16(msb, lsb);
628 err += BCM2048_FREQUENCY_BASE;
629
630 return err;
631}
632
633static int bcm2048_set_fm_af_frequency(struct bcm2048_device *bdev,
925b6578 634 u32 frequency)
899127b6
HV
635{
636 int err;
637
638 if (frequency < bdev->region_info.bottom_frequency ||
925b6578 639 frequency > bdev->region_info.top_frequency)
899127b6
HV
640 return -EDOM;
641
642 frequency -= BCM2048_FREQUENCY_BASE;
643
644 mutex_lock(&bdev->mutex);
645
646 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ0,
925b6578 647 lsb(frequency));
899127b6 648 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ1,
925b6578 649 msb(frequency));
899127b6
HV
650 if (!err)
651 bdev->frequency = frequency;
652
653 mutex_unlock(&bdev->mutex);
654 return err;
655}
656
657static int bcm2048_get_fm_af_frequency(struct bcm2048_device *bdev)
658{
659 int err;
a1f8c0cf 660 u8 lsb = 0, msb = 0;
899127b6
HV
661
662 mutex_lock(&bdev->mutex);
663
664 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AF_FREQ0, &lsb);
665 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_AF_FREQ1, &msb);
666
667 mutex_unlock(&bdev->mutex);
668
669 if (err)
670 return err;
671
672 err = compose_u16(msb, lsb);
673 err += BCM2048_FREQUENCY_BASE;
674
675 return err;
676}
677
678static int bcm2048_set_fm_deemphasis(struct bcm2048_device *bdev, int d)
679{
680 int err;
681 u8 deemphasis;
682
683 if (d == BCM2048_DE_EMPHASIS_75us)
684 deemphasis = BCM2048_DE_EMPHASIS_SELECT;
685 else
686 deemphasis = 0;
687
688 mutex_lock(&bdev->mutex);
689
690 bdev->cache_fm_audio_ctrl0 &= ~BCM2048_DE_EMPHASIS_SELECT;
691 bdev->cache_fm_audio_ctrl0 |= deemphasis;
692
693 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
925b6578 694 bdev->cache_fm_audio_ctrl0);
899127b6
HV
695
696 if (!err)
697 bdev->region_info.deemphasis = d;
698
699 mutex_unlock(&bdev->mutex);
700
701 return err;
702}
703
704static int bcm2048_get_fm_deemphasis(struct bcm2048_device *bdev)
705{
706 int err;
707 u8 value;
708
709 mutex_lock(&bdev->mutex);
710
711 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
712
713 mutex_unlock(&bdev->mutex);
714
715 if (!err) {
716 if (value & BCM2048_DE_EMPHASIS_SELECT)
717 return BCM2048_DE_EMPHASIS_75us;
b317d0f5
LH
718
719 return BCM2048_DE_EMPHASIS_50us;
899127b6
HV
720 }
721
722 return err;
723}
724
725static int bcm2048_set_region(struct bcm2048_device *bdev, u8 region)
726{
727 int err;
728 u32 new_frequency = 0;
729
5d60122b 730 if (region >= ARRAY_SIZE(region_configs))
899127b6
HV
731 return -EINVAL;
732
733 mutex_lock(&bdev->mutex);
65eccc7a 734 bdev->region_info = region_configs[region];
e6cf0c40
JR
735
736 if (region_configs[region].bottom_frequency < 87500)
737 bdev->cache_fm_ctrl |= BCM2048_BAND_SELECT;
738 else
739 bdev->cache_fm_ctrl &= ~BCM2048_BAND_SELECT;
740
741 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
925b6578 742 bdev->cache_fm_ctrl);
e6cf0c40
JR
743 if (err) {
744 mutex_unlock(&bdev->mutex);
745 goto done;
746 }
899127b6
HV
747 mutex_unlock(&bdev->mutex);
748
749 if (bdev->frequency < region_configs[region].bottom_frequency ||
925b6578 750 bdev->frequency > region_configs[region].top_frequency)
899127b6
HV
751 new_frequency = region_configs[region].bottom_frequency;
752
753 if (new_frequency > 0) {
754 err = bcm2048_set_fm_frequency(bdev, new_frequency);
755
756 if (err)
757 goto done;
758 }
759
760 err = bcm2048_set_fm_deemphasis(bdev,
925b6578 761 region_configs[region].deemphasis);
899127b6
HV
762
763done:
764 return err;
765}
766
767static int bcm2048_get_region(struct bcm2048_device *bdev)
768{
769 int err;
770
771 mutex_lock(&bdev->mutex);
772 err = bdev->region_info.region;
773 mutex_unlock(&bdev->mutex);
774
775 return err;
776}
777
778static int bcm2048_set_mute(struct bcm2048_device *bdev, u16 mute)
779{
780 int err;
781
782 mutex_lock(&bdev->mutex);
783
784 bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE);
785
786 if (mute)
787 bdev->cache_fm_audio_ctrl0 |= (BCM2048_RF_MUTE |
925b6578 788 BCM2048_MANUAL_MUTE);
899127b6
HV
789
790 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
925b6578 791 bdev->cache_fm_audio_ctrl0);
899127b6
HV
792
793 if (!err)
794 bdev->mute_state = mute;
795
796 mutex_unlock(&bdev->mutex);
797 return err;
798}
799
800static int bcm2048_get_mute(struct bcm2048_device *bdev)
801{
802 int err;
803 u8 value;
804
805 mutex_lock(&bdev->mutex);
806
807 if (bdev->power_state) {
808 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
925b6578 809 &value);
899127b6
HV
810 if (!err)
811 err = value & (BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE);
812 } else {
813 err = bdev->mute_state;
814 }
815
816 mutex_unlock(&bdev->mutex);
817 return err;
818}
819
820static int bcm2048_set_audio_route(struct bcm2048_device *bdev, u8 route)
821{
822 int err;
823
824 mutex_lock(&bdev->mutex);
825
826 route &= (BCM2048_AUDIO_ROUTE_DAC | BCM2048_AUDIO_ROUTE_I2S);
827 bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_AUDIO_ROUTE_DAC |
925b6578 828 BCM2048_AUDIO_ROUTE_I2S);
899127b6
HV
829 bdev->cache_fm_audio_ctrl0 |= route;
830
831 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
925b6578 832 bdev->cache_fm_audio_ctrl0);
899127b6
HV
833
834 mutex_unlock(&bdev->mutex);
835 return err;
836}
837
838static int bcm2048_get_audio_route(struct bcm2048_device *bdev)
839{
840 int err;
841 u8 value;
842
843 mutex_lock(&bdev->mutex);
844
845 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
846
847 mutex_unlock(&bdev->mutex);
848
849 if (!err)
850 return value & (BCM2048_AUDIO_ROUTE_DAC |
925b6578 851 BCM2048_AUDIO_ROUTE_I2S);
899127b6
HV
852
853 return err;
854}
855
856static int bcm2048_set_dac_output(struct bcm2048_device *bdev, u8 channels)
857{
858 int err;
859
860 mutex_lock(&bdev->mutex);
861
862 bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_DAC_OUTPUT_LEFT |
863 BCM2048_DAC_OUTPUT_RIGHT);
864 bdev->cache_fm_audio_ctrl0 |= channels;
865
866 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
925b6578 867 bdev->cache_fm_audio_ctrl0);
899127b6
HV
868
869 mutex_unlock(&bdev->mutex);
870 return err;
871}
872
873static int bcm2048_get_dac_output(struct bcm2048_device *bdev)
874{
875 int err;
876 u8 value;
877
878 mutex_lock(&bdev->mutex);
879
880 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
881
882 mutex_unlock(&bdev->mutex);
883
884 if (!err)
885 return value & (BCM2048_DAC_OUTPUT_LEFT |
925b6578 886 BCM2048_DAC_OUTPUT_RIGHT);
899127b6
HV
887
888 return err;
889}
890
891static int bcm2048_set_fm_search_rssi_threshold(struct bcm2048_device *bdev,
925b6578 892 u8 threshold)
899127b6
HV
893{
894 int err;
895
896 mutex_lock(&bdev->mutex);
897
898 threshold &= BCM2048_SEARCH_RSSI_THRESHOLD;
899 bdev->cache_fm_search_ctrl0 &= ~BCM2048_SEARCH_RSSI_THRESHOLD;
900 bdev->cache_fm_search_ctrl0 |= threshold;
901
902 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0,
925b6578 903 bdev->cache_fm_search_ctrl0);
899127b6
HV
904
905 mutex_unlock(&bdev->mutex);
906 return err;
907}
908
909static int bcm2048_get_fm_search_rssi_threshold(struct bcm2048_device *bdev)
910{
911 int err;
912 u8 value;
913
914 mutex_lock(&bdev->mutex);
915
916 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, &value);
917
918 mutex_unlock(&bdev->mutex);
919
920 if (!err)
921 return value & BCM2048_SEARCH_RSSI_THRESHOLD;
922
923 return err;
924}
925
926static int bcm2048_set_fm_search_mode_direction(struct bcm2048_device *bdev,
927 u8 direction)
928{
929 int err;
930
931 mutex_lock(&bdev->mutex);
932
933 bdev->cache_fm_search_ctrl0 &= ~BCM2048_SEARCH_DIRECTION;
934
935 if (direction)
936 bdev->cache_fm_search_ctrl0 |= BCM2048_SEARCH_DIRECTION;
937
938 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0,
925b6578 939 bdev->cache_fm_search_ctrl0);
899127b6
HV
940
941 mutex_unlock(&bdev->mutex);
942 return err;
943}
944
945static int bcm2048_get_fm_search_mode_direction(struct bcm2048_device *bdev)
946{
947 int err;
948 u8 value;
949
950 mutex_lock(&bdev->mutex);
951
952 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, &value);
953
954 mutex_unlock(&bdev->mutex);
955
956 if (!err && (value & BCM2048_SEARCH_DIRECTION))
957 return BCM2048_SEARCH_DIRECTION_UP;
958
959 return err;
960}
961
962static int bcm2048_set_fm_search_tune_mode(struct bcm2048_device *bdev,
925b6578 963 u8 mode)
899127b6
HV
964{
965 int err, timeout, restart_rds = 0;
966 u8 value, flags;
967
968 value = mode & BCM2048_FM_AUTO_SEARCH;
969
970 flags = BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
971 BCM2048_FM_FLAG_SEARCH_TUNE_FAIL;
972
973 mutex_lock(&bdev->mutex);
974
975 /*
976 * If RDS is enabled, and frequency is changed, RDS quits working.
977 * Thus, always restart RDS if it's enabled. Moreover, RDS must
978 * not be enabled while changing the frequency because it can
979 * provide a race to the mutex from the workqueue handler if RDS
980 * IRQ occurs while waiting for frequency changed IRQ.
981 */
982 if (bcm2048_get_rds_no_lock(bdev)) {
983 err = bcm2048_set_rds_no_lock(bdev, 0);
984 if (err)
985 goto unlock;
986 restart_rds = 1;
987 }
988
989 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, flags);
990
991 if (err)
992 goto unlock;
993
994 bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE, value);
995
996 if (mode != BCM2048_FM_AUTO_SEARCH_MODE)
997 timeout = BCM2048_DEFAULT_TIMEOUT;
998 else
999 timeout = BCM2048_AUTO_SEARCH_TIMEOUT;
1000
1001 if (!wait_for_completion_timeout(&bdev->compl,
21312f6d
JM
1002 msecs_to_jiffies(timeout)))
1003 dev_err(&bdev->client->dev, "IRQ timeout.\n");
899127b6
HV
1004
1005 if (value)
1006 if (!bdev->scan_state)
1007 err = -EIO;
1008
1009unlock:
1010 if (restart_rds)
1011 err |= bcm2048_set_rds_no_lock(bdev, 1);
1012
1013 mutex_unlock(&bdev->mutex);
1014
1015 return err;
1016}
1017
1018static int bcm2048_get_fm_search_tune_mode(struct bcm2048_device *bdev)
1019{
1020 int err;
1021 u8 value;
1022
1023 mutex_lock(&bdev->mutex);
1024
1025 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE,
925b6578 1026 &value);
899127b6
HV
1027
1028 mutex_unlock(&bdev->mutex);
1029
1030 if (!err)
1031 return value & BCM2048_FM_AUTO_SEARCH;
1032
1033 return err;
1034}
1035
1036static int bcm2048_set_rds_b_block_mask(struct bcm2048_device *bdev, u16 mask)
1037{
1038 int err;
1039
1040 mutex_lock(&bdev->mutex);
1041
925b6578
AG
1042 err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MASK0,
1043 lsb(mask));
1044 err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MASK1,
1045 msb(mask));
899127b6
HV
1046
1047 mutex_unlock(&bdev->mutex);
1048 return err;
1049}
1050
1051static int bcm2048_get_rds_b_block_mask(struct bcm2048_device *bdev)
1052{
1053 int err;
a1f8c0cf 1054 u8 lsb = 0, msb = 0;
899127b6
HV
1055
1056 mutex_lock(&bdev->mutex);
1057
925b6578
AG
1058 err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MASK0, &lsb);
1059 err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MASK1, &msb);
899127b6
HV
1060
1061 mutex_unlock(&bdev->mutex);
1062
1063 if (!err)
1064 return compose_u16(msb, lsb);
1065
1066 return err;
1067}
1068
1069static int bcm2048_set_rds_b_block_match(struct bcm2048_device *bdev,
925b6578 1070 u16 match)
899127b6
HV
1071{
1072 int err;
1073
1074 mutex_lock(&bdev->mutex);
1075
925b6578
AG
1076 err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH0,
1077 lsb(match));
1078 err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH1,
1079 msb(match));
899127b6
HV
1080
1081 mutex_unlock(&bdev->mutex);
1082 return err;
1083}
1084
1085static int bcm2048_get_rds_b_block_match(struct bcm2048_device *bdev)
1086{
1087 int err;
a1f8c0cf 1088 u8 lsb = 0, msb = 0;
899127b6
HV
1089
1090 mutex_lock(&bdev->mutex);
1091
925b6578
AG
1092 err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH0, &lsb);
1093 err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH1, &msb);
899127b6
HV
1094
1095 mutex_unlock(&bdev->mutex);
1096
1097 if (!err)
1098 return compose_u16(msb, lsb);
1099
1100 return err;
1101}
1102
1103static int bcm2048_set_rds_pi_mask(struct bcm2048_device *bdev, u16 mask)
1104{
1105 int err;
1106
1107 mutex_lock(&bdev->mutex);
1108
925b6578
AG
1109 err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MASK0, lsb(mask));
1110 err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MASK1, msb(mask));
899127b6
HV
1111
1112 mutex_unlock(&bdev->mutex);
1113 return err;
1114}
1115
1116static int bcm2048_get_rds_pi_mask(struct bcm2048_device *bdev)
1117{
1118 int err;
a1f8c0cf 1119 u8 lsb = 0, msb = 0;
899127b6
HV
1120
1121 mutex_lock(&bdev->mutex);
1122
925b6578
AG
1123 err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MASK0, &lsb);
1124 err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MASK1, &msb);
899127b6
HV
1125
1126 mutex_unlock(&bdev->mutex);
1127
1128 if (!err)
1129 return compose_u16(msb, lsb);
1130
1131 return err;
1132}
1133
1134static int bcm2048_set_rds_pi_match(struct bcm2048_device *bdev, u16 match)
1135{
1136 int err;
1137
1138 mutex_lock(&bdev->mutex);
1139
925b6578
AG
1140 err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MATCH0,
1141 lsb(match));
1142 err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MATCH1,
1143 msb(match));
899127b6
HV
1144
1145 mutex_unlock(&bdev->mutex);
1146 return err;
1147}
1148
1149static int bcm2048_get_rds_pi_match(struct bcm2048_device *bdev)
1150{
1151 int err;
a1f8c0cf 1152 u8 lsb = 0, msb = 0;
899127b6
HV
1153
1154 mutex_lock(&bdev->mutex);
1155
925b6578
AG
1156 err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MATCH0, &lsb);
1157 err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MATCH1, &msb);
899127b6
HV
1158
1159 mutex_unlock(&bdev->mutex);
1160
1161 if (!err)
1162 return compose_u16(msb, lsb);
1163
1164 return err;
1165}
1166
1167static int bcm2048_set_fm_rds_mask(struct bcm2048_device *bdev, u16 mask)
1168{
1169 int err;
1170
1171 mutex_lock(&bdev->mutex);
1172
925b6578
AG
1173 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, lsb(mask));
1174 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1, msb(mask));
899127b6
HV
1175
1176 mutex_unlock(&bdev->mutex);
1177 return err;
1178}
1179
1180static int bcm2048_get_fm_rds_mask(struct bcm2048_device *bdev)
1181{
1182 int err;
a1f8c0cf 1183 u8 value0 = 0, value1 = 0;
899127b6
HV
1184
1185 mutex_lock(&bdev->mutex);
1186
1187 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_MASK0, &value0);
1188 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_MASK1, &value1);
1189
1190 mutex_unlock(&bdev->mutex);
1191
1192 if (!err)
1193 return compose_u16(value1, value0);
1194
1195 return err;
1196}
1197
1198static int bcm2048_get_fm_rds_flags(struct bcm2048_device *bdev)
1199{
1200 int err;
a1f8c0cf 1201 u8 value0 = 0, value1 = 0;
899127b6
HV
1202
1203 mutex_lock(&bdev->mutex);
1204
1205 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &value0);
1206 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &value1);
1207
1208 mutex_unlock(&bdev->mutex);
1209
1210 if (!err)
1211 return compose_u16(value1, value0);
1212
1213 return err;
1214}
1215
1216static int bcm2048_get_region_bottom_frequency(struct bcm2048_device *bdev)
1217{
1218 return bdev->region_info.bottom_frequency;
1219}
1220
1221static int bcm2048_get_region_top_frequency(struct bcm2048_device *bdev)
1222{
1223 return bdev->region_info.top_frequency;
1224}
1225
1226static int bcm2048_set_fm_best_tune_mode(struct bcm2048_device *bdev, u8 mode)
1227{
1228 int err;
a1f8c0cf 1229 u8 value = 0;
899127b6
HV
1230
1231 mutex_lock(&bdev->mutex);
1232
1233 /* Perform read as the manual indicates */
1234 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
925b6578 1235 &value);
899127b6
HV
1236 value &= ~BCM2048_BEST_TUNE_MODE;
1237
1238 if (mode)
1239 value |= BCM2048_BEST_TUNE_MODE;
1240 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
925b6578 1241 value);
899127b6
HV
1242
1243 mutex_unlock(&bdev->mutex);
1244 return err;
1245}
1246
1247static int bcm2048_get_fm_best_tune_mode(struct bcm2048_device *bdev)
1248{
1249 int err;
1250 u8 value;
1251
1252 mutex_lock(&bdev->mutex);
1253
1254 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
925b6578 1255 &value);
899127b6
HV
1256
1257 mutex_unlock(&bdev->mutex);
1258
1259 if (!err && (value & BCM2048_BEST_TUNE_MODE))
1260 return BCM2048_ITEM_ENABLED;
1261
1262 return err;
1263}
1264
1265static int bcm2048_get_fm_carrier_error(struct bcm2048_device *bdev)
1266{
1267 int err = 0;
1268 s8 value;
1269
1270 mutex_lock(&bdev->mutex);
1271 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_CARRIER, &value);
1272 mutex_unlock(&bdev->mutex);
1273
1274 if (!err)
1275 return value;
1276
1277 return err;
1278}
1279
1280static int bcm2048_get_fm_rssi(struct bcm2048_device *bdev)
1281{
1282 int err;
1283 s8 value;
1284
1285 mutex_lock(&bdev->mutex);
1286 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RSSI, &value);
1287 mutex_unlock(&bdev->mutex);
1288
1289 if (!err)
1290 return value;
1291
1292 return err;
1293}
1294
1295static int bcm2048_set_rds_wline(struct bcm2048_device *bdev, u8 wline)
1296{
1297 int err;
1298
1299 mutex_lock(&bdev->mutex);
1300
1301 err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_WLINE, wline);
1302
1303 if (!err)
1304 bdev->fifo_size = wline;
1305
1306 mutex_unlock(&bdev->mutex);
1307 return err;
1308}
1309
1310static int bcm2048_get_rds_wline(struct bcm2048_device *bdev)
1311{
1312 int err;
1313 u8 value;
1314
1315 mutex_lock(&bdev->mutex);
1316
1317 err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_WLINE, &value);
1318
1319 mutex_unlock(&bdev->mutex);
1320
1321 if (!err) {
1322 bdev->fifo_size = value;
1323 return value;
1324 }
1325
1326 return err;
1327}
1328
1329static int bcm2048_checkrev(struct bcm2048_device *bdev)
1330{
1331 int err;
1332 u8 version;
1333
1334 mutex_lock(&bdev->mutex);
1335
1336 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_REV, &version);
1337
1338 mutex_unlock(&bdev->mutex);
1339
1340 if (!err) {
1341 dev_info(&bdev->client->dev, "BCM2048 Version 0x%x\n",
925b6578 1342 version);
899127b6
HV
1343 return version;
1344 }
1345
1346 return err;
1347}
1348
1349static int bcm2048_get_rds_rt(struct bcm2048_device *bdev, char *data)
1350{
1351 int err = 0, i, j = 0, ce = 0, cr = 0;
3ac086fb 1352 char data_buffer[BCM2048_MAX_RDS_RT + 1];
899127b6
HV
1353
1354 mutex_lock(&bdev->mutex);
1355
1356 if (!bdev->rds_info.text_len) {
1357 err = -EINVAL;
1358 goto unlock;
1359 }
1360
1361 for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
1362 if (bdev->rds_info.rds_rt[i]) {
1363 ce = i;
1364 /* Skip the carriage return */
1365 if (bdev->rds_info.rds_rt[i] != 0x0d) {
1366 data_buffer[j++] = bdev->rds_info.rds_rt[i];
1367 } else {
1368 cr = i;
1369 break;
1370 }
1371 }
1372 }
1373
1374 if (j <= BCM2048_MAX_RDS_RT)
1375 data_buffer[j] = 0;
1376
1377 for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
1378 if (!bdev->rds_info.rds_rt[i]) {
1379 if (cr && (i < cr)) {
1380 err = -EBUSY;
1381 goto unlock;
1382 }
1383 if (i < ce) {
1384 if (cr && (i >= cr))
1385 break;
1386 err = -EBUSY;
1387 goto unlock;
1388 }
1389 }
1390 }
1391
1392 memcpy(data, data_buffer, sizeof(data_buffer));
1393
1394unlock:
1395 mutex_unlock(&bdev->mutex);
1396 return err;
1397}
1398
1399static int bcm2048_get_rds_ps(struct bcm2048_device *bdev, char *data)
1400{
1401 int err = 0, i, j = 0;
3ac086fb 1402 char data_buffer[BCM2048_MAX_RDS_PS + 1];
899127b6
HV
1403
1404 mutex_lock(&bdev->mutex);
1405
1406 if (!bdev->rds_info.text_len) {
1407 err = -EINVAL;
1408 goto unlock;
1409 }
1410
1411 for (i = 0; i < BCM2048_MAX_RDS_PS; i++) {
1412 if (bdev->rds_info.rds_ps[i]) {
1413 data_buffer[j++] = bdev->rds_info.rds_ps[i];
1414 } else {
1415 if (i < (BCM2048_MAX_RDS_PS - 1)) {
1416 err = -EBUSY;
1417 goto unlock;
1418 }
1419 }
1420 }
1421
1422 if (j <= BCM2048_MAX_RDS_PS)
1423 data_buffer[j] = 0;
1424
1425 memcpy(data, data_buffer, sizeof(data_buffer));
1426
1427unlock:
1428 mutex_unlock(&bdev->mutex);
1429 return err;
1430}
1431
1432static void bcm2048_parse_rds_pi(struct bcm2048_device *bdev)
1433{
1434 int i, cnt = 0;
1435 u16 pi;
1436
1437 for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
899127b6
HV
1438 /* Block A match, only data without crc errors taken */
1439 if (bdev->rds_info.radio_text[i] == BCM2048_RDS_BLOCK_A) {
3ac086fb
AG
1440 pi = (bdev->rds_info.radio_text[i + 1] << 8) +
1441 bdev->rds_info.radio_text[i + 2];
899127b6
HV
1442
1443 if (!bdev->rds_info.rds_pi) {
1444 bdev->rds_info.rds_pi = pi;
1445 return;
1446 }
1447 if (pi != bdev->rds_info.rds_pi) {
1448 cnt++;
1449 if (cnt > 3) {
1450 bdev->rds_info.rds_pi = pi;
1451 cnt = 0;
1452 }
1453 } else {
1454 cnt = 0;
1455 }
1456 }
1457 }
1458}
1459
1460static int bcm2048_rds_block_crc(struct bcm2048_device *bdev, int i)
1461{
1462 return bdev->rds_info.radio_text[i] & BCM2048_RDS_CRC_MASK;
1463}
1464
1465static void bcm2048_parse_rds_rt_block(struct bcm2048_device *bdev, int i,
925b6578 1466 int index, int crc)
899127b6
HV
1467{
1468 /* Good data will overwrite poor data */
1469 if (crc) {
1470 if (!bdev->rds_info.rds_rt[index])
1471 bdev->rds_info.rds_rt[index] =
3ac086fb
AG
1472 bdev->rds_info.radio_text[i + 1];
1473 if (!bdev->rds_info.rds_rt[index + 1])
1474 bdev->rds_info.rds_rt[index + 1] =
1475 bdev->rds_info.radio_text[i + 2];
899127b6 1476 } else {
3ac086fb
AG
1477 bdev->rds_info.rds_rt[index] =
1478 bdev->rds_info.radio_text[i + 1];
1479 bdev->rds_info.rds_rt[index + 1] =
1480 bdev->rds_info.radio_text[i + 2];
899127b6
HV
1481 }
1482}
1483
1484static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i)
1485{
1486 int crc, rt_id, rt_group_b, rt_ab, index = 0;
1487
1488 crc = bcm2048_rds_block_crc(bdev, i);
1489
1490 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1491 return -EIO;
1492
1493 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
925b6578 1494 BCM2048_RDS_BLOCK_B) {
3ac086fb 1495 rt_id = bdev->rds_info.radio_text[i + 1] &
8126e17f 1496 BCM2048_RDS_BLOCK_MASK;
3ac086fb 1497 rt_group_b = bdev->rds_info.radio_text[i + 1] &
899127b6 1498 BCM2048_RDS_GROUP_AB_MASK;
3ac086fb 1499 rt_ab = bdev->rds_info.radio_text[i + 2] &
899127b6
HV
1500 BCM2048_RDS_RT_AB_MASK;
1501
1502 if (rt_group_b != bdev->rds_info.rds_rt_group_b) {
1503 memset(bdev->rds_info.rds_rt, 0,
925b6578 1504 sizeof(bdev->rds_info.rds_rt));
899127b6
HV
1505 bdev->rds_info.rds_rt_group_b = rt_group_b;
1506 }
1507
1508 if (rt_id == BCM2048_RDS_RT) {
1509 /* A to B or (vice versa), means: clear screen */
1510 if (rt_ab != bdev->rds_info.rds_rt_ab) {
1511 memset(bdev->rds_info.rds_rt, 0,
925b6578 1512 sizeof(bdev->rds_info.rds_rt));
899127b6
HV
1513 bdev->rds_info.rds_rt_ab = rt_ab;
1514 }
1515
3ac086fb 1516 index = bdev->rds_info.radio_text[i + 2] &
899127b6
HV
1517 BCM2048_RDS_RT_INDEX;
1518
1519 if (bdev->rds_info.rds_rt_group_b)
1520 index <<= 1;
1521 else
1522 index <<= 2;
1523
1524 return index;
1525 }
1526 }
1527
1528 return -EIO;
1529}
1530
1531static int bcm2048_parse_rt_match_c(struct bcm2048_device *bdev, int i,
925b6578 1532 int index)
899127b6
HV
1533{
1534 int crc;
1535
1536 crc = bcm2048_rds_block_crc(bdev, i);
1537
1538 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1539 return 0;
1540
1541 BUG_ON((index+2) >= BCM2048_MAX_RDS_RT);
1542
1543 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1544 BCM2048_RDS_BLOCK_C) {
1545 if (bdev->rds_info.rds_rt_group_b)
1546 return 1;
1547 bcm2048_parse_rds_rt_block(bdev, i, index, crc);
1548 return 1;
1549 }
1550
1551 return 0;
1552}
1553
1554static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i,
925b6578 1555 int index)
899127b6
HV
1556{
1557 int crc;
1558
1559 crc = bcm2048_rds_block_crc(bdev, i);
1560
1561 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1562 return;
1563
1564 BUG_ON((index+4) >= BCM2048_MAX_RDS_RT);
1565
1566 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
925b6578 1567 BCM2048_RDS_BLOCK_D)
3ac086fb 1568 bcm2048_parse_rds_rt_block(bdev, i, index + 2, crc);
899127b6
HV
1569}
1570
b6cca54f 1571static void bcm2048_parse_rds_rt(struct bcm2048_device *bdev)
899127b6
HV
1572{
1573 int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0;
1574
1575 for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
899127b6
HV
1576 if (match_b) {
1577 match_b = 0;
1578 index = bcm2048_parse_rt_match_b(bdev, i);
1579 if (index >= 0 && index <= (BCM2048_MAX_RDS_RT - 5))
1580 match_c = 1;
1581 continue;
1582 } else if (match_c) {
1583 match_c = 0;
1584 if (bcm2048_parse_rt_match_c(bdev, i, index))
1585 match_d = 1;
1586 continue;
1587 } else if (match_d) {
1588 match_d = 0;
1589 bcm2048_parse_rt_match_d(bdev, i, index);
1590 continue;
1591 }
1592
1593 /* Skip erroneous blocks due to messed up A block altogether */
925b6578
AG
1594 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1595 BCM2048_RDS_BLOCK_A) {
899127b6
HV
1596 crc = bcm2048_rds_block_crc(bdev, i);
1597 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1598 continue;
3066bc05 1599 /* Synchronize to a good RDS PI */
925b6578
AG
1600 if (((bdev->rds_info.radio_text[i + 1] << 8) +
1601 bdev->rds_info.radio_text[i + 2]) ==
1602 bdev->rds_info.rds_pi)
1603 match_b = 1;
899127b6
HV
1604 }
1605 }
899127b6
HV
1606}
1607
1608static void bcm2048_parse_rds_ps_block(struct bcm2048_device *bdev, int i,
925b6578 1609 int index, int crc)
899127b6
HV
1610{
1611 /* Good data will overwrite poor data */
1612 if (crc) {
1613 if (!bdev->rds_info.rds_ps[index])
1614 bdev->rds_info.rds_ps[index] =
3ac086fb
AG
1615 bdev->rds_info.radio_text[i + 1];
1616 if (!bdev->rds_info.rds_ps[index + 1])
1617 bdev->rds_info.rds_ps[index + 1] =
1618 bdev->rds_info.radio_text[i + 2];
899127b6 1619 } else {
3ac086fb
AG
1620 bdev->rds_info.rds_ps[index] =
1621 bdev->rds_info.radio_text[i + 1];
1622 bdev->rds_info.rds_ps[index + 1] =
1623 bdev->rds_info.radio_text[i + 2];
899127b6
HV
1624 }
1625}
1626
1627static int bcm2048_parse_ps_match_c(struct bcm2048_device *bdev, int i,
925b6578 1628 int index)
899127b6
HV
1629{
1630 int crc;
1631
1632 crc = bcm2048_rds_block_crc(bdev, i);
1633
1634 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1635 return 0;
1636
1637 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
925b6578 1638 BCM2048_RDS_BLOCK_C)
899127b6
HV
1639 return 1;
1640
1641 return 0;
1642}
1643
1644static void bcm2048_parse_ps_match_d(struct bcm2048_device *bdev, int i,
925b6578 1645 int index)
899127b6
HV
1646{
1647 int crc;
1648
1649 crc = bcm2048_rds_block_crc(bdev, i);
1650
1651 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1652 return;
1653
1654 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
925b6578 1655 BCM2048_RDS_BLOCK_D)
899127b6
HV
1656 bcm2048_parse_rds_ps_block(bdev, i, index, crc);
1657}
1658
1659static int bcm2048_parse_ps_match_b(struct bcm2048_device *bdev, int i)
1660{
1661 int crc, index, ps_id, ps_group;
1662
1663 crc = bcm2048_rds_block_crc(bdev, i);
1664
1665 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1666 return -EIO;
1667
1668 /* Block B Radio PS match */
1669 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
925b6578 1670 BCM2048_RDS_BLOCK_B) {
3ac086fb 1671 ps_id = bdev->rds_info.radio_text[i + 1] &
899127b6 1672 BCM2048_RDS_BLOCK_MASK;
3ac086fb 1673 ps_group = bdev->rds_info.radio_text[i + 1] &
899127b6
HV
1674 BCM2048_RDS_GROUP_AB_MASK;
1675
1676 /*
1677 * Poor RSSI will lead to RDS data corruption
1678 * So using 3 (same) sequential values to justify major changes
1679 */
1680 if (ps_group != bdev->rds_info.rds_ps_group) {
1681 if (crc == BCM2048_RDS_CRC_NONE) {
1682 bdev->rds_info.rds_ps_group_cnt++;
1683 if (bdev->rds_info.rds_ps_group_cnt > 2) {
1684 bdev->rds_info.rds_ps_group = ps_group;
1685 bdev->rds_info.rds_ps_group_cnt = 0;
1686 dev_err(&bdev->client->dev,
1687 "RDS PS Group change!\n");
1688 } else {
1689 return -EIO;
1690 }
1691 } else {
1692 bdev->rds_info.rds_ps_group_cnt = 0;
1693 }
1694 }
1695
1696 if (ps_id == BCM2048_RDS_PS) {
3ac086fb 1697 index = bdev->rds_info.radio_text[i + 2] &
899127b6
HV
1698 BCM2048_RDS_PS_INDEX;
1699 index <<= 1;
1700 return index;
1701 }
1702 }
1703
1704 return -EIO;
1705}
1706
1707static void bcm2048_parse_rds_ps(struct bcm2048_device *bdev)
1708{
1709 int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0;
1710
1711 for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
899127b6
HV
1712 if (match_b) {
1713 match_b = 0;
1714 index = bcm2048_parse_ps_match_b(bdev, i);
1715 if (index >= 0 && index < (BCM2048_MAX_RDS_PS - 1))
1716 match_c = 1;
1717 continue;
1718 } else if (match_c) {
1719 match_c = 0;
1720 if (bcm2048_parse_ps_match_c(bdev, i, index))
1721 match_d = 1;
1722 continue;
1723 } else if (match_d) {
1724 match_d = 0;
1725 bcm2048_parse_ps_match_d(bdev, i, index);
1726 continue;
1727 }
1728
1729 /* Skip erroneous blocks due to messed up A block altogether */
925b6578
AG
1730 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1731 BCM2048_RDS_BLOCK_A) {
899127b6
HV
1732 crc = bcm2048_rds_block_crc(bdev, i);
1733 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1734 continue;
3066bc05 1735 /* Synchronize to a good RDS PI */
925b6578
AG
1736 if (((bdev->rds_info.radio_text[i + 1] << 8) +
1737 bdev->rds_info.radio_text[i + 2]) ==
1738 bdev->rds_info.rds_pi)
1739 match_b = 1;
899127b6
HV
1740 }
1741 }
1742}
1743
1744static void bcm2048_rds_fifo_receive(struct bcm2048_device *bdev)
1745{
1746 int err;
1747
1748 mutex_lock(&bdev->mutex);
1749
1750 err = bcm2048_recv_duples(bdev, BCM2048_I2C_RDS_DATA,
925b6578 1751 bdev->rds_info.radio_text, bdev->fifo_size);
899127b6
HV
1752 if (err != 2) {
1753 dev_err(&bdev->client->dev, "RDS Read problem\n");
66c5e592 1754 mutex_unlock(&bdev->mutex);
899127b6
HV
1755 return;
1756 }
1757
1758 bdev->rds_info.text_len = bdev->fifo_size;
1759
1760 bcm2048_parse_rds_pi(bdev);
1761 bcm2048_parse_rds_rt(bdev);
1762 bcm2048_parse_rds_ps(bdev);
1763
1764 mutex_unlock(&bdev->mutex);
1765
1766 wake_up_interruptible(&bdev->read_queue);
1767}
1768
1769static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data)
1770{
1771 int err = 0, i, p = 0;
1772 char *data_buffer;
1773
1774 mutex_lock(&bdev->mutex);
1775
1776 if (!bdev->rds_info.text_len) {
1777 err = -EINVAL;
1778 goto unlock;
1779 }
1780
5869066a 1781 data_buffer = kcalloc(BCM2048_MAX_RDS_RADIO_TEXT, 5, GFP_KERNEL);
899127b6
HV
1782 if (!data_buffer) {
1783 err = -ENOMEM;
1784 goto unlock;
1785 }
1786
1787 for (i = 0; i < bdev->rds_info.text_len; i++) {
3ac086fb 1788 p += sprintf(data_buffer + p, "%x ",
925b6578 1789 bdev->rds_info.radio_text[i]);
899127b6
HV
1790 }
1791
1792 memcpy(data, data_buffer, p);
1793 kfree(data_buffer);
1794
1795unlock:
1796 mutex_unlock(&bdev->mutex);
1797 return err;
1798}
1799
1800/*
1801 * BCM2048 default initialization sequence
1802 */
1803static int bcm2048_init(struct bcm2048_device *bdev)
1804{
1805 int err;
1806
1807 err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
1808 if (err < 0)
1809 goto exit;
1810
1811 err = bcm2048_set_audio_route(bdev, BCM2048_AUDIO_ROUTE_DAC);
1812 if (err < 0)
1813 goto exit;
1814
1815 err = bcm2048_set_dac_output(bdev, BCM2048_DAC_OUTPUT_LEFT |
925b6578 1816 BCM2048_DAC_OUTPUT_RIGHT);
899127b6
HV
1817
1818exit:
1819 return err;
1820}
1821
1822/*
1823 * BCM2048 default deinitialization sequence
1824 */
1825static int bcm2048_deinit(struct bcm2048_device *bdev)
1826{
1827 int err;
1828
1829 err = bcm2048_set_audio_route(bdev, 0);
1830 if (err < 0)
58f31812 1831 return err;
899127b6
HV
1832
1833 err = bcm2048_set_dac_output(bdev, 0);
1834 if (err < 0)
58f31812 1835 return err;
899127b6
HV
1836
1837 err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
899127b6 1838
899127b6
HV
1839 return err;
1840}
1841
1842/*
1843 * BCM2048 probe sequence
1844 */
1845static int bcm2048_probe(struct bcm2048_device *bdev)
1846{
1847 int err;
1848
1849 err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
1850 if (err < 0)
1851 goto unlock;
1852
1853 err = bcm2048_checkrev(bdev);
1854 if (err < 0)
1855 goto unlock;
1856
1857 err = bcm2048_set_mute(bdev, BCM2048_DEFAULT_MUTE);
1858 if (err < 0)
1859 goto unlock;
1860
1861 err = bcm2048_set_region(bdev, BCM2048_DEFAULT_REGION);
1862 if (err < 0)
1863 goto unlock;
1864
1865 err = bcm2048_set_fm_search_rssi_threshold(bdev,
1866 BCM2048_DEFAULT_RSSI_THRESHOLD);
1867 if (err < 0)
1868 goto unlock;
1869
1870 err = bcm2048_set_fm_automatic_stereo_mono(bdev, BCM2048_ITEM_ENABLED);
1871 if (err < 0)
1872 goto unlock;
1873
1874 err = bcm2048_get_rds_wline(bdev);
1875 if (err < BCM2048_DEFAULT_RDS_WLINE)
1876 err = bcm2048_set_rds_wline(bdev, BCM2048_DEFAULT_RDS_WLINE);
1877 if (err < 0)
1878 goto unlock;
1879
1880 err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
1881
1882 init_waitqueue_head(&bdev->read_queue);
1883 bdev->rds_data_available = 0;
1884 bdev->rd_index = 0;
1885 bdev->users = 0;
1886
1887unlock:
1888 return err;
1889}
1890
1891/*
1892 * BCM2048 workqueue handler
1893 */
1894static void bcm2048_work(struct work_struct *work)
1895{
1896 struct bcm2048_device *bdev;
a1f8c0cf 1897 u8 flag_lsb = 0, flag_msb = 0, flags;
899127b6
HV
1898
1899 bdev = container_of(work, struct bcm2048_device, work);
1900 bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &flag_lsb);
1901 bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &flag_msb);
1902
1903 if (flag_lsb & (BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
1904 BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)) {
899127b6
HV
1905 if (flag_lsb & BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)
1906 bdev->scan_state = BCM2048_SCAN_FAIL;
1907 else
1908 bdev->scan_state = BCM2048_SCAN_OK;
1909
1910 complete(&bdev->compl);
1911 }
1912
1913 if (flag_msb & BCM2048_RDS_FLAG_FIFO_WLINE) {
1914 bcm2048_rds_fifo_receive(bdev);
1915 if (bdev->rds_state) {
1916 flags = BCM2048_RDS_FLAG_FIFO_WLINE;
1917 bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
925b6578 1918 flags);
899127b6
HV
1919 }
1920 bdev->rds_data_available = 1;
1921 bdev->rd_index = 0; /* new data, new start */
1922 }
1923}
1924
1925/*
1926 * BCM2048 interrupt handler
1927 */
1928static irqreturn_t bcm2048_handler(int irq, void *dev)
1929{
1930 struct bcm2048_device *bdev = dev;
1931
1932 dev_dbg(&bdev->client->dev, "IRQ called, queuing work\n");
1933 if (bdev->power_state)
1934 schedule_work(&bdev->work);
1935
1936 return IRQ_HANDLED;
1937}
1938
1939/*
1940 * BCM2048 sysfs interface definitions
1941 */
1942#define property_write(prop, type, mask, check) \
1943static ssize_t bcm2048_##prop##_write(struct device *dev, \
1944 struct device_attribute *attr, \
1945 const char *buf, \
1946 size_t count) \
1947{ \
1948 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
1949 type value; \
1950 int err; \
1951 \
1952 if (!bdev) \
1953 return -ENODEV; \
1954 \
b317d0f5
LH
1955 if (sscanf(buf, mask, &value) != 1) \
1956 return -EINVAL; \
899127b6
HV
1957 \
1958 if (check) \
1959 return -EDOM; \
1960 \
1961 err = bcm2048_set_##prop(bdev, value); \
1962 \
1963 return err < 0 ? err : count; \
1964}
1965
1966#define property_read(prop, size, mask) \
1967static ssize_t bcm2048_##prop##_read(struct device *dev, \
1968 struct device_attribute *attr, \
1969 char *buf) \
1970{ \
1971 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
356ba021 1972 int value; \
899127b6
HV
1973 \
1974 if (!bdev) \
1975 return -ENODEV; \
1976 \
1977 value = bcm2048_get_##prop(bdev); \
1978 \
1979 if (value >= 0) \
1980 value = sprintf(buf, mask "\n", value); \
1981 \
1982 return value; \
1983}
1984
1985#define property_signed_read(prop, size, mask) \
1986static ssize_t bcm2048_##prop##_read(struct device *dev, \
1987 struct device_attribute *attr, \
1988 char *buf) \
1989{ \
1990 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
1991 size value; \
1992 \
1993 if (!bdev) \
1994 return -ENODEV; \
1995 \
1996 value = bcm2048_get_##prop(bdev); \
1997 \
1998 value = sprintf(buf, mask "\n", value); \
1999 \
2000 return value; \
2001}
2002
2003#define DEFINE_SYSFS_PROPERTY(prop, signal, size, mask, check) \
2004property_write(prop, signal size, mask, check) \
2005property_read(prop, size, mask)
2006
2007#define property_str_read(prop, size) \
2008static ssize_t bcm2048_##prop##_read(struct device *dev, \
2009 struct device_attribute *attr, \
2010 char *buf) \
2011{ \
2012 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
2013 int count; \
2014 u8 *out; \
2015 \
2016 if (!bdev) \
2017 return -ENODEV; \
2018 \
2019 out = kzalloc(size + 1, GFP_KERNEL); \
2020 if (!out) \
2021 return -ENOMEM; \
2022 \
2023 bcm2048_get_##prop(bdev, out); \
2024 count = sprintf(buf, "%s\n", out); \
2025 \
2026 kfree(out); \
2027 \
2028 return count; \
2029}
2030
2031DEFINE_SYSFS_PROPERTY(power_state, unsigned, int, "%u", 0)
2032DEFINE_SYSFS_PROPERTY(mute, unsigned, int, "%u", 0)
2033DEFINE_SYSFS_PROPERTY(audio_route, unsigned, int, "%u", 0)
2034DEFINE_SYSFS_PROPERTY(dac_output, unsigned, int, "%u", 0)
2035
2036DEFINE_SYSFS_PROPERTY(fm_hi_lo_injection, unsigned, int, "%u", 0)
2037DEFINE_SYSFS_PROPERTY(fm_frequency, unsigned, int, "%u", 0)
2038DEFINE_SYSFS_PROPERTY(fm_af_frequency, unsigned, int, "%u", 0)
2039DEFINE_SYSFS_PROPERTY(fm_deemphasis, unsigned, int, "%u", 0)
2040DEFINE_SYSFS_PROPERTY(fm_rds_mask, unsigned, int, "%u", 0)
2041DEFINE_SYSFS_PROPERTY(fm_best_tune_mode, unsigned, int, "%u", 0)
2042DEFINE_SYSFS_PROPERTY(fm_search_rssi_threshold, unsigned, int, "%u", 0)
2043DEFINE_SYSFS_PROPERTY(fm_search_mode_direction, unsigned, int, "%u", 0)
2044DEFINE_SYSFS_PROPERTY(fm_search_tune_mode, unsigned, int, "%u", value > 3)
2045
2046DEFINE_SYSFS_PROPERTY(rds, unsigned, int, "%u", 0)
2047DEFINE_SYSFS_PROPERTY(rds_b_block_mask, unsigned, int, "%u", 0)
2048DEFINE_SYSFS_PROPERTY(rds_b_block_match, unsigned, int, "%u", 0)
2049DEFINE_SYSFS_PROPERTY(rds_pi_mask, unsigned, int, "%u", 0)
2050DEFINE_SYSFS_PROPERTY(rds_pi_match, unsigned, int, "%u", 0)
2051DEFINE_SYSFS_PROPERTY(rds_wline, unsigned, int, "%u", 0)
2052property_read(rds_pi, unsigned int, "%x")
2053property_str_read(rds_rt, (BCM2048_MAX_RDS_RT + 1))
2054property_str_read(rds_ps, (BCM2048_MAX_RDS_PS + 1))
2055
2056property_read(fm_rds_flags, unsigned int, "%u")
3ac086fb 2057property_str_read(rds_data, BCM2048_MAX_RDS_RADIO_TEXT * 5)
899127b6
HV
2058
2059property_read(region_bottom_frequency, unsigned int, "%u")
2060property_read(region_top_frequency, unsigned int, "%u")
2061property_signed_read(fm_carrier_error, int, "%d")
2062property_signed_read(fm_rssi, int, "%d")
2063DEFINE_SYSFS_PROPERTY(region, unsigned, int, "%u", 0)
2064
2065static struct device_attribute attrs[] = {
2066 __ATTR(power_state, S_IRUGO | S_IWUSR, bcm2048_power_state_read,
925b6578 2067 bcm2048_power_state_write),
899127b6 2068 __ATTR(mute, S_IRUGO | S_IWUSR, bcm2048_mute_read,
925b6578 2069 bcm2048_mute_write),
899127b6 2070 __ATTR(audio_route, S_IRUGO | S_IWUSR, bcm2048_audio_route_read,
925b6578 2071 bcm2048_audio_route_write),
899127b6 2072 __ATTR(dac_output, S_IRUGO | S_IWUSR, bcm2048_dac_output_read,
925b6578 2073 bcm2048_dac_output_write),
899127b6 2074 __ATTR(fm_hi_lo_injection, S_IRUGO | S_IWUSR,
925b6578
AG
2075 bcm2048_fm_hi_lo_injection_read,
2076 bcm2048_fm_hi_lo_injection_write),
899127b6 2077 __ATTR(fm_frequency, S_IRUGO | S_IWUSR, bcm2048_fm_frequency_read,
925b6578 2078 bcm2048_fm_frequency_write),
899127b6 2079 __ATTR(fm_af_frequency, S_IRUGO | S_IWUSR,
925b6578
AG
2080 bcm2048_fm_af_frequency_read,
2081 bcm2048_fm_af_frequency_write),
899127b6 2082 __ATTR(fm_deemphasis, S_IRUGO | S_IWUSR, bcm2048_fm_deemphasis_read,
925b6578 2083 bcm2048_fm_deemphasis_write),
899127b6 2084 __ATTR(fm_rds_mask, S_IRUGO | S_IWUSR, bcm2048_fm_rds_mask_read,
925b6578 2085 bcm2048_fm_rds_mask_write),
899127b6 2086 __ATTR(fm_best_tune_mode, S_IRUGO | S_IWUSR,
925b6578
AG
2087 bcm2048_fm_best_tune_mode_read,
2088 bcm2048_fm_best_tune_mode_write),
899127b6 2089 __ATTR(fm_search_rssi_threshold, S_IRUGO | S_IWUSR,
925b6578
AG
2090 bcm2048_fm_search_rssi_threshold_read,
2091 bcm2048_fm_search_rssi_threshold_write),
899127b6 2092 __ATTR(fm_search_mode_direction, S_IRUGO | S_IWUSR,
925b6578
AG
2093 bcm2048_fm_search_mode_direction_read,
2094 bcm2048_fm_search_mode_direction_write),
899127b6 2095 __ATTR(fm_search_tune_mode, S_IRUGO | S_IWUSR,
925b6578
AG
2096 bcm2048_fm_search_tune_mode_read,
2097 bcm2048_fm_search_tune_mode_write),
899127b6 2098 __ATTR(rds, S_IRUGO | S_IWUSR, bcm2048_rds_read,
925b6578 2099 bcm2048_rds_write),
899127b6 2100 __ATTR(rds_b_block_mask, S_IRUGO | S_IWUSR,
925b6578
AG
2101 bcm2048_rds_b_block_mask_read,
2102 bcm2048_rds_b_block_mask_write),
899127b6 2103 __ATTR(rds_b_block_match, S_IRUGO | S_IWUSR,
925b6578
AG
2104 bcm2048_rds_b_block_match_read,
2105 bcm2048_rds_b_block_match_write),
899127b6 2106 __ATTR(rds_pi_mask, S_IRUGO | S_IWUSR, bcm2048_rds_pi_mask_read,
925b6578 2107 bcm2048_rds_pi_mask_write),
899127b6 2108 __ATTR(rds_pi_match, S_IRUGO | S_IWUSR, bcm2048_rds_pi_match_read,
925b6578 2109 bcm2048_rds_pi_match_write),
899127b6 2110 __ATTR(rds_wline, S_IRUGO | S_IWUSR, bcm2048_rds_wline_read,
925b6578 2111 bcm2048_rds_wline_write),
899127b6
HV
2112 __ATTR(rds_pi, S_IRUGO, bcm2048_rds_pi_read, NULL),
2113 __ATTR(rds_rt, S_IRUGO, bcm2048_rds_rt_read, NULL),
2114 __ATTR(rds_ps, S_IRUGO, bcm2048_rds_ps_read, NULL),
2115 __ATTR(fm_rds_flags, S_IRUGO, bcm2048_fm_rds_flags_read, NULL),
2116 __ATTR(region_bottom_frequency, S_IRUGO,
925b6578 2117 bcm2048_region_bottom_frequency_read, NULL),
899127b6 2118 __ATTR(region_top_frequency, S_IRUGO,
925b6578 2119 bcm2048_region_top_frequency_read, NULL),
899127b6 2120 __ATTR(fm_carrier_error, S_IRUGO,
925b6578 2121 bcm2048_fm_carrier_error_read, NULL),
899127b6 2122 __ATTR(fm_rssi, S_IRUGO,
925b6578 2123 bcm2048_fm_rssi_read, NULL),
899127b6 2124 __ATTR(region, S_IRUGO | S_IWUSR, bcm2048_region_read,
925b6578 2125 bcm2048_region_write),
899127b6
HV
2126 __ATTR(rds_data, S_IRUGO, bcm2048_rds_data_read, NULL),
2127};
2128
2129static int bcm2048_sysfs_unregister_properties(struct bcm2048_device *bdev,
925b6578 2130 int size)
899127b6
HV
2131{
2132 int i;
2133
2134 for (i = 0; i < size; i++)
2135 device_remove_file(&bdev->client->dev, &attrs[i]);
2136
2137 return 0;
2138}
2139
2140static int bcm2048_sysfs_register_properties(struct bcm2048_device *bdev)
2141{
2142 int err = 0;
2143 int i;
2144
2145 for (i = 0; i < ARRAY_SIZE(attrs); i++) {
2146 if (device_create_file(&bdev->client->dev, &attrs[i]) != 0) {
2147 dev_err(&bdev->client->dev,
925b6578 2148 "could not register sysfs entry\n");
899127b6
HV
2149 err = -EBUSY;
2150 bcm2048_sysfs_unregister_properties(bdev, i);
2151 break;
2152 }
2153 }
2154
2155 return err;
2156}
2157
899127b6
HV
2158static int bcm2048_fops_open(struct file *file)
2159{
2160 struct bcm2048_device *bdev = video_drvdata(file);
2161
2162 bdev->users++;
2163 bdev->rd_index = 0;
2164 bdev->rds_data_available = 0;
2165
2166 return 0;
2167}
2168
2169static int bcm2048_fops_release(struct file *file)
2170{
2171 struct bcm2048_device *bdev = video_drvdata(file);
2172
2173 bdev->users--;
2174
2175 return 0;
2176}
2177
2178static unsigned int bcm2048_fops_poll(struct file *file,
925b6578 2179 struct poll_table_struct *pts)
899127b6
HV
2180{
2181 struct bcm2048_device *bdev = video_drvdata(file);
2182 int retval = 0;
2183
2184 poll_wait(file, &bdev->read_queue, pts);
2185
2186 if (bdev->rds_data_available)
2187 retval = POLLIN | POLLRDNORM;
2188
2189 return retval;
2190}
2191
2192static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
925b6578 2193 size_t count, loff_t *ppos)
899127b6
HV
2194{
2195 struct bcm2048_device *bdev = video_drvdata(file);
2196 int i;
2197 int retval = 0;
2198
2199 /* we return at least 3 bytes, one block */
2200 count = (count / 3) * 3; /* only multiples of 3 */
2201 if (count < 3)
2202 return -ENOBUFS;
2203
2204 while (!bdev->rds_data_available) {
2205 if (file->f_flags & O_NONBLOCK) {
2206 retval = -EWOULDBLOCK;
2207 goto done;
2208 }
2209 /* interruptible_sleep_on(&bdev->read_queue); */
2210 if (wait_event_interruptible(bdev->read_queue,
925b6578 2211 bdev->rds_data_available) < 0) {
899127b6
HV
2212 retval = -EINTR;
2213 goto done;
2214 }
2215 }
2216
2217 mutex_lock(&bdev->mutex);
2218 /* copy data to userspace */
2219 i = bdev->fifo_size - bdev->rd_index;
2220 if (count > i)
2221 count = (i / 3) * 3;
2222
2223 i = 0;
2224 while (i < count) {
2225 unsigned char tmpbuf[3];
b317d0f5 2226
3ac086fb
AG
2227 tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index + i + 2];
2228 tmpbuf[i + 1] =
2229 bdev->rds_info.radio_text[bdev->rd_index + i + 1];
2230 tmpbuf[i + 2] =
2231 (bdev->rds_info.radio_text[bdev->rd_index + i] &
2232 0xf0) >> 4;
2233 if ((bdev->rds_info.radio_text[bdev->rd_index + i] &
925b6578 2234 BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE)
3ac086fb
AG
2235 tmpbuf[i + 2] |= 0x80;
2236 if (copy_to_user(buf + i, tmpbuf, 3)) {
899127b6
HV
2237 retval = -EFAULT;
2238 break;
12d1ee1f 2239 }
899127b6
HV
2240 i += 3;
2241 }
2242
2243 bdev->rd_index += i;
2244 if (bdev->rd_index >= bdev->fifo_size)
2245 bdev->rds_data_available = 0;
2246
2247 mutex_unlock(&bdev->mutex);
2248 if (retval == 0)
2249 retval = i;
2250
2251done:
2252 return retval;
2253}
2254
2255/*
2256 * bcm2048_fops - file operations interface
2257 */
2258static const struct v4l2_file_operations bcm2048_fops = {
2259 .owner = THIS_MODULE,
2e1328dd 2260 .unlocked_ioctl = video_ioctl2,
899127b6
HV
2261 /* for RDS read support */
2262 .open = bcm2048_fops_open,
2263 .release = bcm2048_fops_release,
2264 .read = bcm2048_fops_read,
2265 .poll = bcm2048_fops_poll
2266};
2267
2268/*
2269 * Video4Linux Interface
2270 */
2271static struct v4l2_queryctrl bcm2048_v4l2_queryctrl[] = {
2272 {
2273 .id = V4L2_CID_AUDIO_VOLUME,
2274 .flags = V4L2_CTRL_FLAG_DISABLED,
2275 },
2276 {
2277 .id = V4L2_CID_AUDIO_BALANCE,
2278 .flags = V4L2_CTRL_FLAG_DISABLED,
2279 },
2280 {
2281 .id = V4L2_CID_AUDIO_BASS,
2282 .flags = V4L2_CTRL_FLAG_DISABLED,
2283 },
2284 {
2285 .id = V4L2_CID_AUDIO_TREBLE,
2286 .flags = V4L2_CTRL_FLAG_DISABLED,
2287 },
2288 {
2289 .id = V4L2_CID_AUDIO_MUTE,
2290 .type = V4L2_CTRL_TYPE_BOOLEAN,
2291 .name = "Mute",
2292 .minimum = 0,
2293 .maximum = 1,
2294 .step = 1,
2295 .default_value = 1,
2296 },
2297 {
2298 .id = V4L2_CID_AUDIO_LOUDNESS,
2299 .flags = V4L2_CTRL_FLAG_DISABLED,
2300 },
2301};
2302
2303static int bcm2048_vidioc_querycap(struct file *file, void *priv,
925b6578 2304 struct v4l2_capability *capability)
899127b6
HV
2305{
2306 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2307
2308 strlcpy(capability->driver, BCM2048_DRIVER_NAME,
2309 sizeof(capability->driver));
2310 strlcpy(capability->card, BCM2048_DRIVER_CARD,
2311 sizeof(capability->card));
2312 snprintf(capability->bus_info, 32, "I2C: 0x%X", bdev->client->addr);
57e774cc 2313 capability->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
899127b6 2314 V4L2_CAP_HW_FREQ_SEEK;
57e774cc
HV
2315 capability->capabilities = capability->device_caps |
2316 V4L2_CAP_DEVICE_CAPS;
899127b6
HV
2317
2318 return 0;
2319}
2320
2321static int bcm2048_vidioc_g_input(struct file *filp, void *priv,
925b6578 2322 unsigned int *i)
899127b6
HV
2323{
2324 *i = 0;
2325
2326 return 0;
2327}
2328
2329static int bcm2048_vidioc_s_input(struct file *filp, void *priv,
925b6578 2330 unsigned int i)
899127b6
HV
2331{
2332 if (i)
2333 return -EINVAL;
2334
2335 return 0;
2336}
2337
2338static int bcm2048_vidioc_queryctrl(struct file *file, void *priv,
925b6578 2339 struct v4l2_queryctrl *qc)
899127b6
HV
2340{
2341 int i;
2342
2343 for (i = 0; i < ARRAY_SIZE(bcm2048_v4l2_queryctrl); i++) {
2344 if (qc->id && qc->id == bcm2048_v4l2_queryctrl[i].id) {
65eccc7a 2345 *qc = bcm2048_v4l2_queryctrl[i];
899127b6
HV
2346 return 0;
2347 }
2348 }
2349
2350 return -EINVAL;
2351}
2352
2353static int bcm2048_vidioc_g_ctrl(struct file *file, void *priv,
925b6578 2354 struct v4l2_control *ctrl)
899127b6
HV
2355{
2356 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2357 int err = 0;
2358
2359 if (!bdev)
2360 return -ENODEV;
2361
2362 switch (ctrl->id) {
2363 case V4L2_CID_AUDIO_MUTE:
2364 err = bcm2048_get_mute(bdev);
2365 if (err >= 0)
2366 ctrl->value = err;
2367 break;
2368 }
2369
2370 return err;
2371}
2372
2373static int bcm2048_vidioc_s_ctrl(struct file *file, void *priv,
925b6578 2374 struct v4l2_control *ctrl)
899127b6
HV
2375{
2376 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2377 int err = 0;
2378
2379 if (!bdev)
2380 return -ENODEV;
2381
2382 switch (ctrl->id) {
2383 case V4L2_CID_AUDIO_MUTE:
2384 if (ctrl->value) {
2385 if (bdev->power_state) {
2386 err = bcm2048_set_mute(bdev, ctrl->value);
2387 err |= bcm2048_deinit(bdev);
2388 }
2389 } else {
2390 if (!bdev->power_state) {
2391 err = bcm2048_init(bdev);
2392 err |= bcm2048_set_mute(bdev, ctrl->value);
2393 }
2394 }
2395 break;
2396 }
2397
2398 return err;
2399}
2400
2401static int bcm2048_vidioc_g_audio(struct file *file, void *priv,
925b6578 2402 struct v4l2_audio *audio)
899127b6
HV
2403{
2404 if (audio->index > 1)
2405 return -EINVAL;
2406
2407 strncpy(audio->name, "Radio", 32);
2408 audio->capability = V4L2_AUDCAP_STEREO;
2409
2410 return 0;
2411}
2412
2413static int bcm2048_vidioc_s_audio(struct file *file, void *priv,
925b6578 2414 const struct v4l2_audio *audio)
899127b6
HV
2415{
2416 if (audio->index != 0)
2417 return -EINVAL;
2418
2419 return 0;
2420}
2421
2422static int bcm2048_vidioc_g_tuner(struct file *file, void *priv,
925b6578 2423 struct v4l2_tuner *tuner)
899127b6
HV
2424{
2425 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2426 s8 f_error;
2427 s8 rssi;
2428
2429 if (!bdev)
2430 return -ENODEV;
2431
2432 if (tuner->index > 0)
2433 return -EINVAL;
2434
2435 strncpy(tuner->name, "FM Receiver", 32);
2436 tuner->type = V4L2_TUNER_RADIO;
2437 tuner->rangelow =
2438 dev_to_v4l2(bcm2048_get_region_bottom_frequency(bdev));
2439 tuner->rangehigh =
2440 dev_to_v4l2(bcm2048_get_region_top_frequency(bdev));
2441 tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
2442 tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW;
2443 tuner->audmode = V4L2_TUNER_MODE_STEREO;
2444 tuner->afc = 0;
2445 if (bdev->power_state) {
2446 /*
2447 * Report frequencies with high carrier errors to have zero
2448 * signal level
2449 */
2450 f_error = bcm2048_get_fm_carrier_error(bdev);
2451 if (f_error < BCM2048_FREQ_ERROR_FLOOR ||
2452 f_error > BCM2048_FREQ_ERROR_ROOF) {
2453 tuner->signal = 0;
2454 } else {
2455 /*
2456 * RSSI level -60 dB is defined to report full
69e98df7 2457 * signal strength
899127b6
HV
2458 */
2459 rssi = bcm2048_get_fm_rssi(bdev);
2460 if (rssi >= BCM2048_RSSI_LEVEL_BASE) {
2461 tuner->signal = 0xFFFF;
2462 } else if (rssi > BCM2048_RSSI_LEVEL_ROOF) {
2463 tuner->signal = (rssi +
2464 BCM2048_RSSI_LEVEL_ROOF_NEG)
2465 * BCM2048_SIGNAL_MULTIPLIER;
2466 } else {
2467 tuner->signal = 0;
2468 }
2469 }
2470 } else {
2471 tuner->signal = 0;
2472 }
2473
2474 return 0;
2475}
2476
2477static int bcm2048_vidioc_s_tuner(struct file *file, void *priv,
925b6578 2478 const struct v4l2_tuner *tuner)
899127b6
HV
2479{
2480 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2481
2482 if (!bdev)
2483 return -ENODEV;
2484
2485 if (tuner->index > 0)
2486 return -EINVAL;
2487
2488 return 0;
2489}
2490
2491static int bcm2048_vidioc_g_frequency(struct file *file, void *priv,
925b6578 2492 struct v4l2_frequency *freq)
899127b6
HV
2493{
2494 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2495 int err = 0;
2496 int f;
2497
2498 if (!bdev->power_state)
2499 return -ENODEV;
2500
2501 freq->type = V4L2_TUNER_RADIO;
2502 f = bcm2048_get_fm_frequency(bdev);
2503
2504 if (f < 0)
2505 err = f;
2506 else
2507 freq->frequency = dev_to_v4l2(f);
2508
2509 return err;
2510}
2511
2512static int bcm2048_vidioc_s_frequency(struct file *file, void *priv,
925b6578 2513 const struct v4l2_frequency *freq)
899127b6
HV
2514{
2515 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2516 int err;
2517
2518 if (freq->type != V4L2_TUNER_RADIO)
2519 return -EINVAL;
2520
2521 if (!bdev->power_state)
2522 return -ENODEV;
2523
2524 err = bcm2048_set_fm_frequency(bdev, v4l2_to_dev(freq->frequency));
2525 err |= bcm2048_set_fm_search_tune_mode(bdev, BCM2048_FM_PRE_SET_MODE);
2526
2527 return err;
2528}
2529
2530static int bcm2048_vidioc_s_hw_freq_seek(struct file *file, void *priv,
925b6578 2531 const struct v4l2_hw_freq_seek *seek)
899127b6
HV
2532{
2533 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2534 int err;
2535
2536 if (!bdev->power_state)
2537 return -ENODEV;
2538
2539 if ((seek->tuner != 0) || (seek->type != V4L2_TUNER_RADIO))
2540 return -EINVAL;
2541
2542 err = bcm2048_set_fm_search_mode_direction(bdev, seek->seek_upward);
2543 err |= bcm2048_set_fm_search_tune_mode(bdev,
925b6578 2544 BCM2048_FM_AUTO_SEARCH_MODE);
899127b6
HV
2545
2546 return err;
2547}
2548
2549static struct v4l2_ioctl_ops bcm2048_ioctl_ops = {
2550 .vidioc_querycap = bcm2048_vidioc_querycap,
2551 .vidioc_g_input = bcm2048_vidioc_g_input,
2552 .vidioc_s_input = bcm2048_vidioc_s_input,
2553 .vidioc_queryctrl = bcm2048_vidioc_queryctrl,
2554 .vidioc_g_ctrl = bcm2048_vidioc_g_ctrl,
2555 .vidioc_s_ctrl = bcm2048_vidioc_s_ctrl,
2556 .vidioc_g_audio = bcm2048_vidioc_g_audio,
2557 .vidioc_s_audio = bcm2048_vidioc_s_audio,
2558 .vidioc_g_tuner = bcm2048_vidioc_g_tuner,
2559 .vidioc_s_tuner = bcm2048_vidioc_s_tuner,
2560 .vidioc_g_frequency = bcm2048_vidioc_g_frequency,
2561 .vidioc_s_frequency = bcm2048_vidioc_s_frequency,
2562 .vidioc_s_hw_freq_seek = bcm2048_vidioc_s_hw_freq_seek,
2563};
2564
2565/*
2566 * bcm2048_viddev_template - video device interface
2567 */
2568static struct video_device bcm2048_viddev_template = {
2569 .fops = &bcm2048_fops,
2570 .name = BCM2048_DRIVER_NAME,
54ad7b9d 2571 .release = video_device_release_empty,
899127b6
HV
2572 .ioctl_ops = &bcm2048_ioctl_ops,
2573};
2574
2575/*
2576 * I2C driver interface
2577 */
2578static int bcm2048_i2c_driver_probe(struct i2c_client *client,
925b6578 2579 const struct i2c_device_id *id)
899127b6
HV
2580{
2581 struct bcm2048_device *bdev;
bb17141c 2582 int err;
899127b6
HV
2583
2584 bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
2585 if (!bdev) {
899127b6
HV
2586 err = -ENOMEM;
2587 goto exit;
2588 }
2589
899127b6
HV
2590 bdev->client = client;
2591 i2c_set_clientdata(client, bdev);
2592 mutex_init(&bdev->mutex);
2593 init_completion(&bdev->compl);
2594 INIT_WORK(&bdev->work, bcm2048_work);
2595
2596 if (client->irq) {
2597 err = request_irq(client->irq,
925b6578
AG
2598 bcm2048_handler, IRQF_TRIGGER_FALLING,
2599 client->name, bdev);
899127b6
HV
2600 if (err < 0) {
2601 dev_err(&client->dev, "Could not request IRQ\n");
54ad7b9d 2602 goto free_bdev;
899127b6
HV
2603 }
2604 dev_dbg(&client->dev, "IRQ requested.\n");
2605 } else {
2606 dev_dbg(&client->dev, "IRQ not configured. Using timeouts.\n");
2607 }
2608
54ad7b9d
HV
2609 bdev->videodev = bcm2048_viddev_template;
2610 video_set_drvdata(&bdev->videodev, bdev);
2611 if (video_register_device(&bdev->videodev, VFL_TYPE_RADIO, radio_nr)) {
899127b6
HV
2612 dev_dbg(&client->dev, "Could not register video device.\n");
2613 err = -EIO;
2614 goto free_irq;
2615 }
2616
2617 err = bcm2048_sysfs_register_properties(bdev);
2618 if (err < 0) {
2619 dev_dbg(&client->dev, "Could not register sysfs interface.\n");
2620 goto free_registration;
2621 }
2622
2623 err = bcm2048_probe(bdev);
2624 if (err < 0) {
2625 dev_dbg(&client->dev, "Failed to probe device information.\n");
2626 goto free_sysfs;
2627 }
2628
2629 return 0;
2630
2631free_sysfs:
2632 bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
2633free_registration:
54ad7b9d 2634 video_unregister_device(&bdev->videodev);
899127b6
HV
2635free_irq:
2636 if (client->irq)
2637 free_irq(client->irq, bdev);
899127b6 2638free_bdev:
54ad7b9d 2639 i2c_set_clientdata(client, NULL);
899127b6
HV
2640 kfree(bdev);
2641exit:
2642 return err;
2643}
2644
2645static int __exit bcm2048_i2c_driver_remove(struct i2c_client *client)
2646{
2647 struct bcm2048_device *bdev = i2c_get_clientdata(client);
899127b6
HV
2648
2649 if (!client->adapter)
2650 return -ENODEV;
2651
2652 if (bdev) {
899127b6 2653 bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
54ad7b9d 2654 video_unregister_device(&bdev->videodev);
899127b6
HV
2655
2656 if (bdev->power_state)
2657 bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
2658
2659 if (client->irq > 0)
2660 free_irq(client->irq, bdev);
2661
2662 cancel_work_sync(&bdev->work);
2663
2664 kfree(bdev);
2665 }
2666
899127b6
HV
2667 return 0;
2668}
2669
2670/*
2671 * bcm2048_i2c_driver - i2c driver interface
2672 */
2673static const struct i2c_device_id bcm2048_id[] = {
5937a784 2674 { "bcm2048", 0 },
899127b6
HV
2675 { },
2676};
2677MODULE_DEVICE_TABLE(i2c, bcm2048_id);
2678
2679static struct i2c_driver bcm2048_i2c_driver = {
2680 .driver = {
2681 .name = BCM2048_DRIVER_NAME,
2682 },
2683 .probe = bcm2048_i2c_driver_probe,
2684 .remove = __exit_p(bcm2048_i2c_driver_remove),
2685 .id_table = bcm2048_id,
2686};
2687
4c205ab5 2688module_i2c_driver(bcm2048_i2c_driver);
899127b6
HV
2689
2690MODULE_LICENSE("GPL");
2691MODULE_AUTHOR(BCM2048_DRIVER_AUTHOR);
2692MODULE_DESCRIPTION(BCM2048_DRIVER_DESC);
2693MODULE_VERSION("0.0.2");
This page took 0.462002 seconds and 5 git commands to generate.