From f645e84376082020a47c0aafcd19ad343f5998d1 Mon Sep 17 00:00:00 2001 From: Jihong Sui Date: Sat, 28 Apr 2018 12:51:24 +0800 Subject: [PATCH] dtv_demod: add dtv demod for txlx PD#165005: dtv_demod: add dtv demod for txlx Change-Id: I311fea46351644902a5e886be4623601e21ec6ac Signed-off-by: Jihong Sui --- MAINTAINERS | 5 + arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts | 24 + arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts | 24 + arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts | 24 + .../boot/dts/amlogic/txlx_t962x_r311_720p.dts | 24 + arch/arm64/configs/meson64_defconfig | 1 + drivers/amlogic/media/Kconfig | 2 +- drivers/amlogic/media/Makefile | 1 + drivers/amlogic/media/amldemod/Kconfig | 17 + drivers/amlogic/media/amldemod/Makefile | 18 + drivers/amlogic/media/amldemod/aml_demod.c | 708 ++++ drivers/amlogic/media/amldemod/amlfrontend.c | 4041 ++++++++++++++++++++ drivers/amlogic/media/amldemod/atsc_func.c | 1658 ++++++++ drivers/amlogic/media/amldemod/demod_func.c | 1538 ++++++++ drivers/amlogic/media/amldemod/dtmb_func.c | 762 ++++ drivers/amlogic/media/amldemod/dvbc_func.c | 371 ++ drivers/amlogic/media/amldemod/dvbc_v2.c | 876 +++++ drivers/amlogic/media/amldemod/dvbc_v3.c | 521 +++ drivers/amlogic/media/amldemod/dvbt_v2.c | 783 ++++ drivers/amlogic/media/amldemod/i2c_func.c | 40 + .../amldemod/include/acf_filter_coefficient.h | 412 ++ .../amlogic/media/amldemod/include/addr_dtmb_che.h | 75 + .../media/amldemod/include/addr_dtmb_che_bit.h | 264 ++ .../media/amldemod/include/addr_dtmb_front.h | 68 + .../media/amldemod/include/addr_dtmb_front_bit.h | 434 +++ .../media/amldemod/include/addr_dtmb_sync.h | 51 + .../media/amldemod/include/addr_dtmb_sync_bit.h | 111 + .../amlogic/media/amldemod/include/addr_dtmb_top.h | 90 + .../media/amldemod/include/addr_dtmb_top_bit.h | 362 ++ .../amlogic/media/amldemod/include/amlfrontend.h | 435 +++ drivers/amlogic/media/amldemod/include/atsc_func.h | 83 + .../amlogic/media/amldemod/include/demod_func.h | 824 ++++ drivers/amlogic/media/amldemod/include/depend.h | 53 + drivers/amlogic/media/amldemod/tuner_func.c | 232 ++ include/uapi/linux/dvb/aml_demod.h | 223 ++ 35 files changed, 15154 insertions(+), 1 deletion(-) create mode 100644 drivers/amlogic/media/amldemod/Kconfig create mode 100644 drivers/amlogic/media/amldemod/Makefile create mode 100644 drivers/amlogic/media/amldemod/aml_demod.c create mode 100644 drivers/amlogic/media/amldemod/amlfrontend.c create mode 100644 drivers/amlogic/media/amldemod/atsc_func.c create mode 100644 drivers/amlogic/media/amldemod/demod_func.c create mode 100644 drivers/amlogic/media/amldemod/dtmb_func.c create mode 100644 drivers/amlogic/media/amldemod/dvbc_func.c create mode 100644 drivers/amlogic/media/amldemod/dvbc_v2.c create mode 100644 drivers/amlogic/media/amldemod/dvbc_v3.c create mode 100644 drivers/amlogic/media/amldemod/dvbt_v2.c create mode 100644 drivers/amlogic/media/amldemod/i2c_func.c create mode 100644 drivers/amlogic/media/amldemod/include/acf_filter_coefficient.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_che.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_che_bit.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_front.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_front_bit.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_sync.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_sync_bit.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_top.h create mode 100644 drivers/amlogic/media/amldemod/include/addr_dtmb_top_bit.h create mode 100644 drivers/amlogic/media/amldemod/include/amlfrontend.h create mode 100644 drivers/amlogic/media/amldemod/include/atsc_func.h create mode 100644 drivers/amlogic/media/amldemod/include/demod_func.h create mode 100644 drivers/amlogic/media/amldemod/include/depend.h create mode 100644 drivers/amlogic/media/amldemod/tuner_func.c create mode 100644 include/uapi/linux/dvb/aml_demod.h diff --git a/MAINTAINERS b/MAINTAINERS index f8cc6fb..ef4bc99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14437,3 +14437,8 @@ M: Weiming Liu F: drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c F: drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.h +AMLOGIC DTV DEMOD DRIVER +M: Jihong Sui +F: include/uapi/linux/dvb/aml_demod.h +F: drivers/amlogic/media/aml_demod/* + diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts index 2c955fb..c031611 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts @@ -1279,7 +1279,31 @@ // &clock GCLK_IDX_U_PARSER_TOP>; //reset-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; }; + aml_dtv_demod { + compatible = "amlogic, ddemod-txlx"; + dev_name = "aml_dtv_demod"; + status = "disable"; + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + + reg = <0x0 0xff644000 0x0 0x2000 /*dtv demod base*/ + 0x0 0xff63c000 0x0 0x2000 /*hiu reg base*/ + 0x0 0xff800000 0x0 0x1000 /*io_aobus_base*/ + 0x0 0xffd01000 0x0 0x1000 /*reset*/ + >; + /*move from dvbfe*/ + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + memory-region = <&demod_cma_reserved>;//<&demod_reserved>; + }; dvbfe { compatible = "amlogic, dvbfe"; dev_name = "dvbfe"; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts index 33f92d2..dd090f9 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -1312,7 +1312,31 @@ // &clock GCLK_IDX_U_PARSER_TOP>; //reset-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; }; + aml_dtv_demod { + compatible = "amlogic, ddemod-txlx"; + dev_name = "aml_dtv_demod"; + status = "disable"; + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + + reg = <0x0 0xff644000 0x0 0x2000 /*dtv demod base*/ + 0x0 0xff63c000 0x0 0x2000 /*hiu reg base*/ + 0x0 0xff800000 0x0 0x1000 /*io_aobus_base*/ + 0x0 0xffd01000 0x0 0x1000 /*reset*/ + >; + /*move from dvbfe*/ + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + memory-region = <&demod_cma_reserved>;//<&demod_reserved>; + }; dvbfe { compatible = "amlogic, dvbfe"; dev_name = "dvbfe"; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index d1f7e44..4b326c2 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -1312,7 +1312,31 @@ // &clock GCLK_IDX_U_PARSER_TOP>; //reset-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; }; + aml_dtv_demod { + compatible = "amlogic, ddemod-txlx"; + dev_name = "aml_dtv_demod"; + status = "disable"; + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + + reg = <0x0 0xff644000 0x0 0x2000 /*dtv demod base*/ + 0x0 0xff63c000 0x0 0x2000 /*hiu reg base*/ + 0x0 0xff800000 0x0 0x1000 /*io_aobus_base*/ + 0x0 0xffd01000 0x0 0x1000 /*reset*/ + >; + /*move from dvbfe*/ + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + memory-region = <&demod_cma_reserved>;//<&demod_reserved>; + }; dvbfe { compatible = "amlogic, dvbfe"; dev_name = "dvbfe"; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts index a663a8b..0348d96 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts @@ -1311,7 +1311,31 @@ // &clock GCLK_IDX_U_PARSER_TOP>; //reset-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; }; + aml_dtv_demod { + compatible = "amlogic, ddemod-txlx"; + dev_name = "aml_dtv_demod"; + status = "disable"; + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + + reg = <0x0 0xff644000 0x0 0x2000 /*dtv demod base*/ + 0x0 0xff63c000 0x0 0x2000 /*hiu reg base*/ + 0x0 0xff800000 0x0 0x1000 /*io_aobus_base*/ + 0x0 0xffd01000 0x0 0x1000 /*reset*/ + >; + /*move from dvbfe*/ + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + memory-region = <&demod_cma_reserved>;//<&demod_reserved>; + }; dvbfe { compatible = "amlogic, dvbfe"; dev_name = "dvbfe"; diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 296368a..6dc65e6 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -309,6 +309,7 @@ CONFIG_AMLOGIC_PIC_DEC=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y +CONFIG_AMLOGIC_DTV_DEMOD=y CONFIG_AMLOGIC_MMC=y CONFIG_AMLOGIC_NAND=y CONFIG_AMLOGIC_VRTC=y diff --git a/drivers/amlogic/media/Kconfig b/drivers/amlogic/media/Kconfig index 009b3bb..1c7758f 100644 --- a/drivers/amlogic/media/Kconfig +++ b/drivers/amlogic/media/Kconfig @@ -53,5 +53,5 @@ source "drivers/amlogic/media/vin/Kconfig" source "drivers/amlogic/media/video_processor/Kconfig" source "drivers/amlogic/media/enhancement/Kconfig" endif - +source "drivers/amlogic/media/amldemod/Kconfig" endmenu diff --git a/drivers/amlogic/media/Makefile b/drivers/amlogic/media/Makefile index 5a884df..e22a933 100644 --- a/drivers/amlogic/media/Makefile +++ b/drivers/amlogic/media/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += deinterlace/ obj-$(CONFIG_AMLOGIC_MEDIA_VIN) += vin/ obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR) += video_processor/ obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT) += enhancement/ +obj-$(CONFIG_AMLOGIC_DTV_DEMOD) += amldemod/ diff --git a/drivers/amlogic/media/amldemod/Kconfig b/drivers/amlogic/media/amldemod/Kconfig new file mode 100644 index 0000000..9ca4aa3 --- /dev/null +++ b/drivers/amlogic/media/amldemod/Kconfig @@ -0,0 +1,17 @@ +# +# DTV driver configuration +# + +menu "Amlogic DTV driver" + +config AMLOGIC_DTV_DEMOD + tristate "Amlogic DTVDEMOD device driver" + default n + help + DTVDEMOD device driver. + Y: enable + N: disable + M: build as module + +endmenu + diff --git a/drivers/amlogic/media/amldemod/Makefile b/drivers/amlogic/media/amldemod/Makefile new file mode 100644 index 0000000..272531f --- /dev/null +++ b/drivers/amlogic/media/amldemod/Makefile @@ -0,0 +1,18 @@ + +obj-$(CONFIG_AMLOGIC_DTV_DEMOD) += dtvdemod.o +#obj-y += dtvdemod.o +#obj-m += dtvdemod.o + +dtvdemod-objs := demod_func.o dvbc_func.o i2c_func.o tuner_func.o atsc_func.o dvbc_v2.o dvbc_v3.o dtmb_func.o dvbt_v2.o#dvbt_func.o + +dtvdemod-objs += amlfrontend.o + +dtvdemod-objs += aml_demod.o + + +ccflags-y += -I. +ccflags-y += -I$(srctree)/drivers/media/dvb-core +ccflags-y += -Idrivers/amlogic/media/amldemod/include +#ccflags-y += -I./include +#ccflags-y += -Idrivers/amlogic/dvb_tv/ +ccflags-y += -DDVB_CORE_ORI=1 -DDVB_49=1 -DDEBUG diff --git a/drivers/amlogic/media/amldemod/aml_demod.c b/drivers/amlogic/media/amldemod/aml_demod.c new file mode 100644 index 0000000..c9cf7f1 --- /dev/null +++ b/drivers/amlogic/media/amldemod/aml_demod.c @@ -0,0 +1,708 @@ +/* + * drivers/amlogic/media/amldemod/aml_demod.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* #include */ +#include +#include + +/* #include */ +#include +#include +#include "demod_func.h" + +#include +#ifdef CONFIG_COMPAT +#include +#endif +/*#include "sdio/sdio_init.h"*/ +#define DRIVER_NAME "aml_demod" +#define MODULE_NAME "aml_demod" +#define DEVICE_NAME "aml_demod" +#define DEVICE_UI_NAME "aml_demod_ui" + +#define pr_dbg(a ...) \ + do { \ + if (1) { \ + printk(a); \ + } \ + } while (0) + + +const char aml_demod_dev_id[] = "aml_demod"; +#define CONFIG_AM_DEMOD_DVBAPI /*ary temp*/ + +/******************************* + *#ifndef CONFIG_AM_DEMOD_DVBAPI + * static struct aml_demod_i2c demod_i2c; + * static struct aml_demod_sta demod_sta; + * #else + * extern struct aml_demod_i2c demod_i2c; + * extern struct aml_demod_sta demod_sta; + * #endif + *******************************/ + +static struct aml_demod_sta demod_sta; +static int read_start; + +int sdio_read_ddr(unsigned long sdio_addr, unsigned long byte_count, + unsigned char *data_buf) +{ + return 0; +} + +int sdio_write_ddr(unsigned long sdio_addr, unsigned long byte_count, + unsigned char *data_buf) +{ + return 0; +} +#if 0 +int read_reg(int addr) +{ + addr = addr + ddemod_reg_base; /* DEMOD_BASE;*/ + return apb_read_reg(addr); +} +#endif +void wait_capture(int cap_cur_addr, int depth_MB, int start) +{ + int readfirst; + int tmp; + int time_out; + int last = 0x90000000; + + time_out = readfirst = 0; + tmp = depth_MB << 20; + while (tmp && (time_out < 1000)) { /*10seconds time out */ + time_out = time_out + 1; + msleep(20); + readfirst = app_apb_read_reg(cap_cur_addr); + if ((last - readfirst) > 0) + tmp = 0; + else + last = readfirst; + /* usleep(1000); */ + /* readsecond= app_apb_read_reg(cap_cur_addr); */ + + /* if((readsecond-start)>tmp) */ +/* tmp=0;*/ +/* if((readsecond-readfirst)<0) // turn around*/ +/* tmp=0;*/ + pr_dbg("First %x = [%08x],[%08x]%x\n", cap_cur_addr, readfirst, + last, (last - readfirst)); +/* printf("Second %x = [%08x]\n",cap_cur_addr, readsecond);*/ + msleep(20); + } + read_start = readfirst + 0x40000000; + pr_dbg("read_start is %x\n", read_start); +} + +int cap_adc_data(struct aml_cap_data *cap) +{ + int tmp; + int tb_depth; + + pr_dbg("capture ADC\n "); + /* printf("set mem_start (you can read in kernel start log */ + /* (memstart is ).(hex) : ");*/ + /* scanf("%x",&tmp);*/ + tmp = 0x94400000; + app_apb_write_reg(0x9d, cap->cap_addr); + app_apb_write_reg(0x9e, cap->cap_addr + cap->cap_size * 0x100000); + /*0x8000000-128m, 0x400000-4m */ + read_start = tmp + 0x40000000; + /*printf("set afifo rate. (hex)(adc_clk/demod_clk)*256+2 : "); // */ + /* (adc_clk/demod_clk)*256+2 */ + /* scanf("%x",&tmp); */ + cap->cap_afifo = 0x60; + app_apb_write_reg(0x15, 0x18715f2); + app_apb_write_reg(0x15, (app_apb_read_reg(0x15) & 0xfff00fff) | + ((cap->cap_afifo & 0xff) << 12)); /* set afifo */ + app_apb_write_reg(0x9b, 0x1c9); /* capture ADC 10bits */ + app_apb_write_reg(0x7f, 0x00008000); /* enable testbus 0x8000 */ + + tb_depth = cap->cap_size; /*127; */ + tmp = 9; + app_apb_write_reg(0x9b, (app_apb_read_reg(0x9b) & ~0x1f) | tmp); + /* set testbus width */ + + tmp = 0x100000; + app_apb_write_reg(0x9c, tmp); /* by ADC data enable */ + /* printf("Set test mode. (0 is normal ,1 is testmode) : "); //0 */ + /* scanf("%d",&tmp); */ + tmp = 0; + if (tmp == 1) + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 10)); + /* set test mode; */ + else + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 10)); + /* close test mode; */ + + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 9)); + /* close cap; */ + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 9)); + /* open cap; */ + + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 7)); + /* close tb; */ + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 7)); + /* open tb; */ + + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 5)); + /* close intlv; */ + + app_apb_write_reg(0x303, 0x8); /* open dc_arbit */ + + tmp = 0; + if (tmp) + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 5)); + /* open intlv; */ + + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 8)); + /* go tb; */ + + wait_capture(0x9f, tb_depth, app_apb_read_reg(0x9d)); + + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 8)); + /* stop tb; */ + app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 7)); + /* close tb; */ + return 0; +} + +static DECLARE_WAIT_QUEUE_HEAD(lock_wq); + +static ssize_t aml_demod_info(struct class *cla, + struct class_attribute *attr, char *buf) +{ + return 0; +} + +static struct class_attribute aml_demod_class_attrs[] = { + __ATTR(info, + 0644, + aml_demod_info, + NULL), + __ATTR_NULL +}; + +static struct class aml_demod_class = { + .name = "aml_demod", + .class_attrs = aml_demod_class_attrs, +}; + + +static int aml_demod_open(struct inode *inode, struct file *file) +{ + pr_dbg("Amlogic Demod DVB-T/C Open\n"); + return 0; +} + +static int aml_demod_release(struct inode *inode, struct file *file) +{ + pr_dbg("Amlogic Demod DVB-T/C Release\n"); + return 0; +} + +#if 0 +static int amdemod_islock(void) +{ + struct aml_demod_sts demod_sts; + + if (demod_sta.dvb_mode == 0) { + dvbc_status(&demod_sta, &demod_i2c, &demod_sts); + return demod_sts.ch_sts & 0x1; + } else if (demod_sta.dvb_mode == 1) { + dvbt_status(&demod_sta, &demod_i2c, &demod_sts); + return demod_sts.ch_sts >> 12 & 0x1; + } + return 0; +} +#endif + +void mem_read(struct aml_demod_mem *arg) +{ + int data; + int addr; + + addr = arg->addr; + data = arg->dat; +/* memcpy(mem_buf[addr],data,1);*/ + pr_dbg("[addr %x] data is %x\n", addr, data); +} +static long aml_demod_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int strength = 0; + struct dvb_frontend *dvbfe; + struct aml_tuner_sys *tuner; + + switch (cmd) { + case AML_DEMOD_GET_RSSI: + pr_dbg("Ioctl Demod GET_RSSI.\n"); + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ +#if 0 + if (dvbfe != NULL) + strength = dvbfe->ops.tuner_ops.get_strength(dvbfe); +#else + strength = tuner_get_ch_power2(); +#endif + pr_dbg("[si2177] strength is %d\n", strength - 256); + if (strength < 0) + strength = 0 - strength; + tuner = (struct aml_tuner_sys *)arg; + tuner->rssi = strength; + break; + + case AML_DEMOD_SET_TUNER: + pr_dbg("Ioctl Demod Set Tuner.\n"); + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ + #if 0 /*ary temp for my_tool:*/ + if (dvbfe != NULL) + dvbfe->ops.tuner_ops.set_tuner(dvbfe, &demod_sta, + &demod_i2c, + (struct aml_tuner_sys *) + arg); + #endif + break; + + case AML_DEMOD_SET_SYS: + pr_dbg("Ioctl Demod Set System\n"); + demod_set_sys(&demod_sta,/* &demod_i2c,*/ + (struct aml_demod_sys *)arg); + break; + + case AML_DEMOD_GET_SYS: + pr_dbg("Ioctl Demod Get System\n"); + + /*demod_get_sys(&demod_i2c, (struct aml_demod_sys *)arg); */ + break; + + case AML_DEMOD_TEST: + pr_dbg("Ioctl Demod Test. It is blank now\n"); + /*demod_msr_clk(13); */ + /*demod_msr_clk(14); */ + /*demod_calc_clk(&demod_sta); */ + break; + + case AML_DEMOD_TURN_ON: + pr_dbg("Ioctl Demod Turn ON.It is blank now\n"); + /*demod_turn_on(&demod_sta, (struct aml_demod_sys *)arg); */ + break; + + case AML_DEMOD_TURN_OFF: + pr_dbg("Ioctl Demod Turn OFF.It is blank now\n"); + /*demod_turn_off(&demod_sta, (struct aml_demod_sys *)arg); */ + break; + + case AML_DEMOD_DVBC_SET_CH: + pr_dbg("Ioctl DVB-C Set Channel.\n"); + dvbc_set_ch(&demod_sta,/* &demod_i2c,*/ + (struct aml_demod_dvbc *)arg); + break; + + case AML_DEMOD_DVBC_GET_CH: + /* pr_dbg("Ioctl DVB-C Get Channel. It is blank\n"); */ + dvbc_status(&demod_sta, /*&demod_i2c,*/ + (struct aml_demod_sts *)arg); + break; + case AML_DEMOD_DVBC_TEST: + pr_dbg("Ioctl DVB-C Test. It is blank\n"); + /*dvbc_get_test_out(0xb, 1000, (u32 *)arg); */ + break; + case AML_DEMOD_DVBT_SET_CH: + pr_dbg("Ioctl DVB-T Set Channel\n"); + dvbt_set_ch(&demod_sta, /*&demod_i2c,*/ + (struct aml_demod_dvbt *)arg); + break; + + case AML_DEMOD_DVBT_GET_CH: + pr_dbg("Ioctl DVB-T Get Channel\n"); + /*dvbt_status(&demod_sta, &demod_i2c,*/ + /* (struct aml_demod_sts *)arg); */ + break; + + case AML_DEMOD_DVBT_TEST: + pr_dbg("Ioctl DVB-T Test. It is blank\n"); + /*dvbt_get_test_out(0x1e, 1000, (u32 *)arg); */ + break; + + case AML_DEMOD_DTMB_SET_CH: + dtmb_set_ch(&demod_sta, /*&demod_i2c,*/ + (struct aml_demod_dtmb *)arg); + break; + + case AML_DEMOD_DTMB_GET_CH: + break; + + case AML_DEMOD_DTMB_TEST: + break; + + case AML_DEMOD_ATSC_SET_CH: + atsc_set_ch(&demod_sta, /*&demod_i2c,*/ + (struct aml_demod_atsc *)arg); + break; + + case AML_DEMOD_ATSC_GET_CH: + check_atsc_fsm_status(); + break; + + case AML_DEMOD_ATSC_TEST: + break; + + case AML_DEMOD_SET_REG: + /* pr_dbg("Ioctl Set Register\n"); */ + demod_set_reg((struct aml_demod_reg *)arg); + break; + + case AML_DEMOD_GET_REG: + /* pr_dbg("Ioctl Get Register\n"); */ + demod_get_reg((struct aml_demod_reg *)arg); + break; + +/* case AML_DEMOD_SET_REGS: */ +/* break; */ + +/* case AML_DEMOD_GET_REGS: */ +/* break; */ + + case AML_DEMOD_RESET_MEM: + pr_dbg("set mem ok\n"); + break; + + case AML_DEMOD_READ_MEM: + break; + case AML_DEMOD_SET_MEM: + /*step=(struct aml_demod_mem)arg;*/ + /* pr_dbg("[%x]0x%x------------------\n",i,mem_buf[step]); */ + /* for(i=step;i<1024-1;i++){ */ + /* pr_dbg("0x%x,",mem_buf[i]); */ + /* } */ + mem_read((struct aml_demod_mem *)arg); + break; + + case AML_DEMOD_ATSC_IRQ: + atsc_read_iqr_reg(); + break; + + default: + pr_dbg("Enter Default ! 0x%X\n", cmd); +/* pr_dbg("AML_DEMOD_GET_REGS=0x%08X\n", AML_DEMOD_GET_REGS); */ +/* pr_dbg("AML_DEMOD_SET_REGS=0x%08X\n", AML_DEMOD_SET_REGS); */ + return -EINVAL; + } + + return 0; +} + +#ifdef CONFIG_COMPAT + +static long aml_demod_compat_ioctl(struct file *file, unsigned int cmd, + ulong arg) +{ + return aml_demod_ioctl(file, cmd, (ulong)compat_ptr(arg)); +} + +#endif + + +static const struct file_operations aml_demod_fops = { + .owner = THIS_MODULE, + .open = aml_demod_open, + .release = aml_demod_release, + .unlocked_ioctl = aml_demod_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = aml_demod_compat_ioctl, +#endif +}; + +static int aml_demod_ui_open(struct inode *inode, struct file *file) +{ + pr_dbg("Amlogic aml_demod_ui_open Open\n"); + return 0; +} + +static int aml_demod_ui_release(struct inode *inode, struct file *file) +{ + pr_dbg("Amlogic aml_demod_ui_open Release\n"); + return 0; +} +char buf_all[100]; +static ssize_t aml_demod_ui_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + char *capture_buf = buf_all; + int res = 0; + + if (count >= 4 * 1024 * 1024) + count = 4 * 1024 * 1024; + else if (count == 0) + return 0; + + res = copy_to_user((void *)buf, (char *)capture_buf, count); + if (res < 0) { + pr_dbg("[aml_demod_ui_read]res is %d", res); + return res; + } + + return count; +} + +static ssize_t aml_demod_ui_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + return 0; +} + +static struct device *aml_demod_ui_dev; +static dev_t aml_demod_devno_ui; +static struct cdev *aml_demod_cdevp_ui; +static const struct file_operations aml_demod_ui_fops = { + .owner = THIS_MODULE, + .open = aml_demod_ui_open, + .release = aml_demod_ui_release, + .read = aml_demod_ui_read, + .write = aml_demod_ui_write, + /* .unlocked_ioctl = aml_demod_ui_ioctl, */ +}; + +#if 0 +static ssize_t aml_demod_ui_info(struct class *cla, + struct class_attribute *attr, char *buf) +{ + return 0; +} + +static struct class_attribute aml_demod_ui_class_attrs[] = { + __ATTR(info, + 0644, + aml_demod_ui_info, + NULL), + __ATTR_NULL +}; +#endif + +static struct class aml_demod_ui_class = { + .name = "aml_demod_ui", +/* .class_attrs = aml_demod_ui_class_attrs,*/ +}; + +int aml_demod_ui_init(void) +{ + int r = 0; + + r = class_register(&aml_demod_ui_class); + if (r) { + pr_dbg("create aml_demod class fail\r\n"); + class_unregister(&aml_demod_ui_class); + return r; + } + + r = alloc_chrdev_region(&aml_demod_devno_ui, 0, 1, DEVICE_UI_NAME); + if (r < 0) { + PR_ERR("aml_demod_ui: failed to alloc major number\n"); + r = -ENODEV; + unregister_chrdev_region(aml_demod_devno_ui, 1); + class_unregister(&aml_demod_ui_class); + return r; + } + + aml_demod_cdevp_ui = kmalloc(sizeof(struct cdev), GFP_KERNEL); + if (!aml_demod_cdevp_ui) { + PR_ERR("aml_demod_ui: failed to allocate memory\n"); + r = -ENOMEM; + unregister_chrdev_region(aml_demod_devno_ui, 1); + kfree(aml_demod_cdevp_ui); + class_unregister(&aml_demod_ui_class); + return r; + } + /* connect the file operation with cdev */ + cdev_init(aml_demod_cdevp_ui, &aml_demod_ui_fops); + aml_demod_cdevp_ui->owner = THIS_MODULE; + /* connect the major/minor number to cdev */ + r = cdev_add(aml_demod_cdevp_ui, aml_demod_devno_ui, 1); + if (r) { + PR_ERR("aml_demod_ui:failed to add cdev\n"); + unregister_chrdev_region(aml_demod_devno_ui, 1); + cdev_del(aml_demod_cdevp_ui); + kfree(aml_demod_cdevp_ui); + class_unregister(&aml_demod_ui_class); + return r; + } + + aml_demod_ui_dev = device_create(&aml_demod_ui_class, NULL, + MKDEV(MAJOR(aml_demod_devno_ui), 0), + NULL, DEVICE_UI_NAME); + + if (IS_ERR(aml_demod_ui_dev)) { + pr_dbg("Can't create aml_demod device\n"); + unregister_chrdev_region(aml_demod_devno_ui, 1); + cdev_del(aml_demod_cdevp_ui); + kfree(aml_demod_cdevp_ui); + class_unregister(&aml_demod_ui_class); + return r; + } + + return r; +} + +void aml_demod_exit_ui(void) +{ + unregister_chrdev_region(aml_demod_devno_ui, 1); + cdev_del(aml_demod_cdevp_ui); + kfree(aml_demod_cdevp_ui); + class_unregister(&aml_demod_ui_class); +} + +static struct device *aml_demod_dev; +static dev_t aml_demod_devno; +static struct cdev *aml_demod_cdevp; + +#ifdef CONFIG_AM_DEMOD_DVBAPI +int aml_demod_init(void) +#else +static int __init aml_demod_init(void) +#endif +{ + int r = 0; + + pr_dbg("Amlogic Demod DVB-T/C DebugIF Init\n"); + + init_waitqueue_head(&lock_wq); + + /* hook demod isr */ + /* r = request_irq(INT_DEMOD, &aml_demod_isr, */ + /* IRQF_SHARED, "aml_demod", */ + /* (void *)aml_demod_dev_id); */ + /* if (r) { */ + /* pr_dbg("aml_demod irq register error.\n"); */ + /* r = -ENOENT; */ + /* goto err0; */ + /* } */ + + /* sysfs node creation */ + r = class_register(&aml_demod_class); + if (r) { + pr_dbg("create aml_demod class fail\r\n"); + goto err1; + } + + r = alloc_chrdev_region(&aml_demod_devno, 0, 1, DEVICE_NAME); + if (r < 0) { + PR_ERR("aml_demod: failed to alloc major number\n"); + r = -ENODEV; + goto err2; + } + + aml_demod_cdevp = kmalloc(sizeof(struct cdev), GFP_KERNEL); + if (!aml_demod_cdevp) { + PR_ERR("aml_demod: failed to allocate memory\n"); + r = -ENOMEM; + goto err3; + } + /* connect the file operation with cdev */ + cdev_init(aml_demod_cdevp, &aml_demod_fops); + aml_demod_cdevp->owner = THIS_MODULE; + /* connect the major/minor number to cdev */ + r = cdev_add(aml_demod_cdevp, aml_demod_devno, 1); + if (r) { + PR_ERR("aml_demod:failed to add cdev\n"); + goto err4; + } + + aml_demod_dev = device_create(&aml_demod_class, NULL, + MKDEV(MAJOR(aml_demod_devno), 0), NULL, + DEVICE_NAME); + + if (IS_ERR(aml_demod_dev)) { + pr_dbg("Can't create aml_demod device\n"); + goto err5; + } + pr_dbg("Amlogic Demod DVB-T/C DebugIF Init ok----------------\n"); +#if defined(CONFIG_AM_AMDEMOD_FPGA_VER) && !defined(CONFIG_AM_DEMOD_DVBAPI) + pr_dbg("sdio_init\n"); + sdio_init(); +#endif + aml_demod_ui_init(); + + return 0; + +err5: + cdev_del(aml_demod_cdevp); +err4: + kfree(aml_demod_cdevp); + +err3: + unregister_chrdev_region(aml_demod_devno, 1); + +err2: +/* free_irq(INT_DEMOD, (void *)aml_demod_dev_id);*/ + +err1: + class_unregister(&aml_demod_class); + +/* err0:*/ + return r; +} + +#ifdef CONFIG_AM_DEMOD_DVBAPI +void aml_demod_exit(void) +#else +static void __exit aml_demod_exit(void) +#endif +{ + pr_dbg("Amlogic Demod DVB-T/C DebugIF Exit\n"); + + unregister_chrdev_region(aml_demod_devno, 1); + device_destroy(&aml_demod_class, MKDEV(MAJOR(aml_demod_devno), 0)); + cdev_del(aml_demod_cdevp); + kfree(aml_demod_cdevp); + + /* free_irq(INT_DEMOD, (void *)aml_demod_dev_id); */ + + class_unregister(&aml_demod_class); + + aml_demod_exit_ui(); +} + +#ifndef CONFIG_AM_DEMOD_DVBAPI +module_init(aml_demod_init); +module_exit(aml_demod_exit); + +MODULE_LICENSE("GPL"); +/*MODULE_AUTHOR(DRV_AUTHOR);*/ +/*MODULE_DESCRIPTION(DRV_DESC);*/ +#endif diff --git a/drivers/amlogic/media/amldemod/amlfrontend.c b/drivers/amlogic/media/amldemod/amlfrontend.c new file mode 100644 index 0000000..42e02e2 --- /dev/null +++ b/drivers/amlogic/media/amldemod/amlfrontend.c @@ -0,0 +1,4041 @@ +/* + * drivers/amlogic/media/amldemod/amlfrontend.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. + * + */ + +/***************************************************************** + ** author : + ** Shijie.Rong@amlogic.com + ** version : + ** v1.0 12/3/13 + ** v2.0 15/10/12 + ** v3.0 17/11/15 + *****************************************************************/ +#define __DVB_CORE__ /*ary 2018-1-31*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include /*IS_ERR*/ +#include /*clk tree*/ +#include + + +#ifdef ARC_700 +#include +#else +/* #include */ +#endif +#include +#include + + +#include +#include "demod_func.h" + +#include "depend.h" /**/ + +#include "amlfrontend.h" + +/*dma_get_cma_size_int_byte*/ +#include +#include + +#include + + +MODULE_PARM_DESC(debug_aml, "\n\t\t Enable frontend debug information"); +static int debug_aml = 1; +module_param(debug_aml, int, 0644); + +MODULE_PARM_DESC(auto_search_std, "\n\t\t atsc-c std&hrc search"); +static unsigned int auto_search_std; +module_param(auto_search_std, int, 0644); + +MODULE_PARM_DESC(std_lock_timeout, "\n\t\t atsc-c std lock timeout"); +static unsigned int std_lock_timeout = 1000; +module_param(std_lock_timeout, int, 0644); +/*0.001for field,0.002 for performance*/ +static char *demod_version = "V0.03"; + + +int aml_demod_debug = DBG_INFO|DBG_ATSC; + + +#if 0 +#define PR_DBG(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_INFO) { \ + pr_info("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +#endif + +/* debug info------------------------*/ + + +module_param(aml_demod_debug, int, 0644); +MODULE_PARM_DESC(aml_demod_debug, "set debug level (info=bit1, reg=bit2, atsc=bit4,"); + +/*-----------------------------------*/ +struct amldtvdemod_device_s *dtvdd_devp; + +static int last_lock = -1; /*debug only*/ +#define DEMOD_DEVICE_NAME "Amlogic_Demod" +static int cci_thread; +static int freq_dvbc; +static struct aml_demod_sta demod_status; +static enum fe_modulation atsc_mode = VSB_8; +static struct aml_demod_para para_demod; +static int atsc_flag; + +static int memstart = 0x1ef00000;/* move to aml_dtv_demod*/ + +long *mem_buf; + +MODULE_PARM_DESC(frontend_mode, "\n\t\t Frontend mode 0-DVBC, 1-DVBT"); +static int frontend_mode = -1; +module_param(frontend_mode, int, 0444); + +MODULE_PARM_DESC(frontend_i2c, "\n\t\t IIc adapter id of frontend"); +static int frontend_i2c = -1; +module_param(frontend_i2c, int, 0444); + +MODULE_PARM_DESC(frontend_tuner, + "\n\t\t Frontend tuner type 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316"); +static int frontend_tuner = -1; +module_param(frontend_tuner, int, 0444); + +MODULE_PARM_DESC(frontend_tuner_addr, "\n\t\t Tuner IIC address of frontend"); +static int frontend_tuner_addr = -1; +module_param(frontend_tuner_addr, int, 0444); + +MODULE_PARM_DESC(demod_thread, "\n\t\t demod thread"); +static int demod_thread = 1; +module_param(demod_thread, int, 0644); + + +static int dvb_tuner_delay = 100; +module_param(dvb_tuner_delay, int, 0644); +MODULE_PARM_DESC(dvb_atsc_count, "dvb_tuner_delay"); +#define THRD_TUNER_STRENTH_ATSC (-87) +#define THRD_TUNER_STRENTH_J83 (-76) + + +static int autoflags, autoFlagsTrig; + +/*static struct mutex aml_lock;move to dtvdd_devp->lock*/ +const char *name_reg[] = { + "demod", + "iohiu", + "aobus", + "reset", +}; +/*also see: IC_VER_NUB*/ +const char *name_ic[] = { + "gxtvbb", + "txl", + "txlx", + "gxlx", + "txhd", +}; + +#define END_SYS_DELIVERY 19 +const char *name_fe_delivery_system[] = { + "UNDEFINED", + "DVBC_ANNEX_A", + "DVBC_ANNEX_B", + "DVBT", + "DSS", + "DVBS", + "DVBS2", + "DVBH", + "ISDBT", + "ISDBS", + "ISDBC", + "ATSC", + "ATSCMH", + "DTMB", + "CMMB", + "DAB", + "DVBT2", + "TURBO", + "DVBC_ANNEX_C", + "ANALOG", /*19*/ +}; +void dbg_delsys(unsigned char id) +{ + if (id <= END_SYS_DELIVERY) + PR_INFO("%s:%s:\n", __func__, name_fe_delivery_system[id]); + else + PR_INFO("%s:%d\n", __func__, id); + +} +static void dtvdemod_vdac_enable(bool on); +static void dtvdemod_set_agc_pinmux(int on); + + + +static int Gxtv_Demod_Dvbc_Init(/*struct aml_fe_dev *dev, */int mode); + +static ssize_t dvbc_auto_sym_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "dvbc_autoflags: %s\n", autoflags ? "on" : "off"); +} + +static ssize_t dvbc_auto_sym_store(struct class *cls, + struct class_attribute *attr, + const char *buf, size_t count) +{ + + return 0; +} + +static unsigned int dtmb_mode; +static unsigned int atsc_mode_para; +static unsigned int demod_mode_para; + + +enum { + DTMB_READ_STRENGTH = 0, + DTMB_READ_SNR = 1, + DTMB_READ_LOCK = 2, + DTMB_READ_BCH = 3, +}; + +enum { + ATSC_READ_STRENGTH = 0, + ATSC_READ_SNR = 1, + ATSC_READ_LOCK = 2, + ATSC_READ_SER = 3, + ATSC_READ_FREQ = 4, +}; + +enum { + UNKNOWN = 0, + AML_DVBC, + AML_DTMB, + AML_DVBT, + AML_ATSC, + AML_J83B, + AML_ISDBT, + AML_DVBT2 +}; + + + + + +int convert_snr(int in_snr) +{ + int out_snr; + static int calce_snr[40] = { + 5, 6, 8, 10, 13, + 16, 20, 25, 32, 40, + 50, 63, 80, 100, 126, + 159, 200, 252, 318, 400, + 504, 634, 798, 1005, 1265, + 1592, 2005, 2524, 3177, 4000, + 5036, 6340, 7981, 10048, 12649, + 15924, 20047, 25238, 31773, 40000}; + for (out_snr = 1 ; out_snr <= 40; out_snr++) + if (in_snr <= calce_snr[out_snr]) + break; + + return out_snr; +} + +static int freq_p; +static ssize_t atsc_para_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + int snr, lock_status, ser; + struct dvb_frontend *dvbfe; + int strength = 0; + + if (atsc_mode != VSB_8) + return 0; + + if (atsc_mode_para == ATSC_READ_STRENGTH) { + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ +#if 0 + if (dvbfe != NULL) { + if (dvbfe->ops.tuner_ops.get_strength) { + strength = + dvbfe->ops.tuner_ops.get_strength(dvbfe); + } + strength -= 100; + } +#else + strength = tuner_get_ch_power2(); + strength -= 100; +#endif + return sprintf(buf, "strength is %d\n", strength); + } else if (atsc_mode_para == ATSC_READ_SNR) { + snr = atsc_read_snr(); + return sprintf(buf, "snr is %d\n", snr); + } else if (atsc_mode_para == ATSC_READ_LOCK) { + lock_status = + atsc_read_reg(0x0980); + return sprintf(buf, "lock_status is %x\n", lock_status); + } else if (atsc_mode_para == ATSC_READ_SER) { + ser = atsc_read_ser(); + return sprintf(buf, "ser is %d\n", ser); + } else if (atsc_mode_para == ATSC_READ_FREQ) { + return sprintf(buf, "freq is %d\n", freq_p); + } else { + return sprintf(buf, "atsc_para_show can't match mode\n"); + } +} + +static ssize_t atsc_para_store(struct class *cls, + struct class_attribute *attr, + const char *buf, size_t count) +{ + if (buf[0] == '0') + atsc_mode_para = ATSC_READ_STRENGTH; + else if (buf[0] == '1') + atsc_mode_para = ATSC_READ_SNR; + else if (buf[0] == '2') + atsc_mode_para = ATSC_READ_LOCK; + else if (buf[0] == '3') + atsc_mode_para = ATSC_READ_SER; + else if (buf[0] == '4') + atsc_mode_para = ATSC_READ_FREQ; + + return count; +} + +static ssize_t demod_para_store(struct class *cls, + struct class_attribute *attr, + const char *buf, size_t count) +{ + if (buf[0] == '0') + demod_mode_para = UNKNOWN; + else if (buf[0] == '1') + demod_mode_para = AML_DVBC; + else if (buf[0] == '2') + demod_mode_para = AML_DTMB; + else if (buf[0] == '3') + demod_mode_para = AML_DVBT; + else if (buf[0] == '4') + demod_mode_para = AML_ATSC; + else if (buf[0] == '5') + demod_mode_para = AML_J83B; + else if (buf[0] == '6') + demod_mode_para = AML_ISDBT; + else if (buf[0] == '7') + demod_mode_para = AML_DVBT2; + + return count; +} + +void store_dvbc_qam_mode(int qam_mode, int symbolrate) +{ + int qam_para; + + switch (qam_mode) { + case QAM_16: + qam_para = 4; + break; + case QAM_32: + qam_para = 5; + break; + case QAM_64: + qam_para = 6; + break; + case QAM_128: + qam_para = 7; + break; + case QAM_256: + qam_para = 8; + break; + case QAM_AUTO: + qam_para = 6; + break; + default: + qam_para = 6; + break; + } + para_demod.dvbc_qam = qam_para; + para_demod.dvbc_symbol = symbolrate; + PR_DBG("dvbc_qam is %d, symbolrate is %d\n", + para_demod.dvbc_qam, para_demod.dvbc_symbol); +} + +static ssize_t demod_para_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + int rate, symolrate, qam, coderate, a; + + if (demod_mode_para == AML_DVBC) { + symolrate = para_demod.dvbc_symbol; + qam = para_demod.dvbc_qam; + rate = 944*symolrate*qam; + rate /= 1000; + } else if (demod_mode_para == AML_DTMB) { + coderate = para_demod.dtmb_coderate; + qam = para_demod.dtmb_qam; + a = 4725; + rate = 25614*qam*coderate/a; + rate *= 1024; + } else if (demod_mode_para == AML_DVBT) { + rate = 19855; + } else if (demod_mode_para == AML_ATSC) { + if (atsc_mode == VSB_8) + rate = 19855; + else if (atsc_mode == QAM_64) + rate = 27617; + else if (atsc_mode == QAM_256) + rate = 39741; + else + rate = 19855; + } else { + return sprintf(buf, "can't match mode\n"); + } + return sprintf(buf, "rate %d\n", rate); +} + + + + + +static ssize_t dtmb_para_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + int snr, lock_status, bch, agc_if_gain; + struct dvb_frontend *dvbfe; + int strength = 0; + + if (dtmb_mode == DTMB_READ_STRENGTH) { + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ + +#if 0 + if (dvbfe != NULL) + if (dvbfe->ops.tuner_ops.get_strength) { + strength = + dvbfe->ops.tuner_ops.get_strength(dvbfe); + } +#else + strength = tuner_get_ch_power2(); +#endif + if (strength <= -56) { + dtmb_read_agc(DTMB_D9_IF_GAIN, &agc_if_gain); + strength = dtmb_get_power_strength(agc_if_gain); + } + return sprintf(buf, "strength is %d\n", strength); + } else if (dtmb_mode == DTMB_READ_SNR) { + /*snr = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) & 0x3fff;*/ + snr = dtmb_reg_r_che_snr(); + snr = convert_snr(snr); + return sprintf(buf, "snr is %d\n", snr); + } else if (dtmb_mode == DTMB_READ_LOCK) { + lock_status = dtmb_reg_r_fec_lock(); + return sprintf(buf, "lock_status is %d\n", lock_status); + } else if (dtmb_mode == DTMB_READ_BCH) { + bch = dtmb_reg_r_bch(); + return sprintf(buf, "bch is %d\n", bch); + } else { + return sprintf(buf, "dtmb_para_show can't match mode\n"); + } +} + + +static ssize_t dtmb_para_store(struct class *cls, + struct class_attribute *attr, + const char *buf, size_t count) +{ + if (buf[0] == '0') + dtmb_mode = DTMB_READ_STRENGTH; + else if (buf[0] == '1') + dtmb_mode = DTMB_READ_SNR; + else if (buf[0] == '2') + dtmb_mode = DTMB_READ_LOCK; + else if (buf[0] == '3') + dtmb_mode = DTMB_READ_BCH; + + return count; +} + +static int readregdata; + +static ssize_t dvbc_reg_show(struct class *cls, struct class_attribute *attr, + char *buf) +{ +/* int readregaddr=0;*/ + char *pbuf = buf; + + pbuf += sprintf(pbuf, "%x", readregdata); + + PR_INFO("read dvbc_reg\n"); + return pbuf - buf; +} + +static ssize_t dvbc_reg_store(struct class *cls, struct class_attribute *attr, + const char *buf, size_t count) +{ + return 0; +} + + +static ssize_t info_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + int pos = 0; + unsigned int size = PAGE_SIZE; + + int snr, lock_status, bch, agc_if_gain, ser; + struct dvb_frontend *dvbfe; + int strength = 0; + + pos += snprintf(buf+pos, size-pos, "dtv demod info:\n"); + + switch (demod_mode_para) { + case AML_DVBC: + pos += snprintf(buf+pos, size-pos, "mode:AML_DVBC\n"); + break; + + case AML_DTMB: + pos += snprintf(buf+pos, size-pos, "mode:AML_DTMB\n"); + + /* DTMB_READ_STRENGTH */ + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ +#if 0 + if (dvbfe != NULL) + if (dvbfe->ops.tuner_ops.get_strength) { + strength = + dvbfe->ops.tuner_ops.get_strength(dvbfe); + } +#else + strength = tuner_get_ch_power2(); +#endif + if (strength <= -56) { + dtmb_read_agc(DTMB_D9_IF_GAIN, &agc_if_gain); + strength = dtmb_get_power_strength(agc_if_gain); + } + pos += snprintf(buf+pos, size-pos, + "strength: %d\n", strength); + + /* DTMB_READ_SNR */ + /*snr = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) & 0x3fff;*/ + snr = dtmb_reg_r_che_snr(); + snr = convert_snr(snr); + pos += snprintf(buf+pos, size-pos, "snr: %d\n", snr); + + /* DTMB_READ_LOCK */ + /*lock_status = */ + /* (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1;*/ + lock_status = dtmb_reg_r_fec_lock(); + pos += snprintf(buf+pos, size-pos, "lock: %d\n", lock_status); + + /* DTMB_READ_BCH */ + bch = dtmb_reg_r_bch(); + + pos += snprintf(buf+pos, size-pos, "bch: %d\n", bch); + + break; + case AML_DVBT: + pos += snprintf(buf+pos, size-pos, "mode:AML_DVBT\n"); + break; + case AML_ATSC: + pos += snprintf(buf+pos, size-pos, "mode:AML_ATSC\n"); + if (atsc_mode != VSB_8) + return pos; + + + /* ATSC_READ_STRENGTH */ + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ + if (dvbfe != NULL) { +#if 0 + if (dvbfe->ops.tuner_ops.get_strength) { + strength = + dvbfe->ops.tuner_ops.get_strength(dvbfe); + } +#else + strength = tuner_get_ch_power2(); +#endif + strength -= 100; + } + pos += snprintf(buf+pos, size-pos, "strength: %d\n", strength); + + + /* ATSC_READ_SNR */ + snr = atsc_read_snr(); + pos += snprintf(buf+pos, size-pos, "snr: %d\n", snr); + + /* ATSC_READ_LOCK */ + lock_status = atsc_read_reg(0x0980); + pos += snprintf(buf+pos, size-pos, "lock: %d\n", lock_status); + + /* ATSC_READ_SER */ + ser = atsc_read_ser(); + pos += snprintf(buf+pos, size-pos, "ser: %d\n", ser); + + /* ATSC_READ_FREQ */ + pos += snprintf(buf+pos, size-pos, "freq: %d\n", freq_p); + + break; + case AML_J83B: + pos += snprintf(buf+pos, size-pos, "mode:AML_J83B\n"); + break; + case AML_ISDBT: + pos += snprintf(buf+pos, size-pos, "mode:AML_ISDBT\n"); + break; + case AML_DVBT2: + pos += snprintf(buf+pos, size-pos, "mode:AML_DVBT2\n"); + break; + default: + pos += snprintf(buf+pos, size-pos, "mode:Unknown\n"); + break; + } + + return pos; +} + + +static CLASS_ATTR(auto_sym, 0644, dvbc_auto_sym_show, dvbc_auto_sym_store); +static CLASS_ATTR(dtmb_para, 0644, dtmb_para_show, dtmb_para_store); +/*from 666 to 644*/ +static CLASS_ATTR(dvbc_reg, 0644, dvbc_reg_show, dvbc_reg_store); +static CLASS_ATTR(atsc_para, 0644, atsc_para_show, atsc_para_store); +static CLASS_ATTR(demod_rate, 0644, demod_para_show, demod_para_store); +/* DebugInfo */ +static CLASS_ATTR(info, 0444, info_show, NULL); + + +/*static void dtvdemod_version(struct aml_fe_dev *dev)*/ +static void dtvdemod_version(struct amldtvdemod_device_s *dev) + +{ + char soc_version[20]; + char *atsc_version = "1"; + int ic_v = get_ic_ver(); + + if (dev->atsc_version == 1) + atsc_version = "1"; + else if (dev->atsc_version == 2) + atsc_version = "2"; + else + atsc_version = "1"; + atsc_set_version(dev->atsc_version); + + if (ic_v < IC_VER_NUB) { + strcpy(soc_version, name_ic[ic_v]); + strcat(soc_version, "-"); + } else { + strcpy(soc_version, "other-"); + } + strcat(soc_version, demod_version); + strcat(soc_version, atsc_version); + PR_INFO("[dtvdemod_version] [%s]\n", soc_version); +} + + +static int amdemod_qam(enum fe_modulation qam) +{ + switch (qam) { + case QAM_16: + return 0; + case QAM_32: + return 1; + case QAM_64: + return 2; + case QAM_128: + return 3; + case QAM_256: + return 4; + case VSB_8: + return 5; + case QAM_AUTO: + return 6; + default: + return 2; + } + return 2; +} + +static int amdemod_stat_islock(/*struct aml_fe_dev *dev,*/ int mode) +{ + struct aml_demod_sts demod_sts; + int lock_status; + int dvbt_status1; + int atsc_fsm; + int ret = 0; + + if (mode == 0) { + /*DVBC*/ + + demod_sts.ch_sts = dvbc_get_ch_sts(); + return demod_sts.ch_sts & 0x1; + } else if (mode == 1) { + /*DVBT*/ + dvbt_status1 = + ((dvbt_read_reg((0x0a << 2)) >> 20) & 0x3ff); + lock_status = (dvbt_read_reg((0x2a << 2))) & 0xf; + if ((((lock_status) == 9) || ((lock_status) == 10)) + && ((dvbt_status1) != 0)) + return 1; + else + return 0; + /*((apb_read_reg(DVBT_BASE+0x0)>>12)&0x1);// */ + /* dvbt_get_status_ops()->get_status(&demod_sts, &demod_sta);*/ + } else if (mode == 2) { + + } else if (mode == 3) { + /*ATSC*/ + if ((atsc_mode == QAM_64) || (atsc_mode == QAM_256)) { + /*return (atsc_read_iqr_reg() >> 16) == 0x1f;*/ + if ((atsc_read_iqr_reg() >> 16) == 0x1f) + ret = 1; + } else if (atsc_mode == VSB_8) { + atsc_fsm = atsc_read_reg(0x0980); + PR_DBGL("atsc status [%x]\n", atsc_fsm); + /*return atsc_read_reg(0x0980) >= 0x79;*/ + if (atsc_read_reg(0x0980) >= 0x79) + ret = 1; + } else { + atsc_fsm = atsc_read_reg(0x0980); + PR_DBGL("atsc status [%x]\n", atsc_fsm); + /*return atsc_read_reg(0x0980) >= 0x79;*/ + if (atsc_read_reg(0x0980) >= 0x79) + ret = 1; + } + + return ret; + } else if (mode == 4) { + /*DTMB*/ + + + /*return (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1;*/ + return dtmb_reg_r_fec_lock(); + } + return 0; +} + +#define amdemod_dvbc_stat_islock() amdemod_stat_islock(0) +#define amdemod_dvbt_stat_islock() amdemod_stat_islock(1) +#define amdemod_isdbt_stat_islock() amdemod_stat_islock(2) +#define amdemod_atsc_stat_islock() amdemod_stat_islock(3) +#define amdemod_dtmb_stat_islock() amdemod_stat_islock(4) + +#if 0 +/*this function is not use for txlx*/ +static int gxtv_demod_dvbc_set_qam_mode(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_dvbc param; /*mode 0:16, 1:32, 2:64, 3:128, 4:256*/ + + memset(¶m, 0, sizeof(param)); + param.mode = amdemod_qam(c->modulation); + dvbc_set_qam_mode(param.mode); + return 0; +} +static int aml_dtvdm_set_qam_mode(struct dvb_frontend *fe) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + int ret = 0; + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_set_qam_mode(fe); + break; + case AM_FE_OFDM_N: + + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_set_qam_mode(fe); + break; + case AM_FE_DTMB_N: + + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + + return ret; +} +static int gxtv_demod_atsc_set_qam_mode(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_atsc param; /*mode 3:64, 5:256, 7:vsb*/ + enum fe_modulation mode; + + memset(¶m, 0, sizeof(param)); + mode = c->modulation; + /*pr_dbg("mode is %d\n", mode);*/ + PR_ATSC("mode is %d\n", mode); + atsc_qam_set(mode); + return 0; +} + +#endif +static void gxtv_demod_dvbc_release(struct dvb_frontend *fe) +{ + +} +#if 0 +static int gxtv_demod_dvbc_read_status + (struct dvb_frontend *fe, enum fe_status *status) +{ +/* struct aml_fe_dev *dev = afe->dtv_demod;*/ + struct aml_demod_sts demod_sts; + struct aml_demod_sta demod_sta; + /*struct aml_demod_i2c demod_i2c;*/ + int ilock; + + /*demod_sts.ch_sts = qam_read_reg(0x6);*/ + demod_sts.ch_sts = dvbc_get_ch_sts(); + dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts); + if (demod_sts.ch_sts & 0x1) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } else { + ilock = 0; + *status = FE_TIMEDOUT; + } + if (last_lock != ilock) { + PR_DBG("%s.\n", + ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); + last_lock = ilock; + } + + return 0; +} +#endif +struct timer_t { + int enable; + unsigned int start; + unsigned int max; +}; +static struct timer_t gtimer; + +int timer_set_max(unsigned int max_val) +{ + gtimer.max = max_val; + return 0; +} +int timer_begain(void) +{ + gtimer.start = jiffies_to_msecs(jiffies); + gtimer.enable = 1; + + PR_DBG("st=%d\n", gtimer.start); + return 0; +} +int timer_not_enough(void) +{ + int ret = 0; + unsigned int time; + + if (gtimer.enable) { + time = jiffies_to_msecs(jiffies); + if ((time - gtimer.start) < gtimer.max) { + PR_DBG("now=%d\n", time); + ret = 1; + } + } + return ret; +} +int timer_tuner_not_enough(void) +{ + int ret = 0; + unsigned int time; + + if (gtimer.enable) { + time = jiffies_to_msecs(jiffies); + if ((time - gtimer.start) < 200) { + PR_DBG("nowt=%d\n", time); + ret = 1; + } + } + return ret; +} + + +static int gxtv_demod_dvbc_read_status_timer + (struct dvb_frontend *fe, enum fe_status *status) +{ + struct aml_demod_sts demod_sts; + struct aml_demod_sta demod_sta; + int strenth; + + int ilock; + + /*check tuner*/ + if (!timer_tuner_not_enough()) { + strenth = tuner_get_ch_power(fe)-256; + if (strenth < -85) { + *status = FE_TIMEDOUT; + return 0; + } + } + /*demod_sts.ch_sts = qam_read_reg(0x6);*/ + demod_sts.ch_sts = dvbc_get_ch_sts(); + dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts); + if (demod_sts.ch_sts & 0x1) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } else { + ilock = 0; + + if (timer_not_enough()) { + *status = 0; + PR_DBG("s=0\n"); + } else { + *status = FE_TIMEDOUT; + } + } + if (last_lock != ilock) { + PR_DBG("%s.\n", + ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); + last_lock = ilock; + } + + return 0; +} + +static int gxtv_demod_dvbc_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + /*struct aml_fe_dev *dev = afe->dtv_demod;*/ + struct aml_demod_sts demod_sts; + /*struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + + dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts); + *ber = demod_sts.ch_ber; + return 0; +} + +static int gxtv_demod_dvbc_read_signal_strength + (struct dvb_frontend *fe, u16 *strength) +{ + int tn_strength = 0; + +#if 0 + if (fe->ops.tuner_ops.get_strength) + tn_strength = fe->ops.tuner_ops.get_strength(fe); +#else + tn_strength = tuner_get_ch_power2(); +#endif + *strength = 256 - tn_strength; + return 0; +} + +static int gxtv_demod_dvbc_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct aml_demod_sts demod_sts; + /*struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + + dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts); + *snr = demod_sts.ch_snr / 100; + return 0; +} + +static int gxtv_demod_dvbc_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + *ucblocks = 0; + return 0; +} + +/*extern int aml_fe_analog_set_frontend(struct dvb_frontend *fe);*/ + +static int gxtv_demod_dvbc_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_dvbc param; /*mode 0:16, 1:32, 2:64, 3:128, 4:256*/ + struct aml_demod_sts demod_sts; + + PR_INFO("%s\n", __func__); + timer_set_max(4000); + timer_begain(); + + memset(¶m, 0, sizeof(param)); + param.ch_freq = c->frequency / 1000; + param.mode = amdemod_qam(c->modulation); + param.symb_rate = c->symbol_rate / 1000; + store_dvbc_qam_mode(c->modulation, param.symb_rate); + if ((param.mode == 3) && (demod_status.tmp != Adc_mode)) { + Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode); + /*pr_dbg("Gxtv_Demod_Dvbc_Init,Adc_mode\n");*/ + } else { + /*Gxtv_Demod_Dvbc_Init(dev,Cry_mode);*/ + } + if (autoflags == 0) { + /*pr_dbg("QAM_TUNING mode\n");*/ + /*flag=0;*/ + } + if ((autoflags == 1) && (autoFlagsTrig == 0) + && (freq_dvbc == param.ch_freq)) { + PR_DBG("now is auto symbrating\n"); + return 0; + } + autoFlagsTrig = 0; + last_lock = -1; + PR_DBG("[gxtv_demod_dvbc_set_frontend]PARA\t" + "param.ch_freq is %d||||param.symb_rate is %d,\t" + "param.mode is %d\n", + param.ch_freq, param.symb_rate, param.mode); + tuner_set_params(fe);/*aml_fe_analog_set_frontend(fe);*/ + dvbc_set_ch(&demod_status, /*&demod_i2c,*/ ¶m); + /*0xf33 dvbc mode, 0x10f33 j.83b mode*/ + #if 0 + if (is_meson_txlx_cpu() || is_meson_gxlx_cpu()) + /*qam_write_reg(0x7, 0xf33);*/ + dvbc_init_reg_ext(); + #endif + if (is_dvbc_ver(IC_DVBC_V3)) + dvbc_init_reg_ext(); + + if (autoflags == 1) { + PR_DBG("QAM_PLAYING mode,start auto sym\n"); + dvbc_set_auto_symtrack(); + /* flag=1;*/ + } + dvbc_status(&demod_status, /*&demod_i2c,*/ &demod_sts); + freq_dvbc = param.ch_freq; + + PR_DBG("AML amldemod => frequency=%d,symbol_rate=%d\r\n", c->frequency, + c->symbol_rate); + return 0; +} + +static int gxtv_demod_dvbc_get_frontend(struct dvb_frontend *fe) +{ /*these content will be writed into eeprom .*/ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 qam_mode; + + + qam_mode = dvbc_get_qam_mode(); + c->modulation = qam_mode + 1; + PR_DBG("[mode] is %d\n", c->modulation); + + return 0; +} + +static int Gxtv_Demod_Dvbc_Init(/*struct aml_fe_dev *dev, */int mode) +{ + struct aml_demod_sys sys; + /*struct aml_demod_i2c i2c;*/ + + PR_DBG("%s\n", __func__); + memset(&sys, 0, sizeof(sys)); + /*memset(&i2c, 0, sizeof(i2c));*/ + /*i2c.tuner = dev->drv->id;*/ + /*i2c.addr = dev->i2c_addr;*/ + /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ + demod_status.dvb_mode = Gxtv_Dvbc; + + if (mode == Adc_mode) { + sys.adc_clk = Adc_Clk_25M; + sys.demod_clk = Demod_Clk_200M; + demod_status.tmp = Adc_mode; + } else { + sys.adc_clk = Adc_Clk_24M; + sys.demod_clk = Demod_Clk_72M; + demod_status.tmp = Cry_mode; + } + demod_status.ch_if = Si2176_5M_If * 1000; + PR_DBG("[%s]adc_clk is %d,demod_clk is %d\n", __func__, sys.adc_clk, + sys.demod_clk); + autoFlagsTrig = 0; + /*demod_set_sys(&demod_status, &i2c, &sys);*/ + demod_set_sys(&demod_status, &sys); + demod_mode_para = AML_DVBC; + return 0; +} + +static void gxtv_demod_dvbt_release(struct dvb_frontend *fe) +{ + +} + +static int gxtv_demod_dvbt_read_status + (struct dvb_frontend *fe, enum fe_status *status) +{ +/* struct aml_fe *afe = fe->demodulator_priv;*/ + /*struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + int ilock; + unsigned char s = 0; + + s = dvbt_get_status_ops()->get_status(&demod_sta/*, &demod_i2c*/); + if (s == 1) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } else { + if (timer_not_enough()) { + ilock = 0; + *status = 0; + PR_INFO("timer not enough\n"); + + } else { + ilock = 0; + *status = FE_TIMEDOUT; + } + } + if (last_lock != ilock) { + PR_INFO("%s.\n", + ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); + last_lock = ilock; + } + + return 0; +} + +static int gxtv_demod_dvbt_read_ber(struct dvb_frontend *fe, u32 *ber) +{ +/* struct aml_fe *afe = fe->demodulator_priv;*/ + /*struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + + *ber = dvbt_get_status_ops()->get_ber(&demod_sta) & 0xffff; + return 0; +} + +static int gxtv_demod_dvbt_read_signal_strength + (struct dvb_frontend *fe, u16 *strength) +{ + /*struct aml_fe *afe = fe->demodulator_priv;*/ + /*struct aml_fe_dev *dev = afe->dtv_demod;*/ + + *strength = 256 - tuner_get_ch_power(fe); + PR_DBGL("[RSJ]tuner strength is %d dbm\n", *strength); + return 0; +} + +static int gxtv_demod_dvbt_read_snr(struct dvb_frontend *fe, u16 *snr) +{ +/* struct aml_fe *afe = fe->demodulator_priv;*/ +/* struct aml_demod_sts demod_sts;*/ +/* struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + + *snr = dvbt_get_status_ops()->get_snr(&demod_sta/*, &demod_i2c*/); + *snr /= 8; + PR_DBGL("[RSJ]snr is %d dbm\n", *snr); + return 0; +} + +static int gxtv_demod_dvbt_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + *ucblocks = 0; + return 0; +} +int convert_bandwidth(unsigned int input) +{ + /*int output;*/ + enum fe_bandwidth output; + + output = 3; + switch (input) { + case 10000000: + output = BANDWIDTH_10_MHZ; + break; + case 8000000: + output = BANDWIDTH_8_MHZ; + break; + case 7000000: + output = BANDWIDTH_7_MHZ; + break; + case 6000000: + output = BANDWIDTH_6_MHZ; + break; + case 5000000: + output = BANDWIDTH_5_MHZ; + break; + case 1712000: + output = BANDWIDTH_1_712_MHZ; + break; + case 0: + output = BANDWIDTH_AUTO; + break; + } + return output; + + +} + +static int gxtv_demod_dvbt_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + /*struct aml_demod_sts demod_sts;*/ + struct aml_demod_dvbt param; + + timer_set_max(1000); + timer_begain(); + + /*////////////////////////////////////*/ + /* bw == 0 : 8M*/ + /* 1 : 7M*/ + /* 2 : 6M*/ + /* 3 : 5M*/ + /* agc_mode == 0: single AGC*/ + /* 1: dual AGC*/ + /*////////////////////////////////////*/ + memset(¶m, 0, sizeof(param)); + param.ch_freq = c->frequency / 1000; + + //param.bw = c->bandwidth_hz; + param.bw = convert_bandwidth(c->bandwidth_hz); + PR_INFO("%s:bw=%d\n", __func__, c->bandwidth_hz); + param.agc_mode = 1; + /*ISDBT or DVBT : 0 is QAM, 1 is DVBT, 2 is ISDBT,*/ + /* 3 is DTMB, 4 is ATSC */ + param.dat0 = 1; + last_lock = -1; + + tuner_set_params(fe);/*aml_fe_analog_set_frontend(fe);*/ + dvbt_set_ch(&demod_status, /*&demod_i2c,*/ ¶m); + + + /*pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n",*/ + /* p->frequency,p->u.qam.symbol_rate);*/ + return 0; +} + +static int gxtv_demod_dvbt_get_frontend(struct dvb_frontend *fe) +{ /*these content will be writed into eeprom .*/ + + return 0; +} + +/*int Gxtv_Demod_Dvbt_Init(struct aml_fe_dev *dev)*/ +int Gxtv_Demod_Dvbt_Init(void) +{ + struct aml_demod_sys sys; + + PR_DBG("AML Demod DVB-T init\r\n"); + + memset(&sys, 0, sizeof(sys)); + + memset(&demod_status, 0, sizeof(demod_status)); + + /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ + demod_status.dvb_mode = Gxtv_Dvbt_Isdbt; + sys.adc_clk = Adc_Clk_24M; + sys.demod_clk = Demod_Clk_60M; + demod_status.ch_if = Si2176_5M_If * 1000; + + demod_set_sys(&demod_status, &sys); + demod_mode_para = AML_DVBT; + return 0; +} + +static void gxtv_demod_atsc_release(struct dvb_frontend *fe) +{ + +} + + +static int gxtv_demod_atsc_get_frontend_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_HW; +} +static int gxtv_demod_txlx_get_frontend_algo(struct dvb_frontend *fe) +{ + + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = DVBFE_ALGO_SW; + + switch (nmode) { + case AM_FE_QPSK_N: + break; + + case AM_FE_QAM_N: + /*dvbc*/ + + break; + case AM_FE_OFDM_N: + /*dvbt*/ + + break; + case AM_FE_ISDBT_N: + + break; + case AM_FE_ATSC_N: + ret = DVBFE_ALGO_HW; + break; + case AM_FE_DTMB_N: + ret = DVBFE_ALGO_HW; + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + + return ret; + +} + +unsigned int ats_thread_flg; +static int gxtv_demod_atsc_read_status + (struct dvb_frontend *fe, enum fe_status *status) +{ + + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_sts demod_sts; + /*struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + int ilock; + struct dvb_frontend *dvbfe; + unsigned char s = 0; + int strength = 0; + + /*debug only*/ + static enum fe_status dbg_lst_status; /* last status */ + + + if (!demod_thread) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + return 0; + } + if (!get_dtvpll_init_flag()) + return 0; + + if ((c->modulation <= QAM_AUTO) && (c->modulation != QPSK) + && (atsc_flag == QAM_AUTO)) { + s = amdemod_dvbc_stat_islock(); + dvbc_status(&demod_sta,/* &demod_i2c, */&demod_sts); + } else if ((c->modulation > QAM_AUTO) + && (atsc_flag == VSB_8)) { + /*atsc_thread();*/ + s = amdemod_atsc_stat_islock(); + if ((s == 0) && (last_lock == 1) + && (atsc_read_reg(0x0980) >= 0x76)) { + s = 1; + PR_ATSC("[rsj] unlock,but fsm >= 0x76\n"); + } + } +#if 0 /*debug only move to end*/ + dvbfe = get_si2177_tuner(); + if (dvbfe != NULL) + if (dvbfe->ops.tuner_ops.get_strength) { + strength = + dvbfe->ops.tuner_ops.get_strength(dvbfe); + } + /*strength -= 100;*/ + pr_dbg("[rsj_test]freq[%d] strength[%d]\n", freq_p, strength); +#endif + if (s == 1) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } else { + ilock = 0; + + /* *status = FE_TIMEDOUT; */ + if (ats_thread_flg) + *status = FE_TIMEDOUT; + else + *status = 0; + + } +#if 0 /*debug only*/ + if (last_lock != ilock) { + pr_error("%s.\n", + ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); + last_lock = ilock; + } +#endif + /*debug only*/ + if (aml_demod_debug & DBG_ATSC) { + if ((dbg_lst_status != s) || (last_lock != ilock)) { + /* check tuner */ + dvbfe = aml_get_fe();/*get_si2177_tuner();*/ + if (dvbfe != NULL) { +#if 0 + if (dvbfe->ops.tuner_ops.get_strength) { + strength = + dvbfe->ops.tuner_ops.get_strength(dvbfe); + } +#else + strength = tuner_get_ch_power2(); +#endif + strength -= 100; + } + + PR_ATSC("s=%d(1 is lock),lock=%d\n", s, ilock); + PR_ATSC("[rsj_test]freq[%d] strength[%d]\n", + freq_p, strength); + + /*update */ + dbg_lst_status = s; + last_lock = ilock; + } + /*aml_dbgatscl(".");*/ + } + return 0; +} + +static int gxtv_demod_atsc_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (!get_dtvpll_init_flag()) + return 0; + if ((c->modulation > QAM_AUTO) + && (atsc_flag == VSB_8)) + *ber = atsc_read_reg(0x980)&0xffff; + else if (((c->modulation == QAM_256) + || (c->modulation == QAM_64)) + && (atsc_flag == QAM_AUTO)) + + *ber = dvbc_get_status(); + return 0; +} + +static int gxtv_demod_atsc_read_signal_strength + (struct dvb_frontend *fe, u16 *strength) +{ +/* struct aml_fe *afe = fe->demodulator_priv;*/ + /*struct aml_fe_dev *dev = afe->dtv_demod; */ + int read_strength; + + read_strength = tuner_get_ch_power(fe); + /*read_strength -= 100;*/ + if (read_strength < -100) + *strength = 0; + else + *strength = (100 + read_strength); + /*pr_dbg("[read_strength]read_strength is %d,*strength is %d\n",*/ + /* read_strength, *strength);*/ + if (*strength < 0) + *strength = 0; + else if (*strength > 100) + *strength = 100; + return 0; +} + +static int gxtv_demod_atsc_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_sts demod_sts; + /*struct aml_demod_i2c demod_i2c;*/ + struct aml_demod_sta demod_sta; + + if ((c->modulation <= QAM_AUTO) + && (c->modulation != QPSK) + && (atsc_flag == QAM_AUTO)) { + dvbc_status(&demod_sta, /*&demod_i2c, */&demod_sts); + *snr = demod_sts.ch_snr / 100; + } else if ((c->modulation > QAM_AUTO) + && (atsc_flag == VSB_8)) + *snr = atsc_read_snr(); + return 0; +} + +static int gxtv_demod_atsc_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (!demod_thread) + return 0; + if ((c->modulation > QAM_AUTO) + && (atsc_flag == VSB_8)) + atsc_thread(); + *ucblocks = 0; + return 0; +} + +static int gxtv_demod_atsc_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_atsc param_atsc; + struct aml_demod_dvbc param_j83b; + int temp_freq = 0; + + memset(¶m_atsc, 0, sizeof(param_atsc)); + memset(¶m_j83b, 0, sizeof(param_j83b)); + if (!demod_thread) + return 0; + freq_p = c->frequency / 1000; + PR_INFO("c->modulation is %d,freq_p is %d, atsc_flag is %d\n", + c->modulation, freq_p, atsc_flag); + last_lock = -1; + atsc_mode = c->modulation; + /* param.mode = amdemod_qam(p->u.vsb.modulation);*/ + tuner_set_params(fe);/*aml_fe_analog_set_frontend(fe);*/ + if ((c->modulation <= QAM_AUTO) && (c->modulation != QPSK)) { + if (atsc_flag != QAM_AUTO) + atsc_flag = QAM_AUTO; + /* demod_set_demod_reg(0x502, TXLX_ADC_REG6);*/ + dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x502); + demod_set_mode_ts(Gxtv_Dvbc); + param_j83b.ch_freq = c->frequency / 1000; + param_j83b.mode = amdemod_qam(c->modulation); + if (c->modulation == QAM_64) + param_j83b.symb_rate = 5057; + else if (c->modulation == QAM_256) + param_j83b.symb_rate = 5361; + else + param_j83b.symb_rate = 5361; + dvbc_set_ch(&demod_status, /*&demod_i2c, */¶m_j83b); + } else if (c->modulation > QAM_AUTO) { + if (atsc_flag != VSB_8) + atsc_flag = VSB_8; + /*demod_set_demod_reg(0x507, TXLX_ADC_REG6);*/ + dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x507); + demod_set_mode_ts(Gxtv_Atsc); + param_atsc.ch_freq = c->frequency / 1000; + param_atsc.mode = c->modulation; + atsc_set_ch(&demod_status, /*&demod_i2c,*/ ¶m_atsc); + } + if ((auto_search_std == 1) && ((c->modulation <= QAM_AUTO) + && (c->modulation != QPSK))) { + unsigned char s = 0; + + msleep(std_lock_timeout); + s = amdemod_dvbc_stat_islock(); + if (s == 1) { + PR_DBG("atsc std mode is %d locked\n", atsc_mode); + + return 0; + } + if ((c->frequency == 79000000) || (c->frequency == 85000000)) { + temp_freq = (c->frequency + 2000000) / 1000; + param_j83b.ch_freq = temp_freq; + PR_DBG("irc fre:%d\n", param_j83b.ch_freq); + c->frequency = param_j83b.ch_freq * 1000; + + + tuner_set_params(fe); + demod_set_mode_ts(Gxtv_Dvbc); + param_j83b.mode = amdemod_qam(c->modulation); + if (c->modulation == QAM_64) + param_j83b.symb_rate = 5057; + else if (c->modulation == QAM_256) + param_j83b.symb_rate = 5361; + else + param_j83b.symb_rate = 5361; + dvbc_set_ch(&demod_status, /*&demod_i2c,*/ + ¶m_j83b); + + msleep(std_lock_timeout); + s = amdemod_dvbc_stat_islock(); + if (s == 1) { + PR_DBG("irc mode is %d locked\n", atsc_mode); + } else { + temp_freq = (c->frequency - 1250000) / 1000; + param_j83b.ch_freq = temp_freq; + PR_DBG("hrc fre:%d\n", param_j83b.ch_freq); + c->frequency = param_j83b.ch_freq * 1000; + + tuner_set_params(fe); + demod_set_mode_ts(Gxtv_Dvbc); + param_j83b.mode = amdemod_qam(c->modulation); + if (c->modulation == QAM_64) + param_j83b.symb_rate = 5057; + else if (c->modulation == QAM_256) + param_j83b.symb_rate = 5361; + else + param_j83b.symb_rate = 5361; + dvbc_set_ch(&demod_status, /*&demod_i2c,*/ + ¶m_j83b); + } + } else { + param_j83b.ch_freq = (c->frequency - 1250000) / 1000; + PR_DBG("hrc fre:%d\n", param_j83b.ch_freq); + c->frequency = param_j83b.ch_freq * 1000; + + demod_set_mode_ts(Gxtv_Dvbc); + param_j83b.mode = amdemod_qam(c->modulation); + if (c->modulation == QAM_64) + param_j83b.symb_rate = 5057; + else if (c->modulation == QAM_256) + param_j83b.symb_rate = 5361; + else + param_j83b.symb_rate = 5361; + dvbc_set_ch(&demod_status, /*&demod_i2c,*/ + ¶m_j83b); + } + } + PR_DBG("atsc_mode is %d\n", atsc_mode); + /*pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n",*/ + /* p->frequency,p->u.qam.symbol_rate);*/ + return 0; +} + +static int gxtv_demod_atsc_get_frontend(struct dvb_frontend *fe) +{ /*these content will be writed into eeprom .*/ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + PR_DBG("c->frequency is %d\n", c->frequency); + return 0; +} + +void atsc_detect_first(struct dvb_frontend *fe, enum fe_status *status) +{ + unsigned int ucblocks; + unsigned int atsc_status; + enum fe_status s; + int strenth; + + + /*tuner strength*/ + if (dvb_tuner_delay > 9) + msleep(dvb_tuner_delay); + + strenth = tuner_get_ch_power(fe); + if (strenth < THRD_TUNER_STRENTH_ATSC) { + *status = FE_TIMEDOUT; + PR_ATSC("tuner:no signal!\n"); + return; + } + + gxtv_demod_atsc_read_ucblocks(fe, &ucblocks); + + gxtv_demod_atsc_read_status(fe, &s); + + *status = s; + + if (s != 0x1f) { + gxtv_demod_atsc_read_ber(fe, &atsc_status); + if ((atsc_status < 0x60)) + *status = FE_TIMEDOUT; + + } + PR_ATSC("%s, detect=0x%x\n", __func__, (unsigned int)*status); +} + + +static int dvb_j83b_count = 5; +module_param(dvb_j83b_count, int, 0644); +MODULE_PARM_DESC(dvb_atsc_count, "dvb_j83b_count"); +/*come from j83b_speedup_func*/ +static int atsc_j83b_detect_first(struct dvb_frontend *fe, enum fe_status *s) +{ + int j83b_status, i; + /*struct dvb_frontend_private *fepriv = fe->frontend_priv;*/ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int strenth; + + PR_DBG("+6+"); + + if (dvb_tuner_delay > 9) + msleep(dvb_tuner_delay); + + strenth = tuner_get_ch_power(fe); + if (strenth < THRD_TUNER_STRENTH_J83) { + *s = FE_TIMEDOUT; + PR_ATSC("tuner:no signal!j83\n"); + return 0; + } + + gxtv_demod_atsc_read_status(fe, s); + + if (*s != 0x1f) { + /*msleep(200);*/ + PR_DBG("[j.83b] 1\n"); + for (i = 0; i < dvb_j83b_count; i++) { + msleep(25); + gxtv_demod_atsc_read_ber(fe, &j83b_status); + + /*J.83 status >=0x38,has signal*/ + if (j83b_status >= 0x3) + break; + } + PR_DBG("[rsj]j.83b_status is %x,modulation is %d\n", + j83b_status, + c->modulation); + } + + if (j83b_status < 0x3) + *s = FE_TIMEDOUT; + + + return 0; +} + +void atsc_polling(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (c->modulation == QPSK) { + PR_DBG("mode is qpsk, return;\n"); + /*return;*/ + } else if (c->modulation <= QAM_AUTO) { + PR_DBG("do nothing!\n"); + } else { + atsc_thread(); + } + +} + + +static int gxtv_demod_atsc_tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, unsigned int *delay, enum fe_status *status) +{ + /* + * It is safe to discard "params" here, as the DVB core will sync + * fe->dtv_property_cache with fepriv->parameters_in, where the + * DVBv3 params are stored. The only practical usage for it indicate + * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is + * true. + */ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + /*int ret = 0;*/ + + PR_ATSC("%s:\n", __func__); + *delay = HZ * 3; + if (re_tune) { + dtvdd_devp->en_detect = 1; /*fist set*/ + /*c->delivery_system = aml_demod_delivery_sys;*/ + /*PR_ATSC("delivery_system=%d\n", aml_demod_delivery_sys);*/ + gxtv_demod_atsc_set_frontend(fe); + + if (c->modulation == QPSK) { + PR_ATSC("modulation is QPSK do nothing!"); + } else if (c->modulation <= QAM_AUTO) { + PR_ATSC("j83\n"); + atsc_j83b_detect_first(fe, status); + } else if (c->modulation > QAM_AUTO) { + atsc_detect_first(fe, status); + } + + return 0; + } +#if 0 + if (!dtvdd_devp->en_detect) { + PR_DBG("tune:not enable\n"); + return ret; + } +#endif + atsc_polling(fe); + + return gxtv_demod_atsc_read_status(fe, status); + +} + +int Gxtv_Demod_Atsc_Init(void/*struct aml_fe_dev *dev*/) +{ + struct aml_demod_sys sys; + /*struct aml_demod_i2c i2c;*/ + + PR_DBG("%s\n", __func__); + + memset(&sys, 0, sizeof(sys)); + /*memset(&i2c, 0, sizeof(i2c));*/ + memset(&demod_status, 0, sizeof(demod_status)); + /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ + demod_status.dvb_mode = Gxtv_Atsc; + sys.adc_clk = Adc_Clk_24M; /*Adc_Clk_26M;*/ + sys.demod_clk = Demod_Clk_225M; /*Demod_Clk_71M;//Demod_Clk_78M;*/ + demod_status.ch_if = 5000; + demod_status.tmp = Adc_mode; + /*demod_set_sys(&demod_status, &i2c, &sys);*/ + demod_set_sys(&demod_status, &sys); + demod_mode_para = AML_ATSC; + atsc_flag = VSB_8; + return 0; +} + +static void gxtv_demod_dtmb_release(struct dvb_frontend *fe) +{ + +} + +static int gxtv_demod_dtmb_read_status + (struct dvb_frontend *fe, enum fe_status *status) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + *status = pollm->last_s; + return 0; +} + +void dtmb_save_status(unsigned int s) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + if (s) { + pollm->last_s = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + + } else { + pollm->last_s = FE_TIMEDOUT; + } +} +void dtmb_poll_start(void) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + pollm->last_s = 0; + pollm->flg_restart = 1; + /*pr_dbg("dtmb_poll_start!\n");*/ + PR_DTMB("dtmb_poll_start2\n"); + +} + + +void dtmb_poll_stop(void) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + pollm->flg_stop = 1; + +} +void dtmb_set_delay(unsigned int delay) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + pollm->delayms = delay; + pollm->flg_updelay = 1; +} +unsigned int dtmb_is_update_delay(void) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + return pollm->flg_updelay; +} +unsigned int dtmb_get_delay_clear(void) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + pollm->flg_updelay = 0; + + return pollm->delayms; +} + +void dtmb_poll_clear(void) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + memset(pollm, 0, sizeof(struct poll_machie_s)); + +} + +#define DTMBM_NO_SIGNEL_CHECK 0x01 +#define DTMBM_HV_SIGNEL_CHECK 0x02 +#define DTMBM_BCH_OVER_CHEK 0x04 + +#define DTMBM_CHEK_NO (DTMBM_NO_SIGNEL_CHECK) +#define DTMBM_CHEK_HV (DTMBM_HV_SIGNEL_CHECK | DTMBM_BCH_OVER_CHEK) +#define DTMBM_WORK (DTMBM_NO_SIGNEL_CHECK | DTMBM_HV_SIGNEL_CHECK\ + | DTMBM_BCH_OVER_CHEK) + +#define DTMBM_POLL_CNT_NO_SIGNAL (10) +#define DTMBM_POLL_CNT_WAIT_LOCK (3) /*from 30 to 3 */ +#define DTMBM_POLL_DELAY_NO_SIGNAL (120) +#define DTMBM_POLL_DELAY_HAVE_SIGNAL (100) +/*dtmb_poll_v3 is same as dtmb_check_status_txl*/ +void dtmb_poll_v3(void) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + unsigned int bch_tmp; + unsigned int s; + + if (!pollm->state) { + /* idle */ + /* idle -> start check */ + if (!pollm->flg_restart) { + PR_DBG("x"); + return; + } + } else { + if (pollm->flg_stop) { + PR_DBG("dtmb poll stop !\n"); + dtmb_poll_clear(); + dtmb_set_delay(3*HZ); + return; + } + } + + /* restart: clear */ + if (pollm->flg_restart) { + PR_DBG("dtmb poll restart!\n"); + dtmb_poll_clear(); + + } + PR_DBG("-"); + s = check_dtmb_fec_lock(); + + /* bch exceed the threshold: wait lock*/ + if (pollm->state & DTMBM_BCH_OVER_CHEK) { + if (pollm->crrcnt < DTMBM_POLL_CNT_WAIT_LOCK) { + pollm->crrcnt++; + + if (s) { + PR_DBG("after reset get lock again!cnt=%d\n", + pollm->crrcnt); + dtmb_constell_check(); + pollm->state = DTMBM_HV_SIGNEL_CHECK; + pollm->crrcnt = 0; + pollm->bch = dtmb_reg_r_bch(); + + + dtmb_save_status(s); + } + } else { + PR_DBG("can't lock after reset!\n"); + pollm->state = DTMBM_NO_SIGNEL_CHECK; + pollm->crrcnt = 0; + /* to no signal*/ + dtmb_save_status(s); + } + return; + } + + + if (s) { + /*have signal*/ + if (!pollm->state) { + pollm->state = DTMBM_CHEK_NO; + PR_DBG("from idle to have signal wait 1\n"); + return; + } + if (pollm->state & DTMBM_CHEK_NO) { + /*no to have*/ + PR_DBG("poll machie: from no signal to have signal\n"); + pollm->bch = dtmb_reg_r_bch(); + pollm->state = DTMBM_HV_SIGNEL_CHECK; + + dtmb_set_delay(DTMBM_POLL_DELAY_HAVE_SIGNAL); + return; + } + + + bch_tmp = dtmb_reg_r_bch(); + if (bch_tmp > (pollm->bch + 50)) { + pollm->state = DTMBM_BCH_OVER_CHEK; + + PR_DBG("bch add ,need reset,wait not to reset\n"); + dtmb_reset(); + + pollm->crrcnt = 0; + dtmb_set_delay(DTMBM_POLL_DELAY_HAVE_SIGNAL); + } else { + pollm->bch = bch_tmp; + pollm->state = DTMBM_HV_SIGNEL_CHECK; + + dtmb_save_status(s); + /*have signale to have signal*/ + dtmb_set_delay(300); + } + return; + } + + + /*no signal */ + if (!pollm->state) { + /* idle -> no signal */ + PR_DBG("poll machie: from idle to no signal\n"); + pollm->crrcnt = 0; + + pollm->state = DTMBM_NO_SIGNEL_CHECK; + } else if (pollm->state & DTMBM_CHEK_HV) { + /*have signal -> no signal*/ + PR_DBG("poll machie: from have signal to no signal\n"); + pollm->crrcnt = 0; + pollm->state = DTMBM_NO_SIGNEL_CHECK; + dtmb_save_status(s); + } + + /*no siganel check process */ + if (pollm->crrcnt < DTMBM_POLL_CNT_NO_SIGNAL) { + dtmb_no_signal_check_v3(); + pollm->crrcnt++; + + dtmb_set_delay(DTMBM_POLL_DELAY_NO_SIGNAL); + } else { + dtmb_no_signal_check_finishi_v3(); + pollm->crrcnt = 0; + + dtmb_save_status(s); + /*no signal to no signal*/ + dtmb_set_delay(300); + } + +} + +void dtmb_poll_start_tune(unsigned int state) +{ + struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; + + dtmb_poll_clear(); + + pollm->state = state; + if (state & DTMBM_NO_SIGNEL_CHECK) + dtmb_save_status(0); + else + dtmb_save_status(1); + PR_DTMB("dtmb_poll_start tune to %d\n", state); + +} + +/*come from gxtv_demod_dtmb_read_status, have ms_delay*/ +int dtmb_poll_v2(struct dvb_frontend *fe, enum fe_status *status) +{ + int ilock; + unsigned char s = 0; + + s = dtmb_check_status_gxtv(fe); + + if (s == 1) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } else { + ilock = 0; + *status = FE_TIMEDOUT; + } + if (last_lock != ilock) { + PR_INFO("%s.\n", + ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); + last_lock = ilock; + } + + return 0; +} + + +/*this is ori gxtv_demod_dtmb_read_status*/ +static int gxtv_demod_dtmb_read_status_old + (struct dvb_frontend *fe, enum fe_status *status) +{ + + int ilock; + unsigned char s = 0; + + if (is_dtmb_ver(IC_DTMB_V2)) { + s = dtmb_check_status_gxtv(fe); + } else if (is_dtmb_ver(IC_DTMB_V3)) { + s = dtmb_check_status_txl(fe); + } else { + + PR_ERR("%s:not support %d!\n", __func__, get_dtmb_ver()); + return -1; + } + s = amdemod_dtmb_stat_islock(); +/* s=1;*/ + if (s == 1) { + ilock = 1; + *status = + FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } else { + ilock = 0; + *status = FE_TIMEDOUT; + } + if (last_lock != ilock) { + PR_INFO("%s.\n", + ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); + last_lock = ilock; + } + + return 0; +} + +static int gxtv_demod_dtmb_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + + return 0; +} + +static int gxtv_demod_dtmb_read_signal_strength + (struct dvb_frontend *fe, u16 *strength) +{ + + *strength = tuner_get_ch_power(fe); + return 0; +} + +static int gxtv_demod_dtmb_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + int tmp, snr_avg; + + tmp = snr_avg = 0; + /* tmp = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR);*/ + tmp = dtmb_reg_r_che_snr(); + + *snr = convert_snr(tmp); + + return 0; +} + +static int gxtv_demod_dtmb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + *ucblocks = 0; + return 0; +} + + +static int gxtv_demod_dtmb_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_dtmb param; + int times; + + times = 2; + PR_DBG("gxtv_demod_dtmb_set_frontend,freq is %d\n", c->frequency); + memset(¶m, 0, sizeof(param)); + param.ch_freq = c->frequency / 1000; + + last_lock = -1; +/* demod_power_switch(PWR_OFF); */ + tuner_set_params(fe); /*aml_fe_analog_set_frontend(fe);*/ + msleep(100); +/* demod_power_switch(PWR_ON); */ + dtmb_set_ch(&demod_status, /*&demod_i2c,*/ ¶m); + + return 0; +} + + +static int gxtv_demod_dtmb_get_frontend(struct dvb_frontend *fe) +{ /*these content will be writed into eeprom .*/ + + return 0; +} + +/*int Gxtv_Demod_Dtmb_Init(struct aml_fe_dev *dev)*/ +int Gxtv_Demod_Dtmb_Init(struct amldtvdemod_device_s *dev) +{ + struct aml_demod_sys sys; + /*struct aml_demod_i2c i2c;*/ + PR_DBG("AML Demod DTMB init\r\n"); + + memset(&sys, 0, sizeof(sys)); + /*memset(&i2c, 0, sizeof(i2c));*/ + memset(&demod_status, 0, sizeof(demod_status)); + /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ + demod_status.dvb_mode = Gxtv_Dtmb; + + if (is_dtmb_ver(IC_DTMB_V2)) { + sys.adc_clk = Adc_Clk_25M; /*Adc_Clk_26M;*/ + sys.demod_clk = Demod_Clk_200M; + } else if (is_dtmb_ver(IC_DTMB_V3)) { + if (is_ic_ver(IC_VER_TXL)) { + sys.adc_clk = Adc_Clk_25M; + sys.demod_clk = Demod_Clk_225M; + } else { + sys.adc_clk = Adc_Clk_24M; + sys.demod_clk = Demod_Clk_225M; + } + } else { + PR_ERR("%s:not support %d\n", __func__, get_dtmb_ver()); + return -1; + } + + demod_status.ch_if = Si2176_5M_If; + demod_status.tmp = Adc_mode; + demod_status.spectrum = dev->spectrum; + /*demod_set_sys(&demod_status, &i2c, &sys);*/ + demod_set_sys(&demod_status, &sys); + demod_mode_para = AML_DTMB; + + return 0; +} +#ifdef DVB_CORE_ORI + + +static int gxtv_demod_dvbc_tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, unsigned int *delay, enum fe_status *status) +{ + /*struct dtv_frontend_properties *c = &fe->dtv_property_cache;*/ + int ret = 0; + /*unsigned int up_delay;*/ + /*unsigned int firstdetet;*/ + + + + if (re_tune) { + /*first*/ + dtvdd_devp->en_detect = 1; + + *delay = HZ / 4; + gxtv_demod_dvbc_set_frontend(fe); + timer_set_max(4000); + timer_begain(); + gxtv_demod_dvbc_read_status_timer(fe, status); + + PR_DBG("tune finish!\n"); + + return ret; + } + + if (!dtvdd_devp->en_detect) { + PR_DBG("tune:not enable\n"); + return ret; + } + + gxtv_demod_dvbc_read_status_timer(fe, status); + + return ret; + +} + +static int gxtv_demod_dtmb_tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, unsigned int *delay, enum fe_status *status) +{ + /*struct dtv_frontend_properties *c = &fe->dtv_property_cache;*/ + int ret = 0; + unsigned int up_delay; + unsigned int firstdetet; + + + + if (re_tune) { + /*first*/ + dtvdd_devp->en_detect = 1; + + *delay = HZ / 4; + gxtv_demod_dtmb_set_frontend(fe); + firstdetet = dtmb_detect_first(); + if (firstdetet == 1) { + *status = FE_TIMEDOUT; + /*polling mode*/ + dtmb_poll_start_tune(DTMBM_NO_SIGNEL_CHECK); + + } else if (firstdetet == 2) { /*need check*/ + *status = FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + dtmb_poll_start_tune(DTMBM_HV_SIGNEL_CHECK); + + } else if (firstdetet == 0) { + PR_DBG("use read_status\n"); + gxtv_demod_dtmb_read_status_old(fe, status); + if (*status | (0x1f)) + dtmb_poll_start_tune(DTMBM_HV_SIGNEL_CHECK); + else + dtmb_poll_start_tune(DTMBM_NO_SIGNEL_CHECK); + + + } + PR_DBG("tune finish!\n"); + + return ret; + } + + if (!dtvdd_devp->en_detect) { + PR_DBG("tune:not enable\n"); + return ret; + } + +#if 0 /**/ + *delay = HZ / 4; + gxtv_demod_dtmb_read_status_old(fe, status); +#else /*try polling*/ + + /*pr_dbg("+");*/ + if (is_dtmb_ver(IC_DTMB_V3)) { + dtmb_poll_v3(); + gxtv_demod_dtmb_read_status(fe, status); + if (dtmb_is_update_delay()) { + up_delay = (dtmb_get_delay_clear()*HZ)/1000; + if (up_delay > 0) + *delay = up_delay; + else + PR_DBG("warning:delay is 0\n"); + } + } else if (is_dtmb_ver(IC_DTMB_V2)) { + *delay = HZ / 3; + dtmb_poll_v2(fe, status); + } + +#endif + return ret; + +} + +#endif + + + +#ifdef CONFIG_CMA +/*void dtmb_cma_alloc(struct aml_fe_dev *devp)*/ +void dtmb_cma_alloc(struct amldtvdemod_device_s *devp) +{ + unsigned int mem_size = devp->cma_mem_size; + /* dma_alloc_from_contiguous*/ + devp->venc_pages = + dma_alloc_from_contiguous(&(devp->this_pdev->dev), + mem_size >> PAGE_SHIFT, 0); + PR_DBG("[cma]mem_size is %d,%d\n", + mem_size, mem_size >> PAGE_SHIFT); + if (devp->venc_pages) { + devp->mem_start = page_to_phys(devp->venc_pages); + devp->mem_size = mem_size; + PR_DBG("demod mem_start = 0x%x, mem_size = 0x%x\n", + devp->mem_start, devp->mem_size); + PR_DBG("demod cma alloc ok!\n"); + } else { + PR_DBG("demod cma mem undefined2.\n"); + } +} + +/*void dtmb_cma_release(struct aml_fe_dev *devp)*/ +void dtmb_cma_release(struct amldtvdemod_device_s *devp) +{ + /* dma_release_from_contiguous*/ + dma_release_from_contiguous(&(devp->this_pdev->dev), + devp->venc_pages, + devp->cma_mem_size>>PAGE_SHIFT); + PR_DBG("demod cma release ok!\n"); + devp->mem_start = 0; + devp->mem_size = 0; +} +#endif + +static int enter_mode(int mode) +{ + /*struct aml_fe_dev *dev = fe->dtv_demod;*/ + struct amldtvdemod_device_s *devn = dtvdd_devp; + int memstart_dtmb; + + PR_INFO("%s:%d\n", __func__, mode); + + dtvdemod_set_agc_pinmux(1); + + /*-------------------*/ + /* must enable the adc ref signal for demod, */ + /*vdac_enable(1, 0x2);*/ + dtvdemod_vdac_enable(1);/*on*/ + dtvdd_devp->en_detect = 0;/**/ + dtvdd_devp->n_mode = mode; + dtmb_poll_stop();/*polling mode*/ + + autoFlagsTrig = 1; + if (cci_thread) + if (dvbc_get_cci_task() == 1) + dvbc_create_cci_task(); + /*mem_buf = (long *)phys_to_virt(memstart);*/ + if (mode == AM_FE_DTMB_N) { + Gxtv_Demod_Dtmb_Init(devn); + if (devn->cma_flag == 1) { + PR_DBG("CMA MODE, cma flag is %d,mem size is %d", + devn->cma_flag, devn->cma_mem_size); + dtmb_cma_alloc(devn); + memstart_dtmb = devn->mem_start; + } else { + memstart_dtmb = devn->mem_start;/*??*/ + } + + dtmb_set_mem_st(memstart_dtmb); + + demod_write_reg(DEMOD_REG4, 0x8); + + } else if (mode == AM_FE_QAM_N) { + Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode); + } else if (mode == AM_FE_ATSC_N) { + Gxtv_Demod_Atsc_Init(); + } else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) { + Gxtv_Demod_Dvbt_Init(); + if (devn->cma_flag == 1) { + PR_DBG("CMA MODE, cma flag is %d,mem size is %d", + devn->cma_flag, + devn->cma_mem_size); + dtmb_cma_alloc(devn); + memstart_dtmb = devn->mem_start; + } else { + memstart_dtmb = devn->mem_start;/*??*/ + } + PR_DBG("[im]memstart is %x\n", memstart_dtmb); + dvbt_write_reg((0x10 << 2), memstart_dtmb); + } + + return 0; + +} + +static int leave_mode(int mode) +{ +/* struct aml_fe_dev *dev = fe->dtv_demod;*/ + struct amldtvdemod_device_s *devn = dtvdd_devp; + + PR_INFO("%s:\n", __func__); + dtvdd_devp->en_detect = 0; + dtvdd_devp->last_delsys = SYS_UNDEFINED; + + dtvpll_init_flag(0); + /*dvbc_timer_exit();*/ + if (cci_thread) + dvbc_kill_cci_task(); + if (mode == AM_FE_DTMB_N) { + dtmb_poll_stop(); /*polling mode*/ + /* close arbit */ + + demod_write_reg(DEMOD_REG4, 0x0); + if (devn->cma_flag == 1) + dtmb_cma_release(devn); + } + + + adc_set_pll_cntl(0, 0x04, NULL); + demod_mode_para = UNKNOWN; + /* should disable the adc ref signal for demod */ + /*vdac_enable(0, 0x2);*/ + dtvdemod_vdac_enable(0);/*off*/ + dtvdemod_set_agc_pinmux(0); + msleep(200); + + + return 0; + +} +/* when can't get ic_config by dts, use this*/ +const struct meson_ddemod_data data_gxtvbb = { + .name = "ddmode_gxtvbb", + .icver = { + .atsc = IC_MD_NONE, + .dvbt = IC_MD_NONE, + .dtmb = IC_DTMB_V2, + .dvbc = IC_DVBC_V2, + .reserved = 0, + .offset = IC_OFFS_V2, + .ic = IC_VER_GTVBB, + }, + +}; + +const struct meson_ddemod_data data_txl = { + .name = "ddmode_txl", + .icver = { + .atsc = IC_MD_NONE, + .dvbt = IC_MD_NONE, + .dtmb = IC_DTMB_V3, + .dvbc = IC_DVBC_V2, + .reserved = 0, + .offset = IC_OFFS_V2, + .ic = IC_VER_TXL, + }, + +}; + +const struct meson_ddemod_data data_txlx = { + .name = "ddmode_txlx", + .icver = { + .atsc = IC_ATSC_V2, + .dvbt = IC_DVBT_V2, + .dtmb = IC_MD_NONE, + .dvbc = IC_DVBC_V3, + .reserved = 0, + .offset = IC_OFFS_V3, + .ic = IC_VER_TXLX, + }, + +}; + +const struct meson_ddemod_data data_gxlx = { + .name = "ddmode_gxlx", + .icver = { + .atsc = IC_MD_NONE, + .dvbt = IC_MD_NONE, + .dtmb = IC_MD_NONE, + .dvbc = IC_DVBC_V3, + .reserved = 0, + .offset = IC_OFFS_V3, + .ic = IC_VER_GXLX, + }, + +}; + +const struct meson_ddemod_data data_txhd = { + .name = "ddmode_txhd", + .icver = { + .atsc = IC_MD_NONE, + .dvbt = IC_MD_NONE, + .dtmb = IC_DTMB_V3, + .dvbc = IC_MD_NONE, + .reserved = 0, + .offset = IC_OFFS_V3, + .ic = IC_VER_TXHD, + }, + +}; + +static const struct of_device_id meson_ddemod_match[] = { + { + .compatible = "amlogic, ddemod-gxtvbb", + .data = &data_gxtvbb, + }, { + .compatible = "amlogic, ddemod-txl", + .data = &data_txl, + }, { + .compatible = "amlogic, ddemod-txlx", + .data = &data_txlx, + }, { + .compatible = "amlogic, ddemod-gxlx", + .data = &data_gxlx, + }, { + .compatible = "amlogic, ddemod-txhd", + .data = &data_txhd, + }, + {}, +}; + + + +/* + * dds_init_reg_map - physical addr map + * + * map physical address of I/O memory resources + * into the core virtual address space + */ +static int dds_init_reg_map(struct platform_device *pdev) +{ + + struct ss_reg_phy *preg = &dtvdd_devp->reg_p[0]; + struct ss_reg_vt *pv = &dtvdd_devp->reg_v[0]; + int i; + struct resource *res = 0; + int size = 0; + int ret = 0; + + for (i = 0; i < ES_MAP_ADDR_NUM; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (!res) { + PR_ERR("%s: res %d is faile\n", __func__, i); + ret = -ENOMEM; + break; + } + size = resource_size(res); + preg[i].size = size; + preg[i].phy_addr = res->start; + + pv[i].v = devm_ioremap_nocache(&pdev->dev, + res->start, size); + } + return ret; +} + +int dtvdemod_set_iccfg_by_dts(struct platform_device *pdev) +{ + + /*struct ic_cfg_s *ic_cfg = &dtvdd_devp->iccfg;*/ + + /*int size_io_reg;*/ + u32 value; + int ret; + /*struct resource *res = &dtvdemod_mem;*/ + + + PR_DBG("%s:\n", __func__); + + + /*agc pinmux: option*/ + ret = of_property_read_string(pdev->dev.of_node, "pinctrl-names", + &dtvdd_devp->pin_name); + + if (ret) + PR_INFO("pinmux:not define in dts\n"); + else + PR_INFO("pinmux name:%s\n", dtvdd_devp->pin_name); + +/*move from aml_fe*/ + /*snprintf(buf, sizeof(buf), "%s%d_spectrum", name, id);*/ +#ifdef CONFIG_OF + ret = of_property_read_u32(pdev->dev.of_node, "spectrum", &value); + if (!ret) { + dtvdd_devp->spectrum = value; + PR_INFO("spectrum: %d\n", value); + } else { + dtvdd_devp->spectrum = 2; + } +#else /*CONFIG_OF */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spectrum"); + if (res) { + int spectrum = res->start; + + dtvdd_devp->spectrum = spectrum; + } else { + dtvdd_devp->spectrum = 0; + } +#endif + /*snprintf(buf, sizeof(buf), "%s%d_cma_flag", name, id);*/ +#ifdef CONFIG_OF + ret = of_property_read_u32(pdev->dev.of_node, "cma_flag", &value); + if (!ret) { + dtvdd_devp->cma_flag = value; + PR_INFO("cma_flag: %d\n", value); + } else { + dtvdd_devp->cma_flag = 0; + } +#else /*CONFIG_OF */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cma_flag"); + if (res) { + int cma_flag = res->start; + + dtvdd_devp->cma_flag = cma_flag; + } else { + dtvdd_devp->cma_flag = 0; + } +#endif + /*snprintf(buf, sizeof(buf), "%s%d_atsc_version", name, id);*/ +#ifdef CONFIG_OF + ret = of_property_read_u32(pdev->dev.of_node, "atsc_version", &value); + if (!ret) { + dtvdd_devp->atsc_version = value; + PR_INFO("atsc_version: %d\n", value); + } else { + dtvdd_devp->atsc_version = 0; + } +#else /*CONFIG_OF */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "atsc_version"); + if (res) { + int atsc_version = res->start; + + dtvdd_devp->atsc_version = atsc_version; + } else { + dtvdd_devp->atsc_version = 0; + } +#endif + + if (dtvdd_devp->cma_flag == 1) { + /*snprintf(buf, sizeof(buf), "%s%d_cma_mem_size", name, id);*/ +#ifdef CONFIG_CMA +#ifdef CONFIG_OF + ret = of_property_read_u32(pdev->dev.of_node, + "cma_mem_size", &value); + if (!ret) { + dtvdd_devp->cma_mem_size = value; + PR_INFO("cma_mem_size: %d\n", value); + } else { + dtvdd_devp->cma_mem_size = 0; + } +#else /*CONFIG_OF */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "cma_mem_size"); + if (res) { + int cma_mem_size = res->start; + + dtvdd_devp->cma_mem_size = cma_mem_size; + } else { + dtvdd_devp->cma_mem_size = 0; + } +#endif + dtvdd_devp->cma_mem_size = + dma_get_cma_size_int_byte(&pdev->dev); + dtvdd_devp->this_pdev = pdev; + dtvdd_devp->cma_mem_alloc = 0; + PR_INFO("[cma]demod cma_mem_size = %d MB\n", + (u32)dtvdd_devp->cma_mem_size/SZ_1M); +#endif + } else { +#ifdef CONFIG_OF + dtvdd_devp->mem_start = memstart; +#endif + } + +/*end-------------*/ + return 0; + +} +#if (defined CONFIG_AM_DTVDEMOD) /*move to aml_dtv_demod*/ +static int rmem_demod_device_init(struct reserved_mem *rmem, struct device *dev) +{ + unsigned int demod_mem_start; + unsigned int demod_mem_size; + + demod_mem_start = rmem->base; + demod_mem_size = rmem->size; + memstart = demod_mem_start; + pr_info("demod reveser memory 0x%x, size %dMB.\n", + demod_mem_start, (demod_mem_size >> 20)); + return 1; +} + +static void rmem_demod_device_release(struct reserved_mem *rmem, + struct device *dev) +{ +} + +static const struct reserved_mem_ops rmem_demod_ops = { + .device_init = rmem_demod_device_init, + .device_release = rmem_demod_device_release, +}; + +static int __init rmem_demod_setup(struct reserved_mem *rmem) +{ + /* + * struct cma *cma; + * int err; + * pr_info("%s setup.\n",__func__); + * err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma); + * if (err) { + * pr_err("Reserved memory: unable to setup CMA region\n"); + * return err; + * } + */ + rmem->ops = &rmem_demod_ops; + /* rmem->priv = cma; */ + + pr_info + ("DTV demod reserved memory: %pa, size %ld MiB\n", + &rmem->base, (unsigned long)rmem->size / SZ_1M); + + return 0; +} + +RESERVEDMEM_OF_DECLARE(demod, "amlogic, demod-mem", rmem_demod_setup); +#endif + +int dtvdemod_init_regaddr_byversion(struct platform_device *pdev) +{ + struct ic_ver *pic = &dtvdd_devp->icver; /*in*/ + struct ddemod_reg_off *ireg = &dtvdd_devp->ireg; /*set*/ + + unsigned int off_ver = pic->offset; + int ret = 0; + + /*clear*/ + ireg->off_demod = 0x00; + ireg->off_dvbc = 0x00; + ireg->off_dtmb = 0x00; + ireg->off_dvbt = 0x00; + ireg->off_atsc = 0x00; + + if (is_offset_ver(IC_OFFS_V2)) { + ireg->off_demod = 0xc00; + + ireg->off_dvbc = 0x400; + ireg->off_dtmb = 0x00; + } else if (is_offset_ver(IC_OFFS_V3)) { + ireg->off_demod = 0xf00; + + ireg->off_dvbc = 0xc00; + ireg->off_dtmb = 0x000; + ireg->off_dvbt = 0x400; + ireg->off_atsc = 0x800; + } else { + PR_ERR("ic_offset_version[%d] is not support!\n", off_ver); + ireg->off_demod = 0xf00; + + ireg->off_dvbc = 0xc00; + ireg->off_dtmb = 0x000; + ireg->off_dvbt = 0x400; + ireg->off_atsc = 0x800; + + ret = -1; + } + + + return ret; +} + + + + + +/* It's a correspondence with enum es_map_addr*/ + +void dbg_ic_cfg(void) +{ + struct ic_ver *pic = &dtvdd_devp->icver; + struct ss_reg_phy *preg = &dtvdd_devp->reg_p[0]; + int i; + + PR_INFO("ic_version=0x%x\n", pic->ic); + PR_INFO("\tver_dvbc:\t%d\n", pic->dvbc); + PR_INFO("\tver_dtmb:\t%d\n", pic->dtmb); + PR_INFO("\tver_dvbt:\t%d\n", pic->dvbt); + PR_INFO("\tver_atsc:\t%d\n", pic->atsc); + PR_INFO("\tver_offset:\t%d\n", pic->offset); + + + for (i = 0; i < ES_MAP_ADDR_NUM; i++) + PR_INFO("reg:%s:st=0x%x,size=0x%x\n", + name_reg[i], preg[i].phy_addr, preg[i].size); + + +} + +void dbg_reg_addr(void) +{ + struct ddemod_reg_off *ireg = &dtvdd_devp->ireg; + struct ss_reg_vt *regv = &dtvdd_devp->reg_v[0]; + int i; + + PR_INFO("%s\n", __func__); + + PR_INFO("reg address offset:\n"); + PR_INFO("\tdemod:\t0x%x\n", ireg->off_demod); + PR_INFO("\tdvbc:\t0x%x\n", ireg->off_dvbc); + PR_INFO("\tdtmb:\t0x%x\n", ireg->off_dtmb); + PR_INFO("\tdvbt:\t0x%x\n", ireg->off_dvbt); + PR_INFO("\tatsc:\t0x%x\n", ireg->off_atsc); + + PR_INFO("virtual addr:\n"); + for (i = 0; i < ES_MAP_ADDR_NUM; i++) + PR_INFO("\t%s:\t0x%p\n", name_reg[i], regv[i].v); + + +} +static void dtvdemod_set_agc_pinmux(int on) +{ + if (dtvdd_devp->pin_name == NULL) { + PR_INFO("no pinmux control\n"); + return; + } + + if (on) { + dtvdd_devp->pin = devm_pinctrl_get_select(dtvdd_devp->dev, + dtvdd_devp->pin_name); + } else { + /*off*/ + if (dtvdd_devp->pin != NULL) { + devm_pinctrl_put(dtvdd_devp->pin); + dtvdd_devp->pin = NULL; + } + } + +} + +static void dtvdemod_clktree_probe(struct device *dev) +{ + dtvdd_devp->clk_gate_state = 0; + + dtvdd_devp->vdac_clk_gate = devm_clk_get(dev, "vdac_clk_gate"); + if (IS_ERR(dtvdd_devp->vdac_clk_gate)) + PR_ERR("error: %s: clk vdac_clk_gate\n", __func__); +} + +static void dtvdemod_clktree_remove(struct device *dev) +{ + if (!IS_ERR(dtvdd_devp->vdac_clk_gate)) + devm_clk_put(dev, dtvdd_devp->vdac_clk_gate); +} +static void vdac_clk_gate_ctrl(int status) +{ + if (status) { + if (dtvdd_devp->clk_gate_state) { + PR_INFO("clk_gate is already on\n"); + return; + } + + if (IS_ERR(dtvdd_devp->vdac_clk_gate)) + PR_ERR("error: %s: vdac_clk_gate\n", __func__); + else + clk_prepare_enable(dtvdd_devp->vdac_clk_gate); + + dtvdd_devp->clk_gate_state = 1; + } else { + if (dtvdd_devp->clk_gate_state == 0) { + PR_INFO("clk_gate is already off\n"); + return; + } + + if (IS_ERR(dtvdd_devp->vdac_clk_gate)) + PR_ERR("error: %s: vdac_clk_gate\n", __func__); + else + clk_disable_unprepare(dtvdd_devp->vdac_clk_gate); + + dtvdd_devp->clk_gate_state = 0; + } +} +/* + * use dtvdemod_vdac_enable replace vdac_enable + */ +static void dtvdemod_vdac_enable(bool on) +{ + if (on) { + vdac_clk_gate_ctrl(1); + vdac_enable(1, 0x02); + } else { + vdac_clk_gate_ctrl(0); + vdac_enable(0, 0x02); + } +} + + + + +/* platform driver*/ +static int aml_dtvdemod_probe(struct platform_device *pdev) +{ + int ret = 0; + const struct of_device_id *match; + + PR_INFO("%s\n", __func__); + /*memory*/ + + dtvdd_devp = kzalloc(sizeof(struct amldtvdemod_device_s), + GFP_KERNEL); + + if (!dtvdd_devp) + goto fail_alloc_region; + + + /*class attr */ + dtvdd_devp->clsp = class_create(THIS_MODULE, DEMOD_DEVICE_NAME); + if (!dtvdd_devp->clsp) + goto fail_create_class; + + ret = class_create_file(dtvdd_devp->clsp, &class_attr_auto_sym); + if (ret) + goto fail_class_create_file; + + ret = class_create_file(dtvdd_devp->clsp, &class_attr_dtmb_para); + if (ret) + goto fail_class_create_file; + + ret = class_create_file(dtvdd_devp->clsp, &class_attr_dvbc_reg); + if (ret) + goto fail_class_create_file; + + ret = class_create_file(dtvdd_devp->clsp, &class_attr_atsc_para); + if (ret) + goto fail_class_create_file; + + ret = class_create_file(dtvdd_devp->clsp, &class_attr_demod_rate); + if (ret) + goto fail_class_create_file; + + ret = class_create_file(dtvdd_devp->clsp, &class_attr_info); + if (ret) + goto fail_class_create_file; + + /**/ + match = of_match_device(meson_ddemod_match, &pdev->dev); + if (match == NULL) { + PR_ERR("%s,no matched table\n", __func__); + goto fail_ic_config; + } + dtvdd_devp->data = (struct meson_ddemod_data *)match->data; + dtvdd_devp->icver = dtvdd_devp->data->icver; + + /*reg*/ + ret = dds_init_reg_map(pdev); + if (ret) + goto fail_ic_config; + + /*mem info from dts*/ + ret = dtvdemod_set_iccfg_by_dts(pdev); + if (ret) + goto fail_ic_config; + /*dtvdemod_set_iccfg_by_cputype();*/ + + ret = dtvdemod_init_regaddr_byversion(pdev); + if (ret) + goto fail_ic_config; + + /*debug:*/ + dbg_ic_cfg(); + dbg_reg_addr(); + + /**/ + dtvpll_lock_init(); + /* init */ + /*dtvdemod_base_add_init();*/ + mutex_init(&dtvdd_devp->lock); + + dtvdd_devp->dev = &pdev->dev; + + dtvdemod_clktree_probe(&pdev->dev); + + + dtvdd_devp->state = DTVDEMOD_ST_IDLE; + dtvdemod_version(dtvdd_devp); + + //ary temp: + aml_demod_init(); + + PR_INFO("[amldtvdemod.] : probe ok.\n"); + return 0; +fail_ic_config: + PR_ERR("ic config error.\n"); +fail_class_create_file: + PR_ERR("dtvdemod class file create error.\n"); + class_destroy(dtvdd_devp->clsp); +fail_create_class: + PR_ERR("dtvdemod class create error.\n"); + kfree(dtvdd_devp); +fail_alloc_region: + PR_ERR("dtvdemod alloc error.\n"); + PR_ERR("dtvdemod_init fail.\n"); + dtvdd_devp->state = DTVDEMOD_ST_NOT_INI; + + + + return ret; +} + +static int __exit aml_dtvdemod_remove(struct platform_device *pdev) +{ + if (dtvdd_devp == NULL) + return -1; + + dtvdemod_clktree_remove(&pdev->dev); + + mutex_destroy(&dtvdd_devp->lock); + + class_remove_file(dtvdd_devp->clsp, &class_attr_auto_sym); + class_remove_file(dtvdd_devp->clsp, &class_attr_dtmb_para); + class_remove_file(dtvdd_devp->clsp, &class_attr_dvbc_reg); + class_remove_file(dtvdd_devp->clsp, &class_attr_atsc_para); + class_remove_file(dtvdd_devp->clsp, &class_attr_demod_rate); + class_remove_file(dtvdd_devp->clsp, &class_attr_info); + + class_destroy(dtvdd_devp->clsp); + + kfree(dtvdd_devp); + PR_INFO("%s:remove.\n", __func__); + + aml_demod_exit();//ary temp + return 0; +} + +static void aml_dtvdemod_shutdown(struct platform_device *pdev) +{ + pr_info("%s\n", __func__); + + if (dtvdd_devp->state != DTVDEMOD_ST_IDLE) { + leave_mode(0); + dtvdd_devp->state = DTVDEMOD_ST_IDLE; + } + +} + +static struct platform_driver aml_dtvdemod_driver = { + .driver = { + .name = "aml_dtv_demod", + .owner = THIS_MODULE, + /*aml_dtvdemod_dt_match*/ + .of_match_table = meson_ddemod_match, + }, + .shutdown = aml_dtvdemod_shutdown, + .probe = aml_dtvdemod_probe, + .remove = __exit_p(aml_dtvdemod_remove), +}; + + +static int __init aml_dtvdemod_init(void) +{ + if (platform_driver_register(&aml_dtvdemod_driver)) { + pr_err("failed to register amldtvdemod driver module\n"); + return -ENODEV; + } + PR_INFO("[amldtvdemod..]%s.\n", __func__); + return 0; +} + +static void __exit aml_dtvdemod_exit(void) +{ + platform_driver_unregister(&aml_dtvdemod_driver); + PR_INFO("[amldtvdemod..]%s: driver removed ok.\n", __func__); +} + + +static int delsys_confirm(struct dvb_frontend *fe) +{ + enum fe_delivery_system ldelsys = dtvdd_devp->last_delsys; + enum fe_delivery_system cdelsys; + + int ncaps, support; + enum aml_fe_n_mode_t mode = AM_FE_UNKNOWN_N; + + cdelsys = fe->dtv_property_cache.delivery_system; + + /*same*/ + if (ldelsys == cdelsys) { + //PR_DBG("delsys is same, do nothing\n"); + return 0; + } + + /*support ?*/ + ncaps = 0; + support = 0; + while (ncaps < 10 && fe->ops.delsys[ncaps]) { + if (fe->ops.delsys[ncaps] == cdelsys) { + + support = 1; + break; + } + ncaps++; + } + + if (!support) { + PR_INFO("delsys:%d is not support!\n", cdelsys); + return 0; + } + + PR_DBG("%s:l=%d,c=%d\n", __func__, ldelsys, cdelsys); + + switch (cdelsys) { + + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + /*dvbc*/ + if (ldelsys == SYS_DVBC_ANNEX_A + || ldelsys == SYS_DVBC_ANNEX_C) { + break; + } + mode = AM_FE_QAM_N; + break; + case SYS_ATSC: + case SYS_ATSCMH: + case SYS_DVBC_ANNEX_B: + /*atsc*/ + if (ldelsys == SYS_ATSC + || ldelsys == SYS_ATSCMH + || ldelsys == SYS_DVBC_ANNEX_B) { + break; + + } + mode = AM_FE_ATSC_N; + break; + case SYS_DVBT: + case SYS_DVBT2: + /*dvbt, OFDM*/ + if (ldelsys == SYS_DVBT + || ldelsys == SYS_DVBT2) { + break; + + } + mode = AM_FE_OFDM_N; + break; + case SYS_ISDBT: + if (ldelsys != SYS_ISDBT) + mode = AM_FE_ISDBT_N; + break; + case SYS_DTMB: + /*dtmb*/ + mode = AM_FE_DTMB_N; + break; + case SYS_DVBS: + case SYS_DVBS2: + /*QPSK*/ + if (ldelsys == SYS_DVBS + || ldelsys == SYS_DVBS2) { + + break; + + } + mode = AM_FE_QPSK_N; + break; + + case SYS_DSS: + case SYS_DVBH: + + case SYS_ISDBS: + case SYS_ISDBC: + case SYS_CMMB: + case SYS_DAB: + case SYS_TURBO: + case SYS_UNDEFINED: + case SYS_ANALOG: + mode = AM_FE_UNKNOWN_N; + PR_INFO("delsys not support!%d=\n", cdelsys); + return 0; + } + + if (mode != AM_FE_UNKNOWN_N) + enter_mode(mode); + + if (!get_dtvpll_init_flag()) { + PR_INFO("pll is not set!\n"); + leave_mode(mode); + dtvdd_devp->last_delsys = SYS_UNDEFINED; + return 0; + } + + dtvdd_devp->last_delsys = cdelsys; + + return 0; +} + +static int delsys_set(struct dvb_frontend *fe, unsigned int delsys) +{ + enum fe_delivery_system ldelsys = dtvdd_devp->last_delsys; + enum fe_delivery_system cdelsys; + + int ncaps, support; + enum aml_fe_n_mode_t mode = AM_FE_UNKNOWN_N; + enum aml_fe_n_mode_t lmode = dtvdd_devp->n_mode; + + cdelsys = delsys; /*diff*/ + + /*same*/ + if (ldelsys == cdelsys) { + //PR_DBG("delsys is same, do nothing\n"); + return 0; + } + + /*support ?*/ + ncaps = 0; + support = 0; + while (ncaps < 10 && fe->ops.delsys[ncaps]) { + if (fe->ops.delsys[ncaps] == cdelsys) { + + support = 1; + break; + } + ncaps++; + } + + if (!support) { + if (get_dtvpll_init_flag()) { + /**/ + PR_INFO("delsys:%d is not support!\n", cdelsys); + leave_mode(lmode); + } + return 0; + } + + PR_DBG("%s:l=%d,c=%d\n", __func__, ldelsys, cdelsys); + dbg_delsys(cdelsys); + + switch (cdelsys) { + + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + /*dvbc*/ + if (ldelsys == SYS_DVBC_ANNEX_A + || ldelsys == SYS_DVBC_ANNEX_C) { + break; + } + mode = AM_FE_QAM_N; + break; + case SYS_ATSC: + case SYS_ATSCMH: + case SYS_DVBC_ANNEX_B: + /*atsc*/ + if (ldelsys == SYS_ATSC + || ldelsys == SYS_ATSCMH + || ldelsys == SYS_DVBC_ANNEX_B) { + break; + + } + mode = AM_FE_ATSC_N; + break; + case SYS_DVBT: + case SYS_DVBT2: + /*dvbt, OFDM*/ + if (ldelsys == SYS_DVBT + || ldelsys == SYS_DVBT2) { + break; + + } + mode = AM_FE_OFDM_N; + break; + case SYS_ISDBT: + if (ldelsys != SYS_ISDBT) + mode = AM_FE_ISDBT_N; + break; + case SYS_DTMB: + /*dtmb*/ + mode = AM_FE_DTMB_N; + break; + case SYS_DVBS: + case SYS_DVBS2: + /*QPSK*/ + if (ldelsys == SYS_DVBS + || ldelsys == SYS_DVBS2) { + + break; + + } + mode = AM_FE_QPSK_N; + break; + + case SYS_DSS: + case SYS_DVBH: + + case SYS_ISDBS: + case SYS_ISDBC: + case SYS_CMMB: + case SYS_DAB: + case SYS_TURBO: + case SYS_UNDEFINED: + case SYS_ANALOG: + mode = AM_FE_UNKNOWN_N; + PR_INFO("delsys not support!%d=\n", cdelsys); + return 0; + } + + if (mode != AM_FE_UNKNOWN_N) + enter_mode(mode); + + if (!get_dtvpll_init_flag()) { + PR_INFO("pll is not set!\n"); + leave_mode(mode); + dtvdd_devp->last_delsys = SYS_UNDEFINED; + return 0; + } + + dtvdd_devp->last_delsys = cdelsys; +#if 1 /*ary add for test*/ + PR_INFO("info type:%d", fe->ops.info.type); + if (mode == AM_FE_ATSC_N) + fe->ops.info.type = FE_ATSC; + else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) + fe->ops.info.type = FE_OFDM; + + fe->ops.tuner_ops.set_config(fe, NULL); + +#endif + + return 0; +} + +static int is_not_active(struct dvb_frontend *fe) +{ + enum fe_delivery_system cdelsys; + enum fe_delivery_system ldelsys = dtvdd_devp->last_delsys; + + if (!get_dtvpll_init_flag()) + return 1; + + cdelsys = fe->dtv_property_cache.delivery_system; + if (ldelsys != cdelsys) + return 2; + + + return 0;/*active*/ +} +/*ko attach==============================*/ +static int aml_dtvdm_init(struct dvb_frontend *fe) +{ + + return 0; +} +static int aml_dtvdm_sleep(struct dvb_frontend *fe) +{ + return 0; +} +static int aml_dtvdm_set_parameters(struct dvb_frontend *fe) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + int ret = 0; + + PR_INFO("%s", __func__); + + delsys_confirm(fe); + if (is_not_active(fe)) { + PR_DBG("set parm:not active\n"); + return 0; + } + switch (nmode) { + case AM_FE_QPSK_N: + + break; + case AM_FE_QAM_N: + PR_INFO("FE_QAM\n"); + ret = gxtv_demod_dvbc_set_frontend(fe); + break; + case AM_FE_OFDM_N: + PR_INFO("FE_OFDM\n"); + ret = gxtv_demod_dvbt_set_frontend(fe); + break; + case AM_FE_ISDBT_N: /*same as dvbt*/ + PR_INFO("FE_OFDM\n"); + ret = gxtv_demod_dvbt_set_frontend(fe); + + break; + case AM_FE_ATSC_N: + PR_INFO("FE_ATSC\n"); + ret = gxtv_demod_atsc_set_frontend(fe); + break; + case AM_FE_DTMB_N: + PR_INFO("FE_DTMB\n"); + ret = gxtv_demod_dtmb_set_frontend(fe); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; +} + +static int aml_dtvdm_get_frontend(struct dvb_frontend *fe, + struct dtv_frontend_properties *p) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("get parm:not active\n"); + return 0; + } + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_get_frontend(fe); + break; + case AM_FE_OFDM_N: + ret = gxtv_demod_dvbt_get_frontend(fe); + break; + case AM_FE_ISDBT_N: /*same as dvbt*/ + ret = gxtv_demod_dvbt_get_frontend(fe); + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_get_frontend(fe); + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_get_frontend(fe); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; +} +static int aml_dtvdm_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings + *fe_tune_settings) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("get parm:not active\n"); + return 0; + } + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + fe_tune_settings->min_delay_ms = 4000; + fe_tune_settings->step_size = 0; /* no zigzag */ + fe_tune_settings->max_drift = 0; + + break; + case AM_FE_OFDM_N: + /*dvbt*/ + fe_tune_settings->min_delay_ms = 4000; + fe_tune_settings->step_size = 0; + fe_tune_settings->max_drift = 0; + break; + case AM_FE_ISDBT_N: /*same as dvbt*/ + /*isdbt*/ + fe_tune_settings->min_delay_ms = 4000; + fe_tune_settings->step_size = 0; + fe_tune_settings->max_drift = 0; + + break; + case AM_FE_ATSC_N: + + break; + case AM_FE_DTMB_N: + + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; +} +static int aml_dtvdm_read_status(struct dvb_frontend *fe, + enum fe_status *status) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("read status:not active\n"); + return 0; + } + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_read_status_timer(fe, status); + break; + case AM_FE_OFDM_N: + ret = gxtv_demod_dvbt_read_status(fe, status); + break; + case AM_FE_ISDBT_N: + ret = gxtv_demod_dvbt_read_status(fe, status); + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_read_status(fe, status); + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_read_status(fe, status); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; + +} +static int aml_dtvdm_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("read ber:not active\n"); + return 0; + } + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_read_ber(fe, ber); + break; + case AM_FE_OFDM_N: + ret = gxtv_demod_dvbt_read_ber(fe, ber); + break; + case AM_FE_ISDBT_N: /*same as dvbt*/ + ret = gxtv_demod_dvbt_read_ber(fe, ber); + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_read_ber(fe, ber); + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_read_ber(fe, ber); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; + +} + +static int aml_dtvdm_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("read strength:not active\n"); + return 0; + } + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_read_signal_strength(fe, strength); + break; + case AM_FE_OFDM_N: + ret = gxtv_demod_dvbt_read_signal_strength(fe, strength); + break; + case AM_FE_ISDBT_N: /*same as dvbt*/ + ret = gxtv_demod_dvbt_read_signal_strength(fe, strength); + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_read_signal_strength(fe, strength); + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_read_signal_strength(fe, strength); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; + +} +static int aml_dtvdm_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("read snr :not active\n"); + return 0; + } + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_read_snr(fe, snr); + break; + case AM_FE_OFDM_N: + ret = gxtv_demod_dvbt_read_snr(fe, snr); + break; + case AM_FE_ISDBT_N: + ret = gxtv_demod_dvbt_read_snr(fe, snr); + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_read_snr(fe, snr); + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_read_snr(fe, snr); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; + +} +static int aml_dtvdm_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + int ret = 0; + + if (is_not_active(fe)) { + PR_DBG("read ucblocks :not active\n"); + return 0; + } + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + ret = gxtv_demod_dvbc_read_ucblocks(fe, ucblocks); + break; + case AM_FE_OFDM_N: + ret = gxtv_demod_dvbt_read_ucblocks(fe, ucblocks); + break; + case AM_FE_ISDBT_N: + ret = gxtv_demod_dvbt_read_ucblocks(fe, ucblocks); + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_read_ucblocks(fe, ucblocks); + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_read_ucblocks(fe, ucblocks); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } + return ret; + +} +static void aml_dtvdm_release(struct dvb_frontend *fe) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + gxtv_demod_dvbc_release(fe); + break; + case AM_FE_OFDM_N: + case AM_FE_ISDBT_N: + gxtv_demod_dvbt_release(fe); + break; + case AM_FE_ATSC_N: + gxtv_demod_atsc_release(fe); + break; + case AM_FE_DTMB_N: + gxtv_demod_dtmb_release(fe); + break; + case AM_FE_UNKNOWN_N: + default: + + break; + } +} + + +static int aml_dtvdm_tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, unsigned int *delay, enum fe_status *status) +{ + enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode; + int ret = 0; + static int flg; /*debug only*/ + + delsys_confirm(fe); + + if (is_not_active(fe)) { + PR_DBG("tune :not active\n"); + return 0; + } + + if ((flg > 0) && (flg < 5)) + PR_INFO("%s\n", __func__); + + + switch (nmode) { + case AM_FE_QPSK_N: + + break; + + case AM_FE_QAM_N: + gxtv_demod_dvbc_tune(fe, re_tune, mode_flags, + delay, status); + + break; + case AM_FE_OFDM_N: + case AM_FE_ISDBT_N: + break; + case AM_FE_ATSC_N: + ret = gxtv_demod_atsc_tune(fe, re_tune, mode_flags, + delay, status); + flg++; + break; + case AM_FE_DTMB_N: + ret = gxtv_demod_dtmb_tune(fe, re_tune, mode_flags, + delay, status); + + break; + case AM_FE_UNKNOWN_N: + default: + flg = 0; + break; + } + + return ret; + +} +static int aml_dtvdm_set_property(struct dvb_frontend *dev, + struct dtv_property *tvp) +{ + int r = 0; + u32 delsys; + + switch (tvp->cmd) { + case DTV_DELIVERY_SYSTEM: + delsys = tvp->u.data; + delsys_set(dev, delsys); + break; + + default: + break; + } + + + return r; + +} +static int aml_dtvdm_get_property(struct dvb_frontend *dev, + struct dtv_property *tvp) +{ + return 0; +} + +static struct dvb_frontend_ops aml_dtvdm_gxtvbb_ops = { + .delsys = { SYS_DVBC_ANNEX_A, SYS_DTMB}, + .info = { + /*in aml_fe, it is 'amlogic dvb frontend' */ + .name = "amlogic dtv demod txlx", + .frequency_min = 51000000, + .frequency_max = 900000000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, /**/ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS + }, + .init = aml_dtvdm_init, + .sleep = aml_dtvdm_sleep, + .set_frontend = aml_dtvdm_set_parameters, + .get_frontend = aml_dtvdm_get_frontend, + .get_tune_settings = aml_dtvdm_get_tune_settings, + .read_status = aml_dtvdm_read_status, + .read_ber = aml_dtvdm_read_ber, + .read_signal_strength = aml_dtvdm_read_signal_strength, + .read_snr = aml_dtvdm_read_snr, + .read_ucblocks = aml_dtvdm_read_ucblocks, + .release = aml_dtvdm_release, + .set_property = aml_dtvdm_set_property, + .get_property = aml_dtvdm_get_property, + +/*-------------*/ + .tune = aml_dtvdm_tune, + .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo, + +}; + +static struct dvb_frontend_ops aml_dtvdm_txl_ops = { + .delsys = { SYS_DVBC_ANNEX_A, SYS_DTMB}, + .info = { + /*in aml_fe, it is 'amlogic dvb frontend' */ + .name = "amlogic dtv demod txlx", + .frequency_min = 51000000, + .frequency_max = 900000000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, /**/ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS + }, + .init = aml_dtvdm_init, + .sleep = aml_dtvdm_sleep, + .set_frontend = aml_dtvdm_set_parameters, + .get_frontend = aml_dtvdm_get_frontend, + .get_tune_settings = aml_dtvdm_get_tune_settings, + .read_status = aml_dtvdm_read_status, + .read_ber = aml_dtvdm_read_ber, + .read_signal_strength = aml_dtvdm_read_signal_strength, + .read_snr = aml_dtvdm_read_snr, + .read_ucblocks = aml_dtvdm_read_ucblocks, + .release = aml_dtvdm_release, + .set_property = aml_dtvdm_set_property, + .get_property = aml_dtvdm_get_property, + +/*-------------*/ + .tune = aml_dtvdm_tune, + .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo, + +}; + +static struct dvb_frontend_ops aml_dtvdm_txlx_ops = { + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT}, + .info = { + /*in aml_fe, it is 'amlogic dvb frontend' */ + .name = "amlogic dtv demod txlx", + .frequency_min = 51000000, + .frequency_max = 900000000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, /**/ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS + }, + .init = aml_dtvdm_init, + .sleep = aml_dtvdm_sleep, + .set_frontend = aml_dtvdm_set_parameters, + .get_frontend = aml_dtvdm_get_frontend, + .get_tune_settings = aml_dtvdm_get_tune_settings, + .read_status = aml_dtvdm_read_status, + .read_ber = aml_dtvdm_read_ber, + .read_signal_strength = aml_dtvdm_read_signal_strength, + .read_snr = aml_dtvdm_read_snr, + .read_ucblocks = aml_dtvdm_read_ucblocks, + .release = aml_dtvdm_release, + .set_property = aml_dtvdm_set_property, + .get_property = aml_dtvdm_get_property, + +/*-------------*/ + .tune = aml_dtvdm_tune, + .get_frontend_algo = gxtv_demod_txlx_get_frontend_algo, + +}; +static struct dvb_frontend_ops aml_dtvdm_gxlx_ops = { + .delsys = { SYS_DVBC_ANNEX_A }, + .info = { + /*in aml_fe, it is 'amlogic dvb frontend' */ + .name = "amlogic dtv demod txlx", + .frequency_min = 51000000, + .frequency_max = 900000000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, /**/ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS + }, + .init = aml_dtvdm_init, + .sleep = aml_dtvdm_sleep, + .set_frontend = aml_dtvdm_set_parameters, + .get_frontend = aml_dtvdm_get_frontend, + .get_tune_settings = aml_dtvdm_get_tune_settings, + .read_status = aml_dtvdm_read_status, + .read_ber = aml_dtvdm_read_ber, + .read_signal_strength = aml_dtvdm_read_signal_strength, + .read_snr = aml_dtvdm_read_snr, + .read_ucblocks = aml_dtvdm_read_ucblocks, + .release = aml_dtvdm_release, + .set_property = aml_dtvdm_set_property, + .get_property = aml_dtvdm_get_property, + +/*-------------*/ + .tune = aml_dtvdm_tune, + .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo, + +}; + +static struct dvb_frontend_ops aml_dtvdm_txhd_ops = { + .delsys = { SYS_DTMB }, + .info = { + /*in aml_fe, it is 'amlogic dvb frontend' */ + .name = "amlogic dtv demod txlx", + .frequency_min = 51000000, + .frequency_max = 900000000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, /**/ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS + }, + .init = aml_dtvdm_init, + .sleep = aml_dtvdm_sleep, + .set_frontend = aml_dtvdm_set_parameters, + .get_frontend = aml_dtvdm_get_frontend, + .get_tune_settings = aml_dtvdm_get_tune_settings, + .read_status = aml_dtvdm_read_status, + .read_ber = aml_dtvdm_read_ber, + .read_signal_strength = aml_dtvdm_read_signal_strength, + .read_snr = aml_dtvdm_read_snr, + .read_ucblocks = aml_dtvdm_read_ucblocks, + .release = aml_dtvdm_release, + .set_property = aml_dtvdm_set_property, + .get_property = aml_dtvdm_get_property, + +/*-------------*/ + .tune = aml_dtvdm_tune, + .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo, + +}; + +struct dvb_frontend *aml_dtvdm_attach(const struct amlfe_exp_config *config) + + +{ + int ic_version = get_ic_ver(); + + + /*mem setting is in prob*/ + + struct dvb_frontend *fe = &dtvdd_devp->frontend; + + /* mem of dvb_frontend is define in aml_fe*/ + + switch (ic_version) { + + case IC_VER_GTVBB: + memcpy(&fe->ops, &aml_dtvdm_gxtvbb_ops, + sizeof(struct dvb_frontend_ops)); + break; + case IC_VER_TXL: + memcpy(&fe->ops, &aml_dtvdm_txl_ops, + sizeof(struct dvb_frontend_ops)); + break; + case IC_VER_TXLX: + memcpy(&fe->ops, &aml_dtvdm_txlx_ops, + sizeof(struct dvb_frontend_ops)); + break; + case IC_VER_GXLX: + memcpy(&fe->ops, &aml_dtvdm_gxlx_ops, + sizeof(struct dvb_frontend_ops)); + break; + case IC_VER_TXHD: + memcpy(&fe->ops, &aml_dtvdm_txhd_ops, + sizeof(struct dvb_frontend_ops)); + break; + default: + PR_ERR("attach fail! ic=%d\n", ic_version); + /*return NULL;*/ + fe = NULL; + break; + } + /* mem of dvb_frontend is define in aml_fe*/ + + dtvdd_devp->last_delsys = SYS_UNDEFINED; + + + return fe; +} +EXPORT_SYMBOL(aml_dtvdm_attach); + +/*-------------------------*/ +static struct aml_exp_func aml_exp_ops = { + .leave_mode = leave_mode, +}; + +struct aml_exp_func *aml_dtvdm_exp_attach(struct aml_exp_func *exp) +{ + if (exp) { + memcpy(exp, &aml_exp_ops, sizeof(struct aml_exp_func)); + } else { + PR_ERR("%s:fail!\n", __func__); + return NULL; + + } + return exp; +} +EXPORT_SYMBOL(aml_dtvdm_exp_attach); + +/*-------------------------*/ +struct dvb_frontend *aml_get_fe(void) +{ + + return &dtvdd_devp->frontend; + +} + +void aml_exp_attach(struct aml_exp_func *afe) +{ + +} +EXPORT_SYMBOL(aml_exp_attach); + +/*=======================================*/ + +fs_initcall(aml_dtvdemod_init); +module_exit(aml_dtvdemod_exit); + +MODULE_DESCRIPTION("gxtv_demod DVB-T/DVB-C/DTMB Demodulator driver"); +MODULE_AUTHOR("RSJ"); +MODULE_LICENSE("GPL"); diff --git a/drivers/amlogic/media/amldemod/atsc_func.c b/drivers/amlogic/media/amldemod/atsc_func.c new file mode 100644 index 0000000..e2d4fef --- /dev/null +++ b/drivers/amlogic/media/amldemod/atsc_func.c @@ -0,0 +1,1658 @@ +/* + * drivers/amlogic/media/amldemod/atsc_func.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 "demod_func.h" +#include +#include +#include +#include + +/* static void __iomem * demod_meson_reg_map[4]; */ +#if 0 +#define pr_dbg(fmt, args ...) \ + do { \ + if (debug_atsc) \ + pr_info("FE: " fmt, ## args); \ + } while (0) +#define pr_error(fmt, args ...) pr_info("FE: " fmt, ## args) +#endif + +MODULE_PARM_DESC(debug_atsc, "\n\t\t Enable frontend atsc debug information"); +static int debug_atsc = 1; +module_param(debug_atsc, int, 0644); + +MODULE_PARM_DESC(atsc_thread_enable, "\n\t\t Enable frontend debug information"); +static int atsc_thread_enable = 1; +module_param(atsc_thread_enable, int, 0644); + +MODULE_PARM_DESC(ar_enable, "\n\t\t Enable ar"); +static int ar_enable; +module_param(ar_enable, int, 0644); + +MODULE_PARM_DESC(cci_enable, "\n\t\t Enable ar"); +static int cci_enable = 1; +module_param(cci_enable, int, 0644); + +MODULE_PARM_DESC(cfo_count, "\n\t\t cfo_count"); +static int cfo_count; +module_param(cfo_count, int, 0644); + +MODULE_PARM_DESC(field_test_version, "\n\t\t field_test_version"); +static int field_test_version; +module_param(field_test_version, int, 0644); + +MODULE_PARM_DESC(cfo_times, "\n\t\t cfo_times"); +static int cfo_times = 30; +module_param(cfo_times, int, 0644); + + +static int dagc_switch; +static int ar_flag; +static int awgn_flag; + +/* 8vsb */ +static struct atsc_cfg list_8vsb[22] = { + {0x0733, 0x00, 0}, + {0x0734, 0xff, 0}, + {0x0716, 0x02, 0}, /* F06[7] invert spectrum 0x02 0x06 */ + {0x05e7, 0x00, 0}, + {0x05e8, 0x00, 0}, + {0x0f06, 0x80, 0}, + {0x0f09, 0x04, 0}, + {0x070c, 0x18, 0}, + {0x070d, 0x9d, 0}, + {0x070e, 0x89, 0}, + {0x070f, 0x6a, 0}, + {0x0710, 0x75, 0}, + {0x0711, 0x6f, 0}, + {0x072a, 0x02, 0}, + {0x072c, 0x02, 0}, + {0x090d, 0x03, 0}, + {0x090e, 0x02, 0}, + {0x090f, 0x00, 0}, + {0x0900, 0x01, 0}, + {0x0900, 0x00, 0}, + {0x0f00, 0x01, 0}, + {0x0000, 0x00, 1} +}; + +/* 64qam */ +static struct atsc_cfg list_qam64[111] = { + {0x0900, 0x01, 0}, + {0x0f04, 0x08, 0}, + {0x0f06, 0x80, 0}, + {0x0f07, 0x00, 0}, + {0x0f00, 0xe0, 0}, + {0x0f00, 0xec, 0}, + {0x0001, 0x05, 0}, + {0x0002, 0x61, 0}, /* /0x61 invert spectrum */ + {0x0003, 0x3e, 0}, + {0x0004, 0xed, 0}, /* 0x9d */ + {0x0005, 0x10, 0}, + {0x0006, 0xc0, 0}, + {0x0007, 0x5c, 0}, + {0x0008, 0x0f, 0}, + {0x0009, 0x4f, 0}, + {0x000a, 0xfc, 0}, + {0x000b, 0x0c, 0}, + {0x000c, 0x6c, 0}, + {0x000d, 0x3a, 0}, + {0x000e, 0x10, 0}, + {0x000f, 0x02, 0}, + {0x0011, 0x00, 0}, + {0x0012, 0xf5, 0}, + {0x0013, 0x74, 0}, + {0x0014, 0xb9, 0}, + {0x0015, 0x1f, 0}, + {0x0016, 0x80, 0}, + {0x0017, 0x1f, 0}, + {0x0018, 0x0f, 0}, + {0x001e, 0x00, 0}, + {0x001f, 0x00, 0}, + {0x0023, 0x03, 0}, + {0x0025, 0x20, 0}, + {0x0026, 0xff, 0}, + {0x0027, 0xff, 0}, + {0x0028, 0xf8, 0}, + {0x0200, 0x20, 0}, + {0x0201, 0x62, 0}, + {0x0202, 0x23, 0}, + {0x0204, 0x19, 0}, + {0x0205, 0x74, 0}, + {0x0206, 0xab, 0}, + {0x0207, 0xff, 0}, + {0x0208, 0xc0, 0}, + {0x0209, 0xff, 0}, + {0x0211, 0xc0, 0}, + {0x0212, 0xb0, 0}, + {0x0213, 0x05, 0}, + {0x0215, 0x08, 0}, + {0x0222, 0xe0, 0}, + {0x0223, 0xf0, 0}, + {0x0226, 0x40, 0}, + {0x0229, 0x23, 0}, + {0x022a, 0x02, 0}, + {0x022c, 0x01, 0}, + {0x022e, 0x01, 0}, + {0x022f, 0x25, 0}, + {0x0230, 0x40, 0}, + {0x0231, 0x01, 0}, + {0x0734, 0xff, 0}, + {0x073a, 0xff, 0}, + {0x073b, 0x04, 0}, + {0x073c, 0x08, 0}, + {0x073d, 0x08, 0}, + {0x073e, 0x01, 0}, + {0x073f, 0xf8, 0}, + {0x0740, 0xf1, 0}, + {0x0741, 0xf3, 0}, + {0x0742, 0xff, 0}, + {0x0743, 0x0f, 0}, + {0x0744, 0x1a, 0}, + {0x0745, 0x16, 0}, + {0x0746, 0x00, 0}, + {0x0747, 0xe3, 0}, + {0x0748, 0xce, 0}, + {0x0749, 0xd4, 0}, + {0x074a, 0x00, 0}, + {0x074b, 0x4b, 0}, + {0x074c, 0x00, 0}, + {0x074d, 0xa2, 0}, + {0x074e, 0x00, 0}, + {0x074f, 0xe6, 0}, + {0x0750, 0x00, 0}, + {0x0751, 0x00, 0}, + {0x0752, 0x01, 0}, + {0x0753, 0x03, 0}, + {0x0400, 0x00, 0}, + {0x0408, 0x04, 0}, + {0x040e, 0xe0, 0}, + {0x0500, 0x02, 0}, + {0x05e7, 0x00, 0}, + {0x05e8, 0x00, 0}, + {0x0f09, 0x18, 0}, + {0x070c, 0x20, 0}, + {0x070d, 0x41, 0}, /* 0x49 */ + {0x070e, 0x04, 0}, /* 0x37 */ + {0x070f, 0x00, 0}, + {0x0710, 0x00, 0}, + {0x0711, 0x00, 0}, + {0x0716, 0xf0, 0}, + {0x090f, 0x00, 0}, + {0x0900, 0x01, 1}, + {0x0900, 0x00, 0}, + {0x0001, 0xf5, 0}, + {0x0001, 0xf5, 1}, + {0x0001, 0xf5, 1}, + {0x0001, 0xf5, 1}, + {0x0001, 0xf5, 1}, + {0x0001, 0x05, 0}, + {0x0001, 0x05, 1}, + {0x0000, 0x00, 1} +}; + +/* 256qam */ +static struct atsc_cfg list_qam256[113] = { + {0x0900, 0x01, 0}, + {0x0f04, 0x08, 0}, + {0x0f06, 0x80, 0}, + {0x0f00, 0xe0, 0}, + {0x0f00, 0xec, 0}, + {0x0001, 0x05, 0}, + {0x0002, 0x01, 0}, /* 0x09 */ + {0x0003, 0x2c, 0}, + {0x0004, 0x91, 0}, + {0x0005, 0x10, 0}, + {0x0006, 0xc0, 0}, + {0x0007, 0x5c, 0}, + {0x0008, 0x0f, 0}, + {0x0009, 0x4f, 0}, + {0x000a, 0xfc, 0}, + {0x000b, 0x0c, 0}, + {0x000c, 0x6c, 0}, + {0x000d, 0x3a, 0}, + {0x000e, 0x10, 0}, + {0x000f, 0x02, 0}, + {0x0011, 0x80, 0}, + {0x0012, 0xf5, 0}, /* a5 */ + {0x0013, 0x74, 0}, + {0x0014, 0xb9, 0}, + {0x0015, 0x1f, 0}, + {0x0016, 0x80, 0}, + {0x0017, 0x1f, 0}, + {0x0018, 0x0f, 0}, + {0x001e, 0x00, 0}, + {0x001f, 0x00, 0}, + {0x0023, 0x03, 0}, + {0x0025, 0x20, 0}, + {0x0026, 0xff, 0}, + {0x0027, 0xff, 0}, + {0x0028, 0xf8, 0}, + {0x0200, 0x20, 0}, + {0x0201, 0x62, 0}, + {0x0202, 0x23, 0}, + {0x0204, 0x19, 0}, + {0x0205, 0x76, 0}, + {0x0206, 0xd2, 0}, + {0x0207, 0xff, 0}, + {0x0208, 0xc0, 0}, + {0x0209, 0xff, 0}, + {0x0211, 0xc0, 0}, + {0x0212, 0xb0, 0}, + {0x0213, 0x05, 0}, + {0x0215, 0x08, 0}, + {0x0222, 0xf0, 0}, + {0x0223, 0xff, 0}, + {0x0226, 0x40, 0}, + {0x0229, 0x23, 0}, + {0x022a, 0x02, 0}, + {0x022c, 0x01, 0}, + {0x022e, 0x01, 0}, + {0x022f, 0x05, 0}, + {0x0230, 0x40, 0}, + {0x0231, 0x01, 0}, + {0x0400, 0x02, 0}, + {0x0401, 0x30, 0}, + {0x0402, 0x13, 0}, + {0x0406, 0x06, 0}, + {0x0408, 0x04, 0}, + {0x040e, 0xe0, 0}, + {0x0411, 0x02, 0}, + {0x073a, 0x02, 0}, + {0x073b, 0x09, 0}, + {0x073c, 0x0c, 0}, + {0x073d, 0x08, 0}, + {0x073e, 0xfd, 0}, + {0x073f, 0xf2, 0}, + {0x0740, 0xed, 0}, + {0x0741, 0xf4, 0}, + {0x0742, 0x03, 0}, + {0x0743, 0x15, 0}, + {0x0744, 0x1d, 0}, + {0x0745, 0x15, 0}, + {0x0746, 0xfc, 0}, + {0x0747, 0xde, 0}, + {0x0748, 0xcc, 0}, + {0x0749, 0xd6, 0}, + {0x074a, 0x04, 0}, + {0x074b, 0x4f, 0}, + {0x074c, 0x00, 0}, + {0x074d, 0xa2, 0}, + {0x074e, 0x00, 0}, + {0x074f, 0xe3, 0}, + {0x0750, 0x00, 0}, + {0x0751, 0xfc, 0}, + {0x0752, 0x00, 0}, + {0x0753, 0x03, 0}, + {0x0500, 0x02, 0}, + {0x05e7, 0x00, 0}, + {0x05e8, 0x00, 0}, + {0x0f09, 0x18, 0}, + {0x070c, 0x20, 0}, + {0x070d, 0x49, 0}, + {0x070e, 0x37, 0}, + {0x070f, 0x00, 0}, + {0x0710, 0x00, 0}, + {0x0711, 0x00, 0}, + {0x0716, 0xf0, 0}, + {0x090f, 0x00, 0}, + {0x0900, 0x01, 1}, + {0x0900, 0x00, 0}, + {0x0001, 0xf5, 0}, + {0x0001, 0xf5, 1}, + {0x0001, 0xf5, 1}, + {0x0001, 0xf5, 1}, + {0x0001, 0xf5, 1}, + {0x0001, 0x05, 0}, + {0x0001, 0x05, 1}, + {0x0000, 0x00, 1} +}; + +unsigned int SNR_table[56] = { + 0, 7, 9, 11, 14, + 17, 22, 27, 34, 43, 54, + 68, 86, 108, 136, 171, + 215, 271, 341, 429, 540, + 566, 592, 620, 649, 680, + 712, 746, 781, 818, 856, + 896, 939, 983, 1029, 1078, + 1182, 1237, 1237, 1296, 1357, + 1708, 2150, 2707, 3408, 4291, + 5402, 6800, 8561, 10778, 13568, + 16312, 17081, 18081, 19081, 65536 +}; +unsigned int SNR_dB_table[56] = { + 360, 350, 340, 330, 320, + 310, 300, 290, 280, 270, 260, + 250, 240, 230, 220, 210, + 200, 190, 180, 170, 160, + 158, 156, 154, 152, 150, + 148, 146, 144, 142, 140, + 138, 136, 134, 132, 130, + 128, 126, 124, 122, 120, + 110, 100, 90, 80, 70, + 60, 50, 40, 30, 20, + 12, 10, 4, 2, 0 +}; + +void atsc_set_version(int version) +{ + if (version == 1) + field_test_version = 1; + else if (version == 2) + field_test_version = 0; + else + field_test_version = 1; +} + +/*int atsc_qam_set(fe_modulation_t mode)*/ +int atsc_qam_set(enum fe_modulation mode) + +{ + int i, j; + + if (mode == VSB_8) { /* 5-8vsb, 2-64qam, 4-256qam */ + for (i = 0; list_8vsb[i].adr != 0; i++) { + if (list_8vsb[i].rw) + atsc_read_reg(list_8vsb[i].adr); + /* msleep(20); */ + else + atsc_write_reg(list_8vsb[i].adr, + list_8vsb[i].dat); + /* msleep(20); */ + } + j = 15589; + PR_ATSC("8-vsb mode\n"); + } else if (mode == QAM_64) { + for (i = 0; list_qam64[i].adr != 0; i++) { + if (list_qam64[i].rw) { + atsc_read_reg(list_qam64[i].adr); + msleep(20); + } else { + atsc_write_reg(list_qam64[i].adr, + list_qam64[i].dat); + msleep(20); + } + } + j = 16588; /* 33177; */ + PR_ATSC("64qam mode\n"); + } else if (mode == QAM_256) { + for (i = 0; list_qam256[i].adr != 0; i++) { + if (list_qam256[i].rw) { + atsc_read_reg(list_qam256[i].adr); + msleep(20); + } else { + atsc_write_reg(list_qam256[i].adr, + list_qam256[i].dat); + msleep(20); + } + } + j = 15649; /* 31298; */ + PR_ATSC("256qam mode\n"); + } else { + for (i = 0; list_qam256[i].adr != 0; i++) { + if (list_qam256[i].rw) { + atsc_read_reg(list_qam256[i].adr); + msleep(20); + } else { + atsc_write_reg(list_qam256[i].adr, + list_qam256[i].dat); + msleep(20); + } + } + j = 15649; /* 31298; */ + PR_ATSC("256qam mode\n"); + } + return j; +} + +int read_snr_atsc_tune(void) +{ + unsigned int SNR; + unsigned int SNR_dB; + int tmp[3]; + + tmp[0] = atsc_read_reg(0x0511); + tmp[1] = atsc_read_reg(0x0512); + SNR = (tmp[0] << 8) + tmp[1]; + SNR_dB = SNR_dB_table[atsc_find(SNR, SNR_table, 56)]; + return SNR_dB; +} + +void set_cr_ck_rate(void) +{ + atsc_write_reg(0x0f07, 0x21);/*0x50*/ + /*25M ADC B2*/ + /*atsc_write_reg(0x070c, 0x19);*/ + /*atsc_write_reg(0x070d, 0x30);*/ + /*atsc_write_reg(0x070e, 0xbe);*/ + /*atsc_write_reg(0x070f, 0x52);*/ + /*atsc_write_reg(0x0710, 0xab);*/ + /*atsc_write_reg(0x0711, 0xfe);*/ + /*24M Crystal*/ + atsc_write_reg(0x70c, 0x1a); + atsc_write_reg(0x70d, 0xaa); + atsc_write_reg(0x70e, 0xaa); + atsc_write_reg(0x70f, 0x3a); + atsc_write_reg(0x710, 0xe5); + atsc_write_reg(0x711, 0xc9); + atsc_write_reg(0x0f06, 0x00); + atsc_write_reg(0x0580, 0x01); + atsc_write_reg(0x0520, 0x09); + atsc_write_reg(0x0f28, 0x0f); + atsc_write_reg(0x0f2d, 0x80); + atsc_write_reg(0x0f2b, 0x04); + atsc_write_reg(0x07f0, 0x31); + atsc_write_reg(0x07f1, 0x31); + atsc_write_reg(0x07f2, 0x31); + atsc_write_reg(0x07f3, 0x31); + atsc_write_reg(0x07f4, 0x31); + atsc_write_reg(0x07f5, 0x31); + atsc_write_reg(0x07f6, 0x31); + atsc_write_reg(0x072c, 0x04); + /* 50 ck confirm cnt*/ + atsc_write_reg(0x054f, 0x20); + /* 76 timeout cnt*/ + atsc_write_reg(0x0550, 0x02); + /* 77 timeout cnt */ + atsc_write_reg(0x0572, 0x18); + /* 77 timeout cnt */ + atsc_write_reg(0x0556, 0x04); + /* DFE sz for 75 */ + atsc_write_reg(0x0557, 0x04); + /* DFE sz for 76 */ + atsc_write_reg(0x055a, 0x04); + /* DFE sz for 79 MUST */ + atsc_write_reg(0x0f33, 0x33); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x0f32, 0x33); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x0f31, 0x33); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x0912, 0xf0); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x0555, 0x02); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x053c, 0x0e); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x053d, 0x0e); + /* FA stepsize 0.5 MUST */ + atsc_write_reg(0x053b, 0x0d); + atsc_write_reg(0x057b, 0x01); + atsc_write_reg(0x057a, 0x0d); + atsc_write_reg(0x0f6f, 0x81); + atsc_write_reg(0x0735, 0x83); + atsc_write_reg(0x0f6a, 0x00); + atsc_write_reg(0x0724, 0x00); + /* PN 2cond correlation threshold ,*/ + /* case138 fail if it is default 16 */ + atsc_write_reg(0x0552, 0x10); + /* FSM79 TO cnt */ + atsc_write_reg(0x0551, 0x30); + /* FSM78 TO cnt */ + atsc_write_reg(0x050e, 0x20); + /* FSM77 TO thres 10dB */ + atsc_write_reg(0x050f, 0x1a); + /* FSM78 TO thres 11dB */ + atsc_write_reg(0x0510, 0x1a); + /* FSM78 TO thres 11dB */ + atsc_write_reg(0x05f2, 0x82); + /* decrease lock time 0x88->0x82 */ + atsc_write_reg(0x05f3, 0x82); + /* decrease lock time 0x88->0x82 */ + atsc_write_reg(0x736, 0x60); + atsc_write_reg(0x737, 0x00); + atsc_write_reg(0x738, 0x00); + atsc_write_reg(0x739, 0x00); + atsc_write_reg(0x735, 0x83); + atsc_write_reg(0x918, 0x0); + + /*filed test bug in sfo*/ + atsc_write_reg(0x53b, 0x0b); + atsc_write_reg(0x545, 0x0); + atsc_write_reg(0x546, 0x80); + +if (!field_test_version) { + /*improve phase nosie 20170820*/ + atsc_write_reg(0x912, 0x10); + atsc_write_reg(0xf55, 0x00); + atsc_write_reg(0xf56, 0x00); + atsc_write_reg(0xf57, 0x00); + /*improve impluse nosie 20170820*/ + atsc_write_reg(0x546, 0xa0); + /*improve awgn*/ + atsc_write_reg(0x52d, 0x04); + atsc_write_reg(0x562, 0x0b); + atsc_write_reg(0x53b, 0x0d); + atsc_write_reg(0x735, 0x00); + + /*r2,2 case*/ + atsc_write_reg(0x505, 0x19); + atsc_write_reg(0x506, 0x15); + atsc_write_reg(0xf6f, 0xc0); + atsc_write_reg(0xf6e, 0x09); + atsc_write_reg(0x562, 0x08); + + if (awgn_flag == TASK4_TASK5) + atsc_set_performance_register(TASK4_TASK5, 1); + else if (awgn_flag == AWGN) + atsc_set_performance_register(AWGN, 1); + else if (awgn_flag == TASK4_TASK5) + atsc_set_performance_register(TASK8_R22, 1); + atsc_write_reg(0x716, 0x02); +} else { + PR_ATSC("!!!!!! field test !!!!!!!!!"); + atsc_write_reg(0x716, 0x02); + atsc_write_reg(0x552, 0x20); + atsc_write_reg(0x551, 0x28); + atsc_write_reg(0x550, 0x08); + atsc_write_reg(0x54f, 0x08); + atsc_write_reg(0x54e, 0x08); + atsc_write_reg(0x54d, 0x08); + atsc_write_reg(0x54c, 0x08); + atsc_write_reg(0x53b, 0x0e); +} + ar_flag = 0; +} + + +void atsc_initial(struct aml_demod_sta *demod_sta) +{ + int fc, fs, cr, ck, j; + enum fe_modulation mode; + + mode = demod_sta->ch_mode; + + j = atsc_qam_set(mode); /* set mode */ + + fs = demod_sta->adc_freq; /* KHZ 25200 */ + fc = demod_sta->ch_if; /* KHZ 6350 */ + + cr = (fc * (1 << 17) / fs) * (1 << 6); + ck = fs * j / 10 - (1 << 25); + /* ck_rate = (f_samp / f_vsb /2 -1)*(1<<25);*/ + /*double f_vsb = 10.76238;// double f_64q = 5.056941;*/ + /* // double f_256q = 5.360537; */ + + atsc_write_reg(0x070e, cr & 0xff); + atsc_write_reg(0x070d, (cr >> 8) & 0xff); + atsc_write_reg(0x070c, (cr >> 16) & 0xff); + + if (demod_sta->ch_mode == VSB_8) { + atsc_write_reg(0x0711, ck & 0xff); + atsc_write_reg(0x0710, (ck >> 8) & 0xff); + atsc_write_reg(0x070f, (ck >> 16) & 0xff); + } + PR_ATSC("0x70e is %x, 0x70d is %x, 0x70c is %x\n", + cr & 0xff, (cr >> 8) & 0xff, (cr >> 16) & 0xff); + PR_ATSC("fs is %d(SR),fc is %d(IF),cr is %x,ck is %x\n", + fs, fc, cr, ck); +} + +int atsc_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_atsc *demod_atsc) +{ + int ret = 0; + u8 demod_mode; + u8 bw, sr, ifreq, agc_mode; + u32 ch_freq; + + bw = demod_atsc->bw; + sr = demod_atsc->sr; + ifreq = demod_atsc->ifreq; + agc_mode = demod_atsc->agc_mode; + ch_freq = demod_atsc->ch_freq; + demod_mode = demod_atsc->dat0; + demod_sta->ch_mode = demod_atsc->mode; /* TODO */ + demod_sta->agc_mode = agc_mode; + demod_sta->ch_freq = ch_freq; + demod_sta->dvb_mode = demod_mode; + demod_sta->ch_bw = (8 - bw) * 1000; + /*atsc_initial(demod_sta);*/ + set_cr_ck_rate(); + atsc_reset(); + /*set_cr_ck_rate();*/ + dagc_switch = Dagc_Open; + PR_ATSC("ATSC mode\n"); + return ret; +} + +int read_atsc_fsm(void) +{ + return atsc_read_reg(0x980); +} + +int atsc_read_ser(void) +{ + return atsc_read_reg(0x0687) + + (atsc_read_reg(0x0686) << 8) + + (atsc_read_reg(0x0685) << 16) + + (atsc_read_reg(0x0684) << 24); +} + + +int atsc_find(unsigned int data, unsigned int *ptable, int len) +{ + int end; + int index; + int start; + int cnt = 0; + + start = 0; + end = len; + while ((len > 1) && (cnt < 10)) { + cnt++; + index = (len / 2); + if (data > ptable[start + index]) { + start = start + index; + len = len - index; + } else if (data < ptable[start + index]) { + len = index; + } else if (data == ptable[start + index]) { + start = start + index; + break; + } + } + return start; +} + +void atsc_reset(void) +{ + atsc_write_reg(0x0900, 0x01); + msleep(20); + atsc_write_reg(0x0900, 0x00); +} + + +int atsc_read_snr(void) +{ + int SNR; + int SNR_dB; + + SNR = (atsc_read_reg(0x0511) << 8) + + atsc_read_reg(0x0512); + SNR_dB = SNR_dB_table[atsc_find(SNR, SNR_table, 56)]; + return SNR_dB/10; + +} + +int atsc_read_snr_10(void) +{ + int SNR; + int SNR_dB; + + SNR = (atsc_read_reg(0x0511) << 8) + + atsc_read_reg(0x0512); + SNR_dB = SNR_dB_table[atsc_find(SNR, SNR_table, 56)]; + return SNR_dB; +} + + +int check_snr_ser(int ser_threshholds) +{ + int ser_be, ser_af; + int SNR; + int SNR_dB; + + SNR = (atsc_read_reg(0x0511) << 8) + + atsc_read_reg(0x0512); + SNR_dB = SNR_dB_table[atsc_find(SNR, SNR_table, 56)]; + ser_be = atsc_read_ser(); + msleep(100); + ser_af = atsc_read_ser(); + PR_ATSC("check_snr_ser [%d][%2d]\n", + (ser_af - ser_be), SNR_dB/10); + if (((ser_af - ser_be) > ser_threshholds) || + (SNR_dB/10 < 14)) + return -1; + else + return 0; +} + +int peak[2048]; +int cci_run(void) +{ + int tmp0[4], tmp1[4], tmp2[4], tmp3[4]; + int result[4], bin[4], power[4]; + int max_p[2], max_b[2], ck0; + int cci_cnt = 0; + int avg_len = 4; + int threshold; + int time[10]; + + threshold = avg_len*200; + time[0] = jiffies_to_msecs(jiffies); + for (ck0 = 0; ck0 < 2048; ck0++) + peak[ck0] = 0; + for (ck0 = 0; ck0 < 2; ck0++) { + max_p[ck0] = 0; + max_b[ck0] = 0; + } + time[1] = jiffies_to_msecs(jiffies); + PR_ATSC("[atsc_time][cci_run1,%d ms]\n", + (time[1] - time[0])); + for (ck0 = 0; ck0 < avg_len; ck0++) { + /* step1: set 0x918[0] = 1;*/ + atsc_write_reg(0x918, 0x3); + tmp0[1] = atsc_read_reg(0x981); + tmp0[2] = atsc_read_reg(0x982); + tmp0[3] = atsc_read_reg(0x983); + tmp1[1] = atsc_read_reg(0x984); + tmp1[2] = atsc_read_reg(0x985); + tmp1[3] = atsc_read_reg(0x986); + tmp2[1] = atsc_read_reg(0x987); + tmp2[2] = atsc_read_reg(0x988); + tmp2[3] = atsc_read_reg(0x989); + tmp3[1] = atsc_read_reg(0x98a); + tmp3[2] = atsc_read_reg(0x98b); + tmp3[3] = atsc_read_reg(0x98c); + result[0] = (tmp0[3]<<16) + + (tmp0[2]<<8) + tmp0[1]; + power[0] = result[0]>>11; + bin[0] = result[0]&0x7ff; + result[1] = (tmp1[3]<<16) + + (tmp1[2]<<8) + tmp1[1]; + power[1] = result[1]>>11; + bin[1] = result[1]&0x7ff; + result[2] = (tmp2[3]<<16) + + (tmp2[2]<<8) + tmp2[1]; + power[2] = result[2]>>11; + bin[2] = result[2]&0x7ff; + result[3] = (tmp3[3]<<16) + + (tmp3[2]<<8) + tmp3[1]; + power[3] = result[3]>>11; + bin[3] = result[3]&0x7ff; + + peak[bin[0]] = peak[bin[0]] + power[0]; + peak[bin[1]] = peak[bin[1]] + power[1]; + peak[bin[2]] = peak[bin[2]] + power[2]; + peak[bin[3]] = peak[bin[3]] + power[3]; + PR_ATSC("[%x]%x,[%x]%x,[%x]%x,[%x]%x\n", + bin[0], peak[bin[0]], bin[1], + peak[bin[1]], bin[2], peak[bin[2]], + bin[3], peak[bin[3]]); + } + time[2] = jiffies_to_msecs(jiffies); + PR_ATSC("[atsc_time][cci_run2,%d ms]\n", + (time[2] - time[1])); + cci_cnt = 0; + for (ck0 = 0; ck0 < 2048; ck0++) { + if (peak[ck0] > threshold) { + if (peak[ck0] > max_p[0]) { + max_p[1] = max_p[0];/*Shift Max*/ + max_b[1] = max_b[0]; + max_p[0] = peak[ck0]; + max_b[0] = ck0; + } else if (peak[ck0] > max_p[1]) { + max_p[1] = peak[ck0]; + max_b[1] = ck0; + } + cci_cnt = cci_cnt + 1; + } + } + time[3] = jiffies_to_msecs(jiffies); + PR_ATSC("[atsc_time][cci_run3,%d ms]\n", + (time[3] - time[2])); + atsc_write_reg(0x736, ((max_b[0]>>8)&0x7) + 0x40); + atsc_write_reg(0x737, max_b[0]&0xff); + atsc_write_reg(0x738, (max_b[1]>>8)&0x7); + atsc_write_reg(0x739, max_b[1]&0xff); + atsc_write_reg(0x735, 0x80); + for (ck0 = 0; ck0 < 2; ck0++) { + PR_ATSC(" %d - %d CCI: pos %x power %x .\n", + cci_cnt, ck0, max_b[ck0], max_p[ck0]); + } + time[4] = jiffies_to_msecs(jiffies); + PR_ATSC("[atsc_time][cci_run4,%d ms]\n", (time[4] - time[3])); + PR_ATSC("[atsc_time]--------printf cost %d us\n", + jiffies_to_msecs(jiffies) - time[4]); + return 0; +} + +int cfo_run(void) +{ + int crRate0, crRate1, crRate2, crRate; + int Fcent, Fs; + int cfo_sta, cr_peak_sta; + int i, j; + int sys_state; + int table_count; + int max_count; + int freq_table[] = {0, -50, 50, -100, 100, -150, 150}; + int scan_range; + int Offset; + int detec_cfo_times = 3; + int ret = 0; + + if (cfo_count == 1) + max_count = 3; + else if (cfo_count == 2) + max_count = 5; + else + max_count = 7; + /*for field test do 3 times*/ + if (field_test_version) { + max_count = 1; + detec_cfo_times = 20; + } + Fcent = Si2176_5M_If*1000;/*if*/ + Fs = Adc_Clk_24M;/*crystal*/ + cfo_sta = 0; + cr_peak_sta = 0; + table_count = 0; + scan_range = 10; + Offset = freq_table[table_count]; + PR_ATSC("Fcent[%d], Fs[%d]\n", Fcent, Fs); + for (i = -(scan_range-1); i <= scan_range+1; i++) { + atsc_reset(); + cfo_sta = UnLock; + cr_peak_sta = UnLock; + crRate = (1<<10)*(Fcent+Offset)/Fs; + crRate *= (1<<13); + crRate0 = crRate&0xff; + crRate1 = (crRate>>8)&0xff; + crRate2 = (crRate>>16)&0xff; + /*set ddc init*/ + atsc_write_reg(0x70e, crRate0); + atsc_write_reg(0x70d, crRate1); + atsc_write_reg(0x70c, crRate2); + PR_ATSC("[autoscan]crRate is %x, Offset is %dkhz\n ", + crRate, Offset); + /*detec cfo signal*/ + for (j = 0; j < detec_cfo_times; j++) { + sys_state = read_atsc_fsm(); + /*sys_state = (sys_state >> 4) & 0x0f;*/ + if (sys_state >= CR_Lock) { + cfo_sta = Lock; + PR_ATSC("fsm[%x][autoscan]cfo lock\n", + read_atsc_fsm()); + break; + } + msleep(20); + } + PR_ATSC("fsm[%x]cfo_sta is %d\n", + read_atsc_fsm(), cfo_sta); + /*detec cr peak signal*/ + if (cfo_sta == Lock) { + for (j = 0; j < cfo_times; j++) { + sys_state = read_atsc_fsm(); + PR_ATSC("fsm[%x]in CR LOCK\n", read_atsc_fsm()); + /*sys_state = (sys_state >> 4) & 0x0f;*/ + if (sys_state >= CR_Peak_Lock) { + cr_peak_sta = Lock; + PR_ATSC( + "fsm[%x][autoscan]cr peak lock\n", + read_atsc_fsm()); + break; + } else if (sys_state <= 20) { + PR_ATSC("no signal,break\n"); + break; + } + msleep(20); + } + } else { + if (table_count >= (max_count-1)) + break; + table_count++; + Offset = freq_table[table_count]; + continue; + } + /*reset*/ + if (cr_peak_sta == Lock) { + /*atsc_reset();*/ + PR_ATSC("fsm[%x][autoscan]atsc_reset\n", + read_atsc_fsm()); + /*return Cfo_Ok;*/ + ret = Cfo_Ok; + } else { + if (table_count >= (max_count-1)) { + PR_ATSC("cfo not lock,will try again\n"); + /*return Cfo_Fail;*/ + ret = Cfo_Fail; + } else { + table_count++; + Offset = freq_table[table_count]; + } + } + } + return ret; +} + +int AR_run(void) +{ + int snr_buffer; + + msleep(100); + snr_buffer = read_snr_atsc_tune(); + snr_buffer = snr_buffer / 10; + PR_ATSC("[AR]AR_run, snr_buffer is %d,ar_flag is %d\n", + snr_buffer, ar_flag); + if ((snr_buffer > 15) && ar_flag) { + atsc_write_reg(0xf2b, 0x4); + ar_flag = 0; + PR_ATSC("[AR]close AR\n"); + } else if ((snr_buffer < 12) && !ar_flag) { + atsc_write_reg(0xf28, 0x8c); + atsc_write_reg(0xf28, 0xc); + atsc_write_reg(0xf2b, 0x14); + ar_flag = 1; + PR_ATSC("[AR]open AR\n"); + } + return 0; +} + +int atsc_check_fsm_status_oneshot(void) +{ + unsigned int SNR; + unsigned int atsc_snr = 0; + unsigned int SNR_dB; + int tmp[3]; + int cr; + int ck; + int SM; + int ber; + int ser; + int cnt; + + cnt = 0; + ber = 0; + ser = 0; + tmp[0] = atsc_read_reg(0x0511); + tmp[1] = atsc_read_reg(0x0512); + SNR = (tmp[0] << 8) + tmp[1]; + SNR_dB = SNR_dB_table[atsc_find(SNR, SNR_table, 56)]; + tmp[2] = atsc_read_reg(0x0782); + tmp[1] = atsc_read_reg(0x0781); + tmp[0] = atsc_read_reg(0x0780); + cr = tmp[0] + (tmp[1] << 8) + (tmp[2] << 16); + tmp[0] = atsc_read_reg(0x0786); + tmp[1] = atsc_read_reg(0x0787); + tmp[2] = atsc_read_reg(0x0788); + ck = (tmp[0] << 16) + (tmp[1] << 8) + tmp[2]; + SM = atsc_read_reg(0x0980); +/* ber per */ + /*Enable SER/BER*/ + atsc_write_reg(0x0601, 0x8); + ber = atsc_read_reg(0x0683) + (atsc_read_reg(0x0682) << 8)+ + (atsc_read_reg(0x0681) << 16) + (atsc_read_reg(0x0680) << 24); + ser = atsc_read_reg(0x0687) + (atsc_read_reg(0x0686) << 8)+ + (atsc_read_reg(0x0685) << 16) + (atsc_read_reg(0x0684) << 24); + PR_ATSC + ("SNR %4x SNRdB %2d.%2d FSM %x cr %6x ck %6x", + SNR, (SNR_dB / 10) + , (SNR_dB - (SNR_dB / 10) * 10) + , SM, cr, ck); + PR_ATSC + (" ber is %8x, ser is %8x\n", + ber, ser); + + atsc_snr = (SNR_dB / 10); + return atsc_snr; +} + +int snr_avg_100_times(void) +{ + int i; + int snr_table[100], snr_all = 0; + int cnt = 0; + + for (i = 0; i < 100; i++) { + snr_table[i] = atsc_read_snr_10(); + snr_all += snr_table[i]; + cnt++; + if (cnt > 10) { + cnt = 0; + msleep(20); + }; + } + snr_all /= 100; + PR_ATSC("snr_all is %d\n", snr_all); + return snr_all/10; + +} + +void atsc_set_r22_register(int flag) +{ + if ((flag == 1) && (awgn_flag == 0)) { + atsc_write_reg(0x5bc, 0x01); + awgn_flag = 1; + PR_ATSC("open awgn setting\n"); + msleep(50); + } else { + awgn_flag = 0; + /*atsc_write_reg(0x5bc, 0x08);*/ + PR_ATSC("close awgn setting\n"); + } +} + +void atsc_set_performance_register(int flag, int init) +{ + if (flag == TASK4_TASK5) { + atsc_write_reg(0x912, 0x00); + atsc_write_reg(0x716, 0x00); + atsc_write_reg(0x5bc, 0x01); + awgn_flag = TASK4_TASK5; + } else if (flag == AWGN) { + atsc_write_reg(0x912, 0x00); + atsc_write_reg(0x5bc, 0x01); + atsc_write_reg(0x716, 0x02); + awgn_flag = AWGN; + } else { + atsc_write_reg(0x912, 0x50); + atsc_write_reg(0x716, 0x02); + if (init == 0) { + atsc_write_reg(0x5bc, 0x07); + atsc_write_reg(0xf6e, 0xaf); + } else { + atsc_write_reg(0x5bc, 0x8); + atsc_write_reg(0xf6e, 0x09); + } + awgn_flag = TASK8_R22; + } +} + +void atsc_thread(void) +{ + int time_table[10]; + int i; + int time[10]; + int ret; + int ser_thresholds; + static int register_set_flag; + static int fsm_status; + int snr_now; + char *info1 = "[atsc_time]fsm"; + + fsm_status = Idle; + ser_thresholds = 200; + time[4] = jiffies_to_msecs(jiffies); + fsm_status = read_atsc_fsm(); + + /*change */ + if (!atsc_thread_enable) + return; + + if (!field_test_version) + PR_ATSC("awgn_flag is %d\n", awgn_flag); + if (fsm_status < Atsc_Lock) { + /*step1:open dagc*/ + + fsm_status = read_atsc_fsm(); + PR_ATSC("fsm[%x]not lock,need to run cci\n", fsm_status); + time[0] = jiffies_to_msecs(jiffies); + /*step2:run cci*/ + set_cr_ck_rate(); + atsc_reset(); + register_set_flag = 0; + /*step:check AR*/ + if (ar_enable) + AR_run(); + if (cci_enable && !field_test_version) + ret = cci_run(); + atsc_reset(); + time[1] = jiffies_to_msecs(jiffies); + time_table[0] = (time[1]-time[0]); + fsm_status = read_atsc_fsm(); + PR_ATSC("%s[%x]cci finish,need to run cfo,cost %d ms\n", + info1, fsm_status, time_table[0]); + if (fsm_status >= Atsc_Lock) { + return; + } else if (fsm_status < CR_Lock) { + /*step3:run cfo*/ + ret = cfo_run(); + } else { + ret = Cfo_Ok; + msleep(100); + } + time[2] = jiffies_to_msecs(jiffies); + time_table[1] = (time[2] - time[1]); + PR_ATSC("fsm[%x][atsc_time]cfo done,cost %d ms,\n", + read_atsc_fsm(), time_table[1]); + if (ret == Cfo_Fail) + return; + for (i = 0; i < 80; i++) { + fsm_status = read_atsc_fsm(); + if (fsm_status >= Atsc_Lock) { + time[3] = jiffies_to_msecs(jiffies); + PR_ATSC("----------------------\n"); + time_table[2] = (time[3] - time[2]); + time_table[3] = (time[3] - time[0]); + time_table[4] = (time[3] - time[5]); + PR_ATSC("%s[%x]cfo->fec lock cost %d ms\n", + info1, fsm_status, time_table[2]); + PR_ATSC("%s[%x]lock,one cost %d ms,\n", + info1, fsm_status, time_table[3]); + break; + } else if (fsm_status <= Idle) { + PR_ATSC("atsc idle,retune, and reset\n"); + set_cr_ck_rate(); + atsc_reset(); + awgn_flag = TASK8_R22; + break; + } + msleep(20); + } + } else { + time[4] = jiffies_to_msecs(jiffies); + atsc_check_fsm_status_oneshot(); + if (ar_enable) + AR_run(); + fsm_status = read_atsc_fsm(); + PR_ATSC("lock\n"); + msleep(100); + if (!field_test_version) { + if (register_set_flag == 0) { + snr_now = snr_avg_100_times(); + PR_ATSC("snr_now is %d\n", snr_now); + if ((snr_now <= 16) && snr_now >= 10) { + atsc_set_performance_register + (AWGN, 0); + } else if (snr_now < 10) { + atsc_set_performance_register + (TASK4_TASK5, 0); + } else { + if (snr_now > 23) { + atsc_set_performance_register + (TASK4_TASK5, 0); + PR_ATSC("snr(23)\n"); + } else if ((snr_now > 16) + && (snr_now <= 23)) { + atsc_set_performance_register + (TASK8_R22, 0); + PR_ATSC("snr(16,23)\n"); + } else { + awgn_flag = TASK8_R22; + } + } + register_set_flag = 1; + msleep(200); + /*%lx to %x*/ + PR_ATSC("912 is %x,5bc is %x\n", + atsc_read_reg(0x912), + atsc_read_reg(0x5bc)); + } + } + + time[5] = jiffies_to_msecs(jiffies); + PR_ATSC("fsm[%x][atsc_time]check lock %d ms,\n", + fsm_status, time[5]-time[4]); + } + +} + + +#if 0 +static dtmb_cfg_t list_dtmb_v1[99] = { + {0x00000000, 0x01, 0}, + {0x00001000, 0x02, 0}, + {0x00000000, 0x03, 0}, + {0x00000000, 0x04, 0}, + {0x00000000, 0x05, 0}, + {0x00000000, 0x06, 0}, + {0x007fffff, 0x07, 0}, + {0x0000000f, 0x08, 0}, + {0x00003000, 0x09, 0}, + {0x00000001, 0x0a, 0}, + {0x0c403006, 0x0b, 0}, + {0x44444400, 0x0c, 0}, + {0x1412c320, 0x0d, 0}, + {0x00000152, 0x10, 0}, + {0x47080137, 0x11, 0}, + {0x02200a16, 0x12, 0}, + {0x42190190, 0x13, 0}, + {0x7f807f80, 0x14, 0}, + {0x0000199a, 0x15, 0}, + {0x000a1466, 0x18, 0}, + {0x00274217, 0x1a, 0}, + {0x00131036, 0x1b, 1}, + {0x00000396, 0x1c, 0}, + {0x0037f3cc, 0x1d, 0}, + {0x00000029, 0x1e, 0}, + {0x0004f031, 0x1f, 0}, + {0x00f3cbd4, 0x20, 0}, + {0x0000007e, 0x21, 0}, + {0x23270b6a, 0x22, 0}, + {0x5f700c1b, 0x23, 0}, + {0x00133c2b, 0x24, 0}, + {0x2d3e0f12, 0x25, 0}, + {0x06363038, 0x26, 0}, + {0x060e0a3e, 0x27, 0}, + {0x0015161f, 0x28, 0}, + {0x0809031b, 0x29, 0}, + {0x181c0307, 0x2a, 0}, + {0x051f1a1b, 0x2b, 0}, + {0x00451dce, 0x2c, 0}, + {0x242fde12, 0x2d, 0}, + {0x0034e8fa, 0x2e, 0}, + {0x00000007, 0x30, 0}, + {0x16000d0c, 0x31, 0}, + {0x0000011f, 0x32, 0}, + {0x01000200, 0x33, 0}, + {0x10bbf376, 0x34, 0}, + {0x00000044, 0x35, 0}, + {0x00000000, 0x36, 0}, + {0x00000000, 0x37, 0}, + {0x00000000, 0x38, 0}, + {0x00000000, 0x39, 0}, + {0x00000031, 0x3a, 0}, + {0x4d6b0a58, 0x3b, 0}, + {0x00000c04, 0x3c, 0}, + {0x0d3b0a50, 0x3d, 0}, + {0x03140480, 0x3e, 0}, + {0x05e60452, 0x3f, 0}, + {0x05780400, 0x40, 0}, + {0x0063c025, 0x41, 0}, + {0x05050202, 0x42, 0}, + {0x5e4a0a14, 0x43, 0}, + {0x00003b42, 0x44, 0}, + {0xa53080ff, 0x45, 0}, + {0x00000000, 0x46, 0}, + {0x00133202, 0x47, 0}, + {0x01f00000, 0x48, 0}, + {0x00000000, 0x49, 0}, + {0x00000000, 0x4a, 0}, + {0x00000000, 0x4b, 0}, + {0x00000000, 0x4c, 0}, + {0x20405dc8, 0x4d, 0}, + {0x00000000, 0x4e, 0}, + {0x1f0205df, 0x4f, 0}, + {0x00001120, 0x50, 0}, + {0x4f190803, 0x51, 0}, + {0x00000000, 0x52, 0}, + {0x00000040, 0x53, 0}, + {0x00100050, 0x54, 0}, + {0x00cd1000, 0x55, 0}, + {0x00010fab, 0x56, 0}, + {0x03f0fc3f, 0x58, 0}, + {0x02005014, 0x59, 0}, + {0x01405014, 0x5a, 0}, + {0x00014284, 0x5b, 0}, + {0x00000320, 0x5c, 0}, + {0x14130e05, 0x5d, 0}, + {0x4321c963, 0x5f, 0}, + {0x624668f8, 0x60, 0}, + {0xccc08888, 0x61, 0}, + {0x13212111, 0x62, 0}, + {0x21100000, 0x63, 0}, + {0x624668f8, 0x64, 0}, + {0xccc08888, 0x65, 0}, + {0x13212111, 0x66, 0}, + {0x21100000, 0x67, 0}, + {0x624668f8, 0x68, 0}, + {0xccc08888, 0x69, 0}, + {0x0, 0x0, 0} +}; +#endif + +int find_2(int data, int *table, int len) +{ + int end; + int index; + int start; + int cnt = 0; + + start = 0; + end = len; + /* printf("data is %d\n",data); */ + while ((len > 1) && (cnt < 10)) { + cnt++; + index = (len / 2); + if (data > table[start + index]) { + start = start + index; + len = len - index - 1; + } + if (data < table[start + index]) { + len = index + 1; + } else if (data == table[start + index]) { + start = start + index; + break; + } + } + return start; +} + +int read_atsc_all_reg(void) +{ + return 0; +#if 0 + int i, j, k; + unsigned long data; + + j = 4; + + PR_ATSC("system agc is:"); /* system agc */ + for (i = 0xc00; i <= 0xc0c; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0xc80; i <= 0xc87; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n vsb control is:"); /*vsb control */ + j = 4; + for (i = 0x900; i <= 0x905; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x908; i <= 0x912; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x917; i <= 0x91b; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x980; i <= 0x992; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n vsb demod is:"); /*vsb demod */ + j = 4; + for (i = 0x700; i <= 0x711; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x716; i <= 0x720; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x722; i <= 0x724; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x726; i <= 0x72c; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x730; i <= 0x732; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x735; i <= 0x751; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x780; i <= 0x795; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x752; i <= 0x755; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n vsb equalizer is:"); /*vsb equalizer */ + j = 4; + for (i = 0x501; i <= 0x5ff; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n vsb fec is:"); /*vsb fec */ + j = 4; + for (i = 0x601; i <= 0x601; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x682; i <= 0x685; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n qam demod is:"); /*qam demod */ + j = 4; + for (i = 0x1; i <= 0x1a; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x25; i <= 0x28; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x101; i <= 0x10b; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x206; i <= 0x207; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n qam equalize is:"); /*qam equalize */ + j = 4; + for (i = 0x200; i <= 0x23d; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + j = 4; + for (i = 0x260; i <= 0x275; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n qam fec is:"); /*qam fec */ + j = 4; + for (i = 0x400; i <= 0x418; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n system mpeg formatter is:"); /*system mpeg formatter */ + j = 4; + for (i = 0xf00; i <= 0xf09; i++) { + data = atsc_read_reg(i); + if (j == 4) { + PR_ATSC("\n[addr:0x%x]", i); + j = 0; + } + PR_ATSC("%02x ", data); + j++; + } + PR_ATSC("\n\n"); + return 0; +#endif +} + +int check_atsc_fsm_status(void) +{ + unsigned int SNR; + unsigned int atsc_snr = 0; + unsigned int SNR_dB; + int tmp[3]; + int cr; + int ck; + int SM; + int tni; + int ber; + int ser; + int cnt; + unsigned int cap_status, cap_usr_dc_addr; + + cnt = 0; + ber = 0; + ser = 0; + tni = atsc_read_reg((0x08) >> 16); + tmp[0] = atsc_read_reg(0x0511); + tmp[1] = atsc_read_reg(0x0512); + SNR = (tmp[0] << 8) + tmp[1]; + SNR_dB = SNR_dB_table[atsc_find(SNR, SNR_table, 56)]; + tmp[2] = atsc_read_reg(0x0782); + tmp[1] = atsc_read_reg(0x0781); + tmp[0] = atsc_read_reg(0x0780); + cr = tmp[0] + (tmp[1] << 8) + (tmp[2] << 16); + tmp[0] = atsc_read_reg(0x0786); + tmp[1] = atsc_read_reg(0x0787); + tmp[2] = atsc_read_reg(0x0788); + ck = (tmp[0] << 16) + (tmp[1] << 8) + tmp[2]; + SM = atsc_read_reg(0x0980); + /* ber per */ + atsc_write_reg(0x0601, 0x8);/* Enable SER/BER*/ + ber = atsc_read_reg(0x0683) + (atsc_read_reg(0x0682) << 8) + + (atsc_read_reg(0x0681) << 16) + + (atsc_read_reg(0x0680) << 24); + ser = atsc_read_reg(0x0687) + (atsc_read_reg(0x0686) << 8) + + (atsc_read_reg(0x0685) << 16) + + (atsc_read_reg(0x0684) << 24); + cap_status = app_apb_read_reg(0x196); + cap_usr_dc_addr = app_apb_read_reg(0x1a1); + +/* read_atsc_all_reg(); */ + + PR_ATSC + ("INT %x SNR %4x SNRdB %2d.%2d FSM %x cr %6x ck %6x", + tni, SNR, (SNR_dB / 10) + , (SNR_dB - (SNR_dB / 10) * 10) + , SM, cr, ck); + PR_ATSC + (" ber is %8x, ser is %8x, cap %4d cap_addr %8x\n", + ber, ser, cap_status>>16, cap_usr_dc_addr); + + atsc_snr = (SNR_dB / 10); + return atsc_snr; +} + diff --git a/drivers/amlogic/media/amldemod/demod_func.c b/drivers/amlogic/media/amldemod/demod_func.c new file mode 100644 index 0000000..fe0acc6 --- /dev/null +++ b/drivers/amlogic/media/amldemod/demod_func.c @@ -0,0 +1,1538 @@ +/* + * drivers/amlogic/media/amldemod/demod_func.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 "demod_func.h" +#include "amlfrontend.h" + +#include +#include +#include +/*#include "acf_filter_coefficient.h"*/ +#include + + +#include + + +#define M6D + +/* static void __iomem * demod_meson_reg_map[4]; */ + + +MODULE_PARM_DESC(debug_demod, "\n\t\t Enable frontend debug information"); +static int debug_demod; +module_param(debug_demod, int, 0644); + + + + + + + + + +MODULE_PARM_DESC(demod_mobile_power, "\n\t\t demod_mobile_power debug information"); +static int demod_mobile_power = 100; +module_param(demod_mobile_power, int, 0644); + + + + +static struct mutex mp; +static struct mutex dtvpll_init_lock; +static int dtvpll_init; +/*static int dtmb_spectrum = 2;*/ +#if defined DEMOD_FPGA_VERSION +static int fpga_version = 1; +#else +static int fpga_version = -1; +#endif + +#if 0 +/*register base address*/ +unsigned int ddemod_reg_base; +unsigned int dd_hiu_reg_base; +unsigned int dtvafe_reg_base; /* only txhd */ + +void dtvdemod_base_add_init(void) +{ + /* init value */ + ddemod_reg_base = IO_DEMOD_BASE; + dd_hiu_reg_base = IO_HIU_BASE; + dtvafe_reg_base = TXHD_TVFE_BASE; + + if (is_meson_gxtvbb_cpu()) { + ddemod_reg_base = IO_DEMOD_BASE; + dd_hiu_reg_base = IO_HIU_BASE; + } else if (is_meson_txl_cpu()) { + ddemod_reg_base = IO_DEMOD_BASE; + dd_hiu_reg_base = IO_HIU_BASE; + } else if (is_meson_txlx_cpu()) { + ddemod_reg_base = TXLX_DEMOD_BASE; + dd_hiu_reg_base = TXLX_IO_HIU_BASE; + } else if (is_meson_gxlx_cpu()) { + ddemod_reg_base = GXLX_DEMOD_BASE; + dd_hiu_reg_base = IO_HIU_BASE; + } else if (is_meson_txhd_cpu()) { + ddemod_reg_base = TXHD_DEMOD_BASE; + dd_hiu_reg_base = TXLX_IO_HIU_BASE; + dtvafe_reg_base = TXHD_TVFE_BASE; + } else { + ddemod_reg_base = TXHD_DEMOD_BASE; + dd_hiu_reg_base = TXLX_IO_HIU_BASE; + dtvafe_reg_base = TXHD_TVFE_BASE; + } + + PR_DBG(" dtv demod reg base address init =0x%x\n", ddemod_reg_base); +} +#endif + +void dtvpll_lock_init(void) +{ + mutex_init(&dtvpll_init_lock); +} + +void dtvpll_init_flag(int on) +{ + mutex_lock(&dtvpll_init_lock); + dtvpll_init = on; + mutex_unlock(&dtvpll_init_lock); + pr_err("%s %d\n", __func__, on); +} + +int get_dtvpll_init_flag(void) +{ + int val; + + mutex_lock(&dtvpll_init_lock); + val = dtvpll_init; + mutex_unlock(&dtvpll_init_lock); + if (!val) + pr_err("%s: %d\n", __func__, val); + return val; +} + + +void adc_dpll_setup(int clk_a, int clk_b, int clk_sys, int dvb_mode) +{ + int unit, found, ena, enb, div2; + int pll_m, pll_n, pll_od_a, pll_od_b, pll_xd_a, pll_xd_b; + long freq_osc, freq_dco, freq_b, freq_a, freq_sys; + long freq_b_act, freq_a_act, freq_sys_act, err_tmp, best_err; + union adc_pll_cntl adc_pll_cntl; + union adc_pll_cntl2 adc_pll_cntl2; + union adc_pll_cntl3 adc_pll_cntl3; + union adc_pll_cntl4 adc_pll_cntl4; + union demod_dig_clk dig_clk_cfg; + + struct dfe_adcpll_para ddemod_pll; + int sts_pll; + + adc_pll_cntl.d32 = 0; + adc_pll_cntl2.d32 = 0; + adc_pll_cntl3.d32 = 0; + adc_pll_cntl4.d32 = 0; + + PR_DBG("target clk_a %d clk_b %d\n", clk_a, clk_b); + + unit = 10000; /* 10000 as 1 MHz, 0.1 kHz resolution. */ + freq_osc = 24 * unit; + + if (clk_a < 1000) + freq_a = clk_a * unit; + else + freq_a = clk_a * (unit / 1000); + + if (clk_b < 1000) + freq_b = clk_b * unit; + else + freq_b = clk_b * (unit / 1000); + + ena = clk_a > 0 ? 1 : 0; + enb = clk_b > 0 ? 1 : 0; + + if (ena || enb) + adc_pll_cntl3.b.enable = 1; + adc_pll_cntl3.b.reset = 1; + + found = 0; + best_err = 100 * unit; + pll_od_a = 1; + pll_od_b = 1; + pll_n = 1; + for (pll_m = 1; pll_m < 512; pll_m++) { + /* for (pll_n=1; pll_n<=5; pll_n++) { */ + #if 0 + if ((is_meson_txl_cpu()) || (is_meson_txlx_cpu()) + || (is_meson_gxlx_cpu()) || (is_meson_txhd_cpu())) { + freq_dco = freq_osc * pll_m / pll_n / 2; + /*txl add div2*/ + if (freq_dco < 700 * unit || freq_dco > 1000 * unit) + continue; + } else { + freq_dco = freq_osc * pll_m / pll_n; + if (freq_dco < 750 * unit || freq_dco > 1550 * unit) + continue; + } + #else + /*if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {*/ + if (get_ic_ver() >= IC_VER_TXL) { + /*txl add div2*/ + freq_dco = freq_osc * pll_m / pll_n / 2; + if (freq_dco < 700 * unit || freq_dco > 1000 * unit) + continue; + + } else { + freq_dco = freq_osc * pll_m / pll_n; + if (freq_dco < 750 * unit || freq_dco > 1550 * unit) + continue; + + } + #endif + pll_xd_a = freq_dco / (1 << pll_od_a) / freq_a; + pll_xd_b = freq_dco / (1 << pll_od_b) / freq_b; + + freq_a_act = freq_dco / (1 << pll_od_a) / pll_xd_a; + freq_b_act = freq_dco / (1 << pll_od_b) / pll_xd_b; + + err_tmp = (freq_a_act - freq_a) * ena + (freq_b_act - freq_b) * + enb; + + if (err_tmp >= best_err) + continue; + + adc_pll_cntl.b.pll_m = pll_m; + adc_pll_cntl.b.pll_n = pll_n; + adc_pll_cntl.b.pll_od0 = pll_od_b; + adc_pll_cntl.b.pll_od1 = pll_od_a; + adc_pll_cntl.b.pll_xd0 = pll_xd_b; + adc_pll_cntl.b.pll_xd1 = pll_xd_a; + #if 0 + if ((is_meson_txl_cpu()) || (is_meson_txlx_cpu()) + || (is_meson_gxlx_cpu()) || (is_meson_txhd_cpu())) { + adc_pll_cntl4.b.pll_od3 = 0; + adc_pll_cntl.b.pll_od2 = 0; + } else { + adc_pll_cntl2.b.div2_ctrl = + freq_dco > 1000 * unit ? 1 : 0; + } + #else + /*if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {*/ + if (get_ic_ver() >= IC_VER_TXL) { + adc_pll_cntl4.b.pll_od3 = 0; + adc_pll_cntl.b.pll_od2 = 0; + + } else { + adc_pll_cntl2.b.div2_ctrl = + freq_dco > 1000 * unit ? 1 : 0; + + } + #endif + found = 1; + best_err = err_tmp; + /* } */ + } + + pll_m = adc_pll_cntl.b.pll_m; + pll_n = adc_pll_cntl.b.pll_n; + pll_od_b = adc_pll_cntl.b.pll_od0; + pll_od_a = adc_pll_cntl.b.pll_od1; + pll_xd_b = adc_pll_cntl.b.pll_xd0; + pll_xd_a = adc_pll_cntl.b.pll_xd1; + + #if 0 + if ((is_meson_txl_cpu()) || (is_meson_txlx_cpu()) + || (is_meson_gxlx_cpu()) || (is_meson_txhd_cpu())) + div2 = 1; + else + div2 = adc_pll_cntl2.b.div2_ctrl; + + #else + /*if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))*/ + if (get_ic_ver() >= IC_VER_TXL) + div2 = 1; + else + div2 = adc_pll_cntl2.b.div2_ctrl; + + #endif + /* + * p_adc_pll_cntl = adc_pll_cntl.d32; + * p_adc_pll_cntl2 = adc_pll_cntl2.d32; + * p_adc_pll_cntl3 = adc_pll_cntl3.d32; + * p_adc_pll_cntl4 = adc_pll_cntl4.d32; + */ + adc_pll_cntl3.b.reset = 0; + /* *p_adc_pll_cntl3 = adc_pll_cntl3.d32; */ + if (!found) { + PR_DBG(" ERROR can't setup %7ld kHz %7ld kHz\n", + freq_b / (unit / 1000), freq_a / (unit / 1000)); + } else { + #if 0 + if ((is_meson_txl_cpu()) || (is_meson_txlx_cpu()) + || (is_meson_gxlx_cpu()) || (is_meson_txhd_cpu())) + freq_dco = freq_osc * pll_m / pll_n / 2; + else + freq_dco = freq_osc * pll_m / pll_n; + #else + /*if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))*/ + if (get_ic_ver() >= IC_VER_TXL) + freq_dco = freq_osc * pll_m / pll_n / 2; + else + freq_dco = freq_osc * pll_m / pll_n; + #endif + PR_DBG(" ADC PLL M %3d N %3d\n", pll_m, pll_n); + PR_DBG(" ADC PLL DCO %ld kHz\n", freq_dco / (unit / 1000)); + + PR_DBG(" ADC PLL XD %3d OD %3d\n", pll_xd_b, pll_od_b); + PR_DBG(" ADC PLL XD %3d OD %3d\n", pll_xd_a, pll_od_a); + + freq_a_act = freq_dco / (1 << pll_od_a) / pll_xd_a; + freq_b_act = freq_dco / (1 << pll_od_b) / pll_xd_b; + + PR_DBG(" B %7ld kHz %7ld kHz\n", + freq_b / (unit / 1000), freq_b_act / (unit / 1000)); + PR_DBG(" A %7ld kHz %7ld kHz\n", + freq_a / (unit / 1000), freq_a_act / (unit / 1000)); + + if (clk_sys > 0) { + dig_clk_cfg.b.demod_clk_en = 1; + dig_clk_cfg.b.demod_clk_sel = 3; + if (clk_sys < 1000) + freq_sys = clk_sys * unit; + else + freq_sys = clk_sys * (unit / 1000); + + dig_clk_cfg.b.demod_clk_div = freq_dco / (1 + div2) / + freq_sys - 1; + freq_sys_act = freq_dco / (1 + div2) / + (dig_clk_cfg.b.demod_clk_div + 1); + PR_DBG(" SYS %7ld kHz div %d+1 %7ld kHz\n", + freq_sys / (unit / 1000), + dig_clk_cfg.b.demod_clk_div, + freq_sys_act / (unit / 1000)); + } else { + dig_clk_cfg.b.demod_clk_en = 0; + } + + /* *p_demod_dig_clk = dig_clk_cfg.d32; */ + } +#if 0 + if (is_meson_txlx_cpu()) { + demod_set_demod_reg(TXLX_ADC_RESET_VALUE, TXLX_ADC_REG3); + demod_set_demod_reg(adc_pll_cntl.d32, TXLX_ADC_REG1); + demod_set_demod_reg(dig_clk_cfg.d32, TXLX_ADC_REG6); + if (dvb_mode == Gxtv_Atsc) + demod_set_demod_reg(0x507, TXLX_ADC_REG6); + else + demod_set_demod_reg(0x502, TXLX_ADC_REG6); + demod_set_demod_reg(TXLX_ADC_REG3_VALUE, TXLX_ADC_REG3); + /* debug */ + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG1, + demod_read_demod_reg(TXLX_ADC_REG1)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG2, + demod_read_demod_reg(TXLX_ADC_REG2)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG3, + demod_read_demod_reg(TXLX_ADC_REG3)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG4, + demod_read_demod_reg(TXLX_ADC_REG4)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG5, + demod_read_demod_reg(TXLX_ADC_REG5)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG6, + demod_read_demod_reg(TXLX_ADC_REG6)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG7, + demod_read_demod_reg(TXLX_ADC_REG7)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG8, + demod_read_demod_reg(TXLX_ADC_REG8)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REG9, + demod_read_demod_reg(TXLX_ADC_REG9)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REGB, + demod_read_demod_reg(TXLX_ADC_REGB)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REGC, + demod_read_demod_reg(TXLX_ADC_REGC)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REGD, + demod_read_demod_reg(TXLX_ADC_REGD)); + PR_DBG("[adc][%x]%x\n", TXLX_ADC_REGE, + demod_read_demod_reg(TXLX_ADC_REGE)); + PR_DBG("[demod][%x]%x\n", TXLX_DEMOD_REG1, + demod_read_demod_reg(TXLX_DEMOD_REG1)); + PR_DBG("[demod][%x]%x\n", TXLX_DEMOD_REG2, + demod_read_demod_reg(TXLX_DEMOD_REG2)); + PR_DBG("[demod][%x]%x\n", TXLX_DEMOD_REG3, + demod_read_demod_reg(TXLX_DEMOD_REG3)); + } else if (is_meson_txl_cpu()) { + demod_set_demod_reg(TXLX_ADC_RESET_VALUE, ADC_REG3); + demod_set_demod_reg(adc_pll_cntl.d32, ADC_REG1); + demod_set_demod_reg(dig_clk_cfg.d32, ADC_REG6); + demod_set_demod_reg(0x502, ADC_REG6); + demod_set_demod_reg(TXLX_ADC_REG3_VALUE, ADC_REG3); + /* debug */ + PR_DBG("[adc][%x]%x\n", ADC_REG1, + demod_read_demod_reg(ADC_REG1)); + PR_DBG("[adc][%x]%x\n", ADC_REG2, + demod_read_demod_reg(ADC_REG2)); + PR_DBG("[adc][%x]%x\n", ADC_REG3, + demod_read_demod_reg(ADC_REG3)); + PR_DBG("[adc][%x]%x\n", ADC_REG4, + demod_read_demod_reg(ADC_REG4)); + PR_DBG("[adc][%x]%x\n", ADC_REG5, + demod_read_demod_reg(ADC_REG5)); + PR_DBG("[adc][%x]%x\n", ADC_REG6, + demod_read_demod_reg(ADC_REG6)); + PR_DBG("[adc][%x]%x\n", ADC_REG7, + demod_read_demod_reg(ADC_REG7)); + PR_DBG("[adc][%x]%x\n", ADC_REG8, + demod_read_demod_reg(ADC_REG8)); + PR_DBG("[adc][%x]%x\n", ADC_REG9, + demod_read_demod_reg(ADC_REG9)); + PR_DBG("[adc][%x]%x\n", ADC_REGB, + demod_read_demod_reg(ADC_REGB)); + PR_DBG("[adc][%x]%x\n", ADC_REGC, + demod_read_demod_reg(ADC_REGC)); + PR_DBG("[adc][%x]%x\n", ADC_REGD, + demod_read_demod_reg(ADC_REGD)); + PR_DBG("[adc][%x]%x\n", ADC_REGE, + demod_read_demod_reg(ADC_REGE)); + PR_DBG("[demod][%x]%x\n", DEMOD_REG1, + demod_read_demod_reg(DEMOD_REG1)); + PR_DBG("[demod][%x]%x\n", DEMOD_REG2, + demod_read_demod_reg(DEMOD_REG2)); + PR_DBG("[demod][%x]%x\n", DEMOD_REG3, + demod_read_demod_reg(DEMOD_REG3)); + } else if (is_meson_gxlx_cpu()) { + /*demod_set_demod_reg(TXLX_ADC_RESET_VALUE, ADC_REG3);*/ + /*demod_set_demod_reg(adc_pll_cntl.d32, ADC_REG1);*/ + demod_set_demod_reg(dig_clk_cfg.d32, ADC_REG6); + demod_set_demod_reg(0x1000502, ADC_REG6); + /*demod_set_demod_reg(TXLX_ADC_REG3_VALUE, ADC_REG3);*/ + /* debug */ + PR_DBG("gxlx[adc][%x]%x\n", ADC_REG1, + demod_read_demod_reg(ADC_REG1)); + PR_DBG("[adc][%x]%x\n", ADC_REG2, + demod_read_demod_reg(ADC_REG2)); + PR_DBG("[adc][%x]%x\n", ADC_REG3, + demod_read_demod_reg(ADC_REG3)); + PR_DBG("[adc][%x]%x\n", ADC_REG4, + demod_read_demod_reg(ADC_REG4)); + PR_DBG("[adc][%x]%x\n", ADC_REG5, + demod_read_demod_reg(ADC_REG5)); + PR_DBG("[adc][%x]%x\n", ADC_REG6, + demod_read_demod_reg(ADC_REG6)); + PR_DBG("[adc][%x]%x\n", ADC_REG7, + demod_read_demod_reg(ADC_REG7)); + PR_DBG("[adc][%x]%x\n", ADC_REG8, + demod_read_demod_reg(ADC_REG8)); + PR_DBG("[adc][%x]%x\n", ADC_REG9, + demod_read_demod_reg(ADC_REG9)); + PR_DBG("[adc][%x]%x\n", ADC_REGB, + demod_read_demod_reg(ADC_REGB)); + PR_DBG("[adc][%x]%x\n", ADC_REGC, + demod_read_demod_reg(ADC_REGC)); + PR_DBG("[adc][%x]%x\n", ADC_REGD, + demod_read_demod_reg(ADC_REGD)); + PR_DBG("[adc][%x]%x\n", ADC_REGE, + demod_read_demod_reg(ADC_REGE)); + PR_DBG("[demod][%x]%x\n", GXLX_DEMOD_REG1, + demod_read_demod_reg(GXLX_DEMOD_REG1)); + PR_DBG("[demod][%x]%x\n", GXLX_DEMOD_REG2, + demod_read_demod_reg(GXLX_DEMOD_REG2)); + PR_DBG("[demod][%x]%x\n", GXLX_DEMOD_REG3, + demod_read_demod_reg(GXLX_DEMOD_REG3)); + } else { + demod_set_demod_reg(ADC_RESET_VALUE, ADC_REG3); /* adc reset */ + demod_set_demod_reg(adc_pll_cntl.d32, ADC_REG1); + demod_set_demod_reg(dig_clk_cfg.d32, ADC_REG6); + demod_set_demod_reg(ADC_REG3_VALUE, ADC_REG3); + /* debug */ + PR_DBG("[adc][%x]%x\n", ADC_REG1, + demod_read_demod_reg(ADC_REG1)); + PR_DBG("[adc][%x]%x\n", ADC_REG2, + demod_read_demod_reg(ADC_REG2)); + PR_DBG("[adc][%x]%x\n", ADC_REG3, + demod_read_demod_reg(ADC_REG3)); + PR_DBG("[adc][%x]%x\n", ADC_REG4, + demod_read_demod_reg(ADC_REG4)); + PR_DBG("[adc][%x]%x\n", ADC_REG6, + demod_read_demod_reg(ADC_REG6)); + PR_DBG("[demod][%x]%x\n", DEMOD_REG1, + demod_read_demod_reg(DEMOD_REG1)); + PR_DBG("[demod][%x]%x\n", DEMOD_REG2, + demod_read_demod_reg(DEMOD_REG2)); + PR_DBG("[demod][%x]%x\n", DEMOD_REG3, + demod_read_demod_reg(DEMOD_REG3)); + } +#endif + ddemod_pll.adcpllctl = adc_pll_cntl.d32; + ddemod_pll.demodctl = dig_clk_cfg.d32; + ddemod_pll.atsc = 0; + /*if ((dvb_mode == Gxtv_Atsc) && (is_meson_txlx_cpu()))*/ + if ((dvb_mode == Gxtv_Atsc) && !is_atsc_ver(IC_MD_NONE)) + ddemod_pll.atsc = 1; + + + /* debug only */ + /*printk("adcpllctl=0x%x\n",adc_pll_cntl.d32);*/ + + sts_pll = adc_set_pll_cntl(1, 0x0c, &ddemod_pll); + if (sts_pll < 0) { + /*set pll fail*/ + PR_ERR("%s:set pll fail! please check!\n", __func__); + } else { + dtvpll_init_flag(1); + } + + debug_adc_pll(); + +} + +void demod_set_adc_core_clk(int adc_clk, int sys_clk, int dvb_mode) +{ + adc_dpll_setup(25, adc_clk, sys_clk, dvb_mode); +} + +void demod_set_cbus_reg(unsigned int data, unsigned int addr) +{ + void __iomem *vaddr; + + PR_DBG("[cbus][write]%x\n", (IO_CBUS_PHY_BASE + (addr << 2))); + vaddr = ioremap((IO_CBUS_PHY_BASE + (addr << 2)), 0x4); + writel(data, vaddr); + iounmap(vaddr); +} + +unsigned int demod_read_cbus_reg(unsigned int addr) +{ +/* return __raw_readl(CBUS_REG_ADDR(addr)); */ + unsigned int tmp; + void __iomem *vaddr; + + vaddr = ioremap((IO_CBUS_PHY_BASE + (addr << 2)), 0x4); + tmp = readl(vaddr); + iounmap(vaddr); +/* tmp = aml_read_cbus(addr); */ + PR_DBG("[cbus][read]%x,data is %x\n", + (IO_CBUS_PHY_BASE + (addr << 2)), tmp); + return tmp; +} + +void demod_set_ao_reg(unsigned int data, unsigned int addr) +{ + writel(data, gbase_aobus() + addr); +} + +unsigned int demod_read_ao_reg(unsigned int addr) +{ + unsigned int tmp; + + tmp = readl(gbase_aobus() + addr); + + return tmp; +} + + +void demod_set_demod_reg(unsigned int data, unsigned int addr) +{ + void __iomem *vaddr; + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + vaddr = ioremap((addr), 0x4); + writel(data, vaddr); + iounmap(vaddr); + mutex_unlock(&mp); +} + +unsigned int demod_read_demod_reg(unsigned int addr) +{ + unsigned int tmp; + void __iomem *vaddr; + + mutex_lock(&mp); + vaddr = ioremap((addr), 0x4); + tmp = readl(vaddr); + iounmap(vaddr); + mutex_unlock(&mp); +/* printk("[demod][read]%x,data is %x\n",(addr),tmp); */ + return tmp; +} + +void power_sw_hiu_reg(int on) +{ + if (on == PWR_ON) { + dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, + (dd_tvafe_hiu_reg_read(HHI_DEMOD_MEM_PD_REG) & (~0x2fff))); + } else { + dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, + (dd_tvafe_hiu_reg_read(HHI_DEMOD_MEM_PD_REG) | 0x2fff)); + + } +} +void power_sw_reset_reg(int en) +{ + if (en) { + reset_reg_write(RESET_RESET0_LEVEL, + (reset_reg_read(RESET_RESET0_LEVEL) & (~(0x1 << 8)))); + } else { + reset_reg_write(RESET_RESET0_LEVEL, + (reset_reg_read(RESET_RESET0_LEVEL) | (0x1 << 8))); + + } +} +void demod_power_switch(int pwr_cntl) +{ + int reg_data; +#if 1 +/*if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) {*/ +if (is_ic_ver(IC_VER_TXLX) || is_ic_ver(IC_VER_TXHD)) { + + if (pwr_cntl == PWR_ON) { + PR_DBG("[PWR]: Power on demod_comp %x,%x\n", + AO_RTI_GEN_PWR_SLEEP0, AO_RTI_GEN_PWR_ISO0); + /* Powerup demod_comb */ + reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); + demod_set_ao_reg((reg_data & (~(0x1 << 10))), + AO_RTI_GEN_PWR_SLEEP0); + /* [10] power on */ + /*PR_DBG("[PWR]: Power on demod_comp %x,%x\n",*/ + /* TXLX_HHI_DEMOD_MEM_PD_REG, TXLX_RESET0_LEVEL);*/ + /* Power up memory */ + power_sw_hiu_reg(PWR_ON); + /* reset */ + power_sw_reset_reg(1); /*reset*/ + /* msleep(20);*/ + + /* remove isolation */ + demod_set_ao_reg( + (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) & + (~(0x3 << 14))), AO_RTI_GEN_PWR_ISO0); + /* pull up reset */ + power_sw_reset_reg(0); /*reset*/ +/* *P_RESET0_LEVEL |= (0x1<<8); */ + } else { + PR_DBG("[PWR]: Power off demod_comp\n"); + /* add isolation */ + + demod_set_ao_reg( + (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) | + (0x3 << 14)), AO_RTI_GEN_PWR_ISO0); + + /* power down memory */ + power_sw_hiu_reg(PWR_OFF); + /* power down demod_comb */ + reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); + demod_set_ao_reg((reg_data | (0x1 << 10)), + AO_RTI_GEN_PWR_SLEEP0); + /* [10] power on */ + } + /*} else if (is_meson_gxlx_cpu()) {*/ +} else if (is_ic_ver(IC_VER_GXLX)) { + + PR_DBG("[PWR]: GXLX not support power switch,power mem\n"); + + power_sw_hiu_reg(PWR_ON); +} else { + if (pwr_cntl == PWR_ON) { + PR_DBG("[PWR]: Power on demod_comp %x,%x\n", + AO_RTI_GEN_PWR_SLEEP0, AO_RTI_GEN_PWR_ISO0); + /* Powerup demod_comb */ + reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); + demod_set_ao_reg((reg_data & (~(0x1 << 10))), + AO_RTI_GEN_PWR_SLEEP0); + /* [10] power on */ + /*PR_DBG("[PWR]: Power on demod_comp %x,%x\n",*/ + /* HHI_DEMOD_MEM_PD_REG, RESET0_LEVEL);*/ + + /* Power up memory */ + power_sw_hiu_reg(PWR_ON); + /* reset */ + power_sw_reset_reg(1); /*reset*/ + /* msleep(20);*/ + /* remove isolation */ + demod_set_ao_reg( + (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) & + (~(0x3 << 14))), AO_RTI_GEN_PWR_ISO0); + /* pull up reset */ + power_sw_reset_reg(0); /*reset*/ +/* *P_RESET0_LEVEL |= (0x1<<8); */ + } else { + PR_DBG("[PWR]: Power off demod_comp\n"); + /* add isolation */ + + demod_set_ao_reg( + (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) | + (0x3 << 14)), AO_RTI_GEN_PWR_ISO0); + + /* power down memory */ + power_sw_hiu_reg(PWR_OFF); + /* power down demod_comb */ + reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); + demod_set_ao_reg((reg_data | (0x1 << 10)), + AO_RTI_GEN_PWR_SLEEP0); + /* [10] power on */ + } +} + +#endif +} +/* // 0 -DVBC J.83B, 1-DVBT, ISDBT, 2-ATSC,3-DTMB */ +void demod_set_mode_ts(unsigned char dvb_mode) +{ + union demod_cfg0 cfg0; + + cfg0.b.adc_format = 1; + cfg0.b.adc_regout = 1; + if (dvb_mode == Gxtv_Dtmb) { + cfg0.b.ts_sel = 1; + cfg0.b.mode = 1; + } else if (dvb_mode == Gxtv_Dvbt_Isdbt) { + cfg0.b.ts_sel = 1<<1; + cfg0.b.mode = 1<<1; + cfg0.b.adc_format = 0; + cfg0.b.adc_regout = 0; + } else if (dvb_mode == Gxtv_Atsc) { + cfg0.b.ts_sel = 1<<2; + cfg0.b.mode = 1<<2; + cfg0.b.adc_format = 0; + cfg0.b.adc_regout = 1; + cfg0.b.adc_regadj = 2; + } else if (dvb_mode == Gxtv_Dvbc) { + cfg0.b.ts_sel = 1<<3; + cfg0.b.mode = 1<<3; + cfg0.b.adc_format = 0; + cfg0.b.adc_regout = 0; + } + + demod_write_reg(DEMOD_REG1, cfg0.d32); + +} + +void clocks_set_sys_defaults(unsigned char dvb_mode) +{ + union demod_cfg2 cfg2; + int sts_pll; + + demod_power_switch(PWR_ON); + + tvafe_set_ddemod_default(); + demod_set_demod_default(); + + sts_pll = adc_set_pll_cntl(1, 0x04, NULL); + if (sts_pll < 0) { + /*set pll fail*/ + PR_ERR("%s:set pll default fail! please check!\n", __func__); + } + demod_set_mode_ts(dvb_mode); + cfg2.b.biasgen_en = 1; + cfg2.b.en_adc = 1; + + demod_write_reg(DEMOD_REG3, cfg2.d32); + PR_DBG("dvb_mode is %d\n", dvb_mode); + debug_check_reg_val(REG_M_DEMOD, DEMOD_REG1); + +} +#if 0 +void dtmb_write_reg(int reg_addr, int reg_data) +{ + if (!get_dtvpll_init_flag()) + return; + /* ary demod_set_demod_reg(reg_data, reg_addr); */ + demod_set_reg_rlt(reg_addr, reg_data); +/* apb_write_reg(reg_addr,reg_data); */ +} + +unsigned int dtmb_read_reg(unsigned int reg_addr) +{ + if (!get_dtvpll_init_flag()) + return 0; + /*ary return demod_read_demod_reg(reg_addr);*/ + return demod_read_reg_rlt(reg_addr); +} +#else +/* */ + +void dtmb_write_reg(int reg_addr, int reg_data) +{ + if (!get_dtvpll_init_flag()) + return; + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(reg_data, gbase_dtmb() + reg_addr); + + mutex_unlock(&mp); +/* apb_write_reg(reg_addr,reg_data); */ +} + +unsigned int dtmb_read_reg(unsigned int reg_addr) +{ + unsigned int tmp; + + if (!get_dtvpll_init_flag()) + return 0; + + mutex_lock(&mp); + tmp = readl(gbase_dtmb() + reg_addr); + mutex_unlock(&mp); + + return tmp; +} + +#endif +/* */ +void dvbt_write_reg(unsigned int addr, unsigned int data) +{ + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_dvbt() + addr); + + mutex_unlock(&mp); +} + +unsigned int dvbt_read_reg(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_dvbt() + addr); + + mutex_unlock(&mp); +/* printk("[demod][read]%x,data is %x\n",(addr),tmp); */ + return tmp; +} + +void atsc_write_reg(unsigned int reg_addr, unsigned int reg_data) +{ + unsigned int data; + + if (!get_dtvpll_init_flag()) + return; + + data = (reg_addr & 0xffff) << 8 | (reg_data & 0xff); + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + writel(data, gbase_atsc()); + mutex_unlock(&mp); +} + +unsigned int atsc_read_reg(unsigned int reg_addr) +{ + unsigned int tmp; + + if (!get_dtvpll_init_flag()) + return 0; + + mutex_lock(&mp); + + writel((reg_addr & 0xffff) << 8, gbase_atsc() + 4); + tmp = readl(gbase_atsc()); + + mutex_unlock(&mp); + + return tmp & 0xff; +} + +unsigned int atsc_read_iqr_reg(void) +{ + unsigned int tmp; + + if (!get_dtvpll_init_flag()) + return 0; + + mutex_lock(&mp); + + tmp = readl(gbase_atsc() + 8); + + mutex_unlock(&mp); + + PR_DBG("[atsc irq] is %x\n", tmp); + return tmp & 0xffffffff; +} + + + + +int demod_set_sys(struct aml_demod_sta *demod_sta, + struct aml_demod_sys *demod_sys) +{ +/* int adc_clk; */ +/* demod_sta->tmp=Adc_mode; */ + unsigned char dvb_mode; + int clk_adc, clk_dem; + /* int gpioDV_2;*/ + /*int gpiW_2;*/ + + dvb_mode = demod_sta->dvb_mode; + clk_adc = demod_sys->adc_clk; + clk_dem = demod_sys->demod_clk; + PR_DBG + ("demod_set_sys,clk_adc is %d,clk_demod is %d\n", + clk_adc, clk_dem); + mutex_init(&mp); + clocks_set_sys_defaults(dvb_mode); + #if 0 /*use dtvdemod_set_agc_pinmux*/ + /* open dtv adc pinmux */ + if (is_meson_txlx_cpu() || is_meson_gxlx_cpu()) { + PR_DBG("[R840][txlx_gxlx]set adc pinmux\n"); + } else if (is_meson_txhd_cpu()) { + gpioDV_2 = demod_read_demod_reg(0xff634400 + (0x27 << 2)); + PR_DBG("[txhd_R840]set adc pinmux,gpioDV_2 %x\n", gpioDV_2); + /* bit [11:8] */ + gpioDV_2 = gpioDV_2 & 0xfffff0ff; + gpioDV_2 = gpioDV_2 | (0x1 << 8); + + demod_set_demod_reg(gpioDV_2, 0xff634400 + (0x27 << 2)); + PR_DBG("[R840]set adc pinmux,gpioDV_2 %x\n", gpioDV_2); + } else if (is_meson_txl_cpu()) { + gpioDV_2 = demod_read_demod_reg(0xc8834400 + (0x2e << 2)); + PR_DBG("[R840]set adc pinmux,gpioDV_2 %x\n", gpioDV_2); + gpioDV_2 = gpioDV_2 | (0x1 << 22); + gpioDV_2 = gpioDV_2 & ~(0x3 << 19); + gpioDV_2 = gpioDV_2 & ~(0x1 << 23); + gpioDV_2 = gpioDV_2 & ~(0x1 << 31); + demod_set_demod_reg(gpioDV_2, 0xc8834400 + (0x2e << 2)); + PR_DBG("[R840]set adc pinmux,gpioDV_2 %x\n", gpioDV_2); + } else { + gpiW_2 = demod_read_demod_reg(0xc88344c4); + gpiW_2 = gpiW_2 | (0x1 << 25); + gpiW_2 = gpiW_2 & ~(0xd << 24); + demod_set_demod_reg(gpiW_2, 0xc88344c4); + PR_DBG("[R840]set adc pinmux,gpiW_2 %x\n", gpiW_2); + } + #endif + /* set adc clk */ + demod_set_adc_core_clk(clk_adc, clk_dem, dvb_mode); + /* init for dtmb */ + if (dvb_mode == Gxtv_Dtmb) { + #if 0 + if (is_meson_txhd_cpu()) { + /* demod_set_demod_reg(0x8, TXLX_DEMOD_REG4);*/ + demod_set_reg_rlt(TXLX_DEMOD_REG4, 0x8); + } else if (!is_meson_txlx_cpu()) { + /* open arbit */ + /* demod_set_demod_reg(0x8, DEMOD_REG4);*/ + demod_set_reg_rlt(GXBB_DEMOD_REG4, 0x8); + PR_DBG("[open arbit]dtmb\n"); + } + #else + demod_write_reg(DEMOD_REG4, 0x8); + PR_DBG("[open arbit]dtmb\n"); + #endif +/* } else if ((dvb_mode == Gxtv_Dvbt_Isdbt) && is_meson_txlx_cpu()) {*/ + } else if ((dvb_mode == Gxtv_Dvbt_Isdbt) && is_ic_ver(IC_VER_TXLX)) { + #if 0 + /* open arbit */ + /*demod_set_demod_reg(0x8, TXLX_DEMOD_REG4);*/ + demod_set_reg_rlt(TXLX_DEMOD_REG4, 0x8); + #else + demod_write_reg(DEMOD_REG4, 0x8); + #endif + PR_DBG("[open arbit]dvbt,txlx\n"); + } + demod_sta->adc_freq = clk_adc; + demod_sta->clk_freq = clk_dem; + return 0; +} + +void demod_set_reg(struct aml_demod_reg *demod_reg) +{ + if (fpga_version == 1) { +#if defined DEMOD_FPGA_VERSION + fpga_write_reg(demod_reg->mode, demod_reg->addr, + demod_reg->val); +#endif + } else { + switch (demod_reg->mode) { + case AMLOGIC_DVBC_J83B: + demod_reg->addr = (demod_reg->addr)>>2; + break; + case AMLOGIC_DVBT_ISDBT: + demod_reg->addr = demod_reg->addr * 4 + DVBT_BASE; + break; + case AMLOGIC_DTMB: + demod_reg->addr = gphybase_demod() + + DTMB_TOP_ADDR(demod_reg->addr); + break; + case AMLOGIC_ATSC: + /* demod_reg->addr=ATSC_BASE; */ + break; + case AMLOGIC_DEMOD_CFG: + + demod_reg->addr = demod_reg->addr * 4 + + gphybase_demod() + DEMOD_CFG_BASE; + break; + case AMLOGIC_DEMOD_BASE: + /* demod_reg->addr = demod_reg->addr + DEMOD_BASE;*/ + /*demod_reg->addr = demod_reg->addr + ddemod_reg_base;*/ + demod_reg->addr = demod_reg->addr + gphybase_demod(); + break; + case AMLOGIC_DEMOD_FPGA: + break; + case AMLOGIC_DEMOD_OTHERS: + demod_reg->addr = demod_reg->addr; + break; + case AMLOGIC_DEMOD_COLLECT_DATA: + break; + } + + if (demod_reg->mode == AMLOGIC_ATSC) + atsc_write_reg(demod_reg->addr, demod_reg->val); + else if (demod_reg->mode == AMLOGIC_DEMOD_OTHERS) + demod_set_cbus_reg(demod_reg->val, demod_reg->addr); + else if (demod_reg->mode == AMLOGIC_DVBC_J83B) + qam_write_reg(demod_reg->addr, demod_reg->val); + else if (demod_reg->mode == AMLOGIC_DEMOD_COLLECT_DATA) + apb_write_reg_collect(demod_reg->addr, demod_reg->val); + else + demod_set_demod_reg(demod_reg->val, demod_reg->addr); + + } +} + +void demod_get_reg(struct aml_demod_reg *demod_reg) +{ + if (fpga_version == 1) { + #if defined DEMOD_FPGA_VERSION + demod_reg->val = fpga_read_reg(demod_reg->mode, + demod_reg->addr); + #endif + } else { + if (demod_reg->mode == AMLOGIC_DVBC_J83B) + demod_reg->addr = (demod_reg->addr)>>2; + else if (demod_reg->mode == AMLOGIC_DTMB) + demod_reg->addr = gphybase_demod() + + DTMB_TOP_ADDR(demod_reg->addr); + else if (demod_reg->mode == AMLOGIC_DVBT_ISDBT) + demod_reg->addr = demod_reg->addr * 4 + DVBT_BASE; + else if (demod_reg->mode == AMLOGIC_ATSC) + ; + else if (demod_reg->mode == AMLOGIC_DEMOD_CFG) + + demod_reg->addr = demod_reg->addr * 4 + + gphybase_demod() + DEMOD_CFG_BASE; + else if (demod_reg->mode == AMLOGIC_DEMOD_BASE) + /* demod_reg->addr = demod_reg->addr + DEMOD_BASE;*/ + /* demod_reg->addr = demod_reg->addr + ddemod_reg_base;*/ + demod_reg->addr = demod_reg->addr + gphybase_demod(); + else if (demod_reg->mode == AMLOGIC_DEMOD_FPGA) + ; + else if (demod_reg->mode == AMLOGIC_DEMOD_OTHERS) + demod_reg->addr = demod_reg->addr; + else if (demod_reg->mode == AMLOGIC_DEMOD_COLLECT_DATA) + ; + + if (demod_reg->mode == AMLOGIC_ATSC) + demod_reg->val = atsc_read_reg(demod_reg->addr); + else if (demod_reg->mode == AMLOGIC_DVBC_J83B) + demod_reg->val = qam_read_reg(demod_reg->addr); + else if (demod_reg->mode == AMLOGIC_DEMOD_OTHERS) + demod_reg->val = demod_read_cbus_reg(demod_reg->addr); + else if (demod_reg->mode == AMLOGIC_DEMOD_COLLECT_DATA) + demod_reg->val = apb_read_reg_collect(demod_reg->addr); + else + demod_reg->val = demod_read_demod_reg(demod_reg->addr); + } +} + +void apb_write_reg_collect(unsigned int addr, unsigned int data) +{ + writel(data, ((void __iomem *)(phys_to_virt(addr)))); +/* *(volatile unsigned int*)addr = data; */ +} + +unsigned long apb_read_reg_collect(unsigned long addr) +{ + unsigned long tmp; + + tmp = readl((void __iomem *)(phys_to_virt(addr))); + + return tmp & 0xffffffff; +} + + + +void apb_write_reg(unsigned int addr, unsigned int data) +{ + demod_set_demod_reg(data, addr); +} + +unsigned long apb_read_reg_high(unsigned long addr) +{ + unsigned long tmp; + + tmp = 0; + return (tmp >> 32) & 0xffffffff; +} + +unsigned long apb_read_reg(unsigned long addr) +{ + return demod_read_demod_reg(addr); +} + + + + +int app_apb_read_reg(int addr) +{ + addr = DTMB_TOP_ADDR(addr); + return (int)demod_read_demod_reg(addr); +} + +int app_apb_write_reg(int addr, int data) +{ + addr = DTMB_TOP_ADDR(addr); + demod_set_demod_reg(data, addr); + return 0; +} + +void monitor_isdbt(void) +{ + int SNR; + int SNR_SP = 500; + int SNR_TPS = 0; + int SNR_CP = 0; + int timeStamp = 0; + int SFO_residual = 0; + int SFO_esti = 0; + int FCFO_esti = 0; + int FCFO_residual = 0; + int AGC_Gain = 0; + int RF_AGC = 0; + int Signal_power = 0; + int FECFlag = 0; + int EQ_seg_ratio = 0; + int tps_0 = 0; + int tps_1 = 0; + int tps_2 = 0; + + int time_stamp; + int SFO; + int FCFO; + int timing_adj; + int RS_CorrectNum; + + int cnt; + int tmpAGCGain; + + tmpAGCGain = 0; + cnt = 0; + +/* app_apb_write_reg(0x8, app_apb_read_reg(0x8) & ~(1 << 17));*/ +/* // TPS symbol index update : active high */ + time_stamp = app_apb_read_reg(0x07) & 0xffff; + SNR = app_apb_read_reg(0x0a); + FECFlag = (app_apb_read_reg(0x00) >> 11) & 0x3; + SFO = app_apb_read_reg(0x47) & 0xfff; + SFO_esti = app_apb_read_reg(0x60) & 0xfff; + FCFO_esti = (app_apb_read_reg(0x60) >> 11) & 0xfff; + FCFO = (app_apb_read_reg(0x26)) & 0xffffff; + RF_AGC = app_apb_read_reg(0x0c) & 0x1fff; + timing_adj = app_apb_read_reg(0x6f) & 0x1fff; + RS_CorrectNum = app_apb_read_reg(0xc1) & 0xfffff; + Signal_power = (app_apb_read_reg(0x1b)) & 0x1ff; + EQ_seg_ratio = app_apb_read_reg(0x6e) & 0x3ffff; + tps_0 = app_apb_read_reg(0x64); + tps_1 = app_apb_read_reg(0x65); + tps_2 = app_apb_read_reg(0x66) & 0xf; + + timeStamp = (time_stamp >> 8) * 68 + (time_stamp & 0x7f); + SFO_residual = (SFO > 0x7ff) ? (SFO - 0x1000) : SFO; + FCFO_residual = (FCFO > 0x7fffff) ? (FCFO - 0x1000000) : FCFO; + /* RF_AGC = (RF_AGC>0x3ff)? (RF_AGC - 0x800): RF_AGC; */ + FCFO_esti = (FCFO_esti > 0x7ff) ? (FCFO_esti - 0x1000) : FCFO_esti; + SNR_CP = (SNR) & 0x3ff; + SNR_TPS = (SNR >> 10) & 0x3ff; + SNR_SP = (SNR >> 20) & 0x3ff; + SNR_SP = (SNR_SP > 0x1ff) ? SNR_SP - 0x400 : SNR_SP; + SNR_TPS = (SNR_TPS > 0x1ff) ? SNR_TPS - 0x400 : SNR_TPS; + SNR_CP = (SNR_CP > 0x1ff) ? SNR_CP - 0x400 : SNR_CP; + AGC_Gain = tmpAGCGain >> 4; + tmpAGCGain = (AGC_Gain > 0x3ff) ? AGC_Gain - 0x800 : AGC_Gain; + timing_adj = (timing_adj > 0xfff) ? timing_adj - 0x2000 : timing_adj; + EQ_seg_ratio = + (EQ_seg_ratio > 0x1ffff) ? EQ_seg_ratio - 0x40000 : EQ_seg_ratio; + + PR_DBG + ("T %4x SP %3d TPS %3d CP %3d EQS %8x RSC %4d", + app_apb_read_reg(0xbf) + , SNR_SP, SNR_TPS, SNR_CP +/* ,EQ_seg_ratio */ + , app_apb_read_reg(0x62) + , RS_CorrectNum); + PR_DBG + ("SFO %4d FCFO %4d Vit %4x Timing %3d SigP %3x", + SFO_residual, FCFO_residual, RF_AGC, timing_adj, + Signal_power); + PR_DBG + ("FEC %x RSErr %8x ReSyn %x tps %03x%08x", + FECFlag, app_apb_read_reg(0x0b) + , (app_apb_read_reg(0xc0) >> 20) & 0xff, + app_apb_read_reg(0x05) & 0xfff, app_apb_read_reg(0x04) + ); + PR_DBG("\n"); +} + +/* new api */ +unsigned int demod_reg_get_abs_ddr(unsigned int reg_mode, unsigned int reg_add) +{ + unsigned int base_add = 0; + int ret = 0; + + switch (reg_mode) { + case REG_M_DEMOD: + /*base_add = ddemod_reg_base;*/ + base_add = gphybase_demodcfg(); + break; + case REG_M_HIU: + /*base_add = dd_hiu_reg_base;*/ + base_add = gphybase_hiu(); + break; +#if 0 + case REG_M_TVAFE: + base_add = dtvafe_reg_base; + break; +#endif + case REG_M_NONE: + default: + ret = -1; + break; + } + + if (ret < 0) + return 0xffffffff; + else + return base_add + reg_add; +} + + +/*dvbc_write_reg -> apb_write_reg in dvbc_func*/ +/*dvbc_read_reg -> apb_read_reg in dvbc_func*/ +#if 0 +void dvbc_write_reg(unsigned int addr, unsigned int data) +{ + demod_set_demod_reg(data, ddemod_reg_base + addr); +} +unsigned int dvbc_read_reg(unsigned int addr) +{ + return demod_read_demod_reg(ddemod_reg_base + addr); +} +#else +void dvbc_write_reg(unsigned int addr, unsigned int data) +{ + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_dvbc() + addr); + + mutex_unlock(&mp); +} +unsigned int dvbc_read_reg(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_dvbc() + addr); + + mutex_unlock(&mp); + + return tmp; +} + +#endif +void demod_write_reg(unsigned int addr, unsigned int data) +{ + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_demod() + addr); + + mutex_unlock(&mp); +} +unsigned int demod_read_reg(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_demod() + addr); + + mutex_unlock(&mp); + + return tmp; +} + +/*dvbc v3:*/ +void qam_write_reg(unsigned int reg_addr, unsigned int reg_data) +{ + if (!get_dtvpll_init_flag()) + return; + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(reg_data, gbase_dvbc() + (reg_addr << 2)); + + mutex_unlock(&mp); + +} + +unsigned int qam_read_reg(unsigned int reg_addr) +{ + + unsigned int tmp; + + if (!get_dtvpll_init_flag()) + return 0; + + + mutex_lock(&mp); + + tmp = readl(gbase_dvbc() + (reg_addr << 2)); + + mutex_unlock(&mp); + + return tmp; + +} +#if 0 +int dd_tvafe_hiu_reg_write(unsigned int reg, unsigned int val) +{ + demod_set_demod_reg(val, dd_hiu_reg_base + reg); + + return 0; +} +unsigned int dd_tvafe_hiu_reg_read(unsigned int addr) +{ + return demod_read_demod_reg(dd_hiu_reg_base + addr); +} +#else +int dd_tvafe_hiu_reg_write(unsigned int reg, unsigned int val) +{ + mutex_lock(&mp); + + writel(val, gbase_iohiu() + reg); + + mutex_unlock(&mp); + + return 0; +} +unsigned int dd_tvafe_hiu_reg_read(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_iohiu() + addr); + + mutex_unlock(&mp); + + return tmp; +} + +#endif +int reset_reg_write(unsigned int reg, unsigned int val) +{ + mutex_lock(&mp); + + writel(val, gbase_reset() + reg); + + mutex_unlock(&mp); + + return 0; +} +unsigned int reset_reg_read(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_reset() + addr); + + mutex_unlock(&mp); + + return tmp; +} + +#if 0 +int dd_tvafe_reg_write(unsigned int reg, unsigned int val) +{ + demod_set_demod_reg(val, dtvafe_reg_base + reg); + + return 0; +} +unsigned int dd_tvafe_reg_read(unsigned int addr) +{ + return demod_read_demod_reg(dtvafe_reg_base + addr); +} +#endif + +void demod_set_demod_default(void) +{ + #if 0 + if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) { + demod_set_reg_rlt(GXBB_DEMOD_REG1, DEMOD_REG1_VALUE); + demod_set_reg_rlt(GXBB_DEMOD_REG2, DEMOD_REG2_VALUE); + demod_set_reg_rlt(GXBB_DEMOD_REG3, DEMOD_REG3_VALUE); + + } else if (is_meson_txlx_cpu() || is_meson_gxlx_cpu() + || is_meson_txhd_cpu()) { + demod_set_reg_rlt(TXLX_DEMOD_REG1, DEMOD_REG1_VALUE); + demod_set_reg_rlt(TXLX_DEMOD_REG2, DEMOD_REG2_VALUE); + demod_set_reg_rlt(TXLX_DEMOD_REG3, DEMOD_REG3_VALUE); + + } + #else + demod_write_reg(DEMOD_REG1, DEMOD_REG1_VALUE); + demod_write_reg(DEMOD_REG2, DEMOD_REG2_VALUE); + demod_write_reg(DEMOD_REG3, DEMOD_REG3_VALUE); + + #endif + +} + + +void debug_check_reg_val(unsigned int reg_mode, unsigned int reg) +{ + unsigned int regAddr; + unsigned int val; +#if 0 + regAddr = demod_reg_get_abs_ddr(reg_mode, reg); + + if (regAddr == 0xffffffff) { + PR_DBG("[reg=%x][mode=%d] is onthing!\n", reg, reg_mode); + return; + } + val = demod_read_demod_reg(regAddr); +#endif + switch (reg_mode) { + case REG_M_DEMOD: + val = demod_read_reg(reg); + regAddr = gphybase_demodcfg() + reg; + PR_DBG("[demod][%x]%x\n", regAddr, val); + break; +#if 0 + case REG_M_TVAFE: + regAddr = demod_reg_get_abs_ddr(reg_mode, reg); + val = demod_read_demod_reg(regAddr); + PR_DBG("[tafe][%x]%x\n", regAddr, val); + break; +#endif + case REG_M_HIU: + val = dd_tvafe_hiu_reg_read(reg); + regAddr = gphybase_hiu() + reg; + PR_DBG("[adc][%x]%x\n", regAddr, val); + break; + default: + PR_DBG("[reg=%x][mode=%d] is onthing!\n", reg, reg_mode); + break; + } +} + +const unsigned int adc_check_tab_hiu[] = { + REG_M_HIU, D_HHI_ADC_PLL_CNTL, + REG_M_HIU, D_HHI_ADC_PLL_CNTL2, + REG_M_HIU, D_HHI_ADC_PLL_CNTL3, + REG_M_HIU, D_HHI_ADC_PLL_CNTL4, + REG_M_HIU, D_HHI_HDMI_CLK_CNTL, + REG_M_HIU, D_HHI_DEMOD_CLK_CNTL, + REG_M_HIU, D_HHI_DADC_CNTL, + REG_M_HIU, D_HHI_DADC_CNTL2, + REG_M_HIU, D_HHI_DADC_CNTL3, + REG_M_HIU, D_HHI_ADC_PLL_CNTL1, + REG_M_HIU, D_HHI_ADC_PLL_CNTL5, + REG_M_HIU, D_HHI_ADC_PLL_CNTL6, + REG_M_HIU, D_HHI_VDAC_CNTL0, + /* end */ + TABLE_FLG_END, TABLE_FLG_END, + +}; +const unsigned int adc_check_tab_gxtvbb[] = { + REG_M_HIU, D_HHI_ADC_PLL_CNTL, + REG_M_HIU, D_HHI_ADC_PLL_CNTL2, + REG_M_HIU, D_HHI_ADC_PLL_CNTL3, + REG_M_HIU, D_HHI_ADC_PLL_CNTL4, +/* REG_M_HIU, D_HHI_HDMI_CLK_CNTL, */ + + REG_M_DEMOD, DEMOD_REG1, + REG_M_DEMOD, DEMOD_REG2, + REG_M_DEMOD, DEMOD_REG3, + REG_M_DEMOD, DEMOD_REG4, + /* end */ + TABLE_FLG_END, TABLE_FLG_END, + +}; + +const unsigned int adc_check_tab_demod_txlx[] = { + REG_M_DEMOD, DEMOD_REG1, + REG_M_DEMOD, DEMOD_REG2, + REG_M_DEMOD, DEMOD_REG3, + REG_M_DEMOD, DEMOD_REG4, + /* end */ + TABLE_FLG_END, TABLE_FLG_END, +}; +const unsigned int adc_check_tab_demod_gxbb[] = { + REG_M_DEMOD, DEMOD_REG1, + REG_M_DEMOD, DEMOD_REG2, + REG_M_DEMOD, DEMOD_REG3, + REG_M_DEMOD, DEMOD_REG4, + /* end */ + TABLE_FLG_END, TABLE_FLG_END, +}; +void debug_check_reg_table(const unsigned int *pTab) +{ + + unsigned int cnt = 0; + unsigned int add; + unsigned int reg_mode; + + unsigned int pretect = 0; + + reg_mode = pTab[cnt++]; + add = pTab[cnt++]; + + while ((reg_mode != TABLE_FLG_END) && (pretect < 100)) { + debug_check_reg_val(reg_mode, add); + reg_mode = pTab[cnt++]; + add = pTab[cnt++]; + pretect++; + } + +} +void debug_adc_pll(void) +{ + if (is_ic_ver(IC_VER_TXL)) { + debug_check_reg_table(&adc_check_tab_hiu[0]); + debug_check_reg_table(&adc_check_tab_demod_gxbb[0]); + + } else if (is_ic_ver(IC_VER_TXLX) || is_ic_ver(IC_VER_GXLX) + || is_ic_ver(IC_VER_TXHD)) { + debug_check_reg_table(&adc_check_tab_hiu[0]); + debug_check_reg_table(&adc_check_tab_demod_txlx[0]); + + } else { + /* gxtvbb */ + debug_check_reg_table(&adc_check_tab_gxtvbb[0]); + } + +} + + diff --git a/drivers/amlogic/media/amldemod/dtmb_func.c b/drivers/amlogic/media/amldemod/dtmb_func.c new file mode 100644 index 0000000..efb0b7d --- /dev/null +++ b/drivers/amlogic/media/amldemod/dtmb_func.c @@ -0,0 +1,762 @@ +/* + * drivers/amlogic/media/amldemod/dtmb_func.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 "addr_dtmb_front_bit.h" +/*#include "reg_dtmb.h"*/ + +#include "demod_func.h" + +#if 0 +#ifdef pr_dbg +undef pr_dbg +#endif + +#define pr_dbg aml_dbgdtmb +#endif + +static int dtmb_spectrum = 2; +MODULE_PARM_DESC(demod_enable_performance, "\n\t\t demod_enable_performance information"); +static int demod_enable_performance = 1; +module_param(demod_enable_performance, int, 0644); + +MODULE_PARM_DESC(demod_sync_count, "\n\t\t timeout debug information"); +static int demod_sync_count = 60; +module_param(demod_sync_count, int, 0644); + +MODULE_PARM_DESC(demod_sync_delay_time, "\n\t\t timeout debug information"); +static int demod_sync_delay_time = 8; +module_param(demod_sync_delay_time, int, 0644); + + +MODULE_PARM_DESC(demod_timeout, "\n\t\t timeout debug information"); +static int demod_timeout = 120; +module_param(demod_timeout, int, 0644); + + +void dtmb_set_fe_config_modify(unsigned int modify) +{ + union DTMB_SYNC_FE_CONFIG_BITS fe_cofig; + + fe_cofig.d32 = dtmb_read_reg(DTMB_SYNC_FE_CONFIG); + fe_cofig.b.fe_modify = modify; + + dtmb_write_reg(DTMB_SYNC_FE_CONFIG, fe_cofig.d32); + PR_DTMB("set modiy=0x%x,0x%x\n", modify, fe_cofig.d32); +} +/* formula: fs(MHz) + * 2*7.56*2^23/fs/256 + * 24MHz: 0x50a3 + * 25MHz: 0x4d6a + */ +void dtmb_clk_set(unsigned int adc_clk) +{ + unsigned int fe_modify = 0x4d6a; + + if (adc_clk) + fe_modify = 3963617280 / (adc_clk << 3); + + dtmb_set_fe_config_modify(fe_modify); + +} +#if 0 +void dtmb_clk_set(unsigned int adc_clk) +{ + unsigned int fe_modify = 0x4d6a; + + switch (adc_clk) { + case Adc_Clk_24M: + fe_modify = 0x50a3; + break; + case Adc_Clk_25M: + fe_modify = 0x4d6a; + break; + default: + pr_error("error:%s:not support,adc_clk=%d\n", + __func__, adc_clk); + fe_modify = 0x4d6a; + break; + } + dtmb_set_fe_config_modify(fe_modify); +} +#endif + +void dtmb_all_reset(void) +{ + int temp_data = 0; + + if (is_ic_ver(IC_VER_TXL)) { + /*fix bug 139044: DTMB lost sync*/ + /*dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1f);*/ + dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x22); + /*modified bu xiaotong*/ + dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); + dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x1a027719); + dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x101a7); + /*21bit set ddr access urgent*/ + dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331a31); + /*detect 64qam 420 595 problems*/ + dtmb_write_reg(DTMB_FRONT_19_CONFIG, 0x300); + dtmb_write_reg(DTMB_FRONT_4d_CONFIG, 0x12ffbe0); + /*fix fsm b bug*/ + dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x5680000); + /*fix agc problem,skip warm_up status*/ + dtmb_write_reg(DTMB_FRONT_46_CONFIG, 0x1a000f0f); + dtmb_write_reg(DTMB_FRONT_ST_FREQ, 0xf2400000); + dtmb_clk_set(Adc_Clk_25M); + } else if (is_ic_ver(IC_VER_TXHD)) { + /* dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1f); */ + dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1e); + + /*demod can't sync when freq offset >1.5KHz for air signal*/ + dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x6aaaaa); + dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, 0x13196596); + + /*modified bu xiaotong*/ + dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); + dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x1a027719); + dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x101a7); + /*21bit set ddr access urgent*/ + dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331a31); + /*detect 64qam 420 595 problems*/ + dtmb_write_reg(DTMB_FRONT_19_CONFIG, 0x300); + dtmb_write_reg(DTMB_FRONT_4d_CONFIG, 0x12ffbe0); + /*fix fsm b bug*/ + dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x5680000); + /*fix agc problem,skip warm_up status*/ + dtmb_write_reg(DTMB_FRONT_46_CONFIG, 0x1a000f0f); + dtmb_write_reg(DTMB_FRONT_ST_FREQ, 0xf2400000); + dtmb_clk_set(Adc_Clk_24M); + } else { + dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x10127); + dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG6, 0x943228cc); + dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG7, 0xc09aa8cd); + dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, 0x0); + dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x9dc59); + /*0x2 is auto,0x406 is invert spectrum*/ + if (dtmb_spectrum == 0) + dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x406); + else if (dtmb_spectrum == 1) + dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x402); + else + dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x2); + + PR_DTMB("dtmb_spectrum is %d\n", dtmb_spectrum); + dtmb_write_reg(DTMB_TOP_CTRL_FEC, 0x41444400); + dtmb_write_reg(DTMB_TOP_CTRL_INTLV_TIME, 0x180300); + dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x662ca0); + dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x29); + dtmb_write_reg(DTMB_FRONT_DC_HOLD, 0xa1066); + /*cci para*/ + dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG3, 0x80201f6); + dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG2, 0x3f20080); + dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); + dtmb_write_reg(DTMB_TOP_CTRL_AGC, 0x3); + dtmb_write_reg(DTMB_TOP_CTRL_TS_SFO_CFO, 0x20403006); + dtmb_write_reg(DTMB_FRONT_AGC_CONFIG2, 0x7200a16); + dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x1e00000); + dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0x7fffff); + /*close ts3 timing loop*/ + dtmb_write_reg(DTMB_TOP_CTRL_DAGC_CCI, 0x305); + /*dektec card issue,close f case snr drop*/ + dtmb_write_reg(DTMB_CHE_MC_SC_TIMING_POWTHR, 0xc06100a); + if (demod_enable_performance) { + dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG1, 0x4040002); + temp_data = dtmb_read_reg(DTMB_CHE_FD_TD_COEFF); + temp_data = (temp_data & ~0x3fff)|(0x241f & 0x3fff); + temp_data = temp_data | (1<<21); + /*Set freeze_mode and reset coeff*/ + dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, temp_data); + temp_data = temp_data & ~(1<<21); + /*Set freeze_mode and reset coeff*/ + dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, temp_data); + } + } +} + +void dtmb_initial(struct aml_demod_sta *demod_sta) +{ +/* dtmb_write_reg(0x049, memstart); //only for init */ + dtmb_spectrum = 1; + dtmb_spectrum = demod_sta->spectrum; + dtmb_register_reset(); + dtmb_all_reset(); + +} + +int check_dtmb_fec_lock(void) +{ + int fec_lock, snr, status; + /*fec_lock = (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1;*/ + fec_lock = dtmb_reg_r_fec_lock(); + /*snr = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) & 0x3fff;*/ + snr = dtmb_reg_r_che_snr(); + if (fec_lock && (snr > 4)) + status = 1; + else + status = 0; + return status; +} + +int check_dtmb_mobile_det(void) +{ + int mobile_det = 0; + + mobile_det = (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff; + return mobile_det; + +} + + +int dtmb_information(void) +{ + int tps, snr, fec_lock, fec_bch_add, fec_ldpc_unc_acc, fec_ldpc_it_avg, + /*tmp,*/ che_snr; + + + unsigned int buf[3]; /**/ + + struct dvb_frontend *fe = aml_get_fe(); + + tps = dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT); + + che_snr = dtmb_reg_r_che_snr(); + snr = che_snr; + snr = convert_snr(snr); + /* if (che_snr >= 8192) */ + /* che_snr = che_snr - 16384;*/ + /* snr = che_snr / 32;*/ + /* snr = 10*log10(snr)-6; */ + /* fec_lock = (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1; */ + fec_lock = dtmb_reg_r_fec_lock(); + fec_bch_add = dtmb_reg_r_bch(); + fec_ldpc_unc_acc = dtmb_read_reg(DTMB_TOP_FEC_LDPC_UNC_ACC); + fec_ldpc_it_avg = dtmb_read_reg(DTMB_TOP_FEC_LDPC_IT_AVG); + PR_DTMB("[FSM] : %x %x %x %x\n", + dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0), + dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE1), + dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE2), + dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE3)); + /* PR_DTMB*/ + /* ("[AGC]: agc_power %d,agc_if_gain %d,agc_rf_gain %d,",*/ + /* (-(((dtmb_read_reg(DTMB_TOP_FRONT_AGC) >> 22) & 0x3ff) / 16)),*/ + /* ((dtmb_read_reg(DTMB_TOP_FRONT_AGC)) & 0x3ff),*/ + /* ((dtmb_read_reg(DTMB_TOP_FRONT_AGC) >> 11) & 0x7ff));*/ + + dtmb_read_agc(DTMB_D9_ALL, &buf[0]); + PR_DTMB + ("[AGC]: agc_power %d,agc_if_gain %d,agc_rf_gain %d,", + (-((buf[2]) / 16)), + buf[0], + buf[1]); + + PR_DTMB + ("dagc_power %3d,dagc_gain %3d mobi_det_power %d\n", + ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 0) & 0xff), + ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 8) & 0xfff), + (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff); + PR_DTMB + ("[TPS] SC or MC %2d,f_r %2d qam_nr %2d ", + (dtmb_read_reg(DTMB_TOP_CHE_OBS_STATE1) >> 1) & 0x1, + (tps >> 22) & 0x1, (tps >> 21) & 0x1); + PR_DTMB + ("intlv %2d,cr %2d constl %2d\n", + (tps >> 20) & 0x1, + (tps >> 18) & 0x3, (tps >> 16) & 0x3); + + PR_DTMB + ("[dtmb] snr is %d,fec_lock is %d,fec_bch_add is %d,", + snr, fec_lock, fec_bch_add); + PR_DTMB + ("fec_ldpc_unc_acc is %d ,fec_ldpc_it_avg is %d\n", + fec_ldpc_unc_acc, + fec_ldpc_it_avg / 256); + PR_DTMB + ("------------------------------------------------------------\n"); + + tuner_get_ch_power(fe); + + return 0; +} + +int dtmb_check_cci(void) +{ + int cci_det = 0; + + cci_det = + ((dtmb_read_reg(DTMB_TOP_SYNC_CCI_NF2_POSITION) >> 22) + & 0x3); + + if (cci_det > 0) { + PR_DTMB("find cci\n"); + dtmb_write_reg(DTMB_CHE_CCIDET_CONFIG, 0x20210290); + dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG3, 0x20081f6); + dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG2, 0x3f08020); + } + return cci_det; +} + +int dtmb_bch_check(void) +{ + int fec_bch_add, i; + char *info1 = "fec lock,but bch add ,need reset,wait not to reset"; + char *info2 = "fec lock,but bch add ,need reset,now is lock"; + + fec_bch_add = dtmb_reg_r_bch(); + + /*PR_DTMB("[debug]fec lock,fec_bch_add is %d\n", fec_bch_add);*/ + msleep(100); + if ((dtmb_reg_r_bch()-fec_bch_add) >= 50) { + PR_DTMB("%s\n", info1); + dtmb_reset(); + for (i = 0; i < 30; i++) { + msleep(100); + if (check_dtmb_fec_lock() == 1) { + PR_DTMB("%s\n", info2); + return 0; + } + } + } + return 0; +} + +int dtmb_constell_check(void) +{ + int constell; + + constell = dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT)>>16 & 0x3; + if (constell == 0)/*4qam*/ + dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x333221); + else if (constell == 1)/*16qam*/ + dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x332821); + else if (constell == 2)/*32qam*/ + dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331e21); + else if (constell == 3)/*64qam*/ + dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331a31); + + return 0; +} + + +int dtmb_check_fsm(void) +{ + int tmp, fsm_status, i, has_signal; + + tmp = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); + fsm_status = tmp&0xffffffff; + has_signal = 0; + PR_DTMB("fsm_status is %x\n", fsm_status); + for (i = 0 ; i < 8 ; i++) { + if (((fsm_status >> (i*4)) & 0xf) > 3) { + /*has signal*/ + /* PR_DTMB("has signal\n");*/ + has_signal = 1; + } + } + return has_signal; + +} + +int patch_ts3(int delay1_us, int delay2_us) +{ + if (((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) == 0x7)&1) { + dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x300f); + dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x310f); + msleep(delay1_us); + dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0xffdfff); + dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0xffffff); + dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3110); + dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3010); + dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3000); + return 1; + } else + return 0; +} + + +int read_cfo_all(void) +{ + int icfo_all, fcfo_all; + + icfo_all = dtmb_read_reg(DTMB_TOP_CTRL_ICFO_ALL) & 0xfffff; + fcfo_all = dtmb_read_reg(DTMB_TOP_CTRL_FCFO_ALL) & 0x3fff; + if (icfo_all > (1 << 19)) + icfo_all = icfo_all - (1 << 20); + if (fcfo_all > (1 << 13)) + fcfo_all = fcfo_all - (1 << 14); + + return (int)(icfo_all*4+fcfo_all); + +} + + +int dtmb_v3_soft_sync(int cfo_init) +{ + +/* int cfo_all;*/ +/* int cfo_setting;*/ + + if (cfo_init == 0) { + cfo_init = patch_ts3(11, 0); + #if 0 + if (cfo_init == 1) { + cfo_all = read_cfo_all(); + cfo_setting = dtmb_read_reg(DTMB_FRONT_DDC_BYPASS); + dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, + cfo_setting+cfo_all); + dtmb_write_reg(DTMB_TOP_CTRL_LOOP, 0x3); + dtmb_reset(); + } + #endif + } + return cfo_init; + +} + +int dtmb_check_status_gxtv(struct dvb_frontend *fe) +{ + int local_state; + int time_cnt;/* cci_det, src_config;*/ + int cfo_init, count; + + dtmb_information(); + time_cnt = 0; + local_state = 0; + cfo_init = 0; + if (check_dtmb_fec_lock() != 1) { + dtmb_register_reset(); + dtmb_all_reset(); + count = 15; + while ((count) && + ((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) < 0x6)) { + msleep(20); + count--; + } + + count = demod_sync_count; + while ((count) && (cfo_init == 0)) { + + cfo_init = dtmb_v3_soft_sync(cfo_init); + + msleep(demod_sync_delay_time); + count--; + } + if ((cfo_init == 0) && + ((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) <= 7)) { + PR_DTMB("over 400ms,status is %x, need reset\n", + (dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf)); + return 0; + } + while ((time_cnt < 10) && (check_dtmb_fec_lock() != 1)) { + msleep(demod_timeout); + time_cnt++; + local_state = AMLOGIC_DTMB_STEP3; + dtmb_information(); + dtmb_check_cci(); + if (time_cnt > 8) + PR_DTMB + ("* local_state = %d\n", local_state); + } + if (time_cnt >= 10 && (check_dtmb_fec_lock() != 1)) { + local_state = AMLOGIC_DTMB_STEP4; + time_cnt = 0; + PR_DTMB + ("*all reset,timeout is %d\n", demod_timeout); + } + } else { + dtmb_check_cci(); + dtmb_bch_check(); + #if 0 + cci_det = dtmb_check_cci(); + if ((check_dtmb_mobile_det() <= demod_mobile_power) + && (cci_det == 0)) { + /* open */ + src_config = (dtmb_read_reg(DTMB_FRONT_SRC_CONFIG1)); + dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, + src_config & (~(0x1 << 28))); + } else { + /* close */ + src_config = (dtmb_read_reg(DTMB_FRONT_SRC_CONFIG1)); + dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, + src_config | (0x1 << 28)); + } + #endif + } + if (check_dtmb_fec_lock() == 1) + dtmb_write_reg(DTMB_TOP_CTRL_LOOP, 0xf); + return 0; +} + + +int dtmb_check_status_txl(struct dvb_frontend *fe) +{ + int time_cnt; + + time_cnt = 0; + /*ary temp dtmb_information();*/ + if (check_dtmb_fec_lock() != 1) { + while ((time_cnt < 10) && (check_dtmb_fec_lock() != 1)) { + msleep(demod_timeout); + time_cnt++; + /*ary temp dtmb_information();*/ + if (((dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT) + >> 21) & 0x1) == 0x1) { + PR_DTMB("4qam-nr,need set spectrum\n"); + if (dtmb_spectrum == 1) { + dtmb_write_reg + (DTMB_TOP_CTRL_TPS, 0x1010406); + } else if (dtmb_spectrum == 0) { + dtmb_write_reg + (DTMB_TOP_CTRL_TPS, 0x1010402); + } else { + dtmb_write_reg + (DTMB_TOP_CTRL_TPS, 0x1010002); + } + } + if (time_cnt > 8) + PR_DTMB + ("* time_cnt = %d\n", time_cnt); + } + if (time_cnt >= 10 && (check_dtmb_fec_lock() != 1)) { + time_cnt = 0; + dtmb_register_reset(); + dtmb_all_reset(); + if (dtmb_spectrum == 0) + dtmb_spectrum = 1; + else + dtmb_spectrum = 0; + PR_DTMB + ("*all reset,timeout is %d\n", demod_timeout); + } + } else { + dtmb_bch_check(); + dtmb_constell_check(); + } + return 0; +} + +#ifdef DVB_CORE_ORI + + + +void dtmb_no_signal_check_v3(void) +{ + + if (((dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT) + >> 21) & 0x1) == 0x1) { + PR_DTMB("4qam-nr,need set spectrum\n"); + if (dtmb_spectrum == 1) { + dtmb_write_reg + (DTMB_TOP_CTRL_TPS, 0x1010406); + } else if (dtmb_spectrum == 0) { + dtmb_write_reg + (DTMB_TOP_CTRL_TPS, 0x1010402); + } else { + dtmb_write_reg + (DTMB_TOP_CTRL_TPS, 0x1010002); + } + } + +} +void dtmb_no_signal_check_finishi_v3(void) +{ + dtmb_register_reset(); + dtmb_all_reset(); + if (dtmb_spectrum == 0) + dtmb_spectrum = 1; + else + dtmb_spectrum = 0; + +} + + + +#endif +void dtmb_reset(void) +{ + union DTMB_TOP_CTRL_SW_RST_BITS sw_rst; + + sw_rst.b.ctrl_sw_rst = 1; + sw_rst.b.ctrl_sw_rst_noreg = 1; + dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); + sw_rst.b.ctrl_sw_rst = 0; + sw_rst.b.ctrl_sw_rst_noreg = 0; + dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); +} + +void dtmb_register_reset(void) +{ + union DTMB_TOP_CTRL_SW_RST_BITS sw_rst; + + sw_rst.b.ctrl_sw_rst = 1; + dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); + sw_rst.b.ctrl_sw_rst = 0; + dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); +} + +int dtmb_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_dtmb *demod_dtmb) +{ + int ret = 0; + u8 demod_mode; + u8 bw, sr, ifreq, agc_mode; + u32 ch_freq; + + bw = demod_dtmb->bw; + sr = demod_dtmb->sr; + ifreq = demod_dtmb->ifreq; + agc_mode = demod_dtmb->agc_mode; + ch_freq = demod_dtmb->ch_freq; + demod_mode = demod_dtmb->dat0; + demod_sta->ch_mode = demod_dtmb->mode; /* TODO */ + demod_sta->agc_mode = agc_mode; + demod_sta->ch_freq = ch_freq; + demod_sta->dvb_mode = demod_mode; + demod_sta->ch_bw = (8 - bw) * 1000; + dtmb_initial(demod_sta); + PR_DTMB("DTMB mode\n"); + return ret; +} + +void dtmb_set_mem_st(int mem_start) +{ + PR_DTMB("[im]memstart is %x\n", mem_start); + dtmb_write_reg(DTMB_FRONT_MEM_ADDR, mem_start); + PR_DTMB("[dtmb]mem_buf is 0x%x\n", dtmb_read_reg(DTMB_FRONT_MEM_ADDR)); +} + +int dtmb_read_agc(enum REG_DTMB_D9 type, unsigned int *buf) +{ + union DTMB_TOP_FRONT_AGC_BITS rval; + + rval.d32 = dtmb_read_reg(DTMB_TOP_FRONT_AGC); + + /*PR_DTMB("%s:type=%d,val=0x%x\n", __func__, type, rval.d32);*/ + /*PR_DTMB("if=0x%x,rf=0x%x,pw=0x%x", rval.b.front_agc_if_gain,*/ + /* rval.b.front_agc_rf_gain,*/ + /* rval.b.front_agc_power);*/ + switch (type) { + case DTMB_D9_IF_GAIN: + *buf = rval.b.front_agc_if_gain; + break; + case DTMB_D9_RF_GAIN: + *buf = rval.b.front_agc_rf_gain; + break; + case DTMB_D9_POWER: + *buf = rval.b.front_agc_power; + break; + case DTMB_D9_ALL: + buf[0] = rval.b.front_agc_if_gain; + buf[1] = rval.b.front_agc_rf_gain; + buf[2] = rval.b.front_agc_power; + break; + } + + return 0; + +} + +unsigned int dtmb_reg_r_fec_lock(void) +{ + + union DTMB_TOP_FEC_LOCK_SNR_BITS rval; + unsigned int fec_lock; + + rval.d32 = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR); + + if (is_dtmb_ver(IC_DTMB_V2)) + fec_lock = rval.b_v2.fec_lock; + else + fec_lock = rval.b.fec_lock; + + return fec_lock; +} +unsigned int dtmb_reg_r_che_snr(void) +{ + union DTMB_TOP_FEC_LOCK_SNR_BITS rval; + unsigned int che_snr; + + rval.d32 = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR); + + if (is_dtmb_ver(IC_DTMB_V2)) + che_snr = rval.b_v2.che_snr; + else + che_snr = rval.b.che_snr; + + return che_snr; + +} + +unsigned int dtmb_reg_r_bch(void) +{ + return dtmb_read_reg(DTMB_TOP_FEC_BCH_ACC); +} + +/*move from dvb-core dvb_frontend.c dvb_frontend_swzigzag*/ +/*1: timeout;2:have signal*/ +unsigned int dtmb_detect_first(void) +{ + int has_signal, i; + unsigned int dtmb_status; + + unsigned int timeout = 0; + + PR_DTMB("%s\n", __func__); + /*printk("k:%s\n",__func__);*/ + + has_signal = 0; + msleep(200); + + /*fsm status is 4,maybe analog signal*/ + dtmb_status = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); + + for (i = 0 ; i < 8 ; i++) { + if (((dtmb_status >> (i*4)) & 0xf) > 4) { + /*has signal*/ + /* dprintk("has signal\n");*/ + has_signal = 0x1; + } + } + if (has_signal == 0x1) { + /*fsm status is 6,digital signal*/ + /*fsm (1->4) 30ms,(4->5) 20ms,*/ + /*(5->6) 10ms,(6->7) 75ms,*/ + /*(7->8) 8ms,(8->9) 55ms, (9->a) 350ms*/ + msleep(500); + dtmb_status = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); + for (i = 0 ; i < 8 ; i++) { + if (((dtmb_status >> (i*4)) + & 0xf) > 6) { + /*has signal*/ + /* dprintk("has signal\n");*/ + has_signal = 0x3; + } + } + } + + PR_DTMB("[DTV]has_signal is %d\n", has_signal); + if ((has_signal == 0) || (has_signal == 0x1)) { + timeout = 1; /*FE_TIMEDOUT;*/ + PR_DTMB("\t timeout\n"); + + } else { + /*timeout = 2; *//*have signal*/ + PR_DTMB("\thave signal\n"); + } + + return timeout; +} diff --git a/drivers/amlogic/media/amldemod/dvbc_func.c b/drivers/amlogic/media/amldemod/dvbc_func.c new file mode 100644 index 0000000..95fbda6 --- /dev/null +++ b/drivers/amlogic/media/amldemod/dvbc_func.c @@ -0,0 +1,371 @@ +/* + * drivers/amlogic/media/amldemod/dvbc_func.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 +#include +#include +#include +#include "demod_func.h" +#include + +/*#include "dvbc_func.h"*/ + +MODULE_PARM_DESC(debug_amldvbc, "\n\t\t Enable frontend demod debug information"); +static int debug_amldvbc; +module_param(debug_amldvbc, int, 0644); + +/*#define dprintk(a ...) do { if (debug_amldvbc) printk(a); } while (0)*/ + +/*move to dvbc_old.c*/ +/* static struct task_struct *cci_task; */ +/*int cciflag = 0;*/ +struct timer_list mytimer; + + +static void dvbc_cci_timer(unsigned long data) +{ +#if 0 + int count; + int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1, + tmp, tmp2, reg_0xa8, reg_0xac; + int reg_0xa8_t, reg_0xac_t; + + count = 100; + if ((((dvbc_read_reg(QAM_BASE + 0x18)) & 0x1) == 1)) { + PR_DVBC("[cci]lock "); + if (cciflag == 0) { + dvbc_write_reg(QAM_BASE + 0xa8, 0); + + cciflag = 0; + } + PR_DVBC("\n"); + mdelay(500); + mod_timer(&mytimer, jiffies + 2 * HZ); + return; + } + if (cciflag == 1) { + PR_DVBC("[cci]cciflag is 1,wait 20\n"); + mdelay(20000); + } + times = 300; + tmp = 0x2be2be3; + /*0x2ae4772; IF = 6M, fs = 35M, dec2hex(round(8*IF/fs*2^25)) */ + tmp2 = 0x2000; + tmp1 = 8; + reg_0xa8 = 0xc0000000; /* bypass CCI */ + reg_0xac = 0xc0000000; /* bypass CCI */ + + maxCCI = 0; + maxCCI_p = 0; + for (i = 0; i < times; i++) { + /*reg_0xa8 = app_apb_read_reg(0xa8); */ + reg_0xa8_t = reg_0xa8 + tmp + i * tmp2; + dvbc_write_reg(QAM_BASE + 0xa8, reg_0xa8_t); + reg_0xac_t = reg_0xac + tmp - i * tmp2; + dvbc_write_reg(QAM_BASE + 0xac, reg_0xac_t); + sum = 0; + sum1 = 0; + for (j = 0; j < tmp1; j++) { + /* msleep(20); */ + /* mdelay(20); */ + reg_0xf0 = dvbc_read_reg(QAM_BASE + 0xf0); + re = (reg_0xf0 >> 24) & 0xff; + im = (reg_0xf0 >> 16) & 0xff; + if (re > 127) + /*re = re - 256; */ + re = 256 - re; + if (im > 127) + /*im = im - 256; */ + im = 256 - im; + + sum += re + im; + re = (reg_0xf0 >> 8) & 0xff; + im = (reg_0xf0 >> 0) & 0xff; + if (re > 127) + /*re = re - 256; */ + re = 256 - re; + if (im > 127) + /*im = im - 256; */ + im = 256 - im; + + sum1 += re + im; + } + sum = sum / tmp1; + sum1 = sum1 / tmp1; + if (sum1 > sum) { + sum = sum1; + reg_0xa8_t = reg_0xac_t; + } + if (sum > maxCCI) { + maxCCI = sum; + if (maxCCI > 24) + maxCCI_p = reg_0xa8_t & 0x7fffffff; + } + if ((sum < 24) && (maxCCI_p > 0)) + break; /* stop CCI detect. */ + } + + if (maxCCI_p > 0) { + dvbc_write_reg(QAM_BASE + 0xa8, maxCCI_p & 0x7fffffff); + /* enable CCI */ + dvbc_write_reg(QAM_BASE + 0xac, maxCCI_p & 0x7fffffff); + /* enable CCI */ + /* if(dvbc.mode == 4) // 256QAM */ + dvbc_write_reg(QAM_BASE + 0x54, 0xa25705fa); + /**/ cciflag = 1; + mdelay(1000); + } else { + PR_DVBC + ("[cci] ------------ find NO CCI -------------------\n"); + cciflag = 0; + } + + PR_DVBC("[cci][%s]--------------------------\n", __func__); + mod_timer(&mytimer, jiffies + 2 * HZ); + return; +/* }*/ +#endif +} + +int dvbc_timer_init(void) +{ + PR_DVBC("%s\n", __func__); + setup_timer(&mytimer, dvbc_cci_timer, (unsigned long)"Hello, world!"); + mytimer.expires = jiffies + 2 * HZ; + add_timer(&mytimer); + return 0; +} + +void dvbc_timer_exit(void) +{ + PR_DVBC("%s\n", __func__); + del_timer(&mytimer); +} +#if 0 /*ary*/ +int dvbc_cci_task(void *data) +{ + int count; + int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1, + tmp, tmp2, reg_0xa8, reg_0xac; + int reg_0xa8_t, reg_0xac_t; + + count = 100; + while (1) { + msleep(200); + if ((((dvbc_read_reg(QAM_BASE + 0x18)) & 0x1) == 1)) { + PR_DVBC("[cci]lock "); + if (cciflag == 0) { + dvbc_write_reg(QAM_BASE + 0xa8, 0); + dvbc_write_reg(QAM_BASE + 0xac, 0); + PR_DVBC("no cci "); + cciflag = 0; + } + PR_DVBC("\n"); + msleep(500); + continue; + } + + if (cciflag == 1) { + PR_DVBC("[cci]cciflag is 1,wait 20\n"); + msleep(20000); + } + times = 300; + tmp = 0x2be2be3; + /*0x2ae4772; IF = 6M,fs = 35M, dec2hex(round(8*IF/fs*2^25)) */ + tmp2 = 0x2000; + tmp1 = 8; + reg_0xa8 = 0xc0000000; /* bypass CCI */ + reg_0xac = 0xc0000000; /* bypass CCI */ + + maxCCI = 0; + maxCCI_p = 0; + for (i = 0; i < times; i++) { + /*reg_0xa8 = app_apb_read_reg(0xa8); */ + reg_0xa8_t = reg_0xa8 + tmp + i * tmp2; + dvbc_write_reg(QAM_BASE + 0xa8, reg_0xa8_t); + reg_0xac_t = reg_0xac + tmp - i * tmp2; + dvbc_write_reg(QAM_BASE + 0xac, reg_0xac_t); + sum = 0; + sum1 = 0; + for (j = 0; j < tmp1; j++) { + /* msleep(1); */ + reg_0xf0 = dvbc_read_reg(QAM_BASE + 0xf0); + re = (reg_0xf0 >> 24) & 0xff; + im = (reg_0xf0 >> 16) & 0xff; + if (re > 127) + /*re = re - 256; */ + re = 256 - re; + if (im > 127) + /*im = im - 256; */ + im = 256 - im; + + sum += re + im; + + re = (reg_0xf0 >> 8) & 0xff; + im = (reg_0xf0 >> 0) & 0xff; + if (re > 127) + /*re = re - 256; */ + re = 256 - re; + if (im > 127) + /*im = im - 256; */ + im = 256 - im; + + sum1 += re + im; + } + sum = sum / tmp1; + sum1 = sum1 / tmp1; + if (sum1 > sum) { + sum = sum1; + reg_0xa8_t = reg_0xac_t; + } + if (sum > maxCCI) { + maxCCI = sum; + if (maxCCI > 24) + maxCCI_p = reg_0xa8_t & 0x7fffffff; + } + + if ((sum < 24) && (maxCCI_p > 0)) + break; /* stop CCI detect. */ + } + + if (maxCCI_p > 0) { + dvbc_write_reg(QAM_BASE + 0xa8, maxCCI_p & 0x7fffffff); + /* enable CCI */ + dvbc_write_reg(QAM_BASE + 0xac, maxCCI_p & 0x7fffffff); + /* enable CCI */ + /* if(dvbc.mode == 4) // 256QAM */ + dvbc_write_reg(QAM_BASE + 0x54, 0xa25705fa); + /**/ cciflag = 1; + msleep(1000); + } else { + cciflag = 0; + } + + PR_DVBC("[cci][%s]--------------------------\n", __func__); + } + return 0; +} + +int dvbc_get_cci_task(void) +{ + if (cci_task) + return 0; + else + return 1; +} + +void dvbc_create_cci_task(void) +{ + int ret; + + /*dvbc_write_reg(QAM_BASE+0xa8, 0x42b2ebe3); // enable CCI */ + /* dvbc_write_reg(QAM_BASE+0xac, 0x42b2ebe3); // enable CCI */ +/* if(dvbc.mode == 4) // 256QAM*/ + /* dvbc_write_reg(QAM_BASE+0x54, 0xa25705fa); // */ + ret = 0; + cci_task = kthread_create(dvbc_cci_task, NULL, "cci_task"); + if (ret != 0) { + PR_DVBC("[%s]Create cci kthread error!\n", __func__); + cci_task = NULL; + return; + } + wake_up_process(cci_task); + PR_DVBC("[%s]Create cci kthread and wake up!\n", __func__); +} + +void dvbc_kill_cci_task(void) +{ + if (cci_task) { + kthread_stop(cci_task); + cci_task = NULL; + PR_DVBC("[%s]kill cci kthread !\n", __func__); + } +} +#endif + + +int dvbc_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_dvbc *demod_dvbc) +{ + int ret = 0; + u16 symb_rate; + u8 mode; + u32 ch_freq; + + PR_DVBC("f=%d, s=%d, q=%d\n", + demod_dvbc->ch_freq, demod_dvbc->symb_rate, demod_dvbc->mode); +/*ary no use demod_i2c->tuner = 7;*/ + mode = demod_dvbc->mode; + symb_rate = demod_dvbc->symb_rate; + ch_freq = demod_dvbc->ch_freq; + if (mode > 4) { + PR_DVBC("Error: Invalid QAM mode option %d\n", mode); + mode = 4; + ret = -1; + } + + if (symb_rate < 1000 || symb_rate > 7000) { + PR_DVBC("Error: Invalid Symbol Rate option %d\n", symb_rate); + symb_rate = 5361; + ret = -1; + } + + if (ch_freq < 1000 || ch_freq > 900000) { + PR_DVBC("Error: Invalid Channel Freq option %d\n", ch_freq); + ch_freq = 474000; + ret = -1; + } + /* if (ret != 0) return ret; */ + demod_sta->dvb_mode = 0; + demod_sta->ch_mode = mode; + /* 0:16, 1:32, 2:64, 3:128, 4:256 */ + demod_sta->agc_mode = 1; + /* 0:NULL, 1:IF, 2:RF, 3:both */ + demod_sta->ch_freq = ch_freq; + /*ary no use demod_sta->tuner = demod_i2c->tuner;*/ +#if 0 /*ary no use*/ + if (demod_i2c->tuner == 1) + demod_sta->ch_if = 36130; /* TODO DCT tuner */ + else if (demod_i2c->tuner == 2) + demod_sta->ch_if = 4570; /* TODO Maxlinear tuner */ + else if (demod_i2c->tuner == 7) + /* demod_sta->ch_if = 5000; // TODO Si2176 tuner */ +#endif + demod_sta->ch_bw = 8000; /* TODO */ + if (demod_sta->ch_if == 0) + demod_sta->ch_if = 5000; + demod_sta->symb_rate = symb_rate; + demod_sta->adc_freq = demod_dvbc->dat0; +#if 0 + if (is_meson_txlx_cpu() || is_meson_gxlx_cpu()) + dvbc_reg_initial(demod_sta); + else + dvbc_reg_initial_old(demod_sta); +#endif + if (is_dvbc_ver(IC_DVBC_V2)) + dvbc_reg_initial_old(demod_sta); + else if (is_dvbc_ver(IC_DVBC_V3)) + dvbc_reg_initial(demod_sta); + else + PR_ERR("%s:not support %d\n", __func__, get_dvbc_ver()); + + return ret; +} + + + diff --git a/drivers/amlogic/media/amldemod/dvbc_v2.c b/drivers/amlogic/media/amldemod/dvbc_v2.c new file mode 100644 index 0000000..fb5cd74 --- /dev/null +++ b/drivers/amlogic/media/amldemod/dvbc_v2.c @@ -0,0 +1,876 @@ +/* + * drivers/amlogic/media/amldemod/dvbc_v2.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 +#include +#include + +#include + +#include "demod_func.h" + +/*#define dprintk(a ...) aml_dbgdvbc_reg(a)*/ + +static struct task_struct *cci_task; +int cciflag; + + +void enable_qam_int(int idx) +{ + unsigned long mask; + + mask = dvbc_read_reg(0xd0); + mask |= (1 << idx); + dvbc_write_reg(0xd0, mask); +} + + +void disable_qam_int(int idx) +{ + unsigned long mask; + + mask = dvbc_read_reg(0xd0); + mask &= ~(1 << idx); + dvbc_write_reg(0xd0, mask); +} + + + + +int dvbc_cci_task(void *data) +{ + int count; + int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1, + tmp, tmp2, reg_0xa8, reg_0xac; + int reg_0xa8_t, reg_0xac_t; + + count = 100; + while (1) { + msleep(200); + if ((((dvbc_read_reg(0x18)) & 0x1) == 1)) { + PR_DVBC("[cci]lock "); + if (cciflag == 0) { + dvbc_write_reg(0xa8, 0); + dvbc_write_reg(0xac, 0); + PR_DVBC("no cci "); + cciflag = 0; + } + PR_DVBC("\n"); + msleep(500); + continue; + } + + if (cciflag == 1) { + PR_DVBC("[cci]cciflag is 1,wait 20\n"); + msleep(20000); + } + times = 300; + tmp = 0x2be2be3; + /*0x2ae4772; IF = 6M,fs = 35M, dec2hex(round(8*IF/fs*2^25)) */ + tmp2 = 0x2000; + tmp1 = 8; + reg_0xa8 = 0xc0000000; /* bypass CCI */ + reg_0xac = 0xc0000000; /* bypass CCI */ + + maxCCI = 0; + maxCCI_p = 0; + for (i = 0; i < times; i++) { + /*reg_0xa8 = app_apb_read_reg(0xa8); */ + reg_0xa8_t = reg_0xa8 + tmp + i * tmp2; + dvbc_write_reg(0xa8, reg_0xa8_t); + reg_0xac_t = reg_0xac + tmp - i * tmp2; + dvbc_write_reg(0xac, reg_0xac_t); + sum = 0; + sum1 = 0; + for (j = 0; j < tmp1; j++) { + /* msleep(1); */ + reg_0xf0 = dvbc_read_reg(0xf0); + re = (reg_0xf0 >> 24) & 0xff; + im = (reg_0xf0 >> 16) & 0xff; + if (re > 127) + /*re = re - 256; */ + re = 256 - re; + if (im > 127) + /*im = im - 256; */ + im = 256 - im; + + sum += re + im; + + re = (reg_0xf0 >> 8) & 0xff; + im = (reg_0xf0 >> 0) & 0xff; + if (re > 127) + /*re = re - 256; */ + re = 256 - re; + if (im > 127) + /*im = im - 256; */ + im = 256 - im; + + sum1 += re + im; + } + sum = sum / tmp1; + sum1 = sum1 / tmp1; + if (sum1 > sum) { + sum = sum1; + reg_0xa8_t = reg_0xac_t; + } + if (sum > maxCCI) { + maxCCI = sum; + if (maxCCI > 24) + maxCCI_p = reg_0xa8_t & 0x7fffffff; + } + + if ((sum < 24) && (maxCCI_p > 0)) + break; /* stop CCI detect. */ + } + + if (maxCCI_p > 0) { + dvbc_write_reg(0xa8, maxCCI_p & 0x7fffffff); + /* enable CCI */ + dvbc_write_reg(0xac, maxCCI_p & 0x7fffffff); + /* enable CCI */ + /* if(dvbc.mode == 4) // 256QAM */ + dvbc_write_reg(0x54, 0xa25705fa); + /**/ cciflag = 1; + msleep(1000); + } else { + cciflag = 0; + } + + PR_DVBC("[cci][%s]--------------------------\n", __func__); + } + return 0; +} + +int dvbc_get_cci_task(void) +{ + if (cci_task) + return 0; + else + return 1; +} + +void dvbc_create_cci_task(void) +{ + int ret; + + /*dvbc_write_reg(QAM_BASE+0xa8, 0x42b2ebe3); // enable CCI */ + /* dvbc_write_reg(QAM_BASE+0xac, 0x42b2ebe3); // enable CCI */ +/* if(dvbc.mode == 4) // 256QAM*/ + /* dvbc_write_reg(QAM_BASE+0x54, 0xa25705fa); // */ + ret = 0; + cci_task = kthread_create(dvbc_cci_task, NULL, "cci_task"); + if (ret != 0) { + PR_DVBC("[%s]Create cci kthread error!\n", __func__); + cci_task = NULL; + return; + } + wake_up_process(cci_task); + PR_DVBC("[%s]Create cci kthread and wake up!\n", __func__); +} + +void dvbc_kill_cci_task(void) +{ + if (cci_task) { + kthread_stop(cci_task); + cci_task = NULL; + PR_DVBC("[%s]kill cci kthread !\n", __func__); + } +} + + + + +u32 dvbc_set_qam_mode(unsigned char mode) +{ + PR_DVBC("auto change mode ,now mode is %d\n", mode); + dvbc_write_reg(0x008, (mode & 7)); + /* qam mode */ + switch (mode) { + case 0: /* 16 QAM */ + dvbc_write_reg(0x054, 0x23460224); + /* EQ_FIR_CTL, */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + dvbc_write_reg(0x074, 0x50001a0); + /* EQ_TH_LMS 40db 13db */ + dvbc_write_reg(0x07c, 0x003001e9); + /* EQ_NORM and EQ_TH_MMA */ + /*dvbc_write_reg(QAM_BASE+0x080, 0x000be1ff);*/ + /* // EQ_TH_SMMA0*/ + dvbc_write_reg(0x080, 0x000e01fe); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x00000000); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2b);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292b);*/ + /* // Pilips Tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292d);*/ + /* // Pilips Tuner*/ + dvbc_write_reg(0x094, 0x7f80092d); + /* Pilips Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f66); + /* by raymond 20121213 */ + break; + + case 1: /* 32 QAM */ + dvbc_write_reg(0x054, 0x24560506); + /* EQ_FIR_CTL, */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x5000260);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x50001f0); + /* EQ_TH_LMS 40db 17.5db */ + dvbc_write_reg(0x07c, 0x00500102); + /* EQ_TH_MMA 0x000001cc */ + dvbc_write_reg(0x080, 0x00077140); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x001fb000); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2b);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292b);*/ + /* // Pilips Tuner*/ + dvbc_write_reg(0x094, 0x7f80092b); + /* Pilips Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f66); + /* by raymond 20121213 */ + break; + + case 2: /* 64 QAM */ + /*dvbc_write_reg(QAM_BASE+0x054, 0x2256033a);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0x2336043a); + /* EQ_FIR_CTL, by raymond */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x5000260);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x5000230); + /* EQ_TH_LMS 40db 17.5db */ + dvbc_write_reg(0x07c, 0x007001bd); + /* EQ_TH_MMA */ + dvbc_write_reg(0x080, 0x000580ed); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x001771fb); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips & maxlinear Tuner*/ + dvbc_write_reg(0x094, 0x7f802b3d); + /* Pilips Tuner & maxlinear Tuner */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f802b3a);*/ + /* // Pilips Tuner & maxlinear Tuner*/ + dvbc_write_reg(0x0c0, 0x061f2f66); + /* by raymond 20121213 */ + break; + + case 3: /* 128 QAM */ + /*dvbc_write_reg(QAM_BASE+0x054, 0x2557046a);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0x2437067a); + /* EQ_FIR_CTL, by raymond 20121213 */ + dvbc_write_reg(0x068, 0x00c000d0); + /* EQ_CRTH_SNR */ + /* dvbc_write_reg(QAM_BASE+0x074, 0x02440240);*/ + /* // EQ_TH_LMS 18.5db 18db*/ + /* dvbc_write_reg(QAM_BASE+0x074, 0x04000400);*/ + /* // EQ_TH_LMS 22db 22.5db*/ + dvbc_write_reg(0x074, 0x5000260); + /* EQ_TH_LMS 40db 19db */ + /*dvbc_write_reg(QAM_BASE+0x07c, 0x00b000f2);*/ + /* // EQ_TH_MMA0x000000b2*/ + dvbc_write_reg(0x07c, 0x00b00132); + /* EQ_TH_MMA0x000000b2 by raymond 20121213 */ + dvbc_write_reg(0x080, 0x0003a09d); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x000f8150); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x001a51f8); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips Tuner*/ + dvbc_write_reg(0x094, 0x7f80092c); + /* Pilips Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f66); + /* by raymond 20121213 */ + break; + + case 4: /* 256 QAM */ + /*dvbc_write_reg(QAM_BASE+0x054, 0xa2580588);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0xa25905f9); + /* EQ_FIR_CTL, by raymond 20121213 */ + dvbc_write_reg(0x068, 0x01e00220); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x50002a0);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x5000270); + /* EQ_TH_LMS 40db 19db by raymond 201211213 */ + dvbc_write_reg(0x07c, 0x00f001a5); + /* EQ_TH_MMA */ + dvbc_write_reg(0x080, 0x0002c077); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x000bc0fe); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x0013f17e); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x01bc01f9); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips Tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292d);*/ + /* // Maxlinear Tuner*/ + dvbc_write_reg(0x094, 0x7f80092d); + /* Maxlinear Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213, when adc=35M,sys=70M,*/ + /* its better than 0x61f2f66*/ + break; + default: /*64qam */ + /*dvbc_write_reg(QAM_BASE+0x054, 0x2256033a);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0x2336043a); + /* EQ_FIR_CTL, by raymond */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x5000260);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x5000230); + /* EQ_TH_LMS 40db 17.5db */ + dvbc_write_reg(0x07c, 0x007001bd); + /* EQ_TH_MMA */ + dvbc_write_reg(0x080, 0x000580ed); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x001771fb); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips & maxlinear Tuner*/ + dvbc_write_reg(0x094, 0x7f802b3d); + /* Pilips Tuner & maxlinear Tuner */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f802b3a);*/ + /* // Pilips Tuner & maxlinear Tuner*/ + dvbc_write_reg(0x0c0, 0x061f2f66); + /* by raymond 20121213 */ + break; + } + return 0; +} + + + + +void dvbc_reg_initial_old(struct aml_demod_sta *demod_sta) +{ + u32 clk_freq; + u32 adc_freq; + /*ary no use u8 tuner;*/ + u8 ch_mode; + u8 agc_mode; + u32 ch_freq; + u16 ch_if; + u16 ch_bw; + u16 symb_rate; + u32 phs_cfg; + int afifo_ctr; + int max_frq_off, tmp; + + clk_freq = demod_sta->clk_freq; /* kHz */ + adc_freq = demod_sta->adc_freq; /* kHz */ +/* adc_freq = 25414;*/ + /*ary no use tuner = demod_sta->tuner;*/ + ch_mode = demod_sta->ch_mode; + agc_mode = demod_sta->agc_mode; + ch_freq = demod_sta->ch_freq; /* kHz */ + ch_if = demod_sta->ch_if; /* kHz */ + ch_bw = demod_sta->ch_bw; /* kHz */ + symb_rate = demod_sta->symb_rate; /* k/sec */ + PR_DVBC("ch_if is %d, %d, %d, %d, %d\n", + ch_if, ch_mode, ch_freq, ch_bw, symb_rate); +/* ch_mode=4;*/ +/* dvbc_write_reg(DEMOD_CFG_BASE,0x00000007);*/ + /* disable irq */ + dvbc_write_reg(0xd0, 0); + + /* reset */ + /*dvbc_reset(); */ + dvbc_write_reg(0x4, + dvbc_read_reg(0x4) & ~(1 << 4)); + /* disable fsm_en */ + dvbc_write_reg(0x4, + dvbc_read_reg(0x4) & ~(1 << 0)); + /* Sw disable demod */ + dvbc_write_reg(0x4, + dvbc_read_reg(0x4) | (1 << 0)); + /* Sw enable demod */ + + dvbc_write_reg(0x000, 0x00000000); + /* QAM_STATUS */ + dvbc_write_reg(0x004, 0x00000f00); + /* QAM_GCTL0 */ + dvbc_write_reg(0x008, (ch_mode & 7)); + /* qam mode */ + + switch (ch_mode) { + case 0:/* 16 QAM */ + dvbc_write_reg(0x054, 0x23460224); + /* EQ_FIR_CTL, */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + dvbc_write_reg(0x074, 0x50001a0); + /* EQ_TH_LMS 40db 13db */ + dvbc_write_reg(0x07c, 0x003001e9); + /* EQ_NORM and EQ_TH_MMA */ + /*dvbc_write_reg(QAM_BASE+0x080, 0x000be1ff);*/ + /* // EQ_TH_SMMA0*/ + dvbc_write_reg(0x080, 0x000e01fe); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x00000000); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2b);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292b);*/ + /* // Pilips Tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292d);*/ + /* // Pilips Tuner*/ + dvbc_write_reg(0x094, 0x7f80092d); + /* Pilips Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213 */ + break; + + case 1:/* 32 QAM */ + dvbc_write_reg(0x054, 0x24560506); + /* EQ_FIR_CTL, */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x5000260);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x50001f0); + /* EQ_TH_LMS 40db 17.5db */ + dvbc_write_reg(0x07c, 0x00500102); + /* EQ_TH_MMA 0x000001cc */ + dvbc_write_reg(0x080, 0x00077140); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x001fb000); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2b);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292b);*/ + /* // Pilips Tuner*/ + dvbc_write_reg(0x094, 0x7f80092b); + /* Pilips Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213 */ + break; + + case 2:/* 64 QAM */ + /*dvbc_write_reg(QAM_BASE+0x054, 0x2256033a);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0x2336043a); + /* EQ_FIR_CTL, by raymond */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x5000260);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x5000230); + /* EQ_TH_LMS 40db 17.5db */ + dvbc_write_reg(0x07c, 0x007001bd); + /* EQ_TH_MMA */ + dvbc_write_reg(0x080, 0x000580ed); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x001771fb); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips & maxlinear Tuner*/ + dvbc_write_reg(0x094, 0x7f802b3d); + /* Pilips Tuner & maxlinear Tuner */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f802b3a);*/ + /* // Pilips Tuner & maxlinear Tuner*/ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213 */ + break; + + case 3:/* 128 QAM */ + /*dvbc_write_reg(QAM_BASE+0x054, 0x2557046a);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0x2437067a); + /* EQ_FIR_CTL, by raymond 20121213 */ + dvbc_write_reg(0x068, 0x00c000d0); + /* EQ_CRTH_SNR */ + /* dvbc_write_reg(QAM_BASE+0x074, 0x02440240);*/ + /* // EQ_TH_LMS 18.5db 18db*/ + /* dvbc_write_reg(QAM_BASE+0x074, 0x04000400);*/ + /* // EQ_TH_LMS 22db 22.5db*/ + dvbc_write_reg(0x074, 0x5000260); + /* EQ_TH_LMS 40db 19db */ + /*dvbc_write_reg(QAM_BASE+0x07c, 0x00b000f2);*/ + /* // EQ_TH_MMA0x000000b2*/ + dvbc_write_reg(0x07c, 0x00b00132); + /* EQ_TH_MMA0x000000b2 by raymond 20121213 */ + dvbc_write_reg(0x080, 0x0003a09d); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x000f8150); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x001a51f8); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips Tuner*/ + dvbc_write_reg(0x094, 0x7f80092c); + /* Pilips Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213 */ + break; + + case 4:/* 256 QAM */ + /*dvbc_write_reg(QAM_BASE+0x054, 0xa2580588);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0xa25905f9); + /* EQ_FIR_CTL, by raymond 20121213 */ + dvbc_write_reg(0x068, 0x01e00220); + /* EQ_CRTH_SNR */ + /*dvbc_write_reg(QAM_BASE+0x074, 0x50002a0);*/ + /* // EQ_TH_LMS 40db 19db*/ + dvbc_write_reg(0x074, 0x5000270); + /* EQ_TH_LMS 40db 19db by raymond 201211213 */ + dvbc_write_reg(0x07c, 0x00f001a5); + /* EQ_TH_MMA */ + dvbc_write_reg(0x080, 0x0002c077); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x000bc0fe); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x0013f17e); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x01bc01f9); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips Tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292d);*/ + /* // Maxlinear Tuner*/ + dvbc_write_reg(0x094, 0x7f80092d); + /* Maxlinear Tuner */ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213, when adc=35M,sys=70M,*/ + /* its better than 0x61f2f66*/ + break; + default: /*64qam */ + /*dvbc_write_reg(QAM_BASE+0x054, 0x2256033a);*/ + /* // EQ_FIR_CTL,*/ + dvbc_write_reg(0x054, 0x2336043a); + /* EQ_FIR_CTL, by raymond */ + dvbc_write_reg(0x068, 0x00c000c0); + /* EQ_CRTH_SNR */ + /* EQ_TH_LMS 40db 19db */ + dvbc_write_reg(0x074, 0x5000230); + /* EQ_TH_LMS 40db 17.5db */ + dvbc_write_reg(0x07c, 0x007001bd); + /* EQ_TH_MMA */ + dvbc_write_reg(0x080, 0x000580ed); + /* EQ_TH_SMMA0 */ + dvbc_write_reg(0x084, 0x001771fb); + /* EQ_TH_SMMA1 */ + dvbc_write_reg(0x088, 0x00000000); + /* EQ_TH_SMMA2 */ + dvbc_write_reg(0x08c, 0x00000000); + /* EQ_TH_SMMA3 */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);*/ + /* // AGC_CTRL ALPS tuner*/ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c);*/ + /* // Pilips & maxlinear Tuner*/ + dvbc_write_reg(0x094, 0x7f802b3d); + /* Pilips Tuner & maxlinear Tuner */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f802b3a);*/ + /* // Pilips Tuner & maxlinear Tuner*/ + dvbc_write_reg(0x0c0, 0x061f2f67); + /* by raymond 20121213 */ + break; + } + + /*dvbc_write_reg(QAM_BASE+0x00c, 0xfffffffe);*/ + /* // adc_cnt, symb_cnt*/ + dvbc_write_reg(0x00c, 0xffff8ffe); + /* adc_cnt, symb_cnt by raymond 20121213 */ + if (clk_freq == 0) + afifo_ctr = 0; + else + afifo_ctr = (adc_freq * 256 / clk_freq) + 2; + if (afifo_ctr > 255) + afifo_ctr = 255; + dvbc_write_reg(0x010, (afifo_ctr << 16) | 8000); + /* afifo, rs_cnt_cfg */ + + /*dvbc_write_reg(QAM_BASE+0x020, 0x21353e54);*/ + /* // PHS_reset & TIM_CTRO_ACCURATE sw_tim_select=0*/ + /*dvbc_write_reg(QAM_BASE+0x020, 0x21b53e54);*/ + /* //modified by qiancheng*/ + dvbc_write_reg(0x020, 0x61b53e54); + /*modified by qiancheng by raymond 20121208 0x63b53e54 for cci */ + /* dvbc_write_reg(QAM_BASE+0x020, 0x6192bfe2);*/ + /* //modifed by ligg 20130613 auto symb_rate scan*/ + if (adc_freq == 0) + phs_cfg = 0; + else + phs_cfg = (1 << 31) / adc_freq * ch_if / (1 << 8); + /* 8*fo/fs*2^20 fo=36.125, fs = 28.57114, = 21d775 */ + /* PR_DVBC("phs_cfg = %x\n", phs_cfg); */ + dvbc_write_reg(0x024, 0x4c000000 | (phs_cfg & 0x7fffff)); + /* PHS_OFFSET, IF offset, */ + + if (adc_freq == 0) { + max_frq_off = 0; + } else { + max_frq_off = (1 << 29) / symb_rate; + /* max_frq_off = (400KHz * 2^29) / */ + /* (AD=28571 * symbol_rate=6875) */ + tmp = 40000000 / adc_freq; + max_frq_off = tmp * max_frq_off; + } + PR_DVBC("max_frq_off is %x,\n", max_frq_off); + dvbc_write_reg(0x02c, max_frq_off & 0x3fffffff); + /* max frequency offset, by raymond 20121208 */ + + /*dvbc_write_reg(QAM_BASE+0x030, 0x011bf400);*/ + /* // TIM_CTL0 start speed is 0, when know symbol rate*/ + dvbc_write_reg(0x030, 0x245cf451); + /*MODIFIED BY QIANCHENG */ +/* dvbc_write_reg(QAM_BASE+0x030, 0x245bf451);*/ +/* //modified by ligg 20130613 --auto symb_rate scan*/ + dvbc_write_reg(0x034, + ((adc_freq & 0xffff) << 16) | (symb_rate & 0xffff)); + + dvbc_write_reg(0x038, 0x00400000); + /* TIM_SWEEP_RANGE 16000 */ + +/************* hw state machine config **********/ + dvbc_write_reg(0x040, 0x003c); +/* configure symbol rate step step 0*/ + + /* modified 0x44 0x48 */ + dvbc_write_reg(0x044, (symb_rate & 0xffff) * 256); + /* blind search, configure max symbol_rate for 7218 fb=3.6M */ + /*dvbc_write_reg(QAM_BASE+0x048, 3600*256);*/ + /* // configure min symbol_rate fb = 6.95M*/ + dvbc_write_reg(0x048, 3400 * 256); + /* configure min symbol_rate fb = 6.95M */ + + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff6f); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xfffffd68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffff2f67);*/ + /* // threshold for skyworth*/ + /* dvbc_write_reg(QAM_BASE+0x0c0, 0x061f2f67); // by raymond 20121208 */ + /* dvbc_write_reg(QAM_BASE+0x0c0, 0x061f2f66);*/ + /* // by raymond 20121213, remove it to every constellation*/ +/************* hw state machine config **********/ + + dvbc_write_reg(0x04c, 0x00008800); /* reserved */ + + /*dvbc_write_reg(QAM_BASE+0x050, 0x00000002); // EQ_CTL0 */ + dvbc_write_reg(0x050, 0x01472002); + /* EQ_CTL0 by raymond 20121208 */ + + /*dvbc_write_reg(QAM_BASE+0x058, 0xff550e1e); // EQ_FIR_INITPOS */ + dvbc_write_reg(0x058, 0xff100e1e); + /* EQ_FIR_INITPOS for skyworth */ + + dvbc_write_reg(0x05c, 0x019a0000); /* EQ_FIR_INITVAL0 */ + dvbc_write_reg(0x060, 0x019a0000); /* EQ_FIR_INITVAL1 */ + + /*dvbc_write_reg(QAM_BASE+0x064, 0x01101128); // EQ_CRTH_TIMES */ + dvbc_write_reg(0x064, 0x010a1128); + /* EQ_CRTH_TIMES for skyworth */ + dvbc_write_reg(0x06c, 0x00041a05); /* EQ_CRTH_PPM */ + + dvbc_write_reg(0x070, 0xffb9aa01); /* EQ_CRLP */ + + /*dvbc_write_reg(QAM_BASE+0x090, 0x00020bd5); // agc control */ + dvbc_write_reg(0x090, 0x00000bd5); /* agc control */ + + /* agc control */ + /* dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);// AGC_CTRL ALPS tuner */ + /* dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c); // Pilips Tuner */ + if ((agc_mode & 1) == 0) + /* freeze if agc */ + dvbc_write_reg(0x094, + dvbc_read_reg(0x94) | (0x1 << 10)); + if ((agc_mode & 2) == 0) { + /* IF control */ + /*freeze rf agc */ + dvbc_write_reg(0x094, + dvbc_read_reg(0x94) | (0x1 << 13)); + } + /*Maxlinear Tuner */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292d); */ + dvbc_write_reg(0x098, 0x9fcc8190); + /* AGC_IFGAIN_CTRL */ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e028c00);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e03cc00);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e028700);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800 now*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e03cd00);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0603cd11);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800 by raymond,*/ + /* if Adjcent channel test, maybe it need change.20121208 ad invert*/ + dvbc_write_reg(0x0a0, 0x0603cd10); + /* AGC_RFGAIN_CTRL 0x0e020800 by raymond,*/ + /* if Adjcent channel test, maybe it need change.*/ + /* 20121208 ad invert,20130221, suit for two path channel.*/ + + dvbc_write_reg(0x004, + dvbc_read_reg(0x004) | 0x33); + /* IMQ, QAM Enable */ + + /* start hardware machine */ + /*dvbc_sw_reset(0x004, 4); */ + dvbc_write_reg(0x4, + dvbc_read_reg(0x4) | (1 << 4)); + dvbc_write_reg(0x0e8, + (dvbc_read_reg(0x0e8) | (1 << 2))); + + /* clear irq status */ + dvbc_read_reg(0xd4); + + /* enable irq */ + dvbc_write_reg(0xd0, 0x7fff << 3); + +/*auto track*/ + /* dvbc_set_auto_symtrack(); */ +} + + + + + + +void dvbc_disable_irq(int dvbc_irq) +{ + u32 mask; + + /* disable irq */ + mask = dvbc_read_reg(0xd0); + mask &= ~(1 << dvbc_irq); + dvbc_write_reg(0xd0, mask); + /* clear status */ + dvbc_read_reg(0xd4); +} + +char *dvbc_irq_name[] = { + " ADC", + " Symbol", + " RS", + " In_Sync0", + " In_Sync1", + " In_Sync2", + " In_Sync3", + " In_Sync4", + "Out_Sync0", + "Out_Sync1", + "Out_Sync2", + "Out_Sync3", + "Out_Sync4", + "In_SyncCo", + "OutSyncCo", + " In_Dagc", + " Out_Dagc", + " Eq_Mode", + "RS_Uncorr" +}; + +void dvbc_isr(struct aml_demod_sta *demod_sta) +{ + u32 stat, mask; + int dvbc_irq; + + stat = dvbc_read_reg(0xd4); + mask = dvbc_read_reg(0xd0); + stat &= mask; + + for (dvbc_irq = 0; dvbc_irq < 20; dvbc_irq++) { + if (stat >> dvbc_irq & 1) { + if (demod_sta->debug) + PR_DVBC("irq: dvbc %2d %s %8x\n", + dvbc_irq, dvbc_irq_name[dvbc_irq], + stat); + /* dvbc_disable_irq(dvbc_irq); */ + } + } +} + +int dvbc_isr_islock(void) +{ +#define IN_SYNC4_MASK (0x80) + + u32 stat, mask; + + stat = dvbc_read_reg(0xd4); + dvbc_write_reg(0xd4, 0); + mask = dvbc_read_reg(0xd0); + stat &= mask; + + return (stat & IN_SYNC4_MASK) == IN_SYNC4_MASK; +} diff --git a/drivers/amlogic/media/amldemod/dvbc_v3.c b/drivers/amlogic/media/amldemod/dvbc_v3.c new file mode 100644 index 0000000..74a8316 --- /dev/null +++ b/drivers/amlogic/media/amldemod/dvbc_v3.c @@ -0,0 +1,521 @@ +/* + * drivers/amlogic/media/amldemod/dvbc_v3.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 +#include +#include +#include "demod_func.h" + +/*#define dprintk(a ...) aml_dbgdvbc_reg(a)*/ + + +#if 0 +void qam_write_reg(int reg_addr, int reg_data) +{ + if (!get_dtvpll_init_flag()) + return; + + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + demod_set_demod_reg(reg_data, TXLX_QAM_BASE + (reg_addr << 2)); + else if (is_meson_gxlx_cpu()) + demod_set_demod_reg(reg_data, GXLX_QAM_BASE + (reg_addr << 2)); + else + demod_set_demod_reg(reg_data, ddemod_reg_base + QAM_BASE + + (reg_addr << 2)); +} + +unsigned long qam_read_reg(int reg_addr) +{ + if (!get_dtvpll_init_flag()) + return 0; + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + return demod_read_demod_reg(TXLX_QAM_BASE + (reg_addr << 2)); + else if (is_meson_gxlx_cpu()) + return demod_read_demod_reg(GXLX_QAM_BASE + (reg_addr << 2)); + else + return demod_read_demod_reg(ddemod_reg_base + QAM_BASE + + (reg_addr << 2)); +} + +#endif + + +u32 dvbc_get_status(void) +{ +/* PR_DVBC("c4 is %x\n",dvbc_read_reg(QAM_BASE+0xc4));*/ + return qam_read_reg(0x31) & 0xf; +} + +static u32 dvbc_get_ch_power(void) +{ + u32 tmp; + u32 ad_power; + u32 agc_gain; + u32 ch_power; + + tmp = qam_read_reg(0x27); + + ad_power = (tmp >> 22) & 0x1ff; + agc_gain = (tmp >> 0) & 0x7ff; + + ad_power = ad_power >> 4; + /* ch_power = lookuptable(agc_gain) + ad_power; TODO */ + ch_power = (ad_power & 0xffff) + ((agc_gain & 0xffff) << 16); + + return ch_power; +} + +static u32 dvbc_get_snr(void) +{ + u32 tmp, snr; + + tmp = qam_read_reg(0x5) & 0xfff; + snr = tmp * 100 / 32; /* * 1e2 */ + + return snr; +} + +static u32 dvbc_get_ber(void) +{ + u32 rs_ber; + u32 rs_packet_len; + + rs_packet_len = qam_read_reg(0x4) & 0xffff; + rs_ber = qam_read_reg(0x5) >> 12 & 0xfffff; + + /* rs_ber = rs_ber / 204.0 / 8.0 / rs_packet_len; */ + if (rs_packet_len == 0) + rs_ber = 1000000; + else + rs_ber = rs_ber * 613 / rs_packet_len; /* 1e-6 */ + + return rs_ber; +} + +static u32 dvbc_get_per(void) +{ + u32 rs_per; + u32 rs_packet_len; + u32 acc_rs_per_times; + + rs_packet_len = qam_read_reg(0x4) & 0xffff; + rs_per = qam_read_reg(0x6) >> 16 & 0xffff; + + acc_rs_per_times = qam_read_reg(0x33) & 0xffff; + /*rs_per = rs_per / rs_packet_len; */ + + if (rs_packet_len == 0) + rs_per = 10000; + else + rs_per = 10000 * rs_per / rs_packet_len; /* 1e-4 */ + + /*return rs_per; */ + return acc_rs_per_times; +} + +static u32 dvbc_get_symb_rate(void) +{ + u32 tmp; + u32 adc_freq; + u32 symb_rate; + + adc_freq = qam_read_reg(0xd) >> 16 & 0xffff; + tmp = qam_read_reg(0x2e); + + if ((tmp >> 15) == 0) + symb_rate = 0; + else + symb_rate = 10 * (adc_freq << 12) / (tmp >> 15); + /* 1e4 */ + + return symb_rate; +} + +static int dvbc_get_freq_off(void) +{ + int tmp; + int symb_rate; + int freq_off; + + symb_rate = dvbc_get_symb_rate(); + tmp = qam_read_reg(0x38) & 0x3fffffff; + if (tmp >> 29 & 1) + tmp -= (1 << 30); + + freq_off = ((tmp >> 16) * 25 * (symb_rate >> 10)) >> 3; + + return freq_off; +} + + + +void qam_auto_scan(int auto_qam_enable) +{ + if (auto_qam_enable) { + qam_write_reg(0xc, 0x235cf459); + /*qam_write_reg(0xe, 0x2d82d);*/ + qam_write_reg(0xe, 0x400);/*reduce range to 0.05m*/ + qam_write_reg(0x4e, 0x12010012); + } else + qam_write_reg(0x4e, 0x12000012); + +} + + +void dvbc_reg_initial(struct aml_demod_sta *demod_sta) +{ + u32 clk_freq; + u32 adc_freq; + /*ary no use u8 tuner;*/ + u8 ch_mode; + u8 agc_mode; + u32 ch_freq; + u16 ch_if; + u16 ch_bw; + u16 symb_rate; + u32 phs_cfg; + int afifo_ctr; + int max_frq_off, tmp, adc_format; + + clk_freq = demod_sta->clk_freq; /* kHz */ + adc_freq = demod_sta->adc_freq; /* kHz */ + adc_freq = 24000; + adc_format = 1; + /*ary no use tuner = demod_sta->tuner;*/ + ch_mode = demod_sta->ch_mode; + agc_mode = demod_sta->agc_mode; + ch_freq = demod_sta->ch_freq; /* kHz */ + ch_if = demod_sta->ch_if; /* kHz */ + ch_bw = demod_sta->ch_bw; /* kHz */ + symb_rate = demod_sta->symb_rate; /* k/sec */ + PR_DVBC("ch_if is %d, %d, %d, %d, %d %d\n", + ch_if, ch_mode, ch_freq, ch_bw, symb_rate, adc_freq); +/* ch_mode=4;*/ + /* disable irq */ + qam_write_reg(0x34, 0); + + /* reset */ + /*dvbc_reset(); */ + qam_write_reg(0x7, qam_read_reg(0x7) & ~(1 << 4)); + /* disable fsm_en */ + qam_write_reg(0x7, qam_read_reg(0x7) & ~(1 << 0)); + /* Sw disable demod */ + qam_write_reg(0x7, qam_read_reg(0x7) | (1 << 0)); + /* Sw enable demod */ + qam_write_reg(0x0, 0x0); + /* QAM_STATUS */ + qam_write_reg(0x7, 0x00000f00); + /* QAM_GCTL0 */ + qam_write_reg(0x2, (qam_read_reg(0x2) & ~7) | (ch_mode & 7)); + /* qam mode */ + + switch (ch_mode) { + case 0: /*16qam*/ + qam_write_reg(0x71, 0x000a2200); + qam_write_reg(0x72, 0x0c2b04a9); + qam_write_reg(0x73, 0x02020000); + qam_write_reg(0x75, 0x000e9178); + qam_write_reg(0x76, 0x0001c100); + qam_write_reg(0x7a, 0x002ab7ff); + qam_write_reg(0x93, 0x641a180c); + qam_write_reg(0x94, 0x0c141400); + break; + case 1:/*32qam*/ + qam_write_reg(0x71, 0x00061200); + qam_write_reg(0x72, 0x099301ae); + qam_write_reg(0x73, 0x08080000); + qam_write_reg(0x75, 0x000bf10c); + qam_write_reg(0x76, 0x0000a05c); + qam_write_reg(0x77, 0x001000d6); + qam_write_reg(0x7a, 0x0019a7ff); + qam_write_reg(0x7c, 0x00111222); + qam_write_reg(0x7d, 0x05050505); + qam_write_reg(0x7e, 0x03000d0d); + qam_write_reg(0x93, 0x641f1d0c); + qam_write_reg(0x94, 0x0c1a1a00); + break; + case 2:/*64qam*/ + break; + case 3:/*128qam*/ + qam_write_reg(0x71, 0x0002c200); + qam_write_reg(0x72, 0x0a6e0059); + qam_write_reg(0x73, 0x08080000); + qam_write_reg(0x75, 0x000a70e9); + qam_write_reg(0x76, 0x00002013); + qam_write_reg(0x77, 0x00035068); + qam_write_reg(0x78, 0x000ab100); + qam_write_reg(0x7a, 0x002ba7ff); + qam_write_reg(0x7c, 0x00111222); + qam_write_reg(0x7d, 0x05050505); + qam_write_reg(0x7e, 0x03000d0d); + qam_write_reg(0x93, 0x642a240c); + qam_write_reg(0x94, 0x0c262600); + break; + case 4: + break; + } + /*dvbc_write_reg(QAM_BASE+0x00c, 0xfffffffe);*/ + /* // adc_cnt, symb_cnt*/ + qam_write_reg(0x3, 0xffff8ffe); + /* adc_cnt, symb_cnt by raymond 20121213 */ + if (clk_freq == 0) + afifo_ctr = 0; + else + afifo_ctr = (adc_freq * 256 / clk_freq) + 2; + if (afifo_ctr > 255) + afifo_ctr = 255; + qam_write_reg(0x4, (afifo_ctr << 16) | 8000); + /* afifo, rs_cnt_cfg */ + + /*dvbc_write_reg(QAM_BASE+0x020, 0x21353e54);*/ + /* // PHS_reset & TIM_CTRO_ACCURATE sw_tim_select=0*/ + /*dvbc_write_reg(QAM_BASE+0x020, 0x21b53e54);*/ + /* //modified by qiancheng*/ + qam_write_reg(0x8, 0x61b53e54); + /*modified by qiancheng by raymond 20121208 0x63b53e54 for cci */ + /* dvbc_write_reg(QAM_BASE+0x020, 0x6192bfe2);*/ + /* //modifed by ligg 20130613 auto symb_rate scan*/ + if (adc_freq == 0) + phs_cfg = 0; + else + phs_cfg = (1 << 31) / adc_freq * ch_if / (1 << 8); + /* 8*fo/fs*2^20 fo=36.125, fs = 28.57114, = 21d775 */ + /* PR_DVBC("phs_cfg = %x\n", phs_cfg); */ + qam_write_reg(0x9, 0x4c000000 | (phs_cfg & 0x7fffff)); + /* PHS_OFFSET, IF offset, */ + + if (adc_freq == 0) { + max_frq_off = 0; + } else { + max_frq_off = (1 << 29) / symb_rate; + /* max_frq_off = (400KHz * 2^29) / */ + /* (AD=28571 * symbol_rate=6875) */ + tmp = 40000000 / adc_freq; + max_frq_off = tmp * max_frq_off; + } + PR_DVBC("max_frq_off is %x,\n", max_frq_off); + qam_write_reg(0xb, max_frq_off & 0x3fffffff); + /* max frequency offset, by raymond 20121208 */ + + /*dvbc_write_reg(QAM_BASE+0x030, 0x011bf400);*/ + /* // TIM_CTL0 start speed is 0, when know symbol rate*/ + /*rsj//qam_write_reg(0xc, 0x235cf451);*/ + /*MODIFIED BY QIANCHENG */ +/* dvbc_write_reg(QAM_BASE+0x030, 0x245bf451);*/ + /* //modified by ligg 20130613 --auto symb_rate scan*/ + qam_write_reg(0xd, + ((adc_freq & 0xffff) << 16) | (symb_rate & 0xffff)); + /*dvbc_write_reg(QAM_BASE + (0xE << 2), 0x00400000);*/ + /* TIM_SWEEP_RANGE 16000 */ + +/************* hw state machine config **********/ + /*dvbc_write_reg(QAM_BASE + (0x10 << 2), 0x003c);*/ +/* configure symbol rate step step 0*/ + + /* modified 0x44 0x48 */ + qam_write_reg(0x11, (symb_rate & 0xffff) * 256); + /* blind search, configure max symbol_rate for 7218 fb=3.6M */ + /*dvbc_write_reg(QAM_BASE+0x048, 3600*256);*/ + /* // configure min symbol_rate fb = 6.95M*/ + qam_write_reg(0x12, (qam_read_reg(0x12) & ~(0xff<<8)) | 3400 * 256); + /* configure min symbol_rate fb = 6.95M */ + + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff6f); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xfffffd68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ + /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffff2f67);*/ + /* // threshold for skyworth*/ + /* dvbc_write_reg(QAM_BASE+0x0c0, 0x061f2f67); // by raymond 20121208 */ + /* dvbc_write_reg(QAM_BASE+0x0c0, 0x061f2f66);*/ + /* // by raymond 20121213, remove it to every constellation*/ +/************* hw state machine config **********/ + /* agc control */ + /* dvbc_write_reg(QAM_BASE+0x094, 0x7f800d2c);// AGC_CTRL ALPS tuner */ + /* dvbc_write_reg(QAM_BASE+0x094, 0x7f80292c); // Pilips Tuner */ + if ((agc_mode & 1) == 0) + /* freeze if agc */ + qam_write_reg(0x25, + qam_read_reg(0x25) | (0x1 << 10)); + if ((agc_mode & 2) == 0) { + /* IF control */ + /*freeze rf agc */ + qam_write_reg(0x25, + qam_read_reg(0x25) | (0x1 << 13)); + } + /*Maxlinear Tuner */ + /*dvbc_write_reg(QAM_BASE+0x094, 0x7f80292d); */ + /*dvbc_write_reg(QAM_BASE + 0x098, 0x9fcc8190);*/ + /* AGC_IFGAIN_CTRL */ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e028c00);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e03cc00);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e028700);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800 now*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0e03cd00);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800*/ + /*dvbc_write_reg(QAM_BASE+0x0a0, 0x0603cd11);*/ + /* // AGC_RFGAIN_CTRL 0x0e020800 by raymond,*/ + /* if Adjcent channel test, maybe it need change.*/ + /*20121208 ad invert*/ + /*rsj//qam_write_reg(0x28, 0x0603cd10);*/ + qam_write_reg(0x28, + qam_read_reg(0x28) | (adc_format << 27)); + /* AGC_RFGAIN_CTRL 0x0e020800 by raymond,*/ + /* if Adjcent channel test, maybe it need change.*/ + /* 20121208 ad invert,20130221, suit for two path channel.*/ + + qam_write_reg(0x7, qam_read_reg(0x7) | 0x33); + /* IMQ, QAM Enable */ + + /* start hardware machine */ + /*dvbc_sw_reset(0x004, 4); */ + qam_write_reg(0x7, qam_read_reg(0x7) | (1 << 4)); + qam_write_reg(0x3a, qam_read_reg(0x3a) | (1 << 2)); + + /* clear irq status */ + qam_read_reg(0x35); + + /* enable irq */ + qam_write_reg(0x34, 0x7fff << 3); +#if 1 + /*if (is_meson_txlx_cpu()) {*/ + if (is_ic_ver(IC_VER_TXLX)) { + /*my_tool setting j83b mode*/ + qam_write_reg(0x7, 0x10f33); + /*j83b filter para*/ + qam_write_reg(0x40, 0x3f010201); + qam_write_reg(0x41, 0x0a003a3b); + qam_write_reg(0x42, 0xe1ee030e); + qam_write_reg(0x43, 0x002601f2); + qam_write_reg(0x44, 0x009b006b); + qam_write_reg(0x45, 0xb3a1905); + qam_write_reg(0x46, 0x1c396e07); + qam_write_reg(0x47, 0x3801cc08); + qam_write_reg(0x48, 0x10800a2); + qam_write_reg(0x12, 0x50e1000); + qam_write_reg(0x30, 0x41f2f69); + /*j83b_symbolrate(please see register doc)*/ + qam_write_reg(0x4d, 0x23d125f7); + /*for phase noise case 256qam*/ + qam_write_reg(0x9c, 0x2a232100); + qam_write_reg(0x57, 0x606040d); + /*for phase noise case 64qam*/ + qam_write_reg(0x54, 0x606050d); + qam_write_reg(0x52, 0x346dc); + qam_auto_scan(1); + } +#endif + qam_write_reg(0x7, 0x10f23); + qam_write_reg(0x3a, 0x0); + qam_write_reg(0x7, 0x10f33); + qam_write_reg(0x3a, 0x4); +/*auto track*/ + /* dvbc_set_auto_symtrack(); */ +} + +u32 dvbc_set_auto_symtrack(void) +{ + qam_write_reg(0xc, 0x245bf45c); /*open track */ + qam_write_reg(0x8, 0x61b2bf5c); + qam_write_reg(0x11, (7000 & 0xffff) * 256); + qam_write_reg(0xe, 0x00220000); + qam_write_reg(0x7, qam_read_reg(0x7) & ~(1 << 0)); + /* Sw disable demod */ + qam_write_reg(0x7, qam_read_reg(0x7) | (1 << 0)); + /* Sw enable demod */ + return 0; +} + + + +int dvbc_status(struct aml_demod_sta *demod_sta, + struct aml_demod_sts *demod_sts) +{ + int ftmp, tmp; + + struct dvb_frontend *fe = aml_get_fe(); + + demod_sts->ch_sts = qam_read_reg(0x6); + demod_sts->ch_pow = dvbc_get_ch_power(); + demod_sts->ch_snr = dvbc_get_snr(); + demod_sts->ch_ber = dvbc_get_ber(); + demod_sts->ch_per = dvbc_get_per(); + demod_sts->symb_rate = dvbc_get_symb_rate(); + demod_sts->freq_off = dvbc_get_freq_off(); + /*demod_sts->dat0 = dvbc_read_reg(QAM_BASE+0x28); */ +/* demod_sts->dat0 = tuner_get_ch_power(demod_i2c);*/ + demod_sts->dat1 = tuner_get_ch_power(fe); +#if 1 + + ftmp = demod_sts->ch_sts; + PR_DVBC("[dvbc debug] ch_sts is %x\n", ftmp); + ftmp = demod_sts->ch_snr; + ftmp /= 100; + PR_DVBC("snr %d dB ", ftmp); + ftmp = demod_sts->ch_ber; + PR_DVBC("ber %.d ", ftmp); + tmp = demod_sts->ch_per; + PR_DVBC("per %d ", tmp); + ftmp = demod_sts->symb_rate; + PR_DVBC("srate %.d ", ftmp); + ftmp = demod_sts->freq_off; + PR_DVBC("freqoff %.d kHz ", ftmp); + tmp = demod_sts->dat1; + /*change %lu to %u*/ + PR_DVBC("strength %ddb 0xe0 status is %u ,b4 status is %u", tmp, + (qam_read_reg(0x38) & 0xffff), + (qam_read_reg(0x2d) & 0xffff)); + /*change %lu to %u*/ + PR_DVBC("dagc_gain is %u ", qam_read_reg(0x29) & 0x7f); + tmp = demod_sts->ch_pow; + PR_DVBC("power is %ddb\n", (tmp & 0xffff)); + +#endif + + return 0; +} + +void dvbc_enable_irq(int dvbc_irq) +{ + u32 mask; + + /* clear status */ + qam_read_reg(0x35); + /* enable irq */ + mask = qam_read_reg(0x34); + mask |= (1 << dvbc_irq); + qam_write_reg(0x34, mask); +} + + +void dvbc_init_reg_ext(void) +{ + /*ary move from amlfrontend.c */ + qam_write_reg(0x7, 0xf33); +} + +u32 dvbc_get_ch_sts(void) +{ + return qam_read_reg(0x6); +} +u32 dvbc_get_qam_mode(void) +{ + return qam_read_reg(0x2) & 7; +} diff --git a/drivers/amlogic/media/amldemod/dvbt_v2.c b/drivers/amlogic/media/amldemod/dvbt_v2.c new file mode 100644 index 0000000..bfb1f30 --- /dev/null +++ b/drivers/amlogic/media/amldemod/dvbt_v2.c @@ -0,0 +1,783 @@ +/* + * drivers/amlogic/media/amldemod/dvbt_v2.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. + * + */ + + /* Enables DVBv3 compatibility bits at the headers */ +#define __DVB_CORE__ /*ary 2018-1-31*/ + +#include "demod_func.h" +#include +#include +#include +#include "acf_filter_coefficient.h" +#include + +#if 0 +#ifdef pr_dbg +undef pr_dbg +#endif + +#define pr_dbg aml_dbgdvbt + +#endif + +void apb_write_regb(unsigned long addr, int index, unsigned long data) +{ + /*to achieve write func*/ +} +void dvbt_write_regb(unsigned long addr, int index, unsigned long data) +{ + /*to achieve write func*/ +} + + + +int dvbt_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_dvbt *demod_dvbt) +{ + int ret = 0; + u8_t demod_mode = 1; + u8_t bw, sr, ifreq, agc_mode; + u32_t ch_freq; + + bw = demod_dvbt->bw; + sr = demod_dvbt->sr; + ifreq = demod_dvbt->ifreq; + agc_mode = demod_dvbt->agc_mode; + ch_freq = demod_dvbt->ch_freq; + demod_mode = demod_dvbt->dat0; + if (ch_freq < 1000 || ch_freq > 900000000) { + /* PR_DVBT("Error: Invalid Channel Freq option %d\n",*/ + /* ch_freq); */ + ch_freq = 474000; + ret = -1; + } + + if (demod_mode < 0 || demod_mode > 4) { + /* PR_DVBT("Error: Invalid demod mode option %d\n",*/ + /* demod_mode); */ + demod_mode = 1; + ret = -1; + } + + /* demod_sta->dvb_mode = 1; */ + demod_sta->ch_mode = 0; /* TODO */ + demod_sta->agc_mode = agc_mode; + demod_sta->ch_freq = ch_freq; + demod_sta->dvb_mode = demod_mode; + /* if (demod_i2c->tuner == 1) */ + /* demod_sta->ch_if = 36130;*/ + /* else if (demod_i2c->tuner == 2)*/ + /* demod_sta->ch_if = 4570;*/ + /* else if (demod_i2c->tuner == 3)*/ + /* demod_sta->ch_if = 4000;// It is nouse.(alan)*/ + /* else if (demod_i2c->tuner == 7)*/ + /* demod_sta->ch_if = 5000;//silab 5000kHz IF*/ + + demod_sta->ch_bw = (8 - bw) * 1000; + demod_sta->symb_rate = 0; /* TODO */ + +/* bw=0; */ + demod_mode = 1; + /* for si2176 IF:5M sr 28.57 */ + sr = 4; + ifreq = 4; + /*bw = convert_bandwidth(bw);*/ + PR_INFO("%s:1:bw=%d, demod_mode=%d\n", __func__, bw, demod_mode); + + /*bw = BANDWIDTH_AUTO;*/ + if (bw == BANDWIDTH_AUTO) + demod_mode = 2; +#if 0 + PR_INFO("%s:2:bw=%d, demod_mode=%d\n", __func__, bw, demod_mode); + bw = BANDWIDTH_8_MHZ; + demod_mode = 1; + + PR_INFO("%s:3:bw=%d, demod_mode=%d\n", __func__, bw, demod_mode); +#endif + ofdm_initial(bw, + /* 00:8M 01:7M 10:6M 11:5M */ + sr, + /* 00:45M 01:20.8333M 10:20.7M 11:28.57 100:24m */ + ifreq, + /* 000:36.13M 001:-5.5M 010:4.57M 011:4M 100:5M */ + demod_mode - 1, + /* 00:DVBT,01:ISDBT */ + 1 + /* 0: Unsigned, 1:TC */ + ); + PR_DVBT("DVBT/ISDBT mode\n"); + + return ret; +} + +void ini_icfo_pn_index(int mode) +{ /* 00:DVBT,01:ISDBT */ + if (mode == 0) { + dvbt_write_reg(0x3f8, 0x00000031); + dvbt_write_reg(0x3fc, 0x00030000); + dvbt_write_reg(0x3f8, 0x00000032); + dvbt_write_reg(0x3fc, 0x00057036); + dvbt_write_reg(0x3f8, 0x00000033); + dvbt_write_reg(0x3fc, 0x0009c08d); + dvbt_write_reg(0x3f8, 0x00000034); + dvbt_write_reg(0x3fc, 0x000c90c0); + dvbt_write_reg(0x3f8, 0x00000035); + dvbt_write_reg(0x3fc, 0x001170ff); + dvbt_write_reg(0x3f8, 0x00000036); + dvbt_write_reg(0x3fc, 0x0014d11a); + } else if (mode == 1) { + dvbt_write_reg(0x3f8, 0x00000031); + dvbt_write_reg(0x3fc, 0x00085046); + dvbt_write_reg(0x3f8, 0x00000032); + dvbt_write_reg(0x3fc, 0x0019a0e9); + dvbt_write_reg(0x3f8, 0x00000033); + dvbt_write_reg(0x3fc, 0x0024b1dc); + dvbt_write_reg(0x3f8, 0x00000034); + dvbt_write_reg(0x3fc, 0x003b3313); + dvbt_write_reg(0x3f8, 0x00000035); + dvbt_write_reg(0x3fc, 0x0048d409); + dvbt_write_reg(0x3f8, 0x00000036); + dvbt_write_reg(0x3fc, 0x00527509); + } +} + +static int coef[] = { + 0xf900, 0xfe00, 0x0000, 0x0000, 0x0100, 0x0100, 0x0000, 0x0000, + 0xfd00, 0xf700, 0x0000, 0x0000, 0x4c00, 0x0000, 0x0000, 0x0000, + 0x2200, 0x0c00, 0x0000, 0x0000, 0xf700, 0xf700, 0x0000, 0x0000, + 0x0300, 0x0900, 0x0000, 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, + 0xfc00, 0xf300, 0x0000, 0x0000, 0x2e00, 0x0000, 0x0000, 0x0000, + 0x3900, 0x1300, 0x0000, 0x0000, 0xfa00, 0xfa00, 0x0000, 0x0000, + 0x0100, 0x0200, 0x0000, 0x0000, 0xf600, 0x0000, 0x0000, 0x0000, + 0x0700, 0x0700, 0x0000, 0x0000, 0xfe00, 0xfb00, 0x0000, 0x0000, + 0x0900, 0x0000, 0x0000, 0x0000, 0x3200, 0x1100, 0x0000, 0x0000, + 0x0400, 0x0400, 0x0000, 0x0000, 0xfe00, 0xfb00, 0x0000, 0x0000, + 0x0e00, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfb00, 0x0000, 0x0000, + 0x0100, 0x0200, 0x0000, 0x0000, 0xf400, 0x0000, 0x0000, 0x0000, + 0x3900, 0x1300, 0x0000, 0x0000, 0x1700, 0x1700, 0x0000, 0x0000, + 0xfc00, 0xf300, 0x0000, 0x0000, 0x0c00, 0x0000, 0x0000, 0x0000, + 0x0300, 0x0900, 0x0000, 0x0000, 0xee00, 0x0000, 0x0000, 0x0000, + 0x2200, 0x0c00, 0x0000, 0x0000, 0x2600, 0x2600, 0x0000, 0x0000, + 0xfd00, 0xf700, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, + 0xf900, 0xfe00, 0x0000, 0x0000, 0x0400, 0x0b00, 0x0000, 0x0000, + 0xf900, 0x0000, 0x0000, 0x0000, 0x0700, 0x0200, 0x0000, 0x0000, + 0x2100, 0x2100, 0x0000, 0x0000, 0x0200, 0x0700, 0x0000, 0x0000, + 0xf900, 0x0000, 0x0000, 0x0000, 0x0b00, 0x0400, 0x0000, 0x0000, + 0xfe00, 0xf900, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, + 0xf700, 0xfd00, 0x0000, 0x0000, 0x2600, 0x2600, 0x0000, 0x0000, + 0x0c00, 0x2200, 0x0000, 0x0000, 0xee00, 0x0000, 0x0000, 0x0000, + 0x0900, 0x0300, 0x0000, 0x0000, 0x0c00, 0x0000, 0x0000, 0x0000, + 0xf300, 0xfc00, 0x0000, 0x0000, 0x1700, 0x1700, 0x0000, 0x0000, + 0x1300, 0x3900, 0x0000, 0x0000, 0xf400, 0x0000, 0x0000, 0x0000, + 0x0200, 0x0100, 0x0000, 0x0000, 0xfb00, 0xfb00, 0x0000, 0x0000, + 0x0e00, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfe00, 0x0000, 0x0000, + 0x0400, 0x0400, 0x0000, 0x0000, 0x1100, 0x3200, 0x0000, 0x0000, + 0x0900, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfe00, 0x0000, 0x0000, + 0x0700, 0x0700, 0x0000, 0x0000, 0xf600, 0x0000, 0x0000, 0x0000, + 0x0200, 0x0100, 0x0000, 0x0000, 0xfa00, 0xfa00, 0x0000, 0x0000, + 0x1300, 0x3900, 0x0000, 0x0000, 0x2e00, 0x0000, 0x0000, 0x0000, + 0xf300, 0xfc00, 0x0000, 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, + 0x0900, 0x0300, 0x0000, 0x0000, 0xf700, 0xf700, 0x0000, 0x0000, + 0x0c00, 0x2200, 0x0000, 0x0000, 0x4c00, 0x0000, 0x0000, 0x0000, + 0xf700, 0xfd00, 0x0000, 0x0000, 0x0100, 0x0100, 0x0000, 0x0000, + 0xfe00, 0xf900, 0x0000, 0x0000, 0x0b00, 0x0400, 0x0000, 0x0000, + 0xfc00, 0xfc00, 0x0000, 0x0000, 0x0200, 0x0700, 0x0000, 0x0000, + 0x4200, 0x0000, 0x0000, 0x0000, 0x0700, 0x0200, 0x0000, 0x0000, + 0xfc00, 0xfc00, 0x0000, 0x0000, 0x0400, 0x0b00, 0x0000, 0x0000 +}; + + +void tfd_filter_coff_ini(void) +{ + int i = 0; + + for (i = 0; i < 336; i++) { + dvbt_write_reg(0x99 * 4, (i << 16) | coef[i]); + dvbt_write_reg(0x03 * 4, (1 << 12)); + } +} + +void ofdm_initial(int bandwidth, + /* 00:8M 01:7M 10:6M 11:5M */ + int samplerate, + /* 00:45M 01:20.8333M 10:20.7M 11:28.57 100: 24.00 */ + int IF, + /* 000:36.13M 001:-5.5M 010:4.57M 011:4M 100:5M */ + int mode, + /* 00:DVBT,01:ISDBT */ + int tc_mode + /* 0: Unsigned, 1:TC */ + ) +{ +#if 1 + int tmp; + int ch_if; + int adc_freq; + /*int memstart;*/ + PR_DVBT + ("[ofdm_initial]bandwidth is %d,samplerate is %d", + bandwidth, samplerate); + PR_DVBT + ("IF is %d, mode is %d,tc_mode is %d\n", + IF, mode, tc_mode); + switch (IF) { + case 0: + ch_if = 36130; + break; + case 1: + ch_if = -5500; + break; + case 2: + ch_if = 4570; + break; + case 3: + ch_if = 4000; + break; + case 4: + ch_if = 5000; + break; + default: + ch_if = 4000; + break; + } + switch (samplerate) { + case 0: + adc_freq = 45000; + break; + case 1: + adc_freq = 20833; + break; + case 2: + adc_freq = 20700; + break; + case 3: + adc_freq = 28571; + break; + case 4: + adc_freq = 24000; + break; + case 5: + adc_freq = 25000; + break; + default: + adc_freq = 28571; + break; + } + + dvbt_write_reg((0x02 << 2), 0x00800000); + /* SW reset bit[23] ; write anything to zero */ + dvbt_write_reg((0x00 << 2), 0x00000000); + + dvbt_write_reg((0xe << 2), 0xffff); + /* enable interrupt */ + + if (mode == 0) { /* DVBT */ + switch (samplerate) { + case 0: + dvbt_write_reg((0x08 << 2), 0x00005a00); + break; /* 45MHz */ + case 1: + dvbt_write_reg((0x08 << 2), 0x000029aa); + break; /* 20.833 */ + case 2: + dvbt_write_reg((0x08 << 2), 0x00002966); + break; /* 20.7 SAMPLERATE*512 */ + case 3: + dvbt_write_reg((0x08 << 2), 0x00003924); + break; /* 28.571 */ + case 4: + dvbt_write_reg((0x08 << 2), 0x00003000); + break; /* 24 */ + case 5: + dvbt_write_reg((0x08 << 2), 0x00003200); + break; /* 25 */ + default: + dvbt_write_reg((0x08 << 2), 0x00003924); + break; /* 28.571 */ + } + } else { /* ISDBT */ + switch (samplerate) { + case 0: + dvbt_write_reg((0x08 << 2), 0x0000580d); + break; /* 45MHz */ + case 1: + dvbt_write_reg((0x08 << 2), 0x0000290d); + break; /* 20.833 = 56/7 * 20.8333 / (512/63)*512 */ + case 2: + dvbt_write_reg((0x08 << 2), 0x000028da); + break; /* 20.7 */ + case 3: + dvbt_write_reg((0x08 << 2), 0x0000383F); + break; /* 28.571 3863 */ + case 4: + dvbt_write_reg((0x08 << 2), 0x00002F40); + break; /* 24 */ + default: + dvbt_write_reg((0x08 << 2), 0x00003863); + break; /* 28.571 */ + } + } + /* memstart = 0x35400000;*/ + /* PR_DVBT("memstart is %x\n", memstart);*/ + /* dvbt_write_reg((0x10 << 2), memstart);*/ + /* 0x8f300000 */ + + dvbt_write_reg((0x14 << 2), 0xe81c4ff6); + /* AGC_TARGET 0xf0121385 */ + + switch (samplerate) { + case 0: + dvbt_write_reg((0x15 << 2), 0x018c2df2); + break; + case 1: + dvbt_write_reg((0x15 << 2), 0x0185bdf2); + break; + case 2: + dvbt_write_reg((0x15 << 2), 0x0185bdf2); + break; + case 3: + dvbt_write_reg((0x15 << 2), 0x0187bdf2); + break; + case 4: + dvbt_write_reg((0x15 << 2), 0x0187bdf2); + break; + default: + dvbt_write_reg((0x15 << 2), 0x0187bdf2); + break; + } + if (tc_mode == 1) + dvbt_write_regb((0x15 << 2), 11, 0); + /* For TC mode. Notice, For ADC input is Unsigned,*/ + /* For Capture Data, It is TC. */ + dvbt_write_regb((0x15 << 2), 26, 1); + /* [19:0] = [I , Q], I is high, Q is low. This bit is swap I/Q. */ + + dvbt_write_reg((0x16 << 2), 0x00047f80); + /* AGC_IFGAIN_CTRL */ + dvbt_write_reg((0x17 << 2), 0x00027f80); + /* AGC_RFGAIN_CTRL */ + dvbt_write_reg((0x18 << 2), 0x00000190); + /* AGC_IFGAIN_ACCUM */ + dvbt_write_reg((0x19 << 2), 0x00000190); + /* AGC_RFGAIN_ACCUM */ + if (ch_if < 0) + ch_if += adc_freq; + if (ch_if > adc_freq) + ch_if -= adc_freq; + + tmp = ch_if * (1 << 15) / adc_freq; + dvbt_write_reg((0x20 << 2), tmp); + + dvbt_write_reg((0x21 << 2), 0x001ff000); + /* DDC CS_FCFO_ADJ_CTRL */ + dvbt_write_reg((0x22 << 2), 0x00000000); + /* DDC ICFO_ADJ_CTRL */ + dvbt_write_reg((0x23 << 2), 0x00004000); + /* DDC TRACK_FCFO_ADJ_CTRL */ + + dvbt_write_reg((0x27 << 2), (1 << 23) + | (3 << 19) | (3 << 15) | (1000 << 4) | 9); + /* {8'd0,1'd1,4'd3,4'd3,11'd50,4'd9});//FSM_1 */ + dvbt_write_reg((0x28 << 2), (100 << 13) | 1000); + /* {8'd0,11'd40,13'd50});//FSM_2 */ + dvbt_write_reg((0x29 << 2), (31 << 20) | (1 << 16) | + (24 << 9) | (3 << 6) | 20); + /* {5'd0,7'd127,1'd0,3'd0,7'd24,3'd5,6'd20}); */ + /*8K cannot sync*/ + dvbt_write_reg((0x29 << 2), + dvbt_read_reg((0x29 << 2)) | + 0x7f << 9 | 0x7f << 20); + + if (mode == 0) { /* DVBT */ + if (bandwidth == 0) { /* 8M */ + switch (samplerate) { + case 0: + ini_acf_iireq_src_45m_8m(); + dvbt_write_reg((0x44 << 2), + 0x004ebf2e); + break; /* 45M */ + case 1: + ini_acf_iireq_src_207m_8m(); + dvbt_write_reg((0x44 << 2), + 0x00247551); + break; /* 20.833M */ + case 2: + ini_acf_iireq_src_207m_8m(); + dvbt_write_reg((0x44 << 2), + 0x00243999); + break; /* 20.7M */ + case 3: + ini_acf_iireq_src_2857m_8m(); + dvbt_write_reg((0x44 << 2), + 0x0031ffcd); + break; /* 28.57M */ + case 4: + ini_acf_iireq_src_24m_8m(); + dvbt_write_reg((0x44 << 2), + 0x002A0000); + break; /* 24M */ + default: + ini_acf_iireq_src_2857m_8m(); + dvbt_write_reg((0x44 << 2), + 0x0031ffcd); + break; /* 28.57M */ + } + } else if (bandwidth == 1) { /* 7M */ + switch (samplerate) { + case 0: + ini_acf_iireq_src_45m_7m(); + dvbt_write_reg((0x44 << 2), + 0x0059ff10); + break; /* 45M */ + case 1: + ini_acf_iireq_src_207m_7m(); + dvbt_write_reg((0x44 << 2), + 0x0029aaa6); + break; /* 20.833M */ + case 2: + ini_acf_iireq_src_207m_7m(); + dvbt_write_reg((0x44 << 2), + 0x00296665); + break; /* 20.7M */ + case 3: + ini_acf_iireq_src_2857m_7m(); + dvbt_write_reg((0x44 << 2), + 0x00392491); + break; /* 28.57M */ + case 4: + ini_acf_iireq_src_24m_7m(); + dvbt_write_reg((0x44 << 2), + 0x00300000); + break; /* 24M */ + default: + ini_acf_iireq_src_2857m_7m(); + dvbt_write_reg((0x44 << 2), + 0x00392491); + break; /* 28.57M */ + } + } else if (bandwidth == 2) { /* 6M */ + switch (samplerate) { + case 0: + ini_acf_iireq_src_45m_6m(); + dvbt_write_reg((0x44 << 2), + 0x00690000); + break; /* 45M */ + case 1: + ini_acf_iireq_src_207m_6m(); + dvbt_write_reg((0x44 << 2), + 0x00309c3e); + break; /* 20.833M */ + case 2: + ini_acf_iireq_src_207m_6m(); + dvbt_write_reg((0x44 << 2), + 0x002eaaaa); + break; /* 20.7M */ + case 3: + ini_acf_iireq_src_2857m_6m(); + dvbt_write_reg((0x44 << 2), + 0x0042AA69); + break; /* 28.57M */ + case 4: + ini_acf_iireq_src_24m_6m(); + dvbt_write_reg((0x44 << 2), + 0x00380000); + break; /* 24M */ + default: + ini_acf_iireq_src_2857m_6m(); + dvbt_write_reg((0x44 << 2), + 0x0042AA69); + break; /* 28.57M */ + } + } else { /* 5M */ + switch (samplerate) { + case 0: + ini_acf_iireq_src_45m_5m(); + dvbt_write_reg((0x44 << 2), + 0x007dfbe0); + break; /* 45M */ + case 1: + ini_acf_iireq_src_207m_5m(); + dvbt_write_reg((0x44 << 2), + 0x003a554f); + break; /* 20.833M */ + case 2: + ini_acf_iireq_src_207m_5m(); + dvbt_write_reg((0x44 << 2), + 0x0039f5c0); + break; /* 20.7M */ + case 3: + ini_acf_iireq_src_2857m_5m(); + dvbt_write_reg((0x44 << 2), + 0x004FFFFE); + break; /* 28.57M */ + case 4: + ini_acf_iireq_src_24m_5m(); + dvbt_write_reg((0x44 << 2), + 0x00433333); + break; /* 24M */ + default: + ini_acf_iireq_src_2857m_5m(); + dvbt_write_reg((0x44 << 2), + 0x004FFFFE); + break; /* 28.57M */ + } + } + } else { /* ISDBT */ + switch (samplerate) { + case 0: + ini_acf_iireq_src_45m_6m(); + dvbt_write_reg((0x44 << 2), 0x00589800); + break; + /* 45M */ + /*SampleRate/(symbolRate)*2^20, */ + /*symbolRate = 512/63 for isdbt */ + case 1: + ini_acf_iireq_src_207m_6m(); + dvbt_write_reg((0x44 << 2), 0x002903d4); + break; /* 20.833M */ + case 2: + ini_acf_iireq_src_207m_6m(); + dvbt_write_reg((0x44 << 2), 0x00280ccc); + break; /* 20.7M */ + case 3: + ini_acf_iireq_src_2857m_6m(); + dvbt_write_reg((0x44 << 2), 0x00383fc8); + break; /* 28.57M */ + case 4: + ini_acf_iireq_src_24m_6m(); + dvbt_write_reg((0x44 << 2), 0x002F4000); + break; /* 24M */ + default: + ini_acf_iireq_src_2857m_6m(); + dvbt_write_reg((0x44 << 2), 0x00383fc8); + break; /* 28.57M */ + } + } + + if (mode == 0) /* DVBT */ + dvbt_write_reg((0x02 << 2), + (bandwidth << 20) | 0x10002); + else /* ISDBT */ + dvbt_write_reg((0x02 << 2), (1 << 20) | 0x1001a); + /* {0x000,2'h1,20'h1_001a}); //For ISDBT , bandwidth should be 1,*/ + + dvbt_write_reg((0x45 << 2), 0x00000000); + /* SRC SFO_ADJ_CTRL */ + dvbt_write_reg((0x46 << 2), 0x02004000); + /* SRC SFO_ADJ_CTRL */ + dvbt_write_reg((0x48 << 2), 0x000c0287); + /* DAGC_CTRL1 */ + dvbt_write_reg((0x49 << 2), 0x00000005); + /* DAGC_CTRL2 */ + dvbt_write_reg((0x4c << 2), 0x00000bbf); + /* CCI_RP */ + dvbt_write_reg((0x4d << 2), 0x00000376); + /* CCI_RPSQ */ + dvbt_write_reg((0x4e << 2), 0x0f0f1d09); + /* CCI_CTRL */ + dvbt_write_reg((0x4f << 2), 0x00000000); + /* CCI DET_INDX1 */ + dvbt_write_reg((0x50 << 2), 0x00000000); + /* CCI DET_INDX2 */ + dvbt_write_reg((0x51 << 2), 0x00000000); + /* CCI_NOTCH1_A1 */ + dvbt_write_reg((0x52 << 2), 0x00000000); + /* CCI_NOTCH1_A2 */ + dvbt_write_reg((0x53 << 2), 0x00000000); + /* CCI_NOTCH1_B1 */ + dvbt_write_reg((0x54 << 2), 0x00000000); + /* CCI_NOTCH2_A1 */ + dvbt_write_reg((0x55 << 2), 0x00000000); + /* CCI_NOTCH2_A2 */ + dvbt_write_reg((0x56 << 2), 0x00000000); + /* CCI_NOTCH2_B1 */ + dvbt_write_reg((0x58 << 2), 0x00000885); + /* MODE_DETECT_CTRL // 582 */ + if (mode == 0) /* DVBT */ + dvbt_write_reg((0x5c << 2), 0x00001011); /* */ + else + dvbt_write_reg((0x5c << 2), 0x00000753); + /* ICFO_EST_CTRL ISDBT ICFO thres = 2 */ + + dvbt_write_reg((0x5f << 2), 0x0ffffe10); + /* TPS_FCFO_CTRL */ + dvbt_write_reg((0x61 << 2), 0x0000006c); + /* FWDT ctrl */ + dvbt_write_reg((0x68 << 2), 0x128c3929); + dvbt_write_reg((0x69 << 2), 0x91017f2d); + /* 0x1a8 */ + dvbt_write_reg((0x6b << 2), 0x00442211); + /* 0x1a8 */ + dvbt_write_reg((0x6c << 2), 0x01fc400a); + /* 0x */ + dvbt_write_reg((0x6d << 2), 0x0030303f); + /* 0x */ + dvbt_write_reg((0x73 << 2), 0xffffffff); + /* CCI0_PILOT_UPDATE_CTRL */ + dvbt_write_reg((0x74 << 2), 0xffffffff); + /* CCI0_DATA_UPDATE_CTRL */ + dvbt_write_reg((0x75 << 2), 0xffffffff); + /* CCI1_PILOT_UPDATE_CTRL */ + dvbt_write_reg((0x76 << 2), 0xffffffff); + /* CCI1_DATA_UPDATE_CTRL */ + + tmp = mode == 0 ? 0x000001a2 : 0x00000da2; + dvbt_write_reg((0x78 << 2), tmp); /* FEC_CTR */ + + dvbt_write_reg((0x7d << 2), 0x0000009d); + dvbt_write_reg((0x7e << 2), 0x00004000); + dvbt_write_reg((0x7f << 2), 0x00008000); + + dvbt_write_reg(((0x8b + 0) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 1) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 2) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 3) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 4) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 5) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 6) << 2), 0x20002000); + dvbt_write_reg(((0x8b + 7) << 2), 0x20002000); + + dvbt_write_reg((0x93 << 2), 0x31); + dvbt_write_reg((0x94 << 2), 0x00); + dvbt_write_reg((0x95 << 2), 0x7f1); + dvbt_write_reg((0x96 << 2), 0x20); + + dvbt_write_reg((0x98 << 2), 0x03f9115a); + dvbt_write_reg((0x9b << 2), 0x000005df); + + dvbt_write_reg((0x9c << 2), 0x00100000); + /* TestBus write valid, 0 is system clk valid */ + dvbt_write_reg((0x9d << 2), 0x01000000); + /* DDR Start address */ + dvbt_write_reg((0x9e << 2), 0x02000000); + /* DDR End address */ + + dvbt_write_regb((0x9b << 2), 7, 0); + /* Enable Testbus dump to DDR */ + dvbt_write_regb((0x9b << 2), 8, 0); + /* Run Testbus dump to DDR */ + + dvbt_write_reg((0xd6 << 2), 0x00000003); + /* apb_write_reg(DVBT_BASE+(0xd7<<2), 0x00000008); */ + dvbt_write_reg((0xd8 << 2), 0x00000120); + dvbt_write_reg((0xd9 << 2), 0x01010101); + + ini_icfo_pn_index(mode); + tfd_filter_coff_ini(); + + calculate_cordic_para(); + msleep(20); + /* delay_us(1); */ + + dvbt_write_reg((0x02 << 2), + dvbt_read_reg((0x02 << 2)) | (1 << 0)); + dvbt_write_reg((0x02 << 2), + dvbt_read_reg((0x02 << 2)) | (1 << 24)); +#endif +/* dvbt_check_status(); */ +} + +void calculate_cordic_para(void) +{ + dvbt_write_reg(0x0c, 0x00000040); +} + +char *ofdm_fsm_name[] = { " IDLE", + " AGC", + " CCI", + " ACQ", + " SYNC", + "TRACKING", + " TIMING", + " SP_SYNC", + " TPS_DEC", + "FEC_LOCK", + "FEC_LOST" +}; + +void check_fsm_state(void) +{ + unsigned long tmp; + + tmp = dvbt_read_reg(0xa8); + + + if ((tmp & 0xf) == 3) { + dvbt_write_regb((0x9b << 2), 8, 1); + /* Stop dump testbus; */ + dvbt_write_regb((0x0f << 2), 0, 1); + tmp = dvbt_read_reg((0x9f << 2)); + + } +} + +void ofdm_read_all_regs(void) +{ + int i; + unsigned long tmp; + + for (i = 0; i < 0xff; i++) + tmp = dvbt_read_reg(0x00 + i * 4); + /* printk("OFDM Reg (0x%x) is 0x%x\n", i, tmp); */ + +} + +static int dvbt_get_status(struct aml_demod_sta *demod_sta) +{ + return dvbt_read_reg(0x0) >> 12 & 1; +} + +static int dvbt_get_ber(struct aml_demod_sta *demod_sta) +{ +/* PR_DVBT("[RSJ]per is %u\n",apb_read_reg(DVBT_BASE+(0xbf<<2))); */ + return dvbt_read_reg((0xbf << 2)); +} + +static int dvbt_get_snr(struct aml_demod_sta *demod_sta) +{ +/* PR_DVBT("2snr is %u\n",((apb_read_reg(DVBT_BASE+(0x0a<<2)))>>20)&0x3ff); */ + return ((dvbt_read_reg((0x0a << 2))) >> 20) & 0x3ff; + /*dBm: bit0~bit2=decimal */ +} + +static int dvbt_get_strength(struct aml_demod_sta *demod_sta) +{ +/* int dbm = dvbt_get_ch_power(demod_sta, demod_i2c); */ +/* return dbm; */ + return 0; +} + +static int dvbt_get_ucblocks(struct aml_demod_sta *demod_sta) +{ + return 0; +/* return dvbt_get_per(); */ +} + +struct demod_status_ops *dvbt_get_status_ops(void) +{ + static struct demod_status_ops ops = { + .get_status = dvbt_get_status, + .get_ber = dvbt_get_ber, + .get_snr = dvbt_get_snr, + .get_strength = dvbt_get_strength, + .get_ucblocks = dvbt_get_ucblocks, + }; + + return &ops; +} + diff --git a/drivers/amlogic/media/amldemod/i2c_func.c b/drivers/amlogic/media/amldemod/i2c_func.c new file mode 100644 index 0000000..2e7a491 --- /dev/null +++ b/drivers/amlogic/media/amldemod/i2c_func.c @@ -0,0 +1,40 @@ +/* + * drivers/amlogic/media/amldemod/i2c_func.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 +#include +#include +#include +#include "demod_func.h" + +int am_demod_i2c_xfer(struct aml_demod_i2c *adap, struct i2c_msg msgs[], + int num) +{ + int ret = 0; + + if (adap->scl_oe) { + /* ret = aml_i2c_sw_bit_xfer(adap, msgs, num);*/ + } else { + if (adap->i2c_priv) + ret = i2c_transfer((struct i2c_adapter *)adap->i2c_priv, + msgs, num); + else + ; + /* printk("i2c error, no valid i2c\n");*/ + } + return ret; +} diff --git a/drivers/amlogic/media/amldemod/include/acf_filter_coefficient.h b/drivers/amlogic/media/amldemod/include/acf_filter_coefficient.h new file mode 100644 index 0000000..858386f --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/acf_filter_coefficient.h @@ -0,0 +1,412 @@ +/* + * drivers/amlogic/media/amldemod/include/acf_filter_coefficient.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. + * + */ + +void program_acf(int acf1[20], int acf2[33]) +{ + int i; + + for (i = 0; i < 20; i++) + dvbt_write_reg((0x2c + i) * 4, acf1[i]); + for (i = 0; i < 33; i++) { + dvbt_write_reg(0xfe * 4, i); + dvbt_write_reg(0xff * 4, acf2[i]); + } +} + +void ini_acf_iireq_src_45m_8m(void) +{ + int acf1[] = { 0x294, 0x085, 0x076, 0x01e, + 0x27c, 0x0af, 0x2bf, 0x06d, + 0x265, 0x0d8, 0x270, 0x05e, + 0x257, 0x0ef, 0x25b, 0x04b, + 0x24f, 0x0fc, 0x254, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3da7cd, 0x3c0f9b, 0x3a7768, 0x38df35, + 0x373f01, + 0x3596cd, 0x33ee98, 0x323e62, 0x307e2b, 0x2eb5f3, + 0x2ce5b9, + 0x2b057e, 0x290d41, 0x26fd00, 0x24dcbd, 0x229477, + 0x202c2c, + 0x1d93dc, 0x1ac386, 0x17b328, 0x144ac1, 0x106a4d, + 0x0be1c8, + 0x07e129, 0x04d0cc, 0x015064, 0x3d47ec, 0x38675e, + 0x326eb1, + 0x326e4d, 0x326e4d, 0x00064d + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_45m_7m(void) +{ + int acf1[] = { 0x283, 0x091, 0x02f, 0x01e, + 0x26a, 0x0b8, 0x296, 0x06d, + 0x253, 0x0dc, 0x257, 0x05e, + 0x245, 0x0f1, 0x246, 0x04b, + 0x23d, 0x0fc, 0x241, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3dafce, 0x3c1f9c, 0x3a8769, 0x38ef37, + 0x374f03, + 0x35aecf, 0x34069b, 0x325665, 0x30962e, 0x2ecdf6, + 0x2cfdbc, + 0x2b1581, 0x291d43, 0x271503, 0x24e4bf, 0x229c78, + 0x202c2d, + 0x1d8bdc, 0x1ab384, 0x179325, 0x141abc, 0x102a46, + 0x0b81be, + 0x07711c, 0x0448bd, 0x00b052, 0x3c7fd6, 0x374740, + 0x308684, + 0x308610, 0x308610, 0x000610 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_45m_6m(void) +{ + int acf1[] = { 0x272, 0x09e, 0x3dc, 0x01e, + 0x259, 0x0c0, 0x272, 0x06d, + 0x242, 0x0e1, 0x240, 0x05e, + 0x235, 0x0f3, 0x234, 0x04b, + 0x22e, 0x0fd, 0x230, 0x04d + }; + int acf2[] = { 0x3f47ff, 0x3dbfcf, 0x3c379e, 0x3aa76d, 0x391f3c, + 0x378709, + 0x35e6d6, 0x343ea2, 0x328e6d, 0x30d636, 0x2f0dfe, + 0x2d35c4, + 0x2b4d88, 0x294d49, 0x273d08, 0x2504c4, 0x22b47c, + 0x203c2f, + 0x1d9bde, 0x1ac386, 0x17a327, 0x1432bf, 0x104249, + 0x0ba9c2, + 0x07a922, 0x0490c5, 0x01185c, 0x3d0fe5, 0x383f58, + 0x3286af, + 0x328650, 0x328650, 0x000650 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_45m_5m(void) +{ + int acf1[] = { 0x260, 0x0ab, 0x37e, 0x02e, + 0x249, 0x0ca, 0x251, 0x06d, + 0x233, 0x0e6, 0x22d, 0x05e, + 0x227, 0x0f5, 0x224, 0x04b, + 0x220, 0x0fd, 0x221, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c279d, 0x3a9f6c, 0x39073a, + 0x377707, + 0x35d6d4, 0x3436a0, 0x328e6b, 0x30d636, 0x2f15ff, + 0x2d4dc6, + 0x2b758c, 0x29854f, 0x278511, 0x256ccf, 0x232c89, + 0x20cc3f, + 0x1e33f0, 0x1b6b9b, 0x185b3d, 0x14e2d5, 0x10f260, + 0x0c51d7, + 0x082934, 0x04f8d4, 0x014066, 0x3ccfe4, 0x372f46, + 0x2f5673, + 0x2f55ea, 0x2f55ea, 0x0005ea + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_2857m_8m(void) +{ + int acf1[] = { 0x2df, 0x059, 0x144, 0x00e, + 0x2d3, 0x08f, 0x38d, 0x06f, + 0x2c6, 0x0c5, 0x302, 0x05e, + 0x2be, 0x0e7, 0x2d6, 0x04b, + 0x2b7, 0x0f9, 0x2c8, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3dbfcf, 0x3c379e, 0x3aaf6d, 0x391f3c, + 0x37870a, + 0x35eed7, 0x344ea3, 0x32a66f, 0x30f639, 0x2f3602, + 0x2d65c9, + 0x2b858e, 0x299552, 0x278d12, 0x2564cf, 0x231c88, + 0x20b43d, + 0x1e13ec, 0x1b3395, 0x181336, 0x1492cc, 0x109254, + 0x0be1cb, + 0x07c127, 0x0498c7, 0x00f85b, 0x3cbfde, 0x377747, + 0x309e88, + 0x309e13, 0x309e13, 0x000613 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_2857m_7m(void) +{ + int acf1[] = { 0x2c6, 0x067, 0x10f, 0x01e, + 0x2b4, 0x099, 0x344, 0x06f, + 0x2a2, 0x0cb, 0x2cb, 0x05e, + 0x297, 0x0ea, 0x2a7, 0x04b, + 0x28f, 0x0fa, 0x29c, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3dbfcf, 0x3c379e, 0x3aa76d, 0x39173b, + 0x378709, + 0x35e6d6, 0x3446a2, 0x329e6d, 0x30e637, 0x2f2600, + 0x2d4dc7, + 0x2b6d8c, 0x297d4e, 0x276d0e, 0x2544cb, 0x22fc84, + 0x208438, + 0x1de3e7, 0x1b0b90, 0x17eb30, 0x146ac7, 0x107250, + 0x0bc9c6, + 0x07b124, 0x0490c5, 0x00f85b, 0x3cc7df, 0x37974a, + 0x30ce8d, + 0x30ce19, 0x30ce19, 0x000619 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_2857m_6m(void) +{ + int acf1[] = { 0x2ac, 0x076, 0x0c9, 0x01e, + 0x297, 0x0a4, 0x2fd, 0x06d, + 0x281, 0x0d2, 0x299, 0x05e, + 0x274, 0x0ed, 0x27d, 0x04b, + 0x26c, 0x0fb, 0x274, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c279d, 0x3a976b, 0x390739, + 0x376f07, + 0x35ced3, 0x342e9f, 0x327e6a, 0x30c634, 0x2f05fc, + 0x2d35c4, + 0x2b5d89, 0x29654c, 0x275d0c, 0x253cca, 0x22fc83, + 0x209439, + 0x1dfbe9, 0x1b2b93, 0x181b35, 0x14b2ce, 0x10ca5a, + 0x0c41d4, + 0x084935, 0x0538d9, 0x01c071, 0x3db7fa, 0x38bf6b, + 0x327eb9, + 0x327e4f, 0x327e4f, 0x00064f + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_2857m_5m(void) +{ + int acf1[] = { 0x292, 0x087, 0x06e, 0x01e, + 0x27a, 0x0b0, 0x2b9, 0x06d, + 0x262, 0x0d8, 0x26d, 0x05e, + 0x254, 0x0f0, 0x258, 0x04b, + 0x24c, 0x0fc, 0x252, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3db7ce, 0x3c279d, 0x3a976b, 0x38ff38, + 0x376706, + 0x35c6d2, 0x341e9d, 0x326e68, 0x30ae31, 0x2eedf9, + 0x2d15c0, + 0x2b2d84, 0x293546, 0x272506, 0x24fcc2, 0x22ac7b, + 0x203c2f, + 0x1d9bde, 0x1ac386, 0x17a327, 0x1422be, 0x103247, + 0x0b91bf, + 0x07891e, 0x0470c1, 0x00e858, 0x3ccfde, 0x37bf4d, + 0x313e96, + 0x313e27, 0x313e27, 0x000627 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_24m_8m(void) +{ + int acf1[] = { 0x303, 0x048, 0x17e, 0x00e, + 0x302, 0x081, 0x3f8, 0x00a, + 0x300, 0x0bd, 0x35b, 0x05e, + 0x2fe, 0x0e3, 0x325, 0x04b, + 0x2fb, 0x0f8, 0x313, 0x04d + }; + int acf2[] = { 0x3f47ff, 0x3dc7d0, 0x3c3fa0, 0x3abf6f, 0x392f3e, + 0x37a70d, + 0x360eda, 0x346ea7, 0x32c673, 0x31163d, 0x2f5606, + 0x2d8dce, + 0x2bad93, 0x29bd56, 0x27b517, 0x258cd4, 0x23448d, + 0x20cc41, + 0x1e2bf0, 0x1b4b98, 0x182338, 0x149ace, 0x109255, + 0x0bd1ca, + 0x07a123, 0x0468c2, 0x00b054, 0x3c5fd4, 0x37073a, + 0x302e79, + 0x302e05, 0x302e05, 0x000605 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_24m_7m(void) +{ + int acf1[] = { 0x2e7, 0x055, 0x153, 0x00e, + 0x2dd, 0x08b, 0x3a5, 0x06f, + 0x2d2, 0x0c4, 0x315, 0x05e, + 0x2cb, 0x0e6, 0x2e7, 0x04b, + 0x2c5, 0x0f9, 0x2d8, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3dbfcf, 0x3c379e, 0x3aaf6d, 0x391f3c, + 0x37870a, + 0x35eed7, 0x344ea3, 0x32a66f, 0x30ee39, 0x2f2e02, + 0x2d65c9, + 0x2b858e, 0x298d51, 0x278511, 0x255cce, 0x231487, + 0x20a43c, + 0x1e0beb, 0x1b3394, 0x181335, 0x1492cb, 0x109254, + 0x0be1ca, + 0x07b925, 0x0480c5, 0x00d858, 0x3c87d8, 0x373740, + 0x305e80, + 0x305e0b, 0x305e0b, 0x00060b + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_24m_6m(void) +{ + int acf1[] = { 0x2c9, 0x065, 0x118, 0x01e, + 0x2b9, 0x097, 0x34f, 0x06f, + 0x2a7, 0x0ca, 0x2d3, 0x05e, + 0x29c, 0x0e9, 0x2ae, 0x04b, + 0x295, 0x0fa, 0x2a2, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c2f9d, 0x3a9f6c, 0x390f3a, + 0x377707, + 0x35d6d4, 0x342ea0, 0x32866b, 0x30ce34, 0x2f05fd, + 0x2d35c3, + 0x2b5588, 0x295d4b, 0x27550b, 0x252cc8, 0x22dc80, + 0x206c35, + 0x1dcbe4, 0x1af38c, 0x17cb2d, 0x144ac3, 0x104a4b, + 0x0b99c1, + 0x07791d, 0x0448be, 0x00b052, 0x3c6fd4, 0x37473f, + 0x30c686, + 0x30c618, 0x30c618, 0x000618 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_24m_5m(void) +{ + int acf1[] = { 0x2ab, 0x077, 0x0c6, 0x01e, + 0x295, 0x0a5, 0x2fa, 0x06d, + 0x27f, 0x0d2, 0x297, 0x05e, + 0x272, 0x0ed, 0x27b, 0x04b, + 0x26a, 0x0fb, 0x272, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c2f9e, 0x3aa76c, 0x39173b, + 0x377f08, + 0x35ded5, 0x343ea1, 0x328e6c, 0x30de36, 0x2f15ff, + 0x2d45c6, + 0x2b658a, 0x29754d, 0x27650d, 0x253cca, 0x22f483, + 0x208438, + 0x1de3e7, 0x1b0b90, 0x17eb30, 0x1472c7, 0x107a51, + 0x0bd9c8, + 0x07c927, 0x04a8c9, 0x01205f, 0x3cf7e4, 0x37e752, + 0x31669a, + 0x31662c, 0x31662c, 0x00062c + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_207m_8m(void) +{ + int acf1[] = { 0x327, 0x039, 0x1a5, 0x07b, + 0x332, 0x076, 0x05c, 0x06e, + 0x33e, 0x0b6, 0x3b8, 0x05e, + 0x344, 0x0e0, 0x37a, 0x04b, + 0x345, 0x0f7, 0x365, 0x04d + }; + int acf2[] = { 0x3f47ff, 0x3dcfd1, 0x3c57a1, 0x3ad772, 0x394f42, + 0x37c711, + 0x3636df, 0x34a6ad, 0x32fe7a, 0x315645, 0x2f9e0f, + 0x2dd5d7, + 0x2bfd9d, 0x2a0d61, 0x280d21, 0x25e4df, 0x239c98, + 0x212c4d, + 0x1e8bfc, 0x1baba4, 0x188344, 0x14fad9, 0x10ea61, + 0x0c29d4, + 0x07e92d, 0x04a8cb, 0x00f05c, 0x3c87da, 0x371f3e, + 0x30267a, + 0x302604, 0x302604, 0x000604 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_207m_7m(void) +{ + int acf1[] = { 0x307, 0x046, 0x182, 0x00e, + 0x306, 0x080, 0x002, 0x00a, + 0x306, 0x0bd, 0x364, 0x05e, + 0x304, 0x0e3, 0x32d, 0x04b, + 0x301, 0x0f8, 0x31b, 0x04d + }; + int acf2[] = { 0x3f47ff, 0x3dc7d0, 0x3c47a0, 0x3abf6f, 0x39373f, + 0x37a70d, + 0x3616db, 0x3476a8, 0x32d674, 0x31263f, 0x2f6608, + 0x2d9dd0, + 0x2bbd96, 0x29d559, 0x27cd19, 0x25a4d7, 0x235c90, + 0x20ec45, + 0x1e53f4, 0x1b739d, 0x18533d, 0x14d2d4, 0x10d25c, + 0x0c19d1, + 0x07e12c, 0x04a8ca, 0x00f05c, 0x3c8fdb, 0x372740, + 0x302e7c, + 0x302e05, 0x302e05, 0x000605 + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_207m_6m(void) +{ + int acf1[] = { 0x2e6, 0x056, 0x151, 0x00e, + 0x2db, 0x08c, 0x3a1, 0x06f, + 0x2d0, 0x0c4, 0x312, 0x05e, + 0x2c9, 0x0e6, 0x2e4, 0x04b, + 0x2c3, 0x0f9, 0x2d6, 0x04d + }; + int acf2[] = { 0x3f47ff, 0x3dbfd0, 0x3c3f9f, 0x3ab76e, 0x39273d, + 0x37970b, + 0x35fed9, 0x345ea5, 0x32b671, 0x31063b, 0x2f4604, + 0x2d75cb, + 0x2b9590, 0x29a553, 0x279513, 0x256cd0, 0x232489, + 0x20b43d, + 0x1e0bec, 0x1b3395, 0x180b35, 0x148acb, 0x108253, + 0x0bd1c8, + 0x07a123, 0x0470c2, 0x00c055, 0x3c77d6, 0x372f3e, + 0x306e80, + 0x306e0d, 0x306e0d, 0x00060d + }; + + program_acf(acf1, acf2); +} + +void ini_acf_iireq_src_207m_5m(void) +{ + int acf1[] = { 0x2c3, 0x068, 0x109, 0x01e, + 0x2b1, 0x09a, 0x33d, 0x06f, + 0x29f, 0x0cc, 0x2c6, 0x05e, + 0x293, 0x0ea, 0x2a3, 0x04b, + 0x28c, 0x0fa, 0x298, 0x04d + }; + int acf2[] = { 0x3f3fff, 0x3db7ce, 0x3c279d, 0x3a976b, 0x38ff38, + 0x376706, + 0x35c6d2, 0x341e9e, 0x327669, 0x30be32, 0x2ef5fb, + 0x2d25c1, + 0x2b4586, 0x295549, 0x274509, 0x251cc6, 0x22dc80, + 0x206c34, + 0x1dcbe4, 0x1afb8d, 0x17db2e, 0x1462c5, 0x106a4f, + 0x0bc9c6, + 0x07b124, 0x0488c5, 0x00e859, 0x3cafdc, 0x377f47, + 0x30ee8c, + 0x30ee1d, 0x30ee1d, 0x00061d + }; + + program_acf(acf1, acf2); +} diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_che.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_che.h new file mode 100644 index 0000000..2e6af63 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_che.h @@ -0,0 +1,75 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_che.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 __ADDR_DTMB_CHE_H__ +#define __ADDR_DTMB_CHE_H__ + +#include "addr_dtmb_top.h" + +#define DTMB_CHE_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) + +#define DTMB_CHE_TE_HREB_SNR DTMB_CHE_ADDR(0x8d) +#define DTMB_CHE_MC_SC_TIMING_POWTHR DTMB_CHE_ADDR(0x8e) +#define DTMB_CHE_MC_SC_PROTECT_GD DTMB_CHE_ADDR(0x8f) +#define DTMB_CHE_TIMING_LIMIT DTMB_CHE_ADDR(0x90) +#define DTMB_CHE_TPS_CONFIG DTMB_CHE_ADDR(0x91) +#define DTMB_CHE_FD_TD_STEPSIZE DTMB_CHE_ADDR(0x92) +#define DTMB_CHE_QSTEP_SET DTMB_CHE_ADDR(0x93) +#define DTMB_CHE_SEG_CONFIG DTMB_CHE_ADDR(0x94) +#define DTMB_CHE_FD_TD_LEAKSIZE_CONFIG1 DTMB_CHE_ADDR(0x95) +#define DTMB_CHE_FD_TD_LEAKSIZE_CONFIG2 DTMB_CHE_ADDR(0x96) +#define DTMB_CHE_FD_TD_COEFF DTMB_CHE_ADDR(0x97) +#define DTMB_CHE_M_CCI_THR_CONFIG1 DTMB_CHE_ADDR(0x98) +#define DTMB_CHE_M_CCI_THR_CONFIG2 DTMB_CHE_ADDR(0x99) +#define DTMB_CHE_M_CCI_THR_CONFIG3 DTMB_CHE_ADDR(0x9a) +#define DTMB_CHE_CCIDET_CONFIG DTMB_CHE_ADDR(0x9b) +#define DTMB_CHE_IBDFE_CONFIG1 DTMB_CHE_ADDR(0x9d) +#define DTMB_CHE_IBDFE_CONFIG2 DTMB_CHE_ADDR(0x9e) +#define DTMB_CHE_IBDFE_CONFIG3 DTMB_CHE_ADDR(0x9f) +#define DTMB_CHE_TD_COEFF DTMB_CHE_ADDR(0xa0) +#define DTMB_CHE_FD_TD_STEPSIZE_ADJ DTMB_CHE_ADDR(0xa1) +#define DTMB_CHE_FD_COEFF_FRZ DTMB_CHE_ADDR(0xa2) +#define DTMB_CHE_FD_COEFF DTMB_CHE_ADDR(0xa3) +#define DTMB_CHE_FD_LEAKSIZE DTMB_CHE_ADDR(0xa4) +#define DTMB_CHE_IBDFE_CONFIG4 DTMB_CHE_ADDR(0xa5) +#define DTMB_CHE_IBDFE_CONFIG5 DTMB_CHE_ADDR(0xa6) +#define DTMB_CHE_IBDFE_CONFIG6 DTMB_CHE_ADDR(0xa7) +#define DTMB_CHE_IBDFE_CONFIG7 DTMB_CHE_ADDR(0xa8) +#define DTMB_CHE_DCM_SC_MC_GD_LEN DTMB_CHE_ADDR(0xa9) +#define DTMB_CHE_EQMC_PICK_THR DTMB_CHE_ADDR(0xaa) +#define DTMB_CHE_EQMC_THRESHOLD DTMB_CHE_ADDR(0xab) +#define DTMB_CHE_EQSC_PICK_THR DTMB_CHE_ADDR(0xad) +#define DTMB_CHE_EQSC_THRESHOLD DTMB_CHE_ADDR(0xae) +#define DTMB_CHE_PROTECT_GD_TPS DTMB_CHE_ADDR(0xaf) +#define DTMB_CHE_FD_TD_STEPSIZE_THR1 DTMB_CHE_ADDR(0xb0) +#define DTMB_CHE_TDFD_SWITCH_SYM1 DTMB_CHE_ADDR(0xb1) +#define DTMB_CHE_TDFD_SWITCH_SYM2 DTMB_CHE_ADDR(0xb2) +#define DTMB_CHE_EQ_CONFIG DTMB_CHE_ADDR(0xb3) +#define DTMB_CHE_EQSC_SNR_IMP_THR1 DTMB_CHE_ADDR(0xb4) +#define DTMB_CHE_EQSC_SNR_IMP_THR2 DTMB_CHE_ADDR(0xb5) +#define DTMB_CHE_EQMC_SNR_IMP_THR1 DTMB_CHE_ADDR(0xb6) +#define DTMB_CHE_EQMC_SNR_IMP_THR2 DTMB_CHE_ADDR(0xb7) +#define DTMB_CHE_EQSC_SNR_DROP_THR DTMB_CHE_ADDR(0xb8) +#define DTMB_CHE_EQMC_SNR_DROP_THR DTMB_CHE_ADDR(0xb9) +#define DTMB_CHE_M_CCI_THR DTMB_CHE_ADDR(0xba) +#define DTMB_CHE_TPS_MC DTMB_CHE_ADDR(0xbb) +#define DTMB_CHE_TPS_SC DTMB_CHE_ADDR(0xbc) +#define DTMB_CHE_CHE_SET_FSM DTMB_CHE_ADDR(0xbd) +#define DTMB_CHE_ZERO_NUM_THR DTMB_CHE_ADDR(0xbe) +#define DTMB_CHE_TIMING_READY DTMB_CHE_ADDR(0xbf) + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_che_bit.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_che_bit.h new file mode 100644 index 0000000..54c9098 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_che_bit.h @@ -0,0 +1,264 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_che_bit.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 __ADDR_DTMB_CHE_BIT_H__ +#define __ADDR_DTMB_CHE_BIT_H__ + +struct DTMB_CHE_TE_HREB_SNR_BITS { + unsigned int te_hreb_snr:21, reserved0:11; +}; +struct DTMB_CHE_MC_SC_TIMING_POWTHR_BITS { + unsigned int mc_timing_powthr1:5, + reserved1:3, + mc_timing_powthr0:5, + reserved2:2, + sc_timing_powthr1:5, reserved3:4, sc_timing_powthr0:5, reserved4:3; +}; +struct DTMB_CHE_MC_SC_PROTECT_GD_BITS { + unsigned int h_valid:2, + reserved5:2, + dist:3, + reserved6:1, + ma_size:3, + reserved7:1, + mc_protect_gd:5, reserved8:3, sc_protect_gd:5, reserved9:7; +}; +struct DTMB_CHE_TIMING_LIMIT_BITS { + unsigned int ncoh_thd:3, + reserved10:1, + coh_thd:3, + reserved11:1, + strong_loc_thd:8, reserved12:4, timing_limit:5, reserved13:7; +}; +struct DTMB_CHE_TPS_CONFIG_BITS { + unsigned int tps_pst_num:5, + reserved14:3, + tps_pre_num:5, reserved15:3, chi_power_thr:8, reserved16:8; +}; +struct DTMB_CHE_FD_TD_STEPSIZE_BITS { + unsigned int fd_stepsize_thr03:5, + fd_stepsize_thr02:5, + fd_stepsize_thr01:5, + td_stepsize_thr03:5, + td_stepsize_thr02:5, td_stepsize_thr01:5, reserved17:2; +}; +struct DTMB_CHE_QSTEP_SET_BITS { + unsigned int factor_stable_thres:10, + reserved18:2, qstep_set:13, qstep_set_val:1, reserved19:6; +}; +struct DTMB_CHE_SEG_CONFIG_BITS { + unsigned int seg_bypass:1, + seg_num_1seg_log2:3, + seg_alpha:3, + seg_read_val:1, seg_read_addr:12, noise_input_shift:4, reserved20:8; +}; +struct DTMB_CHE_FD_TD_LEAKSIZE_CONFIG1_BITS { + unsigned int fd_leaksize_thr03:5, + fd_leaksize_thr02:5, + fd_leaksize_thr01:5, + td_leaksize_thr03:5, + td_leaksize_thr02:5, td_leaksize_thr01:5, reserved21:2; +}; +struct DTMB_CHE_FD_TD_LEAKSIZE_CONFIG2_BITS { + unsigned int fd_leaksize_thr13:5, + fd_leaksize_thr12:5, + fd_leaksize_thr11:5, + td_leaksize_thr13:5, + td_leaksize_thr12:5, td_leaksize_thr11:5, reserved22:2; +}; +struct DTMB_CHE_FD_TD_COEFF_BITS { + unsigned int td_coeff_frz:14, + reserved23:2, + td_coeff_addr:4, + td_coeff_init:1, + td_coeff_rst:1, + fd_coeff_init:1, + fd_coeff_done:1, + fd_coeff_rst:1, td_coeff_done:1, fd_coeff_addr:5, reserved24:1; +}; +struct DTMB_CHE_M_CCI_THR_CONFIG1_BITS { + unsigned int m_cci_thr_mc1:10, + m_cci_thr_mc2:10, m_cci_thr_mc3:10, reserved25:2; +}; +struct DTMB_CHE_M_CCI_THR_CONFIG2_BITS { + unsigned int m_cci_thr_sc2:10, + m_cci_thr_sc3:10, m_cci_thr_mc0:10, reserved26:2; +}; +struct DTMB_CHE_M_CCI_THR_CONFIG3_BITS { + unsigned int m_cci_thr_ma:10, + m_cci_thr_sc0:10, m_cci_thr_sc1:10, reserved27:2; +}; +struct DTMB_CHE_CCIDET_CONFIG_BITS { + unsigned int ccidet_dly:7, + ccidet_malpha:3, + ccidet_sc_mask_rng:5, + ccidet_mc_mask_rng:5, + ccidet_masize:4, + ccidect_sat_sft:3, + ccicnt_out_sel:2, tune_mask:1, m_cci_bypass:1, reserved28:1; +}; +struct DTMB_CHE_IBDFE_CONFIG1_BITS { + unsigned int ibdfe_cci_just_thr:13, + reserved29:3, + ibdfe_dmsg_point:5, reserved30:3, ibdfe_dmsg_alp:3, reserved31:5; +}; +struct DTMB_CHE_IBDFE_CONFIG2_BITS { + unsigned int ibdfe_rou_rat_1:10, + reserved32:6, ibdfe_rou_rat_0:10, reserved33:6; +}; +struct DTMB_CHE_IBDFE_CONFIG3_BITS { + unsigned int ibdfe_rou_rat_3:10, + reserved34:6, ibdfe_rou_rat_2:10, reserved35:6; +}; +struct DTMB_CHE_TD_COEFF_BITS { + unsigned int td_coeff:24, reserved36:8; +}; +struct DTMB_CHE_FD_TD_STEPSIZE_ADJ_BITS { + unsigned int fd_stepsize_adj:3, td_stepsize_adj:3, reserved37:26; +}; +struct DTMB_CHE_FD_COEFF_BITS { + unsigned int fd_coeff:24, reserved38:8; +}; +struct DTMB_CHE_FD_LEAKSIZE_BITS { + unsigned int fd_leaksize:18, reserved39:14; +}; +struct DTMB_CHE_IBDFE_CONFIG4_BITS { + unsigned int ibdfe_fdbk_iter:4, + ibdfe_eqout_iter:4, + eq_dist_thr_tps:4, + eq_soft_slicer_en:1, + reserved40:3, + gd_len:5, ibdfe_blank_y:1, reserved41:1, ibdfe_dmsg_start_cnt:9; +}; +struct DTMB_CHE_IBDFE_CONFIG5_BITS { + unsigned int ibdfe_init_snr:12, + reserved42:4, eq_init_snr:12, reserved43:4; +}; +struct DTMB_CHE_IBDFE_CONFIG6_BITS { + unsigned int ibdfe_const_thr3:4, + ibdfe_const_thr2:4, + ibdfe_const_thr1:4, + ibdfe_const_thr0:4, + ibdfe_threshold3:4, + ibdfe_threshold2:4, ibdfe_threshold1:4, ibdfe_threshold0:4; +}; +struct DTMB_CHE_IBDFE_CONFIG7_BITS { + unsigned int ibdfe_pick_thr3:8, + ibdfe_pick_thr2:8, ibdfe_pick_thr1:8, ibdfe_pick_thr0:8; +}; +struct DTMB_CHE_DCM_SC_MC_GD_LEN_BITS { + unsigned int dcm_mc_gd_len:6, + reserved44:2, dcm_sc_gd_len:6, reserved45:2, eq_dsnr_slc2drm:16; +}; +struct DTMB_CHE_EQMC_PICK_THR_BITS { + unsigned int eqmc_pick_thr3:8, + eqmc_pick_thr2:8, eqmc_pick_thr1:8, eqmc_pick_thr0:8; +}; +struct DTMB_CHE_EQMC_THRESHOLD_BITS { + unsigned int eqmc_const_thr3:4, + eqmc_const_thr2:4, + eqmc_const_thr1:4, + eqmc_const_thr0:4, + eqmc_threshold3:4, + eqmc_threshold2:4, eqmc_threshold1:4, eqmc_threshold0:4; +}; +struct DTMB_CHE_EQSC_PICK_THR_BITS { + unsigned int eqsc_pick_thr3:8, + eqsc_pick_thr2:8, eqsc_pick_thr1:8, eqsc_pick_thr0:8; +}; +struct DTMB_CHE_EQSC_THRESHOLD_BITS { + unsigned int eqsc_const_thr3:4, + eqsc_const_thr2:4, + eqsc_const_thr1:4, + eqsc_const_thr0:4, + eqsc_threshold3:4, + eqsc_threshold2:4, eqsc_threshold1:4, eqsc_threshold0:4; +}; +struct DTMB_CHE_PROTECT_GD_TPS_BITS { + unsigned int pow_norm:10, + ncoh_thd_tps:3, + coh_thd_tps:3, thr_max:10, protect_gd_tps:5, reserved46:1; +}; +struct DTMB_CHE_FD_TD_STEPSIZE_THR1_BITS { + unsigned int fd_stepsize_thr13:5, + fd_stepsize_thr12:5, + fd_stepsize_thr11:5, + td_stepsize_thr13:5, + td_stepsize_thr12:5, td_stepsize_thr11:5, reserved47:2; +}; +struct DTMB_CHE_TDFD_SWITCH_SYM1_BITS { + unsigned int tdfd_switch_sym00:16, tdfd_switch_sym01:16; +}; +struct DTMB_CHE_TDFD_SWITCH_SYM2_BITS { + unsigned int tdfd_switch_sym10:16, tdfd_switch_sym11:16; +}; +struct DTMB_CHE_EQ_CONFIG_BITS { + unsigned int eq_dsnr_h2drm:6, + eq_cmp_en:1, + eq_imp_setzero_en:1, + dcm_sc_bypass:1, + dcm_mc_bypass:1, + dcm_sc_h_limit:4, + dcm_mc_h_limit:4, + eqsnr_imp_alp:3, eqsnr_avg_alp:3, dcm_alpha:2, reserved48:6; +}; +struct DTMB_CHE_EQSC_SNR_IMP_THR1_BITS { + unsigned int eqsc_snr_imp_thr1:12, eqsc_snr_imp_thr0:12, reserved49:8; +}; +struct DTMB_CHE_EQSC_SNR_IMP_THR2_BITS { + unsigned int eqsc_snr_imp_thr3:12, eqsc_snr_imp_thr2:12, reserved50:8; +}; +struct DTMB_CHE_EQMC_SNR_IMP_THR1_BITS { + unsigned int eqmc_snr_imp_thr1:12, eqmc_snr_imp_thr0:12, reserved51:8; +}; +struct DTMB_CHE_EQMC_SNR_IMP_THR2_BITS { + unsigned int eqmc_snr_imp_thr3:12, eqmc_snr_imp_thr2:12, reserved52:8; +}; +struct DTMB_CHE_EQSC_SNR_DROP_THR_BITS { + unsigned int eqsc_snr_drop_thr3:8, + eqsc_snr_drop_thr2:8, eqsc_snr_drop_thr1:8, eqsc_snr_drop_thr0:8; +}; +struct DTMB_CHE_EQMC_SNR_DROP_THR_BITS { + unsigned int eqmc_snr_drop_thr3:8, + eqmc_snr_drop_thr2:8, eqmc_snr_drop_thr1:8, eqmc_snr_drop_thr0:8; +}; +struct DTMB_CHE_M_CCI_THR_BITS { + unsigned int ccidet_mask_rng_tps:5, + m_cci_thr_tps:10, m_cci_thr_ma_tps:10, reserved53:7; +}; +struct DTMB_CHE_TPS_MC_BITS { + unsigned int tps_mc_run_tim_limit:10, + tps_mc_suc_limit:7, tps_mc_q_thr:7, tps_mc_alpha:3, reserved54:5; +}; +struct DTMB_CHE_TPS_SC_BITS { + unsigned int tps_sc_run_tim_limit:10, + tps_sc_suc_limit:7, tps_sc_q_thr:7, tps_sc_alpha:3, reserved55:5; +}; +struct DTMB_CHE_CHE_SET_FSM_BITS { + unsigned int che_open_loop_len:12, + reserved56:4, + che_set_fsm_st:3, reserved57:1, che_set_fsm_en:1, reserved58:11; +}; +struct DTMB_CHE_ZERO_NUM_THR_BITS { + unsigned int null_frame_thr:16, zero_num_thr:12, reserved59:4; +}; +struct DTMB_CHE_TIMING_READY_BITS { + unsigned int timing_offset:11, + reserved60:5, timing_ready:1, reserved61:15; +}; + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_front.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_front.h new file mode 100644 index 0000000..0ee9482 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_front.h @@ -0,0 +1,68 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_front.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 __ADDR_DTMB_FRONT_H__ +#define __ADDR_DTMB_FRONT_H__ + +#include "addr_dtmb_top.h" + +#define DTMB_FRONT_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) + +#define DTMB_FRONT_AFIFO_ADC DTMB_FRONT_ADDR(0x20) +#define DTMB_FRONT_AGC_CONFIG1 DTMB_FRONT_ADDR(0x21) +#define DTMB_FRONT_AGC_CONFIG2 DTMB_FRONT_ADDR(0x22) +#define DTMB_FRONT_AGC_CONFIG3 DTMB_FRONT_ADDR(0x23) +#define DTMB_FRONT_AGC_CONFIG4 DTMB_FRONT_ADDR(0x24) +#define DTMB_FRONT_DDC_BYPASS DTMB_FRONT_ADDR(0x25) +#define DTMB_FRONT_DC_HOLD DTMB_FRONT_ADDR(0x28) +#define DTMB_FRONT_DAGC_TARGET_POWER DTMB_FRONT_ADDR(0x29) +#define DTMB_FRONT_ACF_BYPASS DTMB_FRONT_ADDR(0x2a) +#define DTMB_FRONT_COEF_SET1 DTMB_FRONT_ADDR(0x2b) +#define DTMB_FRONT_COEF_SET2 DTMB_FRONT_ADDR(0x2c) +#define DTMB_FRONT_COEF_SET3 DTMB_FRONT_ADDR(0x2d) +#define DTMB_FRONT_COEF_SET4 DTMB_FRONT_ADDR(0x2e) +#define DTMB_FRONT_COEF_SET5 DTMB_FRONT_ADDR(0x2f) +#define DTMB_FRONT_COEF_SET6 DTMB_FRONT_ADDR(0x30) +#define DTMB_FRONT_COEF_SET7 DTMB_FRONT_ADDR(0x31) +#define DTMB_FRONT_COEF_SET8 DTMB_FRONT_ADDR(0x32) +#define DTMB_FRONT_COEF_SET9 DTMB_FRONT_ADDR(0x33) +#define DTMB_FRONT_COEF_SET10 DTMB_FRONT_ADDR(0x34) +#define DTMB_FRONT_COEF_SET11 DTMB_FRONT_ADDR(0x35) +#define DTMB_FRONT_COEF_SET12 DTMB_FRONT_ADDR(0x36) +#define DTMB_FRONT_COEF_SET13 DTMB_FRONT_ADDR(0x37) +#define DTMB_FRONT_COEF_SET14 DTMB_FRONT_ADDR(0x38) +#define DTMB_FRONT_COEF_SET15 DTMB_FRONT_ADDR(0x39) +#define DTMB_FRONT_COEF_SET16 DTMB_FRONT_ADDR(0x3a) +#define DTMB_FRONT_COEF_SET17 DTMB_FRONT_ADDR(0x3b) +#define DTMB_FRONT_COEF_SET18 DTMB_FRONT_ADDR(0x3c) +#define DTMB_FRONT_COEF_SET19 DTMB_FRONT_ADDR(0x3d) +#define DTMB_FRONT_SRC_CONFIG1 DTMB_FRONT_ADDR(0x3e) +#define DTMB_FRONT_SRC_CONFIG2 DTMB_FRONT_ADDR(0x3f) +#define DTMB_FRONT_SFIFO_OUT_LEN DTMB_FRONT_ADDR(0x40) +#define DTMB_FRONT_DAGC_GAIN DTMB_FRONT_ADDR(0x41) +#define DTMB_FRONT_IQIB_STEP DTMB_FRONT_ADDR(0x42) +#define DTMB_FRONT_IQIB_CONFIG DTMB_FRONT_ADDR(0x43) +#define DTMB_FRONT_ST_CONFIG DTMB_FRONT_ADDR(0x44) +#define DTMB_FRONT_ST_FREQ DTMB_FRONT_ADDR(0x45) +#define DTMB_FRONT_46_CONFIG DTMB_FRONT_ADDR(0x46) +#define DTMB_FRONT_47_CONFIG DTMB_FRONT_ADDR(0x47) +#define DTMB_FRONT_DEBUG_CFG DTMB_FRONT_ADDR(0x48) +#define DTMB_FRONT_MEM_ADDR DTMB_FRONT_ADDR(0x49) +#define DTMB_FRONT_19_CONFIG DTMB_FRONT_ADDR(0x19) +#define DTMB_FRONT_4d_CONFIG DTMB_FRONT_ADDR(0x4d) + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_front_bit.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_front_bit.h new file mode 100644 index 0000000..327a188 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_front_bit.h @@ -0,0 +1,434 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_front_bit.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 __ADDR_DTMB_FRONT_BIT_H__ +#define __ADDR_DTMB_FRONT_BIT_H__ + +union DTMB_FRONT_AFIFO_ADC_BITS { + unsigned int d32; + struct { + unsigned int afifo_nco_rate:8, + afifo_data_format:1, + afifo_bypass:1, + adc_sample:6, + adc_IQ:1, + reserved0:15; + } b; +}; +union DTMB_FRONT_AGC_CONFIG1_BITS { + unsigned int d32; + struct { + unsigned int agc_target:4, + agc_cal_intv:2, + reserved1:2, + agc_gain_step2:6, + reserved2:2, + agc_gain_step1:6, + reserved3:2, + agc_a_filter_coef2:3, + reserved4:1, + agc_a_filter_coef1:3, + reserved5:1; + } b; +}; +union DTMB_FRONT_AGC_CONFIG2_BITS { + unsigned int d32; + struct { + unsigned int agc_imp_thresh:4, + agc_imp_en:1, + agc_iq_exchange:1, + reserved6:2, + agc_clip_ratio:5, + reserved7:3, + agc_signal_clip_thr:6, + reserved8:2, + agc_sd_rate:7, + reserved9:1; + } b; +}; +union DTMB_FRONT_AGC_CONFIG3_BITS { + unsigned int d32; + struct { + unsigned int agc_rffb_value:11, + reserved10:1, + agc_iffb_value:11, + reserved11:1, + agc_gain_step_rf:1, + agc_rfgain_freeze:1, + agc_tuning_slope:1, + agc_rffb_set:1, + agc_gain_step_if:1, + agc_ifgain_freeze:1, + agc_if_only:1, + agc_iffb_set:1; + } b; +}; +union DTMB_FRONT_AGC_CONFIG4_BITS { + unsigned int d32; + struct { + unsigned int agc_rffb_gain_sat_i:8, + agc_rffb_gain_sat:8, + agc_iffb_gain_sat_i:8, + agc_iffb_gain_sat:8; + } b; +}; +union DTMB_FRONT_DDC_BYPASS_BITS { + unsigned int d32; + struct { + unsigned int ddc_phase:25, + reserved12:3, + ddc_bypass:1, + reserved13:3; + } b; +}; +union DTMB_FRONT_DC_HOLD_BITS { + unsigned int d32; + struct { + unsigned int dc_hold:1, + dc_alpha:3, + mobi_det_accu_len:3, + reserved14:1, + mobi_det_observe_len:3, + reserved15:1, + channel_static_th:4, + channel_portable_th:4, + dc_bypass:1, + reserved16:3, + dc_len:3, + reserved17:5; + } b; +}; +union DTMB_FRONT_DAGC_TARGET_POWER_BITS { + unsigned int d32; + struct { + unsigned int dagc_target_power_l:8, + dagc_target_power_h:8, + dagc_target_power_ler:8, + dagc_target_power_her:8; + } b; +}; +union DTMB_FRONT_ACF_BYPASS_BITS { + unsigned int d32; + struct { + unsigned int coef65:11, + reserved18:1, + coef66:11, + reserved19:1, + acf_bypass:1, + reserved20:7; + } b; +}; +union DTMB_FRONT_COEF_SET1_BITS { + unsigned int d32; + struct { + unsigned int coef63:11, + reserved21:1, + coef64:11, + reserved22:9; + } b; +}; +union DTMB_FRONT_COEF_SET2_BITS { + unsigned int d32; + struct { + unsigned int coef62:10, + reserved23:22; + } b; +}; +union DTMB_FRONT_COEF_SET3_BITS { + unsigned int d32; + struct { + unsigned int coef60:10, + reserved24:2, + coef61:10, + reserved25:10; + } b; +}; +union DTMB_FRONT_COEF_SET4_BITS { + unsigned int d32; + struct { + unsigned int coef59:9, + reserved26:23; + } b; +}; +union DTMB_FRONT_COEF_SET5_BITS { + unsigned int d32; + struct { + unsigned int coef57:9, + reserved27:3, + coef58:9, + reserved28:11; + } b; +}; +union DTMB_FRONT_COEF_SET6_BITS { + unsigned int d32; + struct { + unsigned int coef54:8, + coef55:8, + coef56:8, + reserved29:8; + } b; +}; +union DTMB_FRONT_COEF_SET7_BITS { + unsigned int d32; + struct { + unsigned int coef53:7, + reserved30:25; + } b; +}; +union DTMB_FRONT_COEF_SET8_BITS { + unsigned int d32; + struct { + unsigned int coef49:7, + reserved31:1, + coef50:7, + reserved32:1, + coef51:7, + reserved33:1, + coef52:7, + reserved34:1; + } b; +}; +union DTMB_FRONT_COEF_SET9_BITS { + unsigned int d32; + struct { + unsigned int coef45:7, + reserved35:1, + coef46:7, + reserved36:1, + coef47:7, + reserved37:1, + coef48:7, + reserved38:1; + } b; +}; +union DTMB_FRONT_COEF_SET10_BITS { + unsigned int d32; + struct { + unsigned int coef42:6, + reserved39:2, + coef43:6, + reserved40:2, + coef44:6, + reserved41:10; + } b; +}; +union DTMB_FRONT_COEF_SET11_BITS { + unsigned int d32; + struct { + unsigned int coef38:6, + reserved42:2, + coef39:6, + reserved43:2, + coef40:6, + reserved44:2, + coef41:6, + reserved45:2; + } b; +}; +union DTMB_FRONT_COEF_SET12_BITS { + unsigned int d32; + struct { + unsigned int coef34:6, + reserved46:2, + coef35:6, + reserved47:2, + coef36:6, + reserved48:2, + coef37:6, + reserved49:2; + } b; +}; +union DTMB_FRONT_COEF_SET13_BITS { + unsigned int d32; + struct { + unsigned int coef30:6, + reserved50:2, + coef31:6, + reserved51:2, + coef32:6, + reserved52:2, + coef33:6, + reserved53:2; + } b; +}; +union DTMB_FRONT_COEF_SET14_BITS { + unsigned int d32; + struct { + unsigned int coef27:5, + reserved54:3, + coef28:5, + reserved55:3, + coef29:5, + reserved56:11; + } b; +}; +union DTMB_FRONT_COEF_SET15_BITS { + unsigned int d32; + struct { + unsigned int coef23:5, + reserved57:3, + coef24:5, + reserved58:3, + coef25:5, + reserved59:3, + coef26:5, + reserved60:3; + } b; +}; +union DTMB_FRONT_COEF_SET16_BITS { + unsigned int d32; + struct { + unsigned int coef19:5, + reserved61:3, + coef20:5, + reserved62:3, + coef21:5, + reserved63:3, + coef22:5, + reserved64:3; + } b; +}; +union DTMB_FRONT_COEF_SET17_BITS { + unsigned int d32; + struct { + unsigned int coef15:5, + reserved65:3, + coef16:5, + reserved66:3, + coef17:5, + reserved67:3, + coef18:5, + reserved68:3; + } b; +}; +union DTMB_FRONT_COEF_SET18_BITS { + unsigned int d32; + struct { + unsigned int coef08:4, + coef09:4, + coef10:4, + coef11:4, + coef12:4, + coef13:4, + coef14:4, + reserved69:4; + } b; +}; +union DTMB_FRONT_COEF_SET19_BITS { + unsigned int d32; + struct { + unsigned int coef00:4, + coef01:4, + coef02:4, + coef03:4, + coef04:4, + coef05:4, + coef06:4, + coef07:4; + } b; +}; +union DTMB_FRONT_SRC_CONFIG1_BITS { + unsigned int d32; + struct { + unsigned int src_norm_inrate:24, + src_tim_shr:4, + src_ted_disable:1, + reserved70:3; + } b; +}; +union DTMB_FRONT_SRC_CONFIG2_BITS { + unsigned int d32; + struct { + unsigned int src_stable_timeout:4, + src_seg_len:3, + reserved71:1, + src_ted_beta:3, + reserved72:1, + src_time_err_thr:4, + src_time_mu1:5, + reserved73:3, + src_time_mu2:5, + reserved74:3; + } b; +}; +union DTMB_FRONT_SFIFO_OUT_LEN_BITS { + unsigned int d32; + struct { + unsigned int sfifo_out_len:4, + reserved75:28; + } b; +}; +union DTMB_FRONT_DAGC_GAIN_BITS { + unsigned int d32; + struct { + unsigned int dagc_bypass:1, + dagc_power_alpha:2, + dagc_bw:3, + dagc_gain_ctrl:12, + dagc_gain_step_er:6, + dagc_gain_step:6, + reserved76:2; + } b; +}; +union DTMB_FRONT_IQIB_STEP_BITS { + unsigned int d32; + struct { + unsigned int iqib_step_b:2, + iqib_step_a:2, + iqib_period:3, + reserved77:1, + iqib_bypass:1, + reserved78:23; + } b; +}; +union DTMB_FRONT_IQIB_CONFIG_BITS { + unsigned int d32; + struct { + unsigned int iqib_set_b:12, + iqib_set_a:10, + reserved79:2, + iqib_set_val:1, + iqib_hold:1, + reserved80:6; + } b; +}; +union DTMB_FRONT_ST_CONFIG_BITS { + unsigned int d32; + struct { + unsigned int st_enable:1, + reserved81:3, + st_dc_len:3, + reserved82:1, + st_alpha:3, + reserved83:1, + st_Q_thrsh:8, + st_dist:3, + reserved84:1, + st_len:5, + reserved85:3; + } b; +}; +union DTMB_FRONT_ST_FREQ_BITS { + unsigned int d32; + struct { + unsigned int st_freq_v:1, + st_freq_i:19, + reserved86:12; + } b; +}; + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_sync.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_sync.h new file mode 100644 index 0000000..5ede848 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_sync.h @@ -0,0 +1,51 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_sync.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 __ADDR_DTMB_SYNC_H__ +#define __ADDR_DTMB_SYNC_H__ + +#include "addr_dtmb_top.h" +#define DTMB_SYNC_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) + +#define DTMB_SYNC_TS_CFO_PN_VALUE DTMB_SYNC_ADDR(0x57) +#define DTMB_SYNC_TS_CFO_ERR_LIMIT DTMB_SYNC_ADDR(0x58) +#define DTMB_SYNC_TS_CFO_PN_MODIFY DTMB_SYNC_ADDR(0x59) +#define DTMB_SYNC_TS_GAIN DTMB_SYNC_ADDR(0x5a) +#define DTMB_SYNC_FE_CONFIG DTMB_SYNC_ADDR(0x5b) +#define DTMB_SYNC_PNPHASE_OFFSET DTMB_SYNC_ADDR(0x5c) +#define DTMB_SYNC_PNPHASE_CONFIG DTMB_SYNC_ADDR(0x5d) +#define DTMB_SYNC_SFO_SFO_PN0_MODIFY DTMB_SYNC_ADDR(0x5e) +#define DTMB_SYNC_SFO_SFO_PN1_MODIFY DTMB_SYNC_ADDR(0x5f) +#define DTMB_SYNC_SFO_SFO_PN2_MODIFY DTMB_SYNC_ADDR(0x60) +#define DTMB_SYNC_SFO_CONFIG DTMB_SYNC_ADDR(0x61) +#define DTMB_SYNC_FEC_CFG DTMB_SYNC_ADDR(0x67) +#define DTMB_SYNC_FEC_DEBUG_CFG DTMB_SYNC_ADDR(0x68) +#define DTMB_SYNC_DATA_DDR_ADR DTMB_SYNC_ADDR(0x69) +#define DTMB_SYNC_DEBUG_DDR_ADR DTMB_SYNC_ADDR(0x6a) +#define DTMB_SYNC_FEC_SIM_CFG1 DTMB_SYNC_ADDR(0x6b) +#define DTMB_SYNC_FEC_SIM_CFG2 DTMB_SYNC_ADDR(0x6c) +#define DTMB_SYNC_TRACK_CFO_MAX DTMB_SYNC_ADDR(0x6d) +#define DTMB_SYNC_CCI_DAGC_CONFIG1 DTMB_SYNC_ADDR(0x6e) +#define DTMB_SYNC_CCI_DAGC_CONFIG2 DTMB_SYNC_ADDR(0x6f) +#define DTMB_SYNC_CCI_RP DTMB_SYNC_ADDR(0x70) +#define DTMB_SYNC_CCI_DET_THRES DTMB_SYNC_ADDR(0x71) +#define DTMB_SYNC_CCI_NOTCH1_CONFIG1 DTMB_SYNC_ADDR(0x72) +#define DTMB_SYNC_CCI_NOTCH1_CONFIG2 DTMB_SYNC_ADDR(0x73) +#define DTMB_SYNC_CCI_NOTCH2_CONFIG1 DTMB_SYNC_ADDR(0x74) +#define DTMB_SYNC_CCI_NOTCH2_CONFIG2 DTMB_SYNC_ADDR(0x75) + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_sync_bit.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_sync_bit.h new file mode 100644 index 0000000..c29ee31 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_sync_bit.h @@ -0,0 +1,111 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_sync_bit.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 __ADDR_DTMB_SYNC_BIT_H__ +#define __ADDR_DTMB_SYNC_BIT_H__ + +struct DTMB_SYNC_TS_CFO_PN_VALUE_BITS { + unsigned int ts_cfo_pn1_value:16, ts_cfo_pn0_value:16; +}; +struct DTMB_SYNC_TS_CFO_ERR_LIMIT_BITS { + unsigned int ts_cfo_err_limit:16, ts_cfo_pn2_value:16; +}; +struct DTMB_SYNC_TS_CFO_PN_MODIFY_BITS { + unsigned int ts_cfo_pn1_modify:16, ts_cfo_pn0_modify:16; +}; +struct DTMB_SYNC_TS_GAIN_BITS { + unsigned int ts_gain:2, + reserved0:2, + ts_sat_shift:3, + reserved1:1, + ts_fixpn_en:1, + ts_fixpn:2, reserved2:1, ts_cfo_cut:4, ts_cfo_pn2_modify:16; +}; +union DTMB_SYNC_FE_CONFIG_BITS { + unsigned int d32; + struct { + unsigned int fe_lock_len:4, + fe_sat_shift:3, reserved3:1, fe_cut:4, reserved4:4, fe_modify:16; + } b; +}; +struct DTMB_SYNC_PNPHASE_OFFSET_BITS { + unsigned int pnphase_offset2:4, + pnphase_offset1:4, pnphase_offset0:4, reserved5:20; +}; +struct DTMB_SYNC_PNPHASE_CONFIG_BITS { + unsigned int pnphase_gain:2, + reserved6:2, + pnphase_sat_shift:4, pnphase_cut:4, reserved7:4, pnphase_modify:16; +}; +struct DTMB_SYNC_SFO_SFO_PN0_MODIFY_BITS { + unsigned int sfo_cfo_pn0_modify:16, sfo_sfo_pn0_modify:16; +}; +struct DTMB_SYNC_SFO_SFO_PN1_MODIFY_BITS { + unsigned int sfo_cfo_pn1_modify:16, sfo_sfo_pn1_modify:16; +}; +struct DTMB_SYNC_SFO_SFO_PN2_MODIFY_BITS { + unsigned int sfo_cfo_pn2_modify:16, sfo_sfo_pn2_modify:16; +}; +struct DTMB_SYNC_SFO_CONFIG_BITS { + unsigned int sfo_sat_shift:4, + sfo_gain:2, + reserved8:2, + sfo_dist:2, + reserved9:2, + sfo_cfo_cut:4, sfo_sfo_cut:4, sfo_cci_th:4, reserved10:8; +}; +struct DTMB_SYNC_TRACK_CFO_MAX_BITS { + unsigned int track_cfo_max:8, + track_sfo_max:8, track_max_en:1, ctrl_fe_to_th:4, reserved11:11; +}; +struct DTMB_SYNC_CCI_DAGC_CONFIG1_BITS { + unsigned int cci_dagc_bypass:1, + cci_dagc_power_alpha:2, + cci_dagc_bw:3, + cci_dagc_gain_ctrl:12, + cci_dagc_gain_step_er:6, cci_dagc_gain_step:6, reserved12:2; +}; +struct DTMB_SYNC_CCI_DAGC_CONFIG2_BITS { + unsigned int cci_dagc_target_power_l:8, + cci_dagc_target_power_h:8, + cci_dagc_target_power_ler:8, cci_dagc_target_power_her:8; +}; +struct DTMB_SYNC_CCI_RP_BITS { + unsigned int cci_rpsq_n:10, reserved13:2, cci_rp_n:13, reserved14:7; +}; +struct DTMB_SYNC_CCI_DET_THRES_BITS { + unsigned int cci_avr_times:5, + reserved15:3, cci_det_thres:3, reserved16:21; +}; +struct DTMB_SYNC_CCI_NOTCH1_CONFIG1_BITS { + unsigned int cci_notch1_a1:10, + reserved17:2, cci_notch1_en:1, reserved18:19; +}; +struct DTMB_SYNC_CCI_NOTCH1_CONFIG2_BITS { + unsigned int cci_notch1_b1:10, + reserved19:2, cci_notch1_a2:10, reserved20:10; +}; +struct DTMB_SYNC_CCI_NOTCH2_CONFIG1_BITS { + unsigned int cci_notch2_a1:10, + reserved21:2, cci_notch2_en:1, reserved22:3, cci_mpthres:16; +}; +struct DTMB_SYNC_CCI_NOTCH2_CONFIG2_BITS { + unsigned int cci_notch2_b1:10, + reserved23:2, cci_notch2_a2:10, reserved24:10; +}; + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_top.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_top.h new file mode 100644 index 0000000..1ad8a34 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_top.h @@ -0,0 +1,90 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_top.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 __ADDR_DTMB_TOP_H__ +#define __ADDR_DTMB_TOP_H__ + +#include "addr_dtmb_top_bit.h" +#include "addr_dtmb_sync.h" +#include "addr_dtmb_sync_bit.h" +#include "addr_dtmb_che.h" +#include "addr_dtmb_che_bit.h" +#include "addr_dtmb_front.h" +#include "addr_dtmb_front_bit.h" + +/* #define DTMB_DEMOD_BASE DEMOD_REG_ADDR(0x0) */ +#define DTMB_DEMOD_BASE DEMOD_REG_ADDR_OFFSET(0x0) + +#define DTMB_TOP_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) + +#define DTMB_TOP_CTRL_SW_RST DTMB_TOP_ADDR(0x1) +#define DTMB_TOP_TESTBUS DTMB_TOP_ADDR(0x2) +#define DTMB_TOP_TB DTMB_TOP_ADDR(0x3) +#define DTMB_TOP_TB_V DTMB_TOP_ADDR(0x4) +#define DTMB_TOP_TB_ADDR_BEGIN DTMB_TOP_ADDR(0x5) +#define DTMB_TOP_TB_ADDR_END DTMB_TOP_ADDR(0x6) +#define DTMB_TOP_CTRL_ENABLE DTMB_TOP_ADDR(0x7) +#define DTMB_TOP_CTRL_LOOP DTMB_TOP_ADDR(0x8) +#define DTMB_TOP_CTRL_FSM DTMB_TOP_ADDR(0x9) +#define DTMB_TOP_CTRL_AGC DTMB_TOP_ADDR(0xa) +#define DTMB_TOP_CTRL_TS_SFO_CFO DTMB_TOP_ADDR(0xb) +#define DTMB_TOP_CTRL_FEC DTMB_TOP_ADDR(0xc) +#define DTMB_TOP_CTRL_INTLV_TIME DTMB_TOP_ADDR(0xd) +#define DTMB_TOP_CTRL_DAGC_CCI DTMB_TOP_ADDR(0xe) +#define DTMB_TOP_CTRL_TPS DTMB_TOP_ADDR(0xf) +#define DTMB_TOP_TPS_BIT DTMB_TOP_ADDR(0x10) +#define DTMB_TOP_CCI_FLG DTMB_TOP_ADDR(0xc7) +#define DTMB_TOP_TESTBUS_OUT DTMB_TOP_ADDR(0xc8) +#define DTMB_TOP_TBUS_DC_ADDR DTMB_TOP_ADDR(0xc9) +#define DTMB_TOP_FRONT_IQIB_CHECK DTMB_TOP_ADDR(0xca) +#define DTMB_TOP_SYNC_TS DTMB_TOP_ADDR(0xcb) +#define DTMB_TOP_SYNC_PNPHASE DTMB_TOP_ADDR(0xcd) +#define DTMB_TOP_CTRL_DDC_ICFO DTMB_TOP_ADDR(0xd2) +#define DTMB_TOP_CTRL_DDC_FCFO DTMB_TOP_ADDR(0xd3) +#define DTMB_TOP_CTRL_FSM_STATE0 DTMB_TOP_ADDR(0xd4) +#define DTMB_TOP_CTRL_FSM_STATE1 DTMB_TOP_ADDR(0xd5) +#define DTMB_TOP_CTRL_FSM_STATE2 DTMB_TOP_ADDR(0xd6) +#define DTMB_TOP_CTRL_FSM_STATE3 DTMB_TOP_ADDR(0xd7) +#define DTMB_TOP_CTRL_TS2 DTMB_TOP_ADDR(0xd8) +#define DTMB_TOP_FRONT_AGC DTMB_TOP_ADDR(0xd9) +#define DTMB_TOP_FRONT_DAGC DTMB_TOP_ADDR(0xda) +#define DTMB_TOP_FEC_TIME_STS DTMB_TOP_ADDR(0xdb) +#define DTMB_TOP_FEC_LDPC_STS DTMB_TOP_ADDR(0xdc) +#define DTMB_TOP_FEC_LDPC_IT_AVG DTMB_TOP_ADDR(0xdd) +#define DTMB_TOP_FEC_LDPC_UNC_ACC DTMB_TOP_ADDR(0xde) +#define DTMB_TOP_FEC_BCH_ACC DTMB_TOP_ADDR(0xdf) +#define DTMB_TOP_CTRL_ICFO_ALL DTMB_TOP_ADDR(0xe0) +#define DTMB_TOP_CTRL_FCFO_ALL DTMB_TOP_ADDR(0xe1) +#define DTMB_TOP_CTRL_SFO_ALL DTMB_TOP_ADDR(0xe2) +#define DTMB_TOP_FEC_LOCK_SNR DTMB_TOP_ADDR(0xe3) +#define DTMB_TOP_CHE_SEG_FACTOR DTMB_TOP_ADDR(0xe4) +#define DTMB_TOP_CTRL_CHE_WORKCNT DTMB_TOP_ADDR(0xe5) +#define DTMB_TOP_CHE_OBS_STATE1 DTMB_TOP_ADDR(0xe6) +#define DTMB_TOP_CHE_OBS_STATE2 DTMB_TOP_ADDR(0xe7) +#define DTMB_TOP_CHE_OBS_STATE3 DTMB_TOP_ADDR(0xe8) +#define DTMB_TOP_CHE_OBS_STATE4 DTMB_TOP_ADDR(0xe9) +#define DTMB_TOP_CHE_OBS_STATE5 DTMB_TOP_ADDR(0xea) +#define DTMB_TOP_SYNC_CCI_NF1 DTMB_TOP_ADDR(0xee) +#define DTMB_TOP_SYNC_CCI_NF2 DTMB_TOP_ADDR(0xef) +#define DTMB_TOP_SYNC_CCI_NF2_POSITION DTMB_TOP_ADDR(0xf0) +#define DTMB_TOP_CTRL_SYS_OFDM_CNT DTMB_TOP_ADDR(0xf1) +#define DTMB_TOP_CTRL_TPS_Q_FINAL DTMB_TOP_ADDR(0xf2) +#define DTMB_TOP_FRONT_DC DTMB_TOP_ADDR(0xf3) +#define DTMB_TOP_CHE_DEBUG DTMB_TOP_ADDR(0xf6) +#define DTMB_TOP_CTRL_TOTPS_READY_CNT DTMB_TOP_ADDR(0xff) + +#endif diff --git a/drivers/amlogic/media/amldemod/include/addr_dtmb_top_bit.h b/drivers/amlogic/media/amldemod/include/addr_dtmb_top_bit.h new file mode 100644 index 0000000..ac26d92 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/addr_dtmb_top_bit.h @@ -0,0 +1,362 @@ +/* + * drivers/amlogic/media/amldemod/include/addr_dtmb_top_bit.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 __ADDR_DTMB_TOP_BIT_H__ +#define __ADDR_DTMB_TOP_BIT_H__ + +/*dtmb_cfg_01*/ + +union DTMB_TOP_CTRL_SW_RST_BITS { + unsigned int d32; + struct { + unsigned int ctrl_sw_rst:1, ctrl_sw_rst_noreg:1, reserved0:30; + } b; +}; +/*dtmb_cfg_02*/ + +union DTMB_TOP_TESTBUS_BITS { + unsigned int d32; + struct { + unsigned int testbus_addr:16, testbus_en:1, reserved1:15; + } b; +}; +/*dtmb_cfg_03*/ + +union DTMB_TOP_TB_BITS { + unsigned int d32; + struct { + unsigned int tb_act_width:5, + reserved2:3, + tb_dc_mk:3, + reserved3:1, tb_capture_stop:1, tb_self_test:1, + reserved4:18; + } b; +}; +/*dtmb_cfg_07*/ + +union DTMB_TOP_CTRL_ENABLE_BITS { + unsigned int d32; + struct { + unsigned int ctrl_enable:24, reserved5:8; + } b; +}; +/*dtmb_cfg_08*/ + +union DTMB_TOP_CTRL_LOOP_BITS { + unsigned int d32; + struct { + unsigned int ctrl_src_pnphase_loop:1, + ctrl_src_sfo_loop:1, + ctrl_ddc_fcfo_loop:1, ctrl_ddc_icfo_loop:1, reserved6:28; + } b; +}; +/*dtmb_cfg_09*/ + +union DTMB_TOP_CTRL_FSM_BITS { + unsigned int d32; + struct { + unsigned int ctrl_fsm_state:5, + reserved7:3, + ctrl_fsm_v:1, reserved8:3, ctrl_reset_state:4, + reserved9:16; + } b; +}; +/*dtmb_cfg_0a*/ + +union DTMB_TOP_CTRL_AGC_BITS { + unsigned int d32; + struct { + unsigned int ctrl_fast_agc:1, + ctrl_agc_bypass:1, + ts_cfo_bypass:1, sfo_strong0_bypass:1, reserved10:28; + } b; +}; +/*dtmb_cfg_0b*/ + +union DTMB_TOP_CTRL_TS_SFO_CFO_BITS { + unsigned int d32; + struct { + unsigned int ctrl_ts_q:10, + reserved11:2, + ctrl_pnphase_q:7, reserved12:1, ctrl_sfo_q:4, ctrl_cfo_q:8; + } b; +}; +/*dtmb_cfg_0c*/ + +union DTMB_TOP_CTRL_FEC_BITS { + unsigned int d32; + struct { + unsigned int reserved13:8, + ctrl_ts_to_th:4, + ctrl_pnphase_to_th:4, + ctrl_sfo_to_th:4, + ctrl_fe_to_th:4, ctrl_che_to_th:4, ctrl_fec_to_th:4; + } b; +}; +/*dtmb_cfg_0d*/ + +union DTMB_TOP_CTRL_INTLV_TIME_BITS { + unsigned int d32; + struct { + unsigned int ctrl_intlv720_time:12, ctrl_intlv240_time:12, + reserved14:8; + } b; +}; +/*dtmb_cfg_0e*/ + +union DTMB_TOP_CTRL_DAGC_CCI_BITS { + unsigned int d32; + struct { + unsigned int dagc_mode:2, + cci_dagc_mode:2, + cci_bypass:1, + fe_bypass:1, + reserved15:1, + new_sync1:1, new_sync2:1, fec_inzero_check:1, + reserved16:22; + } b; +}; +/*dtmb_cfg_0f*/ +union DTMB_TOP_CTRL_TPS_BITS { + unsigned int d32; + struct { + unsigned int sfo_gain:2, + freq_reverse:1, + qam4_nr:1, + intlv_mode:1, + code_rate:2, + constell:2, + tps_carrier_mode:1, + freq_reverse_known:1, tps_known:1, ctrl_tps_to_th:4, + reserved17:16; + } b; +}; +/*dtmb_cfg_c7*/ +union DTMB_TOP_CCI_FLG_BITS { + unsigned int d32; + struct { + unsigned int cci_flg_cnt:8, m_cci_ready:1, reserved18:23; + } b; +}; +/*dtmb_cfg_ca*/ +union DTMB_TOP_FRONT_IQIB_CHECK_BITS { + unsigned int d32; + struct { + unsigned int front_iqib_check_b:12, + front_iqib_check_a:10, reserved19:10; + } b; +}; +/*dtmb_cfg_cb*/ +union DTMB_TOP_SYNC_TS_BITS { + unsigned int d32; + struct { + unsigned int sync_ts_idx:2, sync_ts_pos:13, sync_ts_q:10, + reserved20:7; + } b; +}; +/*dtmb_cfg_cd*/ + +union DTMB_TOP_SYNC_PNPHASE_BITS { + unsigned int d32; + struct { + unsigned int sync_pnphase_max_q_idx:2, + sync_pnphase:8, sync_pnphase_max_q:7, reserved21:15; + } b; +}; +/*dtmb_cfg_d2*/ + +union DTMB_TOP_CTRL_DDC_ICFO_BITS { + unsigned int d32; + struct { + unsigned int ctrl_ddc_icfo:20, reserved22:12; + } b; +}; +/*dtmb_cfg_d3*/ + +union DTMB_TOP_CTRL_DDC_FCFO_BITS { + unsigned int d32; + struct { + unsigned int ctrl_src_sfo:17, ctrl_ddc_fcfo:14, reserved23:1; + } b; +}; +/*dtmb_cfg_d8*/ + +union DTMB_TOP_CTRL_TS2_BITS { + unsigned int d32; + struct { + unsigned int ctrl_ts2_workcnt:8, + ctrl_pnphase_workcnt:8, ctrl_sfo_workcnt:8, + sync_fe_workcnt:8; + } b; +}; +/*dtmb_cfg_d9*/ + +union DTMB_TOP_FRONT_AGC_BITS { + unsigned int d32; + struct { + unsigned int front_agc_if_gain:11, + front_agc_rf_gain:11, front_agc_power:9, reserved:1; + } b_v2; + struct { + unsigned int front_agc_if_gain:11, + front_agc_rf_gain:11, front_agc_power:10; + } b; +}; +/*dtmb_cfg_da*/ + +union DTMB_TOP_FRONT_DAGC_BITS { + unsigned int d32; + struct { + unsigned int front_dagc_power:8, front_dagc_gain:12, + reserved24:12; + } b; +}; +/*dtmb_cfg_dd*/ + +union DTMB_TOP_FEC_LDPC_IT_AVG_BITS { + unsigned int d32; + struct { + unsigned int fec_ldpc_it_avg:16, fec_ldpc_per_rpt:13, + reserved25:3; + } b; +}; +/*dtmb_cfg_e0*/ + +union DTMB_TOP_CTRL_ICFO_ALL_BITS { + unsigned int d32; + struct { + unsigned int ctrl_icfo_all:20, reserved26:12; + } b; +}; +/*dtmb_cfg_e1*/ + +union DTMB_TOP_CTRL_FCFO_ALL_BITS { + unsigned int d32; + struct { + unsigned int ctrl_fcfo_all:20, reserved27:12; + } b; +}; +/*dtmb_cfg_e2*/ + +union DTMB_TOP_CTRL_SFO_ALL_BITS { + unsigned int d32; + struct { + unsigned int ctrl_sfo_all:25, reserved28:7; + } b; +}; +/*dtmb_cfg_e3*//*have v2*/ +union DTMB_TOP_FEC_LOCK_SNR_BITS { + unsigned int d32; + struct { + unsigned int che_snr:12, + fec_lock:1, reserved29:1, che_snr_average:12, reserved30:6; + } b_v2; + struct { + unsigned int che_snr:14, + fec_lock:1, reserved29:1, che_snr_average:14, reserved30:2; + } b; +}; +/*dtmb_cfg_e4*/ + +union DTMB_TOP_CHE_SEG_FACTOR_BITS { + unsigned int d32; + struct { + unsigned int che_seg_factor:14, reserved31:18; + } b; +}; +/*dtmb_cfg_e5*/ + +union DTMB_TOP_CTRL_CHE_WORKCNT_BITS { + unsigned int d32; + struct { + unsigned int ctrl_che_workcnt:8, + ctrl_fec_workcnt:8, + ctrl_constell:2, + ctrl_code_rate:2, + ctrl_intlv_mode:1, + ctrl_qam4_nr:1, ctrl_freq_reverse:1, reserved32:9; + } b; +}; +/*dtmb_cfg_ee*/ + +union DTMB_TOP_SYNC_CCI_NF1_BITS { + unsigned int d32; + struct { + unsigned int sync_cci_nf1_b1:10, + sync_cci_nf1_a2:10, sync_cci_nf1_a1:10, reserved33:2; + } b; +}; +/*dtmb_cfg_ef*/ + +union DTMB_TOP_SYNC_CCI_NF2_BITS { + unsigned int d32; + struct { + unsigned int sync_cci_nf2_b1:10, + sync_cci_nf2_a2:10, sync_cci_nf2_a1:10, reserved34:2; + } b; +}; +/*dtmb_cfg_f0*/ + +union DTMB_TOP_SYNC_CCI_NF2_POSITION_BITS { + unsigned int d32; + struct { + unsigned int sync_cci_nf2_position:11, + sync_cci_nf1_position:11, + sync_cci_nf2_det:1, sync_cci_nf1_det:1, reserved35:8; + } b; +}; +/*dtmb_cfg_f1*/ + +union DTMB_TOP_CTRL_SYS_OFDM_CNT_BITS { + unsigned int d32; + struct { + unsigned int ctrl_sys_ofdm_cnt:8, + mobi_det_power_var:19, + reserved36:1, ctrl_che_working_state:2, reserved37:2; + } b; +}; +/*dtmb_cfg_f2*/ + +union DTMB_TOP_CTRL_TPS_Q_FINAL_BITS { + unsigned int d32; + struct { + unsigned int ctrl_tps_q_final:7, ctrl_tps_suc_cnt:7, + reserved38:18; + } b; +}; +/*dtmb_cfg_f3*/ + +union DTMB_TOP_FRONT_DC_BITS { + unsigned int d32; + struct { + unsigned int front_dc_q:10, front_dc_i:10, + reserved39:12; + } b; +}; +/*dtmb_cfg_ff*/ + +union DTMB_TOP_CTRL_TOTPS_READY_CNT_BITS { + unsigned int d32; + struct { + unsigned int ctrl_dead_lock_det:1, + ctrl_dead_lock:1, + reserved40:2, + ctrl_dead_cnt:4, reserved41:8, ctrl_totps_ready_cnt:16; + } b; +}; + +#endif diff --git a/drivers/amlogic/media/amldemod/include/amlfrontend.h b/drivers/amlogic/media/amldemod/include/amlfrontend.h new file mode 100644 index 0000000..c00af73 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/amlfrontend.h @@ -0,0 +1,435 @@ +/* + * drivers/amlogic/media/amldemod/include/amlfrontend.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 _AMLFRONTEND_H +#define _AMLFRONTEND_H +/**/ +#include "depend.h" /**/ + +#define KERNEL_4_9_EN 1 + +struct amlfe_config { + int fe_mode; + int i2c_id; + int tuner_type; + int tuner_addr; +}; +enum Gxtv_Demod_Tuner_If { + Si2176_5M_If = 5, + Si2176_6M_If = 6 +}; +/* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC */ +enum Gxtv_Demod_Dvb_Mode { + Gxtv_Dvbc = 0, + Gxtv_Dvbt_Isdbt = 1, + Gxtv_Atsc = 2, + Gxtv_Dtmb = 3, +}; +#define Adc_Clk_35M 35714 /* adc clk dvbc */ +#define Demod_Clk_71M 71428 /* demod clk */ + +#define Adc_Clk_24M 24000 +#define Demod_Clk_72M 72000 +#define Demod_Clk_60M 60000 + +#define Adc_Clk_28M 28571 /* dvbt,isdbt */ +#define Demod_Clk_66M 66666 + +#define Adc_Clk_26M 26000 /* atsc air */ +#define Demod_Clk_78M 78000 /* */ + +#define Adc_Clk_25_2M 25200 /* atsc cable */ +#define Demod_Clk_75M 75600 /* */ + +#define Adc_Clk_25M 25000 /* dtmb */ +#define Demod_Clk_100M 100000 /* */ +#define Demod_Clk_180M 180000 /* */ +#define Demod_Clk_200M 200000 /* */ +#define Demod_Clk_225M 225000 + +#define Adc_Clk_27M 27777 /* atsc */ +#define Demod_Clk_83M 83333 /* */ + +enum M6_Demod_Pll_Mode { + Cry_mode = 0, + Adc_mode = 1 +}; + +/* + * e: enum + * s: system + */ +enum es_map_addr { + ES_MAP_ADDR_DEMOD, + ES_MAP_ADDR_IOHIU, + ES_MAP_ADDR_AOBUS, + ES_MAP_ADDR_RESET, + ES_MAP_ADDR_NUM +}; +struct ss_reg_phy { + unsigned int phy_addr; + unsigned int size; + /*void __iomem *p;*/ + /*int flag;*/ +}; +struct ss_reg_vt { + void __iomem *v; + int flag; +}; + +/* rigister offset page */ +#define IC_OFFS_V2 (0x02) /*MG9TV, GXTVBB, TXL*/ +#define IC_OFFS_V3 (0x03) /*TXLX, GXLX...*/ + + + +#define IC_MD_NONE (0x00) + +#define IC_DVBC_V2 (0x02) /*MG9TV, GXTVBB, TXL*/ +#define IC_DVBC_V3 (0x03) /*TXLX, GXLX*/ + +#define IC_DTMB_V2 (0x02) /*MG9TV, GXTVBB*/ +#define IC_DTMB_V3 (0x03) /*TXL, TXHD*/ + +#define IC_DVBT_V2 (0x02) /*TXLX*/ +#define IC_ATSC_V2 (0x02) /*TXLX*/ + +#define IC_OFFS_V2 (0x02) /*MG9TV, GXTVBB, TXL*/ +#define IC_OFFS_V3 (0x03) /*TXLX, GXLX, TXHD*/ + +/*-----------------------*/ +#define IC_VER_GTVBB (0x00) +#define IC_VER_TXL (0x01) +#define IC_VER_TXLX (0x02) +#define IC_VER_GXLX (0x03) +#define IC_VER_TXHD (0x04) + +#define IC_VER_NUB (0x05) + + +/*-----------------------*/ +#if 0 +struct ic_cfg_s { + /* register */ +#if 0 + unsigned int reg_demod_st; + unsigned int reg_demod_size; + unsigned int reg_iohiu_st; + unsigned int reg_iohiu_size; + unsigned int reg_aobus_st; /*ao bus*/ + unsigned int reg_aobus_size; + unsigned int reg_reset_st; /*reset*/ + unsigned int reg_reset_size; +#endif + + /* module version */ + union { + unsigned int all; + struct { + unsigned int atsc:4, dvbt:4, dtmb:4, dvbc:4, + reserved:4, offset:4, ic:8; + } b; + } hwver; +}; +#endif + +struct ic_ver { + unsigned int atsc:4, dvbt:4, dtmb:4, dvbc:4, + reserved:4, offset:4, ic:8; + +}; +struct ddemod_reg_off { + /* register address offset for demod*/ + unsigned int off_demod; + unsigned int off_dvbc; + unsigned int off_dtmb; + unsigned int off_dvbt; + unsigned int off_atsc; + +#if 0 + /*vertual address for dtv demod*/ + void __iomem *base_demod; + void __iomem *base_iohiu; + void __iomem *base_aobus; + void __iomem *base_reset; +#else + +#endif +}; +struct meson_ddemod_data { + const char *name; + struct ic_ver icver; + /*struct ddemod_reg_off regoff;*/ +}; +enum DTVDEMOD_ST { + DTVDEMOD_ST_NOT_INI, /*driver is not init or init failed*/ + DTVDEMOD_ST_IDLE, /*leave mode*/ + DTVDEMOD_ST_WORK, /*enter_mode*/ +}; + +/*polling*/ +struct poll_machie_s { + unsigned int flg_stop; /**/ + unsigned int flg_restart; + + unsigned int state; /*idel, work,*/ + + + /**/ + unsigned int delayms; + unsigned int flg_updelay; + + unsigned int crrcnt; + unsigned int maxcnt; + + enum fe_status last_s; + unsigned int bch; + + +}; +struct amlfe_exp_config { + /*config by aml_fe ?*/ + /* */ + int set_mode; +}; + +struct amldtvdemod_device_s { + + struct class *clsp; + struct device *dev; + enum DTVDEMOD_ST state; + struct mutex lock; /*aml_lock*/ + + /*struct ic_cfg_s iccfg;*/ + struct ic_ver icver; + struct ss_reg_phy reg_p[ES_MAP_ADDR_NUM]; + struct ss_reg_vt reg_v[ES_MAP_ADDR_NUM]; + + struct ddemod_reg_off ireg; + struct meson_ddemod_data *data; + + + struct poll_machie_s poll_machie; + + unsigned int en_detect; +#ifdef KERNEL_4_9_EN + /* clktree */ + unsigned int clk_gate_state; + struct clk *vdac_clk_gate; +#endif + /*agc pin mux*/ + struct pinctrl *pin; + const char *pin_name; + +#if 1 /*move to aml_dtv_demod*/ + /*for mem reserved*/ + int mem_start; + int mem_end; + int mem_size; + int cma_flag; +#ifdef CONFIG_CMA + struct platform_device *this_pdev; + struct page *venc_pages; + unsigned int cma_mem_size;/* BYTE */ + unsigned int cma_mem_alloc; +#endif + + /*for dtv spectrum*/ + int spectrum; + /*for atsc version*/ + int atsc_version; + /*for dtv priv*/ +#endif + enum aml_fe_n_mode_t n_mode; /*temp for mode*/ + enum fe_delivery_system last_delsys; +#ifndef DVB_49 + struct dvb_frontend *frontend; /**/ +#else + struct dvb_frontend frontend; /**/ +#endif + const struct amlfe_exp_config *afe_cfg; + +}; +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; + +/*version*/ +static inline int is_atsc_ver(unsigned int ver) +{ + return dtvdd_devp->icver.atsc == ver; +} +static inline int is_dvbt_ver(unsigned int ver) +{ + return dtvdd_devp->icver.dvbt == ver; +} +static inline int is_dtmb_ver(unsigned int ver) +{ + return dtvdd_devp->icver.dtmb == ver; +} +static inline int is_dvbc_ver(unsigned int ver) +{ + return dtvdd_devp->icver.dvbc == ver; +} + +static inline int is_offset_ver(unsigned int ver) +{ + return dtvdd_devp->icver.offset == ver; +} +static inline int get_atsc_ver(void) +{ + return dtvdd_devp->icver.atsc; +} +static inline int get_dvbt_ver(void) +{ + return dtvdd_devp->icver.dvbt; +} + +static inline int get_dtmb_ver(void) +{ + return dtvdd_devp->icver.dtmb; +} +static inline int get_dvbc_ver(void) +{ + return dtvdd_devp->icver.dvbc; +} + +static inline int is_ic_ver(unsigned int ver) +{ + return dtvdd_devp->icver.ic == ver; +} +static inline int get_ic_ver(void) +{ + return dtvdd_devp->icver.ic; +} + +#if 0 +static inline void __iomem *gbase_dvbt(void) +{ + return dtvdd_devp->ireg.base_demod + dtvdd_devp->ireg.off_dvbt; +} +static inline void __iomem *gbase_dvbc(void) +{ + return dtvdd_devp->ireg.base_demod + dtvdd_devp->ireg.off_dvbc; +} +static inline void __iomem *gbase_dtmb(void) +{ + return dtvdd_devp->ireg.base_demod + dtvdd_devp->ireg.off_dtmb; +} + +static inline void __iomem *gbase_atsc(void) +{ + return dtvdd_devp->ireg.base_demod + dtvdd_devp->ireg.off_atsc; +} +static inline void __iomem *gbase_demod(void) +{ + return dtvdd_devp->ireg.base_demod + dtvdd_devp->ireg.off_demod; +} + +static inline void __iomem *gbase_aobus(void) +{ + return dtvdd_devp->ireg.base_aobus; +} + +static inline void __iomem *gbase_iohiu(void) +{ + return dtvdd_devp->ireg.base_iohiu; +} +static inline void __iomem *gbase_reset(void) +{ + return dtvdd_devp->ireg.base_reset; +} + +static inline unsigned int gphybase_demod(void) +{ + return dtvdd_devp->iccfg.reg_demod_st + dtvdd_devp->ireg.off_demod; +} +static inline unsigned int gphybase_hiu(void) +{ + return dtvdd_devp->iccfg.reg_iohiu_st; +} +#else +static inline void __iomem *gbase_dvbt(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_dvbt; +} +static inline void __iomem *gbase_dvbc(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_dvbc; +} +static inline void __iomem *gbase_dtmb(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_dtmb; +} + +static inline void __iomem *gbase_atsc(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_atsc; +} +static inline void __iomem *gbase_demod(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_demod; +} + +static inline void __iomem *gbase_aobus(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_AOBUS].v; +} + +static inline void __iomem *gbase_iohiu(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_IOHIU].v; +} +static inline void __iomem *gbase_reset(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_RESET].v; +} + +static inline unsigned int gphybase_demod(void) +{ + return dtvdd_devp->reg_p[ES_MAP_ADDR_DEMOD].phy_addr; +} +static inline unsigned int gphybase_demodcfg(void) +{ + return dtvdd_devp->reg_p[ES_MAP_ADDR_DEMOD].phy_addr + + dtvdd_devp->ireg.off_demod; +} + +static inline unsigned int gphybase_hiu(void) +{ + return dtvdd_devp->reg_p[ES_MAP_ADDR_IOHIU].phy_addr; +} + +#endif +/*poll*/ +extern void dtmb_poll_start(void); +extern void dtmb_poll_stop(void); +extern unsigned int dtmb_is_update_delay(void); +extern unsigned int dtmb_get_delay_clear(void); +extern unsigned int dtmb_is_have_check(void); +extern void dtmb_poll_v3(void); +#endif diff --git a/drivers/amlogic/media/amldemod/include/atsc_func.h b/drivers/amlogic/media/amldemod/include/atsc_func.h new file mode 100644 index 0000000..d0597d15 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/atsc_func.h @@ -0,0 +1,83 @@ +/* + * drivers/amlogic/media/amldemod/include/atsc_func.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. + * + */ + +#ifdef ATSC_FUNC_H +#else +#define ATSC_FUNC_H + +#include "demod_func.h" + +enum atsc_state_machine { + Idle = 0x20, + CR_Lock = 0x50, + CR_Peak_Lock = 0x62, + Atsc_sync_lock = 0x70, + Atsc_Lock = 0x76 +}; + +enum atsc_performance { + TASK4_TASK5 = 1, + AWGN, + TASK8_R22, +}; + +#define Lock 1 +#define UnLock 0 +#define Cfo_Ok 1 +#define Cfo_Fail 0 +#define Dagc_Open 1 +#define Dagc_Close 0 +#define Atsc_BandWidth (6000) + +/* atsc */ + +int atsc_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_atsc *demod_atsc); +int check_atsc_fsm_status(void); + +void atsc_write_reg(unsigned int reg_addr, unsigned int reg_data); + +unsigned int atsc_read_reg(unsigned int reg_addr); + +unsigned int atsc_read_iqr_reg(void); + +/*int atsc_qam_set(fe_modulation_t mode);*/ +int atsc_qam_set(enum fe_modulation mode); + + +void qam_initial(int qam_id); + +void set_cr_ck_rate(void); + +void atsc_reset(void); + +int atsc_find(unsigned int data, unsigned int *ptable, int len); + +int atsc_read_snr(void); + +int atsc_read_ser(void); + +void atsc_thread(void); + +void atsc_set_performance_register(int flag, int init); + +int snr_avg_100_times(void); + +void atsc_set_version(int version); + +#endif diff --git a/drivers/amlogic/media/amldemod/include/demod_func.h b/drivers/amlogic/media/amldemod/include/demod_func.h new file mode 100644 index 0000000..109eecf --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/demod_func.h @@ -0,0 +1,824 @@ +/* + * drivers/amlogic/media/amldemod/include/demod_func.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 __DEMOD_FUNC_H__ + +#define __DEMOD_FUNC_H__ + +#include + +#include +/*#include "aml_fe.h"*/ +#include "dvb_frontend.h" /**/ +#include "amlfrontend.h" +#include "addr_dtmb_top.h" +/*#include "c_stb_define.h"*/ +/*#include "c_stb_regs_define.h"*/ +#include +#include +#include "atsc_func.h" +#if defined DEMOD_FPGA_VERSION +#include "fpga_func.h" +#endif + + + +/* #define G9_TV */ +#define GX_TV +#define safe_addr + +#define PWR_ON 1 +#define PWR_OFF 0 + +#define dtmb_mobile_mode + +/* void __iomem *meson_reg_demod_map[1024]; */ + +/* base address define */ +/* gxtvbb txl */ +#define IO_DEMOD_BASE (0xc8844000) +#define IO_AOBUS_BASE (0xc8100000) +#define IO_HIU_BASE (0xc883c000) + +/* txlx */ +#define TXLX_DEMOD_BASE (0xff644000) +#define TXLX_IO_AOBUS_BASE (0xff800000) +#define TXLX_IO_HIU_BASE (0xff63c000) + +/* gxlx only support dvbc */ +#define GXLX_DEMOD_BASE (0xc8840000) + +/* txhd */ +#define TXHD_DEMOD_BASE (0xff644000) +#define TXHD_TVFE_BASE (0xff642000) + + +/* register define */ +/*#define TXLX_RESET0_LEVEL (0xffd01080)*/ +/*#define TXLX_HHI_DEMOD_MEM_PD_REG (0xff63c000 + (0x43 << 2)) */ + + +/* txhd */ +#define TXHD_TOP_BASE_ADD 0x300 +#define TXHD_TVFE_VAFE_CTRL0 ((TXHD_TOP_BASE_ADD+0xB0)<<2) +#define TXHD_TVFE_VAFE_CTRL1 ((TXHD_TOP_BASE_ADD+0xB1)<<2) +#define TXHD_TVFE_VAFE_CTRL2 ((TXHD_TOP_BASE_ADD+0xB2)<<2) + +/* offset define */ +#define DEMOD_REG_ADDR_OFFSET(reg) (reg & 0xfffff) +#define QAM_BASE (0x400) /* is offset */ +#define DEMOD_CFG_BASE (0xC00) /* is offset */ + +/* adc */ +#define D_HHI_DADC_CNTL (0x27 << 2) +#define D_HHI_DADC_CNTL2 (0x28 << 2) +#define D_HHI_DADC_RDBK0_I (0x29 << 2) +#define D_HHI_DADC_CNTL3 (0x2a << 2) +#define D_HHI_DADC_CNTL4 (0x2b << 2) + +#define D_HHI_VDAC_CNTL0 (0xbd << 2) + +/* PLL */ +#define D_HHI_ADC_PLL_CNTL5 (0x9e << 2) +#define D_HHI_ADC_PLL_CNTL6 (0x9f << 2) +#define D_HHI_ADC_PLL_CNTL (0xaa << 2) +#define D_HHI_ADC_PLL_CNTL2 (0xab << 2) +#define D_HHI_ADC_PLL_CNTL3 (0xac << 2) +#define D_HHI_ADC_PLL_CNTL4 (0xad << 2) +#define D_HHI_ADC_PLL_CNTL1 (0xaf << 2) + +/**/ +#define D_HHI_HDMI_CLK_CNTL (0x73 << 2) +#define D_HHI_DEMOD_CLK_CNTL (0x74 << 2) +/*redefine*/ +#define HHI_DEMOD_MEM_PD_REG (0x43 << 2) +/*redefine*/ +#define RESET_RESET0_LEVEL (0x80) + +/*----------------------------------*/ +/*register offset define in C_stb_regs_define.h*/ +#define AO_RTI_GEN_PWR_SLEEP0 ((0x00 << 10) | (0x3a << 2)) +#define AO_RTI_GEN_PWR_ISO0 ((0x00 << 10) | (0x3b << 2)) +/*----------------------------------*/ + + +/* demod register */ +#define DEMOD_REG1 (0x00) +#define DEMOD_REG2 (0x04) +#define DEMOD_REG3 (0x08) +#define DEMOD_REG4 (0x0C) + +#if 0 +/* demod register: */ +#define GXBB_DEMOD_REG1 (0xc00) +#define GXBB_DEMOD_REG2 (0xc04) +#define GXBB_DEMOD_REG3 (0xc08) +#define GXBB_DEMOD_REG4 (0xc0c) + + +#define TXLX_DEMOD_REG1 (0xF00) +#define TXLX_DEMOD_REG2 (0xF04) +#define TXLX_DEMOD_REG3 (0xF08) +#define TXLX_DEMOD_REG4 (0xF0c) + +#endif + + +/* old define */ +#define DVBT_BASE (TXLX_DEMOD_BASE+0x400) +#define TXLX_ATSC_BASE (TXLX_DEMOD_BASE+0x800) +#define TXLX_QAM_BASE (TXLX_DEMOD_BASE+0xC00) + + +#define GXLX_QAM_BASE (GXLX_DEMOD_BASE+0xC00) +/*#define GXLX_HHI_DEMOD_MEM_PD_REG (0xc883c000 + (0x43 << 2))*/ + +/*#define RESET0_LEVEL 0xc1104480*/ +/*#define HHI_DEMOD_MEM_PD_REG (0xc883c000 + (0x43 << 2))*/ + +#define IO_CBUS_PHY_BASE (0xc0800000) + + +/* #ifdef TXL_TV */ +/*txl and txlx is the same*/ +#define TXLX_ADC_RESET_VALUE 0xca6a2110 /* 0xce7a2110 */ +#define TXLX_ADC_REG1_VALUE 0x5d414260 +#define TXLX_ADC_REG2_VALUE 0x5ba00384 /* 0x34e0bf81 */ +#define TXLX_ADC_REG2_VALUE_CRY 0x5ba00385 +#define TXLX_ADC_REG3_VALUE 0x4a6a2110 /* 0x4e7a2110 */ +#define TXLX_ADC_REG4_VALUE 0x02913004 +#define TXLX_ADC_REG4_CRY_VALUE 0x301 +#define TXLX_ADC_REG7_VALUE 0x00102038 +#define TXLX_ADC_REG8_VALUE 0x00000406 +#define TXLX_ADC_REG9_VALUE 0x00082183 +#define TXLX_ADC_REGA_VALUE 0x80480240 +#define TXLX_ADC_REGB_VALUE 0x22000442 +#define TXLX_ADC_REGC_VALUE 0x00034a00 +#define TXLX_ADC_REGD_VALUE 0x00005000 +#define TXLX_ADC_REGE_VALUE 0x00000200 + + + + +/* #ifdef GX_TV */ + +#define ADC_RESET_VALUE 0x8a2a2110 /* 0xce7a2110 */ +#define ADC_REG1_VALUE 0x00100228 +#define ADC_REG2_VALUE 0x34e0bf80 /* 0x34e0bf81 */ +#define ADC_REG2_VALUE_CRY 0x34e0bf81 +#define ADC_REG3_VALUE 0x0a2a2110 /* 0x4e7a2110 */ +#define ADC_REG4_VALUE 0x02933800 +#define ADC_REG4_CRY_VALUE 0x301 +#define ADC_REG7_VALUE 0x01411036 +#define ADC_REG8_VALUE 0x00000000 +#define ADC_REG9_VALUE 0x00430036 +#define ADC_REGA_VALUE 0x80480240 +#if 0 +/* DADC DPLL */ +#define ADC_REG1 (IO_HIU_BASE + (0xaa << 2)) +#define ADC_REG2 (IO_HIU_BASE + (0xab << 2)) +#define ADC_REG3 (IO_HIU_BASE + (0xac << 2)) +#define ADC_REG4 (IO_HIU_BASE + (0xad << 2)) + +#define ADC_REG5 (IO_HIU_BASE + (0x73 << 2)) +#define ADC_REG6 (IO_HIU_BASE + (0x74 << 2)) + +/* DADC REG */ +#define ADC_REG7 (IO_HIU_BASE + (0x27 << 2)) +#define ADC_REG8 (IO_HIU_BASE + (0x28 << 2)) +#define ADC_REG9 (IO_HIU_BASE + (0x2a << 2)) +#define ADC_REGA (IO_HIU_BASE + (0x2b << 2)) +#endif +/* #endif */ + +#if 0 +/* #ifdef G9_TV */ + +#define ADC_RESET_VALUE 0x8a2a2110 /* 0xce7a2110 */ +#define ADC_REG1_VALUE 0x00100228 +#define ADC_REG2_VALUE 0x34e0bf80 /* 0x34e0bf81 */ +#define ADC_REG2_VALUE_CRY 0x34e0bf81 +#define ADC_REG3_VALUE 0x0a2a2110 /* 0x4e7a2110 */ +#define ADC_REG4_VALUE 0x02933800 +#define ADC_REG4_CRY_VALUE 0x301 +#define ADC_REG7_VALUE 0x01411036 +#define ADC_REG8_VALUE 0x00000000 +#define ADC_REG9_VALUE 0x00430036 +#define ADC_REGA_VALUE 0x80480240 + +/* DADC DPLL */ +#define ADC_REG1 0x10aa +#define ADC_REG2 0x10ab +#define ADC_REG3 0x10ac +#define ADC_REG4 0x10ad + +#define ADC_REG5 0x1073 +#define ADC_REG6 0x1074 + +/* DADC REG */ +#define ADC_REG7 0x1027 +#define ADC_REG8 0x1028 +#define ADC_REG9 0x102a +#define ADC_REGA 0x102b +#endif + +#if 0 +/* #ifdef M6_TV */ +#define ADC_REG1_VALUE 0x003b0232 +#define ADC_REG2_VALUE 0x814d3928 +#define ADC_REG3_VALUE 0x6b425012 +#define ADC_REG4_VALUE 0x101 +#define ADC_REG4_CRY_VALUE 0x301 +#define ADC_REG5_VALUE 0x70b +#define ADC_REG6_VALUE 0x713 + +#define ADC_REG1 0x10aa +#define ADC_REG2 0x10ab +#define ADC_REG3 0x10ac +#define ADC_REG4 0x10ad +#define ADC_REG5 0x1073 +#define ADC_REG6 0x1074 +#endif + +#define DEMOD_REG1_VALUE 0x0000d007 +#define DEMOD_REG2_VALUE 0x2e805400 +#define DEMOD_REG3_VALUE 0x201 + +/* for table end */ +#define TABLE_FLG_END 0xffffffff + +/* debug info=====================================================*/ +extern int aml_demod_debug; + +#define DBG_INFO 1 +#define DBG_REG 2 +#define DBG_ATSC 4 +#define DBG_DTMB 8 +#define DBG_LOOP 16 +#define DBG_DVBC 32 +#define DBG_DVBT 64 + + + +#if 0 +#define aml_printk(kern, fmt, arg...) \ + printk(kern "%s: " fmt, __func__, ##arg) +#endif + +#if 0 +#define aml_printk(kern, fmt, arg...) \ + printk("%s: " fmt, __func__, ##arg) + +#define amldemod_prk(kern, fmt, arg...) \ + printk("amldemod:%s: " fmt, __func__, ##arg) + +#define aml_info(fmt, arg...) aml_printk(KERN_INFO "amldemod:" fmt, ##arg) +#define aml_warn(fmt, arg...) aml_printk(KERN_WARNING, fmt, ##arg) +#define aml_err(fmt, arg...) aml_printk(KERN_ERR, fmt, ##arg) + +/*amldemod_prk, printk,pr_debug*/ +#define _aml_dbg(flg, fmt, arg...) \ + do { \ + if (((aml_demod_debug) & flg) == flg) { \ + printk(fmt, ##arg); \ + } \ + } while (0) + + + +#define aml_loop(flg, a...) \ + do { \ + if (((aml_demod_debug) & flg) == flg) { \ + printk(a); \ + } \ + } while (0) + +#define aml_dbg(fmt, arg...) _aml_dbg((DBG_INFO), fmt, ##arg) +#define aml_dbgatsc(fmt, arg...) _aml_dbg((DBG_ATSC|DBG_INFO), \ + fmt, ##arg) +#define aml_dbgatscl(a...) aml_loop((DBG_ATSC|DBG_INFO|DBG_LOOP), a) + +#define aml_dbgdvbc_reg(fmt, arg...) _aml_dbg((DBG_DVBC|DBG_REG), \ + fmt, ##arg) +#define aml_dbgdtmb(fmt, arg...) _aml_dbg((DBG_DTMB|DBG_INFO), \ + fmt, ##arg) +#define aml_dbgdvbt(fmt, arg...) _aml_dbg((DBG_DVBT|DBG_INFO), \ + fmt, ##arg) + +#endif +/*new*/ +#define PR_INFO(fmt, args ...) printk("dtv_dmd:"fmt, ##args) + +#define PR_DBG(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_INFO) { \ + printk("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +#define PR_ATSC(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_ATSC) { \ + printk("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +#define PR_DVBC(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_DVBC) { \ + pr_info("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +#define PR_DVBT(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_DVBT) { \ + pr_info("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +#define PR_DTMB(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_DTMB) { \ + pr_info("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +/*polling*/ +#define PR_DBGL(fmt, args ...) \ + do { \ + if (aml_demod_debug & DBG_LOOP) { \ + pr_info("dtv_dmd:"fmt, ##args); \ + } \ + } while (0) + +#define PR_ERR(fmt, args ...) pr_err("dtv_dmd:"fmt, ## args) +#define PR_WAR(fmt, args...) pr_warn("dtv_dmd:" fmt, ## args) + +/*=============================================================*/ +/* #define Wr(addr, data) WRITE_CBUS_REG(addr, data)*/ +/* #define Rd(addr) READ_CBUS_REG(addr) */ + +/*#define Wr(addr, data) *(volatile unsigned long *)(addr) = (data)*/ +/*#define Rd(addr) *(volatile unsigned long *)(addr)*/ + +enum { + enable_mobile, + disable_mobile +}; + +enum { + OPEN_TIME_EQ, + CLOSE_TIME_EQ +}; + +enum { + AMLOGIC_DTMB = 1, + AMLOGIC_DVBT_ISDBT, + AMLOGIC_ATSC = 4, + AMLOGIC_DVBC_J83B, + AMLOGIC_DEMOD_CFG, + AMLOGIC_DEMOD_BASE, + AMLOGIC_DEMOD_FPGA, + AMLOGIC_DEMOD_COLLECT_DATA = 10, + AMLOGIC_DEMOD_OTHERS +}; + + +enum { + AMLOGIC_DTMB_STEP0, + AMLOGIC_DTMB_STEP1, + AMLOGIC_DTMB_STEP2, + AMLOGIC_DTMB_STEP3, + AMLOGIC_DTMB_STEP4, + AMLOGIC_DTMB_STEP5, /* time eq */ + AMLOGIC_DTMB_STEP6, /* set normal mode sc */ + AMLOGIC_DTMB_STEP7, + AMLOGIC_DTMB_STEP8, /* set time eq mode */ + AMLOGIC_DTMB_STEP9, /* reset */ + AMLOGIC_DTMB_STEP10, /* set normal mode mc */ + AMLOGIC_DTMB_STEP11, +}; + +enum { + DTMB_IDLE = 0, + DTMB_AGC_READY = 1, + DTMB_TS1_READY = 2, + DTMB_TS2_READY = 3, + DTMB_FE_READY = 4, + DTMB_PNPHASE_READY = 5, + DTMB_SFO_INIT_READY = 6, + DTMB_TS3_READY = 7, + DTMB_PM_INIT_READY = 8, + DTMB_CHE_INIT_READY = 9, + DTMB_FEC_READY = 10 +}; + +enum { + REG_M_DEMOD = 0, + /*REG_M_TVAFE,*/ + REG_M_HIU, + REG_M_NONE +}; + +extern struct dvb_frontend *aml_get_fe(void); + +extern void tuner_set_params(struct dvb_frontend *fe); + + +int tuner_get_ch_power(struct dvb_frontend *fe); +int tuner_get_ch_power2(void); + + +int dtmb_get_power_strength(int agc_gain); + + + + +/* dvbt */ +int dvbt_set_ch(struct aml_demod_sta *demod_sta, + struct aml_demod_dvbt *demod_dvbt); + +struct demod_status_ops { + int (*get_status)(struct aml_demod_sta *demod_sta); + int (*get_ber)(struct aml_demod_sta *demod_sta); + int (*get_snr)(struct aml_demod_sta *demod_sta); + int (*get_strength)(struct aml_demod_sta *demod_sta); + int (*get_ucblocks)(struct aml_demod_sta *demod_sta); +}; + +struct demod_status_ops *dvbt_get_status_ops(void); + +/* dvbc */ + +int dvbc_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_dvbc *demod_dvbc); +int dvbc_status(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_sts *demod_sts); +int dvbc_isr_islock(void); +void dvbc_isr(struct aml_demod_sta *demod_sta); +u32 dvbc_set_qam_mode(unsigned char mode); +u32 dvbc_get_status(void); +u32 dvbc_set_auto_symtrack(void); +int dvbc_timer_init(void); +void dvbc_timer_exit(void); +int dvbc_cci_task(void *data); +int dvbc_get_cci_task(void); +void dvbc_create_cci_task(void); +void dvbc_kill_cci_task(void); + +/* DVBC */ +/*gxtvbb*/ + +extern void dvbc_reg_initial_old(struct aml_demod_sta *demod_sta); + +/*txlx*/ +extern void dvbc_reg_initial(struct aml_demod_sta *demod_sta); +extern void dvbc_init_reg_ext(void); +extern u32 dvbc_get_ch_sts(void); +extern u32 dvbc_get_qam_mode(void); + + +/* dtmb */ + +int dtmb_set_ch(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_dtmb *demod_atsc); + +void dtmb_reset(void); + +int dtmb_check_status_gxtv(struct dvb_frontend *fe); +int dtmb_check_status_txl(struct dvb_frontend *fe); + +void dtmb_write_reg(int reg_addr, int reg_data); +unsigned int dtmb_read_reg(unsigned int reg_addr); +void dtmb_register_reset(void); + +/* + * dtmb register write / read + */ + +/*test only*/ +enum REG_DTMB_D9 { + DTMB_D9_IF_GAIN, + DTMB_D9_RF_GAIN, + DTMB_D9_POWER, + DTMB_D9_ALL, +}; + +extern void dtmb_set_mem_st(int mem_start); +extern int dtmb_read_agc(enum REG_DTMB_D9 type, unsigned int *buf); +extern unsigned int dtmb_reg_r_che_snr(void); +extern unsigned int dtmb_reg_r_fec_lock(void); +extern unsigned int dtmb_reg_r_bch(void); +extern int check_dtmb_fec_lock(void); +extern int dtmb_constell_check(void); + +extern void dtmb_no_signal_check_v3(void); +extern void dtmb_no_signal_check_finishi_v3(void); +extern unsigned int dtmb_detect_first(void); + + +/* demod functions */ +unsigned long apb_read_reg_collect(unsigned long addr); +void apb_write_reg_collect(unsigned int addr, unsigned int data); +void apb_write_reg(unsigned int reg, unsigned int val); +unsigned long apb_read_reg_high(unsigned long addr); +unsigned long apb_read_reg(unsigned long reg); +int app_apb_write_reg(int addr, int data); +int app_apb_read_reg(int addr); + +void demod_set_cbus_reg(unsigned int data, unsigned int addr); +unsigned int demod_read_cbus_reg(unsigned int addr); +void demod_set_demod_reg(unsigned int data, unsigned int addr); +unsigned int demod_read_demod_reg(unsigned int addr); + +/* extern int clk_measure(char index); */ + +void ofdm_initial(int bandwidth, + /* 00:8M 01:7M 10:6M 11:5M */ + int samplerate, + /* 00:45M 01:20.8333M 10:20.7M 11:28.57 */ + int IF, + /* 000:36.13M 001:-5.5M 010:4.57M 011:4M 100:5M */ + int mode, + /* 00:DVBT,01:ISDBT */ + int tc_mode + /* 0: Unsigned, 1:TC */); + +void monitor_isdbt(void); +void demod_set_reg(struct aml_demod_reg *demod_reg); +void demod_get_reg(struct aml_demod_reg *demod_reg); + +/* void demod_calc_clk(struct aml_demod_sta *demod_sta); */ +int demod_set_sys(struct aml_demod_sta *demod_sta, + /*struct aml_demod_i2c *demod_i2c,*/ + struct aml_demod_sys *demod_sys); + + +/* for g9tv */ +void adc_dpll_setup(int clk_a, int clk_b, int clk_sys, int dvb_mode); +void demod_power_switch(int pwr_cntl); + +union adc_pll_cntl { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned pll_m:9; + unsigned pll_n:5; + unsigned pll_od0:2; + unsigned pll_od1:2; + unsigned pll_od2:2; + unsigned pll_xd0:6; + unsigned pll_xd1:6; + } b; +}; + +union adc_pll_cntl2 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned output_mux_ctrl:4; + unsigned div2_ctrl:1; + unsigned b_polar_control:1; + unsigned a_polar_control:1; + unsigned gate_ctrl:6; + unsigned tdc_buf:8; + unsigned lm_s:6; + unsigned lm_w:4; + unsigned reserved:1; + } b; +}; + +union adc_pll_cntl3 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned afc_dsel_in:1; + unsigned afc_dsel_bypass:1; + unsigned dco_sdmck_sel:2; + unsigned dc_vc_in:2; + unsigned dco_m_en:1; + unsigned dpfd_lmode:1; + unsigned filter_acq1:11; + unsigned enable:1; + unsigned filter_acq2:11; + unsigned reset:1; + } b; +}; + +union adc_pll_cntl4 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned reve:12; + unsigned tdc_en:1; + unsigned dco_sdm_en:1; + unsigned dco_iup:2; + unsigned pvt_fix_en:1; + unsigned iir_bypass_n:1; + unsigned pll_od3:2; + unsigned filter_pvt1:4; + unsigned filter_pvt2:4; + unsigned reserved:4; + } b; +}; + +/* ///////////////////////////////////////////////////////////////// */ + +union demod_dig_clk { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned demod_clk_div:7; + unsigned reserved0:1; + unsigned demod_clk_en:1; + unsigned demod_clk_sel:2; + unsigned reserved1:5; + unsigned adc_extclk_div:7; /* 34 */ + unsigned use_adc_extclk:1; /* 1 */ + unsigned adc_extclk_en:1; /* 1 */ + unsigned adc_extclk_sel:3; /* 1 */ + unsigned reserved2:4; + } b; +}; + +union demod_adc_clk { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned pll_m:9; + unsigned pll_n:5; + unsigned pll_od:2; + unsigned pll_xd:5; + unsigned reserved0:3; + unsigned pll_ss_clk:4; + unsigned pll_ss_en:1; + unsigned reset:1; + unsigned pll_pd:1; + unsigned reserved1:1; + } b; +}; + +union demod_cfg0 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned mode:4; + unsigned ts_sel:4; + unsigned test_bus_clk:1; + unsigned adc_ext:1; + unsigned adc_rvs:1; + unsigned adc_swap:1; + unsigned adc_format:1; + unsigned adc_regout:1; + unsigned adc_regsel:1; + unsigned adc_regadj:5; + unsigned adc_value:10; + unsigned adc_test:1; + unsigned ddr_sel:1; + } b; +}; + +union demod_cfg1 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned reserved:8; + unsigned ref_top:2; + unsigned ref_bot:2; + unsigned cml_xs:2; + unsigned cml_1s:2; + unsigned vdda_sel:2; + unsigned bias_sel_sha:2; + unsigned bias_sel_mdac2:2; + unsigned bias_sel_mdac1:2; + unsigned fast_chg:1; + unsigned rin_sel:3; + unsigned en_ext_vbg:1; + unsigned en_cmlgen_res:1; + unsigned en_ext_vdd12:1; + unsigned en_ext_ref:1; + } b; +}; + +union demod_cfg2 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned en_adc:1; + unsigned biasgen_ibipt_sel:2; + unsigned biasgen_ibic_sel:2; + unsigned biasgen_rsv:4; + unsigned biasgen_en:1; + unsigned biasgen_bias_sel_adc:2; + unsigned biasgen_bias_sel_cml1:2; + unsigned biasgen_bias_sel_ref_op:2; + unsigned clk_phase_sel:1; + unsigned reserved:15; + } b; +}; + +union demod_cfg3 { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned dc_arb_mask:3; + unsigned dc_arb_enable:1; + unsigned reserved:28; + } b; +}; + +struct atsc_cfg { + int adr; + int dat; + int rw; +}; + +struct agc_power_tab { + char name[128]; + int level; + int ncalcE; + int *calcE; +}; + +struct dtmb_cfg { + int dat; + int adr; + int rw; +}; + +void dtvpll_lock_init(void); +void dtvpll_init_flag(int on); +void demod_set_irq_mask(void); +void demod_clr_irq_stat(void); +void demod_set_adc_core_clk(int adc_clk, int sys_clk, int dvb_mode); +void demod_set_adc_core_clk_fix(int clk_adc, int clk_dem); +void calculate_cordic_para(void); +void ofdm_read_all_regs(void); +/*extern int aml_fe_analog_set_frontend(struct dvb_frontend *fe);*/ +int get_dtvpll_init_flag(void); +void demod_set_mode_ts(unsigned char dvb_mode); +void qam_write_reg(unsigned int reg_addr, unsigned int reg_data); +unsigned int qam_read_reg(unsigned int reg_addr); +/*bool is_meson_txlx_cpu(void);*/ + +/* add new function */ +/*extern void dtvdemod_base_add_init(void);*/ +/*extern unsigned ddemod_reg_base;*/ +#if 0 +extern void demod_set_reg_rlt(unsigned int addr, unsigned int data); +extern unsigned int demod_read_reg_rlt(unsigned int addr); +#endif +extern void dvbc_write_reg(unsigned int addr, unsigned int data); +extern unsigned int dvbc_read_reg(unsigned int addr); +extern void demod_write_reg(unsigned int addr, unsigned int data); +extern unsigned int demod_read_reg(unsigned int addr); + +extern int dd_tvafe_hiu_reg_write(unsigned int reg, unsigned int val); +extern unsigned int dd_tvafe_hiu_reg_read(unsigned int addr); + +extern int reset_reg_write(unsigned int reg, unsigned int val); +extern unsigned int reset_reg_read(unsigned int addr); + + +extern void clocks_set_sys_defaults(unsigned char dvb_mode); +extern void demod_set_demod_default(void); + +extern void debug_adc_pll(void); +extern void debug_check_reg_val(unsigned int reg_mode, unsigned int reg); + +/*register access api new*/ +extern void dvbt_write_reg(unsigned int addr, unsigned int data); +extern unsigned int dvbt_read_reg(unsigned int addr); + +int aml_demod_init(void); /*ary temp*/ +void aml_demod_exit(void); /*ary temp*/ + +#endif diff --git a/drivers/amlogic/media/amldemod/include/depend.h b/drivers/amlogic/media/amldemod/include/depend.h new file mode 100644 index 0000000..680f725 --- /dev/null +++ b/drivers/amlogic/media/amldemod/include/depend.h @@ -0,0 +1,53 @@ +/* + * drivers/amlogic/media/amldemod/include/depend.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 __DEPEND_H__ +#define __DEPEND_H__ + +#include /**/ + + +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); +/*dma_release_from_contiguous*/ +bool aml_dma_release_contiguous(struct device *dev, struct page *pages, + int count); + + +/*void ary_test(void);*/ +enum aml_fe_n_mode_t { /*same as aml_fe_mode_t in aml_fe.h*/ + AM_FE_UNKNOWN_N = 0, + AM_FE_QPSK_N = 1, + AM_FE_QAM_N = 2, + AM_FE_OFDM_N = 4, + AM_FE_ATSC_N = 8, + /*AM_FE_ANALOG = 16,*/ + AM_FE_DTMB_N = 32, + AM_FE_ISDBT_N = 64 +}; + +/*----------------------------------*/ + +struct aml_exp_func { + + int (*leave_mode)(int mode); +}; + +#endif /*__DEPEND_H__*/ diff --git a/drivers/amlogic/media/amldemod/tuner_func.c b/drivers/amlogic/media/amldemod/tuner_func.c new file mode 100644 index 0000000..55383bd --- /dev/null +++ b/drivers/amlogic/media/amldemod/tuner_func.c @@ -0,0 +1,232 @@ +/* + * drivers/amlogic/media/amldemod/tuner_func.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 +#include +#include +#include "demod_func.h" +/*#include "aml_fe.h"*/ + + +/*add to replase aml_fe_analog_set_frontend*/ +void tuner_set_params(struct dvb_frontend *fe) +{ + int ret = -1; + + PR_INFO("%s:\n", __func__); + + if (fe->ops.tuner_ops.set_params) + ret = fe->ops.tuner_ops.set_params(fe); + else + PR_ERR("error: no tuner"); + + +} + +int tuner_get_ch_power(struct dvb_frontend *fe) +{ + int strength = 0; + u16 strengtha = 0; + + if (fe != NULL) { +#if 0 + if (fe->ops.tuner_ops.get_strength) + strength = fe->ops.tuner_ops.get_strength(fe); + else + PR_INFO("no tuner get_strength\n"); +#endif + if (fe->ops.tuner_ops.get_rf_strength) { + fe->ops.tuner_ops.get_rf_strength(fe, &strengtha); + strength = strengtha; /* - 256;*/ + } else { + PR_INFO("no tuner get_strength\n"); + } + } + + + return strength; +} + +int tuner_get_ch_power2(void) +{ +#if 0 + int strength = 0; + u16 strengtha = 0; + struct dvb_frontend *fe; + + fe = aml_get_fe(); + if (fe != NULL) { + + if (fe->ops.tuner_ops.get_rf_strength) { + fe->ops.tuner_ops.get_rf_strength(fe, &strengtha); + //strength = strengtha - 256; + strength = (int)strengtha; + } else { + PR_INFO("no tuner get_strength\n"); + } + } + + + return strength; +#endif + return 0; +} + +struct dvb_tuner_info *tuner_get_info(int type, int mode) +{ + /*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */ + /*mode: 0-DVBC 1-DVBT */ + static struct dvb_tuner_info tinfo_null = { }; + + static struct dvb_tuner_info tinfo_MXL5003S[2] = { + [1] = { /*DVBT*/ .name = "Maxliner", + .frequency_min = 44000000, + .frequency_max = 885000000, } + }; + static struct dvb_tuner_info tinfo_FJ2207[2] = { + [0] = { /*DVBC*/ .name = "FJ2207", + .frequency_min = 54000000, + .frequency_max = 870000000, }, + [1] = { /*DVBT*/ .name = "FJ2207", + .frequency_min = 174000000, + .frequency_max = 864000000, }, + }; + static struct dvb_tuner_info tinfo_DCT7070[2] = { + [0] = { /*DVBC*/ .name = "DCT7070", + .frequency_min = 51000000, + .frequency_max = 860000000, } + }; + static struct dvb_tuner_info tinfo_TD1316[2] = { + [1] = { /*DVBT*/ .name = "TD1316", + .frequency_min = 51000000, + .frequency_max = 858000000, } + }; + static struct dvb_tuner_info tinfo_SI2176[2] = { + [0] = { /*DVBC*/ + /*#error please add SI2176 code*/ + .name = "SI2176", + .frequency_min = 51000000, + .frequency_max = 860000000, + } + }; + + struct dvb_tuner_info *tinfo[] = { + &tinfo_null, + tinfo_DCT7070, + tinfo_MXL5003S, + tinfo_FJ2207, + tinfo_TD1316, + tinfo_SI2176 + }; + + if ((type < 0) || (type > 4) || (mode < 0) || (mode > 1)) + return tinfo[0]; + + return &tinfo[type][mode]; +} + +struct agc_power_tab *tuner_get_agc_power_table(int type) +{ + /*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */ + static int calcE_FJ2207[31] = { + 87, 118, 138, 154, 172, 197, 245, + 273, 292, 312, 327, 354, 406, 430, + 448, 464, 481, 505, 558, 583, 599, + 616, 632, 653, 698, 725, 745, 762, + 779, 801, 831 }; + static int calcE_Maxliner[79] = { + 543, 552, 562, 575, 586, 596, 608, + 618, 627, 635, 645, 653, 662, 668, + 678, 689, 696, 705, 715, 725, 733, + 742, 752, 763, 769, 778, 789, 800, + 807, 816, 826, 836, 844, 854, 864, + 874, 884, 894, 904, 913, 923, 932, + 942, 951, 961, 970, 980, 990, 1000, + 1012, 1022, 1031, 1040, 1049, 1059, + 1069, 1079, 1088, 1098, 1107, 1115, + 1123, 1132, 1140, 1148, 1157, 1165, + 1173, 1179, 1186, 1192, 1198, 1203, + 1208, 1208, 1214, 1217, 1218, 1220 }; + + static struct agc_power_tab power_tab[] = { + [0] = { "null", 0, 0, NULL }, + [1] = { + .name = "DCT7070", + .level = 0, + .ncalcE = 0, + .calcE = NULL, + }, + [2] = { + .name = "Maxlear", + .level = -22, + .ncalcE = sizeof(calcE_Maxliner) / sizeof(int), + .calcE = calcE_Maxliner, + }, + [3] = { + .name = "FJ2207", + .level = -62, + .ncalcE = sizeof(calcE_FJ2207) / sizeof(int), + .calcE = calcE_FJ2207, + }, + [4] = { + .name = "TD1316", + .level = 0, + .ncalcE = 0, + .calcE = NULL, + }, + }; + + if (type >= 2 && type <= 3) + return &power_tab[type]; + else + return &power_tab[3]; +}; + +int agc_power_to_dbm(int agc_gain, int ad_power, int offset, int tuner) +{ + struct agc_power_tab *ptab = tuner_get_agc_power_table(tuner); + int est_rf_power; + int j; + + for (j = 0; j < ptab->ncalcE; j++) + if (agc_gain <= ptab->calcE[j]) + break; + + est_rf_power = ptab->level - j - (ad_power >> 4) + 12 + offset; + + return est_rf_power; +} + +int dtmb_get_power_strength(int agc_gain) +{ + int strength; + int j; + static int calcE_R840[13] = { + 1010, 969, 890, 840, 800, + 760, 720, 680, 670, 660, + 510, 440, 368}; + for (j = 0; j < sizeof(calcE_R840)/sizeof(int); j++) + if (agc_gain >= calcE_R840[j]) + break; + if (agc_gain >= 440) + strength = -90+j*3; + else + strength = -56; + return strength; +} + + diff --git a/include/uapi/linux/dvb/aml_demod.h b/include/uapi/linux/dvb/aml_demod.h new file mode 100644 index 0000000..342e690 --- /dev/null +++ b/include/uapi/linux/dvb/aml_demod.h @@ -0,0 +1,223 @@ +#ifndef AML_DEMOD_H +#define AML_DEMOD_H +#ifndef CONFIG_AM_DEMOD_FPGA_VER +#define CONFIG_AM_DEMOD_FPGA_VER +#endif /*CONFIG_AM_DEMOD_FPGA_VER */ + +/*#include */ +#define u8_t u8 +#define u16_t u16 +#define u32_t u32 +#define u64_t u64 +#include + +struct aml_demod_i2c { + u8_t tuner; /*type */ + u8_t addr; /*slave addr */ + u32_t scl_oe; + u32_t scl_out; + u32_t scl_in; + u8_t scl_bit; + u32_t sda_oe; + u32_t sda_out; + u32_t sda_in; + u8_t sda_bit; + u8_t udelay; /*us */ + u8_t retries; + u8_t debug; /*1:debug */ + u8_t tmp; /*spare */ + u8_t i2c_id; + void *i2c_priv; +}; + +struct aml_tuner_sys { + u8_t mode; + u8_t amp; + u8_t if_agc_speed; + u32_t ch_freq; + u32_t if_freq; + u32_t rssi; + u32_t delay; + u8_t bandwidth; +}; + +struct aml_demod_sys { + u8_t clk_en; /* 1:on */ + u8_t clk_src; /*2 bits */ + u8_t clk_div; /*7 bits */ + u8_t pll_n; /*5 bits */ + u16_t pll_m; /*9 bits */ + u8_t pll_od; /*7 bits */ + u8_t pll_sys_xd; /*5 bits */ + u8_t pll_adc_xd; /*5 bits */ + u8_t agc_sel; /*pin mux */ + u8_t adc_en; /*1:on */ + u8_t debug; /*1:debug */ + u32_t i2c; /*pointer */ + u32_t adc_clk; + u32_t demod_clk; +}; + +struct aml_demod_sts { + u32_t ch_sts; + u32_t freq_off; /*Hz */ + u32_t ch_pow; + u32_t ch_snr; + u32_t ch_ber; + u32_t ch_per; + u32_t symb_rate; + u32_t dat0; + u32_t dat1; +}; + +struct aml_demod_sta { + u8_t clk_en; /*on/off */ + u8_t adc_en; /*on/off */ + u32_t clk_freq; /*kHz */ + u32_t adc_freq; /*kHz */ + u8_t dvb_mode; /*dvb-t/c mode */ + u8_t ch_mode; /* 16,32,..,256QAM or 2K,4K,8K */ + u8_t agc_mode; /*if, rf or both. */ + u8_t tuner; /*type */ + u32_t ch_freq; /*kHz */ + u16_t ch_if; /*kHz */ + u16_t ch_bw; /*kHz */ + u16_t symb_rate; /*kHz */ + u8_t debug; + u8_t tmp; + u32_t sts; /*pointer */ + u8_t spectrum; +}; + +struct aml_demod_dvbc { + u8_t mode; + u8_t tmp; + u16_t symb_rate; + u32_t ch_freq; + u32_t dat0; + u32_t dat1; +}; + +struct aml_demod_dvbt { + u8_t bw; + u8_t sr; + u8_t ifreq; + u8_t agc_mode; + u32_t ch_freq; + u32_t dat0; + u32_t dat1; + u32_t layer; + +}; + +struct aml_demod_dtmb { + u8_t bw; + u8_t sr; + u8_t ifreq; + u8_t agc_mode; + u32_t ch_freq; + u32_t dat0; + u32_t dat1; + u32_t mode; + +}; + +struct aml_demod_atsc { + u8_t bw; + u8_t sr; + u8_t ifreq; + u8_t agc_mode; + u32_t ch_freq; + u32_t dat0; + u32_t dat1; + u32_t mode; + +}; + +struct aml_demod_mem { + u32_t addr; + u32_t dat; + +}; + +struct aml_cap_data { + u32_t cap_addr; + u32_t cap_size; + u32_t cap_afifo; + char *cap_dev_name; +}; + +struct aml_demod_reg { + u8_t mode; + u8_t rw; /* 0: read, 1: write. */ + u32_t addr; + u32_t val; +/* u32_t val_high;*/ +}; + +struct aml_demod_regs { + u8_t mode; + u8_t rw; /* 0: read, 1: write. */ + u32_t addr; + u32_t addr_len; + u32_t n; + u32_t vals[1]; /*[mode i2c]: write:n*u32_t, read:n*u8_t */ +}; +struct fpga_m1_sdio { + unsigned long addr; + unsigned long byte_count; + unsigned char *data_buf; +}; + +struct aml_demod_para { + u32_t dvbc_symbol; + u32_t dvbc_qam; + u32_t dtmb_qam; + u32_t dtmb_coderate; +}; + + +#define AML_DEMOD_SET_SYS _IOW('D', 0, struct aml_demod_sys) +#define AML_DEMOD_GET_SYS _IOR('D', 1, struct aml_demod_sys) +#define AML_DEMOD_TEST _IOR('D', 2, u32_t) +#define AML_DEMOD_TURN_ON _IOR('D', 3, u32_t) +#define AML_DEMOD_TURN_OFF _IOR('D', 4, u32_t) +#define AML_DEMOD_SET_TUNER _IOW('D', 5, struct aml_tuner_sys) +#define AML_DEMOD_GET_RSSI _IOR('D', 6, struct aml_tuner_sys) + +#define AML_DEMOD_DVBC_SET_CH _IOW('D', 10, struct aml_demod_dvbc) +#define AML_DEMOD_DVBC_GET_CH _IOR('D', 11, struct aml_demod_dvbc) +#define AML_DEMOD_DVBC_TEST _IOR('D', 12, u32_t) + +#define AML_DEMOD_DVBT_SET_CH _IOW('D', 20, struct aml_demod_dvbt) +#define AML_DEMOD_DVBT_GET_CH _IOR('D', 21, struct aml_demod_dvbt) +#define AML_DEMOD_DVBT_TEST _IOR('D', 22, u32_t) + +#define AML_DEMOD_DTMB_SET_CH _IOW('D', 50, struct aml_demod_dtmb) +#define AML_DEMOD_DTMB_GET_CH _IOR('D', 51, struct aml_demod_dtmb) +#define AML_DEMOD_DTMB_TEST _IOR('D', 52, u32_t) + +#define AML_DEMOD_ATSC_SET_CH _IOW('D', 60, struct aml_demod_atsc) +#define AML_DEMOD_ATSC_GET_CH _IOR('D', 61, struct aml_demod_atsc) +#define AML_DEMOD_ATSC_TEST _IOR('D', 62, u32_t) +#define AML_DEMOD_ATSC_IRQ _IOR('D', 63, u32_t) + +#define AML_DEMOD_RESET_MEM _IOR('D', 70, u32_t) +#define AML_DEMOD_READ_MEM _IOR('D', 71, u32_t) +#define AML_DEMOD_SET_MEM _IOR('D', 72, struct aml_demod_mem) + +#define AML_DEMOD_SET_REG _IOW('D', 30, struct aml_demod_reg) +#define AML_DEMOD_GET_REG _IOR('D', 31, struct aml_demod_reg) +/* #define AML_DEMOD_SET_REGS _IOW('D', 32, struct aml_demod_regs)*/ +/*#define AML_DEMOD_GET_REGS _IOR('D', 33, struct aml_demod_regs)*/ +#define FPGA2M1_SDIO_WR_DDR _IOW('D', 40, struct fpga_m1_sdio) +#define FPGA2M1_SDIO_RD_DDR _IOR('D', 41, struct fpga_m1_sdio) +#define FPGA2M1_SDIO_INIT _IO('D', 42) +#define FPGA2M1_SDIO_EXIT _IO('D', 43) + +int read_memory_to_file(struct aml_cap_data *cap); +int read_reg(int addr); +void wait_capture(int cap_cur_addr, int depth_MB, int start); +int cap_adc_data(struct aml_cap_data *cap); + +#endif /* AML_DEMOD_H */ -- 2.7.4