rendered paste body/*
* $Id: dummyadap.c,v 1.5 2003/07/01 03:51:07 obi Exp $
*
* Dummy Adapter Driver
*
* Homepage: http://www.tuxbox.org
*
* Copyright (C) 2002 Florian Schirmer <jolt@tuxbox.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <asm/bitops.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include "drivers/media/dvb/dvb-core/dmxdev.h"
#include "drivers/media/dvb/dvb-core/dvbdev.h"
#include "drivers/media/dvb/dvb-core/dvb_demux.h"
#include "drivers/media/dvb/dvb-core/dvb_frontend.h"
#include "dvb_dummy_fe.h"
static int dvb_video_open(struct inode *inode, struct file *file)
{
printk("Video open!\n");
return 0;
}
static int dvb_video_release(struct inode *inode, struct file *file)
{
return 0;
}
static void dvb_video_poll()
{
}
static void dvb_video_write()
{
}
static void dvb_audio_write()
{
}
static int dvb_audio_open(struct inode *inode, struct file *file)
{
return 0;
}
static int dvb_audio_release(struct inode *inode, struct file *file)
{
return 0;
}
static void dvb_audio_poll()
{
}
static struct file_operations dvb_video_fops = {
.owner = THIS_MODULE,
.write = dvb_video_write,
//.ioctl = dvb_generic_ioctl,
.open = dvb_video_open,
.release = dvb_video_release,
.poll = dvb_video_poll,
};
static struct dvb_device dvbdev_video = {
.priv = NULL,
.users = 6,
.readers = 5, /* arbitrary */
.writers = 1,
.fops = &dvb_video_fops,
//.kernel_ioctl = dvb_video_ioctl,
};
static struct file_operations dvb_audio_fops = {
.owner = THIS_MODULE,
.write = dvb_audio_write,
//.ioctl = dvb_generic_ioctl,
.open = dvb_audio_open,
.release = dvb_audio_release,
.poll = dvb_audio_poll,
};
static struct dvb_device dvbdev_audio = {
.priv = NULL,
.users = 1,
.writers = 1,
.fops = &dvb_audio_fops,
//.kernel_ioctl = dvb_audio_ioctl,
};
#define TS_DMA_PACKETS (8)
#define TS_DMA_BYTES (188 * TS_DMA_PACKETS)
struct dummy2 {
/* pci */
struct pci_dev *pdev;
u8 __iomem *io_mem;
/* dvb */
struct dmx_frontend hw_frontend;
struct dmx_frontend mem_frontend;
struct dmxdev dmxdev;
struct dvb_adapter dvb_adapter;
struct dvb_demux demux;
struct dvb_frontend *fe;
struct dvb_device *video;
struct dvb_device *audio;
//struct dvb_net dvbnet;
unsigned int full_ts_users;
unsigned int users;
/* i2c */
//struct i2c_algo_bit_data i2c_bit;
struct i2c_adapter i2c_adap;
unsigned int i2cbug;
/* irq */
unsigned int overflow;
/* dma */
dma_addr_t dma_addr;
u8 dma_buf[TS_DMA_BYTES];
u8 dummy[4096];
};
static struct dummy2 *adap;
static void dummyadap_before_after_tune(fe_status_t fe_status, void *data)
{
// printk("dummyadap: before_after_tune\n");
}
static int dummyadap_after_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
// printk("dummyadap: after_ioctl\n");
return 0;
}
static int dummyadap_before_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
// printk("dummyadap: before_ioctl\n");
// Returning 0 will skip the fe ioctl
return -ENODEV;
}
static int dummyadap_write_to_decoder(struct dvb_demux_feed *dvbdmxfeed, u8 *buf, size_t count)
{
printk("dummyadap: write_to_decoder\n");
return 0;
}
static int dummyadap_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
printk("dummyadap: start_feed\n");
if (!dvbdmx->dmx.frontend)
return -EINVAL;
printk(" pid: 0x%04X\n", dvbdmxfeed->pid);
switch(dvbdmxfeed->type) {
case DMX_TYPE_TS:
printk(" type: DMX_TYPE_TS\n");
break;
case DMX_TYPE_SEC:
printk(" type: DMX_TYPE_SEC\n");
break;
default:
printk(" type: unknown (%d)\n", dvbdmxfeed->type);
return -EINVAL;
}
printk(" ts_type:");
if (dvbdmxfeed->ts_type & TS_DECODER)
printk(" TS_DECODER");
if (dvbdmxfeed->ts_type & TS_PACKET)
printk(" TS_PACKET");
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
printk(" TS_PAYLOAD_ONLY");
printk("\n");
switch(dvbdmxfeed->pes_type) {
case DMX_TS_PES_VIDEO:
printk(" pes_type: DMX_TS_PES_VIDEO\n");
break;
case DMX_TS_PES_AUDIO:
printk(" pes_type: DMX_TS_PES_AUDIO\n");
break;
case DMX_TS_PES_TELETEXT:
printk(" pes_type: DMX_TS_PES_TELETEXT\n");
break;
case DMX_TS_PES_PCR:
printk(" pes_type: DMX_TS_PES_PCR\n");
break;
case DMX_TS_PES_OTHER:
printk(" pes_type: DMX_TS_PES_OTHER\n");
break;
default:
printk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
return -EINVAL;
}
return 0;
}
static int dummyadap_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
printk("dummyadap: stop_feed\n");
return 0;
}
static int __init dummyadap_init(void)
{
int result;
adap = kzalloc(sizeof(struct dummy2), GFP_KERNEL);
adap->video = kzalloc(sizeof(adap->video), GFP_KERNEL);
adap->audio = kzalloc(sizeof(adap->audio), GFP_KERNEL);
//frontend = dvb_dummy_fe_qpsk_attach();
if ((result = dvb_register_adapter(&adap->dvb_adapter,"Dummy adaptor",THIS_MODULE, NULL)) < 0) {
printk("dummyadap: dvb_register_adapter failed (errno = %d)\n", result);
return result;
}
adap->fe = dvb_dummy_fe_qpsk_attach();
if ((result = dvb_register_frontend(&adap->dvb_adapter, adap->fe)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
dvb_unregister_adapter(&adap->dvb_adapter);
return result;
}
if ((result = dvb_register_device(&adap->dvb_adapter,&adap->video, &dvbdev_video,adap,DVB_DEVICE_VIDEO)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
return result;
}
if ((result = dvb_register_device(&adap->dvb_adapter, &adap->audio, &dvbdev_audio,adap,DVB_DEVICE_AUDIO)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
dvb_unregister_device(adap->video);
return result;
}
adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
adap->demux.priv = NULL;
adap->demux.filternum = 31;
adap->demux.feednum = 31;
adap->demux.start_feed = dummyadap_start_feed;
adap->demux.stop_feed = dummyadap_stop_feed;
adap->demux.write_to_decoder = dummyadap_write_to_decoder;
if ((result = dvb_dmx_init(&adap->demux)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
dvb_unregister_device(adap->video);
dvb_unregister_device(adap->audio);
return result;
}
adap->dmxdev.filternum = 32;
adap->dmxdev.demux = &adap->demux.dmx;
adap->dmxdev.capabilities = 0;
if ((result = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adapter)) < 0) {
printk("dummyadap: dvb_dmxdev_init failed (errno = %d)\n", result);
dvb_dmx_release(&adap->demux);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
dvb_unregister_device(adap->video);
dvb_unregister_device(adap->audio);
return result;
}
adap->hw_frontend.source = DMX_FRONTEND_0;
if ((result = adap->demux.dmx.add_frontend(&adap->demux.dmx, &adap->hw_frontend)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
dvb_dmxdev_release(&adap->dmxdev);
dvb_dmx_release(&adap->demux);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
dvb_unregister_device(adap->video);
dvb_unregister_device(adap->audio);
return result;
}
adap->mem_frontend.source = DMX_MEMORY_FE;
if ((result = adap->demux.dmx.add_frontend(&adap->demux.dmx, &adap->mem_frontend)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
adap->demux.dmx.remove_frontend(&adap->demux.dmx, &adap->hw_frontend);
dvb_dmxdev_release(&adap->dmxdev);
dvb_dmx_release(&adap->demux);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
dvb_unregister_device(adap->video);
dvb_unregister_device(adap->audio);
return result;
}
if ((result = adap->demux.dmx.connect_frontend(&adap->demux.dmx, &adap->hw_frontend)) < 0) {
printk("dummyadap: dvb_dmx_init failed (errno = %d)\n", result);
adap->demux.dmx.remove_frontend(&adap->demux.dmx, &adap->mem_frontend);
adap->demux.dmx.remove_frontend(&adap->demux.dmx, &adap->hw_frontend);
dvb_dmxdev_release(&adap->dmxdev);
dvb_dmx_release(&adap->demux);
dvb_unregister_adapter(&adap->dvb_adapter);
dvb_unregister_frontend(adap->fe);
dvb_unregister_device(adap->video);
dvb_unregister_device(adap->audio);
return result;
}
return 0;
}
static void __exit dummyadap_exit(void)
{
adap->demux.dmx.remove_frontend(&adap->demux.dmx, &adap->mem_frontend);
adap->demux.dmx.remove_frontend(&adap->demux.dmx, &adap->hw_frontend);
dvb_dmxdev_release(&adap->dmxdev);
dvb_dmx_release(&adap->demux);
dvb_unregister_device(adap->video);
dvb_unregister_device(adap->audio);
dvb_unregister_frontend(adap->fe);
dvb_unregister_adapter(&adap->dvb_adapter);
kfree(adap);
}
#ifdef MODULE
module_init(dummyadap_init);
module_exit(dummyadap_exit);
MODULE_DESCRIPTION("dummy dvb adapter driver");
MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif
#endif