/* * $Id: cx88-ivtv.c,v 1.1 2005/11/30 17:26:37 mchehab Exp $ * * IVTV API emulation for the "blackbird" reference design. * * (c) 2005 Catalin Climov * * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), * * 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 #include #include #include "compat.h" #include #include "cx88.h" MODULE_DESCRIPTION("ivtv ioctl emulation module for blackbird TV cards"); MODULE_AUTHOR("Catalin Climov "); MODULE_LICENSE("GPL"); static unsigned int debug = 0; module_param(debug,int,0644); MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); #define dprintk(level,fmt, arg...) if (debug >= level) \ printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg) static int (*prev_ioctl_hook)(struct inode *inode, struct file *file, unsigned int cmd, void *arg); static unsigned int (*prev_ioctl_translator)(unsigned int cmd); /* --- IVTV data structs -------------------------------------------- */ struct ivtv_ioctl_codec { uint32_t aspect; uint32_t audio_bitmask; uint32_t bframes; uint32_t bitrate_mode; uint32_t bitrate; uint32_t bitrate_peak; uint32_t dnr_mode; uint32_t dnr_spatial; uint32_t dnr_temporal; uint32_t dnr_type; uint32_t framerate; /* read only, ignored on write */ uint32_t framespergop; /* read only, ignored on write */ uint32_t gop_closure; uint32_t pulldown; uint32_t stream_type; }; struct ivtv_sliced_vbi_format { unsigned long service_set; /* one or more of the IVTV_SLICED_ defines */ unsigned long packet_size; /* the size in bytes of the ivtv_sliced_data packet */ unsigned long io_size; /* maximum number of bytes passed by one read() call */ unsigned long reserved; }; #define IVTV_IOC_G_CODEC _IOR ('@', 48, struct ivtv_ioctl_codec) #define IVTV_IOC_S_CODEC _IOW ('@', 49, struct ivtv_ioctl_codec) #define IVTV_IOC_S_VBI_MODE _IOWR('@', 35, struct ivtv_sliced_vbi_format) #define IVTV_IOC_G_VBI_MODE _IOR ('@', 36, struct ivtv_sliced_vbi_format) #define IVTV_IOC_S_VBI_EMBED _IOW ('@', 54, int) /* ------------------------------------------------------------------ */ static unsigned int ivtv_translate_ioctl(unsigned int cmd) { #if 0 printk( KERN_INFO "ivtv_translate_ioctl\n" ); #endif switch( cmd ) { case 0xFFEE7703: cmd = IVTV_IOC_G_CODEC; break; case 0xFFEE7704: cmd = IVTV_IOC_S_CODEC; break; case 0xFFEE7781: /*cmd = IVTV_IOC_PLAY; break;*/ case 0xFFEE7782: /*cmd = IVTV_IOC_PAUSE; break;*/ case 0xFFEE7783: /*cmd = IVTV_IOC_FRAMESYNC; break;*/ case 0xFFEE7784: /*cmd = IVTV_IOC_GET_TIMING; break;*/ case 0xFFEE7785: /*cmd = IVTV_IOC_S_SLOW_FAST; break;*/ case 0xFFEE7786: /*cmd = IVTV_IOC_S_START_DECODE; break;*/ case 0xFFEE7787: /*cmd = IVTV_IOC_S_STOP_DECODE; break;*/ case 0xFFEE7789: /*cmd = IVTV_IOC_GET_FB; break;*/ printk( KERN_INFO "IVTV: 0x%x\n", cmd ); } return prev_ioctl_translator( cmd ); } static int ivtv_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct cx8802_fh *fh = file->private_data; struct cx8802_dev *dev = fh->dev; /* struct cx88_core *core = dev->core; */ /* int err; */ if (debug > 1) v4l_print_ioctl(dev->core->name,cmd); #if 1 printk( KERN_INFO "IVTV IOCTL: 0x%x\n", cmd ); v4l_print_ioctl(dev->core->name,cmd); #endif dprintk( 1, "IVTV IOCTL: 0x%x\n", cmd ); switch (cmd) { /* --- IVTV emulation layer --------------------------- */ case IVTV_IOC_S_CODEC: printk( KERN_INFO "IVTV_IOC_S_CODEC\n" ); case IVTV_IOC_G_CODEC: { struct ivtv_ioctl_codec *codec = arg; #if 1 printk( KERN_INFO "IVTV_IOC_G/S_CODEC\n" ); printk( KERN_INFO "CODEC: aspect: %d\n", codec->aspect ); printk( KERN_INFO "CODEC: audio : %d\n", codec->audio_bitmask ); printk( KERN_INFO "CODEC: bfrms : %d\n", codec->bframes ); printk( KERN_INFO "CODEC: br_mod: %d\n", codec->bitrate_mode ); printk( KERN_INFO "CODEC: btrate: %d\n", codec->bitrate ); printk( KERN_INFO "CODEC: btr_pk: %d\n", codec->bitrate_peak ); printk( KERN_INFO "CODEC: dnr_md: %d\n", codec->dnr_mode ); printk( KERN_INFO "CODEC: dnr_sp: %d\n", codec->dnr_spatial ); printk( KERN_INFO "CODEC: dnr_tp: %d\n", codec->dnr_temporal ); printk( KERN_INFO "CODEC: dnr_ty: %d\n", codec->dnr_type ); printk( KERN_INFO "CODEC: framer: %d\n", codec->framerate ); printk( KERN_INFO "CODEC: grmgop: %d\n", codec->framespergop ); printk( KERN_INFO "CODEC: gop_cl: %d\n", codec->gop_closure ); printk( KERN_INFO "CODEC: pulldn: %d\n", codec->pulldown ); printk( KERN_INFO "CODEC: strtyp: %d\n\n", codec->stream_type ); #endif codec->aspect = 2; /* 4:3 */ codec->audio_bitmask = (2 << 2) | (14 << 4); /* layer II | 384kbps */ codec->bframes = 2; codec->bitrate_mode = 1; /* cbr */ codec->bitrate = 4500000; /* bps */ codec->bitrate_peak = 6000000; /* peak */ codec->dnr_mode = 0; /* spatial=manual | temporal=manual */ codec->dnr_spatial = 0; codec->dnr_temporal = 0; codec->dnr_type = 0; /* disabled */ codec->framerate = 1; /* 25fps */ codec->framespergop = 15; codec->gop_closure = 0; /* open */ codec->pulldown = 0; /* enabled */ codec->stream_type = 0; /* program stream */ #if 1 printk( KERN_INFO "CODEC: aspect: %d\n", codec->aspect ); printk( KERN_INFO "CODEC: audio : %d\n", codec->audio_bitmask ); printk( KERN_INFO "CODEC: bfrms : %d\n", codec->bframes ); printk( KERN_INFO "CODEC: br_mod: %d\n", codec->bitrate_mode ); printk( KERN_INFO "CODEC: btrate: %d\n", codec->bitrate ); printk( KERN_INFO "CODEC: btr_pk: %d\n", codec->bitrate_peak ); printk( KERN_INFO "CODEC: dnr_md: %d\n", codec->dnr_mode ); printk( KERN_INFO "CODEC: dnr_sp: %d\n", codec->dnr_spatial ); printk( KERN_INFO "CODEC: dnr_tp: %d\n", codec->dnr_temporal ); printk( KERN_INFO "CODEC: dnr_ty: %d\n", codec->dnr_type ); printk( KERN_INFO "CODEC: framer: %d\n", codec->framerate ); printk( KERN_INFO "CODEC: grmgop: %d\n", codec->framespergop ); printk( KERN_INFO "CODEC: gop_cl: %d\n", codec->gop_closure ); printk( KERN_INFO "CODEC: pulldn: %d\n", codec->pulldown ); printk( KERN_INFO "CODEC: strtyp: %d\n", codec->stream_type ); #endif return 0; } case IVTV_IOC_S_VBI_MODE: { struct ivtv_sliced_vbi_format *fmt = arg; printk( KERN_INFO "IVTV_IOC_S_VBI_MODE: ss: %ld, ps: %ld, is: %ld\n", fmt->service_set, fmt->packet_size, fmt->io_size ); #if 0 fmt->service_set = 0; /* one or more of the IVTV_SLICED_ defines */ fmt->packet_size = 0; /* the size in bytes of the ivtv_sliced_data packet */ fmt->io_size = 0; /* maximum number of bytes passed by one read() call */ #endif return 0; } case IVTV_IOC_G_VBI_MODE: { struct ivtv_sliced_vbi_format *fmt = arg; fmt->service_set = 1; /* one or more of the IVTV_SLICED_ defines */ fmt->packet_size = 0; /* the size in bytes of the ivtv_sliced_data packet */ fmt->io_size = 0; /* maximum number of bytes passed by one read() call */ return 0; } case IVTV_IOC_S_VBI_EMBED: { int *embed = arg; printk( KERN_INFO "IVTV_IOC_S_VBI_EMBED: %d\n", *embed ); return 0; } default: if( prev_ioctl_hook ) return prev_ioctl_hook( inode, file, cmd, arg ); else return -EINVAL; } return 0; } static int __init cx88_ivtv_init(void) { printk(KERN_INFO "ivtv emulation for blackbird version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif request_module( "cx88-blackbird" ); prev_ioctl_translator = cx88_ioctl_translator; cx88_ioctl_translator = ivtv_translate_ioctl; prev_ioctl_hook = cx88_ioctl_hook; cx88_ioctl_hook = ivtv_do_ioctl; return 0; } static void __exit cx88_ivtv_fini(void) { cx88_ioctl_hook = prev_ioctl_hook; cx88_ioctl_translator = prev_ioctl_translator; } module_init(cx88_ivtv_init); module_exit(cx88_ivtv_fini); /* * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */