void einkfb_set_res_info(struct fb_info *info, int xres, int yres) { einkfb_xres = xres; einkfb_yres = yres; if ( info ) { bool swap_height_width = false; if ( (info->var.yres == xres) && (info->var.xres == yres) ) swap_height_width = true; info->var.xres = info->var.xres_virtual = xres; info->var.yres = info->var.yres_virtual = yres; if ( swap_height_width ) { u32 saved_height = info->var.height; info->var.height = info->var.width; info->var.width = saved_height; } info->fix.line_length = BPP_SIZE(xres, einkfb_bpp); } }
static void fslepdc_blank_screen(void) { struct einkfb_info info; einkfb_get_info(&info); memset(info.buf, EINKFB_WHITE, BPP_SIZE((info.xres * info.yres), info.bpp)); fslepdc_update_display_buffer(fx_update_slow, info.buf); }
struct fb_info* einkfb_probe(struct platform_device *dev) { einkfb_init_err_t err = einkfb_init_err_none; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; struct fb_info *info = NULL; boot_milestone_write(EINK_HAL_STARTED_BOM, EINK_HAL_STARTED_BOM_SZ); if ( !(info = framebuffer_alloc(sizeof(struct fb_info), &dev->dev)) ) goto err1; // einkfb_init_err_framebuffer_alloc einkfb_fbinfo = info; info->fbops = &einkfb_ops; /* * Get the module's variable & fixed screeninfo. */ if ( EINKFB_FAILURE == HAL_SW_INIT(&var, &fix) ) goto err2; // einkfb_init_err_hw_sw_init /* * Allocate an address space for our real, virtual, and scratch buffers. */ einkfb_blen = BPP_SIZE((var.xres * (var.yres + 1)), var.bits_per_pixel); einkfb_size = BPP_SIZE((var.xres * var.yres), var.bits_per_pixel); einkfb_mem = FB_ROUNDUP(einkfb_blen, PAGE_SIZE) * 3; einkfb_dma = HAL_NEEDS_DMA(); if ( !(einkfb = EINKFB_MALLOC_HAL(einkfb_mem, einkfb_dma ? &einkfb_phys : NULL)) ) goto err3; // einkfb_init_err_einkfb_malloc_hal /* * Clear memory to prevent kernel info from "leaking" * into userspace. */ einkfb_memset(einkfb, einkfb_white(var.bits_per_pixel), einkfb_mem); fix.smem_start = einkfb_dma ? (unsigned long)einkfb_phys.addr : (unsigned long)einkfb; fix.smem_len = (einkfb_mem/3) << 1; /* real & virtual */ info->screen_base = (char __iomem *)einkfb; info->screen_size = einkfb_mem/3; /* just real */ info->var = var; info->fix = fix; info->pseudo_palette = NULL; /* info->par */ info->par = NULL; info->flags = FBINFO_FLAG_DEFAULT; if ( fb_alloc_cmap(&info->cmap, BPP_MAX(var.bits_per_pixel), 0) < 0 ) goto err4; // einkfb_init_err_fb_alloc_cmap switch ( var.bits_per_pixel ) { case EINKFB_1BPP: fb_copy_cmap(&einkfb_1bpp_cmap, &info->cmap); break; case EINKFB_2BPP: fb_copy_cmap(&einkfb_2bpp_cmap, &info->cmap); break; case EINKFB_4BPP: fb_copy_cmap(&einkfb_4bpp_cmap, &info->cmap); break; case EINKFB_8BPP: fb_copy_cmap(&einkfb_8bpp_cmap, &info->cmap); break; } einkfb_bpp = info->var.bits_per_pixel; einkfb_xres = info->var.xres; einkfb_yres = info->var.yres; einkfb_vfb = einkfb + info->screen_size; einkfb_buf = einkfb_vfb + info->screen_size; einkfb_hw_bringup_mode_actual = HAL_HW_INIT(info, einkfb_hw_bringup_mode); einkfb_align_x = einkfb_set_byte_alignment_x(einkfb_bpp); einkfb_align_y = einkfb_set_byte_alignment_y(einkfb_bpp); if ( register_framebuffer(info) < 0 ) goto err5; // einkfb_init_err_register_framebuffer BLANK_INIT(); boot_milestone_write(EINK_HAL_LOADED_BOM, EINK_HAL_LOADED_BOM_SZ); return info; err5: err++; // err = einkfb_init_err_register_framebuffer err4: err++; // err = einkfb_init_err_fb_alloc_cmap err3: err++; // err = einkfb_init_err_einkfb_malloc_hal err2: err++; // err = einkfb_init_err_hw_sw_init err1: err++; // err = einkfb_init_err_fb_info_alloc einkfb_remove(info, err); return NULL; }
static bool fslepdc_sw_init(struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix) { // Note: We're doing this backwards here at the moment. That is, we're getting // the panel resolution information from the EPDC driver. We should be // reading the waveform from the panel, using the information from the // waveform header to tell us what kind of panel is actually connected // to the device, and then using that information to tell the EPDC // driver how to run the panel. // // If we're not boot-strapped, get the screen into the right state. // if ( !FSLEPDC_BOOTSTRAPPED() ) { struct fb_var_screeninfo temp_var; struct fb_fix_screeninfo temp_fix; int waveform_proxy_size = 0; fslepdc_init_screen_var_fix_info(&temp_var, &temp_fix); // Read in the waveform and waveform proxy files. // fslepdc_waveform_proxy = einkwf_panel_get_waveform(fslepdc_wf_to_use, &waveform_proxy_size); // Upon success, pass the waveform proxy file to the EPDC. Otherwise, // log an error that it couldn't be used. // if ( fslepdc_waveform_proxy ) { einkwf_set_buffer(fslepdc_waveform_proxy); fslepdc_waveform_name = einkwf_get_waveform_version_string(eink_waveform_filename); mxc_epdc_set_wv_file((void *)fslepdc_waveform_proxy, fslepdc_waveform_name, waveform_proxy_size); } else einkfb_print_warn("waveform_to_use \"%s\" couldn't be set\n", fslepdc_wf_to_use); // Before bringing the display up for the first time, ensure that the VCOM value from // the panel is set. // fslepdc_pmic_set_vcom(einkwf_panel_get_vcom()); // Set the orientation for the display. // fslepdc_set_orientation(); // Set the waveform modes from the waveform. // fsledpc_set_waveform_modes(); // Tell the EPDC driver to use the snapshot update scheme since it's more compatible // with how Broadsheet/ISIS works. // //mxc_epdc_fb_set_upd_scheme(UPDATE_SCHEME_SNAPSHOT, NULL); // Get the default variable and fixed screen_info from the EPDC. // mxc_epdc_get_var_fix_info(&temp_var, &temp_fix); // Say that we want to switch into Y8-inverted mode: This is where the INIT waveform // update occurs. // temp_var.bits_per_pixel = BPP; temp_var.grayscale = GRAYSCALE_8BIT_INVERTED; mxc_epdc_fb_set(&temp_var); // Say that we want to switch to portrait mode. // temp_var.rotate = FSLEPDC_ROTATE_90; mxc_epdc_fb_set(&temp_var); // Now, return to the eInk HAL how things are actually set up. // // Note: We should also be setting the width and height fields, which are the width // and height of the panel in millimeters for DPI computations. But we need // to be getting resolution of the panel from the waveform so that we can // set those values correctly. // mxc_epdc_get_var_fix_info(&temp_var, &temp_fix); fslepdc_var.xres = temp_var.xres; fslepdc_var.yres = temp_var.yres; fslepdc_var.xres_virtual = temp_var.xres; fslepdc_var.yres_virtual = temp_var.yres; fslepdc_var.bits_per_pixel = temp_var.bits_per_pixel; fslepdc_var.width = FSLEPDC_DEFAULT_WIDTH; fslepdc_var.height = FSLEPDC_DEFAULT_HEIGHT; fslepdc_fix.smem_len = BPP_SIZE((fslepdc_var.xres * fslepdc_var.yres), fslepdc_var.bits_per_pixel); fslepdc_fix.line_length = BPP_SIZE(fslepdc_var.xres, fslepdc_var.bits_per_pixel); } *var = fslepdc_var; *fix = fslepdc_fix; return ( EINKFB_SUCCESS ); }
.grayscale = 1, .activate = FB_ACTIVATE_TEST, .height = -1, .width = -1 }; static struct fb_fix_screeninfo fslepdc_fix = { .id = EINKFB_NAME, .smem_len = FSLEPDC_SIZE, .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_STATIC_PSEUDOCOLOR, .xpanstep = 0, .ypanstep = 0, .ywrapstep = 0, .line_length = BPP_SIZE(XRES_6, BPP), .accel = FB_ACCEL_NONE }; static orientation_t fslepdc_orientations[8] = { // Upright orientations. // orientation_landscape, orientation_portrait, orientation_landscape_upside_down, orientation_portrait_upside_down, // Upside down orientations. // orientation_landscape_upside_down,
static bool broadsheet_sw_init(struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix) { bool result = EINKFB_FAILURE; bs_resolution_t res; // If we're overridden with a value other than portrait or landscape, switch us // back to the default. // switch ( bs_orientation ) { case EINKFB_ORIENT_LANDSCAPE: case EINKFB_ORIENT_PORTRAIT: break; default: bs_orientation = EINKFB_ORIENT_PORTRAIT; break; } // Initialize enough of the hardware to ascertain the resolution we need to set up for. // bs_sw_init_controller(FULL_BRINGUP_CONTROLLER, bs_orientation, &res); scratchfb_size = BPP_SIZE((res.x_hw*res.y_hw), EINKFB_8BPP); broadsheet_num_ram_banks = broadsheet_get_ram_size()/BROADSHEET_RAM_BANK_SIZE; scratchfb = broadsheet_needs_dma() ? EINKFB_MALLOC_MOD(scratchfb_size, &scratchfb_phys) : vmalloc(scratchfb_size); if ( scratchfb ) { switch ( bs_bpp ) { // If we're overridden with a value other than 2, 4, or 8 bpp, switch us // back to the default. // default: bs_bpp = BPP; case EINKFB_2BPP: case EINKFB_4BPP: case EINKFB_8BPP: broadsheet_size = BPP_SIZE((res.x_sw*res.y_sw), bs_bpp); broadsheet_var.bits_per_pixel = bs_bpp; broadsheet_fix.smem_len = broadsheet_size; broadsheet_fix.line_length = BPP_SIZE(res.x_sw, bs_bpp); break; } broadsheet_var.xres = broadsheet_var.xres_virtual = res.x_sw; broadsheet_var.yres = broadsheet_var.yres_virtual = res.y_sw; broadsheet_var.width = res.x_mm; broadsheet_var.height = res.y_mm; *var = broadsheet_var; *fix = broadsheet_fix; result = EINKFB_SUCCESS; } return ( result ); }