⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videodev.c

📁 it s a source code for how to integrate your tvp5150 decoder with driver and how to capture an image
💻 C
字号:
/* * Video capture interface for Linux Character Device Driver. *              based on   *              Alan Cox, <alan@redhat.com> video4linux  * * Author:      SW.LEE <hitchcar@samsung.com>         *              2004 (C) Samsung Electronics  *              Modified for S3C2440/S3C24A0 Interface * * This file is released under the GPLv2 */#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/smp_lock.h>#include <linux/mm.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/kmod.h>#include <linux/slab.h>#include <linux/devfs_fs_kernel.h>#include <linux/miscdevice.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/semaphore.h>#include "camif.h"#include "videodev.h"#include "miscdevice.h"static DECLARE_MUTEX(videodev_lock);const char *fimc_version = "$Id: videodev.c,v 1.1.1.1 2004/04/27 03:52:50 swlee Exp $";#define VIDEO_NAME              "video4linux"/* 2.6 俊辑 哪颇老且锭 俊矾啊 惯积秦辑 积帆窃 */#if 0 //坷府瘤朝 static inline unsigned iminor(struct inode *inode){    return MINOR(inode->i_rdev);}static inline unsigned imajor(struct inode *inode){    return MAJOR(inode->i_rdev);}#endif#define VIDEO_NUM_DEVICES   2 static struct video_device *video_device[VIDEO_NUM_DEVICES];static inline struct video_device * get_vd(int nr){    if ( nr == CODEC_MINOR)        return video_device[0];    else {        assert ( nr & PREVIEW_MINOR);        return video_device[1];    }}static inline void set_vd ( struct video_device * vd, int nr){    if ( nr == CODEC_MINOR)        video_device[0] = vd;    else {        assert ( nr & PREVIEW_MINOR);        video_device[1] = vd;    }}static inline int video_release(struct inode *inode, struct file *f){    int minor = MINOR(inode->i_rdev);    struct video_device *vfd;    vfd = get_vd(minor);#if 1 /* needed until all drivers are fixed */    if (!vfd->release)        return 0;#endif    vfd->release(vfd);    return 0;}struct video_device* video_devdata(struct file *file){    return video_device[iminor(file->f_dentry->d_inode)];}/* *  Open a video device. */static int video_open(struct inode *inode, struct file *file){    int minor = MINOR(inode->i_rdev);    int err = 0;    struct video_device *vfl;    struct file_operations *old_fops;        down(&videodev_lock);    vfl = get_vd(minor);    old_fops = file->f_op;    file->f_op = fops_get(vfl->fops);    if(file->f_op->open)        err = file->f_op->open(inode,file);    if (err) {        fops_put(file->f_op);        file->f_op = fops_get(old_fops);    }    fops_put(old_fops);    up(&videodev_lock);    return err;}/* * open/release helper functions -- handle exclusive opens */extern int video_exclusive_open(struct inode *inode, struct file *file){    struct  video_device *vfl = get_vd(MINOR(inode->i_rdev));    int retval = 0;    down(&vfl->lock);    if (vfl->users) {        retval = -EBUSY;    } else {        vfl->users++;    }    up(&vfl->lock);    return retval;}extern int video_exclusive_release(struct inode *inode, struct file *file){    struct  video_device *vfl = get_vd(MINOR(inode->i_rdev));    vfl->users--;    return 0;}intvideo_usercopy(struct inode *inode, struct file *file,           unsigned int cmd, unsigned long arg,           int (*func)(struct inode *inode, struct file *file,               unsigned int cmd, void *arg)){    char    sbuf[128];    void    *mbuf = NULL;    void    *parg = NULL;    int err  = -EINVAL;    //  cmd = video_fix_command(cmd);    /*  Copy arguments into temp kernel buffer  */    switch (_IOC_DIR(cmd)) {    case _IOC_NONE:        parg = (void *)arg;        break;    case _IOC_READ:    case _IOC_WRITE:    case (_IOC_WRITE | _IOC_READ):        if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {            parg = sbuf;        } else {            /* too big to allocate from stack */            mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);            if (NULL == mbuf)                return -ENOMEM;            parg = mbuf;        }                err = -EFAULT;        if (_IOC_DIR(cmd) & _IOC_WRITE)            if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))                goto out;        break;    }    /* call driver */    err = func(inode, file, cmd, parg);    if (err == -ENOIOCTLCMD)        err = -EINVAL;    if (err < 0)        goto out;    /*  Copy results into user buffer  */    switch (_IOC_DIR(cmd))    {    case _IOC_READ:    case (_IOC_WRITE | _IOC_READ):        if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))            err = -EFAULT;        break;    }out:    if (mbuf)        kfree(mbuf);    return err;}static struct file_operations video_fops={    .owner      = THIS_MODULE,    .llseek     = no_llseek,    .open       = video_open,    .release    = video_release,};static struct miscdevice codec_dev = {    minor: CODEC_MINOR,    name : "codec",    fops : &video_fops};static struct miscdevice preview_dev = {    minor: PREVIEW_MINOR,    name : "preview",    fops : &video_fops};/** *  video_register_device - register video4linux devices *  @vfd:  video device structure we want to register *  @type: type of device to register *  @nr:   minor number  *   *  Zero is returned on success. *      type : ignored. *      nr :  *           0 Codec index *           1 Preview index */int video_register_device(struct video_device *vfd, int type, int nr){    int ret=0;    /* pick a minor number */    down(&videodev_lock);    set_vd (vfd, nr);    vfd->minor=nr;    up(&videodev_lock);    switch (vfd->minor) {        case CODEC_MINOR:            ret = misc_register(&codec_dev);            if (ret) {                printk(KERN_ERR                         "can't misc_register : codec on minor=%d\n", CODEC_MINOR);                panic(" Give me misc codec \n");            }            break;        case PREVIEW_MINOR:            ret = misc_register(&preview_dev);            if (ret) {                printk(KERN_ERR                         "can't misc_register (preview) on minor=%d\n", PREVIEW_MINOR);                panic(" Give me misc preview \n");            }            break;    }#if 0 /* needed until all drivers are fixed */    if (!vfd->release)        printk(KERN_WARNING "videodev: \"%s\" has no release callback. "                "Please fix your driver for proper sysfs support, see "                "http://lwn.net/Articles/36850/\n", vfd->name);#endif    return 0;}/** *  video_unregister_device - unregister a video4linux device *  @vfd: the device to unregister * *  This unregisters the passed device and deassigns the minor *  number. Future open calls will be met with errors. */ void video_unregister_device(struct video_device *vfd){    down(&videodev_lock);    if(get_vd(vfd->minor)!=vfd)        panic("videodev: bad unregister");    if (vfd->minor== CODEC_MINOR)        misc_deregister(&codec_dev);    else        misc_deregister(&preview_dev);    set_vd (NULL, vfd->minor);    up(&videodev_lock);}/* *  Initialise video for linux */ static int __init videodev_init(void){//  printk(KERN_INFO "FIMC2.0 Built:"__DATE__" "__TIME__"\n%s\n",fimc_version);    return 0;}static void __exit videodev_exit(void){}module_init(videodev_init)module_exit(videodev_exit)EXPORT_SYMBOL(video_register_device);EXPORT_SYMBOL(fimc_version);EXPORT_SYMBOL(video_unregister_device);EXPORT_SYMBOL(video_usercopy);EXPORT_SYMBOL(video_exclusive_open);EXPORT_SYMBOL(video_exclusive_release);MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");MODULE_DESCRIPTION("VideoDev For FIMC2.0 MISC Drivers");MODULE_LICENSE("GPL");/* * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -