--- /dev/null
- static int aml_dtvdm_get_property(struct dvb_frontend *dev,
- struct dtv_property *tvp)
- {
- return 0;
- }
+/*
+ * drivers/amlogic/media/dtv_demod/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>
+#include <linux/of_reserved_mem.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"
+
+/*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>
+#include <linux/amlogic/media/vout/vdac_dev.h>
+#include <linux/amlogic/aml_dtvdemod.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
+ *0.04: new method of tl1 dvbc channel fast search(Hisense project)
+ */
+static char *demod_version = "V0.04";
+
+
+int aml_demod_debug = DBG_INFO;
+
+/*use this flag to mark the new method for dvbc channel fast search
+ *it's disabled as default, can be enabled if needed
+ *we can make it always enabled after all testing are passed
+ */
+static unsigned int demod_dvbc_speedup_en = 1;
+
+
+#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",
+ "tl1",
+ "tm2",
+};
+
+#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*/
+};
+
+static const char * const name_fe_n_mode[] = {
+ "AM_FE_UNKNOWN_N",
+ "AM_FE_QPSK_N",
+ "AM_FE_QAM_N",
+ "AM_FE_OFDM_N",
+ "AM_FE_ATSC_N",
+ "AM_FE_DTMB_N",
+ "AM_FE_ISDBT_N",
+ "AM_FE_NUM",
+};
+
+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 enum demod_md 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 demod_md demod_get_current_mode(void)
+{
+ return demod_mode_para;
+}
+
+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();
+#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[3];
+ 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[0]);
+ strength = dtmb_get_power_strength(agc_if_gain[0]);
+ }
+ 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[3], 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[0]);
+ strength = dtmb_get_power_strength(agc_if_gain[0]);
+ }
+ 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 && strlen(name_ic[ic_v]) < 10) {
+ strcpy(soc_version, name_ic[ic_v]);
+ strcat(soc_version, "-");
+ } else {
+ strcpy(soc_version, "other-");
+ }
+ if (strlen(demod_version) < 8)
+ 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) {
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ if (atsc_read_reg_v4(0x2e) >= 0x76)
+ 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;
+ }
+ } 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[4];
+enum ddemod_timer_s {
+ D_TIMER_DETECT,
+ D_TIMER_SET,
+ D_TIMER_DBG1,
+ D_TIMER_DBG2,
+};
+int timer_set_max(enum ddemod_timer_s tmid, unsigned int max_val)
+{
+ gtimer[tmid].max = max_val;
+ return 0;
+}
+int timer_begain(enum ddemod_timer_s tmid)
+{
+ gtimer[tmid].start = jiffies_to_msecs(jiffies);
+ gtimer[tmid].enable = 1;
+
+ PR_DBG("st %d=%d\n", tmid, (int)gtimer[tmid].start);
+ return 0;
+}
+int timer_disable(enum ddemod_timer_s tmid)
+{
+
+ gtimer[tmid].enable = 0;
+
+ return 0;
+}
+
+int timer_is_en(enum ddemod_timer_s tmid)
+{
+ return gtimer[tmid].enable;
+}
+
+int timer_not_enough(enum ddemod_timer_s tmid)
+{
+ int ret = 0;
+ unsigned int time;
+
+ if (gtimer[tmid].enable) {
+ time = jiffies_to_msecs(jiffies);
+ if ((time - gtimer[tmid].start) < gtimer[tmid].max) {
+ PR_DBG("now=%d\n", (int)time);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+int timer_is_enough(enum ddemod_timer_s tmid)
+{
+ int ret = 0;
+ unsigned int time;
+
+ /*Signal stability takes 200ms */
+ if (gtimer[tmid].enable) {
+ time = jiffies_to_msecs(jiffies);
+ if ((time - gtimer[tmid].start) >= gtimer[tmid].max) {
+ PR_DBG("now=%d\n", (int)time);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+int timer_tuner_not_enough(void)
+{
+ int ret = 0;
+ unsigned int time;
+ enum ddemod_timer_s tmid;
+
+ tmid = D_TIMER_DETECT;
+
+ /*Signal stability takes 200ms */
+ if (gtimer[tmid].enable) {
+ time = jiffies_to_msecs(jiffies);
+ if ((time - gtimer[tmid].start) < 200) {
+ PR_DBG("nowt=%d\n", (int)time);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+
+unsigned int demod_get_adc_clk(void)
+{
+ return demod_status.adc_freq;
+}
+
+unsigned int demod_get_sys_clk(void)
+{
+ return demod_status.clk_freq;
+}
+
+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 = 0;
+
+ /*check tuner*/
+ if (!timer_tuner_not_enough()) {
+ strenth = tuner_get_ch_power2();
+
+ /*agc control,fine tune strength*/
+ if (is_ic_ver(IC_VER_TL1) && (dtvdd_devp->pin_name != NULL) &&
+ (strncmp(fe->ops.tuner_ops.info.name, "r842", 4)
+ == 0)) {
+ strenth += 22;
+
+ if (strenth <= -80)
+ strenth = dvbc_get_power_strength(
+ qam_read_reg(0x27) & 0x7ff, strenth);
+ }
+
+ if (strenth < -87) {
+ *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(D_TIMER_DETECT)) {
+ *status = 0;
+ PR_DBG("s=0\n");
+ } else {
+ *status = FE_TIMEDOUT;
+ timer_disable(D_TIMER_DETECT);
+ }
+ }
+
+ if (last_lock != ilock) {
+ PR_DBG("%s.\n",
+ ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!");
+ last_lock = ilock;
+ }
+
+ return 0;
+}
+
+static int demod_dvbc_speed_up(enum fe_status *status)
+{
+ unsigned int cnt, i, sts, check_ok = 0;
+ struct aml_demod_sts demod_sts;
+ const int dvbc_count = 5;
+ int ilock = 0;
+
+ if (*status == 0) {
+ for (cnt = 0; cnt < 10; cnt++) {
+ demod_sts.ch_sts = dvbc_get_ch_sts();
+
+ if (demod_sts.ch_sts & 0x1) {
+ /*have signal*/
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL |
+ FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ ilock = 1;
+ check_ok = 1;
+ } else {
+ for (i = 0; i < dvbc_count; i++) {
+ msleep(25);
+ sts = dvbc_get_status();
+
+ if (sts >= 0x3)
+ break;
+ }
+
+ PR_DBG("[rsj]dvbc_status is 0x%x\n", sts);
+
+ if (sts < 0x3) {
+ *status = FE_TIMEDOUT;
+ ilock = 0;
+ check_ok = 1;
+ timer_disable(D_TIMER_DETECT);
+ }
+ }
+
+ if (check_ok == 1)
+ break;
+
+ msleep(20);
+ }
+ }
+
+ if (last_lock != ilock) {
+ PR_DBG("%s : %s.\n", __func__,
+ 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 tuner_sr;
+
+
+#if 0
+ if (fe->ops.tuner_ops.get_strength)
+ tn_strength = fe->ops.tuner_ops.get_strength(fe);
+ *strength = 256 - tn_strength;
+#else
+ if (is_ic_ver(IC_VER_TL1) &&
+ (dtvdd_devp->pin_name != NULL) &&
+ (strncmp(fe->ops.tuner_ops.info.name, "r842", 4) == 0)) {
+ tuner_sr = tuner_get_ch_power2();
+ tuner_sr += 22;
+
+ if (tuner_sr <= -80)
+ tuner_sr = dvbc_get_power_strength(
+ qam_read_reg(0x27) & 0x7ff, tuner_sr);
+
+ if (tuner_sr < -100)
+ *strength = 0;
+ else
+ *strength = tuner_sr + 100;
+ } else
+ *strength = tuner_get_ch_power3();
+#endif
+
+ 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(D_TIMER_DETECT, 4000);*/
+ /*timer_begain(D_TIMER_DETECT);*/
+ 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 (!is_ic_ver(IC_VER_TL1) && !is_ic_ver(IC_VER_TM2)) {
+ 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)
+{
+ #if 0
+ /*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);
+ #endif
+
+ 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;
+ }
+
+ if (is_ic_ver(IC_VER_TL1)) {
+ sys.adc_clk = ADC_CLK_24M;
+ /*for timeshift mosaic issue,already fixed with tm2*/
+ sys.demod_clk = Demod_Clk_167M;
+ demod_status.tmp = Cry_mode;
+ } else if (is_ic_ver(IC_VER_TM2)) {
+ sys.adc_clk = ADC_CLK_24M;
+ sys.demod_clk = Demod_Clk_250M;
+ 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(D_TIMER_DETECT)) {
+ ilock = 0;
+ *status = 0;
+ PR_INFO("timer not enough\n");
+
+ } else {
+ ilock = 0;
+ *status = FE_TIMEDOUT;
+ timer_disable(D_TIMER_DETECT);
+ }
+ }
+ 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);*/
+
+ *strength = tuner_get_ch_power3();
+
+ 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;
+
+
+
+
+ /*////////////////////////////////////*/
+ /* 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_HW;
+
+ switch (nmode) {
+ case AM_FE_QPSK_N:
+ break;
+
+ case AM_FE_QAM_N:
+ /*dvbc*/
+ ret = DVBFE_ALGO_HW;
+ break;
+
+ case AM_FE_OFDM_N:
+ case AM_FE_ISDBT_N:
+ /*dvbt*/
+ ret = DVBFE_ALGO_HW;
+
+ 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 (!is_ic_ver(IC_VER_TL1) && !is_ic_ver(IC_VER_TM2)) {
+ 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;
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ if (timer_not_enough(D_TIMER_DETECT)) {
+ *status = 0;
+ PR_DBG("s=0\n");
+ } else {
+ *status = FE_TIMEDOUT;
+ timer_disable(D_TIMER_DETECT);
+ }
+ } else {
+ *status = FE_TIMEDOUT;
+ }
+ #if 0
+ if (ats_thread_flg)
+ *status = FE_TIMEDOUT;
+ else
+ *status = 0;
+ #endif
+
+ }
+#if 1 /*debug only*/
+ if (last_lock != ilock) {
+ PR_INFO("%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 */
+ strength = tuner_get_ch_power2();
+
+ 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)
+{
+ int strenth;
+
+ strenth = tuner_get_ch_power(fe);
+/* struct aml_fe *afe = fe->demodulator_priv;*/
+ /*struct aml_fe_dev *dev = afe->dtv_demod; */
+ if (is_ic_ver(IC_VER_TL1) && (dtvdd_devp->pin_name != NULL) &&
+ (strncmp(fe->ops.tuner_ops.info.name, "r842", 4) == 0)) {
+ if ((fe->dtv_property_cache.modulation <= QAM_AUTO) &&
+ (fe->dtv_property_cache.modulation != QPSK))
+ strenth += 18;
+ else {
+ strenth += 15;
+ if (strenth <= -80)
+ strenth = atsc_get_power_strength(
+ atsc_read_reg_v4(0x44) & 0xfff,
+ strenth);
+ }
+
+ if (strenth < -100)
+ *strength = 0;
+ else
+ *strength = strenth + 100;
+ } else
+ *strength = tuner_get_ch_power3();
+
+ 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;
+ union ATSC_DEMOD_REG_0X6A_BITS Val_0x6a;
+ union ATSC_CNTR_REG_0X20_BITS Val_0x20;
+ int nco_rate;
+ /*[0]: specturm inverse(1),normal(0); [1]:if_frequency*/
+ unsigned int tuner_freq[2] = {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);*/
+ /*sys_clk=167M*/
+ if (!is_ic_ver(IC_VER_TM2))
+ 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;
+
+ if (is_ic_ver(IC_VER_TL1)) {
+ /*for timeshift mosaic issue,already fixed with tm2*/
+ demod_status.clk_freq = Demod_Clk_167M;
+ nco_rate = (demod_status.adc_freq * 256)
+ / demod_status.clk_freq + 2;
+ front_write_reg_v4(0x20,
+ ((front_read_reg_v4(0x20) & ~0xff)
+ | (nco_rate & 0xff)));
+ /*for timeshift mosaic issue,already fixed with tm2*/
+ front_write_reg_v4(0x2f, 0x5);
+ } else if (is_ic_ver(IC_VER_TM2)) {
+ nco_rate = (demod_status.adc_freq * 256)
+ / demod_status.clk_freq + 2;
+ front_write_reg_v4(0x20,
+ ((front_read_reg_v4(0x20) & ~0xff)
+ | (nco_rate & 0xff)));
+ }
+
+ dvbc_set_ch(&demod_status, /*&demod_i2c, */¶m_j83b);
+
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ qam_write_reg(0x7, 0x10f33);
+
+ /*don't bypass afifo,can run demod at 250M
+ *for timeshift mosaic issue
+ */
+ if (is_ic_ver(IC_VER_TM2))
+ qam_write_reg(0x87,
+ qam_read_reg(0x87) & 0xfffffffe);
+
+ set_j83b_filter_reg_v4();
+ qam_write_reg(0x12, 0x50e1000);
+ qam_write_reg(0x30, 0x41f2f69);
+ }
+ } else if (c->modulation > QAM_AUTO) {
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ Val_0x6a.bits = atsc_read_reg_v4(ATSC_DEMOD_REG_0X6A);
+ Val_0x6a.b.peak_thd = 0x6;//Let CCFO Quality over 6
+ atsc_write_reg_v4(ATSC_DEMOD_REG_0X6A, Val_0x6a.bits);
+ atsc_write_reg_v4(ATSC_EQ_REG_0XA5, 0x8c);
+
+ if (fe->ops.tuner_ops.get_if_frequency)
+ fe->ops.tuner_ops.
+ get_if_frequency(fe, tuner_freq);
+
+ /*bit 2: invert specturm, for r842 tuner AGC control*/
+ if (tuner_freq[0] == 1)
+ atsc_write_reg_v4(ATSC_DEMOD_REG_0X56, 0x4);
+ else
+ atsc_write_reg_v4(ATSC_DEMOD_REG_0X56, 0x0);
+
+ if (demod_status.adc_freq == ADC_CLK_24M) {
+ atsc_write_reg_v4(ATSC_DEMOD_REG_0X54,
+ 0x1aaaaa);
+
+ atsc_write_reg_v4(ATSC_DEMOD_REG_0X55,
+ 0x3ae28d);
+
+ atsc_write_reg_v4(ATSC_DEMOD_REG_0X6E,
+ 0x16e3600);
+ }
+
+ /*for timeshift mosaic issue*/
+ atsc_write_reg_v4(0x12, 0x18);
+ Val_0x20.bits = atsc_read_reg_v4(ATSC_CNTR_REG_0X20);
+ Val_0x20.b.cpu_rst = 1;
+ atsc_write_reg_v4(ATSC_CNTR_REG_0X20, Val_0x20.bits);
+ Val_0x20.b.cpu_rst = 0;
+ atsc_write_reg_v4(ATSC_CNTR_REG_0X20, Val_0x20.bits);
+ usleep_range(5000, 5001);
+ } else {
+ 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;
+ int cnt;
+ int check_ok;
+
+ /*tuner strength*/
+ if (dvb_tuner_delay > 9)
+ msleep(dvb_tuner_delay);
+
+ strenth = tuner_get_ch_power(fe);
+
+ /*agc control,fine tune strength*/
+ if (is_ic_ver(IC_VER_TL1) && (dtvdd_devp->pin_name != NULL) &&
+ (strncmp(fe->ops.tuner_ops.info.name, "r842", 4) == 0)) {
+ strenth += 15;
+ if (strenth <= -80)
+ strenth = atsc_get_power_strength(
+ atsc_read_reg_v4(0x44) & 0xfff, strenth);
+ }
+
+ if (strenth < THRD_TUNER_STRENTH_ATSC) {
+ *status = FE_TIMEDOUT;
+ PR_ATSC("tuner:no signal!\n");
+ return;
+ }
+ #define CNT_FIRST_ATSC (2)
+ check_ok = 0;
+
+ for (cnt = 0; cnt < CNT_FIRST_ATSC; cnt++) {
+ if (!is_ic_ver(IC_VER_TL1) && !is_ic_ver(IC_VER_TM2))
+ gxtv_demod_atsc_read_ucblocks(fe, &ucblocks);
+
+ gxtv_demod_atsc_read_status(fe, &s);
+
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ *status = s;
+ break;
+ }
+
+ // *status = s;
+
+ if (s != 0x1f) {
+ gxtv_demod_atsc_read_ber(fe, &atsc_status);
+ if ((atsc_status < 0x60)) {
+ *status = FE_TIMEDOUT;
+ check_ok = 1;
+ }
+ } else {
+ check_ok = 1;
+ *status = s;
+ }
+
+ if (check_ok)
+ break;
+
+ }
+ PR_ATSC("%s,detect=0x%x,cnt=%d\n", __func__,
+ (unsigned int)*status, cnt);
+}
+
+
+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;
+ enum fe_status cs;
+ int cnt;
+ int check_ok;
+
+ j83b_status = 0;
+
+ /*tuner:*/
+ if (dvb_tuner_delay > 9)
+ msleep(dvb_tuner_delay);
+
+ strenth = tuner_get_ch_power(fe);
+
+ /*agc control,fine tune strength*/
+ if (is_ic_ver(IC_VER_TL1) && (dtvdd_devp->pin_name != NULL) &&
+ (strncmp(fe->ops.tuner_ops.info.name, "r842", 4) == 0))
+ strenth += 18;
+
+ if (strenth < THRD_TUNER_STRENTH_J83) {
+ *s = FE_TIMEDOUT;
+ PR_ATSC("tuner:no signal!j83\n");
+ return 0;
+ }
+ check_ok = 0;
+
+ /*first check signal max time*/
+ #define CNT_FIRST (10)
+
+ for (cnt = 0; cnt < CNT_FIRST; cnt++) {
+ gxtv_demod_atsc_read_status(fe, &cs);
+
+ if (cs != 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;
+ check_ok = 1;
+ }
+
+ } else {
+ /*have signal*/
+ *s = cs;
+ check_ok = 1;
+ }
+
+ if (check_ok)
+ break;
+
+ msleep(50);
+ }
+
+
+ if (!check_ok)
+ *s = FE_TIMEDOUT;
+
+ PR_ATSC("j83 first:cnt:%d,sgn:0x%x\n", cnt, *s);
+ return 0;
+}
+static int atsc_j83b_polling(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("+7+");
+
+ j83b_status = 0;
+ strenth = tuner_get_ch_power(fe);
+ if (strenth < THRD_TUNER_STRENTH_J83) {
+ *s = FE_TIMEDOUT;
+ PR_DBGL("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, enum fe_status *status)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (!demod_thread)
+ return;
+
+ if (c->modulation == QPSK) {
+ PR_DBG("mode is qpsk, return;\n");
+ /*return;*/
+ } else if (c->modulation <= QAM_AUTO) {
+ atsc_j83b_polling(fe, status);
+ } else {
+ atsc_thread();
+ gxtv_demod_atsc_read_status(fe, status);
+ }
+
+
+
+}
+
+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/2;
+ 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 (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2))
+ timer_begain(D_TIMER_DETECT);
+
+ 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 1
+ if (!dtvdd_devp->en_detect) {
+ PR_DBGL("tune:not enable\n");
+ return 0;
+ }
+#endif
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ if (c->modulation > QAM_AUTO)
+ atsc_detect_first(fe, status);
+ else if (c->modulation <= QAM_AUTO &&
+ (c->modulation != QPSK))
+ atsc_j83b_detect_first(fe, status);
+ } else {
+ atsc_polling(fe, status);
+ }
+
+ return 0;
+
+}
+
+static int gxtv_demod_dvbt_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.
+ */
+
+ *delay = HZ/2;
+
+ /*PR_ATSC("%s:\n", __func__);*/
+#if 1
+ if (re_tune) {
+
+ timer_begain(D_TIMER_DETECT);
+ PR_INFO("%s:\n", __func__);
+ dtvdd_devp->en_detect = 1; /*fist set*/
+
+ gxtv_demod_dvbt_set_frontend(fe);
+ gxtv_demod_dvbt_read_status(fe, status);
+ return 0;
+ }
+#endif
+ if (!dtvdd_devp->en_detect) {
+ PR_DBGL("tune:not enable\n");
+ return 0;
+ }
+ /*polling*/
+ gxtv_demod_dvbt_read_status(fe, status);
+
+ if (*status & FE_HAS_LOCK) {
+ timer_disable(D_TIMER_SET);
+ } else {
+ if (!timer_is_en(D_TIMER_SET))
+ timer_begain(D_TIMER_SET);
+ }
+
+ if (timer_is_enough(D_TIMER_SET)) {
+ gxtv_demod_dvbt_set_frontend(fe);
+ timer_disable(D_TIMER_SET);
+ }
+
+
+
+ return 0;
+
+}
+
+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;*/
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2))
+ sys.demod_clk = Demod_Clk_250M;
+ else
+ sys.demod_clk = Demod_Clk_225M;
+ 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)) {
+ if (!is_ic_ver(IC_VER_TL1) && !is_ic_ver(IC_VER_TM2))
+ 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();
+
+ 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)
+{
+ *ber = 0;
+
+ return 0;
+}
+
+static int gxtv_demod_dtmb_read_signal_strength
+ (struct dvb_frontend *fe, u16 *strength)
+{
+ int tuner_sr;
+
+ if (is_ic_ver(IC_VER_TL1) &&
+ (dtvdd_devp->pin_name != NULL) &&
+ (strncmp(fe->ops.tuner_ops.info.name, "r842", 4) == 0)) {
+ tuner_sr = tuner_get_ch_power2();
+ tuner_sr += 16;
+
+ if (tuner_sr < -100)
+ *strength = 0;
+ else
+ *strength = tuner_sr + 100;
+ } else
+ *strength = tuner_get_ch_power3();
+ 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;
+
+ if (!demod_thread)
+ return 0;
+
+ 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 if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2)) {
+ sys.adc_clk = ADC_CLK_24M;
+ sys.demod_clk = Demod_Clk_250M;
+ } 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
+unsigned int demod_dvbc_get_fast_search(void)
+{
+ return demod_dvbc_speedup_en;
+}
+
+void demod_dvbc_set_fast_search(unsigned int en)
+{
+ if (en)
+ demod_dvbc_speedup_en = 1;
+ else
+ demod_dvbc_speedup_en = 0;
+}
+
+void demod_dvbc_fsm_reset(void)
+{
+ //qam_write_reg(0x7, 0xf23);
+ qam_write_reg(0x7, qam_read_reg(0x7) & ~(1 << 4));
+ qam_write_reg(0x3a, 0x0);
+ //qam_write_reg(0x7, 0xf33);
+ qam_write_reg(0x7, qam_read_reg(0x7) | (1 << 4));
+ qam_write_reg(0x3a, 0x4);
+}
+
+//return val : 0=no signal,1=has signal,2=waiting
+unsigned int demod_dvbc_64_256_auto_fast(unsigned int *delay)
+{
+ static unsigned int times, no_sig_cnt;
+ static unsigned int qam64 = 1;
+
+ if (tuner_get_ch_power2() < -87)
+ return 0;
+
+ times++;
+ PR_DVBC("fast search : times = %d\n", times);
+ if (times < 6)
+ *delay = HZ / 8;//125ms
+ else
+ *delay = HZ / 2;//500ms
+
+ if ((qam_read_reg(0x31) & 0xf) < 3) {
+ no_sig_cnt++;
+
+ if (no_sig_cnt == 2 && times == 2) {//250ms
+ no_sig_cnt = 0;
+ times = 0;
+ *delay = HZ / 4;
+ qam64 = 1;
+ return 0;
+ }
+ } else if ((qam_read_reg(0x31) & 0xf) == 5) {
+ no_sig_cnt = 0;
+ times = 0;
+ *delay = HZ / 4;
+ qam64 = 1;
+ return 1;
+ }
+
+ if (times == 14) {
+ times = 0;
+ no_sig_cnt = 0;
+ *delay = HZ / 4;
+ qam64 = 1;
+ return 0;
+ }
+
+ qam64 = !qam64;
+
+ PR_DVBC("fast search : qam64 = %d\n", qam64);
+ if (qam64)
+ demod_dvbc_set_qam(2);//64qam
+ else
+ demod_dvbc_set_qam(4);//256qam
+
+ demod_dvbc_fsm_reset();
+
+ return 2;
+}
+
+//return val : 0=no signal,1=has signal,2=waiting
+unsigned int demod_dvbc_fast_search(unsigned int *delay)
+{
+ static unsigned int times, no_sig_cnt;
+
+ if (tuner_get_ch_power2() < -87)
+ return 0;
+
+ times++;
+ PR_DVBC("fast search : times = %d\n", times);
+ if (times < 3)
+ *delay = HZ / 8;//125ms
+ else
+ *delay = HZ / 2;//500ms
+
+ if ((qam_read_reg(0x31) & 0xf) < 3) {
+ no_sig_cnt++;
+
+ if (no_sig_cnt == 2 && times == 2) {//250ms
+ no_sig_cnt = 0;
+ times = 0;
+ *delay = HZ / 4;
+ return 0;
+ }
+ } else if ((qam_read_reg(0x31) & 0xf) == 5) {
+ no_sig_cnt = 0;
+ times = 0;
+ *delay = HZ / 4;
+ return 1;
+ }
+
+ if (times == 7) {
+ times = 0;
+ no_sig_cnt = 0;
+ *delay = HZ / 4;
+ return 0;
+ }
+
+ demod_dvbc_fsm_reset();
+
+ return 2;
+}
+
+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 sig_flg;
+ static unsigned int fast_search_finish = 1;
+ /*unsigned int up_delay;*/
+ /*unsigned int firstdetet;*/
+
+ *delay = HZ / 4;
+
+ if (!demod_thread)
+ return 0;
+
+ if (re_tune) {
+ /*first*/
+ dtvdd_devp->en_detect = 1;
+
+ gxtv_demod_dvbc_set_frontend(fe);
+
+ if (demod_dvbc_speedup_en == 1) {
+ fast_search_finish = 0;
+ *status = 0;
+ *delay = HZ / 8;
+ qam_write_reg(0x65, 0x400c);
+ qam_write_reg(0x60, 0x10466000);
+ qam_write_reg(0xac, (qam_read_reg(0xac) & (~0xff00))
+ | 0x800);
+ qam_write_reg(0xae, (qam_read_reg(0xae)
+ & (~0xff000000)) | 0x8000000);
+
+ if (fe->dtv_property_cache.modulation == QAM_AUTO)
+ demod_dvbc_set_qam(2);//64 QAM
+ } else
+ qam_write_reg(0x65, 0x800c);
+
+ if (demod_dvbc_speedup_en == 1)
+ return 0;
+
+ /*timer_set_max(D_TIMER_DETECT, 4000);*/
+ timer_begain(D_TIMER_DETECT);
+ gxtv_demod_dvbc_read_status_timer(fe, status);
+
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2))
+ demod_dvbc_speed_up(status);
+
+ PR_DBG("tune finish!\n");
+
+ return ret;
+ }
+
+ if (!dtvdd_devp->en_detect) {
+ PR_DBGL("tune:not enable\n");
+ return ret;
+ }
+
+ if (demod_dvbc_speedup_en == 1) {
+ if (!fast_search_finish) {
+ if (fe->dtv_property_cache.modulation == QAM_AUTO)
+ sig_flg = demod_dvbc_64_256_auto_fast(delay);
+ else
+ sig_flg = demod_dvbc_fast_search(delay);
+
+ switch (sig_flg) {
+ case 0:
+ *status = FE_TIMEDOUT;
+ fast_search_finish = 1;
+ PR_DVBC(">>>unlock<<<\n");
+ break;
+ case 1:
+ *status =
+ FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC;
+ fast_search_finish = 1;
+ PR_DVBC(">>>lock<<<\n");
+ break;
+ case 2:
+ *status = 0;
+ break;
+ default:
+ PR_DVBC("wrong return value\n");
+ break;
+ }
+ } else {
+ gxtv_demod_dvbc_read_status_timer(fe, status);
+ }
+ } else {
+ gxtv_demod_dvbc_read_status_timer(fe, status);
+ }
+
+ if (demod_dvbc_speedup_en == 1)
+ return 0;
+
+ #if 0
+ if (is_ic_ver(IC_VER_TL1))
+ return ret;
+ #endif
+
+ if (*status & FE_HAS_LOCK) {
+ timer_disable(D_TIMER_SET);
+ } else {
+ if (!timer_is_en(D_TIMER_SET))
+ timer_begain(D_TIMER_SET);
+ }
+
+ if (timer_is_enough(D_TIMER_SET)) {
+ gxtv_demod_dvbc_set_frontend(fe);
+ timer_disable(D_TIMER_SET);
+ }
+
+ 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 1 /**/
+ *delay = HZ / 4;
+ gxtv_demod_dtmb_read_status_old(fe, status);
+
+ if (*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
+ dtmb_poll_start_tune(DTMBM_NO_SIGNEL_CHECK);
+
+#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)*/
+bool dtmb_cma_alloc(struct amldtvdemod_device_s *devp)
+{
+ bool ret;
+
+ 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;
+ devp->flg_cma_allc = true;
+ 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");
+ ret = true;
+ } else {
+ PR_DBG("demod cma mem undefined2.\n");
+ ret = false;
+ }
+ return ret;
+}
+
+/*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 bool enter_mode(enum aml_fe_n_mode_t mode)
+{
+ /*struct aml_fe_dev *dev = fe->dtv_demod;*/
+ struct amldtvdemod_device_s *devn = dtvdd_devp;
+ int memstart_dtmb;
+ bool ret = true;
+
+ if (mode < AM_FE_NUM)
+ PR_INFO("%s:%s\n", __func__, name_fe_n_mode[mode]);
+ else
+ PR_ERR("%s:%d\n", __func__, mode);
+
+ dtvdemod_set_agc_pinmux(1);
+
+ /*-------------------*/
+ /* must enable the adc ref signal for demod, */
+ /*vdac_enable(1, VDAC_MODULE_DTV_DEMOD);*/
+ 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);
+
+ if (dtmb_cma_alloc(devn)) {
+ memstart_dtmb = devn->mem_start;
+ } else {
+ ret = false;
+ return ret;
+ }
+ } else {
+ memstart_dtmb = devn->mem_start;/*??*/
+ }
+
+ devn->act_dtmb = true;
+ dtmb_set_mem_st(memstart_dtmb);
+
+ //?, already set in Gxtv_Demod_Dtmb_Init()
+ if (!is_ic_ver(IC_VER_TL1) && !is_ic_ver(IC_VER_TM2))
+ demod_write_reg(DEMOD_TOP_REGC, 0x8);
+ } else if (mode == AM_FE_QAM_N) {
+ Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode);
+
+ /*The maximum time of signal detection is 3s*/
+ timer_set_max(D_TIMER_DETECT, 3000);
+ /*reset is 4s*/
+ timer_set_max(D_TIMER_SET, 4000);
+ } else if (mode == AM_FE_ATSC_N) {
+ Gxtv_Demod_Atsc_Init();
+
+ if (is_ic_ver(IC_VER_TL1) || is_ic_ver(IC_VER_TM2))
+ timer_set_max(D_TIMER_DETECT, 4000);
+ } else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) {
+ Gxtv_Demod_Dvbt_Init();
+ /*The maximum time of signal detection is 2s */
+ timer_set_max(D_TIMER_DETECT, 2000);
+ /*reset is 4s*/
+ timer_set_max(D_TIMER_SET, 4000);
+
+ if (devn->cma_flag == 1) {
+ PR_DBG("CMA MODE, cma flag is %d,mem size is %d",
+ devn->cma_flag,
+ devn->cma_mem_size);
+ if (dtmb_cma_alloc(devn)) {
+ memstart_dtmb = devn->mem_start;
+ } else {
+ ret = false;
+ return ret;
+ }
+ } else {
+ memstart_dtmb = devn->mem_start;/*??*/
+ }
+
+ PR_DBG("[im]memstart is %x\n", memstart_dtmb);
+ dvbt_write_reg((0x10 << 2), memstart_dtmb);
+ }
+
+ return ret;
+
+}
+
+static int leave_mode(enum aml_fe_n_mode_t mode)
+{
+/* struct aml_fe_dev *dev = fe->dtv_demod;*/
+ struct amldtvdemod_device_s *devn = dtvdd_devp;
+
+ if (mode < AM_FE_NUM)
+ PR_INFO("%s:%s\n", __func__, name_fe_n_mode[mode]);
+ else
+ PR_ERR("%s:%d\n", __func__, mode);
+
+ dtvdd_devp->en_detect = 0;
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+ dtvdd_devp->n_mode = AM_FE_UNKNOWN_N;
+
+ dtvpll_init_flag(0);
+ /*dvbc_timer_exit();*/
+ if (cci_thread)
+ dvbc_kill_cci_task();
+
+ if (mode == AM_FE_DTMB_N) {
+ if (dtvdd_devp->act_dtmb) {
+ dtmb_poll_stop(); /*polling mode*/
+ /* close arbit */
+ demod_write_reg(DEMOD_TOP_REGC, 0x0);
+ dtvdd_devp->act_dtmb = false;
+ }
+
+ if ((devn->cma_flag == 1) && dtvdd_devp->flg_cma_allc) {
+ dtmb_cma_release(devn);
+ dtvdd_devp->flg_cma_allc = false;
+ }
+ } else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) {
+ if ((devn->cma_flag == 1) && dtvdd_devp->flg_cma_allc) {
+ dtmb_cma_release(devn);
+ dtvdd_devp->flg_cma_allc = false;
+ }
+ }
+
+ adc_set_pll_cntl(0, 0x4, NULL);
+ adc_set_pll_cntl(0, 0x8, NULL);
+ demod_mode_para = UNKNOWN;
+ /* should disable the adc ref signal for demod */
+ /*vdac_enable(0, VDAC_MODULE_DTV_DEMOD);*/
+ 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,
+ },
+
+};
+
+const struct meson_ddemod_data data_tl1 = {
+ .name = "ddmode_tl1",
+ .icver = {
+ .atsc = IC_ATSC_V2,
+ .dvbt = IC_MD_NONE,
+ .dtmb = IC_DTMB_V3,
+ .dvbc = IC_DVBC_V3,
+ .reserved = 0,
+ .offset = IC_OFFS_V4,
+ .ic = IC_VER_TL1,
+ }
+};
+
+const struct meson_ddemod_data data_tm2 = {
+ .name = "ddmode_tm2",
+ .icver = {
+ .atsc = IC_ATSC_V2,
+ .dvbt = IC_MD_NONE,
+ .dtmb = IC_DTMB_V3,
+ .dvbc = IC_DVBC_V3,
+ .reserved = 0,
+ .offset = IC_OFFS_V4,
+ .ic = IC_VER_TM2,
+ }
+};
+
+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,
+ }, {
+ .compatible = "amlogic, ddemod-tl1",
+ .data = &data_tl1,
+ }, {
+ .compatible = "amlogic, ddemod-tm2",
+ .data = &data_tm2,
+ },
+ {},
+};
+
+
+
+/*
+ * 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__);
+
+ ret = of_reserved_mem_device_init(&pdev->dev);
+ if (ret != 0)
+ PR_INFO("no reserved mem.\n");
+
+
+ /*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_AMLOGIC_DTV_DEMOD) /*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_top = 0x00;
+ ireg->off_dvbc = 0x00;
+ ireg->off_dtmb = 0x00;
+ ireg->off_dvbt = 0x00;
+ ireg->off_atsc = 0x00;
+ ireg->off_front = 0x00;
+ ireg->off_isdbt = 0x00;
+
+ if (is_offset_ver(IC_OFFS_V2)) {
+ ireg->off_demod_top = 0xc00;
+ ireg->off_dvbc = 0x400;
+ ireg->off_dtmb = 0x00;
+ } else if (is_offset_ver(IC_OFFS_V3)) {
+ ireg->off_demod_top = 0xf00;
+ ireg->off_dvbc = 0xc00;
+ ireg->off_dtmb = 0x000;
+ ireg->off_dvbt = 0x400;
+ ireg->off_isdbt = ireg->off_dvbt;
+ ireg->off_atsc = 0x800;
+ } else if (is_offset_ver(IC_OFFS_V4)) {
+ ireg->off_demod_top = 0x3c00;
+ ireg->off_dvbc = 0x1000;
+ ireg->off_dtmb = 0x0000;
+ ireg->off_dvbt = 0x0400;
+ ireg->off_isdbt = 0x0800;
+ ireg->off_atsc = 0x0c00;
+ ireg->off_front = 0x3800;
+ } else {
+ PR_ERR("ic_offset_version[%d] is not support!\n", off_ver);
+ ireg->off_demod_top = 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 top:\t0x%x\n", ireg->off_demod_top);
+ 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("\tisdbt:\t0x%x\n", ireg->off_isdbt);
+ PR_INFO("\tatsc:\t0x%x\n", ireg->off_atsc);
+ PR_INFO("\tfront:\t0x%x\n", ireg->off_front);
+
+ 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);
+ if (IS_ERR(dtvdd_devp->pin)) {
+ dtvdd_devp->pin = NULL;
+ PR_ERR("get agc pins fail\n");
+ }
+ } else {
+ /*off*/
+ if (!IS_ERR_OR_NULL(dtvdd_devp->pin)) {
+ 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, VDAC_MODULE_DTV_DEMOD);
+ } else {
+ vdac_clk_gate_ctrl(0);
+ vdac_enable(0, VDAC_MODULE_DTV_DEMOD);
+ }
+}
+
+/* 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;
+
+ dtvdd_devp->state = DTVDEMOD_ST_NOT_INI;
+
+
+ /*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);
+ dtvdd_devp->flg_cma_allc = false;
+ dtvdd_devp->act_dtmb = false;
+ //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");
+
+
+ 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)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ pr_info("%s\n", __func__);
+
+ if (dtvdd_devp->state != DTVDEMOD_ST_IDLE) {
+ if (nmode != AM_FE_UNKNOWN_N)
+ leave_mode(nmode);
+ dtvdd_devp->state = DTVDEMOD_ST_IDLE;
+ }
+ adc_pll_down();
+
+}
+
+static int aml_dtvdemod_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ PR_INFO("%s, mode = %d\n", __func__, nmode);
+
+ if (nmode != AM_FE_UNKNOWN_N)
+ leave_mode(nmode);
+
+ return 0;
+}
+
+static int aml_dtvdemod_resume(struct platform_device *pdev)
+{
+ PR_INFO("%s is called\n", __func__);
+ return 0;
+}
+
+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),
+#ifdef CONFIG_PM
+ .suspend = aml_dtvdemod_suspend,
+ .resume = aml_dtvdemod_resume,
+#endif
+};
+
+
+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__);
+}
+
+#if 0
+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 < MAX_DELSYS && 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:
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+ case SYS_ANALOG:
+#endif
+ 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);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+ dtvdd_devp->n_mode = AM_FE_UNKNOWN_N;
+ return 0;
+ }
+
+ dtvdd_devp->last_delsys = cdelsys;
+
+ return 0;
+}
+#endif
+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 < MAX_DELSYS && fe->ops.delsys[ncaps]) {
+ if (fe->ops.delsys[ncaps] == cdelsys) {
+
+ support = 1;
+ break;
+ }
+ ncaps++;
+ }
+
+ if (!support) {
+ #if 0
+ if (get_dtvpll_init_flag()) {
+ /**/
+ PR_INFO("delsys:%d is not support!\n", cdelsys);
+ leave_mode(lmode);
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ dtvdd_devp->last_delsys = SYS_UNDEFINED;
+ dtvdd_devp->n_mode = AM_FE_UNKNOWN_N;
+ }
+ #endif
+ PR_INFO("delsys:%d is not support!\n", cdelsys);
+ return 0;
+ }
+
+ if (ldelsys <= END_SYS_DELIVERY && cdelsys <= END_SYS_DELIVERY) {
+ PR_DBG("%s:l=%s,c=%s\n", __func__,
+ name_fe_delivery_system[ldelsys],
+ name_fe_delivery_system[cdelsys]);
+ } else
+ PR_ERR("%s:last=%d,cur=%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:
+ return 0;
+
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+ case SYS_ANALOG:
+ if (get_dtvpll_init_flag()) {
+ PR_INFO("delsys not support : %d\n", cdelsys);
+ leave_mode(lmode);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ }
+
+ return 0;
+#endif
+ }
+
+ if (mode != AM_FE_UNKNOWN_N) {
+ if (lmode != AM_FE_UNKNOWN_N) {
+ leave_mode(lmode);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ }
+
+ if (!enter_mode(mode)) {
+ PR_INFO("enter_mode failed,leave!\n");
+ leave_mode(mode);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ return 0;
+ }
+ }
+
+ if (!get_dtvpll_init_flag()) {
+ PR_INFO("pll is not set!\n");
+ leave_mode(mode);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ return 0;
+ }
+
+ dtvdd_devp->last_delsys = cdelsys;
+ 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)
+ fe->ops.info.type = FE_OFDM;
+ else if (mode == AM_FE_DTMB_N)
+ fe->ops.info.type = FE_DTMB;
+ else if (mode == AM_FE_QAM_N)
+ fe->ops.info.type = FE_QAM;
+ else if (mode == AM_FE_ISDBT_N)
+ fe->ops.info.type = FE_ISDBT;
+
+ if (fe->ops.tuner_ops.set_config)
+ fe->ops.tuner_ops.set_config(fe, NULL);
+
+ 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)
+{
+ enum aml_fe_n_mode_t nmode = dtvdd_devp->n_mode;
+
+ if (get_dtvpll_init_flag()) {
+ PR_INFO("%s\n", __func__);
+ if (nmode != AM_FE_UNKNOWN_N)
+ leave_mode(nmode);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(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");
+ timer_begain(D_TIMER_DETECT);
+ dtvdd_devp->en_detect = 1; /*fist set*/
+ ret = gxtv_demod_dvbc_set_frontend(fe);
+ break;
+ case AM_FE_OFDM_N:
+ PR_INFO("FE_OFDM\n");
+ timer_begain(D_TIMER_DETECT);
+ dtvdd_devp->en_detect = 1; /*fist set*/
+
+ ret = gxtv_demod_dvbt_set_frontend(fe);
+
+ break;
+ case AM_FE_ISDBT_N: /*same as dvbt*/
+ PR_INFO("FE_ISDBT\n");
+
+ timer_begain(D_TIMER_DETECT);
+ dtvdd_devp->en_detect = 1; /*fist set*/
+ 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_DBGL("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_DBGL("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 = 300;
+ 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 = 500;
+ 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 = 300;
+ 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 (nmode == AM_FE_UNKNOWN_N)
+ return 0;
+
+ if (is_not_active(fe)) {
+ PR_DBGL("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_DBGL("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_DBGL("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_DBGL("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_DBGL("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;
+ }
+
+ if (get_dtvpll_init_flag()) {
+ PR_INFO("%s\n", __func__);
+ if (nmode != AM_FE_UNKNOWN_N)
+ leave_mode(nmode);
+
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
+ }
+}
+
+
+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*/
+
+ if (re_tune)
+ ;//delsys_confirm(fe);
+
+ if (nmode == AM_FE_UNKNOWN_N) {
+ *delay = HZ * 5;
+ *status = 0;
+ return 0;
+ }
+
+ if (is_not_active(fe)) {
+ *status = 0;
+ PR_DBGL("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:
+ ret = gxtv_demod_dvbt_tune(fe, re_tune, mode_flags,
+ delay, status);
+ 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;
+
+}
- .get_property = aml_dtvdm_get_property,
+
+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, SYS_ANALOG},
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod txl",
+ .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 = {
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+ .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT,
+ SYS_ANALOG, SYS_ISDBT},
+#else
+ .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT},
+#endif
+ .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,
+
+};
+
+static struct dvb_frontend_ops aml_dtvdm_tl1_ops = {
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+ .delsys = {SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_ATSC, SYS_DTMB,
+ SYS_ANALOG},
+#else
+ .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT},
+#endif
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod tl1",
+ .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_tm2_ops = {
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+ .delsys = {SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_ATSC, SYS_DTMB,
+ SYS_ANALOG},
+#else
+ .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT},
+#endif
+ .info = {
+ /*in aml_fe, it is 'amlogic dvb frontend' */
+ .name = "amlogic dtv demod tm2",
+ .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,
+
+/*-------------*/
+ .tune = aml_dtvdm_tune,
+ .get_frontend_algo = gxtv_demod_txlx_get_frontend_algo,
+
+};
+
+struct dvb_frontend *aml_dtvdm_attach(const struct demod_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;
+ case IC_VER_TL1:
+ memcpy(&fe->ops, &aml_dtvdm_tl1_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ case IC_VER_TM2:
+ memcpy(&fe->ops, &aml_dtvdm_tm2_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");