/*
 *  drivers/i2c/busses/i2c-comcerto.c
 *
 *  Copyright (C) 2008 Mindspeed Technologies, Inc.
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/sizes.h>
#include <mach/i2c.h>
#include <mach/irqs.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/reset.h>

MODULE_AUTHOR("Mindspeed Technologies, Inc.");
MODULE_DESCRIPTION("Comcerto I2C bus driver");
MODULE_LICENSE("GPL");

#define SPEED_HIGH_KHZ		3400
#define SPEED_FULL_KHZ		400
#define SPEED_NORMAL_KHZ	100

static int force_poll = 0;
static struct clk *clk_i2c;
module_param(force_poll, bool, S_IRUGO);
MODULE_PARM_DESC(force_poll, "Force polling mode: 0=interrupt mode, polling mode otherwise");

static int speed = 0;
module_param(speed, int, S_IRUGO);
MODULE_PARM_DESC(speed, "I2C speed: 0=standard, 1=fast, 2=high speed");

struct comcerto_i2c
{
	struct i2c_adapter	*adapter;
	struct device		*dev;
	unsigned long		membase;
	struct resource		*io;
	int			irq;
	u32			speed_khz;

	wait_queue_head_t	wait;
	struct i2c_msg		*msg;
	int			msg_state;
	int			msg_status;	/* < 0: error, == 0: success, > 0: message in progress */
	int			msg_len;
	int			msg_retries;
};

#define REG_ADDR(i2c, offset)		((i2c)->membase + (offset))
#define RD_REG(i2c, offset)		__raw_readb(REG_ADDR(i2c, offset))
#define WR_REG(i2c, offset, byte)	__raw_writeb(byte, REG_ADDR(i2c, offset))
#define RD_DATA(i2c)			RD_REG(i2c, COMCERTO_I2C_DATA)
#define WR_DATA(i2c, byte)		WR_REG(i2c, COMCERTO_I2C_DATA, byte)
#define RD_CNTR(i2c)			RD_REG(i2c, COMCERTO_I2C_CNTR)
#define WR_CNTR(i2c, byte)		WR_REG(i2c, COMCERTO_I2C_CNTR, byte)
#define RD_STAT(i2c)			RD_REG(i2c, COMCERTO_I2C_STAT)
#define WR_CCRFS(i2c, byte)		WR_REG(i2c, COMCERTO_I2C_CCRFS, byte)
#define WR_CCRH(i2c, byte)		WR_REG(i2c, COMCERTO_I2C_CCRH, byte)
#define WR_RESET(i2c, byte)		WR_REG(i2c, COMCERTO_I2C_RESET, byte)

enum
{
	TR_IDLE = 0,
	TR_START_ACK,
	TR_ADDR_ACK,
	TR_DATA_ACK,
	RX_DATA_NACK,
};

static u8 comcerto_i2c_calculate_dividers(struct comcerto_i2c *i2c)
{
	int m, n, hz, speed_hz;
	int saved_n, saved_m, saved_hz;
	u8 dividers;
	unsigned int i2c_clk;

	/* Get the i2c clock rate */
	i2c_clk = clk_get_rate(clk_i2c);

	speed_hz = i2c->speed_khz * 1000;
	saved_hz = saved_n = saved_m = 0;

	for (m = 0; m < 16; m++) {
		for (n = 0; n < 8; n++) {
			hz = i2c_clk / ((1 << n) * (m + 1) * 10);
			if (!saved_hz || abs(speed_hz - hz) < abs(speed_hz - saved_hz)) {
				saved_n = n;
				saved_m = m;
				saved_hz = hz;
			}
		}
	}

	dividers = (saved_m << 3) | saved_n;
	dev_dbg(i2c->dev, "%s: speed=%dkHz, M=%d, N=%d, dividers=0x%02x\n", __FUNCTION__,
		saved_hz/1000, saved_m, saved_n, dividers);
	printk("%s: speed=%dkHz, M=%d, N=%d, dividers=0x%02x\n", __FUNCTION__, saved_hz/1000, saved_m, saved_n, dividers);

	return dividers;
}

/*
 * Returns the timeout (in jiffies) for the given message.
 */
static int comcerto_i2c_calculate_timeout(struct comcerto_i2c *i2c, struct i2c_msg *msg)
{
	int timeout;

	/* if no timeout was specified, calculate it */
	if (i2c->adapter->timeout <= 0) {
		if (i2c->irq >= 0) {
			/* for the interrupt mode calculate timeout for 'full' message */
			timeout = ((int)msg->len) * 10;	/* convert approx. to bits */
			timeout /= i2c->speed_khz;	/* convert to bits per ms (note of kHz scale) */
			timeout += timeout >> 1;	/* add 50% */
			timeout = timeout*HZ / 1000;	/* convert to jiffies */
			if (timeout < HZ / 5)		/* at least 200ms */
				timeout = HZ / 5;
		}
		else
			timeout = HZ;			/* 1 second for the polling mode */
	}
	else
		timeout = i2c->adapter->timeout;

	return timeout;
}

/*
 * Initialize I2C core. Zero CNTR and DATA, try RESET. Short busy wait and check core status.
 * After that set dividers for choosen speed.
 */
static void comcerto_i2c_reset(struct comcerto_i2c *i2c)
{
	u8 status, dividers;

	dev_dbg(i2c->dev, "%s\n", __FUNCTION__);

	WR_CNTR(i2c, 0);
	WR_DATA(i2c, 0);
	WR_RESET(i2c, 1);

	udelay(10);

	status = RD_STAT(i2c);
	if (status != STAT_NO_RELEVANT_INFO)
		dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected status after reset: 0x%02x\n", __FUNCTION__, status);

	/* dividers should be placed in CCRH for high-sped mode and in CCRFS for standard/full modes */
	dividers = comcerto_i2c_calculate_dividers(i2c);
	if (i2c->speed_khz == SPEED_HIGH_KHZ)
		WR_CCRH(i2c, dividers);
	else
		WR_CCRFS(i2c, dividers);
}

static inline void comcerto_i2c_message_complete(struct comcerto_i2c *i2c, int status)
{
	WR_CNTR(i2c, CNTR_STP);
	i2c->msg_status = status;
}

static inline int comcerto_i2c_message_in_progress(struct comcerto_i2c *i2c)
{
	return i2c->msg_status > 0;
}

/*
 * Wait event. This function sleeps in polling mode, in interrupt
 * mode it enables IRQ from I2C core and exits immediately.
 */
static int comcerto_i2c_wait(struct comcerto_i2c *i2c, u8 cntr)
{
	cntr &= ~(CNTR_IFLG | CNTR_IEN);	/* clear both IFLG and IEN */

	if (i2c->irq < 0) {
		ulong jiffies_mark = jiffies + comcerto_i2c_calculate_timeout(i2c, i2c->msg);

		WR_CNTR(i2c, cntr);
		while ((RD_CNTR(i2c) & CNTR_IFLG) == 0) {
			if (need_resched())
				schedule();

			if (time_after(jiffies, jiffies_mark)) {
				dev_printk(KERN_DEBUG, i2c->dev, "%s: polling transfer timeout\n", __FUNCTION__);
				comcerto_i2c_message_complete(i2c, -ETIME);
				comcerto_i2c_reset(i2c);
				break;
			}
		}
	}
	else {
		/* enable interrupt */
		WR_CNTR(i2c, cntr | CNTR_IEN);
	}

	return 0;
}

static void comcerto_i2c_state_idle(struct comcerto_i2c *i2c, u8 *cntr)
{
	if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
		i2c->msg_state = TR_ADDR_ACK;
	}
	else {
		*cntr = CNTR_STP|CNTR_STA;	/* SPT|STA to auto recover from bus error state transparently at the start of the transfer */
		i2c->msg_state = TR_START_ACK;
	}
}

static void comcerto_i2c_state_start_ack(struct comcerto_i2c *i2c, u8 *cntr)
{
	u8 status, addr;

	*cntr = 0;	/* zero IFLG, IEN (for the interrupt mode it will be enabled in wait function) */

	status = RD_STAT(i2c);

	if (status == STAT_START || status == STAT_START_REPEATED) {
		i2c->msg_state = TR_ADDR_ACK;

		addr = i2c->msg->addr << 1;
		if (i2c->msg->flags & I2C_M_RD)
			addr |= 1;
		if (i2c->msg->flags & I2C_M_REV_DIR_ADDR)
			addr ^= 1;		/* invert RW bit if it's requested */

		WR_DATA(i2c, addr);		/* write address and read/write bit */
	} else {
		dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected state (%#x) on start phase, %s\n",
			__FUNCTION__, status, i2c->msg_retries > 1 ? "retrying":"aborting");

		if (--i2c->msg_retries < 0)
			comcerto_i2c_message_complete(i2c, -1);
		else
			comcerto_i2c_state_idle(i2c, cntr);
	}
}

static void comcerto_i2c_rx(struct comcerto_i2c *i2c)
{
	u8 status, cntr = 0;

restart:
	switch (i2c->msg_state) {
	case TR_IDLE:
		comcerto_i2c_state_idle(i2c, &cntr);
		if (unlikely(i2c->msg->flags & I2C_M_NOSTART))
			goto restart;	/* needed to avoid event loss in interrupt mode */
		break;

	case TR_START_ACK:
		comcerto_i2c_state_start_ack(i2c, &cntr);
		break;

	case TR_ADDR_ACK:
		if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
			/* we can enter this state if skip start/addr flag is set, so fake good ack */
			status = STAT_ADDR_RD_ACK;
		}
		else {
			status = RD_STAT(i2c);
			/* check whether we should ignore NACK */
			if (status == STAT_DATA_RD_NACK && (i2c->msg->flags & I2C_M_IGNORE_NAK))
				status = STAT_DATA_RD_ACK;
		}

		if (likely(status == STAT_ADDR_RD_ACK)) {
			/* start reception phase - wait until data is ready and loop in RX_DATA_ACK state
			 * until we read all the data, sending ACK after each byte (but the last)
			 */
			i2c->msg_len = 0;
			if (i2c->msg->len > 1) {
				i2c->msg_state = TR_DATA_ACK;
				cntr = CNTR_AAK;
			}
			else if (i2c->msg->len == 1) {
				i2c->msg_state = RX_DATA_NACK;
			}
			else {	/* nothing to receive, send STOP and signal success */
				comcerto_i2c_message_complete(i2c, 0);
			}
		}
		else {
			dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected state (%#x) on address phase, %s\n",
				__FUNCTION__, status, i2c->msg_retries > 1 ? "retrying":"aborting");

			if (--i2c->msg_retries < 0)
				comcerto_i2c_message_complete(i2c, -1);
			else
				comcerto_i2c_state_idle(i2c, &cntr);
		}
		break;

	case TR_DATA_ACK:
		status = RD_STAT(i2c);

		if (likely(status == STAT_DATA_RD_ACK)) {
			i2c->msg->buf[i2c->msg_len++] = RD_DATA(i2c);
			if (likely(i2c->msg->len - i2c->msg_len > 1)) {
				cntr = CNTR_AAK;
			}
			else {
				i2c->msg_state = RX_DATA_NACK;
				/* NACK should be transmitted on the last byte */
			}
		}
		else {
			dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected state (%#x) on read phase\n", __FUNCTION__, status);
			comcerto_i2c_message_complete(i2c, -1);
		}
		break;

	case RX_DATA_NACK:
		status = RD_STAT(i2c);
		if (likely(status == STAT_DATA_RD_NACK)) {
			i2c->msg->buf[i2c->msg_len++] = RD_DATA(i2c);
			comcerto_i2c_message_complete(i2c, 0);
		}
		else {
			dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected state (%#x) on finishing read phase\n", __FUNCTION__, status);
			comcerto_i2c_message_complete(i2c, -1);
		}
	}

	/* no wait if we completed message */
	if (comcerto_i2c_message_in_progress(i2c))
		comcerto_i2c_wait(i2c, cntr);
}

static void comcerto_i2c_tx(struct comcerto_i2c *i2c)
{
	u8 status, cntr = 0;

restart:
	switch (i2c->msg_state) {
	case TR_IDLE:
		comcerto_i2c_state_idle(i2c, &cntr);
		if (unlikely(i2c->msg->flags & I2C_M_NOSTART))
			goto restart;	/* needed to avoid event loss in interrupt mode */
		break;

	case TR_START_ACK:
		comcerto_i2c_state_start_ack(i2c, &cntr);
		break;

	case TR_ADDR_ACK:
		if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
			/* we can enter this state if skip start/addr flag is set, so fake good ack */
			status = STAT_ADDR_WR_ACK;
		}
		else {
			status = RD_STAT(i2c);
			if (status == STAT_DATA_WR_NACK && (i2c->msg->flags & I2C_M_IGNORE_NAK))
				status = STAT_DATA_WR_ACK;
		}

		if (likely(status == STAT_ADDR_WR_ACK)) {
			/* start reception phase - wait until data is ready and loop in TX_DATA_ACK state
			 * until we read all the data, sending ACK after each byte (but the last)
			 */
			i2c->msg_state = TR_DATA_ACK;
			i2c->msg_len = 0;
			if (likely(i2c->msg->len != 0)) {
				WR_DATA(i2c, i2c->msg->buf[i2c->msg_len++]);
				//printk("comcerto_i2c_tx: i2c->msg->buf[i2c->msg_len - 1]=%d\n", i2c->msg->buf[i2c->msg_len - 1]);
			}
			else {
				/* nothing to transmit, send STOP and signal success */
				comcerto_i2c_message_complete(i2c, 0);
			}
		}
		else {
			dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected state (%#x) on address phase, %s\n",
				__FUNCTION__, status, i2c->msg_retries > 1 ? "retrying":"aborting");

			if (--i2c->msg_retries < 0)
				comcerto_i2c_message_complete(i2c, -1);
			else
				comcerto_i2c_state_idle(i2c, &cntr);
		}
		break;

	case TR_DATA_ACK:
		status = RD_STAT(i2c);
		if (status == STAT_DATA_WR_NACK && (i2c->msg->flags & I2C_M_IGNORE_NAK))
			status = STAT_DATA_WR_ACK;

		if (likely(status == STAT_DATA_WR_ACK)) {
			if (i2c->msg->len > i2c->msg_len)
				WR_DATA(i2c, i2c->msg->buf[i2c->msg_len++]);
			else
				comcerto_i2c_message_complete(i2c, 0);
		}
		else {
			dev_printk(KERN_DEBUG, i2c->dev, "%s: unexpected state (%#x) on read data phase\n", __FUNCTION__, status);
			comcerto_i2c_message_complete(i2c, -1);
		}
		break;
	}

	if (comcerto_i2c_message_in_progress(i2c))
		comcerto_i2c_wait(i2c, cntr);
}

static irqreturn_t comcerto_i2c_interrupt(int irq, void *dev_id)
{
	struct comcerto_i2c *i2c = dev_id;

	if (!(RD_CNTR(i2c) & CNTR_IFLG))
		goto none;

	/* IRQ enable/disable logic is hidden in state handlers, all we need is to wake
	 * process when message completed.
	 */
	if (i2c->msg->flags & I2C_M_RD)
		comcerto_i2c_rx(i2c);
	else
		comcerto_i2c_tx(i2c);

	if (!comcerto_i2c_message_in_progress(i2c)) {
		WR_CNTR(i2c, RD_CNTR(i2c) & ~CNTR_IEN);	/* disable interrupt unconditionally */
		wake_up(&i2c->wait);
	}

	return IRQ_HANDLED;
none:
	return IRQ_NONE;
}

static void comcerto_i2c_message_process(struct comcerto_i2c *i2c, struct i2c_msg *msg)
{
	i2c->msg = msg;
	i2c->msg_state = TR_IDLE;
	i2c->msg_status = 1;
	i2c->msg_retries = i2c->adapter->retries;

polling_mode:
	if (msg->flags & I2C_M_RD)
		comcerto_i2c_rx(i2c);
	else
		comcerto_i2c_tx(i2c);

	if (i2c->irq < 0) {
		/*if (i2c->msg != NULL)*/
			goto polling_mode;
	}
	else {
		int timeout, res;
		ulong flags;

		timeout = comcerto_i2c_calculate_timeout(i2c, msg);

		res = wait_event_timeout(i2c->wait, i2c->msg_status <= 0, timeout);

		local_irq_save(flags);

		/* check if we timed out and set respective error codes */
		if (res == 0) {
			if (comcerto_i2c_message_in_progress(i2c)) {
				dev_printk(KERN_DEBUG, i2c->dev, "%s: interrupt transfer timeout\n", __FUNCTION__);
				comcerto_i2c_message_complete(i2c, -ETIME);
				comcerto_i2c_reset(i2c);
			}
		}

		local_irq_restore(flags);
	}
}

/*
 * Generic master transfer entrypoint.
 * Returns the number of processed messages or error value
 */
static int comcerto_i2c_master_xfer(struct i2c_adapter *adapter, struct i2c_msg msgs[], int num)
{
	struct comcerto_i2c *i2c = i2c_get_adapdata(adapter);
	int i;

	dev_dbg(i2c->dev, "%s: %d messages to process\n", __FUNCTION__, num);

	for (i = 0; i < num; i++) {
		dev_dbg(i2c->dev, "%s: message #%d: addr=%#x, flags=%#x, len=%u\n", __FUNCTION__,
			i, msgs[i].addr, msgs[i].flags, msgs[i].len);

		comcerto_i2c_message_process(i2c, &msgs[i]);

		if (i2c->msg_status < 0) {
			dev_printk(KERN_DEBUG, i2c->dev, "%s: transfer failed on message #%d (addr=%#x, flags=%#x, len=%u)\n",
				__FUNCTION__, i, msgs[i].addr, msgs[i].flags, msgs[i].len);
			break;
		}
	}

	if (i2c->msg_status == -1)
		i2c->msg_status = -EIO;

	if (i2c->msg_status == 0)
		i2c->msg_status = num;

	return i2c->msg_status;
}

static u32 comcerto_i2c_functionality(struct i2c_adapter *adap)
{
	return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL);
}

static struct i2c_algorithm comcerto_i2c_algo = {
	.master_xfer	= comcerto_i2c_master_xfer,
	.functionality	= comcerto_i2c_functionality,
};

static struct i2c_adapter comcerto_i2c_adapter = {
	.name		= "comcerto_i2c",
	.owner		= THIS_MODULE,
	.algo		= &comcerto_i2c_algo,
	.timeout	= 0,	/* <= zero means that we calculate timeout in run-time, can be changed with ioctl call */
	.retries	= 0,	/* no retries by default - let the user decide what's the best, can be changed with ioctl call */
};

static int comcerto_i2c_probe(struct platform_device *pdev)
{
	struct comcerto_i2c *i2c;
	struct resource *irq;
	int res = -1;

	dev_dbg(&pdev->dev, "%s\n", __FUNCTION__);
	
	/* Put the I2C device Out-Of-Reset*/
	c2000_block_reset(COMPONENT_AXI_I2C,0);

	/* Clock divider configuration, get the i2c clock*/
	clk_i2c = clk_get(NULL, "spi_i2c");
	if (IS_ERR(clk_i2c)){
		pr_err("%s: Unable to obtain i2c clock: %ld\n", __func__, PTR_ERR(clk_i2c));
		return PTR_ERR(clk_i2c);
	}

	/*Enable the i2c clock */
	res = clk_enable(clk_i2c); 
	if (res){
		pr_err("%s: i2c clock failed to enable:\n", __func__);
		goto err0;
	}

	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
	if (i2c == NULL) {
		dev_err(&pdev->dev, "%s: failed allocate memory\n", __FUNCTION__);
		res = -ENOMEM;
		goto err0;
	}

	i2c->adapter = &comcerto_i2c_adapter;
	i2c->adapter->dev.parent = &pdev->dev;
	i2c->dev = &pdev->dev;

	init_waitqueue_head(&i2c->wait);

	platform_set_drvdata(pdev, i2c);
	i2c_set_adapdata(&comcerto_i2c_adapter, i2c);

	i2c->io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (i2c->io == NULL) {
		dev_err(&pdev->dev, "%s: no IO region specified\n", __FUNCTION__);
		res = -ENOENT;
		goto err1;
	}

	if (!request_mem_region(i2c->io->start, i2c->io->end - i2c->io->start + 1, "I2C")) {
		dev_err(i2c->dev, "%s: failed to request memory region\n", __FUNCTION__);
		goto err1;
	}

	i2c->membase = APB_VADDR(i2c->io->start);

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (irq == NULL && !force_poll) {
		dev_warn(i2c->dev, "%s: no IRQ specified in resources, polling mode forced\n", __FUNCTION__);
		force_poll = 1;
		i2c->irq = -1;
	}

	if (speed == 0) {
		i2c->speed_khz = SPEED_NORMAL_KHZ;
	}
	else if (speed == 1) {
		i2c->speed_khz = SPEED_FULL_KHZ;
	}
	else if (speed == 2) {
		i2c->speed_khz = SPEED_HIGH_KHZ;
	}
	else {
		dev_err(i2c->dev, "%s: invalid 'speed' module option provided (%d, must be 0,1,2 for normal/full/high modes)\n",
			__FUNCTION__, speed);
		goto err2;
	}


	comcerto_i2c_reset(i2c);

	if (!force_poll) {
		i2c->irq = irq->start;

		res = request_irq(i2c->irq, comcerto_i2c_interrupt, IRQF_SHARED, "I2C", i2c);
		if (res < 0) {
			dev_warn(i2c->dev, "%s: failed to request IRQ%d, polling mode forced\n", __FUNCTION__, i2c->irq);
			force_poll = 1;
			i2c->irq = -1;
		}
	}
	else
		i2c->irq = -1;

	if (i2c_add_numbered_adapter(&comcerto_i2c_adapter) != 0) {
		dev_err(i2c->dev, "%s: failed to add I2C adapter\n", __FUNCTION__);
		goto err3;
	}

	dev_dbg(&pdev->dev, "%s: I2C adapter registered\n", __FUNCTION__);

	return 0;

err3:
	if (i2c->irq >= 0)
		free_irq(i2c->irq, i2c);

err2:
	release_mem_region(i2c->io->start, i2c->io->end - i2c->io->end + 1);

err1:
	kfree(i2c);

err0:
	return res;
}

static int comcerto_i2c_remove(struct platform_device *pdev)
{
	struct comcerto_i2c *i2c = platform_get_drvdata(pdev);

	dev_dbg(i2c->dev, "%s\n", __FUNCTION__);

	platform_set_drvdata(pdev, NULL);

	i2c_del_adapter(i2c->adapter);

	if (i2c->irq >= 0)
		free_irq(i2c->irq, i2c);

	release_mem_region(i2c->io->start, i2c->io->end - i2c->io->start + 1);

	kfree(i2c);

	/* Disable the Clock */
	clk_disable(clk_i2c);
	clk_put(clk_i2c);

	/* Put the I2C device in reset state*/
	c2000_block_reset(COMPONENT_AXI_I2C,1);

	return 0;
}

#ifdef CONFIG_PM
static int comcerto_i2c_suspend(struct platform_device *pdev, pm_message_t state)
{
	/* No need to suspend client drivers here. Because clients are
	 * children, client drivers get suspended before adapter driver
	*/
	
	/* So do the Clock disable here , This clock is depends upon Legacy SPI*/
	clk_disable(clk_i2c);
	return 0;
}
	
static int comcerto_i2c_resume(struct platform_device *pdev)
{
	int ret;
	/* No need to suspend client drivers here. Because clients are
	 * children, client drivers get suspended before adapter driver
	*/

	/* So do the Clock Enable here , This clock is depends upon Legacy SPI*/
	ret = clk_enable(clk_i2c);
	if (ret)
	{
		pr_err("%s: I2C clock enable failed \n",__func__);
		return ret;
	}
	return 0;
}
#endif

static struct platform_driver comcerto_i2c_driver = {
	.driver = {
		.name	= "comcerto_i2c",
		.owner	= THIS_MODULE,
	},
	.probe	= comcerto_i2c_probe,
	.remove	= comcerto_i2c_remove,
#ifdef CONFIG_PM
	.suspend = comcerto_i2c_suspend,
	.resume  = comcerto_i2c_resume,
#endif
};

static int __init comcerto_i2c_init(void)
{
	if (platform_driver_register(&comcerto_i2c_driver)) {
		return -1;
	}

	return 0;
}

static void __exit comcerto_i2c_exit(void)
{
	platform_driver_unregister(&comcerto_i2c_driver);
}

module_init(comcerto_i2c_init);
module_exit(comcerto_i2c_exit);
