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