summaryrefslogtreecommitdiff
path: root/drivers/amlogic/cec/hdmi_ao_cec.c (plain)
blob: e2245f7842c9de52aa70700d0858de644579546c
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 inline bool is_report_phy_addr_msg(const unsigned char *msg, int len)
779{
780 if (!msg || len < 4)
781 return false;
782 if (msg[1] == CEC_OC_REPORT_PHYSICAL_ADDRESS)
783 return true;
784 return false;
785}
786
787static bool need_nack_repeat_msg(const unsigned char *msg, int len, int t)
788{
789 if (len == last_cec_msg->len &&
790 (is_poll_message(msg[0]) || is_feature_abort_msg(msg, len) ||
791 is_report_phy_addr_msg(msg, len)) &&
792 last_cec_msg->last_result == CEC_FAIL_NACK &&
793 jiffies - last_cec_msg->last_jiffies < t) {
794 return true;
795 }
796 return false;
797}
798
799static void cec_clear_logical_addr(void)
800{
801 if (ee_cec) {
802 hdmirx_cec_write(DWC_CEC_ADDR_L, 0);
803 hdmirx_cec_write(DWC_CEC_ADDR_H, 0x80);
804 } else
805 aocec_wr_reg(CEC_LOGICAL_ADDR0, 0);
806 udelay(100);
807}
808
809int cec_rx_buf_check(void)
810{
811 unsigned int rx_num_msg;
812
813 if (ee_cec) {
814 cecrx_check_irq_enable();
815 cecrx_irq_handle();
816 return 0;
817 }
818
819 rx_num_msg = aocec_rd_reg(CEC_RX_NUM_MSG);
820 if (rx_num_msg)
821 CEC_INFO("rx msg num:0x%02x\n", rx_num_msg);
822
823 return rx_num_msg;
824}
825
826int cec_ll_rx(unsigned char *msg, unsigned char *len)
827{
828 int i;
829 int ret = -1;
830 int pos;
831 int rx_stat;
832
833 rx_stat = aocec_rd_reg(CEC_RX_MSG_STATUS);
834 if ((rx_stat != RX_DONE) || (aocec_rd_reg(CEC_RX_NUM_MSG) != 1)) {
835 CEC_INFO("rx status:%x\n", rx_stat);
836 writel((1 << 2), cec_dev->cec_reg + AO_CEC_INTR_CLR);
837 aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT);
838 aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP);
839 cec_rx_buf_clear();
840 return ret;
841 }
842
843 *len = aocec_rd_reg(CEC_RX_MSG_LENGTH) + 1;
844
845 for (i = 0; i < (*len) && i < MAX_MSG; i++)
846 msg[i] = aocec_rd_reg(CEC_RX_MSG_0_HEADER + i);
847
848 ret = rx_stat;
849
850 /* ignore ping message */
851 if (cec_msg_dbg_en == 1 && *len > 1) {
852 pos = 0;
853 pos += sprintf(msg_log_buf + pos,
854 "CEC: rx msg len: %d dat: ", *len);
855 for (i = 0; i < (*len); i++)
856 pos += sprintf(msg_log_buf + pos, "%02x ", msg[i]);
857 pos += sprintf(msg_log_buf + pos, "\n");
858 msg_log_buf[pos] = '\0';
859 CEC_INFO("%s", msg_log_buf);
860 }
861 last_cec_msg->len = 0; /* invalid back up msg when rx */
862 writel((1 << 2), cec_dev->cec_reg + AO_CEC_INTR_CLR);
863 aocec_wr_reg(CEC_RX_MSG_CMD, RX_ACK_CURRENT);
864 aocec_wr_reg(CEC_RX_MSG_CMD, RX_NO_OP);
865 cec_rx_buf_clear();
866 pin_status = 1;
867 return ret;
868}
869
870/************************ cec arbitration cts code **************************/
871/* using the cec pin as fiq gpi to assist the bus arbitration */
872
873/* return value: 1: successful 0: error */
874static int cec_ll_trigle_tx(const unsigned char *msg, int len)
875{
876 int i;
877 unsigned int n;
878 int pos;
879 int reg;
880 unsigned int j = 40;
881 unsigned int tx_stat;
882 static int cec_timeout_cnt = 1;
883
884 while (1) {
885 tx_stat = aocec_rd_reg(CEC_TX_MSG_STATUS);
886 if (tx_stat != TX_BUSY)
887 break;
888
889 if (!(j--)) {
890 CEC_INFO("waiting busy timeout\n");
891 aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT);
892 cec_timeout_cnt++;
893 if (cec_timeout_cnt > 0x08)
894 cec_hw_reset();
895 break;
896 }
897 msleep(20);
898 }
899
900 reg = aocec_rd_reg(CEC_TX_MSG_STATUS);
901 if (reg == TX_IDLE || reg == TX_DONE) {
902 for (i = 0; i < len; i++)
903 aocec_wr_reg(CEC_TX_MSG_0_HEADER + i, msg[i]);
904
905 aocec_wr_reg(CEC_TX_MSG_LENGTH, len-1);
906 aocec_wr_reg(CEC_TX_MSG_CMD, TX_REQ_CURRENT);
907
908 if (cec_msg_dbg_en == 1) {
909 pos = 0;
910 pos += sprintf(msg_log_buf + pos,
911 "CEC: tx msg len: %d dat: ", len);
912 for (n = 0; n < len; n++) {
913 pos += sprintf(msg_log_buf + pos,
914 "%02x ", msg[n]);
915 }
916
917 pos += sprintf(msg_log_buf + pos, "\n");
918
919 msg_log_buf[pos] = '\0';
920 pr_info("%s", msg_log_buf);
921 }
922 cec_timeout_cnt = 0;
923 return 0;
924 }
925 return -1;
926}
927
928void tx_irq_handle(void)
929{
930 unsigned int tx_status = aocec_rd_reg(CEC_TX_MSG_STATUS);
931
932 cec_tx_result = -1;
933 switch (tx_status) {
934 case TX_DONE:
935 aocec_wr_reg(CEC_TX_MSG_CMD, TX_NO_OP);
936 cec_tx_result = CEC_FAIL_NONE;
937 break;
938
939 case TX_BUSY:
940 CEC_ERR("TX_BUSY\n");
941 cec_tx_result = CEC_FAIL_BUSY;
942 break;
943
944 case TX_ERROR:
945 if (cec_msg_dbg_en == 1)
946 CEC_ERR("TX ERROR!!!\n");
947 aocec_wr_reg(CEC_TX_MSG_CMD, TX_ABORT);
948 cec_hw_reset();
949 cec_tx_result = CEC_FAIL_NACK;
950 break;
951
952 case TX_IDLE:
953 CEC_ERR("TX_IDLE\n");
954 cec_tx_result = CEC_FAIL_OTHER;
955 break;
956 default:
957 break;
958 }
959 writel((1 << 1), cec_dev->cec_reg + AO_CEC_INTR_CLR);
960 complete(&cec_dev->tx_ok);
961}
962
963static int get_line(void)
964{
965 int reg, ret = -EINVAL;
966
967 reg = readl(cec_dev->cec_reg + AO_GPIO_I);
968 ret = (reg & (1 << cec_dev->plat_data->line_bit));
969
970 return ret;
971}
972
973static enum hrtimer_restart cec_line_check(struct hrtimer *timer)
974{
975 if (get_line() == 0)
976 cec_line_cnt++;
977 hrtimer_forward_now(timer, HR_DELAY(1));
978 return HRTIMER_RESTART;
979}
980
981static int check_confilct(void)
982{
983 int i;
984
985 for (i = 0; i < 200; i++) {
986 /*
987 * sleep 20ms and using hrtimer to check cec line every 1ms
988 */
989 cec_line_cnt = 0;
990 hrtimer_start(&start_bit_check, HR_DELAY(1), HRTIMER_MODE_REL);
991 msleep(20);
992 hrtimer_cancel(&start_bit_check);
993 if (cec_line_cnt == 0)
994 break;
995 CEC_INFO("line busy:%d\n", cec_line_cnt);
996 }
997 if (i >= 200)
998 return -EBUSY;
999 else
1000 return 0;
1001}
1002
1003static bool check_physical_addr_valid(int timeout)
1004{
1005 while (timeout > 0) {
1006 if (cec_dev->dev_type == DEV_TYPE_TV)
1007 break;
1008 if (phy_addr_test)
1009 break;
1010 /* physical address for box */
1011 if (cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.valid == 0) {
1012 msleep(100);
1013 timeout--;
1014 } else
1015 break;
1016 }
1017 if (timeout <= 0)
1018 return false;
1019 return true;
1020}
1021
1022/* Return value: < 0: fail, > 0: success */
1023int cec_ll_tx(const unsigned char *msg, unsigned char len)
1024{
1025 int ret = -1;
1026 int t = msecs_to_jiffies(ee_cec ? 2000 : 5000);
1027 int retry = 2;
1028
1029 if (len == 0)
1030 return CEC_FAIL_NONE;
1031
1032 if (is_poll_message(msg[0]))
1033 cec_clear_logical_addr();
1034
1035 /*
1036 * for CEC CTS 9.3. Android will try 3 poll message if got NACK
1037 * but AOCEC will retry 4 tx for each poll message. Framework
1038 * repeat this poll message so quick makes 12 sequential poll
1039 * waveform seen on CEC bus. And did not pass CTS
1040 * specification of 9.3
1041 */
1042 if (!ee_cec && need_nack_repeat_msg(msg, len, t)) {
1043 if (!memcmp(msg, last_cec_msg->msg, len)) {
1044 CEC_INFO("NACK repeat message:%x\n", len);
1045 return CEC_FAIL_NACK;
1046 }
1047 }
1048
1049 mutex_lock(&cec_dev->cec_mutex);
1050 /* make sure we got valid physical address */
1051 if (len >= 2 && msg[1] == CEC_OC_REPORT_PHYSICAL_ADDRESS)
1052 check_physical_addr_valid(3);
1053
1054try_again:
1055 reinit_completion(&cec_dev->tx_ok);
1056 /*
1057 * CEC controller won't ack message if it is going to send
1058 * state. If we detect cec line is low during waiting signal
1059 * free time, that means a send is already started by other
1060 * device, we should wait it finished.
1061 */
1062 if (check_confilct()) {
1063 CEC_ERR("bus confilct too long\n");
1064 mutex_unlock(&cec_dev->cec_mutex);
1065 return CEC_FAIL_BUSY;
1066 }
1067
1068 if (ee_cec)
1069 ret = cecrx_trigle_tx(msg, len);
1070 else
1071 ret = cec_ll_trigle_tx(msg, len);
1072 if (ret < 0) {
1073 /* we should increase send idx if busy */
1074 CEC_INFO("tx busy\n");
1075 if (retry > 0) {
1076 retry--;
1077 msleep(100 + (prandom_u32() & 0x07) * 10);
1078 goto try_again;
1079 }
1080 mutex_unlock(&cec_dev->cec_mutex);
1081 return CEC_FAIL_BUSY;
1082 }
1083 cec_tx_result = -1;
1084 ret = wait_for_completion_timeout(&cec_dev->tx_ok, t);
1085 if (ret <= 0) {
1086 /* timeout or interrupt */
1087 if (ret == 0) {
1088 CEC_ERR("tx timeout\n");
1089 cec_hw_reset();
1090 }
1091 ret = CEC_FAIL_OTHER;
1092 } else {
1093 ret = cec_tx_result;
1094 }
1095 if (ret != CEC_FAIL_NONE && ret != CEC_FAIL_NACK) {
1096 if (retry > 0) {
1097 retry--;
1098 msleep(100 + (prandom_u32() & 0x07) * 10);
1099 goto try_again;
1100 }
1101 }
1102 mutex_unlock(&cec_dev->cec_mutex);
1103
1104 if (!ee_cec) {
1105 last_cec_msg->last_result = ret;
1106 if (ret == CEC_FAIL_NACK) {
1107 memcpy(last_cec_msg->msg, msg, len);
1108 last_cec_msg->len = len;
1109 last_cec_msg->last_jiffies = jiffies;
1110 }
1111 }
1112 return ret;
1113}
1114
1115/* -------------------------------------------------------------------------- */
1116/* AO CEC0 config */
1117/* -------------------------------------------------------------------------- */
1118void ao_cec_init(void)
1119{
1120 unsigned long data32;
1121 unsigned int reg;
1122
1123 if (get_meson_cpu_version(MESON_CPU_VERSION_LVL_MAJOR) >=
1124 MESON_CPU_MAJOR_ID_GXBB) {
1125 reg = (0 << 31) |
1126 (0 << 30) |
1127 (1 << 28) | /* clk_div0/clk_div1 in turn */
1128 ((732-1) << 12) | /* Div_tcnt1 */
1129 ((733-1) << 0); /* Div_tcnt0 */
1130 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1131 reg = (0 << 13) |
1132 ((11-1) << 12) |
1133 ((8-1) << 0);
1134 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL1);
1135
1136 reg = readl(cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1137 reg |= (1 << 31);
1138 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1139
1140 udelay(200);
1141 reg |= (1 << 30);
1142 writel(reg, cec_dev->cec_reg + AO_RTC_ALT_CLK_CNTL0);
1143
1144 reg = readl(cec_dev->cec_reg + AO_CRT_CLK_CNTL1);
1145 reg |= (0x800 << 16); /* select cts_rtc_oscin_clk */
1146 writel(reg, cec_dev->cec_reg + AO_CRT_CLK_CNTL1);
1147
1148 reg = readl(cec_dev->cec_reg + AO_RTI_PWR_CNTL_REG0);
1149 reg &= ~(0x07 << 10);
1150 reg |= (0x04 << 10); /* XTAL generate 32k */
1151 writel(reg, cec_dev->cec_reg + AO_RTI_PWR_CNTL_REG0);
1152 }
1153
1154 data32 = 0;
1155 data32 |= 0 << 1; /* [2:1] cntl_clk: */
1156 /* 0=Disable clk (Power-off mode); */
1157 /* 1=Enable gated clock (Normal mode); */
1158 /* 2=Enable free-run clk (Debug mode). */
1159 data32 |= 1 << 0; /* [0] sw_reset: 1=Reset */
1160 writel(data32, cec_dev->cec_reg + AO_CEC_GEN_CNTL);
1161 /* Enable gated clock (Normal mode). */
1162 cec_set_reg_bits(AO_CEC_GEN_CNTL, 1, 1, 1);
1163 /* Release SW reset */
1164 cec_set_reg_bits(AO_CEC_GEN_CNTL, 0, 0, 1);
1165
1166 /* Enable all AO_CEC interrupt sources */
1167 cec_irq_enable(true);
1168}
1169
1170void cec_arbit_bit_time_set(unsigned int bit_set,
1171 unsigned int time_set, unsigned int flag)
1172{ /* 11bit:bit[10:0] */
1173 if (flag) {
1174 CEC_INFO("bit_set:0x%x;time_set:0x%x\n",
1175 bit_set, time_set);
1176 }
1177
1178 switch (bit_set) {
1179 case 3:
1180 /* 3 bit */
1181 if (flag) {
1182 CEC_INFO("read 3 bit:0x%x%x\n",
1183 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT10_8),
1184 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT7_0));
1185 }
1186 aocec_wr_reg(AO_CEC_TXTIME_4BIT_BIT7_0, time_set & 0xff);
1187 aocec_wr_reg(AO_CEC_TXTIME_4BIT_BIT10_8, (time_set >> 8) & 0x7);
1188 if (flag) {
1189 CEC_INFO("write 3 bit:0x%x%x\n",
1190 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT10_8),
1191 aocec_rd_reg(AO_CEC_TXTIME_4BIT_BIT7_0));
1192 }
1193 break;
1194 /* 5 bit */
1195 case 5:
1196 if (flag) {
1197 CEC_INFO("read 5 bit:0x%x%x\n",
1198 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT10_8),
1199 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT7_0));
1200 }
1201 aocec_wr_reg(AO_CEC_TXTIME_2BIT_BIT7_0, time_set & 0xff);
1202 aocec_wr_reg(AO_CEC_TXTIME_2BIT_BIT10_8, (time_set >> 8) & 0x7);
1203 if (flag) {
1204 CEC_INFO("write 5 bit:0x%x%x\n",
1205 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT10_8),
1206 aocec_rd_reg(AO_CEC_TXTIME_2BIT_BIT7_0));
1207 }
1208 break;
1209 /* 7 bit */
1210 case 7:
1211 if (flag) {
1212 CEC_INFO("read 7 bit:0x%x%x\n",
1213 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT10_8),
1214 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT7_0));
1215 }
1216 aocec_wr_reg(AO_CEC_TXTIME_17MS_BIT7_0, time_set & 0xff);
1217 aocec_wr_reg(AO_CEC_TXTIME_17MS_BIT10_8, (time_set >> 8) & 0x7);
1218 if (flag) {
1219 CEC_INFO("write 7 bit:0x%x%x\n",
1220 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT10_8),
1221 aocec_rd_reg(AO_CEC_TXTIME_17MS_BIT7_0));
1222 }
1223 break;
1224 default:
1225 break;
1226 }
1227}
1228
1229static unsigned int ao_cec_intr_stat(void)
1230{
1231 return readl(cec_dev->cec_reg + AO_CEC_INTR_STAT);
1232}
1233
1234unsigned int cec_intr_stat(void)
1235{
1236 return ao_cec_intr_stat();
1237}
1238
1239/*
1240 *wr_flag: 1 write; value valid
1241 * 0 read; value invalid
1242 */
1243unsigned int cec_config(unsigned int value, bool wr_flag)
1244{
1245 if (wr_flag)
1246 cec_set_reg_bits(AO_DEBUG_REG0, value, 0, 8);
1247
1248 return readl(cec_dev->cec_reg + AO_DEBUG_REG0) & 0xff;
1249}
1250
1251/*
1252 *wr_flag:1 write; value valid
1253 * 0 read; value invalid
1254 */
1255unsigned int cec_phyaddr_config(unsigned int value, bool wr_flag)
1256{
1257 if (wr_flag)
1258 cec_set_reg_bits(AO_DEBUG_REG1, value, 0, 16);
1259
1260 return readl(cec_dev->cec_reg + AO_DEBUG_REG1);
1261}
1262
1263void cec_keep_reset(void)
1264{
1265 if (ee_cec)
1266 cecrx_hw_reset();
1267 else
1268 writel(0x1, cec_dev->cec_reg + AO_CEC_GEN_CNTL);
1269}
1270/*
1271 * cec hw module init before allocate logical address
1272 */
1273static void cec_pre_init(void)
1274{
1275 unsigned int reg = readl(cec_dev->cec_reg + AO_RTI_STATUS_REG1);
1276
1277 reg &= 0xfffff;
1278 if ((reg & 0xffff) == 0xffff)
1279 wake_ok = 0;
1280 pr_info("cec: wake up flag:%x\n", reg);
1281
1282 if (ee_cec) {
1283 cecrx_hw_init();
1284 return;
1285 }
1286 ao_cec_init();
1287
1288 cec_arbit_bit_time_set(3, 0x118, 0);
1289 cec_arbit_bit_time_set(5, 0x000, 0);
1290 cec_arbit_bit_time_set(7, 0x2aa, 0);
1291}
1292
1293static int cec_late_check_rx_buffer(void)
1294{
1295 int ret;
1296 struct delayed_work *dwork = &cec_dev->cec_work;
1297
1298 ret = cec_rx_buf_check();
1299 if (!ret)
1300 return 0;
1301 /*
1302 * start another check if rx buffer is full
1303 */
1304 if ((-1) == cec_ll_rx(rx_msg, &rx_len)) {
1305 CEC_INFO("buffer got unrecorgnized msg\n");
1306 cec_rx_buf_clear();
1307 return 0;
1308 }
1309 mod_delayed_work(cec_dev->cec_thread, dwork, 0);
1310 return 1;
1311}
1312
1313void cec_key_report(int suspend)
1314{
1315 input_event(cec_dev->cec_info.remote_cec_dev, EV_KEY, KEY_POWER, 1);
1316 input_sync(cec_dev->cec_info.remote_cec_dev);
1317 input_event(cec_dev->cec_info.remote_cec_dev, EV_KEY, KEY_POWER, 0);
1318 input_sync(cec_dev->cec_info.remote_cec_dev);
1319 if (!suspend)
1320 CEC_INFO("== WAKE UP BY CEC ==\n")
1321 else
1322 CEC_INFO("== SLEEP by CEC==\n")
1323}
1324
1325void cec_give_version(unsigned int dest)
1326{
1327 unsigned char index = cec_dev->cec_info.log_addr;
1328 unsigned char msg[3];
1329
1330 if (dest != 0xf) {
1331 msg[0] = ((index & 0xf) << 4) | dest;
1332 msg[1] = CEC_OC_CEC_VERSION;
1333 msg[2] = cec_dev->cec_info.cec_version;
1334 cec_ll_tx(msg, 3);
1335 }
1336}
1337
1338void cec_report_physical_address_smp(void)
1339{
1340 unsigned char msg[5];
1341 unsigned char index = cec_dev->cec_info.log_addr;
1342 unsigned char phy_addr_ab, phy_addr_cd;
1343
1344 phy_addr_ab = (cec_dev->phy_addr >> 8) & 0xff;
1345 phy_addr_cd = (cec_dev->phy_addr >> 0) & 0xff;
1346 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1347 msg[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS;
1348 msg[2] = phy_addr_ab;
1349 msg[3] = phy_addr_cd;
1350 msg[4] = cec_dev->dev_type;
1351
1352 cec_ll_tx(msg, 5);
1353}
1354
1355void cec_device_vendor_id(void)
1356{
1357 unsigned char index = cec_dev->cec_info.log_addr;
1358 unsigned char msg[5];
1359 unsigned int vendor_id;
1360
1361 vendor_id = cec_dev->v_data.vendor_id;
1362 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1363 msg[1] = CEC_OC_DEVICE_VENDOR_ID;
1364 msg[2] = (vendor_id >> 16) & 0xff;
1365 msg[3] = (vendor_id >> 8) & 0xff;
1366 msg[4] = (vendor_id >> 0) & 0xff;
1367
1368 cec_ll_tx(msg, 5);
1369}
1370
1371void cec_give_deck_status(unsigned int dest)
1372{
1373 unsigned char index = cec_dev->cec_info.log_addr;
1374 unsigned char msg[3];
1375
1376 msg[0] = ((index & 0xf) << 4) | dest;
1377 msg[1] = CEC_OC_DECK_STATUS;
1378 msg[2] = 0x1a;
1379 cec_ll_tx(msg, 3);
1380}
1381
1382void cec_menu_status_smp(int dest, int status)
1383{
1384 unsigned char msg[3];
1385 unsigned char index = cec_dev->cec_info.log_addr;
1386
1387 msg[0] = ((index & 0xf) << 4) | dest;
1388 msg[1] = CEC_OC_MENU_STATUS;
1389 if (status == DEVICE_MENU_ACTIVE)
1390 msg[2] = DEVICE_MENU_ACTIVE;
1391 else
1392 msg[2] = DEVICE_MENU_INACTIVE;
1393 cec_ll_tx(msg, 3);
1394}
1395
1396void cec_inactive_source(int dest)
1397{
1398 unsigned char index = cec_dev->cec_info.log_addr;
1399 unsigned char msg[4];
1400 unsigned char phy_addr_ab, phy_addr_cd;
1401
1402 phy_addr_ab = (cec_dev->phy_addr >> 8) & 0xff;
1403 phy_addr_cd = (cec_dev->phy_addr >> 0) & 0xff;
1404 msg[0] = ((index & 0xf) << 4) | dest;
1405 msg[1] = CEC_OC_INACTIVE_SOURCE;
1406 msg[2] = phy_addr_ab;
1407 msg[3] = phy_addr_cd;
1408
1409 cec_ll_tx(msg, 4);
1410}
1411
1412void cec_set_osd_name(int dest)
1413{
1414 unsigned char index = cec_dev->cec_info.log_addr;
1415 unsigned char osd_len = strlen(cec_dev->cec_info.osd_name);
1416 unsigned char msg[16];
1417
1418 if (dest != 0xf) {
1419 msg[0] = ((index & 0xf) << 4) | dest;
1420 msg[1] = CEC_OC_SET_OSD_NAME;
1421 memcpy(&msg[2], cec_dev->cec_info.osd_name, osd_len);
1422
1423 cec_ll_tx(msg, 2 + osd_len);
1424 }
1425}
1426
1427void cec_active_source_smp(void)
1428{
1429 unsigned char msg[4];
1430 unsigned char index = cec_dev->cec_info.log_addr;
1431 unsigned char phy_addr_ab;
1432 unsigned char phy_addr_cd;
1433
1434 phy_addr_ab = (cec_dev->phy_addr >> 8) & 0xff;
1435 phy_addr_cd = (cec_dev->phy_addr >> 0) & 0xff;
1436 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1437 msg[1] = CEC_OC_ACTIVE_SOURCE;
1438 msg[2] = phy_addr_ab;
1439 msg[3] = phy_addr_cd;
1440 cec_ll_tx(msg, 4);
1441}
1442
1443void cec_request_active_source(void)
1444{
1445 unsigned char msg[2];
1446 unsigned char index = cec_dev->cec_info.log_addr;
1447
1448 msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
1449 msg[1] = CEC_OC_REQUEST_ACTIVE_SOURCE;
1450 cec_ll_tx(msg, 2);
1451}
1452
1453void cec_set_stream_path(unsigned char *msg)
1454{
1455 unsigned int phy_addr_active;
1456
1457 phy_addr_active = (unsigned int)(msg[2] << 8 | msg[3]);
1458 if (phy_addr_active == cec_dev->phy_addr) {
1459 cec_active_source_smp();
1460 /*
1461 * some types of TV such as panasonic need to send menu status,
1462 * otherwise it will not send remote key event to control
1463 * device's menu
1464 */
1465 cec_menu_status_smp(msg[0] >> 4, DEVICE_MENU_ACTIVE);
1466 }
1467}
1468
1469void cec_report_power_status(int dest, int status)
1470{
1471 unsigned char index = cec_dev->cec_info.log_addr;
1472 unsigned char msg[3];
1473
1474 msg[0] = ((index & 0xf) << 4) | dest;
1475 msg[1] = CEC_OC_REPORT_POWER_STATUS;
1476 msg[2] = status;
1477 cec_ll_tx(msg, 3);
1478}
1479
1480static void cec_rx_process(void)
1481{
1482 int len = rx_len;
1483 int initiator, follower;
1484 int opcode;
1485 unsigned char msg[MAX_MSG] = {};
1486 int dest_phy_addr;
1487
1488 if (len < 2 || !new_msg) /* ignore ping message */
1489 return;
1490
1491 memcpy(msg, rx_msg, len);
1492 initiator = ((msg[0] >> 4) & 0xf);
1493 follower = msg[0] & 0xf;
1494 if (follower != 0xf && follower != cec_dev->cec_info.log_addr) {
1495 CEC_ERR("wrong rx message of bad follower:%x", follower);
1496 return;
1497 }
1498 opcode = msg[1];
1499 switch (opcode) {
1500 case CEC_OC_ACTIVE_SOURCE:
1501 if (wake_ok == 0) {
1502 int phy_addr = msg[2] << 8 | msg[3];
1503
1504 if (phy_addr == 0xffff)
1505 break;
1506 wake_ok = 1;
1507 phy_addr |= (initiator << 16);
1508 writel(phy_addr, cec_dev->cec_reg + AO_RTI_STATUS_REG1);
1509 CEC_INFO("found wake up source:%x", phy_addr);
1510 }
1511 break;
1512
1513 case CEC_OC_ROUTING_CHANGE:
1514 dest_phy_addr = msg[4] << 8 | msg[5];
1515 if ((dest_phy_addr == cec_dev->phy_addr) &&
1516 (cec_dev->cec_suspend == CEC_EARLY_SUSPEND)) {
1517 CEC_INFO("wake up by ROUTING_CHANGE\n");
1518 cec_key_report(0);
1519 }
1520 break;
1521
1522 case CEC_OC_GET_CEC_VERSION:
1523 cec_give_version(initiator);
1524 break;
1525
1526 case CEC_OC_GIVE_DECK_STATUS:
1527 cec_give_deck_status(initiator);
1528 break;
1529
1530 case CEC_OC_GIVE_PHYSICAL_ADDRESS:
1531 cec_report_physical_address_smp();
1532 break;
1533
1534 case CEC_OC_GIVE_DEVICE_VENDOR_ID:
1535 cec_device_vendor_id();
1536 break;
1537
1538 case CEC_OC_GIVE_OSD_NAME:
1539 cec_set_osd_name(initiator);
1540 break;
1541
1542 case CEC_OC_STANDBY:
1543 cec_inactive_source(initiator);
1544 cec_menu_status_smp(initiator, DEVICE_MENU_INACTIVE);
1545 break;
1546
1547 case CEC_OC_SET_STREAM_PATH:
1548 cec_set_stream_path(msg);
1549 /* wake up if in early suspend */
1550 if (cec_dev->cec_suspend == CEC_EARLY_SUSPEND)
1551 cec_key_report(0);
1552 break;
1553
1554 case CEC_OC_REQUEST_ACTIVE_SOURCE:
1555 if (cec_dev->cec_suspend == CEC_POWER_ON)
1556 cec_active_source_smp();
1557 break;
1558
1559 case CEC_OC_GIVE_DEVICE_POWER_STATUS:
1560 if (cec_dev->cec_suspend == CEC_DEEP_SUSPEND)
1561 cec_report_power_status(initiator, POWER_STANDBY);
1562 else if (cec_dev->cec_suspend == CEC_EARLY_SUSPEND)
1563 cec_report_power_status(initiator, TRANS_ON_TO_STANDBY);
1564 else if (cec_dev->cec_suspend == CEC_POWER_RESUME)
1565 cec_report_power_status(initiator, TRANS_STANDBY_TO_ON);
1566 else
1567 cec_report_power_status(initiator, POWER_ON);
1568 break;
1569
1570 case CEC_OC_USER_CONTROL_PRESSED:
1571 /* wake up by key function */
1572 if (cec_dev->cec_suspend == CEC_EARLY_SUSPEND) {
1573 if (msg[2] == 0x40 || msg[2] == 0x6d)
1574 cec_key_report(0);
1575 }
1576 break;
1577
1578 case CEC_OC_MENU_REQUEST:
1579 if (cec_dev->cec_suspend != CEC_POWER_ON)
1580 cec_menu_status_smp(initiator, DEVICE_MENU_INACTIVE);
1581 else
1582 cec_menu_status_smp(initiator, DEVICE_MENU_ACTIVE);
1583 break;
1584
1585 default:
1586 CEC_ERR("unsupported command:%x\n", opcode);
1587 break;
1588 }
1589 new_msg = 0;
1590}
1591
1592static bool cec_service_suspended(void)
1593{
1594 /* service is not enabled */
1595 if (!(cec_dev->hal_flag & (1 << HDMI_OPTION_SERVICE_FLAG)))
1596 return false;
1597 if (!(cec_dev->hal_flag & (1 << HDMI_OPTION_SYSTEM_CEC_CONTROL)))
1598 return true;
1599 return false;
1600}
1601
1602static void cec_task(struct work_struct *work)
1603{
1604 struct delayed_work *dwork;
1605
1606 dwork = &cec_dev->cec_work;
1607 if (cec_dev && (!wake_ok || cec_service_suspended()))
1608 cec_rx_process();
1609
1610 if (!cec_late_check_rx_buffer())
1611 queue_delayed_work(cec_dev->cec_thread, dwork, CEC_FRAME_DELAY);
1612}
1613
1614static irqreturn_t cec_isr_handler(int irq, void *dev_instance)
1615{
1616 unsigned int intr_stat = 0;
1617 struct delayed_work *dwork;
1618
1619 dwork = &cec_dev->cec_work;
1620 intr_stat = cec_intr_stat();
1621 if (intr_stat & (1<<1)) { /* aocec tx intr */
1622 tx_irq_handle();
1623 return IRQ_HANDLED;
1624 }
1625 if ((-1) == cec_ll_rx(rx_msg, &rx_len))
1626 return IRQ_HANDLED;
1627
1628 complete(&cec_dev->rx_ok);
1629 /* check rx buffer is full */
1630 new_msg = 1;
1631 mod_delayed_work(cec_dev->cec_thread, dwork, 0);
1632 return IRQ_HANDLED;
1633}
1634
1635static void check_wake_up(void)
1636{
1637 if (wake_ok == 0)
1638 cec_request_active_source();
1639}
1640
1641/******************** cec class interface *************************/
1642static ssize_t device_type_show(struct class *cla,
1643 struct class_attribute *attr, char *buf)
1644{
1645 return sprintf(buf, "%ld\n", cec_dev->dev_type);
1646}
1647
1648static ssize_t device_type_store(struct class *cla,
1649 struct class_attribute *attr, const char *buf, size_t count)
1650{
1651 unsigned int type;
1652
1653 if (kstrtouint(buf, 10, &type) != 1)
1654 return -EINVAL;
1655
1656 cec_dev->dev_type = type;
1657 CEC_ERR("set dev_type to %d\n", type);
1658 return count;
1659}
1660
1661static ssize_t menu_language_show(struct class *cla,
1662 struct class_attribute *attr, char *buf)
1663{
1664 char a, b, c;
1665
1666 a = ((cec_dev->cec_info.menu_lang >> 16) & 0xff);
1667 b = ((cec_dev->cec_info.menu_lang >> 8) & 0xff);
1668 c = ((cec_dev->cec_info.menu_lang >> 0) & 0xff);
1669 return sprintf(buf, "%c%c%c\n", a, b, c);
1670}
1671
1672static ssize_t menu_language_store(struct class *cla,
1673 struct class_attribute *attr, const char *buf, size_t count)
1674{
1675 char a, b, c;
1676
1677 if (sscanf(buf, "%c%c%c", &a, &b, &c) != 3)
1678 return -EINVAL;
1679
1680 cec_dev->cec_info.menu_lang = (a << 16) | (b << 8) | c;
1681 CEC_ERR("set menu_language to %s\n", buf);
1682 return count;
1683}
1684
1685static ssize_t vendor_id_show(struct class *cla,
1686 struct class_attribute *attr, char *buf)
1687{
1688 return sprintf(buf, "%x\n", cec_dev->cec_info.vendor_id);
1689}
1690
1691static ssize_t vendor_id_store(struct class *cla, struct class_attribute *attr,
1692 const char *buf, size_t count)
1693{
1694 unsigned int id;
1695
1696 if (kstrtouint(buf, 16, &id) != 1)
1697 return -EINVAL;
1698 cec_dev->cec_info.vendor_id = id;
1699 return count;
1700}
1701
1702static ssize_t port_num_show(struct class *cla,
1703 struct class_attribute *attr, char *buf)
1704{
1705 return sprintf(buf, "%d\n", cec_dev->port_num);
1706}
1707
1708static const char * const cec_reg_name1[] = {
1709 "CEC_TX_MSG_LENGTH",
1710 "CEC_TX_MSG_CMD",
1711 "CEC_TX_WRITE_BUF",
1712 "CEC_TX_CLEAR_BUF",
1713 "CEC_RX_MSG_CMD",
1714 "CEC_RX_CLEAR_BUF",
1715 "CEC_LOGICAL_ADDR0",
1716 "CEC_LOGICAL_ADDR1",
1717 "CEC_LOGICAL_ADDR2",
1718 "CEC_LOGICAL_ADDR3",
1719 "CEC_LOGICAL_ADDR4",
1720 "CEC_CLOCK_DIV_H",
1721 "CEC_CLOCK_DIV_L"
1722};
1723
1724static const char * const cec_reg_name2[] = {
1725 "CEC_RX_MSG_LENGTH",
1726 "CEC_RX_MSG_STATUS",
1727 "CEC_RX_NUM_MSG",
1728 "CEC_TX_MSG_STATUS",
1729 "CEC_TX_NUM_MSG"
1730};
1731
1732static ssize_t dump_reg_show(struct class *cla,
1733 struct class_attribute *attr, char *b)
1734{
1735 int i, s = 0;
1736
1737 if (ee_cec)
1738 return dump_cecrx_reg(b);
1739
1740 s += sprintf(b + s, "TX buffer:\n");
1741 for (i = 0; i <= CEC_TX_MSG_F_OP14; i++)
1742 s += sprintf(b + s, "%2d:%2x\n", i, aocec_rd_reg(i));
1743
1744 for (i = 0; i < ARRAY_SIZE(cec_reg_name1); i++) {
1745 s += sprintf(b + s, "%s:%2x\n",
1746 cec_reg_name1[i], aocec_rd_reg(i + 0x10));
1747 }
1748
1749 s += sprintf(b + s, "RX buffer:\n");
1750 for (i = 0; i <= CEC_TX_MSG_F_OP14; i++)
1751 s += sprintf(b + s, "%2d:%2x\n", i, aocec_rd_reg(i + 0x80));
1752
1753 for (i = 0; i < ARRAY_SIZE(cec_reg_name2); i++) {
1754 s += sprintf(b + s, "%s:%2x\n",
1755 cec_reg_name2[i], aocec_rd_reg(i + 0x90));
1756 }
1757 return s;
1758}
1759
1760static ssize_t arc_port_show(struct class *cla,
1761 struct class_attribute *attr, char *buf)
1762{
1763 return sprintf(buf, "%x\n", cec_dev->arc_port);
1764}
1765
1766static ssize_t osd_name_show(struct class *cla,
1767 struct class_attribute *attr, char *buf)
1768{
1769 return sprintf(buf, "%s\n", cec_dev->cec_info.osd_name);
1770}
1771
1772static ssize_t port_seq_store(struct class *cla,
1773 struct class_attribute *attr,
1774 const char *buf, size_t count)
1775{
1776 unsigned int seq;
1777
1778 if (kstrtouint(buf, 16, &seq) != 1)
1779 return -EINVAL;
1780
1781 CEC_ERR("port_seq:%x\n", seq);
1782 cec_dev->port_seq = seq;
1783 return count;
1784}
1785
1786static ssize_t port_seq_show(struct class *cla,
1787 struct class_attribute *attr, char *buf)
1788{
1789 return sprintf(buf, "%x\n", cec_dev->port_seq);
1790}
1791
1792static ssize_t port_status_show(struct class *cla,
1793 struct class_attribute *attr, char *buf)
1794{
1795 unsigned int tmp;
1796 unsigned int tx_hpd;
1797
1798 tx_hpd = cec_dev->tx_dev->hpd_state;
1799 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) {
1800 tmp = tx_hpd;
1801 return sprintf(buf, "%x\n", tmp);
1802 }
1803
1804 tmp = hdmirx_rd_top(TOP_HPD_PWR5V);
1805 CEC_INFO("TOP_HPD_PWR5V:%x\n", tmp);
1806 tmp >>= 20;
1807 tmp &= 0xf;
1808 tmp |= (tx_hpd << 16);
1809 return sprintf(buf, "%x\n", tmp);
1810}
1811
1812static ssize_t pin_status_show(struct class *cla,
1813 struct class_attribute *attr, char *buf)
1814{
1815 unsigned int tx_hpd;
1816 char p;
1817
1818 tx_hpd = cec_dev->tx_dev->hpd_state;
1819 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) {
1820 if (!tx_hpd) {
1821 pin_status = 0;
1822 return sprintf(buf, "%s\n", "disconnected");
1823 }
1824 if (pin_status == 0) {
1825 p = (cec_dev->cec_info.log_addr << 4) | CEC_TV_ADDR;
1826 if (cec_ll_tx(&p, 1) == CEC_FAIL_NONE)
1827 return sprintf(buf, "%s\n", "ok");
1828 else
1829 return sprintf(buf, "%s\n", "fail");
1830 } else
1831 return sprintf(buf, "%s\n", "ok");
1832 } else {
1833 return sprintf(buf, "%s\n", pin_status ? "ok" : "fail");
1834 }
1835}
1836
1837static ssize_t physical_addr_show(struct class *cla,
1838 struct class_attribute *attr, char *buf)
1839{
1840 unsigned int tmp = cec_dev->phy_addr;
1841
1842 return sprintf(buf, "%04x\n", tmp);
1843}
1844
1845static ssize_t physical_addr_store(struct class *cla,
1846 struct class_attribute *attr,
1847 const char *buf, size_t count)
1848{
1849 int addr;
1850
1851 if (kstrtouint(buf, 16, &addr) != 1)
1852 return -EINVAL;
1853
1854 if (addr > 0xffff || addr < 0) {
1855 CEC_ERR("invalid input:%s\n", buf);
1856 phy_addr_test = 0;
1857 return -EINVAL;
1858 }
1859 cec_dev->phy_addr = addr;
1860 phy_addr_test = 1;
1861 return count;
1862}
1863
1864static ssize_t dbg_en_show(struct class *cla,
1865 struct class_attribute *attr, char *buf)
1866{
1867 return sprintf(buf, "%x\n", cec_msg_dbg_en);
1868}
1869
1870static ssize_t dbg_en_store(struct class *cla, struct class_attribute *attr,
1871 const char *buf, size_t count)
1872{
1873 int en;
1874
1875 if (kstrtouint(buf, 16, &en) != 1)
1876 return -EINVAL;
1877
1878 cec_msg_dbg_en = en ? 1 : 0;
1879 return count;
1880}
1881
1882static ssize_t cmd_store(struct class *cla, struct class_attribute *attr,
1883 const char *bu, size_t count)
1884{
1885 char buf[6] = {};
1886 int cnt;
1887
1888 cnt = sscanf(bu, "%x %x %x %x %x %x",
1889 (int *)&buf[0], (int *)&buf[1], (int *)&buf[2],
1890 (int *)&buf[3], (int *)&buf[4], (int *)&buf[5]);
1891 if (cnt < 0)
1892 return -EINVAL;
1893 cec_ll_tx(buf, cnt);
1894 return count;
1895}
1896
1897static ssize_t wake_up_show(struct class *cla,
1898 struct class_attribute *attr, char *buf)
1899{
1900 unsigned int reg = readl(cec_dev->cec_reg + AO_RTI_STATUS_REG1);
1901
1902 return sprintf(buf, "%x\n", reg & 0xfffff);
1903}
1904
1905static ssize_t fun_cfg_store(struct class *cla, struct class_attribute *attr,
1906 const char *bu, size_t count)
1907{
1908 int cnt, val;
1909
1910 cnt = kstrtouint(bu, 16, &val);
1911 if (cnt < 0 || val > 0xff)
1912 return -EINVAL;
1913 cec_config(val, 1);
1914 if (val == 0)
1915 cec_keep_reset();
1916 else
1917 cec_pre_init();
1918 return count;
1919}
1920
1921static ssize_t fun_cfg_show(struct class *cla,
1922 struct class_attribute *attr, char *buf)
1923{
1924 unsigned int reg = cec_config(0, 0);
1925
1926 return sprintf(buf, "0x%x\n", reg & 0xff);
1927}
1928
1929static ssize_t cec_version_show(struct class *cla,
1930 struct class_attribute *attr, char *buf)
1931{
1932 return sprintf(buf, "%d\n", cec_dev->cec_info.cec_version);
1933}
1934
1935static ssize_t log_addr_store(struct class *cla, struct class_attribute *attr,
1936 const char *bu, size_t count)
1937{
1938 int cnt, val;
1939
1940 cnt = kstrtoint(bu, 16, &val);
1941 if (cnt < 0 || val > 0xf)
1942 return -EINVAL;
1943 cec_logicaddr_set(val);
1944 /* add by hal, to init some data structure */
1945 cec_dev->cec_info.log_addr = val;
1946 cec_dev->cec_info.power_status = POWER_ON;
1947
1948 return count;
1949}
1950
1951static ssize_t log_addr_show(struct class *cla,
1952 struct class_attribute *attr, char *buf)
1953{
1954 return sprintf(buf, "0x%x\n", cec_dev->cec_info.log_addr);
1955}
1956
1957static struct class_attribute aocec_class_attr[] = {
1958 __ATTR_WO(cmd),
1959 __ATTR_RO(port_num),
1960 __ATTR_RO(osd_name),
1961 __ATTR_RO(dump_reg),
1962 __ATTR_RO(port_status),
1963 __ATTR_RO(pin_status),
1964 __ATTR_RO(cec_version),
1965 __ATTR_RO(arc_port),
1966 __ATTR_RO(wake_up),
1967 __ATTR(port_seq, 0664, port_seq_show, port_seq_store),
1968 __ATTR(physical_addr, 0664, physical_addr_show, physical_addr_store),
1969 __ATTR(vendor_id, 0664, vendor_id_show, vendor_id_store),
1970 __ATTR(menu_language, 0664, menu_language_show, menu_language_store),
1971 __ATTR(device_type, 0664, device_type_show, device_type_store),
1972 __ATTR(dbg_en, 0664, dbg_en_show, dbg_en_store),
1973 __ATTR(log_addr, 0664, log_addr_show, log_addr_store),
1974 __ATTR(fun_cfg, 0664, fun_cfg_show, fun_cfg_store),
1975 __ATTR_NULL
1976};
1977
1978/******************** cec hal interface ***************************/
1979static int hdmitx_cec_open(struct inode *inode, struct file *file)
1980{
1981 if (atomic_add_return(1, &cec_dev->cec_info.open_count)) {
1982 cec_dev->cec_info.hal_ctl = 1;
1983 /* set default logical addr flag for uboot */
1984 cec_set_reg_bits(AO_DEBUG_REG1, 0xf, 16, 4);
1985 }
1986 return 0;
1987}
1988
1989static int hdmitx_cec_release(struct inode *inode, struct file *file)
1990{
1991 if (!atomic_sub_return(1, &cec_dev->cec_info.open_count))
1992 cec_dev->cec_info.hal_ctl = 0;
1993 return 0;
1994}
1995
1996static ssize_t hdmitx_cec_read(struct file *f, char __user *buf,
1997 size_t size, loff_t *p)
1998{
1999 int ret;
2000
2001 if ((cec_dev->hal_flag & (1 << HDMI_OPTION_SYSTEM_CEC_CONTROL)))
2002 rx_len = 0;
2003 ret = wait_for_completion_timeout(&cec_dev->rx_ok, CEC_FRAME_DELAY);
2004 if (ret <= 0)
2005 return ret;
2006 if (rx_len == 0)
2007 return 0;
2008
2009 if (copy_to_user(buf, rx_msg, rx_len))
2010 return -EINVAL;
2011 return rx_len;
2012}
2013
2014static ssize_t hdmitx_cec_write(struct file *f, const char __user *buf,
2015 size_t size, loff_t *p)
2016{
2017 unsigned char tempbuf[16] = {};
2018 int ret;
2019
2020 if (size > 16)
2021 size = 16;
2022 if (size <= 0)
2023 return -EINVAL;
2024
2025 if (copy_from_user(tempbuf, buf, size))
2026 return -EINVAL;
2027
2028 ret = cec_ll_tx(tempbuf, size);
2029 return ret;
2030}
2031
2032static void init_cec_port_info(struct hdmi_port_info *port,
2033 struct ao_cec_dev *cec_dev)
2034{
2035 unsigned int a, b, c, d, e = 0;
2036 unsigned int phy_head = 0xf000, phy_app = 0x1000, phy_addr;
2037 struct hdmitx_dev *tx_dev;
2038
2039 /* physical address for TV or repeator */
2040 tx_dev = cec_dev->tx_dev;
2041 if (tx_dev == NULL || cec_dev->dev_type == DEV_TYPE_TV) {
2042 phy_addr = 0;
2043 } else if (tx_dev->hdmi_info.vsdb_phy_addr.valid == 1) {
2044 a = tx_dev->hdmi_info.vsdb_phy_addr.a;
2045 b = tx_dev->hdmi_info.vsdb_phy_addr.b;
2046 c = tx_dev->hdmi_info.vsdb_phy_addr.c;
2047 d = tx_dev->hdmi_info.vsdb_phy_addr.d;
2048 phy_addr = ((a << 12) | (b << 8) | (c << 4) | (d));
2049 } else
2050 phy_addr = 0;
2051
2052 /* found physical address append for repeator */
2053 for (a = 0; a < 4; a++) {
2054 if (phy_addr & phy_head) {
2055 phy_head >>= 4;
2056 phy_app >>= 4;
2057 } else
2058 break;
2059 }
2060 if (cec_dev->dev_type == DEV_TYPE_TUNER)
2061 b = cec_dev->port_num - 1;
2062 else
2063 b = cec_dev->port_num;
2064
2065 /* init for port info */
2066 for (a = 0; a < sizeof(cec_dev->port_seq) * 2; a++) {
2067 /* set port physical address according port sequence */
2068 if (cec_dev->port_seq) {
2069 c = (cec_dev->port_seq >> (4 * a)) & 0xf;
2070 if (c == 0xf) { /* not used */
2071 CEC_INFO("port %d is not used\n", a);
2072 continue;
2073 } else if (!c)
2074 break;
2075 port[e].physical_address = (c) * phy_app + phy_addr;
2076 } else {
2077 /* asending order if port_seq is not set */
2078 port[e].physical_address = (e + 1) * phy_app + phy_addr;
2079 }
2080 port[e].type = HDMI_INPUT;
2081 port[e].port_id = a + 1;
2082 port[e].cec_supported = 1;
2083 /* set ARC feature according mask */
2084 if (cec_dev->arc_port & (1 << a))
2085 port[e].arc_supported = 1;
2086 else
2087 port[e].arc_supported = 0;
2088 e++;
2089 if (e >= b)
2090 break;
2091 }
2092
2093 if (cec_dev->dev_type == DEV_TYPE_TUNER) {
2094 /* last port is for tx in mixed tx/rx */
2095 port[e].type = HDMI_OUTPUT;
2096 port[e].port_id = 0; /* 0 for tx port id */
2097 port[e].cec_supported = 1;
2098 port[e].arc_supported = 0;
2099 port[e].physical_address = phy_addr;
2100 }
2101}
2102
2103static long hdmitx_cec_ioctl(struct file *f,
2104 unsigned int cmd, unsigned long arg)
2105{
2106 void __user *argp = (void __user *)arg;
2107 unsigned long tmp;
2108 struct hdmi_port_info *port;
2109 int a, b, c, d;
2110 struct hdmitx_dev *tx_dev;
2111 int tx_hpd;
2112
2113 mutex_lock(&cec_dev->cec_ioctl_mutex);
2114 switch (cmd) {
2115 case CEC_IOC_GET_PHYSICAL_ADDR:
2116 check_physical_addr_valid(20);
2117 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK && !phy_addr_test) {
2118 /* physical address for mbox */
2119 if (cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.valid
2120 == 0) {
2121 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2122 return -EINVAL;
2123 }
2124 a = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.a;
2125 b = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.b;
2126 c = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.c;
2127 d = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.d;
2128 tmp = ((a << 12) | (b << 8) | (c << 4) | (d << 0));
2129 } else {
2130 /* physical address for TV or repeator */
2131 tx_dev = cec_dev->tx_dev;
2132 if (!tx_dev || cec_dev->dev_type == DEV_TYPE_TV) {
2133 tmp = 0;
2134 } else if (tx_dev->hdmi_info.vsdb_phy_addr.valid == 1) {
2135 a = tx_dev->hdmi_info.vsdb_phy_addr.a;
2136 b = tx_dev->hdmi_info.vsdb_phy_addr.b;
2137 c = tx_dev->hdmi_info.vsdb_phy_addr.c;
2138 d = tx_dev->hdmi_info.vsdb_phy_addr.d;
2139 tmp = ((a << 12) | (b << 8) | (c << 4) | (d));
2140 } else
2141 tmp = 0;
2142 }
2143 if (!phy_addr_test) {
2144 cec_dev->phy_addr = tmp;
2145 cec_phyaddr_config(tmp, 1);
2146 } else
2147 tmp = cec_dev->phy_addr;
2148
2149 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2150 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2151 return -EINVAL;
2152 }
2153 break;
2154
2155 case CEC_IOC_GET_VERSION:
2156 tmp = cec_dev->cec_info.cec_version;
2157 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2158 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2159 return -EINVAL;
2160 }
2161 break;
2162
2163 case CEC_IOC_GET_VENDOR_ID:
2164 tmp = cec_dev->v_data.vendor_id;
2165 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2166 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2167 return -EINVAL;
2168 }
2169 break;
2170
2171 case CEC_IOC_GET_PORT_NUM:
2172 tmp = cec_dev->port_num;
2173 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2174 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2175 return -EINVAL;
2176 }
2177 break;
2178
2179 case CEC_IOC_GET_PORT_INFO:
2180 port = kcalloc(cec_dev->port_num, sizeof(*port), GFP_KERNEL);
2181 if (!port) {
2182 CEC_ERR("no memory\n");
2183 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2184 return -EINVAL;
2185 }
2186 check_physical_addr_valid(20);
2187 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) {
2188 /* for tx only 1 port */
2189 a = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.a;
2190 b = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.b;
2191 c = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.c;
2192 d = cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.d;
2193 tmp = ((a << 12) | (b << 8) | (c << 4) | (d << 0));
2194 if (cec_dev->tx_dev->hdmi_info.vsdb_phy_addr.valid == 0)
2195 tmp = 0xffff;
2196 port->type = HDMI_OUTPUT;
2197 port->port_id = 0;
2198 port->cec_supported = 1;
2199 /* not support arc for tx */
2200 port->arc_supported = 0;
2201 port->physical_address = tmp & 0xffff;
2202 if (copy_to_user(argp, port, sizeof(*port))) {
2203 kfree(port);
2204 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2205 return -EINVAL;
2206 }
2207 } else {
2208 b = cec_dev->port_num;
2209 init_cec_port_info(port, cec_dev);
2210 if (copy_to_user(argp, port, sizeof(*port) * b)) {
2211 kfree(port);
2212 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2213 return -EINVAL;
2214 }
2215 }
2216 kfree(port);
2217 break;
2218
2219 case CEC_IOC_SET_OPTION_WAKEUP:
2220 tmp = cec_config(0, 0);
2221 tmp &= ~(1 << AUTO_POWER_ON_MASK);
2222 tmp |= (arg << AUTO_POWER_ON_MASK);
2223 cec_config(tmp, 1);
2224 break;
2225
2226 case CEC_IOC_SET_AUTO_DEVICE_OFF:
2227 tmp = cec_config(0, 0);
2228 tmp &= ~(1 << ONE_TOUCH_STANDBY_MASK);
2229 tmp |= (arg << ONE_TOUCH_STANDBY_MASK);
2230 cec_config(tmp, 1);
2231 break;
2232
2233 case CEC_IOC_SET_OPTION_ENALBE_CEC:
2234 tmp = (1 << HDMI_OPTION_ENABLE_CEC);
2235 if (arg) {
2236 cec_dev->hal_flag |= tmp;
2237 cec_config(0x2f, 1);
2238 cec_pre_init();
2239 } else {
2240 cec_dev->hal_flag &= ~(tmp);
2241 CEC_INFO("disable CEC\n");
2242 cec_config(0x0, 1);
2243 cec_keep_reset();
2244 }
2245 break;
2246
2247 case CEC_IOC_SET_OPTION_SYS_CTRL:
2248 tmp = (1 << HDMI_OPTION_SYSTEM_CEC_CONTROL);
2249 if (arg) {
2250 cec_dev->hal_flag |= tmp;
2251 cec_config(0x2f, 1);
2252 } else
2253 cec_dev->hal_flag &= ~(tmp);
2254 cec_dev->hal_flag |= (1 << HDMI_OPTION_SERVICE_FLAG);
2255 break;
2256
2257 case CEC_IOC_SET_OPTION_SET_LANG:
2258 cec_dev->cec_info.menu_lang = arg;
2259 break;
2260
2261 case CEC_IOC_GET_CONNECT_STATUS:
2262 tx_hpd = cec_dev->tx_dev->hpd_state;
2263 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK)
2264 tmp = tx_hpd;
2265 else {
2266 if (copy_from_user(&a, argp, _IOC_SIZE(cmd))) {
2267 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2268 return -EINVAL;
2269 }
2270 if (!a && cec_dev->dev_type == DEV_TYPE_TUNER)
2271 tmp = tx_hpd;
2272 else { /* mixed for rx */
2273 tmp = (hdmirx_rd_top(TOP_HPD_PWR5V) >> 20);
2274 if (tmp & (1 << (a - 1)))
2275 tmp = 1;
2276 else
2277 tmp = 0;
2278 }
2279 }
2280 if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) {
2281 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2282 return -EINVAL;
2283 }
2284 break;
2285
2286 case CEC_IOC_ADD_LOGICAL_ADDR:
2287 tmp = arg & 0xf;
2288 cec_logicaddr_set(tmp);
2289 /* add by hal, to init some data structure */
2290 cec_dev->cec_info.log_addr = tmp;
2291 cec_dev->cec_info.power_status = POWER_ON;
2292
2293 cec_dev->cec_info.vendor_id = cec_dev->v_data.vendor_id;
2294 strcpy(cec_dev->cec_info.osd_name,
2295 cec_dev->v_data.cec_osd_string);
2296
2297 if (cec_dev->dev_type == DEV_TYPE_PLAYBACK)
2298 cec_dev->cec_info.menu_status = DEVICE_MENU_ACTIVE;
2299 else
2300 check_wake_up();
2301 break;
2302
2303 case CEC_IOC_CLR_LOGICAL_ADDR:
2304 cec_clear_logical_addr();
2305 break;
2306
2307 case CEC_IOC_SET_DEV_TYPE:
2308 if (arg > DEV_TYPE_VIDEO_PROCESSOR) {
2309 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2310 return -EINVAL;
2311 }
2312 cec_dev->dev_type = arg;
2313 break;
2314
2315 case CEC_IOC_SET_ARC_ENABLE:
2316 /* select arc according arg */
2317 if (arg)
2318 hdmirx_wr_top(TOP_ARCTX_CNTL, 0x01);
2319 else
2320 hdmirx_wr_top(TOP_ARCTX_CNTL, 0x00);
2321 CEC_INFO("set arc en:%ld, reg:%lx\n",
2322 arg, hdmirx_rd_top(TOP_ARCTX_CNTL));
2323 break;
2324
2325 default:
2326 break;
2327 }
2328 mutex_unlock(&cec_dev->cec_ioctl_mutex);
2329 return 0;
2330}
2331
2332#ifdef CONFIG_COMPAT
2333static long hdmitx_cec_compat_ioctl(struct file *f,
2334 unsigned int cmd, unsigned long arg)
2335{
2336 arg = (unsigned long)compat_ptr(arg);
2337 return hdmitx_cec_ioctl(f, cmd, arg);
2338}
2339#endif
2340
2341/* for improve rw permission */
2342static char *aml_cec_class_devnode(struct device *dev, umode_t *mode)
2343{
2344 if (mode) {
2345 *mode = 0666;
2346 CEC_INFO("mode is %x\n", *mode);
2347 } else
2348 CEC_INFO("mode is null\n");
2349 return NULL;
2350}
2351
2352static struct class aocec_class = {
2353 .name = CEC_DEV_NAME,
2354 .class_attrs = aocec_class_attr,
2355 .devnode = aml_cec_class_devnode,
2356};
2357
2358
2359static const struct file_operations hdmitx_cec_fops = {
2360 .owner = THIS_MODULE,
2361 .open = hdmitx_cec_open,
2362 .read = hdmitx_cec_read,
2363 .write = hdmitx_cec_write,
2364 .release = hdmitx_cec_release,
2365 .unlocked_ioctl = hdmitx_cec_ioctl,
2366#ifdef CONFIG_COMPAT
2367 .compat_ioctl = hdmitx_cec_compat_ioctl,
2368#endif
2369};
2370
2371/************************ cec high level code *****************************/
2372#ifdef CONFIG_HAS_EARLYSUSPEND
2373static void aocec_early_suspend(struct early_suspend *h)
2374{
2375 cec_dev->cec_suspend = CEC_EARLY_SUSPEND;
2376 CEC_INFO("%s, suspend:%d\n", __func__, cec_dev->cec_suspend);
2377}
2378
2379static void aocec_late_resume(struct early_suspend *h)
2380{
2381 cec_dev->cec_suspend = CEC_POWER_ON;
2382 CEC_INFO("%s, suspend:%d\n", __func__, cec_dev->cec_suspend);
2383
2384}
2385#endif
2386
2387#ifdef CONFIG_OF
2388static const struct cec_platform_data_s cec_gxl_data = {
2389 .line_bit = 8,
2390 .ee_to_ao = 0,
2391};
2392
2393static const struct cec_platform_data_s cec_txlx_data = {
2394 .line_bit = 7,
2395 .ee_to_ao = 1,
2396};
2397
2398static const struct of_device_id aml_cec_dt_match[] = {
2399 {
2400 .compatible = "amlogic, amlogic-aocec",
2401 .data = &cec_gxl_data,
2402 },
2403 {
2404 .compatible = "amlogic, aocec-txlx",
2405 .data = &cec_txlx_data,
2406 },
2407};
2408#endif
2409
2410static int aml_cec_probe(struct platform_device *pdev)
2411{
2412 struct device *cdev;
2413 int ret = 0;
2414 const struct of_device_id *of_id;
2415#ifdef CONFIG_OF
2416 struct device_node *node = pdev->dev.of_node;
2417 int irq_idx = 0, r;
2418 const char *irq_name = NULL;
2419 /*struct pinctrl *p;*/
2420 struct vendor_info_data *vend;
2421 struct resource *res;
2422 resource_size_t *base;
2423#endif
2424
2425 cec_dev = devm_kzalloc(&pdev->dev, sizeof(struct ao_cec_dev),
2426 GFP_KERNEL);
2427 if (!cec_dev) {
2428 CEC_ERR("device malloc err!\n");
2429 ret = -ENOMEM;
2430 goto tag_cec_devm_err;
2431 }
2432 CEC_ERR("cec driver date:%s\n", CEC_DRIVER_VERSION);
2433 cec_dev->dev_type = DEV_TYPE_PLAYBACK;
2434 cec_dev->dbg_dev = &pdev->dev;
2435 cec_dev->tx_dev = get_hdmitx_device();
2436 cec_dev->cpu_type = get_cpu_type();
2437 phy_addr_test = 0;
2438
2439 /* cdev registe */
2440 r = class_register(&aocec_class);
2441 if (r) {
2442 CEC_ERR("regist class failed\n");
2443 ret = -EINVAL;
2444 goto tag_cec_class_reg;
2445 }
2446 pdev->dev.class = &aocec_class;
2447 r = register_chrdev(0, CEC_DEV_NAME,
2448 &hdmitx_cec_fops);
2449 if (r < 0) {
2450 CEC_ERR("alloc chrdev failed\n");
2451 ret = -EINVAL;
2452 goto tag_cec_chr_reg_err;
2453 }
2454 cec_dev->cec_info.dev_no = r;
2455 CEC_INFO("alloc chrdev %x\n", cec_dev->cec_info.dev_no);
2456 cdev = device_create(&aocec_class, &pdev->dev,
2457 MKDEV(cec_dev->cec_info.dev_no, 0),
2458 NULL, CEC_DEV_NAME);
2459 if (IS_ERR(cdev)) {
2460 CEC_ERR("create chrdev failed, dev:%p\n", cdev);
2461 ret = -EINVAL;
2462 goto tag_cec_device_create_err;
2463 }
2464
2465 /*get compatible matched device, to get chip related data*/
2466 of_id = of_match_device(aml_cec_dt_match, &pdev->dev);
2467 if (!of_id)
2468 CEC_ERR("unable to get matched device\n");
2469 cec_dev->plat_data = (struct cec_platform_data_s *)of_id->data;
2470
2471 cec_dev->cec_info.open_count.counter = 0;
2472 init_completion(&cec_dev->rx_ok);
2473 init_completion(&cec_dev->tx_ok);
2474 mutex_init(&cec_dev->cec_mutex);
2475 mutex_init(&cec_dev->cec_ioctl_mutex);
2476 spin_lock_init(&cec_dev->cec_reg_lock);
2477 cec_dev->cec_thread = create_workqueue("cec_work");
2478 if (cec_dev->cec_thread == NULL) {
2479 CEC_INFO("create work queue failed\n");
2480 ret = -EFAULT;
2481 goto tag_cec_threat_err;
2482 }
2483 INIT_DELAYED_WORK(&cec_dev->cec_work, cec_task);
2484 cec_dev->cec_info.remote_cec_dev = input_allocate_device();
2485 if (!cec_dev->cec_info.remote_cec_dev) {
2486 CEC_INFO("No enough memory\n");
2487 ret = -ENOMEM;
2488 goto tag_cec_alloc_input_err;
2489 }
2490
2491 cec_dev->cec_info.remote_cec_dev->name = "cec_input";
2492
2493 cec_dev->cec_info.remote_cec_dev->evbit[0] = BIT_MASK(EV_KEY);
2494 cec_dev->cec_info.remote_cec_dev->keybit[BIT_WORD(BTN_0)] =
2495 BIT_MASK(BTN_0);
2496 cec_dev->cec_info.remote_cec_dev->id.bustype = BUS_ISA;
2497 cec_dev->cec_info.remote_cec_dev->id.vendor = 0x1b8e;
2498 cec_dev->cec_info.remote_cec_dev->id.product = 0x0cec;
2499 cec_dev->cec_info.remote_cec_dev->id.version = 0x0001;
2500
2501 set_bit(KEY_POWER, cec_dev->cec_info.remote_cec_dev->keybit);
2502
2503 if (input_register_device(cec_dev->cec_info.remote_cec_dev)) {
2504 CEC_INFO("Failed to register device\n");
2505 input_free_device(cec_dev->cec_info.remote_cec_dev);
2506 }
2507
2508#ifdef CONFIG_OF
2509 /* if using EE CEC */
2510 if (of_property_read_bool(node, "ee_cec"))
2511 ee_cec = 1;
2512 else
2513 ee_cec = 0;
2514 CEC_INFO("using EE cec:%d\n", ee_cec);
2515 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2516 if (res) {
2517 base = ioremap(res->start, res->end - res->start);
2518 cec_dev->exit_reg = (void *)base;
2519 } else {
2520 CEC_INFO("no memory resource\n");
2521 cec_dev->exit_reg = NULL;
2522 }
2523 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2524 if (res) {
2525 base = ioremap(res->start, res->end - res->start);
2526 cec_dev->cec_reg = (void *)base;
2527 } else {
2528 CEC_ERR("no CEC reg resource\n");
2529 cec_dev->cec_reg = NULL;
2530 }
2531 res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
2532 if (res) {
2533 base = ioremap(res->start, res->end - res->start);
2534 cec_dev->hdmi_rxreg = (void *)base;
2535 } else {
2536 CEC_ERR("no hdmirx reg resource\n");
2537 cec_dev->hdmi_rxreg = NULL;
2538 }
2539 res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
2540 if (res) {
2541 base = ioremap(res->start, res->end - res->start);
2542 cec_dev->hhi_reg = (void *)base;
2543 } else {
2544 CEC_ERR("no hhi reg resource\n");
2545 cec_dev->hhi_reg = NULL;
2546 }
2547 r = of_property_read_u32(node, "port_num", &(cec_dev->port_num));
2548 if (r) {
2549 CEC_ERR("not find 'port_num'\n");
2550 cec_dev->port_num = 1;
2551 }
2552 r = of_property_read_u32(node, "arc_port_mask", &(cec_dev->arc_port));
2553 if (r) {
2554 CEC_ERR("not find 'arc_port_mask'\n");
2555 cec_dev->arc_port = 0;
2556 }
2557
2558 vend = &cec_dev->v_data;
2559 r = of_property_read_string(node, "vendor_name",
2560 (const char **)&(vend->vendor_name));
2561 if (r)
2562 CEC_INFO("not find vendor name\n");
2563
2564 r = of_property_read_u32(node, "vendor_id", &(vend->vendor_id));
2565 if (r)
2566 CEC_INFO("not find vendor id\n");
2567
2568 r = of_property_read_string(node, "product_desc",
2569 (const char **)&(vend->product_desc));
2570 if (r)
2571 CEC_INFO("not find product desc\n");
2572
2573 r = of_property_read_string(node, "cec_osd_string",
2574 (const char **)&(vend->cec_osd_string));
2575 if (r) {
2576 CEC_INFO("not find cec osd string\n");
2577 strcpy(vend->cec_osd_string, "AML TV/BOX");
2578 }
2579 r = of_property_read_u32(node, "cec_version",
2580 &(cec_dev->cec_info.cec_version));
2581 if (r) {
2582 /* default set to 2.0 */
2583 CEC_INFO("not find cec_version\n");
2584 cec_dev->cec_info.cec_version = CEC_VERSION_20;
2585 }
2586
2587 /* irq set */
2588 cec_irq_enable(false);
2589 irq_idx = of_irq_get(node, 0);
2590 cec_dev->irq_cec = irq_idx;
2591 if (of_get_property(node, "interrupt-names", NULL)) {
2592 r = of_property_read_string(node, "interrupt-names", &irq_name);
2593 if (!r && !ee_cec) {
2594 r = request_irq(irq_idx, &cec_isr_handler, IRQF_SHARED,
2595 irq_name, (void *)cec_dev);
2596 }
2597 if (!r && ee_cec) {
2598 r = request_irq(irq_idx, &cecrx_isr, IRQF_SHARED,
2599 irq_name, (void *)cec_dev);
2600 }
2601 }
2602#endif
2603
2604 if (!ee_cec) {
2605 last_cec_msg = devm_kzalloc(&pdev->dev,
2606 sizeof(*last_cec_msg), GFP_KERNEL);
2607 if (!last_cec_msg) {
2608 CEC_ERR("allocate last_cec_msg failed\n");
2609 ret = -ENOMEM;
2610 goto tag_cec_msg_alloc_err;
2611 }
2612 }
2613
2614#ifdef CONFIG_HAS_EARLYSUSPEND
2615 aocec_suspend_handler.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
2616 aocec_suspend_handler.suspend = aocec_early_suspend;
2617 aocec_suspend_handler.resume = aocec_late_resume;
2618 aocec_suspend_handler.param = cec_dev;
2619 register_early_suspend(&aocec_suspend_handler);
2620#endif
2621 hrtimer_init(&start_bit_check, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2622 start_bit_check.function = cec_line_check;
2623 /* for init */
2624 cec_pre_init();
2625 queue_delayed_work(cec_dev->cec_thread, &cec_dev->cec_work, 0);
2626
2627 return 0;
2628tag_cec_msg_alloc_err:
2629 input_free_device(cec_dev->cec_info.remote_cec_dev);
2630tag_cec_alloc_input_err:
2631 destroy_workqueue(cec_dev->cec_thread);
2632tag_cec_threat_err:
2633 device_destroy(&aocec_class,
2634 MKDEV(cec_dev->cec_info.dev_no, 0));
2635tag_cec_device_create_err:
2636 unregister_chrdev(cec_dev->cec_info.dev_no, CEC_DEV_NAME);
2637tag_cec_chr_reg_err:
2638 class_unregister(&aocec_class);
2639tag_cec_class_reg:
2640 devm_kfree(&pdev->dev, cec_dev);
2641tag_cec_devm_err:
2642 return ret;
2643}
2644
2645static int aml_cec_remove(struct platform_device *pdev)
2646{
2647 CEC_INFO("cec uninit!\n");
2648 free_irq(cec_dev->irq_cec, (void *)cec_dev);
2649 kfree(last_cec_msg);
2650
2651 if (cec_dev->cec_thread) {
2652 cancel_delayed_work_sync(&cec_dev->cec_work);
2653 destroy_workqueue(cec_dev->cec_thread);
2654 }
2655 input_unregister_device(cec_dev->cec_info.remote_cec_dev);
2656 unregister_chrdev(cec_dev->cec_info.dev_no, CEC_DEV_NAME);
2657 class_unregister(&aocec_class);
2658 kfree(cec_dev);
2659 return 0;
2660}
2661
2662#ifdef CONFIG_PM
2663static int aml_cec_pm_prepare(struct device *dev)
2664{
2665 cec_dev->cec_suspend = CEC_DEEP_SUSPEND;
2666 CEC_INFO("%s, cec_suspend:%d\n", __func__, cec_dev->cec_suspend);
2667 return 0;
2668}
2669
2670static void aml_cec_pm_complete(struct device *dev)
2671{
2672 int exit = 0;
2673
2674 if (cec_dev->exit_reg) {
2675 exit = readl(cec_dev->exit_reg);
2676 CEC_INFO("wake up flag:%x\n", exit);
2677 }
2678 if (((exit >> 28) & 0xf) == CEC_WAKEUP)
2679 cec_key_report(0);
2680}
2681
2682static int aml_cec_suspend_noirq(struct device *dev)
2683{
2684 return 0;
2685}
2686
2687static int aml_cec_resume_noirq(struct device *dev)
2688{
2689 CEC_INFO("cec resume noirq!\n");
2690 cec_dev->cec_info.power_status = TRANS_STANDBY_TO_ON;
2691 cec_dev->cec_suspend = CEC_POWER_RESUME;
2692
2693 return 0;
2694}
2695
2696static const struct dev_pm_ops aml_cec_pm = {
2697 .prepare = aml_cec_pm_prepare,
2698 .complete = aml_cec_pm_complete,
2699 .suspend_noirq = aml_cec_suspend_noirq,
2700 .resume_noirq = aml_cec_resume_noirq,
2701};
2702#endif
2703
2704static struct platform_driver aml_cec_driver = {
2705 .driver = {
2706 .name = "cectx",
2707 .owner = THIS_MODULE,
2708 #ifdef CONFIG_PM
2709 .pm = &aml_cec_pm,
2710 #endif
2711 #ifdef CONFIG_OF
2712 .of_match_table = aml_cec_dt_match,
2713 #endif
2714 },
2715 .probe = aml_cec_probe,
2716 .remove = aml_cec_remove,
2717};
2718
2719static int __init cec_init(void)
2720{
2721 int ret;
2722
2723 ret = platform_driver_register(&aml_cec_driver);
2724 return ret;
2725}
2726
2727static void __exit cec_uninit(void)
2728{
2729 platform_driver_unregister(&aml_cec_driver);
2730}
2731
2732module_init(cec_init);
2733module_exit(cec_uninit);
2734MODULE_DESCRIPTION("AMLOGIC HDMI TX CEC driver");
2735MODULE_LICENSE("GPL");
2736