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