xref: /openbmc/linux/drivers/i2c/busses/i2c-lpc2k.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
23f9c37a0SJoachim Eastwood /*
33f9c37a0SJoachim Eastwood  * Copyright (C) 2011 NXP Semiconductors
43f9c37a0SJoachim Eastwood  *
53f9c37a0SJoachim Eastwood  * Code portions referenced from the i2x-pxa and i2c-pnx drivers
63f9c37a0SJoachim Eastwood  *
73f9c37a0SJoachim Eastwood  * Make SMBus byte and word transactions work on LPC178x/7x
83f9c37a0SJoachim Eastwood  * Copyright (c) 2012
93f9c37a0SJoachim Eastwood  * Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com
103f9c37a0SJoachim Eastwood  * Anton Protopopov, Emcraft Systems, antonp@emcraft.com
113f9c37a0SJoachim Eastwood  *
123f9c37a0SJoachim Eastwood  * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
133f9c37a0SJoachim Eastwood  */
143f9c37a0SJoachim Eastwood 
153f9c37a0SJoachim Eastwood #include <linux/clk.h>
163f9c37a0SJoachim Eastwood #include <linux/errno.h>
173f9c37a0SJoachim Eastwood #include <linux/i2c.h>
183f9c37a0SJoachim Eastwood #include <linux/interrupt.h>
193f9c37a0SJoachim Eastwood #include <linux/io.h>
203f9c37a0SJoachim Eastwood #include <linux/kernel.h>
213f9c37a0SJoachim Eastwood #include <linux/module.h>
223f9c37a0SJoachim Eastwood #include <linux/of.h>
233f9c37a0SJoachim Eastwood #include <linux/platform_device.h>
243f9c37a0SJoachim Eastwood #include <linux/sched.h>
253f9c37a0SJoachim Eastwood #include <linux/time.h>
263f9c37a0SJoachim Eastwood 
273f9c37a0SJoachim Eastwood /* LPC24xx register offsets and bits */
283f9c37a0SJoachim Eastwood #define LPC24XX_I2CONSET	0x00
293f9c37a0SJoachim Eastwood #define LPC24XX_I2STAT		0x04
303f9c37a0SJoachim Eastwood #define LPC24XX_I2DAT		0x08
313f9c37a0SJoachim Eastwood #define LPC24XX_I2ADDR		0x0c
323f9c37a0SJoachim Eastwood #define LPC24XX_I2SCLH		0x10
333f9c37a0SJoachim Eastwood #define LPC24XX_I2SCLL		0x14
343f9c37a0SJoachim Eastwood #define LPC24XX_I2CONCLR	0x18
353f9c37a0SJoachim Eastwood 
363f9c37a0SJoachim Eastwood #define LPC24XX_AA		BIT(2)
373f9c37a0SJoachim Eastwood #define LPC24XX_SI		BIT(3)
383f9c37a0SJoachim Eastwood #define LPC24XX_STO		BIT(4)
393f9c37a0SJoachim Eastwood #define LPC24XX_STA		BIT(5)
403f9c37a0SJoachim Eastwood #define LPC24XX_I2EN		BIT(6)
413f9c37a0SJoachim Eastwood 
423f9c37a0SJoachim Eastwood #define LPC24XX_STO_AA		(LPC24XX_STO | LPC24XX_AA)
433f9c37a0SJoachim Eastwood #define LPC24XX_CLEAR_ALL	(LPC24XX_AA | LPC24XX_SI | LPC24XX_STO | \
443f9c37a0SJoachim Eastwood 				 LPC24XX_STA | LPC24XX_I2EN)
453f9c37a0SJoachim Eastwood 
463f9c37a0SJoachim Eastwood /* I2C SCL clock has different duty cycle depending on mode */
473f9c37a0SJoachim Eastwood #define I2C_STD_MODE_DUTY		46
483f9c37a0SJoachim Eastwood #define I2C_FAST_MODE_DUTY		36
493f9c37a0SJoachim Eastwood #define I2C_FAST_MODE_PLUS_DUTY		38
503f9c37a0SJoachim Eastwood 
513f9c37a0SJoachim Eastwood /*
523f9c37a0SJoachim Eastwood  * 26 possible I2C status codes, but codes applicable only
533f9c37a0SJoachim Eastwood  * to master are listed here and used in this driver
543f9c37a0SJoachim Eastwood  */
553f9c37a0SJoachim Eastwood enum {
563f9c37a0SJoachim Eastwood 	M_BUS_ERROR		= 0x00,
573f9c37a0SJoachim Eastwood 	M_START			= 0x08,
583f9c37a0SJoachim Eastwood 	M_REPSTART		= 0x10,
593f9c37a0SJoachim Eastwood 	MX_ADDR_W_ACK		= 0x18,
603f9c37a0SJoachim Eastwood 	MX_ADDR_W_NACK		= 0x20,
613f9c37a0SJoachim Eastwood 	MX_DATA_W_ACK		= 0x28,
623f9c37a0SJoachim Eastwood 	MX_DATA_W_NACK		= 0x30,
633f9c37a0SJoachim Eastwood 	M_DATA_ARB_LOST		= 0x38,
643f9c37a0SJoachim Eastwood 	MR_ADDR_R_ACK		= 0x40,
653f9c37a0SJoachim Eastwood 	MR_ADDR_R_NACK		= 0x48,
663f9c37a0SJoachim Eastwood 	MR_DATA_R_ACK		= 0x50,
673f9c37a0SJoachim Eastwood 	MR_DATA_R_NACK		= 0x58,
683f9c37a0SJoachim Eastwood 	M_I2C_IDLE		= 0xf8,
693f9c37a0SJoachim Eastwood };
703f9c37a0SJoachim Eastwood 
713f9c37a0SJoachim Eastwood struct lpc2k_i2c {
723f9c37a0SJoachim Eastwood 	void __iomem		*base;
733f9c37a0SJoachim Eastwood 	struct clk		*clk;
743f9c37a0SJoachim Eastwood 	int			irq;
753f9c37a0SJoachim Eastwood 	wait_queue_head_t	wait;
763f9c37a0SJoachim Eastwood 	struct i2c_adapter	adap;
773f9c37a0SJoachim Eastwood 	struct i2c_msg		*msg;
783f9c37a0SJoachim Eastwood 	int			msg_idx;
793f9c37a0SJoachim Eastwood 	int			msg_status;
803f9c37a0SJoachim Eastwood 	int			is_last;
813f9c37a0SJoachim Eastwood };
823f9c37a0SJoachim Eastwood 
i2c_lpc2k_reset(struct lpc2k_i2c * i2c)833f9c37a0SJoachim Eastwood static void i2c_lpc2k_reset(struct lpc2k_i2c *i2c)
843f9c37a0SJoachim Eastwood {
853f9c37a0SJoachim Eastwood 	/* Will force clear all statuses */
863f9c37a0SJoachim Eastwood 	writel(LPC24XX_CLEAR_ALL, i2c->base + LPC24XX_I2CONCLR);
873f9c37a0SJoachim Eastwood 	writel(0, i2c->base + LPC24XX_I2ADDR);
883f9c37a0SJoachim Eastwood 	writel(LPC24XX_I2EN, i2c->base + LPC24XX_I2CONSET);
893f9c37a0SJoachim Eastwood }
903f9c37a0SJoachim Eastwood 
i2c_lpc2k_clear_arb(struct lpc2k_i2c * i2c)913f9c37a0SJoachim Eastwood static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c)
923f9c37a0SJoachim Eastwood {
933f9c37a0SJoachim Eastwood 	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
943f9c37a0SJoachim Eastwood 
953f9c37a0SJoachim Eastwood 	/*
963f9c37a0SJoachim Eastwood 	 * If the transfer needs to abort for some reason, we'll try to
973f9c37a0SJoachim Eastwood 	 * force a stop condition to clear any pending bus conditions
983f9c37a0SJoachim Eastwood 	 */
993f9c37a0SJoachim Eastwood 	writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET);
1003f9c37a0SJoachim Eastwood 
1013f9c37a0SJoachim Eastwood 	/* Wait for status change */
1023f9c37a0SJoachim Eastwood 	while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) {
1033f9c37a0SJoachim Eastwood 		if (time_after(jiffies, timeout)) {
1043f9c37a0SJoachim Eastwood 			/* Bus was not idle, try to reset adapter */
1053f9c37a0SJoachim Eastwood 			i2c_lpc2k_reset(i2c);
1063f9c37a0SJoachim Eastwood 			return -EBUSY;
1073f9c37a0SJoachim Eastwood 		}
1083f9c37a0SJoachim Eastwood 
1093f9c37a0SJoachim Eastwood 		cpu_relax();
1103f9c37a0SJoachim Eastwood 	}
1113f9c37a0SJoachim Eastwood 
1123f9c37a0SJoachim Eastwood 	return 0;
1133f9c37a0SJoachim Eastwood }
1143f9c37a0SJoachim Eastwood 
i2c_lpc2k_pump_msg(struct lpc2k_i2c * i2c)1153f9c37a0SJoachim Eastwood static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
1163f9c37a0SJoachim Eastwood {
1173f9c37a0SJoachim Eastwood 	unsigned char data;
1183f9c37a0SJoachim Eastwood 	u32 status;
1193f9c37a0SJoachim Eastwood 
1203f9c37a0SJoachim Eastwood 	/*
1213f9c37a0SJoachim Eastwood 	 * I2C in the LPC2xxx series is basically a state machine.
1223f9c37a0SJoachim Eastwood 	 * Just run through the steps based on the current status.
1233f9c37a0SJoachim Eastwood 	 */
1243f9c37a0SJoachim Eastwood 	status = readl(i2c->base + LPC24XX_I2STAT);
1253f9c37a0SJoachim Eastwood 
1263f9c37a0SJoachim Eastwood 	switch (status) {
1273f9c37a0SJoachim Eastwood 	case M_START:
1283f9c37a0SJoachim Eastwood 	case M_REPSTART:
1293f9c37a0SJoachim Eastwood 		/* Start bit was just sent out, send out addr and dir */
130043f47f4SWolfram Sang 		data = i2c_8bit_addr_from_msg(i2c->msg);
1313f9c37a0SJoachim Eastwood 
1323f9c37a0SJoachim Eastwood 		writel(data, i2c->base + LPC24XX_I2DAT);
1333f9c37a0SJoachim Eastwood 		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
1343f9c37a0SJoachim Eastwood 		break;
1353f9c37a0SJoachim Eastwood 
1363f9c37a0SJoachim Eastwood 	case MX_ADDR_W_ACK:
1373f9c37a0SJoachim Eastwood 	case MX_DATA_W_ACK:
1383f9c37a0SJoachim Eastwood 		/*
1393f9c37a0SJoachim Eastwood 		 * Address or data was sent out with an ACK. If there is more
1403f9c37a0SJoachim Eastwood 		 * data to send, send it now
1413f9c37a0SJoachim Eastwood 		 */
1423f9c37a0SJoachim Eastwood 		if (i2c->msg_idx < i2c->msg->len) {
1433f9c37a0SJoachim Eastwood 			writel(i2c->msg->buf[i2c->msg_idx],
1443f9c37a0SJoachim Eastwood 			       i2c->base + LPC24XX_I2DAT);
1453f9c37a0SJoachim Eastwood 		} else if (i2c->is_last) {
1463f9c37a0SJoachim Eastwood 			/* Last message, send stop */
1473f9c37a0SJoachim Eastwood 			writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
1483f9c37a0SJoachim Eastwood 			writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
1493f9c37a0SJoachim Eastwood 			i2c->msg_status = 0;
1503f9c37a0SJoachim Eastwood 			disable_irq_nosync(i2c->irq);
1513f9c37a0SJoachim Eastwood 		} else {
1523f9c37a0SJoachim Eastwood 			i2c->msg_status = 0;
1533f9c37a0SJoachim Eastwood 			disable_irq_nosync(i2c->irq);
1543f9c37a0SJoachim Eastwood 		}
1553f9c37a0SJoachim Eastwood 
1563f9c37a0SJoachim Eastwood 		i2c->msg_idx++;
1573f9c37a0SJoachim Eastwood 		break;
1583f9c37a0SJoachim Eastwood 
1593f9c37a0SJoachim Eastwood 	case MR_ADDR_R_ACK:
1603f9c37a0SJoachim Eastwood 		/* Receive first byte from slave */
1613f9c37a0SJoachim Eastwood 		if (i2c->msg->len == 1) {
1623f9c37a0SJoachim Eastwood 			/* Last byte, return NACK */
1633f9c37a0SJoachim Eastwood 			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
1643f9c37a0SJoachim Eastwood 		} else {
1653f9c37a0SJoachim Eastwood 			/* Not last byte, return ACK */
1663f9c37a0SJoachim Eastwood 			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);
1673f9c37a0SJoachim Eastwood 		}
1683f9c37a0SJoachim Eastwood 
1693f9c37a0SJoachim Eastwood 		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
1703f9c37a0SJoachim Eastwood 		break;
1713f9c37a0SJoachim Eastwood 
1723f9c37a0SJoachim Eastwood 	case MR_DATA_R_NACK:
1733f9c37a0SJoachim Eastwood 		/*
1743f9c37a0SJoachim Eastwood 		 * The I2C shows NACK status on reads, so we need to accept
1753f9c37a0SJoachim Eastwood 		 * the NACK as an ACK here. This should be ok, as the real
1763f9c37a0SJoachim Eastwood 		 * BACK would of been caught on the address write.
1773f9c37a0SJoachim Eastwood 		 */
1783f9c37a0SJoachim Eastwood 	case MR_DATA_R_ACK:
1793f9c37a0SJoachim Eastwood 		/* Data was received */
1803f9c37a0SJoachim Eastwood 		if (i2c->msg_idx < i2c->msg->len) {
1813f9c37a0SJoachim Eastwood 			i2c->msg->buf[i2c->msg_idx] =
1823f9c37a0SJoachim Eastwood 					readl(i2c->base + LPC24XX_I2DAT);
1833f9c37a0SJoachim Eastwood 		}
1843f9c37a0SJoachim Eastwood 
1853f9c37a0SJoachim Eastwood 		/* If transfer is done, send STOP */
1863f9c37a0SJoachim Eastwood 		if (i2c->msg_idx >= i2c->msg->len - 1 && i2c->is_last) {
1873f9c37a0SJoachim Eastwood 			writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
1883f9c37a0SJoachim Eastwood 			writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
1893f9c37a0SJoachim Eastwood 			i2c->msg_status = 0;
1903f9c37a0SJoachim Eastwood 		}
1913f9c37a0SJoachim Eastwood 
1923f9c37a0SJoachim Eastwood 		/* Message is done */
1933f9c37a0SJoachim Eastwood 		if (i2c->msg_idx >= i2c->msg->len - 1) {
1943f9c37a0SJoachim Eastwood 			i2c->msg_status = 0;
1953f9c37a0SJoachim Eastwood 			disable_irq_nosync(i2c->irq);
1963f9c37a0SJoachim Eastwood 		}
1973f9c37a0SJoachim Eastwood 
1983f9c37a0SJoachim Eastwood 		/*
1993f9c37a0SJoachim Eastwood 		 * One pre-last data input, send NACK to tell the slave that
2003f9c37a0SJoachim Eastwood 		 * this is going to be the last data byte to be transferred.
2013f9c37a0SJoachim Eastwood 		 */
2023f9c37a0SJoachim Eastwood 		if (i2c->msg_idx >= i2c->msg->len - 2) {
2033f9c37a0SJoachim Eastwood 			/* One byte left to receive - NACK */
2043f9c37a0SJoachim Eastwood 			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
2053f9c37a0SJoachim Eastwood 		} else {
2063f9c37a0SJoachim Eastwood 			/* More than one byte left to receive - ACK */
2073f9c37a0SJoachim Eastwood 			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);
2083f9c37a0SJoachim Eastwood 		}
2093f9c37a0SJoachim Eastwood 
2103f9c37a0SJoachim Eastwood 		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
2113f9c37a0SJoachim Eastwood 		i2c->msg_idx++;
2123f9c37a0SJoachim Eastwood 		break;
2133f9c37a0SJoachim Eastwood 
2143f9c37a0SJoachim Eastwood 	case MX_ADDR_W_NACK:
2153f9c37a0SJoachim Eastwood 	case MX_DATA_W_NACK:
2163f9c37a0SJoachim Eastwood 	case MR_ADDR_R_NACK:
2173f9c37a0SJoachim Eastwood 		/* NACK processing is done */
2183f9c37a0SJoachim Eastwood 		writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
2193f9c37a0SJoachim Eastwood 		i2c->msg_status = -ENXIO;
2203f9c37a0SJoachim Eastwood 		disable_irq_nosync(i2c->irq);
2213f9c37a0SJoachim Eastwood 		break;
2223f9c37a0SJoachim Eastwood 
2233f9c37a0SJoachim Eastwood 	case M_DATA_ARB_LOST:
2243f9c37a0SJoachim Eastwood 		/* Arbitration lost */
2253f9c37a0SJoachim Eastwood 		i2c->msg_status = -EAGAIN;
2263f9c37a0SJoachim Eastwood 
2273f9c37a0SJoachim Eastwood 		/* Release the I2C bus */
2283f9c37a0SJoachim Eastwood 		writel(LPC24XX_STA | LPC24XX_STO, i2c->base + LPC24XX_I2CONCLR);
2293f9c37a0SJoachim Eastwood 		disable_irq_nosync(i2c->irq);
2303f9c37a0SJoachim Eastwood 		break;
2313f9c37a0SJoachim Eastwood 
2323f9c37a0SJoachim Eastwood 	default:
2333f9c37a0SJoachim Eastwood 		/* Unexpected statuses */
2343f9c37a0SJoachim Eastwood 		i2c->msg_status = -EIO;
2353f9c37a0SJoachim Eastwood 		disable_irq_nosync(i2c->irq);
2363f9c37a0SJoachim Eastwood 		break;
2373f9c37a0SJoachim Eastwood 	}
2383f9c37a0SJoachim Eastwood 
2393f9c37a0SJoachim Eastwood 	/* Exit on failure or all bytes transferred */
2403f9c37a0SJoachim Eastwood 	if (i2c->msg_status != -EBUSY)
2413f9c37a0SJoachim Eastwood 		wake_up(&i2c->wait);
2423f9c37a0SJoachim Eastwood 
2433f9c37a0SJoachim Eastwood 	/*
2443f9c37a0SJoachim Eastwood 	 * If `msg_status` is zero, then `lpc2k_process_msg()`
2453f9c37a0SJoachim Eastwood 	 * is responsible for clearing the SI flag.
2463f9c37a0SJoachim Eastwood 	 */
2473f9c37a0SJoachim Eastwood 	if (i2c->msg_status != 0)
2483f9c37a0SJoachim Eastwood 		writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
2493f9c37a0SJoachim Eastwood }
2503f9c37a0SJoachim Eastwood 
lpc2k_process_msg(struct lpc2k_i2c * i2c,int msgidx)2513f9c37a0SJoachim Eastwood static int lpc2k_process_msg(struct lpc2k_i2c *i2c, int msgidx)
2523f9c37a0SJoachim Eastwood {
2533f9c37a0SJoachim Eastwood 	/* A new transfer is kicked off by initiating a start condition */
2543f9c37a0SJoachim Eastwood 	if (!msgidx) {
2553f9c37a0SJoachim Eastwood 		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);
2563f9c37a0SJoachim Eastwood 	} else {
2573f9c37a0SJoachim Eastwood 		/*
2583f9c37a0SJoachim Eastwood 		 * A multi-message I2C transfer continues where the
2593f9c37a0SJoachim Eastwood 		 * previous I2C transfer left off and uses the
2603f9c37a0SJoachim Eastwood 		 * current condition of the I2C adapter.
2613f9c37a0SJoachim Eastwood 		 */
2623f9c37a0SJoachim Eastwood 		if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
2633f9c37a0SJoachim Eastwood 			WARN_ON(i2c->msg->len == 0);
2643f9c37a0SJoachim Eastwood 
2653f9c37a0SJoachim Eastwood 			if (!(i2c->msg->flags & I2C_M_RD)) {
2663f9c37a0SJoachim Eastwood 				/* Start transmit of data */
2673f9c37a0SJoachim Eastwood 				writel(i2c->msg->buf[0],
2683f9c37a0SJoachim Eastwood 				       i2c->base + LPC24XX_I2DAT);
2693f9c37a0SJoachim Eastwood 				i2c->msg_idx++;
2703f9c37a0SJoachim Eastwood 			}
2713f9c37a0SJoachim Eastwood 		} else {
2723f9c37a0SJoachim Eastwood 			/* Start or repeated start */
2733f9c37a0SJoachim Eastwood 			writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);
2743f9c37a0SJoachim Eastwood 		}
2753f9c37a0SJoachim Eastwood 
2763f9c37a0SJoachim Eastwood 		writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
2773f9c37a0SJoachim Eastwood 	}
2783f9c37a0SJoachim Eastwood 
2793f9c37a0SJoachim Eastwood 	enable_irq(i2c->irq);
2803f9c37a0SJoachim Eastwood 
2813f9c37a0SJoachim Eastwood 	/* Wait for transfer completion */
2823f9c37a0SJoachim Eastwood 	if (wait_event_timeout(i2c->wait, i2c->msg_status != -EBUSY,
2833f9c37a0SJoachim Eastwood 			       msecs_to_jiffies(1000)) == 0) {
2843f9c37a0SJoachim Eastwood 		disable_irq_nosync(i2c->irq);
2853f9c37a0SJoachim Eastwood 
2863f9c37a0SJoachim Eastwood 		return -ETIMEDOUT;
2873f9c37a0SJoachim Eastwood 	}
2883f9c37a0SJoachim Eastwood 
2893f9c37a0SJoachim Eastwood 	return i2c->msg_status;
2903f9c37a0SJoachim Eastwood }
2913f9c37a0SJoachim Eastwood 
i2c_lpc2k_xfer(struct i2c_adapter * adap,struct i2c_msg * msgs,int msg_num)2923f9c37a0SJoachim Eastwood static int i2c_lpc2k_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
2933f9c37a0SJoachim Eastwood 			  int msg_num)
2943f9c37a0SJoachim Eastwood {
2953f9c37a0SJoachim Eastwood 	struct lpc2k_i2c *i2c = i2c_get_adapdata(adap);
2963f9c37a0SJoachim Eastwood 	int ret, i;
2973f9c37a0SJoachim Eastwood 	u32 stat;
2983f9c37a0SJoachim Eastwood 
2993f9c37a0SJoachim Eastwood 	/* Check for bus idle condition */
3003f9c37a0SJoachim Eastwood 	stat = readl(i2c->base + LPC24XX_I2STAT);
3013f9c37a0SJoachim Eastwood 	if (stat != M_I2C_IDLE) {
3023f9c37a0SJoachim Eastwood 		/* Something is holding the bus, try to clear it */
3033f9c37a0SJoachim Eastwood 		return i2c_lpc2k_clear_arb(i2c);
3043f9c37a0SJoachim Eastwood 	}
3053f9c37a0SJoachim Eastwood 
3063f9c37a0SJoachim Eastwood 	/* Process a single message at a time */
3073f9c37a0SJoachim Eastwood 	for (i = 0; i < msg_num; i++) {
3083f9c37a0SJoachim Eastwood 		/* Save message pointer and current message data index */
3093f9c37a0SJoachim Eastwood 		i2c->msg = &msgs[i];
3103f9c37a0SJoachim Eastwood 		i2c->msg_idx = 0;
3113f9c37a0SJoachim Eastwood 		i2c->msg_status = -EBUSY;
3123f9c37a0SJoachim Eastwood 		i2c->is_last = (i == (msg_num - 1));
3133f9c37a0SJoachim Eastwood 
3143f9c37a0SJoachim Eastwood 		ret = lpc2k_process_msg(i2c, i);
3153f9c37a0SJoachim Eastwood 		if (ret)
3163f9c37a0SJoachim Eastwood 			return ret;
3173f9c37a0SJoachim Eastwood 	}
3183f9c37a0SJoachim Eastwood 
3193f9c37a0SJoachim Eastwood 	return msg_num;
3203f9c37a0SJoachim Eastwood }
3213f9c37a0SJoachim Eastwood 
i2c_lpc2k_handler(int irq,void * dev_id)3223f9c37a0SJoachim Eastwood static irqreturn_t i2c_lpc2k_handler(int irq, void *dev_id)
3233f9c37a0SJoachim Eastwood {
3243f9c37a0SJoachim Eastwood 	struct lpc2k_i2c *i2c = dev_id;
3253f9c37a0SJoachim Eastwood 
3263f9c37a0SJoachim Eastwood 	if (readl(i2c->base + LPC24XX_I2CONSET) & LPC24XX_SI) {
3273f9c37a0SJoachim Eastwood 		i2c_lpc2k_pump_msg(i2c);
3283f9c37a0SJoachim Eastwood 		return IRQ_HANDLED;
3293f9c37a0SJoachim Eastwood 	}
3303f9c37a0SJoachim Eastwood 
3313f9c37a0SJoachim Eastwood 	return IRQ_NONE;
3323f9c37a0SJoachim Eastwood }
3333f9c37a0SJoachim Eastwood 
i2c_lpc2k_functionality(struct i2c_adapter * adap)3343f9c37a0SJoachim Eastwood static u32 i2c_lpc2k_functionality(struct i2c_adapter *adap)
3353f9c37a0SJoachim Eastwood {
3363f9c37a0SJoachim Eastwood 	/* Only emulated SMBus for now */
3373f9c37a0SJoachim Eastwood 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
3383f9c37a0SJoachim Eastwood }
3393f9c37a0SJoachim Eastwood 
3403f9c37a0SJoachim Eastwood static const struct i2c_algorithm i2c_lpc2k_algorithm = {
3413f9c37a0SJoachim Eastwood 	.master_xfer	= i2c_lpc2k_xfer,
3423f9c37a0SJoachim Eastwood 	.functionality	= i2c_lpc2k_functionality,
3433f9c37a0SJoachim Eastwood };
3443f9c37a0SJoachim Eastwood 
i2c_lpc2k_probe(struct platform_device * pdev)3453f9c37a0SJoachim Eastwood static int i2c_lpc2k_probe(struct platform_device *pdev)
3463f9c37a0SJoachim Eastwood {
3473f9c37a0SJoachim Eastwood 	struct lpc2k_i2c *i2c;
3483f9c37a0SJoachim Eastwood 	u32 bus_clk_rate;
3493f9c37a0SJoachim Eastwood 	u32 scl_high;
3503f9c37a0SJoachim Eastwood 	u32 clkrate;
3513f9c37a0SJoachim Eastwood 	int ret;
3523f9c37a0SJoachim Eastwood 
3533f9c37a0SJoachim Eastwood 	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
3543f9c37a0SJoachim Eastwood 	if (!i2c)
3553f9c37a0SJoachim Eastwood 		return -ENOMEM;
3563f9c37a0SJoachim Eastwood 
357e0442d76SDejin Zheng 	i2c->base = devm_platform_ioremap_resource(pdev, 0);
3583f9c37a0SJoachim Eastwood 	if (IS_ERR(i2c->base))
3593f9c37a0SJoachim Eastwood 		return PTR_ERR(i2c->base);
3603f9c37a0SJoachim Eastwood 
3613f9c37a0SJoachim Eastwood 	i2c->irq = platform_get_irq(pdev, 0);
362e42688edSDejin Zheng 	if (i2c->irq < 0)
3633f9c37a0SJoachim Eastwood 		return i2c->irq;
3643f9c37a0SJoachim Eastwood 
3653f9c37a0SJoachim Eastwood 	init_waitqueue_head(&i2c->wait);
3663f9c37a0SJoachim Eastwood 
3679d8b7b61SAndi Shyti 	i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);
3683f9c37a0SJoachim Eastwood 	if (IS_ERR(i2c->clk)) {
3699d8b7b61SAndi Shyti 		dev_err(&pdev->dev, "failed to enable clock.\n");
3703f9c37a0SJoachim Eastwood 		return PTR_ERR(i2c->clk);
3713f9c37a0SJoachim Eastwood 	}
3723f9c37a0SJoachim Eastwood 
3733f9c37a0SJoachim Eastwood 	ret = devm_request_irq(&pdev->dev, i2c->irq, i2c_lpc2k_handler, 0,
3743f9c37a0SJoachim Eastwood 			       dev_name(&pdev->dev), i2c);
3753f9c37a0SJoachim Eastwood 	if (ret < 0) {
3763f9c37a0SJoachim Eastwood 		dev_err(&pdev->dev, "can't request interrupt.\n");
3779d8b7b61SAndi Shyti 		return ret;
3783f9c37a0SJoachim Eastwood 	}
3793f9c37a0SJoachim Eastwood 
3803f9c37a0SJoachim Eastwood 	disable_irq_nosync(i2c->irq);
3813f9c37a0SJoachim Eastwood 
3823f9c37a0SJoachim Eastwood 	/* Place controller is a known state */
3833f9c37a0SJoachim Eastwood 	i2c_lpc2k_reset(i2c);
3843f9c37a0SJoachim Eastwood 
3853f9c37a0SJoachim Eastwood 	ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
3863f9c37a0SJoachim Eastwood 				   &bus_clk_rate);
3873f9c37a0SJoachim Eastwood 	if (ret)
38890224e64SAndy Shevchenko 		bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ;
3893f9c37a0SJoachim Eastwood 
3903f9c37a0SJoachim Eastwood 	clkrate = clk_get_rate(i2c->clk);
3913f9c37a0SJoachim Eastwood 	if (clkrate == 0) {
3923f9c37a0SJoachim Eastwood 		dev_err(&pdev->dev, "can't get I2C base clock\n");
3939d8b7b61SAndi Shyti 		return -EINVAL;
3943f9c37a0SJoachim Eastwood 	}
3953f9c37a0SJoachim Eastwood 
3963f9c37a0SJoachim Eastwood 	/* Setup I2C dividers to generate clock with proper duty cycle */
3973f9c37a0SJoachim Eastwood 	clkrate = clkrate / bus_clk_rate;
39890224e64SAndy Shevchenko 	if (bus_clk_rate <= I2C_MAX_STANDARD_MODE_FREQ)
3993f9c37a0SJoachim Eastwood 		scl_high = (clkrate * I2C_STD_MODE_DUTY) / 100;
40090224e64SAndy Shevchenko 	else if (bus_clk_rate <= I2C_MAX_FAST_MODE_FREQ)
4013f9c37a0SJoachim Eastwood 		scl_high = (clkrate * I2C_FAST_MODE_DUTY) / 100;
4023f9c37a0SJoachim Eastwood 	else
4033f9c37a0SJoachim Eastwood 		scl_high = (clkrate * I2C_FAST_MODE_PLUS_DUTY) / 100;
4043f9c37a0SJoachim Eastwood 
4053f9c37a0SJoachim Eastwood 	writel(scl_high, i2c->base + LPC24XX_I2SCLH);
4063f9c37a0SJoachim Eastwood 	writel(clkrate - scl_high, i2c->base + LPC24XX_I2SCLL);
4073f9c37a0SJoachim Eastwood 
4083f9c37a0SJoachim Eastwood 	platform_set_drvdata(pdev, i2c);
4093f9c37a0SJoachim Eastwood 
4103f9c37a0SJoachim Eastwood 	i2c_set_adapdata(&i2c->adap, i2c);
4113f9c37a0SJoachim Eastwood 	i2c->adap.owner = THIS_MODULE;
412ea1558ceSWolfram Sang 	strscpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name));
4133f9c37a0SJoachim Eastwood 	i2c->adap.algo = &i2c_lpc2k_algorithm;
4143f9c37a0SJoachim Eastwood 	i2c->adap.dev.parent = &pdev->dev;
4153f9c37a0SJoachim Eastwood 	i2c->adap.dev.of_node = pdev->dev.of_node;
4163f9c37a0SJoachim Eastwood 
4173f9c37a0SJoachim Eastwood 	ret = i2c_add_adapter(&i2c->adap);
418ea734404SWolfram Sang 	if (ret < 0)
4199d8b7b61SAndi Shyti 		return ret;
4203f9c37a0SJoachim Eastwood 
4213f9c37a0SJoachim Eastwood 	dev_info(&pdev->dev, "LPC2K I2C adapter\n");
4223f9c37a0SJoachim Eastwood 
4233f9c37a0SJoachim Eastwood 	return 0;
4243f9c37a0SJoachim Eastwood }
4253f9c37a0SJoachim Eastwood 
i2c_lpc2k_remove(struct platform_device * dev)426e190a0c3SUwe Kleine-König static void i2c_lpc2k_remove(struct platform_device *dev)
4273f9c37a0SJoachim Eastwood {
4283f9c37a0SJoachim Eastwood 	struct lpc2k_i2c *i2c = platform_get_drvdata(dev);
4293f9c37a0SJoachim Eastwood 
4303f9c37a0SJoachim Eastwood 	i2c_del_adapter(&i2c->adap);
4313f9c37a0SJoachim Eastwood }
4323f9c37a0SJoachim Eastwood 
i2c_lpc2k_suspend(struct device * dev)4333f9c37a0SJoachim Eastwood static int i2c_lpc2k_suspend(struct device *dev)
4343f9c37a0SJoachim Eastwood {
4359242e72aSMasahiro Yamada 	struct lpc2k_i2c *i2c = dev_get_drvdata(dev);
4363f9c37a0SJoachim Eastwood 
4373f9c37a0SJoachim Eastwood 	clk_disable(i2c->clk);
4383f9c37a0SJoachim Eastwood 
4393f9c37a0SJoachim Eastwood 	return 0;
4403f9c37a0SJoachim Eastwood }
4413f9c37a0SJoachim Eastwood 
i2c_lpc2k_resume(struct device * dev)4423f9c37a0SJoachim Eastwood static int i2c_lpc2k_resume(struct device *dev)
4433f9c37a0SJoachim Eastwood {
4449242e72aSMasahiro Yamada 	struct lpc2k_i2c *i2c = dev_get_drvdata(dev);
4453f9c37a0SJoachim Eastwood 
4463f9c37a0SJoachim Eastwood 	clk_enable(i2c->clk);
4473f9c37a0SJoachim Eastwood 	i2c_lpc2k_reset(i2c);
4483f9c37a0SJoachim Eastwood 
4493f9c37a0SJoachim Eastwood 	return 0;
4503f9c37a0SJoachim Eastwood }
4513f9c37a0SJoachim Eastwood 
4523f9c37a0SJoachim Eastwood static const struct dev_pm_ops i2c_lpc2k_dev_pm_ops = {
4533f9c37a0SJoachim Eastwood 	.suspend_noirq = i2c_lpc2k_suspend,
4543f9c37a0SJoachim Eastwood 	.resume_noirq = i2c_lpc2k_resume,
4553f9c37a0SJoachim Eastwood };
4563f9c37a0SJoachim Eastwood 
4573f9c37a0SJoachim Eastwood static const struct of_device_id lpc2k_i2c_match[] = {
4583f9c37a0SJoachim Eastwood 	{ .compatible = "nxp,lpc1788-i2c" },
4593f9c37a0SJoachim Eastwood 	{},
4603f9c37a0SJoachim Eastwood };
4613f9c37a0SJoachim Eastwood MODULE_DEVICE_TABLE(of, lpc2k_i2c_match);
4623f9c37a0SJoachim Eastwood 
4633f9c37a0SJoachim Eastwood static struct platform_driver i2c_lpc2k_driver = {
4643f9c37a0SJoachim Eastwood 	.probe	= i2c_lpc2k_probe,
465e190a0c3SUwe Kleine-König 	.remove_new = i2c_lpc2k_remove,
4663f9c37a0SJoachim Eastwood 	.driver	= {
4673f9c37a0SJoachim Eastwood 		.name		= "lpc2k-i2c",
468*9f38edafSPaul Cercueil 		.pm		= pm_sleep_ptr(&i2c_lpc2k_dev_pm_ops),
4693f9c37a0SJoachim Eastwood 		.of_match_table	= lpc2k_i2c_match,
4703f9c37a0SJoachim Eastwood 	},
4713f9c37a0SJoachim Eastwood };
4723f9c37a0SJoachim Eastwood module_platform_driver(i2c_lpc2k_driver);
4733f9c37a0SJoachim Eastwood 
4743f9c37a0SJoachim Eastwood MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
4753f9c37a0SJoachim Eastwood MODULE_DESCRIPTION("I2C driver for LPC2xxx devices");
4763f9c37a0SJoachim Eastwood MODULE_LICENSE("GPL");
4773f9c37a0SJoachim Eastwood MODULE_ALIAS("platform:lpc2k-i2c");
478