summaryrefslogtreecommitdiff
authorEvoke Zhang <evoke.zhang@amlogic.com>2019-07-22 10:27:14 (GMT)
committer Shen Liu <shen.liu@amlogic.com>2020-05-27 06:04:10 (GMT)
commit6f878ef98ec345419a10d7a165fd13c2b317616c (patch)
treece00e93f07c35b91ae28e47006ce28a4b779c269
parent15fb89454bd0ad46d05d46cd22725e1bb165b6d7 (diff)
downloadcommon-6f878ef98ec345419a10d7a165fd13c2b317616c.zip
common-6f878ef98ec345419a10d7a165fd13c2b317616c.tar.gz
common-6f878ef98ec345419a10d7a165fd13c2b317616c.tar.bz2
vdac: optimize the vdac controlling [1/1]
PD#SWPL-8385 Problem: no cvbsout on ab311 Solution: 1.optimize the vdac controlling 2.enable cvbsout in ab311 dts Verify: ab311 Change-Id: Ib046e760eca1c9ad3ae30749c546aff538504b33 Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
Diffstat
-rw-r--r--MAINTAINERS5
-rw-r--r--arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts2
-rw-r--r--arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts2
-rw-r--r--drivers/amlogic/atv_demod/atv_demod_ops.c5
-rw-r--r--drivers/amlogic/media/dtv_demod/amlfrontend.c9
-rw-r--r--drivers/amlogic/media/dtv_demod/include/amlfrontend.h1
-rw-r--r--drivers/amlogic/media/dtv_demod/include/depend.h2
-rw-r--r--drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c5
-rw-r--r--drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h1
-rw-r--r--drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c1
-rw-r--r--drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c26
-rw-r--r--drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h3
-rw-r--r--drivers/amlogic/media/vout/cvbs/cvbs_out.c20
-rw-r--r--drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h2
-rw-r--r--drivers/amlogic/media/vout/cvbs/enc_clk_config.c6
-rw-r--r--drivers/amlogic/media/vout/vdac/Makefile2
-rw-r--r--drivers/amlogic/media/vout/vdac/vdac_config.c189
-rw-r--r--drivers/amlogic/media/vout/vdac/vdac_dev.c940
-rw-r--r--drivers/amlogic/media/vout/vdac/vdac_dev.h69
-rw-r--r--include/linux/amlogic/media/vout/vdac_dev.h32
20 files changed, 805 insertions, 517 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 7db33a8..1bb521b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14743,3 +14743,8 @@ F: drivers/amlogic/media/camera/*
F: drivers/amlogic/media/common/canvas/canvas_mgr.c
F: drivers/amlogic/media/common/vfm/vfm.c
F: include/linux/amlogic/media/camera/*
+
+AMLOGIC VDAC
+M: Evoke Zhang <evoke.zhang@amlogic.com>
+F: drivers/amlogic/media/vout/vdac/vdac_dev.h
+F: drivers/amlogic/media/vout/vdac/vdac_config.c
diff --git a/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts
index 3d8cb63..cfd7e48 100644
--- a/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts
+++ b/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts
@@ -930,7 +930,7 @@
cvbsout {
compatible = "amlogic, cvbsout-txlx";
dev_name = "cvbsout";
- status = "disabled";
+ status = "okay";
clocks = <&clkc CLKID_VCLK2_ENCI
&clkc CLKID_VCLK2_VENCI0
&clkc CLKID_VCLK2_VENCI1
diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
index abf3c56..de30010 100644
--- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
+++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
@@ -929,7 +929,7 @@
cvbsout {
compatible = "amlogic, cvbsout-txlx";
dev_name = "cvbsout";
- status = "disabled";
+ status = "okay";
clocks = <&clkc CLKID_VCLK2_ENCI
&clkc CLKID_VCLK2_VENCI0
&clkc CLKID_VCLK2_VENCI1
diff --git a/drivers/amlogic/atv_demod/atv_demod_ops.c b/drivers/amlogic/atv_demod/atv_demod_ops.c
index 029d652..ec635b6 100644
--- a/drivers/amlogic/atv_demod/atv_demod_ops.c
+++ b/drivers/amlogic/atv_demod/atv_demod_ops.c
@@ -20,6 +20,7 @@
#include <uapi/linux/dvb/frontend.h>
#include <linux/amlogic/aml_atvdemod.h>
+#include <linux/amlogic/media/vout/vdac_dev.h>
#include "drivers/media/tuners/tuner-i2c.h"
#include "drivers/media/dvb-core/dvb_frontend.h"
@@ -141,7 +142,7 @@ int atv_demod_enter_mode(struct dvb_frontend *fe)
}
err_code = adc_set_pll_cntl(1, ADC_EN_ATV_DEMOD, NULL);
- vdac_enable(1, 1);
+ vdac_enable(1, VDAC_MODULE_AVOUT_ATV);
usleep_range(2000, 2100);
atvdemod_clk_init();
/* err_code = atvdemod_init(); */
@@ -187,7 +188,7 @@ int atv_demod_leave_mode(struct dvb_frontend *fe)
amlatvdemod_devp->agc_pin = NULL;
}
- vdac_enable(0, 1);
+ vdac_enable(0, VDAC_MODULE_AVOUT_ATV);
adc_set_pll_cntl(0, ADC_EN_ATV_DEMOD, NULL);
if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
aud_demod_clk_gate(0);
diff --git a/drivers/amlogic/media/dtv_demod/amlfrontend.c b/drivers/amlogic/media/dtv_demod/amlfrontend.c
index 0e9f226..5aa338e 100644
--- a/drivers/amlogic/media/dtv_demod/amlfrontend.c
+++ b/drivers/amlogic/media/dtv_demod/amlfrontend.c
@@ -60,6 +60,7 @@
#include <linux/dma-contiguous.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#include <linux/amlogic/media/vout/vdac_dev.h>
MODULE_PARM_DESC(debug_aml, "\n\t\t Enable frontend debug information");
@@ -2841,7 +2842,7 @@ static bool enter_mode(int mode)
/*-------------------*/
/* must enable the adc ref signal for demod, */
- /*vdac_enable(1, 0x2);*/
+ /*vdac_enable(1, VDAC_MODULE_DTV_DEMOD);*/
dtvdemod_vdac_enable(1);/*on*/
dtvdd_devp->en_detect = 0;/**/
dtvdd_devp->n_mode = mode;
@@ -2953,7 +2954,7 @@ static int leave_mode(int mode)
adc_set_pll_cntl(0, 0x04, NULL);
demod_mode_para = UNKNOWN;
/* should disable the adc ref signal for demod */
- /*vdac_enable(0, 0x2);*/
+ /*vdac_enable(0, VDAC_MODULE_DTV_DEMOD);*/
dtvdemod_vdac_enable(0);/*off*/
dtvdemod_set_agc_pinmux(0);
msleep(200);
@@ -3455,10 +3456,10 @@ static void dtvdemod_vdac_enable(bool on)
{
if (on) {
vdac_clk_gate_ctrl(1);
- vdac_enable(1, 0x02);
+ vdac_enable(1, VDAC_MODULE_DTV_DEMOD);
} else {
vdac_clk_gate_ctrl(0);
- vdac_enable(0, 0x02);
+ vdac_enable(0, VDAC_MODULE_DTV_DEMOD);
}
}
diff --git a/drivers/amlogic/media/dtv_demod/include/amlfrontend.h b/drivers/amlogic/media/dtv_demod/include/amlfrontend.h
index 5d43cab..7d80eab 100644
--- a/drivers/amlogic/media/dtv_demod/include/amlfrontend.h
+++ b/drivers/amlogic/media/dtv_demod/include/amlfrontend.h
@@ -272,7 +272,6 @@ extern struct amldtvdemod_device_s *dtvdd_devp; /**/
/*int M6_Demod_Dtmb_Init(struct aml_fe_dev *dev);*/
int convert_snr(int in_snr);
-extern int vdac_enable_check_dtv(void);
extern unsigned int ats_thread_flg;
diff --git a/drivers/amlogic/media/dtv_demod/include/depend.h b/drivers/amlogic/media/dtv_demod/include/depend.h
index b594c5b..20d0199 100644
--- a/drivers/amlogic/media/dtv_demod/include/depend.h
+++ b/drivers/amlogic/media/dtv_demod/include/depend.h
@@ -21,8 +21,6 @@
#include <linux/device.h> /**/
-extern void vdac_enable(bool on, unsigned int module_sel);
-
/*dma_alloc_from_contiguous*/
struct page *aml_dma_alloc_contiguous(struct device *dev, int count,
unsigned int order);
diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c
index 2e99da3..809fd3f 100644
--- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c
+++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c
@@ -46,6 +46,7 @@
/*#include <linux/amlogic/amports/vframe_provider.h>*/
/*#include <linux/amlogic/amports/vframe_receiver.h>*/
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#include <linux/amlogic/media/vout/vdac_dev.h>
/*#include <linux/amlogic/amports/vframe.h>*/
#include <linux/of_gpio.h>
#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
@@ -298,7 +299,7 @@ int hdmirx_dec_open(struct tvin_frontend_s *fe, enum tvin_port_e port)
devp->param.port = port;
/* should enable the adc ref signal for audio pll */
- vdac_enable(1, 0x10);
+ vdac_enable(1, VDAC_MODULE_AUDIO_OUT);
hdmirx_open_port(port);
rx.open_fg = 1;
@@ -358,7 +359,7 @@ void hdmirx_dec_close(struct tvin_frontend_s *fe)
*/
/* For txl,also need to keep bandgap always on:SWPL-1224 */
/* if (rx.hdmirxdev->data->chip_id == CHIP_ID_TXL) */
- /* vdac_enable(0, 0x10); */
+ /* vdac_enable(0, VDAC_MODULE_AUDIO_OUT); */
/* open_flage = 0; */
rx.open_fg = 0;
devp = container_of(fe, struct hdmirx_dev_s, frontend);
diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
index b51798c..36c20c4 100644
--- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
+++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
@@ -528,7 +528,6 @@ extern unsigned int *pd_fifo_buf;
/* for other modules */
extern int External_Mute(int mute_flag);
-extern void vdac_enable(bool on, unsigned int module_sel);
extern int rx_is_hdcp22_support(void);
extern int hdmirx_get_connect_info(void);
#endif
diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
index 7d4adbc..b50e44d 100644
--- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
+++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#include <linux/amlogic/media/vout/vdac_dev.h>
#include <linux/arm-smccc.h>
/* Local include */
diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c
index 70c8faa..d410b12c 100644
--- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c
+++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c
@@ -23,6 +23,7 @@
/*#include <mach/am_regs.h>*/
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#include <linux/amlogic/media/vout/vdac_dev.h>
#include "../tvin_global.h"
#include "../tvin_format_table.h"
#include "tvafe_regs.h"
@@ -535,7 +536,10 @@ void tvafe_set_ddemod_default(void)
W_HIU_REG(HHI_DADC_CNTL3, 0x00082183);
/*W_HIU_REG(HHI_VDAC_CNTL0, 0x00000200);*/
- W_HIU_BIT(HHI_VDAC_CNTL0, 1, 9, 1);
+ /*W_HIU_BIT(HHI_VDAC_CNTL0, 1, 9, 1);*/
+ /* remove vdac reg write, make sure it write in vdac driver,
+ * because multi module use it
+ */
} else if (tvafe_cpu_type() == CPU_TYPE_TXHD) {
W_HIU_REG(HHI_DADC_CNTL, 0x00102038);
@@ -560,7 +564,10 @@ void tvafe_set_ddemod_default(void)
W_HIU_REG(HHI_DADC_CNTL3, 0x08300b83);
//HHI_VDAC_CNTL1
- W_HIU_REG(0xbc, 0x0);
+ /*W_HIU_REG(0xbc, 0x0);*/
+ /* remove vdac reg write, make sure it write in vdac driver,
+ * because multi module use it
+ */
}
}
@@ -575,23 +582,16 @@ void tvafe_enable_avout(enum tvin_port_e port, bool enable)
if (enable) {
tvafe_clk_gate_ctrl(1);
if (port == TVIN_PORT_CVBS3) {
- vdac_enable(1, 0x1);
- /* clock delay control */
- W_HIU_BIT(HHI_VIID_CLK_DIV, 1, 19, 1);
- /* vdac_clock_mux form atv demod */
- W_HIU_BIT(HHI_VID_CLK_CNTL2, 1, 8, 1);
- W_HIU_BIT(HHI_VID_CLK_CNTL2, 1, 4, 1);
- /* vdac_clk gated clock control */
- W_VCBUS_BIT(VENC_VDAC_DACSEL0, 1, 5, 1);
+ vdac_enable(1, VDAC_MODULE_AVOUT_ATV);
} else {
W_APB_REG(TVFE_ATV_DMD_CLP_CTRL, 0);
- vdac_enable(1, 0x4);
+ vdac_enable(1, VDAC_MODULE_AVOUT_AV);
}
} else {
if (port == TVIN_PORT_CVBS3)
- vdac_enable(0, 0x1);
+ vdac_enable(0, VDAC_MODULE_AVOUT_ATV);
else
- vdac_enable(0, 0x4);
+ vdac_enable(0, VDAC_MODULE_AVOUT_AV);
tvafe_clk_gate_ctrl(0);
}
}
diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h
index 85d6a32..6dc0f4f 100644
--- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h
+++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h
@@ -185,9 +185,6 @@ extern void tvafe_set_apb_bus_err_ctrl(void);
extern void tvafe_enable_module(bool enable);
extern void tvafe_enable_avout(enum tvin_port_e port, bool enable);
-/* vdac ctrl,adc/dac ref signal,cvbs out signal*/
-/* module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8*/
-void vdac_enable(bool on, unsigned int module_sel);
extern void adc_set_pll_reset(void);
extern int tvafe_adc_get_pll_flag(void);
extern int tvafe_cpu_type(void);
diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out.c b/drivers/amlogic/media/vout/cvbs/cvbs_out.c
index 7cda8b2..44c3001 100644
--- a/drivers/amlogic/media/vout/cvbs/cvbs_out.c
+++ b/drivers/amlogic/media/vout/cvbs/cvbs_out.c
@@ -231,7 +231,7 @@ static void cvbs_cntl_output(unsigned int open)
vdac_set_ctrl0_ctrl1(cntl0, cntl1);
/* must enable adc bandgap, the adc ref signal for demod */
- vdac_enable(0, 0x8);
+ vdac_enable(0, VDAC_MODULE_CVBS_OUT);
} else if (open == 1) { /* open */
cntl0 = info->cvbs_data->cntl0_val;
@@ -241,7 +241,7 @@ static void cvbs_cntl_output(unsigned int open)
vdac_set_ctrl0_ctrl1(cntl0, cntl1);
/*vdac ctrl for cvbsout/rf signal,adc bandgap*/
- vdac_enable(1, 0x8);
+ vdac_enable(1, VDAC_MODULE_CVBS_OUT);
}
}
@@ -909,15 +909,13 @@ static void cvbs_performance_regs_dump(void)
else
size = sizeof(performance_regs_vdac)/sizeof(unsigned int);
pr_info("------------------------\n");
- for (i = 0; i < size; i++) {
- if (cvbs_cpu_type() == CVBS_CPU_TYPE_G12A ||
- cvbs_cpu_type() == CVBS_CPU_TYPE_G12B)
- pr_info("hiu [0x%x] = 0x%x\n",
- performance_regs_vdac_g12a[i],
- cvbs_out_hiu_read(performance_regs_vdac_g12a[i]));
- else
- pr_info("hiu [0x%x] = 0x%x\n", performance_regs_vdac[i],
- cvbs_out_hiu_read(performance_regs_vdac[i]));
+ vdac_reg0 = vdac_get_reg_addr(0);
+ vdac_reg1 = vdac_get_reg_addr(1);
+ if ((vdac_reg0 < 0x1000) && (vdac_reg1 < 0x1000)) {
+ pr_info("hiu [0x%x] = 0x%x\n"
+ "hiu [0x%x] = 0x%x\n",
+ vdac_reg0, cvbs_out_hiu_read(vdac_reg0),
+ vdac_reg1, cvbs_out_hiu_read(vdac_reg1));
}
pr_info("------------------------\n");
}
diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h b/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h
index be66ef4..56b666b 100644
--- a/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h
+++ b/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h
@@ -144,6 +144,8 @@
#define HHI_DIF_CSI_PHY_CNTL5 0xdd
#define HHI_LVDS_TX_PHY_CNTL0 0xde
#define HHI_LVDS_TX_PHY_CNTL1 0xdf
+#define HHI_LVDS_TX_PHY_CNTL0_TL1 0x9a
+#define HHI_LVDS_TX_PHY_CNTL1_TL1 0x9b
#define HHI_VID2_PLL_CNTL 0xe0
#define HHI_VID2_PLL_CNTL2 0xe1
#define HHI_VID2_PLL_CNTL3 0xe2
diff --git a/drivers/amlogic/media/vout/cvbs/enc_clk_config.c b/drivers/amlogic/media/vout/cvbs/enc_clk_config.c
index 28b6fc8..6e2f09b 100644
--- a/drivers/amlogic/media/vout/cvbs/enc_clk_config.c
+++ b/drivers/amlogic/media/vout/cvbs/enc_clk_config.c
@@ -105,6 +105,9 @@ static void cvbs_set_vid1_clk(unsigned int src_pll)
/* vclk: 27M */
/* [31:28]=0 enci_clk_sel, select vclk_div1 */
cvbs_out_hiu_setb(HHI_VID_CLK_DIV, 0, 28, 4);
+ /* [31:28]=0 vdac_clk_sel, select vclk_div1 */
+ /* [19]=0 disable atv_demod clk for vdac */
+ cvbs_out_hiu_setb(HHI_VIID_CLK_DIV, 0, 19, 1);
cvbs_out_hiu_setb(HHI_VIID_CLK_DIV, 0, 28, 4);
/* release vclk_div_reset and enable vclk_div */
cvbs_out_hiu_setb(HHI_VID_CLK_DIV, 1, VCLK_XD_EN, 2);
@@ -150,6 +153,9 @@ static void cvbs_set_vid2_clk(unsigned int src_pll)
/* vclk: 27M */
/* [31:28]=8 enci_clk_sel, select vclk2_div1 */
cvbs_out_hiu_setb(HHI_VID_CLK_DIV, 8, 28, 4);
+ /* [31:28]=8 vdac_clk_sel, select vclk2_div1 */
+ /* [19]=0 disable atv_demod clk for vdac */
+ cvbs_out_hiu_setb(HHI_VIID_CLK_DIV, 0, 19, 1);
cvbs_out_hiu_setb(HHI_VIID_CLK_DIV, 8, 28, 4);
/* release vclk2_div_reset and enable vclk2_div */
cvbs_out_hiu_setb(HHI_VIID_CLK_DIV, 1, VCLK2_XD_EN, 2);
diff --git a/drivers/amlogic/media/vout/vdac/Makefile b/drivers/amlogic/media/vout/vdac/Makefile
index 752cf7f..438445c 100644
--- a/drivers/amlogic/media/vout/vdac/Makefile
+++ b/drivers/amlogic/media/vout/vdac/Makefile
@@ -1,3 +1,3 @@
-obj-$(CONFIG_AMLOGIC_VDAC) += vdac_dev.o
+obj-$(CONFIG_AMLOGIC_VDAC) += vdac_dev.o vdac_config.o
ccflags-y += -Idrivers/amlogic/display/ \ No newline at end of file
diff --git a/drivers/amlogic/media/vout/vdac/vdac_config.c b/drivers/amlogic/media/vout/vdac/vdac_config.c
new file mode 100644
index 0000000..76b254c
--- a/dev/null
+++ b/drivers/amlogic/media/vout/vdac/vdac_config.c
@@ -0,0 +1,189 @@
+/*
+ * drivers/amlogic/media/vout/vdac/vdac_config.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include "vdac_dev.h"
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_gxl[] = {
+ {HHI_VDAC_CNTL0, 0, 9, 1},
+ {HHI_VDAC_CNTL0, 1, 10, 1},
+ {HHI_VDAC_CNTL0, 1, 0, 1},
+ {HHI_VDAC_CNTL1, 0, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_txl[] = {
+ {HHI_VDAC_CNTL0, 1, 9, 1},
+ {HHI_VDAC_CNTL0, 1, 10, 1},
+ {HHI_VDAC_CNTL0, 1, 0, 1},
+ {HHI_VDAC_CNTL1, 1, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_txlx[] = {
+ {HHI_VDAC_CNTL0, 1, 9, 1},
+ {HHI_VDAC_CNTL0, 1, 10, 1},
+ {HHI_VDAC_CNTL0, 1, 0, 1},
+ {HHI_VDAC_CNTL0, 0, 13, 1}, /* bandgap */
+ {HHI_VDAC_CNTL1, 1, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_g12ab[] = {
+ {HHI_VDAC_CNTL0_G12A, 0, 9, 1},
+ {HHI_VDAC_CNTL0_G12A, 1, 0, 1},
+ {HHI_VDAC_CNTL1_G12A, 0, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_tl1[] = {
+ {HHI_VDAC_CNTL0_G12A, 0, 9, 1},
+ {HHI_VDAC_CNTL0_G12A, 1, 0, 1},
+ {HHI_VDAC_CNTL1_G12A, 0, 3, 1},
+ {HHI_VDAC_CNTL1_G12A, 0, 7, 1}, /* bandgap */
+ {HHI_VDAC_CNTL1_G12A, 1, 6, 1}, /* bypass avout */
+ {HHI_VDAC_CNTL1_G12A, 1, 8, 1}, /* bypass avout */
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+/* ********************************************************* */
+static struct meson_vdac_data meson_gx_l_m_vdac_data = {
+ .cpu_id = VDAC_CPU_GX_L_M,
+ .name = "meson-gx_l_m-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_gxl,
+};
+
+static struct meson_vdac_data meson_txl_vdac_data = {
+ .cpu_id = VDAC_CPU_TXL,
+ .name = "meson-txl-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_txl,
+};
+
+static struct meson_vdac_data meson_txlx_vdac_data = {
+ .cpu_id = VDAC_CPU_TXLX,
+ .name = "meson-txlx-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_txlx,
+};
+
+static struct meson_vdac_data meson_gxlx_vdac_data = {
+ .cpu_id = VDAC_CPU_GXLX,
+ .name = "meson-gxlx-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_txl,
+};
+
+static struct meson_vdac_data meson_g12ab_vdac_data = {
+ .cpu_id = VDAC_CPU_G12AB,
+ .name = "meson-g12ab-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_g12ab,
+};
+
+static struct meson_vdac_data meson_tl1_vdac_data = {
+ .cpu_id = VDAC_CPU_TL1,
+ .name = "meson-tl1-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_tl1,
+};
+
+static struct meson_vdac_data meson_sm1_vdac_data = {
+ .cpu_id = VDAC_CPU_SM1,
+ .name = "meson-sm1-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_g12ab,
+};
+
+static struct meson_vdac_data meson_tm2_vdac_data = {
+ .cpu_id = VDAC_CPU_TM2,
+ .name = "meson-tm2-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_tl1,
+};
+
+const struct of_device_id meson_vdac_dt_match[] = {
+ {
+ .compatible = "amlogic, vdac-gxl",
+ .data = &meson_gx_l_m_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-gxm",
+ .data = &meson_gx_l_m_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-txl",
+ .data = &meson_txl_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-txlx",
+ .data = &meson_txlx_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-gxlx",
+ .data = &meson_gxlx_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-g12a",
+ .data = &meson_g12ab_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-g12b",
+ .data = &meson_g12ab_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-tl1",
+ .data = &meson_tl1_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-sm1",
+ .data = &meson_sm1_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-tm2",
+ .data = &meson_tm2_vdac_data,
+ },
+ {}
+};
+
+struct meson_vdac_data *aml_vdac_config_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct meson_vdac_data *data;
+
+ match = of_match_device(meson_vdac_dt_match, &pdev->dev);
+ if (!match) {
+ pr_err("%s, no matched table\n", __func__);
+ return NULL;
+ }
+ data = (struct meson_vdac_data *)match->data;
+ if (data) {
+ pr_info("%s: cpu_id:%d, name:%s\n", __func__,
+ data->cpu_id, data->name);
+ }
+
+ return data;
+}
diff --git a/drivers/amlogic/media/vout/vdac/vdac_dev.c b/drivers/amlogic/media/vout/vdac/vdac_dev.c
index b5b3533..7523556 100644
--- a/drivers/amlogic/media/vout/vdac/vdac_dev.c
+++ b/drivers/amlogic/media/vout/vdac/vdac_dev.c
@@ -38,6 +38,7 @@
#include <linux/amlogic/iomap.h>
#include <linux/io.h>
#include <linux/mutex.h>
+#include "vdac_dev.h"
#define AMVDAC_NAME "amvdac"
#define AMVDAC_DRIVER_NAME "amvdac"
@@ -56,310 +57,261 @@ static struct amvdac_dev_s amvdac_dev;
static struct meson_vdac_data *s_vdac_data;
static struct mutex vdac_mutex;
-#define HHI_VDAC_CNTL0 0xbd
-#define HHI_VDAC_CNTL1 0xbe
-#define HHI_VDAC_CNTL0_G12A 0xbb
-#define HHI_VDAC_CNTL1_G12A 0xbc
-
-#define VDAC_MODULE_ATV_DEMOD 0x1
-#define VDAC_MODULE_DTV_DEMOD 0x2
-#define VDAC_MODULE_TVAFE 0x4
-#define VDAC_MODULE_CVBS_OUT 0x8
-#define VDAC_MODULE_AUDIO_OUT 0x10
-
-static bool vdac_init_succ_flag;
-
/* priority for module,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; cvbsout:0x8
+ * #define VDAC_MODULE_ATV_DEMOD (1 << 0)
+ * #define VDAC_MODULE_DTV_DEMOD (1 << 1)
+ * #define VDAC_MODULE_TVAFE (1 << 2)
+ * #define VDAC_MODULE_CVBS_OUT (1 << 3)
+ * #define VDAC_MODULE_AUDIO_OUT (1 << 4)
+ * #define VDAC_MODULE_AVOUT_ATV (1 << 5)
+ * #define VDAC_MODULE_AVOUT_AV (1 << 6)
*/
static unsigned int pri_flag;
-static unsigned int vdac_cntl0_bit9;
-module_param(vdac_cntl0_bit9, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl0_bit9, "vdac_cntl0_bit9");
-
-static unsigned int vdac_cntl1_bit3;
-module_param(vdac_cntl1_bit3, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl1_bit3, "vdac_cntl1_bit3");
-
-static unsigned int vdac_cntl0_bit0;
-module_param(vdac_cntl0_bit0, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl0_bit0, "vdac_cntl0_bit0");
+static unsigned int vdac_debug_print;
-static unsigned int vdac_cntl0_bit10;
-module_param(vdac_cntl0_bit10, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl0_bit10, "vdac_cntl0_bit10");
-
-static inline uint32_t vdac_hiu_reg_read(uint32_t reg)
+static inline unsigned int vdac_hiu_reg_read(unsigned int reg)
{
return aml_read_hiubus(reg);
}
-static inline void vdac_hiu_reg_write(uint32_t reg, uint32_t val)
+static inline void vdac_hiu_reg_write(unsigned int reg, unsigned int val)
{
- return aml_write_hiubus(reg, val);
+ aml_write_hiubus(reg, val);
}
-static inline void vdac_hiu_reg_setb(uint32_t reg,
- const uint32_t value,
- const uint32_t start,
- const uint32_t len)
+static inline void vdac_hiu_reg_setb(unsigned int reg, unsigned int value,
+ unsigned int start, unsigned int len)
{
- aml_write_hiubus(reg, ((aml_read_hiubus(reg) &
+ vdac_hiu_reg_write(reg, ((vdac_hiu_reg_read(reg) &
~(((1L << (len)) - 1) << (start))) |
(((value) & ((1L << (len)) - 1)) << (start))));
}
-static inline uint32_t vdac_hiu_reg_getb(uint32_t reg,
- const uint32_t start,
- const uint32_t len)
+static inline unsigned int vdac_hiu_reg_getb(unsigned int reg,
+ unsigned int start,
+ unsigned int len)
{
- uint32_t val;
+ unsigned int val;
val = ((vdac_hiu_reg_read(reg) >> (start)) & ((1L << (len)) - 1));
return val;
}
-/* adc/dac ref signal,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void ana_ref_cntl0_bit9(bool on, unsigned int module_sel)
+static inline unsigned int vdac_vcbus_reg_read(unsigned int reg)
{
- bool enable = 0;
+ return aml_read_vcbus(reg);
+}
- /*tl1:bandgap en, bc[7] default:0 opened*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1)
- return;
+static inline void vdac_vcbus_reg_write(unsigned int reg, unsigned int val)
+{
+ aml_write_vcbus(reg, val);
+}
- switch (module_sel & 0x1f) {
- case VDAC_MODULE_ATV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* cvbs in demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- case VDAC_MODULE_AUDIO_OUT: /* audio out ctrl*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_AUDIO_OUT;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_AUDIO_OUT;
- }
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
- }
- /* pr_info("\nvdac_cntl0_bit9: 0x%x\n", vdac_cntl0_bit9); */
+static inline void vdac_vcbus_reg_setb(unsigned int reg, unsigned int value,
+ unsigned int start, unsigned int len)
+{
+ vdac_vcbus_reg_write(reg, ((vdac_vcbus_reg_read(reg) &
+ ~(((1L << (len)) - 1) << (start))) |
+ (((value) & ((1L << (len)) - 1)) << (start))));
+}
- if ((vdac_cntl0_bit9 & 0x1f) == 0)
- enable = 0;
- else
- enable = 1;
+static inline unsigned int vdac_vcbus_reg_getb(unsigned int reg,
+ unsigned int start,
+ unsigned int len)
+{
+ unsigned int val;
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, enable, 9, 1);
- else if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0_G12A, ~enable, 9, 1);
- else
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, ~enable, 9, 1);
+ val = ((vdac_vcbus_reg_read(reg) >> (start)) & ((1L << (len)) - 1));
+
+ return val;
}
-EXPORT_SYMBOL(ana_ref_cntl0_bit9);
-/*avin cvbsout signal,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void vdac_out_cntl0_bit10(bool on, unsigned int module_sel)
+static int vdac_ctrl_config(bool on, unsigned int reg, unsigned int bit)
{
- bool enable = 0;
+ struct meson_vdac_ctrl_s *table = s_vdac_data->ctrl_table;
+ unsigned int val;
+ int i = 0;
+ int ret = -1;
- /*bit10 is for bandgap startup setting in g12a*/
- if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- return;
-
- switch (module_sel & 0xf) {
- case VDAC_MODULE_ATV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* av in demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs out demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
+ while (i < VDAC_CTRL_MAX) {
+ if (table[i].reg == VDAC_REG_MAX)
+ break;
+ if ((table[i].reg == reg) && (table[i].bit == bit)) {
+ if (on)
+ val = table[i].val;
+ else
+ val = table[i].val ? 0 : 1;
+ vdac_hiu_reg_setb(reg, val, bit, table[i].len);
+ if (vdac_debug_print) {
+ pr_info("vdac: reg=0x%02x set bit%d=%d, readback=0x%08x\n",
+ reg, bit, val, vdac_hiu_reg_read(reg));
+ }
+ ret = 0;
+ break;
+ }
+ i++;
}
- /* pr_info("\vdac_cntl0_bit0: 0x%x\n", vdac_cntl1_bit3); */
-
- if ((vdac_cntl0_bit10 & 0xf) == 0)
- enable = 0;
- else
- enable = 1;
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, enable, 10, 1);
+ return ret;
}
-EXPORT_SYMBOL(vdac_out_cntl0_bit10);
-/*atv cvbsout signal,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void vdac_out_cntl0_bit0(bool on, unsigned int module_sel)
+static void vdac_enable_avout_atv(bool on)
{
- bool enable = 0;
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ /* clock delay control */
+ vdac_hiu_reg_setb(HHI_VIID_CLK_DIV, 1, 19, 1);
+ /* vdac_clock_mux form atv demod */
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 1, 8, 1);
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 1, 4, 1);
+ /* vdac_clk gated clock control */
+ vdac_vcbus_reg_setb(VENC_VDAC_DACSEL0, 1, 5, 1);
+
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ /*after txlx need reset bandgap after bit9 enabled*/
+ /*bit10 reset bandgap in g12a*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
- switch (module_sel & 0xf) {
- case VDAC_MODULE_ATV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* av in demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
- }
- /* pr_info("\vdac_cntl0_bit0: 0x%x\n", vdac_cntl1_bit3); */
+ /*Cdac pwd*/
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ /* enable AFE output buffer */
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ vdac_ctrl_config(1, reg_cntl0, 0);
- if ((vdac_cntl0_bit0 & 0xf) == 0)
- enable = 0;
- else
- enable = 1;
- if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0_G12A, enable, 0, 1);
- else
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, enable, 0, 1);
+ } else {
+ vdac_ctrl_config(0, reg_cntl0, 9);
+
+ vdac_ctrl_config(0, reg_cntl0, 0);
+ /* Disable AFE output buffer */
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ /* disable dac output */
+ vdac_ctrl_config(0, reg_cntl1, 3);
+
+ /* vdac_clk gated clock control */
+ vdac_vcbus_reg_setb(VENC_VDAC_DACSEL0, 0, 5, 1);
+ /* vdac_clock_mux form atv demod */
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 0, 4, 1);
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 0, 8, 1);
+ /* clock delay control */
+ vdac_hiu_reg_setb(HHI_VIID_CLK_DIV, 0, 19, 1);
+ }
}
-EXPORT_SYMBOL(vdac_out_cntl0_bit0);
-/* dac out pwd ctl,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void vdac_out_cntl1_bit3(bool on, unsigned int module_sel)
+static void vdac_enable_dtv_demod(bool on)
{
- bool enable = 0;
-
- switch (module_sel & 0xf) {
- case VDAC_MODULE_ATV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* av in demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ vdac_ctrl_config(1, reg_cntl0, 0);
+ } else {
+ vdac_ctrl_config(0, reg_cntl0, 9);
+ vdac_ctrl_config(0, reg_cntl1, 3);
}
- /* pr_info("\nvdac_cntl1_bit3: 0x%x\n", vdac_cntl1_bit3); */
+}
- if ((vdac_cntl1_bit3 & 0xf) == 0)
- enable = 0;
- else
- enable = 1;
+static void vdac_enable_avout_av(bool on)
+{
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ /*txlx need reset bandgap after bit9 enabled*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1, enable, 3, 1);
- else if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, ~enable, 3, 1);
- else
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1, ~enable, 3, 1);
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(1, reg_cntl0, 10);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ /*[6][8]bypass buffer enable*/
+ vdac_ctrl_config(1, reg_cntl1, 6);
+ vdac_ctrl_config(1, reg_cntl1, 8);
+ }
+ } else {
+ vdac_ctrl_config(0, reg_cntl0, 9);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ /*[6][8]bypass buffer disable*/
+ vdac_ctrl_config(0, reg_cntl1, 6);
+ vdac_ctrl_config(0, reg_cntl1, 8);
+ }
+
+ /* Disable AFE output buffer */
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ /* disable dac output */
+ vdac_ctrl_config(0, reg_cntl1, 3);
+ }
}
-EXPORT_SYMBOL(vdac_out_cntl1_bit3);
-void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1)
+static void vdac_enable_cvbs_out(bool on)
{
- if (!s_vdac_data) {
- pr_err("\n%s: s_vdac_data NULL\n", __func__);
- return;
- }
- if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB) {
- vdac_hiu_reg_write(HHI_VDAC_CNTL0_G12A, ctrl0);
- vdac_hiu_reg_write(HHI_VDAC_CNTL1_G12A, ctrl1);
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ vdac_ctrl_config(1, reg_cntl0, 0);
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
} else {
- vdac_hiu_reg_write(HHI_VDAC_CNTL0, ctrl0);
- vdac_hiu_reg_write(HHI_VDAC_CNTL1, ctrl1);
+ vdac_ctrl_config(0, reg_cntl0, 9);
+ vdac_ctrl_config(0, reg_cntl0, 0);
+ vdac_ctrl_config(0, reg_cntl1, 3);
+ }
+}
+
+static void vdac_enable_audio_out(bool on)
+{
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+
+ /*Bandgap optimization*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX)
+ vdac_hiu_reg_setb(reg_cntl0, 0xe, 3, 5);
+
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
+ s_vdac_data->cpu_id == VDAC_CPU_TXLX ||
+ s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ if (on)
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ else
+ vdac_ctrl_config(0, reg_cntl0, 9);
}
}
-EXPORT_SYMBOL(vdac_set_ctrl0_ctrl1);
-/* dac ctl,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
void vdac_enable(bool on, unsigned int module_sel)
{
if (!s_vdac_data) {
@@ -367,150 +319,104 @@ void vdac_enable(bool on, unsigned int module_sel)
return;
}
- pr_info("\n%s: on:%d,module_sel:%x\n", __func__, on, module_sel);
+ pr_info("\n%s: %d, module_sel:0x%x, private_flag:0x%x\n",
+ __func__, on, module_sel, pri_flag);
mutex_lock(&vdac_mutex);
switch (module_sel) {
- case VDAC_MODULE_ATV_DEMOD: /* atv demod */
- if ((on && (pri_flag & VDAC_MODULE_ATV_DEMOD))
- || (!on && !(pri_flag & VDAC_MODULE_ATV_DEMOD))) {
- pr_info("%s: ATV DEMOD had done!:%d.\n", __func__, on);
- break;
- }
-
+ case VDAC_MODULE_AVOUT_ATV: /* atv avout */
if (on) {
- ana_ref_cntl0_bit9(1, VDAC_MODULE_ATV_DEMOD);
- /*after txlx need reset bandgap after bit9 enabled*/
- /*bit10 reset bandgap in g12a*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
+ if (pri_flag & VDAC_MODULE_AVOUT_ATV) {
+ pr_info("%s: avout_atv is already on\n",
+ __func__);
+ break;
}
- pri_flag &= ~VDAC_MODULE_TVAFE;
- pri_flag |= VDAC_MODULE_ATV_DEMOD;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ pri_flag |= VDAC_MODULE_AVOUT_ATV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
break;
- /*Cdac pwd*/
- vdac_out_cntl1_bit3(1, VDAC_MODULE_ATV_DEMOD);
- /* enable AFE output buffer */
- if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 10, 1);
- vdac_out_cntl0_bit0(1, VDAC_MODULE_ATV_DEMOD);
+ }
+ vdac_enable_avout_atv(1);
} else {
- ana_ref_cntl0_bit9(0, VDAC_MODULE_ATV_DEMOD);
- pri_flag &= ~VDAC_MODULE_ATV_DEMOD;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ if (!(pri_flag & VDAC_MODULE_AVOUT_ATV)) {
+ pr_info("%s: avout_atv is already off\n",
+ __func__);
break;
- vdac_out_cntl0_bit0(0, VDAC_MODULE_ATV_DEMOD);
- /* Disable AFE output buffer */
- if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 10, 1);
- /* enable dac output */
- vdac_out_cntl1_bit3(0, VDAC_MODULE_ATV_DEMOD);
+ }
+ pri_flag &= ~VDAC_MODULE_AVOUT_ATV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ if (vdac_debug_print) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
+ }
+ break;
+ }
+ vdac_enable_avout_atv(0);
}
break;
case VDAC_MODULE_DTV_DEMOD: /* dtv demod */
if (on) {
- if (s_vdac_data->cpu_id == VDAC_CPU_GXLX)
- vdac_out_cntl1_bit3(1, VDAC_MODULE_DTV_DEMOD);
- ana_ref_cntl0_bit9(1, VDAC_MODULE_DTV_DEMOD);
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
- }
pri_flag |= VDAC_MODULE_DTV_DEMOD;
+ vdac_enable_dtv_demod(1);
} else {
- ana_ref_cntl0_bit9(0, VDAC_MODULE_DTV_DEMOD);
- if (s_vdac_data->cpu_id == VDAC_CPU_GXLX)
- vdac_out_cntl1_bit3(0, VDAC_MODULE_DTV_DEMOD);
pri_flag &= ~VDAC_MODULE_DTV_DEMOD;
+ if (pri_flag & VDAC_MODULE_MASK)
+ break;
+ vdac_enable_dtv_demod(0);
}
break;
- case VDAC_MODULE_TVAFE: /* av in demod */
+ case VDAC_MODULE_AVOUT_AV: /* avin avout */
if (on) {
- ana_ref_cntl0_bit9(1, VDAC_MODULE_TVAFE);
- /*after txlx need reset bandgap after bit9 enabled*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
- }
- pri_flag &= ~VDAC_MODULE_ATV_DEMOD;
- pri_flag |= VDAC_MODULE_TVAFE;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ pri_flag |= VDAC_MODULE_AVOUT_AV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
break;
- vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
- vdac_out_cntl0_bit10(1, VDAC_MODULE_TVAFE);
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1) {
- /*[6][8]bypass buffer enable*/
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 6, 1);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 8, 1);
}
+ vdac_enable_avout_av(1);
} else {
- ana_ref_cntl0_bit9(0, VDAC_MODULE_TVAFE);
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1) {
- /*[6][8]bypass buffer disable*/
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 6, 1);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 8, 1);
+ pri_flag &= ~VDAC_MODULE_AVOUT_AV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ if (vdac_debug_print) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
+ }
+ break;
}
- pri_flag &= ~VDAC_MODULE_TVAFE;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ if (pri_flag & VDAC_MODULE_MASK)
break;
- /* Disable AFE output buffer */
- vdac_out_cntl0_bit10(0, VDAC_MODULE_TVAFE);
- /* enable dac output */
- vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
+ vdac_enable_avout_av(0);
}
break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
+ case VDAC_MODULE_CVBS_OUT:
if (on) {
- vdac_out_cntl1_bit3(1, VDAC_MODULE_CVBS_OUT);
- vdac_out_cntl0_bit0(1, VDAC_MODULE_CVBS_OUT);
- ana_ref_cntl0_bit9(1, VDAC_MODULE_CVBS_OUT);
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
- }
- vdac_out_cntl0_bit10(0, VDAC_MODULE_CVBS_OUT);
pri_flag |= VDAC_MODULE_CVBS_OUT;
+ vdac_enable_cvbs_out(1);
} else {
- /*vdac_out_cntl0_bit10(0, VDAC_MODULE_CVBS_OUT);*/
- ana_ref_cntl0_bit9(0, VDAC_MODULE_CVBS_OUT);
- vdac_out_cntl0_bit0(0, VDAC_MODULE_CVBS_OUT);
- vdac_out_cntl1_bit3(0, VDAC_MODULE_CVBS_OUT);
pri_flag &= ~VDAC_MODULE_CVBS_OUT;
- if (pri_flag & VDAC_MODULE_ATV_DEMOD) {
- vdac_out_cntl1_bit3(1, VDAC_MODULE_ATV_DEMOD);
- if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0,
- 0, 10, 1);
- vdac_out_cntl0_bit0(1, VDAC_MODULE_ATV_DEMOD);
- } else if (pri_flag & VDAC_MODULE_TVAFE) {
- vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
- vdac_out_cntl0_bit10(1, VDAC_MODULE_TVAFE);
- } else if (pri_flag & VDAC_MODULE_DTV_DEMOD) {
- if (s_vdac_data->cpu_id == VDAC_CPU_GXLX)
- vdac_out_cntl1_bit3(1,
- VDAC_MODULE_DTV_DEMOD);
- ana_ref_cntl0_bit9(1, VDAC_MODULE_DTV_DEMOD);
+ if ((pri_flag & VDAC_MODULE_MASK) == 0) {
+ vdac_enable_cvbs_out(0);
+ break;
}
+
+ if (pri_flag & VDAC_MODULE_AVOUT_ATV)
+ vdac_enable_avout_atv(1);
+ else if (pri_flag & VDAC_MODULE_AVOUT_AV)
+ vdac_enable_avout_av(1);
+ else if (pri_flag & VDAC_MODULE_DTV_DEMOD)
+ vdac_enable_dtv_demod(1);
}
break;
case VDAC_MODULE_AUDIO_OUT: /* audio demod */
- /*Bandgap optimization*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXHD ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0xe, 3, 5);
-
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- if (on)
- ana_ref_cntl0_bit9(1, VDAC_MODULE_AUDIO_OUT);
- else
- ana_ref_cntl0_bit9(0, VDAC_MODULE_AUDIO_OUT);
+ if (on) {
+ pri_flag |= VDAC_MODULE_AUDIO_OUT;
+ vdac_enable_audio_out(1);
+ } else {
+ pri_flag &= ~VDAC_MODULE_AUDIO_OUT;
+ if (pri_flag & VDAC_MODULE_MASK)
+ break;
+ vdac_enable_audio_out(0);
}
break;
default:
@@ -519,15 +425,205 @@ void vdac_enable(bool on, unsigned int module_sel)
break;
}
+ if (vdac_debug_print) {
+ pr_info("private_flag: 0x%02x\n"
+ "reg_cntl0: 0x%02x=0x%08x\n"
+ "reg_cntl1: 0x%02x=0x%08x\n",
+ pri_flag,
+ s_vdac_data->reg_cntl0,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl0),
+ s_vdac_data->reg_cntl1,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl1));
+ }
+
mutex_unlock(&vdac_mutex);
}
EXPORT_SYMBOL(vdac_enable);
+void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1)
+{
+ unsigned int reg_cntl0;
+ unsigned int reg_cntl1;
+
+ if (!s_vdac_data) {
+ pr_err("\n%s: s_vdac_data NULL\n", __func__);
+ return;
+ }
+
+ reg_cntl0 = s_vdac_data->reg_cntl0;
+ reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ vdac_hiu_reg_write(reg_cntl0, ctrl0);
+ vdac_hiu_reg_write(reg_cntl1, ctrl1);
+ if (vdac_debug_print) {
+ pr_info("vdac: set reg 0x%02x=0x%08x, readback=0x%08x\n",
+ reg_cntl0, ctrl0, vdac_hiu_reg_read(reg_cntl0));
+ pr_info("vdac: set reg 0x%02x=0x%08x, readback=0x%08x\n",
+ reg_cntl1, ctrl1, vdac_hiu_reg_read(reg_cntl1));
+ }
+}
+
+unsigned int vdac_get_reg_addr(unsigned int index)
+{
+ unsigned int reg;
+
+ if (!s_vdac_data) {
+ pr_err("\n%s: s_vdac_data NULL\n", __func__);
+ return 0xffffffff;
+ }
+
+ if (index)
+ reg = s_vdac_data->reg_cntl1;
+ else
+ reg = s_vdac_data->reg_cntl0;
+
+ return reg;
+}
+
int vdac_enable_check_dtv(void)
{
- return (pri_flag & VDAC_MODULE_DTV_DEMOD) ? 1:0;
+ return (pri_flag & VDAC_MODULE_DTV_DEMOD) ? 1 : 0;
+}
+
+int vdac_enable_check_cvbs(void)
+{
+ return (pri_flag & VDAC_MODULE_CVBS_OUT) ? 1 : 0;
+}
+
+/* ********************************************************* */
+static ssize_t vdac_info_show(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+
+ if (!s_vdac_data)
+ return sprintf(buf, "vdac data is NULL\n");
+
+ len = sprintf(buf, "vdac driver info:\n");
+ len += sprintf(buf + len,
+ "chip_type: %s(%d)\n"
+ "private_flag: 0x%02x\n"
+ "reg_cntl0: 0x%02x=0x%08x\n"
+ "reg_cntl1: 0x%02x=0x%08x\n"
+ "debug_print: %d\n",
+ s_vdac_data->name, s_vdac_data->cpu_id, pri_flag,
+ s_vdac_data->reg_cntl0,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl0),
+ s_vdac_data->reg_cntl1,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl1),
+ vdac_debug_print);
+
+ return len;
+}
+
+static const char *vdac_debug_usage_str = {
+"Usage:\n"
+" cat /sys/class/amvdac/info ; print vdac information\n"
+" echo flag > /sys/class/amvdac/debug ; vdac_private_flag config\n"
+" echo print <val_dec> > /sys/class/amvdac/debug ; vdac_debug_print config\n"
+};
+
+static ssize_t vdac_debug_show(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", vdac_debug_usage_str);
+}
+
+static void vdac_parse_param(char *buf_orig, char **parm)
+{
+ char *ps, *token;
+ char delim1[3] = " ";
+ char delim2[2] = "\n";
+ unsigned int n = 0;
+
+ ps = buf_orig;
+ strcat(delim1, delim2);
+ while (1) {
+ token = strsep(&ps, delim1);
+ if (!token)
+ break;
+ if (*token == '\0')
+ continue;
+ parm[n++] = token;
+ }
}
+static ssize_t vdac_debug_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buff, size_t count)
+{
+ char *buf_orig;
+ char *parm[3] = {NULL};
+
+ if (!s_vdac_data) {
+ pr_info("vdac data is null\n");
+ return count;
+ }
+
+ buf_orig = kstrdup(buff, GFP_KERNEL);
+ vdac_parse_param(buf_orig, (char **)&parm);
+ if (!parm[0])
+ return count;
+
+ if (!strcmp(parm[0], "flag")) {
+ pr_info("vdac_private_flag: 0x%x\n", pri_flag);
+ } else if (!strcmp(parm[0], "print")) {
+ if (parm[1]) {
+ if (kstrtouint(parm[1], 10, &vdac_debug_print) < 0)
+ goto vdac_store_err;
+ }
+ pr_info("vdac_debug_print:%d\n", vdac_debug_print);
+ } else {
+ pr_info("invalid cmd\n");
+ }
+
+ kfree(buf_orig);
+ return count;
+
+vdac_store_err:
+ kfree(buf_orig);
+ return -EINVAL;
+}
+
+static struct class_attribute vdac_class_attrs[] = {
+ __ATTR(info, 0644, vdac_info_show, NULL),
+ __ATTR(debug, 0644, vdac_debug_show, vdac_debug_store),
+};
+
+static int vdac_create_class(struct amvdac_dev_s *devp)
+{
+ int i;
+
+ if (IS_ERR_OR_NULL(devp->clsp)) {
+ pr_err("vdac: %s debug class is null\n", __func__);
+ return -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vdac_class_attrs); i++) {
+ if (class_create_file(devp->clsp, &vdac_class_attrs[i])) {
+ pr_err("vdac: create debug attribute %s failed\n",
+ vdac_class_attrs[i].attr.name);
+ }
+ }
+
+ return 0;
+}
+
+static int vdac_remove_class(struct amvdac_dev_s *devp)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vdac_class_attrs); i++)
+ class_remove_file(devp->clsp, &vdac_class_attrs[i]);
+
+ class_destroy(devp->clsp);
+ devp->clsp = NULL;
+
+ return 0;
+}
+
+/* ********************************************************* */
+
static int amvdac_open(struct inode *inode, struct file *file)
{
struct amvdac_dev_s *devp;
@@ -549,97 +645,22 @@ static const struct file_operations amvdac_fops = {
.release = amvdac_release,
};
-struct meson_vdac_data meson_gxtvbb_vdac_data = {
- .cpu_id = VDAC_CPU_GXTVBB,
- .name = "meson-gxtvbb-vdac",
-};
-
-struct meson_vdac_data meson_gx_l_m_vdac_data = {
- .cpu_id = VDAC_CPU_GX_L_M,
- .name = "meson-gx_l_m-vdac",
-};
-
-struct meson_vdac_data meson_txl_vdac_data = {
- .cpu_id = VDAC_CPU_TXL,
- .name = "meson-txl-vdac",
-};
-
-struct meson_vdac_data meson_txlx_vdac_data = {
- .cpu_id = VDAC_CPU_TXLX,
- .name = "meson-txlx-vdac",
-};
-
-struct meson_vdac_data meson_gxlx_vdac_data = {
- .cpu_id = VDAC_CPU_GXLX,
- .name = "meson-gxlx-vdac",
-};
-
-struct meson_vdac_data meson_txhd_vdac_data = {
- .cpu_id = VDAC_CPU_TXHD,
- .name = "meson-txhd-vdac",
-};
-
-struct meson_vdac_data meson_g12ab_vdac_data = {
- .cpu_id = VDAC_CPU_G12AB,
- .name = "meson-g12ab-vdac",
-};
-
-struct meson_vdac_data meson_tl1_vdac_data = {
- .cpu_id = VDAC_CPU_TL1,
- .name = "meson-tl1-vdac",
-};
-
-static const struct of_device_id meson_vdac_dt_match[] = {
- {
- .compatible = "amlogic, vdac-gxtvbb",
- .data = &meson_gxtvbb_vdac_data,
- }, {
- .compatible = "amlogic, vdac-gxl",
- .data = &meson_gx_l_m_vdac_data,
- }, {
- .compatible = "amlogic, vdac-gxm",
- .data = &meson_gx_l_m_vdac_data,
- }, {
- .compatible = "amlogic, vdac-txl",
- .data = &meson_txl_vdac_data,
- }, {
- .compatible = "amlogic, vdac-txlx",
- .data = &meson_txlx_vdac_data,
- }, {
- .compatible = "amlogic, vdac-gxlx",
- .data = &meson_gxlx_vdac_data,
- }, {
- .compatible = "amlogic, vdac-txhd",
- .data = &meson_txhd_vdac_data,
- }, {
- .compatible = "amlogic, vdac-g12a",
- .data = &meson_g12ab_vdac_data,
- }, {
- .compatible = "amlogic, vdac-g12b",
- .data = &meson_g12ab_vdac_data,
- }, {
- .compatible = "amlogic, vdac-tl1",
- .data = &meson_tl1_vdac_data,
- },
- {},
-};
+/* ********************************************************* */
static int aml_vdac_probe(struct platform_device *pdev)
{
int ret = 0;
- const struct of_device_id *match;
struct amvdac_dev_s *devp = &amvdac_dev;
memset(devp, 0, (sizeof(struct amvdac_dev_s)));
- match = of_match_device(meson_vdac_dt_match, &pdev->dev);
- if (match == NULL) {
- pr_err("%s,no matched table\n", __func__);
- return -1;
+ s_vdac_data = aml_vdac_config_probe(pdev);
+ if (!s_vdac_data) {
+ pr_err("%s: config probe failed\n", __func__);
+ return ret;
}
- s_vdac_data = (struct meson_vdac_data *)match->data;
- pr_info("%s:probe start.cpu_id:%d,name:%s\n", __func__,
- s_vdac_data->cpu_id, s_vdac_data->name);
+
+ mutex_init(&vdac_mutex);
ret = alloc_chrdev_region(&devp->devno, 0, 1, AMVDAC_NAME);
if (ret < 0)
@@ -664,6 +685,8 @@ static int aml_vdac_probe(struct platform_device *pdev)
goto fail_create_device;
}
+ vdac_create_class(devp);
+
pr_info("%s: ok\n", __func__);
return ret;
@@ -687,11 +710,14 @@ static int __exit aml_vdac_remove(struct platform_device *pdev)
{
struct amvdac_dev_s *devp = &amvdac_dev;
+ vdac_remove_class(devp);
device_destroy(devp->clsp, devp->devno);
cdev_del(&devp->cdev);
class_destroy(devp->clsp);
unregister_chrdev_region(devp->devno, 1);
+ mutex_destroy(&vdac_mutex);
+
pr_info("%s: amvdac_exit.\n", __func__);
return 0;
@@ -701,14 +727,23 @@ static int __exit aml_vdac_remove(struct platform_device *pdev)
static int amvdac_drv_suspend(struct platform_device *pdev,
pm_message_t state)
{
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL)
- vdac_hiu_reg_write(HHI_VDAC_CNTL0, 0);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
+ s_vdac_data->cpu_id == VDAC_CPU_TXLX)
+ vdac_hiu_reg_write(s_vdac_data->reg_cntl0, 0);
+ else if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2)
+ vdac_ctrl_config(0, s_vdac_data->reg_cntl1, 7);
pr_info("%s: suspend module\n", __func__);
return 0;
}
static int amvdac_drv_resume(struct platform_device *pdev)
{
+ /*0xbc[7] for bandgap enable: 0:enable,1:disable*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ vdac_ctrl_config(1, s_vdac_data->reg_cntl1, 7);
+ }
pr_info("%s: resume module\n", __func__);
return 0;
}
@@ -718,7 +753,8 @@ static void amvdac_drv_shutdown(struct platform_device *pdev)
{
unsigned int cntl0, cntl1;
- pr_info("%s: shutdown module\n", __func__);
+ pr_info("%s: shutdown module, private_flag:0x%x\n",
+ __func__, pri_flag);
cntl0 = 0x0;
if (is_meson_txl_cpu() || is_meson_txlx_cpu())
cntl1 = 0x0;
@@ -739,31 +775,23 @@ static struct platform_driver aml_vdac_driver = {
.suspend = amvdac_drv_suspend,
.resume = amvdac_drv_resume,
#endif
- .shutdown = amvdac_drv_shutdown,
+ .shutdown = amvdac_drv_shutdown,
};
static int __init aml_vdac_init(void)
{
- pr_info("%s: module init\n", __func__);
-
- vdac_init_succ_flag = 0;
s_vdac_data = NULL;
- mutex_init(&vdac_mutex);
-
if (platform_driver_register(&aml_vdac_driver)) {
pr_err("%s: failed to register vdac driver module\n", __func__);
return -ENODEV;
}
- vdac_init_succ_flag = 1;
return 0;
}
static void __exit aml_vdac_exit(void)
{
- mutex_destroy(&vdac_mutex);
- pr_info("%s: module exit\n", __func__);
platform_driver_unregister(&aml_vdac_driver);
}
diff --git a/drivers/amlogic/media/vout/vdac/vdac_dev.h b/drivers/amlogic/media/vout/vdac/vdac_dev.h
new file mode 100644
index 0000000..695e28c
--- a/dev/null
+++ b/drivers/amlogic/media/vout/vdac/vdac_dev.h
@@ -0,0 +1,69 @@
+/*
+ * drivers/amlogic/media/vout/vdac/vdac_dev.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _VDAC_DEV_H_
+#define _VDAC_DEV_H_
+
+#define HHI_VDAC_CNTL0 0xbd
+#define HHI_VDAC_CNTL1 0xbe
+#define HHI_VDAC_CNTL0_G12A 0xbb
+#define HHI_VDAC_CNTL1_G12A 0xbc
+
+#define HHI_VIID_CLK_DIV 0x4a
+#define HHI_VIID_CLK_CNTL 0x4b
+#define HHI_VIID_DIVIDER_CNTL 0x4c
+#define HHI_VID_CLK_CNTL2 0x65
+#define HHI_VID_DIVIDER_CNTL 0x66
+
+#define VENC_VDAC_DACSEL0 0x1b78
+
+#define VDAC_CTRL_MAX 10
+
+enum vdac_cpu_type {
+ VDAC_CPU_GX_L_M = 0,
+ VDAC_CPU_TXL = 1,
+ VDAC_CPU_TXLX = 2,
+ VDAC_CPU_GXLX = 3,
+ VDAC_CPU_G12AB = 4,
+ VDAC_CPU_TL1 = 5,
+ VDAC_CPU_SM1 = 6,
+ VDAC_CPU_TM2 = 7,
+ VDAC_CPU_MAX,
+};
+
+#define VDAC_REG_MAX 0xffff
+
+struct meson_vdac_data {
+ enum vdac_cpu_type cpu_id;
+ const char *name;
+
+ unsigned int reg_cntl0;
+ unsigned int reg_cntl1;
+ struct meson_vdac_ctrl_s *ctrl_table;
+};
+
+struct meson_vdac_ctrl_s {
+ unsigned int reg;
+ unsigned int val;
+ unsigned int bit;
+ unsigned int len;
+};
+
+extern const struct of_device_id meson_vdac_dt_match[];
+struct meson_vdac_data *aml_vdac_config_probe(struct platform_device *pdev);
+
+#endif
diff --git a/include/linux/amlogic/media/vout/vdac_dev.h b/include/linux/amlogic/media/vout/vdac_dev.h
index 69031fe..f5d326b 100644
--- a/include/linux/amlogic/media/vout/vdac_dev.h
+++ b/include/linux/amlogic/media/vout/vdac_dev.h
@@ -15,26 +15,20 @@
*
*/
-#ifndef _VDAC_DEV_H_
-#define _VDAC_DEV_H_
+#ifndef _INC_VDAC_DEV_H_
+#define _INC_VDAC_DEV_H_
-enum vdac_cpu_type {
- VDAC_CPU_GXTVBB = 0,
- VDAC_CPU_GX_L_M = 1,
- VDAC_CPU_TXL = 2,
- VDAC_CPU_TXLX = 3,
- VDAC_CPU_GXLX = 4,
- VDAC_CPU_TXHD = 5,
- VDAC_CPU_G12AB = 6,
- VDAC_CPU_TL1 = 7,
- VDAC_CPU_MAX,
-};
+#define VDAC_MODULE_MASK (0x1f)
+#define VDAC_MODULE_AVOUT_ATV 0x1
+#define VDAC_MODULE_DTV_DEMOD 0x2
+#define VDAC_MODULE_AVOUT_AV 0x4
+#define VDAC_MODULE_CVBS_OUT 0x8
+#define VDAC_MODULE_AUDIO_OUT 0x10
-struct meson_vdac_data {
- enum vdac_cpu_type cpu_id;
- const char *name;
-};
-
-extern void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1);
+void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1);
+void vdac_enable(bool on, unsigned int module_sel);
+int vdac_enable_check_dtv(void);
+int vdac_enable_check_cvbs(void);
+unsigned int vdac_get_reg_addr(unsigned int index);
#endif