author | Evoke 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) |
commit | 6f878ef98ec345419a10d7a165fd13c2b317616c (patch) | |
tree | ce00e93f07c35b91ae28e47006ce28a4b779c269 | |
parent | 15fb89454bd0ad46d05d46cd22725e1bb165b6d7 (diff) | |
download | common-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>
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 |