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