Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for the internal tuner of Montage M88RS6000
0004  *
0005  * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
0006  */
0007 
0008 #include "m88rs6000t.h"
0009 #include <linux/regmap.h>
0010 
0011 struct m88rs6000t_dev {
0012     struct m88rs6000t_config cfg;
0013     struct i2c_client *client;
0014     struct regmap *regmap;
0015     u32 frequency_khz;
0016 };
0017 
0018 struct m88rs6000t_reg_val {
0019     u8 reg;
0020     u8 val;
0021 };
0022 
0023 /* set demod main mclk and ts mclk */
0024 static int m88rs6000t_set_demod_mclk(struct dvb_frontend *fe)
0025 {
0026     struct m88rs6000t_dev *dev = fe->tuner_priv;
0027     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0028     u8 reg11, reg15, reg16, reg1D, reg1E, reg1F;
0029     u8 N, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
0030     u16 pll_div_fb;
0031     u32 div, ts_mclk;
0032     unsigned int utmp;
0033     int ret;
0034 
0035     /* select demod main mclk */
0036     ret = regmap_read(dev->regmap, 0x15, &utmp);
0037     if (ret)
0038         goto err;
0039     reg15 = utmp;
0040     if (c->symbol_rate > 45010000) {
0041         reg11 = 0x0E;
0042         reg15 |= 0x02;
0043         reg16 = 115; /* mclk = 110.25MHz */
0044     } else {
0045         reg11 = 0x0A;
0046         reg15 &= ~0x02;
0047         reg16 = 96; /* mclk = 96MHz */
0048     }
0049 
0050     /* set ts mclk */
0051     if (c->delivery_system == SYS_DVBS)
0052         ts_mclk = 96000;
0053     else
0054         ts_mclk = 144000;
0055 
0056     pll_div_fb = (reg15 & 0x01) << 8;
0057     pll_div_fb += reg16;
0058     pll_div_fb += 32;
0059 
0060     div = 36000 * pll_div_fb;
0061     div /= ts_mclk;
0062 
0063     if (div <= 32) {
0064         N = 2;
0065         f0 = 0;
0066         f1 = div / 2;
0067         f2 = div - f1;
0068         f3 = 0;
0069     } else if (div <= 48) {
0070         N = 3;
0071         f0 = div / 3;
0072         f1 = (div - f0) / 2;
0073         f2 = div - f0 - f1;
0074         f3 = 0;
0075     } else if (div <= 64) {
0076         N = 4;
0077         f0 = div / 4;
0078         f1 = (div - f0) / 3;
0079         f2 = (div - f0 - f1) / 2;
0080         f3 = div - f0 - f1 - f2;
0081     } else {
0082         N = 4;
0083         f0 = 16;
0084         f1 = 16;
0085         f2 = 16;
0086         f3 = 16;
0087     }
0088 
0089     if (f0 == 16)
0090         f0 = 0;
0091     if (f1 == 16)
0092         f1 = 0;
0093     if (f2 == 16)
0094         f2 = 0;
0095     if (f3 == 16)
0096         f3 = 0;
0097 
0098     ret = regmap_read(dev->regmap, 0x1D, &utmp);
0099     if (ret)
0100         goto err;
0101     reg1D = utmp;
0102     reg1D &= ~0x03;
0103     reg1D |= N - 1;
0104     reg1E = ((f3 << 4) + f2) & 0xFF;
0105     reg1F = ((f1 << 4) + f0) & 0xFF;
0106 
0107     /* program and recalibrate demod PLL */
0108     ret = regmap_write(dev->regmap, 0x05, 0x40);
0109     if (ret)
0110         goto err;
0111     ret = regmap_write(dev->regmap, 0x11, 0x08);
0112     if (ret)
0113         goto err;
0114     ret = regmap_write(dev->regmap, 0x15, reg15);
0115     if (ret)
0116         goto err;
0117     ret = regmap_write(dev->regmap, 0x16, reg16);
0118     if (ret)
0119         goto err;
0120     ret = regmap_write(dev->regmap, 0x1D, reg1D);
0121     if (ret)
0122         goto err;
0123     ret = regmap_write(dev->regmap, 0x1E, reg1E);
0124     if (ret)
0125         goto err;
0126     ret = regmap_write(dev->regmap, 0x1F, reg1F);
0127     if (ret)
0128         goto err;
0129     ret = regmap_write(dev->regmap, 0x17, 0xc1);
0130     if (ret)
0131         goto err;
0132     ret = regmap_write(dev->regmap, 0x17, 0x81);
0133     if (ret)
0134         goto err;
0135     usleep_range(5000, 50000);
0136     ret = regmap_write(dev->regmap, 0x05, 0x00);
0137     if (ret)
0138         goto err;
0139     ret = regmap_write(dev->regmap, 0x11, reg11);
0140     if (ret)
0141         goto err;
0142     usleep_range(5000, 50000);
0143 err:
0144     if (ret)
0145         dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0146     return ret;
0147 }
0148 
0149 static int m88rs6000t_set_pll_freq(struct m88rs6000t_dev *dev,
0150             u32 tuner_freq_MHz)
0151 {
0152     u32 fcry_KHz, ulNDiv1, ulNDiv2, ulNDiv;
0153     u8 refDiv, ucLoDiv1, ucLomod1, ucLoDiv2, ucLomod2, ucLoDiv, ucLomod;
0154     u8 reg27, reg29, reg42, reg42buf;
0155     unsigned int utmp;
0156     int ret;
0157 
0158     fcry_KHz = 27000; /* in kHz */
0159     refDiv = 27;
0160 
0161     ret = regmap_write(dev->regmap, 0x36, (refDiv - 8));
0162     if (ret)
0163         goto err;
0164     ret = regmap_write(dev->regmap, 0x31, 0x00);
0165     if (ret)
0166         goto err;
0167     ret = regmap_write(dev->regmap, 0x2c, 0x02);
0168     if (ret)
0169         goto err;
0170 
0171     if (tuner_freq_MHz >= 1550) {
0172         ucLoDiv1 = 2;
0173         ucLomod1 = 0;
0174         ucLoDiv2 = 2;
0175         ucLomod2 = 0;
0176     } else if (tuner_freq_MHz >= 1380) {
0177         ucLoDiv1 = 3;
0178         ucLomod1 = 16;
0179         ucLoDiv2 = 2;
0180         ucLomod2 = 0;
0181     } else if (tuner_freq_MHz >= 1070) {
0182         ucLoDiv1 = 3;
0183         ucLomod1 = 16;
0184         ucLoDiv2 = 3;
0185         ucLomod2 = 16;
0186     } else if (tuner_freq_MHz >= 1000) {
0187         ucLoDiv1 = 3;
0188         ucLomod1 = 16;
0189         ucLoDiv2 = 4;
0190         ucLomod2 = 64;
0191     } else if (tuner_freq_MHz >= 775) {
0192         ucLoDiv1 = 4;
0193         ucLomod1 = 64;
0194         ucLoDiv2 = 4;
0195         ucLomod2 = 64;
0196     } else if (tuner_freq_MHz >= 700) {
0197         ucLoDiv1 = 6;
0198         ucLomod1 = 48;
0199         ucLoDiv2 = 4;
0200         ucLomod2 = 64;
0201     } else if (tuner_freq_MHz >= 520) {
0202         ucLoDiv1 = 6;
0203         ucLomod1 = 48;
0204         ucLoDiv2 = 6;
0205         ucLomod2 = 48;
0206     } else {
0207         ucLoDiv1 = 8;
0208         ucLomod1 = 96;
0209         ucLoDiv2 = 8;
0210         ucLomod2 = 96;
0211     }
0212 
0213     ulNDiv1 = ((tuner_freq_MHz * ucLoDiv1 * 1000) * refDiv
0214             / fcry_KHz - 1024) / 2;
0215     ulNDiv2 = ((tuner_freq_MHz * ucLoDiv2 * 1000) * refDiv
0216             / fcry_KHz - 1024) / 2;
0217 
0218     reg27 = (((ulNDiv1 >> 8) & 0x0F) + ucLomod1) & 0x7F;
0219     ret = regmap_write(dev->regmap, 0x27, reg27);
0220     if (ret)
0221         goto err;
0222     ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv1 & 0xFF));
0223     if (ret)
0224         goto err;
0225     reg29 = (((ulNDiv2 >> 8) & 0x0F) + ucLomod2) & 0x7f;
0226     ret = regmap_write(dev->regmap, 0x29, reg29);
0227     if (ret)
0228         goto err;
0229     ret = regmap_write(dev->regmap, 0x2a, (u8)(ulNDiv2 & 0xFF));
0230     if (ret)
0231         goto err;
0232     ret = regmap_write(dev->regmap, 0x2F, 0xf5);
0233     if (ret)
0234         goto err;
0235     ret = regmap_write(dev->regmap, 0x30, 0x05);
0236     if (ret)
0237         goto err;
0238     ret = regmap_write(dev->regmap, 0x08, 0x1f);
0239     if (ret)
0240         goto err;
0241     ret = regmap_write(dev->regmap, 0x08, 0x3f);
0242     if (ret)
0243         goto err;
0244     ret = regmap_write(dev->regmap, 0x09, 0x20);
0245     if (ret)
0246         goto err;
0247     ret = regmap_write(dev->regmap, 0x09, 0x00);
0248     if (ret)
0249         goto err;
0250     ret = regmap_write(dev->regmap, 0x3e, 0x11);
0251     if (ret)
0252         goto err;
0253     ret = regmap_write(dev->regmap, 0x08, 0x2f);
0254     if (ret)
0255         goto err;
0256     ret = regmap_write(dev->regmap, 0x08, 0x3f);
0257     if (ret)
0258         goto err;
0259     ret = regmap_write(dev->regmap, 0x09, 0x10);
0260     if (ret)
0261         goto err;
0262     ret = regmap_write(dev->regmap, 0x09, 0x00);
0263     if (ret)
0264         goto err;
0265     usleep_range(2000, 50000);
0266 
0267     ret = regmap_read(dev->regmap, 0x42, &utmp);
0268     if (ret)
0269         goto err;
0270     reg42 = utmp;
0271 
0272     ret = regmap_write(dev->regmap, 0x3e, 0x10);
0273     if (ret)
0274         goto err;
0275     ret = regmap_write(dev->regmap, 0x08, 0x2f);
0276     if (ret)
0277         goto err;
0278     ret = regmap_write(dev->regmap, 0x08, 0x3f);
0279     if (ret)
0280         goto err;
0281     ret = regmap_write(dev->regmap, 0x09, 0x10);
0282     if (ret)
0283         goto err;
0284     ret = regmap_write(dev->regmap, 0x09, 0x00);
0285     if (ret)
0286         goto err;
0287     usleep_range(2000, 50000);
0288 
0289     ret = regmap_read(dev->regmap, 0x42, &utmp);
0290     if (ret)
0291         goto err;
0292     reg42buf = utmp;
0293     if (reg42buf < reg42) {
0294         ret = regmap_write(dev->regmap, 0x3e, 0x11);
0295         if (ret)
0296             goto err;
0297     }
0298     usleep_range(5000, 50000);
0299 
0300     ret = regmap_read(dev->regmap, 0x2d, &utmp);
0301     if (ret)
0302         goto err;
0303     ret = regmap_write(dev->regmap, 0x2d, utmp);
0304     if (ret)
0305         goto err;
0306     ret = regmap_read(dev->regmap, 0x2e, &utmp);
0307     if (ret)
0308         goto err;
0309     ret = regmap_write(dev->regmap, 0x2e, utmp);
0310     if (ret)
0311         goto err;
0312 
0313     ret = regmap_read(dev->regmap, 0x27, &utmp);
0314     if (ret)
0315         goto err;
0316     reg27 = utmp & 0x70;
0317     ret = regmap_read(dev->regmap, 0x83, &utmp);
0318     if (ret)
0319         goto err;
0320     if (reg27 == (utmp & 0x70)) {
0321         ucLoDiv = ucLoDiv1;
0322         ulNDiv = ulNDiv1;
0323         ucLomod = ucLomod1 / 16;
0324     } else {
0325         ucLoDiv = ucLoDiv2;
0326         ulNDiv = ulNDiv2;
0327         ucLomod = ucLomod2 / 16;
0328     }
0329 
0330     if ((ucLoDiv == 3) || (ucLoDiv == 6)) {
0331         refDiv = 18;
0332         ret = regmap_write(dev->regmap, 0x36, (refDiv - 8));
0333         if (ret)
0334             goto err;
0335         ulNDiv = ((tuner_freq_MHz * ucLoDiv * 1000) * refDiv
0336                 / fcry_KHz - 1024) / 2;
0337     }
0338 
0339     reg27 = (0x80 + ((ucLomod << 4) & 0x70)
0340             + ((ulNDiv >> 8) & 0x0F)) & 0xFF;
0341     ret = regmap_write(dev->regmap, 0x27, reg27);
0342     if (ret)
0343         goto err;
0344     ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv & 0xFF));
0345     if (ret)
0346         goto err;
0347     ret = regmap_write(dev->regmap, 0x29, 0x80);
0348     if (ret)
0349         goto err;
0350     ret = regmap_write(dev->regmap, 0x31, 0x03);
0351     if (ret)
0352         goto err;
0353 
0354     if (ucLoDiv == 3)
0355         utmp = 0xCE;
0356     else
0357         utmp = 0x8A;
0358     ret = regmap_write(dev->regmap, 0x3b, utmp);
0359     if (ret)
0360         goto err;
0361 
0362     dev->frequency_khz = fcry_KHz * (ulNDiv * 2 + 1024) / refDiv / ucLoDiv;
0363 
0364     dev_dbg(&dev->client->dev,
0365         "actual tune frequency=%d\n", dev->frequency_khz);
0366 err:
0367     if (ret)
0368         dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0369     return ret;
0370 }
0371 
0372 static int m88rs6000t_set_bb(struct m88rs6000t_dev *dev,
0373         u32 symbol_rate_KSs, s32 lpf_offset_KHz)
0374 {
0375     u32 f3dB;
0376     u8  reg40;
0377 
0378     f3dB = symbol_rate_KSs * 9 / 14 + 2000;
0379     f3dB += lpf_offset_KHz;
0380     f3dB = clamp_val(f3dB, 6000U, 43000U);
0381     reg40 = f3dB / 1000;
0382     return regmap_write(dev->regmap, 0x40, reg40);
0383 }
0384 
0385 static int m88rs6000t_set_params(struct dvb_frontend *fe)
0386 {
0387     struct m88rs6000t_dev *dev = fe->tuner_priv;
0388     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0389     int ret;
0390     s32 lpf_offset_KHz;
0391     u32 realFreq, freq_MHz;
0392 
0393     dev_dbg(&dev->client->dev,
0394             "frequency=%d symbol_rate=%d\n",
0395             c->frequency, c->symbol_rate);
0396 
0397     if (c->symbol_rate < 5000000)
0398         lpf_offset_KHz = 3000;
0399     else
0400         lpf_offset_KHz = 0;
0401 
0402     realFreq = c->frequency + lpf_offset_KHz;
0403     /* set tuner pll.*/
0404     freq_MHz = (realFreq + 500) / 1000;
0405     ret = m88rs6000t_set_pll_freq(dev, freq_MHz);
0406     if (ret)
0407         goto err;
0408     ret = m88rs6000t_set_bb(dev, c->symbol_rate / 1000, lpf_offset_KHz);
0409     if (ret)
0410         goto err;
0411     ret = regmap_write(dev->regmap, 0x00, 0x01);
0412     if (ret)
0413         goto err;
0414     ret = regmap_write(dev->regmap, 0x00, 0x00);
0415     if (ret)
0416         goto err;
0417     /* set demod mlck */
0418     ret = m88rs6000t_set_demod_mclk(fe);
0419 err:
0420     if (ret)
0421         dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0422     return ret;
0423 }
0424 
0425 static int m88rs6000t_init(struct dvb_frontend *fe)
0426 {
0427     struct m88rs6000t_dev *dev = fe->tuner_priv;
0428     int ret;
0429 
0430     dev_dbg(&dev->client->dev, "%s:\n", __func__);
0431 
0432     ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08);
0433     if (ret)
0434         goto err;
0435     usleep_range(5000, 50000);
0436     ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01);
0437     if (ret)
0438         goto err;
0439     usleep_range(10000, 50000);
0440     ret = regmap_write(dev->regmap, 0x07, 0x7d);
0441 err:
0442     if (ret)
0443         dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0444     return ret;
0445 }
0446 
0447 static int m88rs6000t_sleep(struct dvb_frontend *fe)
0448 {
0449     struct m88rs6000t_dev *dev = fe->tuner_priv;
0450     int ret;
0451 
0452     dev_dbg(&dev->client->dev, "%s:\n", __func__);
0453 
0454     ret = regmap_write(dev->regmap, 0x07, 0x6d);
0455     if (ret) {
0456         dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0457         return ret;
0458     }
0459     usleep_range(5000, 10000);
0460     return 0;
0461 }
0462 
0463 static int m88rs6000t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0464 {
0465     struct m88rs6000t_dev *dev = fe->tuner_priv;
0466 
0467     dev_dbg(&dev->client->dev, "\n");
0468 
0469     *frequency = dev->frequency_khz;
0470     return 0;
0471 }
0472 
0473 static int m88rs6000t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0474 {
0475     struct m88rs6000t_dev *dev = fe->tuner_priv;
0476 
0477     dev_dbg(&dev->client->dev, "\n");
0478 
0479     *frequency = 0; /* Zero-IF */
0480     return 0;
0481 }
0482 
0483 
0484 static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
0485 {
0486     struct m88rs6000t_dev *dev = fe->tuner_priv;
0487     unsigned int val, i;
0488     int ret;
0489     u16 gain;
0490     u32 PGA2_cri_GS = 46, PGA2_crf_GS = 290, TIA_GS = 290;
0491     u32 RF_GC = 1200, IF_GC = 1100, BB_GC = 300;
0492     u32 PGA2_GC = 300, TIA_GC = 300, PGA2_cri = 0, PGA2_crf = 0;
0493     u32 RFG = 0, IFG = 0, BBG = 0, PGA2G = 0, TIAG = 0;
0494     u32 RFGS[13] = {0, 245, 266, 268, 270, 285,
0495             298, 295, 283, 285, 285, 300, 300};
0496     u32 IFGS[12] = {0, 300, 230, 270, 270, 285,
0497             295, 285, 290, 295, 295, 310};
0498     u32 BBGS[14] = {0, 286, 275, 290, 294, 300, 290,
0499             290, 285, 283, 260, 295, 290, 260};
0500 
0501     ret = regmap_read(dev->regmap, 0x5A, &val);
0502     if (ret)
0503         goto err;
0504     RF_GC = val & 0x0f;
0505 
0506     ret = regmap_read(dev->regmap, 0x5F, &val);
0507     if (ret)
0508         goto err;
0509     IF_GC = val & 0x0f;
0510 
0511     ret = regmap_read(dev->regmap, 0x3F, &val);
0512     if (ret)
0513         goto err;
0514     TIA_GC = (val >> 4) & 0x07;
0515 
0516     ret = regmap_read(dev->regmap, 0x77, &val);
0517     if (ret)
0518         goto err;
0519     BB_GC = (val >> 4) & 0x0f;
0520 
0521     ret = regmap_read(dev->regmap, 0x76, &val);
0522     if (ret)
0523         goto err;
0524     PGA2_GC = val & 0x3f;
0525     PGA2_cri = PGA2_GC >> 2;
0526     PGA2_crf = PGA2_GC & 0x03;
0527 
0528     for (i = 0; i <= RF_GC && i < ARRAY_SIZE(RFGS); i++)
0529         RFG += RFGS[i];
0530 
0531     if (RF_GC == 0)
0532         RFG += 400;
0533     if (RF_GC == 1)
0534         RFG += 300;
0535     if (RF_GC == 2)
0536         RFG += 200;
0537     if (RF_GC == 3)
0538         RFG += 100;
0539 
0540     for (i = 0; i <= IF_GC && i < ARRAY_SIZE(IFGS); i++)
0541         IFG += IFGS[i];
0542 
0543     TIAG = TIA_GC * TIA_GS;
0544 
0545     for (i = 0; i <= BB_GC && i < ARRAY_SIZE(BBGS); i++)
0546         BBG += BBGS[i];
0547 
0548     PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS;
0549 
0550     gain = RFG + IFG - TIAG + BBG + PGA2G;
0551 
0552     /* scale value to 0x0000-0xffff */
0553     gain = clamp_val(gain, 1000U, 10500U);
0554     *strength = (10500 - gain) * 0xffff / (10500 - 1000);
0555 err:
0556     if (ret)
0557         dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0558     return ret;
0559 }
0560 
0561 static const struct dvb_tuner_ops m88rs6000t_tuner_ops = {
0562     .info = {
0563         .name             = "Montage M88RS6000 Internal Tuner",
0564         .frequency_min_hz =  950 * MHz,
0565         .frequency_max_hz = 2150 * MHz,
0566     },
0567 
0568     .init = m88rs6000t_init,
0569     .sleep = m88rs6000t_sleep,
0570     .set_params = m88rs6000t_set_params,
0571     .get_frequency = m88rs6000t_get_frequency,
0572     .get_if_frequency = m88rs6000t_get_if_frequency,
0573     .get_rf_strength = m88rs6000t_get_rf_strength,
0574 };
0575 
0576 static int m88rs6000t_probe(struct i2c_client *client,
0577         const struct i2c_device_id *id)
0578 {
0579     struct m88rs6000t_config *cfg = client->dev.platform_data;
0580     struct dvb_frontend *fe = cfg->fe;
0581     struct m88rs6000t_dev *dev;
0582     int ret, i;
0583     unsigned int utmp;
0584     static const struct regmap_config regmap_config = {
0585         .reg_bits = 8,
0586         .val_bits = 8,
0587     };
0588     static const struct m88rs6000t_reg_val reg_vals[] = {
0589         {0x10, 0xfb},
0590         {0x24, 0x38},
0591         {0x11, 0x0a},
0592         {0x12, 0x00},
0593         {0x2b, 0x1c},
0594         {0x44, 0x48},
0595         {0x54, 0x24},
0596         {0x55, 0x06},
0597         {0x59, 0x00},
0598         {0x5b, 0x4c},
0599         {0x60, 0x8b},
0600         {0x61, 0xf4},
0601         {0x65, 0x07},
0602         {0x6d, 0x6f},
0603         {0x6e, 0x31},
0604         {0x3c, 0xf3},
0605         {0x37, 0x0f},
0606         {0x48, 0x28},
0607         {0x49, 0xd8},
0608         {0x70, 0x66},
0609         {0x71, 0xCF},
0610         {0x72, 0x81},
0611         {0x73, 0xA7},
0612         {0x74, 0x4F},
0613         {0x75, 0xFC},
0614     };
0615 
0616     dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0617     if (!dev) {
0618         ret = -ENOMEM;
0619         dev_err(&client->dev, "kzalloc() failed\n");
0620         goto err;
0621     }
0622 
0623     memcpy(&dev->cfg, cfg, sizeof(struct m88rs6000t_config));
0624     dev->client = client;
0625     dev->regmap = devm_regmap_init_i2c(client, &regmap_config);
0626     if (IS_ERR(dev->regmap)) {
0627         ret = PTR_ERR(dev->regmap);
0628         goto err;
0629     }
0630 
0631     ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08);
0632     if (ret)
0633         goto err;
0634     usleep_range(5000, 50000);
0635     ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01);
0636     if (ret)
0637         goto err;
0638     usleep_range(10000, 50000);
0639     ret = regmap_write(dev->regmap, 0x07, 0x7d);
0640     if (ret)
0641         goto err;
0642     ret = regmap_write(dev->regmap, 0x04, 0x01);
0643     if (ret)
0644         goto err;
0645 
0646     /* check tuner chip id */
0647     ret = regmap_read(dev->regmap, 0x01, &utmp);
0648     if (ret)
0649         goto err;
0650     dev_info(&dev->client->dev, "chip_id=%02x\n", utmp);
0651     if (utmp != 0x64) {
0652         ret = -ENODEV;
0653         goto err;
0654     }
0655 
0656     /* tuner init. */
0657     ret = regmap_write(dev->regmap, 0x05, 0x40);
0658     if (ret)
0659         goto err;
0660     ret = regmap_write(dev->regmap, 0x11, 0x08);
0661     if (ret)
0662         goto err;
0663     ret = regmap_write(dev->regmap, 0x15, 0x6c);
0664     if (ret)
0665         goto err;
0666     ret = regmap_write(dev->regmap, 0x17, 0xc1);
0667     if (ret)
0668         goto err;
0669     ret = regmap_write(dev->regmap, 0x17, 0x81);
0670     if (ret)
0671         goto err;
0672     usleep_range(10000, 50000);
0673     ret = regmap_write(dev->regmap, 0x05, 0x00);
0674     if (ret)
0675         goto err;
0676     ret = regmap_write(dev->regmap, 0x11, 0x0a);
0677     if (ret)
0678         goto err;
0679 
0680     for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
0681         ret = regmap_write(dev->regmap,
0682                 reg_vals[i].reg, reg_vals[i].val);
0683         if (ret)
0684             goto err;
0685     }
0686 
0687     dev_info(&dev->client->dev, "Montage M88RS6000 internal tuner successfully identified\n");
0688 
0689     fe->tuner_priv = dev;
0690     memcpy(&fe->ops.tuner_ops, &m88rs6000t_tuner_ops,
0691             sizeof(struct dvb_tuner_ops));
0692     i2c_set_clientdata(client, dev);
0693     return 0;
0694 err:
0695     dev_dbg(&client->dev, "failed=%d\n", ret);
0696     kfree(dev);
0697     return ret;
0698 }
0699 
0700 static int m88rs6000t_remove(struct i2c_client *client)
0701 {
0702     struct m88rs6000t_dev *dev = i2c_get_clientdata(client);
0703     struct dvb_frontend *fe = dev->cfg.fe;
0704 
0705     dev_dbg(&client->dev, "\n");
0706 
0707     memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
0708     fe->tuner_priv = NULL;
0709     kfree(dev);
0710 
0711     return 0;
0712 }
0713 
0714 static const struct i2c_device_id m88rs6000t_id[] = {
0715     {"m88rs6000t", 0},
0716     {}
0717 };
0718 MODULE_DEVICE_TABLE(i2c, m88rs6000t_id);
0719 
0720 static struct i2c_driver m88rs6000t_driver = {
0721     .driver = {
0722         .name   = "m88rs6000t",
0723     },
0724     .probe      = m88rs6000t_probe,
0725     .remove     = m88rs6000t_remove,
0726     .id_table   = m88rs6000t_id,
0727 };
0728 
0729 module_i2c_driver(m88rs6000t_driver);
0730 
0731 MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
0732 MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver");
0733 MODULE_LICENSE("GPL");