summaryrefslogtreecommitdiff
path: root/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c (plain)
blob: d7918704065f355a6e783bd75093c72a67b89ea6
1/*
2 * drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.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, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18#include <linux/version.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/kthread.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/fs.h>
26#include <linux/slab.h>
27#include <linux/init.h>
28#include <linux/device.h>
29#include <linux/mm.h>
30#include <linux/major.h>
31#include <linux/platform_device.h>
32#include <linux/pinctrl/consumer.h>
33#include <linux/mutex.h>
34#include <linux/cdev.h>
35#include <linux/ctype.h>
36#include <linux/extcon.h>
37#include <linux/proc_fs.h>
38#include <linux/uaccess.h>
39#include <linux/workqueue.h>
40/* #include <mach/am_regs.h> */
41
42/* #include <linux/amlogic/osd/osd_dev.h> */
43#include "hdmi_tx_hdcp.h"
44
45#include <linux/input.h>
46#include <linux/irq.h>
47#include <linux/io.h>
48#include <linux/of.h>
49#include <linux/of_platform.h>
50#include <linux/of_address.h>
51#include <linux/reboot.h>
52#include <linux/extcon.h>
53
54#include <linux/amlogic/cpu_version.h>
55#include <linux/amlogic/media/vout/vinfo.h>
56#include <linux/amlogic/media/vout/vout_notify.h>
57#ifdef CONFIG_AMLOGIC_SND_SOC
58#include <linux/amlogic/media/sound/aout_notify.h>
59#endif
60#include <linux/amlogic/media/vout/hdmi_tx/hdmi_info_global.h>
61#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_ddc.h>
62#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
63#include <linux/amlogic/media/vout/hdmi_tx/hdmi_config.h>
64#include <linux/i2c.h>
65#include "hw/tvenc_conf.h"
66#ifdef CONFIG_INSTABOOT
67#include <linux/amlogic/instaboot/instaboot.h>
68#endif
69
70#define DEVICE_NAME "amhdmitx"
71#define HDMI_TX_COUNT 32
72#define HDMI_TX_POOL_NUM 6
73#define HDMI_TX_RESOURCE_NUM 4
74#define HDMI_TX_PWR_CTRL_NUM 6
75
76static dev_t hdmitx_id;
77static struct class *hdmitx_class;
78static int set_disp_mode_auto(void);
79struct vinfo_s *hdmi_get_current_vinfo(void);
80static void hdmitx_get_edid(struct hdmitx_dev *hdev);
81static void hdmitx_set_drm_pkt(struct master_display_info_s *data);
82static void hdmitx_set_vsif_pkt(enum eotf_type type, uint8_t tunnel_mode);
83static int check_fbc_special(unsigned char *edid_dat);
84static int hdcp_tst_sig;
85static DEFINE_MUTEX(setclk_mutex);
86static DEFINE_MUTEX(getedid_mutex);
87static atomic_t kref_audio_mute;
88static atomic_t kref_video_mute;
89static char fmt_attr[16];
90
91#ifndef CONFIG_AMLOGIC_VOUT
92/* Fake vinfo */
93struct vinfo_s vinfo_1080p60hz = {
94 .name = "1080p60hz",
95 .mode = VMODE_1080P,
96 .width = 1920,
97 .height = 1080,
98 .field_height = 1080,
99 .aspect_ratio_num = 16,
100 .aspect_ratio_den = 9,
101 .sync_duration_num = 60,
102 .sync_duration_den = 1,
103 .video_clk = 148500000,
104};
105struct vinfo_s *get_current_vinfo(void)
106{
107 return &vinfo_1080p60hz;
108}
109#endif
110
111struct hdmi_config_platform_data *hdmi_pdata;
112
113static const unsigned int hdmi_cable[] = {
114 EXTCON_DISP_HDMI,
115 EXTCON_NONE,
116};
117
118static struct hdmitx_dev hdmitx_device;
119struct extcon_dev *hdmitx_extcon_hdmi;
120struct extcon_dev *hdmitx_excton_audio;
121struct extcon_dev *hdmitx_excton_power;
122struct extcon_dev *hdmitx_excton_hdr;
123struct extcon_dev *hdmitx_excton_rxsense;
124struct extcon_dev *hdmitx_excton_hdcp;
125
126static int hdmi_init;
127
128static inline void hdmitx_notify_hpd(int hpd)
129{
130 if (hpd)
131 hdmitx_event_notify(HDMITX_PLUG, NULL);
132 else
133 hdmitx_event_notify(HDMITX_UNPLUG, NULL);
134}
135#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
136#include <linux/amlogic/pm.h>
137static void hdmitx_early_suspend(struct early_suspend *h)
138{
139 const struct vinfo_s *info = hdmi_get_current_vinfo();
140 struct hdmitx_dev *phdmi = (struct hdmitx_dev *)h->param;
141
142 if (info && (strncmp(info->name, "panel", 5) == 0
143 || strncmp(info->name, "null", 4) == 0))
144 return;
145
146 phdmi->hpd_lock = 1;
147 msleep(20);
148 phdmi->HWOp.CntlMisc(phdmi, MISC_AVMUTE_OP, SET_AVMUTE);
149 mdelay(100);
150 hdmi_print(IMP, SYS "HDMITX: early suspend\n");
151 phdmi->HWOp.Cntl((struct hdmitx_dev *)h->param,
152 HDMITX_EARLY_SUSPEND_RESUME_CNTL, HDMITX_EARLY_SUSPEND);
153 phdmi->cur_VIC = HDMI_Unknown;
154 phdmi->output_blank_flag = 0;
155 phdmi->HWOp.CntlDDC(phdmi, DDC_HDCP_MUX_INIT, 1);
156 phdmi->HWOp.CntlDDC(phdmi, DDC_HDCP_OP, HDCP14_OFF);
157 extcon_set_state_sync(hdmitx_excton_power, EXTCON_DISP_HDMI, 0);
158 phdmi->HWOp.CntlConfig(&hdmitx_device, CONF_CLR_AVI_PACKET, 0);
159 phdmi->HWOp.CntlConfig(&hdmitx_device, CONF_CLR_VSDB_PACKET, 0);
160}
161
162static int hdmitx_is_hdmi_vmode(char *mode_name)
163{
164 enum hdmi_vic vic = hdmitx_edid_vic_tab_map_vic(mode_name);
165
166 if (vic == HDMI_Unknown)
167 return 0;
168
169 return 1;
170}
171
172static void hdmitx_late_resume(struct early_suspend *h)
173{
174 const struct vinfo_s *info = hdmi_get_current_vinfo();
175 struct hdmitx_dev *phdmi = (struct hdmitx_dev *)h->param;
176
177 if (info && (strncmp(info->name, "panel", 5) == 0 ||
178 strncmp(info->name, "null", 4) == 0)) {
179 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
180 CONF_VIDEO_BLANK_OP, VIDEO_UNBLANK);
181 return;
182 } else {
183 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
184 CONF_VIDEO_BLANK_OP, VIDEO_BLANK);
185 }
186
187 if (hdmitx_is_hdmi_vmode(info->name) == 1)
188 phdmi->HWOp.CntlMisc(&hdmitx_device, MISC_HPLL_FAKE, 0);
189
190 phdmi->hpd_lock = 0;
191
192 /* update status for hpd and switch/state */
193 hdmitx_device.hpd_state = !!(hdmitx_device.HWOp.CntlMisc(&hdmitx_device,
194 MISC_HPD_GPI_ST, 0));
195 hdmitx_notify_hpd(hdmitx_device.hpd_state);
196
197 /*force to get EDID after resume for Amplifer Power case*/
198 if (hdmitx_device.hpd_state)
199 hdmitx_get_edid(phdmi);
200
201 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
202 CONF_AUDIO_MUTE_OP, AUDIO_MUTE);
203 set_disp_mode_auto();
204
205 extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI,
206 hdmitx_device.hpd_state);
207 extcon_set_state_sync(hdmitx_excton_power, EXTCON_DISP_HDMI,
208 hdmitx_device.hpd_state);
209
210 pr_info("amhdmitx: late resume module %d\n", __LINE__);
211 phdmi->HWOp.Cntl((struct hdmitx_dev *)h->param,
212 HDMITX_EARLY_SUSPEND_RESUME_CNTL, HDMITX_LATE_RESUME);
213 hdmi_print(INF, SYS "late resume\n");
214}
215
216/* Set avmute_set signal to HDMIRX */
217static int hdmitx_reboot_notifier(struct notifier_block *nb,
218 unsigned long action, void *data)
219{
220 struct hdmitx_dev *hdev = container_of(nb, struct hdmitx_dev, nb);
221
222 hdev->HWOp.CntlMisc(hdev, MISC_AVMUTE_OP, SET_AVMUTE);
223 mdelay(100);
224 hdev->HWOp.CntlMisc(hdev, MISC_TMDS_PHY_OP, TMDS_PHY_DISABLE);
225 hdev->HWOp.CntlMisc(hdev, MISC_HPLL_OP, HPLL_DISABLE);
226 return NOTIFY_OK;
227}
228
229static struct early_suspend hdmitx_early_suspend_handler = {
230 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 10,
231 .suspend = hdmitx_early_suspend,
232 .resume = hdmitx_late_resume,
233 .param = &hdmitx_device,
234};
235#endif
236
237/* static struct hdmitx_info hdmi_info; */
238#define INIT_FLAG_VDACOFF 0x1
239 /* unplug powerdown */
240#define INIT_FLAG_POWERDOWN 0x2
241
242#define INIT_FLAG_NOT_LOAD 0x80
243
244int hdmi_ch = 1; /* 1: 2ch */
245
246static unsigned char init_flag;
247#undef DISABLE_AUDIO
248/* if set to 1, then HDMI will output no audio */
249/* In KTV case, HDMI output Picture only, and Audio is driven by other
250 * sources.
251 */
252unsigned char hdmi_audio_off_flag;
253/*
254 * 0, do not unmux hpd when off or unplug ;
255 * 1, unmux hpd when unplug;
256 * 2, unmux hpd when unplug or off;
257 */
258static int hpdmode = 1;
259/* 0xffff=disable; 0=PRBS 11; 1=PRBS 15; 2=PRBS 7; 3=PRBS 31*/
260static int hdmi_prbs_mode = 0xffff;
261static int hdmi_detect_when_booting = 1;
262/* 1: error 2: important 3: normal 4: detailed */
263static int debug_level = INF;
264
265int get_cur_vout_index(void)
266/*
267 * return value: 1, vout; 2, vout2;
268 */
269{
270 int vout_index = 1;
271 return vout_index;
272}
273
274struct vinfo_s *hdmi_get_current_vinfo(void)
275{
276 struct vinfo_s *info;
277
278 info = get_current_vinfo();
279 return info;
280}
281
282static int set_disp_mode(const char *mode)
283{
284 int ret = -1;
285 enum hdmi_vic vic;
286
287 vic = hdmitx_edid_get_VIC(&hdmitx_device, mode, 1);
288 if (strncmp(mode, "2160p30hz", strlen("2160p30hz")) == 0)
289 vic = HDMI_4k2k_30;
290 else if (strncmp(mode, "2160p25hz", strlen("2160p25hz")) == 0)
291 vic = HDMI_4k2k_25;
292 else if (strncmp(mode, "2160p24hz", strlen("2160p24hz")) == 0)
293 vic = HDMI_4k2k_24;
294 else if (strncmp(mode, "smpte24hz", strlen("smpte24hz")) == 0)
295 vic = HDMI_4k2k_smpte_24;
296 else
297 ;/* nothing */
298
299 if (strncmp(mode, "1080p60hz", strlen("1080p60hz")) == 0)
300 vic = HDMI_1080p60;
301 if (strncmp(mode, "1080p50hz", strlen("1080p50hz")) == 0)
302 vic = HDMI_1080p50;
303
304 if (vic != HDMI_Unknown) {
305 hdmitx_device.mux_hpd_if_pin_high_flag = 1;
306 if (hdmitx_device.vic_count == 0) {
307 if (hdmitx_device.unplug_powerdown)
308 return 0;
309 }
310 }
311#if 0
312 set_vmode_enc_hw(vic);
313#endif
314 hdmitx_device.cur_VIC = HDMI_Unknown;
315 ret = hdmitx_set_display(&hdmitx_device, vic);
316 if (ret >= 0) {
317 hdmitx_device.HWOp.Cntl(&hdmitx_device,
318 HDMITX_AVMUTE_CNTL, AVMUTE_CLEAR);
319 hdmitx_device.cur_VIC = vic;
320 hdmitx_device.audio_param_update_flag = 1;
321 hdmitx_device.auth_process_timer = AUTH_PROCESS_TIME;
322 }
323
324 if (hdmitx_device.cur_VIC == HDMI_Unknown) {
325 if (hpdmode == 2) {
326 /* edid will be read again when hpd is muxed and
327 * it is high
328 */
329 hdmitx_edid_clear(&hdmitx_device);
330 hdmitx_device.mux_hpd_if_pin_high_flag = 0;
331 }
332 if (hdmitx_device.HWOp.Cntl) {
333 hdmitx_device.HWOp.Cntl(&hdmitx_device,
334 HDMITX_HWCMD_TURNOFF_HDMIHW,
335 (hpdmode == 2)?1:0);
336 }
337 }
338
339 return ret;
340}
341
342static void hdmitx_pre_display_init(void)
343{
344 hdmitx_device.cur_VIC = HDMI_Unknown;
345 hdmitx_device.auth_process_timer = AUTH_PROCESS_TIME;
346 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
347 CONF_VIDEO_BLANK_OP, VIDEO_BLANK);
348 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
349 CONF_AUDIO_MUTE_OP, AUDIO_MUTE);
350 hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_HDCP_MUX_INIT, 1);
351 hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_HDCP_OP, HDCP14_OFF);
352 /* msleep(10); */
353 hdmitx_device.HWOp.CntlMisc(&hdmitx_device, MISC_TMDS_PHY_OP,
354 TMDS_PHY_DISABLE);
355 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
356 CONF_CLR_AVI_PACKET, 0);
357 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
358 CONF_CLR_VSDB_PACKET, 0);
359}
360
361/* fr_tab[]
362 * 1080p24hz, 24:1
363 * 1080p23.976hz, 2997:125
364 * 25/50/100/200hz, no change
365 */
366static struct frac_rate_table fr_tab[] = {
367 {"24hz", 24, 1, 2997, 125},
368 {"30hz", 30, 1, 2997, 100},
369 {"60hz", 60, 1, 2997, 50},
370 {"120hz", 120, 1, 2997, 25},
371 {"240hz", 120, 1, 5994, 25},
372 {NULL},
373};
374
375static void recalc_vinfo_sync_duration(struct vinfo_s *info, unsigned int frac)
376{
377 struct frac_rate_table *fr = &fr_tab[0];
378
379 while (fr->hz) {
380 if (strstr(info->name, fr->hz)) {
381 if (frac) {
382 info->sync_duration_num = fr->sync_num_dec;
383 info->sync_duration_den = fr->sync_den_dec;
384 } else {
385 info->sync_duration_num = fr->sync_num_int;
386 info->sync_duration_den = fr->sync_den_int;
387 }
388 break;
389 }
390 fr++;
391 }
392}
393
394static void hdmi_physcial_size_update(struct vinfo_s *info,
395 struct hdmitx_dev *hdev)
396{
397 unsigned int width, height;
398
399 if (info == NULL) {
400 hdmi_print(ERR, VID "cann't get valid mode\n");
401 return;
402 }
403
404 width = hdev->RXCap.physcial_weight;
405 height = hdev->RXCap.physcial_height;
406 if ((width == 0) || (height == 0)) {
407 info->screen_real_width = info->aspect_ratio_num;
408 info->screen_real_height = info->aspect_ratio_den;
409 } else {
410 info->screen_real_width = width * 10; /* transfer mm */
411 info->screen_real_height = height * 10; /* transfer mm */
412 }
413 pr_info("hdmitx: update physcial size: %d %d\n",
414 info->screen_real_width, info->screen_real_height);
415}
416
417static int set_disp_mode_auto(void)
418{
419 int ret = -1;
420 struct vinfo_s *info = NULL;
421 struct hdmitx_dev *hdev = &hdmitx_device;
422 struct hdmi_format_para *para = NULL;
423 unsigned char mode[32];
424 enum hdmi_vic vic = HDMI_Unknown;
425 /* vic_ready got from IP */
426 enum hdmi_vic vic_ready = hdev->HWOp.GetState(
427 hdev, STAT_VIDEO_VIC, 0);
428
429 memset(mode, 0, sizeof(mode));
430
431 /* get current vinfo */
432 info = hdmi_get_current_vinfo();
433 hdmi_print(IMP, VID "get current mode: %s\n",
434 info ? info->name : "null");
435 if (info == NULL)
436 return -1;
437
438 info->fresh_tx_hdr_pkt = hdmitx_set_drm_pkt;
439 info->fresh_tx_vsif_pkt = hdmitx_set_vsif_pkt;
440 info->dv_info = &hdev->RXCap.dv_info;
441 if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
442 (strncmp(info->name, "576cvbs", 7) == 0) ||
443 (strncmp(info->name, "null", 4) == 0))) {
444 info->hdr_info.hdr_support = (hdev->RXCap.hdr_sup_eotf_sdr << 0)
445 | (hdev->RXCap.hdr_sup_eotf_hdr << 1)
446 | (hdev->RXCap.hdr_sup_eotf_smpte_st_2084 << 2);
447 info->hdr_info.lumi_max = hdev->RXCap.hdr_lum_max;
448 info->hdr_info.lumi_avg = hdev->RXCap.hdr_lum_avg;
449 info->hdr_info.lumi_min = hdev->RXCap.hdr_lum_min;
450 pr_info("hdmitx: update rx hdr info %x\n",
451 info->hdr_info.hdr_support);
452 }
453 hdmi_physcial_size_update(info, hdev);
454
455 /* If info->name equals to cvbs, then set mode to I mode to hdmi
456 */
457 if ((strncmp(info->name, "480cvbs", 7) == 0) ||
458 (strncmp(info->name, "576cvbs", 7) == 0) ||
459 (strncmp(info->name, "ntsc_m", 6) == 0) ||
460 (strncmp(info->name, "pal_m", 5) == 0) ||
461 (strncmp(info->name, "pal_n", 5) == 0) ||
462 (strncmp(info->name, "panel", 5) == 0) ||
463 (strncmp(info->name, "null", 4) == 0)) {
464 hdmi_print(ERR, VID "%s not valid hdmi mode\n", info->name);
465 hdev->HWOp.CntlConfig(hdev, CONF_CLR_AVI_PACKET, 0);
466 hdev->HWOp.CntlConfig(hdev, CONF_CLR_VSDB_PACKET, 0);
467 hdev->HWOp.CntlMisc(hdev, MISC_TMDS_PHY_OP, TMDS_PHY_DISABLE);
468 hdev->HWOp.CntlConfig(hdev, CONF_VIDEO_BLANK_OP, VIDEO_UNBLANK);
469 hdev->para = para = hdmi_get_fmt_name("invalid", fmt_attr);
470 return -1;
471 }
472 memcpy(mode, info->name, strlen(info->name));
473 if (strstr(mode, "fp")) {
474 int i = 0;
475
476 for (; mode[i]; i++) {
477 if ((mode[i] == 'f') && (mode[i + 1] == 'p')) {
478 /* skip "f", 1080fp60hz -> 1080p60hz */
479 do {
480 mode[i] = mode[i + 1];
481 i++;
482 } while (mode[i]);
483 break;
484 }
485 }
486 }
487
488 /* In the file hdmi_common/hdmi_parameters.c,
489 * the data array all_fmt_paras[] treat 2160p60hz and 2160p60hz420
490 * as two different modes, such Scrambler
491 * So if node "attr" contains 420, need append 420 to mode.
492 */
493 if (strstr(fmt_attr, "420")) {
494 if (!strstr(mode, "420"))
495 strncat(mode, "420", 3);
496 }
497 para = hdmi_get_fmt_name(mode, fmt_attr);
498 hdev->para = para;
499 /* msleep(500); */
500 vic = hdmitx_edid_get_VIC(hdev, mode, 1);
501 if (strncmp(info->name, "2160p30hz", strlen("2160p30hz")) == 0) {
502 vic = HDMI_4k2k_30;
503 } else if (strncmp(info->name, "2160p25hz",
504 strlen("2160p25hz")) == 0) {
505 vic = HDMI_4k2k_25;
506 } else if (strncmp(info->name, "2160p24hz",
507 strlen("2160p24hz")) == 0) {
508 vic = HDMI_4k2k_24;
509 } else if (strncmp(info->name, "smpte24hz",
510 strlen("smpte24hz")) == 0)
511 vic = HDMI_4k2k_smpte_24;
512 else {
513 /* nothing */
514 }
515 if ((vic_ready != HDMI_Unknown) && (vic_ready == vic)) {
516 hdmi_print(IMP, SYS "[%s] ALREADY init VIC = %d\n",
517 __func__, vic);
518 if (hdev->RXCap.IEEEOUI == 0) {
519 /* DVI case judgement. In uboot, directly output HDMI
520 * mode
521 */
522 hdev->HWOp.CntlConfig(hdev, CONF_HDMI_DVI_MODE,
523 DVI_MODE);
524 hdmi_print(IMP, SYS "change to DVI mode\n");
525 } else if ((hdev->RXCap.IEEEOUI == 0xc03) &&
526 (hdev->HWOp.CntlConfig(hdev, CONF_GET_HDMI_DVI_MODE, 0)
527 == DVI_MODE)) {
528 hdev->HWOp.CntlConfig(hdev, CONF_HDMI_DVI_MODE,
529 HDMI_MODE);
530 hdmi_print(IMP, SYS "change to HDMI mode\n");
531 }
532 hdev->cur_VIC = vic;
533 hdev->output_blank_flag = 1;
534 hdev->ready = 1;
535 return 1;
536 }
537 hdmitx_pre_display_init();
538
539 hdev->cur_VIC = HDMI_Unknown;
540/* if vic is HDMI_Unknown, hdmitx_set_display will disable HDMI */
541 ret = hdmitx_set_display(hdev, vic);
542 pr_info("%s %d %d\n", info->name, info->sync_duration_num,
543 info->sync_duration_den);
544 recalc_vinfo_sync_duration(info, hdev->frac_rate_policy);
545 pr_info("%s %d %d\n", info->name, info->sync_duration_num,
546 info->sync_duration_den);
547 if (ret >= 0) {
548 hdev->HWOp.Cntl(hdev, HDMITX_AVMUTE_CNTL, AVMUTE_CLEAR);
549 hdev->cur_VIC = vic;
550 hdev->audio_param_update_flag = 1;
551 hdev->auth_process_timer = AUTH_PROCESS_TIME;
552 }
553 if (hdev->cur_VIC == HDMI_Unknown) {
554 if (hpdmode == 2) {
555 /* edid will be read again when hpd is muxed
556 * and it is high
557 */
558 hdmitx_edid_clear(hdev);
559 hdev->mux_hpd_if_pin_high_flag = 0;
560 }
561 /* If current display is NOT panel, needn't TURNOFF_HDMIHW */
562 if (strncmp(mode, "panel", 5) == 0) {
563 hdev->HWOp.Cntl(hdev, HDMITX_HWCMD_TURNOFF_HDMIHW,
564 (hpdmode == 2)?1:0);
565 }
566 }
567 hdmitx_set_audio(hdev, &(hdev->cur_audio_param), hdmi_ch);
568 hdev->output_blank_flag = 1;
569 hdev->ready = 1;
570 return ret;
571}
572
573/*disp_mode attr*/
574static ssize_t show_disp_mode(struct device *dev,
575 struct device_attribute *attr, char *buf)
576{
577 int pos = 0;
578
579 pos += snprintf(buf+pos, PAGE_SIZE, "VIC:%d\n",
580 hdmitx_device.cur_VIC);
581 return pos;
582}
583
584static ssize_t store_disp_mode(struct device *dev,
585 struct device_attribute *attr, const char *buf, size_t count)
586{
587 set_disp_mode(buf);
588 return count;
589}
590
591static ssize_t show_attr(struct device *dev,
592 struct device_attribute *attr, char *buf)
593{
594 int pos = 0;
595
596 pos += snprintf(buf+pos, PAGE_SIZE, "%s\n\r", fmt_attr);
597 return pos;
598}
599
600static ssize_t store_attr(struct device *dev,
601 struct device_attribute *attr, const char *buf, size_t count)
602{
603 memcpy(fmt_attr, buf, sizeof(fmt_attr));
604 return count;
605}
606
607/*aud_mode attr*/
608static ssize_t show_aud_mode(struct device *dev,
609 struct device_attribute *attr, char *buf)
610{
611 return 0;
612}
613
614static ssize_t store_aud_mode(struct device *dev,
615 struct device_attribute *attr, const char *buf, size_t count)
616{
617 /* set_disp_mode(buf); */
618 struct hdmitx_audpara *audio_param =
619 &(hdmitx_device.cur_audio_param);
620 if (strncmp(buf, "32k", 3) == 0)
621 audio_param->sample_rate = FS_32K;
622 else if (strncmp(buf, "44.1k", 5) == 0)
623 audio_param->sample_rate = FS_44K1;
624 else if (strncmp(buf, "48k", 3) == 0)
625 audio_param->sample_rate = FS_48K;
626 else {
627 hdmitx_device.force_audio_flag = 0;
628 return count;
629 }
630 audio_param->type = CT_PCM;
631 audio_param->channel_num = CC_2CH;
632 audio_param->sample_size = SS_16BITS;
633
634 hdmitx_device.audio_param_update_flag = 1;
635 hdmitx_device.force_audio_flag = 1;
636
637 return count;
638}
639
640/*edid attr*/
641static ssize_t show_edid(struct device *dev,
642 struct device_attribute *attr, char *buf)
643{
644 return hdmitx_edid_dump(&hdmitx_device, buf, PAGE_SIZE);
645}
646
647static int dump_edid_data(unsigned int type, char *path)
648{
649 struct file *filp = NULL;
650 loff_t pos = 0;
651 char line[128] = {0};
652 mm_segment_t old_fs = get_fs();
653 unsigned int i = 0, j = 0, k = 0, size = 0, block_cnt = 0;
654
655 set_fs(KERNEL_DS);
656 filp = filp_open(path, O_RDWR|O_CREAT, 0666);
657 if (IS_ERR(filp)) {
658 pr_info("[%s] failed to open/create file: |%s|\n",
659 __func__, path);
660 goto PROCESS_END;
661 }
662
663 block_cnt = hdmitx_device.EDID_buf[0x7e] + 1;
664 if (type == 1) {
665 /* dump as bin file*/
666 size = vfs_write(filp, hdmitx_device.EDID_buf,
667 block_cnt*128, &pos);
668 } else if (type == 2) {
669 /* dump as txt file*/
670
671 for (i = 0; i < block_cnt; i++) {
672 for (j = 0; j < 8; j++) {
673 for (k = 0; k < 16; k++) {
674 snprintf((char *)&line[k*6], 7,
675 "0x%02x, ",
676 hdmitx_device.EDID_buf[i*128+j*16+k]);
677 }
678 line[16*6-1] = '\n';
679 line[16*6] = 0x0;
680 pos = (i*8+j)*16*6;
681 size += vfs_write(filp, line, 16*6, &pos);
682 }
683 }
684 }
685
686 pr_info("[%s] write %d bytes to file %s\n", __func__, size, path);
687
688 vfs_fsync(filp, 0);
689 filp_close(filp, NULL);
690
691PROCESS_END:
692 set_fs(old_fs);
693 return 0;
694}
695
696unsigned int use_loaded_edid;
697static int load_edid_data(unsigned int type, char *path)
698{
699 struct file *filp = NULL;
700 loff_t pos = 0;
701 mm_segment_t old_fs = get_fs();
702
703 struct kstat stat;
704 unsigned int length = 0, max_len = EDID_MAX_BLOCK * 128;
705 char *buf = NULL;
706
707 set_fs(KERNEL_DS);
708
709 filp = filp_open(path, O_RDONLY, 0444);
710 if (IS_ERR(filp)) {
711 pr_info("[%s] failed to open file: |%s|\n", __func__, path);
712 goto PROCESS_END;
713 }
714
715 vfs_stat(path, &stat);
716
717 length = (stat.size > max_len)?max_len:stat.size;
718
719 buf = kmalloc(length, GFP_KERNEL);
720 if (buf == NULL)
721 goto PROCESS_END;
722
723 vfs_read(filp, buf, length, &pos);
724
725 memcpy(hdmitx_device.EDID_buf, buf, length);
726
727 kfree(buf);
728 filp_close(filp, NULL);
729
730 pr_info("[%s] %d bytes loaded from file %s\n", __func__, length, path);
731
732 hdmitx_edid_clear(&hdmitx_device);
733 hdmitx_edid_parse(&hdmitx_device);
734 pr_info("[%s] new edid loaded!\n", __func__);
735
736PROCESS_END:
737 set_fs(old_fs);
738 return 0;
739}
740
741static ssize_t store_edid(struct device *dev,
742 struct device_attribute *attr, const char *buf, size_t count)
743{
744 unsigned int argn = 0;
745 char *p = NULL, *para = NULL, *argv[8] = {NULL};
746 unsigned int path_length = 0;
747
748 p = kstrdup(buf, GFP_KERNEL);
749 if (p == NULL)
750 return count;
751
752 do {
753 para = strsep(&p, " ");
754 if (para != NULL) {
755 argv[argn] = para;
756 argn++;
757 if (argn > 7)
758 break;
759 }
760 } while (para != NULL);
761
762 if (buf[0] == 'h') {
763 int i;
764
765 hdmi_print(INF, EDID "EDID hash value:\n");
766 for (i = 0; i < 20; i++)
767 pr_info("%02x", hdmitx_device.EDID_hash[i]);
768 pr_info("\n");
769 }
770 if (buf[0] == 'd') {
771 int ii, jj;
772 unsigned long block_idx;
773 int ret;
774
775 ret = kstrtoul(buf+1, 16, &block_idx);
776 if (block_idx < EDID_MAX_BLOCK) {
777 for (ii = 0; ii < 8; ii++) {
778 for (jj = 0; jj < 16; jj++) {
779 hdmi_print(INF, "%02x ",
780 hdmitx_device.EDID_buf[block_idx*128+ii*16+jj]);
781 }
782 hdmi_print(INF, "\n");
783 }
784 hdmi_print(INF, "\n");
785 }
786 }
787 if (buf[0] == 'e') {
788 int ii, jj;
789 unsigned long block_idx;
790 int ret;
791
792 ret = kstrtoul(buf+1, 16, &block_idx);
793 if (block_idx < EDID_MAX_BLOCK) {
794 for (ii = 0; ii < 8; ii++) {
795 for (jj = 0; jj < 16; jj++) {
796 hdmi_print(INF, "%02x ",
797 hdmitx_device.EDID_buf1[block_idx*128+ii*16+jj]);
798 }
799 hdmi_print(INF, "\n");
800 }
801 hdmi_print(INF, "\n");
802 }
803 }
804
805 if (!strncmp(argv[0], "save", strlen("save"))) {
806 unsigned int type = 0;
807
808 if (argn != 3) {
809 pr_info("[%s] cmd format: save bin/txt edid_file_path\n",
810 __func__);
811 goto PROCESS_END;
812 }
813 if (!strncmp(argv[1], "bin", strlen("bin")))
814 type = 1;
815 else if (!strncmp(argv[1], "txt", strlen("txt")))
816 type = 2;
817
818 if ((type == 1) || (type == 2)) {
819 /* clean '\n' from file path*/
820 path_length = strlen(argv[2]);
821 if (argv[2][path_length-1] == '\n')
822 argv[2][path_length-1] = 0x0;
823
824 dump_edid_data(type, argv[2]);
825 }
826 } else if (!strncmp(argv[0], "load", strlen("load"))) {
827 if (argn != 2) {
828 pr_info("[%s] cmd format: load edid_file_path\n",
829 __func__);
830 goto PROCESS_END;
831 }
832
833 /* clean '\n' from file path*/
834 path_length = strlen(argv[1]);
835 if (argv[1][path_length-1] == '\n')
836 argv[1][path_length-1] = 0x0;
837 load_edid_data(0, argv[1]);
838 }
839
840PROCESS_END:
841 kfree(p);
842 return 16;
843}
844
845/* rawedid attr */
846static ssize_t show_rawedid(struct device *dev,
847 struct device_attribute *attr, char *buf)
848{
849 int pos = 0;
850 int i;
851 struct hdmitx_dev *hdev = &hdmitx_device;
852 int num;
853
854 /* prevent null prt */
855 if (!hdev->edid_ptr)
856 hdev->edid_ptr = hdev->EDID_buf;
857
858 if (hdev->edid_ptr[0x7e] < 4)
859 num = (hdev->edid_ptr[0x7e]+1)*0x80;
860 else
861 num = 0x100;
862
863 for (i = 0; i < num; i++)
864 pos += snprintf(buf+pos, PAGE_SIZE, "%02x", hdev->edid_ptr[i]);
865
866 pos += snprintf(buf+pos, PAGE_SIZE, "\n");
867
868 return pos;
869}
870
871/*
872 * edid_parsing attr
873 * If RX edid data are all correct, HEAD(00 ff ff ff ff ff ff 00), checksum,
874 * version, etc), then return "ok". Otherwise, "ng"
875 * Actually, in some old televisions, EDID is stored in EEPROM.
876 * some bits in EEPROM may reverse with time.
877 * But it does not affect edid_parsing.
878 * Therefore, we consider the RX edid data are all correct, return "OK"
879 */
880static ssize_t show_edid_parsing(struct device *dev,
881 struct device_attribute *attr, char *buf)
882{
883 int pos = 0;
884
885 pos += snprintf(buf+pos, PAGE_SIZE, "ok\n");
886 return pos;
887}
888
889/*
890 * sink_type attr
891 * sink, or repeater
892 */
893static ssize_t show_sink_type(struct device *dev, struct device_attribute *attr,
894 char *buf)
895{
896 int pos = 0;
897 struct hdmitx_dev *hdev = &hdmitx_device;
898
899 if (!hdev->hpd_state) {
900 pos += snprintf(buf+pos, PAGE_SIZE, "none\n");
901 return pos;
902 }
903
904 if (hdev->hdmi_info.vsdb_phy_addr.b)
905 pos += snprintf(buf+pos, PAGE_SIZE, "repeater\n");
906 else
907 pos += snprintf(buf+pos, PAGE_SIZE, "sink\n");
908
909 return pos;
910}
911
912/*
913 * hdcp_repeater attr
914 * For hdcp 22, hdcp_tx22 will write to store_hdcp_repeater
915 * For hdcp 14, directly get bcaps bit
916 */
917static ssize_t show_hdcp_repeater(struct device *dev,
918 struct device_attribute *attr, char *buf)
919{
920 int pos = 0;
921 struct hdmitx_dev *hdev = &hdmitx_device;
922
923 if (hdev->hdcp_mode == 1)
924 hdev->hdcp_bcaps_repeater = hdev->HWOp.CntlDDC(hdev,
925 DDC_HDCP14_GET_BCAPS_RP, 0);
926
927 pos += snprintf(buf+pos, PAGE_SIZE, "%d\n", hdev->hdcp_bcaps_repeater);
928
929 return pos;
930}
931
932static ssize_t store_hdcp_repeater(struct device *dev,
933 struct device_attribute *attr, const char *buf, size_t count)
934{
935 struct hdmitx_dev *hdev = &hdmitx_device;
936
937 if (hdev->hdcp_mode == 2)
938 hdev->hdcp_bcaps_repeater = (buf[0] == '1');
939
940 return count;
941}
942
943/*
944 * hdcp22_type attr
945 */
946static bool hdcp22_type;
947static ssize_t show_hdcp22_type(struct device *dev,
948 struct device_attribute *attr, char *buf)
949{
950 int pos = 0;
951
952 pos += snprintf(buf+pos, PAGE_SIZE, "%d\n", hdcp22_type);
953
954 return pos;
955}
956
957static ssize_t store_hdcp22_type(struct device *dev,
958 struct device_attribute *attr, const char *buf, size_t count)
959{
960 if (buf[0] == '0')
961 hdcp22_type = 0;
962 if (buf[0] == '1')
963 hdcp22_type = 1;
964
965 return count;
966}
967
968static ssize_t show_hdcp22_base(struct device *dev,
969 struct device_attribute *attr, char *buf)
970{
971 int pos = 0;
972
973 pos += snprintf(buf+pos, PAGE_SIZE, "0x%x\n", get_hdcp22_base());
974
975 return pos;
976}
977
978void hdmitx_audio_mute_op(unsigned int flag)
979{
980 hdmitx_device.tx_aud_cfg = flag;
981 if (flag == 0)
982 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
983 CONF_AUDIO_MUTE_OP, AUDIO_MUTE);
984 else
985 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
986 CONF_AUDIO_MUTE_OP, AUDIO_UNMUTE);
987}
988EXPORT_SYMBOL(hdmitx_audio_mute_op);
989
990void hdmitx_video_mute_op(unsigned int flag)
991{
992 if (flag == 0)
993 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
994 CONF_VIDEO_MUTE_OP, VIDEO_MUTE);
995 else
996 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
997 CONF_VIDEO_MUTE_OP, VIDEO_UNMUTE);
998}
999EXPORT_SYMBOL(hdmitx_video_mute_op);
1000
1001static void hdr_work_func(struct work_struct *work)
1002{
1003 struct hdmitx_dev *hdev =
1004 container_of(work, struct hdmitx_dev, work_hdr);
1005
1006 unsigned char DRM_HB[3] = {0x87, 0x1, 26};
1007 unsigned char DRM_DB[26] = {0x0};
1008
1009 hdev->HWOp.SetPacket(HDMI_PACKET_DRM, DRM_DB, DRM_HB);
1010 hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, CLR_AVI_BT2020);
1011 msleep(1500);/*delay 1.5s*/
1012
1013 if (hdev->hdr_transfer_feature == T_BT709 &&
1014 hdev->hdr_color_feature == C_BT709)
1015 hdev->HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL);
1016 /* switch_set_state(&hdmi_hdr, hdev->hdr_src_feature); */
1017}
1018
1019#define GET_LOW8BIT(a) ((a) & 0xff)
1020#define GET_HIGH8BIT(a) (((a) >> 8) & 0xff)
1021static void hdmitx_set_drm_pkt(struct master_display_info_s *data)
1022{
1023 struct hdmitx_dev *hdev = &hdmitx_device;
1024 unsigned char DRM_HB[3] = {0x87, 0x1, 26};
1025 unsigned char DRM_DB[26] = {0x0};
1026
1027 /*
1028 *hdr_color_feature: bit 23-16: color_primaries
1029 * 1:bt709 0x9:bt2020
1030 *hdr_transfer_feature: bit 15-8: transfer_characteristic
1031 * 1:bt709 0xe:bt2020-10 0x10:smpte-st-2084 0x12:hlg(todo)
1032 */
1033 if (data) {
1034 hdev->hdr_transfer_feature = (data->features >> 8) & 0xff;
1035 hdev->hdr_color_feature = (data->features >> 16) & 0xff;
1036 }
1037 if ((!data) || (!(hdev->RXCap.hdr_sup_eotf_smpte_st_2084) &&
1038 !(hdev->RXCap.hdr_sup_eotf_hdr) &&
1039 !(hdev->RXCap.hdr_sup_eotf_sdr) &&
1040 !(hdev->RXCap.hdr_sup_eotf_hlg))) {
1041 DRM_HB[1] = 0;
1042 DRM_HB[2] = 0;
1043 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL);
1044 hdmitx_device.HWOp.CntlConfig(&hdmitx_device, CONF_AVI_BT2020,
1045 CLR_AVI_BT2020);
1046 return;
1047 }
1048
1049 /*SDR*/
1050 if (hdev->hdr_transfer_feature == T_BT709 &&
1051 hdev->hdr_color_feature == C_BT709) {
1052 schedule_work(&hdev->work_hdr);
1053 return;
1054 }
1055
1056 DRM_DB[1] = 0x0;
1057 DRM_DB[2] = GET_LOW8BIT(data->primaries[0][0]);
1058 DRM_DB[3] = GET_HIGH8BIT(data->primaries[0][0]);
1059 DRM_DB[4] = GET_LOW8BIT(data->primaries[0][1]);
1060 DRM_DB[5] = GET_HIGH8BIT(data->primaries[0][1]);
1061 DRM_DB[6] = GET_LOW8BIT(data->primaries[1][0]);
1062 DRM_DB[7] = GET_HIGH8BIT(data->primaries[1][0]);
1063 DRM_DB[8] = GET_LOW8BIT(data->primaries[1][1]);
1064 DRM_DB[9] = GET_HIGH8BIT(data->primaries[1][1]);
1065 DRM_DB[10] = GET_LOW8BIT(data->primaries[2][0]);
1066 DRM_DB[11] = GET_HIGH8BIT(data->primaries[2][0]);
1067 DRM_DB[12] = GET_LOW8BIT(data->primaries[2][1]);
1068 DRM_DB[13] = GET_HIGH8BIT(data->primaries[2][1]);
1069 DRM_DB[14] = GET_LOW8BIT(data->white_point[0]);
1070 DRM_DB[15] = GET_HIGH8BIT(data->white_point[0]);
1071 DRM_DB[16] = GET_LOW8BIT(data->white_point[1]);
1072 DRM_DB[17] = GET_HIGH8BIT(data->white_point[1]);
1073 DRM_DB[18] = GET_LOW8BIT(data->luminance[0]);
1074 DRM_DB[19] = GET_HIGH8BIT(data->luminance[0]);
1075 DRM_DB[20] = GET_LOW8BIT(data->luminance[1]);
1076 DRM_DB[21] = GET_HIGH8BIT(data->luminance[1]);
1077 DRM_DB[22] = GET_LOW8BIT(data->max_content);
1078 DRM_DB[23] = GET_HIGH8BIT(data->max_content);
1079 DRM_DB[24] = GET_LOW8BIT(data->max_frame_average);
1080 DRM_DB[25] = GET_HIGH8BIT(data->max_frame_average);
1081
1082 /* bt2020 + gamma transfer */
1083 if (hdev->hdr_transfer_feature == T_BT709 &&
1084 hdev->hdr_color_feature == C_BT2020) {
1085 if (hdev->sdr_hdr_feature == 0) {
1086 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM,
1087 NULL, NULL);
1088 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
1089 CONF_AVI_BT2020, SET_AVI_BT2020);
1090 } else if (hdev->sdr_hdr_feature == 1) {
1091 memset(DRM_DB, 0, sizeof(DRM_DB));
1092 hdev->HWOp.SetPacket(HDMI_PACKET_DRM,
1093 DRM_DB, DRM_HB);
1094 hdev->HWOp.CntlConfig(&hdmitx_device,
1095 CONF_AVI_BT2020, SET_AVI_BT2020);
1096 } else {
1097 DRM_DB[0] = 0x02; /* SMPTE ST 2084 */
1098 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM,
1099 DRM_DB, DRM_HB);
1100 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
1101 CONF_AVI_BT2020, SET_AVI_BT2020);
1102 }
1103 return;
1104 }
1105
1106 /* SMPTE ST 2084 and (BT2020 or NON_STANDARD) */
1107 if (hdev->RXCap.hdr_sup_eotf_smpte_st_2084) {
1108 if (hdev->hdr_transfer_feature == T_SMPTE_ST_2084 &&
1109 hdev->hdr_color_feature == C_BT2020) {
1110 DRM_DB[0] = 0x02; /* SMPTE ST 2084 */
1111 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM,
1112 DRM_DB, DRM_HB);
1113 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
1114 CONF_AVI_BT2020, SET_AVI_BT2020);
1115 return;
1116 } else if (hdev->hdr_transfer_feature == T_SMPTE_ST_2084 &&
1117 hdev->hdr_color_feature != C_BT2020) {
1118 DRM_DB[0] = 0x02; /* no standard SMPTE ST 2084 */
1119 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM,
1120 DRM_DB, DRM_HB);
1121 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
1122 CONF_AVI_BT2020, CLR_AVI_BT2020);
1123 return;
1124 }
1125 }
1126
1127 /*HLG and BT2020*/
1128 if (hdev->RXCap.hdr_sup_eotf_hlg) {
1129 if (hdev->hdr_color_feature == C_BT2020 &&
1130 (hdev->hdr_transfer_feature == T_BT2020_10 ||
1131 hdev->hdr_transfer_feature == T_HLG)) {
1132 DRM_DB[0] = 0x03;/* HLG is 0x03 */
1133 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM,
1134 DRM_DB, DRM_HB);
1135 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
1136 CONF_AVI_BT2020, SET_AVI_BT2020);
1137 return;
1138 }
1139 }
1140
1141 /*other case*/
1142 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL);
1143 hdmitx_device.HWOp.CntlConfig(&hdmitx_device, CONF_AVI_BT2020,
1144 CLR_AVI_BT2020);
1145 return;
1146}
1147
1148static void hdmitx_set_vsif_pkt(enum eotf_type type, uint8_t tunnel_mode)
1149{
1150 struct hdmitx_dev *hdev = &hdmitx_device;
1151 unsigned char VEN_HB[3] = {0x81, 0x01};
1152 unsigned char VEN_DB[24] = {0x00};
1153 unsigned char len = 0;
1154 unsigned int vic = hdev->cur_VIC;
1155 unsigned int hdmi_vic_4k_flag = 0;
1156
1157 if (get_cpu_type() < MESON_CPU_MAJOR_ID_GXL) {
1158 pr_info("hdmitx: not support DolbyVision\n");
1159 return;
1160 }
1161
1162 if ((vic == HDMI_3840x2160p30_16x9) ||
1163 (vic == HDMI_3840x2160p25_16x9) ||
1164 (vic == HDMI_3840x2160p24_16x9) ||
1165 (vic == HDMI_4096x2160p24_256x135))
1166 hdmi_vic_4k_flag = 1;
1167
1168 switch (type) {
1169 case EOTF_T_DOLBYVISION:
1170 len = 0x18;
1171 break;
1172 case EOTF_T_HDR10:
1173 len = 0x05;
1174 break;
1175 case EOTF_T_SDR:
1176 len = 0x05;
1177 break;
1178 case EOTF_T_NULL:
1179 default:
1180 len = 0x05;
1181 break;
1182 }
1183
1184 VEN_HB[2] = len;
1185 VEN_DB[0] = 0x03;
1186 VEN_DB[1] = 0x0c;
1187 VEN_DB[2] = 0x00;
1188 VEN_DB[3] = 0x00;
1189
1190 if (hdmi_vic_4k_flag) {
1191 VEN_DB[3] = 0x20;
1192 if (vic == HDMI_3840x2160p30_16x9)
1193 VEN_DB[4] = 0x1;
1194 else if (vic == HDMI_3840x2160p25_16x9)
1195 VEN_DB[4] = 0x2;
1196 else if (vic == HDMI_3840x2160p24_16x9)
1197 VEN_DB[4] = 0x3;
1198 else if (vic == HDMI_4096x2160p24_256x135)
1199 VEN_DB[4] = 0x4;
1200 else
1201 VEN_DB[4] = 0x0;
1202 }
1203
1204 if (type == EOTF_T_DOLBYVISION) {
1205 hdev->HWOp.SetPacket(HDMI_PACKET_VEND, VEN_DB, VEN_HB);
1206 if (tunnel_mode == 1) {
1207 hdev->HWOp.CntlConfig(hdev, CONF_AVI_RGBYCC_INDIC,
1208 COLORSPACE_RGB444);
1209 hdev->HWOp.CntlConfig(hdev, CONF_AVI_Q01,
1210 RGB_RANGE_FUL);
1211 } else {
1212 hdev->HWOp.CntlConfig(hdev, CONF_AVI_RGBYCC_INDIC,
1213 COLORSPACE_YUV422);
1214 hdev->HWOp.CntlConfig(hdev, CONF_AVI_YQ01,
1215 YCC_RANGE_FUL);
1216 }
1217 } else {
1218 if (hdmi_vic_4k_flag)
1219 hdev->HWOp.SetPacket(HDMI_PACKET_VEND, VEN_DB, VEN_HB);
1220 else
1221 hdev->HWOp.SetPacket(HDMI_PACKET_VEND, NULL, NULL);
1222 hdev->HWOp.CntlConfig(hdev, CONF_AVI_RGBYCC_INDIC,
1223 hdev->para->cs);
1224 hdev->HWOp.CntlConfig(hdev, CONF_AVI_Q01, RGB_RANGE_LIM);
1225 hdev->HWOp.CntlConfig(hdev, CONF_AVI_YQ01, YCC_RANGE_LIM);
1226 }
1227}
1228
1229/*config attr*/
1230static ssize_t show_config(struct device *dev,
1231 struct device_attribute *attr, char *buf)
1232{
1233 int pos = 0;
1234 unsigned char *conf;
1235 struct hdmitx_dev *hdev = &hdmitx_device;
1236
1237 pos += snprintf(buf+pos, PAGE_SIZE, "cur_VIC: %d\n", hdev->cur_VIC);
1238 if (hdev->cur_video_param)
1239 pos += snprintf(buf+pos, PAGE_SIZE,
1240 "cur_video_param->VIC=%d\n",
1241 hdev->cur_video_param->VIC);
1242 if (hdev->para) {
1243 pos += snprintf(buf+pos, PAGE_SIZE, "cd = %d\n",
1244 hdev->para->cd);
1245 pos += snprintf(buf+pos, PAGE_SIZE, "cs = %d\n",
1246 hdev->para->cs);
1247 }
1248
1249 switch (hdev->tx_aud_cfg) {
1250 case 0:
1251 conf = "off";
1252 break;
1253 case 1:
1254 conf = "on";
1255 break;
1256 case 2:
1257 conf = "auto";
1258 break;
1259 default:
1260 conf = "none";
1261 }
1262 pos += snprintf(buf+pos, PAGE_SIZE, "audio config: %s\n", conf);
1263
1264 if (hdev->flag_3dfp)
1265 conf = "FramePacking";
1266 else if (hdev->flag_3dss)
1267 conf = "SidebySide";
1268 else if (hdev->flag_3dtb)
1269 conf = "TopButtom";
1270 else
1271 conf = "off";
1272 pos += snprintf(buf+pos, PAGE_SIZE, "3D config: %s\n", conf);
1273 return pos;
1274}
1275
1276static ssize_t store_config(struct device *dev,
1277 struct device_attribute *attr, const char *buf, size_t count)
1278{
1279 int ret = 0;
1280
1281 pr_info("hdmitx: config: %s\n", buf);
1282 if (strncmp(buf, "force", 5) == 0)
1283 hdmitx_device.disp_switch_config = DISP_SWITCH_FORCE;
1284 else if (strncmp(buf, "edid", 4) == 0)
1285 hdmitx_device.disp_switch_config = DISP_SWITCH_EDID;
1286 else if (strncmp(buf, "unplug_powerdown", 16) == 0) {
1287 if (buf[16] == '0')
1288 hdmitx_device.unplug_powerdown = 0;
1289 else
1290 hdmitx_device.unplug_powerdown = 1;
1291 } else if (strncmp(buf, "3d", 2) == 0) {
1292 /* Second, set 3D parameters */
1293 if (strncmp(buf+2, "tb", 2) == 0) {
1294 hdmitx_device.flag_3dtb = 1;
1295 hdmitx_device.flag_3dss = 0;
1296 hdmitx_device.flag_3dfp = 0;
1297 hdmi_set_3d(&hdmitx_device, T3D_TAB, 0);
1298 } else if ((strncmp(buf+2, "lr", 2) == 0) ||
1299 (strncmp(buf+2, "ss", 2) == 0)) {
1300 unsigned long sub_sample_mode = 0;
1301
1302 hdmitx_device.flag_3dtb = 0;
1303 hdmitx_device.flag_3dss = 1;
1304 hdmitx_device.flag_3dfp = 0;
1305 if (buf[2])
1306 ret = kstrtoul(buf+2, 10,
1307 &sub_sample_mode);
1308 /* side by side */
1309 hdmi_set_3d(&hdmitx_device, T3D_SBS_HALF,
1310 sub_sample_mode);
1311 } else if (strncmp(buf+2, "fp", 2) == 0) {
1312 hdmitx_device.flag_3dtb = 0;
1313 hdmitx_device.flag_3dss = 0;
1314 hdmitx_device.flag_3dfp = 1;
1315 hdmi_set_3d(&hdmitx_device, T3D_FRAME_PACKING, 0);
1316 } else if (strncmp(buf+2, "off", 3) == 0) {
1317 hdmitx_device.flag_3dfp = 0;
1318 hdmitx_device.flag_3dtb = 0;
1319 hdmitx_device.flag_3dss = 0;
1320 hdmi_set_3d(&hdmitx_device, T3D_DISABLE, 0);
1321 }
1322 } else if (strncmp(buf, "audio_", 6) == 0) {
1323 if (strncmp(buf+6, "off", 3) == 0) {
1324 hdmitx_audio_mute_op(0);
1325 hdmi_print(IMP, AUD "configure off\n");
1326 } else if (strncmp(buf+6, "on", 2) == 0) {
1327 hdmitx_audio_mute_op(1);
1328 hdmi_print(IMP, AUD "configure on\n");
1329 } else if (strncmp(buf+6, "auto", 4) == 0) {
1330 /* auto mode. if sink doesn't support current
1331 * audio format, then no audio output
1332 */
1333 hdmitx_device.tx_aud_cfg = 2;
1334 hdmi_print(IMP, AUD "configure auto\n");
1335 } else
1336 hdmi_print(ERR, AUD "configure error\n");
1337 } else if (strncmp(buf, "drm", 3) == 0) {
1338 unsigned char DRM_HB[3] = {0x87, 0x1, 26};
1339 unsigned char DRM_DB[26] = {
1340 0x00, 0x00, 0xc2, 0x33, 0xc4, 0x86, 0x4c, 0x1d,
1341 0xb8, 0x0b, 0xd0, 0x84, 0x80, 0x3e, 0x13, 0x3d,
1342 0x42, 0x40, 0x4c, 0x04, 0x00, 0x00, 0x00, 0x00,
1343 0x00, 0x00,
1344 };
1345
1346 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB)
1347 hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM,
1348 DRM_DB, DRM_HB);
1349 } else if (strncmp(buf, "vsif", 4) == 0)
1350 hdmitx_set_vsif_pkt(buf[4] - '0', buf[5] == '1');
1351
1352 return 16;
1353}
1354
1355static ssize_t show_aud_mute(struct device *dev,
1356 struct device_attribute *attr, char *buf)
1357{
1358 int pos = 0;
1359
1360 pos += snprintf(buf+pos, PAGE_SIZE, "%d\n",
1361 atomic_read(&kref_audio_mute));
1362 return pos;
1363}
1364
1365static ssize_t store_aud_mute(struct device *dev,
1366 struct device_attribute *attr, const char *buf, size_t count)
1367{
1368 if (buf[0] == '1') {
1369 atomic_inc(&kref_audio_mute);
1370 if (atomic_read(&kref_audio_mute) == 1)
1371 hdmitx_audio_mute_op(0);
1372 }
1373 if (buf[0] == '0') {
1374 if (!(atomic_sub_and_test(0, &kref_audio_mute))) {
1375 atomic_dec(&kref_audio_mute);
1376 if (atomic_sub_and_test(0, &kref_audio_mute))
1377 hdmitx_audio_mute_op(1);
1378 }
1379 }
1380
1381 return count;
1382}
1383
1384static ssize_t show_vid_mute(struct device *dev,
1385 struct device_attribute *attr, char *buf)
1386{
1387 int pos = 0;
1388
1389 pos += snprintf(buf+pos, PAGE_SIZE, "%d\n",
1390 atomic_read(&kref_video_mute));
1391 return pos;
1392}
1393
1394static ssize_t store_vid_mute(struct device *dev,
1395 struct device_attribute *attr, const char *buf, size_t count)
1396{
1397 if (buf[0] == '1') {
1398 atomic_inc(&kref_video_mute);
1399 if (atomic_read(&kref_video_mute) == 1)
1400 hdmitx_video_mute_op(0);
1401 }
1402 if (buf[0] == '0') {
1403 if (!(atomic_sub_and_test(0, &kref_video_mute))) {
1404 atomic_dec(&kref_video_mute);
1405 if (atomic_sub_and_test(0, &kref_video_mute))
1406 hdmitx_video_mute_op(1);
1407 }
1408 }
1409
1410 return count;
1411}
1412
1413static ssize_t store_debug(struct device *dev,
1414 struct device_attribute *attr, const char *buf, size_t count)
1415{
1416 hdmitx_device.HWOp.DebugFun(&hdmitx_device, buf);
1417 return count;
1418}
1419
1420/* support format lists */
1421const char *disp_mode_t[] = {
1422#if 0
1423 "480i60hz",
1424 "576i50hz",
1425#endif
1426 "480p60hz",
1427 "576p50hz",
1428 "720p60hz",
1429 "1080i60hz",
1430 "1080p60hz",
1431 "720p50hz",
1432 "1080i50hz",
1433 "1080p30hz",
1434 "1080p50hz",
1435 "1080p25hz",
1436 "1080p24hz",
1437 "2160p30hz",
1438 "2160p25hz",
1439 "2160p24hz",
1440 "smpte24hz",
1441 "smpte25hz",
1442 "smpte30hz",
1443 "smpte50hz",
1444 "smpte60hz",
1445 "2160p50hz",
1446 "2160p60hz",
1447 NULL
1448};
1449
1450static int is_4k50_fmt(char *mode)
1451{
1452 int i;
1453 static char const *hdmi4k50[] = {
1454 "2160p50hz",
1455 "2160p60hz",
1456 "smpte50hz",
1457 "smpte50hz",
1458 NULL
1459 };
1460
1461 for (i = 0; hdmi4k50[i]; i++) {
1462 if (strcmp(hdmi4k50[i], mode) == 0)
1463 return 1;
1464 }
1465 return 0;
1466}
1467
1468/**/
1469static ssize_t show_disp_cap(struct device *dev,
1470 struct device_attribute *attr, char *buf)
1471{
1472 int i, pos = 0;
1473 const char *native_disp_mode =
1474 hdmitx_edid_get_native_VIC(&hdmitx_device);
1475 enum hdmi_vic vic;
1476 char mode_tmp[32];
1477
1478 if (hdmitx_device.tv_no_edid) {
1479 pos += snprintf(buf+pos, PAGE_SIZE, "null edid\n");
1480 } else {
1481 for (i = 0; disp_mode_t[i]; i++) {
1482 memset(mode_tmp, 0, sizeof(mode_tmp));
1483 strncpy(mode_tmp, disp_mode_t[i], sizeof(mode_tmp));
1484 vic = hdmitx_edid_get_VIC(&hdmitx_device, mode_tmp, 0);
1485 /* Handling only 4k420 mode */
1486 if (vic == HDMI_Unknown) {
1487 if (is_4k50_fmt(mode_tmp)) {
1488 strcat(mode_tmp, "420");
1489 vic = hdmitx_edid_get_VIC(&hdmitx_device,
1490 mode_tmp, 0);
1491 }
1492 }
1493 if (vic != HDMI_Unknown) {
1494 pos += snprintf(buf+pos, PAGE_SIZE, "%s",
1495 disp_mode_t[i]);
1496 if (native_disp_mode && (strcmp(
1497 native_disp_mode,
1498 disp_mode_t[i]) == 0)) {
1499 pos += snprintf(buf+pos, PAGE_SIZE,
1500 "*\n");
1501 } else
1502 pos += snprintf(buf+pos, PAGE_SIZE, "\n");
1503 }
1504 }
1505 }
1506 return pos;
1507}
1508
1509static ssize_t show_preferred_mode(struct device *dev,
1510 struct device_attribute *attr, char *buf)
1511{
1512 int pos = 0;
1513 struct rx_cap *pRXCap = &hdmitx_device.RXCap;
1514
1515 pos += snprintf(buf+pos, PAGE_SIZE, "%s\n",
1516 hdmitx_edid_vic_to_string(pRXCap->preferred_mode));
1517
1518 return pos;
1519}
1520
1521/**/
1522static int local_support_3dfp(enum hdmi_vic vic)
1523{
1524 switch (vic) {
1525 case HDMI_1280x720p50_16x9:
1526 case HDMI_1280x720p60_16x9:
1527 case HDMI_1920x1080p24_16x9:
1528 case HDMI_1920x1080p25_16x9:
1529 case HDMI_1920x1080p30_16x9:
1530 case HDMI_1920x1080p50_16x9:
1531 case HDMI_1920x1080p60_16x9:
1532 return 1;
1533 default:
1534 return 0;
1535 }
1536}
1537static ssize_t show_disp_cap_3d(struct device *dev,
1538 struct device_attribute *attr, char *buf)
1539{
1540 int i, pos = 0;
1541 int j = 0;
1542 enum hdmi_vic vic;
1543
1544 pos += snprintf(buf+pos, PAGE_SIZE, "3D support lists:\n");
1545 for (i = 0; disp_mode_t[i]; i++) {
1546 /* 3D is not supported under 4k modes */
1547 if (strstr(disp_mode_t[i], "2160p") ||
1548 strstr(disp_mode_t[i], "smpte"))
1549 continue;
1550 vic = hdmitx_edid_get_VIC(&hdmitx_device,
1551 disp_mode_t[i], 0);
1552 for (j = 0; j < hdmitx_device.RXCap.VIC_count; j++) {
1553 if (vic == hdmitx_device.RXCap.VIC[j])
1554 break;
1555 }
1556 pos += snprintf(buf+pos, PAGE_SIZE, "\n%s ",
1557 disp_mode_t[i]);
1558 if (local_support_3dfp(vic)
1559 && (hdmitx_device.RXCap.support_3d_format[
1560 hdmitx_device.RXCap.VIC[j]].frame_packing == 1)) {
1561 pos += snprintf(buf+pos, PAGE_SIZE,
1562 "FramePacking ");
1563 }
1564 if (hdmitx_device.RXCap.support_3d_format[
1565 hdmitx_device.RXCap.VIC[j]].top_and_bottom == 1) {
1566 pos += snprintf(buf+pos, PAGE_SIZE,
1567 "TopBottom ");
1568 }
1569 if (hdmitx_device.RXCap.support_3d_format[
1570 hdmitx_device.RXCap.VIC[j]].side_by_side == 1) {
1571 pos += snprintf(buf+pos, PAGE_SIZE,
1572 "SidebySide ");
1573 }
1574 }
1575 pos += snprintf(buf+pos, PAGE_SIZE, "\n");
1576
1577 return pos;
1578}
1579
1580/**/
1581static ssize_t show_aud_cap(struct device *dev,
1582 struct device_attribute *attr, char *buf)
1583{
1584 int i, pos = 0, j;
1585 static const char * const aud_coding_type[] = {
1586 "ReferToStreamHeader", "PCM", "AC-3", "MPEG1", "MP3",
1587 "MPEG2", "AAC", "DTS", "ATRAC", "OneBitAudio",
1588 "Dobly_Digital+", "DTS-HD", "MAT", "DST", "WMA_Pro",
1589 "Reserved", NULL};
1590 static const char * const aud_sampling_frequency[] = {
1591 "ReferToStreamHeader", "32", "44.1", "48", "88.2", "96",
1592 "176.4", "192", NULL};
1593 static const char * const aud_sample_size[] = {"ReferToStreamHeader",
1594 "16", "20", "24", NULL};
1595
1596 struct rx_cap *pRXCap = &(hdmitx_device.RXCap);
1597
1598 pos += snprintf(buf + pos, PAGE_SIZE,
1599 "CodingType MaxChannels SamplingFreq SampleSize\n");
1600 for (i = 0; i < pRXCap->AUD_count; i++) {
1601 pos += snprintf(buf + pos, PAGE_SIZE, "%s, %d ch, ",
1602 aud_coding_type[pRXCap->RxAudioCap[i].
1603 audio_format_code],
1604 pRXCap->RxAudioCap[i].channel_num_max + 1);
1605 for (j = 0; j < 7; j++) {
1606 if (pRXCap->RxAudioCap[i].freq_cc & (1 << j))
1607 pos += snprintf(buf + pos, PAGE_SIZE, "%s/",
1608 aud_sampling_frequency[j+1]);
1609 }
1610 pos += snprintf(buf + pos - 1, PAGE_SIZE, " kHz, ");
1611 for (j = 0; j < 3; j++) {
1612 if (pRXCap->RxAudioCap[i].cc3 & (1 << j))
1613 pos += snprintf(buf + pos, PAGE_SIZE, "%s/",
1614 aud_sample_size[j+1]);
1615 }
1616 pos += snprintf(buf + pos - 1, PAGE_SIZE, " bit\n");
1617 }
1618
1619 return pos;
1620}
1621
1622/**/
1623static ssize_t show_dc_cap(struct device *dev,
1624 struct device_attribute *attr, char *buf)
1625{
1626 enum hdmi_vic vic = HDMI_Unknown;
1627 int pos = 0;
1628 struct rx_cap *pRXCap = &(hdmitx_device.RXCap);
1629
1630#if 0
1631 if (pRXCap->dc_48bit_420)
1632 pos += snprintf(buf + pos, PAGE_SIZE, "420,16bit\n");
1633 if (pRXCap->dc_36bit_420)
1634 pos += snprintf(buf + pos, PAGE_SIZE, "420,12bit\n");
1635#endif
1636 if (pRXCap->dc_30bit_420) {
1637 pos += snprintf(buf + pos, PAGE_SIZE, "420,10bit\n");
1638 pos += snprintf(buf + pos, PAGE_SIZE, "420,8bit\n");
1639 } else {
1640 vic = hdmitx_edid_get_VIC(&hdmitx_device, "2160p60hz420", 0);
1641 if (vic != HDMI_Unknown) {
1642 pos += snprintf(buf + pos, PAGE_SIZE, "420,8bit\n");
1643 goto next444;
1644 }
1645 vic = hdmitx_edid_get_VIC(&hdmitx_device, "2160p50hz420", 0);
1646 if (vic != HDMI_Unknown) {
1647 pos += snprintf(buf + pos, PAGE_SIZE, "420,8bit\n");
1648 goto next444;
1649 }
1650 vic = hdmitx_edid_get_VIC(&hdmitx_device, "smpte60hz420", 0);
1651 if (vic != HDMI_Unknown) {
1652 pos += snprintf(buf + pos, PAGE_SIZE, "420,8bit\n");
1653 goto next444;
1654 }
1655 vic = hdmitx_edid_get_VIC(&hdmitx_device, "smpte50hz420", 0);
1656 if (vic != HDMI_Unknown) {
1657 pos += snprintf(buf + pos, PAGE_SIZE, "420,8bit\n");
1658 goto next444;
1659 }
1660 }
1661next444:
1662 if (pRXCap->dc_y444) {
1663#if 0
1664 if (pRXCap->dc_36bit)
1665 pos += snprintf(buf + pos, PAGE_SIZE, "444,12bit\n");
1666 if (pRXCap->dc_36bit)
1667 pos += snprintf(buf + pos, PAGE_SIZE, "422,12bit\n");
1668#endif
1669 if (pRXCap->dc_30bit) {
1670 pos += snprintf(buf + pos, PAGE_SIZE, "444,10bit\n");
1671 pos += snprintf(buf + pos, PAGE_SIZE, "444,8bit\n");
1672 }
1673#if 0
1674 if (pRXCap->dc_48bit)
1675 pos += snprintf(buf + pos, PAGE_SIZE, "444,16bit\n");
1676#endif
1677 if (pRXCap->dc_30bit) {
1678 pos += snprintf(buf + pos, PAGE_SIZE, "422,10bit\n");
1679 pos += snprintf(buf + pos, PAGE_SIZE, "422,8bit\n");
1680 goto nextrgb;
1681 }
1682 } else {
1683 if (pRXCap->native_Mode & (1 << 5))
1684 pos += snprintf(buf + pos, PAGE_SIZE, "444,8bit\n");
1685 if (pRXCap->native_Mode & (1 << 4))
1686 pos += snprintf(buf + pos, PAGE_SIZE, "422,8bit\n");
1687 }
1688nextrgb:
1689#if 0
1690 if (pRXCap->dc_48bit)
1691 pos += snprintf(buf + pos, PAGE_SIZE, "rgb,16bit\n");
1692 if (pRXCap->dc_36bit)
1693 pos += snprintf(buf + pos, PAGE_SIZE, "rgb,12bit\n");
1694#endif
1695 if (pRXCap->dc_30bit)
1696 pos += snprintf(buf + pos, PAGE_SIZE, "rgb,10bit\n");
1697 pos += snprintf(buf + pos, PAGE_SIZE, "rgb,8bit\n");
1698 return pos;
1699}
1700
1701static bool valid_mode;
1702static char cvalid_mode[32];
1703
1704static bool pre_process_str(char *name)
1705{
1706 int i;
1707 unsigned int flag = 0;
1708 char *color_format[4] = {"444", "422", "420", "rgb"};
1709
1710 for (i = 0 ; i < 4 ; i++) {
1711 if (strstr(name, color_format[i]) != NULL)
1712 flag++;
1713 }
1714 if (flag >= 2)
1715 return 0;
1716 else
1717 return 1;
1718}
1719
1720static ssize_t show_valid_mode(struct device *dev,
1721 struct device_attribute *attr, char *buf)
1722{
1723 int pos = 0;
1724 struct hdmi_format_para *para = NULL;
1725
1726 if (cvalid_mode[0]) {
1727 valid_mode = pre_process_str(cvalid_mode);
1728 if (valid_mode == 0) {
1729 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n\r",
1730 valid_mode);
1731 return pos;
1732 }
1733 para = hdmi_get_fmt_name(cvalid_mode, cvalid_mode);
1734 }
1735 if (para) {
1736 pr_info("sname = %s\n", para->sname);
1737 pr_info("char_clk = %d\n", para->tmds_clk);
1738 pr_info("cd = %d\n", para->cd);
1739 pr_info("cs = %d\n", para->cs);
1740 }
1741
1742 valid_mode = hdmitx_edid_check_valid_mode(&hdmitx_device, para);
1743
1744 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n\r", valid_mode);
1745
1746 return pos;
1747}
1748
1749static ssize_t store_valid_mode(struct device *dev,
1750 struct device_attribute *attr, const char *buf, size_t count)
1751{
1752 memset(cvalid_mode, 0, sizeof(cvalid_mode));
1753 memcpy(cvalid_mode, buf, sizeof(cvalid_mode));
1754 cvalid_mode[31] = '\0';
1755 return count;
1756}
1757
1758
1759/**/
1760static ssize_t show_hdr_cap(struct device *dev,
1761 struct device_attribute *attr, char *buf)
1762{
1763 int pos = 0;
1764 struct rx_cap *pRXCap = &(hdmitx_device.RXCap);
1765
1766 pos += snprintf(buf + pos, PAGE_SIZE, "Supported EOTF:\n");
1767 pos += snprintf(buf + pos, PAGE_SIZE, " Traditional SDR: %d\n",
1768 pRXCap->hdr_sup_eotf_sdr);
1769 pos += snprintf(buf + pos, PAGE_SIZE, " Traditional HDR: %d\n",
1770 pRXCap->hdr_sup_eotf_hdr);
1771 pos += snprintf(buf + pos, PAGE_SIZE, " SMPTE ST 2084: %d\n",
1772 pRXCap->hdr_sup_eotf_smpte_st_2084);
1773 pos += snprintf(buf + pos, PAGE_SIZE, " Hybrif Log-Gamma: %d\n",
1774 pRXCap->hdr_sup_eotf_hlg);
1775 pos += snprintf(buf + pos, PAGE_SIZE, "Supported SMD type1: %d\n",
1776 pRXCap->hdr_sup_SMD_type1);
1777 pos += snprintf(buf + pos, PAGE_SIZE, "Luminance Data\n");
1778 pos += snprintf(buf + pos, PAGE_SIZE, " Max: %d\n",
1779 pRXCap->hdr_lum_max);
1780 pos += snprintf(buf + pos, PAGE_SIZE, " Avg: %d\n",
1781 pRXCap->hdr_lum_avg);
1782 pos += snprintf(buf + pos, PAGE_SIZE, " Min: %d\n",
1783 pRXCap->hdr_lum_min);
1784
1785 return pos;
1786}
1787
1788static ssize_t show_dv_cap(struct device *dev,
1789 struct device_attribute *attr, char *buf)
1790{
1791 int pos = 0;
1792 const struct dv_info *dv = &(hdmitx_device.RXCap.dv_info);
1793
1794 if (dv->ieeeoui != 0x00d046)
1795 return pos;
1796 pos += snprintf(buf + pos, PAGE_SIZE,
1797 "DolbyVision%d RX support list:\n", dv->ver);
1798 if (dv->sup_yuv422_12bit)
1799 pos += snprintf(buf + pos, PAGE_SIZE, " yuv422_12bit\n");
1800 pos += snprintf(buf + pos, PAGE_SIZE,
1801 " 2160p%shz: 1\n", dv->sup_2160p60hz ? "60" : "30");
1802 if (dv->sup_global_dimming)
1803 pos += snprintf(buf + pos, PAGE_SIZE, " global dimming\n");
1804 if (dv->colorimetry)
1805 pos += snprintf(buf + pos, PAGE_SIZE, " colorimetry\n");
1806 pos += snprintf(buf + pos, PAGE_SIZE,
1807 " IEEEOUI: 0x%06x\n", dv->ieeeoui);
1808 if (dv->ver == 0)
1809 pos += snprintf(buf + pos, PAGE_SIZE, " DM Ver: %x:%x\n",
1810 dv->vers.ver0.dm_major_ver, dv->vers.ver0.dm_minor_ver);
1811 if (dv->ver == 1)
1812 pos += snprintf(buf + pos, PAGE_SIZE, " DM Ver: %x\n",
1813 dv->vers.ver1.dm_version);
1814
1815 return pos;
1816}
1817
1818static ssize_t show_aud_ch(struct device *dev,
1819 struct device_attribute *attr, char *buf)
1820{
1821 int pos = 0;
1822
1823 pos += snprintf(buf + pos, PAGE_SIZE,
1824 "hdmi_channel = %d ch\n", hdmi_ch ? hdmi_ch + 1 : 0);
1825 return pos;
1826}
1827
1828static ssize_t store_aud_ch(struct device *dev,
1829 struct device_attribute *attr, const char *buf, size_t count)
1830{
1831 if (strncmp(buf, "6ch", 3) == 0)
1832 hdmi_ch = 5;
1833 else if (strncmp(buf, "8ch", 3) == 0)
1834 hdmi_ch = 7;
1835 else if (strncmp(buf, "2ch", 3) == 0)
1836 hdmi_ch = 1;
1837 else
1838 return count;
1839
1840 hdmitx_device.audio_param_update_flag = 1;
1841 hdmitx_device.force_audio_flag = 1;
1842
1843 return count;
1844}
1845
1846/* hdmitx audio output channel */
1847static ssize_t show_aud_output_chs(struct device *dev,
1848 struct device_attribute *attr, char *buf)
1849{
1850 struct hdmitx_dev *hdev = &hdmitx_device;
1851 int pos = 0;
1852
1853 if (hdev->aud_output_ch)
1854 pos += snprintf(buf + pos, PAGE_SIZE,
1855 "Audio Output Channels: %x:%x\n",
1856 (hdev->aud_output_ch >> 4) & 0xf,
1857 (hdev->aud_output_ch & 0xf));
1858
1859 return pos;
1860}
1861
1862/*
1863 * aud_output_chs CONFIGURE:
1864 * [7:4] -- Output Channel Numbers, must be 2/4/6/8
1865 * [3:0] -- Output Channel Mask, matched as CH3/2/1/0 R/L
1866 */
1867static ssize_t store_aud_output_chs(struct device *dev,
1868 struct device_attribute *attr, const char *buf, size_t count)
1869{
1870 struct hdmitx_dev *hdev = &hdmitx_device;
1871 int tmp = -1;
1872 int ret = 0;
1873 unsigned long msk;
1874 static unsigned int update_flag = -1;
1875
1876 if (isdigit(buf[0]))
1877 tmp = buf[0] - '0';
1878
1879 if (!((tmp == 2) || (tmp == 4) || (tmp == 6) || (tmp == 8))) {
1880 pr_info("err chn setting, must be 2, 4, 6 or 8, Rst as def\n");
1881 hdev->aud_output_ch = 0;
1882 if (update_flag != hdev->aud_output_ch) {
1883 update_flag = hdev->aud_output_ch;
1884 hdmitx_set_audio(hdev, &(hdev->cur_audio_param), 0);
1885 }
1886 return count;
1887 }
1888
1889 /* get channel no. For I2S, there are 4 I2S_in[3:0] */
1890 if ((buf[1] == ':') && (isxdigit(buf[2])))
1891 ret = kstrtoul(&buf[2], 16, &msk);
1892 else
1893 msk = 0;
1894 if (ret || (msk == 0)) {
1895 pr_info("err chn msk, must larger than 0\n");
1896 return count;
1897 }
1898
1899 hdev->aud_output_ch = (tmp << 4) + msk;
1900
1901 if (update_flag != hdev->aud_output_ch) {
1902 update_flag = hdev->aud_output_ch;
1903 hdmitx_set_audio(hdev, &(hdev->cur_audio_param), 0);
1904 }
1905 return count;
1906}
1907
1908/*
1909 * 1: set avmute
1910 * -1: clear avmute
1911 * 0: off avmute
1912 */
1913static ssize_t store_avmute(struct device *dev,
1914 struct device_attribute *attr, const char *buf, size_t count)
1915{
1916 int cmd = OFF_AVMUTE;
1917
1918 if (strncmp(buf, "-1", 2) == 0)
1919 cmd = CLR_AVMUTE;
1920 else if (strncmp(buf, "0", 1) == 0)
1921 cmd = OFF_AVMUTE;
1922 else if (strncmp(buf, "1", 1) == 0)
1923 cmd = SET_AVMUTE;
1924 else
1925 pr_info("set avmute wrong: %s\n", buf);
1926
1927 hdmitx_device.HWOp.CntlMisc(&hdmitx_device, MISC_AVMUTE_OP, cmd);
1928 return count;
1929}
1930
1931static ssize_t show_avmute(struct device *dev,
1932 struct device_attribute *attr, char *buf)
1933{
1934 return 0;
1935}
1936
1937/*
1938 * 0: clear vic
1939 */
1940static ssize_t store_vic(struct device *dev,
1941 struct device_attribute *attr, const char *buf, size_t count)
1942{
1943 struct hdmitx_dev *hdev = &hdmitx_device;
1944
1945 if (strncmp(buf, "0", 1) == 0) {
1946 hdev->HWOp.CntlConfig(hdev, CONF_CLR_AVI_PACKET, 0);
1947 hdev->HWOp.CntlConfig(hdev, CONF_CLR_VSDB_PACKET, 0);
1948 }
1949
1950 return count;
1951}
1952
1953static ssize_t show_vic(struct device *dev,
1954 struct device_attribute *attr, char *buf)
1955{
1956 struct hdmitx_dev *hdev = &hdmitx_device;
1957 enum hdmi_vic vic = HDMI_Unknown;
1958 int pos = 0;
1959
1960 vic = hdev->HWOp.GetState(hdev, STAT_VIDEO_VIC, 0);
1961 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n", vic);
1962
1963 return pos;
1964}
1965
1966/*
1967 * 1: enable hdmitx phy
1968 * 0: disable hdmitx phy
1969 */
1970static ssize_t store_phy(struct device *dev,
1971 struct device_attribute *attr, const char *buf, size_t count)
1972{
1973 int cmd = TMDS_PHY_ENABLE;
1974
1975 if (strncmp(buf, "0", 1) == 0)
1976 cmd = TMDS_PHY_DISABLE;
1977 else if (strncmp(buf, "1", 1) == 0)
1978 cmd = TMDS_PHY_ENABLE;
1979 else
1980 pr_info("hdmitx: set phy wrong: %s\n", buf);
1981
1982 hdmitx_device.HWOp.CntlMisc(&hdmitx_device, MISC_TMDS_PHY_OP, cmd);
1983 return count;
1984}
1985
1986static ssize_t show_phy(struct device *dev,
1987 struct device_attribute *attr, char *buf)
1988{
1989 return 0;
1990}
1991
1992static ssize_t store_rxsense_policy(struct device *dev,
1993 struct device_attribute *attr, const char *buf, size_t count)
1994{
1995 int val = 0;
1996
1997 if (isdigit(buf[0])) {
1998 val = buf[0] - '0';
1999 pr_info("hdmitx: set rxsense_policy as %d\n", val);
2000 if ((val == 0) || (val == 1))
2001 hdmitx_device.rxsense_policy = val;
2002 else
2003 pr_info("only accept as 0 or 1\n");
2004 }
2005 if (hdmitx_device.rxsense_policy)
2006 queue_delayed_work(hdmitx_device.rxsense_wq,
2007 &hdmitx_device.work_rxsense, 0);
2008 else
2009 cancel_delayed_work(&hdmitx_device.work_rxsense);
2010
2011
2012 return count;
2013}
2014
2015static ssize_t show_rxsense_policy(struct device *dev,
2016 struct device_attribute *attr, char *buf)
2017{
2018 int pos = 0;
2019
2020 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n",
2021 hdmitx_device.rxsense_policy);
2022
2023 return pos;
2024}
2025
2026static ssize_t store_frac_rate(struct device *dev,
2027 struct device_attribute *attr, const char *buf, size_t count)
2028{
2029 int val = 0;
2030
2031 if (isdigit(buf[0])) {
2032 val = buf[0] - '0';
2033 pr_info("hdmitx: set frac_rate_policy as %d\n", val);
2034 if ((val == 0) || (val == 1))
2035 hdmitx_device.frac_rate_policy = val;
2036 else
2037 pr_info("only accept as 0 or 1\n");
2038 }
2039
2040 return count;
2041}
2042
2043static ssize_t show_frac_rate(struct device *dev,
2044 struct device_attribute *attr, char *buf)
2045{
2046 int pos = 0;
2047
2048 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n",
2049 hdmitx_device.frac_rate_policy);
2050
2051 return pos;
2052}
2053
2054static ssize_t store_hdcp_clkdis(struct device *dev,
2055 struct device_attribute *attr, const char *buf, size_t count)
2056{
2057 hdmitx_device.HWOp.CntlMisc(&hdmitx_device, MISC_HDCP_CLKDIS,
2058 buf[0] == '1' ? 1 : 0);
2059 return count;
2060}
2061
2062static ssize_t show_hdcp_clkdis(struct device *dev,
2063 struct device_attribute *attr, char *buf)
2064{
2065 return 0;
2066}
2067
2068static ssize_t store_hdcp_pwr(struct device *dev,
2069 struct device_attribute *attr, const char *buf, size_t count)
2070{
2071 if (buf[0] == '1') {
2072 hdcp_tst_sig = 1;
2073 pr_info("set hdcp_pwr 1\n");
2074 }
2075
2076 return count;
2077}
2078
2079static ssize_t show_hdcp_pwr(struct device *dev,
2080 struct device_attribute *attr, char *buf)
2081{
2082 int pos = 0;
2083
2084 if (hdcp_tst_sig == 1) {
2085 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n", hdcp_tst_sig);
2086 hdcp_tst_sig = 0;
2087 pr_info("restore hdcp_pwr 0\n");
2088 }
2089
2090 return pos;
2091}
2092
2093static ssize_t store_hdcp_byp(struct device *dev,
2094 struct device_attribute *attr, const char *buf, size_t count)
2095{
2096 hdmitx_device.HWOp.CntlMisc(&hdmitx_device, MISC_HDCP_CLKDIS,
2097 buf[0] == '1' ? 1 : 0);
2098
2099 return count;
2100}
2101
2102static int lstore;
2103static ssize_t show_hdcp_lstore(struct device *dev,
2104 struct device_attribute *attr, char *buf)
2105{
2106 int pos = 0;
2107
2108 if (lstore < 0x10) {
2109 lstore = 0;
2110 if (hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2111 DDC_HDCP_14_LSTORE, 0))
2112 lstore += 1;
2113 if (hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2114 DDC_HDCP_22_LSTORE, 0))
2115 lstore += 2;
2116 }
2117 if (lstore & 0x1)
2118 pos += snprintf(buf + pos, PAGE_SIZE, "14\n");
2119 if (lstore & 0x2)
2120 pos += snprintf(buf + pos, PAGE_SIZE, "22\n");
2121 if ((lstore & 0xf) == 0)
2122 pos += snprintf(buf + pos, PAGE_SIZE, "00\n");
2123 return pos;
2124}
2125
2126static ssize_t store_hdcp_lstore(struct device *dev,
2127 struct device_attribute *attr, const char *buf, size_t count)
2128{
2129 pr_info("hdcp: set lstore as %s\n", buf);
2130 if (strncmp(buf, "0", 1) == 0)
2131 lstore = 0x10;
2132 if (strncmp(buf, "11", 2) == 0)
2133 lstore = 0x11;
2134 if (strncmp(buf, "12", 2) == 0)
2135 lstore = 0x12;
2136 if (strncmp(buf, "13", 2) == 0)
2137 lstore = 0x13;
2138
2139 return count;
2140}
2141
2142static unsigned int div40 = -1;
2143static ssize_t show_div40(struct device *dev,
2144 struct device_attribute *attr, char *buf)
2145{
2146 int pos = 0;
2147
2148 if (div40 != -1)
2149 pos += snprintf(buf + pos, PAGE_SIZE, "%d\n", div40);
2150
2151 return pos;
2152}
2153
2154static ssize_t store_div40(struct device *dev,
2155 struct device_attribute *attr, const char *buf, size_t count)
2156{
2157 struct hdmitx_dev *hdev = &hdmitx_device;
2158
2159 hdev->HWOp.CntlDDC(hdev, DDC_SCDC_DIV40_SCRAMB, buf[0] == '1');
2160 div40 = (buf[0] == '1');
2161
2162 return count;
2163}
2164
2165static ssize_t show_hdcp_mode(struct device *dev,
2166 struct device_attribute *attr, char *buf)
2167{
2168 int pos = 0;
2169
2170 switch (hdmitx_device.hdcp_mode) {
2171 case 1:
2172 pos += snprintf(buf + pos, PAGE_SIZE, "14");
2173 break;
2174 case 2:
2175 pos += snprintf(buf + pos, PAGE_SIZE, "22");
2176 break;
2177 default:
2178 pos += snprintf(buf + pos, PAGE_SIZE, "off");
2179 break;
2180 }
2181
2182 return pos;
2183}
2184
2185static ssize_t store_hdcp_mode(struct device *dev,
2186 struct device_attribute *attr, const char *buf, size_t count)
2187{
2188/* temporarily mark, no use SW I2C any more */
2189#if 0
2190 /* Issue SW I2C transaction to take advantage of SDA recovery logic */
2191 char tmp[8];
2192
2193 hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_PIN_MUX_OP, PIN_UNMUX);
2194 edid_rx_data(0x0, tmp, sizeof(tmp));
2195 hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_PIN_MUX_OP, PIN_MUX);
2196#endif
2197
2198 pr_info("hdcp: set mode as %s\n", buf);
2199 hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_HDCP_MUX_INIT, 1);
2200 if (strncmp(buf, "0", 1) == 0) {
2201 hdmitx_device.hdcp_mode = 0;
2202 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2203 DDC_HDCP_OP, HDCP14_OFF);
2204 hdmitx_hdcp_do_work(&hdmitx_device);
2205 }
2206 if (strncmp(buf, "1", 1) == 0) {
2207 hdmitx_device.hdcp_mode = 1;
2208 hdmitx_hdcp_do_work(&hdmitx_device);
2209 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2210 DDC_HDCP_OP, HDCP14_ON);
2211 }
2212 if (strncmp(buf, "2", 1) == 0) {
2213 hdmitx_device.hdcp_mode = 2;
2214 hdmitx_hdcp_do_work(&hdmitx_device);
2215 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2216 DDC_HDCP_MUX_INIT, 2);
2217 }
2218
2219 return count;
2220}
2221
2222void direct_hdcptx14_start(void)
2223{
2224 pr_info("%s[%d]", __func__, __LINE__);
2225 hdmitx_device.hdcp_mode = 1;
2226 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2227 DDC_HDCP_OP, HDCP14_ON);
2228}
2229EXPORT_SYMBOL(direct_hdcptx14_start);
2230
2231void direct_hdcptx14_stop(void)
2232{
2233 pr_info("%s[%d]", __func__, __LINE__);
2234 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2235 DDC_HDCP_OP, HDCP14_OFF);
2236}
2237EXPORT_SYMBOL(direct_hdcptx14_stop);
2238
2239static ssize_t store_hdcp_ctrl(struct device *dev,
2240 struct device_attribute *attr, const char *buf, size_t count)
2241{
2242 if (hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_HDCP_14_LSTORE,
2243 0) == 0)
2244 return count;
2245 dev_warn(dev, "hdmitx20: %s\n", buf);
2246 if (strncmp(buf, "stop", 4) == 0) {
2247 if (strncmp(buf+4, "14", 2) == 0)
2248 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2249 DDC_HDCP_OP, HDCP14_OFF);
2250 if (strncmp(buf+4, "22", 2) == 0)
2251 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2252 DDC_HDCP_OP, HDCP22_OFF);
2253 hdmitx_device.hdcp_mode = 0;
2254 hdmitx_hdcp_do_work(&hdmitx_device);
2255 }
2256
2257 return count;
2258}
2259
2260static ssize_t show_hdcp_ctrl(struct device *dev,
2261 struct device_attribute *attr, char *buf)
2262{
2263 return 0;
2264}
2265
2266static ssize_t show_hdcp_ksv_info(struct device *dev,
2267 struct device_attribute *attr, char *buf)
2268{
2269 int pos = 0, i;
2270 char bksv_buf[5];
2271
2272 hdmitx_device.HWOp.CntlDDC(&hdmitx_device, DDC_HDCP_GET_BKSV,
2273 (unsigned long int)bksv_buf);
2274
2275 pos += snprintf(buf+pos, PAGE_SIZE, "HDCP14 BKSV: ");
2276 for (i = 0; i < 5; i++) {
2277 pos += snprintf(buf+pos, PAGE_SIZE, "%02x",
2278 bksv_buf[i]);
2279 }
2280 pos += snprintf(buf+pos, PAGE_SIZE, " %s\n",
2281 hdcp_ksv_valid(bksv_buf) ? "Valid" : "Invalid");
2282
2283 return pos;
2284}
2285
2286/* Special FBC check */
2287static int check_fbc_special(unsigned char *edid_dat)
2288{
2289 if ((edid_dat[250] == 0xfb) && (edid_dat[251] == 0x0c))
2290 return 1;
2291 else
2292 return 0;
2293}
2294
2295static ssize_t show_hdcp_ver(struct device *dev,
2296 struct device_attribute *attr, char *buf)
2297{
2298 int pos = 0;
2299 uint32_t ver = 0U;
2300
2301 if (check_fbc_special(&hdmitx_device.EDID_buf[0])
2302 || check_fbc_special(&hdmitx_device.EDID_buf1[0])) {
2303 pos += snprintf(buf+pos, PAGE_SIZE, "00\n\r");
2304 return pos;
2305 }
2306
2307 /* if TX don't have HDCP22 key, skip RX hdcp22 ver */
2308 if (hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2309 DDC_HDCP_22_LSTORE, 0) == 0)
2310 goto next;
2311
2312 /* Detect RX support HDCP22 */
2313 mutex_lock(&getedid_mutex);
2314 ver = hdcp_rd_hdcp22_ver();
2315 mutex_unlock(&getedid_mutex);
2316 if (ver) {
2317 pos += snprintf(buf+pos, PAGE_SIZE, "22\n\r");
2318 pos += snprintf(buf+pos, PAGE_SIZE, "14\n\r");
2319 return pos;
2320 }
2321next: /* Detect RX support HDCP14 */
2322 /* Here, must assume RX support HDCP14, otherwise affect 1A-03 */
2323 if (ver == 0U) {
2324 pos += snprintf(buf+pos, PAGE_SIZE, "14\n\r");
2325 return pos;
2326 }
2327 return pos;
2328}
2329
2330static ssize_t show_hpd_state(struct device *dev,
2331 struct device_attribute *attr, char *buf)
2332{
2333 int pos = 0;
2334
2335 pos += snprintf(buf+pos, PAGE_SIZE, "%d",
2336 hdmitx_device.hpd_state);
2337 return pos;
2338}
2339
2340static ssize_t show_hdmi_init(struct device *dev,
2341 struct device_attribute *attr, char *buf)
2342{
2343 int pos = 0;
2344
2345 pos += snprintf(buf+pos, PAGE_SIZE, "%d\n\r", hdmi_init);
2346 return pos;
2347}
2348
2349static ssize_t show_ready(struct device *dev,
2350 struct device_attribute *attr, char *buf)
2351{
2352 int pos = 0;
2353
2354 pos += snprintf(buf+pos, PAGE_SIZE, "%d\r\n",
2355 hdmitx_device.ready);
2356 return pos;
2357}
2358
2359static ssize_t store_ready(struct device *dev,
2360 struct device_attribute *attr, const char *buf, size_t count)
2361{
2362 if (strncmp(buf, "0", 1) == 0)
2363 hdmitx_device.ready = 0;
2364 if (strncmp(buf, "1", 1) == 0)
2365 hdmitx_device.ready = 1;
2366 return count;
2367}
2368
2369static ssize_t show_support_3d(struct device *dev,
2370 struct device_attribute *attr, char *buf)
2371{
2372 int pos = 0;
2373
2374 pos += snprintf(buf+pos, PAGE_SIZE, "%d\n",
2375 hdmitx_device.RXCap.threeD_present);
2376 return pos;
2377}
2378
2379void hdmi_print(int dbg_lvl, const char *fmt, ...)
2380{
2381 va_list args;
2382#if 0
2383 if (dbg_lvl == OFF)
2384 return;
2385#endif
2386 if (dbg_lvl <= debug_level) {
2387 va_start(args, fmt);
2388 vprintk(fmt, args);
2389 va_end(args);
2390 }
2391}
2392
2393static DEVICE_ATTR(disp_mode, 0664, show_disp_mode, store_disp_mode);
2394static DEVICE_ATTR(attr, 0664, show_attr, store_attr);
2395static DEVICE_ATTR(aud_mode, 0644, show_aud_mode, store_aud_mode);
2396static DEVICE_ATTR(aud_mute, 0644, show_aud_mute, store_aud_mute);
2397static DEVICE_ATTR(vid_mute, 0644, show_vid_mute, store_vid_mute);
2398static DEVICE_ATTR(edid, 0644, show_edid, store_edid);
2399static DEVICE_ATTR(rawedid, 0444, show_rawedid, NULL);
2400static DEVICE_ATTR(sink_type, 0444, show_sink_type, NULL);
2401static DEVICE_ATTR(edid_parsing, 0444, show_edid_parsing, NULL);
2402static DEVICE_ATTR(config, 0664, show_config, store_config);
2403static DEVICE_ATTR(debug, 0200, NULL, store_debug);
2404static DEVICE_ATTR(disp_cap, 0444, show_disp_cap, NULL);
2405static DEVICE_ATTR(preferred_mode, 0444, show_preferred_mode, NULL);
2406static DEVICE_ATTR(aud_cap, 0444, show_aud_cap, NULL);
2407static DEVICE_ATTR(hdr_cap, 0444, show_hdr_cap, NULL);
2408static DEVICE_ATTR(dv_cap, 0444, show_dv_cap, NULL);
2409static DEVICE_ATTR(dc_cap, 0444, show_dc_cap, NULL);
2410static DEVICE_ATTR(valid_mode, 0664, show_valid_mode, store_valid_mode);
2411static DEVICE_ATTR(aud_ch, 0664, show_aud_ch, store_aud_ch);
2412static DEVICE_ATTR(aud_output_chs, 0664, show_aud_output_chs,
2413 store_aud_output_chs);
2414static DEVICE_ATTR(avmute, 0664, show_avmute, store_avmute);
2415static DEVICE_ATTR(vic, 0664, show_vic, store_vic);
2416static DEVICE_ATTR(phy, 0664, show_phy, store_phy);
2417static DEVICE_ATTR(frac_rate_policy, 0664, show_frac_rate, store_frac_rate);
2418static DEVICE_ATTR(rxsense_policy, 0644, show_rxsense_policy,
2419 store_rxsense_policy);
2420static DEVICE_ATTR(hdcp_clkdis, 0664, show_hdcp_clkdis, store_hdcp_clkdis);
2421static DEVICE_ATTR(hdcp_pwr, 0664, show_hdcp_pwr, store_hdcp_pwr);
2422static DEVICE_ATTR(hdcp_byp, 0200, NULL, store_hdcp_byp);
2423static DEVICE_ATTR(hdcp_mode, 0664, show_hdcp_mode, store_hdcp_mode);
2424static DEVICE_ATTR(hdcp_lstore, 0664, show_hdcp_lstore, store_hdcp_lstore);
2425static DEVICE_ATTR(hdcp_repeater, 0644, show_hdcp_repeater,
2426 store_hdcp_repeater);
2427static DEVICE_ATTR(hdcp22_type, 0644, show_hdcp22_type, store_hdcp22_type);
2428static DEVICE_ATTR(hdcp22_base, 0444, show_hdcp22_base, NULL);
2429static DEVICE_ATTR(div40, 0664, show_div40, store_div40);
2430static DEVICE_ATTR(hdcp_ctrl, 0664, show_hdcp_ctrl, store_hdcp_ctrl);
2431static DEVICE_ATTR(disp_cap_3d, 0444, show_disp_cap_3d, NULL);
2432static DEVICE_ATTR(hdcp_ksv_info, 0444, show_hdcp_ksv_info, NULL);
2433static DEVICE_ATTR(hdcp_ver, 0444, show_hdcp_ver, NULL);
2434static DEVICE_ATTR(hpd_state, 0444, show_hpd_state, NULL);
2435static DEVICE_ATTR(hdmi_init, 0444, show_hdmi_init, NULL);
2436static DEVICE_ATTR(ready, 0664, show_ready, store_ready);
2437static DEVICE_ATTR(support_3d, 0444, show_support_3d, NULL);
2438
2439struct vinfo_s *hdmi_info;
2440static struct vinfo_s *hdmitx_get_current_info(void)
2441{
2442 return hdmi_info;
2443}
2444
2445static int hdmitx_set_current_vmode(enum vmode_e mode)
2446{
2447 pr_info("%s[%d]\n", __func__, __LINE__);
2448 if (!(mode & VMODE_INIT_BIT_MASK))
2449 set_disp_mode_auto();
2450 else
2451 pr_info("hdmitx: alread display in uboot\n");
2452
2453 return 0;
2454}
2455
2456static enum vmode_e hdmitx_validate_vmode(char *mode)
2457{
2458 struct vinfo_s *info = hdmi_get_valid_vinfo(mode);
2459
2460 if (info) {
2461 hdmi_info = info;
2462 return VMODE_HDMI;
2463 }
2464 return VMODE_MAX;
2465}
2466
2467static int hdmitx_vmode_is_supported(enum vmode_e mode)
2468{
2469 if ((mode & VMODE_MODE_BIT_MASK) == VMODE_HDMI)
2470 return true;
2471 else
2472 return false;
2473}
2474
2475static int hdmitx_module_disable(enum vmode_e cur_vmod)
2476{ /* TODO */
2477 return 0;
2478}
2479
2480
2481static struct vout_server_s hdmitx_server = {
2482 .name = "vout_hdmitx_server",
2483 .op = {
2484 .get_vinfo = hdmitx_get_current_info,
2485 .set_vmode = hdmitx_set_current_vmode,
2486 .validate_vmode = hdmitx_validate_vmode,
2487 .vmode_is_supported = hdmitx_vmode_is_supported,
2488 .disable = hdmitx_module_disable,
2489#ifdef CONFIG_PM
2490 .vout_suspend = NULL,
2491 .vout_resume = NULL,
2492#endif
2493 },
2494};
2495
2496
2497#include <linux/soundcard.h>
2498#include <sound/core.h>
2499#include <sound/pcm.h>
2500#include <sound/initval.h>
2501#include <sound/control.h>
2502
2503static struct rate_map_fs map_fs[] = {
2504 {0, FS_REFER_TO_STREAM},
2505 {32000, FS_32K},
2506 {44100, FS_44K1},
2507 {48000, FS_48K},
2508 {88200, FS_88K2},
2509 {96000, FS_96K},
2510 {176400, FS_176K4},
2511 {192000, FS_192K},
2512};
2513
2514static enum hdmi_audio_fs aud_samp_rate_map(unsigned int rate)
2515{
2516 int i = 0;
2517
2518 for (i = 0; i < ARRAY_SIZE(map_fs); i++) {
2519 if (map_fs[i].rate == rate) {
2520 hdmi_print(IMP, AUD "aout notify rate %d\n",
2521 rate);
2522 return map_fs[i].fs;
2523 }
2524 }
2525 hdmi_print(IMP, AUD "get FS_MAX\n");
2526 return FS_MAX;
2527}
2528
2529static unsigned char *aud_type_string[] = {
2530 "CT_REFER_TO_STREAM",
2531 "CT_PCM",
2532 "CT_AC_3",
2533 "CT_MPEG1",
2534 "CT_MP3",
2535 "CT_MPEG2",
2536 "CT_AAC",
2537 "CT_DTS",
2538 "CT_ATRAC",
2539 "CT_ONE_BIT_AUDIO",
2540 "CT_DOLBY_D",
2541 "CT_DTS_HD",
2542 "CT_MAT",
2543 "CT_DST",
2544 "CT_WMA",
2545 "CT_MAX",
2546};
2547
2548static struct size_map aud_size_map_ss[] = {
2549 {0, SS_REFER_TO_STREAM},
2550 {16, SS_16BITS},
2551 {20, SS_20BITS},
2552 {24, SS_24BITS},
2553 {32, SS_MAX},
2554};
2555
2556static enum hdmi_audio_sampsize aud_size_map(unsigned int bits)
2557{
2558 int i;
2559
2560 for (i = 0; i < ARRAY_SIZE(aud_size_map_ss); i++) {
2561 if (bits == aud_size_map_ss[i].sample_bits) {
2562 hdmi_print(IMP, AUD "aout notify size %d\n",
2563 bits);
2564 return aud_size_map_ss[i].ss;
2565 }
2566 }
2567 hdmi_print(IMP, AUD "get SS_MAX\n");
2568 return SS_MAX;
2569}
2570
2571static int hdmitx_notify_callback_a(struct notifier_block *block,
2572 unsigned long cmd, void *para);
2573static struct notifier_block hdmitx_notifier_nb_a = {
2574 .notifier_call = hdmitx_notify_callback_a,
2575};
2576static int hdmitx_notify_callback_a(struct notifier_block *block,
2577 unsigned long cmd, void *para)
2578{
2579 int i, audio_check = 0;
2580 struct rx_cap *pRXCap = &(hdmitx_device.RXCap);
2581 struct snd_pcm_substream *substream =
2582 (struct snd_pcm_substream *)para;
2583 struct hdmitx_audpara *audio_param =
2584 &(hdmitx_device.cur_audio_param);
2585 enum hdmi_audio_fs n_rate = aud_samp_rate_map(substream->runtime->rate);
2586 enum hdmi_audio_sampsize n_size =
2587 aud_size_map(substream->runtime->sample_bits);
2588
2589 hdmitx_device.audio_param_update_flag = 0;
2590 hdmitx_device.audio_notify_flag = 0;
2591
2592 if (audio_param->sample_rate != n_rate) {
2593 audio_param->sample_rate = n_rate;
2594 hdmitx_device.audio_param_update_flag = 1;
2595 }
2596
2597 if (audio_param->type != cmd) {
2598 audio_param->type = cmd;
2599 hdmi_print(INF, AUD "aout notify format %s\n",
2600 aud_type_string[audio_param->type & 0xff]);
2601 hdmitx_device.audio_param_update_flag = 1;
2602 }
2603
2604 if (audio_param->sample_size != n_size) {
2605 audio_param->sample_size = n_size;
2606 hdmitx_device.audio_param_update_flag = 1;
2607 }
2608
2609 if (audio_param->channel_num !=
2610 (substream->runtime->channels - 1)) {
2611 audio_param->channel_num =
2612 substream->runtime->channels - 1;
2613 hdmitx_device.audio_param_update_flag = 1;
2614 }
2615 if (hdmitx_device.tx_aud_cfg == 2) {
2616 hdmi_print(INF, AUD "auto mode\n");
2617 /* Detect whether Rx is support current audio format */
2618 for (i = 0; i < pRXCap->AUD_count; i++) {
2619 if (pRXCap->RxAudioCap[i].audio_format_code == cmd)
2620 audio_check = 1;
2621 }
2622 /* sink don't support current audio mode */
2623 if ((!audio_check) && (cmd != CT_PCM)) {
2624 pr_info("Sink not support this audio format %lu\n",
2625 cmd);
2626 hdmitx_device.HWOp.CntlConfig(&hdmitx_device,
2627 CONF_AUDIO_MUTE_OP, AUDIO_MUTE);
2628 hdmitx_device.audio_param_update_flag = 0;
2629 }
2630 }
2631 if (hdmitx_device.audio_param_update_flag == 0)
2632 hdmi_print(INF, AUD "no update\n");
2633 else
2634 hdmitx_device.audio_notify_flag = 1;
2635
2636
2637 if ((!hdmi_audio_off_flag) &&
2638 (hdmitx_device.audio_param_update_flag)) {
2639 /* plug-in & update audio param */
2640 if (hdmitx_device.hpd_state == 1) {
2641 hdmitx_set_audio(&hdmitx_device,
2642 &(hdmitx_device.cur_audio_param), hdmi_ch);
2643 if ((hdmitx_device.audio_notify_flag == 1) ||
2644 (hdmitx_device.audio_step == 1)) {
2645 hdmitx_device.audio_notify_flag = 0;
2646 hdmitx_device.audio_step = 0;
2647 }
2648 hdmitx_device.audio_param_update_flag = 0;
2649 hdmi_print(INF, AUD "set audio param\n");
2650 }
2651 }
2652
2653
2654 return 0;
2655}
2656
2657struct i2c_client *i2c_edid_client;
2658
2659static void hdmitx_get_edid(struct hdmitx_dev *hdev)
2660{
2661 mutex_lock(&getedid_mutex);
2662 /* TODO hdmitx_edid_ram_buffer_clear(hdev); */
2663 hdev->HWOp.CntlDDC(hdev, DDC_RESET_EDID, 0);
2664 hdev->HWOp.CntlDDC(hdev, DDC_PIN_MUX_OP, PIN_MUX);
2665 /* start reading edid frist time */
2666 hdev->HWOp.CntlDDC(hdev, DDC_EDID_READ_DATA, 0);
2667 hdev->HWOp.CntlDDC(hdev, DDC_EDID_GET_DATA, 0);
2668 /* If EDID is not correct at first time, then retry */
2669 if (!check_dvi_hdmi_edid_valid(hdev->EDID_buf)) {
2670 msleep(100);
2671 /* start reading edid second time */
2672 hdev->HWOp.CntlDDC(hdev, DDC_EDID_READ_DATA, 0);
2673 hdev->HWOp.CntlDDC(hdev, DDC_EDID_GET_DATA, 1);
2674 }
2675 hdmitx_edid_clear(hdev);
2676 hdmitx_edid_parse(hdev);
2677 hdmitx_edid_buf_compare_print(hdev);
2678 mutex_unlock(&getedid_mutex);
2679}
2680
2681static int get_downstream_hdcp_ver(void)
2682{
2683 /* if TX don't have HDCP22 key, skip RX hdcp22 ver */
2684 if (hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
2685 DDC_HDCP_22_LSTORE, 0) == 0)
2686 goto next;
2687 if (hdcp_rd_hdcp22_ver())
2688 return 22;
2689next:
2690 /* if (hdcp_rd_hdcp14_ver()) */
2691 return 14;
2692}
2693
2694
2695static void hdmitx_rxsense_process(struct work_struct *work)
2696{
2697 int sense;
2698 struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
2699 struct hdmitx_dev, work_rxsense);
2700
2701 sense = hdev->HWOp.CntlMisc(hdev, MISC_TMDS_RXSENSE, 0);
2702 extcon_set_state_sync(hdmitx_excton_rxsense, EXTCON_DISP_HDMI, sense);
2703 queue_delayed_work(hdev->rxsense_wq, &hdev->work_rxsense, HZ);
2704}
2705
2706static void hdmitx_hpd_plugin_handler(struct work_struct *work)
2707{
2708 char bksv_buf[5];
2709 struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
2710 struct hdmitx_dev, work_hpd_plugin);
2711
2712 if (!(hdev->hdmitx_event & (HDMI_TX_HPD_PLUGIN)))
2713 return;
2714 if (hdev->rxsense_policy) {
2715 cancel_delayed_work(&hdev->work_rxsense);
2716 queue_delayed_work(hdev->rxsense_wq, &hdev->work_rxsense, 0);
2717 while (!(hdmitx_excton_rxsense->state))
2718 msleep_interruptible(1000);
2719 }
2720 mutex_lock(&setclk_mutex);
2721 pr_info("hdmitx: plugin\n");
2722 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGIN;
2723 /* start reading E-EDID */
2724 if (hdev->repeater_tx)
2725 rx_repeat_hpd_state(1);
2726 hdmitx_get_edid(hdev);
2727 mutex_lock(&getedid_mutex);
2728 hdev->HWOp.CntlMisc(hdev, MISC_I2C_REACTIVE, 0);
2729 mutex_unlock(&getedid_mutex);
2730 if (hdev->repeater_tx) {
2731 if (check_fbc_special(&hdev->EDID_buf[0])
2732 || check_fbc_special(&hdev->EDID_buf1[0]))
2733 rx_set_repeater_support(0);
2734 else
2735 rx_set_repeater_support(1);
2736 rx_repeat_hdcp_ver(get_downstream_hdcp_ver());
2737 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_GET_BKSV,
2738 (unsigned long int)bksv_buf);
2739 rx_set_receive_hdcp(bksv_buf, 1, 1, 0, 0);
2740 }
2741 set_disp_mode_auto();
2742 hdmitx_set_audio(hdev, &(hdev->cur_audio_param), hdmi_ch);
2743 hdev->hpd_state = 1;
2744 hdmitx_notify_hpd(hdev->hpd_state);
2745
2746 extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 1);
2747
2748 mutex_unlock(&setclk_mutex);
2749}
2750
2751static void clear_hdr_info(struct hdmitx_dev *hdev)
2752{
2753 struct vinfo_s *info = get_current_vinfo();
2754
2755 if (info) {
2756 info->hdr_info.hdr_support = 0;
2757 info->hdr_info.lumi_max = 0;
2758 info->hdr_info.lumi_avg = 0;
2759 info->hdr_info.lumi_min = 0;
2760 pr_info("hdmitx: clear RX hdr info\n");
2761 }
2762}
2763
2764static void hdmitx_aud_hpd_plug_handler(struct work_struct *work)
2765{
2766 int st;
2767 struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
2768 struct hdmitx_dev, work_aud_hpd_plug);
2769
2770 st = hdev->HWOp.CntlMisc(hdev, MISC_HPD_GPI_ST, 0);
2771 pr_info("hdmitx_aud_hpd_plug_handler state:%d\n", st);
2772 extcon_set_state_sync(hdmitx_excton_audio, EXTCON_DISP_HDMI, st);
2773}
2774
2775static void hdmitx_hpd_plugout_handler(struct work_struct *work)
2776{
2777 struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
2778 struct hdmitx_dev, work_hpd_plugout);
2779
2780 if (!(hdev->hdmitx_event & (HDMI_TX_HPD_PLUGOUT)))
2781 return;
2782 hdev->hdcp_mode = 0;
2783 hdev->hdcp_bcaps_repeater = 0;
2784 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_MUX_INIT, 1);
2785 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_OP, HDCP14_OFF);
2786 mutex_lock(&setclk_mutex);
2787 pr_info("hdmitx: plugout\n");
2788 if (!!(hdev->HWOp.CntlMisc(hdev, MISC_HPD_GPI_ST, 0))) {
2789 pr_info("hdmitx: hpd gpi high\n");
2790 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
2791 mutex_unlock(&setclk_mutex);
2792 return;
2793 }
2794 hdev->ready = 0;
2795 if (hdev->repeater_tx)
2796 rx_repeat_hpd_state(0);
2797 hdev->HWOp.CntlConfig(hdev, CONF_CLR_AVI_PACKET, 0);
2798 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_MUX_INIT, 1);
2799 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_OP, HDCP14_OFF);
2800 hdev->HWOp.CntlMisc(hdev, MISC_TMDS_PHY_OP, TMDS_PHY_DISABLE);
2801 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
2802 hdev->HWOp.CntlMisc(hdev, MISC_ESM_RESET, 0);
2803 clear_hdr_info(hdev);
2804 hdmitx_edid_clear(hdev);
2805 hdmitx_edid_ram_buffer_clear(hdev);
2806 hdev->hpd_state = 0;
2807 hdmitx_notify_hpd(hdev->hpd_state);
2808 extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
2809 mutex_unlock(&setclk_mutex);
2810}
2811
2812static void hdmitx_internal_intr_handler(struct work_struct *work)
2813{
2814 struct hdmitx_dev *hdev = container_of((struct work_struct *)work,
2815 struct hdmitx_dev, work_internal_intr);
2816
2817 hdev->HWOp.DebugFun(hdev, "dumpintr");
2818}
2819
2820int get_hpd_state(void)
2821{
2822 int ret;
2823
2824 mutex_lock(&setclk_mutex);
2825 ret = hdmitx_device.hpd_state;
2826 mutex_unlock(&setclk_mutex);
2827
2828 return ret;
2829}
2830EXPORT_SYMBOL(get_hpd_state);
2831
2832/******************************
2833 * hdmitx kernel task
2834 *******************************/
2835int tv_audio_support(int type, struct rx_cap *pRXCap)
2836{
2837 int i, audio_check = 0;
2838
2839 for (i = 0; i < pRXCap->AUD_count; i++) {
2840 if (pRXCap->RxAudioCap[i].audio_format_code == type)
2841 audio_check = 1;
2842 }
2843 return audio_check;
2844}
2845
2846static int hdmi_task_handle(void *data)
2847{
2848 struct hdmitx_dev *hdmitx_device = (struct hdmitx_dev *)data;
2849
2850 hdmitx_extcon_hdmi->state = !!(hdmitx_device->HWOp.CntlMisc(
2851 hdmitx_device, MISC_HPD_GPI_ST, 0));
2852 hdmitx_device->hpd_state = hdmitx_extcon_hdmi->state;
2853 hdmitx_notify_hpd(hdmitx_device->hpd_state);
2854 extcon_set_state_sync(hdmitx_excton_power, EXTCON_DISP_HDMI,
2855 hdmitx_device->hpd_state);
2856 INIT_WORK(&hdmitx_device->work_hdr, hdr_work_func);
2857
2858/* When init hdmi, clear the hdmitx module edid ram and edid buffer. */
2859 hdmitx_edid_ram_buffer_clear(hdmitx_device);
2860
2861 hdmitx_device->hdmi_wq = alloc_workqueue(DEVICE_NAME,
2862 WQ_HIGHPRI | WQ_CPU_INTENSIVE, 0);
2863 INIT_DELAYED_WORK(&hdmitx_device->work_hpd_plugin,
2864 hdmitx_hpd_plugin_handler);
2865 INIT_DELAYED_WORK(&hdmitx_device->work_hpd_plugout,
2866 hdmitx_hpd_plugout_handler);
2867 INIT_DELAYED_WORK(&hdmitx_device->work_aud_hpd_plug,
2868 hdmitx_aud_hpd_plug_handler);
2869 INIT_WORK(&hdmitx_device->work_internal_intr,
2870 hdmitx_internal_intr_handler);
2871
2872 /* for rx sense feature */
2873 hdmitx_device->rxsense_wq = alloc_workqueue(hdmitx_excton_rxsense->name,
2874 WQ_SYSFS | WQ_FREEZABLE, 0);
2875 INIT_DELAYED_WORK(&hdmitx_device->work_rxsense, hdmitx_rxsense_process);
2876
2877 hdmitx_device->tx_aud_cfg = 1; /* default audio configure is on */
2878
2879 hdmitx_device->HWOp.SetupIRQ(hdmitx_device);
2880
2881 /* Trigger */
2882 hdmitx_device->HWOp.CntlMisc(hdmitx_device, MISC_HPD_MUX_OP, PIN_UNMUX);
2883 mdelay(20);
2884 hdmitx_device->HWOp.CntlMisc(hdmitx_device, MISC_HPD_MUX_OP, PIN_MUX);
2885
2886 hdmi_init = 1;
2887 return 0;
2888}
2889
2890/* Linux */
2891/*****************************
2892 * hdmitx driver file_operations
2893 *
2894 ******************************/
2895static int amhdmitx_open(struct inode *node, struct file *file)
2896{
2897 struct hdmitx_dev *hdmitx_in_devp;
2898
2899 /* Get the per-device structure that contains this cdev */
2900 hdmitx_in_devp = container_of(node->i_cdev, struct hdmitx_dev, cdev);
2901 file->private_data = hdmitx_in_devp;
2902
2903 return 0;
2904
2905}
2906
2907
2908static int amhdmitx_release(struct inode *node, struct file *file)
2909{
2910 /* struct hdmitx_dev *hdmitx_in_devp = file->private_data; */
2911
2912 /* Reset file pointer */
2913
2914 /* Release some other fields */
2915 /* ... */
2916 return 0;
2917}
2918
2919static const struct file_operations amhdmitx_fops = {
2920 .owner = THIS_MODULE,
2921 .open = amhdmitx_open,
2922 .release = amhdmitx_release,
2923/* .ioctl = amhdmitx_ioctl, */
2924};
2925
2926struct hdmitx_dev *get_hdmitx_device(void)
2927{
2928 return &hdmitx_device;
2929}
2930EXPORT_SYMBOL(get_hdmitx_device);
2931
2932static int get_dt_vend_init_data(struct device_node *np,
2933 struct vendor_info_data *vend)
2934{
2935 int ret;
2936
2937 ret = of_property_read_string(np, "vendor_name",
2938 (const char **)&(vend->vendor_name));
2939 if (ret)
2940 hdmi_print(INF, SYS "not find vendor name\n");
2941
2942 ret = of_property_read_u32(np, "vendor_id", &(vend->vendor_id));
2943 if (ret)
2944 hdmi_print(INF, SYS "not find vendor id\n");
2945
2946 ret = of_property_read_string(np, "product_desc",
2947 (const char **)&(vend->product_desc));
2948 if (ret)
2949 hdmi_print(INF, SYS "not find product desc\n");
2950 return 0;
2951}
2952
2953static void hdmitx_init_fmt_attr(struct hdmitx_dev *hdev, char *attr)
2954{
2955 memset(attr, 0, sizeof(fmt_attr));
2956 if ((hdev->para->cd == COLORDEPTH_RESERVED) &&
2957 (hdev->para->cs == COLORSPACE_RESERVED)) {
2958 strcpy(fmt_attr, "default");
2959 } else {
2960 switch (hdev->para->cs) {
2961 case COLORSPACE_RGB444:
2962 memcpy(fmt_attr, "rgb,", 4);
2963 break;
2964 case COLORSPACE_YUV422:
2965 memcpy(fmt_attr, "422,", 4);
2966 break;
2967 case COLORSPACE_YUV444:
2968 memcpy(fmt_attr, "444,", 4);
2969 break;
2970 case COLORSPACE_YUV420:
2971 memcpy(fmt_attr, "420,", 4);
2972 break;
2973 default:
2974 break;
2975 }
2976 switch (hdev->para->cd) {
2977 case COLORDEPTH_24B:
2978 strcat(fmt_attr, "8bit");
2979 break;
2980 case COLORDEPTH_30B:
2981 strcat(fmt_attr, "10bit");
2982 break;
2983 case COLORDEPTH_36B:
2984 strcat(fmt_attr, "12bit");
2985 break;
2986 case COLORDEPTH_48B:
2987 strcat(fmt_attr, "16bit");
2988 break;
2989 default:
2990 break;
2991 }
2992 }
2993}
2994
2995static void hdmi_init_chip_type(void)
2996{
2997 /* auto detect chip_type for registers ioremap */
2998 switch (get_cpu_type()) {
2999 case MESON_CPU_MAJOR_ID_TXLX:
3000 hdmitx_device.chip_type = 1;
3001 break;
3002 default:
3003 break;
3004 }
3005
3006 pr_info("hdmitx: %s: %d\n", __func__, hdmitx_device.chip_type);
3007}
3008
3009/* for notify to cec */
3010static BLOCKING_NOTIFIER_HEAD(hdmitx_event_notify_list);
3011int hdmitx_event_notifier_regist(struct notifier_block *nb)
3012{
3013 int ret;
3014
3015 ret = blocking_notifier_chain_register(&hdmitx_event_notify_list, nb);
3016 /* update status when register */
3017 if (!ret && nb && nb->notifier_call) {
3018 hdmitx_notify_hpd(hdmitx_device.hpd_state);
3019 if (hdmitx_device.physical_addr != 0xffff)
3020 hdmitx_event_notify(HDMITX_PHY_ADDR_VALID,
3021 &hdmitx_device.physical_addr);
3022 }
3023
3024 return ret;
3025}
3026EXPORT_SYMBOL(hdmitx_event_notifier_regist);
3027
3028int hdmitx_event_notifier_unregist(struct notifier_block *nb)
3029{
3030 int ret;
3031
3032 ret = blocking_notifier_chain_unregister(&hdmitx_event_notify_list, nb);
3033
3034 return ret;
3035}
3036EXPORT_SYMBOL(hdmitx_event_notifier_unregist);
3037
3038void hdmitx_event_notify(unsigned long state, void *arg)
3039{
3040 blocking_notifier_call_chain(&hdmitx_event_notify_list, state, arg);
3041}
3042
3043void hdmitx_hdcp_status(int hdmi_authenticated)
3044{
3045 extcon_set_state_sync(hdmitx_excton_hdcp, EXTCON_DISP_HDMI,
3046 hdmi_authenticated);
3047}
3048
3049void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
3050{
3051 struct extcon_dev *edev;
3052 int ret;
3053
3054 /*hdmitx extcon hdmi*/
3055 edev = extcon_dev_allocate(hdmi_cable);
3056 if (IS_ERR(edev)) {
3057 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon hdmi\n");
3058 return;
3059 }
3060 edev->dev.parent = dev;
3061 edev->name = "hdmitx_extcon_hdmi";
3062 dev_set_name(&edev->dev, "hdmi");
3063 ret = extcon_dev_register(edev);
3064 if (ret < 0) {
3065 hdmi_print(IMP, SYS "failed to register hdmitx extcon hdmi\n");
3066 return;
3067 }
3068 hdmitx_extcon_hdmi = edev;
3069
3070 /*hdmitx extcon audio*/
3071 edev = extcon_dev_allocate(hdmi_cable);
3072 if (IS_ERR(edev)) {
3073 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon audio\n");
3074 return;
3075 }
3076
3077 edev->dev.parent = dev;
3078 edev->name = "hdmitx_excton_audio";
3079 dev_set_name(&edev->dev, "hdmi_audio");
3080 ret = extcon_dev_register(edev);
3081 if (ret < 0) {
3082 hdmi_print(IMP, SYS "failed to register hdmitx extcon audio\n");
3083 return;
3084 }
3085 hdmitx_excton_audio = edev;
3086
3087 /*hdmitx extcon power*/
3088 edev = extcon_dev_allocate(hdmi_cable);
3089 if (IS_ERR(edev)) {
3090 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon power\n");
3091 return;
3092 }
3093
3094 edev->dev.parent = dev;
3095 edev->name = "hdmitx_excton_power";
3096 dev_set_name(&edev->dev, "hdmi_power");
3097 ret = extcon_dev_register(edev);
3098 if (ret < 0) {
3099 hdmi_print(IMP, SYS "failed to register extcon power\n");
3100 return;
3101 }
3102 hdmitx_excton_power = edev;
3103
3104 /*hdmitx extcon hdr*/
3105 edev = extcon_dev_allocate(hdmi_cable);
3106 if (IS_ERR(edev)) {
3107 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon hdr\n");
3108 return;
3109 }
3110
3111 edev->dev.parent = dev;
3112 edev->name = "hdmitx_excton_hdr";
3113 dev_set_name(&edev->dev, "hdmi_hdr");
3114 ret = extcon_dev_register(edev);
3115 if (ret < 0) {
3116 hdmi_print(IMP, SYS "failed to register hdmitx extcon hdr\n");
3117 return;
3118 }
3119 hdmitx_excton_hdr = edev;
3120
3121 /*hdmitx extcon rxsense*/
3122 edev = extcon_dev_allocate(hdmi_cable);
3123 if (IS_ERR(edev)) {
3124 hdmi_print(IMP, SYS "failed to allocate extcon rxsense\n");
3125 return;
3126 }
3127
3128 edev->dev.parent = dev;
3129 edev->name = "hdmitx_excton_rxsense";
3130 dev_set_name(&edev->dev, "hdmi_rxsense");
3131 ret = extcon_dev_register(edev);
3132 if (ret < 0) {
3133 hdmi_print(IMP, SYS "failed to register extcon rxsense\n");
3134 return;
3135 }
3136 hdmitx_excton_rxsense = edev;
3137
3138 /*hdmitx extcon hdcp*/
3139 edev = extcon_dev_allocate(hdmi_cable);
3140 if (IS_ERR(edev)) {
3141 hdmi_print(IMP, SYS "failed to allocate extcon hdcp\n");
3142 return;
3143 }
3144
3145 edev->dev.parent = dev;
3146 edev->name = "hdmitx_excton_hdcp";
3147 dev_set_name(&edev->dev, "hdcp");
3148 ret = extcon_dev_register(edev);
3149 if (ret < 0) {
3150 hdmi_print(IMP, SYS "failed to register extcon hdcp\n");
3151 return;
3152 }
3153 hdmitx_excton_hdcp = edev;
3154}
3155
3156static int amhdmitx_device_init(struct hdmitx_dev *hdmi_dev)
3157{
3158 if (hdmi_dev == NULL)
3159 return 1;
3160
3161 hdmi_dev->hdtx_dev = NULL;
3162
3163 return 0;
3164}
3165
3166static int amhdmitx_probe(struct platform_device *pdev)
3167{
3168 int r, ret = 0;
3169 struct pinctrl *p;
3170 struct device *dev;
3171
3172#ifdef CONFIG_OF
3173 int val;
3174 phandle phandle;
3175 struct device_node *init_data;
3176#endif
3177
3178 hdmi_print(IMP, SYS "amhdmitx_init\n");
3179 hdmi_print(IMP, SYS "Ver: %s\n", HDMITX_VER);
3180
3181 amhdmitx_device_init(&hdmitx_device);
3182
3183 hdmitx_device.hdtx_dev = &pdev->dev;
3184 hdmitx_device.physical_addr = 0xffff;
3185 /* init para for NULL protection */
3186 hdmitx_device.para = hdmi_get_fmt_name("invalid", fmt_attr);
3187 hdmi_print(IMP, SYS "amhdmitx_probe\n");
3188
3189 r = alloc_chrdev_region(&hdmitx_id, 0, HDMI_TX_COUNT,
3190 DEVICE_NAME);
3191
3192 hdmitx_class = class_create(THIS_MODULE, DEVICE_NAME);
3193 if (IS_ERR(hdmitx_class)) {
3194 unregister_chrdev_region(hdmitx_id, HDMI_TX_COUNT);
3195 return -1;
3196 /* return PTR_ERR(aoe_class); */
3197 }
3198
3199 hdmitx_device.unplug_powerdown = 0;
3200 hdmitx_device.vic_count = 0;
3201 hdmitx_device.auth_process_timer = 0;
3202 hdmitx_device.force_audio_flag = 0;
3203 hdmitx_device.hdcp_mode = 0;
3204 hdmitx_device.ready = 0;
3205 /* no 1.000/1.001 modes by default */
3206 hdmitx_device.frac_rate_policy = 0;
3207 hdmitx_device.rxsense_policy = 0; /* no RxSense by default */
3208
3209#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
3210 register_early_suspend(&hdmitx_early_suspend_handler);
3211#endif
3212 hdmitx_device.nb.notifier_call = hdmitx_reboot_notifier;
3213 register_reboot_notifier(&hdmitx_device.nb);
3214 if ((init_flag&INIT_FLAG_POWERDOWN) && (hpdmode == 2))
3215 hdmitx_device.mux_hpd_if_pin_high_flag = 0;
3216 else
3217 hdmitx_device.mux_hpd_if_pin_high_flag = 1;
3218 hdmitx_device.audio_param_update_flag = 0;
3219 cdev_init(&(hdmitx_device.cdev), &amhdmitx_fops);
3220 hdmitx_device.cdev.owner = THIS_MODULE;
3221 cdev_add(&(hdmitx_device.cdev), hdmitx_id, HDMI_TX_COUNT);
3222
3223 dev = device_create(hdmitx_class, NULL, hdmitx_id, NULL,
3224 "amhdmitx%d", 0); /* kernel>=2.6.27 */
3225
3226 if (dev == NULL) {
3227 hdmi_print(ERR, SYS "device_create create error\n");
3228 class_destroy(hdmitx_class);
3229 r = -EEXIST;
3230 return r;
3231 }
3232 hdmitx_device.hdtx_dev = dev;
3233 ret = device_create_file(dev, &dev_attr_disp_mode);
3234 ret = device_create_file(dev, &dev_attr_attr);
3235 ret = device_create_file(dev, &dev_attr_aud_mode);
3236 ret = device_create_file(dev, &dev_attr_aud_mute);
3237 ret = device_create_file(dev, &dev_attr_vid_mute);
3238 ret = device_create_file(dev, &dev_attr_edid);
3239 ret = device_create_file(dev, &dev_attr_rawedid);
3240 ret = device_create_file(dev, &dev_attr_sink_type);
3241 ret = device_create_file(dev, &dev_attr_edid_parsing);
3242 ret = device_create_file(dev, &dev_attr_config);
3243 ret = device_create_file(dev, &dev_attr_debug);
3244 ret = device_create_file(dev, &dev_attr_disp_cap);
3245 ret = device_create_file(dev, &dev_attr_preferred_mode);
3246 ret = device_create_file(dev, &dev_attr_disp_cap_3d);
3247 ret = device_create_file(dev, &dev_attr_aud_cap);
3248 ret = device_create_file(dev, &dev_attr_hdr_cap);
3249 ret = device_create_file(dev, &dev_attr_dv_cap);
3250 ret = device_create_file(dev, &dev_attr_aud_ch);
3251 ret = device_create_file(dev, &dev_attr_aud_output_chs);
3252 ret = device_create_file(dev, &dev_attr_avmute);
3253 ret = device_create_file(dev, &dev_attr_vic);
3254 ret = device_create_file(dev, &dev_attr_phy);
3255 ret = device_create_file(dev, &dev_attr_frac_rate_policy);
3256 ret = device_create_file(dev, &dev_attr_rxsense_policy);
3257 ret = device_create_file(dev, &dev_attr_hdcp_clkdis);
3258 ret = device_create_file(dev, &dev_attr_hdcp_pwr);
3259 ret = device_create_file(dev, &dev_attr_hdcp_ksv_info);
3260 ret = device_create_file(dev, &dev_attr_hdcp_ver);
3261 ret = device_create_file(dev, &dev_attr_hdcp_byp);
3262 ret = device_create_file(dev, &dev_attr_hdcp_mode);
3263 ret = device_create_file(dev, &dev_attr_hdcp_repeater);
3264 ret = device_create_file(dev, &dev_attr_hdcp22_type);
3265 ret = device_create_file(dev, &dev_attr_hdcp22_base);
3266 ret = device_create_file(dev, &dev_attr_hdcp_lstore);
3267 ret = device_create_file(dev, &dev_attr_div40);
3268 ret = device_create_file(dev, &dev_attr_hdcp_ctrl);
3269 ret = device_create_file(dev, &dev_attr_hpd_state);
3270 ret = device_create_file(dev, &dev_attr_hdmi_init);
3271 ret = device_create_file(dev, &dev_attr_ready);
3272 ret = device_create_file(dev, &dev_attr_support_3d);
3273 ret = device_create_file(dev, &dev_attr_dc_cap);
3274 ret = device_create_file(dev, &dev_attr_valid_mode);
3275
3276 vout_register_server(&hdmitx_server);
3277#ifdef CONFIG_AMLOGIC_SND_SOC
3278 aout_register_client(&hdmitx_notifier_nb_a);
3279#else
3280 r = r ? (long int)&hdmitx_notifier_nb_a :
3281 (long int)&hdmitx_notifier_nb_a;
3282#endif
3283
3284 hdmi_init_chip_type();
3285#ifdef CONFIG_OF
3286 if (pdev->dev.of_node) {
3287 memset(&hdmitx_device.config_data, 0,
3288 sizeof(struct hdmi_config_platform_data));
3289/* HPD pinctrl */
3290 if (of_get_property(pdev->dev.of_node, "pinctrl-names", NULL)) {
3291 ret = of_property_read_string_index(pdev->dev.of_node,
3292 "pinctrl-names", 0, &hdmitx_device.hpd_pin);
3293 if (!ret)
3294 p = devm_pinctrl_get_select(&pdev->dev,
3295 hdmitx_device.hpd_pin);
3296 }
3297/* DDC pinctrl */
3298 if (of_get_property(pdev->dev.of_node, "pinctrl-names", NULL)) {
3299 ret = of_property_read_string_index(pdev->dev.of_node,
3300 "pinctrl-names", 1, &hdmitx_device.ddc_pin);
3301 if (!ret)
3302 p = devm_pinctrl_get_select(&pdev->dev,
3303 hdmitx_device.ddc_pin);
3304 }
3305
3306/* Get vendor information */
3307 ret = of_property_read_u32(pdev->dev.of_node,
3308 "vend-data", &val);
3309 if (ret)
3310 hdmi_print(INF, SYS "not find match init-data\n");
3311 if (ret == 0) {
3312 phandle = val;
3313 init_data = of_find_node_by_phandle(phandle);
3314 if (!init_data)
3315 hdmi_print(INF, SYS "not find device node\n");
3316 hdmitx_device.config_data.vend_data = kzalloc(
3317 sizeof(struct vendor_info_data), GFP_KERNEL);
3318 if (!hdmitx_device.config_data.vend_data)
3319 hdmi_print(INF, SYS
3320 "can not get vend_data dat\n");
3321 ret = get_dt_vend_init_data(init_data,
3322 hdmitx_device.config_data.vend_data);
3323 if (ret)
3324 hdmi_print(INF, SYS "not find vend_init_data\n");
3325 }
3326/* Get power control */
3327 ret = of_property_read_u32(pdev->dev.of_node,
3328 "pwr-ctrl", &val);
3329 if (ret)
3330 hdmi_print(INF, SYS "not find match pwr-ctl\n");
3331 if (ret == 0) {
3332 phandle = val;
3333 init_data = of_find_node_by_phandle(phandle);
3334 if (!init_data)
3335 hdmi_print(INF, SYS "not find device node\n");
3336 hdmitx_device.config_data.pwr_ctl = kzalloc((sizeof(
3337 struct hdmi_pwr_ctl)) * HDMI_TX_PWR_CTRL_NUM,
3338 GFP_KERNEL);
3339 if (!hdmitx_device.config_data.pwr_ctl)
3340 hdmi_print(INF, SYS"can not get pwr_ctl mem\n");
3341 memset(hdmitx_device.config_data.pwr_ctl, 0,
3342 sizeof(struct hdmi_pwr_ctl));
3343 if (ret)
3344 hdmi_print(INF, SYS "not find pwr_ctl\n");
3345 }
3346 }
3347
3348#else
3349 hdmi_pdata = pdev->dev.platform_data;
3350 if (!hdmi_pdata) {
3351 hdmi_print(INF, SYS "not get platform data\n");
3352 r = -ENOENT;
3353 } else {
3354 hdmi_print(INF, SYS "get hdmi platform data\n");
3355 }
3356#endif
3357 hdmitx_device.irq_hpd = platform_get_irq_byname(pdev, "hdmitx_hpd");
3358 if (hdmitx_device.irq_hpd == -ENXIO) {
3359 pr_err("%s: ERROR: hdmitx hpd irq No not found\n",
3360 __func__);
3361 return -ENXIO;
3362 }
3363 pr_info("hdmitx hpd irq = %d\n", hdmitx_device.irq_hpd);
3364
3365 hdmitx_extcon_register(pdev, dev);
3366
3367 hdmitx_init_parameters(&hdmitx_device.hdmi_info);
3368 HDMITX_Meson_Init(&hdmitx_device);
3369 hdmitx_init_fmt_attr(&hdmitx_device, fmt_attr);
3370 pr_info("hdmitx: attr %s\n", fmt_attr);
3371 hdmitx_device.task = kthread_run(hdmi_task_handle,
3372 &hdmitx_device, "kthread_hdmi");
3373 return r;
3374}
3375
3376static int amhdmitx_remove(struct platform_device *pdev)
3377{
3378 struct device *dev = hdmitx_device.hdtx_dev;
3379
3380 cancel_work_sync(&hdmitx_device.work_hdr);
3381
3382 if (hdmitx_device.HWOp.UnInit)
3383 hdmitx_device.HWOp.UnInit(&hdmitx_device);
3384 hdmitx_device.hpd_event = 0xff;
3385 kthread_stop(hdmitx_device.task);
3386 vout_unregister_server(&hdmitx_server);
3387#ifdef CONFIG_AMLOGIC_SND_SOC
3388 aout_unregister_client(&hdmitx_notifier_nb_a);
3389#endif
3390
3391 /* Remove the cdev */
3392 device_remove_file(dev, &dev_attr_disp_mode);
3393 device_remove_file(dev, &dev_attr_attr);
3394 device_remove_file(dev, &dev_attr_aud_mode);
3395 device_remove_file(dev, &dev_attr_aud_mute);
3396 device_remove_file(dev, &dev_attr_vid_mute);
3397 device_remove_file(dev, &dev_attr_edid);
3398 device_remove_file(dev, &dev_attr_rawedid);
3399 device_remove_file(dev, &dev_attr_sink_type);
3400 device_remove_file(dev, &dev_attr_edid_parsing);
3401 device_remove_file(dev, &dev_attr_config);
3402 device_remove_file(dev, &dev_attr_debug);
3403 device_remove_file(dev, &dev_attr_disp_cap);
3404 device_remove_file(dev, &dev_attr_preferred_mode);
3405 device_remove_file(dev, &dev_attr_disp_cap_3d);
3406 device_remove_file(dev, &dev_attr_hdr_cap);
3407 device_remove_file(dev, &dev_attr_dv_cap);
3408 device_remove_file(dev, &dev_attr_dc_cap);
3409 device_remove_file(dev, &dev_attr_valid_mode);
3410 device_remove_file(dev, &dev_attr_hpd_state);
3411 device_remove_file(dev, &dev_attr_hdmi_init);
3412 device_remove_file(dev, &dev_attr_ready);
3413 device_remove_file(dev, &dev_attr_support_3d);
3414 device_remove_file(dev, &dev_attr_avmute);
3415 device_remove_file(dev, &dev_attr_vic);
3416 device_remove_file(dev, &dev_attr_frac_rate_policy);
3417 device_remove_file(dev, &dev_attr_rxsense_policy);
3418 device_remove_file(dev, &dev_attr_hdcp_pwr);
3419 device_remove_file(dev, &dev_attr_aud_output_chs);
3420 device_remove_file(dev, &dev_attr_div40);
3421 device_remove_file(dev, &dev_attr_hdcp_repeater);
3422 device_remove_file(dev, &dev_attr_hdcp22_type);
3423 device_remove_file(dev, &dev_attr_hdcp22_base);
3424
3425 cdev_del(&hdmitx_device.cdev);
3426
3427 device_destroy(hdmitx_class, hdmitx_id);
3428
3429 class_destroy(hdmitx_class);
3430
3431/* TODO */
3432/* kfree(hdmi_pdata->phy_data); */
3433/* kfree(hdmi_pdata); */
3434
3435 unregister_chrdev_region(hdmitx_id, HDMI_TX_COUNT);
3436 return 0;
3437}
3438
3439#ifdef CONFIG_PM
3440static int amhdmitx_suspend(struct platform_device *pdev,
3441 pm_message_t state)
3442{
3443 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
3444 DDC_RESET_HDCP, 0);
3445 pr_info("amhdmitx: suspend and reset hdcp\n");
3446 return 0;
3447}
3448
3449static int amhdmitx_resume(struct platform_device *pdev)
3450{
3451 pr_info("amhdmitx: resume module %d\n", __LINE__);
3452 return 0;
3453}
3454#endif
3455
3456#ifdef CONFIG_INSTABOOT
3457static unsigned char __nosavedata EDID_buf_save[EDID_MAX_BLOCK * 128];
3458static unsigned char __nosavedata EDID_buf1_save[EDID_MAX_BLOCK * 128];
3459static unsigned char __nosavedata EDID_hash_save[20];
3460static struct rx_cap __nosavedata RXCap_save;
3461static struct hdmitx_info __nosavedata hdmi_info_save;
3462
3463static void save_device_param(void)
3464{
3465 memcpy(EDID_buf_save, hdmitx_device.EDID_buf, EDID_MAX_BLOCK * 128);
3466 memcpy(EDID_buf1_save, hdmitx_device.EDID_buf1, EDID_MAX_BLOCK * 128);
3467 memcpy(EDID_hash_save, hdmitx_device.EDID_hash, 20);
3468 memcpy(&RXCap_save, &hdmitx_device.RXCap, sizeof(struct rx_cap));
3469 memcpy(&hdmi_info_save, &hdmitx_device.hdmi_info,
3470 sizeof(struct hdmitx_info));
3471}
3472
3473static void restore_device_param(void)
3474{
3475 memcpy(hdmitx_device.EDID_buf, EDID_buf_save, EDID_MAX_BLOCK * 128);
3476 memcpy(hdmitx_device.EDID_buf1, EDID_buf1_save, EDID_MAX_BLOCK * 128);
3477 memcpy(hdmitx_device.EDID_hash, EDID_hash_save, 20);
3478 memcpy(&hdmitx_device.RXCap, &RXCap_save, sizeof(struct rx_cap));
3479 memcpy(&hdmitx_device.hdmi_info, &hdmi_info_save,
3480 sizeof(struct hdmitx_info));
3481}
3482
3483static int amhdmitx_realdata_save(void)
3484{
3485 save_device_param();
3486 return 0;
3487}
3488
3489static void amhdmitx_realdata_restore(void)
3490{
3491 restore_device_param();
3492}
3493
3494static struct instaboot_realdata_ops amhdmitx_realdata_ops = {
3495 .save = amhdmitx_realdata_save,
3496 .restore = amhdmitx_realdata_restore,
3497};
3498
3499static int amhdmitx_restore(struct device *dev)
3500{
3501 int current_hdmi_state = !!(hdmitx_device.HWOp.CntlMisc(&hdmitx_device,
3502 MISC_HPD_GPI_ST, 0));
3503 char *vout_mode = get_vout_mode_internal();
3504
3505 if (strstr(vout_mode, "cvbs") && current_hdmi_state == 1) {
3506 mutex_lock(&setclk_mutex);
3507 hdmitx_extcon_hdmi->state = 0;
3508 hdmitx_device.hpd_state = hdmitx_extcon_hdmi->state;
3509 hdmitx_notify_hpd(hdmitx_device.hpd_state);
3510 mutex_unlock(&setclk_mutex);
3511 pr_info("resend hdmi plug in event\n");
3512 hdmitx_device.hdmitx_event |= HDMI_TX_HPD_PLUGIN;
3513 hdmitx_device.hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
3514 PREPARE_DELAYED_WORK(&hdmitx_device.work_hpd_plugin,
3515 hdmitx_hpd_plugin_handler);
3516 queue_delayed_work(hdmitx_device.hdmi_wq,
3517 &hdmitx_device.work_hpd_plugin, 2 * HZ);
3518 } else {
3519 mutex_lock(&setclk_mutex);
3520 hdmitx_extcon_hdmi->state = current_hdmi_state;
3521 hdmitx_device.hpd_state = hdmitx_extcon_hdmi->state;
3522 hdmitx_notify_hpd(hdmitx_device.hpd_state);
3523 mutex_unlock(&setclk_mutex);
3524 }
3525 return 0;
3526}
3527static int amhdmitx_pm_suspend(struct device *dev)
3528{
3529 struct platform_device *pdev = to_platform_device(dev);
3530
3531 return amhdmitx_suspend(pdev, PMSG_SUSPEND);
3532}
3533static int amhdmitx_pm_resume(struct device *dev)
3534{
3535 struct platform_device *pdev = to_platform_device(dev);
3536
3537 return amhdmitx_resume(pdev);
3538}
3539static const struct dev_pm_ops amhdmitx_pm = {
3540 .restore = amhdmitx_restore,
3541 .suspend = amhdmitx_pm_suspend,
3542 .resume = amhdmitx_pm_resume,
3543};
3544#endif
3545
3546#ifdef CONFIG_OF
3547static const struct of_device_id meson_amhdmitx_dt_match[] = {
3548 {
3549 .compatible = "amlogic, amhdmitx",
3550 },
3551 {},
3552};
3553#else
3554#define meson_amhdmitx_dt_match NULL
3555#endif
3556static struct platform_driver amhdmitx_driver = {
3557 .probe = amhdmitx_probe,
3558 .remove = amhdmitx_remove,
3559#ifdef CONFIG_PM
3560 .suspend = amhdmitx_suspend,
3561 .resume = amhdmitx_resume,
3562#endif
3563 .driver = {
3564 .name = DEVICE_NAME,
3565 .owner = THIS_MODULE,
3566 .of_match_table = meson_amhdmitx_dt_match,
3567#ifdef CONFIG_HIBERNATION
3568 .pm = &amhdmitx_pm,
3569#endif
3570 }
3571};
3572
3573static int __init amhdmitx_init(void)
3574{
3575 if (init_flag&INIT_FLAG_NOT_LOAD)
3576 return 0;
3577
3578 if (platform_driver_register(&amhdmitx_driver)) {
3579 hdmi_print(ERR, SYS
3580 "failed to register amhdmitx module\n");
3581#if 0
3582 platform_device_del(amhdmi_tx_device);
3583 platform_device_put(amhdmi_tx_device);
3584#endif
3585 return -ENODEV;
3586 }
3587#ifdef CONFIG_INSTABOOT
3588 INIT_LIST_HEAD(&amhdmitx_realdata_ops.node);
3589 register_instaboot_realdata_ops(&amhdmitx_realdata_ops);
3590#endif
3591 return 0;
3592}
3593
3594
3595
3596
3597static void __exit amhdmitx_exit(void)
3598{
3599 hdmi_print(INF, SYS "amhdmitx_exit\n");
3600 platform_driver_unregister(&amhdmitx_driver);
3601/* \\ platform_device_unregister(amhdmi_tx_device); */
3602/* \\ amhdmi_tx_device = NULL; */
3603#ifdef CONFIG_INSTABOOT
3604 unregister_instaboot_realdata_ops(&amhdmitx_realdata_ops);
3605#endif
3606}
3607
3608/* module_init(amhdmitx_init); */
3609subsys_initcall(amhdmitx_init);
3610module_exit(amhdmitx_exit);
3611
3612MODULE_DESCRIPTION("AMLOGIC HDMI TX driver");
3613MODULE_LICENSE("GPL");
3614MODULE_VERSION("1.0.0");
3615
3616/* besides characters defined in separator, '\"' are used as separator;
3617 * and any characters in '\"' will not act as separator
3618 */
3619static char *next_token_ex(char *separator, char *buf, unsigned int size,
3620 unsigned int offset, unsigned int *token_len,
3621 unsigned int *token_offset)
3622{
3623 char *pToken = NULL;
3624 char last_separator = 0;
3625 char trans_char_flag = 0;
3626
3627 if (buf) {
3628 for (; offset < size; offset++) {
3629 int ii = 0;
3630 char ch;
3631
3632 if (buf[offset] == '\\') {
3633 trans_char_flag = 1;
3634 continue;
3635 }
3636 while (((ch = separator[ii++]) != buf[offset]) && (ch))
3637 ;
3638 if (ch) {
3639 if (!pToken) {
3640 continue;
3641 } else {
3642 if (last_separator != '"') {
3643 *token_len = (unsigned int)
3644 (buf + offset - pToken);
3645 *token_offset = offset;
3646 return pToken;
3647 }
3648 }
3649 } else if (!pToken) {
3650 if (trans_char_flag && (buf[offset] == '"'))
3651 last_separator = buf[offset];
3652 pToken = &buf[offset];
3653 } else if ((trans_char_flag && (buf[offset] == '"'))
3654 && (last_separator == '"')) {
3655 *token_len = (unsigned int)(buf + offset - pToken - 2);
3656 *token_offset = offset + 1;
3657 return pToken + 1;
3658 }
3659 trans_char_flag = 0;
3660 }
3661 if (pToken) {
3662 *token_len = (unsigned int)(buf + offset - pToken);
3663 *token_offset = offset;
3664 }
3665 }
3666 return pToken;
3667}
3668
3669static int __init hdmitx_boot_para_setup(char *s)
3670{
3671 char separator[] = {' ', ',', ';', 0x0};
3672 char *token;
3673 unsigned int token_len, token_offset, offset = 0;
3674 int size = strlen(s);
3675
3676 do {
3677 token = next_token_ex(separator, s, size, offset,
3678 &token_len, &token_offset);
3679 if (token) {
3680 if ((token_len == 3)
3681 && (strncmp(token, "off", token_len) == 0)) {
3682 init_flag |= INIT_FLAG_NOT_LOAD;
3683 }
3684 }
3685 offset = token_offset;
3686 } while (token);
3687 return 0;
3688}
3689
3690__setup("hdmitx=", hdmitx_boot_para_setup);
3691
3692MODULE_PARM_DESC(hdmi_detect_when_booting, "\n hdmi_detect_when_booting\n");
3693module_param(hdmi_detect_when_booting, int, 0664);
3694
3695MODULE_PARM_DESC(hdmi_prbs_mode, "\n hdmi_prbs_mode\n");
3696module_param(hdmi_prbs_mode, int, 0664);
3697
3698MODULE_PARM_DESC(debug_level, "\n debug_level\n");
3699module_param(debug_level, int, 0664);
3700