1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * adv7511_cec.c - Analog Devices ADV7511/33 cec driver
4 *
5 * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 */
7
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/clk.h>
12
13 #include <media/cec.h>
14
15 #include <drm/display/drm_hdmi_cec_helper.h>
16
17 #include "adv7511.h"
18
19 static const u8 ADV7511_REG_CEC_RX_FRAME_HDR[] = {
20 ADV7511_REG_CEC_RX1_FRAME_HDR,
21 ADV7511_REG_CEC_RX2_FRAME_HDR,
22 ADV7511_REG_CEC_RX3_FRAME_HDR,
23 };
24
25 static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = {
26 ADV7511_REG_CEC_RX1_FRAME_LEN,
27 ADV7511_REG_CEC_RX2_FRAME_LEN,
28 ADV7511_REG_CEC_RX3_FRAME_LEN,
29 };
30
31 #define ADV7511_INT1_CEC_MASK \
32 (ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | \
33 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT | ADV7511_INT1_CEC_RX_READY1 | \
34 ADV7511_INT1_CEC_RX_READY2 | ADV7511_INT1_CEC_RX_READY3)
35
adv_cec_tx_raw_status(struct adv7511 * adv7511,u8 tx_raw_status)36 static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status)
37 {
38 unsigned int offset = adv7511->info->reg_cec_offset;
39 unsigned int val;
40
41 if (regmap_read(adv7511->regmap_cec,
42 ADV7511_REG_CEC_TX_ENABLE + offset, &val))
43 return;
44
45 if ((val & 0x01) == 0)
46 return;
47
48 if (tx_raw_status & ADV7511_INT1_CEC_TX_ARBIT_LOST) {
49 drm_connector_hdmi_cec_transmit_attempt_done(adv7511->cec_connector,
50 CEC_TX_STATUS_ARB_LOST);
51 return;
52 }
53 if (tx_raw_status & ADV7511_INT1_CEC_TX_RETRY_TIMEOUT) {
54 u8 status;
55 u8 err_cnt = 0;
56 u8 nack_cnt = 0;
57 u8 low_drive_cnt = 0;
58 unsigned int cnt;
59
60 /*
61 * We set this status bit since this hardware performs
62 * retransmissions.
63 */
64 status = CEC_TX_STATUS_MAX_RETRIES;
65 if (regmap_read(adv7511->regmap_cec,
66 ADV7511_REG_CEC_TX_LOW_DRV_CNT + offset, &cnt)) {
67 err_cnt = 1;
68 status |= CEC_TX_STATUS_ERROR;
69 } else {
70 nack_cnt = cnt & 0xf;
71 if (nack_cnt)
72 status |= CEC_TX_STATUS_NACK;
73 low_drive_cnt = cnt >> 4;
74 if (low_drive_cnt)
75 status |= CEC_TX_STATUS_LOW_DRIVE;
76 }
77 drm_connector_hdmi_cec_transmit_done(adv7511->cec_connector, status,
78 0, nack_cnt, low_drive_cnt,
79 err_cnt);
80 return;
81 }
82 if (tx_raw_status & ADV7511_INT1_CEC_TX_READY) {
83 drm_connector_hdmi_cec_transmit_attempt_done(adv7511->cec_connector,
84 CEC_TX_STATUS_OK);
85 return;
86 }
87 }
88
adv7511_cec_rx(struct adv7511 * adv7511,int rx_buf)89 static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf)
90 {
91 unsigned int offset = adv7511->info->reg_cec_offset;
92 struct cec_msg msg = {};
93 unsigned int len;
94 unsigned int val;
95 u8 i;
96
97 if (regmap_read(adv7511->regmap_cec,
98 ADV7511_REG_CEC_RX_FRAME_LEN[rx_buf] + offset, &len))
99 return;
100
101 msg.len = len & 0x1f;
102
103 if (msg.len > 16)
104 msg.len = 16;
105
106 if (!msg.len)
107 return;
108
109 for (i = 0; i < msg.len; i++) {
110 regmap_read(adv7511->regmap_cec,
111 i + ADV7511_REG_CEC_RX_FRAME_HDR[rx_buf] + offset,
112 &val);
113 msg.msg[i] = val;
114 }
115
116 /* Toggle RX Ready Clear bit to re-enable this RX buffer */
117 regmap_update_bits(adv7511->regmap_cec,
118 ADV7511_REG_CEC_RX_BUFFERS + offset, BIT(rx_buf),
119 BIT(rx_buf));
120 regmap_update_bits(adv7511->regmap_cec,
121 ADV7511_REG_CEC_RX_BUFFERS + offset, BIT(rx_buf), 0);
122
123 drm_connector_hdmi_cec_received_msg(adv7511->cec_connector, &msg);
124 }
125
adv7511_cec_irq_process(struct adv7511 * adv7511,unsigned int irq1)126 int adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
127 {
128 unsigned int offset = adv7511->info->reg_cec_offset;
129 const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY |
130 ADV7511_INT1_CEC_TX_ARBIT_LOST |
131 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT;
132 const u32 irq_rx_mask = ADV7511_INT1_CEC_RX_READY1 |
133 ADV7511_INT1_CEC_RX_READY2 |
134 ADV7511_INT1_CEC_RX_READY3;
135 unsigned int rx_status;
136 int rx_order[3] = { -1, -1, -1 };
137 int i;
138 int irq_status = IRQ_NONE;
139
140 if (irq1 & irq_tx_mask) {
141 adv_cec_tx_raw_status(adv7511, irq1);
142 irq_status = IRQ_HANDLED;
143 }
144
145 if (!(irq1 & irq_rx_mask))
146 return irq_status;
147
148 if (regmap_read(adv7511->regmap_cec,
149 ADV7511_REG_CEC_RX_STATUS + offset, &rx_status))
150 return irq_status;
151
152 /*
153 * ADV7511_REG_CEC_RX_STATUS[5:0] contains the reception order of RX
154 * buffers 0, 1, and 2 in bits [1:0], [3:2], and [5:4] respectively.
155 * The values are to be interpreted as follows:
156 *
157 * 0 = buffer unused
158 * 1 = buffer contains oldest received frame (if applicable)
159 * 2 = buffer contains second oldest received frame (if applicable)
160 * 3 = buffer contains third oldest received frame (if applicable)
161 *
162 * Fill rx_order with the sequence of RX buffer indices to
163 * read from in order, where -1 indicates that there are no
164 * more buffers to process.
165 */
166 for (i = 0; i < 3; i++) {
167 unsigned int timestamp = (rx_status >> (2 * i)) & 0x3;
168
169 if (timestamp)
170 rx_order[timestamp - 1] = i;
171 }
172
173 /* Read CEC RX buffers in the appropriate order as prescribed above */
174 for (i = 0; i < 3; i++) {
175 int rx_buf = rx_order[i];
176
177 if (rx_buf < 0)
178 break;
179
180 adv7511_cec_rx(adv7511, rx_buf);
181 }
182
183 return IRQ_HANDLED;
184 }
185
adv7511_cec_enable(struct drm_bridge * bridge,bool enable)186 int adv7511_cec_enable(struct drm_bridge *bridge, bool enable)
187 {
188 struct adv7511 *adv7511 = bridge_to_adv7511(bridge);
189 unsigned int offset = adv7511->info->reg_cec_offset;
190
191 if (adv7511->i2c_cec == NULL)
192 return -EIO;
193
194 if (!adv7511->cec_enabled_adap && enable) {
195 /* power up cec section */
196 regmap_update_bits(adv7511->regmap_cec,
197 ADV7511_REG_CEC_CLK_DIV + offset,
198 0x03, 0x01);
199 /* non-legacy mode and clear all rx buffers */
200 regmap_write(adv7511->regmap_cec,
201 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x0f);
202 regmap_write(adv7511->regmap_cec,
203 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x08);
204 /* initially disable tx */
205 regmap_update_bits(adv7511->regmap_cec,
206 ADV7511_REG_CEC_TX_ENABLE + offset, 1, 0);
207 /* enabled irqs: */
208 /* tx: ready */
209 /* tx: arbitration lost */
210 /* tx: retry timeout */
211 /* rx: ready 1-3 */
212 regmap_update_bits(adv7511->regmap,
213 ADV7511_REG_INT_ENABLE(1), 0x3f,
214 ADV7511_INT1_CEC_MASK);
215 } else if (adv7511->cec_enabled_adap && !enable) {
216 regmap_update_bits(adv7511->regmap,
217 ADV7511_REG_INT_ENABLE(1), 0x3f, 0);
218 /* disable address mask 1-3 */
219 regmap_update_bits(adv7511->regmap_cec,
220 ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
221 0x70, 0x00);
222 /* power down cec section */
223 regmap_update_bits(adv7511->regmap_cec,
224 ADV7511_REG_CEC_CLK_DIV + offset,
225 0x03, 0x00);
226 adv7511->cec_valid_addrs = 0;
227 }
228 adv7511->cec_enabled_adap = enable;
229 return 0;
230 }
231
adv7511_cec_log_addr(struct drm_bridge * bridge,u8 addr)232 int adv7511_cec_log_addr(struct drm_bridge *bridge, u8 addr)
233 {
234 struct adv7511 *adv7511 = bridge_to_adv7511(bridge);
235 unsigned int offset = adv7511->info->reg_cec_offset;
236 unsigned int i, free_idx = ADV7511_MAX_ADDRS;
237
238 if (!adv7511->cec_enabled_adap)
239 return addr == CEC_LOG_ADDR_INVALID ? 0 : -EIO;
240
241 if (addr == CEC_LOG_ADDR_INVALID) {
242 regmap_update_bits(adv7511->regmap_cec,
243 ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
244 0x70, 0);
245 adv7511->cec_valid_addrs = 0;
246 return 0;
247 }
248
249 for (i = 0; i < ADV7511_MAX_ADDRS; i++) {
250 bool is_valid = adv7511->cec_valid_addrs & (1 << i);
251
252 if (free_idx == ADV7511_MAX_ADDRS && !is_valid)
253 free_idx = i;
254 if (is_valid && adv7511->cec_addr[i] == addr)
255 return 0;
256 }
257 if (i == ADV7511_MAX_ADDRS) {
258 i = free_idx;
259 if (i == ADV7511_MAX_ADDRS)
260 return -ENXIO;
261 }
262 adv7511->cec_addr[i] = addr;
263 adv7511->cec_valid_addrs |= 1 << i;
264
265 switch (i) {
266 case 0:
267 /* enable address mask 0 */
268 regmap_update_bits(adv7511->regmap_cec,
269 ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
270 0x10, 0x10);
271 /* set address for mask 0 */
272 regmap_update_bits(adv7511->regmap_cec,
273 ADV7511_REG_CEC_LOG_ADDR_0_1 + offset,
274 0x0f, addr);
275 break;
276 case 1:
277 /* enable address mask 1 */
278 regmap_update_bits(adv7511->regmap_cec,
279 ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
280 0x20, 0x20);
281 /* set address for mask 1 */
282 regmap_update_bits(adv7511->regmap_cec,
283 ADV7511_REG_CEC_LOG_ADDR_0_1 + offset,
284 0xf0, addr << 4);
285 break;
286 case 2:
287 /* enable address mask 2 */
288 regmap_update_bits(adv7511->regmap_cec,
289 ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
290 0x40, 0x40);
291 /* set address for mask 1 */
292 regmap_update_bits(adv7511->regmap_cec,
293 ADV7511_REG_CEC_LOG_ADDR_2 + offset,
294 0x0f, addr);
295 break;
296 }
297 return 0;
298 }
299
adv7511_cec_transmit(struct drm_bridge * bridge,u8 attempts,u32 signal_free_time,struct cec_msg * msg)300 int adv7511_cec_transmit(struct drm_bridge *bridge, u8 attempts,
301 u32 signal_free_time, struct cec_msg *msg)
302 {
303 struct adv7511 *adv7511 = bridge_to_adv7511(bridge);
304 unsigned int offset = adv7511->info->reg_cec_offset;
305 u8 len = msg->len;
306 unsigned int i;
307
308 /*
309 * The number of retries is the number of attempts - 1, but retry
310 * at least once. It's not clear if a value of 0 is allowed, so
311 * let's do at least one retry.
312 */
313 regmap_update_bits(adv7511->regmap_cec,
314 ADV7511_REG_CEC_TX_RETRY + offset,
315 0x70, max(1, attempts - 1) << 4);
316
317 /* blocking, clear cec tx irq status */
318 regmap_update_bits(adv7511->regmap, ADV7511_REG_INT(1), 0x38, 0x38);
319
320 /* write data */
321 for (i = 0; i < len; i++)
322 regmap_write(adv7511->regmap_cec,
323 i + ADV7511_REG_CEC_TX_FRAME_HDR + offset,
324 msg->msg[i]);
325
326 /* set length (data + header) */
327 regmap_write(adv7511->regmap_cec,
328 ADV7511_REG_CEC_TX_FRAME_LEN + offset, len);
329 /* start transmit, enable tx */
330 regmap_write(adv7511->regmap_cec,
331 ADV7511_REG_CEC_TX_ENABLE + offset, 0x01);
332 return 0;
333 }
334
adv7511_cec_parse_dt(struct device * dev,struct adv7511 * adv7511)335 static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511)
336 {
337 adv7511->cec_clk = devm_clk_get(dev, "cec");
338 if (IS_ERR(adv7511->cec_clk)) {
339 int ret = PTR_ERR(adv7511->cec_clk);
340
341 adv7511->cec_clk = NULL;
342 return ret;
343 }
344 clk_prepare_enable(adv7511->cec_clk);
345 adv7511->cec_clk_freq = clk_get_rate(adv7511->cec_clk);
346 return 0;
347 }
348
adv7511_cec_init(struct drm_bridge * bridge,struct drm_connector * connector)349 int adv7511_cec_init(struct drm_bridge *bridge,
350 struct drm_connector *connector)
351 {
352 struct adv7511 *adv7511 = bridge_to_adv7511(bridge);
353 struct device *dev = &adv7511->i2c_main->dev;
354 unsigned int offset = adv7511->info->reg_cec_offset;
355 int ret = adv7511_cec_parse_dt(dev, adv7511);
356
357 if (ret)
358 goto err_cec_parse_dt;
359
360 adv7511->cec_connector = connector;
361
362 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 0);
363 /* cec soft reset */
364 regmap_write(adv7511->regmap_cec,
365 ADV7511_REG_CEC_SOFT_RESET + offset, 0x01);
366 regmap_write(adv7511->regmap_cec,
367 ADV7511_REG_CEC_SOFT_RESET + offset, 0x00);
368
369 /* non-legacy mode - use all three RX buffers */
370 regmap_write(adv7511->regmap_cec,
371 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x08);
372
373 regmap_write(adv7511->regmap_cec,
374 ADV7511_REG_CEC_CLK_DIV + offset,
375 ((adv7511->cec_clk_freq / 750000) - 1) << 2);
376
377 return 0;
378
379 err_cec_parse_dt:
380 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
381 ADV7511_CEC_CTRL_POWER_DOWN);
382 return ret == -EPROBE_DEFER ? ret : 0;
383 }
384