📄 radeon_vid.c
字号:
{ PCI_DEVICE_ID_ATI_RAGE128_PU, "R128Pro PU" }, { PCI_DEVICE_ID_ATI_RAGE128_PV, "R128Pro PV" }, { PCI_DEVICE_ID_ATI_RAGE128_PW, "R128Pro PW" }, { PCI_DEVICE_ID_ATI_RAGE128_PX, "R128Pro PX" },/* Rage128 GL */ { PCI_DEVICE_ID_ATI_RAGE128_RE, "R128 RE" }, { PCI_DEVICE_ID_ATI_RAGE128_RF, "R128 RF" }, { PCI_DEVICE_ID_ATI_RAGE128_RG, "R128 RG" }, { PCI_DEVICE_ID_ATI_RAGE128_RH, "R128 RH" }, { PCI_DEVICE_ID_ATI_RAGE128_RI, "R128 RI" },/* Rage128 VR */ { PCI_DEVICE_ID_ATI_RAGE128_RK, "R128 RK" }, { PCI_DEVICE_ID_ATI_RAGE128_RL, "R128 RL" }, { PCI_DEVICE_ID_ATI_RAGE128_RM, "R128 RM" }, { PCI_DEVICE_ID_ATI_RAGE128_RN, "R128 RN" }, { PCI_DEVICE_ID_ATI_RAGE128_RO, "R128 RO" },/* Rage128 M3 */ { PCI_DEVICE_ID_ATI_RAGE128_LE, "R128 M3 LE" }, { PCI_DEVICE_ID_ATI_RAGE128_LF, "R128 M3 LF" },/* Rage128 Pro Ultra */ { PCI_DEVICE_ID_ATI_RAGE128_U1, "R128Pro U1" }, { PCI_DEVICE_ID_ATI_RAGE128_U2, "R128Pro U2" }, { PCI_DEVICE_ID_ATI_RAGE128_U3, "R128Pro U3" }#else/* Radeons (indeed: Rage 256 Pro ;) */ { PCI_DEVICE_ID_RADEON_QD, "Radeon QD " }, { PCI_DEVICE_ID_RADEON_QE, "Radeon QE " }, { PCI_DEVICE_ID_RADEON_QF, "Radeon QF " }, { PCI_DEVICE_ID_RADEON_QG, "Radeon QG " }, { PCI_DEVICE_ID_RADEON_QY, "Radeon VE QY " }, { PCI_DEVICE_ID_RADEON_QZ, "Radeon VE QZ " }, { PCI_DEVICE_ID_RADEON_LY, "Radeon M6 LY " }, { PCI_DEVICE_ID_RADEON_LZ, "Radeon M6 LZ " }, { PCI_DEVICE_ID_RADEON_LW, "Radeon M7 LW " }, { PCI_DEVICE_ID_R200_QL, "Radeon2 8500 QL " }, { PCI_DEVICE_ID_R200_BB, "Radeon2 8500 AIW" }, { PCI_DEVICE_ID_RV200_QW, "Radeon2 7500 QW " }#endif};static int detected_chip;static int __init radeon_vid_config_card(void){ struct pci_dev *dev = NULL; size_t i; for(i=0;i<sizeof(ati_card_ids)/sizeof(struct ati_card_id_s);i++) if((dev=pci_find_device(PCI_VENDOR_ID_ATI, ati_card_ids[i].id, NULL))) break; if(!dev) { printk(RVID_MSG"No supported cards found\n"); return FALSE; } radeon_mmio_base = ioremap_nocache(pci_resource_start (dev, 2),RADEON_REGSIZE); radeon_mem_base = dev->resource[0].start; RTRACE(RVID_MSG"MMIO at 0x%p\n", radeon_mmio_base); RTRACE(RVID_MSG"Frame Buffer at 0x%08x\n", radeon_mem_base); /* video memory size */ radeon_ram_size = INREG(CONFIG_MEMSIZE); /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */ radeon_ram_size &= CONFIG_MEMSIZE_MASK; radeon_ram_size /= 0x100000; detected_chip = i; printk(RVID_MSG"Found %s (%uMb memory)\n",ati_card_ids[i].name,radeon_ram_size);#ifndef RAGE128 if(ati_card_ids[i].id == PCI_DEVICE_ID_R200_QL || ati_card_ids[i].id == PCI_DEVICE_ID_R200_BB || ati_card_ids[i].id == PCI_DEVICE_ID_RV200_QW) IsR200 = 1;#endif return TRUE;}#define PARAM_BRIGHTNESS "brightness="#define PARAM_SATURATION "saturation="#define PARAM_CONTRAST "contrast="#define PARAM_HUE "hue="#define PARAM_DOUBLE_BUFF "double_buff="#define PARAM_DEINTERLACE "deinterlace="#define PARAM_DEINTERLACE_PATTERN "deinterlace_pattern="#ifdef RADEON_FPUstatic int ovBrightness=0, ovSaturation=0, ovContrast=0, ovHue=0, ov_trans_idx=0;#endifstatic void radeon_param_buff_fill( void ){ unsigned len,saturation; int8_t brightness; brightness = besr.brightness & 0x7f; /* FIXME: It's probably x86 specific convertion. But it doesn't matter for general logic - only for printing value */ if(brightness > 63) brightness = (((~besr.brightness) & 0x3f)+1) * (-1); saturation = besr.saturation; len = 0; len += sprintf(&radeon_param_buff[len],"Interface version: %04X\nDriver version: %s\n",MGA_VID_VERSION,RADEON_VID_VERSION); len += sprintf(&radeon_param_buff[len],"Chip: %s\n",ati_card_ids[detected_chip].name); len += sprintf(&radeon_param_buff[len],"Memory: %x:%x\n",radeon_mem_base,radeon_ram_size*0x100000); len += sprintf(&radeon_param_buff[len],"MMIO: %p\n",radeon_mmio_base); len += sprintf(&radeon_param_buff[len],"Overlay offset: %x\n",radeon_overlay_off);#ifdef CONFIG_MTRR len += sprintf(&radeon_param_buff[len],"Tune MTRR: %s\n",mtrr?"on":"off");#endif if(besr.ckey_on) len += sprintf(&radeon_param_buff[len],"Last used color_key=%X (mask=%X)\n",besr.graphics_key_clr,besr.graphics_key_msk); len += sprintf(&radeon_param_buff[len],"Swapped fourcc: %s\n",swap_fourcc?"on":"off"); len += sprintf(&radeon_param_buff[len],"Last BPP: %u\n",besr.dest_bpp); len += sprintf(&radeon_param_buff[len],"Last fourcc: %s\n\n",fourcc_format_name(besr.fourcc)); len += sprintf(&radeon_param_buff[len],"Configurable stuff:\n"); len += sprintf(&radeon_param_buff[len],"~~~~~~~~~~~~~~~~~~~\n"); len += sprintf(&radeon_param_buff[len],PARAM_DOUBLE_BUFF"%s\n",besr.double_buff?"on":"off");#ifdef RAGE128 len += sprintf(&radeon_param_buff[len],PARAM_BRIGHTNESS"%i\n",(int)brightness); len += sprintf(&radeon_param_buff[len],PARAM_SATURATION"%u\n",saturation);#else#ifdef RADEON_FPU len += sprintf(&radeon_param_buff[len],PARAM_BRIGHTNESS"%i\n",ovBrightness); len += sprintf(&radeon_param_buff[len],PARAM_SATURATION"%i\n",ovSaturation); len += sprintf(&radeon_param_buff[len],PARAM_CONTRAST"%i\n",ovContrast); len += sprintf(&radeon_param_buff[len],PARAM_HUE"%i\n",ovHue);#endif#endif len += sprintf(&radeon_param_buff[len],PARAM_DEINTERLACE"%s\n",besr.deinterlace_on?"on":"off"); len += sprintf(&radeon_param_buff[len],PARAM_DEINTERLACE_PATTERN"%X\n",besr.deinterlace_pattern); radeon_param_buff_len = len;}static ssize_t radeon_vid_read(struct file *file, char *buf, size_t count, loff_t *ppos){ uint32_t size; if(!radeon_param_buff) return -ESPIPE; if(!(*ppos)) radeon_param_buff_fill(); if(*ppos >= radeon_param_buff_len) return 0; size = min(count,radeon_param_buff_len-(uint32_t)(*ppos)); memcpy(buf,radeon_param_buff,size); *ppos += size; return size;}#define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)#define RTFBrightness(a) (((a)*1.0)/2000.0)#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)#define RTFHue(a) (((a)*3.1416)/1000.0)#define RadeonSetParm(a,b,c,d) if((b)>=(c)&&(b)<=(d)) { (a)=(b);\ radeon_set_transform(RTFBrightness(ovBrightness),RTFContrast(ovContrast)\ ,RTFSaturation(ovSaturation),RTFHue(ovHue),ov_trans_idx); }static ssize_t radeon_vid_write(struct file *file, const char *buf, size_t count, loff_t *ppos){#ifdef RAGE128 if(memcmp(buf,PARAM_BRIGHTNESS,min(count,strlen(PARAM_BRIGHTNESS))) == 0) { long brightness; brightness=simple_strtol(&buf[strlen(PARAM_BRIGHTNESS)],NULL,10); if(brightness >= -64 && brightness <= 63) { besr.brightness = brightness; OUTREG(OV0_COLOUR_CNTL, (brightness & 0x7f) | (besr.saturation << 8) | (besr.saturation << 16)); } } else if(memcmp(buf,PARAM_SATURATION,min(count,strlen(PARAM_SATURATION))) == 0) { long saturation; saturation=simple_strtol(&buf[strlen(PARAM_SATURATION)],NULL,10); if(saturation >= 0 && saturation <= 31) OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) | (saturation << 8) | (saturation << 16)); } else#else#ifdef RADEON_FPU if(memcmp(buf,PARAM_BRIGHTNESS,min(count,strlen(PARAM_BRIGHTNESS))) == 0) { int tmp; tmp=simple_strtol(&buf[strlen(PARAM_BRIGHTNESS)],NULL,10); RadeonSetParm(ovBrightness,tmp,-1000,1000); } else if(memcmp(buf,PARAM_SATURATION,min(count,strlen(PARAM_SATURATION))) == 0) { int tmp; tmp=simple_strtol(&buf[strlen(PARAM_SATURATION)],NULL,10); RadeonSetParm(ovSaturation,tmp,-1000,1000); } else if(memcmp(buf,PARAM_CONTRAST,min(count,strlen(PARAM_CONTRAST))) == 0) { int tmp; tmp=simple_strtol(&buf[strlen(PARAM_CONTRAST)],NULL,10); RadeonSetParm(ovContrast,tmp,-1000,1000); } else if(memcmp(buf,PARAM_HUE,min(count,strlen(PARAM_HUE))) == 0) { int tmp; tmp=simple_strtol(&buf[strlen(PARAM_HUE)],NULL,10); RadeonSetParm(ovHue,tmp,-1000,1000); } else#endif#endif if(memcmp(buf,PARAM_DOUBLE_BUFF,min(count,strlen(PARAM_DOUBLE_BUFF))) == 0) { if(memcmp(&buf[strlen(PARAM_DOUBLE_BUFF)],"on",2) == 0) besr.double_buff = 1; else besr.double_buff = 0; } else if(memcmp(buf,PARAM_DEINTERLACE,min(count,strlen(PARAM_DEINTERLACE))) == 0) { if(memcmp(&buf[strlen(PARAM_DEINTERLACE)],"on",2) == 0) besr.deinterlace_on = 1; else besr.deinterlace_on = 0; } else if(memcmp(buf,PARAM_DEINTERLACE_PATTERN,min(count,strlen(PARAM_DEINTERLACE_PATTERN))) == 0) { long dpat; dpat=simple_strtol(&buf[strlen(PARAM_DEINTERLACE_PATTERN)],NULL,16); OUTREG(OV0_DEINTERLACE_PATTERN, dpat); } else count = -EIO; radeon_vid_preset(); return count;}static int radeon_vid_mmap(struct file *file, struct vm_area_struct *vma){ RTRACE(RVID_MSG"mapping video memory into userspace\n"); if(remap_page_range(vma->vm_start, radeon_mem_base + radeon_overlay_off, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { printk(RVID_MSG"error mapping video memory\n"); return(-EAGAIN); } return(0);}static int radeon_vid_release(struct inode *inode, struct file *file){ radeon_vid_in_use = 0; radeon_vid_stop_video(); MOD_DEC_USE_COUNT; return 0;}static long long radeon_vid_lseek(struct file *file, long long offset, int origin){ return -ESPIPE;} static int radeon_vid_open(struct inode *inode, struct file *file){ int minor = MINOR(inode->i_rdev); if(minor != 0) return(-ENXIO); if(radeon_vid_in_use == 1) return(-EBUSY); radeon_vid_in_use = 1; MOD_INC_USE_COUNT; return(0);}#if LINUX_VERSION_CODE >= 0x020400static struct file_operations radeon_vid_fops ={ llseek: radeon_vid_lseek, read: radeon_vid_read, write: radeon_vid_write,/* readdir: poll:*/ ioctl: radeon_vid_ioctl, mmap: radeon_vid_mmap, open: radeon_vid_open,/* flush:*/ release: radeon_vid_release/* fsync: fasync: lock: readv: writev: sendpage: get_unmapped_area:*/};#elsestatic struct file_operations radeon_vid_fops ={ radeon_vid_lseek, radeon_vid_read, radeon_vid_write, NULL, NULL, radeon_vid_ioctl, radeon_vid_mmap, radeon_vid_open, NULL, radeon_vid_release};#endif/* * Main Initialization Function */static int __init radeon_vid_initialize(void){ radeon_vid_in_use = 0;#ifdef RAGE128 printk(RVID_MSG"Rage128/Rage128Pro video overlay driver v"RADEON_VID_VERSION" (C) Nick Kurshev\n");#else printk(RVID_MSG"Radeon video overlay driver v"RADEON_VID_VERSION" (C) Nick Kurshev\n");#endif if(register_chrdev(RADEON_VID_MAJOR, "radeon_vid", &radeon_vid_fops)) { printk(RVID_MSG"unable to get major: %d\n", RADEON_VID_MAJOR); return -EIO; } if (!radeon_vid_config_card()) { printk(RVID_MSG"can't configure this card\n"); unregister_chrdev(RADEON_VID_MAJOR, "radeon_vid"); return -EINVAL; } radeon_param_buff = kmalloc(PARAM_BUFF_SIZE,GFP_KERNEL); if(radeon_param_buff) radeon_param_buff_size = PARAM_BUFF_SIZE;#if 0 radeon_vid_save_state();#endif radeon_vid_make_default(); radeon_vid_preset();#ifdef CONFIG_MTRR if (mtrr) { smtrr.vram = mtrr_add(radeon_mem_base, radeon_ram_size*0x100000, MTRR_TYPE_WRCOMB, 1); smtrr.vram_valid = 1; /* let there be speed */ printk(RVID_MSG"MTRR set to ON\n"); }#endif /* CONFIG_MTRR */ return(0);}int __init init_module(void){ return radeon_vid_initialize();}void __exit cleanup_module(void){#if 0 radeon_vid_restore_state();#endif if(radeon_mmio_base) iounmap(radeon_mmio_base); kfree(radeon_param_buff); RTRACE(RVID_MSG"Cleaning up module\n"); unregister_chrdev(RADEON_VID_MAJOR, "radeon_vid");#ifdef CONFIG_MTRR if (smtrr.vram_valid) mtrr_del(smtrr.vram, radeon_mem_base, radeon_ram_size*0x100000);#endif /* CONFIG_MTRR */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -