hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/dvb-frontends/m88ds3103.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Montage Technology M88DS3103/M88RS6000 demodulator driver
34 *
45 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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.
156 */
167
178 #include "m88ds3103_priv.h"
....@@ -71,6 +62,92 @@
7162 err:
7263 dev_dbg(&client->dev, "failed=%d\n", ret);
7364 return ret;
65
+}
66
+
67
+/*
68
+ * m88ds3103b demod has an internal device related to clocking. First the i2c
69
+ * gate must be opened, for one transaction, then writes will be allowed.
70
+ */
71
+static int m88ds3103b_dt_write(struct m88ds3103_dev *dev, int reg, int data)
72
+{
73
+ struct i2c_client *client = dev->client;
74
+ u8 buf[] = {reg, data};
75
+ u8 val;
76
+ int ret;
77
+ struct i2c_msg msg = {
78
+ .addr = dev->dt_addr, .flags = 0, .buf = buf, .len = 2
79
+ };
80
+
81
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x00);
82
+
83
+ val = 0x11;
84
+ ret = regmap_write(dev->regmap, 0x03, val);
85
+ if (ret)
86
+ dev_dbg(&client->dev, "fail=%d\n", ret);
87
+
88
+ ret = i2c_transfer(dev->dt_client->adapter, &msg, 1);
89
+ if (ret != 1) {
90
+ dev_err(&client->dev, "0x%02x (ret=%i, reg=0x%02x, value=0x%02x)\n",
91
+ dev->dt_addr, ret, reg, data);
92
+
93
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
94
+ return -EREMOTEIO;
95
+ }
96
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
97
+
98
+ dev_dbg(&client->dev, "0x%02x reg 0x%02x, value 0x%02x\n",
99
+ dev->dt_addr, reg, data);
100
+
101
+ return 0;
102
+}
103
+
104
+/*
105
+ * m88ds3103b demod has an internal device related to clocking. First the i2c
106
+ * gate must be opened, for two transactions, then reads will be allowed.
107
+ */
108
+static int m88ds3103b_dt_read(struct m88ds3103_dev *dev, u8 reg)
109
+{
110
+ struct i2c_client *client = dev->client;
111
+ int ret;
112
+ u8 val;
113
+ u8 b0[] = { reg };
114
+ u8 b1[] = { 0 };
115
+ struct i2c_msg msg[] = {
116
+ {
117
+ .addr = dev->dt_addr,
118
+ .flags = 0,
119
+ .buf = b0,
120
+ .len = 1
121
+ },
122
+ {
123
+ .addr = dev->dt_addr,
124
+ .flags = I2C_M_RD,
125
+ .buf = b1,
126
+ .len = 1
127
+ }
128
+ };
129
+
130
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x00);
131
+
132
+ val = 0x12;
133
+ ret = regmap_write(dev->regmap, 0x03, val);
134
+ if (ret)
135
+ dev_dbg(&client->dev, "fail=%d\n", ret);
136
+
137
+ ret = i2c_transfer(dev->dt_client->adapter, msg, 2);
138
+ if (ret != 2) {
139
+ dev_err(&client->dev, "0x%02x (ret=%d, reg=0x%02x)\n",
140
+ dev->dt_addr, ret, reg);
141
+
142
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
143
+ return -EREMOTEIO;
144
+ }
145
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
146
+
147
+ dev_dbg(&client->dev, "0x%02x reg 0x%02x, value 0x%02x\n",
148
+ dev->dt_addr, reg, b1[0]);
149
+
150
+ return b1[0];
74151 }
75152
76153 /*
....@@ -297,6 +374,251 @@
297374 return ret;
298375 }
299376
377
+static int m88ds3103b_select_mclk(struct m88ds3103_dev *dev)
378
+{
379
+ struct i2c_client *client = dev->client;
380
+ struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
381
+ u32 adc_Freq_MHz[3] = {96, 93, 99};
382
+ u8 reg16_list[3] = {96, 92, 100}, reg16, reg15;
383
+ u32 offset_MHz[3];
384
+ u32 max_offset = 0;
385
+ u32 old_setting = dev->mclk;
386
+ u32 tuner_freq_MHz = c->frequency / 1000;
387
+ u8 i;
388
+ char big_symbol = 0;
389
+
390
+ big_symbol = (c->symbol_rate > 45010000) ? 1 : 0;
391
+
392
+ if (big_symbol) {
393
+ reg16 = 115;
394
+ } else {
395
+ reg16 = 96;
396
+
397
+ /* TODO: IS THIS NECESSARY ? */
398
+ for (i = 0; i < 3; i++) {
399
+ offset_MHz[i] = tuner_freq_MHz % adc_Freq_MHz[i];
400
+
401
+ if (offset_MHz[i] > (adc_Freq_MHz[i] / 2))
402
+ offset_MHz[i] = adc_Freq_MHz[i] - offset_MHz[i];
403
+
404
+ if (offset_MHz[i] > max_offset) {
405
+ max_offset = offset_MHz[i];
406
+ reg16 = reg16_list[i];
407
+ dev->mclk = adc_Freq_MHz[i] * 1000 * 1000;
408
+
409
+ if (big_symbol)
410
+ dev->mclk /= 2;
411
+
412
+ dev_dbg(&client->dev, "modifying mclk %u -> %u\n",
413
+ old_setting, dev->mclk);
414
+ }
415
+ }
416
+ }
417
+
418
+ if (dev->mclk == 93000000)
419
+ regmap_write(dev->regmap, 0xA0, 0x42);
420
+ else if (dev->mclk == 96000000)
421
+ regmap_write(dev->regmap, 0xA0, 0x44);
422
+ else if (dev->mclk == 99000000)
423
+ regmap_write(dev->regmap, 0xA0, 0x46);
424
+ else if (dev->mclk == 110250000)
425
+ regmap_write(dev->regmap, 0xA0, 0x4E);
426
+ else
427
+ regmap_write(dev->regmap, 0xA0, 0x44);
428
+
429
+ reg15 = m88ds3103b_dt_read(dev, 0x15);
430
+
431
+ m88ds3103b_dt_write(dev, 0x05, 0x40);
432
+ m88ds3103b_dt_write(dev, 0x11, 0x08);
433
+
434
+ if (big_symbol)
435
+ reg15 |= 0x02;
436
+ else
437
+ reg15 &= ~0x02;
438
+
439
+ m88ds3103b_dt_write(dev, 0x15, reg15);
440
+ m88ds3103b_dt_write(dev, 0x16, reg16);
441
+
442
+ usleep_range(5000, 5500);
443
+
444
+ m88ds3103b_dt_write(dev, 0x05, 0x00);
445
+ m88ds3103b_dt_write(dev, 0x11, (u8)(big_symbol ? 0x0E : 0x0A));
446
+
447
+ usleep_range(5000, 5500);
448
+
449
+ return 0;
450
+}
451
+
452
+static int m88ds3103b_set_mclk(struct m88ds3103_dev *dev, u32 mclk_khz)
453
+{
454
+ u8 reg11 = 0x0A, reg15, reg16, reg1D, reg1E, reg1F, tmp;
455
+ u8 sm, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
456
+ u16 pll_div_fb, N;
457
+ u32 div;
458
+
459
+ reg15 = m88ds3103b_dt_read(dev, 0x15);
460
+ reg16 = m88ds3103b_dt_read(dev, 0x16);
461
+ reg1D = m88ds3103b_dt_read(dev, 0x1D);
462
+
463
+ if (dev->cfg->ts_mode != M88DS3103_TS_SERIAL) {
464
+ if (reg16 == 92)
465
+ tmp = 93;
466
+ else if (reg16 == 100)
467
+ tmp = 99;
468
+ else
469
+ tmp = 96;
470
+
471
+ mclk_khz *= tmp;
472
+ mclk_khz /= 96;
473
+ }
474
+
475
+ pll_div_fb = (reg15 & 0x01) << 8;
476
+ pll_div_fb += reg16;
477
+ pll_div_fb += 32;
478
+
479
+ div = 9000 * pll_div_fb * 4;
480
+ div /= mclk_khz;
481
+
482
+ if (dev->cfg->ts_mode == M88DS3103_TS_SERIAL) {
483
+ reg11 |= 0x02;
484
+
485
+ if (div <= 32) {
486
+ N = 2;
487
+
488
+ f0 = 0;
489
+ f1 = div / N;
490
+ f2 = div - f1;
491
+ f3 = 0;
492
+ } else if (div <= 34) {
493
+ N = 3;
494
+
495
+ f0 = div / N;
496
+ f1 = (div - f0) / (N - 1);
497
+ f2 = div - f0 - f1;
498
+ f3 = 0;
499
+ } else if (div <= 64) {
500
+ N = 4;
501
+
502
+ f0 = div / N;
503
+ f1 = (div - f0) / (N - 1);
504
+ f2 = (div - f0 - f1) / (N - 2);
505
+ f3 = div - f0 - f1 - f2;
506
+ } else {
507
+ N = 4;
508
+
509
+ f0 = 16;
510
+ f1 = 16;
511
+ f2 = 16;
512
+ f3 = 16;
513
+ }
514
+
515
+ if (f0 == 16)
516
+ f0 = 0;
517
+ else if ((f0 < 8) && (f0 != 0))
518
+ f0 = 8;
519
+
520
+ if (f1 == 16)
521
+ f1 = 0;
522
+ else if ((f1 < 8) && (f1 != 0))
523
+ f1 = 8;
524
+
525
+ if (f2 == 16)
526
+ f2 = 0;
527
+ else if ((f2 < 8) && (f2 != 0))
528
+ f2 = 8;
529
+
530
+ if (f3 == 16)
531
+ f3 = 0;
532
+ else if ((f3 < 8) && (f3 != 0))
533
+ f3 = 8;
534
+ } else {
535
+ reg11 &= ~0x02;
536
+
537
+ if (div <= 32) {
538
+ N = 2;
539
+
540
+ f0 = 0;
541
+ f1 = div / N;
542
+ f2 = div - f1;
543
+ f3 = 0;
544
+ } else if (div <= 48) {
545
+ N = 3;
546
+
547
+ f0 = div / N;
548
+ f1 = (div - f0) / (N - 1);
549
+ f2 = div - f0 - f1;
550
+ f3 = 0;
551
+ } else if (div <= 64) {
552
+ N = 4;
553
+
554
+ f0 = div / N;
555
+ f1 = (div - f0) / (N - 1);
556
+ f2 = (div - f0 - f1) / (N - 2);
557
+ f3 = div - f0 - f1 - f2;
558
+ } else {
559
+ N = 4;
560
+
561
+ f0 = 16;
562
+ f1 = 16;
563
+ f2 = 16;
564
+ f3 = 16;
565
+ }
566
+
567
+ if (f0 == 16)
568
+ f0 = 0;
569
+ else if ((f0 < 9) && (f0 != 0))
570
+ f0 = 9;
571
+
572
+ if (f1 == 16)
573
+ f1 = 0;
574
+ else if ((f1 < 9) && (f1 != 0))
575
+ f1 = 9;
576
+
577
+ if (f2 == 16)
578
+ f2 = 0;
579
+ else if ((f2 < 9) && (f2 != 0))
580
+ f2 = 9;
581
+
582
+ if (f3 == 16)
583
+ f3 = 0;
584
+ else if ((f3 < 9) && (f3 != 0))
585
+ f3 = 9;
586
+ }
587
+
588
+ sm = N - 1;
589
+
590
+ /* Write to registers */
591
+ //reg15 &= 0x01;
592
+ //reg15 |= (pll_div_fb >> 8) & 0x01;
593
+
594
+ //reg16 = pll_div_fb & 0xFF;
595
+
596
+ reg1D &= ~0x03;
597
+ reg1D |= sm;
598
+ reg1D |= 0x80;
599
+
600
+ reg1E = ((f3 << 4) + f2) & 0xFF;
601
+ reg1F = ((f1 << 4) + f0) & 0xFF;
602
+
603
+ m88ds3103b_dt_write(dev, 0x05, 0x40);
604
+ m88ds3103b_dt_write(dev, 0x11, 0x08);
605
+ m88ds3103b_dt_write(dev, 0x1D, reg1D);
606
+ m88ds3103b_dt_write(dev, 0x1E, reg1E);
607
+ m88ds3103b_dt_write(dev, 0x1F, reg1F);
608
+
609
+ m88ds3103b_dt_write(dev, 0x17, 0xc1);
610
+ m88ds3103b_dt_write(dev, 0x17, 0x81);
611
+
612
+ usleep_range(5000, 5500);
613
+
614
+ m88ds3103b_dt_write(dev, 0x05, 0x00);
615
+ m88ds3103b_dt_write(dev, 0x11, 0x0A);
616
+
617
+ usleep_range(5000, 5500);
618
+
619
+ return 0;
620
+}
621
+
300622 static int m88ds3103_set_frontend(struct dvb_frontend *fe)
301623 {
302624 struct m88ds3103_dev *dev = fe->demodulator_priv;
....@@ -307,7 +629,7 @@
307629 u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */
308630 u8 buf[3];
309631 u16 u16tmp;
310
- u32 tuner_frequency_khz, target_mclk;
632
+ u32 tuner_frequency_khz, target_mclk, u32tmp;
311633 s32 s32tmp;
312634 static const struct reg_sequence reset_buf[] = {
313635 {0x07, 0x80}, {0x07, 0x00}
....@@ -330,6 +652,20 @@
330652
331653 /* Disable demod clock path */
332654 if (dev->chip_id == M88RS6000_CHIP_ID) {
655
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
656
+ ret = regmap_read(dev->regmap, 0xb2, &u32tmp);
657
+ if (ret)
658
+ goto err;
659
+ if (u32tmp == 0x01) {
660
+ ret = regmap_write(dev->regmap, 0x00, 0x00);
661
+ if (ret)
662
+ goto err;
663
+ ret = regmap_write(dev->regmap, 0xb2, 0x00);
664
+ if (ret)
665
+ goto err;
666
+ }
667
+ }
668
+
333669 ret = regmap_write(dev->regmap, 0x06, 0xe0);
334670 if (ret)
335671 goto err;
....@@ -355,7 +691,7 @@
355691 tuner_frequency_khz = c->frequency;
356692 }
357693
358
- /* select M88RS6000 demod main mclk and ts mclk from tuner die. */
694
+ /* set M88RS6000/DS3103B demod main mclk and ts mclk from tuner die */
359695 if (dev->chip_id == M88RS6000_CHIP_ID) {
360696 if (c->symbol_rate > 45010000)
361697 dev->mclk = 110250000;
....@@ -366,6 +702,11 @@
366702 target_mclk = 96000000;
367703 else
368704 target_mclk = 144000000;
705
+
706
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
707
+ m88ds3103b_select_mclk(dev);
708
+ m88ds3103b_set_mclk(dev, target_mclk / 1000);
709
+ }
369710
370711 /* Enable demod clock path */
371712 ret = regmap_write(dev->regmap, 0x06, 0x00);
....@@ -478,12 +819,42 @@
478819 ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);
479820 if (ret)
480821 goto err;
822
+
823
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
824
+ buf[0] = m88ds3103b_dt_read(dev, 0x15);
825
+ buf[1] = m88ds3103b_dt_read(dev, 0x16);
826
+
827
+ if (c->symbol_rate > 45010000) {
828
+ buf[0] &= ~0x03;
829
+ buf[0] |= 0x02;
830
+ buf[0] |= ((147 - 32) >> 8) & 0x01;
831
+ buf[1] = (147 - 32) & 0xFF;
832
+
833
+ dev->mclk = 110250 * 1000;
834
+ } else {
835
+ buf[0] &= ~0x03;
836
+ buf[0] |= ((128 - 32) >> 8) & 0x01;
837
+ buf[1] = (128 - 32) & 0xFF;
838
+
839
+ dev->mclk = 96000 * 1000;
840
+ }
841
+ m88ds3103b_dt_write(dev, 0x15, buf[0]);
842
+ m88ds3103b_dt_write(dev, 0x16, buf[1]);
843
+
844
+ regmap_read(dev->regmap, 0x30, &u32tmp);
845
+ u32tmp &= ~0x80;
846
+ regmap_write(dev->regmap, 0x30, u32tmp & 0xff);
847
+ }
848
+
481849 ret = regmap_write(dev->regmap, 0xf1, 0x01);
482850 if (ret)
483851 goto err;
484
- ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
485
- if (ret)
486
- goto err;
852
+
853
+ if (dev->chiptype != M88DS3103_CHIPTYPE_3103B) {
854
+ ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
855
+ if (ret)
856
+ goto err;
857
+ }
487858 }
488859
489860 switch (dev->cfg->ts_mode) {
....@@ -497,6 +868,10 @@
497868 break;
498869 case M88DS3103_TS_PARALLEL:
499870 u8tmp = 0x02;
871
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
872
+ u8tmp = 0x01;
873
+ u8tmp1 = 0x01;
874
+ }
500875 break;
501876 case M88DS3103_TS_CI:
502877 u8tmp = 0x03;
....@@ -525,6 +900,13 @@
525900 u8tmp1 = 0x3f;
526901 u8tmp2 = 0x3f;
527902 break;
903
+ case M88DS3103_TS_PARALLEL:
904
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
905
+ ret = m88ds3103_update_bits(dev, 0x29, 0x01, u8tmp1);
906
+ if (ret)
907
+ goto err;
908
+ }
909
+ fallthrough;
528910 default:
529911 u16tmp = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk);
530912 u8tmp1 = u16tmp / 2 - 1;
....@@ -551,6 +933,9 @@
551933 u8tmp = 0x10;
552934 else
553935 u8tmp = 0x06;
936
+
937
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
938
+ m88ds3103b_set_mclk(dev, target_mclk / 1000);
554939
555940 ret = regmap_write(dev->regmap, 0xc3, 0x08);
556941 if (ret)
....@@ -586,6 +971,18 @@
586971 ret = regmap_write(dev->regmap, 0x33, dev->cfg->agc);
587972 if (ret)
588973 goto err;
974
+
975
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
976
+ /* enable/disable 192M LDPC clock */
977
+ ret = m88ds3103_update_bits(dev, 0x29, 0x10,
978
+ (c->delivery_system == SYS_DVBS) ? 0x10 : 0x0);
979
+ if (ret)
980
+ goto err;
981
+
982
+ ret = m88ds3103_update_bits(dev, 0xc9, 0x08, 0x08);
983
+ if (ret)
984
+ goto err;
985
+ }
589986
590987 dev_dbg(&client->dev, "carrier offset=%d\n",
591988 (tuner_frequency_khz - c->frequency));
....@@ -651,7 +1048,7 @@
6511048 if (utmp)
6521049 goto warm;
6531050
654
- /* global reset, global diseqc reset, golbal fec reset */
1051
+ /* global reset, global diseqc reset, global fec reset */
6551052 ret = regmap_write(dev->regmap, 0x07, 0xe0);
6561053 if (ret)
6571054 goto err;
....@@ -661,12 +1058,15 @@
6611058
6621059 /* cold state - try to download firmware */
6631060 dev_info(&client->dev, "found a '%s' in cold state\n",
664
- m88ds3103_ops.info.name);
1061
+ dev->fe.ops.info.name);
6651062
666
- if (dev->chip_id == M88RS6000_CHIP_ID)
1063
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
1064
+ name = M88DS3103B_FIRMWARE;
1065
+ else if (dev->chip_id == M88RS6000_CHIP_ID)
6671066 name = M88RS6000_FIRMWARE;
6681067 else
6691068 name = M88DS3103_FIRMWARE;
1069
+
6701070 /* request the firmware, this will block and timeout */
6711071 ret = request_firmware(&firmware, name, &client->dev);
6721072 if (ret) {
....@@ -709,10 +1109,16 @@
7091109 }
7101110
7111111 dev_info(&client->dev, "found a '%s' in warm state\n",
712
- m88ds3103_ops.info.name);
1112
+ dev->fe.ops.info.name);
7131113 dev_info(&client->dev, "firmware version: %X.%X\n",
7141114 (utmp >> 4) & 0xf, (utmp >> 0 & 0xf));
7151115
1116
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
1117
+ m88ds3103b_dt_write(dev, 0x21, 0x92);
1118
+ m88ds3103b_dt_write(dev, 0x15, 0x6C);
1119
+ m88ds3103b_dt_write(dev, 0x17, 0xC1);
1120
+ m88ds3103b_dt_write(dev, 0x17, 0x81);
1121
+ }
7161122 warm:
7171123 /* warm state */
7181124 dev->warm = true;
....@@ -1283,11 +1689,11 @@
12831689 pdata.attach_in_use = true;
12841690
12851691 memset(&board_info, 0, sizeof(board_info));
1286
- strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
1692
+ strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
12871693 board_info.addr = cfg->i2c_addr;
12881694 board_info.platform_data = &pdata;
1289
- client = i2c_new_device(i2c, &board_info);
1290
- if (!client || !client->dev.driver)
1695
+ client = i2c_new_client_device(i2c, &board_info);
1696
+ if (!i2c_client_has_driver(client))
12911697 return NULL;
12921698
12931699 *tuner_i2c_adapter = pdata.get_i2c_adapter(client);
....@@ -1402,6 +1808,8 @@
14021808 goto err_kfree;
14031809
14041810 dev->chip_id = utmp >> 1;
1811
+ dev->chiptype = (u8)id->driver_data;
1812
+
14051813 dev_dbg(&client->dev, "chip_id=%02x\n", dev->chip_id);
14061814
14071815 switch (dev->chip_id) {
....@@ -1468,8 +1876,11 @@
14681876
14691877 /* create dvb_frontend */
14701878 memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
1471
- if (dev->chip_id == M88RS6000_CHIP_ID)
1472
- strncpy(dev->fe.ops.info.name, "Montage Technology M88RS6000",
1879
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
1880
+ strscpy(dev->fe.ops.info.name, "Montage Technology M88DS3103B",
1881
+ sizeof(dev->fe.ops.info.name));
1882
+ else if (dev->chip_id == M88RS6000_CHIP_ID)
1883
+ strscpy(dev->fe.ops.info.name, "Montage Technology M88RS6000",
14731884 sizeof(dev->fe.ops.info.name));
14741885 if (!pdata->attach_in_use)
14751886 dev->fe.ops.release = NULL;
....@@ -1479,6 +1890,26 @@
14791890 /* setup callbacks */
14801891 pdata->get_dvb_frontend = m88ds3103_get_dvb_frontend;
14811892 pdata->get_i2c_adapter = m88ds3103_get_i2c_adapter;
1893
+
1894
+ if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
1895
+ /* enable i2c repeater for tuner */
1896
+ m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
1897
+
1898
+ /* get frontend address */
1899
+ ret = regmap_read(dev->regmap, 0x29, &utmp);
1900
+ if (ret)
1901
+ goto err_kfree;
1902
+ dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1;
1903
+ dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr);
1904
+
1905
+ dev->dt_client = i2c_new_dummy_device(client->adapter,
1906
+ dev->dt_addr);
1907
+ if (IS_ERR(dev->dt_client)) {
1908
+ ret = PTR_ERR(dev->dt_client);
1909
+ goto err_kfree;
1910
+ }
1911
+ }
1912
+
14821913 return 0;
14831914 err_kfree:
14841915 kfree(dev);
....@@ -1493,6 +1924,9 @@
14931924
14941925 dev_dbg(&client->dev, "\n");
14951926
1927
+ if (dev->dt_client)
1928
+ i2c_unregister_device(dev->dt_client);
1929
+
14961930 i2c_mux_del_adapters(dev->muxc);
14971931
14981932 kfree(dev);
....@@ -1500,7 +1934,9 @@
15001934 }
15011935
15021936 static const struct i2c_device_id m88ds3103_id_table[] = {
1503
- {"m88ds3103", 0},
1937
+ {"m88ds3103", M88DS3103_CHIPTYPE_3103},
1938
+ {"m88rs6000", M88DS3103_CHIPTYPE_RS6000},
1939
+ {"m88ds3103b", M88DS3103_CHIPTYPE_3103B},
15041940 {}
15051941 };
15061942 MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);
....@@ -1522,3 +1958,4 @@
15221958 MODULE_LICENSE("GPL");
15231959 MODULE_FIRMWARE(M88DS3103_FIRMWARE);
15241960 MODULE_FIRMWARE(M88RS6000_FIRMWARE);
1961
+MODULE_FIRMWARE(M88DS3103B_FIRMWARE);