blob: f4c1a3808ba64a1de8fdc8eb8f9ebc603943bd4e
1 | /* |
2 | * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; if not, write to the Free Software Foundation, Inc., |
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | * |
18 | * Description: |
19 | */ |
20 | #include <linux/kernel.h> |
21 | #include <linux/i2c.h> |
22 | #include <linux/dvb/aml_demod.h> |
23 | #include "demod_func.h" |
24 | #include "../aml_fe.h" |
25 | |
26 | int tuner_get_ch_power(struct aml_fe_dev *adap) |
27 | { |
28 | int strength = 0; |
29 | int agc_if_gain; |
30 | |
31 | struct dvb_frontend *dvbfe; |
32 | |
33 | dvbfe = get_si2177_tuner(); |
34 | if (dvbfe != NULL) |
35 | if (dvbfe->ops.tuner_ops.get_strength) |
36 | strength = dvbfe->ops.tuner_ops.get_strength(dvbfe); |
37 | if (strength <= -56) { |
38 | agc_if_gain = |
39 | ((dtmb_read_reg(DTMB_TOP_FRONT_AGC))&0x3ff); |
40 | strength = dtmb_get_power_strength(agc_if_gain); |
41 | } |
42 | |
43 | return strength; |
44 | } |
45 | |
46 | struct dvb_tuner_info *tuner_get_info(int type, int mode) |
47 | { |
48 | /*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */ |
49 | /*mode: 0-DVBC 1-DVBT */ |
50 | static struct dvb_tuner_info tinfo_null = { }; |
51 | |
52 | static struct dvb_tuner_info tinfo_MXL5003S[2] = { |
53 | [1] = { /*DVBT*/ .name = "Maxliner", |
54 | .frequency_min = 44000000, |
55 | .frequency_max = 885000000, } |
56 | }; |
57 | static struct dvb_tuner_info tinfo_FJ2207[2] = { |
58 | [0] = { /*DVBC*/ .name = "FJ2207", |
59 | .frequency_min = 54000000, |
60 | .frequency_max = 870000000, }, |
61 | [1] = { /*DVBT*/ .name = "FJ2207", |
62 | .frequency_min = 174000000, |
63 | .frequency_max = 864000000, }, |
64 | }; |
65 | static struct dvb_tuner_info tinfo_DCT7070[2] = { |
66 | [0] = { /*DVBC*/ .name = "DCT7070", |
67 | .frequency_min = 51000000, |
68 | .frequency_max = 860000000, } |
69 | }; |
70 | static struct dvb_tuner_info tinfo_TD1316[2] = { |
71 | [1] = { /*DVBT*/ .name = "TD1316", |
72 | .frequency_min = 51000000, |
73 | .frequency_max = 858000000, } |
74 | }; |
75 | static struct dvb_tuner_info tinfo_SI2176[2] = { |
76 | [0] = { /*DVBC*/ |
77 | /*#error please add SI2176 code*/ |
78 | .name = "SI2176", |
79 | .frequency_min = 51000000, |
80 | .frequency_max = 860000000, |
81 | } |
82 | }; |
83 | |
84 | struct dvb_tuner_info *tinfo[] = { |
85 | &tinfo_null, |
86 | tinfo_DCT7070, |
87 | tinfo_MXL5003S, |
88 | tinfo_FJ2207, |
89 | tinfo_TD1316, |
90 | tinfo_SI2176 |
91 | }; |
92 | |
93 | if ((type < 0) || (type > 4) || (mode < 0) || (mode > 1)) |
94 | return tinfo[0]; |
95 | |
96 | return &tinfo[type][mode]; |
97 | } |
98 | |
99 | struct agc_power_tab *tuner_get_agc_power_table(int type) |
100 | { |
101 | /*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */ |
102 | static int calcE_FJ2207[31] = { |
103 | 87, 118, 138, 154, 172, 197, 245, |
104 | 273, 292, 312, 327, 354, 406, 430, |
105 | 448, 464, 481, 505, 558, 583, 599, |
106 | 616, 632, 653, 698, 725, 745, 762, |
107 | 779, 801, 831 }; |
108 | static int calcE_Maxliner[79] = { |
109 | 543, 552, 562, 575, 586, 596, 608, |
110 | 618, 627, 635, 645, 653, 662, 668, |
111 | 678, 689, 696, 705, 715, 725, 733, |
112 | 742, 752, 763, 769, 778, 789, 800, |
113 | 807, 816, 826, 836, 844, 854, 864, |
114 | 874, 884, 894, 904, 913, 923, 932, |
115 | 942, 951, 961, 970, 980, 990, 1000, |
116 | 1012, 1022, 1031, 1040, 1049, 1059, |
117 | 1069, 1079, 1088, 1098, 1107, 1115, |
118 | 1123, 1132, 1140, 1148, 1157, 1165, |
119 | 1173, 1179, 1186, 1192, 1198, 1203, |
120 | 1208, 1208, 1214, 1217, 1218, 1220 }; |
121 | |
122 | static struct agc_power_tab power_tab[] = { |
123 | [0] = { "null", 0, 0, NULL }, |
124 | [1] = { |
125 | .name = "DCT7070", |
126 | .level = 0, |
127 | .ncalcE = 0, |
128 | .calcE = NULL, |
129 | }, |
130 | [2] = { |
131 | .name = "Maxlear", |
132 | .level = -22, |
133 | .ncalcE = sizeof(calcE_Maxliner) / sizeof(int), |
134 | .calcE = calcE_Maxliner, |
135 | }, |
136 | [3] = { |
137 | .name = "FJ2207", |
138 | .level = -62, |
139 | .ncalcE = sizeof(calcE_FJ2207) / sizeof(int), |
140 | .calcE = calcE_FJ2207, |
141 | }, |
142 | [4] = { |
143 | .name = "TD1316", |
144 | .level = 0, |
145 | .ncalcE = 0, |
146 | .calcE = NULL, |
147 | }, |
148 | }; |
149 | |
150 | if (type >= 2 && type <= 3) |
151 | return &power_tab[type]; |
152 | else |
153 | return &power_tab[3]; |
154 | }; |
155 | |
156 | int agc_power_to_dbm(int agc_gain, int ad_power, int offset, int tuner) |
157 | { |
158 | struct agc_power_tab *ptab = tuner_get_agc_power_table(tuner); |
159 | int est_rf_power; |
160 | int j; |
161 | |
162 | for (j = 0; j < ptab->ncalcE; j++) |
163 | if (agc_gain <= ptab->calcE[j]) |
164 | break; |
165 | |
166 | est_rf_power = ptab->level - j - (ad_power >> 4) + 12 + offset; |
167 | |
168 | return est_rf_power; |
169 | } |
170 | |
171 | int dtmb_get_power_strength(int agc_gain) |
172 | { |
173 | int strength; |
174 | int j; |
175 | static int calcE_R840[13] = { |
176 | 1010, 969, 890, 840, 800, |
177 | 760, 720, 680, 670, 660, |
178 | 510, 440, 368}; |
179 | for (j = 0; j < sizeof(calcE_R840)/sizeof(int); j++) |
180 | if (agc_gain >= calcE_R840[j]) |
181 | break; |
182 | if (agc_gain >= 440) |
183 | strength = -90+j*3; |
184 | else |
185 | strength = -56; |
186 | return strength; |
187 | } |
188 | |
189 | |
190 |