aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2008-02-03 21:46:16 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:46 -0400
commit04910bdc5c172af9bc937a8869e7f2907db4443f (patch)
treeb8b5f224510cca9938f2f766905622632f0f4861 /drivers/media/video/pvrusb2
parente7f677f33664200b3d75ffc625d218b84ac43875 (diff)
V4L/DVB (7679): pvrusb2: add DVB API framework
Add basic framework for the DVB API. This is enough to control the tuner & demod of the digital frontend, but the stream & buffer handling is still missing. Additional note from Mike Isely <isely@pobox.com> - also, since these changes are still very experimental arrange for DVB changes to be compiled in via new CONFIG_VIDEO_PVRUSB2_DVB option, for now. Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/Makefile6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c179
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.h33
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c7
6 files changed, 232 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 47284e558648..b0fa3ece5aa2 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -1,5 +1,6 @@
1obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o 1obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
2obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o 2obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
3obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
3 4
4pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ 5pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
5 pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ 6 pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
@@ -9,6 +10,11 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
9 pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ 10 pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
10 pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ 11 pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
11 pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ 12 pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
13 $(obj-pvrusb2-dvb-y) \
12 $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) 14 $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
13 15
14obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o 16obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
17
18EXTRA_CFLAGS += -Idrivers/media/video
19EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
20EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index fb5f5d17e8cb..cc2c4d78cf41 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -23,6 +23,7 @@
23 23
24#include <linux/mod_devicetable.h> 24#include <linux/mod_devicetable.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include "pvrusb2-dvb.h"
26 27
27/* 28/*
28 29
@@ -65,6 +66,9 @@ struct pvr2_device_desc {
65 was initialized from internal ROM. */ 66 was initialized from internal ROM. */
66 struct pvr2_string_table fx2_firmware; 67 struct pvr2_string_table fx2_firmware;
67 68
69 /* callback functions to handle attachment of digital tuner & demod */
70 struct pvr2_dvb_props *dvb_props;
71
68 /* Initial standard bits to use for this device, if not zero. 72 /* Initial standard bits to use for this device, if not zero.
69 Anything set here is also implied as an available standard. 73 Anything set here is also implied as an available standard.
70 Note: This is ignored if overridden on the module load line via 74 Note: This is ignored if overridden on the module load line via
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
new file mode 100644
index 000000000000..18c18db2fe3c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -0,0 +1,179 @@
1/*
2 * pvrusb2-dvb.c - linux-dvb api interface to the pvrusb2 driver.
3 *
4 * Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
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
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include "dvbdev.h"
22#include "pvrusb2-hdw-internal.h"
23#include "pvrusb2-hdw.h"
24#include "pvrusb2-dvb.h"
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27
28static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
29{
30 printk(KERN_DEBUG "start pid: 0x%04x, feedtype: %d\n",
31 dvbdmxfeed->pid, dvbdmxfeed->type);
32 return 0; /* FIXME: pvr2_dvb_ctrl_feed(dvbdmxfeed, 1); */
33}
34
35static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
36{
37 printk(KERN_DEBUG "stop pid: 0x%04x, feedtype: %d\n",
38 dvbdmxfeed->pid, dvbdmxfeed->type);
39 return 0; /* FIXME: pvr2_dvb_ctrl_feed(dvbdmxfeed, 0); */
40}
41
42static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
43{
44 int ret;
45
46 ret = dvb_register_adapter(&adap->dvb_adap, "pvrusb2-dvb",
47 THIS_MODULE/*&hdw->usb_dev->owner*/,
48 &adap->pvr->hdw->usb_dev->dev,
49 adapter_nr);
50 if (ret < 0) {
51 err("dvb_register_adapter failed: error %d", ret);
52 goto err;
53 }
54 adap->dvb_adap.priv = adap;
55
56 adap->demux.dmx.capabilities = DMX_TS_FILTERING |
57 DMX_SECTION_FILTERING |
58 DMX_MEMORY_BASED_FILTERING;
59 adap->demux.priv = adap;
60 adap->demux.filternum = 256;
61 adap->demux.feednum = 256;
62 adap->demux.start_feed = pvr2_dvb_start_feed;
63 adap->demux.stop_feed = pvr2_dvb_stop_feed;
64 adap->demux.write_to_decoder = NULL;
65
66 ret = dvb_dmx_init(&adap->demux);
67 if (ret < 0) {
68 err("dvb_dmx_init failed: error %d", ret);
69 goto err_dmx;
70 }
71
72 adap->dmxdev.filternum = adap->demux.filternum;
73 adap->dmxdev.demux = &adap->demux.dmx;
74 adap->dmxdev.capabilities = 0;
75
76 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
77 if (ret < 0) {
78 err("dvb_dmxdev_init failed: error %d", ret);
79 goto err_dmx_dev;
80 }
81
82 dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
83
84 adap->digital_up = 1;
85
86 return 0;
87
88err_dmx_dev:
89 dvb_dmx_release(&adap->demux);
90err_dmx:
91 dvb_unregister_adapter(&adap->dvb_adap);
92err:
93 return ret;
94}
95
96static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
97{
98 if (adap->digital_up) {
99 printk(KERN_DEBUG "unregistering DVB devices\n");
100 dvb_net_release(&adap->dvb_net);
101 adap->demux.dmx.close(&adap->demux.dmx);
102 dvb_dmxdev_release(&adap->dmxdev);
103 dvb_dmx_release(&adap->demux);
104 dvb_unregister_adapter(&adap->dvb_adap);
105 adap->digital_up = 0;
106 }
107 return 0;
108}
109
110static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
111{
112 struct pvr2_dvb_props *dvb_props = adap->pvr->hdw->hdw_desc->dvb_props;
113
114 if (dvb_props == NULL) {
115 err("fe_props not defined!");
116 return -EINVAL;
117 }
118
119 if (dvb_props->frontend_attach == NULL) {
120 err("frontend_attach not defined!");
121 return -EINVAL;
122 }
123
124 if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
125
126 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
127 err("frontend registration failed!");
128 dvb_frontend_detach(adap->fe);
129 adap->fe = NULL;
130 return -ENODEV;
131 }
132
133 if (dvb_props->tuner_attach)
134 dvb_props->tuner_attach(adap);
135
136 if (adap->fe->ops.analog_ops.standby)
137 adap->fe->ops.analog_ops.standby(adap->fe);
138
139 } else {
140 err("no frontend was attached!");
141 return -ENODEV;
142 }
143
144 return 0;
145}
146
147static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
148{
149 if (adap->fe != NULL) {
150 dvb_unregister_frontend(adap->fe);
151 dvb_frontend_detach(adap->fe);
152 }
153 return 0;
154}
155
156int pvr2_dvb_init(struct pvr2_context *pvr)
157{
158 int ret = 0;
159
160 pvr->hdw->dvb.pvr = pvr;
161
162 ret = pvr2_dvb_adapter_init(&pvr->hdw->dvb);
163 if (ret < 0)
164 goto fail;
165
166 ret = pvr2_dvb_frontend_init(&pvr->hdw->dvb);
167fail:
168 return ret;
169}
170
171int pvr2_dvb_exit(struct pvr2_context *pvr)
172{
173 pvr2_dvb_frontend_exit(&pvr->hdw->dvb);
174 pvr2_dvb_adapter_exit(&pvr->hdw->dvb);
175
176 pvr->hdw->dvb.pvr = NULL;
177
178 return 0;
179}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.h b/drivers/media/video/pvrusb2/pvrusb2-dvb.h
new file mode 100644
index 000000000000..0aff05cb9415
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.h
@@ -0,0 +1,33 @@
1#ifndef __PVRUSB2_DVB_H__
2#define __PVRUSB2_DVB_H__
3
4#include "dvb_frontend.h"
5#include "dvb_demux.h"
6#include "dvb_net.h"
7#include "dmxdev.h"
8#include "pvrusb2-context.h"
9
10struct pvr2_dvb_adapter {
11 struct pvr2_context *pvr;
12
13 struct dvb_adapter dvb_adap;
14 struct dmxdev dmxdev;
15 struct dvb_demux demux;
16 struct dvb_net dvb_net;
17 struct dvb_frontend *fe;
18
19 int feedcount;
20 int max_feed_count;
21
22 unsigned int digital_up:1;
23};
24
25struct pvr2_dvb_props {
26 int (*frontend_attach) (struct pvr2_dvb_adapter *);
27 int (*tuner_attach) (struct pvr2_dvb_adapter *);
28};
29
30int pvr2_dvb_init(struct pvr2_context *pvr);
31int pvr2_dvb_exit(struct pvr2_context *pvr);
32
33#endif /* __PVRUSB2_DVB_H__ */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index c725495826ce..6fe0a882209f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -41,6 +41,7 @@
41#include "pvrusb2-io.h" 41#include "pvrusb2-io.h"
42#include <media/cx2341x.h> 42#include <media/cx2341x.h>
43#include "pvrusb2-devattr.h" 43#include "pvrusb2-devattr.h"
44#include "pvrusb2-dvb.h"
44 45
45/* Legal values for PVR2_CID_HSM */ 46/* Legal values for PVR2_CID_HSM */
46#define PVR2_CVAL_HSM_FAIL 0 47#define PVR2_CVAL_HSM_FAIL 0
@@ -373,6 +374,8 @@ struct pvr2_hdw {
373 374
374 struct pvr2_ctrl *controls; 375 struct pvr2_ctrl *controls;
375 unsigned int control_cnt; 376 unsigned int control_cnt;
377
378 struct pvr2_dvb_adapter dvb;
376}; 379};
377 380
378/* This function gets the current frequency */ 381/* This function gets the current frequency */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index b63b2265503a..68f4a7480737 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -60,6 +60,10 @@ static void pvr_setup_attach(struct pvr2_context *pvr)
60{ 60{
61 /* Create association with v4l layer */ 61 /* Create association with v4l layer */
62 pvr2_v4l2_create(pvr); 62 pvr2_v4l2_create(pvr);
63#ifdef CONFIG_VIDEO_PVRUSB2_DVB
64 /* Create association with dvb layer */
65 pvr2_dvb_init(pvr);
66#endif
63#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS 67#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
64 pvr2_sysfs_create(pvr,class_ptr); 68 pvr2_sysfs_create(pvr,class_ptr);
65#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ 69#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
@@ -95,6 +99,9 @@ static void pvr_disconnect(struct usb_interface *intf)
95 99
96 pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr); 100 pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr);
97 101
102#ifdef CONFIG_VIDEO_PVRUSB2_DVB
103 pvr2_dvb_exit(pvr);
104#endif
98 usb_set_intfdata (intf, NULL); 105 usb_set_intfdata (intf, NULL);
99 pvr2_context_disconnect(pvr); 106 pvr2_context_disconnect(pvr);
100 107