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/*
+
// &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";
// &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";
// &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";
// &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";
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
source "drivers/amlogic/media/video_processor/Kconfig"
source "drivers/amlogic/media/enhancement/Kconfig"
endif
-
+source "drivers/amlogic/media/amldemod/Kconfig"
endmenu
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/
--- /dev/null
+#
+# 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
+
--- /dev/null
+
+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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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(¶m, 0, sizeof(param));
+ param.mode = amdemod_qam(c->modulation);
+ dvbc_set_qam_mode(param.mode);
+ return 0;
+}
+static int aml_dtvdm_set_qam_mode(struct dvb_frontend *fe)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+ int ret = 0;
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_set_qam_mode(fe);
+ break;
+ case AM_FE_OFDM_N:
+
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_set_qam_mode(fe);
+ break;
+ case AM_FE_DTMB_N:
+
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+
+ return ret;
+}
+static int gxtv_demod_atsc_set_qam_mode(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct aml_demod_atsc param; /*mode 3:64, 5:256, 7:vsb*/
+ enum fe_modulation mode;
+
+ memset(¶m, 0, sizeof(param));
+ mode = c->modulation;
+ /*pr_dbg("mode is %d\n", mode);*/
+ PR_ATSC("mode is %d\n", mode);
+ atsc_qam_set(mode);
+ return 0;
+}
+
+#endif
+static void gxtv_demod_dvbc_release(struct dvb_frontend *fe)
+{
+
+}
+#if 0
+static int gxtv_demod_dvbc_read_status
+ (struct dvb_frontend *fe, enum fe_status *status)
+{
+/* struct aml_fe_dev *dev = afe->dtv_demod;*/
+ struct aml_demod_sts demod_sts;
+ struct aml_demod_sta demod_sta;
+ /*struct aml_demod_i2c demod_i2c;*/
+ int ilock;
+
+ /*demod_sts.ch_sts = qam_read_reg(0x6);*/
+ demod_sts.ch_sts = dvbc_get_ch_sts();
+ dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts);
+ if (demod_sts.ch_sts & 0x1) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ } else {
+ ilock = 0;
+ *status = FE_TIMEDOUT;
+ }
+ if (last_lock != ilock) {
+ PR_DBG("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+
+ return 0;
+}
+#endif
+struct timer_t {
+ int enable;
+ unsigned int start;
+ unsigned int max;
+};
+static struct timer_t gtimer;
+
+int timer_set_max(unsigned int max_val)
+{
+ gtimer.max = max_val;
+ return 0;
+}
+int timer_begain(void)
+{
+ gtimer.start = jiffies_to_msecs(jiffies);
+ gtimer.enable = 1;
+
+ PR_DBG("st=%d\n", gtimer.start);
+ return 0;
+}
+int timer_not_enough(void)
+{
+ int ret = 0;
+ unsigned int time;
+
+ if (gtimer.enable) {
+ time = jiffies_to_msecs(jiffies);
+ if ((time - gtimer.start) < gtimer.max) {
+ PR_DBG("now=%d\n", time);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+int timer_tuner_not_enough(void)
+{
+ int ret = 0;
+ unsigned int time;
+
+ if (gtimer.enable) {
+ time = jiffies_to_msecs(jiffies);
+ if ((time - gtimer.start) < 200) {
+ PR_DBG("nowt=%d\n", time);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+
+static int gxtv_demod_dvbc_read_status_timer
+ (struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct aml_demod_sts demod_sts;
+ struct aml_demod_sta demod_sta;
+ int strenth;
+
+ int ilock;
+
+ /*check tuner*/
+ if (!timer_tuner_not_enough()) {
+ strenth = tuner_get_ch_power(fe)-256;
+ if (strenth < -85) {
+ *status = FE_TIMEDOUT;
+ return 0;
+ }
+ }
+ /*demod_sts.ch_sts = qam_read_reg(0x6);*/
+ demod_sts.ch_sts = dvbc_get_ch_sts();
+ dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts);
+ if (demod_sts.ch_sts & 0x1) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ } else {
+ ilock = 0;
+
+ if (timer_not_enough()) {
+ *status = 0;
+ PR_DBG("s=0\n");
+ } else {
+ *status = FE_TIMEDOUT;
+ }
+ }
+ if (last_lock != ilock) {
+ PR_DBG("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+
+ return 0;
+}
+
+static int gxtv_demod_dvbc_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ /*struct aml_fe_dev *dev = afe->dtv_demod;*/
+ struct aml_demod_sts demod_sts;
+ /*struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+
+ dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts);
+ *ber = demod_sts.ch_ber;
+ return 0;
+}
+
+static int gxtv_demod_dvbc_read_signal_strength
+ (struct dvb_frontend *fe, u16 *strength)
+{
+ int tn_strength = 0;
+
+#if 0
+ if (fe->ops.tuner_ops.get_strength)
+ tn_strength = fe->ops.tuner_ops.get_strength(fe);
+#else
+ tn_strength = tuner_get_ch_power2();
+#endif
+ *strength = 256 - tn_strength;
+ return 0;
+}
+
+static int gxtv_demod_dvbc_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct aml_demod_sts demod_sts;
+ /*struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+
+ dvbc_status(&demod_sta, /*&demod_i2c,*/ &demod_sts);
+ *snr = demod_sts.ch_snr / 100;
+ return 0;
+}
+
+static int gxtv_demod_dvbc_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ *ucblocks = 0;
+ return 0;
+}
+
+/*extern int aml_fe_analog_set_frontend(struct dvb_frontend *fe);*/
+
+static int gxtv_demod_dvbc_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct aml_demod_dvbc param; /*mode 0:16, 1:32, 2:64, 3:128, 4:256*/
+ struct aml_demod_sts demod_sts;
+
+ PR_INFO("%s\n", __func__);
+ timer_set_max(4000);
+ timer_begain();
+
+ memset(¶m, 0, sizeof(param));
+ param.ch_freq = c->frequency / 1000;
+ param.mode = amdemod_qam(c->modulation);
+ param.symb_rate = c->symbol_rate / 1000;
+ store_dvbc_qam_mode(c->modulation, param.symb_rate);
+ if ((param.mode == 3) && (demod_status.tmp != Adc_mode)) {
+ Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode);
+ /*pr_dbg("Gxtv_Demod_Dvbc_Init,Adc_mode\n");*/
+ } else {
+ /*Gxtv_Demod_Dvbc_Init(dev,Cry_mode);*/
+ }
+ if (autoflags == 0) {
+ /*pr_dbg("QAM_TUNING mode\n");*/
+ /*flag=0;*/
+ }
+ if ((autoflags == 1) && (autoFlagsTrig == 0)
+ && (freq_dvbc == param.ch_freq)) {
+ PR_DBG("now is auto symbrating\n");
+ return 0;
+ }
+ autoFlagsTrig = 0;
+ last_lock = -1;
+ PR_DBG("[gxtv_demod_dvbc_set_frontend]PARA\t"
+ "param.ch_freq is %d||||param.symb_rate is %d,\t"
+ "param.mode is %d\n",
+ param.ch_freq, param.symb_rate, param.mode);
+ tuner_set_params(fe);/*aml_fe_analog_set_frontend(fe);*/
+ dvbc_set_ch(&demod_status, /*&demod_i2c,*/ ¶m);
+ /*0xf33 dvbc mode, 0x10f33 j.83b mode*/
+ #if 0
+ if (is_meson_txlx_cpu() || is_meson_gxlx_cpu())
+ /*qam_write_reg(0x7, 0xf33);*/
+ dvbc_init_reg_ext();
+ #endif
+ if (is_dvbc_ver(IC_DVBC_V3))
+ dvbc_init_reg_ext();
+
+ if (autoflags == 1) {
+ PR_DBG("QAM_PLAYING mode,start auto sym\n");
+ dvbc_set_auto_symtrack();
+ /* flag=1;*/
+ }
+ dvbc_status(&demod_status, /*&demod_i2c,*/ &demod_sts);
+ freq_dvbc = param.ch_freq;
+
+ PR_DBG("AML amldemod => frequency=%d,symbol_rate=%d\r\n", c->frequency,
+ c->symbol_rate);
+ return 0;
+}
+
+static int gxtv_demod_dvbc_get_frontend(struct dvb_frontend *fe)
+{ /*these content will be writed into eeprom .*/
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 qam_mode;
+
+
+ qam_mode = dvbc_get_qam_mode();
+ c->modulation = qam_mode + 1;
+ PR_DBG("[mode] is %d\n", c->modulation);
+
+ return 0;
+}
+
+static int Gxtv_Demod_Dvbc_Init(/*struct aml_fe_dev *dev, */int mode)
+{
+ struct aml_demod_sys sys;
+ /*struct aml_demod_i2c i2c;*/
+
+ PR_DBG("%s\n", __func__);
+ memset(&sys, 0, sizeof(sys));
+ /*memset(&i2c, 0, sizeof(i2c));*/
+ /*i2c.tuner = dev->drv->id;*/
+ /*i2c.addr = dev->i2c_addr;*/
+ /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/
+ demod_status.dvb_mode = Gxtv_Dvbc;
+
+ if (mode == Adc_mode) {
+ sys.adc_clk = Adc_Clk_25M;
+ sys.demod_clk = Demod_Clk_200M;
+ demod_status.tmp = Adc_mode;
+ } else {
+ sys.adc_clk = Adc_Clk_24M;
+ sys.demod_clk = Demod_Clk_72M;
+ demod_status.tmp = Cry_mode;
+ }
+ demod_status.ch_if = Si2176_5M_If * 1000;
+ PR_DBG("[%s]adc_clk is %d,demod_clk is %d\n", __func__, sys.adc_clk,
+ sys.demod_clk);
+ autoFlagsTrig = 0;
+ /*demod_set_sys(&demod_status, &i2c, &sys);*/
+ demod_set_sys(&demod_status, &sys);
+ demod_mode_para = AML_DVBC;
+ return 0;
+}
+
+static void gxtv_demod_dvbt_release(struct dvb_frontend *fe)
+{
+
+}
+
+static int gxtv_demod_dvbt_read_status
+ (struct dvb_frontend *fe, enum fe_status *status)
+{
+/* struct aml_fe *afe = fe->demodulator_priv;*/
+ /*struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+ int ilock;
+ unsigned char s = 0;
+
+ s = dvbt_get_status_ops()->get_status(&demod_sta/*, &demod_i2c*/);
+ if (s == 1) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ } else {
+ if (timer_not_enough()) {
+ ilock = 0;
+ *status = 0;
+ PR_INFO("timer not enough\n");
+
+ } else {
+ ilock = 0;
+ *status = FE_TIMEDOUT;
+ }
+ }
+ if (last_lock != ilock) {
+ PR_INFO("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+
+ return 0;
+}
+
+static int gxtv_demod_dvbt_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+/* struct aml_fe *afe = fe->demodulator_priv;*/
+ /*struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+
+ *ber = dvbt_get_status_ops()->get_ber(&demod_sta) & 0xffff;
+ return 0;
+}
+
+static int gxtv_demod_dvbt_read_signal_strength
+ (struct dvb_frontend *fe, u16 *strength)
+{
+ /*struct aml_fe *afe = fe->demodulator_priv;*/
+ /*struct aml_fe_dev *dev = afe->dtv_demod;*/
+
+ *strength = 256 - tuner_get_ch_power(fe);
+ PR_DBGL("[RSJ]tuner strength is %d dbm\n", *strength);
+ return 0;
+}
+
+static int gxtv_demod_dvbt_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+/* struct aml_fe *afe = fe->demodulator_priv;*/
+/* struct aml_demod_sts demod_sts;*/
+/* struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+
+ *snr = dvbt_get_status_ops()->get_snr(&demod_sta/*, &demod_i2c*/);
+ *snr /= 8;
+ PR_DBGL("[RSJ]snr is %d dbm\n", *snr);
+ return 0;
+}
+
+static int gxtv_demod_dvbt_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ *ucblocks = 0;
+ return 0;
+}
+int convert_bandwidth(unsigned int input)
+{
+ /*int output;*/
+ enum fe_bandwidth output;
+
+ output = 3;
+ switch (input) {
+ case 10000000:
+ output = BANDWIDTH_10_MHZ;
+ break;
+ case 8000000:
+ output = BANDWIDTH_8_MHZ;
+ break;
+ case 7000000:
+ output = BANDWIDTH_7_MHZ;
+ break;
+ case 6000000:
+ output = BANDWIDTH_6_MHZ;
+ break;
+ case 5000000:
+ output = BANDWIDTH_5_MHZ;
+ break;
+ case 1712000:
+ output = BANDWIDTH_1_712_MHZ;
+ break;
+ case 0:
+ output = BANDWIDTH_AUTO;
+ break;
+ }
+ return output;
+
+
+}
+
+static int gxtv_demod_dvbt_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ /*struct aml_demod_sts demod_sts;*/
+ struct aml_demod_dvbt param;
+
+ timer_set_max(1000);
+ timer_begain();
+
+ /*////////////////////////////////////*/
+ /* bw == 0 : 8M*/
+ /* 1 : 7M*/
+ /* 2 : 6M*/
+ /* 3 : 5M*/
+ /* agc_mode == 0: single AGC*/
+ /* 1: dual AGC*/
+ /*////////////////////////////////////*/
+ memset(¶m, 0, sizeof(param));
+ param.ch_freq = c->frequency / 1000;
+
+ //param.bw = c->bandwidth_hz;
+ param.bw = convert_bandwidth(c->bandwidth_hz);
+ PR_INFO("%s:bw=%d\n", __func__, c->bandwidth_hz);
+ param.agc_mode = 1;
+ /*ISDBT or DVBT : 0 is QAM, 1 is DVBT, 2 is ISDBT,*/
+ /* 3 is DTMB, 4 is ATSC */
+ param.dat0 = 1;
+ last_lock = -1;
+
+ tuner_set_params(fe);/*aml_fe_analog_set_frontend(fe);*/
+ dvbt_set_ch(&demod_status, /*&demod_i2c,*/ ¶m);
+
+
+ /*pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n",*/
+ /* p->frequency,p->u.qam.symbol_rate);*/
+ return 0;
+}
+
+static int gxtv_demod_dvbt_get_frontend(struct dvb_frontend *fe)
+{ /*these content will be writed into eeprom .*/
+
+ return 0;
+}
+
+/*int Gxtv_Demod_Dvbt_Init(struct aml_fe_dev *dev)*/
+int Gxtv_Demod_Dvbt_Init(void)
+{
+ struct aml_demod_sys sys;
+
+ PR_DBG("AML Demod DVB-T init\r\n");
+
+ memset(&sys, 0, sizeof(sys));
+
+ memset(&demod_status, 0, sizeof(demod_status));
+
+ /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/
+ demod_status.dvb_mode = Gxtv_Dvbt_Isdbt;
+ sys.adc_clk = Adc_Clk_24M;
+ sys.demod_clk = Demod_Clk_60M;
+ demod_status.ch_if = Si2176_5M_If * 1000;
+
+ demod_set_sys(&demod_status, &sys);
+ demod_mode_para = AML_DVBT;
+ return 0;
+}
+
+static void gxtv_demod_atsc_release(struct dvb_frontend *fe)
+{
+
+}
+
+
+static int gxtv_demod_atsc_get_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_HW;
+}
+static int gxtv_demod_txlx_get_frontend_algo(struct dvb_frontend *fe)
+{
+
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = DVBFE_ALGO_SW;
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+ break;
+
+ case AM_FE_QAM_N:
+ /*dvbc*/
+
+ break;
+ case AM_FE_OFDM_N:
+ /*dvbt*/
+
+ break;
+ case AM_FE_ISDBT_N:
+
+ break;
+ case AM_FE_ATSC_N:
+ ret = DVBFE_ALGO_HW;
+ break;
+ case AM_FE_DTMB_N:
+ ret = DVBFE_ALGO_HW;
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+
+ return ret;
+
+}
+
+unsigned int ats_thread_flg;
+static int gxtv_demod_atsc_read_status
+ (struct dvb_frontend *fe, enum fe_status *status)
+{
+
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct aml_demod_sts demod_sts;
+ /*struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+ int ilock;
+ struct dvb_frontend *dvbfe;
+ unsigned char s = 0;
+ int strength = 0;
+
+ /*debug only*/
+ static enum fe_status dbg_lst_status; /* last status */
+
+
+ if (!demod_thread) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ return 0;
+ }
+ if (!get_dtvpll_init_flag())
+ return 0;
+
+ if ((c->modulation <= QAM_AUTO) && (c->modulation != QPSK)
+ && (atsc_flag == QAM_AUTO)) {
+ s = amdemod_dvbc_stat_islock();
+ dvbc_status(&demod_sta,/* &demod_i2c, */&demod_sts);
+ } else if ((c->modulation > QAM_AUTO)
+ && (atsc_flag == VSB_8)) {
+ /*atsc_thread();*/
+ s = amdemod_atsc_stat_islock();
+ if ((s == 0) && (last_lock == 1)
+ && (atsc_read_reg(0x0980) >= 0x76)) {
+ s = 1;
+ PR_ATSC("[rsj] unlock,but fsm >= 0x76\n");
+ }
+ }
+#if 0 /*debug only move to end*/
+ dvbfe = get_si2177_tuner();
+ if (dvbfe != NULL)
+ if (dvbfe->ops.tuner_ops.get_strength) {
+ strength =
+ dvbfe->ops.tuner_ops.get_strength(dvbfe);
+ }
+ /*strength -= 100;*/
+ pr_dbg("[rsj_test]freq[%d] strength[%d]\n", freq_p, strength);
+#endif
+ if (s == 1) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ } else {
+ ilock = 0;
+
+ /* *status = FE_TIMEDOUT; */
+ if (ats_thread_flg)
+ *status = FE_TIMEDOUT;
+ else
+ *status = 0;
+
+ }
+#if 0 /*debug only*/
+ if (last_lock != ilock) {
+ pr_error("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+#endif
+ /*debug only*/
+ if (aml_demod_debug & DBG_ATSC) {
+ if ((dbg_lst_status != s) || (last_lock != ilock)) {
+ /* check tuner */
+ dvbfe = aml_get_fe();/*get_si2177_tuner();*/
+ if (dvbfe != NULL) {
+#if 0
+ if (dvbfe->ops.tuner_ops.get_strength) {
+ strength =
+ dvbfe->ops.tuner_ops.get_strength(dvbfe);
+ }
+#else
+ strength = tuner_get_ch_power2();
+#endif
+ strength -= 100;
+ }
+
+ PR_ATSC("s=%d(1 is lock),lock=%d\n", s, ilock);
+ PR_ATSC("[rsj_test]freq[%d] strength[%d]\n",
+ freq_p, strength);
+
+ /*update */
+ dbg_lst_status = s;
+ last_lock = ilock;
+ }
+ /*aml_dbgatscl(".");*/
+ }
+ return 0;
+}
+
+static int gxtv_demod_atsc_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (!get_dtvpll_init_flag())
+ return 0;
+ if ((c->modulation > QAM_AUTO)
+ && (atsc_flag == VSB_8))
+ *ber = atsc_read_reg(0x980)&0xffff;
+ else if (((c->modulation == QAM_256)
+ || (c->modulation == QAM_64))
+ && (atsc_flag == QAM_AUTO))
+
+ *ber = dvbc_get_status();
+ return 0;
+}
+
+static int gxtv_demod_atsc_read_signal_strength
+ (struct dvb_frontend *fe, u16 *strength)
+{
+/* struct aml_fe *afe = fe->demodulator_priv;*/
+ /*struct aml_fe_dev *dev = afe->dtv_demod; */
+ int read_strength;
+
+ read_strength = tuner_get_ch_power(fe);
+ /*read_strength -= 100;*/
+ if (read_strength < -100)
+ *strength = 0;
+ else
+ *strength = (100 + read_strength);
+ /*pr_dbg("[read_strength]read_strength is %d,*strength is %d\n",*/
+ /* read_strength, *strength);*/
+ if (*strength < 0)
+ *strength = 0;
+ else if (*strength > 100)
+ *strength = 100;
+ return 0;
+}
+
+static int gxtv_demod_atsc_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct aml_demod_sts demod_sts;
+ /*struct aml_demod_i2c demod_i2c;*/
+ struct aml_demod_sta demod_sta;
+
+ if ((c->modulation <= QAM_AUTO)
+ && (c->modulation != QPSK)
+ && (atsc_flag == QAM_AUTO)) {
+ dvbc_status(&demod_sta, /*&demod_i2c, */&demod_sts);
+ *snr = demod_sts.ch_snr / 100;
+ } else if ((c->modulation > QAM_AUTO)
+ && (atsc_flag == VSB_8))
+ *snr = atsc_read_snr();
+ return 0;
+}
+
+static int gxtv_demod_atsc_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (!demod_thread)
+ return 0;
+ if ((c->modulation > QAM_AUTO)
+ && (atsc_flag == VSB_8))
+ atsc_thread();
+ *ucblocks = 0;
+ return 0;
+}
+
+static int gxtv_demod_atsc_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct aml_demod_atsc param_atsc;
+ struct aml_demod_dvbc param_j83b;
+ int temp_freq = 0;
+
+ memset(¶m_atsc, 0, sizeof(param_atsc));
+ memset(¶m_j83b, 0, sizeof(param_j83b));
+ if (!demod_thread)
+ return 0;
+ freq_p = c->frequency / 1000;
+ PR_INFO("c->modulation is %d,freq_p is %d, atsc_flag is %d\n",
+ c->modulation, freq_p, atsc_flag);
+ last_lock = -1;
+ atsc_mode = c->modulation;
+ /* param.mode = amdemod_qam(p->u.vsb.modulation);*/
+ tuner_set_params(fe);/*aml_fe_analog_set_frontend(fe);*/
+ if ((c->modulation <= QAM_AUTO) && (c->modulation != QPSK)) {
+ if (atsc_flag != QAM_AUTO)
+ atsc_flag = QAM_AUTO;
+ /* demod_set_demod_reg(0x502, TXLX_ADC_REG6);*/
+ dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x502);
+ demod_set_mode_ts(Gxtv_Dvbc);
+ param_j83b.ch_freq = c->frequency / 1000;
+ param_j83b.mode = amdemod_qam(c->modulation);
+ if (c->modulation == QAM_64)
+ param_j83b.symb_rate = 5057;
+ else if (c->modulation == QAM_256)
+ param_j83b.symb_rate = 5361;
+ else
+ param_j83b.symb_rate = 5361;
+ dvbc_set_ch(&demod_status, /*&demod_i2c, */¶m_j83b);
+ } else if (c->modulation > QAM_AUTO) {
+ if (atsc_flag != VSB_8)
+ atsc_flag = VSB_8;
+ /*demod_set_demod_reg(0x507, TXLX_ADC_REG6);*/
+ dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x507);
+ demod_set_mode_ts(Gxtv_Atsc);
+ param_atsc.ch_freq = c->frequency / 1000;
+ param_atsc.mode = c->modulation;
+ atsc_set_ch(&demod_status, /*&demod_i2c,*/ ¶m_atsc);
+ }
+ if ((auto_search_std == 1) && ((c->modulation <= QAM_AUTO)
+ && (c->modulation != QPSK))) {
+ unsigned char s = 0;
+
+ msleep(std_lock_timeout);
+ s = amdemod_dvbc_stat_islock();
+ if (s == 1) {
+ PR_DBG("atsc std mode is %d locked\n", atsc_mode);
+
+ return 0;
+ }
+ if ((c->frequency == 79000000) || (c->frequency == 85000000)) {
+ temp_freq = (c->frequency + 2000000) / 1000;
+ param_j83b.ch_freq = temp_freq;
+ PR_DBG("irc fre:%d\n", param_j83b.ch_freq);
+ c->frequency = param_j83b.ch_freq * 1000;
+
+
+ tuner_set_params(fe);
+ demod_set_mode_ts(Gxtv_Dvbc);
+ param_j83b.mode = amdemod_qam(c->modulation);
+ if (c->modulation == QAM_64)
+ param_j83b.symb_rate = 5057;
+ else if (c->modulation == QAM_256)
+ param_j83b.symb_rate = 5361;
+ else
+ param_j83b.symb_rate = 5361;
+ dvbc_set_ch(&demod_status, /*&demod_i2c,*/
+ ¶m_j83b);
+
+ msleep(std_lock_timeout);
+ s = amdemod_dvbc_stat_islock();
+ if (s == 1) {
+ PR_DBG("irc mode is %d locked\n", atsc_mode);
+ } else {
+ temp_freq = (c->frequency - 1250000) / 1000;
+ param_j83b.ch_freq = temp_freq;
+ PR_DBG("hrc fre:%d\n", param_j83b.ch_freq);
+ c->frequency = param_j83b.ch_freq * 1000;
+
+ tuner_set_params(fe);
+ demod_set_mode_ts(Gxtv_Dvbc);
+ param_j83b.mode = amdemod_qam(c->modulation);
+ if (c->modulation == QAM_64)
+ param_j83b.symb_rate = 5057;
+ else if (c->modulation == QAM_256)
+ param_j83b.symb_rate = 5361;
+ else
+ param_j83b.symb_rate = 5361;
+ dvbc_set_ch(&demod_status, /*&demod_i2c,*/
+ ¶m_j83b);
+ }
+ } else {
+ param_j83b.ch_freq = (c->frequency - 1250000) / 1000;
+ PR_DBG("hrc fre:%d\n", param_j83b.ch_freq);
+ c->frequency = param_j83b.ch_freq * 1000;
+
+ demod_set_mode_ts(Gxtv_Dvbc);
+ param_j83b.mode = amdemod_qam(c->modulation);
+ if (c->modulation == QAM_64)
+ param_j83b.symb_rate = 5057;
+ else if (c->modulation == QAM_256)
+ param_j83b.symb_rate = 5361;
+ else
+ param_j83b.symb_rate = 5361;
+ dvbc_set_ch(&demod_status, /*&demod_i2c,*/
+ ¶m_j83b);
+ }
+ }
+ PR_DBG("atsc_mode is %d\n", atsc_mode);
+ /*pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n",*/
+ /* p->frequency,p->u.qam.symbol_rate);*/
+ return 0;
+}
+
+static int gxtv_demod_atsc_get_frontend(struct dvb_frontend *fe)
+{ /*these content will be writed into eeprom .*/
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ PR_DBG("c->frequency is %d\n", c->frequency);
+ return 0;
+}
+
+void atsc_detect_first(struct dvb_frontend *fe, enum fe_status *status)
+{
+ unsigned int ucblocks;
+ unsigned int atsc_status;
+ enum fe_status s;
+ int strenth;
+
+
+ /*tuner strength*/
+ if (dvb_tuner_delay > 9)
+ msleep(dvb_tuner_delay);
+
+ strenth = tuner_get_ch_power(fe);
+ if (strenth < THRD_TUNER_STRENTH_ATSC) {
+ *status = FE_TIMEDOUT;
+ PR_ATSC("tuner:no signal!\n");
+ return;
+ }
+
+ gxtv_demod_atsc_read_ucblocks(fe, &ucblocks);
+
+ gxtv_demod_atsc_read_status(fe, &s);
+
+ *status = s;
+
+ if (s != 0x1f) {
+ gxtv_demod_atsc_read_ber(fe, &atsc_status);
+ if ((atsc_status < 0x60))
+ *status = FE_TIMEDOUT;
+
+ }
+ PR_ATSC("%s, detect=0x%x\n", __func__, (unsigned int)*status);
+}
+
+
+static int dvb_j83b_count = 5;
+module_param(dvb_j83b_count, int, 0644);
+MODULE_PARM_DESC(dvb_atsc_count, "dvb_j83b_count");
+/*come from j83b_speedup_func*/
+static int atsc_j83b_detect_first(struct dvb_frontend *fe, enum fe_status *s)
+{
+ int j83b_status, i;
+ /*struct dvb_frontend_private *fepriv = fe->frontend_priv;*/
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int strenth;
+
+ PR_DBG("+6+");
+
+ if (dvb_tuner_delay > 9)
+ msleep(dvb_tuner_delay);
+
+ strenth = tuner_get_ch_power(fe);
+ if (strenth < THRD_TUNER_STRENTH_J83) {
+ *s = FE_TIMEDOUT;
+ PR_ATSC("tuner:no signal!j83\n");
+ return 0;
+ }
+
+ gxtv_demod_atsc_read_status(fe, s);
+
+ if (*s != 0x1f) {
+ /*msleep(200);*/
+ PR_DBG("[j.83b] 1\n");
+ for (i = 0; i < dvb_j83b_count; i++) {
+ msleep(25);
+ gxtv_demod_atsc_read_ber(fe, &j83b_status);
+
+ /*J.83 status >=0x38,has signal*/
+ if (j83b_status >= 0x3)
+ break;
+ }
+ PR_DBG("[rsj]j.83b_status is %x,modulation is %d\n",
+ j83b_status,
+ c->modulation);
+ }
+
+ if (j83b_status < 0x3)
+ *s = FE_TIMEDOUT;
+
+
+ return 0;
+}
+
+void atsc_polling(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (c->modulation == QPSK) {
+ PR_DBG("mode is qpsk, return;\n");
+ /*return;*/
+ } else if (c->modulation <= QAM_AUTO) {
+ PR_DBG("do nothing!\n");
+ } else {
+ atsc_thread();
+ }
+
+}
+
+
+static int gxtv_demod_atsc_tune(struct dvb_frontend *fe, bool re_tune,
+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
+{
+ /*
+ * It is safe to discard "params" here, as the DVB core will sync
+ * fe->dtv_property_cache with fepriv->parameters_in, where the
+ * DVBv3 params are stored. The only practical usage for it indicate
+ * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is
+ * true.
+ */
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ /*int ret = 0;*/
+
+ PR_ATSC("%s:\n", __func__);
+ *delay = HZ * 3;
+ if (re_tune) {
+ dtvdd_devp->en_detect = 1; /*fist set*/
+ /*c->delivery_system = aml_demod_delivery_sys;*/
+ /*PR_ATSC("delivery_system=%d\n", aml_demod_delivery_sys);*/
+ gxtv_demod_atsc_set_frontend(fe);
+
+ if (c->modulation == QPSK) {
+ PR_ATSC("modulation is QPSK do nothing!");
+ } else if (c->modulation <= QAM_AUTO) {
+ PR_ATSC("j83\n");
+ atsc_j83b_detect_first(fe, status);
+ } else if (c->modulation > QAM_AUTO) {
+ atsc_detect_first(fe, status);
+ }
+
+ return 0;
+ }
+#if 0
+ if (!dtvdd_devp->en_detect) {
+ PR_DBG("tune:not enable\n");
+ return ret;
+ }
+#endif
+ atsc_polling(fe);
+
+ return gxtv_demod_atsc_read_status(fe, status);
+
+}
+
+int Gxtv_Demod_Atsc_Init(void/*struct aml_fe_dev *dev*/)
+{
+ struct aml_demod_sys sys;
+ /*struct aml_demod_i2c i2c;*/
+
+ PR_DBG("%s\n", __func__);
+
+ memset(&sys, 0, sizeof(sys));
+ /*memset(&i2c, 0, sizeof(i2c));*/
+ memset(&demod_status, 0, sizeof(demod_status));
+ /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/
+ demod_status.dvb_mode = Gxtv_Atsc;
+ sys.adc_clk = Adc_Clk_24M; /*Adc_Clk_26M;*/
+ sys.demod_clk = Demod_Clk_225M; /*Demod_Clk_71M;//Demod_Clk_78M;*/
+ demod_status.ch_if = 5000;
+ demod_status.tmp = Adc_mode;
+ /*demod_set_sys(&demod_status, &i2c, &sys);*/
+ demod_set_sys(&demod_status, &sys);
+ demod_mode_para = AML_ATSC;
+ atsc_flag = VSB_8;
+ return 0;
+}
+
+static void gxtv_demod_dtmb_release(struct dvb_frontend *fe)
+{
+
+}
+
+static int gxtv_demod_dtmb_read_status
+ (struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ *status = pollm->last_s;
+ return 0;
+}
+
+void dtmb_save_status(unsigned int s)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ if (s) {
+ pollm->last_s =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+
+ } else {
+ pollm->last_s = FE_TIMEDOUT;
+ }
+}
+void dtmb_poll_start(void)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ pollm->last_s = 0;
+ pollm->flg_restart = 1;
+ /*pr_dbg("dtmb_poll_start!\n");*/
+ PR_DTMB("dtmb_poll_start2\n");
+
+}
+
+
+void dtmb_poll_stop(void)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ pollm->flg_stop = 1;
+
+}
+void dtmb_set_delay(unsigned int delay)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ pollm->delayms = delay;
+ pollm->flg_updelay = 1;
+}
+unsigned int dtmb_is_update_delay(void)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ return pollm->flg_updelay;
+}
+unsigned int dtmb_get_delay_clear(void)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ pollm->flg_updelay = 0;
+
+ return pollm->delayms;
+}
+
+void dtmb_poll_clear(void)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ memset(pollm, 0, sizeof(struct poll_machie_s));
+
+}
+
+#define DTMBM_NO_SIGNEL_CHECK 0x01
+#define DTMBM_HV_SIGNEL_CHECK 0x02
+#define DTMBM_BCH_OVER_CHEK 0x04
+
+#define DTMBM_CHEK_NO (DTMBM_NO_SIGNEL_CHECK)
+#define DTMBM_CHEK_HV (DTMBM_HV_SIGNEL_CHECK | DTMBM_BCH_OVER_CHEK)
+#define DTMBM_WORK (DTMBM_NO_SIGNEL_CHECK | DTMBM_HV_SIGNEL_CHECK\
+ | DTMBM_BCH_OVER_CHEK)
+
+#define DTMBM_POLL_CNT_NO_SIGNAL (10)
+#define DTMBM_POLL_CNT_WAIT_LOCK (3) /*from 30 to 3 */
+#define DTMBM_POLL_DELAY_NO_SIGNAL (120)
+#define DTMBM_POLL_DELAY_HAVE_SIGNAL (100)
+/*dtmb_poll_v3 is same as dtmb_check_status_txl*/
+void dtmb_poll_v3(void)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+ unsigned int bch_tmp;
+ unsigned int s;
+
+ if (!pollm->state) {
+ /* idle */
+ /* idle -> start check */
+ if (!pollm->flg_restart) {
+ PR_DBG("x");
+ return;
+ }
+ } else {
+ if (pollm->flg_stop) {
+ PR_DBG("dtmb poll stop !\n");
+ dtmb_poll_clear();
+ dtmb_set_delay(3*HZ);
+ return;
+ }
+ }
+
+ /* restart: clear */
+ if (pollm->flg_restart) {
+ PR_DBG("dtmb poll restart!\n");
+ dtmb_poll_clear();
+
+ }
+ PR_DBG("-");
+ s = check_dtmb_fec_lock();
+
+ /* bch exceed the threshold: wait lock*/
+ if (pollm->state & DTMBM_BCH_OVER_CHEK) {
+ if (pollm->crrcnt < DTMBM_POLL_CNT_WAIT_LOCK) {
+ pollm->crrcnt++;
+
+ if (s) {
+ PR_DBG("after reset get lock again!cnt=%d\n",
+ pollm->crrcnt);
+ dtmb_constell_check();
+ pollm->state = DTMBM_HV_SIGNEL_CHECK;
+ pollm->crrcnt = 0;
+ pollm->bch = dtmb_reg_r_bch();
+
+
+ dtmb_save_status(s);
+ }
+ } else {
+ PR_DBG("can't lock after reset!\n");
+ pollm->state = DTMBM_NO_SIGNEL_CHECK;
+ pollm->crrcnt = 0;
+ /* to no signal*/
+ dtmb_save_status(s);
+ }
+ return;
+ }
+
+
+ if (s) {
+ /*have signal*/
+ if (!pollm->state) {
+ pollm->state = DTMBM_CHEK_NO;
+ PR_DBG("from idle to have signal wait 1\n");
+ return;
+ }
+ if (pollm->state & DTMBM_CHEK_NO) {
+ /*no to have*/
+ PR_DBG("poll machie: from no signal to have signal\n");
+ pollm->bch = dtmb_reg_r_bch();
+ pollm->state = DTMBM_HV_SIGNEL_CHECK;
+
+ dtmb_set_delay(DTMBM_POLL_DELAY_HAVE_SIGNAL);
+ return;
+ }
+
+
+ bch_tmp = dtmb_reg_r_bch();
+ if (bch_tmp > (pollm->bch + 50)) {
+ pollm->state = DTMBM_BCH_OVER_CHEK;
+
+ PR_DBG("bch add ,need reset,wait not to reset\n");
+ dtmb_reset();
+
+ pollm->crrcnt = 0;
+ dtmb_set_delay(DTMBM_POLL_DELAY_HAVE_SIGNAL);
+ } else {
+ pollm->bch = bch_tmp;
+ pollm->state = DTMBM_HV_SIGNEL_CHECK;
+
+ dtmb_save_status(s);
+ /*have signale to have signal*/
+ dtmb_set_delay(300);
+ }
+ return;
+ }
+
+
+ /*no signal */
+ if (!pollm->state) {
+ /* idle -> no signal */
+ PR_DBG("poll machie: from idle to no signal\n");
+ pollm->crrcnt = 0;
+
+ pollm->state = DTMBM_NO_SIGNEL_CHECK;
+ } else if (pollm->state & DTMBM_CHEK_HV) {
+ /*have signal -> no signal*/
+ PR_DBG("poll machie: from have signal to no signal\n");
+ pollm->crrcnt = 0;
+ pollm->state = DTMBM_NO_SIGNEL_CHECK;
+ dtmb_save_status(s);
+ }
+
+ /*no siganel check process */
+ if (pollm->crrcnt < DTMBM_POLL_CNT_NO_SIGNAL) {
+ dtmb_no_signal_check_v3();
+ pollm->crrcnt++;
+
+ dtmb_set_delay(DTMBM_POLL_DELAY_NO_SIGNAL);
+ } else {
+ dtmb_no_signal_check_finishi_v3();
+ pollm->crrcnt = 0;
+
+ dtmb_save_status(s);
+ /*no signal to no signal*/
+ dtmb_set_delay(300);
+ }
+
+}
+
+void dtmb_poll_start_tune(unsigned int state)
+{
+ struct poll_machie_s *pollm = &dtvdd_devp->poll_machie;
+
+ dtmb_poll_clear();
+
+ pollm->state = state;
+ if (state & DTMBM_NO_SIGNEL_CHECK)
+ dtmb_save_status(0);
+ else
+ dtmb_save_status(1);
+ PR_DTMB("dtmb_poll_start tune to %d\n", state);
+
+}
+
+/*come from gxtv_demod_dtmb_read_status, have ms_delay*/
+int dtmb_poll_v2(struct dvb_frontend *fe, enum fe_status *status)
+{
+ int ilock;
+ unsigned char s = 0;
+
+ s = dtmb_check_status_gxtv(fe);
+
+ if (s == 1) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ } else {
+ ilock = 0;
+ *status = FE_TIMEDOUT;
+ }
+ if (last_lock != ilock) {
+ PR_INFO("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+
+ return 0;
+}
+
+
+/*this is ori gxtv_demod_dtmb_read_status*/
+static int gxtv_demod_dtmb_read_status_old
+ (struct dvb_frontend *fe, enum fe_status *status)
+{
+
+ int ilock;
+ unsigned char s = 0;
+
+ if (is_dtmb_ver(IC_DTMB_V2)) {
+ s = dtmb_check_status_gxtv(fe);
+ } else if (is_dtmb_ver(IC_DTMB_V3)) {
+ s = dtmb_check_status_txl(fe);
+ } else {
+
+ PR_ERR("%s:not support %d!\n", __func__, get_dtmb_ver());
+ return -1;
+ }
+ s = amdemod_dtmb_stat_islock();
+/* s=1;*/
+ if (s == 1) {
+ ilock = 1;
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ } else {
+ ilock = 0;
+ *status = FE_TIMEDOUT;
+ }
+ if (last_lock != ilock) {
+ PR_INFO("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+
+ return 0;
+}
+
+static int gxtv_demod_dtmb_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+
+ return 0;
+}
+
+static int gxtv_demod_dtmb_read_signal_strength
+ (struct dvb_frontend *fe, u16 *strength)
+{
+
+ *strength = tuner_get_ch_power(fe);
+ return 0;
+}
+
+static int gxtv_demod_dtmb_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ int tmp, snr_avg;
+
+ tmp = snr_avg = 0;
+ /* tmp = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR);*/
+ tmp = dtmb_reg_r_che_snr();
+
+ *snr = convert_snr(tmp);
+
+ return 0;
+}
+
+static int gxtv_demod_dtmb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ *ucblocks = 0;
+ return 0;
+}
+
+
+static int gxtv_demod_dtmb_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct aml_demod_dtmb param;
+ int times;
+
+ times = 2;
+ PR_DBG("gxtv_demod_dtmb_set_frontend,freq is %d\n", c->frequency);
+ memset(¶m, 0, sizeof(param));
+ param.ch_freq = c->frequency / 1000;
+
+ last_lock = -1;
+/* demod_power_switch(PWR_OFF); */
+ tuner_set_params(fe); /*aml_fe_analog_set_frontend(fe);*/
+ msleep(100);
+/* demod_power_switch(PWR_ON); */
+ dtmb_set_ch(&demod_status, /*&demod_i2c,*/ ¶m);
+
+ return 0;
+}
+
+
+static int gxtv_demod_dtmb_get_frontend(struct dvb_frontend *fe)
+{ /*these content will be writed into eeprom .*/
+
+ return 0;
+}
+
+/*int Gxtv_Demod_Dtmb_Init(struct aml_fe_dev *dev)*/
+int Gxtv_Demod_Dtmb_Init(struct amldtvdemod_device_s *dev)
+{
+ struct aml_demod_sys sys;
+ /*struct aml_demod_i2c i2c;*/
+ PR_DBG("AML Demod DTMB init\r\n");
+
+ memset(&sys, 0, sizeof(sys));
+ /*memset(&i2c, 0, sizeof(i2c));*/
+ memset(&demod_status, 0, sizeof(demod_status));
+ /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/
+ demod_status.dvb_mode = Gxtv_Dtmb;
+
+ if (is_dtmb_ver(IC_DTMB_V2)) {
+ sys.adc_clk = Adc_Clk_25M; /*Adc_Clk_26M;*/
+ sys.demod_clk = Demod_Clk_200M;
+ } else if (is_dtmb_ver(IC_DTMB_V3)) {
+ if (is_ic_ver(IC_VER_TXL)) {
+ sys.adc_clk = Adc_Clk_25M;
+ sys.demod_clk = Demod_Clk_225M;
+ } else {
+ sys.adc_clk = Adc_Clk_24M;
+ sys.demod_clk = Demod_Clk_225M;
+ }
+ } else {
+ PR_ERR("%s:not support %d\n", __func__, get_dtmb_ver());
+ return -1;
+ }
+
+ demod_status.ch_if = Si2176_5M_If;
+ demod_status.tmp = Adc_mode;
+ demod_status.spectrum = dev->spectrum;
+ /*demod_set_sys(&demod_status, &i2c, &sys);*/
+ demod_set_sys(&demod_status, &sys);
+ demod_mode_para = AML_DTMB;
+
+ return 0;
+}
+#ifdef DVB_CORE_ORI
+
+
+static int gxtv_demod_dvbc_tune(struct dvb_frontend *fe, bool re_tune,
+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
+{
+ /*struct dtv_frontend_properties *c = &fe->dtv_property_cache;*/
+ int ret = 0;
+ /*unsigned int up_delay;*/
+ /*unsigned int firstdetet;*/
+
+
+
+ if (re_tune) {
+ /*first*/
+ dtvdd_devp->en_detect = 1;
+
+ *delay = HZ / 4;
+ gxtv_demod_dvbc_set_frontend(fe);
+ timer_set_max(4000);
+ timer_begain();
+ gxtv_demod_dvbc_read_status_timer(fe, status);
+
+ PR_DBG("tune finish!\n");
+
+ return ret;
+ }
+
+ if (!dtvdd_devp->en_detect) {
+ PR_DBG("tune:not enable\n");
+ return ret;
+ }
+
+ gxtv_demod_dvbc_read_status_timer(fe, status);
+
+ return ret;
+
+}
+
+static int gxtv_demod_dtmb_tune(struct dvb_frontend *fe, bool re_tune,
+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
+{
+ /*struct dtv_frontend_properties *c = &fe->dtv_property_cache;*/
+ int ret = 0;
+ unsigned int up_delay;
+ unsigned int firstdetet;
+
+
+
+ if (re_tune) {
+ /*first*/
+ dtvdd_devp->en_detect = 1;
+
+ *delay = HZ / 4;
+ gxtv_demod_dtmb_set_frontend(fe);
+ firstdetet = dtmb_detect_first();
+ if (firstdetet == 1) {
+ *status = FE_TIMEDOUT;
+ /*polling mode*/
+ dtmb_poll_start_tune(DTMBM_NO_SIGNEL_CHECK);
+
+ } else if (firstdetet == 2) { /*need check*/
+ *status = FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ dtmb_poll_start_tune(DTMBM_HV_SIGNEL_CHECK);
+
+ } else if (firstdetet == 0) {
+ PR_DBG("use read_status\n");
+ gxtv_demod_dtmb_read_status_old(fe, status);
+ if (*status | (0x1f))
+ dtmb_poll_start_tune(DTMBM_HV_SIGNEL_CHECK);
+ else
+ dtmb_poll_start_tune(DTMBM_NO_SIGNEL_CHECK);
+
+
+ }
+ PR_DBG("tune finish!\n");
+
+ return ret;
+ }
+
+ if (!dtvdd_devp->en_detect) {
+ PR_DBG("tune:not enable\n");
+ return ret;
+ }
+
+#if 0 /**/
+ *delay = HZ / 4;
+ gxtv_demod_dtmb_read_status_old(fe, status);
+#else /*try polling*/
+
+ /*pr_dbg("+");*/
+ if (is_dtmb_ver(IC_DTMB_V3)) {
+ dtmb_poll_v3();
+ gxtv_demod_dtmb_read_status(fe, status);
+ if (dtmb_is_update_delay()) {
+ up_delay = (dtmb_get_delay_clear()*HZ)/1000;
+ if (up_delay > 0)
+ *delay = up_delay;
+ else
+ PR_DBG("warning:delay is 0\n");
+ }
+ } else if (is_dtmb_ver(IC_DTMB_V2)) {
+ *delay = HZ / 3;
+ dtmb_poll_v2(fe, status);
+ }
+
+#endif
+ return ret;
+
+}
+
+#endif
+
+
+
+#ifdef CONFIG_CMA
+/*void dtmb_cma_alloc(struct aml_fe_dev *devp)*/
+void dtmb_cma_alloc(struct amldtvdemod_device_s *devp)
+{
+ unsigned int mem_size = devp->cma_mem_size;
+ /* dma_alloc_from_contiguous*/
+ devp->venc_pages =
+ dma_alloc_from_contiguous(&(devp->this_pdev->dev),
+ mem_size >> PAGE_SHIFT, 0);
+ PR_DBG("[cma]mem_size is %d,%d\n",
+ mem_size, mem_size >> PAGE_SHIFT);
+ if (devp->venc_pages) {
+ devp->mem_start = page_to_phys(devp->venc_pages);
+ devp->mem_size = mem_size;
+ PR_DBG("demod mem_start = 0x%x, mem_size = 0x%x\n",
+ devp->mem_start, devp->mem_size);
+ PR_DBG("demod cma alloc ok!\n");
+ } else {
+ PR_DBG("demod cma mem undefined2.\n");
+ }
+}
+
+/*void dtmb_cma_release(struct aml_fe_dev *devp)*/
+void dtmb_cma_release(struct amldtvdemod_device_s *devp)
+{
+ /* dma_release_from_contiguous*/
+ dma_release_from_contiguous(&(devp->this_pdev->dev),
+ devp->venc_pages,
+ devp->cma_mem_size>>PAGE_SHIFT);
+ PR_DBG("demod cma release ok!\n");
+ devp->mem_start = 0;
+ devp->mem_size = 0;
+}
+#endif
+
+static int enter_mode(int mode)
+{
+ /*struct aml_fe_dev *dev = fe->dtv_demod;*/
+ struct amldtvdemod_device_s *devn = dtvdd_devp;
+ int memstart_dtmb;
+
+ PR_INFO("%s:%d\n", __func__, mode);
+
+ dtvdemod_set_agc_pinmux(1);
+
+ /*-------------------*/
+ /* must enable the adc ref signal for demod, */
+ /*vdac_enable(1, 0x2);*/
+ dtvdemod_vdac_enable(1);/*on*/
+ dtvdd_devp->en_detect = 0;/**/
+ dtvdd_devp->n_mode = mode;
+ dtmb_poll_stop();/*polling mode*/
+
+ autoFlagsTrig = 1;
+ if (cci_thread)
+ if (dvbc_get_cci_task() == 1)
+ dvbc_create_cci_task();
+ /*mem_buf = (long *)phys_to_virt(memstart);*/
+ if (mode == AM_FE_DTMB_N) {
+ Gxtv_Demod_Dtmb_Init(devn);
+ if (devn->cma_flag == 1) {
+ PR_DBG("CMA MODE, cma flag is %d,mem size is %d",
+ devn->cma_flag, devn->cma_mem_size);
+ dtmb_cma_alloc(devn);
+ memstart_dtmb = devn->mem_start;
+ } else {
+ memstart_dtmb = devn->mem_start;/*??*/
+ }
+
+ dtmb_set_mem_st(memstart_dtmb);
+
+ demod_write_reg(DEMOD_REG4, 0x8);
+
+ } else if (mode == AM_FE_QAM_N) {
+ Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode);
+ } else if (mode == AM_FE_ATSC_N) {
+ Gxtv_Demod_Atsc_Init();
+ } else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) {
+ Gxtv_Demod_Dvbt_Init();
+ if (devn->cma_flag == 1) {
+ PR_DBG("CMA MODE, cma flag is %d,mem size is %d",
+ devn->cma_flag,
+ devn->cma_mem_size);
+ dtmb_cma_alloc(devn);
+ memstart_dtmb = devn->mem_start;
+ } else {
+ memstart_dtmb = devn->mem_start;/*??*/
+ }
+ PR_DBG("[im]memstart is %x\n", memstart_dtmb);
+ dvbt_write_reg((0x10 << 2), memstart_dtmb);
+ }
+
+ return 0;
+
+}
+
+static int leave_mode(int mode)
+{
+/* struct aml_fe_dev *dev = fe->dtv_demod;*/
+ struct amldtvdemod_device_s *devn = dtvdd_devp;
+
+ PR_INFO("%s:\n", __func__);
+ dtvdd_devp->en_detect = 0;
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+
+ dtvpll_init_flag(0);
+ /*dvbc_timer_exit();*/
+ if (cci_thread)
+ dvbc_kill_cci_task();
+ if (mode == AM_FE_DTMB_N) {
+ dtmb_poll_stop(); /*polling mode*/
+ /* close arbit */
+
+ demod_write_reg(DEMOD_REG4, 0x0);
+ if (devn->cma_flag == 1)
+ dtmb_cma_release(devn);
+ }
+
+
+ adc_set_pll_cntl(0, 0x04, NULL);
+ demod_mode_para = UNKNOWN;
+ /* should disable the adc ref signal for demod */
+ /*vdac_enable(0, 0x2);*/
+ dtvdemod_vdac_enable(0);/*off*/
+ dtvdemod_set_agc_pinmux(0);
+ msleep(200);
+
+
+ return 0;
+
+}
+/* when can't get ic_config by dts, use this*/
+const struct meson_ddemod_data data_gxtvbb = {
+ .name = "ddmode_gxtvbb",
+ .icver = {
+ .atsc = IC_MD_NONE,
+ .dvbt = IC_MD_NONE,
+ .dtmb = IC_DTMB_V2,
+ .dvbc = IC_DVBC_V2,
+ .reserved = 0,
+ .offset = IC_OFFS_V2,
+ .ic = IC_VER_GTVBB,
+ },
+
+};
+
+const struct meson_ddemod_data data_txl = {
+ .name = "ddmode_txl",
+ .icver = {
+ .atsc = IC_MD_NONE,
+ .dvbt = IC_MD_NONE,
+ .dtmb = IC_DTMB_V3,
+ .dvbc = IC_DVBC_V2,
+ .reserved = 0,
+ .offset = IC_OFFS_V2,
+ .ic = IC_VER_TXL,
+ },
+
+};
+
+const struct meson_ddemod_data data_txlx = {
+ .name = "ddmode_txlx",
+ .icver = {
+ .atsc = IC_ATSC_V2,
+ .dvbt = IC_DVBT_V2,
+ .dtmb = IC_MD_NONE,
+ .dvbc = IC_DVBC_V3,
+ .reserved = 0,
+ .offset = IC_OFFS_V3,
+ .ic = IC_VER_TXLX,
+ },
+
+};
+
+const struct meson_ddemod_data data_gxlx = {
+ .name = "ddmode_gxlx",
+ .icver = {
+ .atsc = IC_MD_NONE,
+ .dvbt = IC_MD_NONE,
+ .dtmb = IC_MD_NONE,
+ .dvbc = IC_DVBC_V3,
+ .reserved = 0,
+ .offset = IC_OFFS_V3,
+ .ic = IC_VER_GXLX,
+ },
+
+};
+
+const struct meson_ddemod_data data_txhd = {
+ .name = "ddmode_txhd",
+ .icver = {
+ .atsc = IC_MD_NONE,
+ .dvbt = IC_MD_NONE,
+ .dtmb = IC_DTMB_V3,
+ .dvbc = IC_MD_NONE,
+ .reserved = 0,
+ .offset = IC_OFFS_V3,
+ .ic = IC_VER_TXHD,
+ },
+
+};
+
+static const struct of_device_id meson_ddemod_match[] = {
+ {
+ .compatible = "amlogic, ddemod-gxtvbb",
+ .data = &data_gxtvbb,
+ }, {
+ .compatible = "amlogic, ddemod-txl",
+ .data = &data_txl,
+ }, {
+ .compatible = "amlogic, ddemod-txlx",
+ .data = &data_txlx,
+ }, {
+ .compatible = "amlogic, ddemod-gxlx",
+ .data = &data_gxlx,
+ }, {
+ .compatible = "amlogic, ddemod-txhd",
+ .data = &data_txhd,
+ },
+ {},
+};
+
+
+
+/*
+ * dds_init_reg_map - physical addr map
+ *
+ * map physical address of I/O memory resources
+ * into the core virtual address space
+ */
+static int dds_init_reg_map(struct platform_device *pdev)
+{
+
+ struct ss_reg_phy *preg = &dtvdd_devp->reg_p[0];
+ struct ss_reg_vt *pv = &dtvdd_devp->reg_v[0];
+ int i;
+ struct resource *res = 0;
+ int size = 0;
+ int ret = 0;
+
+ for (i = 0; i < ES_MAP_ADDR_NUM; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res) {
+ PR_ERR("%s: res %d is faile\n", __func__, i);
+ ret = -ENOMEM;
+ break;
+ }
+ size = resource_size(res);
+ preg[i].size = size;
+ preg[i].phy_addr = res->start;
+
+ pv[i].v = devm_ioremap_nocache(&pdev->dev,
+ res->start, size);
+ }
+ return ret;
+}
+
+int dtvdemod_set_iccfg_by_dts(struct platform_device *pdev)
+{
+
+ /*struct ic_cfg_s *ic_cfg = &dtvdd_devp->iccfg;*/
+
+ /*int size_io_reg;*/
+ u32 value;
+ int ret;
+ /*struct resource *res = &dtvdemod_mem;*/
+
+
+ PR_DBG("%s:\n", __func__);
+
+
+ /*agc pinmux: option*/
+ ret = of_property_read_string(pdev->dev.of_node, "pinctrl-names",
+ &dtvdd_devp->pin_name);
+
+ if (ret)
+ PR_INFO("pinmux:not define in dts\n");
+ else
+ PR_INFO("pinmux name:%s\n", dtvdd_devp->pin_name);
+
+/*move from aml_fe*/
+ /*snprintf(buf, sizeof(buf), "%s%d_spectrum", name, id);*/
+#ifdef CONFIG_OF
+ ret = of_property_read_u32(pdev->dev.of_node, "spectrum", &value);
+ if (!ret) {
+ dtvdd_devp->spectrum = value;
+ PR_INFO("spectrum: %d\n", value);
+ } else {
+ dtvdd_devp->spectrum = 2;
+ }
+#else /*CONFIG_OF */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spectrum");
+ if (res) {
+ int spectrum = res->start;
+
+ dtvdd_devp->spectrum = spectrum;
+ } else {
+ dtvdd_devp->spectrum = 0;
+ }
+#endif
+ /*snprintf(buf, sizeof(buf), "%s%d_cma_flag", name, id);*/
+#ifdef CONFIG_OF
+ ret = of_property_read_u32(pdev->dev.of_node, "cma_flag", &value);
+ if (!ret) {
+ dtvdd_devp->cma_flag = value;
+ PR_INFO("cma_flag: %d\n", value);
+ } else {
+ dtvdd_devp->cma_flag = 0;
+ }
+#else /*CONFIG_OF */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cma_flag");
+ if (res) {
+ int cma_flag = res->start;
+
+ dtvdd_devp->cma_flag = cma_flag;
+ } else {
+ dtvdd_devp->cma_flag = 0;
+ }
+#endif
+ /*snprintf(buf, sizeof(buf), "%s%d_atsc_version", name, id);*/
+#ifdef CONFIG_OF
+ ret = of_property_read_u32(pdev->dev.of_node, "atsc_version", &value);
+ if (!ret) {
+ dtvdd_devp->atsc_version = value;
+ PR_INFO("atsc_version: %d\n", value);
+ } else {
+ dtvdd_devp->atsc_version = 0;
+ }
+#else /*CONFIG_OF */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "atsc_version");
+ if (res) {
+ int atsc_version = res->start;
+
+ dtvdd_devp->atsc_version = atsc_version;
+ } else {
+ dtvdd_devp->atsc_version = 0;
+ }
+#endif
+
+ if (dtvdd_devp->cma_flag == 1) {
+ /*snprintf(buf, sizeof(buf), "%s%d_cma_mem_size", name, id);*/
+#ifdef CONFIG_CMA
+#ifdef CONFIG_OF
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "cma_mem_size", &value);
+ if (!ret) {
+ dtvdd_devp->cma_mem_size = value;
+ PR_INFO("cma_mem_size: %d\n", value);
+ } else {
+ dtvdd_devp->cma_mem_size = 0;
+ }
+#else /*CONFIG_OF */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "cma_mem_size");
+ if (res) {
+ int cma_mem_size = res->start;
+
+ dtvdd_devp->cma_mem_size = cma_mem_size;
+ } else {
+ dtvdd_devp->cma_mem_size = 0;
+ }
+#endif
+ dtvdd_devp->cma_mem_size =
+ dma_get_cma_size_int_byte(&pdev->dev);
+ dtvdd_devp->this_pdev = pdev;
+ dtvdd_devp->cma_mem_alloc = 0;
+ PR_INFO("[cma]demod cma_mem_size = %d MB\n",
+ (u32)dtvdd_devp->cma_mem_size/SZ_1M);
+#endif
+ } else {
+#ifdef CONFIG_OF
+ dtvdd_devp->mem_start = memstart;
+#endif
+ }
+
+/*end-------------*/
+ return 0;
+
+}
+#if (defined CONFIG_AM_DTVDEMOD) /*move to aml_dtv_demod*/
+static int rmem_demod_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+ unsigned int demod_mem_start;
+ unsigned int demod_mem_size;
+
+ demod_mem_start = rmem->base;
+ demod_mem_size = rmem->size;
+ memstart = demod_mem_start;
+ pr_info("demod reveser memory 0x%x, size %dMB.\n",
+ demod_mem_start, (demod_mem_size >> 20));
+ return 1;
+}
+
+static void rmem_demod_device_release(struct reserved_mem *rmem,
+ struct device *dev)
+{
+}
+
+static const struct reserved_mem_ops rmem_demod_ops = {
+ .device_init = rmem_demod_device_init,
+ .device_release = rmem_demod_device_release,
+};
+
+static int __init rmem_demod_setup(struct reserved_mem *rmem)
+{
+ /*
+ * struct cma *cma;
+ * int err;
+ * pr_info("%s setup.\n",__func__);
+ * err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);
+ * if (err) {
+ * pr_err("Reserved memory: unable to setup CMA region\n");
+ * return err;
+ * }
+ */
+ rmem->ops = &rmem_demod_ops;
+ /* rmem->priv = cma; */
+
+ pr_info
+ ("DTV demod reserved memory: %pa, size %ld MiB\n",
+ &rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+ return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(demod, "amlogic, demod-mem", rmem_demod_setup);
+#endif
+
+int dtvdemod_init_regaddr_byversion(struct platform_device *pdev)
+{
+ struct ic_ver *pic = &dtvdd_devp->icver; /*in*/
+ struct ddemod_reg_off *ireg = &dtvdd_devp->ireg; /*set*/
+
+ unsigned int off_ver = pic->offset;
+ int ret = 0;
+
+ /*clear*/
+ ireg->off_demod = 0x00;
+ ireg->off_dvbc = 0x00;
+ ireg->off_dtmb = 0x00;
+ ireg->off_dvbt = 0x00;
+ ireg->off_atsc = 0x00;
+
+ if (is_offset_ver(IC_OFFS_V2)) {
+ ireg->off_demod = 0xc00;
+
+ ireg->off_dvbc = 0x400;
+ ireg->off_dtmb = 0x00;
+ } else if (is_offset_ver(IC_OFFS_V3)) {
+ ireg->off_demod = 0xf00;
+
+ ireg->off_dvbc = 0xc00;
+ ireg->off_dtmb = 0x000;
+ ireg->off_dvbt = 0x400;
+ ireg->off_atsc = 0x800;
+ } else {
+ PR_ERR("ic_offset_version[%d] is not support!\n", off_ver);
+ ireg->off_demod = 0xf00;
+
+ ireg->off_dvbc = 0xc00;
+ ireg->off_dtmb = 0x000;
+ ireg->off_dvbt = 0x400;
+ ireg->off_atsc = 0x800;
+
+ ret = -1;
+ }
+
+
+ return ret;
+}
+
+
+
+
+
+/* It's a correspondence with enum es_map_addr*/
+
+void dbg_ic_cfg(void)
+{
+ struct ic_ver *pic = &dtvdd_devp->icver;
+ struct ss_reg_phy *preg = &dtvdd_devp->reg_p[0];
+ int i;
+
+ PR_INFO("ic_version=0x%x\n", pic->ic);
+ PR_INFO("\tver_dvbc:\t%d\n", pic->dvbc);
+ PR_INFO("\tver_dtmb:\t%d\n", pic->dtmb);
+ PR_INFO("\tver_dvbt:\t%d\n", pic->dvbt);
+ PR_INFO("\tver_atsc:\t%d\n", pic->atsc);
+ PR_INFO("\tver_offset:\t%d\n", pic->offset);
+
+
+ for (i = 0; i < ES_MAP_ADDR_NUM; i++)
+ PR_INFO("reg:%s:st=0x%x,size=0x%x\n",
+ name_reg[i], preg[i].phy_addr, preg[i].size);
+
+
+}
+
+void dbg_reg_addr(void)
+{
+ struct ddemod_reg_off *ireg = &dtvdd_devp->ireg;
+ struct ss_reg_vt *regv = &dtvdd_devp->reg_v[0];
+ int i;
+
+ PR_INFO("%s\n", __func__);
+
+ PR_INFO("reg address offset:\n");
+ PR_INFO("\tdemod:\t0x%x\n", ireg->off_demod);
+ PR_INFO("\tdvbc:\t0x%x\n", ireg->off_dvbc);
+ PR_INFO("\tdtmb:\t0x%x\n", ireg->off_dtmb);
+ PR_INFO("\tdvbt:\t0x%x\n", ireg->off_dvbt);
+ PR_INFO("\tatsc:\t0x%x\n", ireg->off_atsc);
+
+ PR_INFO("virtual addr:\n");
+ for (i = 0; i < ES_MAP_ADDR_NUM; i++)
+ PR_INFO("\t%s:\t0x%p\n", name_reg[i], regv[i].v);
+
+
+}
+static void dtvdemod_set_agc_pinmux(int on)
+{
+ if (dtvdd_devp->pin_name == NULL) {
+ PR_INFO("no pinmux control\n");
+ return;
+ }
+
+ if (on) {
+ dtvdd_devp->pin = devm_pinctrl_get_select(dtvdd_devp->dev,
+ dtvdd_devp->pin_name);
+ } else {
+ /*off*/
+ if (dtvdd_devp->pin != NULL) {
+ devm_pinctrl_put(dtvdd_devp->pin);
+ dtvdd_devp->pin = NULL;
+ }
+ }
+
+}
+
+static void dtvdemod_clktree_probe(struct device *dev)
+{
+ dtvdd_devp->clk_gate_state = 0;
+
+ dtvdd_devp->vdac_clk_gate = devm_clk_get(dev, "vdac_clk_gate");
+ if (IS_ERR(dtvdd_devp->vdac_clk_gate))
+ PR_ERR("error: %s: clk vdac_clk_gate\n", __func__);
+}
+
+static void dtvdemod_clktree_remove(struct device *dev)
+{
+ if (!IS_ERR(dtvdd_devp->vdac_clk_gate))
+ devm_clk_put(dev, dtvdd_devp->vdac_clk_gate);
+}
+static void vdac_clk_gate_ctrl(int status)
+{
+ if (status) {
+ if (dtvdd_devp->clk_gate_state) {
+ PR_INFO("clk_gate is already on\n");
+ return;
+ }
+
+ if (IS_ERR(dtvdd_devp->vdac_clk_gate))
+ PR_ERR("error: %s: vdac_clk_gate\n", __func__);
+ else
+ clk_prepare_enable(dtvdd_devp->vdac_clk_gate);
+
+ dtvdd_devp->clk_gate_state = 1;
+ } else {
+ if (dtvdd_devp->clk_gate_state == 0) {
+ PR_INFO("clk_gate is already off\n");
+ return;
+ }
+
+ if (IS_ERR(dtvdd_devp->vdac_clk_gate))
+ PR_ERR("error: %s: vdac_clk_gate\n", __func__);
+ else
+ clk_disable_unprepare(dtvdd_devp->vdac_clk_gate);
+
+ dtvdd_devp->clk_gate_state = 0;
+ }
+}
+/*
+ * use dtvdemod_vdac_enable replace vdac_enable
+ */
+static void dtvdemod_vdac_enable(bool on)
+{
+ if (on) {
+ vdac_clk_gate_ctrl(1);
+ vdac_enable(1, 0x02);
+ } else {
+ vdac_clk_gate_ctrl(0);
+ vdac_enable(0, 0x02);
+ }
+}
+
+
+
+
+/* platform driver*/
+static int aml_dtvdemod_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ const struct of_device_id *match;
+
+ PR_INFO("%s\n", __func__);
+ /*memory*/
+
+ dtvdd_devp = kzalloc(sizeof(struct amldtvdemod_device_s),
+ GFP_KERNEL);
+
+ if (!dtvdd_devp)
+ goto fail_alloc_region;
+
+
+ /*class attr */
+ dtvdd_devp->clsp = class_create(THIS_MODULE, DEMOD_DEVICE_NAME);
+ if (!dtvdd_devp->clsp)
+ goto fail_create_class;
+
+ ret = class_create_file(dtvdd_devp->clsp, &class_attr_auto_sym);
+ if (ret)
+ goto fail_class_create_file;
+
+ ret = class_create_file(dtvdd_devp->clsp, &class_attr_dtmb_para);
+ if (ret)
+ goto fail_class_create_file;
+
+ ret = class_create_file(dtvdd_devp->clsp, &class_attr_dvbc_reg);
+ if (ret)
+ goto fail_class_create_file;
+
+ ret = class_create_file(dtvdd_devp->clsp, &class_attr_atsc_para);
+ if (ret)
+ goto fail_class_create_file;
+
+ ret = class_create_file(dtvdd_devp->clsp, &class_attr_demod_rate);
+ if (ret)
+ goto fail_class_create_file;
+
+ ret = class_create_file(dtvdd_devp->clsp, &class_attr_info);
+ if (ret)
+ goto fail_class_create_file;
+
+ /**/
+ match = of_match_device(meson_ddemod_match, &pdev->dev);
+ if (match == NULL) {
+ PR_ERR("%s,no matched table\n", __func__);
+ goto fail_ic_config;
+ }
+ dtvdd_devp->data = (struct meson_ddemod_data *)match->data;
+ dtvdd_devp->icver = dtvdd_devp->data->icver;
+
+ /*reg*/
+ ret = dds_init_reg_map(pdev);
+ if (ret)
+ goto fail_ic_config;
+
+ /*mem info from dts*/
+ ret = dtvdemod_set_iccfg_by_dts(pdev);
+ if (ret)
+ goto fail_ic_config;
+ /*dtvdemod_set_iccfg_by_cputype();*/
+
+ ret = dtvdemod_init_regaddr_byversion(pdev);
+ if (ret)
+ goto fail_ic_config;
+
+ /*debug:*/
+ dbg_ic_cfg();
+ dbg_reg_addr();
+
+ /**/
+ dtvpll_lock_init();
+ /* init */
+ /*dtvdemod_base_add_init();*/
+ mutex_init(&dtvdd_devp->lock);
+
+ dtvdd_devp->dev = &pdev->dev;
+
+ dtvdemod_clktree_probe(&pdev->dev);
+
+
+ dtvdd_devp->state = DTVDEMOD_ST_IDLE;
+ dtvdemod_version(dtvdd_devp);
+
+ //ary temp:
+ aml_demod_init();
+
+ PR_INFO("[amldtvdemod.] : probe ok.\n");
+ return 0;
+fail_ic_config:
+ PR_ERR("ic config error.\n");
+fail_class_create_file:
+ PR_ERR("dtvdemod class file create error.\n");
+ class_destroy(dtvdd_devp->clsp);
+fail_create_class:
+ PR_ERR("dtvdemod class create error.\n");
+ kfree(dtvdd_devp);
+fail_alloc_region:
+ PR_ERR("dtvdemod alloc error.\n");
+ PR_ERR("dtvdemod_init fail.\n");
+ dtvdd_devp->state = DTVDEMOD_ST_NOT_INI;
+
+
+
+ return ret;
+}
+
+static int __exit aml_dtvdemod_remove(struct platform_device *pdev)
+{
+ if (dtvdd_devp == NULL)
+ return -1;
+
+ dtvdemod_clktree_remove(&pdev->dev);
+
+ mutex_destroy(&dtvdd_devp->lock);
+
+ class_remove_file(dtvdd_devp->clsp, &class_attr_auto_sym);
+ class_remove_file(dtvdd_devp->clsp, &class_attr_dtmb_para);
+ class_remove_file(dtvdd_devp->clsp, &class_attr_dvbc_reg);
+ class_remove_file(dtvdd_devp->clsp, &class_attr_atsc_para);
+ class_remove_file(dtvdd_devp->clsp, &class_attr_demod_rate);
+ class_remove_file(dtvdd_devp->clsp, &class_attr_info);
+
+ class_destroy(dtvdd_devp->clsp);
+
+ kfree(dtvdd_devp);
+ PR_INFO("%s:remove.\n", __func__);
+
+ aml_demod_exit();//ary temp
+ return 0;
+}
+
+static void aml_dtvdemod_shutdown(struct platform_device *pdev)
+{
+ pr_info("%s\n", __func__);
+
+ if (dtvdd_devp->state != DTVDEMOD_ST_IDLE) {
+ leave_mode(0);
+ dtvdd_devp->state = DTVDEMOD_ST_IDLE;
+ }
+
+}
+
+static struct platform_driver aml_dtvdemod_driver = {
+ .driver = {
+ .name = "aml_dtv_demod",
+ .owner = THIS_MODULE,
+ /*aml_dtvdemod_dt_match*/
+ .of_match_table = meson_ddemod_match,
+ },
+ .shutdown = aml_dtvdemod_shutdown,
+ .probe = aml_dtvdemod_probe,
+ .remove = __exit_p(aml_dtvdemod_remove),
+};
+
+
+static int __init aml_dtvdemod_init(void)
+{
+ if (platform_driver_register(&aml_dtvdemod_driver)) {
+ pr_err("failed to register amldtvdemod driver module\n");
+ return -ENODEV;
+ }
+ PR_INFO("[amldtvdemod..]%s.\n", __func__);
+ return 0;
+}
+
+static void __exit aml_dtvdemod_exit(void)
+{
+ platform_driver_unregister(&aml_dtvdemod_driver);
+ PR_INFO("[amldtvdemod..]%s: driver removed ok.\n", __func__);
+}
+
+
+static int delsys_confirm(struct dvb_frontend *fe)
+{
+ enum fe_delivery_system ldelsys = dtvdd_devp->last_delsys;
+ enum fe_delivery_system cdelsys;
+
+ int ncaps, support;
+ enum aml_fe_n_mode_t mode = AM_FE_UNKNOWN_N;
+
+ cdelsys = fe->dtv_property_cache.delivery_system;
+
+ /*same*/
+ if (ldelsys == cdelsys) {
+ //PR_DBG("delsys is same, do nothing\n");
+ return 0;
+ }
+
+ /*support ?*/
+ ncaps = 0;
+ support = 0;
+ while (ncaps < 10 && fe->ops.delsys[ncaps]) {
+ if (fe->ops.delsys[ncaps] == cdelsys) {
+
+ support = 1;
+ break;
+ }
+ ncaps++;
+ }
+
+ if (!support) {
+ PR_INFO("delsys:%d is not support!\n", cdelsys);
+ return 0;
+ }
+
+ PR_DBG("%s:l=%d,c=%d\n", __func__, ldelsys, cdelsys);
+
+ switch (cdelsys) {
+
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_C:
+ /*dvbc*/
+ if (ldelsys == SYS_DVBC_ANNEX_A
+ || ldelsys == SYS_DVBC_ANNEX_C) {
+ break;
+ }
+ mode = AM_FE_QAM_N;
+ break;
+ case SYS_ATSC:
+ case SYS_ATSCMH:
+ case SYS_DVBC_ANNEX_B:
+ /*atsc*/
+ if (ldelsys == SYS_ATSC
+ || ldelsys == SYS_ATSCMH
+ || ldelsys == SYS_DVBC_ANNEX_B) {
+ break;
+
+ }
+ mode = AM_FE_ATSC_N;
+ break;
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ /*dvbt, OFDM*/
+ if (ldelsys == SYS_DVBT
+ || ldelsys == SYS_DVBT2) {
+ break;
+
+ }
+ mode = AM_FE_OFDM_N;
+ break;
+ case SYS_ISDBT:
+ if (ldelsys != SYS_ISDBT)
+ mode = AM_FE_ISDBT_N;
+ break;
+ case SYS_DTMB:
+ /*dtmb*/
+ mode = AM_FE_DTMB_N;
+ break;
+ case SYS_DVBS:
+ case SYS_DVBS2:
+ /*QPSK*/
+ if (ldelsys == SYS_DVBS
+ || ldelsys == SYS_DVBS2) {
+
+ break;
+
+ }
+ mode = AM_FE_QPSK_N;
+ break;
+
+ case SYS_DSS:
+ case SYS_DVBH:
+
+ case SYS_ISDBS:
+ case SYS_ISDBC:
+ case SYS_CMMB:
+ case SYS_DAB:
+ case SYS_TURBO:
+ case SYS_UNDEFINED:
+ case SYS_ANALOG:
+ mode = AM_FE_UNKNOWN_N;
+ PR_INFO("delsys not support!%d=\n", cdelsys);
+ return 0;
+ }
+
+ if (mode != AM_FE_UNKNOWN_N)
+ enter_mode(mode);
+
+ if (!get_dtvpll_init_flag()) {
+ PR_INFO("pll is not set!\n");
+ leave_mode(mode);
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+ return 0;
+ }
+
+ dtvdd_devp->last_delsys = cdelsys;
+
+ return 0;
+}
+
+static int delsys_set(struct dvb_frontend *fe, unsigned int delsys)
+{
+ enum fe_delivery_system ldelsys = dtvdd_devp->last_delsys;
+ enum fe_delivery_system cdelsys;
+
+ int ncaps, support;
+ enum aml_fe_n_mode_t mode = AM_FE_UNKNOWN_N;
+ enum aml_fe_n_mode_t lmode = dtvdd_devp->n_mode;
+
+ cdelsys = delsys; /*diff*/
+
+ /*same*/
+ if (ldelsys == cdelsys) {
+ //PR_DBG("delsys is same, do nothing\n");
+ return 0;
+ }
+
+ /*support ?*/
+ ncaps = 0;
+ support = 0;
+ while (ncaps < 10 && fe->ops.delsys[ncaps]) {
+ if (fe->ops.delsys[ncaps] == cdelsys) {
+
+ support = 1;
+ break;
+ }
+ ncaps++;
+ }
+
+ if (!support) {
+ if (get_dtvpll_init_flag()) {
+ /**/
+ PR_INFO("delsys:%d is not support!\n", cdelsys);
+ leave_mode(lmode);
+ }
+ return 0;
+ }
+
+ PR_DBG("%s:l=%d,c=%d\n", __func__, ldelsys, cdelsys);
+ dbg_delsys(cdelsys);
+
+ switch (cdelsys) {
+
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_C:
+ /*dvbc*/
+ if (ldelsys == SYS_DVBC_ANNEX_A
+ || ldelsys == SYS_DVBC_ANNEX_C) {
+ break;
+ }
+ mode = AM_FE_QAM_N;
+ break;
+ case SYS_ATSC:
+ case SYS_ATSCMH:
+ case SYS_DVBC_ANNEX_B:
+ /*atsc*/
+ if (ldelsys == SYS_ATSC
+ || ldelsys == SYS_ATSCMH
+ || ldelsys == SYS_DVBC_ANNEX_B) {
+ break;
+
+ }
+ mode = AM_FE_ATSC_N;
+ break;
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ /*dvbt, OFDM*/
+ if (ldelsys == SYS_DVBT
+ || ldelsys == SYS_DVBT2) {
+ break;
+
+ }
+ mode = AM_FE_OFDM_N;
+ break;
+ case SYS_ISDBT:
+ if (ldelsys != SYS_ISDBT)
+ mode = AM_FE_ISDBT_N;
+ break;
+ case SYS_DTMB:
+ /*dtmb*/
+ mode = AM_FE_DTMB_N;
+ break;
+ case SYS_DVBS:
+ case SYS_DVBS2:
+ /*QPSK*/
+ if (ldelsys == SYS_DVBS
+ || ldelsys == SYS_DVBS2) {
+
+ break;
+
+ }
+ mode = AM_FE_QPSK_N;
+ break;
+
+ case SYS_DSS:
+ case SYS_DVBH:
+
+ case SYS_ISDBS:
+ case SYS_ISDBC:
+ case SYS_CMMB:
+ case SYS_DAB:
+ case SYS_TURBO:
+ case SYS_UNDEFINED:
+ case SYS_ANALOG:
+ mode = AM_FE_UNKNOWN_N;
+ PR_INFO("delsys not support!%d=\n", cdelsys);
+ return 0;
+ }
+
+ if (mode != AM_FE_UNKNOWN_N)
+ enter_mode(mode);
+
+ if (!get_dtvpll_init_flag()) {
+ PR_INFO("pll is not set!\n");
+ leave_mode(mode);
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+ return 0;
+ }
+
+ dtvdd_devp->last_delsys = cdelsys;
+#if 1 /*ary add for test*/
+ PR_INFO("info type:%d", fe->ops.info.type);
+ if (mode == AM_FE_ATSC_N)
+ fe->ops.info.type = FE_ATSC;
+ else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N)
+ fe->ops.info.type = FE_OFDM;
+
+ fe->ops.tuner_ops.set_config(fe, NULL);
+
+#endif
+
+ return 0;
+}
+
+static int is_not_active(struct dvb_frontend *fe)
+{
+ enum fe_delivery_system cdelsys;
+ enum fe_delivery_system ldelsys = dtvdd_devp->last_delsys;
+
+ if (!get_dtvpll_init_flag())
+ return 1;
+
+ cdelsys = fe->dtv_property_cache.delivery_system;
+ if (ldelsys != cdelsys)
+ return 2;
+
+
+ return 0;/*active*/
+}
+/*ko attach==============================*/
+static int aml_dtvdm_init(struct dvb_frontend *fe)
+{
+
+ return 0;
+}
+static int aml_dtvdm_sleep(struct dvb_frontend *fe)
+{
+ return 0;
+}
+static int aml_dtvdm_set_parameters(struct dvb_frontend *fe)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+ int ret = 0;
+
+ PR_INFO("%s", __func__);
+
+ delsys_confirm(fe);
+ if (is_not_active(fe)) {
+ PR_DBG("set parm:not active\n");
+ return 0;
+ }
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+ case AM_FE_QAM_N:
+ PR_INFO("FE_QAM\n");
+ ret = gxtv_demod_dvbc_set_frontend(fe);
+ break;
+ case AM_FE_OFDM_N:
+ PR_INFO("FE_OFDM\n");
+ ret = gxtv_demod_dvbt_set_frontend(fe);
+ break;
+ case AM_FE_ISDBT_N: /*same as dvbt*/
+ PR_INFO("FE_OFDM\n");
+ ret = gxtv_demod_dvbt_set_frontend(fe);
+
+ break;
+ case AM_FE_ATSC_N:
+ PR_INFO("FE_ATSC\n");
+ ret = gxtv_demod_atsc_set_frontend(fe);
+ break;
+ case AM_FE_DTMB_N:
+ PR_INFO("FE_DTMB\n");
+ ret = gxtv_demod_dtmb_set_frontend(fe);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+}
+
+static int aml_dtvdm_get_frontend(struct dvb_frontend *fe,
+ struct dtv_frontend_properties *p)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("get parm:not active\n");
+ return 0;
+ }
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_get_frontend(fe);
+ break;
+ case AM_FE_OFDM_N:
+ ret = gxtv_demod_dvbt_get_frontend(fe);
+ break;
+ case AM_FE_ISDBT_N: /*same as dvbt*/
+ ret = gxtv_demod_dvbt_get_frontend(fe);
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_get_frontend(fe);
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_get_frontend(fe);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+}
+static int aml_dtvdm_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings
+ *fe_tune_settings)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("get parm:not active\n");
+ return 0;
+ }
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ fe_tune_settings->min_delay_ms = 4000;
+ fe_tune_settings->step_size = 0; /* no zigzag */
+ fe_tune_settings->max_drift = 0;
+
+ break;
+ case AM_FE_OFDM_N:
+ /*dvbt*/
+ fe_tune_settings->min_delay_ms = 4000;
+ fe_tune_settings->step_size = 0;
+ fe_tune_settings->max_drift = 0;
+ break;
+ case AM_FE_ISDBT_N: /*same as dvbt*/
+ /*isdbt*/
+ fe_tune_settings->min_delay_ms = 4000;
+ fe_tune_settings->step_size = 0;
+ fe_tune_settings->max_drift = 0;
+
+ break;
+ case AM_FE_ATSC_N:
+
+ break;
+ case AM_FE_DTMB_N:
+
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+}
+static int aml_dtvdm_read_status(struct dvb_frontend *fe,
+ enum fe_status *status)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("read status:not active\n");
+ return 0;
+ }
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_read_status_timer(fe, status);
+ break;
+ case AM_FE_OFDM_N:
+ ret = gxtv_demod_dvbt_read_status(fe, status);
+ break;
+ case AM_FE_ISDBT_N:
+ ret = gxtv_demod_dvbt_read_status(fe, status);
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_read_status(fe, status);
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_read_status(fe, status);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+
+}
+static int aml_dtvdm_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("read ber:not active\n");
+ return 0;
+ }
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_read_ber(fe, ber);
+ break;
+ case AM_FE_OFDM_N:
+ ret = gxtv_demod_dvbt_read_ber(fe, ber);
+ break;
+ case AM_FE_ISDBT_N: /*same as dvbt*/
+ ret = gxtv_demod_dvbt_read_ber(fe, ber);
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_read_ber(fe, ber);
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_read_ber(fe, ber);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+
+}
+
+static int aml_dtvdm_read_signal_strength(struct dvb_frontend *fe,
+ u16 *strength)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("read strength:not active\n");
+ return 0;
+ }
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_read_signal_strength(fe, strength);
+ break;
+ case AM_FE_OFDM_N:
+ ret = gxtv_demod_dvbt_read_signal_strength(fe, strength);
+ break;
+ case AM_FE_ISDBT_N: /*same as dvbt*/
+ ret = gxtv_demod_dvbt_read_signal_strength(fe, strength);
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_read_signal_strength(fe, strength);
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_read_signal_strength(fe, strength);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+
+}
+static int aml_dtvdm_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("read snr :not active\n");
+ return 0;
+ }
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_read_snr(fe, snr);
+ break;
+ case AM_FE_OFDM_N:
+ ret = gxtv_demod_dvbt_read_snr(fe, snr);
+ break;
+ case AM_FE_ISDBT_N:
+ ret = gxtv_demod_dvbt_read_snr(fe, snr);
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_read_snr(fe, snr);
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_read_snr(fe, snr);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+
+}
+static int aml_dtvdm_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ int ret = 0;
+
+ if (is_not_active(fe)) {
+ PR_DBG("read ucblocks :not active\n");
+ return 0;
+ }
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ ret = gxtv_demod_dvbc_read_ucblocks(fe, ucblocks);
+ break;
+ case AM_FE_OFDM_N:
+ ret = gxtv_demod_dvbt_read_ucblocks(fe, ucblocks);
+ break;
+ case AM_FE_ISDBT_N:
+ ret = gxtv_demod_dvbt_read_ucblocks(fe, ucblocks);
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_read_ucblocks(fe, ucblocks);
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_read_ucblocks(fe, ucblocks);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+ return ret;
+
+}
+static void aml_dtvdm_release(struct dvb_frontend *fe)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ gxtv_demod_dvbc_release(fe);
+ break;
+ case AM_FE_OFDM_N:
+ case AM_FE_ISDBT_N:
+ gxtv_demod_dvbt_release(fe);
+ break;
+ case AM_FE_ATSC_N:
+ gxtv_demod_atsc_release(fe);
+ break;
+ case AM_FE_DTMB_N:
+ gxtv_demod_dtmb_release(fe);
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+
+ break;
+ }
+}
+
+
+static int aml_dtvdm_tune(struct dvb_frontend *fe, bool re_tune,
+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+ int ret = 0;
+ static int flg; /*debug only*/
+
+ delsys_confirm(fe);
+
+ if (is_not_active(fe)) {
+ PR_DBG("tune :not active\n");
+ return 0;
+ }
+
+ if ((flg > 0) && (flg < 5))
+ PR_INFO("%s\n", __func__);
+
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+
+ break;
+
+ case AM_FE_QAM_N:
+ gxtv_demod_dvbc_tune(fe, re_tune, mode_flags,
+ delay, status);
+
+ break;
+ case AM_FE_OFDM_N:
+ case AM_FE_ISDBT_N:
+ break;
+ case AM_FE_ATSC_N:
+ ret = gxtv_demod_atsc_tune(fe, re_tune, mode_flags,
+ delay, status);
+ flg++;
+ break;
+ case AM_FE_DTMB_N:
+ ret = gxtv_demod_dtmb_tune(fe, re_tune, mode_flags,
+ delay, status);
+
+ break;
+ case AM_FE_UNKNOWN_N:
+ default:
+ flg = 0;
+ break;
+ }
+
+ return ret;
+
+}
+static int aml_dtvdm_set_property(struct dvb_frontend *dev,
+ struct dtv_property *tvp)
+{
+ int r = 0;
+ u32 delsys;
+
+ switch (tvp->cmd) {
+ case DTV_DELIVERY_SYSTEM:
+ delsys = tvp->u.data;
+ delsys_set(dev, delsys);
+ break;
+
+ default:
+ break;
+ }
+
+
+ return r;
+
+}
+static int aml_dtvdm_get_property(struct dvb_frontend *dev,
+ struct dtv_property *tvp)
+{
+ return 0;
+}
+
+static struct dvb_frontend_ops aml_dtvdm_gxtvbb_ops = {
+ .delsys = { SYS_DVBC_ANNEX_A, SYS_DTMB},
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod txlx",
+ .frequency_min = 51000000,
+ .frequency_max = 900000000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0, /**/
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_RECOVER | FE_CAN_MUTE_TS
+ },
+ .init = aml_dtvdm_init,
+ .sleep = aml_dtvdm_sleep,
+ .set_frontend = aml_dtvdm_set_parameters,
+ .get_frontend = aml_dtvdm_get_frontend,
+ .get_tune_settings = aml_dtvdm_get_tune_settings,
+ .read_status = aml_dtvdm_read_status,
+ .read_ber = aml_dtvdm_read_ber,
+ .read_signal_strength = aml_dtvdm_read_signal_strength,
+ .read_snr = aml_dtvdm_read_snr,
+ .read_ucblocks = aml_dtvdm_read_ucblocks,
+ .release = aml_dtvdm_release,
+ .set_property = aml_dtvdm_set_property,
+ .get_property = aml_dtvdm_get_property,
+
+/*-------------*/
+ .tune = aml_dtvdm_tune,
+ .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo,
+
+};
+
+static struct dvb_frontend_ops aml_dtvdm_txl_ops = {
+ .delsys = { SYS_DVBC_ANNEX_A, SYS_DTMB},
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod txlx",
+ .frequency_min = 51000000,
+ .frequency_max = 900000000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0, /**/
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_RECOVER | FE_CAN_MUTE_TS
+ },
+ .init = aml_dtvdm_init,
+ .sleep = aml_dtvdm_sleep,
+ .set_frontend = aml_dtvdm_set_parameters,
+ .get_frontend = aml_dtvdm_get_frontend,
+ .get_tune_settings = aml_dtvdm_get_tune_settings,
+ .read_status = aml_dtvdm_read_status,
+ .read_ber = aml_dtvdm_read_ber,
+ .read_signal_strength = aml_dtvdm_read_signal_strength,
+ .read_snr = aml_dtvdm_read_snr,
+ .read_ucblocks = aml_dtvdm_read_ucblocks,
+ .release = aml_dtvdm_release,
+ .set_property = aml_dtvdm_set_property,
+ .get_property = aml_dtvdm_get_property,
+
+/*-------------*/
+ .tune = aml_dtvdm_tune,
+ .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo,
+
+};
+
+static struct dvb_frontend_ops aml_dtvdm_txlx_ops = {
+ .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT},
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod txlx",
+ .frequency_min = 51000000,
+ .frequency_max = 900000000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0, /**/
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_RECOVER | FE_CAN_MUTE_TS
+ },
+ .init = aml_dtvdm_init,
+ .sleep = aml_dtvdm_sleep,
+ .set_frontend = aml_dtvdm_set_parameters,
+ .get_frontend = aml_dtvdm_get_frontend,
+ .get_tune_settings = aml_dtvdm_get_tune_settings,
+ .read_status = aml_dtvdm_read_status,
+ .read_ber = aml_dtvdm_read_ber,
+ .read_signal_strength = aml_dtvdm_read_signal_strength,
+ .read_snr = aml_dtvdm_read_snr,
+ .read_ucblocks = aml_dtvdm_read_ucblocks,
+ .release = aml_dtvdm_release,
+ .set_property = aml_dtvdm_set_property,
+ .get_property = aml_dtvdm_get_property,
+
+/*-------------*/
+ .tune = aml_dtvdm_tune,
+ .get_frontend_algo = gxtv_demod_txlx_get_frontend_algo,
+
+};
+static struct dvb_frontend_ops aml_dtvdm_gxlx_ops = {
+ .delsys = { SYS_DVBC_ANNEX_A },
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod txlx",
+ .frequency_min = 51000000,
+ .frequency_max = 900000000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0, /**/
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_RECOVER | FE_CAN_MUTE_TS
+ },
+ .init = aml_dtvdm_init,
+ .sleep = aml_dtvdm_sleep,
+ .set_frontend = aml_dtvdm_set_parameters,
+ .get_frontend = aml_dtvdm_get_frontend,
+ .get_tune_settings = aml_dtvdm_get_tune_settings,
+ .read_status = aml_dtvdm_read_status,
+ .read_ber = aml_dtvdm_read_ber,
+ .read_signal_strength = aml_dtvdm_read_signal_strength,
+ .read_snr = aml_dtvdm_read_snr,
+ .read_ucblocks = aml_dtvdm_read_ucblocks,
+ .release = aml_dtvdm_release,
+ .set_property = aml_dtvdm_set_property,
+ .get_property = aml_dtvdm_get_property,
+
+/*-------------*/
+ .tune = aml_dtvdm_tune,
+ .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo,
+
+};
+
+static struct dvb_frontend_ops aml_dtvdm_txhd_ops = {
+ .delsys = { SYS_DTMB },
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod txlx",
+ .frequency_min = 51000000,
+ .frequency_max = 900000000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0, /**/
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_RECOVER | FE_CAN_MUTE_TS
+ },
+ .init = aml_dtvdm_init,
+ .sleep = aml_dtvdm_sleep,
+ .set_frontend = aml_dtvdm_set_parameters,
+ .get_frontend = aml_dtvdm_get_frontend,
+ .get_tune_settings = aml_dtvdm_get_tune_settings,
+ .read_status = aml_dtvdm_read_status,
+ .read_ber = aml_dtvdm_read_ber,
+ .read_signal_strength = aml_dtvdm_read_signal_strength,
+ .read_snr = aml_dtvdm_read_snr,
+ .read_ucblocks = aml_dtvdm_read_ucblocks,
+ .release = aml_dtvdm_release,
+ .set_property = aml_dtvdm_set_property,
+ .get_property = aml_dtvdm_get_property,
+
+/*-------------*/
+ .tune = aml_dtvdm_tune,
+ .get_frontend_algo = gxtv_demod_atsc_get_frontend_algo,
+
+};
+
+struct dvb_frontend *aml_dtvdm_attach(const struct amlfe_exp_config *config)
+
+
+{
+ int ic_version = get_ic_ver();
+
+
+ /*mem setting is in prob*/
+
+ struct dvb_frontend *fe = &dtvdd_devp->frontend;
+
+ /* mem of dvb_frontend is define in aml_fe*/
+
+ switch (ic_version) {
+
+ case IC_VER_GTVBB:
+ memcpy(&fe->ops, &aml_dtvdm_gxtvbb_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ case IC_VER_TXL:
+ memcpy(&fe->ops, &aml_dtvdm_txl_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ case IC_VER_TXLX:
+ memcpy(&fe->ops, &aml_dtvdm_txlx_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ case IC_VER_GXLX:
+ memcpy(&fe->ops, &aml_dtvdm_gxlx_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ case IC_VER_TXHD:
+ memcpy(&fe->ops, &aml_dtvdm_txhd_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ default:
+ PR_ERR("attach fail! ic=%d\n", ic_version);
+ /*return NULL;*/
+ fe = NULL;
+ break;
+ }
+ /* mem of dvb_frontend is define in aml_fe*/
+
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+
+
+ return fe;
+}
+EXPORT_SYMBOL(aml_dtvdm_attach);
+
+/*-------------------------*/
+static struct aml_exp_func aml_exp_ops = {
+ .leave_mode = leave_mode,
+};
+
+struct aml_exp_func *aml_dtvdm_exp_attach(struct aml_exp_func *exp)
+{
+ if (exp) {
+ memcpy(exp, &aml_exp_ops, sizeof(struct aml_exp_func));
+ } else {
+ PR_ERR("%s:fail!\n", __func__);
+ return NULL;
+
+ }
+ return exp;
+}
+EXPORT_SYMBOL(aml_dtvdm_exp_attach);
+
+/*-------------------------*/
+struct dvb_frontend *aml_get_fe(void)
+{
+
+ return &dtvdd_devp->frontend;
+
+}
+
+void aml_exp_attach(struct aml_exp_func *afe)
+{
+
+}
+EXPORT_SYMBOL(aml_exp_attach);
+
+/*=======================================*/
+
+fs_initcall(aml_dtvdemod_init);
+module_exit(aml_dtvdemod_exit);
+
+MODULE_DESCRIPTION("gxtv_demod DVB-T/DVB-C/DTMB Demodulator driver");
+MODULE_AUTHOR("RSJ");
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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]);
+ }
+
+}
+
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
+
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__*/
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+#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 */