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