0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/string.h>
0017 #include <linux/videodev2.h>
0018 #include <linux/gcd.h>
0019
0020 #include "mt2063.h"
0021
0022 static unsigned int debug;
0023 module_param(debug, int, 0644);
0024 MODULE_PARM_DESC(debug, "Set Verbosity level");
0025
0026 #define dprintk(level, fmt, arg...) do { \
0027 if (debug >= level) \
0028 printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
0029 } while (0)
0030
0031
0032
0033
0034
0035 #define MT2063_SPUR_PRESENT_ERR (0x00800000)
0036
0037
0038 #define MT2063_SPUR_CNT_MASK (0x001f0000)
0039 #define MT2063_SPUR_SHIFT (16)
0040
0041
0042 #define MT2063_UPC_RANGE (0x04000000)
0043
0044
0045 #define MT2063_DNC_RANGE (0x08000000)
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 #define MT2063_DECT_AVOID_US_FREQS 0x00000001
0058
0059 #define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
0060
0061 #define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
0062
0063 #define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
0064
0065 enum MT2063_DECT_Avoid_Type {
0066 MT2063_NO_DECT_AVOIDANCE = 0,
0067 MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS,
0068 MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS,
0069 MT2063_AVOID_BOTH
0070 };
0071
0072 #define MT2063_MAX_ZONES 48
0073
0074 struct MT2063_ExclZone_t {
0075 u32 min_;
0076 u32 max_;
0077 struct MT2063_ExclZone_t *next_;
0078 };
0079
0080
0081
0082
0083 struct MT2063_AvoidSpursData_t {
0084 u32 f_ref;
0085 u32 f_in;
0086 u32 f_LO1;
0087 u32 f_if1_Center;
0088 u32 f_if1_Request;
0089 u32 f_if1_bw;
0090 u32 f_LO2;
0091 u32 f_out;
0092 u32 f_out_bw;
0093 u32 f_LO1_Step;
0094 u32 f_LO2_Step;
0095 u32 f_LO1_FracN_Avoid;
0096 u32 f_LO2_FracN_Avoid;
0097 u32 f_zif_bw;
0098 u32 f_min_LO_Separation;
0099 u32 maxH1;
0100 u32 maxH2;
0101 enum MT2063_DECT_Avoid_Type avoidDECT;
0102 u32 bSpurPresent;
0103 u32 bSpurAvoided;
0104 u32 nSpursFound;
0105 u32 nZones;
0106 struct MT2063_ExclZone_t *freeZones;
0107 struct MT2063_ExclZone_t *usedZones;
0108 struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
0109 };
0110
0111
0112
0113
0114
0115 enum MT2063_Mask_Bits {
0116 MT2063_REG_SD = 0x0040,
0117 MT2063_SRO_SD = 0x0020,
0118 MT2063_AFC_SD = 0x0010,
0119 MT2063_PD_SD = 0x0002,
0120 MT2063_PDADC_SD = 0x0001,
0121 MT2063_VCO_SD = 0x8000,
0122 MT2063_LTX_SD = 0x4000,
0123 MT2063_LT1_SD = 0x2000,
0124 MT2063_LNA_SD = 0x1000,
0125 MT2063_UPC_SD = 0x0800,
0126 MT2063_DNC_SD = 0x0400,
0127 MT2063_VGA_SD = 0x0200,
0128 MT2063_AMP_SD = 0x0100,
0129 MT2063_ALL_SD = 0xFF73,
0130 MT2063_NONE_SD = 0x0000
0131 };
0132
0133
0134
0135
0136 enum MT2063_DNC_Output_Enable {
0137 MT2063_DNC_NONE = 0,
0138 MT2063_DNC_1,
0139 MT2063_DNC_2,
0140 MT2063_DNC_BOTH
0141 };
0142
0143
0144
0145
0146
0147 enum MT2063_Register_Offsets {
0148 MT2063_REG_PART_REV = 0,
0149 MT2063_REG_LO1CQ_1,
0150 MT2063_REG_LO1CQ_2,
0151 MT2063_REG_LO2CQ_1,
0152 MT2063_REG_LO2CQ_2,
0153 MT2063_REG_LO2CQ_3,
0154 MT2063_REG_RSVD_06,
0155 MT2063_REG_LO_STATUS,
0156 MT2063_REG_FIFFC,
0157 MT2063_REG_CLEARTUNE,
0158 MT2063_REG_ADC_OUT,
0159 MT2063_REG_LO1C_1,
0160 MT2063_REG_LO1C_2,
0161 MT2063_REG_LO2C_1,
0162 MT2063_REG_LO2C_2,
0163 MT2063_REG_LO2C_3,
0164 MT2063_REG_RSVD_10,
0165 MT2063_REG_PWR_1,
0166 MT2063_REG_PWR_2,
0167 MT2063_REG_TEMP_STATUS,
0168 MT2063_REG_XO_STATUS,
0169 MT2063_REG_RF_STATUS,
0170 MT2063_REG_FIF_STATUS,
0171 MT2063_REG_LNA_OV,
0172 MT2063_REG_RF_OV,
0173 MT2063_REG_FIF_OV,
0174 MT2063_REG_LNA_TGT,
0175 MT2063_REG_PD1_TGT,
0176 MT2063_REG_PD2_TGT,
0177 MT2063_REG_RSVD_1D,
0178 MT2063_REG_RSVD_1E,
0179 MT2063_REG_RSVD_1F,
0180 MT2063_REG_RSVD_20,
0181 MT2063_REG_BYP_CTRL,
0182 MT2063_REG_RSVD_22,
0183 MT2063_REG_RSVD_23,
0184 MT2063_REG_RSVD_24,
0185 MT2063_REG_RSVD_25,
0186 MT2063_REG_RSVD_26,
0187 MT2063_REG_RSVD_27,
0188 MT2063_REG_FIFF_CTRL,
0189 MT2063_REG_FIFF_OFFSET,
0190 MT2063_REG_CTUNE_CTRL,
0191 MT2063_REG_CTUNE_OV,
0192 MT2063_REG_CTRL_2C,
0193 MT2063_REG_FIFF_CTRL2,
0194 MT2063_REG_RSVD_2E,
0195 MT2063_REG_DNC_GAIN,
0196 MT2063_REG_VGA_GAIN,
0197 MT2063_REG_RSVD_31,
0198 MT2063_REG_TEMP_SEL,
0199 MT2063_REG_RSVD_33,
0200 MT2063_REG_RSVD_34,
0201 MT2063_REG_RSVD_35,
0202 MT2063_REG_RSVD_36,
0203 MT2063_REG_RSVD_37,
0204 MT2063_REG_RSVD_38,
0205 MT2063_REG_RSVD_39,
0206 MT2063_REG_RSVD_3A,
0207 MT2063_REG_RSVD_3B,
0208 MT2063_REG_RSVD_3C,
0209 MT2063_REG_END_REGS
0210 };
0211
0212 struct mt2063_state {
0213 struct i2c_adapter *i2c;
0214
0215 bool init;
0216
0217 const struct mt2063_config *config;
0218 struct dvb_tuner_ops ops;
0219 struct dvb_frontend *frontend;
0220
0221 u32 frequency;
0222 u32 srate;
0223 u32 bandwidth;
0224 u32 reference;
0225
0226 u32 tuner_id;
0227 struct MT2063_AvoidSpursData_t AS_Data;
0228 u32 f_IF1_actual;
0229 u32 rcvr_mode;
0230 u32 ctfilt_sw;
0231 u32 CTFiltMax[31];
0232 u32 num_regs;
0233 u8 reg[MT2063_REG_END_REGS];
0234 };
0235
0236
0237
0238
0239 static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
0240 {
0241 struct dvb_frontend *fe = state->frontend;
0242 int ret;
0243 u8 buf[60];
0244 struct i2c_msg msg = {
0245 .addr = state->config->tuner_address,
0246 .flags = 0,
0247 .buf = buf,
0248 .len = len + 1
0249 };
0250
0251 dprintk(2, "\n");
0252
0253 msg.buf[0] = reg;
0254 memcpy(msg.buf + 1, data, len);
0255
0256 if (fe->ops.i2c_gate_ctrl)
0257 fe->ops.i2c_gate_ctrl(fe, 1);
0258 ret = i2c_transfer(state->i2c, &msg, 1);
0259 if (fe->ops.i2c_gate_ctrl)
0260 fe->ops.i2c_gate_ctrl(fe, 0);
0261
0262 if (ret < 0)
0263 printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
0264
0265 return ret;
0266 }
0267
0268
0269
0270
0271 static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
0272 {
0273 int status;
0274
0275 dprintk(2, "\n");
0276
0277 if (reg >= MT2063_REG_END_REGS)
0278 return -ERANGE;
0279
0280 status = mt2063_write(state, reg, &val, 1);
0281 if (status < 0)
0282 return status;
0283
0284 state->reg[reg] = val;
0285
0286 return 0;
0287 }
0288
0289
0290
0291
0292 static int mt2063_read(struct mt2063_state *state,
0293 u8 subAddress, u8 *pData, u32 cnt)
0294 {
0295 int status = 0;
0296 struct dvb_frontend *fe = state->frontend;
0297 u32 i = 0;
0298
0299 dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
0300
0301 if (fe->ops.i2c_gate_ctrl)
0302 fe->ops.i2c_gate_ctrl(fe, 1);
0303
0304 for (i = 0; i < cnt; i++) {
0305 u8 b0[] = { subAddress + i };
0306 struct i2c_msg msg[] = {
0307 {
0308 .addr = state->config->tuner_address,
0309 .flags = 0,
0310 .buf = b0,
0311 .len = 1
0312 }, {
0313 .addr = state->config->tuner_address,
0314 .flags = I2C_M_RD,
0315 .buf = pData + i,
0316 .len = 1
0317 }
0318 };
0319
0320 status = i2c_transfer(state->i2c, msg, 2);
0321 dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
0322 subAddress + i, status, *(pData + i));
0323 if (status < 0)
0324 break;
0325 }
0326 if (fe->ops.i2c_gate_ctrl)
0327 fe->ops.i2c_gate_ctrl(fe, 0);
0328
0329 if (status < 0)
0330 printk(KERN_ERR "Can't read from address 0x%02x,\n",
0331 subAddress + i);
0332
0333 return status;
0334 }
0335
0336
0337
0338
0339 static int MT2063_Sleep(struct dvb_frontend *fe)
0340 {
0341
0342
0343
0344 msleep(100);
0345
0346 return 0;
0347 }
0348
0349
0350
0351
0352
0353
0354 #define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
0355 #define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
0356
0357 struct MT2063_FIFZone_t {
0358 s32 min_;
0359 s32 max_;
0360 };
0361
0362 static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
0363 *pAS_Info,
0364 struct MT2063_ExclZone_t *pPrevNode)
0365 {
0366 struct MT2063_ExclZone_t *pNode;
0367
0368 dprintk(2, "\n");
0369
0370
0371 if (pAS_Info->freeZones != NULL) {
0372
0373 pNode = pAS_Info->freeZones;
0374 pAS_Info->freeZones = pNode->next_;
0375 } else {
0376
0377 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
0378 }
0379
0380 if (pPrevNode != NULL) {
0381 pNode->next_ = pPrevNode->next_;
0382 pPrevNode->next_ = pNode;
0383 } else {
0384
0385 pNode->next_ = pAS_Info->usedZones;
0386 pAS_Info->usedZones = pNode;
0387 }
0388
0389 pAS_Info->nZones++;
0390 return pNode;
0391 }
0392
0393 static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
0394 *pAS_Info,
0395 struct MT2063_ExclZone_t *pPrevNode,
0396 struct MT2063_ExclZone_t
0397 *pNodeToRemove)
0398 {
0399 struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
0400
0401 dprintk(2, "\n");
0402
0403
0404 if (pPrevNode != NULL)
0405 pPrevNode->next_ = pNext;
0406
0407
0408 pNodeToRemove->next_ = pAS_Info->freeZones;
0409 pAS_Info->freeZones = pNodeToRemove;
0410
0411
0412 pAS_Info->nZones--;
0413
0414 return pNext;
0415 }
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
0426 u32 f_min, u32 f_max)
0427 {
0428 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
0429 struct MT2063_ExclZone_t *pPrev = NULL;
0430 struct MT2063_ExclZone_t *pNext = NULL;
0431
0432 dprintk(2, "\n");
0433
0434
0435 if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
0436 && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
0437 && (f_min < f_max)) {
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447 while ((pNode != NULL) && (pNode->max_ < f_min)) {
0448 pPrev = pNode;
0449 pNode = pNode->next_;
0450 }
0451
0452 if ((pNode != NULL) && (pNode->min_ < f_max)) {
0453
0454 if (f_min < pNode->min_)
0455 pNode->min_ = f_min;
0456 if (f_max > pNode->max_)
0457 pNode->max_ = f_max;
0458 } else {
0459 pNode = InsertNode(pAS_Info, pPrev);
0460 pNode->min_ = f_min;
0461 pNode->max_ = f_max;
0462 }
0463
0464
0465 pNext = pNode->next_;
0466 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
0467 if (pNext->max_ > pNode->max_)
0468 pNode->max_ = pNext->max_;
0469
0470 pNext = RemoveNode(pAS_Info, pNode, pNext);
0471 }
0472 }
0473 }
0474
0475
0476
0477
0478
0479 static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
0480 {
0481 u32 center;
0482
0483 dprintk(2, "\n");
0484
0485 pAS_Info->nZones = 0;
0486 pAS_Info->usedZones = NULL;
0487 pAS_Info->freeZones = NULL;
0488
0489 center =
0490 pAS_Info->f_ref *
0491 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
0492 pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
0493 while (center <
0494 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
0495 pAS_Info->f_LO1_FracN_Avoid) {
0496
0497 MT2063_AddExclZone(pAS_Info,
0498 center - pAS_Info->f_LO1_FracN_Avoid,
0499 center - 1);
0500 MT2063_AddExclZone(pAS_Info, center + 1,
0501 center + pAS_Info->f_LO1_FracN_Avoid);
0502 center += pAS_Info->f_ref;
0503 }
0504
0505 center =
0506 pAS_Info->f_ref *
0507 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
0508 pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
0509 while (center <
0510 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
0511 pAS_Info->f_LO2_FracN_Avoid) {
0512
0513 MT2063_AddExclZone(pAS_Info,
0514 center - pAS_Info->f_LO2_FracN_Avoid,
0515 center - 1);
0516 MT2063_AddExclZone(pAS_Info, center + 1,
0517 center + pAS_Info->f_LO2_FracN_Avoid);
0518 center += pAS_Info->f_ref;
0519 }
0520
0521 if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
0522
0523 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in);
0524 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in);
0525 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in);
0526 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in);
0527 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in);
0528 }
0529
0530 if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
0531 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in);
0532 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in);
0533 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in);
0534 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in);
0535 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in);
0536 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in);
0537 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in);
0538 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in);
0539 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in);
0540 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in);
0541 }
0542 }
0543
0544
0545
0546
0547
0548
0549
0550 static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
0551 {
0552
0553
0554
0555
0556
0557
0558
0559
0560 const u32 f_Desired =
0561 pAS_Info->f_LO1_Step *
0562 ((pAS_Info->f_if1_Request + pAS_Info->f_in +
0563 pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
0564 pAS_Info->f_in;
0565 const u32 f_Step =
0566 (pAS_Info->f_LO1_Step >
0567 pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
0568 f_LO2_Step;
0569 u32 f_Center;
0570 s32 i;
0571 s32 j = 0;
0572 u32 bDesiredExcluded = 0;
0573 u32 bZeroExcluded = 0;
0574 s32 tmpMin, tmpMax;
0575 s32 bestDiff;
0576 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
0577 struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
0578
0579 dprintk(2, "\n");
0580
0581 if (pAS_Info->nZones == 0)
0582 return f_Desired;
0583
0584
0585
0586
0587
0588 if (pAS_Info->f_if1_Center > f_Desired)
0589 f_Center =
0590 f_Desired +
0591 f_Step *
0592 ((pAS_Info->f_if1_Center - f_Desired +
0593 f_Step / 2) / f_Step);
0594 else
0595 f_Center =
0596 f_Desired -
0597 f_Step *
0598 ((f_Desired - pAS_Info->f_if1_Center +
0599 f_Step / 2) / f_Step);
0600
0601
0602
0603
0604
0605 while (pNode != NULL) {
0606
0607 tmpMin =
0608 floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
0609
0610
0611 tmpMax =
0612 ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
0613
0614 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
0615 bDesiredExcluded = 1;
0616
0617 if ((tmpMin < 0) && (tmpMax > 0))
0618 bZeroExcluded = 1;
0619
0620
0621 if ((j > 0) && (tmpMin < zones[j - 1].max_))
0622 zones[j - 1].max_ = tmpMax;
0623 else {
0624
0625 zones[j].min_ = tmpMin;
0626 zones[j].max_ = tmpMax;
0627 j++;
0628 }
0629 pNode = pNode->next_;
0630 }
0631
0632
0633
0634
0635 if (bDesiredExcluded == 0)
0636 return f_Desired;
0637
0638
0639
0640
0641 if (bZeroExcluded == 0)
0642 return f_Center;
0643
0644
0645 bestDiff = zones[0].min_;
0646 for (i = 0; i < j; i++) {
0647 if (abs(zones[i].min_) < abs(bestDiff))
0648 bestDiff = zones[i].min_;
0649 if (abs(zones[i].max_) < abs(bestDiff))
0650 bestDiff = zones[i].max_;
0651 }
0652
0653 if (bestDiff < 0)
0654 return f_Center - ((u32) (-bestDiff) * f_Step);
0655
0656 return f_Center + (bestDiff * f_Step);
0657 }
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678 static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
0679 u32 *fm, u32 * fp)
0680 {
0681
0682
0683
0684 u32 n, n0;
0685 const u32 f_LO1 = pAS_Info->f_LO1;
0686 const u32 f_LO2 = pAS_Info->f_LO2;
0687 const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
0688 const u32 c = d - pAS_Info->f_out_bw;
0689 const u32 f = pAS_Info->f_zif_bw / 2;
0690 const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
0691 s32 f_nsLO1, f_nsLO2;
0692 s32 f_Spur;
0693 u32 ma, mb, mc, md, me, mf;
0694 u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
0695
0696 dprintk(2, "\n");
0697
0698 *fm = 0;
0699
0700
0701
0702
0703
0704
0705 lo_gcd = gcd(f_LO1, f_LO2);
0706 gd_Scale = max((u32) gcd(lo_gcd, d), f_Scale);
0707 hgds = gd_Scale / 2;
0708 gc_Scale = max((u32) gcd(lo_gcd, c), f_Scale);
0709 hgcs = gc_Scale / 2;
0710 gf_Scale = max((u32) gcd(lo_gcd, f), f_Scale);
0711 hgfs = gf_Scale / 2;
0712
0713 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
0714
0715
0716 for (n = n0; n <= pAS_Info->maxH1; ++n) {
0717 md = (n * ((f_LO1 + hgds) / gd_Scale) -
0718 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
0719
0720
0721 if (md >= pAS_Info->maxH1)
0722 break;
0723
0724 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
0725 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
0726
0727
0728 if (md == ma)
0729 continue;
0730
0731 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
0732 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
0733 if (mc != md) {
0734 f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
0735 f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
0736 f_Spur =
0737 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
0738 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
0739
0740 *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
0741 *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
0742 return 1;
0743 }
0744
0745
0746 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
0747 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
0748 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
0749 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
0750 if (me != mf) {
0751 f_nsLO1 = n * (f_LO1 / gf_Scale);
0752 f_nsLO2 = me * (f_LO2 / gf_Scale);
0753 f_Spur =
0754 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
0755 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
0756
0757 *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
0758 *fm = (((s32) f - f_Spur) / (me - n)) + 1;
0759 return 1;
0760 }
0761
0762 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
0763 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
0764 if (ma != mb) {
0765 f_nsLO1 = n * (f_LO1 / gc_Scale);
0766 f_nsLO2 = ma * (f_LO2 / gc_Scale);
0767 f_Spur =
0768 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
0769 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
0770
0771 *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
0772 *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
0773 return 1;
0774 }
0775 }
0776
0777
0778 return 0;
0779 }
0780
0781
0782
0783
0784
0785
0786
0787 static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
0788 {
0789 int status = 0;
0790 u32 fm, fp;
0791 pAS_Info->bSpurAvoided = 0;
0792 pAS_Info->nSpursFound = 0;
0793
0794 dprintk(2, "\n");
0795
0796 if (pAS_Info->maxH1 == 0)
0797 return 0;
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
0811 if (pAS_Info->bSpurPresent) {
0812 u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;
0813 u32 zfLO1 = pAS_Info->f_LO1;
0814 u32 zfLO2 = pAS_Info->f_LO2;
0815 u32 delta_IF1;
0816 u32 new_IF1;
0817
0818
0819
0820
0821 do {
0822 pAS_Info->nSpursFound++;
0823
0824
0825 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
0826
0827
0828 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
0829
0830 if (new_IF1 > zfIF1) {
0831 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
0832 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
0833 } else {
0834 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
0835 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
0836 }
0837 zfIF1 = new_IF1;
0838
0839 if (zfIF1 > pAS_Info->f_if1_Center)
0840 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
0841 else
0842 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
0843
0844 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
0845
0846
0847
0848
0849 } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
0850
0851
0852
0853
0854
0855
0856 if (pAS_Info->bSpurPresent == 1) {
0857 status |= MT2063_SPUR_PRESENT_ERR;
0858 pAS_Info->f_LO1 = zfLO1;
0859 pAS_Info->f_LO2 = zfLO2;
0860 } else
0861 pAS_Info->bSpurAvoided = 1;
0862 }
0863
0864 status |=
0865 ((pAS_Info->
0866 nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
0867
0868 return status;
0869 }
0870
0871
0872
0873
0874 #define MT2063_REF_FREQ (16000000UL)
0875 #define MT2063_IF1_BW (22000000UL)
0876 #define MT2063_TUNE_STEP_SIZE (50000UL)
0877 #define MT2063_SPUR_STEP_HZ (250000UL)
0878 #define MT2063_ZIF_BW (2000000UL)
0879 #define MT2063_MAX_HARMONICS_1 (15UL)
0880 #define MT2063_MAX_HARMONICS_2 (5UL)
0881 #define MT2063_MIN_LO_SEP (1000000UL)
0882 #define MT2063_LO1_FRACN_AVOID (0UL)
0883 #define MT2063_LO2_FRACN_AVOID (199999UL)
0884 #define MT2063_MIN_FIN_FREQ (44000000UL)
0885 #define MT2063_MAX_FIN_FREQ (1100000000UL)
0886 #define MT2063_MIN_FOUT_FREQ (36000000UL)
0887 #define MT2063_MAX_FOUT_FREQ (57000000UL)
0888 #define MT2063_MIN_DNC_FREQ (1293000000UL)
0889 #define MT2063_MAX_DNC_FREQ (1614000000UL)
0890 #define MT2063_MIN_UPC_FREQ (1396000000UL)
0891 #define MT2063_MAX_UPC_FREQ (2750000000UL)
0892
0893
0894
0895
0896 #define MT2063_B0 (0x9B)
0897 #define MT2063_B1 (0x9C)
0898 #define MT2063_B2 (0x9D)
0899 #define MT2063_B3 (0x9E)
0900
0901
0902
0903
0904
0905
0906
0907
0908 static int mt2063_lockStatus(struct mt2063_state *state)
0909 {
0910 const u32 nMaxWait = 100;
0911 const u32 nPollRate = 2;
0912 const u32 nMaxLoops = nMaxWait / nPollRate;
0913 const u8 LO1LK = 0x80;
0914 u8 LO2LK = 0x08;
0915 int status;
0916 u32 nDelays = 0;
0917
0918 dprintk(2, "\n");
0919
0920
0921 if (state->tuner_id == MT2063_B0)
0922 LO2LK = 0x40;
0923
0924 do {
0925 status = mt2063_read(state, MT2063_REG_LO_STATUS,
0926 &state->reg[MT2063_REG_LO_STATUS], 1);
0927
0928 if (status < 0)
0929 return status;
0930
0931 if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
0932 (LO1LK | LO2LK)) {
0933 return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
0934 }
0935 msleep(nPollRate);
0936 } while (++nDelays < nMaxLoops);
0937
0938
0939
0940
0941 return 0;
0942 }
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980 enum mt2063_delivery_sys {
0981 MT2063_CABLE_QAM = 0,
0982 MT2063_CABLE_ANALOG,
0983 MT2063_OFFAIR_COFDM,
0984 MT2063_OFFAIR_COFDM_SAWLESS,
0985 MT2063_OFFAIR_ANALOG,
0986 MT2063_OFFAIR_8VSB,
0987 MT2063_NUM_RCVR_MODES
0988 };
0989
0990 static const char *mt2063_mode_name[] = {
0991 [MT2063_CABLE_QAM] = "digital cable",
0992 [MT2063_CABLE_ANALOG] = "analog cable",
0993 [MT2063_OFFAIR_COFDM] = "digital offair",
0994 [MT2063_OFFAIR_COFDM_SAWLESS] = "digital offair without SAW",
0995 [MT2063_OFFAIR_ANALOG] = "analog offair",
0996 [MT2063_OFFAIR_8VSB] = "analog offair 8vsb",
0997 };
0998
0999 static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1000 static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1001 static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1002 static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1003 static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1004 static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1005 static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1006 static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1007 static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1008 static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1009 static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1010 static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1011 static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1012 static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1013
1014
1015
1016
1017 static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1018 enum MT2063_DNC_Output_Enable *pValue)
1019 {
1020 dprintk(2, "\n");
1021
1022 if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) {
1023 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)
1024 *pValue = MT2063_DNC_NONE;
1025 else
1026 *pValue = MT2063_DNC_2;
1027 } else {
1028 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)
1029 *pValue = MT2063_DNC_1;
1030 else
1031 *pValue = MT2063_DNC_BOTH;
1032 }
1033 return 0;
1034 }
1035
1036
1037
1038
1039 static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1040 enum MT2063_DNC_Output_Enable nValue)
1041 {
1042 int status = 0;
1043 u8 val = 0;
1044
1045 dprintk(2, "\n");
1046
1047
1048 switch (nValue) {
1049 case MT2063_DNC_NONE:
1050 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;
1051 if (state->reg[MT2063_REG_DNC_GAIN] !=
1052 val)
1053 status |=
1054 mt2063_setreg(state,
1055 MT2063_REG_DNC_GAIN,
1056 val);
1057
1058 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;
1059 if (state->reg[MT2063_REG_VGA_GAIN] !=
1060 val)
1061 status |=
1062 mt2063_setreg(state,
1063 MT2063_REG_VGA_GAIN,
1064 val);
1065
1066 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40);
1067 if (state->reg[MT2063_REG_RSVD_20] !=
1068 val)
1069 status |=
1070 mt2063_setreg(state,
1071 MT2063_REG_RSVD_20,
1072 val);
1073
1074 break;
1075 case MT2063_DNC_1:
1076 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);
1077 if (state->reg[MT2063_REG_DNC_GAIN] !=
1078 val)
1079 status |=
1080 mt2063_setreg(state,
1081 MT2063_REG_DNC_GAIN,
1082 val);
1083
1084 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;
1085 if (state->reg[MT2063_REG_VGA_GAIN] !=
1086 val)
1087 status |=
1088 mt2063_setreg(state,
1089 MT2063_REG_VGA_GAIN,
1090 val);
1091
1092 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40);
1093 if (state->reg[MT2063_REG_RSVD_20] !=
1094 val)
1095 status |=
1096 mt2063_setreg(state,
1097 MT2063_REG_RSVD_20,
1098 val);
1099
1100 break;
1101 case MT2063_DNC_2:
1102 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;
1103 if (state->reg[MT2063_REG_DNC_GAIN] !=
1104 val)
1105 status |=
1106 mt2063_setreg(state,
1107 MT2063_REG_DNC_GAIN,
1108 val);
1109
1110 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);
1111 if (state->reg[MT2063_REG_VGA_GAIN] !=
1112 val)
1113 status |=
1114 mt2063_setreg(state,
1115 MT2063_REG_VGA_GAIN,
1116 val);
1117
1118 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);
1119 if (state->reg[MT2063_REG_RSVD_20] !=
1120 val)
1121 status |=
1122 mt2063_setreg(state,
1123 MT2063_REG_RSVD_20,
1124 val);
1125
1126 break;
1127 case MT2063_DNC_BOTH:
1128 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);
1129 if (state->reg[MT2063_REG_DNC_GAIN] !=
1130 val)
1131 status |=
1132 mt2063_setreg(state,
1133 MT2063_REG_DNC_GAIN,
1134 val);
1135
1136 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);
1137 if (state->reg[MT2063_REG_VGA_GAIN] !=
1138 val)
1139 status |=
1140 mt2063_setreg(state,
1141 MT2063_REG_VGA_GAIN,
1142 val);
1143
1144 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);
1145 if (state->reg[MT2063_REG_RSVD_20] !=
1146 val)
1147 status |=
1148 mt2063_setreg(state,
1149 MT2063_REG_RSVD_20,
1150 val);
1151
1152 break;
1153 default:
1154 break;
1155 }
1156
1157 return status;
1158 }
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1174 enum mt2063_delivery_sys Mode)
1175 {
1176 int status = 0;
1177 u8 val;
1178 u32 longval;
1179
1180 dprintk(2, "\n");
1181
1182 if (Mode >= MT2063_NUM_RCVR_MODES)
1183 status = -ERANGE;
1184
1185
1186 if (status >= 0) {
1187 val =
1188 (state->
1189 reg[MT2063_REG_PD1_TGT] & ~0x40) | (RFAGCEN[Mode]
1190 ? 0x40 :
1191 0x00);
1192 if (state->reg[MT2063_REG_PD1_TGT] != val)
1193 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1194 }
1195
1196
1197 if (status >= 0) {
1198 u8 val = (state->reg[MT2063_REG_CTRL_2C] & ~0x03) |
1199 (LNARIN[Mode] & 0x03);
1200 if (state->reg[MT2063_REG_CTRL_2C] != val)
1201 status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1202 }
1203
1204
1205 if (status >= 0) {
1206 val =
1207 (state->
1208 reg[MT2063_REG_FIFF_CTRL2] & ~0xF0) |
1209 (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1210 if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1211 status |=
1212 mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1213
1214 val =
1215 (state->reg[MT2063_REG_FIFF_CTRL] | 0x01);
1216 status |=
1217 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1218 val =
1219 (state->
1220 reg[MT2063_REG_FIFF_CTRL] & ~0x01);
1221 status |=
1222 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1223 }
1224 }
1225
1226
1227 status |= mt2063_get_dnc_output_enable(state, &longval);
1228 status |= mt2063_set_dnc_output_enable(state, longval);
1229
1230
1231 if (status >= 0) {
1232 u8 val = (state->reg[MT2063_REG_LNA_OV] & ~0x1F) |
1233 (ACLNAMAX[Mode] & 0x1F);
1234 if (state->reg[MT2063_REG_LNA_OV] != val)
1235 status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1236 }
1237
1238
1239 if (status >= 0) {
1240 u8 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x3F) |
1241 (LNATGT[Mode] & 0x3F);
1242 if (state->reg[MT2063_REG_LNA_TGT] != val)
1243 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1244 }
1245
1246
1247 if (status >= 0) {
1248 u8 val = (state->reg[MT2063_REG_RF_OV] & ~0x1F) |
1249 (ACRFMAX[Mode] & 0x1F);
1250 if (state->reg[MT2063_REG_RF_OV] != val)
1251 status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1252 }
1253
1254
1255 if (status >= 0) {
1256 u8 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x3F) |
1257 (PD1TGT[Mode] & 0x3F);
1258 if (state->reg[MT2063_REG_PD1_TGT] != val)
1259 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1260 }
1261
1262
1263 if (status >= 0) {
1264 u8 val = ACFIFMAX[Mode];
1265 if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1266 val = 5;
1267 val = (state->reg[MT2063_REG_FIF_OV] & ~0x1F) |
1268 (val & 0x1F);
1269 if (state->reg[MT2063_REG_FIF_OV] != val)
1270 status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1271 }
1272
1273
1274 if (status >= 0) {
1275 u8 val = (state->reg[MT2063_REG_PD2_TGT] & ~0x3F) |
1276 (PD2TGT[Mode] & 0x3F);
1277 if (state->reg[MT2063_REG_PD2_TGT] != val)
1278 status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1279 }
1280
1281
1282 if (status >= 0) {
1283 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x80) |
1284 (RFOVDIS[Mode] ? 0x80 : 0x00);
1285 if (state->reg[MT2063_REG_LNA_TGT] != val)
1286 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1287 }
1288
1289
1290 if (status >= 0) {
1291 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x80) |
1292 (FIFOVDIS[Mode] ? 0x80 : 0x00);
1293 if (state->reg[MT2063_REG_PD1_TGT] != val)
1294 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1295 }
1296
1297 if (status >= 0) {
1298 state->rcvr_mode = Mode;
1299 dprintk(1, "mt2063 mode changed to %s\n",
1300 mt2063_mode_name[state->rcvr_mode]);
1301 }
1302
1303 return status;
1304 }
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315 static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1316 enum MT2063_Mask_Bits Bits)
1317 {
1318 int status = 0;
1319
1320 dprintk(2, "\n");
1321 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);
1322 if ((Bits & 0xFF00) != 0) {
1323 state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1324 status |=
1325 mt2063_write(state,
1326 MT2063_REG_PWR_2,
1327 &state->reg[MT2063_REG_PWR_2], 1);
1328 }
1329 if ((Bits & 0xFF) != 0) {
1330 state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1331 status |=
1332 mt2063_write(state,
1333 MT2063_REG_PWR_1,
1334 &state->reg[MT2063_REG_PWR_1], 1);
1335 }
1336
1337 return status;
1338 }
1339
1340
1341
1342
1343
1344
1345 static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1346 {
1347 int status;
1348
1349 dprintk(2, "\n");
1350 if (Shutdown == 1)
1351 state->reg[MT2063_REG_PWR_1] |= 0x04;
1352 else
1353 state->reg[MT2063_REG_PWR_1] &= ~0x04;
1354
1355 status = mt2063_write(state,
1356 MT2063_REG_PWR_1,
1357 &state->reg[MT2063_REG_PWR_1], 1);
1358
1359 if (Shutdown != 1) {
1360 state->reg[MT2063_REG_BYP_CTRL] =
1361 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1362 status |=
1363 mt2063_write(state,
1364 MT2063_REG_BYP_CTRL,
1365 &state->reg[MT2063_REG_BYP_CTRL],
1366 1);
1367 state->reg[MT2063_REG_BYP_CTRL] =
1368 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1369 status |=
1370 mt2063_write(state,
1371 MT2063_REG_BYP_CTRL,
1372 &state->reg[MT2063_REG_BYP_CTRL],
1373 1);
1374 }
1375
1376 return status;
1377 }
1378
1379 static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1380 {
1381 return f_ref * (f_LO / f_ref)
1382 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1383 }
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403 static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1404 {
1405 u32 t1 = (f_ref >> 14) * num;
1406 u32 term1 = t1 / denom;
1407 u32 loss = t1 % denom;
1408 u32 term2 =
1409 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1410 return (term1 << 14) + term2;
1411 }
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430 static u32 MT2063_CalcLO1Mult(u32 *Div,
1431 u32 *FracN,
1432 u32 f_LO,
1433 u32 f_LO_Step, u32 f_Ref)
1434 {
1435
1436 *Div = f_LO / f_Ref;
1437
1438
1439 *FracN =
1440 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1441 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1442
1443 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1444 }
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461 static u32 MT2063_CalcLO2Mult(u32 *Div,
1462 u32 *FracN,
1463 u32 f_LO,
1464 u32 f_LO_Step, u32 f_Ref)
1465 {
1466
1467 *Div = f_LO / f_Ref;
1468
1469
1470 *FracN =
1471 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1472 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1473
1474 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1475 8191);
1476 }
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487 static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1488 {
1489 u32 RFBand;
1490 u32 idx;
1491
1492
1493
1494
1495 RFBand = 31;
1496 for (idx = 0; idx < 31; ++idx) {
1497 if (state->CTFiltMax[idx] >= f_in) {
1498 RFBand = idx;
1499 break;
1500 }
1501 }
1502 return RFBand;
1503 }
1504
1505
1506
1507
1508 static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1509 {
1510
1511 int status = 0;
1512 u32 LO1;
1513 u32 Num1;
1514 u32 f_IF1;
1515 u32 LO2;
1516 u32 Num2;
1517 u32 ofLO1, ofLO2;
1518 u8 fiffc = 0x80;
1519 u32 fiffof;
1520 const u8 LO1LK = 0x80;
1521 u8 LO2LK = 0x08;
1522 u8 val;
1523 u32 RFBand;
1524
1525 dprintk(2, "\n");
1526
1527 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1528 return -EINVAL;
1529
1530 if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1531 || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1532 return -EINVAL;
1533
1534
1535
1536
1537 ofLO1 = state->AS_Data.f_LO1;
1538 ofLO2 = state->AS_Data.f_LO2;
1539
1540
1541
1542
1543 if (state->ctfilt_sw == 1) {
1544 val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1545 if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1546 status |=
1547 mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1548 }
1549 val = state->reg[MT2063_REG_CTUNE_OV];
1550 RFBand = FindClearTuneFilter(state, f_in);
1551 state->reg[MT2063_REG_CTUNE_OV] =
1552 (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1553 | RFBand);
1554 if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1555 status |=
1556 mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1557 }
1558 }
1559
1560
1561
1562
1563 if (status >= 0) {
1564 status |=
1565 mt2063_read(state,
1566 MT2063_REG_FIFFC,
1567 &state->reg[MT2063_REG_FIFFC], 1);
1568 fiffc = state->reg[MT2063_REG_FIFFC];
1569 }
1570
1571
1572
1573 state->AS_Data.f_in = f_in;
1574
1575 state->AS_Data.f_if1_Request =
1576 MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1577 state->AS_Data.f_LO1_Step,
1578 state->AS_Data.f_ref) - f_in;
1579
1580
1581
1582
1583
1584 MT2063_ResetExclZones(&state->AS_Data);
1585
1586 f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1587
1588 state->AS_Data.f_LO1 =
1589 MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1590 state->AS_Data.f_ref);
1591
1592 state->AS_Data.f_LO2 =
1593 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1594 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1595
1596
1597
1598
1599
1600 status |= MT2063_AvoidSpurs(&state->AS_Data);
1601
1602
1603
1604
1605
1606 state->AS_Data.f_LO1 =
1607 MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1608 state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1609 state->AS_Data.f_LO2 =
1610 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1611 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1612 state->AS_Data.f_LO2 =
1613 MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1614 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1615
1616
1617
1618
1619 if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1620 || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1621 status |= MT2063_UPC_RANGE;
1622 if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1623 || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1624 status |= MT2063_DNC_RANGE;
1625
1626 if (state->tuner_id == MT2063_B0)
1627 LO2LK = 0x40;
1628
1629
1630
1631
1632
1633 if ((ofLO1 != state->AS_Data.f_LO1)
1634 || (ofLO2 != state->AS_Data.f_LO2)
1635 || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1636 (LO1LK | LO2LK))) {
1637
1638
1639
1640
1641
1642
1643
1644 fiffof =
1645 (state->AS_Data.f_LO1 -
1646 f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1647 4992;
1648 if (fiffof > 0xFF)
1649 fiffof = 0xFF;
1650
1651
1652
1653
1654
1655 if (status >= 0) {
1656 state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);
1657 state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);
1658 state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)
1659 |(Num2 >> 12));
1660 state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);
1661 state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F));
1662
1663
1664
1665
1666
1667
1668 status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);
1669 if (state->tuner_id == MT2063_B0) {
1670
1671 status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);
1672 }
1673
1674 if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1675 (u8) fiffof) {
1676 state->reg[MT2063_REG_FIFF_OFFSET] =
1677 (u8) fiffof;
1678 status |=
1679 mt2063_write(state,
1680 MT2063_REG_FIFF_OFFSET,
1681 &state->
1682 reg[MT2063_REG_FIFF_OFFSET],
1683 1);
1684 }
1685 }
1686
1687
1688
1689
1690
1691 if (status < 0)
1692 return status;
1693
1694 status = mt2063_lockStatus(state);
1695 if (status < 0)
1696 return status;
1697 if (!status)
1698 return -EINVAL;
1699
1700
1701
1702
1703 state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1704 }
1705
1706 return status;
1707 }
1708
1709 static const u8 MT2063B0_defaults[] = {
1710
1711 0x19, 0x05,
1712 0x1B, 0x1D,
1713 0x1C, 0x1F,
1714 0x1D, 0x0F,
1715 0x1E, 0x3F,
1716 0x1F, 0x0F,
1717 0x20, 0x3F,
1718 0x22, 0x21,
1719 0x23, 0x3F,
1720 0x24, 0x20,
1721 0x25, 0x3F,
1722 0x27, 0xEE,
1723 0x2C, 0x27,
1724 0x30, 0x03,
1725 0x2C, 0x07,
1726 0x2D, 0x87,
1727 0x2E, 0xAA,
1728 0x28, 0xE1,
1729 0x28, 0xE0,
1730 0x00
1731 };
1732
1733
1734 static const u8 MT2063B1_defaults[] = {
1735
1736 0x05, 0xF0,
1737 0x11, 0x10,
1738 0x19, 0x05,
1739 0x1A, 0x6C,
1740 0x1B, 0x24,
1741 0x1C, 0x28,
1742 0x1D, 0x8F,
1743 0x1E, 0x14,
1744 0x1F, 0x8F,
1745 0x20, 0x57,
1746 0x22, 0x21,
1747 0x23, 0x3C,
1748 0x24, 0x20,
1749 0x2C, 0x24,
1750 0x2D, 0x87,
1751 0x2F, 0xF3,
1752 0x30, 0x0C,
1753 0x31, 0x1B,
1754 0x2C, 0x04,
1755 0x28, 0xE1,
1756 0x28, 0xE0,
1757 0x00
1758 };
1759
1760
1761 static const u8 MT2063B3_defaults[] = {
1762
1763 0x05, 0xF0,
1764 0x19, 0x3D,
1765 0x2C, 0x24,
1766 0x2C, 0x04,
1767 0x28, 0xE1,
1768 0x28, 0xE0,
1769 0x00
1770 };
1771
1772 static int mt2063_init(struct dvb_frontend *fe)
1773 {
1774 int status;
1775 struct mt2063_state *state = fe->tuner_priv;
1776 u8 all_resets = 0xF0;
1777 const u8 *def = NULL;
1778 char *step;
1779 u32 FCRUN;
1780 s32 maxReads;
1781 u32 fcu_osc;
1782 u32 i;
1783
1784 dprintk(2, "\n");
1785
1786 state->rcvr_mode = MT2063_CABLE_QAM;
1787
1788
1789 status = mt2063_read(state, MT2063_REG_PART_REV,
1790 &state->reg[MT2063_REG_PART_REV], 1);
1791 if (status < 0) {
1792 printk(KERN_ERR "Can't read mt2063 part ID\n");
1793 return status;
1794 }
1795
1796
1797 switch (state->reg[MT2063_REG_PART_REV]) {
1798 case MT2063_B0:
1799 step = "B0";
1800 break;
1801 case MT2063_B1:
1802 step = "B1";
1803 break;
1804 case MT2063_B2:
1805 step = "B2";
1806 break;
1807 case MT2063_B3:
1808 step = "B3";
1809 break;
1810 default:
1811 printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1812 state->reg[MT2063_REG_PART_REV]);
1813 return -ENODEV;
1814 }
1815
1816
1817 status = mt2063_read(state, MT2063_REG_RSVD_3B,
1818 &state->reg[MT2063_REG_RSVD_3B], 1);
1819
1820
1821 if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1822 printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1823 state->reg[MT2063_REG_PART_REV],
1824 state->reg[MT2063_REG_RSVD_3B]);
1825 return -ENODEV;
1826 }
1827
1828 printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1829
1830
1831 status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1832 if (status < 0)
1833 return status;
1834
1835
1836
1837 switch (state->reg[MT2063_REG_PART_REV]) {
1838 case MT2063_B3:
1839 def = MT2063B3_defaults;
1840 break;
1841
1842 case MT2063_B1:
1843 def = MT2063B1_defaults;
1844 break;
1845
1846 case MT2063_B0:
1847 def = MT2063B0_defaults;
1848 break;
1849
1850 default:
1851 return -ENODEV;
1852 }
1853
1854 while (status >= 0 && *def) {
1855 u8 reg = *def++;
1856 u8 val = *def++;
1857 status = mt2063_write(state, reg, &val, 1);
1858 }
1859 if (status < 0)
1860 return status;
1861
1862
1863 FCRUN = 1;
1864 maxReads = 10;
1865 while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1866 msleep(2);
1867 status = mt2063_read(state,
1868 MT2063_REG_XO_STATUS,
1869 &state->
1870 reg[MT2063_REG_XO_STATUS], 1);
1871 FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1872 }
1873
1874 if (FCRUN != 0 || status < 0)
1875 return -ENODEV;
1876
1877 status = mt2063_read(state,
1878 MT2063_REG_FIFFC,
1879 &state->reg[MT2063_REG_FIFFC], 1);
1880 if (status < 0)
1881 return status;
1882
1883
1884 status = mt2063_read(state,
1885 MT2063_REG_PART_REV,
1886 state->reg, MT2063_REG_END_REGS);
1887 if (status < 0)
1888 return status;
1889
1890
1891 state->tuner_id = state->reg[MT2063_REG_PART_REV];
1892 state->AS_Data.f_ref = MT2063_REF_FREQ;
1893 state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1894 ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1895 state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1896 state->AS_Data.f_out = 43750000UL;
1897 state->AS_Data.f_out_bw = 6750000UL;
1898 state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1899 state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1900 state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1901 state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1902 state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1903 state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1904 state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1905 state->AS_Data.f_LO1 = 2181000000UL;
1906 state->AS_Data.f_LO2 = 1486249786UL;
1907 state->f_IF1_actual = state->AS_Data.f_if1_Center;
1908 state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1909 state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1910 state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1911 state->num_regs = MT2063_REG_END_REGS;
1912 state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1913 state->ctfilt_sw = 0;
1914
1915 state->CTFiltMax[0] = 69230000;
1916 state->CTFiltMax[1] = 105770000;
1917 state->CTFiltMax[2] = 140350000;
1918 state->CTFiltMax[3] = 177110000;
1919 state->CTFiltMax[4] = 212860000;
1920 state->CTFiltMax[5] = 241130000;
1921 state->CTFiltMax[6] = 274370000;
1922 state->CTFiltMax[7] = 309820000;
1923 state->CTFiltMax[8] = 342450000;
1924 state->CTFiltMax[9] = 378870000;
1925 state->CTFiltMax[10] = 416210000;
1926 state->CTFiltMax[11] = 456500000;
1927 state->CTFiltMax[12] = 495790000;
1928 state->CTFiltMax[13] = 534530000;
1929 state->CTFiltMax[14] = 572610000;
1930 state->CTFiltMax[15] = 598970000;
1931 state->CTFiltMax[16] = 635910000;
1932 state->CTFiltMax[17] = 672130000;
1933 state->CTFiltMax[18] = 714840000;
1934 state->CTFiltMax[19] = 739660000;
1935 state->CTFiltMax[20] = 770410000;
1936 state->CTFiltMax[21] = 814660000;
1937 state->CTFiltMax[22] = 846950000;
1938 state->CTFiltMax[23] = 867820000;
1939 state->CTFiltMax[24] = 915980000;
1940 state->CTFiltMax[25] = 947450000;
1941 state->CTFiltMax[26] = 983110000;
1942 state->CTFiltMax[27] = 1021630000;
1943 state->CTFiltMax[28] = 1061870000;
1944 state->CTFiltMax[29] = 1098330000;
1945 state->CTFiltMax[30] = 1138990000;
1946
1947
1948
1949
1950
1951
1952 state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1953 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1954 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1955 if (status < 0)
1956 return status;
1957
1958
1959 status = mt2063_read(state, MT2063_REG_FIFFC,
1960 &state->reg[MT2063_REG_FIFFC], 1);
1961 if (status < 0)
1962 return status;
1963
1964 fcu_osc = state->reg[MT2063_REG_FIFFC];
1965
1966 state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
1967 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1968 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1969 if (status < 0)
1970 return status;
1971
1972
1973 for (i = 0; i < 31; i++)
1974 state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
1975
1976 status = MT2063_SoftwareShutdown(state, 1);
1977 if (status < 0)
1978 return status;
1979 status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
1980 if (status < 0)
1981 return status;
1982
1983 state->init = true;
1984
1985 return 0;
1986 }
1987
1988 static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
1989 {
1990 struct mt2063_state *state = fe->tuner_priv;
1991 int status;
1992
1993 dprintk(2, "\n");
1994
1995 if (!state->init)
1996 return -ENODEV;
1997
1998 *tuner_status = 0;
1999 status = mt2063_lockStatus(state);
2000 if (status < 0)
2001 return status;
2002 if (status)
2003 *tuner_status = TUNER_STATUS_LOCKED;
2004
2005 dprintk(1, "Tuner status: %d", *tuner_status);
2006
2007 return 0;
2008 }
2009
2010 static void mt2063_release(struct dvb_frontend *fe)
2011 {
2012 struct mt2063_state *state = fe->tuner_priv;
2013
2014 dprintk(2, "\n");
2015
2016 fe->tuner_priv = NULL;
2017 kfree(state);
2018 }
2019
2020 static int mt2063_set_analog_params(struct dvb_frontend *fe,
2021 struct analog_parameters *params)
2022 {
2023 struct mt2063_state *state = fe->tuner_priv;
2024 s32 pict_car;
2025 s32 pict2chanb_vsb;
2026 s32 ch_bw;
2027 s32 if_mid;
2028 s32 rcvr_mode;
2029 int status;
2030
2031 dprintk(2, "\n");
2032
2033 if (!state->init) {
2034 status = mt2063_init(fe);
2035 if (status < 0)
2036 return status;
2037 }
2038
2039 switch (params->mode) {
2040 case V4L2_TUNER_RADIO:
2041 pict_car = 38900000;
2042 ch_bw = 8000000;
2043 pict2chanb_vsb = -(ch_bw / 2);
2044 rcvr_mode = MT2063_OFFAIR_ANALOG;
2045 break;
2046 case V4L2_TUNER_ANALOG_TV:
2047 rcvr_mode = MT2063_CABLE_ANALOG;
2048 if (params->std & ~V4L2_STD_MN) {
2049 pict_car = 38900000;
2050 ch_bw = 6000000;
2051 pict2chanb_vsb = -1250000;
2052 } else if (params->std & V4L2_STD_PAL_G) {
2053 pict_car = 38900000;
2054 ch_bw = 7000000;
2055 pict2chanb_vsb = -1250000;
2056 } else {
2057 pict_car = 38900000;
2058 ch_bw = 8000000;
2059 pict2chanb_vsb = -1250000;
2060 }
2061 break;
2062 default:
2063 return -EINVAL;
2064 }
2065 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2066
2067 state->AS_Data.f_LO2_Step = 125000;
2068 state->AS_Data.f_out = if_mid;
2069 state->AS_Data.f_out_bw = ch_bw + 750000;
2070 status = MT2063_SetReceiverMode(state, rcvr_mode);
2071 if (status < 0)
2072 return status;
2073
2074 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2075 params->frequency, ch_bw, pict2chanb_vsb);
2076
2077 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2078 if (status < 0)
2079 return status;
2080
2081 state->frequency = params->frequency;
2082 return 0;
2083 }
2084
2085
2086
2087
2088
2089
2090
2091
2092 #define MAX_SYMBOL_RATE_6MHz 5217391
2093
2094 static int mt2063_set_params(struct dvb_frontend *fe)
2095 {
2096 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2097 struct mt2063_state *state = fe->tuner_priv;
2098 int status;
2099 s32 pict_car;
2100 s32 pict2chanb_vsb;
2101 s32 ch_bw;
2102 s32 if_mid;
2103 s32 rcvr_mode;
2104
2105 if (!state->init) {
2106 status = mt2063_init(fe);
2107 if (status < 0)
2108 return status;
2109 }
2110
2111 dprintk(2, "\n");
2112
2113 if (c->bandwidth_hz == 0)
2114 return -EINVAL;
2115 if (c->bandwidth_hz <= 6000000)
2116 ch_bw = 6000000;
2117 else if (c->bandwidth_hz <= 7000000)
2118 ch_bw = 7000000;
2119 else
2120 ch_bw = 8000000;
2121
2122 switch (c->delivery_system) {
2123 case SYS_DVBT:
2124 rcvr_mode = MT2063_OFFAIR_COFDM;
2125 pict_car = 36125000;
2126 pict2chanb_vsb = -(ch_bw / 2);
2127 break;
2128 case SYS_DVBC_ANNEX_A:
2129 case SYS_DVBC_ANNEX_C:
2130 rcvr_mode = MT2063_CABLE_QAM;
2131 pict_car = 36125000;
2132 pict2chanb_vsb = -(ch_bw / 2);
2133 break;
2134 default:
2135 return -EINVAL;
2136 }
2137 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2138
2139 state->AS_Data.f_LO2_Step = 125000;
2140 state->AS_Data.f_out = if_mid;
2141 state->AS_Data.f_out_bw = ch_bw + 750000;
2142 status = MT2063_SetReceiverMode(state, rcvr_mode);
2143 if (status < 0)
2144 return status;
2145
2146 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2147 c->frequency, ch_bw, pict2chanb_vsb);
2148
2149 status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2150
2151 if (status < 0)
2152 return status;
2153
2154 state->frequency = c->frequency;
2155 return 0;
2156 }
2157
2158 static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2159 {
2160 struct mt2063_state *state = fe->tuner_priv;
2161
2162 dprintk(2, "\n");
2163
2164 if (!state->init)
2165 return -ENODEV;
2166
2167 *freq = state->AS_Data.f_out;
2168
2169 dprintk(1, "IF frequency: %d\n", *freq);
2170
2171 return 0;
2172 }
2173
2174 static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2175 {
2176 struct mt2063_state *state = fe->tuner_priv;
2177
2178 dprintk(2, "\n");
2179
2180 if (!state->init)
2181 return -ENODEV;
2182
2183 *bw = state->AS_Data.f_out_bw - 750000;
2184
2185 dprintk(1, "bandwidth: %d\n", *bw);
2186
2187 return 0;
2188 }
2189
2190 static const struct dvb_tuner_ops mt2063_ops = {
2191 .info = {
2192 .name = "MT2063 Silicon Tuner",
2193 .frequency_min_hz = 45 * MHz,
2194 .frequency_max_hz = 865 * MHz,
2195 },
2196
2197 .init = mt2063_init,
2198 .sleep = MT2063_Sleep,
2199 .get_status = mt2063_get_status,
2200 .set_analog_params = mt2063_set_analog_params,
2201 .set_params = mt2063_set_params,
2202 .get_if_frequency = mt2063_get_if_frequency,
2203 .get_bandwidth = mt2063_get_bandwidth,
2204 .release = mt2063_release,
2205 };
2206
2207 struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2208 struct mt2063_config *config,
2209 struct i2c_adapter *i2c)
2210 {
2211 struct mt2063_state *state = NULL;
2212
2213 dprintk(2, "\n");
2214
2215 state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2216 if (!state)
2217 return NULL;
2218
2219 state->config = config;
2220 state->i2c = i2c;
2221 state->frontend = fe;
2222 state->reference = config->refclock / 1000;
2223 fe->tuner_priv = state;
2224 fe->ops.tuner_ops = mt2063_ops;
2225
2226 printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2227 return fe;
2228 }
2229 EXPORT_SYMBOL_GPL(mt2063_attach);
2230
2231 #if 0
2232
2233
2234
2235
2236 static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2237 {
2238 struct mt2063_state *state = fe->tuner_priv;
2239 int err = 0;
2240
2241 dprintk(2, "\n");
2242
2243 err = MT2063_SoftwareShutdown(state, 1);
2244 if (err < 0)
2245 printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2246
2247 return err;
2248 }
2249
2250 static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2251 {
2252 struct mt2063_state *state = fe->tuner_priv;
2253 int err = 0;
2254
2255 dprintk(2, "\n");
2256
2257 err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2258 if (err < 0)
2259 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2260
2261 return err;
2262 }
2263 #endif
2264
2265 MODULE_AUTHOR("Mauro Carvalho Chehab");
2266 MODULE_DESCRIPTION("MT2063 Silicon tuner");
2267 MODULE_LICENSE("GPL");