@@ -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