1/* 2 * Driver for the internal tuner of Montage M88RS6000 3 * 4 * Copyright (C) 2014 Max nibble <nibble.max@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17#include "m88rs6000t.h" 18#include <linux/regmap.h> 19 20struct m88rs6000t_dev { 21 struct m88rs6000t_config cfg; 22 struct i2c_client *client; 23 struct regmap *regmap; 24 u32 frequency_khz; 25}; 26 27struct m88rs6000t_reg_val { 28 u8 reg; 29 u8 val; 30}; 31 32/* set demod main mclk and ts mclk */ 33static int m88rs6000t_set_demod_mclk(struct dvb_frontend *fe) 34{ 35 struct m88rs6000t_dev *dev = fe->tuner_priv; 36 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 37 u8 reg11, reg15, reg16, reg1D, reg1E, reg1F; 38 u8 N, f0 = 0, f1 = 0, f2 = 0, f3 = 0; 39 u16 pll_div_fb; 40 u32 div, ts_mclk; 41 unsigned int utmp; 42 int ret; 43 44 /* select demod main mclk */ 45 ret = regmap_read(dev->regmap, 0x15, &utmp); 46 if (ret) 47 goto err; 48 reg15 = utmp; 49 if (c->symbol_rate > 45010000) { 50 reg11 = 0x0E; 51 reg15 |= 0x02; 52 reg16 = 115; /* mclk = 110.25MHz */ 53 } else { 54 reg11 = 0x0A; 55 reg15 &= ~0x02; 56 reg16 = 96; /* mclk = 96MHz */ 57 } 58 59 /* set ts mclk */ 60 if (c->delivery_system == SYS_DVBS) 61 ts_mclk = 96000; 62 else 63 ts_mclk = 144000; 64 65 pll_div_fb = (reg15 & 0x01) << 8; 66 pll_div_fb += reg16; 67 pll_div_fb += 32; 68 69 div = 36000 * pll_div_fb; 70 div /= ts_mclk; 71 72 if (div <= 32) { 73 N = 2; 74 f0 = 0; 75 f1 = div / 2; 76 f2 = div - f1; 77 f3 = 0; 78 } else if (div <= 48) { 79 N = 3; 80 f0 = div / 3; 81 f1 = (div - f0) / 2; 82 f2 = div - f0 - f1; 83 f3 = 0; 84 } else if (div <= 64) { 85 N = 4; 86 f0 = div / 4; 87 f1 = (div - f0) / 3; 88 f2 = (div - f0 - f1) / 2; 89 f3 = div - f0 - f1 - f2; 90 } else { 91 N = 4; 92 f0 = 16; 93 f1 = 16; 94 f2 = 16; 95 f3 = 16; 96 } 97 98 if (f0 == 16) 99 f0 = 0; 100 if (f1 == 16) 101 f1 = 0; 102 if (f2 == 16) 103 f2 = 0; 104 if (f3 == 16) 105 f3 = 0; 106 107 ret = regmap_read(dev->regmap, 0x1D, &utmp); 108 if (ret) 109 goto err; 110 reg1D = utmp; 111 reg1D &= ~0x03; 112 reg1D |= N - 1; 113 reg1E = ((f3 << 4) + f2) & 0xFF; 114 reg1F = ((f1 << 4) + f0) & 0xFF; 115 116 /* program and recalibrate demod PLL */ 117 ret = regmap_write(dev->regmap, 0x05, 0x40); 118 if (ret) 119 goto err; 120 ret = regmap_write(dev->regmap, 0x11, 0x08); 121 if (ret) 122 goto err; 123 ret = regmap_write(dev->regmap, 0x15, reg15); 124 if (ret) 125 goto err; 126 ret = regmap_write(dev->regmap, 0x16, reg16); 127 if (ret) 128 goto err; 129 ret = regmap_write(dev->regmap, 0x1D, reg1D); 130 if (ret) 131 goto err; 132 ret = regmap_write(dev->regmap, 0x1E, reg1E); 133 if (ret) 134 goto err; 135 ret = regmap_write(dev->regmap, 0x1F, reg1F); 136 if (ret) 137 goto err; 138 ret = regmap_write(dev->regmap, 0x17, 0xc1); 139 if (ret) 140 goto err; 141 ret = regmap_write(dev->regmap, 0x17, 0x81); 142 if (ret) 143 goto err; 144 usleep_range(5000, 50000); 145 ret = regmap_write(dev->regmap, 0x05, 0x00); 146 if (ret) 147 goto err; 148 ret = regmap_write(dev->regmap, 0x11, reg11); 149 if (ret) 150 goto err; 151 usleep_range(5000, 50000); 152err: 153 if (ret) 154 dev_dbg(&dev->client->dev, "failed=%d\n", ret); 155 return ret; 156} 157 158static int m88rs6000t_set_pll_freq(struct m88rs6000t_dev *dev, 159 u32 tuner_freq_MHz) 160{ 161 u32 fcry_KHz, ulNDiv1, ulNDiv2, ulNDiv; 162 u8 refDiv, ucLoDiv1, ucLomod1, ucLoDiv2, ucLomod2, ucLoDiv, ucLomod; 163 u8 reg27, reg29, reg42, reg42buf; 164 unsigned int utmp; 165 int ret; 166 167 fcry_KHz = 27000; /* in kHz */ 168 refDiv = 27; 169 170 ret = regmap_write(dev->regmap, 0x36, (refDiv - 8)); 171 if (ret) 172 goto err; 173 ret = regmap_write(dev->regmap, 0x31, 0x00); 174 if (ret) 175 goto err; 176 ret = regmap_write(dev->regmap, 0x2c, 0x02); 177 if (ret) 178 goto err; 179 180 if (tuner_freq_MHz >= 1550) { 181 ucLoDiv1 = 2; 182 ucLomod1 = 0; 183 ucLoDiv2 = 2; 184 ucLomod2 = 0; 185 } else if (tuner_freq_MHz >= 1380) { 186 ucLoDiv1 = 3; 187 ucLomod1 = 16; 188 ucLoDiv2 = 2; 189 ucLomod2 = 0; 190 } else if (tuner_freq_MHz >= 1070) { 191 ucLoDiv1 = 3; 192 ucLomod1 = 16; 193 ucLoDiv2 = 3; 194 ucLomod2 = 16; 195 } else if (tuner_freq_MHz >= 1000) { 196 ucLoDiv1 = 3; 197 ucLomod1 = 16; 198 ucLoDiv2 = 4; 199 ucLomod2 = 64; 200 } else if (tuner_freq_MHz >= 775) { 201 ucLoDiv1 = 4; 202 ucLomod1 = 64; 203 ucLoDiv2 = 4; 204 ucLomod2 = 64; 205 } else if (tuner_freq_MHz >= 700) { 206 ucLoDiv1 = 6; 207 ucLomod1 = 48; 208 ucLoDiv2 = 4; 209 ucLomod2 = 64; 210 } else if (tuner_freq_MHz >= 520) { 211 ucLoDiv1 = 6; 212 ucLomod1 = 48; 213 ucLoDiv2 = 6; 214 ucLomod2 = 48; 215 } else { 216 ucLoDiv1 = 8; 217 ucLomod1 = 96; 218 ucLoDiv2 = 8; 219 ucLomod2 = 96; 220 } 221 222 ulNDiv1 = ((tuner_freq_MHz * ucLoDiv1 * 1000) * refDiv 223 / fcry_KHz - 1024) / 2; 224 ulNDiv2 = ((tuner_freq_MHz * ucLoDiv2 * 1000) * refDiv 225 / fcry_KHz - 1024) / 2; 226 227 reg27 = (((ulNDiv1 >> 8) & 0x0F) + ucLomod1) & 0x7F; 228 ret = regmap_write(dev->regmap, 0x27, reg27); 229 if (ret) 230 goto err; 231 ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv1 & 0xFF)); 232 if (ret) 233 goto err; 234 reg29 = (((ulNDiv2 >> 8) & 0x0F) + ucLomod2) & 0x7f; 235 ret = regmap_write(dev->regmap, 0x29, reg29); 236 if (ret) 237 goto err; 238 ret = regmap_write(dev->regmap, 0x2a, (u8)(ulNDiv2 & 0xFF)); 239 if (ret) 240 goto err; 241 ret = regmap_write(dev->regmap, 0x2F, 0xf5); 242 if (ret) 243 goto err; 244 ret = regmap_write(dev->regmap, 0x30, 0x05); 245 if (ret) 246 goto err; 247 ret = regmap_write(dev->regmap, 0x08, 0x1f); 248 if (ret) 249 goto err; 250 ret = regmap_write(dev->regmap, 0x08, 0x3f); 251 if (ret) 252 goto err; 253 ret = regmap_write(dev->regmap, 0x09, 0x20); 254 if (ret) 255 goto err; 256 ret = regmap_write(dev->regmap, 0x09, 0x00); 257 if (ret) 258 goto err; 259 ret = regmap_write(dev->regmap, 0x3e, 0x11); 260 if (ret) 261 goto err; 262 ret = regmap_write(dev->regmap, 0x08, 0x2f); 263 if (ret) 264 goto err; 265 ret = regmap_write(dev->regmap, 0x08, 0x3f); 266 if (ret) 267 goto err; 268 ret = regmap_write(dev->regmap, 0x09, 0x10); 269 if (ret) 270 goto err; 271 ret = regmap_write(dev->regmap, 0x09, 0x00); 272 if (ret) 273 goto err; 274 usleep_range(2000, 50000); 275 276 ret = regmap_read(dev->regmap, 0x42, &utmp); 277 if (ret) 278 goto err; 279 reg42 = utmp; 280 281 ret = regmap_write(dev->regmap, 0x3e, 0x10); 282 if (ret) 283 goto err; 284 ret = regmap_write(dev->regmap, 0x08, 0x2f); 285 if (ret) 286 goto err; 287 ret = regmap_write(dev->regmap, 0x08, 0x3f); 288 if (ret) 289 goto err; 290 ret = regmap_write(dev->regmap, 0x09, 0x10); 291 if (ret) 292 goto err; 293 ret = regmap_write(dev->regmap, 0x09, 0x00); 294 if (ret) 295 goto err; 296 usleep_range(2000, 50000); 297 298 ret = regmap_read(dev->regmap, 0x42, &utmp); 299 if (ret) 300 goto err; 301 reg42buf = utmp; 302 if (reg42buf < reg42) { 303 ret = regmap_write(dev->regmap, 0x3e, 0x11); 304 if (ret) 305 goto err; 306 } 307 usleep_range(5000, 50000); 308 309 ret = regmap_read(dev->regmap, 0x2d, &utmp); 310 if (ret) 311 goto err; 312 ret = regmap_write(dev->regmap, 0x2d, utmp); 313 if (ret) 314 goto err; 315 ret = regmap_read(dev->regmap, 0x2e, &utmp); 316 if (ret) 317 goto err; 318 ret = regmap_write(dev->regmap, 0x2e, utmp); 319 if (ret) 320 goto err; 321 322 ret = regmap_read(dev->regmap, 0x27, &utmp); 323 if (ret) 324 goto err; 325 reg27 = utmp & 0x70; 326 ret = regmap_read(dev->regmap, 0x83, &utmp); 327 if (ret) 328 goto err; 329 if (reg27 == (utmp & 0x70)) { 330 ucLoDiv = ucLoDiv1; 331 ulNDiv = ulNDiv1; 332 ucLomod = ucLomod1 / 16; 333 } else { 334 ucLoDiv = ucLoDiv2; 335 ulNDiv = ulNDiv2; 336 ucLomod = ucLomod2 / 16; 337 } 338 339 if ((ucLoDiv == 3) || (ucLoDiv == 6)) { 340 refDiv = 18; 341 ret = regmap_write(dev->regmap, 0x36, (refDiv - 8)); 342 if (ret) 343 goto err; 344 ulNDiv = ((tuner_freq_MHz * ucLoDiv * 1000) * refDiv 345 / fcry_KHz - 1024) / 2; 346 } 347 348 reg27 = (0x80 + ((ucLomod << 4) & 0x70) 349 + ((ulNDiv >> 8) & 0x0F)) & 0xFF; 350 ret = regmap_write(dev->regmap, 0x27, reg27); 351 if (ret) 352 goto err; 353 ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv & 0xFF)); 354 if (ret) 355 goto err; 356 ret = regmap_write(dev->regmap, 0x29, 0x80); 357 if (ret) 358 goto err; 359 ret = regmap_write(dev->regmap, 0x31, 0x03); 360 if (ret) 361 goto err; 362 363 if (ucLoDiv == 3) 364 utmp = 0xCE; 365 else 366 utmp = 0x8A; 367 ret = regmap_write(dev->regmap, 0x3b, utmp); 368 if (ret) 369 goto err; 370 371 dev->frequency_khz = fcry_KHz * (ulNDiv * 2 + 1024) / refDiv / ucLoDiv; 372 373 dev_dbg(&dev->client->dev, 374 "actual tune frequency=%d\n", dev->frequency_khz); 375err: 376 if (ret) 377 dev_dbg(&dev->client->dev, "failed=%d\n", ret); 378 return ret; 379} 380 381static int m88rs6000t_set_bb(struct m88rs6000t_dev *dev, 382 u32 symbol_rate_KSs, s32 lpf_offset_KHz) 383{ 384 u32 f3dB; 385 u8 reg40; 386 387 f3dB = symbol_rate_KSs * 9 / 14 + 2000; 388 f3dB += lpf_offset_KHz; 389 f3dB = clamp_val(f3dB, 6000U, 43000U); 390 reg40 = f3dB / 1000; 391 return regmap_write(dev->regmap, 0x40, reg40); 392} 393 394static int m88rs6000t_set_params(struct dvb_frontend *fe) 395{ 396 struct m88rs6000t_dev *dev = fe->tuner_priv; 397 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 398 int ret; 399 s32 lpf_offset_KHz; 400 u32 realFreq, freq_MHz; 401 402 dev_dbg(&dev->client->dev, 403 "frequency=%d symbol_rate=%d\n", 404 c->frequency, c->symbol_rate); 405 406 if (c->symbol_rate < 5000000) 407 lpf_offset_KHz = 3000; 408 else 409 lpf_offset_KHz = 0; 410 411 realFreq = c->frequency + lpf_offset_KHz; 412 /* set tuner pll.*/ 413 freq_MHz = (realFreq + 500) / 1000; 414 ret = m88rs6000t_set_pll_freq(dev, freq_MHz); 415 if (ret) 416 goto err; 417 ret = m88rs6000t_set_bb(dev, c->symbol_rate / 1000, lpf_offset_KHz); 418 if (ret) 419 goto err; 420 ret = regmap_write(dev->regmap, 0x00, 0x01); 421 if (ret) 422 goto err; 423 ret = regmap_write(dev->regmap, 0x00, 0x00); 424 if (ret) 425 goto err; 426 /* set demod mlck */ 427 ret = m88rs6000t_set_demod_mclk(fe); 428err: 429 if (ret) 430 dev_dbg(&dev->client->dev, "failed=%d\n", ret); 431 return ret; 432} 433 434static int m88rs6000t_init(struct dvb_frontend *fe) 435{ 436 struct m88rs6000t_dev *dev = fe->tuner_priv; 437 int ret; 438 439 dev_dbg(&dev->client->dev, "%s:\n", __func__); 440 441 ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08); 442 if (ret) 443 goto err; 444 usleep_range(5000, 50000); 445 ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01); 446 if (ret) 447 goto err; 448 usleep_range(10000, 50000); 449 ret = regmap_write(dev->regmap, 0x07, 0x7d); 450err: 451 if (ret) 452 dev_dbg(&dev->client->dev, "failed=%d\n", ret); 453 return ret; 454} 455 456static int m88rs6000t_sleep(struct dvb_frontend *fe) 457{ 458 struct m88rs6000t_dev *dev = fe->tuner_priv; 459 int ret; 460 461 dev_dbg(&dev->client->dev, "%s:\n", __func__); 462 463 ret = regmap_write(dev->regmap, 0x07, 0x6d); 464 if (ret) 465 goto err; 466 usleep_range(5000, 10000); 467err: 468 if (ret) 469 dev_dbg(&dev->client->dev, "failed=%d\n", ret); 470 return ret; 471} 472 473static int m88rs6000t_get_frequency(struct dvb_frontend *fe, u32 *frequency) 474{ 475 struct m88rs6000t_dev *dev = fe->tuner_priv; 476 477 dev_dbg(&dev->client->dev, "\n"); 478 479 *frequency = dev->frequency_khz; 480 return 0; 481} 482 483static int m88rs6000t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) 484{ 485 struct m88rs6000t_dev *dev = fe->tuner_priv; 486 487 dev_dbg(&dev->client->dev, "\n"); 488 489 *frequency = 0; /* Zero-IF */ 490 return 0; 491} 492 493 494static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength) 495{ 496 struct m88rs6000t_dev *dev = fe->tuner_priv; 497 unsigned int val, i; 498 int ret; 499 u16 gain; 500 u32 PGA2_cri_GS = 46, PGA2_crf_GS = 290, TIA_GS = 290; 501 u32 RF_GC = 1200, IF_GC = 1100, BB_GC = 300; 502 u32 PGA2_GC = 300, TIA_GC = 300, PGA2_cri = 0, PGA2_crf = 0; 503 u32 RFG = 0, IFG = 0, BBG = 0, PGA2G = 0, TIAG = 0; 504 u32 RFGS[13] = {0, 245, 266, 268, 270, 285, 505 298, 295, 283, 285, 285, 300, 300}; 506 u32 IFGS[12] = {0, 300, 230, 270, 270, 285, 507 295, 285, 290, 295, 295, 310}; 508 u32 BBGS[14] = {0, 286, 275, 290, 294, 300, 290, 509 290, 285, 283, 260, 295, 290, 260}; 510 511 ret = regmap_read(dev->regmap, 0x5A, &val); 512 if (ret) 513 goto err; 514 RF_GC = val & 0x0f; 515 516 ret = regmap_read(dev->regmap, 0x5F, &val); 517 if (ret) 518 goto err; 519 IF_GC = val & 0x0f; 520 521 ret = regmap_read(dev->regmap, 0x3F, &val); 522 if (ret) 523 goto err; 524 TIA_GC = (val >> 4) & 0x07; 525 526 ret = regmap_read(dev->regmap, 0x77, &val); 527 if (ret) 528 goto err; 529 BB_GC = (val >> 4) & 0x0f; 530 531 ret = regmap_read(dev->regmap, 0x76, &val); 532 if (ret) 533 goto err; 534 PGA2_GC = val & 0x3f; 535 PGA2_cri = PGA2_GC >> 2; 536 PGA2_crf = PGA2_GC & 0x03; 537 538 for (i = 0; i <= RF_GC; i++) 539 RFG += RFGS[i]; 540 541 if (RF_GC == 0) 542 RFG += 400; 543 if (RF_GC == 1) 544 RFG += 300; 545 if (RF_GC == 2) 546 RFG += 200; 547 if (RF_GC == 3) 548 RFG += 100; 549 550 for (i = 0; i <= IF_GC; i++) 551 IFG += IFGS[i]; 552 553 TIAG = TIA_GC * TIA_GS; 554 555 for (i = 0; i <= BB_GC; i++) 556 BBG += BBGS[i]; 557 558 PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS; 559 560 gain = RFG + IFG - TIAG + BBG + PGA2G; 561 562 /* scale value to 0x0000-0xffff */ 563 gain = clamp_val(gain, 1000U, 10500U); 564 *strength = (10500 - gain) * 0xffff / (10500 - 1000); 565err: 566 if (ret) 567 dev_dbg(&dev->client->dev, "failed=%d\n", ret); 568 return ret; 569} 570 571static const struct dvb_tuner_ops m88rs6000t_tuner_ops = { 572 .info = { 573 .name = "Montage M88RS6000 Internal Tuner", 574 .frequency_min = 950000, 575 .frequency_max = 2150000, 576 }, 577 578 .init = m88rs6000t_init, 579 .sleep = m88rs6000t_sleep, 580 .set_params = m88rs6000t_set_params, 581 .get_frequency = m88rs6000t_get_frequency, 582 .get_if_frequency = m88rs6000t_get_if_frequency, 583 .get_rf_strength = m88rs6000t_get_rf_strength, 584}; 585 586static int m88rs6000t_probe(struct i2c_client *client, 587 const struct i2c_device_id *id) 588{ 589 struct m88rs6000t_config *cfg = client->dev.platform_data; 590 struct dvb_frontend *fe = cfg->fe; 591 struct m88rs6000t_dev *dev; 592 int ret, i; 593 unsigned int utmp; 594 static const struct regmap_config regmap_config = { 595 .reg_bits = 8, 596 .val_bits = 8, 597 }; 598 static const struct m88rs6000t_reg_val reg_vals[] = { 599 {0x10, 0xfb}, 600 {0x24, 0x38}, 601 {0x11, 0x0a}, 602 {0x12, 0x00}, 603 {0x2b, 0x1c}, 604 {0x44, 0x48}, 605 {0x54, 0x24}, 606 {0x55, 0x06}, 607 {0x59, 0x00}, 608 {0x5b, 0x4c}, 609 {0x60, 0x8b}, 610 {0x61, 0xf4}, 611 {0x65, 0x07}, 612 {0x6d, 0x6f}, 613 {0x6e, 0x31}, 614 {0x3c, 0xf3}, 615 {0x37, 0x0f}, 616 {0x48, 0x28}, 617 {0x49, 0xd8}, 618 {0x70, 0x66}, 619 {0x71, 0xCF}, 620 {0x72, 0x81}, 621 {0x73, 0xA7}, 622 {0x74, 0x4F}, 623 {0x75, 0xFC}, 624 }; 625 626 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 627 if (!dev) { 628 ret = -ENOMEM; 629 dev_err(&client->dev, "kzalloc() failed\n"); 630 goto err; 631 } 632 633 memcpy(&dev->cfg, cfg, sizeof(struct m88rs6000t_config)); 634 dev->client = client; 635 dev->regmap = devm_regmap_init_i2c(client, ®map_config); 636 if (IS_ERR(dev->regmap)) { 637 ret = PTR_ERR(dev->regmap); 638 goto err; 639 } 640 641 ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08); 642 if (ret) 643 goto err; 644 usleep_range(5000, 50000); 645 ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01); 646 if (ret) 647 goto err; 648 usleep_range(10000, 50000); 649 ret = regmap_write(dev->regmap, 0x07, 0x7d); 650 if (ret) 651 goto err; 652 ret = regmap_write(dev->regmap, 0x04, 0x01); 653 if (ret) 654 goto err; 655 656 /* check tuner chip id */ 657 ret = regmap_read(dev->regmap, 0x01, &utmp); 658 if (ret) 659 goto err; 660 dev_info(&dev->client->dev, "chip_id=%02x\n", utmp); 661 if (utmp != 0x64) { 662 ret = -ENODEV; 663 goto err; 664 } 665 666 /* tuner init. */ 667 ret = regmap_write(dev->regmap, 0x05, 0x40); 668 if (ret) 669 goto err; 670 ret = regmap_write(dev->regmap, 0x11, 0x08); 671 if (ret) 672 goto err; 673 ret = regmap_write(dev->regmap, 0x15, 0x6c); 674 if (ret) 675 goto err; 676 ret = regmap_write(dev->regmap, 0x17, 0xc1); 677 if (ret) 678 goto err; 679 ret = regmap_write(dev->regmap, 0x17, 0x81); 680 if (ret) 681 goto err; 682 usleep_range(10000, 50000); 683 ret = regmap_write(dev->regmap, 0x05, 0x00); 684 if (ret) 685 goto err; 686 ret = regmap_write(dev->regmap, 0x11, 0x0a); 687 if (ret) 688 goto err; 689 690 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 691 ret = regmap_write(dev->regmap, 692 reg_vals[i].reg, reg_vals[i].val); 693 if (ret) 694 goto err; 695 } 696 697 dev_info(&dev->client->dev, "Montage M88RS6000 internal tuner successfully identified\n"); 698 699 fe->tuner_priv = dev; 700 memcpy(&fe->ops.tuner_ops, &m88rs6000t_tuner_ops, 701 sizeof(struct dvb_tuner_ops)); 702 i2c_set_clientdata(client, dev); 703 return 0; 704err: 705 dev_dbg(&client->dev, "failed=%d\n", ret); 706 kfree(dev); 707 return ret; 708} 709 710static int m88rs6000t_remove(struct i2c_client *client) 711{ 712 struct m88rs6000t_dev *dev = i2c_get_clientdata(client); 713 struct dvb_frontend *fe = dev->cfg.fe; 714 715 dev_dbg(&client->dev, "\n"); 716 717 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); 718 fe->tuner_priv = NULL; 719 kfree(dev); 720 721 return 0; 722} 723 724static const struct i2c_device_id m88rs6000t_id[] = { 725 {"m88rs6000t", 0}, 726 {} 727}; 728MODULE_DEVICE_TABLE(i2c, m88rs6000t_id); 729 730static struct i2c_driver m88rs6000t_driver = { 731 .driver = { 732 .owner = THIS_MODULE, 733 .name = "m88rs6000t", 734 }, 735 .probe = m88rs6000t_probe, 736 .remove = m88rs6000t_remove, 737 .id_table = m88rs6000t_id, 738}; 739 740module_i2c_driver(m88rs6000t_driver); 741 742MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>"); 743MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver"); 744MODULE_LICENSE("GPL"); 745