summaryrefslogtreecommitdiff
path: root/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c (plain)
blob: ebf95ab85bb7e97060c219d0a6fb95c109a40a16
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 extcon_set_state_sync(hdmitx_excton_audio, EXTCON_DISP_HDMI, 1);
2748
2749 mutex_unlock(&setclk_mutex);
2750}
2751
2752static void clear_hdr_info(struct hdmitx_dev *hdev)
2753{
2754 struct vinfo_s *info = get_current_vinfo();
2755
2756 if (info) {
2757 info->hdr_info.hdr_support = 0;
2758 info->hdr_info.lumi_max = 0;
2759 info->hdr_info.lumi_avg = 0;
2760 info->hdr_info.lumi_min = 0;
2761 pr_info("hdmitx: clear RX hdr info\n");
2762 }
2763}
2764
2765static void hdmitx_hpd_plugout_handler(struct work_struct *work)
2766{
2767 struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
2768 struct hdmitx_dev, work_hpd_plugout);
2769
2770 if (!(hdev->hdmitx_event & (HDMI_TX_HPD_PLUGOUT)))
2771 return;
2772 hdev->hdcp_mode = 0;
2773 hdev->hdcp_bcaps_repeater = 0;
2774 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_MUX_INIT, 1);
2775 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_OP, HDCP14_OFF);
2776 mutex_lock(&setclk_mutex);
2777 pr_info("hdmitx: plugout\n");
2778 if (!!(hdev->HWOp.CntlMisc(hdev, MISC_HPD_GPI_ST, 0))) {
2779 pr_info("hdmitx: hpd gpi high\n");
2780 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
2781 mutex_unlock(&setclk_mutex);
2782 return;
2783 }
2784 hdev->ready = 0;
2785 if (hdev->repeater_tx)
2786 rx_repeat_hpd_state(0);
2787 hdev->HWOp.CntlConfig(hdev, CONF_CLR_AVI_PACKET, 0);
2788 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_MUX_INIT, 1);
2789 hdev->HWOp.CntlDDC(hdev, DDC_HDCP_OP, HDCP14_OFF);
2790 hdev->HWOp.CntlMisc(hdev, MISC_TMDS_PHY_OP, TMDS_PHY_DISABLE);
2791 hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
2792 hdev->HWOp.CntlMisc(hdev, MISC_ESM_RESET, 0);
2793 clear_hdr_info(hdev);
2794 hdmitx_edid_clear(hdev);
2795 hdmitx_edid_ram_buffer_clear(hdev);
2796 hdev->hpd_state = 0;
2797 hdmitx_notify_hpd(hdev->hpd_state);
2798
2799 extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
2800 extcon_set_state_sync(hdmitx_excton_audio, EXTCON_DISP_HDMI, 0);
2801 mutex_unlock(&setclk_mutex);
2802}
2803
2804static void hdmitx_internal_intr_handler(struct work_struct *work)
2805{
2806 struct hdmitx_dev *hdev = container_of((struct work_struct *)work,
2807 struct hdmitx_dev, work_internal_intr);
2808
2809 hdev->HWOp.DebugFun(hdev, "dumpintr");
2810}
2811
2812int get_hpd_state(void)
2813{
2814 int ret;
2815
2816 mutex_lock(&setclk_mutex);
2817 ret = hdmitx_device.hpd_state;
2818 mutex_unlock(&setclk_mutex);
2819
2820 return ret;
2821}
2822EXPORT_SYMBOL(get_hpd_state);
2823
2824/******************************
2825 * hdmitx kernel task
2826 *******************************/
2827int tv_audio_support(int type, struct rx_cap *pRXCap)
2828{
2829 int i, audio_check = 0;
2830
2831 for (i = 0; i < pRXCap->AUD_count; i++) {
2832 if (pRXCap->RxAudioCap[i].audio_format_code == type)
2833 audio_check = 1;
2834 }
2835 return audio_check;
2836}
2837
2838static int hdmi_task_handle(void *data)
2839{
2840 struct hdmitx_dev *hdmitx_device = (struct hdmitx_dev *)data;
2841
2842 hdmitx_extcon_hdmi->state = !!(hdmitx_device->HWOp.CntlMisc(
2843 hdmitx_device, MISC_HPD_GPI_ST, 0));
2844 hdmitx_device->hpd_state = hdmitx_extcon_hdmi->state;
2845 hdmitx_notify_hpd(hdmitx_device->hpd_state);
2846 extcon_set_state_sync(hdmitx_excton_power, EXTCON_DISP_HDMI,
2847 hdmitx_device->hpd_state);
2848 INIT_WORK(&hdmitx_device->work_hdr, hdr_work_func);
2849
2850/* When init hdmi, clear the hdmitx module edid ram and edid buffer. */
2851 hdmitx_edid_ram_buffer_clear(hdmitx_device);
2852
2853 hdmitx_device->hdmi_wq = alloc_workqueue(DEVICE_NAME,
2854 WQ_HIGHPRI | WQ_CPU_INTENSIVE, 0);
2855 INIT_DELAYED_WORK(&hdmitx_device->work_hpd_plugin,
2856 hdmitx_hpd_plugin_handler);
2857 INIT_DELAYED_WORK(&hdmitx_device->work_hpd_plugout,
2858 hdmitx_hpd_plugout_handler);
2859 INIT_WORK(&hdmitx_device->work_internal_intr,
2860 hdmitx_internal_intr_handler);
2861
2862 /* for rx sense feature */
2863 hdmitx_device->rxsense_wq = alloc_workqueue(hdmitx_excton_rxsense->name,
2864 WQ_SYSFS | WQ_FREEZABLE, 0);
2865 INIT_DELAYED_WORK(&hdmitx_device->work_rxsense, hdmitx_rxsense_process);
2866
2867 hdmitx_device->tx_aud_cfg = 1; /* default audio configure is on */
2868
2869 hdmitx_device->HWOp.SetupIRQ(hdmitx_device);
2870
2871 /* Trigger */
2872 hdmitx_device->HWOp.CntlMisc(hdmitx_device, MISC_HPD_MUX_OP, PIN_UNMUX);
2873 mdelay(20);
2874 hdmitx_device->HWOp.CntlMisc(hdmitx_device, MISC_HPD_MUX_OP, PIN_MUX);
2875
2876 hdmi_init = 1;
2877 return 0;
2878}
2879
2880/* Linux */
2881/*****************************
2882 * hdmitx driver file_operations
2883 *
2884 ******************************/
2885static int amhdmitx_open(struct inode *node, struct file *file)
2886{
2887 struct hdmitx_dev *hdmitx_in_devp;
2888
2889 /* Get the per-device structure that contains this cdev */
2890 hdmitx_in_devp = container_of(node->i_cdev, struct hdmitx_dev, cdev);
2891 file->private_data = hdmitx_in_devp;
2892
2893 return 0;
2894
2895}
2896
2897
2898static int amhdmitx_release(struct inode *node, struct file *file)
2899{
2900 /* struct hdmitx_dev *hdmitx_in_devp = file->private_data; */
2901
2902 /* Reset file pointer */
2903
2904 /* Release some other fields */
2905 /* ... */
2906 return 0;
2907}
2908
2909static const struct file_operations amhdmitx_fops = {
2910 .owner = THIS_MODULE,
2911 .open = amhdmitx_open,
2912 .release = amhdmitx_release,
2913/* .ioctl = amhdmitx_ioctl, */
2914};
2915
2916struct hdmitx_dev *get_hdmitx_device(void)
2917{
2918 return &hdmitx_device;
2919}
2920EXPORT_SYMBOL(get_hdmitx_device);
2921
2922static int get_dt_vend_init_data(struct device_node *np,
2923 struct vendor_info_data *vend)
2924{
2925 int ret;
2926
2927 ret = of_property_read_string(np, "vendor_name",
2928 (const char **)&(vend->vendor_name));
2929 if (ret)
2930 hdmi_print(INF, SYS "not find vendor name\n");
2931
2932 ret = of_property_read_u32(np, "vendor_id", &(vend->vendor_id));
2933 if (ret)
2934 hdmi_print(INF, SYS "not find vendor id\n");
2935
2936 ret = of_property_read_string(np, "product_desc",
2937 (const char **)&(vend->product_desc));
2938 if (ret)
2939 hdmi_print(INF, SYS "not find product desc\n");
2940 return 0;
2941}
2942
2943static void hdmitx_init_fmt_attr(struct hdmitx_dev *hdev, char *attr)
2944{
2945 memset(attr, 0, sizeof(fmt_attr));
2946 if ((hdev->para->cd == COLORDEPTH_RESERVED) &&
2947 (hdev->para->cs == COLORSPACE_RESERVED)) {
2948 strcpy(fmt_attr, "default");
2949 } else {
2950 switch (hdev->para->cs) {
2951 case COLORSPACE_RGB444:
2952 memcpy(fmt_attr, "rgb,", 4);
2953 break;
2954 case COLORSPACE_YUV422:
2955 memcpy(fmt_attr, "422,", 4);
2956 break;
2957 case COLORSPACE_YUV444:
2958 memcpy(fmt_attr, "444,", 4);
2959 break;
2960 case COLORSPACE_YUV420:
2961 memcpy(fmt_attr, "420,", 4);
2962 break;
2963 default:
2964 break;
2965 }
2966 switch (hdev->para->cd) {
2967 case COLORDEPTH_24B:
2968 strcat(fmt_attr, "8bit");
2969 break;
2970 case COLORDEPTH_30B:
2971 strcat(fmt_attr, "10bit");
2972 break;
2973 case COLORDEPTH_36B:
2974 strcat(fmt_attr, "12bit");
2975 break;
2976 case COLORDEPTH_48B:
2977 strcat(fmt_attr, "16bit");
2978 break;
2979 default:
2980 break;
2981 }
2982 }
2983}
2984
2985static void hdmi_init_chip_type(void)
2986{
2987 /* auto detect chip_type for registers ioremap */
2988 switch (get_cpu_type()) {
2989 case MESON_CPU_MAJOR_ID_TXLX:
2990 hdmitx_device.chip_type = 1;
2991 break;
2992 default:
2993 break;
2994 }
2995
2996 pr_info("hdmitx: %s: %d\n", __func__, hdmitx_device.chip_type);
2997}
2998
2999/* for notify to cec */
3000static BLOCKING_NOTIFIER_HEAD(hdmitx_event_notify_list);
3001int hdmitx_event_notifier_regist(struct notifier_block *nb)
3002{
3003 int ret;
3004
3005 ret = blocking_notifier_chain_register(&hdmitx_event_notify_list, nb);
3006 /* update status when register */
3007 if (!ret && nb && nb->notifier_call) {
3008 hdmitx_notify_hpd(hdmitx_device.hpd_state);
3009 if (hdmitx_device.physical_addr != 0xffff)
3010 hdmitx_event_notify(HDMITX_PHY_ADDR_VALID,
3011 &hdmitx_device.physical_addr);
3012 }
3013
3014 return ret;
3015}
3016EXPORT_SYMBOL(hdmitx_event_notifier_regist);
3017
3018int hdmitx_event_notifier_unregist(struct notifier_block *nb)
3019{
3020 int ret;
3021
3022 ret = blocking_notifier_chain_unregister(&hdmitx_event_notify_list, nb);
3023
3024 return ret;
3025}
3026EXPORT_SYMBOL(hdmitx_event_notifier_unregist);
3027
3028void hdmitx_event_notify(unsigned long state, void *arg)
3029{
3030 blocking_notifier_call_chain(&hdmitx_event_notify_list, state, arg);
3031}
3032
3033void hdmitx_hdcp_status(int hdmi_authenticated)
3034{
3035 extcon_set_state_sync(hdmitx_excton_hdcp, EXTCON_DISP_HDMI,
3036 hdmi_authenticated);
3037}
3038
3039void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
3040{
3041 struct extcon_dev *edev;
3042 int ret;
3043
3044 /*hdmitx extcon hdmi*/
3045 edev = extcon_dev_allocate(hdmi_cable);
3046 if (IS_ERR(edev)) {
3047 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon hdmi\n");
3048 return;
3049 }
3050 edev->dev.parent = dev;
3051 edev->name = "hdmitx_extcon_hdmi";
3052 dev_set_name(&edev->dev, "hdmi");
3053 ret = extcon_dev_register(edev);
3054 if (ret < 0) {
3055 hdmi_print(IMP, SYS "failed to register hdmitx extcon hdmi\n");
3056 return;
3057 }
3058 hdmitx_extcon_hdmi = edev;
3059
3060 /*hdmitx extcon audio*/
3061 edev = extcon_dev_allocate(hdmi_cable);
3062 if (IS_ERR(edev)) {
3063 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon audio\n");
3064 return;
3065 }
3066
3067 edev->dev.parent = dev;
3068 edev->name = "hdmitx_excton_audio";
3069 dev_set_name(&edev->dev, "hdmi_audio");
3070 ret = extcon_dev_register(edev);
3071 if (ret < 0) {
3072 hdmi_print(IMP, SYS "failed to register hdmitx extcon audio\n");
3073 return;
3074 }
3075 hdmitx_excton_audio = edev;
3076
3077 /*hdmitx extcon power*/
3078 edev = extcon_dev_allocate(hdmi_cable);
3079 if (IS_ERR(edev)) {
3080 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon power\n");
3081 return;
3082 }
3083
3084 edev->dev.parent = dev;
3085 edev->name = "hdmitx_excton_power";
3086 dev_set_name(&edev->dev, "hdmi_power");
3087 ret = extcon_dev_register(edev);
3088 if (ret < 0) {
3089 hdmi_print(IMP, SYS "failed to register extcon power\n");
3090 return;
3091 }
3092 hdmitx_excton_power = edev;
3093
3094 /*hdmitx extcon hdr*/
3095 edev = extcon_dev_allocate(hdmi_cable);
3096 if (IS_ERR(edev)) {
3097 hdmi_print(IMP, SYS "failed to allocate hdmitx extcon hdr\n");
3098 return;
3099 }
3100
3101 edev->dev.parent = dev;
3102 edev->name = "hdmitx_excton_hdr";
3103 dev_set_name(&edev->dev, "hdmi_hdr");
3104 ret = extcon_dev_register(edev);
3105 if (ret < 0) {
3106 hdmi_print(IMP, SYS "failed to register hdmitx extcon hdr\n");
3107 return;
3108 }
3109 hdmitx_excton_hdr = edev;
3110
3111 /*hdmitx extcon rxsense*/
3112 edev = extcon_dev_allocate(hdmi_cable);
3113 if (IS_ERR(edev)) {
3114 hdmi_print(IMP, SYS "failed to allocate extcon rxsense\n");
3115 return;
3116 }
3117
3118 edev->dev.parent = dev;
3119 edev->name = "hdmitx_excton_rxsense";
3120 dev_set_name(&edev->dev, "hdmi_rxsense");
3121 ret = extcon_dev_register(edev);
3122 if (ret < 0) {
3123 hdmi_print(IMP, SYS "failed to register extcon rxsense\n");
3124 return;
3125 }
3126 hdmitx_excton_rxsense = edev;
3127
3128 /*hdmitx extcon hdcp*/
3129 edev = extcon_dev_allocate(hdmi_cable);
3130 if (IS_ERR(edev)) {
3131 hdmi_print(IMP, SYS "failed to allocate extcon hdcp\n");
3132 return;
3133 }
3134
3135 edev->dev.parent = dev;
3136 edev->name = "hdmitx_excton_hdcp";
3137 dev_set_name(&edev->dev, "hdcp");
3138 ret = extcon_dev_register(edev);
3139 if (ret < 0) {
3140 hdmi_print(IMP, SYS "failed to register extcon hdcp\n");
3141 return;
3142 }
3143 hdmitx_excton_hdcp = edev;
3144}
3145
3146static int amhdmitx_device_init(struct hdmitx_dev *hdmi_dev)
3147{
3148 if (hdmi_dev == NULL)
3149 return 1;
3150
3151 hdmi_dev->hdtx_dev = NULL;
3152
3153 return 0;
3154}
3155
3156static int amhdmitx_probe(struct platform_device *pdev)
3157{
3158 int r, ret = 0;
3159 struct pinctrl *p;
3160 struct device *dev;
3161
3162#ifdef CONFIG_OF
3163 int val;
3164 phandle phandle;
3165 struct device_node *init_data;
3166#endif
3167
3168 hdmi_print(IMP, SYS "amhdmitx_init\n");
3169 hdmi_print(IMP, SYS "Ver: %s\n", HDMITX_VER);
3170
3171 amhdmitx_device_init(&hdmitx_device);
3172
3173 hdmitx_device.hdtx_dev = &pdev->dev;
3174 hdmitx_device.physical_addr = 0xffff;
3175 /* init para for NULL protection */
3176 hdmitx_device.para = hdmi_get_fmt_name("invalid", fmt_attr);
3177 hdmi_print(IMP, SYS "amhdmitx_probe\n");
3178
3179 r = alloc_chrdev_region(&hdmitx_id, 0, HDMI_TX_COUNT,
3180 DEVICE_NAME);
3181
3182 hdmitx_class = class_create(THIS_MODULE, DEVICE_NAME);
3183 if (IS_ERR(hdmitx_class)) {
3184 unregister_chrdev_region(hdmitx_id, HDMI_TX_COUNT);
3185 return -1;
3186 /* return PTR_ERR(aoe_class); */
3187 }
3188
3189 hdmitx_device.unplug_powerdown = 0;
3190 hdmitx_device.vic_count = 0;
3191 hdmitx_device.auth_process_timer = 0;
3192 hdmitx_device.force_audio_flag = 0;
3193 hdmitx_device.hdcp_mode = 0;
3194 hdmitx_device.ready = 0;
3195 /* no 1.000/1.001 modes by default */
3196 hdmitx_device.frac_rate_policy = 0;
3197 hdmitx_device.rxsense_policy = 0; /* no RxSense by default */
3198
3199#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
3200 register_early_suspend(&hdmitx_early_suspend_handler);
3201#endif
3202 hdmitx_device.nb.notifier_call = hdmitx_reboot_notifier;
3203 register_reboot_notifier(&hdmitx_device.nb);
3204 if ((init_flag&INIT_FLAG_POWERDOWN) && (hpdmode == 2))
3205 hdmitx_device.mux_hpd_if_pin_high_flag = 0;
3206 else
3207 hdmitx_device.mux_hpd_if_pin_high_flag = 1;
3208 hdmitx_device.audio_param_update_flag = 0;
3209 cdev_init(&(hdmitx_device.cdev), &amhdmitx_fops);
3210 hdmitx_device.cdev.owner = THIS_MODULE;
3211 cdev_add(&(hdmitx_device.cdev), hdmitx_id, HDMI_TX_COUNT);
3212
3213 dev = device_create(hdmitx_class, NULL, hdmitx_id, NULL,
3214 "amhdmitx%d", 0); /* kernel>=2.6.27 */
3215
3216 if (dev == NULL) {
3217 hdmi_print(ERR, SYS "device_create create error\n");
3218 class_destroy(hdmitx_class);
3219 r = -EEXIST;
3220 return r;
3221 }
3222 hdmitx_device.hdtx_dev = dev;
3223 ret = device_create_file(dev, &dev_attr_disp_mode);
3224 ret = device_create_file(dev, &dev_attr_attr);
3225 ret = device_create_file(dev, &dev_attr_aud_mode);
3226 ret = device_create_file(dev, &dev_attr_aud_mute);
3227 ret = device_create_file(dev, &dev_attr_vid_mute);
3228 ret = device_create_file(dev, &dev_attr_edid);
3229 ret = device_create_file(dev, &dev_attr_rawedid);
3230 ret = device_create_file(dev, &dev_attr_sink_type);
3231 ret = device_create_file(dev, &dev_attr_edid_parsing);
3232 ret = device_create_file(dev, &dev_attr_config);
3233 ret = device_create_file(dev, &dev_attr_debug);
3234 ret = device_create_file(dev, &dev_attr_disp_cap);
3235 ret = device_create_file(dev, &dev_attr_preferred_mode);
3236 ret = device_create_file(dev, &dev_attr_disp_cap_3d);
3237 ret = device_create_file(dev, &dev_attr_aud_cap);
3238 ret = device_create_file(dev, &dev_attr_hdr_cap);
3239 ret = device_create_file(dev, &dev_attr_dv_cap);
3240 ret = device_create_file(dev, &dev_attr_aud_ch);
3241 ret = device_create_file(dev, &dev_attr_aud_output_chs);
3242 ret = device_create_file(dev, &dev_attr_avmute);
3243 ret = device_create_file(dev, &dev_attr_vic);
3244 ret = device_create_file(dev, &dev_attr_phy);
3245 ret = device_create_file(dev, &dev_attr_frac_rate_policy);
3246 ret = device_create_file(dev, &dev_attr_rxsense_policy);
3247 ret = device_create_file(dev, &dev_attr_hdcp_clkdis);
3248 ret = device_create_file(dev, &dev_attr_hdcp_pwr);
3249 ret = device_create_file(dev, &dev_attr_hdcp_ksv_info);
3250 ret = device_create_file(dev, &dev_attr_hdcp_ver);
3251 ret = device_create_file(dev, &dev_attr_hdcp_byp);
3252 ret = device_create_file(dev, &dev_attr_hdcp_mode);
3253 ret = device_create_file(dev, &dev_attr_hdcp_repeater);
3254 ret = device_create_file(dev, &dev_attr_hdcp22_type);
3255 ret = device_create_file(dev, &dev_attr_hdcp22_base);
3256 ret = device_create_file(dev, &dev_attr_hdcp_lstore);
3257 ret = device_create_file(dev, &dev_attr_div40);
3258 ret = device_create_file(dev, &dev_attr_hdcp_ctrl);
3259 ret = device_create_file(dev, &dev_attr_hpd_state);
3260 ret = device_create_file(dev, &dev_attr_hdmi_init);
3261 ret = device_create_file(dev, &dev_attr_ready);
3262 ret = device_create_file(dev, &dev_attr_support_3d);
3263 ret = device_create_file(dev, &dev_attr_dc_cap);
3264 ret = device_create_file(dev, &dev_attr_valid_mode);
3265
3266 vout_register_server(&hdmitx_server);
3267#ifdef CONFIG_AMLOGIC_SND_SOC
3268 aout_register_client(&hdmitx_notifier_nb_a);
3269#else
3270 r = r ? (long int)&hdmitx_notifier_nb_a :
3271 (long int)&hdmitx_notifier_nb_a;
3272#endif
3273
3274 hdmi_init_chip_type();
3275#ifdef CONFIG_OF
3276 if (pdev->dev.of_node) {
3277 memset(&hdmitx_device.config_data, 0,
3278 sizeof(struct hdmi_config_platform_data));
3279/* HPD pinctrl */
3280 if (of_get_property(pdev->dev.of_node, "pinctrl-names", NULL)) {
3281 ret = of_property_read_string_index(pdev->dev.of_node,
3282 "pinctrl-names", 0, &hdmitx_device.hpd_pin);
3283 if (!ret)
3284 p = devm_pinctrl_get_select(&pdev->dev,
3285 hdmitx_device.hpd_pin);
3286 }
3287/* DDC pinctrl */
3288 if (of_get_property(pdev->dev.of_node, "pinctrl-names", NULL)) {
3289 ret = of_property_read_string_index(pdev->dev.of_node,
3290 "pinctrl-names", 1, &hdmitx_device.ddc_pin);
3291 if (!ret)
3292 p = devm_pinctrl_get_select(&pdev->dev,
3293 hdmitx_device.ddc_pin);
3294 }
3295
3296/* Get vendor information */
3297 ret = of_property_read_u32(pdev->dev.of_node,
3298 "vend-data", &val);
3299 if (ret)
3300 hdmi_print(INF, SYS "not find match init-data\n");
3301 if (ret == 0) {
3302 phandle = val;
3303 init_data = of_find_node_by_phandle(phandle);
3304 if (!init_data)
3305 hdmi_print(INF, SYS "not find device node\n");
3306 hdmitx_device.config_data.vend_data = kzalloc(
3307 sizeof(struct vendor_info_data), GFP_KERNEL);
3308 if (!hdmitx_device.config_data.vend_data)
3309 hdmi_print(INF, SYS
3310 "can not get vend_data dat\n");
3311 ret = get_dt_vend_init_data(init_data,
3312 hdmitx_device.config_data.vend_data);
3313 if (ret)
3314 hdmi_print(INF, SYS "not find vend_init_data\n");
3315 }
3316/* Get power control */
3317 ret = of_property_read_u32(pdev->dev.of_node,
3318 "pwr-ctrl", &val);
3319 if (ret)
3320 hdmi_print(INF, SYS "not find match pwr-ctl\n");
3321 if (ret == 0) {
3322 phandle = val;
3323 init_data = of_find_node_by_phandle(phandle);
3324 if (!init_data)
3325 hdmi_print(INF, SYS "not find device node\n");
3326 hdmitx_device.config_data.pwr_ctl = kzalloc((sizeof(
3327 struct hdmi_pwr_ctl)) * HDMI_TX_PWR_CTRL_NUM,
3328 GFP_KERNEL);
3329 if (!hdmitx_device.config_data.pwr_ctl)
3330 hdmi_print(INF, SYS"can not get pwr_ctl mem\n");
3331 memset(hdmitx_device.config_data.pwr_ctl, 0,
3332 sizeof(struct hdmi_pwr_ctl));
3333 if (ret)
3334 hdmi_print(INF, SYS "not find pwr_ctl\n");
3335 }
3336 }
3337
3338#else
3339 hdmi_pdata = pdev->dev.platform_data;
3340 if (!hdmi_pdata) {
3341 hdmi_print(INF, SYS "not get platform data\n");
3342 r = -ENOENT;
3343 } else {
3344 hdmi_print(INF, SYS "get hdmi platform data\n");
3345 }
3346#endif
3347 hdmitx_device.irq_hpd = platform_get_irq_byname(pdev, "hdmitx_hpd");
3348 if (hdmitx_device.irq_hpd == -ENXIO) {
3349 pr_err("%s: ERROR: hdmitx hpd irq No not found\n",
3350 __func__);
3351 return -ENXIO;
3352 }
3353 pr_info("hdmitx hpd irq = %d\n", hdmitx_device.irq_hpd);
3354
3355 hdmitx_extcon_register(pdev, dev);
3356
3357 hdmitx_init_parameters(&hdmitx_device.hdmi_info);
3358 HDMITX_Meson_Init(&hdmitx_device);
3359 hdmitx_init_fmt_attr(&hdmitx_device, fmt_attr);
3360 pr_info("hdmitx: attr %s\n", fmt_attr);
3361 hdmitx_device.task = kthread_run(hdmi_task_handle,
3362 &hdmitx_device, "kthread_hdmi");
3363 return r;
3364}
3365
3366static int amhdmitx_remove(struct platform_device *pdev)
3367{
3368 struct device *dev = hdmitx_device.hdtx_dev;
3369
3370 cancel_work_sync(&hdmitx_device.work_hdr);
3371
3372 if (hdmitx_device.HWOp.UnInit)
3373 hdmitx_device.HWOp.UnInit(&hdmitx_device);
3374 hdmitx_device.hpd_event = 0xff;
3375 kthread_stop(hdmitx_device.task);
3376 vout_unregister_server(&hdmitx_server);
3377#ifdef CONFIG_AMLOGIC_SND_SOC
3378 aout_unregister_client(&hdmitx_notifier_nb_a);
3379#endif
3380
3381 /* Remove the cdev */
3382 device_remove_file(dev, &dev_attr_disp_mode);
3383 device_remove_file(dev, &dev_attr_attr);
3384 device_remove_file(dev, &dev_attr_aud_mode);
3385 device_remove_file(dev, &dev_attr_aud_mute);
3386 device_remove_file(dev, &dev_attr_vid_mute);
3387 device_remove_file(dev, &dev_attr_edid);
3388 device_remove_file(dev, &dev_attr_rawedid);
3389 device_remove_file(dev, &dev_attr_sink_type);
3390 device_remove_file(dev, &dev_attr_edid_parsing);
3391 device_remove_file(dev, &dev_attr_config);
3392 device_remove_file(dev, &dev_attr_debug);
3393 device_remove_file(dev, &dev_attr_disp_cap);
3394 device_remove_file(dev, &dev_attr_preferred_mode);
3395 device_remove_file(dev, &dev_attr_disp_cap_3d);
3396 device_remove_file(dev, &dev_attr_hdr_cap);
3397 device_remove_file(dev, &dev_attr_dv_cap);
3398 device_remove_file(dev, &dev_attr_dc_cap);
3399 device_remove_file(dev, &dev_attr_valid_mode);
3400 device_remove_file(dev, &dev_attr_hpd_state);
3401 device_remove_file(dev, &dev_attr_hdmi_init);
3402 device_remove_file(dev, &dev_attr_ready);
3403 device_remove_file(dev, &dev_attr_support_3d);
3404 device_remove_file(dev, &dev_attr_avmute);
3405 device_remove_file(dev, &dev_attr_vic);
3406 device_remove_file(dev, &dev_attr_frac_rate_policy);
3407 device_remove_file(dev, &dev_attr_rxsense_policy);
3408 device_remove_file(dev, &dev_attr_hdcp_pwr);
3409 device_remove_file(dev, &dev_attr_aud_output_chs);
3410 device_remove_file(dev, &dev_attr_div40);
3411 device_remove_file(dev, &dev_attr_hdcp_repeater);
3412 device_remove_file(dev, &dev_attr_hdcp22_type);
3413 device_remove_file(dev, &dev_attr_hdcp22_base);
3414
3415 cdev_del(&hdmitx_device.cdev);
3416
3417 device_destroy(hdmitx_class, hdmitx_id);
3418
3419 class_destroy(hdmitx_class);
3420
3421/* TODO */
3422/* kfree(hdmi_pdata->phy_data); */
3423/* kfree(hdmi_pdata); */
3424
3425 unregister_chrdev_region(hdmitx_id, HDMI_TX_COUNT);
3426 return 0;
3427}
3428
3429#ifdef CONFIG_PM
3430static int amhdmitx_suspend(struct platform_device *pdev,
3431 pm_message_t state)
3432{
3433 hdmitx_device.HWOp.CntlDDC(&hdmitx_device,
3434 DDC_RESET_HDCP, 0);
3435 pr_info("amhdmitx: suspend and reset hdcp\n");
3436 return 0;
3437}
3438
3439static int amhdmitx_resume(struct platform_device *pdev)
3440{
3441 pr_info("amhdmitx: resume module %d\n", __LINE__);
3442 return 0;
3443}
3444#endif
3445
3446#ifdef CONFIG_INSTABOOT
3447static unsigned char __nosavedata EDID_buf_save[EDID_MAX_BLOCK * 128];
3448static unsigned char __nosavedata EDID_buf1_save[EDID_MAX_BLOCK * 128];
3449static unsigned char __nosavedata EDID_hash_save[20];
3450static struct rx_cap __nosavedata RXCap_save;
3451static struct hdmitx_info __nosavedata hdmi_info_save;
3452
3453static void save_device_param(void)
3454{
3455 memcpy(EDID_buf_save, hdmitx_device.EDID_buf, EDID_MAX_BLOCK * 128);
3456 memcpy(EDID_buf1_save, hdmitx_device.EDID_buf1, EDID_MAX_BLOCK * 128);
3457 memcpy(EDID_hash_save, hdmitx_device.EDID_hash, 20);
3458 memcpy(&RXCap_save, &hdmitx_device.RXCap, sizeof(struct rx_cap));
3459 memcpy(&hdmi_info_save, &hdmitx_device.hdmi_info,
3460 sizeof(struct hdmitx_info));
3461}
3462
3463static void restore_device_param(void)
3464{
3465 memcpy(hdmitx_device.EDID_buf, EDID_buf_save, EDID_MAX_BLOCK * 128);
3466 memcpy(hdmitx_device.EDID_buf1, EDID_buf1_save, EDID_MAX_BLOCK * 128);
3467 memcpy(hdmitx_device.EDID_hash, EDID_hash_save, 20);
3468 memcpy(&hdmitx_device.RXCap, &RXCap_save, sizeof(struct rx_cap));
3469 memcpy(&hdmitx_device.hdmi_info, &hdmi_info_save,
3470 sizeof(struct hdmitx_info));
3471}
3472
3473static int amhdmitx_realdata_save(void)
3474{
3475 save_device_param();
3476 return 0;
3477}
3478
3479static void amhdmitx_realdata_restore(void)
3480{
3481 restore_device_param();
3482}
3483
3484static struct instaboot_realdata_ops amhdmitx_realdata_ops = {
3485 .save = amhdmitx_realdata_save,
3486 .restore = amhdmitx_realdata_restore,
3487};
3488
3489static int amhdmitx_restore(struct device *dev)
3490{
3491 int current_hdmi_state = !!(hdmitx_device.HWOp.CntlMisc(&hdmitx_device,
3492 MISC_HPD_GPI_ST, 0));
3493 char *vout_mode = get_vout_mode_internal();
3494
3495 if (strstr(vout_mode, "cvbs") && current_hdmi_state == 1) {
3496 mutex_lock(&setclk_mutex);
3497 hdmitx_extcon_hdmi->state = 0;
3498 hdmitx_device.hpd_state = hdmitx_extcon_hdmi->state;
3499 hdmitx_notify_hpd(hdmitx_device.hpd_state);
3500 mutex_unlock(&setclk_mutex);
3501 pr_info("resend hdmi plug in event\n");
3502 hdmitx_device.hdmitx_event |= HDMI_TX_HPD_PLUGIN;
3503 hdmitx_device.hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
3504 PREPARE_DELAYED_WORK(&hdmitx_device.work_hpd_plugin,
3505 hdmitx_hpd_plugin_handler);
3506 queue_delayed_work(hdmitx_device.hdmi_wq,
3507 &hdmitx_device.work_hpd_plugin, 2 * HZ);
3508 } else {
3509 mutex_lock(&setclk_mutex);
3510 hdmitx_extcon_hdmi->state = current_hdmi_state;
3511 hdmitx_device.hpd_state = hdmitx_extcon_hdmi->state;
3512 hdmitx_notify_hpd(hdmitx_device.hpd_state);
3513 mutex_unlock(&setclk_mutex);
3514 }
3515 return 0;
3516}
3517static int amhdmitx_pm_suspend(struct device *dev)
3518{
3519 struct platform_device *pdev = to_platform_device(dev);
3520
3521 return amhdmitx_suspend(pdev, PMSG_SUSPEND);
3522}
3523static int amhdmitx_pm_resume(struct device *dev)
3524{
3525 struct platform_device *pdev = to_platform_device(dev);
3526
3527 return amhdmitx_resume(pdev);
3528}
3529static const struct dev_pm_ops amhdmitx_pm = {
3530 .restore = amhdmitx_restore,
3531 .suspend = amhdmitx_pm_suspend,
3532 .resume = amhdmitx_pm_resume,
3533};
3534#endif
3535
3536#ifdef CONFIG_OF
3537static const struct of_device_id meson_amhdmitx_dt_match[] = {
3538 {
3539 .compatible = "amlogic, amhdmitx",
3540 },
3541 {},
3542};
3543#else
3544#define meson_amhdmitx_dt_match NULL
3545#endif
3546static struct platform_driver amhdmitx_driver = {
3547 .probe = amhdmitx_probe,
3548 .remove = amhdmitx_remove,
3549#ifdef CONFIG_PM
3550 .suspend = amhdmitx_suspend,
3551 .resume = amhdmitx_resume,
3552#endif
3553 .driver = {
3554 .name = DEVICE_NAME,
3555 .owner = THIS_MODULE,
3556 .of_match_table = meson_amhdmitx_dt_match,
3557#ifdef CONFIG_HIBERNATION
3558 .pm = &amhdmitx_pm,
3559#endif
3560 }
3561};
3562
3563static int __init amhdmitx_init(void)
3564{
3565 if (init_flag&INIT_FLAG_NOT_LOAD)
3566 return 0;
3567
3568 if (platform_driver_register(&amhdmitx_driver)) {
3569 hdmi_print(ERR, SYS
3570 "failed to register amhdmitx module\n");
3571#if 0
3572 platform_device_del(amhdmi_tx_device);
3573 platform_device_put(amhdmi_tx_device);
3574#endif
3575 return -ENODEV;
3576 }
3577#ifdef CONFIG_INSTABOOT
3578 INIT_LIST_HEAD(&amhdmitx_realdata_ops.node);
3579 register_instaboot_realdata_ops(&amhdmitx_realdata_ops);
3580#endif
3581 return 0;
3582}
3583
3584
3585
3586
3587static void __exit amhdmitx_exit(void)
3588{
3589 hdmi_print(INF, SYS "amhdmitx_exit\n");
3590 platform_driver_unregister(&amhdmitx_driver);
3591/* \\ platform_device_unregister(amhdmi_tx_device); */
3592/* \\ amhdmi_tx_device = NULL; */
3593#ifdef CONFIG_INSTABOOT
3594 unregister_instaboot_realdata_ops(&amhdmitx_realdata_ops);
3595#endif
3596}
3597
3598/* module_init(amhdmitx_init); */
3599subsys_initcall(amhdmitx_init);
3600module_exit(amhdmitx_exit);
3601
3602MODULE_DESCRIPTION("AMLOGIC HDMI TX driver");
3603MODULE_LICENSE("GPL");
3604MODULE_VERSION("1.0.0");
3605
3606/* besides characters defined in separator, '\"' are used as separator;
3607 * and any characters in '\"' will not act as separator
3608 */
3609static char *next_token_ex(char *separator, char *buf, unsigned int size,
3610 unsigned int offset, unsigned int *token_len,
3611 unsigned int *token_offset)
3612{
3613 char *pToken = NULL;
3614 char last_separator = 0;
3615 char trans_char_flag = 0;
3616
3617 if (buf) {
3618 for (; offset < size; offset++) {
3619 int ii = 0;
3620 char ch;
3621
3622 if (buf[offset] == '\\') {
3623 trans_char_flag = 1;
3624 continue;
3625 }
3626 while (((ch = separator[ii++]) != buf[offset]) && (ch))
3627 ;
3628 if (ch) {
3629 if (!pToken) {
3630 continue;
3631 } else {
3632 if (last_separator != '"') {
3633 *token_len = (unsigned int)
3634 (buf + offset - pToken);
3635 *token_offset = offset;
3636 return pToken;
3637 }
3638 }
3639 } else if (!pToken) {
3640 if (trans_char_flag && (buf[offset] == '"'))
3641 last_separator = buf[offset];
3642 pToken = &buf[offset];
3643 } else if ((trans_char_flag && (buf[offset] == '"'))
3644 && (last_separator == '"')) {
3645 *token_len = (unsigned int)(buf + offset - pToken - 2);
3646 *token_offset = offset + 1;
3647 return pToken + 1;
3648 }
3649 trans_char_flag = 0;
3650 }
3651 if (pToken) {
3652 *token_len = (unsigned int)(buf + offset - pToken);
3653 *token_offset = offset;
3654 }
3655 }
3656 return pToken;
3657}
3658
3659static int __init hdmitx_boot_para_setup(char *s)
3660{
3661 char separator[] = {' ', ',', ';', 0x0};
3662 char *token;
3663 unsigned int token_len, token_offset, offset = 0;
3664 int size = strlen(s);
3665
3666 do {
3667 token = next_token_ex(separator, s, size, offset,
3668 &token_len, &token_offset);
3669 if (token) {
3670 if ((token_len == 3)
3671 && (strncmp(token, "off", token_len) == 0)) {
3672 init_flag |= INIT_FLAG_NOT_LOAD;
3673 }
3674 }
3675 offset = token_offset;
3676 } while (token);
3677 return 0;
3678}
3679
3680__setup("hdmitx=", hdmitx_boot_para_setup);
3681
3682MODULE_PARM_DESC(hdmi_detect_when_booting, "\n hdmi_detect_when_booting\n");
3683module_param(hdmi_detect_when_booting, int, 0664);
3684
3685MODULE_PARM_DESC(hdmi_prbs_mode, "\n hdmi_prbs_mode\n");
3686module_param(hdmi_prbs_mode, int, 0664);
3687
3688MODULE_PARM_DESC(debug_level, "\n debug_level\n");
3689module_param(debug_level, int, 0664);
3690