aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-dvb.c
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2006-12-02 18:15:51 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 05:50:47 -0500
commit6c5be74c86f102c2d4e123bc51d2fa93155fd794 (patch)
tree72bb1b00045f7c263721f113f92d286405ae96d7 /drivers/media/video/cx88/cx88-dvb.c
parent91bb9be6ff4101652bb104f9f083f340e73ba6dd (diff)
V4L/DVB (4676): Dynamic cx88 mpeg port management for HVR1300 MPEG2/DVB-T support.
A series of patches to change the cx88 framework to allow the PCI mpeg port to be shared dynamically between different types of drivers or applications. This patch changes the cx88-dvb and cx88-blackbird drivers to become 'sub drivers' of a higher single cx88-mpeg driver. The cx88-mpeg driver is a superset of the previous cx88-mpeg/blackbird drivers and now owns the IRQ. cx88-dvb/blackbird now become mini drivers, registering themselves with cx88-mpeg through a standard interface with callbacks. Sub drivers request access to hardware via the cx88-mpeg driver. In turn the cx88-mpeg driver determines whether the hardware is busy and accepts or refuses the request, grant access using callbacks into the sub drivers. The net effect is that you are no longer able to tamper with the mpeg port from multiple different applications at the same time, potentially breaking a live mpeg2 hardware encoding or dvb stream. The mechanism extends to enable multiple dvb frontends to be registered and share the single resource. Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/cx88/cx88-dvb.c')
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c197
1 files changed, 108 insertions, 89 deletions
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 0ef13e7efa2e..8150c09cd2c0 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -57,7 +57,7 @@ module_param(debug, int, 0644);
57MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); 57MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
58 58
59#define dprintk(level,fmt, arg...) if (debug >= level) \ 59#define dprintk(level,fmt, arg...) if (debug >= level) \
60 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg) 60 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
61 61
62/* ------------------------------------------------------------------ */ 62/* ------------------------------------------------------------------ */
63 63
@@ -315,20 +315,36 @@ static struct cx22702_config hauppauge_novat_config = {
315 .demod_address = 0x43, 315 .demod_address = 0x43,
316 .output_mode = CX22702_SERIAL_OUTPUT, 316 .output_mode = CX22702_SERIAL_OUTPUT,
317}; 317};
318
319static struct cx22702_config hauppauge_hvr1100_config = { 318static struct cx22702_config hauppauge_hvr1100_config = {
320 .demod_address = 0x63, 319 .demod_address = 0x63,
321 .output_mode = CX22702_SERIAL_OUTPUT, 320 .output_mode = CX22702_SERIAL_OUTPUT,
322}; 321};
323 322static struct cx22702_config hauppauge_hvr3000_config = {
324static struct cx22702_config hauppauge_hvr1300_config = {
325 .demod_address = 0x63, 323 .demod_address = 0x63,
326 .output_mode = CX22702_SERIAL_OUTPUT, 324 .output_mode = CX22702_SERIAL_OUTPUT,
327}; 325};
328 326
329static struct cx22702_config hauppauge_hvr3000_config = { 327static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe,
328 int acquire)
329{
330 struct cx8802_dev *dev= fe->dvb->priv;
331 struct cx8802_driver *drv = NULL;
332 int ret = 0;
333
334 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
335 if (drv) {
336 if(acquire)
337 ret = drv->request_acquire(drv);
338 else
339 ret = drv->request_release(drv);
340 }
341
342 return ret;
343}
344
345static struct cx22702_config hauppauge_hvr1300_config = {
330 .demod_address = 0x63, 346 .demod_address = 0x63,
331 .output_mode = CX22702_SERIAL_OUTPUT, 347 .output_mode = CX22702_SERIAL_OUTPUT,
332}; 348};
333 349
334static int or51132_set_ts_param(struct dvb_frontend* fe, 350static int or51132_set_ts_param(struct dvb_frontend* fe,
@@ -555,26 +571,6 @@ static int dvb_register(struct cx8802_dev *dev)
555 &dvb_pll_fmd1216me); 571 &dvb_pll_fmd1216me);
556 } 572 }
557 break; 573 break;
558 case CX88_BOARD_HAUPPAUGE_HVR1300:
559 dev->dvb.frontend = dvb_attach(cx22702_attach,
560 &hauppauge_hvr1300_config,
561 &dev->core->i2c_adap);
562 if (dev->dvb.frontend != NULL) {
563 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
564 &dev->core->i2c_adap,
565 &dvb_pll_fmd1216me);
566 }
567 break;
568 case CX88_BOARD_HAUPPAUGE_HVR3000:
569 dev->dvb.frontend = dvb_attach(cx22702_attach,
570 &hauppauge_hvr3000_config,
571 &dev->core->i2c_adap);
572 if (dev->dvb.frontend != NULL) {
573 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
574 &dev->core->i2c_adap,
575 &dvb_pll_fmd1216me);
576 }
577 break;
578 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 574 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
579 dev->dvb.frontend = dvb_attach(mt352_attach, 575 dev->dvb.frontend = dvb_attach(mt352_attach,
580 &dvico_fusionhdtv, 576 &dvico_fusionhdtv,
@@ -782,6 +778,26 @@ static int dvb_register(struct cx8802_dev *dev)
782 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 778 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
783 } 779 }
784 break; 780 break;
781 case CX88_BOARD_HAUPPAUGE_HVR1300:
782 dev->dvb.frontend = dvb_attach(cx22702_attach,
783 &hauppauge_hvr1300_config,
784 &dev->core->i2c_adap);
785 if (dev->dvb.frontend != NULL) {
786 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
787 &dev->core->i2c_adap,
788 &dvb_pll_fmd1216me);
789 }
790 break;
791 case CX88_BOARD_HAUPPAUGE_HVR3000:
792 dev->dvb.frontend = dvb_attach(cx22702_attach,
793 &hauppauge_hvr3000_config,
794 &dev->core->i2c_adap);
795 if (dev->dvb.frontend != NULL) {
796 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
797 &dev->core->i2c_adap,
798 &dvb_pll_fmd1216me);
799 }
800 break;
785 default: 801 default:
786 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 802 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
787 dev->core->name); 803 dev->core->name);
@@ -796,6 +812,8 @@ static int dvb_register(struct cx8802_dev *dev)
796 dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; 812 dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min;
797 dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; 813 dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max;
798 } 814 }
815 /* Ensure all frontends negotiate bus access */
816 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
799 817
800 /* Put the analog decoder in standby to keep it quiet */ 818 /* Put the analog decoder in standby to keep it quiet */
801 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 819 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
@@ -806,37 +824,67 @@ static int dvb_register(struct cx8802_dev *dev)
806 824
807/* ----------------------------------------------------------- */ 825/* ----------------------------------------------------------- */
808 826
809static int __devinit dvb_probe(struct pci_dev *pci_dev, 827/* CX8802 MPEG -> mini driver - We have been given the hardware */
810 const struct pci_device_id *pci_id) 828static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
811{ 829{
812 struct cx8802_dev *dev; 830 struct cx88_core *core = drv->core;
813 struct cx88_core *core; 831 int err = 0;
832 dprintk( 1, "%s\n", __FUNCTION__);
833
834 switch (core->board) {
835 case CX88_BOARD_HAUPPAUGE_HVR1300:
836 /* We arrive here with either the cx23416 or the cx22702
837 * on the bus. Take the bus from the cx23416 and enable the
838 * cx22702 demod
839 */
840 cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */
841 cx_clear(MO_GP0_IO, 0x00000004);
842 udelay(1000);
843 break;
844 default:
845 err = -ENODEV;
846 }
847 return err;
848}
849
850/* CX8802 MPEG -> mini driver - We no longer have the hardware */
851static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
852{
853 struct cx88_core *core = drv->core;
854 int err = 0;
855 dprintk( 1, "%s\n", __FUNCTION__);
856
857 switch (core->board) {
858 case CX88_BOARD_HAUPPAUGE_HVR1300:
859 /* Do Nothing, leave the cx22702 on the bus. */
860 break;
861 default:
862 err = -ENODEV;
863 }
864 return err;
865}
866
867static int cx8802_dvb_probe(struct cx8802_driver *drv)
868{
869 struct cx88_core *core = drv->core;
870 struct cx8802_dev *dev = drv->core->dvbdev;
814 int err; 871 int err;
815 872
816 /* general setup */ 873 dprintk( 1, "%s\n", __FUNCTION__);
817 core = cx88_core_get(pci_dev); 874 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
818 if (NULL == core) 875 core->board,
819 return -EINVAL; 876 core->name,
877 core->pci_bus,
878 core->pci_slot);
820 879
821 err = -ENODEV; 880 err = -ENODEV;
822 if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) 881 if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
823 goto fail_core; 882 goto fail_core;
824 883
825 err = -ENOMEM;
826 dev = kzalloc(sizeof(*dev),GFP_KERNEL);
827 if (NULL == dev)
828 goto fail_core;
829 dev->pci = pci_dev;
830 dev->core = core;
831
832 err = cx8802_init_common(dev);
833 if (0 != err)
834 goto fail_free;
835
836#ifdef HAVE_VP3054_I2C 884#ifdef HAVE_VP3054_I2C
837 err = vp3054_i2c_probe(dev); 885 err = vp3054_i2c_probe(dev);
838 if (0 != err) 886 if (0 != err)
839 goto fail_free; 887 goto fail_core;
840#endif 888#endif
841 889
842 /* dvb stuff */ 890 /* dvb stuff */
@@ -848,28 +896,16 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
848 sizeof(struct cx88_buffer), 896 sizeof(struct cx88_buffer),
849 dev); 897 dev);
850 err = dvb_register(dev); 898 err = dvb_register(dev);
851 if (0 != err) 899 if (err != 0)
852 goto fail_fini; 900 printk("%s dvb_register failed err = %d\n", __FUNCTION__, err);
853
854 /* Maintain a reference to cx88-video can query the 8802 device. */
855 core->dvbdev = dev;
856 return 0;
857 901
858 fail_fini:
859 cx8802_fini_common(dev);
860 fail_free:
861 kfree(dev);
862 fail_core: 902 fail_core:
863 cx88_core_put(core,pci_dev);
864 return err; 903 return err;
865} 904}
866 905
867static void __devexit dvb_remove(struct pci_dev *pci_dev) 906static int cx8802_dvb_remove(struct cx8802_driver *drv)
868{ 907{
869 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 908 struct cx8802_dev *dev = drv->core->dvbdev;
870
871 /* Destroy any 8802 reference. */
872 dev->core->dvbdev = NULL;
873 909
874 /* dvb */ 910 /* dvb */
875 videobuf_dvb_unregister(&dev->dvb); 911 videobuf_dvb_unregister(&dev->dvb);
@@ -878,33 +914,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
878 vp3054_i2c_remove(dev); 914 vp3054_i2c_remove(dev);
879#endif 915#endif
880 916
881 /* common */ 917 return 0;
882 cx8802_fini_common(dev);
883 cx88_core_put(dev->core,dev->pci);
884 kfree(dev);
885} 918}
886 919
887static struct pci_device_id cx8802_pci_tbl[] = { 920static struct cx8802_driver cx8802_dvb_driver = {
888 { 921 .type_id = CX88_MPEG_DVB,
889 .vendor = 0x14f1, 922 .hw_access = CX8802_DRVCTL_SHARED,
890 .device = 0x8802, 923 .probe = cx8802_dvb_probe,
891 .subvendor = PCI_ANY_ID, 924 .remove = cx8802_dvb_remove,
892 .subdevice = PCI_ANY_ID, 925 .advise_acquire = cx8802_dvb_advise_acquire,
893 },{ 926 .advise_release = cx8802_dvb_advise_release,
894 /* --- end of list --- */
895 }
896};
897MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
898
899static struct pci_driver dvb_pci_driver = {
900 .name = "cx88-dvb",
901 .id_table = cx8802_pci_tbl,
902 .probe = dvb_probe,
903 .remove = __devexit_p(dvb_remove),
904#ifdef CONFIG_PM
905 .suspend = cx8802_suspend_common,
906 .resume = cx8802_resume_common,
907#endif
908}; 927};
909 928
910static int dvb_init(void) 929static int dvb_init(void)
@@ -917,12 +936,12 @@ static int dvb_init(void)
917 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", 936 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
918 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); 937 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
919#endif 938#endif
920 return pci_register_driver(&dvb_pci_driver); 939 return cx8802_register_driver(&cx8802_dvb_driver);
921} 940}
922 941
923static void dvb_fini(void) 942static void dvb_fini(void)
924{ 943{
925 pci_unregister_driver(&dvb_pci_driver); 944 cx8802_unregister_driver(&cx8802_dvb_driver);
926} 945}
927 946
928module_init(dvb_init); 947module_init(dvb_init);