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