2 * I2C bus driver for Amlogic Meson SoCs
4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/clk.h>
12 #include <linux/completion.h>
13 #include <linux/i2c.h>
14 #include <linux/interrupt.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/types.h>
22 /* Meson I2C register map */
24 #define REG_SLAVE_ADDR 0x04
25 #define REG_TOK_LIST0 0x08
26 #define REG_TOK_LIST1 0x0c
27 #define REG_TOK_WDATA0 0x10
28 #define REG_TOK_WDATA1 0x14
29 #define REG_TOK_RDATA0 0x18
30 #define REG_TOK_RDATA1 0x1c
32 /* Control register fields */
33 #define REG_CTRL_START BIT(0)
34 #define REG_CTRL_ACK_IGNORE BIT(1)
35 #define REG_CTRL_STATUS BIT(2)
36 #define REG_CTRL_ERROR BIT(3)
37 #define REG_CTRL_CLKDIV_SHIFT 12
38 #define REG_CTRL_CLKDIV_MASK GENMASK(21, 12)
39 #define REG_CTRL_CLKDIVEXT_SHIFT 28
40 #define REG_CTRL_CLKDIVEXT_MASK GENMASK(29, 28)
42 #define I2C_TIMEOUT_MS 500
47 TOKEN_SLAVE_ADDR_WRITE
,
48 TOKEN_SLAVE_ADDR_READ
,
61 * struct meson_i2c - Meson I2C device private data
63 * @adap: I2C adapter instance
64 * @dev: Pointer to device structure
65 * @regs: Base address of the device memory mapped registers
66 * @clk: Pointer to clock structure
68 * @msg: Pointer to the current I2C message
69 * @state: Current state in the driver state machine
70 * @last: Flag set for the last message in the transfer
71 * @count: Number of bytes to be sent/received in current transfer
72 * @pos: Current position in the send/receive buffer
73 * @error: Flag set when an error is received
74 * @lock: To avoid race conditions between irq handler and xfer code
75 * @done: Completion used to wait for transfer termination
76 * @tokens: Sequence of tokens to be written to the device
77 * @num_tokens: Number of tokens
80 struct i2c_adapter adap
;
93 struct completion done
;
98 static void meson_i2c_set_mask(struct meson_i2c
*i2c
, int reg
, u32 mask
,
103 data
= readl(i2c
->regs
+ reg
);
106 writel(data
, i2c
->regs
+ reg
);
109 static void meson_i2c_reset_tokens(struct meson_i2c
*i2c
)
116 static void meson_i2c_add_token(struct meson_i2c
*i2c
, int token
)
118 if (i2c
->num_tokens
< 8)
119 i2c
->tokens
[0] |= (token
& 0xf) << (i2c
->num_tokens
* 4);
121 i2c
->tokens
[1] |= (token
& 0xf) << ((i2c
->num_tokens
% 8) * 4);
126 static void meson_i2c_set_clk_div(struct meson_i2c
*i2c
, unsigned int freq
)
128 unsigned long clk_rate
= clk_get_rate(i2c
->clk
);
131 div
= DIV_ROUND_UP(clk_rate
, freq
* 4);
133 /* clock divider has 12 bits */
134 if (div
>= (1 << 12)) {
135 dev_err(i2c
->dev
, "requested bus frequency too low\n");
139 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_CLKDIV_MASK
,
140 (div
& GENMASK(9, 0)) << REG_CTRL_CLKDIV_SHIFT
);
142 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_CLKDIVEXT_MASK
,
143 (div
>> 10) << REG_CTRL_CLKDIVEXT_SHIFT
);
145 dev_dbg(i2c
->dev
, "%s: clk %lu, freq %u, div %u\n", __func__
,
146 clk_rate
, freq
, div
);
149 static void meson_i2c_get_data(struct meson_i2c
*i2c
, char *buf
, int len
)
154 rdata0
= readl(i2c
->regs
+ REG_TOK_RDATA0
);
155 rdata1
= readl(i2c
->regs
+ REG_TOK_RDATA1
);
157 dev_dbg(i2c
->dev
, "%s: data %08x %08x len %d\n", __func__
,
158 rdata0
, rdata1
, len
);
160 for (i
= 0; i
< min(4, len
); i
++)
161 *buf
++ = (rdata0
>> i
* 8) & 0xff;
163 for (i
= 4; i
< min(8, len
); i
++)
164 *buf
++ = (rdata1
>> (i
- 4) * 8) & 0xff;
167 static void meson_i2c_put_data(struct meson_i2c
*i2c
, char *buf
, int len
)
169 u32 wdata0
= 0, wdata1
= 0;
172 for (i
= 0; i
< min(4, len
); i
++)
173 wdata0
|= *buf
++ << (i
* 8);
175 for (i
= 4; i
< min(8, len
); i
++)
176 wdata1
|= *buf
++ << ((i
- 4) * 8);
178 writel(wdata0
, i2c
->regs
+ REG_TOK_WDATA0
);
179 writel(wdata1
, i2c
->regs
+ REG_TOK_WDATA1
);
181 dev_dbg(i2c
->dev
, "%s: data %08x %08x len %d\n", __func__
,
182 wdata0
, wdata1
, len
);
185 static void meson_i2c_prepare_xfer(struct meson_i2c
*i2c
)
187 bool write
= !(i2c
->msg
->flags
& I2C_M_RD
);
190 i2c
->count
= min(i2c
->msg
->len
- i2c
->pos
, 8);
192 for (i
= 0; i
< i2c
->count
- 1; i
++)
193 meson_i2c_add_token(i2c
, TOKEN_DATA
);
196 if (write
|| i2c
->pos
+ i2c
->count
< i2c
->msg
->len
)
197 meson_i2c_add_token(i2c
, TOKEN_DATA
);
199 meson_i2c_add_token(i2c
, TOKEN_DATA_LAST
);
203 meson_i2c_put_data(i2c
, i2c
->msg
->buf
+ i2c
->pos
, i2c
->count
);
205 if (i2c
->last
&& i2c
->pos
+ i2c
->count
>= i2c
->msg
->len
)
206 meson_i2c_add_token(i2c
, TOKEN_STOP
);
208 writel(i2c
->tokens
[0], i2c
->regs
+ REG_TOK_LIST0
);
209 writel(i2c
->tokens
[1], i2c
->regs
+ REG_TOK_LIST1
);
212 static irqreturn_t
meson_i2c_irq(int irqno
, void *dev_id
)
214 struct meson_i2c
*i2c
= dev_id
;
217 spin_lock(&i2c
->lock
);
219 meson_i2c_reset_tokens(i2c
);
220 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_START
, 0);
221 ctrl
= readl(i2c
->regs
+ REG_CTRL
);
223 dev_dbg(i2c
->dev
, "irq: state %d, pos %d, count %d, ctrl %08x\n",
224 i2c
->state
, i2c
->pos
, i2c
->count
, ctrl
);
226 if (i2c
->state
== STATE_IDLE
) {
227 spin_unlock(&i2c
->lock
);
231 if (ctrl
& REG_CTRL_ERROR
) {
233 * The bit is set when the IGNORE_NAK bit is cleared
234 * and the device didn't respond. In this case, the
235 * I2C controller automatically generates a STOP
238 dev_dbg(i2c
->dev
, "error bit set\n");
240 i2c
->state
= STATE_IDLE
;
241 complete(&i2c
->done
);
245 if (i2c
->state
== STATE_READ
&& i2c
->count
)
246 meson_i2c_get_data(i2c
, i2c
->msg
->buf
+ i2c
->pos
, i2c
->count
);
248 i2c
->pos
+= i2c
->count
;
250 if (i2c
->pos
>= i2c
->msg
->len
) {
251 i2c
->state
= STATE_IDLE
;
252 complete(&i2c
->done
);
256 /* Restart the processing */
257 meson_i2c_prepare_xfer(i2c
);
258 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_START
, REG_CTRL_START
);
260 spin_unlock(&i2c
->lock
);
265 static void meson_i2c_do_start(struct meson_i2c
*i2c
, struct i2c_msg
*msg
)
269 token
= (msg
->flags
& I2C_M_RD
) ? TOKEN_SLAVE_ADDR_READ
:
270 TOKEN_SLAVE_ADDR_WRITE
;
272 writel(msg
->addr
<< 1, i2c
->regs
+ REG_SLAVE_ADDR
);
273 meson_i2c_add_token(i2c
, TOKEN_START
);
274 meson_i2c_add_token(i2c
, token
);
277 static int meson_i2c_xfer_msg(struct meson_i2c
*i2c
, struct i2c_msg
*msg
,
280 unsigned long time_left
, flags
;
289 meson_i2c_reset_tokens(i2c
);
291 flags
= (msg
->flags
& I2C_M_IGNORE_NAK
) ? REG_CTRL_ACK_IGNORE
: 0;
292 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_ACK_IGNORE
, flags
);
294 if (!(msg
->flags
& I2C_M_NOSTART
))
295 meson_i2c_do_start(i2c
, msg
);
297 i2c
->state
= (msg
->flags
& I2C_M_RD
) ? STATE_READ
: STATE_WRITE
;
298 meson_i2c_prepare_xfer(i2c
);
299 reinit_completion(&i2c
->done
);
301 /* Start the transfer */
302 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_START
, REG_CTRL_START
);
304 time_left
= msecs_to_jiffies(I2C_TIMEOUT_MS
);
305 time_left
= wait_for_completion_timeout(&i2c
->done
, time_left
);
308 * Protect access to i2c struct and registers from interrupt
309 * handlers triggered by a transfer terminated after the
312 spin_lock_irqsave(&i2c
->lock
, flags
);
314 /* Abort any active operation */
315 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_START
, 0);
318 i2c
->state
= STATE_IDLE
;
325 spin_unlock_irqrestore(&i2c
->lock
, flags
);
330 static int meson_i2c_xfer(struct i2c_adapter
*adap
, struct i2c_msg
*msgs
,
333 struct meson_i2c
*i2c
= adap
->algo_data
;
336 clk_enable(i2c
->clk
);
338 for (i
= 0; i
< num
; i
++) {
339 ret
= meson_i2c_xfer_msg(i2c
, msgs
+ i
, i
== num
- 1);
344 clk_disable(i2c
->clk
);
349 static u32
meson_i2c_func(struct i2c_adapter
*adap
)
351 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
354 static const struct i2c_algorithm meson_i2c_algorithm
= {
355 .master_xfer
= meson_i2c_xfer
,
356 .functionality
= meson_i2c_func
,
359 static int meson_i2c_probe(struct platform_device
*pdev
)
361 struct device_node
*np
= pdev
->dev
.of_node
;
362 struct meson_i2c
*i2c
;
363 struct resource
*mem
;
364 struct i2c_timings timings
;
367 i2c
= devm_kzalloc(&pdev
->dev
, sizeof(struct meson_i2c
), GFP_KERNEL
);
371 i2c_parse_fw_timings(&pdev
->dev
, &timings
, true);
373 i2c
->dev
= &pdev
->dev
;
374 platform_set_drvdata(pdev
, i2c
);
376 spin_lock_init(&i2c
->lock
);
377 init_completion(&i2c
->done
);
379 i2c
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
380 if (IS_ERR(i2c
->clk
)) {
381 dev_err(&pdev
->dev
, "can't get device clock\n");
382 return PTR_ERR(i2c
->clk
);
385 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
386 i2c
->regs
= devm_ioremap_resource(&pdev
->dev
, mem
);
387 if (IS_ERR(i2c
->regs
))
388 return PTR_ERR(i2c
->regs
);
390 irq
= platform_get_irq(pdev
, 0);
392 dev_err(&pdev
->dev
, "can't find IRQ\n");
396 ret
= devm_request_irq(&pdev
->dev
, irq
, meson_i2c_irq
, 0, NULL
, i2c
);
398 dev_err(&pdev
->dev
, "can't request IRQ\n");
402 ret
= clk_prepare(i2c
->clk
);
404 dev_err(&pdev
->dev
, "can't prepare clock\n");
408 strlcpy(i2c
->adap
.name
, "Meson I2C adapter",
409 sizeof(i2c
->adap
.name
));
410 i2c
->adap
.owner
= THIS_MODULE
;
411 i2c
->adap
.algo
= &meson_i2c_algorithm
;
412 i2c
->adap
.dev
.parent
= &pdev
->dev
;
413 i2c
->adap
.dev
.of_node
= np
;
414 i2c
->adap
.algo_data
= i2c
;
417 * A transfer is triggered when START bit changes from 0 to 1.
418 * Ensure that the bit is set to 0 after probe
420 meson_i2c_set_mask(i2c
, REG_CTRL
, REG_CTRL_START
, 0);
422 ret
= i2c_add_adapter(&i2c
->adap
);
424 clk_unprepare(i2c
->clk
);
428 meson_i2c_set_clk_div(i2c
, timings
.bus_freq_hz
);
433 static int meson_i2c_remove(struct platform_device
*pdev
)
435 struct meson_i2c
*i2c
= platform_get_drvdata(pdev
);
437 i2c_del_adapter(&i2c
->adap
);
438 clk_unprepare(i2c
->clk
);
443 static const struct of_device_id meson_i2c_match
[] = {
444 { .compatible
= "amlogic,meson6-i2c" },
445 { .compatible
= "amlogic,meson-gxbb-i2c" },
448 MODULE_DEVICE_TABLE(of
, meson_i2c_match
);
450 static struct platform_driver meson_i2c_driver
= {
451 .probe
= meson_i2c_probe
,
452 .remove
= meson_i2c_remove
,
455 .of_match_table
= meson_i2c_match
,
459 module_platform_driver(meson_i2c_driver
);
461 MODULE_DESCRIPTION("Amlogic Meson I2C Bus driver");
462 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
463 MODULE_LICENSE("GPL v2");