blob: bf3ba7da85f20934e140141410facd23d66bad3f [file] [log] [blame]
/*
* drivers/amlogic/media/dtv_demod/tuner_func.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/dvb/aml_demod.h>
#include "demod_func.h"
/*#include "aml_fe.h"*/
/*add to replase aml_fe_analog_set_frontend*/
void tuner_set_params(struct dvb_frontend *fe)
{
int ret = -1;
PR_INFO("%s:\n", __func__);
if (fe->ops.tuner_ops.set_params)
ret = fe->ops.tuner_ops.set_params(fe);
else
PR_ERR("error: no tuner");
}
int tuner_get_ch_power(struct dvb_frontend *fe)
{
int strength = 0;
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
s16 strengtha = 0;
#endif
if (fe != NULL) {
#if 0
if (fe->ops.tuner_ops.get_strength)
strength = fe->ops.tuner_ops.get_strength(fe);
else
PR_INFO("no tuner get_strength\n");
#endif
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
if (fe->ops.tuner_ops.get_strength) {
fe->ops.tuner_ops.get_strength(fe, &strengtha);
strength = (int)strengtha;
} else {
PR_INFO("no tuner get_strength\n");
}
#endif
}
return strength;
}
int tuner_get_ch_power2(void)
{
int strength = 0;
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
s16 strengtha = 0;
#endif
struct dvb_frontend *fe;
fe = aml_get_fe();
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
if (fe != NULL) {
if (fe->ops.tuner_ops.get_strength) {
fe->ops.tuner_ops.get_strength(fe, &strengtha);
//strength = strengtha - 256;
strength = (int)strengtha;
} else {
PR_INFO("no tuner get_strength\n");
}
}
#endif
return strength;
}
u16 tuner_get_ch_power3(void)
{
u16 strength = 0;
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
s16 strengtha = 0;
#endif
struct dvb_frontend *fe;
fe = aml_get_fe();
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
if (fe != NULL) {
if (fe->ops.tuner_ops.get_strength) {
fe->ops.tuner_ops.get_strength(fe, &strengtha);
/*from negative to positive*/
if (strengtha < -100)
strength = 0;
else
strength = strengtha + 100;
} else {
PR_INFO("no tuner get_strength\n");
}
}
#endif
return strength;
}
struct dvb_tuner_info *tuner_get_info(int type, int mode)
{
/*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */
/*mode: 0-DVBC 1-DVBT */
static struct dvb_tuner_info tinfo_null = { };
static struct dvb_tuner_info tinfo_MXL5003S[2] = {
[1] = { /*DVBT*/ .name = "Maxliner",
.frequency_min = 44000000,
.frequency_max = 885000000, }
};
static struct dvb_tuner_info tinfo_FJ2207[2] = {
[0] = { /*DVBC*/ .name = "FJ2207",
.frequency_min = 54000000,
.frequency_max = 870000000, },
[1] = { /*DVBT*/ .name = "FJ2207",
.frequency_min = 174000000,
.frequency_max = 864000000, },
};
static struct dvb_tuner_info tinfo_DCT7070[2] = {
[0] = { /*DVBC*/ .name = "DCT7070",
.frequency_min = 51000000,
.frequency_max = 860000000, }
};
static struct dvb_tuner_info tinfo_TD1316[2] = {
[1] = { /*DVBT*/ .name = "TD1316",
.frequency_min = 51000000,
.frequency_max = 858000000, }
};
static struct dvb_tuner_info tinfo_SI2176[2] = {
[0] = { /*DVBC*/
/*#error please add SI2176 code*/
.name = "SI2176",
.frequency_min = 51000000,
.frequency_max = 860000000,
}
};
struct dvb_tuner_info *tinfo[] = {
&tinfo_null,
tinfo_DCT7070,
tinfo_MXL5003S,
tinfo_FJ2207,
tinfo_TD1316,
tinfo_SI2176
};
if ((type < 0) || (type > 4) || (mode < 0) || (mode > 1))
return tinfo[0];
return &tinfo[type][mode];
}
struct agc_power_tab *tuner_get_agc_power_table(int type)
{
/*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */
static int calcE_FJ2207[31] = {
87, 118, 138, 154, 172, 197, 245,
273, 292, 312, 327, 354, 406, 430,
448, 464, 481, 505, 558, 583, 599,
616, 632, 653, 698, 725, 745, 762,
779, 801, 831 };
static int calcE_Maxliner[79] = {
543, 552, 562, 575, 586, 596, 608,
618, 627, 635, 645, 653, 662, 668,
678, 689, 696, 705, 715, 725, 733,
742, 752, 763, 769, 778, 789, 800,
807, 816, 826, 836, 844, 854, 864,
874, 884, 894, 904, 913, 923, 932,
942, 951, 961, 970, 980, 990, 1000,
1012, 1022, 1031, 1040, 1049, 1059,
1069, 1079, 1088, 1098, 1107, 1115,
1123, 1132, 1140, 1148, 1157, 1165,
1173, 1179, 1186, 1192, 1198, 1203,
1208, 1208, 1214, 1217, 1218, 1220 };
static struct agc_power_tab power_tab[] = {
[0] = { "null", 0, 0, NULL },
[1] = {
.name = "DCT7070",
.level = 0,
.ncalcE = 0,
.calcE = NULL,
},
[2] = {
.name = "Maxlear",
.level = -22,
.ncalcE = sizeof(calcE_Maxliner) / sizeof(int),
.calcE = calcE_Maxliner,
},
[3] = {
.name = "FJ2207",
.level = -62,
.ncalcE = sizeof(calcE_FJ2207) / sizeof(int),
.calcE = calcE_FJ2207,
},
[4] = {
.name = "TD1316",
.level = 0,
.ncalcE = 0,
.calcE = NULL,
},
};
if (type >= 2 && type <= 3)
return &power_tab[type];
else
return &power_tab[3];
};
int agc_power_to_dbm(int agc_gain, int ad_power, int offset, int tuner)
{
struct agc_power_tab *ptab = tuner_get_agc_power_table(tuner);
int est_rf_power;
int j;
for (j = 0; j < ptab->ncalcE; j++)
if (agc_gain <= ptab->calcE[j])
break;
est_rf_power = ptab->level - j - (ad_power >> 4) + 12 + offset;
return est_rf_power;
}
int dtmb_get_power_strength(int agc_gain)
{
int strength;
int j;
static int calcE_R840[13] = {
1010, 969, 890, 840, 800,
760, 720, 680, 670, 660,
510, 440, 368};
for (j = 0; j < sizeof(calcE_R840)/sizeof(int); j++)
if (agc_gain >= calcE_R840[j])
break;
if (agc_gain >= 440)
strength = -90+j*3;
else
strength = -56;
return strength;
}
/*tuner has 3 stage gain control, only last is controlled by demod agc*/
static int dvbc_R842[20] = {
/*-90,-89,-88, -87, -86 , -85 , -84 , -83 , -82 , -81dbm*/
1200, 1180, 1150, 1130, 1100, 1065, 1040, 1030, 1000, 970
};
int dvbc_get_power_strength(int agc_gain, int tuner_strength)
{
int strength;
int i;
for (i = 0; i < sizeof(dvbc_R842)/sizeof(int); i++)
if (agc_gain >= dvbc_R842[i])
break;
if (agc_gain >= 970)
strength = -90+i*1;
else
strength = tuner_strength + 22;
return strength;
}
static int j83b_R842[10] = {
/*-90,-89,-88, -87, -86 , -85 , -84 , -83 , -82 , -81dbm*/
1140, 1110, 1080, 1060, 1030, 1000, 980, 1000, 970, 1000,
/*-80,-79,-78, -77, -76 , -75 , -74 , -73 , -72 , -71dbm*/
/*970 , 980, 960, 970, 950, 960, 970, 980, 960, 970*/
};
int j83b_get_power_strength(int agc_gain, int tuner_strength)
{
int strength;
int i;
for (i = 0; i < sizeof(j83b_R842)/sizeof(int); i++)
if (agc_gain >= j83b_R842[i])
break;
if (agc_gain >= 970)
strength = -90+i*1;
else
strength = tuner_strength + 18;
return strength;
}
static int atsc_R842[6] = {
/*-90,-89,-88, -87, -86 , -85 , -84 , -83 , -82 , -81dbm*/
2160, 2110, 2060, 2010, 1960, 1910/*, 1870, 1910, 1860, 1900*/
};
int atsc_get_power_strength(int agc_gain, int tuner_strength)
{
int strength;
int i;
for (i = 0; i < sizeof(atsc_R842)/sizeof(int); i++)
if (agc_gain >= atsc_R842[i])
break;
if (agc_gain >= 1910)
strength = -90+i*1;
else
strength = tuner_strength;
return strength;
}