1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
4 * Copyright (C) 2017 Jonathan Liu <net147@gmail.com>
9 #include <linux/iopoll.h>
11 #include "sun4i_hdmi.h"
13 #define SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK ( \
14 SUN4I_HDMI_DDC_INT_STATUS_ILLEGAL_FIFO_OPERATION | \
15 SUN4I_HDMI_DDC_INT_STATUS_DDC_RX_FIFO_UNDERFLOW | \
16 SUN4I_HDMI_DDC_INT_STATUS_DDC_TX_FIFO_OVERFLOW | \
17 SUN4I_HDMI_DDC_INT_STATUS_ARBITRATION_ERROR | \
18 SUN4I_HDMI_DDC_INT_STATUS_ACK_ERROR | \
19 SUN4I_HDMI_DDC_INT_STATUS_BUS_ERROR \
22 /* FIFO request bit is set when FIFO level is above RX_THRESHOLD during read */
23 #define RX_THRESHOLD SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MAX
25 static int fifo_transfer(struct sun4i_hdmi
*hdmi
, u8
*buf
, int len
, bool read
)
28 * 1 byte takes 9 clock cycles (8 bits + 1 ACK) = 90 us for 100 kHz
29 * clock. As clock rate is fixed, just round it up to 100 us.
31 const unsigned long byte_time_ns
= 100;
32 const u32 mask
= SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
|
33 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST
|
34 SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE
;
37 * If threshold is inclusive, then the FIFO may only have
38 * RX_THRESHOLD number of bytes, instead of RX_THRESHOLD + 1.
40 int read_len
= RX_THRESHOLD
+
41 (hdmi
->variant
->ddc_fifo_thres_incl
? 0 : 1);
44 * Limit transfer length by FIFO threshold or FIFO size.
45 * For TX the threshold is for an empty FIFO.
47 len
= min_t(int, len
, read
? read_len
: SUN4I_HDMI_DDC_FIFO_SIZE
);
49 /* Wait until error, FIFO request bit set or transfer complete */
50 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_int_status
, reg
,
51 reg
& mask
, len
* byte_time_ns
,
55 if (reg
& SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
)
59 readsb(hdmi
->base
+ hdmi
->variant
->ddc_fifo_reg
, buf
, len
);
61 writesb(hdmi
->base
+ hdmi
->variant
->ddc_fifo_reg
, buf
, len
);
63 /* Clear FIFO request bit by forcing a write to that bit */
64 regmap_field_force_write(hdmi
->field_ddc_int_status
,
65 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST
);
70 static int xfer_msg(struct sun4i_hdmi
*hdmi
, struct i2c_msg
*msg
)
75 /* Set FIFO direction */
76 if (hdmi
->variant
->ddc_fifo_has_dir
) {
77 reg
= readl(hdmi
->base
+ SUN4I_HDMI_DDC_CTRL_REG
);
78 reg
&= ~SUN4I_HDMI_DDC_CTRL_FIFO_DIR_MASK
;
79 reg
|= (msg
->flags
& I2C_M_RD
) ?
80 SUN4I_HDMI_DDC_CTRL_FIFO_DIR_READ
:
81 SUN4I_HDMI_DDC_CTRL_FIFO_DIR_WRITE
;
82 writel(reg
, hdmi
->base
+ SUN4I_HDMI_DDC_CTRL_REG
);
85 /* Clear address register (not cleared by soft reset) */
86 regmap_field_write(hdmi
->field_ddc_addr_reg
, 0);
89 regmap_field_write(hdmi
->field_ddc_slave_addr
, msg
->addr
);
92 * Set FIFO RX/TX thresholds and clear FIFO
94 * If threshold is inclusive, we can set the TX threshold to
97 regmap_field_write(hdmi
->field_ddc_fifo_tx_thres
,
98 hdmi
->variant
->ddc_fifo_thres_incl
? 0 : 1);
99 regmap_field_write(hdmi
->field_ddc_fifo_rx_thres
, RX_THRESHOLD
);
100 regmap_field_write(hdmi
->field_ddc_fifo_clear
, 1);
101 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_fifo_clear
,
102 reg
, !reg
, 100, 2000))
105 /* Set transfer length */
106 regmap_field_write(hdmi
->field_ddc_byte_count
, msg
->len
);
109 regmap_field_write(hdmi
->field_ddc_cmd
,
110 msg
->flags
& I2C_M_RD
?
111 SUN4I_HDMI_DDC_CMD_IMPLICIT_READ
:
112 SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE
);
114 /* Clear interrupt status bits by forcing a write */
115 regmap_field_force_write(hdmi
->field_ddc_int_status
,
116 SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
|
117 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST
|
118 SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE
);
121 regmap_field_write(hdmi
->field_ddc_start
, 1);
124 for (i
= 0; i
< msg
->len
; i
+= len
) {
125 len
= fifo_transfer(hdmi
, msg
->buf
+ i
, msg
->len
- i
,
126 msg
->flags
& I2C_M_RD
);
131 /* Wait for command to finish */
132 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_start
,
133 reg
, !reg
, 100, 100000))
136 /* Check for errors */
137 regmap_field_read(hdmi
->field_ddc_int_status
, ®
);
138 if ((reg
& SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
) ||
139 !(reg
& SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE
)) {
146 static int sun4i_hdmi_i2c_xfer(struct i2c_adapter
*adap
,
147 struct i2c_msg
*msgs
, int num
)
149 struct sun4i_hdmi
*hdmi
= i2c_get_adapdata(adap
);
151 int err
, i
, ret
= num
;
153 for (i
= 0; i
< num
; i
++) {
156 if (msgs
[i
].len
> SUN4I_HDMI_DDC_BYTE_COUNT_MAX
)
160 /* DDC clock needs to be enabled for the module to work */
161 clk_prepare_enable(hdmi
->ddc_clk
);
162 clk_set_rate(hdmi
->ddc_clk
, 100000);
164 /* Reset I2C controller */
165 regmap_field_write(hdmi
->field_ddc_en
, 1);
166 regmap_field_write(hdmi
->field_ddc_reset
, 1);
167 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_reset
,
168 reg
, !reg
, 100, 2000)) {
169 clk_disable_unprepare(hdmi
->ddc_clk
);
173 regmap_field_write(hdmi
->field_ddc_sck_en
, 1);
174 regmap_field_write(hdmi
->field_ddc_sda_en
, 1);
176 for (i
= 0; i
< num
; i
++) {
177 err
= xfer_msg(hdmi
, &msgs
[i
]);
184 clk_disable_unprepare(hdmi
->ddc_clk
);
188 static u32
sun4i_hdmi_i2c_func(struct i2c_adapter
*adap
)
190 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
193 static const struct i2c_algorithm sun4i_hdmi_i2c_algorithm
= {
194 .master_xfer
= sun4i_hdmi_i2c_xfer
,
195 .functionality
= sun4i_hdmi_i2c_func
,
198 static int sun4i_hdmi_init_regmap_fields(struct sun4i_hdmi
*hdmi
)
201 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
202 hdmi
->variant
->field_ddc_en
);
203 if (IS_ERR(hdmi
->field_ddc_en
))
204 return PTR_ERR(hdmi
->field_ddc_en
);
206 hdmi
->field_ddc_start
=
207 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
208 hdmi
->variant
->field_ddc_start
);
209 if (IS_ERR(hdmi
->field_ddc_start
))
210 return PTR_ERR(hdmi
->field_ddc_start
);
212 hdmi
->field_ddc_reset
=
213 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
214 hdmi
->variant
->field_ddc_reset
);
215 if (IS_ERR(hdmi
->field_ddc_reset
))
216 return PTR_ERR(hdmi
->field_ddc_reset
);
218 hdmi
->field_ddc_addr_reg
=
219 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
220 hdmi
->variant
->field_ddc_addr_reg
);
221 if (IS_ERR(hdmi
->field_ddc_addr_reg
))
222 return PTR_ERR(hdmi
->field_ddc_addr_reg
);
224 hdmi
->field_ddc_slave_addr
=
225 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
226 hdmi
->variant
->field_ddc_slave_addr
);
227 if (IS_ERR(hdmi
->field_ddc_slave_addr
))
228 return PTR_ERR(hdmi
->field_ddc_slave_addr
);
230 hdmi
->field_ddc_int_mask
=
231 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
232 hdmi
->variant
->field_ddc_int_mask
);
233 if (IS_ERR(hdmi
->field_ddc_int_mask
))
234 return PTR_ERR(hdmi
->field_ddc_int_mask
);
236 hdmi
->field_ddc_int_status
=
237 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
238 hdmi
->variant
->field_ddc_int_status
);
239 if (IS_ERR(hdmi
->field_ddc_int_status
))
240 return PTR_ERR(hdmi
->field_ddc_int_status
);
242 hdmi
->field_ddc_fifo_clear
=
243 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
244 hdmi
->variant
->field_ddc_fifo_clear
);
245 if (IS_ERR(hdmi
->field_ddc_fifo_clear
))
246 return PTR_ERR(hdmi
->field_ddc_fifo_clear
);
248 hdmi
->field_ddc_fifo_rx_thres
=
249 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
250 hdmi
->variant
->field_ddc_fifo_rx_thres
);
251 if (IS_ERR(hdmi
->field_ddc_fifo_rx_thres
))
252 return PTR_ERR(hdmi
->field_ddc_fifo_rx_thres
);
254 hdmi
->field_ddc_fifo_tx_thres
=
255 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
256 hdmi
->variant
->field_ddc_fifo_tx_thres
);
257 if (IS_ERR(hdmi
->field_ddc_fifo_tx_thres
))
258 return PTR_ERR(hdmi
->field_ddc_fifo_tx_thres
);
260 hdmi
->field_ddc_byte_count
=
261 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
262 hdmi
->variant
->field_ddc_byte_count
);
263 if (IS_ERR(hdmi
->field_ddc_byte_count
))
264 return PTR_ERR(hdmi
->field_ddc_byte_count
);
266 hdmi
->field_ddc_cmd
=
267 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
268 hdmi
->variant
->field_ddc_cmd
);
269 if (IS_ERR(hdmi
->field_ddc_cmd
))
270 return PTR_ERR(hdmi
->field_ddc_cmd
);
272 hdmi
->field_ddc_sda_en
=
273 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
274 hdmi
->variant
->field_ddc_sda_en
);
275 if (IS_ERR(hdmi
->field_ddc_sda_en
))
276 return PTR_ERR(hdmi
->field_ddc_sda_en
);
278 hdmi
->field_ddc_sck_en
=
279 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
280 hdmi
->variant
->field_ddc_sck_en
);
281 if (IS_ERR(hdmi
->field_ddc_sck_en
))
282 return PTR_ERR(hdmi
->field_ddc_sck_en
);
287 int sun4i_hdmi_i2c_create(struct device
*dev
, struct sun4i_hdmi
*hdmi
)
289 struct i2c_adapter
*adap
;
292 ret
= sun4i_ddc_create(hdmi
, hdmi
->ddc_parent_clk
);
296 ret
= sun4i_hdmi_init_regmap_fields(hdmi
);
300 adap
= devm_kzalloc(dev
, sizeof(*adap
), GFP_KERNEL
);
304 adap
->owner
= THIS_MODULE
;
305 adap
->class = I2C_CLASS_DDC
;
306 adap
->algo
= &sun4i_hdmi_i2c_algorithm
;
307 strlcpy(adap
->name
, "sun4i_hdmi_i2c adapter", sizeof(adap
->name
));
308 i2c_set_adapdata(adap
, hdmi
);
310 ret
= i2c_add_adapter(adap
);