Merge branch 'stacking-fixes' (vfs stacking fixes from Jann)
[deliverable/linux.git] / drivers / media / tuners / mt2063.c
1 /*
2 * Driver for mt2063 Micronas tuner
3 *
4 * Copyright (c) 2011 Mauro Carvalho Chehab
5 *
6 * This driver came from a driver originally written by:
7 * Henry Wang <Henry.wang@AzureWave.com>
8 * Made publicly available by Terratec, at:
9 * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
10 * The original driver's license is GPL, as declared with MODULE_LICENSE()
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation under version 2 of the License.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 */
21
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/videodev2.h>
27
28 #include "mt2063.h"
29
30 static unsigned int debug;
31 module_param(debug, int, 0644);
32 MODULE_PARM_DESC(debug, "Set Verbosity level");
33
34 #define dprintk(level, fmt, arg...) do { \
35 if (debug >= level) \
36 printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
37 } while (0)
38
39
40 /* positive error codes used internally */
41
42 /* Info: Unavoidable LO-related spur may be present in the output */
43 #define MT2063_SPUR_PRESENT_ERR (0x00800000)
44
45 /* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */
46 #define MT2063_SPUR_CNT_MASK (0x001f0000)
47 #define MT2063_SPUR_SHIFT (16)
48
49 /* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
50 #define MT2063_UPC_RANGE (0x04000000)
51
52 /* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
53 #define MT2063_DNC_RANGE (0x08000000)
54
55 /*
56 * Constant defining the version of the following structure
57 * and therefore the API for this code.
58 *
59 * When compiling the tuner driver, the preprocessor will
60 * check against this version number to make sure that
61 * it matches the version that the tuner driver knows about.
62 */
63
64 /* DECT Frequency Avoidance */
65 #define MT2063_DECT_AVOID_US_FREQS 0x00000001
66
67 #define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
68
69 #define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
70
71 #define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
72
73 enum MT2063_DECT_Avoid_Type {
74 MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */
75 MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */
76 MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */
77 MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */
78 };
79
80 #define MT2063_MAX_ZONES 48
81
82 struct MT2063_ExclZone_t {
83 u32 min_;
84 u32 max_;
85 struct MT2063_ExclZone_t *next_;
86 };
87
88 /*
89 * Structure of data needed for Spur Avoidance
90 */
91 struct MT2063_AvoidSpursData_t {
92 u32 f_ref;
93 u32 f_in;
94 u32 f_LO1;
95 u32 f_if1_Center;
96 u32 f_if1_Request;
97 u32 f_if1_bw;
98 u32 f_LO2;
99 u32 f_out;
100 u32 f_out_bw;
101 u32 f_LO1_Step;
102 u32 f_LO2_Step;
103 u32 f_LO1_FracN_Avoid;
104 u32 f_LO2_FracN_Avoid;
105 u32 f_zif_bw;
106 u32 f_min_LO_Separation;
107 u32 maxH1;
108 u32 maxH2;
109 enum MT2063_DECT_Avoid_Type avoidDECT;
110 u32 bSpurPresent;
111 u32 bSpurAvoided;
112 u32 nSpursFound;
113 u32 nZones;
114 struct MT2063_ExclZone_t *freeZones;
115 struct MT2063_ExclZone_t *usedZones;
116 struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
117 };
118
119 /*
120 * Parameter for function MT2063_SetPowerMask that specifies the power down
121 * of various sections of the MT2063.
122 */
123 enum MT2063_Mask_Bits {
124 MT2063_REG_SD = 0x0040, /* Shutdown regulator */
125 MT2063_SRO_SD = 0x0020, /* Shutdown SRO */
126 MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */
127 MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */
128 MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */
129 MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */
130 MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */
131 MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */
132 MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */
133 MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */
134 MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */
135 MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */
136 MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */
137 MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */
138 MT2063_NONE_SD = 0x0000 /* No shutdown bits */
139 };
140
141 /*
142 * Possible values for MT2063_DNC_OUTPUT
143 */
144 enum MT2063_DNC_Output_Enable {
145 MT2063_DNC_NONE = 0,
146 MT2063_DNC_1,
147 MT2063_DNC_2,
148 MT2063_DNC_BOTH
149 };
150
151 /*
152 * Two-wire serial bus subaddresses of the tuner registers.
153 * Also known as the tuner's register addresses.
154 */
155 enum MT2063_Register_Offsets {
156 MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */
157 MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */
158 MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */
159 MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */
160 MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */
161 MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */
162 MT2063_REG_RSVD_06, /* 0x06: Reserved */
163 MT2063_REG_LO_STATUS, /* 0x07: LO Status */
164 MT2063_REG_FIFFC, /* 0x08: FIFF Center */
165 MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */
166 MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */
167 MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */
168 MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */
169 MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */
170 MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */
171 MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */
172 MT2063_REG_RSVD_10, /* 0x10: Reserved */
173 MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */
174 MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */
175 MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */
176 MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */
177 MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */
178 MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */
179 MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */
180 MT2063_REG_RF_OV, /* 0x18: RF Attn Override */
181 MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */
182 MT2063_REG_LNA_TGT, /* 0x1A: Reserved */
183 MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */
184 MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */
185 MT2063_REG_RSVD_1D, /* 0x1D: Reserved */
186 MT2063_REG_RSVD_1E, /* 0x1E: Reserved */
187 MT2063_REG_RSVD_1F, /* 0x1F: Reserved */
188 MT2063_REG_RSVD_20, /* 0x20: Reserved */
189 MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */
190 MT2063_REG_RSVD_22, /* 0x22: Reserved */
191 MT2063_REG_RSVD_23, /* 0x23: Reserved */
192 MT2063_REG_RSVD_24, /* 0x24: Reserved */
193 MT2063_REG_RSVD_25, /* 0x25: Reserved */
194 MT2063_REG_RSVD_26, /* 0x26: Reserved */
195 MT2063_REG_RSVD_27, /* 0x27: Reserved */
196 MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */
197 MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */
198 MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */
199 MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */
200 MT2063_REG_CTRL_2C, /* 0x2C: Reserved */
201 MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */
202 MT2063_REG_RSVD_2E, /* 0x2E: Reserved */
203 MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */
204 MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */
205 MT2063_REG_RSVD_31, /* 0x31: Reserved */
206 MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */
207 MT2063_REG_RSVD_33, /* 0x33: Reserved */
208 MT2063_REG_RSVD_34, /* 0x34: Reserved */
209 MT2063_REG_RSVD_35, /* 0x35: Reserved */
210 MT2063_REG_RSVD_36, /* 0x36: Reserved */
211 MT2063_REG_RSVD_37, /* 0x37: Reserved */
212 MT2063_REG_RSVD_38, /* 0x38: Reserved */
213 MT2063_REG_RSVD_39, /* 0x39: Reserved */
214 MT2063_REG_RSVD_3A, /* 0x3A: Reserved */
215 MT2063_REG_RSVD_3B, /* 0x3B: Reserved */
216 MT2063_REG_RSVD_3C, /* 0x3C: Reserved */
217 MT2063_REG_END_REGS
218 };
219
220 struct mt2063_state {
221 struct i2c_adapter *i2c;
222
223 bool init;
224
225 const struct mt2063_config *config;
226 struct dvb_tuner_ops ops;
227 struct dvb_frontend *frontend;
228
229 u32 frequency;
230 u32 srate;
231 u32 bandwidth;
232 u32 reference;
233
234 u32 tuner_id;
235 struct MT2063_AvoidSpursData_t AS_Data;
236 u32 f_IF1_actual;
237 u32 rcvr_mode;
238 u32 ctfilt_sw;
239 u32 CTFiltMax[31];
240 u32 num_regs;
241 u8 reg[MT2063_REG_END_REGS];
242 };
243
244 /*
245 * mt2063_write - Write data into the I2C bus
246 */
247 static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
248 {
249 struct dvb_frontend *fe = state->frontend;
250 int ret;
251 u8 buf[60];
252 struct i2c_msg msg = {
253 .addr = state->config->tuner_address,
254 .flags = 0,
255 .buf = buf,
256 .len = len + 1
257 };
258
259 dprintk(2, "\n");
260
261 msg.buf[0] = reg;
262 memcpy(msg.buf + 1, data, len);
263
264 if (fe->ops.i2c_gate_ctrl)
265 fe->ops.i2c_gate_ctrl(fe, 1);
266 ret = i2c_transfer(state->i2c, &msg, 1);
267 if (fe->ops.i2c_gate_ctrl)
268 fe->ops.i2c_gate_ctrl(fe, 0);
269
270 if (ret < 0)
271 printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
272
273 return ret;
274 }
275
276 /*
277 * mt2063_write - Write register data into the I2C bus, caching the value
278 */
279 static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
280 {
281 int status;
282
283 dprintk(2, "\n");
284
285 if (reg >= MT2063_REG_END_REGS)
286 return -ERANGE;
287
288 status = mt2063_write(state, reg, &val, 1);
289 if (status < 0)
290 return status;
291
292 state->reg[reg] = val;
293
294 return 0;
295 }
296
297 /*
298 * mt2063_read - Read data from the I2C bus
299 */
300 static int mt2063_read(struct mt2063_state *state,
301 u8 subAddress, u8 *pData, u32 cnt)
302 {
303 int status = 0; /* Status to be returned */
304 struct dvb_frontend *fe = state->frontend;
305 u32 i = 0;
306
307 dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
308
309 if (fe->ops.i2c_gate_ctrl)
310 fe->ops.i2c_gate_ctrl(fe, 1);
311
312 for (i = 0; i < cnt; i++) {
313 u8 b0[] = { subAddress + i };
314 struct i2c_msg msg[] = {
315 {
316 .addr = state->config->tuner_address,
317 .flags = 0,
318 .buf = b0,
319 .len = 1
320 }, {
321 .addr = state->config->tuner_address,
322 .flags = I2C_M_RD,
323 .buf = pData + i,
324 .len = 1
325 }
326 };
327
328 status = i2c_transfer(state->i2c, msg, 2);
329 dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
330 subAddress + i, status, *(pData + i));
331 if (status < 0)
332 break;
333 }
334 if (fe->ops.i2c_gate_ctrl)
335 fe->ops.i2c_gate_ctrl(fe, 0);
336
337 if (status < 0)
338 printk(KERN_ERR "Can't read from address 0x%02x,\n",
339 subAddress + i);
340
341 return status;
342 }
343
344 /*
345 * FIXME: Is this really needed?
346 */
347 static int MT2063_Sleep(struct dvb_frontend *fe)
348 {
349 /*
350 * ToDo: Add code here to implement a OS blocking
351 */
352 msleep(100);
353
354 return 0;
355 }
356
357 /*
358 * Microtune spur avoidance
359 */
360
361 /* Implement ceiling, floor functions. */
362 #define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
363 #define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
364
365 struct MT2063_FIFZone_t {
366 s32 min_;
367 s32 max_;
368 };
369
370 static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
371 *pAS_Info,
372 struct MT2063_ExclZone_t *pPrevNode)
373 {
374 struct MT2063_ExclZone_t *pNode;
375
376 dprintk(2, "\n");
377
378 /* Check for a node in the free list */
379 if (pAS_Info->freeZones != NULL) {
380 /* Use one from the free list */
381 pNode = pAS_Info->freeZones;
382 pAS_Info->freeZones = pNode->next_;
383 } else {
384 /* Grab a node from the array */
385 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
386 }
387
388 if (pPrevNode != NULL) {
389 pNode->next_ = pPrevNode->next_;
390 pPrevNode->next_ = pNode;
391 } else { /* insert at the beginning of the list */
392
393 pNode->next_ = pAS_Info->usedZones;
394 pAS_Info->usedZones = pNode;
395 }
396
397 pAS_Info->nZones++;
398 return pNode;
399 }
400
401 static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
402 *pAS_Info,
403 struct MT2063_ExclZone_t *pPrevNode,
404 struct MT2063_ExclZone_t
405 *pNodeToRemove)
406 {
407 struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
408
409 dprintk(2, "\n");
410
411 /* Make previous node point to the subsequent node */
412 if (pPrevNode != NULL)
413 pPrevNode->next_ = pNext;
414
415 /* Add pNodeToRemove to the beginning of the freeZones */
416 pNodeToRemove->next_ = pAS_Info->freeZones;
417 pAS_Info->freeZones = pNodeToRemove;
418
419 /* Decrement node count */
420 pAS_Info->nZones--;
421
422 return pNext;
423 }
424
425 /*
426 * MT_AddExclZone()
427 *
428 * Add (and merge) an exclusion zone into the list.
429 * If the range (f_min, f_max) is totally outside the
430 * 1st IF BW, ignore the entry.
431 * If the range (f_min, f_max) is negative, ignore the entry.
432 */
433 static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
434 u32 f_min, u32 f_max)
435 {
436 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
437 struct MT2063_ExclZone_t *pPrev = NULL;
438 struct MT2063_ExclZone_t *pNext = NULL;
439
440 dprintk(2, "\n");
441
442 /* Check to see if this overlaps the 1st IF filter */
443 if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
444 && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
445 && (f_min < f_max)) {
446 /*
447 * 1 2 3 4 5 6
448 *
449 * New entry: |---| |--| |--| |-| |---| |--|
450 * or or or or or
451 * Existing: |--| |--| |--| |---| |-| |--|
452 */
453
454 /* Check for our place in the list */
455 while ((pNode != NULL) && (pNode->max_ < f_min)) {
456 pPrev = pNode;
457 pNode = pNode->next_;
458 }
459
460 if ((pNode != NULL) && (pNode->min_ < f_max)) {
461 /* Combine me with pNode */
462 if (f_min < pNode->min_)
463 pNode->min_ = f_min;
464 if (f_max > pNode->max_)
465 pNode->max_ = f_max;
466 } else {
467 pNode = InsertNode(pAS_Info, pPrev);
468 pNode->min_ = f_min;
469 pNode->max_ = f_max;
470 }
471
472 /* Look for merging possibilities */
473 pNext = pNode->next_;
474 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
475 if (pNext->max_ > pNode->max_)
476 pNode->max_ = pNext->max_;
477 /* Remove pNext, return ptr to pNext->next */
478 pNext = RemoveNode(pAS_Info, pNode, pNext);
479 }
480 }
481 }
482
483 /*
484 * Reset all exclusion zones.
485 * Add zones to protect the PLL FracN regions near zero
486 */
487 static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
488 {
489 u32 center;
490
491 dprintk(2, "\n");
492
493 pAS_Info->nZones = 0; /* this clears the used list */
494 pAS_Info->usedZones = NULL; /* reset ptr */
495 pAS_Info->freeZones = NULL; /* reset ptr */
496
497 center =
498 pAS_Info->f_ref *
499 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
500 pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
501 while (center <
502 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
503 pAS_Info->f_LO1_FracN_Avoid) {
504 /* Exclude LO1 FracN */
505 MT2063_AddExclZone(pAS_Info,
506 center - pAS_Info->f_LO1_FracN_Avoid,
507 center - 1);
508 MT2063_AddExclZone(pAS_Info, center + 1,
509 center + pAS_Info->f_LO1_FracN_Avoid);
510 center += pAS_Info->f_ref;
511 }
512
513 center =
514 pAS_Info->f_ref *
515 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
516 pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
517 while (center <
518 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
519 pAS_Info->f_LO2_FracN_Avoid) {
520 /* Exclude LO2 FracN */
521 MT2063_AddExclZone(pAS_Info,
522 center - pAS_Info->f_LO2_FracN_Avoid,
523 center - 1);
524 MT2063_AddExclZone(pAS_Info, center + 1,
525 center + pAS_Info->f_LO2_FracN_Avoid);
526 center += pAS_Info->f_ref;
527 }
528
529 if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
530 /* Exclude LO1 values that conflict with DECT channels */
531 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
532 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
533 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
534 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
535 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
536 }
537
538 if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
539 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
540 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
541 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
542 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */
543 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
544 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
545 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
546 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
547 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */
548 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
549 }
550 }
551
552 /*
553 * MT_ChooseFirstIF - Choose the best available 1st IF
554 * If f_Desired is not excluded, choose that first.
555 * Otherwise, return the value closest to f_Center that is
556 * not excluded
557 */
558 static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
559 {
560 /*
561 * Update "f_Desired" to be the nearest "combinational-multiple" of
562 * "f_LO1_Step".
563 * The resulting number, F_LO1 must be a multiple of f_LO1_Step.
564 * And F_LO1 is the arithmetic sum of f_in + f_Center.
565 * Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
566 * However, the sum must be.
567 */
568 const u32 f_Desired =
569 pAS_Info->f_LO1_Step *
570 ((pAS_Info->f_if1_Request + pAS_Info->f_in +
571 pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
572 pAS_Info->f_in;
573 const u32 f_Step =
574 (pAS_Info->f_LO1_Step >
575 pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
576 f_LO2_Step;
577 u32 f_Center;
578 s32 i;
579 s32 j = 0;
580 u32 bDesiredExcluded = 0;
581 u32 bZeroExcluded = 0;
582 s32 tmpMin, tmpMax;
583 s32 bestDiff;
584 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
585 struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
586
587 dprintk(2, "\n");
588
589 if (pAS_Info->nZones == 0)
590 return f_Desired;
591
592 /*
593 * f_Center needs to be an integer multiple of f_Step away
594 * from f_Desired
595 */
596 if (pAS_Info->f_if1_Center > f_Desired)
597 f_Center =
598 f_Desired +
599 f_Step *
600 ((pAS_Info->f_if1_Center - f_Desired +
601 f_Step / 2) / f_Step);
602 else
603 f_Center =
604 f_Desired -
605 f_Step *
606 ((f_Desired - pAS_Info->f_if1_Center +
607 f_Step / 2) / f_Step);
608
609 /*
610 * Take MT_ExclZones, center around f_Center and change the
611 * resolution to f_Step
612 */
613 while (pNode != NULL) {
614 /* floor function */
615 tmpMin =
616 floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
617
618 /* ceil function */
619 tmpMax =
620 ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
621
622 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
623 bDesiredExcluded = 1;
624
625 if ((tmpMin < 0) && (tmpMax > 0))
626 bZeroExcluded = 1;
627
628 /* See if this zone overlaps the previous */
629 if ((j > 0) && (tmpMin < zones[j - 1].max_))
630 zones[j - 1].max_ = tmpMax;
631 else {
632 /* Add new zone */
633 zones[j].min_ = tmpMin;
634 zones[j].max_ = tmpMax;
635 j++;
636 }
637 pNode = pNode->next_;
638 }
639
640 /*
641 * If the desired is okay, return with it
642 */
643 if (bDesiredExcluded == 0)
644 return f_Desired;
645
646 /*
647 * If the desired is excluded and the center is okay, return with it
648 */
649 if (bZeroExcluded == 0)
650 return f_Center;
651
652 /* Find the value closest to 0 (f_Center) */
653 bestDiff = zones[0].min_;
654 for (i = 0; i < j; i++) {
655 if (abs(zones[i].min_) < abs(bestDiff))
656 bestDiff = zones[i].min_;
657 if (abs(zones[i].max_) < abs(bestDiff))
658 bestDiff = zones[i].max_;
659 }
660
661 if (bestDiff < 0)
662 return f_Center - ((u32) (-bestDiff) * f_Step);
663
664 return f_Center + (bestDiff * f_Step);
665 }
666
667 /**
668 * gcd() - Uses Euclid's algorithm
669 *
670 * @u, @v: Unsigned values whose GCD is desired.
671 *
672 * Returns THE greatest common divisor of u and v, if either value is 0,
673 * the other value is returned as the result.
674 */
675 static u32 MT2063_gcd(u32 u, u32 v)
676 {
677 u32 r;
678
679 while (v != 0) {
680 r = u % v;
681 u = v;
682 v = r;
683 }
684
685 return u;
686 }
687
688 /**
689 * IsSpurInBand() - Checks to see if a spur will be present within the IF's
690 * bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
691 *
692 * ma mb mc md
693 * <--+-+-+-------------------+-------------------+-+-+-->
694 * | ^ 0 ^ |
695 * ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^
696 * a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2
697 *
698 * Note that some equations are doubled to prevent round-off
699 * problems when calculating fIFBW/2
700 *
701 * @pAS_Info: Avoid Spurs information block
702 * @fm: If spur, amount f_IF1 has to move negative
703 * @fp: If spur, amount f_IF1 has to move positive
704 *
705 * Returns 1 if an LO spur would be present, otherwise 0.
706 */
707 static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
708 u32 *fm, u32 * fp)
709 {
710 /*
711 ** Calculate LO frequency settings.
712 */
713 u32 n, n0;
714 const u32 f_LO1 = pAS_Info->f_LO1;
715 const u32 f_LO2 = pAS_Info->f_LO2;
716 const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
717 const u32 c = d - pAS_Info->f_out_bw;
718 const u32 f = pAS_Info->f_zif_bw / 2;
719 const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
720 s32 f_nsLO1, f_nsLO2;
721 s32 f_Spur;
722 u32 ma, mb, mc, md, me, mf;
723 u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
724
725 dprintk(2, "\n");
726
727 *fm = 0;
728
729 /*
730 ** For each edge (d, c & f), calculate a scale, based on the gcd
731 ** of f_LO1, f_LO2 and the edge value. Use the larger of this
732 ** gcd-based scale factor or f_Scale.
733 */
734 lo_gcd = MT2063_gcd(f_LO1, f_LO2);
735 gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale);
736 hgds = gd_Scale / 2;
737 gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale);
738 hgcs = gc_Scale / 2;
739 gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale);
740 hgfs = gf_Scale / 2;
741
742 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
743
744 /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */
745 for (n = n0; n <= pAS_Info->maxH1; ++n) {
746 md = (n * ((f_LO1 + hgds) / gd_Scale) -
747 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
748
749 /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */
750 if (md >= pAS_Info->maxH1)
751 break;
752
753 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
754 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
755
756 /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */
757 if (md == ma)
758 continue;
759
760 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
761 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
762 if (mc != md) {
763 f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
764 f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
765 f_Spur =
766 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
767 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
768
769 *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
770 *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
771 return 1;
772 }
773
774 /* Location of Zero-IF-spur to be checked */
775 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
776 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
777 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
778 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
779 if (me != mf) {
780 f_nsLO1 = n * (f_LO1 / gf_Scale);
781 f_nsLO2 = me * (f_LO2 / gf_Scale);
782 f_Spur =
783 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
784 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
785
786 *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
787 *fm = (((s32) f - f_Spur) / (me - n)) + 1;
788 return 1;
789 }
790
791 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
792 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
793 if (ma != mb) {
794 f_nsLO1 = n * (f_LO1 / gc_Scale);
795 f_nsLO2 = ma * (f_LO2 / gc_Scale);
796 f_Spur =
797 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
798 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
799
800 *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
801 *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
802 return 1;
803 }
804 }
805
806 /* No spurs found */
807 return 0;
808 }
809
810 /*
811 * MT_AvoidSpurs() - Main entry point to avoid spurs.
812 * Checks for existing spurs in present LO1, LO2 freqs
813 * and if present, chooses spur-free LO1, LO2 combination
814 * that tunes the same input/output frequencies.
815 */
816 static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
817 {
818 int status = 0;
819 u32 fm, fp; /* restricted range on LO's */
820 pAS_Info->bSpurAvoided = 0;
821 pAS_Info->nSpursFound = 0;
822
823 dprintk(2, "\n");
824
825 if (pAS_Info->maxH1 == 0)
826 return 0;
827
828 /*
829 * Avoid LO Generated Spurs
830 *
831 * Make sure that have no LO-related spurs within the IF output
832 * bandwidth.
833 *
834 * If there is an LO spur in this band, start at the current IF1 frequency
835 * and work out until we find a spur-free frequency or run up against the
836 * 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they
837 * will be unchanged if a spur-free setting is not found.
838 */
839 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
840 if (pAS_Info->bSpurPresent) {
841 u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */
842 u32 zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */
843 u32 zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */
844 u32 delta_IF1;
845 u32 new_IF1;
846
847 /*
848 ** Spur was found, attempt to find a spur-free 1st IF
849 */
850 do {
851 pAS_Info->nSpursFound++;
852
853 /* Raise f_IF1_upper, if needed */
854 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
855
856 /* Choose next IF1 that is closest to f_IF1_CENTER */
857 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
858
859 if (new_IF1 > zfIF1) {
860 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
861 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
862 } else {
863 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
864 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
865 }
866 zfIF1 = new_IF1;
867
868 if (zfIF1 > pAS_Info->f_if1_Center)
869 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
870 else
871 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
872
873 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
874 /*
875 * Continue while the new 1st IF is still within the 1st IF bandwidth
876 * and there is a spur in the band (again)
877 */
878 } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
879
880 /*
881 * Use the LO-spur free values found. If the search went all
882 * the way to the 1st IF band edge and always found spurs, just
883 * leave the original choice. It's as "good" as any other.
884 */
885 if (pAS_Info->bSpurPresent == 1) {
886 status |= MT2063_SPUR_PRESENT_ERR;
887 pAS_Info->f_LO1 = zfLO1;
888 pAS_Info->f_LO2 = zfLO2;
889 } else
890 pAS_Info->bSpurAvoided = 1;
891 }
892
893 status |=
894 ((pAS_Info->
895 nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
896
897 return status;
898 }
899
900 /*
901 * Constants used by the tuning algorithm
902 */
903 #define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */
904 #define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */
905 #define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */
906 #define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */
907 #define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */
908 #define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */
909 #define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */
910 #define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */
911 #define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */
912 #define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */
913 #define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */
914 #define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */
915 #define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */
916 #define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */
917 #define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */
918 #define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */
919 #define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */
920 #define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */
921
922 /*
923 * Define the supported Part/Rev codes for the MT2063
924 */
925 #define MT2063_B0 (0x9B)
926 #define MT2063_B1 (0x9C)
927 #define MT2063_B2 (0x9D)
928 #define MT2063_B3 (0x9E)
929
930 /**
931 * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
932 *
933 * @state: struct mt2063_state pointer
934 *
935 * This function returns 0, if no lock, 1 if locked and a value < 1 if error
936 */
937 static int mt2063_lockStatus(struct mt2063_state *state)
938 {
939 const u32 nMaxWait = 100; /* wait a maximum of 100 msec */
940 const u32 nPollRate = 2; /* poll status bits every 2 ms */
941 const u32 nMaxLoops = nMaxWait / nPollRate;
942 const u8 LO1LK = 0x80;
943 u8 LO2LK = 0x08;
944 int status;
945 u32 nDelays = 0;
946
947 dprintk(2, "\n");
948
949 /* LO2 Lock bit was in a different place for B0 version */
950 if (state->tuner_id == MT2063_B0)
951 LO2LK = 0x40;
952
953 do {
954 status = mt2063_read(state, MT2063_REG_LO_STATUS,
955 &state->reg[MT2063_REG_LO_STATUS], 1);
956
957 if (status < 0)
958 return status;
959
960 if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
961 (LO1LK | LO2LK)) {
962 return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
963 }
964 msleep(nPollRate); /* Wait between retries */
965 } while (++nDelays < nMaxLoops);
966
967 /*
968 * Got no lock or partial lock
969 */
970 return 0;
971 }
972
973 /*
974 * Constants for setting receiver modes.
975 * (6 modes defined at this time, enumerated by mt2063_delivery_sys)
976 * (DNC1GC & DNC2GC are the values, which are used, when the specific
977 * DNC Output is selected, the other is always off)
978 *
979 * enum mt2063_delivery_sys
980 * -------------+----------------------------------------------
981 * Mode 0 : | MT2063_CABLE_QAM
982 * Mode 1 : | MT2063_CABLE_ANALOG
983 * Mode 2 : | MT2063_OFFAIR_COFDM
984 * Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
985 * Mode 4 : | MT2063_OFFAIR_ANALOG
986 * Mode 5 : | MT2063_OFFAIR_8VSB
987 * --------------+----------------------------------------------
988 *
989 * |<---------- Mode -------------->|
990 * Reg Field | 0 | 1 | 2 | 3 | 4 | 5 |
991 * ------------+-----+-----+-----+-----+-----+-----+
992 * RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF
993 * LNARin | 0 | 0 | 3 | 3 | 3 | 3
994 * FIFFQen | 1 | 1 | 1 | 1 | 1 | 1
995 * FIFFq | 0 | 0 | 0 | 0 | 0 | 0
996 * DNC1gc | 0 | 0 | 0 | 0 | 0 | 0
997 * DNC2gc | 0 | 0 | 0 | 0 | 0 | 0
998 * GCU Auto | 1 | 1 | 1 | 1 | 1 | 1
999 * LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31
1000 * LNA Target | 44 | 43 | 43 | 43 | 43 | 43
1001 * ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0
1002 * RF max Atn | 31 | 31 | 31 | 31 | 31 | 31
1003 * PD1 Target | 36 | 36 | 38 | 38 | 36 | 38
1004 * ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0
1005 * FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5
1006 * PD2 Target | 40 | 33 | 42 | 42 | 33 | 42
1007 */
1008
1009 enum mt2063_delivery_sys {
1010 MT2063_CABLE_QAM = 0,
1011 MT2063_CABLE_ANALOG,
1012 MT2063_OFFAIR_COFDM,
1013 MT2063_OFFAIR_COFDM_SAWLESS,
1014 MT2063_OFFAIR_ANALOG,
1015 MT2063_OFFAIR_8VSB,
1016 MT2063_NUM_RCVR_MODES
1017 };
1018
1019 static const char *mt2063_mode_name[] = {
1020 [MT2063_CABLE_QAM] = "digital cable",
1021 [MT2063_CABLE_ANALOG] = "analog cable",
1022 [MT2063_OFFAIR_COFDM] = "digital offair",
1023 [MT2063_OFFAIR_COFDM_SAWLESS] = "digital offair without SAW",
1024 [MT2063_OFFAIR_ANALOG] = "analog offair",
1025 [MT2063_OFFAIR_8VSB] = "analog offair 8vsb",
1026 };
1027
1028 static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1029 static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1030 static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1031 static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1032 static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1033 static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1034 static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1035 static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1036 static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1037 static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1038 static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1039 static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1040 static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1041 static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1042
1043 /*
1044 * mt2063_set_dnc_output_enable()
1045 */
1046 static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1047 enum MT2063_DNC_Output_Enable *pValue)
1048 {
1049 dprintk(2, "\n");
1050
1051 if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
1052 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
1053 *pValue = MT2063_DNC_NONE;
1054 else
1055 *pValue = MT2063_DNC_2;
1056 } else { /* DNC1 is on */
1057 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
1058 *pValue = MT2063_DNC_1;
1059 else
1060 *pValue = MT2063_DNC_BOTH;
1061 }
1062 return 0;
1063 }
1064
1065 /*
1066 * mt2063_set_dnc_output_enable()
1067 */
1068 static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1069 enum MT2063_DNC_Output_Enable nValue)
1070 {
1071 int status = 0; /* Status to be returned */
1072 u8 val = 0;
1073
1074 dprintk(2, "\n");
1075
1076 /* selects, which DNC output is used */
1077 switch (nValue) {
1078 case MT2063_DNC_NONE:
1079 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
1080 if (state->reg[MT2063_REG_DNC_GAIN] !=
1081 val)
1082 status |=
1083 mt2063_setreg(state,
1084 MT2063_REG_DNC_GAIN,
1085 val);
1086
1087 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
1088 if (state->reg[MT2063_REG_VGA_GAIN] !=
1089 val)
1090 status |=
1091 mt2063_setreg(state,
1092 MT2063_REG_VGA_GAIN,
1093 val);
1094
1095 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1096 if (state->reg[MT2063_REG_RSVD_20] !=
1097 val)
1098 status |=
1099 mt2063_setreg(state,
1100 MT2063_REG_RSVD_20,
1101 val);
1102
1103 break;
1104 case MT2063_DNC_1:
1105 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03); /* Set DNC1GC=x */
1106 if (state->reg[MT2063_REG_DNC_GAIN] !=
1107 val)
1108 status |=
1109 mt2063_setreg(state,
1110 MT2063_REG_DNC_GAIN,
1111 val);
1112
1113 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
1114 if (state->reg[MT2063_REG_VGA_GAIN] !=
1115 val)
1116 status |=
1117 mt2063_setreg(state,
1118 MT2063_REG_VGA_GAIN,
1119 val);
1120
1121 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1122 if (state->reg[MT2063_REG_RSVD_20] !=
1123 val)
1124 status |=
1125 mt2063_setreg(state,
1126 MT2063_REG_RSVD_20,
1127 val);
1128
1129 break;
1130 case MT2063_DNC_2:
1131 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
1132 if (state->reg[MT2063_REG_DNC_GAIN] !=
1133 val)
1134 status |=
1135 mt2063_setreg(state,
1136 MT2063_REG_DNC_GAIN,
1137 val);
1138
1139 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03); /* Set DNC2GC=x */
1140 if (state->reg[MT2063_REG_VGA_GAIN] !=
1141 val)
1142 status |=
1143 mt2063_setreg(state,
1144 MT2063_REG_VGA_GAIN,
1145 val);
1146
1147 val = (state->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
1148 if (state->reg[MT2063_REG_RSVD_20] !=
1149 val)
1150 status |=
1151 mt2063_setreg(state,
1152 MT2063_REG_RSVD_20,
1153 val);
1154
1155 break;
1156 case MT2063_DNC_BOTH:
1157 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03); /* Set DNC1GC=x */
1158 if (state->reg[MT2063_REG_DNC_GAIN] !=
1159 val)
1160 status |=
1161 mt2063_setreg(state,
1162 MT2063_REG_DNC_GAIN,
1163 val);
1164
1165 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03); /* Set DNC2GC=x */
1166 if (state->reg[MT2063_REG_VGA_GAIN] !=
1167 val)
1168 status |=
1169 mt2063_setreg(state,
1170 MT2063_REG_VGA_GAIN,
1171 val);
1172
1173 val = (state->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
1174 if (state->reg[MT2063_REG_RSVD_20] !=
1175 val)
1176 status |=
1177 mt2063_setreg(state,
1178 MT2063_REG_RSVD_20,
1179 val);
1180
1181 break;
1182 default:
1183 break;
1184 }
1185
1186 return status;
1187 }
1188
1189 /*
1190 * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
1191 * the selected enum mt2063_delivery_sys type.
1192 *
1193 * (DNC1GC & DNC2GC are the values, which are used, when the specific
1194 * DNC Output is selected, the other is always off)
1195 *
1196 * @state: ptr to mt2063_state structure
1197 * @Mode: desired receiver delivery system
1198 *
1199 * Note: Register cache must be valid for it to work
1200 */
1201
1202 static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1203 enum mt2063_delivery_sys Mode)
1204 {
1205 int status = 0; /* Status to be returned */
1206 u8 val;
1207 u32 longval;
1208
1209 dprintk(2, "\n");
1210
1211 if (Mode >= MT2063_NUM_RCVR_MODES)
1212 status = -ERANGE;
1213
1214 /* RFAGCen */
1215 if (status >= 0) {
1216 val =
1217 (state->
1218 reg[MT2063_REG_PD1_TGT] & ~0x40) | (RFAGCEN[Mode]
1219 ? 0x40 :
1220 0x00);
1221 if (state->reg[MT2063_REG_PD1_TGT] != val)
1222 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1223 }
1224
1225 /* LNARin */
1226 if (status >= 0) {
1227 u8 val = (state->reg[MT2063_REG_CTRL_2C] & ~0x03) |
1228 (LNARIN[Mode] & 0x03);
1229 if (state->reg[MT2063_REG_CTRL_2C] != val)
1230 status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1231 }
1232
1233 /* FIFFQEN and FIFFQ */
1234 if (status >= 0) {
1235 val =
1236 (state->
1237 reg[MT2063_REG_FIFF_CTRL2] & ~0xF0) |
1238 (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1239 if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1240 status |=
1241 mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1242 /* trigger FIFF calibration, needed after changing FIFFQ */
1243 val =
1244 (state->reg[MT2063_REG_FIFF_CTRL] | 0x01);
1245 status |=
1246 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1247 val =
1248 (state->
1249 reg[MT2063_REG_FIFF_CTRL] & ~0x01);
1250 status |=
1251 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1252 }
1253 }
1254
1255 /* DNC1GC & DNC2GC */
1256 status |= mt2063_get_dnc_output_enable(state, &longval);
1257 status |= mt2063_set_dnc_output_enable(state, longval);
1258
1259 /* acLNAmax */
1260 if (status >= 0) {
1261 u8 val = (state->reg[MT2063_REG_LNA_OV] & ~0x1F) |
1262 (ACLNAMAX[Mode] & 0x1F);
1263 if (state->reg[MT2063_REG_LNA_OV] != val)
1264 status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1265 }
1266
1267 /* LNATGT */
1268 if (status >= 0) {
1269 u8 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x3F) |
1270 (LNATGT[Mode] & 0x3F);
1271 if (state->reg[MT2063_REG_LNA_TGT] != val)
1272 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1273 }
1274
1275 /* ACRF */
1276 if (status >= 0) {
1277 u8 val = (state->reg[MT2063_REG_RF_OV] & ~0x1F) |
1278 (ACRFMAX[Mode] & 0x1F);
1279 if (state->reg[MT2063_REG_RF_OV] != val)
1280 status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1281 }
1282
1283 /* PD1TGT */
1284 if (status >= 0) {
1285 u8 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x3F) |
1286 (PD1TGT[Mode] & 0x3F);
1287 if (state->reg[MT2063_REG_PD1_TGT] != val)
1288 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1289 }
1290
1291 /* FIFATN */
1292 if (status >= 0) {
1293 u8 val = ACFIFMAX[Mode];
1294 if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1295 val = 5;
1296 val = (state->reg[MT2063_REG_FIF_OV] & ~0x1F) |
1297 (val & 0x1F);
1298 if (state->reg[MT2063_REG_FIF_OV] != val)
1299 status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1300 }
1301
1302 /* PD2TGT */
1303 if (status >= 0) {
1304 u8 val = (state->reg[MT2063_REG_PD2_TGT] & ~0x3F) |
1305 (PD2TGT[Mode] & 0x3F);
1306 if (state->reg[MT2063_REG_PD2_TGT] != val)
1307 status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1308 }
1309
1310 /* Ignore ATN Overload */
1311 if (status >= 0) {
1312 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x80) |
1313 (RFOVDIS[Mode] ? 0x80 : 0x00);
1314 if (state->reg[MT2063_REG_LNA_TGT] != val)
1315 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1316 }
1317
1318 /* Ignore FIF Overload */
1319 if (status >= 0) {
1320 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x80) |
1321 (FIFOVDIS[Mode] ? 0x80 : 0x00);
1322 if (state->reg[MT2063_REG_PD1_TGT] != val)
1323 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1324 }
1325
1326 if (status >= 0) {
1327 state->rcvr_mode = Mode;
1328 dprintk(1, "mt2063 mode changed to %s\n",
1329 mt2063_mode_name[state->rcvr_mode]);
1330 }
1331
1332 return status;
1333 }
1334
1335 /*
1336 * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
1337 * sections of the MT2063
1338 *
1339 * @Bits: Mask bits to be cleared.
1340 *
1341 * See definition of MT2063_Mask_Bits type for description
1342 * of each of the power bits.
1343 */
1344 static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1345 enum MT2063_Mask_Bits Bits)
1346 {
1347 int status = 0;
1348
1349 dprintk(2, "\n");
1350 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
1351 if ((Bits & 0xFF00) != 0) {
1352 state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1353 status |=
1354 mt2063_write(state,
1355 MT2063_REG_PWR_2,
1356 &state->reg[MT2063_REG_PWR_2], 1);
1357 }
1358 if ((Bits & 0xFF) != 0) {
1359 state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1360 status |=
1361 mt2063_write(state,
1362 MT2063_REG_PWR_1,
1363 &state->reg[MT2063_REG_PWR_1], 1);
1364 }
1365
1366 return status;
1367 }
1368
1369 /*
1370 * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
1371 * When Shutdown is 1, any section whose power
1372 * mask is set will be shutdown.
1373 */
1374 static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1375 {
1376 int status;
1377
1378 dprintk(2, "\n");
1379 if (Shutdown == 1)
1380 state->reg[MT2063_REG_PWR_1] |= 0x04;
1381 else
1382 state->reg[MT2063_REG_PWR_1] &= ~0x04;
1383
1384 status = mt2063_write(state,
1385 MT2063_REG_PWR_1,
1386 &state->reg[MT2063_REG_PWR_1], 1);
1387
1388 if (Shutdown != 1) {
1389 state->reg[MT2063_REG_BYP_CTRL] =
1390 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1391 status |=
1392 mt2063_write(state,
1393 MT2063_REG_BYP_CTRL,
1394 &state->reg[MT2063_REG_BYP_CTRL],
1395 1);
1396 state->reg[MT2063_REG_BYP_CTRL] =
1397 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1398 status |=
1399 mt2063_write(state,
1400 MT2063_REG_BYP_CTRL,
1401 &state->reg[MT2063_REG_BYP_CTRL],
1402 1);
1403 }
1404
1405 return status;
1406 }
1407
1408 static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1409 {
1410 return f_ref * (f_LO / f_ref)
1411 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1412 }
1413
1414 /**
1415 * fLO_FractionalTerm() - Calculates the portion contributed by FracN / denom.
1416 * This function preserves maximum precision without
1417 * risk of overflow. It accurately calculates
1418 * f_ref * num / denom to within 1 HZ with fixed math.
1419 *
1420 * @num : Fractional portion of the multiplier
1421 * @denom: denominator portion of the ratio
1422 * @f_Ref: SRO frequency.
1423 *
1424 * This calculation handles f_ref as two separate 14-bit fields.
1425 * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
1426 * This is the genesis of the magic number "14" and the magic mask value of
1427 * 0x03FFF.
1428 *
1429 * This routine successfully handles denom values up to and including 2^18.
1430 * Returns: f_ref * num / denom
1431 */
1432 static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1433 {
1434 u32 t1 = (f_ref >> 14) * num;
1435 u32 term1 = t1 / denom;
1436 u32 loss = t1 % denom;
1437 u32 term2 =
1438 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1439 return (term1 << 14) + term2;
1440 }
1441
1442 /*
1443 * CalcLO1Mult()- Calculates Integer divider value and the numerator
1444 * value for a FracN PLL.
1445 *
1446 * This function assumes that the f_LO and f_Ref are
1447 * evenly divisible by f_LO_Step.
1448 *
1449 * @Div: OUTPUT: Whole number portion of the multiplier
1450 * @FracN: OUTPUT: Fractional portion of the multiplier
1451 * @f_LO: desired LO frequency.
1452 * @f_LO_Step: Minimum step size for the LO (in Hz).
1453 * @f_Ref: SRO frequency.
1454 * @f_Avoid: Range of PLL frequencies to avoid near integer multiples
1455 * of f_Ref (in Hz).
1456 *
1457 * Returns: Recalculated LO frequency.
1458 */
1459 static u32 MT2063_CalcLO1Mult(u32 *Div,
1460 u32 *FracN,
1461 u32 f_LO,
1462 u32 f_LO_Step, u32 f_Ref)
1463 {
1464 /* Calculate the whole number portion of the divider */
1465 *Div = f_LO / f_Ref;
1466
1467 /* Calculate the numerator value (round to nearest f_LO_Step) */
1468 *FracN =
1469 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1470 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1471
1472 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1473 }
1474
1475 /**
1476 * CalcLO2Mult() - Calculates Integer divider value and the numerator
1477 * value for a FracN PLL.
1478 *
1479 * This function assumes that the f_LO and f_Ref are
1480 * evenly divisible by f_LO_Step.
1481 *
1482 * @Div: OUTPUT: Whole number portion of the multiplier
1483 * @FracN: OUTPUT: Fractional portion of the multiplier
1484 * @f_LO: desired LO frequency.
1485 * @f_LO_Step: Minimum step size for the LO (in Hz).
1486 * @f_Ref: SRO frequency.
1487 * @f_Avoid: Range of PLL frequencies to avoid near
1488 * integer multiples of f_Ref (in Hz).
1489 *
1490 * Returns: Recalculated LO frequency.
1491 */
1492 static u32 MT2063_CalcLO2Mult(u32 *Div,
1493 u32 *FracN,
1494 u32 f_LO,
1495 u32 f_LO_Step, u32 f_Ref)
1496 {
1497 /* Calculate the whole number portion of the divider */
1498 *Div = f_LO / f_Ref;
1499
1500 /* Calculate the numerator value (round to nearest f_LO_Step) */
1501 *FracN =
1502 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1503 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1504
1505 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1506 8191);
1507 }
1508
1509 /*
1510 * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
1511 * used for a given input frequency.
1512 *
1513 * @state: ptr to tuner data structure
1514 * @f_in: RF input center frequency (in Hz).
1515 *
1516 * Returns: ClearTune filter number (0-31)
1517 */
1518 static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1519 {
1520 u32 RFBand;
1521 u32 idx; /* index loop */
1522
1523 /*
1524 ** Find RF Band setting
1525 */
1526 RFBand = 31; /* def when f_in > all */
1527 for (idx = 0; idx < 31; ++idx) {
1528 if (state->CTFiltMax[idx] >= f_in) {
1529 RFBand = idx;
1530 break;
1531 }
1532 }
1533 return RFBand;
1534 }
1535
1536 /*
1537 * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
1538 */
1539 static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1540 { /* RF input center frequency */
1541
1542 int status = 0;
1543 u32 LO1; /* 1st LO register value */
1544 u32 Num1; /* Numerator for LO1 reg. value */
1545 u32 f_IF1; /* 1st IF requested */
1546 u32 LO2; /* 2nd LO register value */
1547 u32 Num2; /* Numerator for LO2 reg. value */
1548 u32 ofLO1, ofLO2; /* last time's LO frequencies */
1549 u8 fiffc = 0x80; /* FIFF center freq from tuner */
1550 u32 fiffof; /* Offset from FIFF center freq */
1551 const u8 LO1LK = 0x80; /* Mask for LO1 Lock bit */
1552 u8 LO2LK = 0x08; /* Mask for LO2 Lock bit */
1553 u8 val;
1554 u32 RFBand;
1555
1556 dprintk(2, "\n");
1557 /* Check the input and output frequency ranges */
1558 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1559 return -EINVAL;
1560
1561 if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1562 || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1563 return -EINVAL;
1564
1565 /*
1566 * Save original LO1 and LO2 register values
1567 */
1568 ofLO1 = state->AS_Data.f_LO1;
1569 ofLO2 = state->AS_Data.f_LO2;
1570
1571 /*
1572 * Find and set RF Band setting
1573 */
1574 if (state->ctfilt_sw == 1) {
1575 val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1576 if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1577 status |=
1578 mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1579 }
1580 val = state->reg[MT2063_REG_CTUNE_OV];
1581 RFBand = FindClearTuneFilter(state, f_in);
1582 state->reg[MT2063_REG_CTUNE_OV] =
1583 (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1584 | RFBand);
1585 if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1586 status |=
1587 mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1588 }
1589 }
1590
1591 /*
1592 * Read the FIFF Center Frequency from the tuner
1593 */
1594 if (status >= 0) {
1595 status |=
1596 mt2063_read(state,
1597 MT2063_REG_FIFFC,
1598 &state->reg[MT2063_REG_FIFFC], 1);
1599 fiffc = state->reg[MT2063_REG_FIFFC];
1600 }
1601 /*
1602 * Assign in the requested values
1603 */
1604 state->AS_Data.f_in = f_in;
1605 /* Request a 1st IF such that LO1 is on a step size */
1606 state->AS_Data.f_if1_Request =
1607 MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1608 state->AS_Data.f_LO1_Step,
1609 state->AS_Data.f_ref) - f_in;
1610
1611 /*
1612 * Calculate frequency settings. f_IF1_FREQ + f_in is the
1613 * desired LO1 frequency
1614 */
1615 MT2063_ResetExclZones(&state->AS_Data);
1616
1617 f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1618
1619 state->AS_Data.f_LO1 =
1620 MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1621 state->AS_Data.f_ref);
1622
1623 state->AS_Data.f_LO2 =
1624 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1625 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1626
1627 /*
1628 * Check for any LO spurs in the output bandwidth and adjust
1629 * the LO settings to avoid them if needed
1630 */
1631 status |= MT2063_AvoidSpurs(&state->AS_Data);
1632 /*
1633 * MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
1634 * Recalculate the LO frequencies and the values to be placed
1635 * in the tuning registers.
1636 */
1637 state->AS_Data.f_LO1 =
1638 MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1639 state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1640 state->AS_Data.f_LO2 =
1641 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1642 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1643 state->AS_Data.f_LO2 =
1644 MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1645 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1646
1647 /*
1648 * Check the upconverter and downconverter frequency ranges
1649 */
1650 if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1651 || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1652 status |= MT2063_UPC_RANGE;
1653 if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1654 || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1655 status |= MT2063_DNC_RANGE;
1656 /* LO2 Lock bit was in a different place for B0 version */
1657 if (state->tuner_id == MT2063_B0)
1658 LO2LK = 0x40;
1659
1660 /*
1661 * If we have the same LO frequencies and we're already locked,
1662 * then skip re-programming the LO registers.
1663 */
1664 if ((ofLO1 != state->AS_Data.f_LO1)
1665 || (ofLO2 != state->AS_Data.f_LO2)
1666 || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1667 (LO1LK | LO2LK))) {
1668 /*
1669 * Calculate the FIFFOF register value
1670 *
1671 * IF1_Actual
1672 * FIFFOF = ------------ - 8 * FIFFC - 4992
1673 * f_ref/64
1674 */
1675 fiffof =
1676 (state->AS_Data.f_LO1 -
1677 f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1678 4992;
1679 if (fiffof > 0xFF)
1680 fiffof = 0xFF;
1681
1682 /*
1683 * Place all of the calculated values into the local tuner
1684 * register fields.
1685 */
1686 if (status >= 0) {
1687 state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF); /* DIV1q */
1688 state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F); /* NUM1q */
1689 state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1) /* DIV2q */
1690 |(Num2 >> 12)); /* NUM2q (hi) */
1691 state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */
1692 state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
1693
1694 /*
1695 * Now write out the computed register values
1696 * IMPORTANT: There is a required order for writing
1697 * (0x05 must follow all the others).
1698 */
1699 status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */
1700 if (state->tuner_id == MT2063_B0) {
1701 /* Re-write the one-shot bits to trigger the tune operation */
1702 status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */
1703 }
1704 /* Write out the FIFF offset only if it's changing */
1705 if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1706 (u8) fiffof) {
1707 state->reg[MT2063_REG_FIFF_OFFSET] =
1708 (u8) fiffof;
1709 status |=
1710 mt2063_write(state,
1711 MT2063_REG_FIFF_OFFSET,
1712 &state->
1713 reg[MT2063_REG_FIFF_OFFSET],
1714 1);
1715 }
1716 }
1717
1718 /*
1719 * Check for LO's locking
1720 */
1721
1722 if (status < 0)
1723 return status;
1724
1725 status = mt2063_lockStatus(state);
1726 if (status < 0)
1727 return status;
1728 if (!status)
1729 return -EINVAL; /* Couldn't lock */
1730
1731 /*
1732 * If we locked OK, assign calculated data to mt2063_state structure
1733 */
1734 state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1735 }
1736
1737 return status;
1738 }
1739
1740 static const u8 MT2063B0_defaults[] = {
1741 /* Reg, Value */
1742 0x19, 0x05,
1743 0x1B, 0x1D,
1744 0x1C, 0x1F,
1745 0x1D, 0x0F,
1746 0x1E, 0x3F,
1747 0x1F, 0x0F,
1748 0x20, 0x3F,
1749 0x22, 0x21,
1750 0x23, 0x3F,
1751 0x24, 0x20,
1752 0x25, 0x3F,
1753 0x27, 0xEE,
1754 0x2C, 0x27, /* bit at 0x20 is cleared below */
1755 0x30, 0x03,
1756 0x2C, 0x07, /* bit at 0x20 is cleared here */
1757 0x2D, 0x87,
1758 0x2E, 0xAA,
1759 0x28, 0xE1, /* Set the FIFCrst bit here */
1760 0x28, 0xE0, /* Clear the FIFCrst bit here */
1761 0x00
1762 };
1763
1764 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1765 static const u8 MT2063B1_defaults[] = {
1766 /* Reg, Value */
1767 0x05, 0xF0,
1768 0x11, 0x10, /* New Enable AFCsd */
1769 0x19, 0x05,
1770 0x1A, 0x6C,
1771 0x1B, 0x24,
1772 0x1C, 0x28,
1773 0x1D, 0x8F,
1774 0x1E, 0x14,
1775 0x1F, 0x8F,
1776 0x20, 0x57,
1777 0x22, 0x21, /* New - ver 1.03 */
1778 0x23, 0x3C, /* New - ver 1.10 */
1779 0x24, 0x20, /* New - ver 1.03 */
1780 0x2C, 0x24, /* bit at 0x20 is cleared below */
1781 0x2D, 0x87, /* FIFFQ=0 */
1782 0x2F, 0xF3,
1783 0x30, 0x0C, /* New - ver 1.11 */
1784 0x31, 0x1B, /* New - ver 1.11 */
1785 0x2C, 0x04, /* bit at 0x20 is cleared here */
1786 0x28, 0xE1, /* Set the FIFCrst bit here */
1787 0x28, 0xE0, /* Clear the FIFCrst bit here */
1788 0x00
1789 };
1790
1791 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1792 static const u8 MT2063B3_defaults[] = {
1793 /* Reg, Value */
1794 0x05, 0xF0,
1795 0x19, 0x3D,
1796 0x2C, 0x24, /* bit at 0x20 is cleared below */
1797 0x2C, 0x04, /* bit at 0x20 is cleared here */
1798 0x28, 0xE1, /* Set the FIFCrst bit here */
1799 0x28, 0xE0, /* Clear the FIFCrst bit here */
1800 0x00
1801 };
1802
1803 static int mt2063_init(struct dvb_frontend *fe)
1804 {
1805 int status;
1806 struct mt2063_state *state = fe->tuner_priv;
1807 u8 all_resets = 0xF0; /* reset/load bits */
1808 const u8 *def = NULL;
1809 char *step;
1810 u32 FCRUN;
1811 s32 maxReads;
1812 u32 fcu_osc;
1813 u32 i;
1814
1815 dprintk(2, "\n");
1816
1817 state->rcvr_mode = MT2063_CABLE_QAM;
1818
1819 /* Read the Part/Rev code from the tuner */
1820 status = mt2063_read(state, MT2063_REG_PART_REV,
1821 &state->reg[MT2063_REG_PART_REV], 1);
1822 if (status < 0) {
1823 printk(KERN_ERR "Can't read mt2063 part ID\n");
1824 return status;
1825 }
1826
1827 /* Check the part/rev code */
1828 switch (state->reg[MT2063_REG_PART_REV]) {
1829 case MT2063_B0:
1830 step = "B0";
1831 break;
1832 case MT2063_B1:
1833 step = "B1";
1834 break;
1835 case MT2063_B2:
1836 step = "B2";
1837 break;
1838 case MT2063_B3:
1839 step = "B3";
1840 break;
1841 default:
1842 printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1843 state->reg[MT2063_REG_PART_REV]);
1844 return -ENODEV; /* Wrong tuner Part/Rev code */
1845 }
1846
1847 /* Check the 2nd byte of the Part/Rev code from the tuner */
1848 status = mt2063_read(state, MT2063_REG_RSVD_3B,
1849 &state->reg[MT2063_REG_RSVD_3B], 1);
1850
1851 /* b7 != 0 ==> NOT MT2063 */
1852 if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1853 printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1854 state->reg[MT2063_REG_PART_REV],
1855 state->reg[MT2063_REG_RSVD_3B]);
1856 return -ENODEV; /* Wrong tuner Part/Rev code */
1857 }
1858
1859 printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1860
1861 /* Reset the tuner */
1862 status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1863 if (status < 0)
1864 return status;
1865
1866 /* change all of the default values that vary from the HW reset values */
1867 /* def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
1868 switch (state->reg[MT2063_REG_PART_REV]) {
1869 case MT2063_B3:
1870 def = MT2063B3_defaults;
1871 break;
1872
1873 case MT2063_B1:
1874 def = MT2063B1_defaults;
1875 break;
1876
1877 case MT2063_B0:
1878 def = MT2063B0_defaults;
1879 break;
1880
1881 default:
1882 return -ENODEV;
1883 break;
1884 }
1885
1886 while (status >= 0 && *def) {
1887 u8 reg = *def++;
1888 u8 val = *def++;
1889 status = mt2063_write(state, reg, &val, 1);
1890 }
1891 if (status < 0)
1892 return status;
1893
1894 /* Wait for FIFF location to complete. */
1895 FCRUN = 1;
1896 maxReads = 10;
1897 while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1898 msleep(2);
1899 status = mt2063_read(state,
1900 MT2063_REG_XO_STATUS,
1901 &state->
1902 reg[MT2063_REG_XO_STATUS], 1);
1903 FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1904 }
1905
1906 if (FCRUN != 0 || status < 0)
1907 return -ENODEV;
1908
1909 status = mt2063_read(state,
1910 MT2063_REG_FIFFC,
1911 &state->reg[MT2063_REG_FIFFC], 1);
1912 if (status < 0)
1913 return status;
1914
1915 /* Read back all the registers from the tuner */
1916 status = mt2063_read(state,
1917 MT2063_REG_PART_REV,
1918 state->reg, MT2063_REG_END_REGS);
1919 if (status < 0)
1920 return status;
1921
1922 /* Initialize the tuner state. */
1923 state->tuner_id = state->reg[MT2063_REG_PART_REV];
1924 state->AS_Data.f_ref = MT2063_REF_FREQ;
1925 state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1926 ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1927 state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1928 state->AS_Data.f_out = 43750000UL;
1929 state->AS_Data.f_out_bw = 6750000UL;
1930 state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1931 state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1932 state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1933 state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1934 state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1935 state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1936 state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1937 state->AS_Data.f_LO1 = 2181000000UL;
1938 state->AS_Data.f_LO2 = 1486249786UL;
1939 state->f_IF1_actual = state->AS_Data.f_if1_Center;
1940 state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1941 state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1942 state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1943 state->num_regs = MT2063_REG_END_REGS;
1944 state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1945 state->ctfilt_sw = 0;
1946
1947 state->CTFiltMax[0] = 69230000;
1948 state->CTFiltMax[1] = 105770000;
1949 state->CTFiltMax[2] = 140350000;
1950 state->CTFiltMax[3] = 177110000;
1951 state->CTFiltMax[4] = 212860000;
1952 state->CTFiltMax[5] = 241130000;
1953 state->CTFiltMax[6] = 274370000;
1954 state->CTFiltMax[7] = 309820000;
1955 state->CTFiltMax[8] = 342450000;
1956 state->CTFiltMax[9] = 378870000;
1957 state->CTFiltMax[10] = 416210000;
1958 state->CTFiltMax[11] = 456500000;
1959 state->CTFiltMax[12] = 495790000;
1960 state->CTFiltMax[13] = 534530000;
1961 state->CTFiltMax[14] = 572610000;
1962 state->CTFiltMax[15] = 598970000;
1963 state->CTFiltMax[16] = 635910000;
1964 state->CTFiltMax[17] = 672130000;
1965 state->CTFiltMax[18] = 714840000;
1966 state->CTFiltMax[19] = 739660000;
1967 state->CTFiltMax[20] = 770410000;
1968 state->CTFiltMax[21] = 814660000;
1969 state->CTFiltMax[22] = 846950000;
1970 state->CTFiltMax[23] = 867820000;
1971 state->CTFiltMax[24] = 915980000;
1972 state->CTFiltMax[25] = 947450000;
1973 state->CTFiltMax[26] = 983110000;
1974 state->CTFiltMax[27] = 1021630000;
1975 state->CTFiltMax[28] = 1061870000;
1976 state->CTFiltMax[29] = 1098330000;
1977 state->CTFiltMax[30] = 1138990000;
1978
1979 /*
1980 ** Fetch the FCU osc value and use it and the fRef value to
1981 ** scale all of the Band Max values
1982 */
1983
1984 state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1985 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1986 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1987 if (status < 0)
1988 return status;
1989
1990 /* Read the ClearTune filter calibration value */
1991 status = mt2063_read(state, MT2063_REG_FIFFC,
1992 &state->reg[MT2063_REG_FIFFC], 1);
1993 if (status < 0)
1994 return status;
1995
1996 fcu_osc = state->reg[MT2063_REG_FIFFC];
1997
1998 state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
1999 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
2000 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
2001 if (status < 0)
2002 return status;
2003
2004 /* Adjust each of the values in the ClearTune filter cross-over table */
2005 for (i = 0; i < 31; i++)
2006 state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
2007
2008 status = MT2063_SoftwareShutdown(state, 1);
2009 if (status < 0)
2010 return status;
2011 status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2012 if (status < 0)
2013 return status;
2014
2015 state->init = true;
2016
2017 return 0;
2018 }
2019
2020 static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
2021 {
2022 struct mt2063_state *state = fe->tuner_priv;
2023 int status;
2024
2025 dprintk(2, "\n");
2026
2027 if (!state->init)
2028 return -ENODEV;
2029
2030 *tuner_status = 0;
2031 status = mt2063_lockStatus(state);
2032 if (status < 0)
2033 return status;
2034 if (status)
2035 *tuner_status = TUNER_STATUS_LOCKED;
2036
2037 dprintk(1, "Tuner status: %d", *tuner_status);
2038
2039 return 0;
2040 }
2041
2042 static int mt2063_release(struct dvb_frontend *fe)
2043 {
2044 struct mt2063_state *state = fe->tuner_priv;
2045
2046 dprintk(2, "\n");
2047
2048 fe->tuner_priv = NULL;
2049 kfree(state);
2050
2051 return 0;
2052 }
2053
2054 static int mt2063_set_analog_params(struct dvb_frontend *fe,
2055 struct analog_parameters *params)
2056 {
2057 struct mt2063_state *state = fe->tuner_priv;
2058 s32 pict_car;
2059 s32 pict2chanb_vsb;
2060 s32 ch_bw;
2061 s32 if_mid;
2062 s32 rcvr_mode;
2063 int status;
2064
2065 dprintk(2, "\n");
2066
2067 if (!state->init) {
2068 status = mt2063_init(fe);
2069 if (status < 0)
2070 return status;
2071 }
2072
2073 switch (params->mode) {
2074 case V4L2_TUNER_RADIO:
2075 pict_car = 38900000;
2076 ch_bw = 8000000;
2077 pict2chanb_vsb = -(ch_bw / 2);
2078 rcvr_mode = MT2063_OFFAIR_ANALOG;
2079 break;
2080 case V4L2_TUNER_ANALOG_TV:
2081 rcvr_mode = MT2063_CABLE_ANALOG;
2082 if (params->std & ~V4L2_STD_MN) {
2083 pict_car = 38900000;
2084 ch_bw = 6000000;
2085 pict2chanb_vsb = -1250000;
2086 } else if (params->std & V4L2_STD_PAL_G) {
2087 pict_car = 38900000;
2088 ch_bw = 7000000;
2089 pict2chanb_vsb = -1250000;
2090 } else { /* PAL/SECAM standards */
2091 pict_car = 38900000;
2092 ch_bw = 8000000;
2093 pict2chanb_vsb = -1250000;
2094 }
2095 break;
2096 default:
2097 return -EINVAL;
2098 }
2099 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2100
2101 state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
2102 state->AS_Data.f_out = if_mid;
2103 state->AS_Data.f_out_bw = ch_bw + 750000;
2104 status = MT2063_SetReceiverMode(state, rcvr_mode);
2105 if (status < 0)
2106 return status;
2107
2108 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2109 params->frequency, ch_bw, pict2chanb_vsb);
2110
2111 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2112 if (status < 0)
2113 return status;
2114
2115 state->frequency = params->frequency;
2116 return 0;
2117 }
2118
2119 /*
2120 * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
2121 * So, the amount of the needed bandwidth is given by:
2122 * Bw = Symbol_rate * (1 + 0.15)
2123 * As such, the maximum symbol rate supported by 6 MHz is given by:
2124 * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
2125 */
2126 #define MAX_SYMBOL_RATE_6MHz 5217391
2127
2128 static int mt2063_set_params(struct dvb_frontend *fe)
2129 {
2130 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2131 struct mt2063_state *state = fe->tuner_priv;
2132 int status;
2133 s32 pict_car;
2134 s32 pict2chanb_vsb;
2135 s32 ch_bw;
2136 s32 if_mid;
2137 s32 rcvr_mode;
2138
2139 if (!state->init) {
2140 status = mt2063_init(fe);
2141 if (status < 0)
2142 return status;
2143 }
2144
2145 dprintk(2, "\n");
2146
2147 if (c->bandwidth_hz == 0)
2148 return -EINVAL;
2149 if (c->bandwidth_hz <= 6000000)
2150 ch_bw = 6000000;
2151 else if (c->bandwidth_hz <= 7000000)
2152 ch_bw = 7000000;
2153 else
2154 ch_bw = 8000000;
2155
2156 switch (c->delivery_system) {
2157 case SYS_DVBT:
2158 rcvr_mode = MT2063_OFFAIR_COFDM;
2159 pict_car = 36125000;
2160 pict2chanb_vsb = -(ch_bw / 2);
2161 break;
2162 case SYS_DVBC_ANNEX_A:
2163 case SYS_DVBC_ANNEX_C:
2164 rcvr_mode = MT2063_CABLE_QAM;
2165 pict_car = 36125000;
2166 pict2chanb_vsb = -(ch_bw / 2);
2167 break;
2168 default:
2169 return -EINVAL;
2170 }
2171 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2172
2173 state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
2174 state->AS_Data.f_out = if_mid;
2175 state->AS_Data.f_out_bw = ch_bw + 750000;
2176 status = MT2063_SetReceiverMode(state, rcvr_mode);
2177 if (status < 0)
2178 return status;
2179
2180 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2181 c->frequency, ch_bw, pict2chanb_vsb);
2182
2183 status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2184
2185 if (status < 0)
2186 return status;
2187
2188 state->frequency = c->frequency;
2189 return 0;
2190 }
2191
2192 static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2193 {
2194 struct mt2063_state *state = fe->tuner_priv;
2195
2196 dprintk(2, "\n");
2197
2198 if (!state->init)
2199 return -ENODEV;
2200
2201 *freq = state->AS_Data.f_out;
2202
2203 dprintk(1, "IF frequency: %d\n", *freq);
2204
2205 return 0;
2206 }
2207
2208 static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2209 {
2210 struct mt2063_state *state = fe->tuner_priv;
2211
2212 dprintk(2, "\n");
2213
2214 if (!state->init)
2215 return -ENODEV;
2216
2217 *bw = state->AS_Data.f_out_bw - 750000;
2218
2219 dprintk(1, "bandwidth: %d\n", *bw);
2220
2221 return 0;
2222 }
2223
2224 static struct dvb_tuner_ops mt2063_ops = {
2225 .info = {
2226 .name = "MT2063 Silicon Tuner",
2227 .frequency_min = 45000000,
2228 .frequency_max = 865000000,
2229 .frequency_step = 0,
2230 },
2231
2232 .init = mt2063_init,
2233 .sleep = MT2063_Sleep,
2234 .get_status = mt2063_get_status,
2235 .set_analog_params = mt2063_set_analog_params,
2236 .set_params = mt2063_set_params,
2237 .get_if_frequency = mt2063_get_if_frequency,
2238 .get_bandwidth = mt2063_get_bandwidth,
2239 .release = mt2063_release,
2240 };
2241
2242 struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2243 struct mt2063_config *config,
2244 struct i2c_adapter *i2c)
2245 {
2246 struct mt2063_state *state = NULL;
2247
2248 dprintk(2, "\n");
2249
2250 state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2251 if (!state)
2252 return NULL;
2253
2254 state->config = config;
2255 state->i2c = i2c;
2256 state->frontend = fe;
2257 state->reference = config->refclock / 1000; /* kHz */
2258 fe->tuner_priv = state;
2259 fe->ops.tuner_ops = mt2063_ops;
2260
2261 printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2262 return fe;
2263 }
2264 EXPORT_SYMBOL_GPL(mt2063_attach);
2265
2266 #if 0
2267 /*
2268 * Ancillary routines visible outside mt2063
2269 * FIXME: Remove them in favor of using standard tuner callbacks
2270 */
2271 static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2272 {
2273 struct mt2063_state *state = fe->tuner_priv;
2274 int err = 0;
2275
2276 dprintk(2, "\n");
2277
2278 err = MT2063_SoftwareShutdown(state, 1);
2279 if (err < 0)
2280 printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2281
2282 return err;
2283 }
2284
2285 static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2286 {
2287 struct mt2063_state *state = fe->tuner_priv;
2288 int err = 0;
2289
2290 dprintk(2, "\n");
2291
2292 err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2293 if (err < 0)
2294 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2295
2296 return err;
2297 }
2298 #endif
2299
2300 MODULE_AUTHOR("Mauro Carvalho Chehab");
2301 MODULE_DESCRIPTION("MT2063 Silicon tuner");
2302 MODULE_LICENSE("GPL");
This page took 0.080893 seconds and 5 git commands to generate.