xref: /linux/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c (revision 260f6f4fda93c8485c8037865c941b42b9cba5d2)
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