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