aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorDirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name>2010-02-11 16:06:34 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:11:11 -0500
commit4f3ca2f152844c5f6ea853077f56d0db877d1f7a (patch)
treebe78601dee9e0c75b8a8bb9cc3a00994f70ba836 /drivers/media/video
parent144dcdceb6ca320d7b3dffa6eea6c0a57cbfbb18 (diff)
V4L/DVB: Add support for SMT7020 to cx88
This patch adds support for the built-in dvb device of a Samsung SMT7020s (x86 based STB) to the cx88 family. Signed-off-by: Dirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name> Signed-off-by: Helmut Auer <helmut@helmutauer.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/cx88/cx88-cards.c23
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c216
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c3
-rw-r--r--drivers/media/video/cx88/cx88.h1
4 files changed, 243 insertions, 0 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index d844f2aaa01d..eaf0ee7de832 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1466,6 +1466,18 @@ static const struct cx88_board cx88_boards[] = {
1466 .audioroute = 8, 1466 .audioroute = 8,
1467 }, 1467 },
1468 }, 1468 },
1469 [CX88_BOARD_SAMSUNG_SMT_7020] = {
1470 .name = "Samsung SMT 7020 DVB-S",
1471 .tuner_type = TUNER_ABSENT,
1472 .radio_type = UNSET,
1473 .tuner_addr = ADDR_UNSET,
1474 .radio_addr = ADDR_UNSET,
1475 .input = { {
1476 .type = CX88_VMUX_DVB,
1477 .vmux = 0,
1478 } },
1479 .mpeg = CX88_MPEG_DVB,
1480 },
1469 [CX88_BOARD_ADSTECH_PTV_390] = { 1481 [CX88_BOARD_ADSTECH_PTV_390] = {
1470 .name = "ADS Tech Instant Video PCI", 1482 .name = "ADS Tech Instant Video PCI",
1471 .tuner_type = TUNER_ABSENT, 1483 .tuner_type = TUNER_ABSENT,
@@ -2355,6 +2367,14 @@ static const struct cx88_subid cx88_subids[] = {
2355 .subvendor = 0x0070, 2367 .subvendor = 0x0070,
2356 .subdevice = 0x1404, 2368 .subdevice = 0x1404,
2357 .card = CX88_BOARD_HAUPPAUGE_HVR3000, 2369 .card = CX88_BOARD_HAUPPAUGE_HVR3000,
2370 }, {
2371 .subvendor = 0x18ac,
2372 .subdevice = 0xdc00,
2373 .card = CX88_BOARD_SAMSUNG_SMT_7020,
2374 }, {
2375 .subvendor = 0x18ac,
2376 .subdevice = 0xdccd,
2377 .card = CX88_BOARD_SAMSUNG_SMT_7020,
2358 },{ 2378 },{
2359 .subvendor = 0x1461, 2379 .subvendor = 0x1461,
2360 .subdevice = 0xc111, /* AverMedia M150-D */ 2380 .subdevice = 0xc111, /* AverMedia M150-D */
@@ -2633,6 +2653,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2633 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */ 2653 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
2634 /* known */ 2654 /* known */
2635 break; 2655 break;
2656 case CX88_BOARD_SAMSUNG_SMT_7020:
2657 cx_set(MO_GP0_IO, 0x008989FF);
2658 break;
2636 default: 2659 default:
2637 warn_printk(core, "warning: unknown hauppauge model #%d\n", 2660 warn_printk(core, "warning: unknown hauppauge model #%d\n",
2638 tv.model); 2661 tv.model);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index b14296923250..5070deffcfc1 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -674,6 +674,194 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev)
674 return 0; 674 return 0;
675} 675}
676 676
677
678
679static u8 samsung_smt_7020_inittab[] = {
680 0x01, 0x15,
681 0x02, 0x00,
682 0x03, 0x00,
683 0x04, 0x7D,
684 0x05, 0x0F,
685 0x06, 0x02,
686 0x07, 0x00,
687 0x08, 0x60,
688
689 0x0A, 0xC2,
690 0x0B, 0x00,
691 0x0C, 0x01,
692 0x0D, 0x81,
693 0x0E, 0x44,
694 0x0F, 0x09,
695 0x10, 0x3C,
696 0x11, 0x84,
697 0x12, 0xDA,
698 0x13, 0x99,
699 0x14, 0x8D,
700 0x15, 0xCE,
701 0x16, 0xE8,
702 0x17, 0x43,
703 0x18, 0x1C,
704 0x19, 0x1B,
705 0x1A, 0x1D,
706
707 0x1C, 0x12,
708 0x1D, 0x00,
709 0x1E, 0x00,
710 0x1F, 0x00,
711 0x20, 0x00,
712 0x21, 0x00,
713 0x22, 0x00,
714 0x23, 0x00,
715
716 0x28, 0x02,
717 0x29, 0x28,
718 0x2A, 0x14,
719 0x2B, 0x0F,
720 0x2C, 0x09,
721 0x2D, 0x05,
722
723 0x31, 0x1F,
724 0x32, 0x19,
725 0x33, 0xFC,
726 0x34, 0x13,
727 0xff, 0xff,
728};
729
730
731static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
732 struct dvb_frontend_parameters *params)
733{
734 struct cx8802_dev *dev = fe->dvb->priv;
735 u8 buf[4];
736 u32 div;
737 struct i2c_msg msg = {
738 .addr = 0x61,
739 .flags = 0,
740 .buf = buf,
741 .len = sizeof(buf) };
742
743 div = params->frequency / 125;
744
745 buf[0] = (div >> 8) & 0x7f;
746 buf[1] = div & 0xff;
747 buf[2] = 0x84; /* 0xC4 */
748 buf[3] = 0x00;
749
750 if (params->frequency < 1500000)
751 buf[3] |= 0x10;
752
753 if (fe->ops.i2c_gate_ctrl)
754 fe->ops.i2c_gate_ctrl(fe, 1);
755
756 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
757 return -EIO;
758
759 return 0;
760}
761
762static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
763 fe_sec_tone_mode_t tone)
764{
765 struct cx8802_dev *dev = fe->dvb->priv;
766 struct cx88_core *core = dev->core;
767
768 cx_set(MO_GP0_IO, 0x0800);
769
770 switch (tone) {
771 case SEC_TONE_ON:
772 cx_set(MO_GP0_IO, 0x08);
773 break;
774 case SEC_TONE_OFF:
775 cx_clear(MO_GP0_IO, 0x08);
776 break;
777 default:
778 return -EINVAL;
779 }
780
781 return 0;
782}
783
784static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
785 fe_sec_voltage_t voltage)
786{
787 struct cx8802_dev *dev = fe->dvb->priv;
788 struct cx88_core *core = dev->core;
789
790 u8 data;
791 struct i2c_msg msg = {
792 .addr = 8,
793 .flags = 0,
794 .buf = &data,
795 .len = sizeof(data) };
796
797 cx_set(MO_GP0_IO, 0x8000);
798
799 switch (voltage) {
800 case SEC_VOLTAGE_OFF:
801 break;
802 case SEC_VOLTAGE_13:
803 data = ISL6421_EN1 | ISL6421_LLC1;
804 cx_clear(MO_GP0_IO, 0x80);
805 break;
806 case SEC_VOLTAGE_18:
807 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
808 cx_clear(MO_GP0_IO, 0x80);
809 break;
810 default:
811 return -EINVAL;
812 };
813
814 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
815}
816
817static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
818 u32 srate, u32 ratio)
819{
820 u8 aclk = 0;
821 u8 bclk = 0;
822
823 if (srate < 1500000) {
824 aclk = 0xb7;
825 bclk = 0x47;
826 } else if (srate < 3000000) {
827 aclk = 0xb7;
828 bclk = 0x4b;
829 } else if (srate < 7000000) {
830 aclk = 0xb7;
831 bclk = 0x4f;
832 } else if (srate < 14000000) {
833 aclk = 0xb7;
834 bclk = 0x53;
835 } else if (srate < 30000000) {
836 aclk = 0xb6;
837 bclk = 0x53;
838 } else if (srate < 45000000) {
839 aclk = 0xb4;
840 bclk = 0x51;
841 }
842
843 stv0299_writereg(fe, 0x13, aclk);
844 stv0299_writereg(fe, 0x14, bclk);
845 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
846 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
847 stv0299_writereg(fe, 0x21, ratio & 0xf0);
848
849 return 0;
850}
851
852
853static struct stv0299_config samsung_stv0299_config = {
854 .demod_address = 0x68,
855 .inittab = samsung_smt_7020_inittab,
856 .mclk = 88000000UL,
857 .invert = 0,
858 .skip_reinit = 0,
859 .lock_output = STV0299_LOCKOUTPUT_LK,
860 .volt13_op0_op1 = STV0299_VOLT13_OP1,
861 .min_delay_ms = 100,
862 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
863};
864
677static int dvb_register(struct cx8802_dev *dev) 865static int dvb_register(struct cx8802_dev *dev)
678{ 866{
679 struct cx88_core *core = dev->core; 867 struct cx88_core *core = dev->core;
@@ -1203,6 +1391,34 @@ static int dvb_register(struct cx8802_dev *dev)
1203 } 1391 }
1204 break; 1392 break;
1205 } 1393 }
1394 case CX88_BOARD_SAMSUNG_SMT_7020:
1395 dev->ts_gen_cntrl = 0x08;
1396
1397 struct cx88_core *core = dev->core;
1398
1399 cx_set(MO_GP0_IO, 0x0101);
1400
1401 cx_clear(MO_GP0_IO, 0x01);
1402 mdelay(100);
1403 cx_set(MO_GP0_IO, 0x01);
1404 mdelay(200);
1405
1406 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1407 &samsung_stv0299_config,
1408 &dev->core->i2c_adap);
1409 if (fe0->dvb.frontend) {
1410 fe0->dvb.frontend->ops.tuner_ops.set_params =
1411 samsung_smt_7020_tuner_set_params;
1412 fe0->dvb.frontend->tuner_priv =
1413 &dev->core->i2c_adap;
1414 fe0->dvb.frontend->ops.set_voltage =
1415 samsung_smt_7020_set_voltage;
1416 fe0->dvb.frontend->ops.set_tone =
1417 samsung_smt_7020_set_tone;
1418 }
1419
1420 break;
1421
1206 default: 1422 default:
1207 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1423 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1208 core->name); 1424 core->name);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index bb5104893411..338af77f7f01 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -110,6 +110,9 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
110 case CX88_BOARD_PCHDTV_HD5500: 110 case CX88_BOARD_PCHDTV_HD5500:
111 cx_write(TS_SOP_STAT, 1<<13); 111 cx_write(TS_SOP_STAT, 1<<13);
112 break; 112 break;
113 case CX88_BOARD_SAMSUNG_SMT_7020:
114 cx_write(TS_SOP_STAT, 0x00);
115 break;
113 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 116 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
114 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 117 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
115 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ 118 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index b1499bf604ea..48b6c04fb497 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -239,6 +239,7 @@ extern struct sram_channel cx88_sram_channels[];
239#define CX88_BOARD_WINFAST_DTV1800H 81 239#define CX88_BOARD_WINFAST_DTV1800H 81
240#define CX88_BOARD_WINFAST_DTV2000H_J 82 240#define CX88_BOARD_WINFAST_DTV2000H_J 82
241#define CX88_BOARD_PROF_7301 83 241#define CX88_BOARD_PROF_7301 83
242#define CX88_BOARD_SAMSUNG_SMT_7020 84
242 243
243enum cx88_itype { 244enum cx88_itype {
244 CX88_VMUX_COMPOSITE1 = 1, 245 CX88_VMUX_COMPOSITE1 = 1,