Merge tag 'asoc-v5.3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-microblaze.git] / drivers / media / tuners / m88rs6000t.c
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++)
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++)
541                 IFG += IFGS[i];
542
543         TIAG = TIA_GC * TIA_GS;
544
545         for (i = 0; i <= BB_GC; 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 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
714 static const struct i2c_device_id m88rs6000t_id[] = {
715         {"m88rs6000t", 0},
716         {}
717 };
718 MODULE_DEVICE_TABLE(i2c, m88rs6000t_id);
719
720 static 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
729 module_i2c_driver(m88rs6000t_driver);
730
731 MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
732 MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver");
733 MODULE_LICENSE("GPL");