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"
/*
#define DVB_MAJOR 250
#define DVB_DEVICE_VIDEO 0
#define DVB_DEVICE_AUDIO 1
#define DVB_DEVICE_SEC 2
#define DVB_DEVICE_FRONTEND 3
#define DVB_DEVICE_DEMUX 4
#define DVB_DEVICE_DVR 5
#define DVB_DEVICE_CA 6
#define DVB_DEVICE_NET 7
#define DVB_DEVICE_OSD 8
struct dvb_adapter {
int num;
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
devfs_handle_t devfs_handle;
#endif
struct list_head list_head;
struct list_head device_list;
const char *name;
u8 proposed_mac [6];
};
struct dvb_device {
struct list_head list_head;
struct file_operations *fops;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
devfs_handle_t devfs_handle;
#endif
struct dvb_adapter *adapter;
int type;
u32 id;
// in theory, 'users' can vanish now,
// but I don't want to change too much now...
int readers;
int writers;
int users;
// don't really need those !? -- FIXME: use video_usercopy
int (*kernel_ioctl)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg);
void *priv;
};
struct dvb_frontend {
struct dvb_frontend_ops ops;
struct dvb_adapter *dvb;
void* demodulator_priv;
void* tuner_priv;
void* frontend_priv;
void* misc_priv;
};
dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev);
*/
#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_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 struct dvb_demux demux;
static struct dmxdev dmxdevice;
static struct dmx_frontend fe_hw;
static struct dmx_frontend fe_mem;
static struct dvb_i2c_bus *i2c_bus;
static struct dvb_frontend *frontend;
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 = kmalloc(sizeof(struct dummy), GFP_KERNEL);
//frontend = dvb_dummy_fe_qpsk_attach();
if ((result = dvb_register_adapter(&adap,"Dummy adaptor",&frontend->frontend_priv, DVB_DEVICE_FRONTEND)) < 0) {
printk("dummyadap: dvb_register_adapter failed (errno = %d)\n", result);
return result;
}
//dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev);
if ((result = dvb_register_adapter(&adap->dvb_adapter,"Dummy adaptor",THIS_MODULE,&adap->pdev)) < 0) {
printk("dummyadap: dvb_register_adapter failed (errno = %d)\n", result);
return result;
}
memset(&adap->demux, 0x0, sizeof(adap->demux));
//demux.dmx.vendor = "Dummy Vendor";
//demux.dmx.model = "Dummy Model";
//demux.dmx.id = "demux0_0";
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_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
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_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
return result;
}
adap->fe = dvb_dummy_fe_qpsk_attach();
//fe_hw.id = "hw_frontend";
//fe_hw.vendor = "Dummy Vendor";
//fe_hw.model = "hw";
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_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
return result;
}
//fe_mem.id = "mem_frontend";
//fe_mem.vendor = "memory";
//fe_mem.model = "sw";
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->mem_frontend);
dvb_dmxdev_release(&adap->dmxdev);
dvb_dmx_release(&adap->demux);
//dvb_unregister_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
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_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
return result;
}
/* if ((result = dvb_add_frontend_notifier(&adap->dvb_adapter, dummyadap_before_after_tune, NULL)) < 0) {
printk("dummyadap: dvb_add_frontend_notifier failed (errno = %d)\n", result);
adap->demux.dmx.close(&adap->demux.dmx);
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_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
return result;
}
if ((result = dvb_add_frontend_ioctls(&adap->dvb_adapter, dummyadap_before_ioctl, dummyadap_after_ioctl, NULL)) < 0) {
printk("dummyadap: dvb_add_frontend_ioctls failed (errno = %d)\n", result);
dvb_remove_frontend_notifier(&adap->dvb_adapter, dummyadap_before_after_tune);
adap->demux.dmx.close(&adap->demux.dmx);
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_i2c_bus(dummyadap_i2c_master_xfer, adap, 0);
dvb_unregister_adapter(&adap->dvb_adapter);
return result;
}
*/
return 0;
}
static void __exit dummyadap_exit(void)
{
}
#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