📄 matroxfb_base.c
字号:
if (ACCESS_FBINFO(dead)) { return -ENXIO; } switch (cmd) { case FBIOGET_VBLANK: { struct fb_vblank vblank; int err; err = matroxfb_get_vblank(PMINFO &vblank); if (err) return err; if (copy_to_user(argp, &vblank, sizeof(vblank))) return -EFAULT; return 0; } case FBIO_WAITFORVSYNC: { u_int32_t crt; if (get_user(crt, (u_int32_t __user *)arg)) return -EFAULT; return matroxfb_wait_for_sync(PMINFO crt); } case MATROXFB_SET_OUTPUT_MODE: { struct matroxioc_output_mode mom; struct matrox_altout *oproc; int val; if (copy_from_user(&mom, argp, sizeof(mom))) return -EFAULT; if (mom.output >= MATROXFB_MAX_OUTPUTS) return -ENXIO; down_read(&ACCESS_FBINFO(altout.lock)); oproc = ACCESS_FBINFO(outputs[mom.output]).output; if (!oproc) { val = -ENXIO; } else if (!oproc->verifymode) { if (mom.mode == MATROXFB_OUTPUT_MODE_MONITOR) { val = 0; } else { val = -EINVAL; } } else { val = oproc->verifymode(ACCESS_FBINFO(outputs[mom.output]).data, mom.mode); } if (!val) { if (ACCESS_FBINFO(outputs[mom.output]).mode != mom.mode) { ACCESS_FBINFO(outputs[mom.output]).mode = mom.mode; val = 1; } } up_read(&ACCESS_FBINFO(altout.lock)); if (val != 1) return val; switch (ACCESS_FBINFO(outputs[mom.output]).src) { case MATROXFB_SRC_CRTC1: matroxfb_set_par(info); break; case MATROXFB_SRC_CRTC2: { struct matroxfb_dh_fb_info* crtc2; down_read(&ACCESS_FBINFO(crtc2.lock)); crtc2 = ACCESS_FBINFO(crtc2.info); if (crtc2) crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon); up_read(&ACCESS_FBINFO(crtc2.lock)); } break; } return 0; } case MATROXFB_GET_OUTPUT_MODE: { struct matroxioc_output_mode mom; struct matrox_altout *oproc; int val; if (copy_from_user(&mom, argp, sizeof(mom))) return -EFAULT; if (mom.output >= MATROXFB_MAX_OUTPUTS) return -ENXIO; down_read(&ACCESS_FBINFO(altout.lock)); oproc = ACCESS_FBINFO(outputs[mom.output]).output; if (!oproc) { val = -ENXIO; } else { mom.mode = ACCESS_FBINFO(outputs[mom.output]).mode; val = 0; } up_read(&ACCESS_FBINFO(altout.lock)); if (val) return val; if (copy_to_user(argp, &mom, sizeof(mom))) return -EFAULT; return 0; } case MATROXFB_SET_OUTPUT_CONNECTION: { u_int32_t tmp; int i; int changes; if (copy_from_user(&tmp, argp, sizeof(tmp))) return -EFAULT; for (i = 0; i < 32; i++) { if (tmp & (1 << i)) { if (i >= MATROXFB_MAX_OUTPUTS) return -ENXIO; if (!ACCESS_FBINFO(outputs[i]).output) return -ENXIO; switch (ACCESS_FBINFO(outputs[i]).src) { case MATROXFB_SRC_NONE: case MATROXFB_SRC_CRTC1: break; default: return -EBUSY; } } } if (ACCESS_FBINFO(devflags.panellink)) { if (tmp & MATROXFB_OUTPUT_CONN_DFP) { if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY) return -EINVAL; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC2) { return -EBUSY; } } } } changes = 0; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (tmp & (1 << i)) { if (ACCESS_FBINFO(outputs[i]).src != MATROXFB_SRC_CRTC1) { changes = 1; ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_CRTC1; } } else if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { changes = 1; ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_NONE; } } if (!changes) return 0; matroxfb_set_par(info); return 0; } case MATROXFB_GET_OUTPUT_CONNECTION: { u_int32_t conn = 0; int i; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { conn |= 1 << i; } } if (put_user(conn, (u_int32_t __user *)arg)) return -EFAULT; return 0; } case MATROXFB_GET_AVAILABLE_OUTPUTS: { u_int32_t conn = 0; int i; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).output) { switch (ACCESS_FBINFO(outputs[i]).src) { case MATROXFB_SRC_NONE: case MATROXFB_SRC_CRTC1: conn |= 1 << i; break; } } } if (ACCESS_FBINFO(devflags.panellink)) { if (conn & MATROXFB_OUTPUT_CONN_DFP) conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY; if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) conn &= ~MATROXFB_OUTPUT_CONN_DFP; } if (put_user(conn, (u_int32_t __user *)arg)) return -EFAULT; return 0; } case MATROXFB_GET_ALL_OUTPUTS: { u_int32_t conn = 0; int i; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).output) { conn |= 1 << i; } } if (put_user(conn, (u_int32_t __user *)arg)) return -EFAULT; return 0; } case VIDIOC_QUERYCAP: { struct v4l2_capability r; memset(&r, 0, sizeof(r)); strcpy(r.driver, "matroxfb"); strcpy(r.card, "Matrox"); sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev))); r.version = KERNEL_VERSION(1,0,0); r.capabilities = V4L2_CAP_VIDEO_OUTPUT; if (copy_to_user(argp, &r, sizeof(r))) return -EFAULT; return 0; } case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl qctrl; int err; if (copy_from_user(&qctrl, argp, sizeof(qctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); if (!ACCESS_FBINFO(outputs[1]).output) { err = -ENXIO; } else if (ACCESS_FBINFO(outputs[1]).output->getqueryctrl) { err = ACCESS_FBINFO(outputs[1]).output->getqueryctrl(ACCESS_FBINFO(outputs[1]).data, &qctrl); } else { err = -EINVAL; } up_read(&ACCESS_FBINFO(altout).lock); if (err >= 0 && copy_to_user(argp, &qctrl, sizeof(qctrl))) return -EFAULT; return err; } case VIDIOC_G_CTRL: { struct v4l2_control ctrl; int err; if (copy_from_user(&ctrl, argp, sizeof(ctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); if (!ACCESS_FBINFO(outputs[1]).output) { err = -ENXIO; } else if (ACCESS_FBINFO(outputs[1]).output->getctrl) { err = ACCESS_FBINFO(outputs[1]).output->getctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); } else { err = -EINVAL; } up_read(&ACCESS_FBINFO(altout).lock); if (err >= 0 && copy_to_user(argp, &ctrl, sizeof(ctrl))) return -EFAULT; return err; } case VIDIOC_S_CTRL_OLD: case VIDIOC_S_CTRL: { struct v4l2_control ctrl; int err; if (copy_from_user(&ctrl, argp, sizeof(ctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); if (!ACCESS_FBINFO(outputs[1]).output) { err = -ENXIO; } else if (ACCESS_FBINFO(outputs[1]).output->setctrl) { err = ACCESS_FBINFO(outputs[1]).output->setctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); } else { err = -EINVAL; } up_read(&ACCESS_FBINFO(altout).lock); return err; } } return -ENOTTY;}/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */static int matroxfb_blank(int blank, struct fb_info *info){ int seq; int crtc; CRITFLAGS MINFO_FROM_INFO(info); DBG(__FUNCTION__) if (ACCESS_FBINFO(dead)) return 1; switch (blank) { case FB_BLANK_NORMAL: seq = 0x20; crtc = 0x00; break; /* works ??? */ case FB_BLANK_VSYNC_SUSPEND: seq = 0x20; crtc = 0x10; break; case FB_BLANK_HSYNC_SUSPEND: seq = 0x20; crtc = 0x20; break; case FB_BLANK_POWERDOWN: seq = 0x20; crtc = 0x30; break; default: seq = 0x00; crtc = 0x00; break; } CRITBEGIN mga_outb(M_SEQ_INDEX, 1); mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq); mga_outb(M_EXTVGA_INDEX, 1); mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc); CRITEND return 0;}static struct fb_ops matroxfb_ops = { .owner = THIS_MODULE, .fb_open = matroxfb_open, .fb_release = matroxfb_release, .fb_check_var = matroxfb_check_var, .fb_set_par = matroxfb_set_par, .fb_setcolreg = matroxfb_setcolreg, .fb_pan_display =matroxfb_pan_display, .fb_blank = matroxfb_blank, .fb_ioctl = matroxfb_ioctl,/* .fb_fillrect = <set by matrox_cfbX_init>, *//* .fb_copyarea = <set by matrox_cfbX_init>, *//* .fb_imageblit = <set by matrox_cfbX_init>, *//* .fb_cursor = <set by matrox_cfbX_init>, */};#define RSDepth(X) (((X) >> 8) & 0x0F)#define RS8bpp 0x1#define RS15bpp 0x2#define RS16bpp 0x3#define RS32bpp 0x4#define RS4bpp 0x5#define RS24bpp 0x6#define RSText 0x7#define RSText8 0x8/* 9-F */static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel; } colors[] = { { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 8 }, { { 10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0}, 16 }, { { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0}, 16 }, { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 24, 8, 0}, 32 }, { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 4 }, { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 24 }, { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode with (default) VGA8x16 */ { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode hardwired to VGA8x8 */};/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */static unsigned int mem; /* "matrox:mem:xxxxxM" */static int option_precise_width = 1; /* cannot be changed, option_precise_width==0 must imply noaccel */static int inv24; /* "matrox:inv24" */static int cross4MB = -1; /* "matrox:cross4MB" */static int disabled; /* "matrox:disabled" */static int noaccel; /* "matrox:noaccel" */static int nopan; /* "matrox:nopan" */static int no_pci_retry; /* "matrox:nopciretry" */static int novga; /* "matrox:novga" */static int nobios; /* "matrox:nobios" */static int noinit = 1; /* "matrox:init" */static int inverse; /* "matrox:inverse" */static int sgram; /* "matrox:sgram" */#ifdef CONFIG_MTRRstatic int mtrr = 1; /* "matrox:nomtrr" */#endifstatic int grayscale; /* "matrox:grayscale" */static int dev = -1; /* "matrox:dev:xxxxx" */static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */static int depth = -1; /* "matrox:depth:xxxxx" */static unsigned int xres; /* "matrox:xres:xxxxx" */static unsigned int yres; /* "matrox:yres:xxxxx" */static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */static unsigned int vslen; /* "matrox:vslen:xxxxx" */static unsigned int left = ~0; /* "matrox:left:xxxxx" */static unsigned int right = ~0; /* "matrox:right:xxxxx" */static unsigned int hslen; /* "matrox:hslen:xxxxx" */static unsigned int pixclock; /* "matrox:pixclock:xxxxx" */static int sync = -1; /* "matrox:sync:xxxxx" */static unsigned int fv; /* "matrox:fv:xxxxx" */static unsigned int fh; /* "matrox:fh:xxxxxk" */static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */static int dfp; /* "matrox:dfp */static int dfp_type = -1; /* "matrox:dfp:xxx */static int memtype = -1; /* "matrox:memtype:xxx" */static char outputs[8]; /* "matrox:outputs:xxx" */#ifndef MODULEstatic char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */#endifstatic int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSize){ vaddr_t vm; unsigned int offs; unsigned int offs2; unsigned char orig; unsigned char bytes[32]; unsigned char* tmp; DBG(__FUNCTION__) vm = ACCESS_FBINFO(video.vbase); maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */ /* at least 2MB */ if (maxSize < 0x0200000) return 0; if (maxSize > 0x2000000) maxSize = 0x2000000; mga_outb(M_EXTVGA_INDEX, 0x03); orig = mga_inb(M_EXTVGA_DATA); mga_outb(M_EXTVGA_DATA, orig | 0x80); tmp = bytes; for (offs = 0x100000; offs < maxSize; offs += 0x200000) *tmp++ = mga_readb(vm, offs); for (offs = 0x100000; offs < maxSize; offs += 0x200000) mga_writeb(vm, offs, 0x02); mga_outb(M_CACHEFLUSH, 0x00); for (offs = 0x100000; offs < maxSize; offs += 0x200000) { if (mga_readb(vm, offs) != 0x02) break; mga_writeb(vm, offs, mga_readb(vm, offs) - 0x02); if (mga_readb(vm, offs)) break; } tmp = bytes; for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000) mga_writeb(vm, offs2, *tmp++);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -