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

📄 matrox.c

📁 VGA 转换 Tv Out源代码,在型号为 Matrox G400Dh的显示卡的基础上编程
💻 C
字号:
#include "kspace.h"#include "kernel/i2c.h"#include <linux/fb.h>#include <sys/ioctl.h>#if 0#define MAT_CLK		0x08#define MAT_DATA	0x02#else#define MAT_CLK		0x20#define MAT_DATA	0x10#endif#include <string.h>volatile unsigned char* DRG;#define M_IDX	0x3C00#define M_DATA	0x3C0A#define KERN_DEBUG#define SPIN_LOCK_UNLOCKED	0#define I2C_DELAY   10static int debug = 1;/* software I2C functions */static void i2c_setlines(struct i2c_bus *bus, int clk, int data){  int v;  DRG[M_IDX] = 0x2A;  v = DRG[M_DATA] | MAT_CLK | MAT_DATA;  if (clk) v &= ~MAT_CLK;  if (data) v &= ~MAT_DATA;  DRG[M_IDX] = 0x2A;  DRG[M_DATA] = v;  udelay(I2C_DELAY);}static int i2c_getdataline(struct i2c_bus *bus){  DRG[M_IDX] = 0x2B;  return (DRG[M_DATA] & MAT_DATA) ? 1 : 0;}static struct i2c_bus parport_i2c_bus_template = {  "...",  123,  NULL,    0, /* spinlock */     NULL,  NULL,	  i2c_setlines,  i2c_getdataline,  NULL,  NULL,};static struct i2c_bus *i2c_parport_attach(void){  struct i2c_bus *b = kmalloc(sizeof(struct i2c_bus), 				      GFP_KERNEL);  *b = parport_i2c_bus_template;  b->data = NULL;  strncpy(b->name, "MATROX", 32);  i2c_register_bus(b);  if (debug)    printk(KERN_DEBUG "i2c: attached\n");  return b;}static void i2c_parport_detach(struct i2c_bus* b){  i2c_unregister_bus(b);  kfree(b);  if (debug)    printk(KERN_DEBUG "i2c: detached\n");}#include <stdio.h>#include <sys/mman.h>#include <unistd.h>#include <fcntl.h>int ReadReg(struct i2c_bus* b, int reg) {	int v;		i2c_start(b);	i2c_sendbyte(b, 0x37, 0);	i2c_sendbyte(b, reg, 0);	v = i2c_readbyte(b, 1);	i2c_stop(b);	return v;}int WriteReg(struct i2c_bus* b, int reg, int val) {	i2c_start(b);	i2c_sendbyte(b, 0x36, 0);	i2c_sendbyte(b, reg, 0);	i2c_sendbyte(b, val, 0);	i2c_stop(b);	return 0;}int WriteRegPair(struct i2c_bus* b, int reg, int val) {	i2c_start(b);	i2c_sendbyte(b, 0x36, 0);	i2c_sendbyte(b, reg, 0);	i2c_sendbyte(b, val, 0);	i2c_sendbyte(b, val >> 8, 0);	i2c_stop(b);	return 0;}int ReadDAC(int reg) {	DRG[M_IDX] = reg;	return DRG[M_DATA];}void WriteDAC(int reg, int data) {	DRG[M_IDX] = reg;	DRG[M_DATA] = data;}int ReadCRTCEXT(int reg) {	DRG[0x1FDE] = reg;	return DRG[0x1FDF];}void WriteCRTCEXT(int reg, int data) {	DRG[0x1FDE] = reg;	DRG[0x1FDF] = data;}int PLL_calcclock(unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {	unsigned int bestdiff = ~0;	unsigned int bestvco = 0;	unsigned int fxtal = 27000;	unsigned int fwant;	unsigned int p;	fwant = freq;	for (p = 1; p <= 3; p++) {		if (fwant * 2 > fmax)			break;		fwant *= 2;	}	if (fwant < 50000) fwant = 50000;	if (fwant > fmax) fwant = fmax;	for (; p-- > 0; fwant >>= 1, bestdiff >>= 1) {		unsigned int m;		if (fwant < 50000) break;		for (m = 2; m <= 31; m++) {			unsigned int diff, fvco;			unsigned int n;			n = (fwant * (m + 1) + (fxtal >> 1)) / fxtal - 1;			if (n > 127) 				break;			if (n < 4)				n = 4;			fvco = (fxtal * (n + 1)) / (m + 1);			if (fvco < fwant)				diff = fwant - fvco;			else				diff = fvco - fwant;			if (diff < bestdiff) {				bestdiff = diff;				*post = p;				*in = m;				*feed = n;				bestvco = fvco;			}		}	}	return bestvco;}static void DAC1064_calcclock(unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {	unsigned int fvco;	unsigned int p;	fvco = PLL_calcclock(freq, fmax, in, feed, &p);	p = (1 << p) - 1;	if (fvco <= 100000)		;	else if (fvco <= 140000)		p |= 0x08;	else if (fvco <= 180000)		p |= 0x10;	else		p |= 0x18;	*post = p;}struct fb_fix_screeninfo ffsi;int gfbi(void) {	int fd;	int err;	fd = open("/dev/fb1", O_RDWR);	if (fd < 0) {		perror("Open /dev/fb1");		return 1;	}	err = ioctl(fd, FBIOGET_FSCREENINFO, &ffsi);	close(fd);	if (err)		return 1;	return 0;}static inline void writel(unsigned int l, volatile void* addr) {	*(volatile unsigned int*)addr = l;}void goCRTC2(volatile unsigned char* DRG, struct fb_var_screeninfo *si) {	unsigned int hdispend = si->xres & ~7;	unsigned int hsyncstart = hdispend + (si->right_margin & ~7);	unsigned int hsyncend = hsyncstart + (si->hsync_len & ~7);	unsigned int htotal = hsyncend + (si->left_margin & ~7);	unsigned int vdispend = si->yres;	unsigned int vsyncstart = vdispend + si->lower_margin;	unsigned int vsyncend = vsyncstart + si->vsync_len;	unsigned int vtotal = vsyncend + si->upper_margin;	unsigned int tmp;	if (si->bits_per_pixel == 32)		tmp = 0x00800000;	else if (si->bits_per_pixel == 16) {		if (si->green.length == 5)			tmp = 0x00200000;		else			tmp = 0x00400000;	} else {		tmp = 0x00040000;		fprintf(stderr, "Depth %d is not supported\n", si->bits_per_pixel);	}	writel(tmp | 0xC0000443, DRG+0x3C10); /* 16bpp and so on... */	writel(((hdispend - 8) << 16) | (htotal - 8), DRG+0x3C14);	writel(((hsyncend - 8) << 16) | (hsyncstart - 8), DRG+0x3C18);	writel(((vdispend - 1) << 16) | (vtotal - 1), DRG+0x3C1C);	writel(((vsyncend - 1) << 16) | (vsyncstart - 1), DRG+0x3C20);	writel((vsyncstart << 16) | (hsyncstart), DRG + 0x3C24); /* preload */	writel(0, DRG + 0x3C28);	     /* vmemory start */	writel(si->xres_virtual * (si->bits_per_pixel >> 3), DRG + 0x3C40);	writel(0x0FFF0000, DRG + 0x3C44);    /* 0x0FFF0000 is linecompare,						0x00000200 vsync polarity						0x00000100 hsync polarity */	writel(0, DRG + 0x3C4C);	     /* data control */	}int main(int argc, char* argv[]) {	int fd;	static unsigned char zero = 0;	unsigned char buffer[128];	struct i2c_bus* b;	int r;	if (gfbi()) {		return 1;	}	fd = open("/dev/mem", O_RDWR);	if (fd < 0) {		perror("Open /dev/mem");		return 1;	}	DRG = mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)(ffsi.mmio_start));	close(fd);	if (!DRG) {		perror("mmap");		return 1;	}  	DRG[M_IDX] = 0x2B;  	DRG[M_DATA] = 0x00;	DRG[M_IDX] = 0x2A;	DRG[M_DATA] = 0xFF;	b = i2c_parport_attach();	if (argc >= 3) {		printf("Writting new value...\n");		WriteReg(b, strtoul(argv[1], NULL, 0), strtoul(argv[2], NULL, 0));	}#if 1	i2c_start(b);	i2c_sendbyte(b, 0x37, 0);	i2c_sendbyte(b, 0, 0);	for (r = 0; r < 256; r++) {	    if (!(r & 0x0F)) {	    	printf("%03X:", r);	    }	    printf(" %02X", i2c_readbyte(b, 0));	    if ((r & 0x0F) == 0x0F) {	    	printf("\n");	    }	}	printf("100: %02X\n", i2c_readbyte(b, 1));	i2c_stop(b);#endif	i2c_parport_detach(b);	munmap(DRG, 16384);	return 0;}	

⌨️ 快捷键说明

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