dtv_demod: add dtv demod for txlx
authorJihong Sui <jihong.sui@amlogic.com>
Sat, 28 Apr 2018 04:51:24 +0000 (12:51 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Fri, 4 May 2018 10:37:40 +0000 (03:37 -0700)
PD#165005: dtv_demod: add dtv demod for txlx

Change-Id: I311fea46351644902a5e886be4623601e21ec6ac
Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>
35 files changed:
MAINTAINERS
arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts
arch/arm64/configs/meson64_defconfig
drivers/amlogic/media/Kconfig
drivers/amlogic/media/Makefile
drivers/amlogic/media/amldemod/Kconfig [new file with mode: 0644]
drivers/amlogic/media/amldemod/Makefile [new file with mode: 0644]
drivers/amlogic/media/amldemod/aml_demod.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/amlfrontend.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/atsc_func.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/demod_func.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/dtmb_func.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/dvbc_func.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/dvbc_v2.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/dvbc_v3.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/dvbt_v2.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/i2c_func.c [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/acf_filter_coefficient.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_che.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_che_bit.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_front.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_front_bit.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_sync.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_sync_bit.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_top.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/addr_dtmb_top_bit.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/amlfrontend.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/atsc_func.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/demod_func.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/include/depend.h [new file with mode: 0644]
drivers/amlogic/media/amldemod/tuner_func.c [new file with mode: 0644]
include/uapi/linux/dvb/aml_demod.h [new file with mode: 0644]

index f8cc6fb..ef4bc99 100644 (file)
@@ -14437,3 +14437,8 @@ M:      Weiming Liu <weiming.liu@amlogic.com>
 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 <jihong.sui@amlogic.com>
+F:      include/uapi/linux/dvb/aml_demod.h
+F:      drivers/amlogic/media/aml_demod/*
+
index 2c955fb..c031611 100644 (file)
                //              &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";
index 33f92d2..dd090f9 100644 (file)
                //              &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";
index d1f7e44..4b326c2 100644 (file)
                //              &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";
index a663a8b..0348d96 100644 (file)
                //              &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";
index 296368a..6dc65e6 100644 (file)
@@ -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
index 009b3bb..1c7758f 100644 (file)
@@ -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
index 5a884df..e22a933 100644 (file)
@@ -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 (file)
index 0000000..9ca4aa3
--- /dev/null
@@ -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 (file)
index 0000000..272531f
--- /dev/null
@@ -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 (file)
index 0000000..c9cf7f1
--- /dev/null
@@ -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 <linux/init.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/major.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/ctype.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+/* #include <mach/am_regs.h> */
+#include <linux/device.h>
+#include <linux/cdev.h>
+
+/* #include <asm/fiq.h> */
+#include <linux/uaccess.h>
+#include <linux/dvb/aml_demod.h>
+#include "demod_func.h"
+
+#include <linux/slab.h>
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#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 (file)
index 0000000..42e02e2
--- /dev/null
@@ -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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/err.h> /*IS_ERR*/
+#include <linux/clk.h> /*clk tree*/
+#include <linux/of_device.h>
+
+
+#ifdef ARC_700
+#include <asm/arch/am_regs.h>
+#else
+/* #include <mach/am_regs.h> */
+#endif
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+
+#include <linux/dvb/aml_demod.h>
+#include "demod_func.h"
+
+#include "depend.h" /**/
+
+#include "amlfrontend.h"
+
+/*dma_get_cma_size_int_byte*/
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/dma-contiguous.h>
+
+#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+
+
+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(&param, 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(&param, 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(&param, 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,*/ &param);
+       /*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(&param, 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,*/ &param);
+
+
+       /*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(&param_atsc, 0, sizeof(param_atsc));
+       memset(&param_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, */&param_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,*/ &param_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,*/
+                       &param_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,*/
+                               &param_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,*/
+                       &param_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(&param, 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,*/ &param);
+
+       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 (file)
index 0000000..e2d4fef
--- /dev/null
@@ -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 <linux/dvb/aml_demod.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+
+/* 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 (file)
index 0000000..fe0acc6
--- /dev/null
@@ -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 <linux/dvb/aml_demod.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+/*#include "acf_filter_coefficient.h"*/
+#include <linux/mutex.h>
+
+
+#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+
+
+#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 (file)
index 0000000..efb0b7d
--- /dev/null
@@ -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 (file)
index 0000000..95fbda6
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/dvb/aml_demod.h>
+#include "demod_func.h"
+#include <linux/kthread.h>
+
+/*#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 (file)
index 0000000..fb5cd74
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#include <linux/dvb/aml_demod.h>
+
+#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 (file)
index 0000000..74a8316
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/dvb/aml_demod.h>
+#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 (file)
index 0000000..bfb1f30
--- /dev/null
@@ -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 <linux/dvb/aml_demod.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include "acf_filter_coefficient.h"
+#include <linux/mutex.h>
+
+#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 (file)
index 0000000..2e7a491
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/dvb/aml_demod.h>
+#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 (file)
index 0000000..858386f
--- /dev/null
@@ -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 (file)
index 0000000..2e6af63
--- /dev/null
@@ -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 (file)
index 0000000..54c9098
--- /dev/null
@@ -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 (file)
index 0000000..0ee9482
--- /dev/null
@@ -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 (file)
index 0000000..327a188
--- /dev/null
@@ -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 (file)
index 0000000..5ede848
--- /dev/null
@@ -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 (file)
index 0000000..c29ee31
--- /dev/null
@@ -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 (file)
index 0000000..1ad8a34
--- /dev/null
@@ -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 (file)
index 0000000..ac26d92
--- /dev/null
@@ -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 (file)
index 0000000..c00af73
--- /dev/null
@@ -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 (file)
index 0000000..d0597d1
--- /dev/null
@@ -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 (file)
index 0000000..109eecf
--- /dev/null
@@ -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 <linux/types.h>
+
+#include <linux/dvb/aml_demod.h>
+/*#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 <linux/io.h>
+#include <linux/jiffies.h>
+#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 (file)
index 0000000..680f725
--- /dev/null
@@ -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 <linux/device.h>      /**/
+
+
+extern void vdac_enable(bool on, unsigned int module_sel);
+
+/*dma_alloc_from_contiguous*/
+struct page *aml_dma_alloc_contiguous(struct device *dev, int count,
+                                               unsigned int order);
+/*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 (file)
index 0000000..55383bd
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/dvb/aml_demod.h>
+#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 (file)
index 0000000..342e690
--- /dev/null
@@ -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 <linux/types.h>*/
+#define u8_t u8
+#define u16_t u16
+#define u32_t u32
+#define u64_t u64
+#include <linux/amlogic/cpu_version.h>
+
+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 */