1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014 MediaTek Inc.
4 * Author: Jie Qiu <jie.qiu@mediatek.com>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
9 #include <linux/time.h>
10 #include <linux/delay.h>
11 #include <linux/errno.h>
12 #include <linux/err.h>
13 #include <linux/platform_device.h>
14 #include <linux/clk.h>
15 #include <linux/slab.h>
17 #include <linux/iopoll.h>
18 #include <linux/of_address.h>
19 #include <linux/of_irq.h>
20 #include <linux/of_platform.h>
22 #define SIF1_CLOK (288)
23 #define DDC_DDCMCTL0 (0x0)
24 #define DDCM_ODRAIN BIT(31)
25 #define DDCM_CLK_DIV_OFFSET (16)
26 #define DDCM_CLK_DIV_MASK (0xfff << 16)
27 #define DDCM_CS_STATUS BIT(4)
28 #define DDCM_SCL_STATE BIT(3)
29 #define DDCM_SDA_STATE BIT(2)
30 #define DDCM_SM0EN BIT(1)
31 #define DDCM_SCL_STRECH BIT(0)
32 #define DDC_DDCMCTL1 (0x4)
33 #define DDCM_ACK_OFFSET (16)
34 #define DDCM_ACK_MASK (0xff << 16)
35 #define DDCM_PGLEN_OFFSET (8)
36 #define DDCM_PGLEN_MASK (0x7 << 8)
37 #define DDCM_SIF_MODE_OFFSET (4)
38 #define DDCM_SIF_MODE_MASK (0x7 << 4)
39 #define DDCM_START (0x1)
40 #define DDCM_WRITE_DATA (0x2)
41 #define DDCM_STOP (0x3)
42 #define DDCM_READ_DATA_NO_ACK (0x4)
43 #define DDCM_READ_DATA_ACK (0x5)
44 #define DDCM_TRI BIT(0)
45 #define DDC_DDCMD0 (0x8)
46 #define DDCM_DATA3 (0xff << 24)
47 #define DDCM_DATA2 (0xff << 16)
48 #define DDCM_DATA1 (0xff << 8)
49 #define DDCM_DATA0 (0xff << 0)
50 #define DDC_DDCMD1 (0xc)
51 #define DDCM_DATA7 (0xff << 24)
52 #define DDCM_DATA6 (0xff << 16)
53 #define DDCM_DATA5 (0xff << 8)
54 #define DDCM_DATA4 (0xff << 0)
57 struct i2c_adapter adap
;
62 static inline void sif_set_bit(struct mtk_hdmi_ddc
*ddc
, unsigned int offset
,
65 writel(readl(ddc
->regs
+ offset
) | val
, ddc
->regs
+ offset
);
68 static inline void sif_clr_bit(struct mtk_hdmi_ddc
*ddc
, unsigned int offset
,
71 writel(readl(ddc
->regs
+ offset
) & ~val
, ddc
->regs
+ offset
);
74 static inline bool sif_bit_is_set(struct mtk_hdmi_ddc
*ddc
, unsigned int offset
,
77 return (readl(ddc
->regs
+ offset
) & val
) == val
;
80 static inline void sif_write_mask(struct mtk_hdmi_ddc
*ddc
, unsigned int offset
,
81 unsigned int mask
, unsigned int shift
,
86 tmp
= readl(ddc
->regs
+ offset
);
88 tmp
|= (val
<< shift
) & mask
;
89 writel(tmp
, ddc
->regs
+ offset
);
92 static inline unsigned int sif_read_mask(struct mtk_hdmi_ddc
*ddc
,
93 unsigned int offset
, unsigned int mask
,
96 return (readl(ddc
->regs
+ offset
) & mask
) >> shift
;
99 static void ddcm_trigger_mode(struct mtk_hdmi_ddc
*ddc
, int mode
)
103 sif_write_mask(ddc
, DDC_DDCMCTL1
, DDCM_SIF_MODE_MASK
,
104 DDCM_SIF_MODE_OFFSET
, mode
);
105 sif_set_bit(ddc
, DDC_DDCMCTL1
, DDCM_TRI
);
106 readl_poll_timeout(ddc
->regs
+ DDC_DDCMCTL1
, val
,
107 (val
& DDCM_TRI
) != DDCM_TRI
, 4, 20000);
110 static int mtk_hdmi_ddc_read_msg(struct mtk_hdmi_ddc
*ddc
, struct i2c_msg
*msg
)
112 struct device
*dev
= ddc
->adap
.dev
.parent
;
113 u32 remain_count
, ack_count
, ack_final
, read_count
, temp_count
;
118 ddcm_trigger_mode(ddc
, DDCM_START
);
119 sif_write_mask(ddc
, DDC_DDCMD0
, 0xff, 0, (msg
->addr
<< 1) | 0x01);
120 sif_write_mask(ddc
, DDC_DDCMCTL1
, DDCM_PGLEN_MASK
, DDCM_PGLEN_OFFSET
,
122 ddcm_trigger_mode(ddc
, DDCM_WRITE_DATA
);
123 ack
= sif_read_mask(ddc
, DDC_DDCMCTL1
, DDCM_ACK_MASK
, DDCM_ACK_OFFSET
);
124 dev_dbg(dev
, "ack = 0x%x\n", ack
);
126 dev_err(dev
, "i2c ack err!\n");
130 remain_count
= msg
->len
;
131 ack_count
= (msg
->len
- 1) / 8;
134 while (remain_count
> 0) {
140 read_count
= remain_count
;
144 sif_write_mask(ddc
, DDC_DDCMCTL1
, DDCM_PGLEN_MASK
,
145 DDCM_PGLEN_OFFSET
, read_count
- 1);
146 ddcm_trigger_mode(ddc
, (ack_final
== 1) ?
147 DDCM_READ_DATA_NO_ACK
:
150 ack
= sif_read_mask(ddc
, DDC_DDCMCTL1
, DDCM_ACK_MASK
,
153 while (((ack
& (1 << temp_count
)) != 0) && (temp_count
< 8))
155 if (((ack_final
== 1) && (temp_count
!= (read_count
- 1))) ||
156 ((ack_final
== 0) && (temp_count
!= read_count
))) {
157 dev_err(dev
, "Address NACK! ACK(0x%x)\n", ack
);
161 for (i
= read_count
; i
>= 1; i
--) {
173 msg
->buf
[index
+ i
- 1] = sif_read_mask(ddc
, offset
,
178 remain_count
-= read_count
;
185 static int mtk_hdmi_ddc_write_msg(struct mtk_hdmi_ddc
*ddc
, struct i2c_msg
*msg
)
187 struct device
*dev
= ddc
->adap
.dev
.parent
;
190 ddcm_trigger_mode(ddc
, DDCM_START
);
191 sif_write_mask(ddc
, DDC_DDCMD0
, DDCM_DATA0
, 0, msg
->addr
<< 1);
192 sif_write_mask(ddc
, DDC_DDCMD0
, DDCM_DATA1
, 8, msg
->buf
[0]);
193 sif_write_mask(ddc
, DDC_DDCMCTL1
, DDCM_PGLEN_MASK
, DDCM_PGLEN_OFFSET
,
195 ddcm_trigger_mode(ddc
, DDCM_WRITE_DATA
);
197 ack
= sif_read_mask(ddc
, DDC_DDCMCTL1
, DDCM_ACK_MASK
, DDCM_ACK_OFFSET
);
198 dev_dbg(dev
, "ack = %d\n", ack
);
201 dev_err(dev
, "i2c ack err!\n");
208 static int mtk_hdmi_ddc_xfer(struct i2c_adapter
*adapter
,
209 struct i2c_msg
*msgs
, int num
)
211 struct mtk_hdmi_ddc
*ddc
= adapter
->algo_data
;
212 struct device
*dev
= adapter
->dev
.parent
;
217 dev_err(dev
, "invalid arguments\n");
221 sif_set_bit(ddc
, DDC_DDCMCTL0
, DDCM_SCL_STRECH
);
222 sif_set_bit(ddc
, DDC_DDCMCTL0
, DDCM_SM0EN
);
223 sif_clr_bit(ddc
, DDC_DDCMCTL0
, DDCM_ODRAIN
);
225 if (sif_bit_is_set(ddc
, DDC_DDCMCTL1
, DDCM_TRI
)) {
226 dev_err(dev
, "ddc line is busy!\n");
230 sif_write_mask(ddc
, DDC_DDCMCTL0
, DDCM_CLK_DIV_MASK
,
231 DDCM_CLK_DIV_OFFSET
, SIF1_CLOK
);
233 for (i
= 0; i
< num
; i
++) {
234 struct i2c_msg
*msg
= &msgs
[i
];
236 dev_dbg(dev
, "i2c msg, adr:0x%x, flags:%d, len :0x%x\n",
237 msg
->addr
, msg
->flags
, msg
->len
);
239 if (msg
->flags
& I2C_M_RD
)
240 ret
= mtk_hdmi_ddc_read_msg(ddc
, msg
);
242 ret
= mtk_hdmi_ddc_write_msg(ddc
, msg
);
247 ddcm_trigger_mode(ddc
, DDCM_STOP
);
252 ddcm_trigger_mode(ddc
, DDCM_STOP
);
253 dev_err(dev
, "ddc failed!\n");
257 static u32
mtk_hdmi_ddc_func(struct i2c_adapter
*adapter
)
259 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
262 static const struct i2c_algorithm mtk_hdmi_ddc_algorithm
= {
263 .master_xfer
= mtk_hdmi_ddc_xfer
,
264 .functionality
= mtk_hdmi_ddc_func
,
267 static int mtk_hdmi_ddc_probe(struct platform_device
*pdev
)
269 struct device
*dev
= &pdev
->dev
;
270 struct mtk_hdmi_ddc
*ddc
;
271 struct resource
*mem
;
274 ddc
= devm_kzalloc(dev
, sizeof(struct mtk_hdmi_ddc
), GFP_KERNEL
);
278 ddc
->clk
= devm_clk_get(dev
, "ddc-i2c");
279 if (IS_ERR(ddc
->clk
)) {
280 dev_err(dev
, "get ddc_clk failed: %p ,\n", ddc
->clk
);
281 return PTR_ERR(ddc
->clk
);
284 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
285 ddc
->regs
= devm_ioremap_resource(&pdev
->dev
, mem
);
286 if (IS_ERR(ddc
->regs
))
287 return PTR_ERR(ddc
->regs
);
289 ret
= clk_prepare_enable(ddc
->clk
);
291 dev_err(dev
, "enable ddc clk failed!\n");
295 strlcpy(ddc
->adap
.name
, "mediatek-hdmi-ddc", sizeof(ddc
->adap
.name
));
296 ddc
->adap
.owner
= THIS_MODULE
;
297 ddc
->adap
.class = I2C_CLASS_DDC
;
298 ddc
->adap
.algo
= &mtk_hdmi_ddc_algorithm
;
299 ddc
->adap
.retries
= 3;
300 ddc
->adap
.dev
.of_node
= dev
->of_node
;
301 ddc
->adap
.algo_data
= ddc
;
302 ddc
->adap
.dev
.parent
= &pdev
->dev
;
304 ret
= i2c_add_adapter(&ddc
->adap
);
306 dev_err(dev
, "failed to add bus to i2c core\n");
307 goto err_clk_disable
;
310 platform_set_drvdata(pdev
, ddc
);
312 dev_dbg(dev
, "ddc->adap: %p\n", &ddc
->adap
);
313 dev_dbg(dev
, "ddc->clk: %p\n", ddc
->clk
);
314 dev_dbg(dev
, "physical adr: %pa, end: %pa\n", &mem
->start
,
320 clk_disable_unprepare(ddc
->clk
);
324 static int mtk_hdmi_ddc_remove(struct platform_device
*pdev
)
326 struct mtk_hdmi_ddc
*ddc
= platform_get_drvdata(pdev
);
328 i2c_del_adapter(&ddc
->adap
);
329 clk_disable_unprepare(ddc
->clk
);
334 static const struct of_device_id mtk_hdmi_ddc_match
[] = {
335 { .compatible
= "mediatek,mt8173-hdmi-ddc", },
339 struct platform_driver mtk_hdmi_ddc_driver
= {
340 .probe
= mtk_hdmi_ddc_probe
,
341 .remove
= mtk_hdmi_ddc_remove
,
343 .name
= "mediatek-hdmi-ddc",
344 .of_match_table
= mtk_hdmi_ddc_match
,
348 MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>");
349 MODULE_DESCRIPTION("MediaTek HDMI DDC Driver");
350 MODULE_LICENSE("GPL v2");