Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * drivers/mfd/si476x-i2c.c -- Core device driver for si476x MFD
0004  * device
0005  *
0006  * Copyright (C) 2012 Innovative Converged Devices(ICD)
0007  * Copyright (C) 2013 Andrey Smirnov
0008  *
0009  * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
0010  */
0011 #include <linux/module.h>
0012 
0013 #include <linux/slab.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/delay.h>
0016 #include <linux/gpio.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <linux/i2c.h>
0019 #include <linux/err.h>
0020 
0021 #include <linux/mfd/si476x-core.h>
0022 
0023 #define SI476X_MAX_IO_ERRORS        10
0024 #define SI476X_DRIVER_RDS_FIFO_DEPTH    128
0025 
0026 /**
0027  * si476x_core_config_pinmux() - pin function configuration function
0028  *
0029  * @core: Core device structure
0030  *
0031  * Configure the functions of the pins of the radio chip.
0032  *
0033  * The function returns zero in case of succes or negative error code
0034  * otherwise.
0035  */
0036 static int si476x_core_config_pinmux(struct si476x_core *core)
0037 {
0038     int err;
0039     dev_dbg(&core->client->dev, "Configuring pinmux\n");
0040     err = si476x_core_cmd_dig_audio_pin_cfg(core,
0041                         core->pinmux.dclk,
0042                         core->pinmux.dfs,
0043                         core->pinmux.dout,
0044                         core->pinmux.xout);
0045     if (err < 0) {
0046         dev_err(&core->client->dev,
0047             "Failed to configure digital audio pins(err = %d)\n",
0048             err);
0049         return err;
0050     }
0051 
0052     err = si476x_core_cmd_zif_pin_cfg(core,
0053                       core->pinmux.iqclk,
0054                       core->pinmux.iqfs,
0055                       core->pinmux.iout,
0056                       core->pinmux.qout);
0057     if (err < 0) {
0058         dev_err(&core->client->dev,
0059             "Failed to configure ZIF pins(err = %d)\n",
0060             err);
0061         return err;
0062     }
0063 
0064     err = si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(core,
0065                               core->pinmux.icin,
0066                               core->pinmux.icip,
0067                               core->pinmux.icon,
0068                               core->pinmux.icop);
0069     if (err < 0) {
0070         dev_err(&core->client->dev,
0071             "Failed to configure IC-Link/GPO pins(err = %d)\n",
0072             err);
0073         return err;
0074     }
0075 
0076     err = si476x_core_cmd_ana_audio_pin_cfg(core,
0077                         core->pinmux.lrout);
0078     if (err < 0) {
0079         dev_err(&core->client->dev,
0080             "Failed to configure analog audio pins(err = %d)\n",
0081             err);
0082         return err;
0083     }
0084 
0085     err = si476x_core_cmd_intb_pin_cfg(core,
0086                        core->pinmux.intb,
0087                        core->pinmux.a1);
0088     if (err < 0) {
0089         dev_err(&core->client->dev,
0090             "Failed to configure interrupt pins(err = %d)\n",
0091             err);
0092         return err;
0093     }
0094 
0095     return 0;
0096 }
0097 
0098 static inline void si476x_core_schedule_polling_work(struct si476x_core *core)
0099 {
0100     schedule_delayed_work(&core->status_monitor,
0101                   usecs_to_jiffies(SI476X_STATUS_POLL_US));
0102 }
0103 
0104 /**
0105  * si476x_core_start() - early chip startup function
0106  * @core: Core device structure
0107  * @soft: When set, this flag forces "soft" startup, where "soft"
0108  * power down is the one done by sending appropriate command instead
0109  * of using reset pin of the tuner
0110  *
0111  * Perform required startup sequence to correctly power
0112  * up the chip and perform initial configuration. It does the
0113  * following sequence of actions:
0114  *       1. Claims and enables the power supplies VD and VIO1 required
0115  *          for I2C interface of the chip operation.
0116  *       2. Waits for 100us, pulls the reset line up, enables irq,
0117  *          waits for another 100us as it is specified by the
0118  *          datasheet.
0119  *       3. Sends 'POWER_UP' command to the device with all provided
0120  *          information about power-up parameters.
0121  *       4. Configures, pin multiplexor, disables digital audio and
0122  *          configures interrupt sources.
0123  *
0124  * The function returns zero in case of succes or negative error code
0125  * otherwise.
0126  */
0127 int si476x_core_start(struct si476x_core *core, bool soft)
0128 {
0129     struct i2c_client *client = core->client;
0130     int err;
0131 
0132     if (!soft) {
0133         if (gpio_is_valid(core->gpio_reset))
0134             gpio_set_value_cansleep(core->gpio_reset, 1);
0135 
0136         if (client->irq)
0137             enable_irq(client->irq);
0138 
0139         udelay(100);
0140 
0141         if (!client->irq) {
0142             atomic_set(&core->is_alive, 1);
0143             si476x_core_schedule_polling_work(core);
0144         }
0145     } else {
0146         if (client->irq)
0147             enable_irq(client->irq);
0148         else {
0149             atomic_set(&core->is_alive, 1);
0150             si476x_core_schedule_polling_work(core);
0151         }
0152     }
0153 
0154     err = si476x_core_cmd_power_up(core,
0155                        &core->power_up_parameters);
0156 
0157     if (err < 0) {
0158         dev_err(&core->client->dev,
0159             "Power up failure(err = %d)\n",
0160             err);
0161         goto disable_irq;
0162     }
0163 
0164     if (client->irq)
0165         atomic_set(&core->is_alive, 1);
0166 
0167     err = si476x_core_config_pinmux(core);
0168     if (err < 0) {
0169         dev_err(&core->client->dev,
0170             "Failed to configure pinmux(err = %d)\n",
0171             err);
0172         goto disable_irq;
0173     }
0174 
0175     if (client->irq) {
0176         err = regmap_write(core->regmap,
0177                    SI476X_PROP_INT_CTL_ENABLE,
0178                    SI476X_RDSIEN |
0179                    SI476X_STCIEN |
0180                    SI476X_CTSIEN);
0181         if (err < 0) {
0182             dev_err(&core->client->dev,
0183                 "Failed to configure interrupt sources"
0184                 "(err = %d)\n", err);
0185             goto disable_irq;
0186         }
0187     }
0188 
0189     return 0;
0190 
0191 disable_irq:
0192     if (err == -ENODEV)
0193         atomic_set(&core->is_alive, 0);
0194 
0195     if (client->irq)
0196         disable_irq(client->irq);
0197     else
0198         cancel_delayed_work_sync(&core->status_monitor);
0199 
0200     if (gpio_is_valid(core->gpio_reset))
0201         gpio_set_value_cansleep(core->gpio_reset, 0);
0202 
0203     return err;
0204 }
0205 EXPORT_SYMBOL_GPL(si476x_core_start);
0206 
0207 /**
0208  * si476x_core_stop() - chip power-down function
0209  * @core: Core device structure
0210  * @soft: When set, function sends a POWER_DOWN command instead of
0211  * bringing reset line low
0212  *
0213  * Power down the chip by performing following actions:
0214  * 1. Disable IRQ or stop the polling worker
0215  * 2. Send the POWER_DOWN command if the power down is soft or bring
0216  *    reset line low if not.
0217  *
0218  * The function returns zero in case of succes or negative error code
0219  * otherwise.
0220  */
0221 int si476x_core_stop(struct si476x_core *core, bool soft)
0222 {
0223     int err = 0;
0224     atomic_set(&core->is_alive, 0);
0225 
0226     if (soft) {
0227         /* TODO: This probably shoud be a configurable option,
0228          * so it is possible to have the chips keep their
0229          * oscillators running
0230          */
0231         struct si476x_power_down_args args = {
0232             .xosc = false,
0233         };
0234         err = si476x_core_cmd_power_down(core, &args);
0235     }
0236 
0237     /* We couldn't disable those before
0238      * 'si476x_core_cmd_power_down' since we expect to get CTS
0239      * interrupt */
0240     if (core->client->irq)
0241         disable_irq(core->client->irq);
0242     else
0243         cancel_delayed_work_sync(&core->status_monitor);
0244 
0245     if (!soft) {
0246         if (gpio_is_valid(core->gpio_reset))
0247             gpio_set_value_cansleep(core->gpio_reset, 0);
0248     }
0249     return err;
0250 }
0251 EXPORT_SYMBOL_GPL(si476x_core_stop);
0252 
0253 /**
0254  * si476x_core_set_power_state() - set the level at which the power is
0255  * supplied for the chip.
0256  * @core: Core device structure
0257  * @next_state: enum si476x_power_state describing power state to
0258  *              switch to.
0259  *
0260  * Switch on all the required power supplies
0261  *
0262  * This function returns 0 in case of suvccess and negative error code
0263  * otherwise.
0264  */
0265 int si476x_core_set_power_state(struct si476x_core *core,
0266                 enum si476x_power_state next_state)
0267 {
0268     /*
0269        It is not clear form the datasheet if it is possible to
0270        work with device if not all power domains are operational.
0271        So for now the power-up policy is "power-up all the things!"
0272      */
0273     int err = 0;
0274 
0275     if (core->power_state == SI476X_POWER_INCONSISTENT) {
0276         dev_err(&core->client->dev,
0277             "The device in inconsistent power state\n");
0278         return -EINVAL;
0279     }
0280 
0281     if (next_state != core->power_state) {
0282         switch (next_state) {
0283         case SI476X_POWER_UP_FULL:
0284             err = regulator_bulk_enable(ARRAY_SIZE(core->supplies),
0285                             core->supplies);
0286             if (err < 0) {
0287                 core->power_state = SI476X_POWER_INCONSISTENT;
0288                 break;
0289             }
0290             /*
0291              * Startup timing diagram recommends to have a
0292              * 100 us delay between enabling of the power
0293              * supplies and turning the tuner on.
0294              */
0295             udelay(100);
0296 
0297             err = si476x_core_start(core, false);
0298             if (err < 0)
0299                 goto disable_regulators;
0300 
0301             core->power_state = next_state;
0302             break;
0303 
0304         case SI476X_POWER_DOWN:
0305             core->power_state = next_state;
0306             err = si476x_core_stop(core, false);
0307             if (err < 0)
0308                 core->power_state = SI476X_POWER_INCONSISTENT;
0309 disable_regulators:
0310             err = regulator_bulk_disable(ARRAY_SIZE(core->supplies),
0311                              core->supplies);
0312             if (err < 0)
0313                 core->power_state = SI476X_POWER_INCONSISTENT;
0314             break;
0315         default:
0316             BUG();
0317         }
0318     }
0319 
0320     return err;
0321 }
0322 EXPORT_SYMBOL_GPL(si476x_core_set_power_state);
0323 
0324 /**
0325  * si476x_core_report_drainer_stop() - mark the completion of the RDS
0326  * buffer drain porcess by the worker.
0327  *
0328  * @core: Core device structure
0329  */
0330 static inline void si476x_core_report_drainer_stop(struct si476x_core *core)
0331 {
0332     mutex_lock(&core->rds_drainer_status_lock);
0333     core->rds_drainer_is_working = false;
0334     mutex_unlock(&core->rds_drainer_status_lock);
0335 }
0336 
0337 /**
0338  * si476x_core_start_rds_drainer_once() - start RDS drainer worker if
0339  * ther is none working, do nothing otherwise
0340  *
0341  * @core: Datastructure corresponding to the chip.
0342  */
0343 static inline void si476x_core_start_rds_drainer_once(struct si476x_core *core)
0344 {
0345     mutex_lock(&core->rds_drainer_status_lock);
0346     if (!core->rds_drainer_is_working) {
0347         core->rds_drainer_is_working = true;
0348         schedule_work(&core->rds_fifo_drainer);
0349     }
0350     mutex_unlock(&core->rds_drainer_status_lock);
0351 }
0352 /**
0353  * si476x_core_drain_rds_fifo() - RDS buffer drainer.
0354  * @work: struct work_struct being ppassed to the function by the
0355  * kernel.
0356  *
0357  * Drain the contents of the RDS FIFO of
0358  */
0359 static void si476x_core_drain_rds_fifo(struct work_struct *work)
0360 {
0361     int err;
0362 
0363     struct si476x_core *core = container_of(work, struct si476x_core,
0364                         rds_fifo_drainer);
0365 
0366     struct si476x_rds_status_report report;
0367 
0368     si476x_core_lock(core);
0369     err = si476x_core_cmd_fm_rds_status(core, true, false, false, &report);
0370     if (!err) {
0371         int i = report.rdsfifoused;
0372         dev_dbg(&core->client->dev,
0373             "%d elements in RDS FIFO. Draining.\n", i);
0374         for (; i > 0; --i) {
0375             err = si476x_core_cmd_fm_rds_status(core, false, false,
0376                                 (i == 1), &report);
0377             if (err < 0)
0378                 goto unlock;
0379 
0380             kfifo_in(&core->rds_fifo, report.rds,
0381                  sizeof(report.rds));
0382             dev_dbg(&core->client->dev, "RDS data:\n %*ph\n",
0383                 (int)sizeof(report.rds), report.rds);
0384         }
0385         dev_dbg(&core->client->dev, "Drrrrained!\n");
0386         wake_up_interruptible(&core->rds_read_queue);
0387     }
0388 
0389 unlock:
0390     si476x_core_unlock(core);
0391     si476x_core_report_drainer_stop(core);
0392 }
0393 
0394 /**
0395  * si476x_core_pronounce_dead()
0396  *
0397  * @core: Core device structure
0398  *
0399  * Mark the device as being dead and wake up all potentially waiting
0400  * threads of execution.
0401  *
0402  */
0403 static void si476x_core_pronounce_dead(struct si476x_core *core)
0404 {
0405     dev_info(&core->client->dev, "Core device is dead.\n");
0406 
0407     atomic_set(&core->is_alive, 0);
0408 
0409     /* Wake up al possible waiting processes */
0410     wake_up_interruptible(&core->rds_read_queue);
0411 
0412     atomic_set(&core->cts, 1);
0413     wake_up(&core->command);
0414 
0415     atomic_set(&core->stc, 1);
0416     wake_up(&core->tuning);
0417 }
0418 
0419 /**
0420  * si476x_core_i2c_xfer()
0421  *
0422  * @core: Core device structure
0423  * @type: Transfer type
0424  * @buf: Transfer buffer for/with data
0425  * @count: Transfer buffer size
0426  *
0427  * Perfrom and I2C transfer(either read or write) and keep a counter
0428  * of I/O errors. If the error counter rises above the threshold
0429  * pronounce device dead.
0430  *
0431  * The function returns zero on succes or negative error code on
0432  * failure.
0433  */
0434 int si476x_core_i2c_xfer(struct si476x_core *core,
0435             enum si476x_i2c_type type,
0436             char *buf, int count)
0437 {
0438     static int io_errors_count;
0439     int err;
0440     if (type == SI476X_I2C_SEND)
0441         err = i2c_master_send(core->client, buf, count);
0442     else
0443         err = i2c_master_recv(core->client, buf, count);
0444 
0445     if (err < 0) {
0446         if (io_errors_count++ > SI476X_MAX_IO_ERRORS)
0447             si476x_core_pronounce_dead(core);
0448     } else {
0449         io_errors_count = 0;
0450     }
0451 
0452     return err;
0453 }
0454 EXPORT_SYMBOL_GPL(si476x_core_i2c_xfer);
0455 
0456 /**
0457  * si476x_core_get_status()
0458  * @core: Core device structure
0459  *
0460  * Get the status byte of the core device by berforming one byte I2C
0461  * read.
0462  *
0463  * The function returns a status value or a negative error code on
0464  * error.
0465  */
0466 static int si476x_core_get_status(struct si476x_core *core)
0467 {
0468     u8 response;
0469     int err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV,
0470                   &response, sizeof(response));
0471 
0472     return (err < 0) ? err : response;
0473 }
0474 
0475 /**
0476  * si476x_core_get_and_signal_status() - IRQ dispatcher
0477  * @core: Core device structure
0478  *
0479  * Dispatch the arrived interrupt request based on the value of the
0480  * status byte reported by the tuner.
0481  *
0482  */
0483 static void si476x_core_get_and_signal_status(struct si476x_core *core)
0484 {
0485     int status = si476x_core_get_status(core);
0486     if (status < 0) {
0487         dev_err(&core->client->dev, "Failed to get status\n");
0488         return;
0489     }
0490 
0491     if (status & SI476X_CTS) {
0492         /* Unfortunately completions could not be used for
0493          * signalling CTS since this flag cannot be cleared
0494          * in status byte, and therefore once it becomes true
0495          * multiple calls to 'complete' would cause the
0496          * commands following the current one to be completed
0497          * before they actually are */
0498         dev_dbg(&core->client->dev, "[interrupt] CTSINT\n");
0499         atomic_set(&core->cts, 1);
0500         wake_up(&core->command);
0501     }
0502 
0503     if (status & SI476X_FM_RDS_INT) {
0504         dev_dbg(&core->client->dev, "[interrupt] RDSINT\n");
0505         si476x_core_start_rds_drainer_once(core);
0506     }
0507 
0508     if (status & SI476X_STC_INT) {
0509         dev_dbg(&core->client->dev, "[interrupt] STCINT\n");
0510         atomic_set(&core->stc, 1);
0511         wake_up(&core->tuning);
0512     }
0513 }
0514 
0515 static void si476x_core_poll_loop(struct work_struct *work)
0516 {
0517     struct si476x_core *core = SI476X_WORK_TO_CORE(work);
0518 
0519     si476x_core_get_and_signal_status(core);
0520 
0521     if (atomic_read(&core->is_alive))
0522         si476x_core_schedule_polling_work(core);
0523 }
0524 
0525 static irqreturn_t si476x_core_interrupt(int irq, void *dev)
0526 {
0527     struct si476x_core *core = dev;
0528 
0529     si476x_core_get_and_signal_status(core);
0530 
0531     return IRQ_HANDLED;
0532 }
0533 
0534 /**
0535  * si476x_core_fwver_to_revision()
0536  * @core: Core device structure
0537  * @func: Selects the boot function of the device:
0538  *         *_BOOTLOADER  - Boot loader
0539  *         *_FM_RECEIVER - FM receiver
0540  *         *_AM_RECEIVER - AM receiver
0541  *         *_WB_RECEIVER - Weatherband receiver
0542  * @major:  Firmware major number
0543  * @minor1: Firmware first minor number
0544  * @minor2: Firmware second minor number
0545  *
0546  * Convert a chip's firmware version number into an offset that later
0547  * will be used to as offset in "vtable" of tuner functions
0548  *
0549  * This function returns a positive offset in case of success and a -1
0550  * in case of failure.
0551  */
0552 static int si476x_core_fwver_to_revision(struct si476x_core *core,
0553                      int func, int major,
0554                      int minor1, int minor2)
0555 {
0556     switch (func) {
0557     case SI476X_FUNC_FM_RECEIVER:
0558         switch (major) {
0559         case 5:
0560             return SI476X_REVISION_A10;
0561         case 8:
0562             return SI476X_REVISION_A20;
0563         case 10:
0564             return SI476X_REVISION_A30;
0565         default:
0566             goto unknown_revision;
0567         }
0568     case SI476X_FUNC_AM_RECEIVER:
0569         switch (major) {
0570         case 5:
0571             return SI476X_REVISION_A10;
0572         case 7:
0573             return SI476X_REVISION_A20;
0574         case 9:
0575             return SI476X_REVISION_A30;
0576         default:
0577             goto unknown_revision;
0578         }
0579     case SI476X_FUNC_WB_RECEIVER:
0580         switch (major) {
0581         case 3:
0582             return SI476X_REVISION_A10;
0583         case 5:
0584             return SI476X_REVISION_A20;
0585         case 7:
0586             return SI476X_REVISION_A30;
0587         default:
0588             goto unknown_revision;
0589         }
0590     case SI476X_FUNC_BOOTLOADER:
0591     default:        /* FALLTHROUGH */
0592         BUG();
0593         return -1;
0594     }
0595 
0596 unknown_revision:
0597     dev_err(&core->client->dev,
0598         "Unsupported version of the firmware: %d.%d.%d, "
0599         "reverting to A10 compatible functions\n",
0600         major, minor1, minor2);
0601 
0602     return SI476X_REVISION_A10;
0603 }
0604 
0605 /**
0606  * si476x_core_get_revision_info()
0607  * @core: Core device structure
0608  *
0609  * Get the firmware version number of the device. It is done in
0610  * following three steps:
0611  *    1. Power-up the device
0612  *    2. Send the 'FUNC_INFO' command
0613  *    3. Powering the device down.
0614  *
0615  * The function return zero on success and a negative error code on
0616  * failure.
0617  */
0618 static int si476x_core_get_revision_info(struct si476x_core *core)
0619 {
0620     int rval;
0621     struct si476x_func_info info;
0622 
0623     si476x_core_lock(core);
0624     rval = si476x_core_set_power_state(core, SI476X_POWER_UP_FULL);
0625     if (rval < 0)
0626         goto exit;
0627 
0628     rval = si476x_core_cmd_func_info(core, &info);
0629     if (rval < 0)
0630         goto power_down;
0631 
0632     core->revision = si476x_core_fwver_to_revision(core, info.func,
0633                                info.firmware.major,
0634                                info.firmware.minor[0],
0635                                info.firmware.minor[1]);
0636 power_down:
0637     si476x_core_set_power_state(core, SI476X_POWER_DOWN);
0638 exit:
0639     si476x_core_unlock(core);
0640 
0641     return rval;
0642 }
0643 
0644 bool si476x_core_has_am(struct si476x_core *core)
0645 {
0646     return core->chip_id == SI476X_CHIP_SI4761 ||
0647         core->chip_id == SI476X_CHIP_SI4764;
0648 }
0649 EXPORT_SYMBOL_GPL(si476x_core_has_am);
0650 
0651 bool si476x_core_has_diversity(struct si476x_core *core)
0652 {
0653     return core->chip_id == SI476X_CHIP_SI4764;
0654 }
0655 EXPORT_SYMBOL_GPL(si476x_core_has_diversity);
0656 
0657 bool si476x_core_is_a_secondary_tuner(struct si476x_core *core)
0658 {
0659     return si476x_core_has_diversity(core) &&
0660         (core->diversity_mode == SI476X_PHDIV_SECONDARY_ANTENNA ||
0661          core->diversity_mode == SI476X_PHDIV_SECONDARY_COMBINING);
0662 }
0663 EXPORT_SYMBOL_GPL(si476x_core_is_a_secondary_tuner);
0664 
0665 bool si476x_core_is_a_primary_tuner(struct si476x_core *core)
0666 {
0667     return si476x_core_has_diversity(core) &&
0668         (core->diversity_mode == SI476X_PHDIV_PRIMARY_ANTENNA ||
0669          core->diversity_mode == SI476X_PHDIV_PRIMARY_COMBINING);
0670 }
0671 EXPORT_SYMBOL_GPL(si476x_core_is_a_primary_tuner);
0672 
0673 bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core)
0674 {
0675     return si476x_core_has_am(core) &&
0676         (core->power_up_parameters.func == SI476X_FUNC_AM_RECEIVER);
0677 }
0678 EXPORT_SYMBOL_GPL(si476x_core_is_in_am_receiver_mode);
0679 
0680 bool si476x_core_is_powered_up(struct si476x_core *core)
0681 {
0682     return core->power_state == SI476X_POWER_UP_FULL;
0683 }
0684 EXPORT_SYMBOL_GPL(si476x_core_is_powered_up);
0685 
0686 static int si476x_core_probe(struct i2c_client *client,
0687                  const struct i2c_device_id *id)
0688 {
0689     int rval;
0690     struct si476x_core          *core;
0691     struct si476x_platform_data *pdata;
0692     struct mfd_cell *cell;
0693     int              cell_num;
0694 
0695     core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
0696     if (!core)
0697         return -ENOMEM;
0698 
0699     core->client = client;
0700 
0701     core->regmap = devm_regmap_init_si476x(core);
0702     if (IS_ERR(core->regmap)) {
0703         rval = PTR_ERR(core->regmap);
0704         dev_err(&client->dev,
0705             "Failed to allocate register map: %d\n",
0706             rval);
0707         return rval;
0708     }
0709 
0710     i2c_set_clientdata(client, core);
0711 
0712     atomic_set(&core->is_alive, 0);
0713     core->power_state = SI476X_POWER_DOWN;
0714 
0715     pdata = dev_get_platdata(&client->dev);
0716     if (pdata) {
0717         memcpy(&core->power_up_parameters,
0718                &pdata->power_up_parameters,
0719                sizeof(core->power_up_parameters));
0720 
0721         core->gpio_reset = -1;
0722         if (gpio_is_valid(pdata->gpio_reset)) {
0723             rval = gpio_request(pdata->gpio_reset, "si476x reset");
0724             if (rval) {
0725                 dev_err(&client->dev,
0726                     "Failed to request gpio: %d\n", rval);
0727                 return rval;
0728             }
0729             core->gpio_reset = pdata->gpio_reset;
0730             gpio_direction_output(core->gpio_reset, 0);
0731         }
0732 
0733         core->diversity_mode = pdata->diversity_mode;
0734         memcpy(&core->pinmux, &pdata->pinmux,
0735                sizeof(struct si476x_pinmux));
0736     } else {
0737         dev_err(&client->dev, "No platform data provided\n");
0738         return -EINVAL;
0739     }
0740 
0741     core->supplies[0].supply = "vd";
0742     core->supplies[1].supply = "va";
0743     core->supplies[2].supply = "vio1";
0744     core->supplies[3].supply = "vio2";
0745 
0746     rval = devm_regulator_bulk_get(&client->dev,
0747                        ARRAY_SIZE(core->supplies),
0748                        core->supplies);
0749     if (rval) {
0750         dev_err(&client->dev, "Failed to get all of the regulators\n");
0751         goto free_gpio;
0752     }
0753 
0754     mutex_init(&core->cmd_lock);
0755     init_waitqueue_head(&core->command);
0756     init_waitqueue_head(&core->tuning);
0757 
0758     rval = kfifo_alloc(&core->rds_fifo,
0759                SI476X_DRIVER_RDS_FIFO_DEPTH *
0760                sizeof(struct v4l2_rds_data),
0761                GFP_KERNEL);
0762     if (rval) {
0763         dev_err(&client->dev, "Could not allocate the FIFO\n");
0764         goto free_gpio;
0765     }
0766     mutex_init(&core->rds_drainer_status_lock);
0767     init_waitqueue_head(&core->rds_read_queue);
0768     INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo);
0769 
0770     if (client->irq) {
0771         rval = devm_request_threaded_irq(&client->dev,
0772                          client->irq, NULL,
0773                          si476x_core_interrupt,
0774                          IRQF_TRIGGER_FALLING |
0775                          IRQF_ONESHOT,
0776                          client->name, core);
0777         if (rval < 0) {
0778             dev_err(&client->dev, "Could not request IRQ %d\n",
0779                 client->irq);
0780             goto free_kfifo;
0781         }
0782         disable_irq(client->irq);
0783         dev_dbg(&client->dev, "IRQ requested.\n");
0784 
0785         core->rds_fifo_depth = 20;
0786     } else {
0787         INIT_DELAYED_WORK(&core->status_monitor,
0788                   si476x_core_poll_loop);
0789         dev_info(&client->dev,
0790              "No IRQ number specified, will use polling\n");
0791 
0792         core->rds_fifo_depth = 5;
0793     }
0794 
0795     core->chip_id = id->driver_data;
0796 
0797     rval = si476x_core_get_revision_info(core);
0798     if (rval < 0) {
0799         rval = -ENODEV;
0800         goto free_kfifo;
0801     }
0802 
0803     cell_num = 0;
0804 
0805     cell = &core->cells[SI476X_RADIO_CELL];
0806     cell->name = "si476x-radio";
0807     cell_num++;
0808 
0809 #ifdef CONFIG_SND_SOC_SI476X
0810     if ((core->chip_id == SI476X_CHIP_SI4761 ||
0811          core->chip_id == SI476X_CHIP_SI4764)   &&
0812         core->pinmux.dclk == SI476X_DCLK_DAUDIO     &&
0813         core->pinmux.dfs  == SI476X_DFS_DAUDIO      &&
0814         core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT &&
0815         core->pinmux.xout == SI476X_XOUT_TRISTATE) {
0816         cell = &core->cells[SI476X_CODEC_CELL];
0817         cell->name          = "si476x-codec";
0818         cell_num++;
0819     }
0820 #endif
0821     rval = mfd_add_devices(&client->dev,
0822                    (client->adapter->nr << 8) + client->addr,
0823                    core->cells, cell_num,
0824                    NULL, 0, NULL);
0825     if (!rval)
0826         return 0;
0827 
0828 free_kfifo:
0829     kfifo_free(&core->rds_fifo);
0830 
0831 free_gpio:
0832     if (gpio_is_valid(core->gpio_reset))
0833         gpio_free(core->gpio_reset);
0834 
0835     return rval;
0836 }
0837 
0838 static int si476x_core_remove(struct i2c_client *client)
0839 {
0840     struct si476x_core *core = i2c_get_clientdata(client);
0841 
0842     si476x_core_pronounce_dead(core);
0843     mfd_remove_devices(&client->dev);
0844 
0845     if (client->irq)
0846         disable_irq(client->irq);
0847     else
0848         cancel_delayed_work_sync(&core->status_monitor);
0849 
0850     kfifo_free(&core->rds_fifo);
0851 
0852     if (gpio_is_valid(core->gpio_reset))
0853         gpio_free(core->gpio_reset);
0854 
0855     return 0;
0856 }
0857 
0858 
0859 static const struct i2c_device_id si476x_id[] = {
0860     { "si4761", SI476X_CHIP_SI4761 },
0861     { "si4764", SI476X_CHIP_SI4764 },
0862     { "si4768", SI476X_CHIP_SI4768 },
0863     { },
0864 };
0865 MODULE_DEVICE_TABLE(i2c, si476x_id);
0866 
0867 static struct i2c_driver si476x_core_driver = {
0868     .driver     = {
0869         .name   = "si476x-core",
0870     },
0871     .probe      = si476x_core_probe,
0872     .remove         = si476x_core_remove,
0873     .id_table       = si476x_id,
0874 };
0875 module_i2c_driver(si476x_core_driver);
0876 
0877 
0878 MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
0879 MODULE_DESCRIPTION("Si4761/64/68 AM/FM MFD core device driver");
0880 MODULE_LICENSE("GPL");