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/of_device.h>
11 #include <linux/slab.h>
12 #include <linux/clk.h>
13 
14 #include <media/cec.h>
15 
16 #include "adv7511.h"
17 
18 #define ADV7511_INT1_CEC_MASK \
19 	(ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | \
20 	 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT | ADV7511_INT1_CEC_RX_READY1)
21 
22 static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status)
23 {
24 	unsigned int offset = adv7511->type == ADV7533 ?
25 					ADV7533_REG_CEC_OFFSET : 0;
26 	unsigned int val;
27 
28 	if (regmap_read(adv7511->regmap_cec,
29 			ADV7511_REG_CEC_TX_ENABLE + offset, &val))
30 		return;
31 
32 	if ((val & 0x01) == 0)
33 		return;
34 
35 	if (tx_raw_status & ADV7511_INT1_CEC_TX_ARBIT_LOST) {
36 		cec_transmit_attempt_done(adv7511->cec_adap,
37 					  CEC_TX_STATUS_ARB_LOST);
38 		return;
39 	}
40 	if (tx_raw_status & ADV7511_INT1_CEC_TX_RETRY_TIMEOUT) {
41 		u8 status;
42 		u8 err_cnt = 0;
43 		u8 nack_cnt = 0;
44 		u8 low_drive_cnt = 0;
45 		unsigned int cnt;
46 
47 		/*
48 		 * We set this status bit since this hardware performs
49 		 * retransmissions.
50 		 */
51 		status = CEC_TX_STATUS_MAX_RETRIES;
52 		if (regmap_read(adv7511->regmap_cec,
53 			    ADV7511_REG_CEC_TX_LOW_DRV_CNT + offset, &cnt)) {
54 			err_cnt = 1;
55 			status |= CEC_TX_STATUS_ERROR;
56 		} else {
57 			nack_cnt = cnt & 0xf;
58 			if (nack_cnt)
59 				status |= CEC_TX_STATUS_NACK;
60 			low_drive_cnt = cnt >> 4;
61 			if (low_drive_cnt)
62 				status |= CEC_TX_STATUS_LOW_DRIVE;
63 		}
64 		cec_transmit_done(adv7511->cec_adap, status,
65 				  0, nack_cnt, low_drive_cnt, err_cnt);
66 		return;
67 	}
68 	if (tx_raw_status & ADV7511_INT1_CEC_TX_READY) {
69 		cec_transmit_attempt_done(adv7511->cec_adap, CEC_TX_STATUS_OK);
70 		return;
71 	}
72 }
73 
74 void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
75 {
76 	unsigned int offset = adv7511->type == ADV7533 ?
77 					ADV7533_REG_CEC_OFFSET : 0;
78 	const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY |
79 				ADV7511_INT1_CEC_TX_ARBIT_LOST |
80 				ADV7511_INT1_CEC_TX_RETRY_TIMEOUT;
81 	struct cec_msg msg = {};
82 	unsigned int len;
83 	unsigned int val;
84 	u8 i;
85 
86 	if (irq1 & irq_tx_mask)
87 		adv_cec_tx_raw_status(adv7511, irq1);
88 
89 	if (!(irq1 & ADV7511_INT1_CEC_RX_READY1))
90 		return;
91 
92 	if (regmap_read(adv7511->regmap_cec,
93 			ADV7511_REG_CEC_RX_FRAME_LEN + offset, &len))
94 		return;
95 
96 	msg.len = len & 0x1f;
97 
98 	if (msg.len > 16)
99 		msg.len = 16;
100 
101 	if (!msg.len)
102 		return;
103 
104 	for (i = 0; i < msg.len; i++) {
105 		regmap_read(adv7511->regmap_cec,
106 			    i + ADV7511_REG_CEC_RX_FRAME_HDR + offset, &val);
107 		msg.msg[i] = val;
108 	}
109 
110 	/* toggle to re-enable rx 1 */
111 	regmap_write(adv7511->regmap_cec,
112 		     ADV7511_REG_CEC_RX_BUFFERS + offset, 1);
113 	regmap_write(adv7511->regmap_cec,
114 		     ADV7511_REG_CEC_RX_BUFFERS + offset, 0);
115 	cec_received_msg(adv7511->cec_adap, &msg);
116 }
117 
118 static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
119 {
120 	struct adv7511 *adv7511 = cec_get_drvdata(adap);
121 	unsigned int offset = adv7511->type == ADV7533 ?
122 					ADV7533_REG_CEC_OFFSET : 0;
123 
124 	if (adv7511->i2c_cec == NULL)
125 		return -EIO;
126 
127 	if (!adv7511->cec_enabled_adap && enable) {
128 		/* power up cec section */
129 		regmap_update_bits(adv7511->regmap_cec,
130 				   ADV7511_REG_CEC_CLK_DIV + offset,
131 				   0x03, 0x01);
132 		/* legacy mode and clear all rx buffers */
133 		regmap_write(adv7511->regmap_cec,
134 			     ADV7511_REG_CEC_RX_BUFFERS + offset, 0x07);
135 		regmap_write(adv7511->regmap_cec,
136 			     ADV7511_REG_CEC_RX_BUFFERS + offset, 0);
137 		/* initially disable tx */
138 		regmap_update_bits(adv7511->regmap_cec,
139 				   ADV7511_REG_CEC_TX_ENABLE + offset, 1, 0);
140 		/* enabled irqs: */
141 		/* tx: ready */
142 		/* tx: arbitration lost */
143 		/* tx: retry timeout */
144 		/* rx: ready 1 */
145 		regmap_update_bits(adv7511->regmap,
146 				   ADV7511_REG_INT_ENABLE(1), 0x3f,
147 				   ADV7511_INT1_CEC_MASK);
148 	} else if (adv7511->cec_enabled_adap && !enable) {
149 		regmap_update_bits(adv7511->regmap,
150 				   ADV7511_REG_INT_ENABLE(1), 0x3f, 0);
151 		/* disable address mask 1-3 */
152 		regmap_update_bits(adv7511->regmap_cec,
153 				   ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
154 				   0x70, 0x00);
155 		/* power down cec section */
156 		regmap_update_bits(adv7511->regmap_cec,
157 				   ADV7511_REG_CEC_CLK_DIV + offset,
158 				   0x03, 0x00);
159 		adv7511->cec_valid_addrs = 0;
160 	}
161 	adv7511->cec_enabled_adap = enable;
162 	return 0;
163 }
164 
165 static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
166 {
167 	struct adv7511 *adv7511 = cec_get_drvdata(adap);
168 	unsigned int offset = adv7511->type == ADV7533 ?
169 					ADV7533_REG_CEC_OFFSET : 0;
170 	unsigned int i, free_idx = ADV7511_MAX_ADDRS;
171 
172 	if (!adv7511->cec_enabled_adap)
173 		return addr == CEC_LOG_ADDR_INVALID ? 0 : -EIO;
174 
175 	if (addr == CEC_LOG_ADDR_INVALID) {
176 		regmap_update_bits(adv7511->regmap_cec,
177 				   ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
178 				   0x70, 0);
179 		adv7511->cec_valid_addrs = 0;
180 		return 0;
181 	}
182 
183 	for (i = 0; i < ADV7511_MAX_ADDRS; i++) {
184 		bool is_valid = adv7511->cec_valid_addrs & (1 << i);
185 
186 		if (free_idx == ADV7511_MAX_ADDRS && !is_valid)
187 			free_idx = i;
188 		if (is_valid && adv7511->cec_addr[i] == addr)
189 			return 0;
190 	}
191 	if (i == ADV7511_MAX_ADDRS) {
192 		i = free_idx;
193 		if (i == ADV7511_MAX_ADDRS)
194 			return -ENXIO;
195 	}
196 	adv7511->cec_addr[i] = addr;
197 	adv7511->cec_valid_addrs |= 1 << i;
198 
199 	switch (i) {
200 	case 0:
201 		/* enable address mask 0 */
202 		regmap_update_bits(adv7511->regmap_cec,
203 				   ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
204 				   0x10, 0x10);
205 		/* set address for mask 0 */
206 		regmap_update_bits(adv7511->regmap_cec,
207 				   ADV7511_REG_CEC_LOG_ADDR_0_1 + offset,
208 				   0x0f, addr);
209 		break;
210 	case 1:
211 		/* enable address mask 1 */
212 		regmap_update_bits(adv7511->regmap_cec,
213 				   ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
214 				   0x20, 0x20);
215 		/* set address for mask 1 */
216 		regmap_update_bits(adv7511->regmap_cec,
217 				   ADV7511_REG_CEC_LOG_ADDR_0_1 + offset,
218 				   0xf0, addr << 4);
219 		break;
220 	case 2:
221 		/* enable address mask 2 */
222 		regmap_update_bits(adv7511->regmap_cec,
223 				   ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
224 				   0x40, 0x40);
225 		/* set address for mask 1 */
226 		regmap_update_bits(adv7511->regmap_cec,
227 				   ADV7511_REG_CEC_LOG_ADDR_2 + offset,
228 				   0x0f, addr);
229 		break;
230 	}
231 	return 0;
232 }
233 
234 static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
235 				     u32 signal_free_time, struct cec_msg *msg)
236 {
237 	struct adv7511 *adv7511 = cec_get_drvdata(adap);
238 	unsigned int offset = adv7511->type == ADV7533 ?
239 					ADV7533_REG_CEC_OFFSET : 0;
240 	u8 len = msg->len;
241 	unsigned int i;
242 
243 	/*
244 	 * The number of retries is the number of attempts - 1, but retry
245 	 * at least once. It's not clear if a value of 0 is allowed, so
246 	 * let's do at least one retry.
247 	 */
248 	regmap_update_bits(adv7511->regmap_cec,
249 			   ADV7511_REG_CEC_TX_RETRY + offset,
250 			   0x70, max(1, attempts - 1) << 4);
251 
252 	/* blocking, clear cec tx irq status */
253 	regmap_update_bits(adv7511->regmap, ADV7511_REG_INT(1), 0x38, 0x38);
254 
255 	/* write data */
256 	for (i = 0; i < len; i++)
257 		regmap_write(adv7511->regmap_cec,
258 			     i + ADV7511_REG_CEC_TX_FRAME_HDR + offset,
259 			     msg->msg[i]);
260 
261 	/* set length (data + header) */
262 	regmap_write(adv7511->regmap_cec,
263 		     ADV7511_REG_CEC_TX_FRAME_LEN + offset, len);
264 	/* start transmit, enable tx */
265 	regmap_write(adv7511->regmap_cec,
266 		     ADV7511_REG_CEC_TX_ENABLE + offset, 0x01);
267 	return 0;
268 }
269 
270 static const struct cec_adap_ops adv7511_cec_adap_ops = {
271 	.adap_enable = adv7511_cec_adap_enable,
272 	.adap_log_addr = adv7511_cec_adap_log_addr,
273 	.adap_transmit = adv7511_cec_adap_transmit,
274 };
275 
276 static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511)
277 {
278 	adv7511->cec_clk = devm_clk_get(dev, "cec");
279 	if (IS_ERR(adv7511->cec_clk)) {
280 		int ret = PTR_ERR(adv7511->cec_clk);
281 
282 		adv7511->cec_clk = NULL;
283 		return ret;
284 	}
285 	clk_prepare_enable(adv7511->cec_clk);
286 	adv7511->cec_clk_freq = clk_get_rate(adv7511->cec_clk);
287 	return 0;
288 }
289 
290 int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
291 {
292 	unsigned int offset = adv7511->type == ADV7533 ?
293 						ADV7533_REG_CEC_OFFSET : 0;
294 	int ret = adv7511_cec_parse_dt(dev, adv7511);
295 
296 	if (ret)
297 		goto err_cec_parse_dt;
298 
299 	adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops,
300 		adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS);
301 	if (IS_ERR(adv7511->cec_adap)) {
302 		ret = PTR_ERR(adv7511->cec_adap);
303 		goto err_cec_alloc;
304 	}
305 
306 	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
307 	/* cec soft reset */
308 	regmap_write(adv7511->regmap_cec,
309 		     ADV7511_REG_CEC_SOFT_RESET + offset, 0x01);
310 	regmap_write(adv7511->regmap_cec,
311 		     ADV7511_REG_CEC_SOFT_RESET + offset, 0x00);
312 
313 	/* legacy mode */
314 	regmap_write(adv7511->regmap_cec,
315 		     ADV7511_REG_CEC_RX_BUFFERS + offset, 0x00);
316 
317 	regmap_write(adv7511->regmap_cec,
318 		     ADV7511_REG_CEC_CLK_DIV + offset,
319 		     ((adv7511->cec_clk_freq / 750000) - 1) << 2);
320 
321 	ret = cec_register_adapter(adv7511->cec_adap, dev);
322 	if (ret)
323 		goto err_cec_register;
324 	return 0;
325 
326 err_cec_register:
327 	cec_delete_adapter(adv7511->cec_adap);
328 	adv7511->cec_adap = NULL;
329 err_cec_alloc:
330 	dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
331 		 ret);
332 err_cec_parse_dt:
333 	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
334 		     ADV7511_CEC_CTRL_POWER_DOWN);
335 	return ret == -EPROBE_DEFER ? ret : 0;
336 }
337