aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/videobuf-dvb.c
diff options
context:
space:
mode:
authorSteven Toth <stoth@linuxtv.org>2008-10-11 10:05:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-17 16:23:10 -0400
commit363c35fc448943c3d6121332d28bcda2d2fbf87c (patch)
tree739864d237b7fa60bef51bc510fe55c888b606ca /drivers/media/video/videobuf-dvb.c
parent548da7625c825eccc31b4b3865ae5389c3660486 (diff)
V4L/DVB (9222): S2API: Add Multiple-frontend on a single adapter support.
A detailed description from the original patches 2 years ago: "The WinTV-HVR3000 has a single transport bus which is shared between a DVB-T and DVB-S modulator. These patches build on the bus acquisition cx88 work from a few weeks ago to add support for this. So to applications the HVR3000 looks like this: /dev/dvb/adapter0/fe0 (cx24123 DVB-S demod) /dev/dvb/adapter0/fe1 (cx22702 DVB-T demod) Additional boards continue as before, eg: /dev/dvb/adapter1/fe0 (lgdt3302 ATSC demod) The basic change is removing the single instance of the videobuf_dvb in cx8802_dev and saa7134_dev(?) and replacing it with a list and some supporting functions. *NOTE* This branch was taken before v4l-dvb was closed for 2.6.19 so two or three current cx88 patches appear to be reversed by this tree, this will be cleaned up in the near future. The patches missing change the mutex handing to core->lock, fix an enumeration problem." It should be recognised that a number of people have been maintaining this patchset. Significant levels of Kudos to everyone one involved, including but not limited to: Darron Broad Fabio M. Di Nitto Carlo Scarfoglio Hans Werner Without the work of these people, and countless others, my two year old patches would of died on the Mercurial linuxtv.org vine a long time ago. TODO: Revise these patches a little further so that the need for demux1 and dvr0 is optional, not mandatory on the HVR3000. HISTORY (darron): This is the last update to MFE prepared by Hans which is based upon the `scratchpad' diff created by Carlo. All MFE work prior to that point must be attributed to Fabio who ported and maintained Steve's original patch up to that time. Signed-off-by: Steven Toth <stoth@linuxtv.org> Signed-off-by: Darron Broad <darron@kewl.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/videobuf-dvb.c')
-rw-r--r--drivers/media/video/videobuf-dvb.c171
1 files changed, 148 insertions, 23 deletions
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index b56cffcbfd45..194fb765e58b 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -135,29 +135,75 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
135} 135}
136 136
137/* ------------------------------------------------------------------ */ 137/* ------------------------------------------------------------------ */
138/* Register a single adapter and one or more frontends */
139int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
140 struct module *module,
141 void *adapter_priv,
142 struct device *device,
143 short *adapter_nr) //NEW
144{
145 struct list_head *list, *q;
146 struct videobuf_dvb_frontend *fe;
147 int res = -EINVAL;
148
149 fe = videobuf_dvb_get_frontend(f, 1);
150 if (!fe) {
151 printk(KERN_WARNING "Unable to register the adapter which has no frontends\n");
152 goto err;
153 }
154
155 /* Bring up the adapter */
156 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, fe->dvb.name, adapter_nr); //NEW
157 if (res < 0) {
158 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
159 goto err;
160 }
138 161
139int videobuf_dvb_register(struct videobuf_dvb *dvb, 162 /* Attach all of the frontends to the adapter */
163 mutex_lock(&f->lock);
164 list_for_each_safe(list, q, &f->frontend.felist) {
165 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
166
167 res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb);
168 if (res < 0) {
169 printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n",
170 fe->dvb.name, res);
171 }
172 }
173 mutex_unlock(&f->lock);
174
175err:
176 return res;
177}
178
179int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
140 struct module *module, 180 struct module *module,
141 void *adapter_priv, 181 void *adapter_priv,
142 struct device *device, 182 struct device *device,
143 short *adapter_nr) 183 char *adapter_name,
184 short *adapter_nr) //NEW
144{ 185{
145 int result; 186 int result;
146 187
147 mutex_init(&dvb->lock); 188 mutex_init(&fe->lock);
148 189
149 /* register adapter */ 190 /* register adapter */
150 result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device, 191 result = dvb_register_adapter(&fe->adapter, adapter_name, module, device, adapter_nr);
151 adapter_nr);
152 if (result < 0) { 192 if (result < 0) {
153 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", 193 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
154 dvb->name, result); 194 adapter_name, result);
155 goto fail_adapter;
156 } 195 }
157 dvb->adapter.priv = adapter_priv; 196 fe->adapter.priv = adapter_priv;
197
198 return result;
199}
200
201int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb)
202{
203 int result;
158 204
159 /* register frontend */ 205 /* register frontend */
160 result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 206 result = dvb_register_frontend(adapter, dvb->frontend);
161 if (result < 0) { 207 if (result < 0) {
162 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", 208 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
163 dvb->name, result); 209 dvb->name, result);
@@ -183,7 +229,9 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
183 dvb->dmxdev.filternum = 256; 229 dvb->dmxdev.filternum = 256;
184 dvb->dmxdev.demux = &dvb->demux.dmx; 230 dvb->dmxdev.demux = &dvb->demux.dmx;
185 dvb->dmxdev.capabilities = 0; 231 dvb->dmxdev.capabilities = 0;
186 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); 232 //result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
233 result = dvb_dmxdev_init(&dvb->dmxdev, adapter);
234
187 if (result < 0) { 235 if (result < 0) {
188 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", 236 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
189 dvb->name, result); 237 dvb->name, result);
@@ -214,7 +262,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
214 } 262 }
215 263
216 /* register network adapter */ 264 /* register network adapter */
217 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 265 dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
218 return 0; 266 return 0;
219 267
220fail_fe_conn: 268fail_fe_conn:
@@ -230,24 +278,101 @@ fail_dmx:
230fail_frontend: 278fail_frontend:
231 dvb_frontend_detach(dvb->frontend); 279 dvb_frontend_detach(dvb->frontend);
232 dvb_unregister_adapter(&dvb->adapter); 280 dvb_unregister_adapter(&dvb->adapter);
233fail_adapter: 281
234 return result; 282 return result;
235} 283}
236 284
237void videobuf_dvb_unregister(struct videobuf_dvb *dvb) 285void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
238{ 286{
239 dvb_net_release(&dvb->net); 287 struct list_head *list, *q;
240 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 288 struct videobuf_dvb_frontend *fe;
241 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 289
242 dvb_dmxdev_release(&dvb->dmxdev); 290 mutex_lock(&f->lock);
243 dvb_dmx_release(&dvb->demux); 291 list_for_each_safe(list, q, &f->frontend.felist) {
244 dvb_unregister_frontend(dvb->frontend); 292 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
245 dvb_frontend_detach(dvb->frontend); 293
246 dvb_unregister_adapter(&dvb->adapter); 294 dvb_net_release(&fe->dvb.net);
295 fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, &fe->dvb.fe_mem);
296 fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, &fe->dvb.fe_hw);
297 dvb_dmxdev_release(&fe->dvb.dmxdev);
298 dvb_dmx_release(&fe->dvb.demux);
299 dvb_unregister_frontend(fe->dvb.frontend);
300 dvb_frontend_detach(fe->dvb.frontend);
301
302 list_del(list);
303 kfree(fe);
304 }
305 mutex_unlock(&f->lock);
306
307 dvb_unregister_adapter(&f->adapter);
308}
309
310struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id)
311{
312 struct list_head *list, *q;
313 struct videobuf_dvb_frontend *fe, *ret = NULL;
314
315 mutex_lock(&f->lock);
316
317 list_for_each_safe(list, q, &f->frontend.felist) {
318 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
319 if (fe->id == id) {
320 ret = fe;
321 break;
322 }
323 }
324
325 mutex_unlock(&f->lock);
326
327 return ret;
328}
329
330int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p)
331{
332 struct list_head *list, *q;
333 struct videobuf_dvb_frontend *fe = NULL;
334 int ret = 0;
335
336 mutex_lock(&f->lock);
337
338 list_for_each_safe(list, q, &f->frontend.felist) {
339 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
340 if (fe->dvb.frontend == p) {
341 ret = fe->id;
342 break;
343 }
344 }
345
346 mutex_unlock(&f->lock);
347
348 return ret;
349}
350
351struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(void *private, struct videobuf_dvb_frontends *f, int id)
352{
353 struct videobuf_dvb_frontend *fe;
354
355 fe = kzalloc(sizeof(struct videobuf_dvb_frontend),GFP_KERNEL);
356 if (fe == NULL)
357 goto fail_alloc;
358
359 fe->dev = private;
360 fe->id = id;
361 mutex_init(&fe->dvb.lock);
362
363 mutex_lock(&f->lock);
364 list_add_tail(&fe->felist,&f->frontend.felist);
365 mutex_unlock(&f->lock);
366
367fail_alloc:
368 return fe;
247} 369}
248 370
249EXPORT_SYMBOL(videobuf_dvb_register); 371EXPORT_SYMBOL(videobuf_dvb_register_bus);
250EXPORT_SYMBOL(videobuf_dvb_unregister); 372EXPORT_SYMBOL(videobuf_dvb_unregister_bus);
373EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);
374EXPORT_SYMBOL(videobuf_dvb_get_frontend);
375EXPORT_SYMBOL(videobuf_dvb_find_frontend);
251 376
252/* ------------------------------------------------------------------ */ 377/* ------------------------------------------------------------------ */
253/* 378/*