📄 viafbdev.c
字号:
const char __user *buffer, unsigned long count, void *data){ char buf[20], *value, *pbuf; u8 reg_val = 0; unsigned long length, i; if (count < 1) return -EINVAL; length = count > 20 ? 20 : count; if (copy_from_user(&buf[0], buffer, length)) return -EFAULT; buf[length - 1] = '\0'; /*Ensure end string */ pbuf = &buf[0]; for (i = 0; i < 3; i++) { value = strsep(&pbuf, " "); if (value != NULL) { reg_val = simple_strtoul(value, NULL, 0); switch (i) { case 0: viafb_write_reg_mask(CR9B, VIACR, reg_val, 0x0f); break; case 1: viafb_write_reg_mask(SR65, VIASR, reg_val << 2, 0x0c); break; case 2: viafb_write_reg_mask(SR65, VIASR, reg_val, 0x03); break; default: break; } } else { break; } } return count;}static int viafb_dfph_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data){ int len = 0; u8 dfp_high = 0; dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; len += sprintf(buf + len, "%x\n", dfp_high); *eof = 1; /*Inform kernel end of data */ return len;}static int viafb_dfph_proc_write(struct file *file, const char __user *buffer, unsigned long count, void *data){ char buf[20]; u8 reg_val = 0; unsigned long length; if (count < 1) return -EINVAL; length = count > 20 ? 20 : count; if (copy_from_user(&buf[0], buffer, length)) return -EFAULT; buf[length - 1] = '\0'; /*Ensure end string */ reg_val = simple_strtoul(&buf[0], NULL, 0); viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); return count;}static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data){ int len = 0; u8 dfp_low = 0; dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; len += sprintf(buf + len, "%x\n", dfp_low); *eof = 1; /*Inform kernel end of data */ return len;}static int viafb_dfpl_proc_write(struct file *file, const char __user *buffer, unsigned long count, void *data){ char buf[20]; u8 reg_val = 0; unsigned long length; if (count < 1) return -EINVAL; length = count > 20 ? 20 : count; if (copy_from_user(&buf[0], buffer, length)) return -EFAULT; buf[length - 1] = '\0'; /*Ensure end string */ reg_val = simple_strtoul(&buf[0], NULL, 0); viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); return count;}static int viafb_vt1636_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data){ int len = 0; u8 vt1636_08 = 0, vt1636_09 = 0; switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { case VT1636_LVDS: vt1636_08 = viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info, 0x08) & 0x0f; vt1636_09 = viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09); break; default: break; } switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { case VT1636_LVDS: vt1636_08 = viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2, 0x08) & 0x0f; vt1636_09 = viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09); break; default: break; } *eof = 1; /*Inform kernel end of data */ return len;}static int viafb_vt1636_proc_write(struct file *file, const char __user *buffer, unsigned long count, void *data){ char buf[30], *value, *pbuf; struct IODATA reg_val; unsigned long length, i; if (count < 1) return -EINVAL; length = count > 30 ? 30 : count; if (copy_from_user(&buf[0], buffer, length)) return -EFAULT; buf[length - 1] = '\0'; /*Ensure end string */ pbuf = &buf[0]; switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { case VT1636_LVDS: for (i = 0; i < 2; i++) { value = strsep(&pbuf, " "); if (value != NULL) { reg_val.Data = simple_strtoul(value, NULL, 0); switch (i) { case 0: reg_val.Index = 0x08; reg_val.Mask = 0x0f; viafb_gpio_i2c_write_mask_lvds (viaparinfo->lvds_setting_info, &viaparinfo-> chip_info->lvds_chip_info, reg_val); break; case 1: reg_val.Index = 0x09; reg_val.Mask = 0x1f; viafb_gpio_i2c_write_mask_lvds (viaparinfo->lvds_setting_info, &viaparinfo-> chip_info->lvds_chip_info, reg_val); break; default: break; } } else { break; } } break; default: break; } switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { case VT1636_LVDS: for (i = 0; i < 2; i++) { value = strsep(&pbuf, " "); if (value != NULL) { reg_val.Data = simple_strtoul(value, NULL, 0); switch (i) { case 0: reg_val.Index = 0x08; reg_val.Mask = 0x0f; viafb_gpio_i2c_write_mask_lvds (viaparinfo->lvds_setting_info2, &viaparinfo-> chip_info->lvds_chip_info2, reg_val); break; case 1: reg_val.Index = 0x09; reg_val.Mask = 0x1f; viafb_gpio_i2c_write_mask_lvds (viaparinfo->lvds_setting_info2, &viaparinfo-> chip_info->lvds_chip_info2, reg_val); break; default: break; } } else { break; } } break; default: break; } return count;}static void viafb_init_proc(struct proc_dir_entry *viafb_entry){ struct proc_dir_entry *entry; viafb_entry = proc_mkdir("viafb", NULL); if (viafb_entry) { entry = create_proc_entry("dvp0", 0, viafb_entry); if (entry) { entry->owner = THIS_MODULE; entry->read_proc = viafb_dvp0_proc_read; entry->write_proc = viafb_dvp0_proc_write; } entry = create_proc_entry("dvp1", 0, viafb_entry); if (entry) { entry->owner = THIS_MODULE; entry->read_proc = viafb_dvp1_proc_read; entry->write_proc = viafb_dvp1_proc_write; } entry = create_proc_entry("dfph", 0, viafb_entry); if (entry) { entry->owner = THIS_MODULE; entry->read_proc = viafb_dfph_proc_read; entry->write_proc = viafb_dfph_proc_write; } entry = create_proc_entry("dfpl", 0, viafb_entry); if (entry) { entry->owner = THIS_MODULE; entry->read_proc = viafb_dfpl_proc_read; entry->write_proc = viafb_dfpl_proc_write; } if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. lvds_chip_name || VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { entry = create_proc_entry("vt1636", 0, viafb_entry); if (entry) { entry->owner = THIS_MODULE; entry->read_proc = viafb_vt1636_proc_read; entry->write_proc = viafb_vt1636_proc_write; } } }}static void viafb_remove_proc(struct proc_dir_entry *viafb_entry){ /* no problem if it was not registered */ remove_proc_entry("dvp0", viafb_entry);/* parent dir */ remove_proc_entry("dvp1", viafb_entry); remove_proc_entry("dfph", viafb_entry); remove_proc_entry("dfpl", viafb_entry); remove_proc_entry("vt1636", viafb_entry); remove_proc_entry("vt1625", viafb_entry);}static int __devinit via_pci_probe(void){ /*unsigned char revision; */ unsigned int default_xres, default_yres; char *tmpc, *tmpm; char *tmpc_sec, *tmpm_sec; int vmode_index; u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length; DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");#define BYTES_PER_LONG (BITS_PER_LONG/8)#define PADDING(A) (BYTES_PER_LONG - (sizeof(A) % BYTES_PER_LONG)) viafb_par_length = sizeof(struct viafb_par) + PADDING(struct viafb_par); tmds_length = sizeof(struct tmds_setting_information) + PADDING(struct tmds_setting_information); lvds_length = sizeof(struct lvds_setting_information) + PADDING(struct lvds_setting_information); crt_length = sizeof(struct crt_setting_information) + PADDING(struct crt_setting_information); chip_length = sizeof(struct chip_information) + PADDING(struct chip_information);#undef PADDING#undef BYTES_PER_LONG /* Allocate fb_info and ***_par here, also including some other needed * variables */ viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length + tmds_length + crt_length + chip_length, NULL); if (!viafbinfo) { printk(KERN_ERR"Could not allocate memory for intelfb_info.\n"); return -ENODEV; } viaparinfo = (struct viafb_par *)viafbinfo->par; viaparinfo->tmds_setting_info = (struct tmds_setting_information *) ((u32)viaparinfo + viafb_par_length); viaparinfo->lvds_setting_info = (struct lvds_setting_information *) ((u32)viaparinfo->tmds_setting_info + tmds_length); viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *) ((u32)viaparinfo->lvds_setting_info + lvds_length); viaparinfo->crt_setting_info = (struct crt_setting_information *) ((u32)viaparinfo->lvds_setting_info2 + lvds_length); viaparinfo->chip_info = (struct chip_information *) ((u32)viaparinfo->crt_setting_info + crt_length); if (viafb_dual_fb) viafb_SAMM_ON = 1; parse_active_dev(); parse_video_dev(); parse_lcd_port(); parse_dvi_port(); /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */ if (!viafb_SAMM_ON) viafb_dual_fb = 0; viafb_init_chip_info(); viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize); viaparinfo->fbmem_free = viaparinfo->memsize; viaparinfo->fbmem_used = 0; viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem, viaparinfo->memsize); viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt; if (!viaparinfo->fbmem_virt) { printk(KERN_INFO "ioremap failed\n"); return -1; } viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len); viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base, viaparinfo->mmio_len); viafbinfo->node = 0; viafbinfo->fbops = &viafb_ops; viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; viafbinfo->pseudo_palette = pseudo_pal; if (via_fb_accel) { viafb_init_accel(); viafb_init_2d_engine(); viafb_hw_cursor_init(); } if (viafb_second_size && (viafb_second_size < 8)) { viafb_second_offset = viaparinfo->fbmem_free - viafb_second_size * 1024 * 1024; } else { viafb_second_size = 8; viafb_second_offset = viaparinfo->fbmem_free - viafb_second_size * 1024 * 1024; } viafb_FB_MM = viaparinfo->fbmem_virt; tmpm = viafb_mode; tmpc = strsep(&tmpm, "x"); default_xres = simple_strtoul(tmpc, NULL, 0); default_yres = simple_strtoul(tmpm, NULL, 0); vmode_index = viafb_get_mode_index(default_xres, default_yres, 0); DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); if (viafb_SAMM_ON == 1) { if (strcmp(viafb_mode, viafb_mode1)) { tmpm_sec = viafb_mode1; tmpc_sec = strsep(&tmpm_sec, "x"); viafb_second_xres = simple_strtoul(tmpc_sec, NULL, 0); viafb_second_yres = simple_strtoul(tmpm_sec, NULL, 0); } else { viafb_second_xres = default_xres; viafb_second_yres = default_yres; } if (0 == viafb_second_virtual_xres) { switch (viafb_second_xres) { case 1400: viafb_second_virtual_xres = 1408; break; default: viafb_second_virtual_xres = viafb_second_xres; break; } } if (0 == viafb_second_virtual_yres) viafb_second_virtual_yres = viafb_second_yres; } switch (via_fb_bpp) { case 0 ... 8: via_fb_bpp = 8; break; case 9 ... 16: via_fb_bpp = 16; break; case 17 ... 32: via_fb_bpp = 32; break; default: via_fb_bpp = 8; } default_var.xres = default_xres; default_var.yres = default_yres; switch (default_xres) { case 1400: default_var.xres_virtual = 1408; break; default: default_var.xres_virtual = default_xres; break; } default_var.yres_virtual = default_yres; default_var.bits_per_pixel = via_fb_bpp; if (default_var.bits_per_pixel == 15) default_var.bits_per_pixel = 16; default_var.pixclock = viafb_get_pixclock(default_xres, default_yres, viafb_refresh); default_var.left_margin = (default_xres >> 3) & 0xf8; default_var.right_margin = 32; default_var.upper_margin = 16; default_var.lower_margin = 4; default_var.hsync_len = default_var.left_margin; default_var.vsync_len = 4; default_var.accel_flags = 0; if (via_fb_accel) { viafbinfo->flags |= (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT); default_var.accel_flags |= FB_ACCELF_TEXT; } else viafbinfo->flags |= FBINFO_HWACCEL_DISABLED; if (viafb_dual_fb) { viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL); if (!viafbinfo1) { printk(KERN_ERR "allocate the second framebuffer struct error\n"); framebuffer_release(viafbinfo); return -ENOMEM; } viaparinfo1 = viafbinfo1->par; memcpy(viaparinfo1, viaparinfo, viafb_par_length); viaparinfo1->memsize = viaparinfo->memsize - viafb_second_offset; viaparinfo->memsize = viafb_second_offset; viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt + viafb_second_offset; viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset; viaparinfo1->fbmem_used = viaparinfo->fbmem_used; viaparinfo1->fbmem_free = viaparinfo1->memsize - viaparinfo1->fbmem_used; viaparinfo->fbmem_free = viaparinfo->memsize; viaparinfo->fbmem_used = 0; if (via_fb_accel) { viaparinfo1->cursor_start = viaparinfo->cursor_start - viafb_second_offset; viaparinfo1->VQ_start = viaparinfo->VQ_start - viafb_second_offset; viaparinfo1->VQ_end = viaparinfo->VQ_end - viafb_second_offset; } memcpy(viafbinfo1, viafbinfo, s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -