File Index
Files and directories
Sign in
FILE

i2c-mt7621.c

File preview with syntax highlighting.

linux-6.19.14/drivers/i2c/busses/i2c-mt7621.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * drivers/i2c/busses/i2c-mt7621.c
  4 *
  5 * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
  6 * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
  7 * Copyright (C) 2018 Jan Breuer <jan.breuer@jaybee.cz>
  8 *
  9 * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
 10 * (C) 2014 Sittisak <sittisaks@hotmail.com>
 11 */
 12
 13#include <linux/clk.h>
 14#include <linux/delay.h>
 15#include <linux/i2c.h>
 16#include <linux/io.h>
 17#include <linux/iopoll.h>
 18#include <linux/module.h>
 19#include <linux/of.h>
 20#include <linux/platform_device.h>
 21#include <linux/reset.h>
 22
 23#define REG_SM0CFG2_REG		0x28
 24#define REG_SM0CTL0_REG		0x40
 25#define REG_SM0CTL1_REG		0x44
 26#define REG_SM0D0_REG		0x50
 27#define REG_SM0D1_REG		0x54
 28#define REG_PINTEN_REG		0x5c
 29#define REG_PINTST_REG		0x60
 30#define REG_PINTCL_REG		0x64
 31
 32/* REG_SM0CFG2_REG */
 33#define SM0CFG2_IS_AUTOMODE	BIT(0)
 34
 35/* REG_SM0CTL0_REG */
 36#define SM0CTL0_ODRAIN		BIT(31)
 37#define SM0CTL0_CLK_DIV_MASK	(0x7ff << 16)
 38#define SM0CTL0_CLK_DIV_MAX	0x7ff
 39#define SM0CTL0_CS_STATUS       BIT(4)
 40#define SM0CTL0_SCL_STATE       BIT(3)
 41#define SM0CTL0_SDA_STATE       BIT(2)
 42#define SM0CTL0_EN              BIT(1)
 43#define SM0CTL0_SCL_STRETCH     BIT(0)
 44
 45/* REG_SM0CTL1_REG */
 46#define SM0CTL1_ACK_MASK	(0xff << 16)
 47#define SM0CTL1_PGLEN_MASK	(0x7 << 8)
 48#define SM0CTL1_PGLEN(x)	((((x) - 1) << 8) & SM0CTL1_PGLEN_MASK)
 49#define SM0CTL1_READ		(5 << 4)
 50#define SM0CTL1_READ_LAST	(4 << 4)
 51#define SM0CTL1_STOP		(3 << 4)
 52#define SM0CTL1_WRITE		(2 << 4)
 53#define SM0CTL1_START		(1 << 4)
 54#define SM0CTL1_MODE_MASK	(0x7 << 4)
 55#define SM0CTL1_TRI		BIT(0)
 56
 57/* timeout waiting for I2C devices to respond */
 58#define TIMEOUT_MS		1000
 59
 60struct mtk_i2c {
 61	void __iomem *base;
 62	struct device *dev;
 63	struct i2c_adapter adap;
 64	u32 bus_freq;
 65	u32 clk_div;
 66	u32 flags;
 67	struct clk *clk;
 68};
 69
 70static int mtk_i2c_wait_idle(struct mtk_i2c *i2c)
 71{
 72	int ret;
 73	u32 val;
 74
 75	ret = readl_relaxed_poll_timeout(i2c->base + REG_SM0CTL1_REG,
 76					 val, !(val & SM0CTL1_TRI),
 77					 10, TIMEOUT_MS * 1000);
 78	if (ret)
 79		dev_dbg(i2c->dev, "idle err(%d)\n", ret);
 80
 81	return ret;
 82}
 83
 84static void mtk_i2c_reset(struct mtk_i2c *i2c)
 85{
 86	int ret;
 87
 88	ret = device_reset(i2c->adap.dev.parent);
 89	if (ret)
 90		dev_err(i2c->dev, "I2C reset failed!\n");
 91
 92	/*
 93	 * Don't set SM0CTL0_ODRAIN as its bit meaning is inverted. To
 94	 * configure open-drain mode, this bit needs to be cleared.
 95	 */
 96	iowrite32(((i2c->clk_div << 16) & SM0CTL0_CLK_DIV_MASK) | SM0CTL0_EN |
 97		  SM0CTL0_SCL_STRETCH, i2c->base + REG_SM0CTL0_REG);
 98	iowrite32(0, i2c->base + REG_SM0CFG2_REG);
 99}
100
101static void mtk_i2c_dump_reg(struct mtk_i2c *i2c)
102{
103	dev_dbg(i2c->dev,
104		"SM0CFG2 %08x, SM0CTL0 %08x, SM0CTL1 %08x, SM0D0 %08x, SM0D1 %08x\n",
105		ioread32(i2c->base + REG_SM0CFG2_REG),
106		ioread32(i2c->base + REG_SM0CTL0_REG),
107		ioread32(i2c->base + REG_SM0CTL1_REG),
108		ioread32(i2c->base + REG_SM0D0_REG),
109		ioread32(i2c->base + REG_SM0D1_REG));
110}
111
112static int mtk_i2c_check_ack(struct mtk_i2c *i2c, u32 expected)
113{
114	u32 ack = readl_relaxed(i2c->base + REG_SM0CTL1_REG);
115	u32 ack_expected = (expected << 16) & SM0CTL1_ACK_MASK;
116
117	return ((ack & ack_expected) == ack_expected) ? 0 : -ENXIO;
118}
119
120static int mtk_i2c_start(struct mtk_i2c *i2c)
121{
122	iowrite32(SM0CTL1_START | SM0CTL1_TRI, i2c->base + REG_SM0CTL1_REG);
123	return mtk_i2c_wait_idle(i2c);
124}
125
126static int mtk_i2c_stop(struct mtk_i2c *i2c)
127{
128	iowrite32(SM0CTL1_STOP | SM0CTL1_TRI, i2c->base + REG_SM0CTL1_REG);
129	return mtk_i2c_wait_idle(i2c);
130}
131
132static int mtk_i2c_cmd(struct mtk_i2c *i2c, u32 cmd, int page_len)
133{
134	iowrite32(cmd | SM0CTL1_TRI | SM0CTL1_PGLEN(page_len),
135		  i2c->base + REG_SM0CTL1_REG);
136	return mtk_i2c_wait_idle(i2c);
137}
138
139static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
140			int num)
141{
142	struct mtk_i2c *i2c;
143	struct i2c_msg *pmsg;
144	u16 addr;
145	int i, j, ret, len, page_len;
146	u32 cmd;
147	u32 data[2];
148
149	i2c = i2c_get_adapdata(adap);
150
151	for (i = 0; i < num; i++) {
152		pmsg = &msgs[i];
153
154		/* wait hardware idle */
155		ret = mtk_i2c_wait_idle(i2c);
156		if (ret)
157			goto err_timeout;
158
159		/* start sequence */
160		ret = mtk_i2c_start(i2c);
161		if (ret)
162			goto err_timeout;
163
164		/* write address */
165		if (pmsg->flags & I2C_M_TEN) {
166			/* 10 bits address */
167			addr = i2c_10bit_addr_hi_from_msg(pmsg);
168			addr |= i2c_10bit_addr_lo_from_msg(pmsg) << 8;
169			len = 2;
170		} else {
171			/* 7 bits address */
172			addr = i2c_8bit_addr_from_msg(pmsg);
173			len = 1;
174		}
175		iowrite32(addr, i2c->base + REG_SM0D0_REG);
176		ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, len);
177		if (ret)
178			goto err_timeout;
179
180		/* check address ACK */
181		if (!(pmsg->flags & I2C_M_IGNORE_NAK)) {
182			ret = mtk_i2c_check_ack(i2c, BIT(0));
183			if (ret)
184				goto err_ack;
185		}
186
187		/* transfer data */
188		for (len = pmsg->len, j = 0; len > 0; len -= 8, j += 8) {
189			page_len = (len >= 8) ? 8 : len;
190
191			if (pmsg->flags & I2C_M_RD) {
192				cmd = (len > 8) ?
193					SM0CTL1_READ : SM0CTL1_READ_LAST;
194			} else {
195				memcpy(data, &pmsg->buf[j], page_len);
196				iowrite32(data[0], i2c->base + REG_SM0D0_REG);
197				iowrite32(data[1], i2c->base + REG_SM0D1_REG);
198				cmd = SM0CTL1_WRITE;
199			}
200
201			ret = mtk_i2c_cmd(i2c, cmd, page_len);
202			if (ret)
203				goto err_timeout;
204
205			if (pmsg->flags & I2C_M_RD) {
206				data[0] = ioread32(i2c->base + REG_SM0D0_REG);
207				data[1] = ioread32(i2c->base + REG_SM0D1_REG);
208				memcpy(&pmsg->buf[j], data, page_len);
209			} else {
210				if (!(pmsg->flags & I2C_M_IGNORE_NAK)) {
211					ret = mtk_i2c_check_ack(i2c,
212								(1 << page_len)
213								- 1);
214					if (ret)
215						goto err_ack;
216				}
217			}
218		}
219	}
220
221	ret = mtk_i2c_stop(i2c);
222	if (ret)
223		goto err_timeout;
224
225	/* the return value is number of executed messages */
226	return i;
227
228err_ack:
229	ret = mtk_i2c_stop(i2c);
230	if (ret)
231		goto err_timeout;
232	return -ENXIO;
233
234err_timeout:
235	mtk_i2c_dump_reg(i2c);
236	mtk_i2c_reset(i2c);
237	return ret;
238}
239
240static u32 mtk_i2c_func(struct i2c_adapter *a)
241{
242	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
243}
244
245static const struct i2c_algorithm mtk_i2c_algo = {
246	.xfer = mtk_i2c_xfer,
247	.functionality = mtk_i2c_func,
248};
249
250static const struct of_device_id i2c_mtk_dt_ids[] = {
251	{ .compatible = "mediatek,mt7621-i2c" },
252	{ /* sentinel */ }
253};
254
255MODULE_DEVICE_TABLE(of, i2c_mtk_dt_ids);
256
257static void mtk_i2c_init(struct mtk_i2c *i2c)
258{
259	i2c->clk_div = clk_get_rate(i2c->clk) / i2c->bus_freq - 1;
260	if (i2c->clk_div < 99)
261		i2c->clk_div = 99;
262	if (i2c->clk_div > SM0CTL0_CLK_DIV_MAX)
263		i2c->clk_div = SM0CTL0_CLK_DIV_MAX;
264
265	mtk_i2c_reset(i2c);
266}
267
268static int mtk_i2c_probe(struct platform_device *pdev)
269{
270	struct mtk_i2c *i2c;
271	struct i2c_adapter *adap;
272	int ret;
273
274	i2c = devm_kzalloc(&pdev->dev, sizeof(struct mtk_i2c), GFP_KERNEL);
275	if (!i2c)
276		return -ENOMEM;
277
278	i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
279	if (IS_ERR(i2c->base))
280		return PTR_ERR(i2c->base);
281
282	i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);
283	if (IS_ERR(i2c->clk)) {
284		dev_err(&pdev->dev, "Failed to enable clock\n");
285		return PTR_ERR(i2c->clk);
286	}
287
288	i2c->dev = &pdev->dev;
289
290	if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
291				 &i2c->bus_freq))
292		i2c->bus_freq = I2C_MAX_STANDARD_MODE_FREQ;
293
294	if (i2c->bus_freq == 0) {
295		dev_warn(i2c->dev, "clock-frequency 0 not supported\n");
296		return -EINVAL;
297	}
298
299	adap = &i2c->adap;
300	adap->owner = THIS_MODULE;
301	adap->algo = &mtk_i2c_algo;
302	adap->retries = 3;
303	adap->dev.parent = &pdev->dev;
304	i2c_set_adapdata(adap, i2c);
305	adap->dev.of_node = pdev->dev.of_node;
306	strscpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
307
308	platform_set_drvdata(pdev, i2c);
309
310	mtk_i2c_init(i2c);
311
312	ret = i2c_add_adapter(adap);
313	if (ret < 0)
314		return ret;
315
316	dev_info(&pdev->dev, "clock %u kHz\n", i2c->bus_freq / 1000);
317
318	return 0;
319}
320
321static void mtk_i2c_remove(struct platform_device *pdev)
322{
323	struct mtk_i2c *i2c = platform_get_drvdata(pdev);
324
325	i2c_del_adapter(&i2c->adap);
326}
327
328static struct platform_driver mtk_i2c_driver = {
329	.probe		= mtk_i2c_probe,
330	.remove		= mtk_i2c_remove,
331	.driver		= {
332		.name	= "i2c-mt7621",
333		.of_match_table = i2c_mtk_dt_ids,
334	},
335};
336
337module_platform_driver(mtk_i2c_driver);
338
339MODULE_AUTHOR("Steven Liu");
340MODULE_DESCRIPTION("MT7621 I2C host driver");
341MODULE_LICENSE("GPL v2");
342MODULE_ALIAS("platform:MT7621-I2C");
~/ Read-only file preview.