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