2 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
3 * Copyright (C) 2017 Jonathan Liu <net147@gmail.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
11 #include <linux/clk.h>
12 #include <linux/i2c.h>
13 #include <linux/iopoll.h>
15 #include "sun4i_hdmi.h"
17 #define SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK ( \
18 SUN4I_HDMI_DDC_INT_STATUS_ILLEGAL_FIFO_OPERATION | \
19 SUN4I_HDMI_DDC_INT_STATUS_DDC_RX_FIFO_UNDERFLOW | \
20 SUN4I_HDMI_DDC_INT_STATUS_DDC_TX_FIFO_OVERFLOW | \
21 SUN4I_HDMI_DDC_INT_STATUS_ARBITRATION_ERROR | \
22 SUN4I_HDMI_DDC_INT_STATUS_ACK_ERROR | \
23 SUN4I_HDMI_DDC_INT_STATUS_BUS_ERROR \
26 /* FIFO request bit is set when FIFO level is above RX_THRESHOLD during read */
27 #define RX_THRESHOLD SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MAX
29 static int fifo_transfer(struct sun4i_hdmi
*hdmi
, u8
*buf
, int len
, bool read
)
32 * 1 byte takes 9 clock cycles (8 bits + 1 ACK) = 90 us for 100 kHz
33 * clock. As clock rate is fixed, just round it up to 100 us.
35 const unsigned long byte_time_ns
= 100;
36 const u32 mask
= SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
|
37 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST
|
38 SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE
;
41 * If threshold is inclusive, then the FIFO may only have
42 * RX_THRESHOLD number of bytes, instead of RX_THRESHOLD + 1.
44 int read_len
= RX_THRESHOLD
+
45 (hdmi
->variant
->ddc_fifo_thres_incl
? 0 : 1);
48 * Limit transfer length by FIFO threshold or FIFO size.
49 * For TX the threshold is for an empty FIFO.
51 len
= min_t(int, len
, read
? read_len
: SUN4I_HDMI_DDC_FIFO_SIZE
);
53 /* Wait until error, FIFO request bit set or transfer complete */
54 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_int_status
, reg
,
55 reg
& mask
, len
* byte_time_ns
,
59 if (reg
& SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
)
63 readsb(hdmi
->base
+ hdmi
->variant
->ddc_fifo_reg
, buf
, len
);
65 writesb(hdmi
->base
+ hdmi
->variant
->ddc_fifo_reg
, buf
, len
);
67 /* Clear FIFO request bit by forcing a write to that bit */
68 regmap_field_force_write(hdmi
->field_ddc_int_status
,
69 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST
);
74 static int xfer_msg(struct sun4i_hdmi
*hdmi
, struct i2c_msg
*msg
)
79 /* Set FIFO direction */
80 if (hdmi
->variant
->ddc_fifo_has_dir
) {
81 reg
= readl(hdmi
->base
+ SUN4I_HDMI_DDC_CTRL_REG
);
82 reg
&= ~SUN4I_HDMI_DDC_CTRL_FIFO_DIR_MASK
;
83 reg
|= (msg
->flags
& I2C_M_RD
) ?
84 SUN4I_HDMI_DDC_CTRL_FIFO_DIR_READ
:
85 SUN4I_HDMI_DDC_CTRL_FIFO_DIR_WRITE
;
86 writel(reg
, hdmi
->base
+ SUN4I_HDMI_DDC_CTRL_REG
);
89 /* Clear address register (not cleared by soft reset) */
90 regmap_field_write(hdmi
->field_ddc_addr_reg
, 0);
93 regmap_field_write(hdmi
->field_ddc_slave_addr
, msg
->addr
);
96 * Set FIFO RX/TX thresholds and clear FIFO
98 * If threshold is inclusive, we can set the TX threshold to
101 regmap_field_write(hdmi
->field_ddc_fifo_tx_thres
,
102 hdmi
->variant
->ddc_fifo_thres_incl
? 0 : 1);
103 regmap_field_write(hdmi
->field_ddc_fifo_rx_thres
, RX_THRESHOLD
);
104 regmap_field_write(hdmi
->field_ddc_fifo_clear
, 1);
105 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_fifo_clear
,
106 reg
, !reg
, 100, 2000))
109 /* Set transfer length */
110 regmap_field_write(hdmi
->field_ddc_byte_count
, msg
->len
);
113 regmap_field_write(hdmi
->field_ddc_cmd
,
114 msg
->flags
& I2C_M_RD
?
115 SUN4I_HDMI_DDC_CMD_IMPLICIT_READ
:
116 SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE
);
118 /* Clear interrupt status bits by forcing a write */
119 regmap_field_force_write(hdmi
->field_ddc_int_status
,
120 SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
|
121 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST
|
122 SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE
);
125 regmap_field_write(hdmi
->field_ddc_start
, 1);
128 for (i
= 0; i
< msg
->len
; i
+= len
) {
129 len
= fifo_transfer(hdmi
, msg
->buf
+ i
, msg
->len
- i
,
130 msg
->flags
& I2C_M_RD
);
135 /* Wait for command to finish */
136 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_start
,
137 reg
, !reg
, 100, 100000))
140 /* Check for errors */
141 regmap_field_read(hdmi
->field_ddc_int_status
, ®
);
142 if ((reg
& SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK
) ||
143 !(reg
& SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE
)) {
150 static int sun4i_hdmi_i2c_xfer(struct i2c_adapter
*adap
,
151 struct i2c_msg
*msgs
, int num
)
153 struct sun4i_hdmi
*hdmi
= i2c_get_adapdata(adap
);
155 int err
, i
, ret
= num
;
157 for (i
= 0; i
< num
; i
++) {
160 if (msgs
[i
].len
> SUN4I_HDMI_DDC_BYTE_COUNT_MAX
)
164 /* DDC clock needs to be enabled for the module to work */
165 clk_prepare_enable(hdmi
->ddc_clk
);
166 clk_set_rate(hdmi
->ddc_clk
, 100000);
168 /* Reset I2C controller */
169 regmap_field_write(hdmi
->field_ddc_en
, 1);
170 regmap_field_write(hdmi
->field_ddc_reset
, 1);
171 if (regmap_field_read_poll_timeout(hdmi
->field_ddc_reset
,
172 reg
, !reg
, 100, 2000)) {
173 clk_disable_unprepare(hdmi
->ddc_clk
);
177 regmap_field_write(hdmi
->field_ddc_sck_en
, 1);
178 regmap_field_write(hdmi
->field_ddc_sda_en
, 1);
180 for (i
= 0; i
< num
; i
++) {
181 err
= xfer_msg(hdmi
, &msgs
[i
]);
188 clk_disable_unprepare(hdmi
->ddc_clk
);
192 static u32
sun4i_hdmi_i2c_func(struct i2c_adapter
*adap
)
194 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
197 static const struct i2c_algorithm sun4i_hdmi_i2c_algorithm
= {
198 .master_xfer
= sun4i_hdmi_i2c_xfer
,
199 .functionality
= sun4i_hdmi_i2c_func
,
202 static int sun4i_hdmi_init_regmap_fields(struct sun4i_hdmi
*hdmi
)
205 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
206 hdmi
->variant
->field_ddc_en
);
207 if (IS_ERR(hdmi
->field_ddc_en
))
208 return PTR_ERR(hdmi
->field_ddc_en
);
210 hdmi
->field_ddc_start
=
211 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
212 hdmi
->variant
->field_ddc_start
);
213 if (IS_ERR(hdmi
->field_ddc_start
))
214 return PTR_ERR(hdmi
->field_ddc_start
);
216 hdmi
->field_ddc_reset
=
217 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
218 hdmi
->variant
->field_ddc_reset
);
219 if (IS_ERR(hdmi
->field_ddc_reset
))
220 return PTR_ERR(hdmi
->field_ddc_reset
);
222 hdmi
->field_ddc_addr_reg
=
223 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
224 hdmi
->variant
->field_ddc_addr_reg
);
225 if (IS_ERR(hdmi
->field_ddc_addr_reg
))
226 return PTR_ERR(hdmi
->field_ddc_addr_reg
);
228 hdmi
->field_ddc_slave_addr
=
229 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
230 hdmi
->variant
->field_ddc_slave_addr
);
231 if (IS_ERR(hdmi
->field_ddc_slave_addr
))
232 return PTR_ERR(hdmi
->field_ddc_slave_addr
);
234 hdmi
->field_ddc_int_mask
=
235 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
236 hdmi
->variant
->field_ddc_int_mask
);
237 if (IS_ERR(hdmi
->field_ddc_int_mask
))
238 return PTR_ERR(hdmi
->field_ddc_int_mask
);
240 hdmi
->field_ddc_int_status
=
241 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
242 hdmi
->variant
->field_ddc_int_status
);
243 if (IS_ERR(hdmi
->field_ddc_int_status
))
244 return PTR_ERR(hdmi
->field_ddc_int_status
);
246 hdmi
->field_ddc_fifo_clear
=
247 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
248 hdmi
->variant
->field_ddc_fifo_clear
);
249 if (IS_ERR(hdmi
->field_ddc_fifo_clear
))
250 return PTR_ERR(hdmi
->field_ddc_fifo_clear
);
252 hdmi
->field_ddc_fifo_rx_thres
=
253 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
254 hdmi
->variant
->field_ddc_fifo_rx_thres
);
255 if (IS_ERR(hdmi
->field_ddc_fifo_rx_thres
))
256 return PTR_ERR(hdmi
->field_ddc_fifo_rx_thres
);
258 hdmi
->field_ddc_fifo_tx_thres
=
259 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
260 hdmi
->variant
->field_ddc_fifo_tx_thres
);
261 if (IS_ERR(hdmi
->field_ddc_fifo_tx_thres
))
262 return PTR_ERR(hdmi
->field_ddc_fifo_tx_thres
);
264 hdmi
->field_ddc_byte_count
=
265 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
266 hdmi
->variant
->field_ddc_byte_count
);
267 if (IS_ERR(hdmi
->field_ddc_byte_count
))
268 return PTR_ERR(hdmi
->field_ddc_byte_count
);
270 hdmi
->field_ddc_cmd
=
271 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
272 hdmi
->variant
->field_ddc_cmd
);
273 if (IS_ERR(hdmi
->field_ddc_cmd
))
274 return PTR_ERR(hdmi
->field_ddc_cmd
);
276 hdmi
->field_ddc_sda_en
=
277 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
278 hdmi
->variant
->field_ddc_sda_en
);
279 if (IS_ERR(hdmi
->field_ddc_sda_en
))
280 return PTR_ERR(hdmi
->field_ddc_sda_en
);
282 hdmi
->field_ddc_sck_en
=
283 devm_regmap_field_alloc(hdmi
->dev
, hdmi
->regmap
,
284 hdmi
->variant
->field_ddc_sck_en
);
285 if (IS_ERR(hdmi
->field_ddc_sck_en
))
286 return PTR_ERR(hdmi
->field_ddc_sck_en
);
291 int sun4i_hdmi_i2c_create(struct device
*dev
, struct sun4i_hdmi
*hdmi
)
293 struct i2c_adapter
*adap
;
296 ret
= sun4i_ddc_create(hdmi
, hdmi
->ddc_parent_clk
);
300 ret
= sun4i_hdmi_init_regmap_fields(hdmi
);
304 adap
= devm_kzalloc(dev
, sizeof(*adap
), GFP_KERNEL
);
308 adap
->owner
= THIS_MODULE
;
309 adap
->class = I2C_CLASS_DDC
;
310 adap
->algo
= &sun4i_hdmi_i2c_algorithm
;
311 strlcpy(adap
->name
, "sun4i_hdmi_i2c adapter", sizeof(adap
->name
));
312 i2c_set_adapdata(adap
, hdmi
);
314 ret
= i2c_add_adapter(adap
);