brintos

brintos / linux-shallow public Read only

0
0
Text · 11.6 KiB · 9fb33cb Raw
478 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2011 NXP Semiconductors4 *5 * Code portions referenced from the i2x-pxa and i2c-pnx drivers6 *7 * Make SMBus byte and word transactions work on LPC178x/7x8 * Copyright (c) 20129 * Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com10 * Anton Protopopov, Emcraft Systems, antonp@emcraft.com11 *12 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>13 */14 15#include <linux/clk.h>16#include <linux/errno.h>17#include <linux/i2c.h>18#include <linux/interrupt.h>19#include <linux/io.h>20#include <linux/kernel.h>21#include <linux/module.h>22#include <linux/of.h>23#include <linux/platform_device.h>24#include <linux/sched.h>25#include <linux/time.h>26 27/* LPC24xx register offsets and bits */28#define LPC24XX_I2CONSET	0x0029#define LPC24XX_I2STAT		0x0430#define LPC24XX_I2DAT		0x0831#define LPC24XX_I2ADDR		0x0c32#define LPC24XX_I2SCLH		0x1033#define LPC24XX_I2SCLL		0x1434#define LPC24XX_I2CONCLR	0x1835 36#define LPC24XX_AA		BIT(2)37#define LPC24XX_SI		BIT(3)38#define LPC24XX_STO		BIT(4)39#define LPC24XX_STA		BIT(5)40#define LPC24XX_I2EN		BIT(6)41 42#define LPC24XX_STO_AA		(LPC24XX_STO | LPC24XX_AA)43#define LPC24XX_CLEAR_ALL	(LPC24XX_AA | LPC24XX_SI | LPC24XX_STO | \44				 LPC24XX_STA | LPC24XX_I2EN)45 46/* I2C SCL clock has different duty cycle depending on mode */47#define I2C_STD_MODE_DUTY		4648#define I2C_FAST_MODE_DUTY		3649#define I2C_FAST_MODE_PLUS_DUTY		3850 51/*52 * 26 possible I2C status codes, but codes applicable only53 * to controller mode are listed here and used in this driver54 */55enum {56	M_BUS_ERROR		= 0x00,57	M_START			= 0x08,58	M_REPSTART		= 0x10,59	MX_ADDR_W_ACK		= 0x18,60	MX_ADDR_W_NACK		= 0x20,61	MX_DATA_W_ACK		= 0x28,62	MX_DATA_W_NACK		= 0x30,63	M_DATA_ARB_LOST		= 0x38,64	MR_ADDR_R_ACK		= 0x40,65	MR_ADDR_R_NACK		= 0x48,66	MR_DATA_R_ACK		= 0x50,67	MR_DATA_R_NACK		= 0x58,68	M_I2C_IDLE		= 0xf8,69};70 71struct lpc2k_i2c {72	void __iomem		*base;73	struct clk		*clk;74	int			irq;75	wait_queue_head_t	wait;76	struct i2c_adapter	adap;77	struct i2c_msg		*msg;78	int			msg_idx;79	int			msg_status;80	int			is_last;81};82 83static void i2c_lpc2k_reset(struct lpc2k_i2c *i2c)84{85	/* Will force clear all statuses */86	writel(LPC24XX_CLEAR_ALL, i2c->base + LPC24XX_I2CONCLR);87	writel(0, i2c->base + LPC24XX_I2ADDR);88	writel(LPC24XX_I2EN, i2c->base + LPC24XX_I2CONSET);89}90 91static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c)92{93	unsigned long timeout = jiffies + msecs_to_jiffies(1000);94 95	/*96	 * If the transfer needs to abort for some reason, we'll try to97	 * force a stop condition to clear any pending bus conditions98	 */99	writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET);100 101	/* Wait for status change */102	while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) {103		if (time_after(jiffies, timeout)) {104			/* Bus was not idle, try to reset adapter */105			i2c_lpc2k_reset(i2c);106			return -EBUSY;107		}108 109		cpu_relax();110	}111 112	return 0;113}114 115static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)116{117	unsigned char data;118	u32 status;119 120	/*121	 * I2C in the LPC2xxx series is basically a state machine.122	 * Just run through the steps based on the current status.123	 */124	status = readl(i2c->base + LPC24XX_I2STAT);125 126	switch (status) {127	case M_START:128	case M_REPSTART:129		/* Start bit was just sent out, send out addr and dir */130		data = i2c_8bit_addr_from_msg(i2c->msg);131 132		writel(data, i2c->base + LPC24XX_I2DAT);133		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);134		break;135 136	case MX_ADDR_W_ACK:137	case MX_DATA_W_ACK:138		/*139		 * Address or data was sent out with an ACK. If there is more140		 * data to send, send it now141		 */142		if (i2c->msg_idx < i2c->msg->len) {143			writel(i2c->msg->buf[i2c->msg_idx],144			       i2c->base + LPC24XX_I2DAT);145		} else if (i2c->is_last) {146			/* Last message, send stop */147			writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);148			writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);149			i2c->msg_status = 0;150			disable_irq_nosync(i2c->irq);151		} else {152			i2c->msg_status = 0;153			disable_irq_nosync(i2c->irq);154		}155 156		i2c->msg_idx++;157		break;158 159	case MR_ADDR_R_ACK:160		/* Receive first byte from target */161		if (i2c->msg->len == 1) {162			/* Last byte, return NACK */163			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);164		} else {165			/* Not last byte, return ACK */166			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);167		}168 169		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);170		break;171 172	case MR_DATA_R_NACK:173		/*174		 * The I2C shows NACK status on reads, so we need to accept175		 * the NACK as an ACK here. This should be ok, as the real176		 * BACK would of been caught on the address write.177		 */178	case MR_DATA_R_ACK:179		/* Data was received */180		if (i2c->msg_idx < i2c->msg->len) {181			i2c->msg->buf[i2c->msg_idx] =182					readl(i2c->base + LPC24XX_I2DAT);183		}184 185		/* If transfer is done, send STOP */186		if (i2c->msg_idx >= i2c->msg->len - 1 && i2c->is_last) {187			writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);188			writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);189			i2c->msg_status = 0;190		}191 192		/* Message is done */193		if (i2c->msg_idx >= i2c->msg->len - 1) {194			i2c->msg_status = 0;195			disable_irq_nosync(i2c->irq);196		}197 198		/*199		 * One pre-last data input, send NACK to tell the target that200		 * this is going to be the last data byte to be transferred.201		 */202		if (i2c->msg_idx >= i2c->msg->len - 2) {203			/* One byte left to receive - NACK */204			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);205		} else {206			/* More than one byte left to receive - ACK */207			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);208		}209 210		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);211		i2c->msg_idx++;212		break;213 214	case MX_ADDR_W_NACK:215	case MX_DATA_W_NACK:216	case MR_ADDR_R_NACK:217		/* NACK processing is done */218		writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);219		i2c->msg_status = -ENXIO;220		disable_irq_nosync(i2c->irq);221		break;222 223	case M_DATA_ARB_LOST:224		/* Arbitration lost */225		i2c->msg_status = -EAGAIN;226 227		/* Release the I2C bus */228		writel(LPC24XX_STA | LPC24XX_STO, i2c->base + LPC24XX_I2CONCLR);229		disable_irq_nosync(i2c->irq);230		break;231 232	default:233		/* Unexpected statuses */234		i2c->msg_status = -EIO;235		disable_irq_nosync(i2c->irq);236		break;237	}238 239	/* Exit on failure or all bytes transferred */240	if (i2c->msg_status != -EBUSY)241		wake_up(&i2c->wait);242 243	/*244	 * If `msg_status` is zero, then `lpc2k_process_msg()`245	 * is responsible for clearing the SI flag.246	 */247	if (i2c->msg_status != 0)248		writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);249}250 251static int lpc2k_process_msg(struct lpc2k_i2c *i2c, int msgidx)252{253	/* A new transfer is kicked off by initiating a start condition */254	if (!msgidx) {255		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);256	} else {257		/*258		 * A multi-message I2C transfer continues where the259		 * previous I2C transfer left off and uses the260		 * current condition of the I2C adapter.261		 */262		if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {263			WARN_ON(i2c->msg->len == 0);264 265			if (!(i2c->msg->flags & I2C_M_RD)) {266				/* Start transmit of data */267				writel(i2c->msg->buf[0],268				       i2c->base + LPC24XX_I2DAT);269				i2c->msg_idx++;270			}271		} else {272			/* Start or repeated start */273			writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);274		}275 276		writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);277	}278 279	enable_irq(i2c->irq);280 281	/* Wait for transfer completion */282	if (wait_event_timeout(i2c->wait, i2c->msg_status != -EBUSY,283			       msecs_to_jiffies(1000)) == 0) {284		disable_irq_nosync(i2c->irq);285 286		return -ETIMEDOUT;287	}288 289	return i2c->msg_status;290}291 292static int i2c_lpc2k_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,293			  int msg_num)294{295	struct lpc2k_i2c *i2c = i2c_get_adapdata(adap);296	int ret, i;297	u32 stat;298 299	/* Check for bus idle condition */300	stat = readl(i2c->base + LPC24XX_I2STAT);301	if (stat != M_I2C_IDLE) {302		/* Something is holding the bus, try to clear it */303		return i2c_lpc2k_clear_arb(i2c);304	}305 306	/* Process a single message at a time */307	for (i = 0; i < msg_num; i++) {308		/* Save message pointer and current message data index */309		i2c->msg = &msgs[i];310		i2c->msg_idx = 0;311		i2c->msg_status = -EBUSY;312		i2c->is_last = (i == (msg_num - 1));313 314		ret = lpc2k_process_msg(i2c, i);315		if (ret)316			return ret;317	}318 319	return msg_num;320}321 322static irqreturn_t i2c_lpc2k_handler(int irq, void *dev_id)323{324	struct lpc2k_i2c *i2c = dev_id;325 326	if (readl(i2c->base + LPC24XX_I2CONSET) & LPC24XX_SI) {327		i2c_lpc2k_pump_msg(i2c);328		return IRQ_HANDLED;329	}330 331	return IRQ_NONE;332}333 334static u32 i2c_lpc2k_functionality(struct i2c_adapter *adap)335{336	/* Only emulated SMBus for now */337	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;338}339 340static const struct i2c_algorithm i2c_lpc2k_algorithm = {341	.xfer = i2c_lpc2k_xfer,342	.functionality = i2c_lpc2k_functionality,343};344 345static int i2c_lpc2k_probe(struct platform_device *pdev)346{347	struct lpc2k_i2c *i2c;348	u32 bus_clk_rate;349	u32 scl_high;350	u32 clkrate;351	int ret;352 353	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);354	if (!i2c)355		return -ENOMEM;356 357	i2c->base = devm_platform_ioremap_resource(pdev, 0);358	if (IS_ERR(i2c->base))359		return PTR_ERR(i2c->base);360 361	i2c->irq = platform_get_irq(pdev, 0);362	if (i2c->irq < 0)363		return i2c->irq;364 365	init_waitqueue_head(&i2c->wait);366 367	i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);368	if (IS_ERR(i2c->clk)) {369		dev_err(&pdev->dev, "failed to enable clock.\n");370		return PTR_ERR(i2c->clk);371	}372 373	ret = devm_request_irq(&pdev->dev, i2c->irq, i2c_lpc2k_handler, 0,374			       dev_name(&pdev->dev), i2c);375	if (ret < 0) {376		dev_err(&pdev->dev, "can't request interrupt.\n");377		return ret;378	}379 380	disable_irq_nosync(i2c->irq);381 382	/* Place controller is a known state */383	i2c_lpc2k_reset(i2c);384 385	ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",386				   &bus_clk_rate);387	if (ret)388		bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ;389 390	clkrate = clk_get_rate(i2c->clk);391	if (clkrate == 0) {392		dev_err(&pdev->dev, "can't get I2C base clock\n");393		return -EINVAL;394	}395 396	/* Setup I2C dividers to generate clock with proper duty cycle */397	clkrate = clkrate / bus_clk_rate;398	if (bus_clk_rate <= I2C_MAX_STANDARD_MODE_FREQ)399		scl_high = (clkrate * I2C_STD_MODE_DUTY) / 100;400	else if (bus_clk_rate <= I2C_MAX_FAST_MODE_FREQ)401		scl_high = (clkrate * I2C_FAST_MODE_DUTY) / 100;402	else403		scl_high = (clkrate * I2C_FAST_MODE_PLUS_DUTY) / 100;404 405	writel(scl_high, i2c->base + LPC24XX_I2SCLH);406	writel(clkrate - scl_high, i2c->base + LPC24XX_I2SCLL);407 408	platform_set_drvdata(pdev, i2c);409 410	i2c_set_adapdata(&i2c->adap, i2c);411	i2c->adap.owner = THIS_MODULE;412	strscpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name));413	i2c->adap.algo = &i2c_lpc2k_algorithm;414	i2c->adap.dev.parent = &pdev->dev;415	i2c->adap.dev.of_node = pdev->dev.of_node;416 417	ret = i2c_add_adapter(&i2c->adap);418	if (ret < 0)419		return ret;420 421	dev_info(&pdev->dev, "LPC2K I2C adapter\n");422 423	return 0;424}425 426static void i2c_lpc2k_remove(struct platform_device *dev)427{428	struct lpc2k_i2c *i2c = platform_get_drvdata(dev);429 430	i2c_del_adapter(&i2c->adap);431}432 433static int i2c_lpc2k_suspend(struct device *dev)434{435	struct lpc2k_i2c *i2c = dev_get_drvdata(dev);436 437	clk_disable(i2c->clk);438 439	return 0;440}441 442static int i2c_lpc2k_resume(struct device *dev)443{444	struct lpc2k_i2c *i2c = dev_get_drvdata(dev);445 446	clk_enable(i2c->clk);447	i2c_lpc2k_reset(i2c);448 449	return 0;450}451 452static const struct dev_pm_ops i2c_lpc2k_dev_pm_ops = {453	.suspend_noirq = i2c_lpc2k_suspend,454	.resume_noirq = i2c_lpc2k_resume,455};456 457static const struct of_device_id lpc2k_i2c_match[] = {458	{ .compatible = "nxp,lpc1788-i2c" },459	{},460};461MODULE_DEVICE_TABLE(of, lpc2k_i2c_match);462 463static struct platform_driver i2c_lpc2k_driver = {464	.probe	= i2c_lpc2k_probe,465	.remove_new = i2c_lpc2k_remove,466	.driver	= {467		.name		= "lpc2k-i2c",468		.pm		= pm_sleep_ptr(&i2c_lpc2k_dev_pm_ops),469		.of_match_table	= lpc2k_i2c_match,470	},471};472module_platform_driver(i2c_lpc2k_driver);473 474MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");475MODULE_DESCRIPTION("I2C driver for LPC2xxx devices");476MODULE_LICENSE("GPL");477MODULE_ALIAS("platform:lpc2k-i2c");478