@@ -29,9 +29,19 @@ struct ts2020_priv {
29
29
/* i2c details */
30
30
int i2c_address ;
31
31
struct i2c_adapter * i2c ;
32
- u8 clk_out_div ;
32
+ u8 clk_out :2 ;
33
+ u8 clk_out_div :5 ;
33
34
u32 frequency ;
34
35
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 ;
35
45
};
36
46
37
47
static int ts2020_release (struct dvb_frontend * fe )
@@ -121,6 +131,9 @@ static int ts2020_sleep(struct dvb_frontend *fe)
121
131
.len = 2
122
132
};
123
133
134
+ if (priv -> tuner == TS2020_M88TS2022 )
135
+ buf [0 ] = 0x00 ;
136
+
124
137
if (fe -> ops .i2c_gate_ctrl )
125
138
fe -> ops .i2c_gate_ctrl (fe , 1 );
126
139
@@ -137,15 +150,64 @@ static int ts2020_sleep(struct dvb_frontend *fe)
137
150
static int ts2020_init (struct dvb_frontend * fe )
138
151
{
139
152
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 ;
140
205
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
+ }
149
211
150
212
return 0 ;
151
213
}
@@ -203,7 +265,14 @@ static int ts2020_set_params(struct dvb_frontend *fe)
203
265
ndiv = ndiv + ndiv % 2 ;
204
266
ndiv = ndiv - 1024 ;
205
267
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
+ }
207
276
208
277
/* Set frequency divider */
209
278
ret |= ts2020_writereg (fe , 0x01 , (ndiv >> 8 ) & 0xf );
@@ -220,14 +289,24 @@ static int ts2020_set_params(struct dvb_frontend *fe)
220
289
ret |= ts2020_tuner_gate_ctrl (fe , 0x08 );
221
290
222
291
/* Tuner RF */
223
- ret |= ts2020_set_tuner_rf (fe );
292
+ if (priv -> tuner == TS2020_M88TS2020 )
293
+ ret |= ts2020_set_tuner_rf (fe );
224
294
225
295
gdiv28 = (TS2020_XTAL_FREQ / 1000 * 1694 + 500 ) / 1000 ;
226
296
ret |= ts2020_writereg (fe , 0x04 , gdiv28 & 0xff );
227
297
ret |= ts2020_tuner_gate_ctrl (fe , 0x04 );
228
298
if (ret < 0 )
229
299
return - ENODEV ;
230
300
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
+
231
310
value = ts2020_readreg (fe , 0x26 );
232
311
233
312
f3db = (symbol_rate * 135 ) / 200 + 2000 ;
@@ -243,8 +322,6 @@ static int ts2020_set_params(struct dvb_frontend *fe)
243
322
if (mlpf_max > 63 )
244
323
mlpf_max = 63 ;
245
324
246
- lpf_coeff = 2766 ;
247
-
248
325
nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
249
326
(TS2020_XTAL_FREQ / 1000 ) + 1 ) / 2 ;
250
327
if (nlpf > 23 )
@@ -285,6 +362,13 @@ static int ts2020_get_frequency(struct dvb_frontend *fe, u32 *frequency)
285
362
{
286
363
struct ts2020_priv * priv = fe -> tuner_priv ;
287
364
* 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 */
288
372
return 0 ;
289
373
}
290
374
@@ -324,6 +408,7 @@ static struct dvb_tuner_ops ts2020_tuner_ops = {
324
408
.sleep = ts2020_sleep ,
325
409
.set_params = ts2020_set_params ,
326
410
.get_frequency = ts2020_get_frequency ,
411
+ .get_if_frequency = ts2020_get_if_frequency ,
327
412
.get_rf_strength = ts2020_read_signal_strength ,
328
413
};
329
414
@@ -340,6 +425,7 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
340
425
341
426
priv -> i2c_address = config -> tuner_address ;
342
427
priv -> i2c = i2c ;
428
+ priv -> clk_out = config -> clk_out ;
343
429
priv -> clk_out_div = config -> clk_out_div ;
344
430
priv -> frequency_div = config -> frequency_div ;
345
431
fe -> tuner_priv = priv ;
@@ -358,9 +444,13 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
358
444
359
445
/* Check the tuner version */
360
446
buf = ts2020_readreg (fe , 0x00 );
361
- if ((buf == 0x01 ) || (buf == 0x41 ) || (buf == 0x81 ))
447
+ if ((buf == 0x01 ) || (buf == 0x41 ) || (buf == 0x81 )) {
362
448
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 {
364
454
printk (KERN_ERR "%s: Read tuner reg[0] = %d\n" , __func__ , buf );
365
455
kfree (priv );
366
456
return NULL ;
0 commit comments