/*
 * drivers/mfd/si476x-i2c.c -- Core device driver for si476x MFD
 * device
 *
 * Copyright (C) 2012 Innovative Converged Devices(ICD)
 * Copyright (C) 2013 Andrey Smirnov
 *
 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 */
#include <linux/module.h>

#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/i2c.h>
#include <linux/err.h>

#include <linux/mfd/si476x-core.h>

#define SI476X_MAX_IO_ERRORS		10
#define SI476X_DRIVER_RDS_FIFO_DEPTH	128

/**
 * si476x_core_config_pinmux() - pin function configuration function
 *
 * @core: Core device structure
 *
 * Configure the functions of the pins of the radio chip.
 *
 * The function returns zero in case of succes or negative error code
 * otherwise.
 */
static int si476x_core_config_pinmux(struct si476x_core *core)
{
	int err;
	dev_dbg(&core->client->dev, "Configuring pinmux\n");
	err = si476x_core_cmd_dig_audio_pin_cfg(core,
						core->pinmux.dclk,
						core->pinmux.dfs,
						core->pinmux.dout,
						core->pinmux.xout);
	if (err < 0) {
		dev_err(&core->client->dev,
			"Failed to configure digital audio pins(err = %d)\n",
			err);
		return err;
	}

	err = si476x_core_cmd_zif_pin_cfg(core,
					  core->pinmux.iqclk,
					  core->pinmux.iqfs,
					  core->pinmux.iout,
					  core->pinmux.qout);
	if (err < 0) {
		dev_err(&core->client->dev,
			"Failed to configure ZIF pins(err = %d)\n",
			err);
		return err;
	}

	err = si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(core,
						      core->pinmux.icin,
						      core->pinmux.icip,
						      core->pinmux.icon,
						      core->pinmux.icop);
	if (err < 0) {
		dev_err(&core->client->dev,
			"Failed to configure IC-Link/GPO pins(err = %d)\n",
			err);
		return err;
	}

	err = si476x_core_cmd_ana_audio_pin_cfg(core,
						core->pinmux.lrout);
	if (err < 0) {
		dev_err(&core->client->dev,
			"Failed to configure analog audio pins(err = %d)\n",
			err);
		return err;
	}

	err = si476x_core_cmd_intb_pin_cfg(core,
					   core->pinmux.intb,
					   core->pinmux.a1);
	if (err < 0) {
		dev_err(&core->client->dev,
			"Failed to configure interrupt pins(err = %d)\n",
			err);
		return err;
	}

	return 0;
}

static inline void si476x_core_schedule_polling_work(struct si476x_core *core)
{
	schedule_delayed_work(&core->status_monitor,
			      usecs_to_jiffies(SI476X_STATUS_POLL_US));
}

/**
 * si476x_core_start() - early chip startup function
 * @core: Core device structure
 * @soft: When set, this flag forces "soft" startup, where "soft"
 * power down is the one done by sending appropriate command instead
 * of using reset pin of the tuner
 *
 * Perform required startup sequence to correctly power
 * up the chip and perform initial configuration. It does the
 * following sequence of actions:
 *       1. Claims and enables the power supplies VD and VIO1 required
 *          for I2C interface of the chip operation.
 *       2. Waits for 100us, pulls the reset line up, enables irq,
 *          waits for another 100us as it is specified by the
 *          datasheet.
 *       3. Sends 'POWER_UP' command to the device with all provided
 *          information about power-up parameters.
 *       4. Configures, pin multiplexor, disables digital audio and
 *          configures interrupt sources.
 *
 * The function returns zero in case of succes or negative error code
 * otherwise.
 */
int si476x_core_start(struct si476x_core *core, bool soft)
{
	struct i2c_client *client = core->client;
	int err;

	if (!soft) {
		if (gpio_is_valid(core->gpio_reset))
			gpio_set_value_cansleep(core->gpio_reset, 1);

		if (client->irq)
			enable_irq(client->irq);

		udelay(100);

		if (!client->irq) {
			atomic_set(&core->is_alive, 1);
			si476x_core_schedule_polling_work(core);
		}
	} else {
		if (client->irq)
			enable_irq(client->irq);
		else {
			atomic_set(&core->is_alive, 1);
			si476x_core_schedule_polling_work(core);
		}
	}

	err = si476x_core_cmd_power_up(core,
				       &core->power_up_parameters);

	if (err < 0) {
		dev_err(&core->client->dev,
			"Power up failure(err = %d)\n",
			err);
		goto disable_irq;
	}

	if (client->irq)
		atomic_set(&core->is_alive, 1);

	err = si476x_core_config_pinmux(core);
	if (err < 0) {
		dev_err(&core->client->dev,
			"Failed to configure pinmux(err = %d)\n",
			err);
		goto disable_irq;
	}

	if (client->irq) {
		err = regmap_write(core->regmap,
				   SI476X_PROP_INT_CTL_ENABLE,
				   SI476X_RDSIEN |
				   SI476X_STCIEN |
				   SI476X_CTSIEN);
		if (err < 0) {
			dev_err(&core->client->dev,
				"Failed to configure interrupt sources"
				"(err = %d)\n", err);
			goto disable_irq;
		}
	}

	return 0;

disable_irq:
	if (err == -ENODEV)
		atomic_set(&core->is_alive, 0);

	if (client->irq)
		disable_irq(client->irq);
	else
		cancel_delayed_work_sync(&core->status_monitor);

	if (gpio_is_valid(core->gpio_reset))
		gpio_set_value_cansleep(core->gpio_reset, 0);

	return err;
}
EXPORT_SYMBOL_GPL(si476x_core_start);

/**
 * si476x_core_stop() - chip power-down function
 * @core: Core device structure
 * @soft: When set, function sends a POWER_DOWN command instead of
 * bringing reset line low
 *
 * Power down the chip by performing following actions:
 * 1. Disable IRQ or stop the polling worker
 * 2. Send the POWER_DOWN command if the power down is soft or bring
 *    reset line low if not.
 *
 * The function returns zero in case of succes or negative error code
 * otherwise.
 */
int si476x_core_stop(struct si476x_core *core, bool soft)
{
	int err = 0;
	atomic_set(&core->is_alive, 0);

	if (soft) {
		/* TODO: This probably shoud be a configurable option,
		 * so it is possible to have the chips keep their
		 * oscillators running
		 */
		struct si476x_power_down_args args = {
			.xosc = false,
		};
		err = si476x_core_cmd_power_down(core, &args);
	}

	/* We couldn't disable those before
	 * 'si476x_core_cmd_power_down' since we expect to get CTS
	 * interrupt */
	if (core->client->irq)
		disable_irq(core->client->irq);
	else
		cancel_delayed_work_sync(&core->status_monitor);

	if (!soft) {
		if (gpio_is_valid(core->gpio_reset))
			gpio_set_value_cansleep(core->gpio_reset, 0);
	}
	return err;
}
EXPORT_SYMBOL_GPL(si476x_core_stop);

/**
 * si476x_core_set_power_state() - set the level at which the power is
 * supplied for the chip.
 * @core: Core device structure
 * @next_state: enum si476x_power_state describing power state to
 *              switch to.
 *
 * Switch on all the required power supplies
 *
 * This function returns 0 in case of suvccess and negative error code
 * otherwise.
 */
int si476x_core_set_power_state(struct si476x_core *core,
				enum si476x_power_state next_state)
{
	/*
	   It is not clear form the datasheet if it is possible to
	   work with device if not all power domains are operational.
	   So for now the power-up policy is "power-up all the things!"
	 */
	int err = 0;

	if (core->power_state == SI476X_POWER_INCONSISTENT) {
		dev_err(&core->client->dev,
			"The device in inconsistent power state\n");
		return -EINVAL;
	}

	if (next_state != core->power_state) {
		switch (next_state) {
		case SI476X_POWER_UP_FULL:
			err = regulator_bulk_enable(ARRAY_SIZE(core->supplies),
						    core->supplies);
			if (err < 0) {
				core->power_state = SI476X_POWER_INCONSISTENT;
				break;
			}
			/*
			 * Startup timing diagram recommends to have a
			 * 100 us delay between enabling of the power
			 * supplies and turning the tuner on.
			 */
			udelay(100);

			err = si476x_core_start(core, true);
			if (err < 0)
				goto disable_regulators;

			core->power_state = next_state;
			break;

		case SI476X_POWER_DOWN:
			core->power_state = next_state;
			err = si476x_core_stop(core, true);
			if (err < 0)
				core->power_state = SI476X_POWER_INCONSISTENT;
disable_regulators:
			err = regulator_bulk_disable(ARRAY_SIZE(core->supplies),
						     core->supplies);
			if (err < 0)
				core->power_state = SI476X_POWER_INCONSISTENT;
			break;
		default:
			BUG();
		}
	}

	return err;
}
EXPORT_SYMBOL_GPL(si476x_core_set_power_state);

/**
 * si476x_core_report_drainer_stop() - mark the completion of the RDS
 * buffer drain porcess by the worker.
 *
 * @core: Core device structure
 */
static inline void si476x_core_report_drainer_stop(struct si476x_core *core)
{
	mutex_lock(&core->rds_drainer_status_lock);
	core->rds_drainer_is_working = false;
	mutex_unlock(&core->rds_drainer_status_lock);
}

/**
 * si476x_core_start_rds_drainer_once() - start RDS drainer worker if
 * ther is none working, do nothing otherwise
 *
 * @core: Datastructure corresponding to the chip.
 */
static inline void si476x_core_start_rds_drainer_once(struct si476x_core *core)
{
	mutex_lock(&core->rds_drainer_status_lock);
	if (!core->rds_drainer_is_working) {
		core->rds_drainer_is_working = true;
		schedule_work(&core->rds_fifo_drainer);
	}
	mutex_unlock(&core->rds_drainer_status_lock);
}
/**
 * si476x_drain_rds_fifo() - RDS buffer drainer.
 * @work: struct work_struct being ppassed to the function by the
 * kernel.
 *
 * Drain the contents of the RDS FIFO of
 */
static void si476x_core_drain_rds_fifo(struct work_struct *work)
{
	int err;

	struct si476x_core *core = container_of(work, struct si476x_core,
						rds_fifo_drainer);

	struct si476x_rds_status_report report;

	si476x_core_lock(core);
	err = si476x_core_cmd_fm_rds_status(core, true, false, false, &report);
	if (!err) {
		int i = report.rdsfifoused;
		dev_dbg(&core->client->dev,
			"%d elements in RDS FIFO. Draining.\n", i);
		for (; i > 0; --i) {
			err = si476x_core_cmd_fm_rds_status(core, false, false,
							    (i == 1), &report);
			if (err < 0)
				goto unlock;

			kfifo_in(&core->rds_fifo, report.rds,
				 sizeof(report.rds));
			dev_dbg(&core->client->dev, "RDS data:\n %*ph\n",
				(int)sizeof(report.rds), report.rds);
		}
		dev_dbg(&core->client->dev, "Drrrrained!\n");
		wake_up_interruptible(&core->rds_read_queue);
	}

unlock:
	si476x_core_unlock(core);
	si476x_core_report_drainer_stop(core);
}

/**
 * si476x_core_pronounce_dead()
 *
 * @core: Core device structure
 *
 * Mark the device as being dead and wake up all potentially waiting
 * threads of execution.
 *
 */
static void si476x_core_pronounce_dead(struct si476x_core *core)
{
	dev_info(&core->client->dev, "Core device is dead.\n");

	atomic_set(&core->is_alive, 0);

	/* Wake up al possible waiting processes */
	wake_up_interruptible(&core->rds_read_queue);

	atomic_set(&core->cts, 1);
	wake_up(&core->command);

	atomic_set(&core->stc, 1);
	wake_up(&core->tuning);
}

/**
 * si476x_core_i2c_xfer()
 *
 * @core: Core device structure
 * @type: Transfer type
 * @buf: Transfer buffer for/with data
 * @count: Transfer buffer size
 *
 * Perfrom and I2C transfer(either read or write) and keep a counter
 * of I/O errors. If the error counter rises above the threshold
 * pronounce device dead.
 *
 * The function returns zero on succes or negative error code on
 * failure.
 */
int si476x_core_i2c_xfer(struct si476x_core *core,
		    enum si476x_i2c_type type,
		    char *buf, int count)
{
	static int io_errors_count;
	int err;
	if (type == SI476X_I2C_SEND)
		err = i2c_master_send(core->client, buf, count);
	else
		err = i2c_master_recv(core->client, buf, count);

	if (err < 0) {
		if (io_errors_count++ > SI476X_MAX_IO_ERRORS)
			si476x_core_pronounce_dead(core);
	} else {
		io_errors_count = 0;
	}

	return err;
}
EXPORT_SYMBOL_GPL(si476x_core_i2c_xfer);

/**
 * si476x_get_status()
 * @core: Core device structure
 *
 * Get the status byte of the core device by berforming one byte I2C
 * read.
 *
 * The function returns a status value or a negative error code on
 * error.
 */
static int si476x_core_get_status(struct si476x_core *core)
{
	u8 response;
	int err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV,
				  &response, sizeof(response));

	return (err < 0) ? err : response;
}

/**
 * si476x_get_and_signal_status() - IRQ dispatcher
 * @core: Core device structure
 *
 * Dispatch the arrived interrupt request based on the value of the
 * status byte reported by the tuner.
 *
 */
static void si476x_core_get_and_signal_status(struct si476x_core *core)
{
	int status = si476x_core_get_status(core);
	if (status < 0) {
		dev_err(&core->client->dev, "Failed to get status\n");
		return;
	}

	if (status & SI476X_CTS) {
		/* Unfortunately completions could not be used for
		 * signalling CTS since this flag cannot be cleared
		 * in status byte, and therefore once it becomes true
		 * multiple calls to 'complete' would cause the
		 * commands following the current one to be completed
		 * before they actually are */
		dev_dbg(&core->client->dev, "[interrupt] CTSINT\n");
		atomic_set(&core->cts, 1);
		wake_up(&core->command);
	}

	if (status & SI476X_FM_RDS_INT) {
		dev_dbg(&core->client->dev, "[interrupt] RDSINT\n");
		si476x_core_start_rds_drainer_once(core);
	}

	if (status & SI476X_STC_INT) {
		dev_dbg(&core->client->dev, "[interrupt] STCINT\n");
		atomic_set(&core->stc, 1);
		wake_up(&core->tuning);
	}
}

static void si476x_core_poll_loop(struct work_struct *work)
{
	struct si476x_core *core = SI476X_WORK_TO_CORE(work);

	si476x_core_get_and_signal_status(core);

	if (atomic_read(&core->is_alive))
		si476x_core_schedule_polling_work(core);
}

static irqreturn_t si476x_core_interrupt(int irq, void *dev)
{
	struct si476x_core *core = dev;

	si476x_core_get_and_signal_status(core);

	return IRQ_HANDLED;
}

/**
 * si476x_firmware_version_to_revision()
 * @core: Core device structure
 * @major:  Firmware major number
 * @minor1: Firmware first minor number
 * @minor2: Firmware second minor number
 *
 * Convert a chip's firmware version number into an offset that later
 * will be used to as offset in "vtable" of tuner functions
 *
 * This function returns a positive offset in case of success and a -1
 * in case of failure.
 */
static int si476x_core_fwver_to_revision(struct si476x_core *core,
					 int func, int major,
					 int minor1, int minor2)
{
	switch (func) {
	case SI476X_FUNC_FM_RECEIVER:
		switch (major) {
		case 5:
			return SI476X_REVISION_A10;
		case 8:
			return SI476X_REVISION_A20;
		case 10:
			return SI476X_REVISION_A30;
		default:
			goto unknown_revision;
		}
	case SI476X_FUNC_AM_RECEIVER:
		switch (major) {
		case 5:
			return SI476X_REVISION_A10;
		case 7:
			return SI476X_REVISION_A20;
		case 9:
			return SI476X_REVISION_A30;
		default:
			goto unknown_revision;
		}
	case SI476X_FUNC_WB_RECEIVER:
		switch (major) {
		case 3:
			return SI476X_REVISION_A10;
		case 5:
			return SI476X_REVISION_A20;
		case 7:
			return SI476X_REVISION_A30;
		default:
			goto unknown_revision;
		}
	case SI476X_FUNC_BOOTLOADER:
	default:		/* FALLTHROUG */
		BUG();
		return -1;
	}

unknown_revision:
	dev_err(&core->client->dev,
		"Unsupported version of the firmware: %d.%d.%d, "
		"reverting to A10 comptible functions\n",
		major, minor1, minor2);

	return SI476X_REVISION_A10;
}

/**
 * si476x_get_revision_info()
 * @core: Core device structure
 *
 * Get the firmware version number of the device. It is done in
 * following three steps:
 *    1. Power-up the device
 *    2. Send the 'FUNC_INFO' command
 *    3. Powering the device down.
 *
 * The function return zero on success and a negative error code on
 * failure.
 */
static int si476x_core_get_revision_info(struct si476x_core *core)
{
	int rval;
	struct si476x_func_info info;

	si476x_core_lock(core);
	rval = si476x_core_set_power_state(core, SI476X_POWER_UP_FULL);
	if (rval < 0)
		goto exit;

	rval = si476x_core_cmd_func_info(core, &info);
	if (rval < 0)
		goto power_down;

	core->revision = si476x_core_fwver_to_revision(core, info.func,
						       info.firmware.major,
						       info.firmware.minor[0],
						       info.firmware.minor[1]);
power_down:
	si476x_core_set_power_state(core, SI476X_POWER_DOWN);
exit:
	si476x_core_unlock(core);

	return rval;
}

bool si476x_core_has_am(struct si476x_core *core)
{
	return core->chip_id == SI476X_CHIP_SI4761 ||
		core->chip_id == SI476X_CHIP_SI4764;
}
EXPORT_SYMBOL_GPL(si476x_core_has_am);

bool si476x_core_has_diversity(struct si476x_core *core)
{
	return core->chip_id == SI476X_CHIP_SI4764;
}
EXPORT_SYMBOL_GPL(si476x_core_has_diversity);

bool si476x_core_is_a_secondary_tuner(struct si476x_core *core)
{
	return si476x_core_has_diversity(core) &&
		(core->diversity_mode == SI476X_PHDIV_SECONDARY_ANTENNA ||
		 core->diversity_mode == SI476X_PHDIV_SECONDARY_COMBINING);
}
EXPORT_SYMBOL_GPL(si476x_core_is_a_secondary_tuner);

bool si476x_core_is_a_primary_tuner(struct si476x_core *core)
{
	return si476x_core_has_diversity(core) &&
		(core->diversity_mode == SI476X_PHDIV_PRIMARY_ANTENNA ||
		 core->diversity_mode == SI476X_PHDIV_PRIMARY_COMBINING);
}
EXPORT_SYMBOL_GPL(si476x_core_is_a_primary_tuner);

bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core)
{
	return si476x_core_has_am(core) &&
		(core->power_up_parameters.func == SI476X_FUNC_AM_RECEIVER);
}
EXPORT_SYMBOL_GPL(si476x_core_is_in_am_receiver_mode);

bool si476x_core_is_powered_up(struct si476x_core *core)
{
	return core->power_state == SI476X_POWER_UP_FULL;
}
EXPORT_SYMBOL_GPL(si476x_core_is_powered_up);

static int si476x_core_probe(struct i2c_client *client,
			     const struct i2c_device_id *id)
{
	int rval;
	struct si476x_core          *core;
	struct si476x_platform_data *pdata;
	struct mfd_cell *cell;
	int              cell_num;

	core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
	if (!core) {
		dev_err(&client->dev,
			"failed to allocate 'struct si476x_core'\n");
		return -ENOMEM;
	}
	core->client = client;

	core->regmap = devm_regmap_init_si476x(core);
	if (IS_ERR(core->regmap)) {
		rval = PTR_ERR(core->regmap);
		dev_err(&client->dev,
			"Failed to allocate register map: %d\n",
			rval);
		return rval;
	}

	i2c_set_clientdata(client, core);

	atomic_set(&core->is_alive, 0);
	core->power_state = SI476X_POWER_DOWN;

	pdata = dev_get_platdata(&client->dev);
	if (pdata) {
		memcpy(&core->power_up_parameters,
		       &pdata->power_up_parameters,
		       sizeof(core->power_up_parameters));

		core->gpio_reset = -1;
		if (gpio_is_valid(pdata->gpio_reset)) {
			rval = gpio_request(pdata->gpio_reset, "si476x reset");
			if (rval) {
				dev_err(&client->dev,
					"Failed to request gpio: %d\n", rval);
				return rval;
			}
			core->gpio_reset = pdata->gpio_reset;
			gpio_direction_output(core->gpio_reset, 0);
		}

		core->diversity_mode = pdata->diversity_mode;
		memcpy(&core->pinmux, &pdata->pinmux,
		       sizeof(struct si476x_pinmux));
	} else {
		dev_warn(&client->dev, "Using default platform data.\n");
		core->power_up_parameters.xcload = 0x28;
		core->power_up_parameters.func = SI476X_FUNC_FM_RECEIVER;
		core->power_up_parameters.freq = SI476X_FREQ_37P209375_MHZ;
		core->diversity_mode = SI476X_PHDIV_DISABLED;
		core->pinmux.dclk = SI476X_DCLK_DAUDIO;
		core->pinmux.dfs  = SI476X_DFS_DAUDIO;
		core->pinmux.dout = SI476X_DOUT_I2S_OUTPUT;
		core->pinmux.xout = SI476X_XOUT_TRISTATE;
	}

	core->supplies[0].supply = "vd";
	core->supplies[1].supply = "va";
	core->supplies[2].supply = "vio1";
	core->supplies[3].supply = "vio2";

	rval = devm_regulator_bulk_get(&client->dev,
				       ARRAY_SIZE(core->supplies),
				       core->supplies);
	if (rval) {
		dev_err(&client->dev, "Failet to gett all of the regulators\n");
		goto free_gpio;
	}

	mutex_init(&core->cmd_lock);
	init_waitqueue_head(&core->command);
	init_waitqueue_head(&core->tuning);

	rval = kfifo_alloc(&core->rds_fifo,
			   SI476X_DRIVER_RDS_FIFO_DEPTH *
			   sizeof(struct v4l2_rds_data),
			   GFP_KERNEL);
	if (rval) {
		dev_err(&client->dev, "Could not allocate the FIFO\n");
		goto free_gpio;
	}
	mutex_init(&core->rds_drainer_status_lock);
	init_waitqueue_head(&core->rds_read_queue);
	INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo);

	if (client->irq) {
		rval = devm_request_threaded_irq(&client->dev,
						 client->irq, NULL,
						 si476x_core_interrupt,
						 IRQF_TRIGGER_FALLING,
						 client->name, core);
		if (rval < 0) {
			dev_err(&client->dev, "Could not request IRQ %d\n",
				client->irq);
			goto free_kfifo;
		}
		disable_irq(client->irq);
		dev_dbg(&client->dev, "IRQ requested.\n");

		core->rds_fifo_depth = 20;
	} else {
		INIT_DELAYED_WORK(&core->status_monitor,
				  si476x_core_poll_loop);
		dev_info(&client->dev,
			 "No IRQ number specified, will use polling\n");

		core->rds_fifo_depth = 5;
	}

	core->chip_id = id->driver_data;

	/* Power down si476x first */
	core->power_state = SI476X_POWER_UP_FULL;
	si476x_core_set_power_state(core, SI476X_POWER_DOWN);

	rval = si476x_core_get_revision_info(core);
	if (rval < 0) {
		rval = -ENODEV;
		goto free_kfifo;
	}

	if (of_property_read_bool(client->dev.of_node, "revision-a10"))
		core->revision = SI476X_REVISION_A10;

	cell_num = 0;

	cell = &core->cells[SI476X_RADIO_CELL];
	cell->name = "si476x-radio";
	cell_num++;

#ifdef CONFIG_SND_SOC_SI476X
	if ((core->chip_id == SI476X_CHIP_SI4761 ||
	     core->chip_id == SI476X_CHIP_SI4764)	&&
	    core->pinmux.dclk == SI476X_DCLK_DAUDIO     &&
	    core->pinmux.dfs  == SI476X_DFS_DAUDIO      &&
	    core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT &&
	    core->pinmux.xout == SI476X_XOUT_TRISTATE) {
		cell = &core->cells[SI476X_CODEC_CELL];
		cell->name          = "si476x-codec";
		cell->of_compatible = "si476x-codec";
		cell_num++;
	}
#endif
	rval = mfd_add_devices(&client->dev,
			       (client->adapter->nr << 8) + client->addr,
			       core->cells, cell_num,
			       NULL, 0, NULL);
	if (!rval)
		return 0;

free_kfifo:
	kfifo_free(&core->rds_fifo);

free_gpio:
	if (gpio_is_valid(core->gpio_reset))
		gpio_free(core->gpio_reset);

	return rval;
}

static int si476x_core_remove(struct i2c_client *client)
{
	struct si476x_core *core = i2c_get_clientdata(client);

	si476x_core_pronounce_dead(core);
	mfd_remove_devices(&client->dev);

	if (client->irq)
		disable_irq(client->irq);
	else
		cancel_delayed_work_sync(&core->status_monitor);

	kfifo_free(&core->rds_fifo);

	if (gpio_is_valid(core->gpio_reset))
		gpio_free(core->gpio_reset);

	return 0;
}


static const struct i2c_device_id si476x_id[] = {
	{ "si4761", SI476X_CHIP_SI4761 },
	{ "si4764", SI476X_CHIP_SI4764 },
	{ "si4768", SI476X_CHIP_SI4768 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, si476x_id);

static struct i2c_driver si476x_core_driver = {
	.driver		= {
		.name	= "si476x-core",
		.owner  = THIS_MODULE,
	},
	.probe		= si476x_core_probe,
	.remove         = si476x_core_remove,
	.id_table       = si476x_id,
};
module_i2c_driver(si476x_core_driver);


MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
MODULE_DESCRIPTION("Si4761/64/68 AM/FM MFD core device driver");
MODULE_LICENSE("GPL");
