xref: /linux/drivers/media/tuners/m88rs6000t.c (revision c6fbb759)
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 
11 struct m88rs6000t_dev {
12 	struct m88rs6000t_config cfg;
13 	struct i2c_client *client;
14 	struct regmap *regmap;
15 	u32 frequency_khz;
16 };
17 
18 struct m88rs6000t_reg_val {
19 	u8 reg;
20 	u8 val;
21 };
22 
23 /* set demod main mclk and ts mclk */
24 static 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);
143 err:
144 	if (ret)
145 		dev_dbg(&dev->client->dev, "failed=%d\n", ret);
146 	return ret;
147 }
148 
149 static 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);
366 err:
367 	if (ret)
368 		dev_dbg(&dev->client->dev, "failed=%d\n", ret);
369 	return ret;
370 }
371 
372 static 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 
385 static 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);
419 err:
420 	if (ret)
421 		dev_dbg(&dev->client->dev, "failed=%d\n", ret);
422 	return ret;
423 }
424 
425 static 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);
441 err:
442 	if (ret)
443 		dev_dbg(&dev->client->dev, "failed=%d\n", ret);
444 	return ret;
445 }
446 
447 static 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 
463 static 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 
473 static 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 
484 static 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);
555 err:
556 	if (ret)
557 		dev_dbg(&dev->client->dev, "failed=%d\n", ret);
558 	return ret;
559 }
560 
561 static 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 
576 static 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, &regmap_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;
694 err:
695 	dev_dbg(&client->dev, "failed=%d\n", ret);
696 	kfree(dev);
697 	return ret;
698 }
699 
700 static void 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 
712 static const struct i2c_device_id m88rs6000t_id[] = {
713 	{"m88rs6000t", 0},
714 	{}
715 };
716 MODULE_DEVICE_TABLE(i2c, m88rs6000t_id);
717 
718 static struct i2c_driver m88rs6000t_driver = {
719 	.driver = {
720 		.name	= "m88rs6000t",
721 	},
722 	.probe		= m88rs6000t_probe,
723 	.remove		= m88rs6000t_remove,
724 	.id_table	= m88rs6000t_id,
725 };
726 
727 module_i2c_driver(m88rs6000t_driver);
728 
729 MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
730 MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver");
731 MODULE_LICENSE("GPL");
732