📄 matrox.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 + -