blob: 250462265a41cad316095009329b7342bc6d415c [file] [log] [blame]
Michael Krufky04910bd2008-02-03 23:46:16 -03001/*
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
Michael Krufky99443ae2008-02-03 23:48:09 -030042static int pvr2_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
43{
44 /* TO DO: This function will call into the core and request for
45 * input to be set to 'dtv' if (acquire) and if it isn't set already.
46 *
47 * If (!acquire) then we should do nothing -- don't switch inputs
48 * again unless the analog side of the driver requests the bus.
49 */
50 return 0;
51}
52
Michael Krufky04910bd2008-02-03 23:46:16 -030053static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
54{
55 int ret;
56
57 ret = dvb_register_adapter(&adap->dvb_adap, "pvrusb2-dvb",
58 THIS_MODULE/*&hdw->usb_dev->owner*/,
59 &adap->pvr->hdw->usb_dev->dev,
60 adapter_nr);
61 if (ret < 0) {
62 err("dvb_register_adapter failed: error %d", ret);
63 goto err;
64 }
65 adap->dvb_adap.priv = adap;
66
67 adap->demux.dmx.capabilities = DMX_TS_FILTERING |
68 DMX_SECTION_FILTERING |
69 DMX_MEMORY_BASED_FILTERING;
70 adap->demux.priv = adap;
71 adap->demux.filternum = 256;
72 adap->demux.feednum = 256;
73 adap->demux.start_feed = pvr2_dvb_start_feed;
74 adap->demux.stop_feed = pvr2_dvb_stop_feed;
75 adap->demux.write_to_decoder = NULL;
76
77 ret = dvb_dmx_init(&adap->demux);
78 if (ret < 0) {
79 err("dvb_dmx_init failed: error %d", ret);
80 goto err_dmx;
81 }
82
83 adap->dmxdev.filternum = adap->demux.filternum;
84 adap->dmxdev.demux = &adap->demux.dmx;
85 adap->dmxdev.capabilities = 0;
86
87 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
88 if (ret < 0) {
89 err("dvb_dmxdev_init failed: error %d", ret);
90 goto err_dmx_dev;
91 }
92
93 dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
94
95 adap->digital_up = 1;
96
97 return 0;
98
99err_dmx_dev:
100 dvb_dmx_release(&adap->demux);
101err_dmx:
102 dvb_unregister_adapter(&adap->dvb_adap);
103err:
104 return ret;
105}
106
107static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
108{
109 if (adap->digital_up) {
110 printk(KERN_DEBUG "unregistering DVB devices\n");
111 dvb_net_release(&adap->dvb_net);
112 adap->demux.dmx.close(&adap->demux.dmx);
113 dvb_dmxdev_release(&adap->dmxdev);
114 dvb_dmx_release(&adap->demux);
115 dvb_unregister_adapter(&adap->dvb_adap);
116 adap->digital_up = 0;
117 }
118 return 0;
119}
120
121static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
122{
123 struct pvr2_dvb_props *dvb_props = adap->pvr->hdw->hdw_desc->dvb_props;
124
125 if (dvb_props == NULL) {
126 err("fe_props not defined!");
127 return -EINVAL;
128 }
129
130 if (dvb_props->frontend_attach == NULL) {
131 err("frontend_attach not defined!");
132 return -EINVAL;
133 }
134
135 if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
136
137 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
138 err("frontend registration failed!");
139 dvb_frontend_detach(adap->fe);
140 adap->fe = NULL;
141 return -ENODEV;
142 }
143
144 if (dvb_props->tuner_attach)
145 dvb_props->tuner_attach(adap);
146
147 if (adap->fe->ops.analog_ops.standby)
148 adap->fe->ops.analog_ops.standby(adap->fe);
149
Michael Krufky99443ae2008-02-03 23:48:09 -0300150 /* Ensure all frontends negotiate bus access */
151 adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
152
Michael Krufky04910bd2008-02-03 23:46:16 -0300153 } else {
154 err("no frontend was attached!");
155 return -ENODEV;
156 }
157
158 return 0;
159}
160
161static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
162{
163 if (adap->fe != NULL) {
164 dvb_unregister_frontend(adap->fe);
165 dvb_frontend_detach(adap->fe);
166 }
167 return 0;
168}
169
170int pvr2_dvb_init(struct pvr2_context *pvr)
171{
172 int ret = 0;
173
174 pvr->hdw->dvb.pvr = pvr;
175
176 ret = pvr2_dvb_adapter_init(&pvr->hdw->dvb);
177 if (ret < 0)
178 goto fail;
179
180 ret = pvr2_dvb_frontend_init(&pvr->hdw->dvb);
181fail:
182 return ret;
183}
184
185int pvr2_dvb_exit(struct pvr2_context *pvr)
186{
187 pvr2_dvb_frontend_exit(&pvr->hdw->dvb);
188 pvr2_dvb_adapter_exit(&pvr->hdw->dvb);
189
190 pvr->hdw->dvb.pvr = NULL;
191
192 return 0;
193}