Пример #1
0
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);
    }
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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 );
}
Пример #5
0
    .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,
Пример #6
0
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 );
}