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