linux/drivers/staging/media/bcm2048/radio-bcm2048.c
<<
>>
Prefs
   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#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/* -60 dB is reported as full signal strength */
 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        /* for rds data device read */
 300        wait_queue_head_t read_queue;
 301        unsigned int users;
 302        unsigned char rds_data_available;
 303        unsigned int rd_index;
 304};
 305
 306static int radio_nr = -1;       /* radio device minor (-1 ==> auto assign) */
 307module_param(radio_nr, int, 0);
 308MODULE_PARM_DESC(radio_nr,
 309                 "Minor number for radio device (-1 ==> auto assign)");
 310
 311static const struct region_info region_configs[] = {
 312        /* USA */
 313        {
 314                .channel_spacing        = 20,
 315                .bottom_frequency       = 87500,
 316                .top_frequency          = 108000,
 317                .deemphasis             = 75,
 318                .region                 = 0,
 319        },
 320        /* Australia */
 321        {
 322                .channel_spacing        = 20,
 323                .bottom_frequency       = 87500,
 324                .top_frequency          = 108000,
 325                .deemphasis             = 50,
 326                .region                 = 1,
 327        },
 328        /* Europe */
 329        {
 330                .channel_spacing        = 10,
 331                .bottom_frequency       = 87500,
 332                .top_frequency          = 108000,
 333                .deemphasis             = 50,
 334                .region                 = 2,
 335        },
 336        /* Japan */
 337        {
 338                .channel_spacing        = 10,
 339                .bottom_frequency       = 76000,
 340                .top_frequency          = 90000,
 341                .deemphasis             = 50,
 342                .region                 = 3,
 343        },
 344};
 345
 346/*
 347 *      I2C Interface read / write
 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 *      BCM2048 - I2C register programming helpers
 417 */
 418static int bcm2048_set_power_state(struct bcm2048_device *bdev, u8 power)
 419{
 420        int err = 0;
 421
 422        mutex_lock(&bdev->mutex);
 423
 424        if (power) {
 425                bdev->power_state = BCM2048_POWER_ON;
 426                bdev->cache_fm_rds_system |= BCM2048_FM_ON;
 427        } else {
 428                bdev->cache_fm_rds_system &= ~BCM2048_FM_ON;
 429        }
 430
 431        /*
 432         * Warning! FM cannot be turned off because then
 433         * the I2C communications get ruined!
 434         * Comment off the "if (power)" when the chip works!
 435         */
 436        if (power)
 437                err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
 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         * If RDS is enabled, and frequency is changed, RDS quits working.
 977         * Thus, always restart RDS if it's enabled. Moreover, RDS must
 978         * not be enabled while changing the frequency because it can
 979         * provide a race to the mutex from the workqueue handler if RDS
 980         * IRQ occurs while waiting for frequency changed IRQ.
 981         */
 982        if (bcm2048_get_rds_no_lock(bdev)) {
 983                err = bcm2048_set_rds_no_lock(bdev, 0);
 984                if (err)
 985                        goto unlock;
 986                restart_rds = 1;
 987        }
 988
 989        err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, flags);
 990
 991        if (err)
 992                goto unlock;
 993
 994        bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE, value);
 995
 996        if (mode != BCM2048_FM_AUTO_SEARCH_MODE)
 997                timeout = BCM2048_DEFAULT_TIMEOUT;
 998        else
 999                timeout = BCM2048_AUTO_SEARCH_TIMEOUT;
1000
1001        if (!wait_for_completion_timeout(&bdev->compl,
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        /* Perform read as the manual indicates */
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                        /* Skip the carriage return */
1365                        if (bdev->rds_info.rds_rt[i] != 0x0d) {
1366                                data_buffer[j++] = bdev->rds_info.rds_rt[i];
1367                        } else {
1368                                cr = i;
1369                                break;
1370                        }
1371                }
1372        }
1373
1374        if (j <= BCM2048_MAX_RDS_RT)
1375                data_buffer[j] = 0;
1376
1377        for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
1378                if (!bdev->rds_info.rds_rt[i]) {
1379                        if (cr && (i < cr)) {
1380                                err = -EBUSY;
1381                                goto unlock;
1382                        }
1383                        if (i < ce) {
1384                                if (cr && (i >= cr))
1385                                        break;
1386                                err = -EBUSY;
1387                                goto unlock;
1388                        }
1389                }
1390        }
1391
1392        memcpy(data, data_buffer, sizeof(data_buffer));
1393
1394unlock:
1395        mutex_unlock(&bdev->mutex);
1396        return err;
1397}
1398
1399static int bcm2048_get_rds_ps(struct bcm2048_device *bdev, char *data)
1400{
1401        int err = 0, i, j = 0;
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                /* Block A match, only data without crc errors taken */
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        /* Good data will overwrite poor data */
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                        /* A to B or (vice versa), means: clear screen */
1510                        if (rt_ab != bdev->rds_info.rds_rt_ab) {
1511                                memset(bdev->rds_info.rds_rt, 0,
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                /* Skip erroneous blocks due to messed up A block altogether */
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                        /* Synchronize to a good RDS PI */
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        /* Good data will overwrite poor data */
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        /* Block B Radio PS match */
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                 * Poor RSSI will lead to RDS data corruption
1678                 * So using 3 (same) sequential values to justify major changes
1679                 */
1680                if (ps_group != bdev->rds_info.rds_ps_group) {
1681                        if (crc == BCM2048_RDS_CRC_NONE) {
1682                                bdev->rds_info.rds_ps_group_cnt++;
1683                                if (bdev->rds_info.rds_ps_group_cnt > 2) {
1684                                        bdev->rds_info.rds_ps_group = ps_group;
1685                                        bdev->rds_info.rds_ps_group_cnt = 0;
1686                                        dev_err(&bdev->client->dev,
1687                                                "RDS PS Group change!\n");
1688                                } else {
1689                                        return -EIO;
1690                                }
1691                        } else {
1692                                bdev->rds_info.rds_ps_group_cnt = 0;
1693                        }
1694                }
1695
1696                if (ps_id == BCM2048_RDS_PS) {
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                /* Skip erroneous blocks due to messed up A block altogether */
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                        /* Synchronize to a good RDS PI */
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 *      BCM2048 default initialization sequence
1802 */
1803static int bcm2048_init(struct bcm2048_device *bdev)
1804{
1805        int err;
1806
1807        err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
1808        if (err < 0)
1809                goto exit;
1810
1811        err = bcm2048_set_audio_route(bdev, BCM2048_AUDIO_ROUTE_DAC);
1812        if (err < 0)
1813                goto exit;
1814
1815        err = bcm2048_set_dac_output(bdev, BCM2048_DAC_OUTPUT_LEFT |
1816                                     BCM2048_DAC_OUTPUT_RIGHT);
1817
1818exit:
1819        return err;
1820}
1821
1822/*
1823 *      BCM2048 default deinitialization sequence
1824 */
1825static int bcm2048_deinit(struct bcm2048_device *bdev)
1826{
1827        int err;
1828
1829        err = bcm2048_set_audio_route(bdev, 0);
1830        if (err < 0)
1831                return err;
1832
1833        err = bcm2048_set_dac_output(bdev, 0);
1834        if (err < 0)
1835                return err;
1836
1837        err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
1838
1839        return err;
1840}
1841
1842/*
1843 *      BCM2048 probe sequence
1844 */
1845static int bcm2048_probe(struct bcm2048_device *bdev)
1846{
1847        int err;
1848
1849        err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
1850        if (err < 0)
1851                goto unlock;
1852
1853        err = bcm2048_checkrev(bdev);
1854        if (err < 0)
1855                goto unlock;
1856
1857        err = bcm2048_set_mute(bdev, BCM2048_DEFAULT_MUTE);
1858        if (err < 0)
1859                goto unlock;
1860
1861        err = bcm2048_set_region(bdev, BCM2048_DEFAULT_REGION);
1862        if (err < 0)
1863                goto unlock;
1864
1865        err = bcm2048_set_fm_search_rssi_threshold(bdev,
1866                                        BCM2048_DEFAULT_RSSI_THRESHOLD);
1867        if (err < 0)
1868                goto unlock;
1869
1870        err = bcm2048_set_fm_automatic_stereo_mono(bdev, BCM2048_ITEM_ENABLED);
1871        if (err < 0)
1872                goto unlock;
1873
1874        err = bcm2048_get_rds_wline(bdev);
1875        if (err < BCM2048_DEFAULT_RDS_WLINE)
1876                err = bcm2048_set_rds_wline(bdev, BCM2048_DEFAULT_RDS_WLINE);
1877        if (err < 0)
1878                goto unlock;
1879
1880        err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
1881
1882        init_waitqueue_head(&bdev->read_queue);
1883        bdev->rds_data_available = 0;
1884        bdev->rd_index = 0;
1885        bdev->users = 0;
1886
1887unlock:
1888        return err;
1889}
1890
1891/*
1892 *      BCM2048 workqueue handler
1893 */
1894static void bcm2048_work(struct work_struct *work)
1895{
1896        struct bcm2048_device *bdev;
1897        u8 flag_lsb = 0, flag_msb = 0, flags;
1898
1899        bdev = container_of(work, struct bcm2048_device, work);
1900        bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &flag_lsb);
1901        bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &flag_msb);
1902
1903        if (flag_lsb & (BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
1904                        BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)) {
1905                if (flag_lsb & BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)
1906                        bdev->scan_state = BCM2048_SCAN_FAIL;
1907                else
1908                        bdev->scan_state = BCM2048_SCAN_OK;
1909
1910                complete(&bdev->compl);
1911        }
1912
1913        if (flag_msb & BCM2048_RDS_FLAG_FIFO_WLINE) {
1914                bcm2048_rds_fifo_receive(bdev);
1915                if (bdev->rds_state) {
1916                        flags = BCM2048_RDS_FLAG_FIFO_WLINE;
1917                        bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
1918                                             flags);
1919                }
1920                bdev->rds_data_available = 1;
1921                bdev->rd_index = 0; /* new data, new start */
1922        }
1923}
1924
1925/*
1926 *      BCM2048 interrupt handler
1927 */
1928static irqreturn_t bcm2048_handler(int irq, void *dev)
1929{
1930        struct bcm2048_device *bdev = dev;
1931
1932        dev_dbg(&bdev->client->dev, "IRQ called, queuing work\n");
1933        if (bdev->power_state)
1934                schedule_work(&bdev->work);
1935
1936        return IRQ_HANDLED;
1937}
1938
1939/*
1940 *      BCM2048 sysfs interface definitions
1941 */
1942#define property_write(prop, type, mask, check)                         \
1943static ssize_t bcm2048_##prop##_write(struct device *dev,               \
1944                                        struct device_attribute *attr,  \
1945                                        const char *buf,                \
1946                                        size_t count)                   \
1947{                                                                       \
1948        struct bcm2048_device *bdev = dev_get_drvdata(dev);             \
1949        type value;                                                     \
1950        int err;                                                        \
1951                                                                        \
1952        if (!bdev)                                                      \
1953                return -ENODEV;                                         \
1954                                                                        \
1955        if (sscanf(buf, mask, &value) != 1)                             \
1956                return -EINVAL;                                         \
1957                                                                        \
1958        if (check)                                                      \
1959                return -EDOM;                                           \
1960                                                                        \
1961        err = bcm2048_set_##prop(bdev, value);                          \
1962                                                                        \
1963        return err < 0 ? err : count;                                   \
1964}
1965
1966#define property_read(prop, size, mask)                                 \
1967static ssize_t bcm2048_##prop##_read(struct device *dev,                \
1968                                        struct device_attribute *attr,  \
1969                                        char *buf)                      \
1970{                                                                       \
1971        struct bcm2048_device *bdev = dev_get_drvdata(dev);             \
1972        int value;                                                      \
1973                                                                        \
1974        if (!bdev)                                                      \
1975                return -ENODEV;                                         \
1976                                                                        \
1977        value = bcm2048_get_##prop(bdev);                               \
1978                                                                        \
1979        if (value >= 0)                                                 \
1980                value = sprintf(buf, mask "\n", value);                 \
1981                                                                        \
1982        return value;                                                   \
1983}
1984
1985#define property_signed_read(prop, size, mask)                          \
1986static ssize_t bcm2048_##prop##_read(struct device *dev,                \
1987                                        struct device_attribute *attr,  \
1988                                        char *buf)                      \
1989{                                                                       \
1990        struct bcm2048_device *bdev = dev_get_drvdata(dev);             \
1991        size value;                                                     \
1992                                                                        \
1993        if (!bdev)                                                      \
1994                return -ENODEV;                                         \
1995                                                                        \
1996        value = bcm2048_get_##prop(bdev);                               \
1997                                                                        \
1998        value = sprintf(buf, mask "\n", value);                         \
1999                                                                        \
2000        return value;                                                   \
2001}
2002
2003#define DEFINE_SYSFS_PROPERTY(prop, signal, size, mask, check)          \
2004property_write(prop, signal size, mask, check)                          \
2005property_read(prop, size, mask)
2006
2007#define property_str_read(prop, size)                                   \
2008static ssize_t bcm2048_##prop##_read(struct device *dev,                \
2009                                        struct device_attribute *attr,  \
2010                                        char *buf)                      \
2011{                                                                       \
2012        struct bcm2048_device *bdev = dev_get_drvdata(dev);             \
2013        int count;                                                      \
2014        u8 *out;                                                        \
2015                                                                        \
2016        if (!bdev)                                                      \
2017                return -ENODEV;                                         \
2018                                                                        \
2019        out = kzalloc(size + 1, GFP_KERNEL);                            \
2020        if (!out)                                                       \
2021                return -ENOMEM;                                         \
2022                                                                        \
2023        bcm2048_get_##prop(bdev, out);                                  \
2024        count = sprintf(buf, "%s\n", out);                              \
2025                                                                        \
2026        kfree(out);                                                     \
2027                                                                        \
2028        return count;                                                   \
2029}
2030
2031DEFINE_SYSFS_PROPERTY(power_state, unsigned, int, "%u", 0)
2032DEFINE_SYSFS_PROPERTY(mute, unsigned, int, "%u", 0)
2033DEFINE_SYSFS_PROPERTY(audio_route, unsigned, int, "%u", 0)
2034DEFINE_SYSFS_PROPERTY(dac_output, unsigned, int, "%u", 0)
2035
2036DEFINE_SYSFS_PROPERTY(fm_hi_lo_injection, unsigned, int, "%u", 0)
2037DEFINE_SYSFS_PROPERTY(fm_frequency, unsigned, int, "%u", 0)
2038DEFINE_SYSFS_PROPERTY(fm_af_frequency, unsigned, int, "%u", 0)
2039DEFINE_SYSFS_PROPERTY(fm_deemphasis, unsigned, int, "%u", 0)
2040DEFINE_SYSFS_PROPERTY(fm_rds_mask, unsigned, int, "%u", 0)
2041DEFINE_SYSFS_PROPERTY(fm_best_tune_mode, unsigned, int, "%u", 0)
2042DEFINE_SYSFS_PROPERTY(fm_search_rssi_threshold, unsigned, int, "%u", 0)
2043DEFINE_SYSFS_PROPERTY(fm_search_mode_direction, unsigned, int, "%u", 0)
2044DEFINE_SYSFS_PROPERTY(fm_search_tune_mode, unsigned, int, "%u", value > 3)
2045
2046DEFINE_SYSFS_PROPERTY(rds, unsigned, int, "%u", 0)
2047DEFINE_SYSFS_PROPERTY(rds_b_block_mask, unsigned, int, "%u", 0)
2048DEFINE_SYSFS_PROPERTY(rds_b_block_match, unsigned, int, "%u", 0)
2049DEFINE_SYSFS_PROPERTY(rds_pi_mask, unsigned, int, "%u", 0)
2050DEFINE_SYSFS_PROPERTY(rds_pi_match, unsigned, int, "%u", 0)
2051DEFINE_SYSFS_PROPERTY(rds_wline, unsigned, int, "%u", 0)
2052property_read(rds_pi, unsigned int, "%x")
2053property_str_read(rds_rt, (BCM2048_MAX_RDS_RT + 1))
2054property_str_read(rds_ps, (BCM2048_MAX_RDS_PS + 1))
2055
2056property_read(fm_rds_flags, unsigned int, "%u")
2057property_str_read(rds_data, BCM2048_MAX_RDS_RADIO_TEXT * 5)
2058
2059property_read(region_bottom_frequency, unsigned int, "%u")
2060property_read(region_top_frequency, unsigned int, "%u")
2061property_signed_read(fm_carrier_error, int, "%d")
2062property_signed_read(fm_rssi, int, "%d")
2063DEFINE_SYSFS_PROPERTY(region, unsigned, int, "%u", 0)
2064
2065static struct device_attribute attrs[] = {
2066        __ATTR(power_state, S_IRUGO | S_IWUSR, bcm2048_power_state_read,
2067               bcm2048_power_state_write),
2068        __ATTR(mute, S_IRUGO | S_IWUSR, bcm2048_mute_read,
2069               bcm2048_mute_write),
2070        __ATTR(audio_route, S_IRUGO | S_IWUSR, bcm2048_audio_route_read,
2071               bcm2048_audio_route_write),
2072        __ATTR(dac_output, S_IRUGO | S_IWUSR, bcm2048_dac_output_read,
2073               bcm2048_dac_output_write),
2074        __ATTR(fm_hi_lo_injection, S_IRUGO | S_IWUSR,
2075               bcm2048_fm_hi_lo_injection_read,
2076               bcm2048_fm_hi_lo_injection_write),
2077        __ATTR(fm_frequency, S_IRUGO | S_IWUSR, bcm2048_fm_frequency_read,
2078               bcm2048_fm_frequency_write),
2079        __ATTR(fm_af_frequency, S_IRUGO | S_IWUSR,
2080               bcm2048_fm_af_frequency_read,
2081               bcm2048_fm_af_frequency_write),
2082        __ATTR(fm_deemphasis, S_IRUGO | S_IWUSR, bcm2048_fm_deemphasis_read,
2083               bcm2048_fm_deemphasis_write),
2084        __ATTR(fm_rds_mask, S_IRUGO | S_IWUSR, bcm2048_fm_rds_mask_read,
2085               bcm2048_fm_rds_mask_write),
2086        __ATTR(fm_best_tune_mode, S_IRUGO | S_IWUSR,
2087               bcm2048_fm_best_tune_mode_read,
2088               bcm2048_fm_best_tune_mode_write),
2089        __ATTR(fm_search_rssi_threshold, S_IRUGO | S_IWUSR,
2090               bcm2048_fm_search_rssi_threshold_read,
2091               bcm2048_fm_search_rssi_threshold_write),
2092        __ATTR(fm_search_mode_direction, S_IRUGO | S_IWUSR,
2093               bcm2048_fm_search_mode_direction_read,
2094               bcm2048_fm_search_mode_direction_write),
2095        __ATTR(fm_search_tune_mode, S_IRUGO | S_IWUSR,
2096               bcm2048_fm_search_tune_mode_read,
2097               bcm2048_fm_search_tune_mode_write),
2098        __ATTR(rds, S_IRUGO | S_IWUSR, bcm2048_rds_read,
2099               bcm2048_rds_write),
2100        __ATTR(rds_b_block_mask, S_IRUGO | S_IWUSR,
2101               bcm2048_rds_b_block_mask_read,
2102               bcm2048_rds_b_block_mask_write),
2103        __ATTR(rds_b_block_match, S_IRUGO | S_IWUSR,
2104               bcm2048_rds_b_block_match_read,
2105               bcm2048_rds_b_block_match_write),
2106        __ATTR(rds_pi_mask, S_IRUGO | S_IWUSR, bcm2048_rds_pi_mask_read,
2107               bcm2048_rds_pi_mask_write),
2108        __ATTR(rds_pi_match, S_IRUGO | S_IWUSR, bcm2048_rds_pi_match_read,
2109               bcm2048_rds_pi_match_write),
2110        __ATTR(rds_wline, S_IRUGO | S_IWUSR, bcm2048_rds_wline_read,
2111               bcm2048_rds_wline_write),
2112        __ATTR(rds_pi, S_IRUGO, bcm2048_rds_pi_read, NULL),
2113        __ATTR(rds_rt, S_IRUGO, bcm2048_rds_rt_read, NULL),
2114        __ATTR(rds_ps, S_IRUGO, bcm2048_rds_ps_read, NULL),
2115        __ATTR(fm_rds_flags, S_IRUGO, bcm2048_fm_rds_flags_read, NULL),
2116        __ATTR(region_bottom_frequency, S_IRUGO,
2117               bcm2048_region_bottom_frequency_read, NULL),
2118        __ATTR(region_top_frequency, S_IRUGO,
2119               bcm2048_region_top_frequency_read, NULL),
2120        __ATTR(fm_carrier_error, S_IRUGO,
2121               bcm2048_fm_carrier_error_read, NULL),
2122        __ATTR(fm_rssi, S_IRUGO,
2123               bcm2048_fm_rssi_read, NULL),
2124        __ATTR(region, S_IRUGO | S_IWUSR, bcm2048_region_read,
2125               bcm2048_region_write),
2126        __ATTR(rds_data, S_IRUGO, bcm2048_rds_data_read, NULL),
2127};
2128
2129static int bcm2048_sysfs_unregister_properties(struct bcm2048_device *bdev,
2130                                               int size)
2131{
2132        int i;
2133
2134        for (i = 0; i < size; i++)
2135                device_remove_file(&bdev->client->dev, &attrs[i]);
2136
2137        return 0;
2138}
2139
2140static int bcm2048_sysfs_register_properties(struct bcm2048_device *bdev)
2141{
2142        int err = 0;
2143        int i;
2144
2145        for (i = 0; i < ARRAY_SIZE(attrs); i++) {
2146                if (device_create_file(&bdev->client->dev, &attrs[i]) != 0) {
2147                        dev_err(&bdev->client->dev,
2148                                "could not register sysfs entry\n");
2149                        err = -EBUSY;
2150                        bcm2048_sysfs_unregister_properties(bdev, i);
2151                        break;
2152                }
2153        }
2154
2155        return err;
2156}
2157
2158static int bcm2048_fops_open(struct file *file)
2159{
2160        struct bcm2048_device *bdev = video_drvdata(file);
2161
2162        bdev->users++;
2163        bdev->rd_index = 0;
2164        bdev->rds_data_available = 0;
2165
2166        return 0;
2167}
2168
2169static int bcm2048_fops_release(struct file *file)
2170{
2171        struct bcm2048_device *bdev = video_drvdata(file);
2172
2173        bdev->users--;
2174
2175        return 0;
2176}
2177
2178static unsigned int bcm2048_fops_poll(struct file *file,
2179                                      struct poll_table_struct *pts)
2180{
2181        struct bcm2048_device *bdev = video_drvdata(file);
2182        int retval = 0;
2183
2184        poll_wait(file, &bdev->read_queue, pts);
2185
2186        if (bdev->rds_data_available)
2187                retval = POLLIN | POLLRDNORM;
2188
2189        return retval;
2190}
2191
2192static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
2193                                 size_t count, loff_t *ppos)
2194{
2195        struct bcm2048_device *bdev = video_drvdata(file);
2196        int i;
2197        int retval = 0;
2198
2199        /* we return at least 3 bytes, one block */
2200        count = (count / 3) * 3; /* only multiples of 3 */
2201        if (count < 3)
2202                return -ENOBUFS;
2203
2204        while (!bdev->rds_data_available) {
2205                if (file->f_flags & O_NONBLOCK) {
2206                        retval = -EWOULDBLOCK;
2207                        goto done;
2208                }
2209                /* interruptible_sleep_on(&bdev->read_queue); */
2210                if (wait_event_interruptible(bdev->read_queue,
2211                    bdev->rds_data_available) < 0) {
2212                        retval = -EINTR;
2213                        goto done;
2214                }
2215        }
2216
2217        mutex_lock(&bdev->mutex);
2218        /* copy data to userspace */
2219        i = bdev->fifo_size - bdev->rd_index;
2220        if (count > i)
2221                count = (i / 3) * 3;
2222
2223        i = 0;
2224        while (i < count) {
2225                unsigned char tmpbuf[3];
2226
2227                tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index + i + 2];
2228                tmpbuf[i + 1] =
2229                        bdev->rds_info.radio_text[bdev->rd_index + i + 1];
2230                tmpbuf[i + 2] =
2231                        (bdev->rds_info.radio_text[bdev->rd_index + i] &
2232                         0xf0) >> 4;
2233                if ((bdev->rds_info.radio_text[bdev->rd_index + i] &
2234                    BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE)
2235                        tmpbuf[i + 2] |= 0x80;
2236                if (copy_to_user(buf + i, tmpbuf, 3)) {
2237                        retval = -EFAULT;
2238                        break;
2239                }
2240                i += 3;
2241        }
2242
2243        bdev->rd_index += i;
2244        if (bdev->rd_index >= bdev->fifo_size)
2245                bdev->rds_data_available = 0;
2246
2247        mutex_unlock(&bdev->mutex);
2248        if (retval == 0)
2249                retval = i;
2250
2251done:
2252        return retval;
2253}
2254
2255/*
2256 *      bcm2048_fops - file operations interface
2257 */
2258static const struct v4l2_file_operations bcm2048_fops = {
2259        .owner          = THIS_MODULE,
2260        .unlocked_ioctl = video_ioctl2,
2261        /* for RDS read support */
2262        .open           = bcm2048_fops_open,
2263        .release        = bcm2048_fops_release,
2264        .read           = bcm2048_fops_read,
2265        .poll           = bcm2048_fops_poll
2266};
2267
2268/*
2269 *      Video4Linux Interface
2270 */
2271static struct v4l2_queryctrl bcm2048_v4l2_queryctrl[] = {
2272        {
2273                .id             = V4L2_CID_AUDIO_VOLUME,
2274                .flags          = V4L2_CTRL_FLAG_DISABLED,
2275        },
2276        {
2277                .id             = V4L2_CID_AUDIO_BALANCE,
2278                .flags          = V4L2_CTRL_FLAG_DISABLED,
2279        },
2280        {
2281                .id             = V4L2_CID_AUDIO_BASS,
2282                .flags          = V4L2_CTRL_FLAG_DISABLED,
2283        },
2284        {
2285                .id             = V4L2_CID_AUDIO_TREBLE,
2286                .flags          = V4L2_CTRL_FLAG_DISABLED,
2287        },
2288        {
2289                .id             = V4L2_CID_AUDIO_MUTE,
2290                .type           = V4L2_CTRL_TYPE_BOOLEAN,
2291                .name           = "Mute",
2292                .minimum        = 0,
2293                .maximum        = 1,
2294                .step           = 1,
2295                .default_value  = 1,
2296        },
2297        {
2298                .id             = V4L2_CID_AUDIO_LOUDNESS,
2299                .flags          = V4L2_CTRL_FLAG_DISABLED,
2300        },
2301};
2302
2303static int bcm2048_vidioc_querycap(struct file *file, void *priv,
2304                                   struct v4l2_capability *capability)
2305{
2306        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2307
2308        strlcpy(capability->driver, BCM2048_DRIVER_NAME,
2309                sizeof(capability->driver));
2310        strlcpy(capability->card, BCM2048_DRIVER_CARD,
2311                sizeof(capability->card));
2312        snprintf(capability->bus_info, 32, "I2C: 0x%X", bdev->client->addr);
2313        capability->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
2314                                        V4L2_CAP_HW_FREQ_SEEK;
2315        capability->capabilities = capability->device_caps |
2316                V4L2_CAP_DEVICE_CAPS;
2317
2318        return 0;
2319}
2320
2321static int bcm2048_vidioc_g_input(struct file *filp, void *priv,
2322                                  unsigned int *i)
2323{
2324        *i = 0;
2325
2326        return 0;
2327}
2328
2329static int bcm2048_vidioc_s_input(struct file *filp, void *priv,
2330                                  unsigned int i)
2331{
2332        if (i)
2333                return -EINVAL;
2334
2335        return 0;
2336}
2337
2338static int bcm2048_vidioc_queryctrl(struct file *file, void *priv,
2339                                    struct v4l2_queryctrl *qc)
2340{
2341        int i;
2342
2343        for (i = 0; i < ARRAY_SIZE(bcm2048_v4l2_queryctrl); i++) {
2344                if (qc->id && qc->id == bcm2048_v4l2_queryctrl[i].id) {
2345                        *qc = bcm2048_v4l2_queryctrl[i];
2346                        return 0;
2347                }
2348        }
2349
2350        return -EINVAL;
2351}
2352
2353static int bcm2048_vidioc_g_ctrl(struct file *file, void *priv,
2354                                 struct v4l2_control *ctrl)
2355{
2356        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2357        int err = 0;
2358
2359        if (!bdev)
2360                return -ENODEV;
2361
2362        switch (ctrl->id) {
2363        case V4L2_CID_AUDIO_MUTE:
2364                err = bcm2048_get_mute(bdev);
2365                if (err >= 0)
2366                        ctrl->value = err;
2367                break;
2368        }
2369
2370        return err;
2371}
2372
2373static int bcm2048_vidioc_s_ctrl(struct file *file, void *priv,
2374                                 struct v4l2_control *ctrl)
2375{
2376        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2377        int err = 0;
2378
2379        if (!bdev)
2380                return -ENODEV;
2381
2382        switch (ctrl->id) {
2383        case V4L2_CID_AUDIO_MUTE:
2384                if (ctrl->value) {
2385                        if (bdev->power_state) {
2386                                err = bcm2048_set_mute(bdev, ctrl->value);
2387                                err |= bcm2048_deinit(bdev);
2388                        }
2389                } else {
2390                        if (!bdev->power_state) {
2391                                err = bcm2048_init(bdev);
2392                                err |= bcm2048_set_mute(bdev, ctrl->value);
2393                        }
2394                }
2395                break;
2396        }
2397
2398        return err;
2399}
2400
2401static int bcm2048_vidioc_g_audio(struct file *file, void *priv,
2402                                  struct v4l2_audio *audio)
2403{
2404        if (audio->index > 1)
2405                return -EINVAL;
2406
2407        strncpy(audio->name, "Radio", 32);
2408        audio->capability = V4L2_AUDCAP_STEREO;
2409
2410        return 0;
2411}
2412
2413static int bcm2048_vidioc_s_audio(struct file *file, void *priv,
2414                                  const struct v4l2_audio *audio)
2415{
2416        if (audio->index != 0)
2417                return -EINVAL;
2418
2419        return 0;
2420}
2421
2422static int bcm2048_vidioc_g_tuner(struct file *file, void *priv,
2423                                  struct v4l2_tuner *tuner)
2424{
2425        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2426        s8 f_error;
2427        s8 rssi;
2428
2429        if (!bdev)
2430                return -ENODEV;
2431
2432        if (tuner->index > 0)
2433                return -EINVAL;
2434
2435        strncpy(tuner->name, "FM Receiver", 32);
2436        tuner->type = V4L2_TUNER_RADIO;
2437        tuner->rangelow =
2438                dev_to_v4l2(bcm2048_get_region_bottom_frequency(bdev));
2439        tuner->rangehigh =
2440                dev_to_v4l2(bcm2048_get_region_top_frequency(bdev));
2441        tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
2442        tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW;
2443        tuner->audmode = V4L2_TUNER_MODE_STEREO;
2444        tuner->afc = 0;
2445        if (bdev->power_state) {
2446                /*
2447                 * Report frequencies with high carrier errors to have zero
2448                 * signal level
2449                 */
2450                f_error = bcm2048_get_fm_carrier_error(bdev);
2451                if (f_error < BCM2048_FREQ_ERROR_FLOOR ||
2452                    f_error > BCM2048_FREQ_ERROR_ROOF) {
2453                        tuner->signal = 0;
2454                } else {
2455                        /*
2456                         * RSSI level -60 dB is defined to report full
2457                         * signal strength
2458                         */
2459                        rssi = bcm2048_get_fm_rssi(bdev);
2460                        if (rssi >= BCM2048_RSSI_LEVEL_BASE) {
2461                                tuner->signal = 0xFFFF;
2462                        } else if (rssi > BCM2048_RSSI_LEVEL_ROOF) {
2463                                tuner->signal = (rssi +
2464                                                 BCM2048_RSSI_LEVEL_ROOF_NEG)
2465                                                 * BCM2048_SIGNAL_MULTIPLIER;
2466                        } else {
2467                                tuner->signal = 0;
2468                        }
2469                }
2470        } else {
2471                tuner->signal = 0;
2472        }
2473
2474        return 0;
2475}
2476
2477static int bcm2048_vidioc_s_tuner(struct file *file, void *priv,
2478                                  const struct v4l2_tuner *tuner)
2479{
2480        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2481
2482        if (!bdev)
2483                return -ENODEV;
2484
2485        if (tuner->index > 0)
2486                return -EINVAL;
2487
2488        return 0;
2489}
2490
2491static int bcm2048_vidioc_g_frequency(struct file *file, void *priv,
2492                                      struct v4l2_frequency *freq)
2493{
2494        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2495        int err = 0;
2496        int f;
2497
2498        if (!bdev->power_state)
2499                return -ENODEV;
2500
2501        freq->type = V4L2_TUNER_RADIO;
2502        f = bcm2048_get_fm_frequency(bdev);
2503
2504        if (f < 0)
2505                err = f;
2506        else
2507                freq->frequency = dev_to_v4l2(f);
2508
2509        return err;
2510}
2511
2512static int bcm2048_vidioc_s_frequency(struct file *file, void *priv,
2513                                      const struct v4l2_frequency *freq)
2514{
2515        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2516        int err;
2517
2518        if (freq->type != V4L2_TUNER_RADIO)
2519                return -EINVAL;
2520
2521        if (!bdev->power_state)
2522                return -ENODEV;
2523
2524        err = bcm2048_set_fm_frequency(bdev, v4l2_to_dev(freq->frequency));
2525        err |= bcm2048_set_fm_search_tune_mode(bdev, BCM2048_FM_PRE_SET_MODE);
2526
2527        return err;
2528}
2529
2530static int bcm2048_vidioc_s_hw_freq_seek(struct file *file, void *priv,
2531                                         const struct v4l2_hw_freq_seek *seek)
2532{
2533        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2534        int err;
2535
2536        if (!bdev->power_state)
2537                return -ENODEV;
2538
2539        if ((seek->tuner != 0) || (seek->type != V4L2_TUNER_RADIO))
2540                return -EINVAL;
2541
2542        err = bcm2048_set_fm_search_mode_direction(bdev, seek->seek_upward);
2543        err |= bcm2048_set_fm_search_tune_mode(bdev,
2544                                               BCM2048_FM_AUTO_SEARCH_MODE);
2545
2546        return err;
2547}
2548
2549static struct v4l2_ioctl_ops bcm2048_ioctl_ops = {
2550        .vidioc_querycap        = bcm2048_vidioc_querycap,
2551        .vidioc_g_input         = bcm2048_vidioc_g_input,
2552        .vidioc_s_input         = bcm2048_vidioc_s_input,
2553        .vidioc_queryctrl       = bcm2048_vidioc_queryctrl,
2554        .vidioc_g_ctrl          = bcm2048_vidioc_g_ctrl,
2555        .vidioc_s_ctrl          = bcm2048_vidioc_s_ctrl,
2556        .vidioc_g_audio         = bcm2048_vidioc_g_audio,
2557        .vidioc_s_audio         = bcm2048_vidioc_s_audio,
2558        .vidioc_g_tuner         = bcm2048_vidioc_g_tuner,
2559        .vidioc_s_tuner         = bcm2048_vidioc_s_tuner,
2560        .vidioc_g_frequency     = bcm2048_vidioc_g_frequency,
2561        .vidioc_s_frequency     = bcm2048_vidioc_s_frequency,
2562        .vidioc_s_hw_freq_seek  = bcm2048_vidioc_s_hw_freq_seek,
2563};
2564
2565/*
2566 * bcm2048_viddev_template - video device interface
2567 */
2568static struct video_device bcm2048_viddev_template = {
2569        .fops                   = &bcm2048_fops,
2570        .name                   = BCM2048_DRIVER_NAME,
2571        .release                = video_device_release_empty,
2572        .ioctl_ops              = &bcm2048_ioctl_ops,
2573};
2574
2575/*
2576 *      I2C driver interface
2577 */
2578static int bcm2048_i2c_driver_probe(struct i2c_client *client,
2579                                    const struct i2c_device_id *id)
2580{
2581        struct bcm2048_device *bdev;
2582        int err;
2583
2584        bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
2585        if (!bdev) {
2586                err = -ENOMEM;
2587                goto exit;
2588        }
2589
2590        bdev->client = client;
2591        i2c_set_clientdata(client, bdev);
2592        mutex_init(&bdev->mutex);
2593        init_completion(&bdev->compl);
2594        INIT_WORK(&bdev->work, bcm2048_work);
2595
2596        if (client->irq) {
2597                err = request_irq(client->irq,
2598                                  bcm2048_handler, IRQF_TRIGGER_FALLING,
2599                                  client->name, bdev);
2600                if (err < 0) {
2601                        dev_err(&client->dev, "Could not request IRQ\n");
2602                        goto free_bdev;
2603                }
2604                dev_dbg(&client->dev, "IRQ requested.\n");
2605        } else {
2606                dev_dbg(&client->dev, "IRQ not configured. Using timeouts.\n");
2607        }
2608
2609        bdev->videodev = bcm2048_viddev_template;
2610        video_set_drvdata(&bdev->videodev, bdev);
2611        if (video_register_device(&bdev->videodev, VFL_TYPE_RADIO, radio_nr)) {
2612                dev_dbg(&client->dev, "Could not register video device.\n");
2613                err = -EIO;
2614                goto free_irq;
2615        }
2616
2617        err = bcm2048_sysfs_register_properties(bdev);
2618        if (err < 0) {
2619                dev_dbg(&client->dev, "Could not register sysfs interface.\n");
2620                goto free_registration;
2621        }
2622
2623        err = bcm2048_probe(bdev);
2624        if (err < 0) {
2625                dev_dbg(&client->dev, "Failed to probe device information.\n");
2626                goto free_sysfs;
2627        }
2628
2629        return 0;
2630
2631free_sysfs:
2632        bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
2633free_registration:
2634        video_unregister_device(&bdev->videodev);
2635free_irq:
2636        if (client->irq)
2637                free_irq(client->irq, bdev);
2638free_bdev:
2639        i2c_set_clientdata(client, NULL);
2640        kfree(bdev);
2641exit:
2642        return err;
2643}
2644
2645static int __exit bcm2048_i2c_driver_remove(struct i2c_client *client)
2646{
2647        struct bcm2048_device *bdev = i2c_get_clientdata(client);
2648
2649        if (!client->adapter)
2650                return -ENODEV;
2651
2652        if (bdev) {
2653                bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
2654                video_unregister_device(&bdev->videodev);
2655
2656                if (bdev->power_state)
2657                        bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
2658
2659                if (client->irq > 0)
2660                        free_irq(client->irq, bdev);
2661
2662                cancel_work_sync(&bdev->work);
2663
2664                kfree(bdev);
2665        }
2666
2667        return 0;
2668}
2669
2670/*
2671 *      bcm2048_i2c_driver - i2c driver interface
2672 */
2673static const struct i2c_device_id bcm2048_id[] = {
2674        { "bcm2048", 0 },
2675        { },
2676};
2677MODULE_DEVICE_TABLE(i2c, bcm2048_id);
2678
2679static struct i2c_driver bcm2048_i2c_driver = {
2680        .driver         = {
2681                .name   = BCM2048_DRIVER_NAME,
2682        },
2683        .probe          = bcm2048_i2c_driver_probe,
2684        .remove         = __exit_p(bcm2048_i2c_driver_remove),
2685        .id_table       = bcm2048_id,
2686};
2687
2688module_i2c_driver(bcm2048_i2c_driver);
2689
2690MODULE_LICENSE("GPL");
2691MODULE_AUTHOR(BCM2048_DRIVER_AUTHOR);
2692MODULE_DESCRIPTION(BCM2048_DRIVER_DESC);
2693MODULE_VERSION("0.0.2");
2694