linux/drivers/mfd/si476x-i2c.c
<<
>>
Prefs
   1/*
   2 * drivers/mfd/si476x-i2c.c -- Core device driver for si476x MFD
   3 * device
   4 *
   5 * Copyright (C) 2012 Innovative Converged Devices(ICD)
   6 * Copyright (C) 2013 Andrey Smirnov
   7 *
   8 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; version 2 of the License.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 */
  20#include <linux/module.h>
  21
  22#include <linux/slab.h>
  23#include <linux/interrupt.h>
  24#include <linux/delay.h>
  25#include <linux/gpio.h>
  26#include <linux/regulator/consumer.h>
  27#include <linux/i2c.h>
  28#include <linux/err.h>
  29
  30#include <linux/mfd/si476x-core.h>
  31
  32#define SI476X_MAX_IO_ERRORS            10
  33#define SI476X_DRIVER_RDS_FIFO_DEPTH    128
  34
  35/**
  36 * si476x_core_config_pinmux() - pin function configuration function
  37 *
  38 * @core: Core device structure
  39 *
  40 * Configure the functions of the pins of the radio chip.
  41 *
  42 * The function returns zero in case of succes or negative error code
  43 * otherwise.
  44 */
  45static int si476x_core_config_pinmux(struct si476x_core *core)
  46{
  47        int err;
  48        dev_dbg(&core->client->dev, "Configuring pinmux\n");
  49        err = si476x_core_cmd_dig_audio_pin_cfg(core,
  50                                                core->pinmux.dclk,
  51                                                core->pinmux.dfs,
  52                                                core->pinmux.dout,
  53                                                core->pinmux.xout);
  54        if (err < 0) {
  55                dev_err(&core->client->dev,
  56                        "Failed to configure digital audio pins(err = %d)\n",
  57                        err);
  58                return err;
  59        }
  60
  61        err = si476x_core_cmd_zif_pin_cfg(core,
  62                                          core->pinmux.iqclk,
  63                                          core->pinmux.iqfs,
  64                                          core->pinmux.iout,
  65                                          core->pinmux.qout);
  66        if (err < 0) {
  67                dev_err(&core->client->dev,
  68                        "Failed to configure ZIF pins(err = %d)\n",
  69                        err);
  70                return err;
  71        }
  72
  73        err = si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(core,
  74                                                      core->pinmux.icin,
  75                                                      core->pinmux.icip,
  76                                                      core->pinmux.icon,
  77                                                      core->pinmux.icop);
  78        if (err < 0) {
  79                dev_err(&core->client->dev,
  80                        "Failed to configure IC-Link/GPO pins(err = %d)\n",
  81                        err);
  82                return err;
  83        }
  84
  85        err = si476x_core_cmd_ana_audio_pin_cfg(core,
  86                                                core->pinmux.lrout);
  87        if (err < 0) {
  88                dev_err(&core->client->dev,
  89                        "Failed to configure analog audio pins(err = %d)\n",
  90                        err);
  91                return err;
  92        }
  93
  94        err = si476x_core_cmd_intb_pin_cfg(core,
  95                                           core->pinmux.intb,
  96                                           core->pinmux.a1);
  97        if (err < 0) {
  98                dev_err(&core->client->dev,
  99                        "Failed to configure interrupt pins(err = %d)\n",
 100                        err);
 101                return err;
 102        }
 103
 104        return 0;
 105}
 106
 107static inline void si476x_core_schedule_polling_work(struct si476x_core *core)
 108{
 109        schedule_delayed_work(&core->status_monitor,
 110                              usecs_to_jiffies(SI476X_STATUS_POLL_US));
 111}
 112
 113/**
 114 * si476x_core_start() - early chip startup function
 115 * @core: Core device structure
 116 * @soft: When set, this flag forces "soft" startup, where "soft"
 117 * power down is the one done by sending appropriate command instead
 118 * of using reset pin of the tuner
 119 *
 120 * Perform required startup sequence to correctly power
 121 * up the chip and perform initial configuration. It does the
 122 * following sequence of actions:
 123 *       1. Claims and enables the power supplies VD and VIO1 required
 124 *          for I2C interface of the chip operation.
 125 *       2. Waits for 100us, pulls the reset line up, enables irq,
 126 *          waits for another 100us as it is specified by the
 127 *          datasheet.
 128 *       3. Sends 'POWER_UP' command to the device with all provided
 129 *          information about power-up parameters.
 130 *       4. Configures, pin multiplexor, disables digital audio and
 131 *          configures interrupt sources.
 132 *
 133 * The function returns zero in case of succes or negative error code
 134 * otherwise.
 135 */
 136int si476x_core_start(struct si476x_core *core, bool soft)
 137{
 138        struct i2c_client *client = core->client;
 139        int err;
 140
 141        if (!soft) {
 142                if (gpio_is_valid(core->gpio_reset))
 143                        gpio_set_value_cansleep(core->gpio_reset, 1);
 144
 145                if (client->irq)
 146                        enable_irq(client->irq);
 147
 148                udelay(100);
 149
 150                if (!client->irq) {
 151                        atomic_set(&core->is_alive, 1);
 152                        si476x_core_schedule_polling_work(core);
 153                }
 154        } else {
 155                if (client->irq)
 156                        enable_irq(client->irq);
 157                else {
 158                        atomic_set(&core->is_alive, 1);
 159                        si476x_core_schedule_polling_work(core);
 160                }
 161        }
 162
 163        err = si476x_core_cmd_power_up(core,
 164                                       &core->power_up_parameters);
 165
 166        if (err < 0) {
 167                dev_err(&core->client->dev,
 168                        "Power up failure(err = %d)\n",
 169                        err);
 170                goto disable_irq;
 171        }
 172
 173        if (client->irq)
 174                atomic_set(&core->is_alive, 1);
 175
 176        err = si476x_core_config_pinmux(core);
 177        if (err < 0) {
 178                dev_err(&core->client->dev,
 179                        "Failed to configure pinmux(err = %d)\n",
 180                        err);
 181                goto disable_irq;
 182        }
 183
 184        if (client->irq) {
 185                err = regmap_write(core->regmap,
 186                                   SI476X_PROP_INT_CTL_ENABLE,
 187                                   SI476X_RDSIEN |
 188                                   SI476X_STCIEN |
 189                                   SI476X_CTSIEN);
 190                if (err < 0) {
 191                        dev_err(&core->client->dev,
 192                                "Failed to configure interrupt sources"
 193                                "(err = %d)\n", err);
 194                        goto disable_irq;
 195                }
 196        }
 197
 198        return 0;
 199
 200disable_irq:
 201        if (err == -ENODEV)
 202                atomic_set(&core->is_alive, 0);
 203
 204        if (client->irq)
 205                disable_irq(client->irq);
 206        else
 207                cancel_delayed_work_sync(&core->status_monitor);
 208
 209        if (gpio_is_valid(core->gpio_reset))
 210                gpio_set_value_cansleep(core->gpio_reset, 0);
 211
 212        return err;
 213}
 214EXPORT_SYMBOL_GPL(si476x_core_start);
 215
 216/**
 217 * si476x_core_stop() - chip power-down function
 218 * @core: Core device structure
 219 * @soft: When set, function sends a POWER_DOWN command instead of
 220 * bringing reset line low
 221 *
 222 * Power down the chip by performing following actions:
 223 * 1. Disable IRQ or stop the polling worker
 224 * 2. Send the POWER_DOWN command if the power down is soft or bring
 225 *    reset line low if not.
 226 *
 227 * The function returns zero in case of succes or negative error code
 228 * otherwise.
 229 */
 230int si476x_core_stop(struct si476x_core *core, bool soft)
 231{
 232        int err = 0;
 233        atomic_set(&core->is_alive, 0);
 234
 235        if (soft) {
 236                /* TODO: This probably shoud be a configurable option,
 237                 * so it is possible to have the chips keep their
 238                 * oscillators running
 239                 */
 240                struct si476x_power_down_args args = {
 241                        .xosc = false,
 242                };
 243                err = si476x_core_cmd_power_down(core, &args);
 244        }
 245
 246        /* We couldn't disable those before
 247         * 'si476x_core_cmd_power_down' since we expect to get CTS
 248         * interrupt */
 249        if (core->client->irq)
 250                disable_irq(core->client->irq);
 251        else
 252                cancel_delayed_work_sync(&core->status_monitor);
 253
 254        if (!soft) {
 255                if (gpio_is_valid(core->gpio_reset))
 256                        gpio_set_value_cansleep(core->gpio_reset, 0);
 257        }
 258        return err;
 259}
 260EXPORT_SYMBOL_GPL(si476x_core_stop);
 261
 262/**
 263 * si476x_core_set_power_state() - set the level at which the power is
 264 * supplied for the chip.
 265 * @core: Core device structure
 266 * @next_state: enum si476x_power_state describing power state to
 267 *              switch to.
 268 *
 269 * Switch on all the required power supplies
 270 *
 271 * This function returns 0 in case of suvccess and negative error code
 272 * otherwise.
 273 */
 274int si476x_core_set_power_state(struct si476x_core *core,
 275                                enum si476x_power_state next_state)
 276{
 277        /*
 278           It is not clear form the datasheet if it is possible to
 279           work with device if not all power domains are operational.
 280           So for now the power-up policy is "power-up all the things!"
 281         */
 282        int err = 0;
 283
 284        if (core->power_state == SI476X_POWER_INCONSISTENT) {
 285                dev_err(&core->client->dev,
 286                        "The device in inconsistent power state\n");
 287                return -EINVAL;
 288        }
 289
 290        if (next_state != core->power_state) {
 291                switch (next_state) {
 292                case SI476X_POWER_UP_FULL:
 293                        err = regulator_bulk_enable(ARRAY_SIZE(core->supplies),
 294                                                    core->supplies);
 295                        if (err < 0) {
 296                                core->power_state = SI476X_POWER_INCONSISTENT;
 297                                break;
 298                        }
 299                        /*
 300                         * Startup timing diagram recommends to have a
 301                         * 100 us delay between enabling of the power
 302                         * supplies and turning the tuner on.
 303                         */
 304                        udelay(100);
 305
 306                        err = si476x_core_start(core, false);
 307                        if (err < 0)
 308                                goto disable_regulators;
 309
 310                        core->power_state = next_state;
 311                        break;
 312
 313                case SI476X_POWER_DOWN:
 314                        core->power_state = next_state;
 315                        err = si476x_core_stop(core, false);
 316                        if (err < 0)
 317                                core->power_state = SI476X_POWER_INCONSISTENT;
 318disable_regulators:
 319                        err = regulator_bulk_disable(ARRAY_SIZE(core->supplies),
 320                                                     core->supplies);
 321                        if (err < 0)
 322                                core->power_state = SI476X_POWER_INCONSISTENT;
 323                        break;
 324                default:
 325                        BUG();
 326                }
 327        }
 328
 329        return err;
 330}
 331EXPORT_SYMBOL_GPL(si476x_core_set_power_state);
 332
 333/**
 334 * si476x_core_report_drainer_stop() - mark the completion of the RDS
 335 * buffer drain porcess by the worker.
 336 *
 337 * @core: Core device structure
 338 */
 339static inline void si476x_core_report_drainer_stop(struct si476x_core *core)
 340{
 341        mutex_lock(&core->rds_drainer_status_lock);
 342        core->rds_drainer_is_working = false;
 343        mutex_unlock(&core->rds_drainer_status_lock);
 344}
 345
 346/**
 347 * si476x_core_start_rds_drainer_once() - start RDS drainer worker if
 348 * ther is none working, do nothing otherwise
 349 *
 350 * @core: Datastructure corresponding to the chip.
 351 */
 352static inline void si476x_core_start_rds_drainer_once(struct si476x_core *core)
 353{
 354        mutex_lock(&core->rds_drainer_status_lock);
 355        if (!core->rds_drainer_is_working) {
 356                core->rds_drainer_is_working = true;
 357                schedule_work(&core->rds_fifo_drainer);
 358        }
 359        mutex_unlock(&core->rds_drainer_status_lock);
 360}
 361/**
 362 * si476x_drain_rds_fifo() - RDS buffer drainer.
 363 * @work: struct work_struct being ppassed to the function by the
 364 * kernel.
 365 *
 366 * Drain the contents of the RDS FIFO of
 367 */
 368static void si476x_core_drain_rds_fifo(struct work_struct *work)
 369{
 370        int err;
 371
 372        struct si476x_core *core = container_of(work, struct si476x_core,
 373                                                rds_fifo_drainer);
 374
 375        struct si476x_rds_status_report report;
 376
 377        si476x_core_lock(core);
 378        err = si476x_core_cmd_fm_rds_status(core, true, false, false, &report);
 379        if (!err) {
 380                int i = report.rdsfifoused;
 381                dev_dbg(&core->client->dev,
 382                        "%d elements in RDS FIFO. Draining.\n", i);
 383                for (; i > 0; --i) {
 384                        err = si476x_core_cmd_fm_rds_status(core, false, false,
 385                                                            (i == 1), &report);
 386                        if (err < 0)
 387                                goto unlock;
 388
 389                        kfifo_in(&core->rds_fifo, report.rds,
 390                                 sizeof(report.rds));
 391                        dev_dbg(&core->client->dev, "RDS data:\n %*ph\n",
 392                                (int)sizeof(report.rds), report.rds);
 393                }
 394                dev_dbg(&core->client->dev, "Drrrrained!\n");
 395                wake_up_interruptible(&core->rds_read_queue);
 396        }
 397
 398unlock:
 399        si476x_core_unlock(core);
 400        si476x_core_report_drainer_stop(core);
 401}
 402
 403/**
 404 * si476x_core_pronounce_dead()
 405 *
 406 * @core: Core device structure
 407 *
 408 * Mark the device as being dead and wake up all potentially waiting
 409 * threads of execution.
 410 *
 411 */
 412static void si476x_core_pronounce_dead(struct si476x_core *core)
 413{
 414        dev_info(&core->client->dev, "Core device is dead.\n");
 415
 416        atomic_set(&core->is_alive, 0);
 417
 418        /* Wake up al possible waiting processes */
 419        wake_up_interruptible(&core->rds_read_queue);
 420
 421        atomic_set(&core->cts, 1);
 422        wake_up(&core->command);
 423
 424        atomic_set(&core->stc, 1);
 425        wake_up(&core->tuning);
 426}
 427
 428/**
 429 * si476x_core_i2c_xfer()
 430 *
 431 * @core: Core device structure
 432 * @type: Transfer type
 433 * @buf: Transfer buffer for/with data
 434 * @count: Transfer buffer size
 435 *
 436 * Perfrom and I2C transfer(either read or write) and keep a counter
 437 * of I/O errors. If the error counter rises above the threshold
 438 * pronounce device dead.
 439 *
 440 * The function returns zero on succes or negative error code on
 441 * failure.
 442 */
 443int si476x_core_i2c_xfer(struct si476x_core *core,
 444                    enum si476x_i2c_type type,
 445                    char *buf, int count)
 446{
 447        static int io_errors_count;
 448        int err;
 449        if (type == SI476X_I2C_SEND)
 450                err = i2c_master_send(core->client, buf, count);
 451        else
 452                err = i2c_master_recv(core->client, buf, count);
 453
 454        if (err < 0) {
 455                if (io_errors_count++ > SI476X_MAX_IO_ERRORS)
 456                        si476x_core_pronounce_dead(core);
 457        } else {
 458                io_errors_count = 0;
 459        }
 460
 461        return err;
 462}
 463EXPORT_SYMBOL_GPL(si476x_core_i2c_xfer);
 464
 465/**
 466 * si476x_get_status()
 467 * @core: Core device structure
 468 *
 469 * Get the status byte of the core device by berforming one byte I2C
 470 * read.
 471 *
 472 * The function returns a status value or a negative error code on
 473 * error.
 474 */
 475static int si476x_core_get_status(struct si476x_core *core)
 476{
 477        u8 response;
 478        int err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV,
 479                                  &response, sizeof(response));
 480
 481        return (err < 0) ? err : response;
 482}
 483
 484/**
 485 * si476x_get_and_signal_status() - IRQ dispatcher
 486 * @core: Core device structure
 487 *
 488 * Dispatch the arrived interrupt request based on the value of the
 489 * status byte reported by the tuner.
 490 *
 491 */
 492static void si476x_core_get_and_signal_status(struct si476x_core *core)
 493{
 494        int status = si476x_core_get_status(core);
 495        if (status < 0) {
 496                dev_err(&core->client->dev, "Failed to get status\n");
 497                return;
 498        }
 499
 500        if (status & SI476X_CTS) {
 501                /* Unfortunately completions could not be used for
 502                 * signalling CTS since this flag cannot be cleared
 503                 * in status byte, and therefore once it becomes true
 504                 * multiple calls to 'complete' would cause the
 505                 * commands following the current one to be completed
 506                 * before they actually are */
 507                dev_dbg(&core->client->dev, "[interrupt] CTSINT\n");
 508                atomic_set(&core->cts, 1);
 509                wake_up(&core->command);
 510        }
 511
 512        if (status & SI476X_FM_RDS_INT) {
 513                dev_dbg(&core->client->dev, "[interrupt] RDSINT\n");
 514                si476x_core_start_rds_drainer_once(core);
 515        }
 516
 517        if (status & SI476X_STC_INT) {
 518                dev_dbg(&core->client->dev, "[interrupt] STCINT\n");
 519                atomic_set(&core->stc, 1);
 520                wake_up(&core->tuning);
 521        }
 522}
 523
 524static void si476x_core_poll_loop(struct work_struct *work)
 525{
 526        struct si476x_core *core = SI476X_WORK_TO_CORE(work);
 527
 528        si476x_core_get_and_signal_status(core);
 529
 530        if (atomic_read(&core->is_alive))
 531                si476x_core_schedule_polling_work(core);
 532}
 533
 534static irqreturn_t si476x_core_interrupt(int irq, void *dev)
 535{
 536        struct si476x_core *core = dev;
 537
 538        si476x_core_get_and_signal_status(core);
 539
 540        return IRQ_HANDLED;
 541}
 542
 543/**
 544 * si476x_firmware_version_to_revision()
 545 * @core: Core device structure
 546 * @major:  Firmware major number
 547 * @minor1: Firmware first minor number
 548 * @minor2: Firmware second minor number
 549 *
 550 * Convert a chip's firmware version number into an offset that later
 551 * will be used to as offset in "vtable" of tuner functions
 552 *
 553 * This function returns a positive offset in case of success and a -1
 554 * in case of failure.
 555 */
 556static int si476x_core_fwver_to_revision(struct si476x_core *core,
 557                                         int func, int major,
 558                                         int minor1, int minor2)
 559{
 560        switch (func) {
 561        case SI476X_FUNC_FM_RECEIVER:
 562                switch (major) {
 563                case 5:
 564                        return SI476X_REVISION_A10;
 565                case 8:
 566                        return SI476X_REVISION_A20;
 567                case 10:
 568                        return SI476X_REVISION_A30;
 569                default:
 570                        goto unknown_revision;
 571                }
 572        case SI476X_FUNC_AM_RECEIVER:
 573                switch (major) {
 574                case 5:
 575                        return SI476X_REVISION_A10;
 576                case 7:
 577                        return SI476X_REVISION_A20;
 578                case 9:
 579                        return SI476X_REVISION_A30;
 580                default:
 581                        goto unknown_revision;
 582                }
 583        case SI476X_FUNC_WB_RECEIVER:
 584                switch (major) {
 585                case 3:
 586                        return SI476X_REVISION_A10;
 587                case 5:
 588                        return SI476X_REVISION_A20;
 589                case 7:
 590                        return SI476X_REVISION_A30;
 591                default:
 592                        goto unknown_revision;
 593                }
 594        case SI476X_FUNC_BOOTLOADER:
 595        default:                /* FALLTHROUG */
 596                BUG();
 597                return -1;
 598        }
 599
 600unknown_revision:
 601        dev_err(&core->client->dev,
 602                "Unsupported version of the firmware: %d.%d.%d, "
 603                "reverting to A10 compatible functions\n",
 604                major, minor1, minor2);
 605
 606        return SI476X_REVISION_A10;
 607}
 608
 609/**
 610 * si476x_get_revision_info()
 611 * @core: Core device structure
 612 *
 613 * Get the firmware version number of the device. It is done in
 614 * following three steps:
 615 *    1. Power-up the device
 616 *    2. Send the 'FUNC_INFO' command
 617 *    3. Powering the device down.
 618 *
 619 * The function return zero on success and a negative error code on
 620 * failure.
 621 */
 622static int si476x_core_get_revision_info(struct si476x_core *core)
 623{
 624        int rval;
 625        struct si476x_func_info info;
 626
 627        si476x_core_lock(core);
 628        rval = si476x_core_set_power_state(core, SI476X_POWER_UP_FULL);
 629        if (rval < 0)
 630                goto exit;
 631
 632        rval = si476x_core_cmd_func_info(core, &info);
 633        if (rval < 0)
 634                goto power_down;
 635
 636        core->revision = si476x_core_fwver_to_revision(core, info.func,
 637                                                       info.firmware.major,
 638                                                       info.firmware.minor[0],
 639                                                       info.firmware.minor[1]);
 640power_down:
 641        si476x_core_set_power_state(core, SI476X_POWER_DOWN);
 642exit:
 643        si476x_core_unlock(core);
 644
 645        return rval;
 646}
 647
 648bool si476x_core_has_am(struct si476x_core *core)
 649{
 650        return core->chip_id == SI476X_CHIP_SI4761 ||
 651                core->chip_id == SI476X_CHIP_SI4764;
 652}
 653EXPORT_SYMBOL_GPL(si476x_core_has_am);
 654
 655bool si476x_core_has_diversity(struct si476x_core *core)
 656{
 657        return core->chip_id == SI476X_CHIP_SI4764;
 658}
 659EXPORT_SYMBOL_GPL(si476x_core_has_diversity);
 660
 661bool si476x_core_is_a_secondary_tuner(struct si476x_core *core)
 662{
 663        return si476x_core_has_diversity(core) &&
 664                (core->diversity_mode == SI476X_PHDIV_SECONDARY_ANTENNA ||
 665                 core->diversity_mode == SI476X_PHDIV_SECONDARY_COMBINING);
 666}
 667EXPORT_SYMBOL_GPL(si476x_core_is_a_secondary_tuner);
 668
 669bool si476x_core_is_a_primary_tuner(struct si476x_core *core)
 670{
 671        return si476x_core_has_diversity(core) &&
 672                (core->diversity_mode == SI476X_PHDIV_PRIMARY_ANTENNA ||
 673                 core->diversity_mode == SI476X_PHDIV_PRIMARY_COMBINING);
 674}
 675EXPORT_SYMBOL_GPL(si476x_core_is_a_primary_tuner);
 676
 677bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core)
 678{
 679        return si476x_core_has_am(core) &&
 680                (core->power_up_parameters.func == SI476X_FUNC_AM_RECEIVER);
 681}
 682EXPORT_SYMBOL_GPL(si476x_core_is_in_am_receiver_mode);
 683
 684bool si476x_core_is_powered_up(struct si476x_core *core)
 685{
 686        return core->power_state == SI476X_POWER_UP_FULL;
 687}
 688EXPORT_SYMBOL_GPL(si476x_core_is_powered_up);
 689
 690static int si476x_core_probe(struct i2c_client *client,
 691                             const struct i2c_device_id *id)
 692{
 693        int rval;
 694        struct si476x_core          *core;
 695        struct si476x_platform_data *pdata;
 696        struct mfd_cell *cell;
 697        int              cell_num;
 698
 699        core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
 700        if (!core)
 701                return -ENOMEM;
 702
 703        core->client = client;
 704
 705        core->regmap = devm_regmap_init_si476x(core);
 706        if (IS_ERR(core->regmap)) {
 707                rval = PTR_ERR(core->regmap);
 708                dev_err(&client->dev,
 709                        "Failed to allocate register map: %d\n",
 710                        rval);
 711                return rval;
 712        }
 713
 714        i2c_set_clientdata(client, core);
 715
 716        atomic_set(&core->is_alive, 0);
 717        core->power_state = SI476X_POWER_DOWN;
 718
 719        pdata = dev_get_platdata(&client->dev);
 720        if (pdata) {
 721                memcpy(&core->power_up_parameters,
 722                       &pdata->power_up_parameters,
 723                       sizeof(core->power_up_parameters));
 724
 725                core->gpio_reset = -1;
 726                if (gpio_is_valid(pdata->gpio_reset)) {
 727                        rval = gpio_request(pdata->gpio_reset, "si476x reset");
 728                        if (rval) {
 729                                dev_err(&client->dev,
 730                                        "Failed to request gpio: %d\n", rval);
 731                                return rval;
 732                        }
 733                        core->gpio_reset = pdata->gpio_reset;
 734                        gpio_direction_output(core->gpio_reset, 0);
 735                }
 736
 737                core->diversity_mode = pdata->diversity_mode;
 738                memcpy(&core->pinmux, &pdata->pinmux,
 739                       sizeof(struct si476x_pinmux));
 740        } else {
 741                dev_err(&client->dev, "No platform data provided\n");
 742                return -EINVAL;
 743        }
 744
 745        core->supplies[0].supply = "vd";
 746        core->supplies[1].supply = "va";
 747        core->supplies[2].supply = "vio1";
 748        core->supplies[3].supply = "vio2";
 749
 750        rval = devm_regulator_bulk_get(&client->dev,
 751                                       ARRAY_SIZE(core->supplies),
 752                                       core->supplies);
 753        if (rval) {
 754                dev_err(&client->dev, "Failed to get all of the regulators\n");
 755                goto free_gpio;
 756        }
 757
 758        mutex_init(&core->cmd_lock);
 759        init_waitqueue_head(&core->command);
 760        init_waitqueue_head(&core->tuning);
 761
 762        rval = kfifo_alloc(&core->rds_fifo,
 763                           SI476X_DRIVER_RDS_FIFO_DEPTH *
 764                           sizeof(struct v4l2_rds_data),
 765                           GFP_KERNEL);
 766        if (rval) {
 767                dev_err(&client->dev, "Could not allocate the FIFO\n");
 768                goto free_gpio;
 769        }
 770        mutex_init(&core->rds_drainer_status_lock);
 771        init_waitqueue_head(&core->rds_read_queue);
 772        INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo);
 773
 774        if (client->irq) {
 775                rval = devm_request_threaded_irq(&client->dev,
 776                                                 client->irq, NULL,
 777                                                 si476x_core_interrupt,
 778                                                 IRQF_TRIGGER_FALLING |
 779                                                 IRQF_ONESHOT,
 780                                                 client->name, core);
 781                if (rval < 0) {
 782                        dev_err(&client->dev, "Could not request IRQ %d\n",
 783                                client->irq);
 784                        goto free_kfifo;
 785                }
 786                disable_irq(client->irq);
 787                dev_dbg(&client->dev, "IRQ requested.\n");
 788
 789                core->rds_fifo_depth = 20;
 790        } else {
 791                INIT_DELAYED_WORK(&core->status_monitor,
 792                                  si476x_core_poll_loop);
 793                dev_info(&client->dev,
 794                         "No IRQ number specified, will use polling\n");
 795
 796                core->rds_fifo_depth = 5;
 797        }
 798
 799        core->chip_id = id->driver_data;
 800
 801        rval = si476x_core_get_revision_info(core);
 802        if (rval < 0) {
 803                rval = -ENODEV;
 804                goto free_kfifo;
 805        }
 806
 807        cell_num = 0;
 808
 809        cell = &core->cells[SI476X_RADIO_CELL];
 810        cell->name = "si476x-radio";
 811        cell_num++;
 812
 813#ifdef CONFIG_SND_SOC_SI476X
 814        if ((core->chip_id == SI476X_CHIP_SI4761 ||
 815             core->chip_id == SI476X_CHIP_SI4764)       &&
 816            core->pinmux.dclk == SI476X_DCLK_DAUDIO     &&
 817            core->pinmux.dfs  == SI476X_DFS_DAUDIO      &&
 818            core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT &&
 819            core->pinmux.xout == SI476X_XOUT_TRISTATE) {
 820                cell = &core->cells[SI476X_CODEC_CELL];
 821                cell->name          = "si476x-codec";
 822                cell_num++;
 823        }
 824#endif
 825        rval = mfd_add_devices(&client->dev,
 826                               (client->adapter->nr << 8) + client->addr,
 827                               core->cells, cell_num,
 828                               NULL, 0, NULL);
 829        if (!rval)
 830                return 0;
 831
 832free_kfifo:
 833        kfifo_free(&core->rds_fifo);
 834
 835free_gpio:
 836        if (gpio_is_valid(core->gpio_reset))
 837                gpio_free(core->gpio_reset);
 838
 839        return rval;
 840}
 841
 842static int si476x_core_remove(struct i2c_client *client)
 843{
 844        struct si476x_core *core = i2c_get_clientdata(client);
 845
 846        si476x_core_pronounce_dead(core);
 847        mfd_remove_devices(&client->dev);
 848
 849        if (client->irq)
 850                disable_irq(client->irq);
 851        else
 852                cancel_delayed_work_sync(&core->status_monitor);
 853
 854        kfifo_free(&core->rds_fifo);
 855
 856        if (gpio_is_valid(core->gpio_reset))
 857                gpio_free(core->gpio_reset);
 858
 859        return 0;
 860}
 861
 862
 863static const struct i2c_device_id si476x_id[] = {
 864        { "si4761", SI476X_CHIP_SI4761 },
 865        { "si4764", SI476X_CHIP_SI4764 },
 866        { "si4768", SI476X_CHIP_SI4768 },
 867        { },
 868};
 869MODULE_DEVICE_TABLE(i2c, si476x_id);
 870
 871static struct i2c_driver si476x_core_driver = {
 872        .driver         = {
 873                .name   = "si476x-core",
 874        },
 875        .probe          = si476x_core_probe,
 876        .remove         = si476x_core_remove,
 877        .id_table       = si476x_id,
 878};
 879module_i2c_driver(si476x_core_driver);
 880
 881
 882MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
 883MODULE_DESCRIPTION("Si4761/64/68 AM/FM MFD core device driver");
 884MODULE_LICENSE("GPL");
 885