📄 viafbdev.c
字号:
if (!active_dev.yres1) { viafb_second_yres = 480; } else { viafb_second_yres = active_dev.yres1; } if (active_dev.bpp != 0) via_fb_bpp = active_dev.bpp; if (active_dev.bpp1 != 0) via_fb_bpp1 = active_dev.bpp1; if (active_dev.refresh != 0) viafb_refresh = active_dev.refresh; if (active_dev.refresh1 != 0) viafb_refresh1 = active_dev.refresh1; if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON)) viafb_SAMM_ON = active_dev.samm; viafb_primary_dev = active_dev.primary_dev; viafb_set_start_addr(); viafb_set_iga_path();}static void viafb_set_video_device(u32 video_dev_info){ viaparinfo->video_on_crt = STATE_OFF; viaparinfo->video_on_dvi = STATE_OFF; viaparinfo->video_on_lcd = STATE_OFF; /* Check available device to enable: */ if ((video_dev_info & CRT_Device) == CRT_Device) { viaparinfo->video_on_crt = STATE_ON; } else if ((video_dev_info & DVI_Device) == DVI_Device) { viaparinfo->video_on_dvi = STATE_ON; } else if ((video_dev_info & LCD_Device) == LCD_Device) { viaparinfo->video_on_lcd = STATE_ON; }}static void viafb_get_video_device(u32 *video_dev_info){ *video_dev_info = None_Device; if (viaparinfo->video_on_crt == STATE_ON) { *video_dev_info |= CRT_Device; } else if (viaparinfo->video_on_dvi == STATE_ON) { *video_dev_info |= DVI_Device; } else if (viaparinfo->video_on_lcd == STATE_ON) { *video_dev_info |= LCD_Device; }}static int get_primary_device(void){ int primary_device = 0; /* Rule: device on iga1 path are the primary device. */ if (viafb_SAMM_ON) { if (viafb_CRT_ON) { if (viaparinfo->crt_setting_info->iga_path == IGA1) { DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", viaparinfo-> crt_setting_info->iga_path); primary_device = CRT_Device; } } if (viafb_DVI_ON) { if (viaparinfo->tmds_setting_info->iga_path == IGA1) { DEBUG_MSG(KERN_INFO "DVI IGA Path:%d\n", viaparinfo-> tmds_setting_info->iga_path); primary_device = DVI_Device; } } if (viafb_LCD_ON) { if (viaparinfo->lvds_setting_info->iga_path == IGA1) { DEBUG_MSG(KERN_INFO "LCD IGA Path:%d\n", viaparinfo-> lvds_setting_info->iga_path); primary_device = LCD_Device; } } if (viafb_LCD2_ON) { if (viaparinfo->lvds_setting_info2->iga_path == IGA1) { DEBUG_MSG(KERN_INFO "LCD2 IGA Path:%d\n", viaparinfo-> lvds_setting_info2->iga_path); primary_device = LCD2_Device; } } } return primary_device;}static u8 is_duoview(void){ if (0 == viafb_SAMM_ON) { if (viafb_LCD_ON + viafb_LCD2_ON + viafb_DVI_ON + viafb_CRT_ON == 2) return TRUE; return FALSE; } else { return FALSE; }}static void apply_second_mode_setting(struct fb_var_screeninfo *sec_var){ u32 htotal, vtotal, long_refresh; htotal = sec_var->xres + sec_var->left_margin + sec_var->right_margin + sec_var->hsync_len; vtotal = sec_var->yres + sec_var->upper_margin + sec_var->lower_margin + sec_var->vsync_len; if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) { /*Is 32 bytes alignment? */ /*32 pixel alignment */ sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31; } htotal = sec_var->xres + sec_var->left_margin + sec_var->right_margin + sec_var->hsync_len; vtotal = sec_var->yres + sec_var->upper_margin + sec_var->lower_margin + sec_var->vsync_len; long_refresh = 1000000000UL / sec_var->pixclock * 1000; long_refresh /= (htotal * vtotal); viafb_second_xres = sec_var->xres; viafb_second_yres = sec_var->yres; viafb_second_virtual_xres = sec_var->xres_virtual; viafb_second_virtual_yres = sec_var->yres_virtual; via_fb_bpp1 = sec_var->bits_per_pixel; viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres, long_refresh);}static int apply_device_setting(struct viafb_ioctl_setting setting_info, struct fb_info *info){ int need_set_mode = 0; DEBUG_MSG(KERN_INFO "apply_device_setting\n"); if (setting_info.device_flag) { need_set_mode = 1; check_available_device_to_enable(setting_info.device_status); } /* Unlock LCD's operation according to LCD flag and check if the setting value is valid. */ /* If the value is valid, apply the new setting value to the device. */ if (viafb_LCD_ON) { if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) { need_set_mode = 1; if (setting_info.lcd_attributes.display_center) { /* Centering */ viaparinfo->lvds_setting_info->display_method = LCD_CENTERING; viafb_lcd_dsp_method = LCD_CENTERING; viaparinfo->lvds_setting_info2->display_method = viafb_lcd_dsp_method = LCD_CENTERING; } else { /* expandsion */ viaparinfo->lvds_setting_info->display_method = LCD_EXPANDSION; viafb_lcd_dsp_method = LCD_EXPANDSION; viaparinfo->lvds_setting_info2->display_method = LCD_EXPANDSION; viafb_lcd_dsp_method = LCD_EXPANDSION; } } if (setting_info.lcd_operation_flag & OP_LCD_MODE) { need_set_mode = 1; if (setting_info.lcd_attributes.lcd_mode == LCD_SPWG) { viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode = LCD_SPWG; } else { viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode = LCD_OPENLDI; } viaparinfo->lvds_setting_info2->lcd_mode = viaparinfo->lvds_setting_info->lcd_mode; } if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) { need_set_mode = 1; if (setting_info.lcd_attributes.panel_id <= LCD_PANEL_ID_MAXIMUM) { viafb_lcd_panel_id = setting_info.lcd_attributes.panel_id; viafb_init_lcd_size(); } } } if (0 != (setting_info.samm_status & OP_SAMM)) { setting_info.samm_status = setting_info.samm_status & (~OP_SAMM); if (setting_info.samm_status == 0 || setting_info.samm_status == 1) { viafb_SAMM_ON = setting_info.samm_status; if (viafb_SAMM_ON) viafb_primary_dev = setting_info.primary_device; viafb_set_start_addr(); viafb_set_iga_path(); } need_set_mode = 1; } viaparinfo->duoview = is_duoview(); if (!need_set_mode) { ; } else { viafb_set_iga_path(); viafb_set_par(info); } return (TRUE);}static void retrieve_device_setting(struct viafb_ioctl_setting *setting_info){ /* get device status */ if (viafb_CRT_ON == 1) setting_info->device_status = CRT_Device; if (viafb_DVI_ON == 1) setting_info->device_status |= DVI_Device; if (viafb_LCD_ON == 1) setting_info->device_status |= LCD_Device; if (viafb_LCD2_ON == 1) setting_info->device_status |= LCD2_Device; if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) { setting_info->video_device_status = viaparinfo->crt_setting_info->iga_path; } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) { setting_info->video_device_status = viaparinfo->tmds_setting_info->iga_path; } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) { setting_info->video_device_status = viaparinfo->lvds_setting_info->iga_path; } else { setting_info->video_device_status = 0; } setting_info->samm_status = viafb_SAMM_ON; setting_info->primary_device = get_primary_device(); setting_info->first_dev_bpp = via_fb_bpp; setting_info->second_dev_bpp = via_fb_bpp1; setting_info->first_dev_refresh = viafb_refresh; setting_info->second_dev_refresh = viafb_refresh1; setting_info->first_dev_hor_res = via_fb_hotplug_Xres; setting_info->first_dev_ver_res = via_fb_hotplug_Yres; setting_info->second_dev_hor_res = viafb_second_xres; setting_info->second_dev_ver_res = viafb_second_yres; /* Get lcd attributes */ setting_info->lcd_attributes.display_center = viafb_lcd_dsp_method; setting_info->lcd_attributes.panel_id = viafb_lcd_panel_id; setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;}static void parse_active_dev(void){ viafb_CRT_ON = STATE_OFF; viafb_DVI_ON = STATE_OFF; viafb_LCD_ON = STATE_OFF; viafb_LCD2_ON = STATE_OFF; /* 1. Modify the active status of devices. */ /* 2. Keep the order of devices, so we can set corresponding IGA path to devices in SAMM case. */ /* Note: The previous of active_dev is primary device, and the following is secondary device. */ if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) { /* CRT+DVI */ viafb_CRT_ON = STATE_ON; viafb_DVI_ON = STATE_ON; viafb_primary_dev = CRT_Device; } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) { /* DVI+CRT */ viafb_CRT_ON = STATE_ON; viafb_DVI_ON = STATE_ON; viafb_primary_dev = DVI_Device; } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) { /* CRT+LCD */ viafb_CRT_ON = STATE_ON; viafb_LCD_ON = STATE_ON; viafb_primary_dev = CRT_Device; } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) { /* LCD+CRT */ viafb_CRT_ON = STATE_ON; viafb_LCD_ON = STATE_ON; viafb_primary_dev = LCD_Device; } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) { /* DVI+LCD */ viafb_DVI_ON = STATE_ON; viafb_LCD_ON = STATE_ON; viafb_primary_dev = DVI_Device; } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) { /* LCD+DVI */ viafb_DVI_ON = STATE_ON; viafb_LCD_ON = STATE_ON; viafb_primary_dev = LCD_Device; } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) { viafb_LCD_ON = STATE_ON; viafb_LCD2_ON = STATE_ON; viafb_primary_dev = LCD_Device; } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) { viafb_LCD_ON = STATE_ON; viafb_LCD2_ON = STATE_ON; viafb_primary_dev = LCD2_Device; } else if (!strncmp(viafb_active_dev, "CRT", 3)) { /* CRT only */ viafb_CRT_ON = STATE_ON; viafb_SAMM_ON = STATE_OFF; } else if (!strncmp(viafb_active_dev, "DVI", 3)) { /* DVI only */ viafb_DVI_ON = STATE_ON; viafb_SAMM_ON = STATE_OFF; } else if (!strncmp(viafb_active_dev, "LCD", 3)) { /* LCD only */ viafb_LCD_ON = STATE_ON; viafb_SAMM_ON = STATE_OFF; } else { viafb_CRT_ON = STATE_ON; viafb_SAMM_ON = STATE_OFF; } viaparinfo->duoview = is_duoview();}static void parse_video_dev(void){ viaparinfo->video_on_crt = STATE_OFF; viaparinfo->video_on_dvi = STATE_OFF; viaparinfo->video_on_lcd = STATE_OFF; if (!strncmp(viafb_video_dev, "CRT", 3)) { /* Video on CRT */ viaparinfo->video_on_crt = STATE_ON; } else if (!strncmp(viafb_video_dev, "DVI", 3)) { /* Video on DVI */ viaparinfo->video_on_dvi = STATE_ON; } else if (!strncmp(viafb_video_dev, "LCD", 3)) { /* Video on LCD */ viaparinfo->video_on_lcd = STATE_ON; }}static int parse_port(char *opt_str, int *output_interface){ if (!strncmp(opt_str, "DVP0", 4)) { *output_interface = INTERFACE_DVP0; } else if (!strncmp(opt_str, "DVP1", 4)) { *output_interface = INTERFACE_DVP1; } else if (!strncmp(opt_str, "DFP_HIGHLOW", 11)) { *output_interface = INTERFACE_DFP; } else if (!strncmp(opt_str, "DFP_HIGH", 8)) { *output_interface = INTERFACE_DFP_HIGH; } else if (!strncmp(opt_str, "DFP_LOW", 8)) { *output_interface = INTERFACE_DFP_LOW; } else { *output_interface = INTERFACE_NONE; } return 0;}static void parse_lcd_port(void){ parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info. output_interface); /*Initialize to avoid unexpected behavior */ viaparinfo->chip_info->lvds_chip_info2.output_interface = INTERFACE_NONE; DEBUG_MSG(KERN_INFO "parse_lcd_port: viafb_lcd_port:%s,interface:%d\n", viafb_lcd_port, iaparinfo->chip_info->lvds_chip_info. output_interface);}static void parse_dvi_port(void){ parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info. output_interface); DEBUG_MSG(KERN_INFO "parse_dvi_port: viafb_dvi_port:%s,interface:%d\n", viafb_dvi_port, viaparinfo->chip_info->tmds_chip_info. output_interface);}/* * The proc filesystem read/write function, a simple proc implement to * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], * CR9B, SR65, CR97, CR99 */static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset,int count, int *eof, void *data){ int len = 0; u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; dvp0_data_dri = (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | (viafb_read_reg(VIASR, SR1B) & BIT1) >> 1; dvp0_clk_dri = (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; len += sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); *eof = 1; /*Inform kernel end of data */ return len;}static int viafb_dvp0_proc_write(struct file *file, 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); DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i, reg_val); switch (i) { case 0: viafb_write_reg_mask(CR96, VIACR, reg_val, 0x0f); break; case 1: viafb_write_reg_mask(SR2A, VIASR, reg_val << 4, BIT5); viafb_write_reg_mask(SR1B, VIASR, reg_val << 1, BIT1); break; case 2: viafb_write_reg_mask(SR2A, VIASR, reg_val << 3, BIT4); viafb_write_reg_mask(SR1E, VIASR, reg_val << 2, BIT2); break; default: break; } } else { break; } } return count;}static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data){ int len = 0; u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; len += sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); *eof = 1; /*Inform kernel end of data */ return len;}static int viafb_dvp1_proc_write(struct file *file,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -