summaryrefslogtreecommitdiff
path: root/drivers/amlogic/cec/hdmi_ao_cec.c (plain)
blob: aa2b4fe0ea77f2f3b7c092cd0c4e7b60c9e73d8e
1/*
2 * drivers/amlogic/cec/hdmi_ao_cec.c
3 *
4 * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 */
16
17#include <asm/irq.h>
18
19#include <linux/version.h>
20#include <linux/module.h>
21#include <linux/irq.h>
22#include <linux/types.h>
23#include <linux/input.h>
24#include <linux/kernel.h>
25#include <linux/kthread.h>
26#include <linux/delay.h>
27#include <linux/uaccess.h>
28#include <linux/interrupt.h>
29#include <linux/fs.h>
30#include <linux/init.h>
31#include <linux/device.h>
32#include <linux/mm.h>
33#include <linux/major.h>
34#include <linux/platform_device.h>
35#include <linux/mutex.h>
36#include <linux/cdev.h>
37#include <linux/io.h>
38#include <linux/slab.h>
39#include <linux/list.h>
40#include <linux/spinlock.h>
41#include <linux/spinlock_types.h>
42#include <linux/workqueue.h>
43#include <linux/timer.h>
44#include <linux/atomic.h>
45#include <linux/of.h>
46#include <linux/of_device.h>
47#include <linux/of_address.h>
48#include <linux/of_irq.h>
49#include <linux/reboot.h>
50#include <linux/notifier.h>
51#include <linux/random.h>
52#include <linux/pinctrl/consumer.h>
53
54#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
55#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h>
56#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
57#include <linux/amlogic/pm.h>
58#include <linux/amlogic/cpu_version.h>
59#include <linux/amlogic/jtag.h>
60
61#ifdef CONFIG_HAS_EARLYSUSPEND
62#include <linux/earlysuspend.h>
63static struct early_suspend aocec_suspend_handler;
64#endif
65
66#include "hdmi_ao_cec.h"
67
68
69#define CEC_FRAME_DELAY msecs_to_jiffies(400)
70#define CEC_DEV_NAME "cec"
71
72#define DEV_TYPE_TV 0
73#define DEV_TYPE_RECORDER 1
74#define DEV_TYPE_RESERVED 2
75#define DEV_TYPE_TUNER 3
76#define DEV_TYPE_PLAYBACK 4
77#define DEV_TYPE_AUDIO_SYSTEM 5
78#define DEV_TYPE_PURE_CEC_SWITCH 6
79#define DEV_TYPE_VIDEO_PROCESSOR 7
80
81#define CEC_POWER_ON (0 << 0)
82#define CEC_EARLY_SUSPEND (1 << 0)
83#define CEC_DEEP_SUSPEND (1 << 1)
84#define CEC_POWER_RESUME (1 << 2)
85
86#define HR_DELAY(n) (ktime_set(0, n * 1000 * 1000))
87#define MAX_INT 0x7ffffff
88
89struct cec_platform_data_s {
90 unsigned int line_bit;/*cec gpio position in reg*/
91 bool ee_to_ao;/*ee cec hw module mv to ao;ao cec delete*/
92};
93
94/* global struct for tx and rx */
95struct ao_cec_dev {
96 unsigned long dev_type;
97 unsigned int port_num;
98 unsigned int arc_port;
99 unsigned int hal_flag;
100 unsigned int phy_addr;
101 unsigned int port_seq;
102 unsigned int cpu_type;
103 unsigned long irq_cec;
104 void __iomem *exit_reg;
105 void __iomem *cec_reg;
106 void __iomem *hdmi_rxreg;
107 void __iomem *hhi_reg;
108 struct hdmitx_dev *tx_dev;
109 struct workqueue_struct *cec_thread;
110 struct device *dbg_dev;
111 const char *pin_name;
112 struct delayed_work cec_work;
113 struct completion rx_ok;
114 struct completion tx_ok;
115 spinlock_t cec_reg_lock;
116 struct mutex cec_mutex;
117 struct mutex cec_ioctl_mutex;
118#ifdef CONFIG_PM
119 int cec_suspend;
120#endif
121 struct vendor_info_data v_data;
122 struct cec_global_info_t cec_info;
123 struct cec_platform_data_s *plat_data;
124};
125
126struct cec_msg_last {
127 unsigned char msg[MAX_MSG];
128 int len;
129 int last_result;
130 unsigned long last_jiffies;
131};
132static struct cec_msg_last *last_cec_msg;
133
134static int phy_addr_test;
135
136/* from android cec hal */
137enum {
138 HDMI_OPTION_WAKEUP = 1,
139 HDMI_OPTION_ENABLE_CEC = 2,
140 HDMI_OPTION_SYSTEM_CEC_CONTROL = 3,
141 HDMI_OPTION_SET_LANG = 5,
142 HDMI_OPTION_SERVICE_FLAG = 16,
143};
144
145static struct ao_cec_dev *cec_dev;
146static int cec_tx_result;
147
148static int cec_line_cnt;
149static struct hrtimer start_bit_check;
150
151static unsigned char rx_msg[MAX_MSG];
152static unsigned char rx_len;
153static unsigned int new_msg;
154static bool wake_ok = 1;
155static bool ee_cec;
156static bool pin_status;
157static bool cec_msg_dbg_en;
158
159#define CEC_ERR(format, args...) \
160 {if (cec_dev->dbg_dev) \
161 dev_err(cec_dev->dbg_dev, format, ##args); \
162 }
163
164#define CEC_INFO(format, args...) \
165 {if (cec_msg_dbg_en && cec_dev->dbg_dev) \
166 dev_info(cec_dev->dbg_dev, format, ##args); \
167 }
168
169static unsigned char msg_log_buf[128] = { 0 };
170
171#define waiting_aocec_free(r) \
172 do {\
173 unsigned long cnt = 0;\
174 while (readl(cec_dev->cec_reg + r) & (1<<23)) {\
175 if (cnt++ == 3500) { \
176 pr_info("waiting aocec %x free time out\n", r);\
177 break;\
178 } \
179 } \
180 } while (0)
181
182static void cec_set_reg_bits(unsigned int addr, unsigned int value,
183 unsigned int offset, unsigned int len)
184{
185 unsigned int data32 = 0;
186
187 data32 = readl(cec_dev->cec_reg + addr);
188 data32 &= ~(((1 << len) - 1) << offset);
189 data32 |= (value & ((1 << len) - 1)) << offset;
190 writel(data32, cec_dev->cec_reg + addr);
191}
192
193unsigned int aocec_rd_reg(unsigned long addr)
194{
195 unsigned int data32;
196 unsigned long flags;
197
198 waiting_aocec_free(AO_CEC_RW_REG);
199 spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
200 data32 = 0;
201 data32 |= 0 << 16; /* [16] cec_reg_wr */
202 data32 |= 0 << 8; /* [15:8] cec_reg_wrdata */
203 data32 |= addr << 0; /* [7:0] cec_reg_addr */
204 writel(data32, cec_dev->cec_reg + AO_CEC_RW_REG);
205
206 waiting_aocec_free(AO_CEC_RW_REG);
207 data32 = ((readl(cec_dev->cec_reg + AO_CEC_RW_REG)) >> 24) & 0xff;
208 spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
209 return data32;
210} /* aocec_rd_reg */
211
212void aocec_wr_reg(unsigned long addr, unsigned long data)
213{
214 unsigned long data32;
215 unsigned long flags;
216
217 waiting_aocec_free(AO_CEC_RW_REG);
218 spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
219 data32 = 0;
220 data32 |= 1 << 16; /* [16] cec_reg_wr */
221 data32 |= data << 8; /* [15:8] cec_reg_wrdata */
222 data32 |= addr << 0; /* [7:0] cec_reg_addr */
223 writel(data32, cec_dev->cec_reg + AO_CEC_RW_REG);
224 spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
225} /* aocec_wr_only_reg */
226
227/*------------for AO_CECB------------------*/
228static unsigned int aocecb_rd_reg(unsigned long addr)
229{
230 unsigned int data32;
231 unsigned long flags;
232
233 spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
234 data32 = 0;
235 data32 |= 0 << 16; /* [16] cec_reg_wr */
236 data32 |= 0 << 8; /* [15:8] cec_reg_wrdata */
237 data32 |= addr << 0; /* [7:0] cec_reg_addr */
238 writel(data32, cec_dev->cec_reg + AO_CECB_RW_REG);
239
240 data32 = ((readl(cec_dev->cec_reg + AO_CECB_RW_REG)) >> 24) & 0xff;
241 spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
242 return data32;
243} /* aocecb_rd_reg */
244
245static void aocecb_wr_reg(unsigned long addr, unsigned long data)
246{
247 unsigned long data32;
248 unsigned long flags;
249
250 spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
251 data32 = 0;
252 data32 |= 1 << 16; /* [16] cec_reg_wr */
253 data32 |= data << 8; /* [15:8] cec_reg_wrdata */
254 data32 |= addr << 0; /* [7:0] cec_reg_addr */
255 writel(data32, cec_dev->cec_reg + AO_CECB_RW_REG);
256 spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
257} /* aocecb_wr_only_reg */
258
259/*----------------- low level for EE cec rx/tx support ----------------*/
260static inline void hdmirx_set_bits_top(uint32_t reg, uint32_t bits,
261 uint32_t start, uint32_t len)
262{
263 unsigned int tmp;
264
265 tmp = hdmirx_rd_top(reg);
266 tmp &= ~(((1 << len) - 1) << start);
267 tmp |= (bits << start);
268 hdmirx_wr_top(reg, tmp);
269}
270
271static unsigned int hdmirx_cec_read(unsigned int reg)
272{
273 /*
274 * TXLX has moved ee cec to ao domain
275 */
276 if (reg >= DWC_CEC_CTRL && cec_dev->plat_data->ee_to_ao)
277 return aocecb_rd_reg((reg - DWC_CEC_CTRL) / 4);
278 else
279 return hdmirx_rd_dwc(reg);
280}
281
282/*only for ee cec*/
283static void hdmirx_cec_write(unsigned int reg, unsigned int value)
284{
285 /*
286 * TXLX has moved ee cec to ao domain
287 */
288 if (reg >= DWC_CEC_CTRL && cec_dev->plat_data->ee_to_ao)
289 aocecb_wr_reg((reg - DWC_CEC_CTRL) / 4, value);
290 else
291 hdmirx_wr_dwc(reg, value);
292}
293
294static inline void hdmirx_set_bits_dwc(uint32_t reg, uint32_t bits,
295 uint32_t start, uint32_t len)
296{
297 unsigned int tmp;
298
299 tmp = hdmirx_cec_read(reg);
300 tmp &= ~(((1 << len) - 1) << start);
301 tmp |= (bits << start);
302 hdmirx_cec_write(reg, tmp);
303}
304
305void cecrx_hw_reset(void)
306{
307 /* cec disable */
308 if (!cec_dev->plat_data->ee_to_ao)
309 hdmirx_set_bits_dwc(DWC_DMI_DISABLE_IF, 0, 5, 1);
310 else
311 cec_set_reg_bits(AO_CECB_GEN_CNTL, 0, 0, 1);
312 udelay(500);
313}
314
315static void cecrx_check_irq_enable(void)
316{
317 unsigned int reg32;
318
319 /* irq on chip txlx has sperate from EE cec, no need check */
320 if (cec_dev->plat_data->ee_to_ao)
321 return;
322
323 reg32 = hdmirx_cec_read(DWC_AUD_CEC_IEN);
324 if ((reg32 & EE_CEC_IRQ_EN_MASK) != EE_CEC_IRQ_EN_MASK) {
325 CEC_INFO("irq_en is wrong:%x, checker:%pf\n",
326 reg32, (void *)_RET_IP_);
327 hdmirx_cec_write(DWC_AUD_CEC_IEN_SET, EE_CEC_IRQ_EN_MASK);
328 }
329}
330
331static int cecrx_trigle_tx(const unsigned char *msg, unsigned char len)
332{
333 int i = 0, size = 0;
334 int lock;
335
336 cecrx_check_irq_enable();
337 while (1) {
338 /* send is in process */
339 lock = hdmirx_cec_read(DWC_CEC_LOCK);
340 if (lock) {
341 CEC_ERR("recevie msg in tx\n");
342 cecrx_irq_handle();
343 return -1;
344 }
345 if (hdmirx_cec_read(DWC_CEC_CTRL) & 0x01)
346 i++;
347 else
348 break;
349 if (i > 25) {
350 CEC_ERR("waiting busy timeout\n");
351 return -1;
352 }
353 msleep(20);
354 }
355 size += sprintf(msg_log_buf + size, "CEC tx msg len %d:", len);
356 for (i = 0; i < len; i++) {
357 hdmirx_cec_write(DWC_CEC_TX_DATA0 + i * 4, msg[i]);
358 size += sprintf(msg_log_buf + size, " %02x", msg[i]);
359 }
360 msg_log_buf[size] = '\0';
361 CEC_INFO("%s\n", msg_log_buf);
362 /* start send */
363 hdmirx_cec_write(DWC_CEC_TX_CNT, len);
364 hdmirx_set_bits_dwc(DWC_CEC_CTRL, 3, 0, 3);
365 return 0;
366}
367
368int cec_has_irq(void)
369{
370 unsigned int intr_cec;
371
372 if (!cec_dev->plat_data->ee_to_ao) {
373 intr_cec = hdmirx_cec_read(DWC_AUD_CEC_ISTS);
374 intr_cec &= EE_CEC_IRQ_EN_MASK;
375 } else {
376 intr_cec = readl(cec_dev->cec_reg + AO_CECB_INTR_STAT);
377 intr_cec &= CECB_IRQ_EN_MASK;
378 }
379 return intr_cec;
380}
381
382static inline void cecrx_clear_irq(unsigned int flags)
383{
384 if (!cec_dev->plat_data->ee_to_ao)
385 hdmirx_cec_write(DWC_AUD_CEC_ICLR, flags);
386 else
387 writel(flags, cec_dev->cec_reg + AO_CECB_INTR_CLR);
388}
389
390static int cec_pick_msg(unsigned char *msg, unsigned char *out_len)
391{
392 int i, size;
393 int len;
394 struct delayed_work *dwork;
395
396 dwork = &cec_dev->cec_work;
397
398 len = hdmirx_cec_read(DWC_CEC_RX_CNT);
399 size = sprintf(msg_log_buf, "CEC RX len %d:", len);
400 for (i = 0; i < len; i++) {
401 msg[i] = hdmirx_cec_read(DWC_CEC_RX_DATA0 + i * 4);
402 size += sprintf(msg_log_buf + size, " %02x", msg[i]);
403 }
404 size += sprintf(msg_log_buf + size, "\n");
405 msg_log_buf[size] = '\0';
406 /* clr CEC lock bit */
407 hdmirx_cec_write(DWC_CEC_LOCK, 0);
408 mod_delayed_work(cec_dev->cec_thread, dwork, 0);
409 CEC_INFO("%s", msg_log_buf);
410 if (((msg[0] & 0xf0) >> 4) == cec_dev->cec_info.log_addr) {
411 *out_len = 0;
412 CEC_ERR("bad iniator with self:%s", msg_log_buf);
413 } else
414 *out_len = len;
415 pin_status = 1;
416 return 0;
417}
418
419void cecrx_irq_handle(void)
420{
421 uint32_t intr_cec;
422 uint32_t lock;
423 int shift = 0;
424
425 intr_cec = cec_has_irq();
426
427 /* clear irq */
428 if (intr_cec != 0)
429 cecrx_clear_irq(intr_cec);
430
431 if (!ee_cec)
432 return;
433
434 if (cec_dev->plat_data->ee_to_ao)
435 shift = 16;
436 /* TX DONE irq, increase tx buffer pointer */
437 if (intr_cec & CEC_IRQ_TX_DONE) {
438 cec_tx_result = CEC_FAIL_NONE;
439 complete(&cec_dev->tx_ok);
440 }
441 lock = hdmirx_cec_read(DWC_CEC_LOCK);
442 /* EOM irq, message is coming */
443 if ((intr_cec & CEC_IRQ_RX_EOM) || lock) {
444 cec_pick_msg(rx_msg, &rx_len);
445 complete(&cec_dev->rx_ok);
446 }
447
448 /* TX error irq flags */
449 if ((intr_cec & CEC_IRQ_TX_NACK) ||
450 (intr_cec & CEC_IRQ_TX_ARB_LOST) ||
451 (intr_cec & CEC_IRQ_TX_ERR_INITIATOR)) {
452 if (!(intr_cec & CEC_IRQ_TX_NACK))
453 CEC_ERR("tx msg failed, flag:%08x\n", intr_cec);
454 if (intr_cec & CEC_IRQ_TX_NACK)
455 cec_tx_result = CEC_FAIL_NACK;
456 else if (intr_cec & CEC_IRQ_TX_ARB_LOST) {
457 cec_tx_result = CEC_FAIL_BUSY;
458 /* clear start */
459 hdmirx_cec_write(DWC_CEC_TX_CNT, 0);
460 hdmirx_set_bits_dwc(DWC_CEC_CTRL, 0, 0, 3);
461 } else
462 cec_tx_result = CEC_FAIL_OTHER;
463 complete(&cec_dev->tx_ok);
464 }
465
466 /* RX error irq flag */
467 if (intr_cec & CEC_IRQ_RX_ERR_FOLLOWER) {
468 CEC_ERR("rx msg failed\n");
469 /* TODO: need reset cec hw logic? */
470 }
471
472 if (intr_cec & CEC_IRQ_RX_WAKEUP) {
473 CEC_INFO("rx wake up\n");
474 hdmirx_cec_write(DWC_CEC_WKUPCTRL, 0);
475 /* TODO: wake up system if needed */
476 }
477}
478
479static irqreturn_t cecrx_isr(int irq, void *dev_instance)
480{
481 cecrx_irq_handle();
482 return IRQ_HANDLED;
483}
484
485static void ao_cecb_init(void)
486{
487 unsigned long data32;
488 unsigned int reg;
489
490 if (!cec_dev->plat_data->ee_to_ao)
491 return;
492
493 reg = (0 << 31) |
494 (0 << 30) |
495 (1 << 28) | /* clk_div0/clk_div1 in turn */
496 ((732-1) << 12) | /* Div_tcnt1 */
497 ((733-1) << 0); /* Div_tcnt0 */
498 writel(reg, cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG0);
499 reg = (0 << 13) |
500 ((11-1) << 12) |
501 ((8-1) << 0);
502 writel(reg, cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG1);
503
504 reg = readl(cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG0);
505 reg |= (1 << 31);
506 writel(reg, cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG0);
507
508 udelay(200);
509 reg |= (1 << 30);
510 writel(reg, cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG0);
511
512 reg = readl(cec_dev->cec_reg + AO_RTI_PWR_CNTL_REG0);
513 reg |= (0x01 << 6); /* xtal gate */
514 writel(reg, cec_dev->cec_reg + AO_RTI_PWR_CNTL_REG0);
515
516 data32 = 0;
517 data32 |= (7 << 12); /* filter_del */
518 data32 |= (1 << 8); /* filter_tick: 1us */
519 data32 |= (1 << 3); /* enable system clock */
520 data32 |= 0 << 1; /* [2:1] cntl_clk: */
521 /* 0=Disable clk (Power-off mode); */
522 /* 1=Enable gated clock (Normal mode); */
523 /* 2=Enable free-run clk (Debug mode). */
524 data32 |= 1 << 0; /* [0] sw_reset: 1=Reset */
525 writel(data32, cec_dev->cec_reg + AO_CECB_GEN_CNTL);
526 /* Enable gated clock (Normal mode). */
527 cec_set_reg_bits(AO_CECB_GEN_CNTL, 1, 1, 1);
528 /* Release SW reset */
529 cec_set_reg_bits(AO_CECB_GEN_CNTL, 0, 0, 1);
530
531 /* Enable all AO_CECB interrupt sources */
532 cec_irq_enable(true);
533 hdmirx_cec_write(DWC_CEC_WKUPCTRL, 0);
534}
535
536void eecec_irq_enable(bool enable)
537{
538 if (cec_dev->cpu_type < MESON_CPU_MAJOR_ID_TXLX) {
539 if (enable)
540 hdmirx_cec_write(DWC_AUD_CEC_IEN_SET,
541 EE_CEC_IRQ_EN_MASK);
542 else {
543 hdmirx_cec_write(DWC_AUD_CEC_ICLR,
544 (~(hdmirx_cec_read(DWC_AUD_CEC_IEN)) |
545 EE_CEC_IRQ_EN_MASK));
546 hdmirx_cec_write(DWC_AUD_CEC_IEN_SET,
547 hdmirx_cec_read(DWC_AUD_CEC_IEN) &
548 ~EE_CEC_IRQ_EN_MASK);
549 hdmirx_cec_write(DWC_AUD_CEC_IEN_CLR,
550 (~(hdmirx_cec_read(DWC_AUD_CEC_IEN)) |
551 EE_CEC_IRQ_EN_MASK));
552 }
553 CEC_INFO("ee enable:int mask:0x%x\n",
554 hdmirx_cec_read(DWC_AUD_CEC_IEN));
555 } else {
556 if (enable)
557 writel(CECB_IRQ_EN_MASK,
558 cec_dev->cec_reg + AO_CECB_INTR_MASKN);
559 else
560 writel(readl(cec_dev->cec_reg + AO_CECB_INTR_MASKN)
561 & ~CECB_IRQ_EN_MASK,
562 cec_dev->cec_reg + AO_CECB_INTR_MASKN);
563 CEC_INFO("ao move enable:int mask:0x%x\n",
564 readl(cec_dev->cec_reg + AO_CECB_INTR_MASKN));
565 }
566}
567
568void cec_irq_enable(bool enable)
569{
570 if (ee_cec)
571 eecec_irq_enable(enable);
572 else
573 aocec_irq_enable(enable);
574}
575
576int cecrx_hw_init(void)
577{
578 unsigned int data32;
579
580 if (!ee_cec)
581 return -1;
582 cecrx_hw_reset();
583 if (!cec_dev->plat_data->ee_to_ao) {
584 /* set cec clk 32768k */
585 data32 = readl(cec_dev->hhi_reg + HHI_32K_CLK_CNTL);
586 data32 = 0;
587 /*
588 * [17:16] clk_sel: 0=oscin; 1=slow_oscin;
589 * 2=fclk_div3; 3=fclk_div5.
590 */
591 data32 |= 0 << 16;
592 /* [ 15] clk_en */
593 data32 |= 1 << 15;
594 /* [13: 0] clk_div */
595 data32 |= (732-1) << 0;
596 writel(data32, cec_dev->hhi_reg + HHI_32K_CLK_CNTL);
597 hdmirx_wr_top(TOP_EDID_ADDR_CEC, EDID_CEC_ID_ADDR);
598
599 /* hdmirx_cecclk_en */
600 hdmirx_set_bits_top(TOP_CLK_CNTL, 1, 2, 1);
601 hdmirx_set_bits_top(TOP_EDID_GEN_CNTL, EDID_AUTO_CEC_EN, 11, 1);
602
603 /* enable all cec irq */
604 cec_irq_enable(true);
605 /* clear all wake up source */
606 hdmirx_cec_write(DWC_CEC_WKUPCTRL, 0);
607 /* cec enable */
608 hdmirx_set_bits_dwc(DWC_DMI_DISABLE_IF, 1, 5, 1);
609 } else
610 ao_cecb_init();
611
612 cec_logicaddr_set(cec_dev->cec_info.log_addr);
613 return 0;
614}
615
616static int dump_cecrx_reg(char *b)
617{
618 int i = 0, s = 0;
619 unsigned char reg;
620 unsigned int reg32;
621
622 if (!cec_dev->plat_data->ee_to_ao) {
623 reg32 = readl(cec_dev->hhi_reg + HHI_32K_CLK_CNTL);
624 s += sprintf(b + s, "HHI_32K_CLK_CNTL: 0x%08x\n", reg32);
625 reg32 = hdmirx_rd_top(TOP_EDID_ADDR_CEC);
626 s += sprintf(b + s, "TOP_EDID_ADDR_CEC: 0x%08x\n", reg32);
627 reg32 = hdmirx_rd_top(TOP_EDID_GEN_CNTL);
628 s += sprintf(b + s, "TOP_EDID_GEN_CNTL: 0x%08x\n", reg32);
629 reg32 = hdmirx_cec_read(DWC_AUD_CEC_IEN);
630 s += sprintf(b + s, "DWC_AUD_CEC_IEN: 0x%08x\n", reg32);
631 reg32 = hdmirx_cec_read(DWC_AUD_CEC_ISTS);
632 s += sprintf(b + s, "DWC_AUD_CEC_ISTS: 0x%08x\n", reg32);
633 reg32 = hdmirx_cec_read(DWC_DMI_DISABLE_IF);
634 s += sprintf(b + s, "DWC_DMI_DISABLE_IF: 0x%08x\n", reg32);
635 reg32 = hdmirx_rd_top(TOP_CLK_CNTL);
636 s += sprintf(b + s, "TOP_CLK_CNTL: 0x%08x\n", reg32);
637 } else {
638 reg32 = readl(cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG0);
639 s += sprintf(b + s, "AO_CECB_CLK_CNTL_REG0: 0x%08x\n", reg32);
640 reg32 = readl(cec_dev->cec_reg + AO_CECB_CLK_CNTL_REG1);
641 s += sprintf(b + s, "AO_CECB_CLK_CNTL_REG1: 0x%08x\n", reg32);
642 reg32 = readl(cec_dev->cec_reg + AO_CECB_GEN_CNTL);
643 s += sprintf(b + s, "AO_CECB_GEN_CNTL: 0x%08x\n", reg32);
644 reg32 = readl(cec_dev->cec_reg + AO_CECB_RW_REG);
645 s += sprintf(b + s, "AO_CECB_RW_REG: 0x%08x\n", reg32);
646 reg32 = readl(cec_dev->cec_reg + AO_CECB_INTR_MASKN);
647 s += sprintf(b + s, "AO_CECB_INTR_MASKN: 0x%08x\n", reg32);
648 reg32 = readl(cec_dev->cec_reg + AO_CECB_INTR_STAT);
649 s += sprintf(b + s, "AO_CECB_INTR_STAT: 0x%08x\n", reg32);
650 }
651
652 s += sprintf(b + s, "CEC MODULE REGS:\n");
653 s += sprintf(b + s, "CEC_CTRL = 0x%02x\n", hdmirx_cec_read(0x1f00));
654 s += sprintf(b + s, "CEC_MASK = 0x%02x\n", hdmirx_cec_read(0x1f08));
655 s += sprintf(b + s, "CEC_ADDR_L = 0x%02x\n", hdmirx_cec_read(0x1f14));
656 s += sprintf(b + s, "CEC_ADDR_H = 0x%02x\n", hdmirx_cec_read(0x1f18));
657 s += sprintf(b + s, "CEC_TX_CNT = 0x%02x\n", hdmirx_cec_read(0x1f1c));
658 s += sprintf(b + s, "CEC_RX_CNT = 0x%02x\n", hdmirx_cec_read(0x1f20));
659 s += sprintf(b + s, "CEC_LOCK = 0x%02x\n", hdmirx_cec_read(0x1fc0));
660 s += sprintf(b + s, "CEC_WKUPCTRL = 0x%02x\n", hdmirx_cec_read(0x1fc4));
661
662 s += sprintf(b + s, "%s", "RX buffer:");
663 for (i = 0; i < 16; i++) {
664 reg = (hdmirx_cec_read(0x1f80 + i * 4) & 0xff);
665 s += sprintf(b + s, " %02x", reg);
666 }
667 s += sprintf(b + s, "\n");
668
669 s += sprintf(b + s, "%s", "TX buffer:");
670 for (i = 0; i < 16; i++) {
671 reg = (hdmirx_cec_read(0x1f40 + i * 4) & 0xff);
672 s += sprintf(b + s, " %02x", reg);
673 }
674 s += sprintf(b + s, "\n");
675 return s;
676}
677
678/*--------------------- END of EE CEC --------------------*/
679
680void aocec_irq_enable(bool enable)
681{
682 if (enable)
683 cec_set_reg_bits(AO_CEC_INTR_MASKN, 0x6, 0, 3);
684 else
685 cec_set_reg_bits(AO_CEC_INTR_MASKN, 0x0, 0, 3);
686 CEC_INFO("ao enable:int mask:0x%x\n",
687 readl(cec_dev->cec_reg + AO_CEC_INTR_MASKN));
688}
689
690static void cec_hw_buf_clear(void)
691{
692 aocec_wr_reg(CEC_RX_MSG_CMD, RX_DISABLE);
693 aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT);
694 aocec_wr_reg(CEC_RX_CLEAR_BUF, 1);
695 aocec_wr_reg(CEC_TX_CLEAR_BUF, 1);
696 udelay(100);
697 aocec_wr_reg(CEC_RX_CLEAR_BUF, 0);
698 aocec_wr_reg(CEC_TX_CLEAR_BUF, 0);
699 udelay(100);
700 aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP);
701 aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP);
702}
703
704void cec_logicaddr_set(int l_add)
705{
706 /* save logical address for suspend/wake up */
707 cec_set_reg_bits(AO_DEBUG_REG1, l_add, 16, 4);
708 if (ee_cec) {
709 /* set ee_cec logical addr */
710 if (l_add < 8)
711 hdmirx_cec_write(DWC_CEC_ADDR_L, 1 << l_add);
712 else
713 hdmirx_cec_write(DWC_CEC_ADDR_H, 1 << (l_add - 8)|0x80);
714 return;
715 }
716 aocec_wr_reg(CEC_LOGICAL_ADDR0, 0);
717 cec_hw_buf_clear();
718 aocec_wr_reg(CEC_LOGICAL_ADDR0, (l_add & 0xf));
719 udelay(100);
720 aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | (l_add & 0xf));
721 if (cec_msg_dbg_en)
722 CEC_INFO("set logical addr:0x%x\n",
723 aocec_rd_reg(CEC_LOGICAL_ADDR0));
724}
725
726static void cec_hw_reset(void)
727{
728 if (ee_cec) {
729 cecrx_hw_init();
730 return;
731 }
732
733 writel(0x1, cec_dev->cec_reg + AO_CEC_GEN_CNTL);
734 /* Enable gated clock (Normal mode). */
735 cec_set_reg_bits(AO_CEC_GEN_CNTL, 1, 1, 1);
736 /* Release SW reset */
737 udelay(100);
738 cec_set_reg_bits(AO_CEC_GEN_CNTL, 0, 0, 1);
739
740 /* Enable all AO_CEC interrupt sources */
741 cec_irq_enable(true);
742
743 cec_logicaddr_set(cec_dev->cec_info.log_addr);
744
745 /* Cec arbitration 3/5/7 bit time set. */
746 cec_arbit_bit_time_set(3, 0x118, 0);
747 cec_arbit_bit_time_set(5, 0x000, 0);
748 cec_arbit_bit_time_set(7, 0x2aa, 0);
749
750 CEC_INFO("hw reset :logical addr:0x%x\n",
751 aocec_rd_reg(CEC_LOGICAL_ADDR0));
752}
753
754void cec_rx_buf_clear(void)
755{
756 aocec_wr_reg(CEC_RX_CLEAR_BUF, 0x1);
757 aocec_wr_reg(CEC_RX_CLEAR_BUF, 0x0);
758}
759
760static inline bool is_poll_message(unsigned char header)
761{
762 unsigned char initiator, follower;
763
764 initiator = (header >> 4) & 0xf;
765 follower = (header) & 0xf;
766 return initiator == follower;
767}
768
769static inline bool is_feature_abort_msg(const unsigned char *msg, int len)
770{
771 if (!msg || len < 2)
772 return false;
773 if (msg[1] == CEC_OC_FEATURE_ABORT)
774 return true;
775 return false;
776}
777
778static bool need_nack_repeat_msg(const unsigned char *msg, int len, int t)
779{
780 if (len == last_cec_msg->len &&
781 (is_poll_message(msg[0]) || is_feature_abort_msg(msg, len)) &&
782 last_cec_msg->last_result == CEC_FAIL_NACK &&
783 jiffies - last_cec_msg->last_jiffies < t) {
784 return true;
785 }
786 return false;
787}
788
789static void cec_clear_logical_addr(void)
790{
791 if (ee_cec) {
792 hdmirx_cec_write(DWC_CEC_ADDR_L, 0);
793 hdmirx_cec_write(DWC_CEC_ADDR_H, 0x80);
794 } else
795 aocec_wr_reg(CEC_LOGICAL_ADDR0, 0);
796 udelay(100);
797}
798
799int cec_rx_buf_check(void)
800{
801 unsigned int rx_num_msg;
802
803 if (ee_cec) {
804 cecrx_check_irq_enable();
805 cecrx_irq_handle();
806 return 0;
807 }
808
809 rx_num_msg = aocec_rd_reg(CEC_RX_NUM_MSG);
810 if (rx_num_msg)
811 CEC_INFO("rx msg num:0x%02x\n", rx_num_msg);
812
813 return rx_num_msg;
814}
815
816int cec_ll_rx(unsigned char *msg, unsigned char *len)
817{
818 int i;
819 int ret = -1;
820 int pos;
821 int rx_stat;
822
823 rx_stat = aocec_rd_reg(CEC_RX_MSG_STATUS);
824 if ((rx_stat != RX_DONE) || (aocec_rd_reg(CEC_RX_NUM_MSG) != 1)) {
825 CEC_INFO("rx status:%x\n", rx_stat);
826 writel((1 << 2), cec_dev->cec_reg + AO_CEC_INTR_CLR);
827 aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT);
828 aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP);
829 cec_rx_buf_clear();
830 return ret;
831 }
832
833 *len = aocec_rd_reg(CEC_RX_MSG_LENGTH) + 1;
834
835 for (i = 0; i < (*len) && i < MAX_MSG; i++)
836 msg[i] = aocec_rd_reg(CEC_RX_MSG_0_HEADER + i);
837
838 ret = rx_stat;
839
840 /* ignore ping message */
841 if (cec_msg_dbg_en == 1 && *len > 1) {
842 pos = 0;
843 pos += sprintf(msg_log_buf + pos,
844 "CEC: rx msg len: %d dat: ", *len);
845 for (i = 0; i < (*len); i++)
846 pos += sprintf(msg_log_buf + pos, "%02x ", msg[i]);
847 pos += sprintf(msg_log_buf + pos, "\n");
848 msg_log_buf[pos] = '\0';
849 CEC_INFO("%s", msg_log_buf);
850 }
851 last_cec_msg->len = 0; /* invalid back up msg when rx */
852 writel((1 << 2), cec_dev->cec_reg + AO_CEC_INTR_CLR);
853 aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT);
854 aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP);
855 cec_rx_buf_clear();
856 pin_status = 1;
857 return ret;
858}
859
860/************************ cec arbitration cts code **************************/
861/* using the cec pin as fiq gpi to assist the bus arbitration */
862
863/* return value: 1: successful 0: error */
864static int cec_ll_trigle_tx(const unsigned char *msg, int len)
865{
866 int i;
867 unsigned int n;
868 int pos;
869 int reg;
870 unsigned int j = 40;
871 unsigned int tx_stat;
872 static int cec_timeout_cnt = 1;
873
874 while (1) {
875 tx_stat = aocec_rd_reg(CEC_TX_MSG_STATUS);
876 if (tx_stat != TX_BUSY)
877 break;
878
879 if (!(j--)) {
880 CEC_INFO("waiting busy timeout\n");
881 aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT);
882 cec_timeout_cnt++;
883 if (cec_timeout_cnt > 0x08)
884 cec_hw_reset();
885 break;
886 }
887 msleep(20);
888 }
889
890 reg = aocec_rd_reg(CEC_TX_MSG_STATUS);
891 if (reg == TX_IDLE || reg == TX_DONE) {
892 for (i = 0; i < len; i++)
893 aocec_wr_reg(CEC_TX_MSG_0_HEADER + i, msg[i]);
894
895 aocec_wr_reg(CEC_TX_MSG_LENGTH, len-1);
896 aocec_wr_reg(CEC_TX_MSG_CMD, TX_REQ_CURRENT);
897
898 if (cec_msg_dbg_en == 1) {
899 pos = 0;
900 pos += sprintf(msg_log_buf + pos,
901 "CEC: tx msg len: %d dat: ", len);
902 for (n = 0; n < len; n++) {
903 pos += sprintf(msg_log_buf + pos,
904 "%02x ", msg[n]);
905 }
906
907 pos += sprintf(msg_log_buf + pos, "\n");
908
909 msg_log_buf[pos] = '\0';
910 pr_info("%s", msg_log_buf);
911 }
912 cec_timeout_cnt = 0;
913 return 0;
914 }
915 return -1;
916}
917
918void tx_irq_handle(void)
919{
920 unsigned int tx_status = aocec_rd_reg(CEC_TX_MSG_STATUS);
921
922 cec_tx_result = -1;
923 switch (tx_status) {
924 case TX_DONE:
925 aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP);
926 cec_tx_result = CEC_FAIL_NONE;
927 break;
928
929 case TX_BUSY:
930 CEC_ERR("TX_BUSY\n");
931 cec_tx_result = CEC_FAIL_BUSY;
932 break;
933
934 case TX_ERROR:
935 if (cec_msg_dbg_en == 1)
936 CEC_ERR("TX ERROR!!!\n");
937 aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT);
938 cec_hw_reset();
939 cec_tx_result = CEC_FAIL_NACK;
940 break;
941
942 case TX_IDLE:
943 CEC_ERR("TX_IDLE\n");
944 cec_tx_result = CEC_FAIL_OTHER;
945 break;
946 default:
947 break;
948 }
949 writel((1 << 1), cec_dev->cec_reg + AO_CEC_INTR_CLR);
950 complete(&cec_dev->tx_ok);
951}
952
953static int get_line(void)
954{
955 int reg, ret = -EINVAL;
956
957 reg = readl(cec_dev->cec_reg + AO_GPIO_I);
958 ret = (reg & (1 << cec_dev->plat_data->line_bit));
959
960 return ret;
961}
962
963static enum hrtimer_restart cec_line_check(struct hrtimer *timer)
964{
965 if (get_line() == 0)
966 cec_line_cnt++;
967 hrtimer_forward_now(timer, HR_DELAY(1));
968 return HRTIMER_RESTART;
969}
970
971static int check_confilct(void)
972{
973 int i;
974
975 for (i = 0; i < 200; i++) {
976 /*
977 * sleep 20ms and using hrtimer to check cec line every 1ms
978 */
979 cec_line_cnt = 0;
980 hrtimer_start(&start_bit_check, HR_DELAY(1), HRTIMER_MODE_REL);
981 msleep(20);
982 hrtimer_cancel(&start_bit_check);
983 if (cec_line_cnt == 0)
984 break;
985 CEC_INFO("line busy:%d\n", cec_line_cnt);
986 }
987 if (i >= 200)
988 return -EBUSY;
989 else
990 return 0;
991}
992
993static bool check_physical_addr_valid(int timeout)
994{
995 while (timeout > 0) {
996 if (cec_dev->dev_type == DEV_TYPE_TV)
997 break;
998 if (phy_addr_test)
999 break;
1000 /* physical address for box */
1001 if (cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.valid == 0) {
1002 msleep(100);
1003 timeout--;
1004 } else
1005 break;
1006 }
1007 if (timeout <= 0)
1008 return false;
1009 return true;
1010}
1011
1012/* Return value: < 0: fail, > 0: success */
1013int cec_ll_tx(const unsigned char *msg, unsigned char len)
1014{
1015 int ret = -1;
1016 int t = msecs_to_jiffies(ee_cec ? 2000 : 5000);
1017 int retry = 2;
1018
1019 if (len == 0)
1020 return CEC_FAIL_NONE;
1021
1022 if (is_poll_message(msg[0]))
1023 cec_clear_logical_addr();
1024
1025 /*
1026 * for CEC CTS 9.3. Android will try 3 poll message if got NACK
1027 * but AOCEC will retry 4 tx for each poll message. Framework
1028 * repeat this poll message so quick makes 12 sequential poll
1029 * waveform seen on CEC bus. And did not pass CTS
1030 * specification of 9.3
1031 */
1032 if (!ee_cec && need_nack_repeat_msg(msg, len, t)) {
1033 if (!memcmp(msg, last_cec_msg->msg, len)) {
1034 CEC_INFO("NACK repeat message:%x\n", len);
1035 return CEC_FAIL_NACK;
1036 }
1037 }
1038
1039 mutex_lock(&cec_dev->cec_mutex);
1040 /* make sure we got valid physical address */
1041 if (len >= 2 && msg[1] == CEC_OC_REPORT_PHYSICAL_ADDRESS)
1042 check_physical_addr_valid(20);
1043
1044try_again:
1045 reinit_completion(&cec_dev->tx_ok);
1046 /*
1047 * CEC controller won't ack message if it is going to send
1048 * state. If we detect cec line is low during waiting signal
1049 * free time, that means a send is already started by other
1050 * device, we should wait it finished.
1051 */
1052 if (check_confilct()) {
1053 CEC_ERR("bus confilct too long\n");
1054 mutex_unlock(&cec_dev->cec_mutex);
1055 return CEC_FAIL_BUSY;
1056 }
1057
1058 if (ee_cec)
1059 ret = cecrx_trigle_tx(msg, len);
1060 else
1061 ret = cec_ll_trigle_tx(msg, len);
1062 if (ret < 0) {
1063 /* we should increase send idx if busy */
1064 CEC_INFO("tx busy\n");
1065 if (retry > 0) {
1066 retry--;
1067 msleep(100 + (prandom_u32() & 0x07) * 10);
1068 goto try_again;
1069 }
1070 mutex_unlock(&cec_dev->cec_mutex);
1071 return CEC_FAIL_BUSY;
1072 }
1073 cec_tx_result = -1;
1074 ret = wait_for_completion_timeout(&cec_dev->tx_ok, t);
1075 if (ret <= 0) {
1076 /* timeout or interrupt */
1077 if (ret == 0) {
1078 CEC_ERR("tx timeout\n");
1079 cec_hw_reset();
1080 }
1081 ret = CEC_FAIL_OTHER;
1082 } else {
1083 ret = cec_tx_result;
1084 }
1085 if (ret != CEC_FAIL_NONE && ret != CEC_FAIL_NACK) {
1086 if (retry > 0) {
1087 retry--;
1088 msleep(100 + (prandom_u32() & 0x07) * 10);
1089 goto try_again;
1090 }
1091 }
1092 mutex_unlock(&cec_dev->cec_mutex);
1093
1094 if (!ee_cec) {
1095 last_cec_msg->last_result = ret;
1096 if (ret == CEC_FAIL_NACK) {
1097 memcpy(last_cec_msg->msg, msg, len);
1098 last_cec_msg->len = len;
1099 last_cec_msg->last_jiffies = jiffies;
1100 }
1101 }
1102 return ret;
1103}
1104
1105/* -------------------------------------------------------------------------- */
1106/* AO CEC0 config */
1107/* -------------------------------------------------------------------------- */
1108void ao_cec_init(void)
1109{
1110 unsigned long data32;
1111 unsigned int reg;
1112
1113 if (get_meson_cpu_version(MESON_CPU_VERSION_LVL_MAJOR) >=
1114 MESON_CPU_MAJOR_ID_GXBB) {
1115 reg = (0 << 31) |
1116 (0 << 30) |
1117 (1 << 28) | /* clk_div0/clk_div1 in turn */
1118 ((732-1) << 12) | /* Div_tcnt1 */
1119 ((733-1) << 0); /* Div_tcnt0 */
1120 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1121 reg = (0 << 13) |
1122 ((11-1) << 12) |
1123 ((8-1) << 0);
1124 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL1);
1125
1126 reg = readl(cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1127 reg |= (1 << 31);
1128 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1129
1130 udelay(200);
1131 reg |= (1 << 30);
1132 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1133
1134 reg = readl(cec_dev->cec_reg + AO_CRT_CLK_CNTL1);
1135 reg |= (0x800 << 16); /* select cts_rtc_oscin_clk */
1136 writel(reg, cec_dev->cec_reg + AO_CRT_CLK_CNTL1);
1137
1138 reg = readl(cec_dev->cec_reg + AO_RTI_PWR_CNTL_REG0);
1139 reg &= ~(0x07 << 10);
1140 reg |= (0x04 << 10); /* XTAL generate 32k */
1141 writel(reg, cec_dev->cec_reg + AO_RTI_PWR_CNTL_REG0);
1142 }
1143
1144 data32 = 0;
1145 data32 |= 0 << 1; /* [2:1] cntl_clk: */
1146 /* 0=Disable clk (Power-off mode); */
1147 /* 1=Enable gated clock (Normal mode); */
1148 /* 2=Enable free-run clk (Debug mode). */
1149 data32 |= 1 << 0; /* [0] sw_reset: 1=Reset */
1150 writel(data32, cec_dev->cec_reg + AO_CEC_GEN_CNTL);
1151 /* Enable gated clock (Normal mode). */
1152 cec_set_reg_bits(AO_CEC_GEN_CNTL, 1, 1, 1);
1153 /* Release SW reset */
1154 cec_set_reg_bits(AO_CEC_GEN_CNTL, 0, 0, 1);
1155
1156 /* Enable all AO_CEC interrupt sources */
1157 cec_irq_enable(true);
1158}
1159
1160void cec_arbit_bit_time_set(unsigned int bit_set,
1161 unsigned int time_set, unsigned int flag)
1162{ /* 11bit:bit[10:0] */
1163 if (flag) {
1164 CEC_INFO("bit_set:0x%x;time_set:0x%x\n",
1165 bit_set, time_set);
1166 }
1167
1168 switch (bit_set) {
1169 case 3:
1170 /* 3 bit */
1171 if (flag) {
1172 CEC_INFO("read 3 bit:0x%x%x\n",
1173 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT10_8),
1174 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT7_0));
1175 }
1176 aocec_wr_reg(AO_CEC_TXTIME_4BIT_BIT7_0, time_set & 0xff);
1177 aocec_wr_reg(AO_CEC_TXTIME_4BIT_BIT10_8, (time_set >> 8) & 0x7);
1178 if (flag) {
1179 CEC_INFO("write 3 bit:0x%x%x\n",
1180 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT10_8),
1181 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT7_0));
1182 }
1183 break;
1184 /* 5 bit */
1185 case 5:
1186 if (flag) {
1187 CEC_INFO("read 5 bit:0x%x%x\n",
1188 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT10_8),
1189 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT7_0));
1190 }
1191 aocec_wr_reg(AO_CEC_TXTIME_2BIT_BIT7_0, time_set & 0xff);
1192 aocec_wr_reg(AO_CEC_TXTIME_2BIT_BIT10_8, (time_set >> 8) & 0x7);
1193 if (flag) {
1194 CEC_INFO("write 5 bit:0x%x%x\n",
1195 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT10_8),
1196 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT7_0));
1197 }
1198 break;
1199 /* 7 bit */
1200 case 7:
1201 if (flag) {
1202 CEC_INFO("read 7 bit:0x%x%x\n",
1203 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT10_8),
1204 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT7_0));
1205 }
1206 aocec_wr_reg(AO_CEC_TXTIME_17MS_BIT7_0, time_set & 0xff);
1207 aocec_wr_reg(AO_CEC_TXTIME_17MS_BIT10_8, (time_set >> 8) & 0x7);
1208 if (flag) {
1209 CEC_INFO("write 7 bit:0x%x%x\n",
1210 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT10_8),
1211 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT7_0));
1212 }
1213 break;
1214 default:
1215 break;
1216 }
1217}
1218
1219static unsigned int ao_cec_intr_stat(void)
1220{
1221 return readl(cec_dev->cec_reg + AO_CEC_INTR_STAT);
1222}
1223
1224unsigned int cec_intr_stat(void)
1225{
1226 return ao_cec_intr_stat();
1227}
1228
1229/*
1230 *wr_flag: 1 write; value valid
1231 * 0 read; value invalid
1232 */
1233unsigned int cec_config(unsigned int value, bool wr_flag)
1234{
1235 if (wr_flag)
1236 cec_set_reg_bits(AO_DEBUG_REG0, value, 0, 8);
1237
1238 return readl(cec_dev->cec_reg + AO_DEBUG_REG0) & 0xff;
1239}
1240
1241/*
1242 *wr_flag:1 write; value valid
1243 * 0 read; value invalid
1244 */
1245unsigned int cec_phyaddr_config(unsigned int value, bool wr_flag)
1246{
1247 if (wr_flag)
1248 cec_set_reg_bits(AO_DEBUG_REG1, value, 0, 16);
1249
1250 return readl(cec_dev->cec_reg + AO_DEBUG_REG1);
1251}
1252
1253void cec_keep_reset(void)
1254{
1255 if (ee_cec)
1256 cecrx_hw_reset();
1257 else
1258 writel(0x1, cec_dev->cec_reg + AO_CEC_GEN_CNTL);
1259}
1260/*
1261 * cec hw module init before allocate logical address
1262 */
1263static void cec_pre_init(void)
1264{
1265 unsigned int reg = readl(cec_dev->cec_reg + AO_RTI_STATUS_REG1);
1266
1267 reg &= 0xfffff;
1268 if ((reg & 0xffff) == 0xffff)
1269 wake_ok = 0;
1270 pr_info("cec: wake up flag:%x\n", reg);
1271
1272 if (ee_cec) {
1273 cecrx_hw_init();
1274 return;
1275 }
1276 ao_cec_init();
1277
1278 cec_arbit_bit_time_set(3, 0x118, 0);
1279 cec_arbit_bit_time_set(5, 0x000, 0);
1280 cec_arbit_bit_time_set(7, 0x2aa, 0);
1281}
1282
1283static int cec_late_check_rx_buffer(void)
1284{
1285 int ret;
1286 struct delayed_work *dwork = &cec_dev->cec_work;
1287
1288 ret = cec_rx_buf_check();
1289 if (!ret)
1290 return 0;
1291 /*
1292 * start another check if rx buffer is full
1293 */
1294 if ((-1) == cec_ll_rx(rx_msg, &rx_len)) {
1295 CEC_INFO("buffer got unrecorgnized msg\n");
1296 cec_rx_buf_clear();
1297 return 0;
1298 }
1299 mod_delayed_work(cec_dev->cec_thread, dwork, 0);
1300 return 1;
1301}
1302
1303void cec_key_report(int suspend)
1304{
1305 input_event(cec_dev->cec_info.remote_cec_dev, EV_KEY, KEY_POWER, 1);
1306 input_sync(cec_dev->cec_info.remote_cec_dev);
1307 input_event(cec_dev->cec_info.remote_cec_dev, EV_KEY, KEY_POWER, 0);
1308 input_sync(cec_dev->cec_info.remote_cec_dev);
1309 if (!suspend)
1310 CEC_INFO("== WAKE UP BY CEC ==\n")
1311 else
1312 CEC_INFO("== SLEEP by CEC==\n")
1313}
1314
1315void cec_give_version(unsigned int dest)
1316{
1317 unsigned char index = cec_dev->cec_info.log_addr;
1318 unsigned char msg[3];
1319
1320 if (dest != 0xf) {
1321 msg[0] = ((index & 0xf) << 4) | dest;
1322 msg[1] = CEC_OC_CEC_VERSION;
1323 msg[2] = cec_dev->cec_info.cec_version;
1324 cec_ll_tx(msg, 3);
1325 }
1326}
1327
1328void cec_report_physical_address_smp(void)
1329{
1330 unsigned char msg[5];
1331 unsigned char index = cec_dev->cec_info.log_addr;
1332 unsigned char phy_addr_ab, phy_addr_cd;
1333
1334 phy_addr_ab = (cec_dev->phy_addr >> 8) & 0xff;
1335 phy_addr_cd = (cec_dev->phy_addr >> 0) & 0xff;
1336 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1337 msg[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS;
1338 msg[2] = phy_addr_ab;
1339 msg[3] = phy_addr_cd;
1340 msg[4] = cec_dev->dev_type;
1341
1342 cec_ll_tx(msg, 5);
1343}
1344
1345void cec_device_vendor_id(void)
1346{
1347 unsigned char index = cec_dev->cec_info.log_addr;
1348 unsigned char msg[5];
1349 unsigned int vendor_id;
1350
1351 vendor_id = cec_dev->v_data.vendor_id;
1352 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1353 msg[1] = CEC_OC_DEVICE_VENDOR_ID;
1354 msg[2] = (vendor_id >> 16) & 0xff;
1355 msg[3] = (vendor_id >> 8) & 0xff;
1356 msg[4] = (vendor_id >> 0) & 0xff;
1357
1358 cec_ll_tx(msg, 5);
1359}
1360
1361void cec_give_deck_status(unsigned int dest)
1362{
1363 unsigned char index = cec_dev->cec_info.log_addr;
1364 unsigned char msg[3];
1365
1366 msg[0] = ((index & 0xf) << 4) | dest;
1367 msg[1] = CEC_OC_DECK_STATUS;
1368 msg[2] = 0x1a;
1369 cec_ll_tx(msg, 3);
1370}
1371
1372void cec_menu_status_smp(int dest, int status)
1373{
1374 unsigned char msg[3];
1375 unsigned char index = cec_dev->cec_info.log_addr;
1376
1377 msg[0] = ((index & 0xf) << 4) | dest;
1378 msg[1] = CEC_OC_MENU_STATUS;
1379 if (status == DEVICE_MENU_ACTIVE)
1380 msg[2] = DEVICE_MENU_ACTIVE;
1381 else
1382 msg[2] = DEVICE_MENU_INACTIVE;
1383 cec_ll_tx(msg, 3);
1384}
1385
1386void cec_inactive_source(int dest)
1387{
1388 unsigned char index = cec_dev->cec_info.log_addr;
1389 unsigned char msg[4];
1390 unsigned char phy_addr_ab, phy_addr_cd;
1391
1392 phy_addr_ab = (cec_dev->phy_addr >> 8) & 0xff;
1393 phy_addr_cd = (cec_dev->phy_addr >> 0) & 0xff;
1394 msg[0] = ((index & 0xf) << 4) | dest;
1395 msg[1] = CEC_OC_INACTIVE_SOURCE;
1396 msg[2] = phy_addr_ab;
1397 msg[3] = phy_addr_cd;
1398
1399 cec_ll_tx(msg, 4);
1400}
1401
1402void cec_set_osd_name(int dest)
1403{
1404 unsigned char index = cec_dev->cec_info.log_addr;
1405 unsigned char osd_len = strlen(cec_dev->cec_info.osd_name);
1406 unsigned char msg[16];
1407
1408 if (dest != 0xf) {
1409 msg[0] = ((index & 0xf) << 4) | dest;
1410 msg[1] = CEC_OC_SET_OSD_NAME;
1411 memcpy(&msg[2], cec_dev->cec_info.osd_name, osd_len);
1412
1413 cec_ll_tx(msg, 2 + osd_len);
1414 }
1415}
1416
1417void cec_active_source_smp(void)
1418{
1419 unsigned char msg[4];
1420 unsigned char index = cec_dev->cec_info.log_addr;
1421 unsigned char phy_addr_ab;
1422 unsigned char phy_addr_cd;
1423
1424 phy_addr_ab = (cec_dev->phy_addr >> 8) & 0xff;
1425 phy_addr_cd = (cec_dev->phy_addr >> 0) & 0xff;
1426 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1427 msg[1] = CEC_OC_ACTIVE_SOURCE;
1428 msg[2] = phy_addr_ab;
1429 msg[3] = phy_addr_cd;
1430 cec_ll_tx(msg, 4);
1431}
1432
1433void cec_request_active_source(void)
1434{
1435 unsigned char msg[2];
1436 unsigned char index = cec_dev->cec_info.log_addr;
1437
1438 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1439 msg[1] = CEC_OC_REQUEST_ACTIVE_SOURCE;
1440 cec_ll_tx(msg, 2);
1441}
1442
1443void cec_set_stream_path(unsigned char *msg)
1444{
1445 unsigned int phy_addr_active;
1446
1447 phy_addr_active = (unsigned int)(msg[2] << 8 | msg[3]);
1448 if (phy_addr_active == cec_dev->phy_addr) {
1449 cec_active_source_smp();
1450 /*
1451 * some types of TV such as panasonic need to send menu status,
1452 * otherwise it will not send remote key event to control
1453 * device's menu
1454 */
1455 cec_menu_status_smp(msg[0] >> 4, DEVICE_MENU_ACTIVE);
1456 }
1457}
1458
1459void cec_report_power_status(int dest, int status)
1460{
1461 unsigned char index = cec_dev->cec_info.log_addr;
1462 unsigned char msg[3];
1463
1464 msg[0] = ((index & 0xf) << 4) | dest;
1465 msg[1] = CEC_OC_REPORT_POWER_STATUS;
1466 msg[2] = status;
1467 cec_ll_tx(msg, 3);
1468}
1469
1470static void cec_rx_process(void)
1471{
1472 int len = rx_len;
1473 int initiator, follower;
1474 int opcode;
1475 unsigned char msg[MAX_MSG] = {};
1476 int dest_phy_addr;
1477
1478 if (len < 2 || !new_msg) /* ignore ping message */
1479 return;
1480
1481 memcpy(msg, rx_msg, len);
1482 initiator = ((msg[0] >> 4) & 0xf);
1483 follower = msg[0] & 0xf;
1484 if (follower != 0xf && follower != cec_dev->cec_info.log_addr) {
1485 CEC_ERR("wrong rx message of bad follower:%x", follower);
1486 return;
1487 }
1488 opcode = msg[1];
1489 switch (opcode) {
1490 case CEC_OC_ACTIVE_SOURCE:
1491 if (wake_ok == 0) {
1492 int phy_addr = msg[2] << 8 | msg[3];
1493
1494 if (phy_addr == 0xffff)
1495 break;
1496 wake_ok = 1;
1497 phy_addr |= (initiator << 16);
1498 writel(phy_addr, cec_dev->cec_reg + AO_RTI_STATUS_REG1);
1499 CEC_INFO("found wake up source:%x", phy_addr);
1500 }
1501 break;
1502
1503 case CEC_OC_ROUTING_CHANGE:
1504 dest_phy_addr = msg[4] << 8 | msg[5];
1505 if ((dest_phy_addr == cec_dev->phy_addr) &&
1506 (cec_dev->cec_suspend == CEC_EARLY_SUSPEND)) {
1507 CEC_INFO("wake up by ROUTING_CHANGE\n");
1508 cec_key_report(0);
1509 }
1510 break;
1511
1512 case CEC_OC_GET_CEC_VERSION:
1513 cec_give_version(initiator);
1514 break;
1515
1516 case CEC_OC_GIVE_DECK_STATUS:
1517 cec_give_deck_status(initiator);
1518 break;
1519
1520 case CEC_OC_GIVE_PHYSICAL_ADDRESS:
1521 cec_report_physical_address_smp();
1522 break;
1523
1524 case CEC_OC_GIVE_DEVICE_VENDOR_ID:
1525 cec_device_vendor_id();
1526 break;
1527
1528 case CEC_OC_GIVE_OSD_NAME:
1529 cec_set_osd_name(initiator);
1530 break;
1531
1532 case CEC_OC_STANDBY:
1533 cec_inactive_source(initiator);
1534 cec_menu_status_smp(initiator, DEVICE_MENU_INACTIVE);
1535 break;
1536
1537 case CEC_OC_SET_STREAM_PATH:
1538 cec_set_stream_path(msg);
1539 /* wake up if in early suspend */
1540 if (cec_dev->cec_suspend == CEC_EARLY_SUSPEND)
1541 cec_key_report(0);
1542 break;
1543
1544 case CEC_OC_REQUEST_ACTIVE_SOURCE:
1545 if (cec_dev->cec_suspend == CEC_POWER_ON)
1546 cec_active_source_smp();
1547 break;
1548
1549 case CEC_OC_GIVE_DEVICE_POWER_STATUS:
1550 if (cec_dev->cec_suspend == CEC_DEEP_SUSPEND)
1551 cec_report_power_status(initiator, POWER_STANDBY);
1552 else if (cec_dev->cec_suspend == CEC_EARLY_SUSPEND)
1553 cec_report_power_status(initiator, TRANS_ON_TO_STANDBY);
1554 else if (cec_dev->cec_suspend == CEC_POWER_RESUME)
1555 cec_report_power_status(initiator, TRANS_STANDBY_TO_ON);
1556 else
1557 cec_report_power_status(initiator, POWER_ON);
1558 break;
1559
1560 case CEC_OC_USER_CONTROL_PRESSED:
1561 /* wake up by key function */
1562 if (cec_dev->cec_suspend == CEC_EARLY_SUSPEND) {
1563 if (msg[2] == 0x40 || msg[2] == 0x6d)
1564 cec_key_report(0);
1565 }
1566 break;
1567
1568 case CEC_OC_MENU_REQUEST:
1569 if (cec_dev->cec_suspend != CEC_POWER_ON)
1570 cec_menu_status_smp(initiator, DEVICE_MENU_INACTIVE);
1571 else
1572 cec_menu_status_smp(initiator, DEVICE_MENU_ACTIVE);
1573 break;
1574
1575 default:
1576 CEC_ERR("unsupported command:%x\n", opcode);
1577 break;
1578 }
1579 new_msg = 0;
1580}
1581
1582static bool cec_service_suspended(void)
1583{
1584 /* service is not enabled */
1585 if (!(cec_dev->hal_flag & (1 << HDMI_OPTION_SERVICE_FLAG)))
1586 return false;
1587 if (!(cec_dev->hal_flag & (1 << HDMI_OPTION_SYSTEM_CEC_CONTROL)))
1588 return true;
1589 return false;
1590}
1591
1592static void cec_task(struct work_struct *work)
1593{
1594 struct delayed_work *dwork;
1595
1596 dwork = &cec_dev->cec_work;
1597 if (cec_dev && (!wake_ok || cec_service_suspended()))
1598 cec_rx_process();
1599
1600 if (!cec_late_check_rx_buffer())
1601 queue_delayed_work(cec_dev->cec_thread, dwork, CEC_FRAME_DELAY);
1602}
1603
1604static irqreturn_t cec_isr_handler(int irq, void *dev_instance)
1605{
1606 unsigned int intr_stat = 0;
1607 struct delayed_work *dwork;
1608
1609 dwork = &cec_dev->cec_work;
1610 intr_stat = cec_intr_stat();
1611 if (intr_stat & (1<<1)) { /* aocec tx intr */
1612 tx_irq_handle();
1613 return IRQ_HANDLED;
1614 }
1615 if ((-1) == cec_ll_rx(rx_msg, &rx_len))
1616 return IRQ_HANDLED;
1617
1618 complete(&cec_dev->rx_ok);
1619 /* check rx buffer is full */
1620 new_msg = 1;
1621 mod_delayed_work(cec_dev->cec_thread, dwork, 0);
1622 return IRQ_HANDLED;
1623}
1624
1625static void check_wake_up(void)
1626{
1627 if (wake_ok == 0)
1628 cec_request_active_source();
1629}
1630
1631/******************** cec class interface *************************/
1632static ssize_t device_type_show(struct class *cla,
1633 struct class_attribute *attr, char *buf)
1634{
1635 return sprintf(buf, "%ld\n", cec_dev->dev_type);
1636}
1637
1638static ssize_t device_type_store(struct class *cla,
1639 struct class_attribute *attr, const char *buf, size_t count)
1640{
1641 unsigned int type;
1642
1643 if (kstrtouint(buf, 10, &type) != 1)
1644 return -EINVAL;
1645
1646 cec_dev->dev_type = type;
1647 CEC_ERR("set dev_type to %d\n", type);
1648 return count;
1649}
1650
1651static ssize_t menu_language_show(struct class *cla,
1652 struct class_attribute *attr, char *buf)
1653{
1654 char a, b, c;
1655
1656 a = ((cec_dev->cec_info.menu_lang >> 16) & 0xff);
1657 b = ((cec_dev->cec_info.menu_lang >> 8) & 0xff);
1658 c = ((cec_dev->cec_info.menu_lang >> 0) & 0xff);
1659 return sprintf(buf, "%c%c%c\n", a, b, c);
1660}
1661
1662static ssize_t menu_language_store(struct class *cla,
1663 struct class_attribute *attr, const char *buf, size_t count)
1664{
1665 char a, b, c;
1666
1667 if (sscanf(buf, "%c%c%c", &a, &b, &c) != 3)
1668 return -EINVAL;
1669
1670 cec_dev->cec_info.menu_lang = (a << 16) | (b << 8) | c;
1671 CEC_ERR("set menu_language to %s\n", buf);
1672 return count;
1673}
1674
1675static ssize_t vendor_id_show(struct class *cla,
1676 struct class_attribute *attr, char *buf)
1677{
1678 return sprintf(buf, "%x\n", cec_dev->cec_info.vendor_id);
1679}
1680
1681static ssize_t vendor_id_store(struct class *cla, struct class_attribute *attr,
1682 const char *buf, size_t count)
1683{
1684 unsigned int id;
1685
1686 if (kstrtouint(buf, 16, &id) != 1)
1687 return -EINVAL;
1688 cec_dev->cec_info.vendor_id = id;
1689 return count;
1690}
1691
1692static ssize_t port_num_show(struct class *cla,
1693 struct class_attribute *attr, char *buf)
1694{
1695 return sprintf(buf, "%d\n", cec_dev->port_num);
1696}
1697
1698static const char * const cec_reg_name1[] = {
1699 "CEC_TX_MSG_LENGTH",
1700 "CEC_TX_MSG_CMD",
1701 "CEC_TX_WRITE_BUF",
1702 "CEC_TX_CLEAR_BUF",
1703 "CEC_RX_MSG_CMD",
1704 "CEC_RX_CLEAR_BUF",
1705 "CEC_LOGICAL_ADDR0",
1706 "CEC_LOGICAL_ADDR1",
1707 "CEC_LOGICAL_ADDR2",
1708 "CEC_LOGICAL_ADDR3",
1709 "CEC_LOGICAL_ADDR4",
1710 "CEC_CLOCK_DIV_H",
1711 "CEC_CLOCK_DIV_L"
1712};
1713
1714static const char * const cec_reg_name2[] = {
1715 "CEC_RX_MSG_LENGTH",
1716 "CEC_RX_MSG_STATUS",
1717 "CEC_RX_NUM_MSG",
1718 "CEC_TX_MSG_STATUS",
1719 "CEC_TX_NUM_MSG"
1720};
1721
1722static ssize_t dump_reg_show(struct class *cla,
1723 struct class_attribute *attr, char *b)
1724{
1725 int i, s = 0;
1726
1727 if (ee_cec)
1728 return dump_cecrx_reg(b);
1729
1730 s += sprintf(b + s, "TX buffer:\n");
1731 for (i = 0; i <= CEC_TX_MSG_F_OP14; i++)
1732 s += sprintf(b + s, "%2d:%2x\n", i, aocec_rd_reg(i));
1733
1734 for (i = 0; i < ARRAY_SIZE(cec_reg_name1); i++) {
1735 s += sprintf(b + s, "%s:%2x\n",
1736 cec_reg_name1[i], aocec_rd_reg(i + 0x10));
1737 }
1738
1739 s += sprintf(b + s, "RX buffer:\n");
1740 for (i = 0; i <= CEC_TX_MSG_F_OP14; i++)
1741 s += sprintf(b + s, "%2d:%2x\n", i, aocec_rd_reg(i + 0x80));
1742
1743 for (i = 0; i < ARRAY_SIZE(cec_reg_name2); i++) {
1744 s += sprintf(b + s, "%s:%2x\n",
1745 cec_reg_name2[i], aocec_rd_reg(i + 0x90));
1746 }
1747 return s;
1748}
1749
1750static ssize_t arc_port_show(struct class *cla,
1751 struct class_attribute *attr, char *buf)
1752{
1753 return sprintf(buf, "%x\n", cec_dev->arc_port);
1754}
1755
1756static ssize_t osd_name_show(struct class *cla,
1757 struct class_attribute *attr, char *buf)
1758{
1759 return sprintf(buf, "%s\n", cec_dev->cec_info.osd_name);
1760}
1761
1762static ssize_t port_seq_store(struct class *cla,
1763 struct class_attribute *attr,
1764 const char *buf, size_t count)
1765{
1766 unsigned int seq;
1767
1768 if (kstrtouint(buf, 16, &seq) != 1)
1769 return -EINVAL;
1770
1771 CEC_ERR("port_seq:%x\n", seq);
1772 cec_dev->port_seq = seq;
1773 return count;
1774}
1775
1776static ssize_t port_seq_show(struct class *cla,
1777 struct class_attribute *attr, char *buf)
1778{
1779 return sprintf(buf, "%x\n", cec_dev->port_seq);
1780}
1781
1782static ssize_t port_status_show(struct class *cla,
1783 struct class_attribute *attr, char *buf)
1784{
1785 unsigned int tmp;
1786 unsigned int tx_hpd;
1787
1788 tx_hpd = cec_dev->tx_dev->hpd_state;
1789 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) {
1790 tmp = tx_hpd;
1791 return sprintf(buf, "%x\n", tmp);
1792 }
1793
1794 tmp = hdmirx_rd_top(TOP_HPD_PWR5V);
1795 CEC_INFO("TOP_HPD_PWR5V:%x\n", tmp);
1796 tmp >>= 20;
1797 tmp &= 0xf;
1798 tmp |= (tx_hpd << 16);
1799 return sprintf(buf, "%x\n", tmp);
1800}
1801
1802static ssize_t pin_status_show(struct class *cla,
1803 struct class_attribute *attr, char *buf)
1804{
1805 unsigned int tx_hpd;
1806 char p;
1807
1808 tx_hpd = cec_dev->tx_dev->hpd_state;
1809 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) {
1810 if (!tx_hpd) {
1811 pin_status = 0;
1812 return sprintf(buf, "%s\n", "disconnected");
1813 }
1814 if (pin_status == 0) {
1815 p = (cec_dev->cec_info.log_addr << 4) | CEC_TV_ADDR;
1816 if (cec_ll_tx(&p, 1) == CEC_FAIL_NONE)
1817 return sprintf(buf, "%s\n", "ok");
1818 else
1819 return sprintf(buf, "%s\n", "fail");
1820 } else
1821 return sprintf(buf, "%s\n", "ok");
1822 } else {
1823 return sprintf(buf, "%s\n", pin_status ? "ok" : "fail");
1824 }
1825}
1826
1827static ssize_t physical_addr_show(struct class *cla,
1828 struct class_attribute *attr, char *buf)
1829{
1830 unsigned int tmp = cec_dev->phy_addr;
1831
1832 return sprintf(buf, "%04x\n", tmp);
1833}
1834
1835static ssize_t physical_addr_store(struct class *cla,
1836 struct class_attribute *attr,
1837 const char *buf, size_t count)
1838{
1839 int addr;
1840
1841 if (kstrtouint(buf, 16, &addr) != 1)
1842 return -EINVAL;
1843
1844 if (addr > 0xffff || addr < 0) {
1845 CEC_ERR("invalid input:%s\n", buf);
1846 phy_addr_test = 0;
1847 return -EINVAL;
1848 }
1849 cec_dev->phy_addr = addr;
1850 phy_addr_test = 1;
1851 return count;
1852}
1853
1854static ssize_t dbg_en_show(struct class *cla,
1855 struct class_attribute *attr, char *buf)
1856{
1857 return sprintf(buf, "%x\n", cec_msg_dbg_en);
1858}
1859
1860static ssize_t dbg_en_store(struct class *cla, struct class_attribute *attr,
1861 const char *buf, size_t count)
1862{
1863 int en;
1864
1865 if (kstrtouint(buf, 16, &en) != 1)
1866 return -EINVAL;
1867
1868 cec_msg_dbg_en = en ? 1 : 0;
1869 return count;
1870}
1871
1872static ssize_t cmd_store(struct class *cla, struct class_attribute *attr,
1873 const char *bu, size_t count)
1874{
1875 char buf[6] = {};
1876 int cnt;
1877
1878 cnt = sscanf(bu, "%x %x %x %x %x %x",
1879 (int *)&buf[0], (int *)&buf[1], (int *)&buf[2],
1880 (int *)&buf[3], (int *)&buf[4], (int *)&buf[5]);
1881 if (cnt < 0)
1882 return -EINVAL;
1883 cec_ll_tx(buf, cnt);
1884 return count;
1885}
1886
1887static ssize_t wake_up_show(struct class *cla,
1888 struct class_attribute *attr, char *buf)
1889{
1890 unsigned int reg = readl(cec_dev->cec_reg + AO_RTI_STATUS_REG1);
1891
1892 return sprintf(buf, "%x\n", reg & 0xfffff);
1893}
1894
1895static ssize_t fun_cfg_store(struct class *cla, struct class_attribute *attr,
1896 const char *bu, size_t count)
1897{
1898 int cnt, val;
1899
1900 cnt = kstrtouint(bu, 16, &val);
1901 if (cnt < 0 || val > 0xff)
1902 return -EINVAL;
1903 cec_config(val, 1);
1904 if (val == 0)
1905 cec_keep_reset();
1906 else
1907 cec_pre_init();
1908 return count;
1909}
1910
1911static ssize_t fun_cfg_show(struct class *cla,
1912 struct class_attribute *attr, char *buf)
1913{
1914 unsigned int reg = cec_config(0, 0);
1915
1916 return sprintf(buf, "0x%x\n", reg & 0xff);
1917}
1918
1919static ssize_t cec_version_show(struct class *cla,
1920 struct class_attribute *attr, char *buf)
1921{
1922 return sprintf(buf, "%d\n", cec_dev->cec_info.cec_version);
1923}
1924
1925static ssize_t log_addr_store(struct class *cla, struct class_attribute *attr,
1926 const char *bu, size_t count)
1927{
1928 int cnt, val;
1929
1930 cnt = kstrtoint(bu, 16, &val);
1931 if (cnt < 0 || val > 0xf)
1932 return -EINVAL;
1933 cec_logicaddr_set(val);
1934 /* add by hal, to init some data structure */
1935 cec_dev->cec_info.log_addr = val;
1936 cec_dev->cec_info.power_status = POWER_ON;
1937
1938 return count;
1939}
1940
1941static ssize_t log_addr_show(struct class *cla,
1942 struct class_attribute *attr, char *buf)
1943{
1944 return sprintf(buf, "0x%x\n", cec_dev->cec_info.log_addr);
1945}
1946
1947static struct class_attribute aocec_class_attr[] = {
1948 __ATTR_WO(cmd),
1949 __ATTR_RO(port_num),
1950 __ATTR_RO(osd_name),
1951 __ATTR_RO(dump_reg),
1952 __ATTR_RO(port_status),
1953 __ATTR_RO(pin_status),
1954 __ATTR_RO(cec_version),
1955 __ATTR_RO(arc_port),
1956 __ATTR_RO(wake_up),
1957 __ATTR(port_seq, 0664, port_seq_show, port_seq_store),
1958 __ATTR(physical_addr, 0664, physical_addr_show, physical_addr_store),
1959 __ATTR(vendor_id, 0664, vendor_id_show, vendor_id_store),
1960 __ATTR(menu_language, 0664, menu_language_show, menu_language_store),
1961 __ATTR(device_type, 0664, device_type_show, device_type_store),
1962 __ATTR(dbg_en, 0664, dbg_en_show, dbg_en_store),
1963 __ATTR(log_addr, 0664, log_addr_show, log_addr_store),
1964 __ATTR(fun_cfg, 0664, fun_cfg_show, fun_cfg_store),
1965 __ATTR_NULL
1966};
1967
1968/******************** cec hal interface ***************************/
1969static int hdmitx_cec_open(struct inode *inode, struct file *file)
1970{
1971 if (atomic_add_return(1, &cec_dev->cec_info.open_count)) {
1972 cec_dev->cec_info.hal_ctl = 1;
1973 /* set default logical addr flag for uboot */
1974 cec_set_reg_bits(AO_DEBUG_REG1, 0xf, 16, 4);
1975 }
1976 return 0;
1977}
1978
1979static int hdmitx_cec_release(struct inode *inode, struct file *file)
1980{
1981 if (!atomic_sub_return(1, &cec_dev->cec_info.open_count))
1982 cec_dev->cec_info.hal_ctl = 0;
1983 return 0;
1984}
1985
1986static ssize_t hdmitx_cec_read(struct file *f, char __user *buf,
1987 size_t size, loff_t *p)
1988{
1989 int ret;
1990
1991 if ((cec_dev->hal_flag & (1 << HDMI_OPTION_SYSTEM_CEC_CONTROL)))
1992 rx_len = 0;
1993 ret = wait_for_completion_timeout(&cec_dev->rx_ok, CEC_FRAME_DELAY);
1994 if (ret <= 0)
1995 return ret;
1996 if (rx_len == 0)
1997 return 0;
1998
1999 if (copy_to_user(buf, rx_msg, rx_len))
2000 return -EINVAL;
2001 return rx_len;
2002}
2003
2004static ssize_t hdmitx_cec_write(struct file *f, const char __user *buf,
2005 size_t size, loff_t *p)
2006{
2007 unsigned char tempbuf[16] = {};
2008 int ret;
2009
2010 if (size > 16)
2011 size = 16;
2012 if (size <= 0)
2013 return -EINVAL;
2014
2015 if (copy_from_user(tempbuf, buf, size))
2016 return -EINVAL;
2017
2018 ret = cec_ll_tx(tempbuf, size);
2019 return ret;
2020}
2021
2022static void init_cec_port_info(struct hdmi_port_info *port,
2023 struct ao_cec_dev *cec_dev)
2024{
2025 unsigned int a, b, c, d, e = 0;
2026 unsigned int phy_head = 0xf000, phy_app = 0x1000, phy_addr;
2027 struct hdmitx_dev *tx_dev;
2028
2029 /* physical address for TV or repeator */
2030 tx_dev = cec_dev->tx_dev;
2031 if (tx_dev == NULL || cec_dev->dev_type == DEV_TYPE_TV) {
2032 phy_addr = 0;
2033 } else if (tx_dev->hdmi_info.vsdb_phy_addr.valid == 1) {
2034 a = tx_dev->hdmi_info.vsdb_phy_addr.a;
2035 b = tx_dev->hdmi_info.vsdb_phy_addr.b;
2036 c = tx_dev->hdmi_info.vsdb_phy_addr.c;
2037 d = tx_dev->hdmi_info.vsdb_phy_addr.d;
2038 phy_addr = ((a << 12) | (b << 8) | (c << 4) | (d));
2039 } else
2040 phy_addr = 0;
2041
2042 /* found physical address append for repeator */
2043 for (a = 0; a < 4; a++) {
2044 if (phy_addr & phy_head) {
2045 phy_head >>= 4;
2046 phy_app >>= 4;
2047 } else
2048 break;
2049 }
2050 if (cec_dev->dev_type == DEV_TYPE_TUNER)
2051 b = cec_dev->port_num - 1;
2052 else
2053 b = cec_dev->port_num;
2054
2055 /* init for port info */
2056 for (a = 0; a < sizeof(cec_dev->port_seq) * 2; a++) {
2057 /* set port physical address according port sequence */
2058 if (cec_dev->port_seq) {
2059 c = (cec_dev->port_seq >> (4 * a)) & 0xf;
2060 if (c == 0xf) { /* not used */
2061 CEC_INFO("port %d is not used\n", a);
2062 continue;
2063 } else if (!c)
2064 break;
2065 port[e].physical_address = (c) * phy_app + phy_addr;
2066 } else {
2067 /* asending order if port_seq is not set */
2068 port[e].physical_address = (e + 1) * phy_app + phy_addr;
2069 }
2070 port[e].type = HDMI_INPUT;
2071 port[e].port_id = a + 1;
2072 port[e].cec_supported = 1;
2073 /* set ARC feature according mask */
2074 if (cec_dev->arc_port & (1 << a))
2075 port[e].arc_supported = 1;
2076 else
2077 port[e].arc_supported = 0;
2078 e++;
2079 if (e >= b)
2080 break;
2081 }
2082
2083 if (cec_dev->dev_type == DEV_TYPE_TUNER) {
2084 /* last port is for tx in mixed tx/rx */
2085 port[e].type = HDMI_OUTPUT;
2086 port[e].port_id = 0; /* 0 for tx port id */
2087 port[e].cec_supported = 1;
2088 port[e].arc_supported = 0;
2089 port[e].physical_address = phy_addr;
2090 }
2091}
2092
2093static long hdmitx_cec_ioctl(struct file *f,
2094 unsigned int cmd, unsigned long arg)
2095{
2096 void __user *argp = (void __user *)arg;
2097 unsigned long tmp;
2098 struct hdmi_port_info *port;
2099 int a, b, c, d;
2100 struct hdmitx_dev *tx_dev;
2101 int tx_hpd;
2102
2103 mutex_lock(&cec_dev->cec_ioctl_mutex);
2104 switch (cmd) {
2105 case CEC_IOC_GET_PHYSICAL_ADDR:
2106 check_physical_addr_valid(20);
2107 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK && !phy_addr_test) {
2108 /* physical address for mbox */
2109 if (cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.valid
2110 == 0) {
2111 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2112 return -EINVAL;
2113 }
2114 a = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.a;
2115 b = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.b;
2116 c = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.c;
2117 d = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.d;
2118 tmp = ((a << 12) | (b << 8) | (c << 4) | (d << 0));
2119 } else {
2120 /* physical address for TV or repeator */
2121 tx_dev = cec_dev->tx_dev;
2122 if (!tx_dev || cec_dev->dev_type == DEV_TYPE_TV) {
2123 tmp = 0;
2124 } else if (tx_dev->hdmi_info.vsdb_phy_addr.valid == 1) {
2125 a = tx_dev->hdmi_info.vsdb_phy_addr.a;
2126 b = tx_dev->hdmi_info.vsdb_phy_addr.b;
2127 c = tx_dev->hdmi_info.vsdb_phy_addr.c;
2128 d = tx_dev->hdmi_info.vsdb_phy_addr.d;
2129 tmp = ((a << 12) | (b << 8) | (c << 4) | (d));
2130 } else
2131 tmp = 0;
2132 }
2133 if (!phy_addr_test) {
2134 cec_dev->phy_addr = tmp;
2135 cec_phyaddr_config(tmp, 1);
2136 } else
2137 tmp = cec_dev->phy_addr;
2138
2139 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2140 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2141 return -EINVAL;
2142 }
2143 break;
2144
2145 case CEC_IOC_GET_VERSION:
2146 tmp = cec_dev->cec_info.cec_version;
2147 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2148 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2149 return -EINVAL;
2150 }
2151 break;
2152
2153 case CEC_IOC_GET_VENDOR_ID:
2154 tmp = cec_dev->v_data.vendor_id;
2155 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2156 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2157 return -EINVAL;
2158 }
2159 break;
2160
2161 case CEC_IOC_GET_PORT_NUM:
2162 tmp = cec_dev->port_num;
2163 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2164 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2165 return -EINVAL;
2166 }
2167 break;
2168
2169 case CEC_IOC_GET_PORT_INFO:
2170 port = kcalloc(cec_dev->port_num, sizeof(*port), GFP_KERNEL);
2171 if (!port) {
2172 CEC_ERR("no memory\n");
2173 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2174 return -EINVAL;
2175 }
2176 check_physical_addr_valid(20);
2177 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) {
2178 /* for tx only 1 port */
2179 a = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.a;
2180 b = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.b;
2181 c = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.c;
2182 d = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.d;
2183 tmp = ((a << 12) | (b << 8) | (c << 4) | (d << 0));
2184 if (cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.valid == 0)
2185 tmp = 0xffff;
2186 port->type = HDMI_OUTPUT;
2187 port->port_id = 0;
2188 port->cec_supported = 1;
2189 /* not support arc for tx */
2190 port->arc_supported = 0;
2191 port->physical_address = tmp & 0xffff;
2192 if (copy_to_user(argp, port, sizeof(*port))) {
2193 kfree(port);
2194 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2195 return -EINVAL;
2196 }
2197 } else {
2198 b = cec_dev->port_num;
2199 init_cec_port_info(port, cec_dev);
2200 if (copy_to_user(argp, port, sizeof(*port) * b)) {
2201 kfree(port);
2202 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2203 return -EINVAL;
2204 }
2205 }
2206 kfree(port);
2207 break;
2208
2209 case CEC_IOC_SET_OPTION_WAKEUP:
2210 tmp = cec_config(0, 0);
2211 tmp &= ~(1 << AUTO_POWER_ON_MASK);
2212 tmp |= (arg << AUTO_POWER_ON_MASK);
2213 cec_config(tmp, 1);
2214 break;
2215
2216 case CEC_IOC_SET_AUTO_DEVICE_OFF:
2217 tmp = cec_config(0, 0);
2218 tmp &= ~(1 << ONE_TOUCH_STANDBY_MASK);
2219 tmp |= (arg << ONE_TOUCH_STANDBY_MASK);
2220 cec_config(tmp, 1);
2221 break;
2222
2223 case CEC_IOC_SET_OPTION_ENALBE_CEC:
2224 tmp = (1 << HDMI_OPTION_ENABLE_CEC);
2225 if (arg) {
2226 cec_dev->hal_flag |= tmp;
2227 cec_config(0x2f, 1);
2228 cec_pre_init();
2229 } else {
2230 cec_dev->hal_flag &= ~(tmp);
2231 CEC_INFO("disable CEC\n");
2232 cec_config(0x0, 1);
2233 cec_keep_reset();
2234 }
2235 break;
2236
2237 case CEC_IOC_SET_OPTION_SYS_CTRL:
2238 tmp = (1 << HDMI_OPTION_SYSTEM_CEC_CONTROL);
2239 if (arg) {
2240 cec_dev->hal_flag |= tmp;
2241 cec_config(0x2f, 1);
2242 } else
2243 cec_dev->hal_flag &= ~(tmp);
2244 cec_dev->hal_flag |= (1 << HDMI_OPTION_SERVICE_FLAG);
2245 break;
2246
2247 case CEC_IOC_SET_OPTION_SET_LANG:
2248 cec_dev->cec_info.menu_lang = arg;
2249 break;
2250
2251 case CEC_IOC_GET_CONNECT_STATUS:
2252 tx_hpd = cec_dev->tx_dev->hpd_state;
2253 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK)
2254 tmp = tx_hpd;
2255 else {
2256 if (copy_from_user(&a, argp, _IOC_SIZE(cmd))) {
2257 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2258 return -EINVAL;
2259 }
2260 if (!a && cec_dev->dev_type == DEV_TYPE_TUNER)
2261 tmp = tx_hpd;
2262 else { /* mixed for rx */
2263 tmp = (hdmirx_rd_top(TOP_HPD_PWR5V) >> 20);
2264 if (tmp & (1 << (a - 1)))
2265 tmp = 1;
2266 else
2267 tmp = 0;
2268 }
2269 }
2270 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2271 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2272 return -EINVAL;
2273 }
2274 break;
2275
2276 case CEC_IOC_ADD_LOGICAL_ADDR:
2277 tmp = arg & 0xf;
2278 cec_logicaddr_set(tmp);
2279 /* add by hal, to init some data structure */
2280 cec_dev->cec_info.log_addr = tmp;
2281 cec_dev->cec_info.power_status = POWER_ON;
2282
2283 cec_dev->cec_info.vendor_id = cec_dev->v_data.vendor_id;
2284 strcpy(cec_dev->cec_info.osd_name,
2285 cec_dev->v_data.cec_osd_string);
2286
2287 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK)
2288 cec_dev->cec_info.menu_status = DEVICE_MENU_ACTIVE;
2289 else
2290 check_wake_up();
2291 break;
2292
2293 case CEC_IOC_CLR_LOGICAL_ADDR:
2294 cec_clear_logical_addr();
2295 break;
2296
2297 case CEC_IOC_SET_DEV_TYPE:
2298 if (arg > DEV_TYPE_VIDEO_PROCESSOR) {
2299 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2300 return -EINVAL;
2301 }
2302 cec_dev->dev_type = arg;
2303 break;
2304
2305 case CEC_IOC_SET_ARC_ENABLE:
2306 /* select arc according arg */
2307 if (arg)
2308 hdmirx_wr_top(TOP_ARCTX_CNTL, 0x01);
2309 else
2310 hdmirx_wr_top(TOP_ARCTX_CNTL, 0x00);
2311 CEC_INFO("set arc en:%ld, reg:%lx\n",
2312 arg, hdmirx_rd_top(TOP_ARCTX_CNTL));
2313 break;
2314
2315 default:
2316 break;
2317 }
2318 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2319 return 0;
2320}
2321
2322#ifdef CONFIG_COMPAT
2323static long hdmitx_cec_compat_ioctl(struct file *f,
2324 unsigned int cmd, unsigned long arg)
2325{
2326 arg = (unsigned long)compat_ptr(arg);
2327 return hdmitx_cec_ioctl(f, cmd, arg);
2328}
2329#endif
2330
2331/* for improve rw permission */
2332static char *aml_cec_class_devnode(struct device *dev, umode_t *mode)
2333{
2334 if (mode) {
2335 *mode = 0666;
2336 CEC_INFO("mode is %x\n", *mode);
2337 } else
2338 CEC_INFO("mode is null\n");
2339 return NULL;
2340}
2341
2342static struct class aocec_class = {
2343 .name = CEC_DEV_NAME,
2344 .class_attrs = aocec_class_attr,
2345 .devnode = aml_cec_class_devnode,
2346};
2347
2348
2349static const struct file_operations hdmitx_cec_fops = {
2350 .owner = THIS_MODULE,
2351 .open = hdmitx_cec_open,
2352 .read = hdmitx_cec_read,
2353 .write = hdmitx_cec_write,
2354 .release = hdmitx_cec_release,
2355 .unlocked_ioctl = hdmitx_cec_ioctl,
2356#ifdef CONFIG_COMPAT
2357 .compat_ioctl = hdmitx_cec_compat_ioctl,
2358#endif
2359};
2360
2361/************************ cec high level code *****************************/
2362#ifdef CONFIG_HAS_EARLYSUSPEND
2363static void aocec_early_suspend(struct early_suspend *h)
2364{
2365 cec_dev->cec_suspend = CEC_EARLY_SUSPEND;
2366 CEC_INFO("%s, suspend:%d\n", __func__, cec_dev->cec_suspend);
2367}
2368
2369static void aocec_late_resume(struct early_suspend *h)
2370{
2371 cec_dev->cec_suspend = CEC_POWER_ON;
2372 CEC_INFO("%s, suspend:%d\n", __func__, cec_dev->cec_suspend);
2373
2374}
2375#endif
2376
2377#ifdef CONFIG_OF
2378static const struct cec_platform_data_s cec_gxl_data = {
2379 .line_bit = 8,
2380 .ee_to_ao = 0,
2381};
2382
2383static const struct cec_platform_data_s cec_txlx_data = {
2384 .line_bit = 7,
2385 .ee_to_ao = 1,
2386};
2387
2388static const struct of_device_id aml_cec_dt_match[] = {
2389 {
2390 .compatible = "amlogic, amlogic-aocec",
2391 .data = &cec_gxl_data,
2392 },
2393 {
2394 .compatible = "amlogic, aocec-txlx",
2395 .data = &cec_txlx_data,
2396 },
2397};
2398#endif
2399
2400static int aml_cec_probe(struct platform_device *pdev)
2401{
2402 struct device *cdev;
2403 int ret = 0;
2404 const struct of_device_id *of_id;
2405#ifdef CONFIG_OF
2406 struct device_node *node = pdev->dev.of_node;
2407 int irq_idx = 0, r;
2408 const char *irq_name = NULL;
2409 /*struct pinctrl *p;*/
2410 struct vendor_info_data *vend;
2411 struct resource *res;
2412 resource_size_t *base;
2413#endif
2414
2415 cec_dev = devm_kzalloc(&pdev->dev, sizeof(struct ao_cec_dev),
2416 GFP_KERNEL);
2417 if (!cec_dev) {
2418 CEC_ERR("device malloc err!\n");
2419 ret = -ENOMEM;
2420 goto tag_cec_devm_err;
2421 }
2422 CEC_ERR("cec driver date:%s\n", CEC_DRIVER_VERSION);
2423 cec_dev->dev_type = DEV_TYPE_PLAYBACK;
2424 cec_dev->dbg_dev = &pdev->dev;
2425 cec_dev->tx_dev = get_hdmitx_device();
2426 cec_dev->cpu_type = get_cpu_type();
2427 phy_addr_test = 0;
2428
2429 /* cdev registe */
2430 r = class_register(&aocec_class);
2431 if (r) {
2432 CEC_ERR("regist class failed\n");
2433 ret = -EINVAL;
2434 goto tag_cec_class_reg;
2435 }
2436 pdev->dev.class = &aocec_class;
2437 r = register_chrdev(0, CEC_DEV_NAME,
2438 &hdmitx_cec_fops);
2439 if (r < 0) {
2440 CEC_ERR("alloc chrdev failed\n");
2441 ret = -EINVAL;
2442 goto tag_cec_chr_reg_err;
2443 }
2444 cec_dev->cec_info.dev_no = r;
2445 CEC_INFO("alloc chrdev %x\n", cec_dev->cec_info.dev_no);
2446 cdev = device_create(&aocec_class, &pdev->dev,
2447 MKDEV(cec_dev->cec_info.dev_no, 0),
2448 NULL, CEC_DEV_NAME);
2449 if (IS_ERR(cdev)) {
2450 CEC_ERR("create chrdev failed, dev:%p\n", cdev);
2451 ret = -EINVAL;
2452 goto tag_cec_device_create_err;
2453 }
2454
2455 /*get compatible matched device, to get chip related data*/
2456 of_id = of_match_device(aml_cec_dt_match, &pdev->dev);
2457 if (!of_id)
2458 CEC_ERR("unable to get matched device\n");
2459 cec_dev->plat_data = (struct cec_platform_data_s *)of_id->data;
2460
2461 cec_dev->cec_info.open_count.counter = 0;
2462 init_completion(&cec_dev->rx_ok);
2463 init_completion(&cec_dev->tx_ok);
2464 mutex_init(&cec_dev->cec_mutex);
2465 mutex_init(&cec_dev->cec_ioctl_mutex);
2466 spin_lock_init(&cec_dev->cec_reg_lock);
2467 cec_dev->cec_thread = create_workqueue("cec_work");
2468 if (cec_dev->cec_thread == NULL) {
2469 CEC_INFO("create work queue failed\n");
2470 ret = -EFAULT;
2471 goto tag_cec_threat_err;
2472 }
2473 INIT_DELAYED_WORK(&cec_dev->cec_work, cec_task);
2474 cec_dev->cec_info.remote_cec_dev = input_allocate_device();
2475 if (!cec_dev->cec_info.remote_cec_dev) {
2476 CEC_INFO("No enough memory\n");
2477 ret = -ENOMEM;
2478 goto tag_cec_alloc_input_err;
2479 }
2480
2481 cec_dev->cec_info.remote_cec_dev->name = "cec_input";
2482
2483 cec_dev->cec_info.remote_cec_dev->evbit[0] = BIT_MASK(EV_KEY);
2484 cec_dev->cec_info.remote_cec_dev->keybit[BIT_WORD(BTN_0)] =
2485 BIT_MASK(BTN_0);
2486 cec_dev->cec_info.remote_cec_dev->id.bustype = BUS_ISA;
2487 cec_dev->cec_info.remote_cec_dev->id.vendor = 0x1b8e;
2488 cec_dev->cec_info.remote_cec_dev->id.product = 0x0cec;
2489 cec_dev->cec_info.remote_cec_dev->id.version = 0x0001;
2490
2491 set_bit(KEY_POWER, cec_dev->cec_info.remote_cec_dev->keybit);
2492
2493 if (input_register_device(cec_dev->cec_info.remote_cec_dev)) {
2494 CEC_INFO("Failed to register device\n");
2495 input_free_device(cec_dev->cec_info.remote_cec_dev);
2496 }
2497
2498#ifdef CONFIG_OF
2499 /* if using EE CEC */
2500 if (of_property_read_bool(node, "ee_cec"))
2501 ee_cec = 1;
2502 else
2503 ee_cec = 0;
2504 CEC_INFO("using EE cec:%d\n", ee_cec);
2505 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2506 if (res) {
2507 base = ioremap(res->start, res->end - res->start);
2508 cec_dev->exit_reg = (void *)base;
2509 } else {
2510 CEC_INFO("no memory resource\n");
2511 cec_dev->exit_reg = NULL;
2512 }
2513 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2514 if (res) {
2515 base = ioremap(res->start, res->end - res->start);
2516 cec_dev->cec_reg = (void *)base;
2517 } else {
2518 CEC_ERR("no CEC reg resource\n");
2519 cec_dev->cec_reg = NULL;
2520 }
2521 res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
2522 if (res) {
2523 base = ioremap(res->start, res->end - res->start);
2524 cec_dev->hdmi_rxreg = (void *)base;
2525 } else {
2526 CEC_ERR("no hdmirx reg resource\n");
2527 cec_dev->hdmi_rxreg = NULL;
2528 }
2529 res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
2530 if (res) {
2531 base = ioremap(res->start, res->end - res->start);
2532 cec_dev->hhi_reg = (void *)base;
2533 } else {
2534 CEC_ERR("no hhi reg resource\n");
2535 cec_dev->hhi_reg = NULL;
2536 }
2537 r = of_property_read_u32(node, "port_num", &(cec_dev->port_num));
2538 if (r) {
2539 CEC_ERR("not find 'port_num'\n");
2540 cec_dev->port_num = 1;
2541 }
2542 r = of_property_read_u32(node, "arc_port_mask", &(cec_dev->arc_port));
2543 if (r) {
2544 CEC_ERR("not find 'arc_port_mask'\n");
2545 cec_dev->arc_port = 0;
2546 }
2547
2548 vend = &cec_dev->v_data;
2549 r = of_property_read_string(node, "vendor_name",
2550 (const char **)&(vend->vendor_name));
2551 if (r)
2552 CEC_INFO("not find vendor name\n");
2553
2554 r = of_property_read_u32(node, "vendor_id", &(vend->vendor_id));
2555 if (r)
2556 CEC_INFO("not find vendor id\n");
2557
2558 r = of_property_read_string(node, "product_desc",
2559 (const char **)&(vend->product_desc));
2560 if (r)
2561 CEC_INFO("not find product desc\n");
2562
2563 r = of_property_read_string(node, "cec_osd_string",
2564 (const char **)&(vend->cec_osd_string));
2565 if (r) {
2566 CEC_INFO("not find cec osd string\n");
2567 strcpy(vend->cec_osd_string, "AML TV/BOX");
2568 }
2569 r = of_property_read_u32(node, "cec_version",
2570 &(cec_dev->cec_info.cec_version));
2571 if (r) {
2572 /* default set to 2.0 */
2573 CEC_INFO("not find cec_version\n");
2574 cec_dev->cec_info.cec_version = CEC_VERSION_20;
2575 }
2576
2577 /* irq set */
2578 cec_irq_enable(false);
2579 irq_idx = of_irq_get(node, 0);
2580 cec_dev->irq_cec = irq_idx;
2581 if (of_get_property(node, "interrupt-names", NULL)) {
2582 r = of_property_read_string(node, "interrupt-names", &irq_name);
2583 if (!r && !ee_cec) {
2584 r = request_irq(irq_idx, &cec_isr_handler, IRQF_SHARED,
2585 irq_name, (void *)cec_dev);
2586 }
2587 if (!r && ee_cec) {
2588 r = request_irq(irq_idx, &cecrx_isr, IRQF_SHARED,
2589 irq_name, (void *)cec_dev);
2590 }
2591 }
2592#endif
2593
2594 if (!ee_cec) {
2595 last_cec_msg = devm_kzalloc(&pdev->dev,
2596 sizeof(*last_cec_msg), GFP_KERNEL);
2597 if (!last_cec_msg) {
2598 CEC_ERR("allocate last_cec_msg failed\n");
2599 ret = -ENOMEM;
2600 goto tag_cec_msg_alloc_err;
2601 }
2602 }
2603
2604#ifdef CONFIG_HAS_EARLYSUSPEND
2605 aocec_suspend_handler.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
2606 aocec_suspend_handler.suspend = aocec_early_suspend;
2607 aocec_suspend_handler.resume = aocec_late_resume;
2608 aocec_suspend_handler.param = cec_dev;
2609 register_early_suspend(&aocec_suspend_handler);
2610#endif
2611 hrtimer_init(&start_bit_check, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2612 start_bit_check.function = cec_line_check;
2613 /* for init */
2614 cec_pre_init();
2615 queue_delayed_work(cec_dev->cec_thread, &cec_dev->cec_work, 0);
2616
2617 return 0;
2618tag_cec_msg_alloc_err:
2619 input_free_device(cec_dev->cec_info.remote_cec_dev);
2620tag_cec_alloc_input_err:
2621 destroy_workqueue(cec_dev->cec_thread);
2622tag_cec_threat_err:
2623 device_destroy(&aocec_class,
2624 MKDEV(cec_dev->cec_info.dev_no, 0));
2625tag_cec_device_create_err:
2626 unregister_chrdev(cec_dev->cec_info.dev_no, CEC_DEV_NAME);
2627tag_cec_chr_reg_err:
2628 class_unregister(&aocec_class);
2629tag_cec_class_reg:
2630 devm_kfree(&pdev->dev, cec_dev);
2631tag_cec_devm_err:
2632 return ret;
2633}
2634
2635static int aml_cec_remove(struct platform_device *pdev)
2636{
2637 CEC_INFO("cec uninit!\n");
2638 free_irq(cec_dev->irq_cec, (void *)cec_dev);
2639 kfree(last_cec_msg);
2640
2641 if (cec_dev->cec_thread) {
2642 cancel_delayed_work_sync(&cec_dev->cec_work);
2643 destroy_workqueue(cec_dev->cec_thread);
2644 }
2645 input_unregister_device(cec_dev->cec_info.remote_cec_dev);
2646 unregister_chrdev(cec_dev->cec_info.dev_no, CEC_DEV_NAME);
2647 class_unregister(&aocec_class);
2648 kfree(cec_dev);
2649 return 0;
2650}
2651
2652#ifdef CONFIG_PM
2653static int aml_cec_pm_prepare(struct device *dev)
2654{
2655 cec_dev->cec_suspend = CEC_DEEP_SUSPEND;
2656 CEC_INFO("%s, cec_suspend:%d\n", __func__, cec_dev->cec_suspend);
2657 return 0;
2658}
2659
2660static void aml_cec_pm_complete(struct device *dev)
2661{
2662 int exit = 0;
2663
2664 if (cec_dev->exit_reg) {
2665 exit = readl(cec_dev->exit_reg);
2666 CEC_INFO("wake up flag:%x\n", exit);
2667 }
2668 if (((exit >> 28) & 0xf) == CEC_WAKEUP)
2669 cec_key_report(0);
2670}
2671
2672static int aml_cec_suspend_noirq(struct device *dev)
2673{
2674 return 0;
2675}
2676
2677static int aml_cec_resume_noirq(struct device *dev)
2678{
2679 CEC_INFO("cec resume noirq!\n");
2680 cec_dev->cec_info.power_status = TRANS_STANDBY_TO_ON;
2681 cec_dev->cec_suspend = CEC_POWER_RESUME;
2682
2683 return 0;
2684}
2685
2686static const struct dev_pm_ops aml_cec_pm = {
2687 .prepare = aml_cec_pm_prepare,
2688 .complete = aml_cec_pm_complete,
2689 .suspend_noirq = aml_cec_suspend_noirq,
2690 .resume_noirq = aml_cec_resume_noirq,
2691};
2692#endif
2693
2694static struct platform_driver aml_cec_driver = {
2695 .driver = {
2696 .name = "cectx",
2697 .owner = THIS_MODULE,
2698 #ifdef CONFIG_PM
2699 .pm = &aml_cec_pm,
2700 #endif
2701 #ifdef CONFIG_OF
2702 .of_match_table = aml_cec_dt_match,
2703 #endif
2704 },
2705 .probe = aml_cec_probe,
2706 .remove = aml_cec_remove,
2707};
2708
2709static int __init cec_init(void)
2710{
2711 int ret;
2712
2713 ret = platform_driver_register(&aml_cec_driver);
2714 return ret;
2715}
2716
2717static void __exit cec_uninit(void)
2718{
2719 platform_driver_unregister(&aml_cec_driver);
2720}
2721
2722module_init(cec_init);
2723module_exit(cec_uninit);
2724MODULE_DESCRIPTION("AMLOGIC HDMI TX CEC driver");
2725MODULE_LICENSE("GPL");
2726