@@ -29,9 +29,19 @@ struct ts2020_priv {
2929 /* i2c details */
3030 int i2c_address ;
3131 struct i2c_adapter * i2c ;
32- u8 clk_out_div ;
32+ u8 clk_out :2 ;
33+ u8 clk_out_div :5 ;
3334 u32 frequency ;
3435 u32 frequency_div ;
36+ #define TS2020_M88TS2020 0
37+ #define TS2020_M88TS2022 1
38+ u8 tuner ;
39+ u8 loop_through :1 ;
40+ };
41+
42+ struct ts2020_reg_val {
43+ u8 reg ;
44+ u8 val ;
3545};
3646
3747static int ts2020_release (struct dvb_frontend * fe )
@@ -121,6 +131,9 @@ static int ts2020_sleep(struct dvb_frontend *fe)
121131 .len = 2
122132 };
123133
134+ if (priv -> tuner == TS2020_M88TS2022 )
135+ buf [0 ] = 0x00 ;
136+
124137 if (fe -> ops .i2c_gate_ctrl )
125138 fe -> ops .i2c_gate_ctrl (fe , 1 );
126139
@@ -137,15 +150,64 @@ static int ts2020_sleep(struct dvb_frontend *fe)
137150static int ts2020_init (struct dvb_frontend * fe )
138151{
139152 struct ts2020_priv * priv = fe -> tuner_priv ;
153+ int i ;
154+ u8 u8tmp ;
155+
156+ if (priv -> tuner == TS2020_M88TS2020 ) {
157+ ts2020_writereg (fe , 0x42 , 0x73 );
158+ ts2020_writereg (fe , 0x05 , priv -> clk_out_div );
159+ ts2020_writereg (fe , 0x20 , 0x27 );
160+ ts2020_writereg (fe , 0x07 , 0x02 );
161+ ts2020_writereg (fe , 0x11 , 0xff );
162+ ts2020_writereg (fe , 0x60 , 0xf9 );
163+ ts2020_writereg (fe , 0x08 , 0x01 );
164+ ts2020_writereg (fe , 0x00 , 0x41 );
165+ } else {
166+ static const struct ts2020_reg_val reg_vals [] = {
167+ {0x7d , 0x9d },
168+ {0x7c , 0x9a },
169+ {0x7a , 0x76 },
170+ {0x3b , 0x01 },
171+ {0x63 , 0x88 },
172+ {0x61 , 0x85 },
173+ {0x22 , 0x30 },
174+ {0x30 , 0x40 },
175+ {0x20 , 0x23 },
176+ {0x24 , 0x02 },
177+ {0x12 , 0xa0 },
178+ };
179+
180+ ts2020_writereg (fe , 0x00 , 0x01 );
181+ ts2020_writereg (fe , 0x00 , 0x03 );
182+
183+ switch (priv -> clk_out ) {
184+ case TS2020_CLK_OUT_DISABLED :
185+ u8tmp = 0x60 ;
186+ break ;
187+ case TS2020_CLK_OUT_ENABLED :
188+ u8tmp = 0x70 ;
189+ ts2020_writereg (fe , 0x05 , priv -> clk_out_div );
190+ break ;
191+ case TS2020_CLK_OUT_ENABLED_XTALOUT :
192+ u8tmp = 0x6c ;
193+ break ;
194+ default :
195+ u8tmp = 0x60 ;
196+ break ;
197+ }
198+
199+ ts2020_writereg (fe , 0x42 , u8tmp );
200+
201+ if (priv -> loop_through )
202+ u8tmp = 0xec ;
203+ else
204+ u8tmp = 0x6c ;
140205
141- ts2020_writereg (fe , 0x42 , 0x73 );
142- ts2020_writereg (fe , 0x05 , priv -> clk_out_div );
143- ts2020_writereg (fe , 0x20 , 0x27 );
144- ts2020_writereg (fe , 0x07 , 0x02 );
145- ts2020_writereg (fe , 0x11 , 0xff );
146- ts2020_writereg (fe , 0x60 , 0xf9 );
147- ts2020_writereg (fe , 0x08 , 0x01 );
148- ts2020_writereg (fe , 0x00 , 0x41 );
206+ ts2020_writereg (fe , 0x62 , u8tmp );
207+
208+ for (i = 0 ; i < ARRAY_SIZE (reg_vals ); i ++ )
209+ ts2020_writereg (fe , reg_vals [i ].reg , reg_vals [i ].val );
210+ }
149211
150212 return 0 ;
151213}
@@ -203,7 +265,14 @@ static int ts2020_set_params(struct dvb_frontend *fe)
203265 ndiv = ndiv + ndiv % 2 ;
204266 ndiv = ndiv - 1024 ;
205267
206- ret = ts2020_writereg (fe , 0x10 , 0x80 | lo );
268+ if (priv -> tuner == TS2020_M88TS2020 ) {
269+ lpf_coeff = 2766 ;
270+ ret = ts2020_writereg (fe , 0x10 , 0x80 | lo );
271+ } else {
272+ lpf_coeff = 3200 ;
273+ ret = ts2020_writereg (fe , 0x10 , 0x0b );
274+ ret |= ts2020_writereg (fe , 0x11 , 0x40 );
275+ }
207276
208277 /* Set frequency divider */
209278 ret |= ts2020_writereg (fe , 0x01 , (ndiv >> 8 ) & 0xf );
@@ -220,14 +289,24 @@ static int ts2020_set_params(struct dvb_frontend *fe)
220289 ret |= ts2020_tuner_gate_ctrl (fe , 0x08 );
221290
222291 /* Tuner RF */
223- ret |= ts2020_set_tuner_rf (fe );
292+ if (priv -> tuner == TS2020_M88TS2020 )
293+ ret |= ts2020_set_tuner_rf (fe );
224294
225295 gdiv28 = (TS2020_XTAL_FREQ / 1000 * 1694 + 500 ) / 1000 ;
226296 ret |= ts2020_writereg (fe , 0x04 , gdiv28 & 0xff );
227297 ret |= ts2020_tuner_gate_ctrl (fe , 0x04 );
228298 if (ret < 0 )
229299 return - ENODEV ;
230300
301+ if (priv -> tuner == TS2020_M88TS2022 ) {
302+ ret = ts2020_writereg (fe , 0x25 , 0x00 );
303+ ret |= ts2020_writereg (fe , 0x27 , 0x70 );
304+ ret |= ts2020_writereg (fe , 0x41 , 0x09 );
305+ ret |= ts2020_writereg (fe , 0x08 , 0x0b );
306+ if (ret < 0 )
307+ return - ENODEV ;
308+ }
309+
231310 value = ts2020_readreg (fe , 0x26 );
232311
233312 f3db = (symbol_rate * 135 ) / 200 + 2000 ;
@@ -243,8 +322,6 @@ static int ts2020_set_params(struct dvb_frontend *fe)
243322 if (mlpf_max > 63 )
244323 mlpf_max = 63 ;
245324
246- lpf_coeff = 2766 ;
247-
248325 nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
249326 (TS2020_XTAL_FREQ / 1000 ) + 1 ) / 2 ;
250327 if (nlpf > 23 )
@@ -285,6 +362,13 @@ static int ts2020_get_frequency(struct dvb_frontend *fe, u32 *frequency)
285362{
286363 struct ts2020_priv * priv = fe -> tuner_priv ;
287364 * frequency = priv -> frequency ;
365+
366+ return 0 ;
367+ }
368+
369+ static int ts2020_get_if_frequency (struct dvb_frontend * fe , u32 * frequency )
370+ {
371+ * frequency = 0 ; /* Zero-IF */
288372 return 0 ;
289373}
290374
@@ -324,6 +408,7 @@ static struct dvb_tuner_ops ts2020_tuner_ops = {
324408 .sleep = ts2020_sleep ,
325409 .set_params = ts2020_set_params ,
326410 .get_frequency = ts2020_get_frequency ,
411+ .get_if_frequency = ts2020_get_if_frequency ,
327412 .get_rf_strength = ts2020_read_signal_strength ,
328413};
329414
@@ -340,6 +425,7 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
340425
341426 priv -> i2c_address = config -> tuner_address ;
342427 priv -> i2c = i2c ;
428+ priv -> clk_out = config -> clk_out ;
343429 priv -> clk_out_div = config -> clk_out_div ;
344430 priv -> frequency_div = config -> frequency_div ;
345431 fe -> tuner_priv = priv ;
@@ -358,9 +444,13 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
358444
359445 /* Check the tuner version */
360446 buf = ts2020_readreg (fe , 0x00 );
361- if ((buf == 0x01 ) || (buf == 0x41 ) || (buf == 0x81 ))
447+ if ((buf == 0x01 ) || (buf == 0x41 ) || (buf == 0x81 )) {
362448 printk (KERN_INFO "%s: Find tuner TS2020!\n" , __func__ );
363- else {
449+ priv -> tuner = TS2020_M88TS2020 ;
450+ } else if ((buf == 0x83 ) || (buf == 0xc3 )) {
451+ printk (KERN_INFO "%s: Find tuner TS2022!\n" , __func__ );
452+ priv -> tuner = TS2020_M88TS2022 ;
453+ } else {
364454 printk (KERN_ERR "%s: Read tuner reg[0] = %d\n" , __func__ , buf );
365455 kfree (priv );
366456 return NULL ;
0 commit comments