// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2013 STMicroelectronics
 *
 * I2C master mode controller driver, used in STMicroelectronics devices.
 *
 * Author: Maxime Coquelin <maxime.coquelin@st.com>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>

/* SSC registers */
#define SSC_BRG				0x000
#define SSC_TBUF			0x004
#define SSC_RBUF			0x008
#define SSC_CTL				0x00C
#define SSC_IEN				0x010
#define SSC_STA				0x014
#define SSC_I2C				0x018
#define SSC_SLAD			0x01C
#define SSC_REP_START_HOLD		0x020
#define SSC_START_HOLD			0x024
#define SSC_REP_START_SETUP		0x028
#define SSC_DATA_SETUP			0x02C
#define SSC_STOP_SETUP			0x030
#define SSC_BUS_FREE			0x034
#define SSC_TX_FSTAT			0x038
#define SSC_RX_FSTAT			0x03C
#define SSC_PRE_SCALER_BRG		0x040
#define SSC_CLR				0x080
#define SSC_NOISE_SUPP_WIDTH		0x100
#define SSC_PRSCALER			0x104
#define SSC_NOISE_SUPP_WIDTH_DATAOUT	0x108
#define SSC_PRSCALER_DATAOUT		0x10c

/* SSC Control */
#define SSC_CTL_DATA_WIDTH_9		0x8
#define SSC_CTL_DATA_WIDTH_MSK		0xf
#define SSC_CTL_BM			0xf
#define SSC_CTL_HB			BIT(4)
#define SSC_CTL_PH			BIT(5)
#define SSC_CTL_PO			BIT(6)
#define SSC_CTL_SR			BIT(7)
#define SSC_CTL_MS			BIT(8)
#define SSC_CTL_EN			BIT(9)
#define SSC_CTL_LPB			BIT(10)
#define SSC_CTL_EN_TX_FIFO		BIT(11)
#define SSC_CTL_EN_RX_FIFO		BIT(12)
#define SSC_CTL_EN_CLST_RX		BIT(13)

/* SSC Interrupt Enable */
#define SSC_IEN_RIEN			BIT(0)
#define SSC_IEN_TIEN			BIT(1)
#define SSC_IEN_TEEN			BIT(2)
#define SSC_IEN_REEN			BIT(3)
#define SSC_IEN_PEEN			BIT(4)
#define SSC_IEN_AASEN			BIT(6)
#define SSC_IEN_STOPEN			BIT(7)
#define SSC_IEN_ARBLEN			BIT(8)
#define SSC_IEN_NACKEN			BIT(10)
#define SSC_IEN_REPSTRTEN		BIT(11)
#define SSC_IEN_TX_FIFO_HALF		BIT(12)
#define SSC_IEN_RX_FIFO_HALF_FULL	BIT(14)

/* SSC Status */
#define SSC_STA_RIR			BIT(0)
#define SSC_STA_TIR			BIT(1)
#define SSC_STA_TE			BIT(2)
#define SSC_STA_RE			BIT(3)
#define SSC_STA_PE			BIT(4)
#define SSC_STA_CLST			BIT(5)
#define SSC_STA_AAS			BIT(6)
#define SSC_STA_STOP			BIT(7)
#define SSC_STA_ARBL			BIT(8)
#define SSC_STA_BUSY			BIT(9)
#define SSC_STA_NACK			BIT(10)
#define SSC_STA_REPSTRT			BIT(11)
#define SSC_STA_TX_FIFO_HALF		BIT(12)
#define SSC_STA_TX_FIFO_FULL		BIT(13)
#define SSC_STA_RX_FIFO_HALF		BIT(14)

/* SSC I2C Control */
#define SSC_I2C_I2CM			BIT(0)
#define SSC_I2C_STRTG			BIT(1)
#define SSC_I2C_STOPG			BIT(2)
#define SSC_I2C_ACKG			BIT(3)
#define SSC_I2C_AD10			BIT(4)
#define SSC_I2C_TXENB			BIT(5)
#define SSC_I2C_REPSTRTG		BIT(11)
#define SSC_I2C_SLAVE_DISABLE		BIT(12)

/* SSC Tx FIFO Status */
#define SSC_TX_FSTAT_STATUS		0x07

/* SSC Rx FIFO Status */
#define SSC_RX_FSTAT_STATUS		0x07

/* SSC Clear bit operation */
#define SSC_CLR_SSCAAS			BIT(6)
#define SSC_CLR_SSCSTOP			BIT(7)
#define SSC_CLR_SSCARBL			BIT(8)
#define SSC_CLR_NACK			BIT(10)
#define SSC_CLR_REPSTRT			BIT(11)

/* SSC Clock Prescaler */
#define SSC_PRSC_VALUE			0x0f


#define SSC_TXFIFO_SIZE			0x8
#define SSC_RXFIFO_SIZE			0x8

enum st_i2c_mode {
	I2C_MODE_STANDARD,
	I2C_MODE_FAST,
	I2C_MODE_END,
};

/**
 * struct st_i2c_timings - per-Mode tuning parameters
 * @rate: I2C bus rate
 * @rep_start_hold: I2C repeated start hold time requirement
 * @rep_start_setup: I2C repeated start set up time requirement
 * @start_hold: I2C start hold time requirement
 * @data_setup_time: I2C data set up time requirement
 * @stop_setup_time: I2C stop set up time requirement
 * @bus_free_time: I2C bus free time requirement
 * @sda_pulse_min_limit: I2C SDA pulse mini width limit
 */
struct st_i2c_timings {
	u32 rate;
	u32 rep_start_hold;
	u32 rep_start_setup;
	u32 start_hold;
	u32 data_setup_time;
	u32 stop_setup_time;
	u32 bus_free_time;
	u32 sda_pulse_min_limit;
};

/**
 * struct st_i2c_client - client specific data
 * @addr: 8-bit slave addr, including r/w bit
 * @count: number of bytes to be transfered
 * @xfered: number of bytes already transferred
 * @buf: data buffer
 * @result: result of the transfer
 * @stop: last I2C msg to be sent, i.e. STOP to be generated
 */
struct st_i2c_client {
	u8	addr;
	u32	count;
	u32	xfered;
	u8	*buf;
	int	result;
	bool	stop;
};

/**
 * struct st_i2c_dev - private data of the controller
 * @adap: I2C adapter for this controller
 * @dev: device for this controller
 * @base: virtual memory area
 * @complete: completion of I2C message
 * @irq: interrupt line for th controller
 * @clk: hw ssc block clock
 * @mode: I2C mode of the controller. Standard or Fast only supported
 * @scl_min_width_us: SCL line minimum pulse width in us
 * @sda_min_width_us: SDA line minimum pulse width in us
 * @client: I2C transfert information
 * @busy: I2C transfer on-going
 */
struct st_i2c_dev {
	struct i2c_adapter	adap;
	struct device		*dev;
	void __iomem		*base;
	struct completion	complete;
	int			irq;
	struct clk		*clk;
	int			mode;
	u32			scl_min_width_us;
	u32			sda_min_width_us;
	struct st_i2c_client	client;
	bool			busy;
};

static inline void st_i2c_set_bits(void __iomem *reg, u32 mask)
{
	writel_relaxed(readl_relaxed(reg) | mask, reg);
}

static inline void st_i2c_clr_bits(void __iomem *reg, u32 mask)
{
	writel_relaxed(readl_relaxed(reg) & ~mask, reg);
}

/*
 * From I2C Specifications v0.5.
 *
 * All the values below have +10% margin added to be
 * compatible with some out-of-spec devices,
 * like HDMI link of the Toshiba 19AV600 TV.
 */
static struct st_i2c_timings i2c_timings[] = {
	[I2C_MODE_STANDARD] = {
		.rate			= I2C_MAX_STANDARD_MODE_FREQ,
		.rep_start_hold		= 4400,
		.rep_start_setup	= 5170,
		.start_hold		= 4400,
		.data_setup_time	= 275,
		.stop_setup_time	= 4400,
		.bus_free_time		= 5170,
	},
	[I2C_MODE_FAST] = {
		.rate			= I2C_MAX_FAST_MODE_FREQ,
		.rep_start_hold		= 660,
		.rep_start_setup	= 660,
		.start_hold		= 660,
		.data_setup_time	= 110,
		.stop_setup_time	= 660,
		.bus_free_time		= 1430,
	},
};

static void st_i2c_flush_rx_fifo(struct st_i2c_dev *i2c_dev)
{
	int count, i;

	/*
	 * Counter only counts up to 7 but fifo size is 8...
	 * When fifo is full, counter is 0 and RIR bit of status register is
	 * set
	 */
	if (readl_relaxed(i2c_dev->base + SSC_STA) & SSC_STA_RIR)
		count = SSC_RXFIFO_SIZE;
	else
		count = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT) &
			SSC_RX_FSTAT_STATUS;

	for (i = 0; i < count; i++)
		readl_relaxed(i2c_dev->base + SSC_RBUF);
}

static void st_i2c_soft_reset(struct st_i2c_dev *i2c_dev)
{
	/*
	 * FIFO needs to be emptied before reseting the IP,
	 * else the controller raises a BUSY error.
	 */
	st_i2c_flush_rx_fifo(i2c_dev);

	st_i2c_set_bits(i2c_dev->base + SSC_CTL, SSC_CTL_SR);
	st_i2c_clr_bits(i2c_dev->base + SSC_CTL, SSC_CTL_SR);
}

/**
 * st_i2c_hw_config() - Prepare SSC block, calculate and apply tuning timings
 * @i2c_dev: Controller's private data
 */
static void st_i2c_hw_config(struct st_i2c_dev *i2c_dev)
{
	unsigned long rate;
	u32 val, ns_per_clk;
	struct st_i2c_timings *t = &i2c_timings[i2c_dev->mode];

	st_i2c_soft_reset(i2c_dev);

	val = SSC_CLR_REPSTRT | SSC_CLR_NACK | SSC_CLR_SSCARBL |
		SSC_CLR_SSCAAS | SSC_CLR_SSCSTOP;
	writel_relaxed(val, i2c_dev->base + SSC_CLR);

	/* SSC Control register setup */
	val = SSC_CTL_PO | SSC_CTL_PH | SSC_CTL_HB | SSC_CTL_DATA_WIDTH_9;
	writel_relaxed(val, i2c_dev->base + SSC_CTL);

	rate = clk_get_rate(i2c_dev->clk);
	ns_per_clk = 1000000000 / rate;

	/* Baudrate */
	val = rate / (2 * t->rate);
	writel_relaxed(val, i2c_dev->base + SSC_BRG);

	/* Pre-scaler baudrate */
	writel_relaxed(1, i2c_dev->base + SSC_PRE_SCALER_BRG);

	/* Enable I2C mode */
	writel_relaxed(SSC_I2C_I2CM, i2c_dev->base + SSC_I2C);

	/* Repeated start hold time */
	val = t->rep_start_hold / ns_per_clk;
	writel_relaxed(val, i2c_dev->base + SSC_REP_START_HOLD);

	/* Repeated start set up time */
	val = t->rep_start_setup / ns_per_clk;
	writel_relaxed(val, i2c_dev->base + SSC_REP_START_SETUP);

	/* Start hold time */
	val = t->start_hold / ns_per_clk;
	writel_relaxed(val, i2c_dev->base + SSC_START_HOLD);

	/* Data set up time */
	val = t->data_setup_time / ns_per_clk;
	writel_relaxed(val, i2c_dev->base + SSC_DATA_SETUP);

	/* Stop set up time */
	val = t->stop_setup_time / ns_per_clk;
	writel_relaxed(val, i2c_dev->base + SSC_STOP_SETUP);

	/* Bus free time */
	val = t->bus_free_time / ns_per_clk;
	writel_relaxed(val, i2c_dev->base + SSC_BUS_FREE);

	/* Prescalers set up */
	val = rate / 10000000;
	writel_relaxed(val, i2c_dev->base + SSC_PRSCALER);
	writel_relaxed(val, i2c_dev->base + SSC_PRSCALER_DATAOUT);

	/* Noise suppression witdh */
	val = i2c_dev->scl_min_width_us * rate / 100000000;
	writel_relaxed(val, i2c_dev->base + SSC_NOISE_SUPP_WIDTH);

	/* Noise suppression max output data delay width */
	val = i2c_dev->sda_min_width_us * rate / 100000000;
	writel_relaxed(val, i2c_dev->base + SSC_NOISE_SUPP_WIDTH_DATAOUT);
}

static int st_i2c_recover_bus(struct i2c_adapter *i2c_adap)
{
	struct st_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
	u32 ctl;

	dev_dbg(i2c_dev->dev, "Trying to recover bus\n");

	/*
	 * SSP IP is dual role SPI/I2C to generate 9 clock pulses
	 * we switch to SPI node, 9 bit words and write a 0. This
	 * has been validate with a oscilloscope and is easier
	 * than switching to GPIO mode.
	 */

	/* Disable interrupts */
	writel_relaxed(0, i2c_dev->base + SSC_IEN);

	st_i2c_hw_config(i2c_dev);

	ctl = SSC_CTL_EN | SSC_CTL_MS |	SSC_CTL_EN_RX_FIFO | SSC_CTL_EN_TX_FIFO;
	st_i2c_set_bits(i2c_dev->base + SSC_CTL, ctl);

	st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_I2CM);
	usleep_range(8000, 10000);

	writel_relaxed(0, i2c_dev->base + SSC_TBUF);
	usleep_range(2000, 4000);
	st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_I2CM);

	return 0;
}

static int st_i2c_wait_free_bus(struct st_i2c_dev *i2c_dev)
{
	u32 sta;
	int i, ret;

	for (i = 0; i < 10; i++) {
		sta = readl_relaxed(i2c_dev->base + SSC_STA);
		if (!(sta & SSC_STA_BUSY))
			return 0;

		usleep_range(2000, 4000);
	}

	dev_err(i2c_dev->dev, "bus not free (status = 0x%08x)\n", sta);

	ret = i2c_recover_bus(&i2c_dev->adap);
	if (ret) {
		dev_err(i2c_dev->dev, "Failed to recover the bus (%d)\n", ret);
		return ret;
	}

	return -EBUSY;
}

/**
 * st_i2c_write_tx_fifo() - Write a byte in the Tx FIFO
 * @i2c_dev: Controller's private data
 * @byte: Data to write in the Tx FIFO
 */
static inline void st_i2c_write_tx_fifo(struct st_i2c_dev *i2c_dev, u8 byte)
{
	u16 tbuf = byte << 1;

	writel_relaxed(tbuf | 1, i2c_dev->base + SSC_TBUF);
}

/**
 * st_i2c_wr_fill_tx_fifo() - Fill the Tx FIFO in write mode
 * @i2c_dev: Controller's private data
 *
 * This functions fills the Tx FIFO with I2C transfert buffer when
 * in write mode.
 */
static void st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev)
{
	struct st_i2c_client *c = &i2c_dev->client;
	u32 tx_fstat, sta;
	int i;

	sta = readl_relaxed(i2c_dev->base + SSC_STA);
	if (sta & SSC_STA_TX_FIFO_FULL)
		return;

	tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT);
	tx_fstat &= SSC_TX_FSTAT_STATUS;

	if (c->count < (SSC_TXFIFO_SIZE - tx_fstat))
		i = c->count;
	else
		i = SSC_TXFIFO_SIZE - tx_fstat;

	for (; i > 0; i--, c->count--, c->buf++)
		st_i2c_write_tx_fifo(i2c_dev, *c->buf);
}

/**
 * st_i2c_rd_fill_tx_fifo() - Fill the Tx FIFO in read mode
 * @i2c_dev: Controller's private data
 * @max: Maximum amount of data to fill into the Tx FIFO
 *
 * This functions fills the Tx FIFO with fixed pattern when
 * in read mode to trigger clock.
 */
static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max)
{
	struct st_i2c_client *c = &i2c_dev->client;
	u32 tx_fstat, sta;
	int i;

	sta = readl_relaxed(i2c_dev->base + SSC_STA);
	if (sta & SSC_STA_TX_FIFO_FULL)
		return;

	tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT);
	tx_fstat &= SSC_TX_FSTAT_STATUS;

	if (max < (SSC_TXFIFO_SIZE - tx_fstat))
		i = max;
	else
		i = SSC_TXFIFO_SIZE - tx_fstat;

	for (; i > 0; i--, c->xfered++)
		st_i2c_write_tx_fifo(i2c_dev, 0xff);
}

static void st_i2c_read_rx_fifo(struct st_i2c_dev *i2c_dev)
{
	struct st_i2c_client *c = &i2c_dev->client;
	u32 i, sta;
	u16 rbuf;

	sta = readl_relaxed(i2c_dev->base + SSC_STA);
	if (sta & SSC_STA_RIR) {
		i = SSC_RXFIFO_SIZE;
	} else {
		i = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT);
		i &= SSC_RX_FSTAT_STATUS;
	}

	for (; (i > 0) && (c->count > 0); i--, c->count--) {
		rbuf = readl_relaxed(i2c_dev->base + SSC_RBUF) >> 1;
		*c->buf++ = (u8)rbuf & 0xff;
	}

	if (i) {
		dev_err(i2c_dev->dev, "Unexpected %d bytes in rx fifo\n", i);
		st_i2c_flush_rx_fifo(i2c_dev);
	}
}

/**
 * st_i2c_terminate_xfer() - Send either STOP or REPSTART condition
 * @i2c_dev: Controller's private data
 */
static void st_i2c_terminate_xfer(struct st_i2c_dev *i2c_dev)
{
	struct st_i2c_client *c = &i2c_dev->client;

	st_i2c_clr_bits(i2c_dev->base + SSC_IEN, SSC_IEN_TEEN);
	st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG);

	if (c->stop) {
		st_i2c_set_bits(i2c_dev->base + SSC_IEN, SSC_IEN_STOPEN);
		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
	} else {
		st_i2c_set_bits(i2c_dev->base + SSC_IEN, SSC_IEN_REPSTRTEN);
		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_REPSTRTG);
	}
}

/**
 * st_i2c_handle_write() - Handle FIFO empty interrupt in case of write
 * @i2c_dev: Controller's private data
 */
static void st_i2c_handle_write(struct st_i2c_dev *i2c_dev)
{
	struct st_i2c_client *c = &i2c_dev->client;

	st_i2c_flush_rx_fifo(i2c_dev);

	if (!c->count)
		/* End of xfer, send stop or repstart */
		st_i2c_terminate_xfer(i2c_dev);
	else
		st_i2c_wr_fill_tx_fifo(i2c_dev);
}

/**
 * st_i2c_handle_read() - Handle FIFO empty interrupt in case of read
 * @i2c_dev: Controller's private data
 */
static void st_i2c_handle_read(struct st_i2c_dev *i2c_dev)
{
	struct st_i2c_client *c = &i2c_dev->client;
	u32 ien;

	/* Trash the address read back */
	if (!c->xfered) {
		readl_relaxed(i2c_dev->base + SSC_RBUF);
		st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_TXENB);
	} else {
		st_i2c_read_rx_fifo(i2c_dev);
	}

	if (!c->count) {
		/* End of xfer, send stop or repstart */
		st_i2c_terminate_xfer(i2c_dev);
	} else if (c->count == 1) {
		/* Penultimate byte to xfer, disable ACK gen. */
		st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_ACKG);

		/* Last received byte is to be handled by NACK interrupt */
		ien = SSC_IEN_NACKEN | SSC_IEN_ARBLEN;
		writel_relaxed(ien, i2c_dev->base + SSC_IEN);

		st_i2c_rd_fill_tx_fifo(i2c_dev, c->count);
	} else {
		st_i2c_rd_fill_tx_fifo(i2c_dev, c->count - 1);
	}
}

/**
 * st_i2c_isr_thread() - Interrupt routine
 * @irq: interrupt number
 * @data: Controller's private data
 */
static irqreturn_t st_i2c_isr_thread(int irq, void *data)
{
	struct st_i2c_dev *i2c_dev = data;
	struct st_i2c_client *c = &i2c_dev->client;
	u32 sta, ien;
	int it;

	ien = readl_relaxed(i2c_dev->base + SSC_IEN);
	sta = readl_relaxed(i2c_dev->base + SSC_STA);

	/* Use __fls() to check error bits first */
	it = __fls(sta & ien);
	if (it < 0) {
		dev_dbg(i2c_dev->dev, "spurious it (sta=0x%04x, ien=0x%04x)\n",
				sta, ien);
		return IRQ_NONE;
	}

	switch (1 << it) {
	case SSC_STA_TE:
		if (c->addr & I2C_M_RD)
			st_i2c_handle_read(i2c_dev);
		else
			st_i2c_handle_write(i2c_dev);
		break;

	case SSC_STA_STOP:
	case SSC_STA_REPSTRT:
		writel_relaxed(0, i2c_dev->base + SSC_IEN);
		complete(&i2c_dev->complete);
		break;

	case SSC_STA_NACK:
		writel_relaxed(SSC_CLR_NACK, i2c_dev->base + SSC_CLR);

		/* Last received byte handled by NACK interrupt */
		if ((c->addr & I2C_M_RD) && (c->count == 1) && (c->xfered)) {
			st_i2c_handle_read(i2c_dev);
			break;
		}

		it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN;
		writel_relaxed(it, i2c_dev->base + SSC_IEN);

		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
		c->result = -EIO;
		break;

	case SSC_STA_ARBL:
		writel_relaxed(SSC_CLR_SSCARBL, i2c_dev->base + SSC_CLR);

		it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN;
		writel_relaxed(it, i2c_dev->base + SSC_IEN);

		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
		c->result = -EAGAIN;
		break;

	default:
		dev_err(i2c_dev->dev,
				"it %d unhandled (sta=0x%04x)\n", it, sta);
	}

	/*
	 * Read IEN register to ensure interrupt mask write is effective
	 * before re-enabling interrupt at GIC level, and thus avoid spurious
	 * interrupts.
	 */
	readl(i2c_dev->base + SSC_IEN);

	return IRQ_HANDLED;
}

/**
 * st_i2c_xfer_msg() - Transfer a single I2C message
 * @i2c_dev: Controller's private data
 * @msg: I2C message to transfer
 * @is_first: first message of the sequence
 * @is_last: last message of the sequence
 */
static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
			    bool is_first, bool is_last)
{
	struct st_i2c_client *c = &i2c_dev->client;
	u32 ctl, i2c, it;
	unsigned long timeout;
	int ret;

	c->addr		= i2c_8bit_addr_from_msg(msg);
	c->buf		= msg->buf;
	c->count	= msg->len;
	c->xfered	= 0;
	c->result	= 0;
	c->stop		= is_last;

	reinit_completion(&i2c_dev->complete);

	ctl = SSC_CTL_EN | SSC_CTL_MS |	SSC_CTL_EN_RX_FIFO | SSC_CTL_EN_TX_FIFO;
	st_i2c_set_bits(i2c_dev->base + SSC_CTL, ctl);

	i2c = SSC_I2C_TXENB;
	if (c->addr & I2C_M_RD)
		i2c |= SSC_I2C_ACKG;
	st_i2c_set_bits(i2c_dev->base + SSC_I2C, i2c);

	/* Write slave address */
	st_i2c_write_tx_fifo(i2c_dev, c->addr);

	/* Pre-fill Tx fifo with data in case of write */
	if (!(c->addr & I2C_M_RD))
		st_i2c_wr_fill_tx_fifo(i2c_dev);

	it = SSC_IEN_NACKEN | SSC_IEN_TEEN | SSC_IEN_ARBLEN;
	writel_relaxed(it, i2c_dev->base + SSC_IEN);

	if (is_first) {
		ret = st_i2c_wait_free_bus(i2c_dev);
		if (ret)
			return ret;

		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG);
	}

	timeout = wait_for_completion_timeout(&i2c_dev->complete,
			i2c_dev->adap.timeout);
	ret = c->result;

	if (!timeout) {
		dev_err(i2c_dev->dev, "Write to slave 0x%x timed out\n",
				c->addr);
		ret = -ETIMEDOUT;
	}

	i2c = SSC_I2C_STOPG | SSC_I2C_REPSTRTG;
	st_i2c_clr_bits(i2c_dev->base + SSC_I2C, i2c);

	writel_relaxed(SSC_CLR_SSCSTOP | SSC_CLR_REPSTRT,
			i2c_dev->base + SSC_CLR);

	return ret;
}

/**
 * st_i2c_xfer() - Transfer a single I2C message
 * @i2c_adap: Adapter pointer to the controller
 * @msgs: Pointer to data to be written.
 * @num: Number of messages to be executed
 */
static int st_i2c_xfer(struct i2c_adapter *i2c_adap,
			struct i2c_msg msgs[], int num)
{
	struct st_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
	int ret, i;

	i2c_dev->busy = true;

	ret = clk_prepare_enable(i2c_dev->clk);
	if (ret) {
		dev_err(i2c_dev->dev, "Failed to prepare_enable clock\n");
		return ret;
	}

	pinctrl_pm_select_default_state(i2c_dev->dev);

	st_i2c_hw_config(i2c_dev);

	for (i = 0; (i < num) && !ret; i++)
		ret = st_i2c_xfer_msg(i2c_dev, &msgs[i], i == 0, i == num - 1);

	pinctrl_pm_select_idle_state(i2c_dev->dev);

	clk_disable_unprepare(i2c_dev->clk);

	i2c_dev->busy = false;

	return (ret < 0) ? ret : i;
}

#ifdef CONFIG_PM_SLEEP
static int st_i2c_suspend(struct device *dev)
{
	struct st_i2c_dev *i2c_dev = dev_get_drvdata(dev);

	if (i2c_dev->busy)
		return -EBUSY;

	pinctrl_pm_select_sleep_state(dev);

	return 0;
}

static int st_i2c_resume(struct device *dev)
{
	pinctrl_pm_select_default_state(dev);
	/* Go in idle state if available */
	pinctrl_pm_select_idle_state(dev);

	return 0;
}

static SIMPLE_DEV_PM_OPS(st_i2c_pm, st_i2c_suspend, st_i2c_resume);
#define ST_I2C_PM	(&st_i2c_pm)
#else
#define ST_I2C_PM	NULL
#endif

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

static const struct i2c_algorithm st_i2c_algo = {
	.master_xfer = st_i2c_xfer,
	.functionality = st_i2c_func,
};

static struct i2c_bus_recovery_info st_i2c_recovery_info = {
	.recover_bus = st_i2c_recover_bus,
};

static int st_i2c_of_get_deglitch(struct device_node *np,
		struct st_i2c_dev *i2c_dev)
{
	int ret;

	ret = of_property_read_u32(np, "st,i2c-min-scl-pulse-width-us",
			&i2c_dev->scl_min_width_us);
	if ((ret == -ENODATA) || (ret == -EOVERFLOW)) {
		dev_err(i2c_dev->dev, "st,i2c-min-scl-pulse-width-us invalid\n");
		return ret;
	}

	ret = of_property_read_u32(np, "st,i2c-min-sda-pulse-width-us",
			&i2c_dev->sda_min_width_us);
	if ((ret == -ENODATA) || (ret == -EOVERFLOW)) {
		dev_err(i2c_dev->dev, "st,i2c-min-sda-pulse-width-us invalid\n");
		return ret;
	}

	return 0;
}

static int st_i2c_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct st_i2c_dev *i2c_dev;
	struct resource *res;
	u32 clk_rate;
	struct i2c_adapter *adap;
	int ret;

	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
	if (!i2c_dev)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(i2c_dev->base))
		return PTR_ERR(i2c_dev->base);

	i2c_dev->irq = irq_of_parse_and_map(np, 0);
	if (!i2c_dev->irq) {
		dev_err(&pdev->dev, "IRQ missing or invalid\n");
		return -EINVAL;
	}

	i2c_dev->clk = of_clk_get_by_name(np, "ssc");
	if (IS_ERR(i2c_dev->clk)) {
		dev_err(&pdev->dev, "Unable to request clock\n");
		return PTR_ERR(i2c_dev->clk);
	}

	i2c_dev->mode = I2C_MODE_STANDARD;
	ret = of_property_read_u32(np, "clock-frequency", &clk_rate);
	if (!ret && (clk_rate == I2C_MAX_FAST_MODE_FREQ))
		i2c_dev->mode = I2C_MODE_FAST;

	i2c_dev->dev = &pdev->dev;

	ret = devm_request_threaded_irq(&pdev->dev, i2c_dev->irq,
			NULL, st_i2c_isr_thread,
			IRQF_ONESHOT, pdev->name, i2c_dev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
		return ret;
	}

	pinctrl_pm_select_default_state(i2c_dev->dev);
	/* In case idle state available, select it */
	pinctrl_pm_select_idle_state(i2c_dev->dev);

	ret = st_i2c_of_get_deglitch(np, i2c_dev);
	if (ret)
		return ret;

	adap = &i2c_dev->adap;
	i2c_set_adapdata(adap, i2c_dev);
	snprintf(adap->name, sizeof(adap->name), "ST I2C(%pa)", &res->start);
	adap->owner = THIS_MODULE;
	adap->timeout = 2 * HZ;
	adap->retries = 0;
	adap->algo = &st_i2c_algo;
	adap->bus_recovery_info = &st_i2c_recovery_info;
	adap->dev.parent = &pdev->dev;
	adap->dev.of_node = pdev->dev.of_node;

	init_completion(&i2c_dev->complete);

	ret = i2c_add_adapter(adap);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, i2c_dev);

	dev_info(i2c_dev->dev, "%s initialized\n", adap->name);

	return 0;
}

static int st_i2c_remove(struct platform_device *pdev)
{
	struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev);

	i2c_del_adapter(&i2c_dev->adap);

	return 0;
}

static const struct of_device_id st_i2c_match[] = {
	{ .compatible = "st,comms-ssc-i2c", },
	{ .compatible = "st,comms-ssc4-i2c", },
	{},
};
MODULE_DEVICE_TABLE(of, st_i2c_match);

static struct platform_driver st_i2c_driver = {
	.driver = {
		.name = "st-i2c",
		.of_match_table = st_i2c_match,
		.pm = ST_I2C_PM,
	},
	.probe = st_i2c_probe,
	.remove = st_i2c_remove,
};

module_platform_driver(st_i2c_driver);

MODULE_AUTHOR("Maxime Coquelin <maxime.coquelin@st.com>");
MODULE_DESCRIPTION("STMicroelectronics I2C driver");
MODULE_LICENSE("GPL v2");
