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

📄 i810tv.c

📁 LINUX 下的intel 810 TO TV的源代码,结合芯片CHRONTEL使用
💻 C
字号:
/*	Hardware driver for Intel i810 LCD/TV 	Copyright 2002 Lars Gustavsson <lars@textalk.se>	----------------------------------------------------------	This software may be used and distributed according to the terms        of the GNU General Public License, incorporated herein by reference. */#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/spinlock.h>#include <linux/random.h>#include <linux/miscdevice.h>#include <linux/smp_lock.h>#include <linux/mm.h>#include <asm/io.h>#include <asm/uaccess.h>#include "i810tv.h"/* * core module and version information */#define TV_VERSION "0.1.0"#define TV_MODULE_NAME "i810_tv"#define TV_DRIVER_NAME   TV_MODULE_NAME " hardware driver " TV_VERSION#define IO_CTRL 0x5000#define IO_CTRL_LEN 0x1000#define CLKPWR_CTRL 0x6000#define CLKPWR_LEN  0x1000#define TV_ADDR 0x60000#define TV_LEN  0x1000#define TV_MINOR 42static __u8 *tv_mem, *io_mem, *clk_mem;static struct semaphore tv_open_sem;static char * print_bin( int b ) {	static char bin[33];        int i;        for (i=0;i<32;i++) {	    bin[i] = b&0x80000000?'1':'0';	    b <<= 1;	}	bin[32]='\0';	return bin;}			static inline void outlong( __u8 *base, int adr, unsigned int val ) {      *((unsigned int *) ( base + adr )) = val;//        writel(tv_mem+adr,val);      printk("i810 set 0x%08x=%s\n", adr, print_bin(val) );}static inline unsigned int readlong( __u8 *base,  int adr ) {      return *((unsigned int *)(base+adr));//        return readl(tv_mem+adr);}static int tv_dev_open (struct inode *inode, struct file *filp){	return 0;}static int tv_dev_release (struct inode *inode, struct file *filp){	return 0;}static int tv_ioctl(struct inode *inode, struct file *file,		    unsigned int cmd, unsigned long arg);static struct file_operations tv_chrdev_ops = {	owner:		THIS_MODULE,	open:		tv_dev_open,	release:	tv_dev_release,	ioctl:		tv_ioctl,};static struct miscdevice tv_miscdev = {	TV_MINOR,	TV_MODULE_NAME,	&tv_chrdev_ops,};static int __init tv_init_one (struct pci_dev *dev){	unsigned long cadr;	int rc, i;	u8 hw_status;	rc = misc_register (&tv_miscdev);	if (rc) {		printk ("cannot register misc device\n");		goto err_out;	}	cadr = dev->resource[1].start;	printk("0x%08x\n", cadr );	tv_mem = ioremap (cadr + TV_ADDR, TV_LEN);	if (tv_mem == NULL) {		printk ("cannot ioremap TV Memory\n");		rc = -EBUSY;		goto err_out_free_miscdev;	}	io_mem =  ioremap_nocache(cadr + IO_CTRL, IO_CTRL_LEN );        if (io_mem == NULL) {		iounmap(tv_mem);		printk ("cannot ioremap io ctrl memory\n");		rc = -EBUSY;		goto err_out_free_miscdev;	}	clk_mem =  ioremap_nocache(cadr + CLKPWR_CTRL, CLKPWR_LEN );	if (clk_mem == NULL) {		iounmap(tv_mem);		iounmap(io_mem);	        printk ("cannot ioremap io ctrl memory\n");	        rc = -EBUSY;	        goto err_out_free_miscdev;        }	for(i=0;i<0x20;i+=4)	  printk("0x600%02x: 0x%08x\n", i, readlong(tv_mem,i));	printk("---- clock ----\n");	for(i=0;i<=0x14;i+=4)	  printk("0x60%02x: 0x%08x\n", i, readlong(clk_mem,i));	printk("0x%08x\n", readlong(clk_mem,0x14));	return 0;err_out_free_map:	iounmap (tv_mem);err_out_free_miscdev:	misc_deregister (&tv_miscdev);err_out:	return rc;}/* * Data for PCI driver interface * * This data only exists for exporting the supported * PCI ids via MODULE_DEVICE_TABLE.  We do not actually * register a pci_driver, because someone else might one day * want to register another driver on the same PCI id. */static struct pci_device_id tv_pci_tbl[] __initdata = {	{ 0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, },	{ 0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, },	{ 0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, },	{ 0, },};MODULE_DEVICE_TABLE (pci, tv_pci_tbl);MODULE_AUTHOR("Lars Gustavsson");MODULE_DESCRIPTION("Intel i810 LCD/TV driver");MODULE_LICENSE("GPL");static int __init tv_init (void){	int rc;	struct pci_dev *pdev;	init_MUTEX (&tv_open_sem);	pci_for_each_dev(pdev) {		if (pci_match_device (tv_pci_tbl, pdev) != NULL)			goto match;	}	return -ENODEV;match:	rc = tv_init_one (pdev);	if (rc)		return rc;	printk ("i810 LCD/TV driver loaded\n");	return 0;}static void __exit tv_cleanup (void){	misc_deregister (&tv_miscdev);	iounmap (tv_mem);}static int tv_ioctl(struct inode *inode, struct file *file,		    unsigned int cmd, unsigned long arg){	unsigned int minor = MINOR(inode->i_rdev);	int retval = 0;	unsigned int memdata, tmpval;	switch ( cmd ) {		case TV_SET_BORDER:			memdata=readlong(tv_mem,0x18);			if (arg)				memdata |= 0x80;			else				memdata &= 0xffffff7f;			outlong(tv_mem,0x18,memdata);			break;		case TV_GET_BORDER:			memdata=readlong(tv_mem,0x18) & 0x80;			if (copy_to_user((int *) arg, &memdata, sizeof(int)))			        return -EFAULT;			break;		case TV_SET_CENTER:		        memdata=readlong(tv_mem,0x18);		        if (arg)		              memdata |=  0x20000000;		        else		              memdata &= 0xdfffffff;		        outlong(tv_mem,0x18,memdata);		        break;		case TV_GET_CENTER:		        memdata=readlong(tv_mem,0x18) & 0x20000000;		        if (copy_to_user((int *) arg, &memdata, sizeof(int)))		             return -EFAULT;		        break;		case TV_SET_VGAOUT:			if (arg) {				// Turn vga output on				outlong(io_mem,0,0);				outlong(clk_mem,0x14,3);			} else {				// Turn off VGA output				outlong(io_mem,0,0);				outlong(clk_mem,0x14,2);			}			break;		case TV_SET_HOR_TOT:			if (!arg)				return -EFAULT;			memdata = ((arg & 0xfff) - 1) << 16;			tmpval = readlong(tv_mem,0x00) & 0xf000ffff;			outlong( tv_mem, 0x00, memdata|tmpval );			tmpval = readlong(tv_mem,0x04) & 0xf000ffff;			outlong( tv_mem, 0x04, memdata|tmpval );			printk("horz: 0x%08x\n",memdata|tmpval);			break;		case TV_SET_VER_TOT:			if (!arg)				return -EFAULT;			memdata = ((arg & 0xfff) - 1) << 16;			tmpval = readlong(tv_mem,0x0c) & 0xf000ffff;			outlong( tv_mem, 0x0c, memdata|tmpval );			tmpval = readlong(tv_mem,0x10) & 0xf000ffff;			outlong( tv_mem, 0x10, memdata|tmpval );			printk("vert: 0x%08x\n",memdata|tmpval);			break;		case TV_GET_VGAOUT:			memdata=readlong(clk_mem,0x14)&1;			if (copy_to_user((int *) arg, &memdata, sizeof(int)))			        return -EFAULT;			break;		case TV_SET_TVOUT:			if (arg) {				// LCD/TV on				outlong(tv_mem,0x00,0x03a7031f);				outlong(tv_mem,0x04,0x03a7031f);				outlong(tv_mem,0x08,0x04a30363);				outlong(tv_mem,0x0c,0x03430257);				outlong(tv_mem,0x10,0x03430257);				outlong(tv_mem,0x14,0x0290028d);				outlong(tv_mem,0x18,0xa0000007);				outlong(clk_mem,0x00,0x00030013);                                outlong(clk_mem,0x04,0x00100053);				outlong(clk_mem,0x08,0x0011007b);				outlong(clk_mem,0x0c,0x0001000a);				outlong(clk_mem,0x10,0x30404040);			} else {				outlong(tv_mem,0x18,0x00000000);				outlong(clk_mem,0x00,0x00030013);				outlong(clk_mem,0x04,0x00100053);				outlong(clk_mem,0x08,0x0011007b);				outlong(clk_mem,0x0c,0x00030013);				outlong(clk_mem,0x10,0x40404040);			}			break;		case TV_GET_VSYNC_START:		        memdata=readlong(tv_mem,0x14)&0x00000fff;		        if (copy_to_user((int *) arg, &memdata, sizeof(int)))		             return -EFAULT;			break;		case TV_SET_VSYNC_START:			memdata=readlong(tv_mem,0x14)&0xfffff000;			memdata |= (arg & 0xfff);			outlong(tv_mem,0x14,memdata);			break;		case TV_GET_VSYNC_END:			memdata=(readlong(tv_mem,0x14)>>16)&0x00000fff;			if (copy_to_user((int *) arg, &memdata, sizeof(int)))			       return -EFAULT;			break;		case TV_SET_VSYNC_END:		        memdata=readlong(tv_mem,0x14)&0xf000ffff;		        memdata |= ((arg&0xfff)<<16);		        outlong(tv_mem,0x14,memdata);		        break;		case TV_GET_HSYNC_START:			memdata=readlong(tv_mem,0x08)&0x00000fff;			if (copy_to_user((int *) arg, &memdata, sizeof(int)))			     return -EFAULT;			break;          	case TV_SET_HSYNC_START:	                memdata=readlong(tv_mem,0x08)&0xfffff000;	                memdata |= (arg & 0xfff);	                outlong(tv_mem,0x08,memdata);	                break;		case TV_GET_HSYNC_END:			memdata=(readlong(tv_mem,0x08)>>16)&0x00000fff;			if (copy_to_user((int *) arg, &memdata, sizeof(int)))			     return -EFAULT;			break;		case TV_SET_HSYNC_END:			memdata=readlong(tv_mem,0x08)&0xf000ffff;			memdata |= ((arg&0xfff)<<16);			outlong(tv_mem,0x08,memdata);			break;		default:			retval = -EINVAL;	}	return retval;}module_init (tv_init);module_exit (tv_cleanup);

⌨️ 快捷键说明

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