⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mq200fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (regno >= 256)       return 1;    get_color_palette(fb_info, regno, red, green, blue);    *red <<= 8;    *green <<= 8;    *blue <<= 8;    *transp = 0;               /* right now, transparency is not                                  implemented */    return 0;}/**** *  Set a single color register. The values supplied have a 16 bit *  magnitude. *  Return != 0 for invalid regno. */static int mq200fb_setcolreg(unsigned regno,                            unsigned red,                            unsigned green,                            unsigned blue,                            unsigned transp,                            struct fb_info *info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    if (regno >= 256)       return 1;    set_color_palette(fb_info, regno, red >> 8, green >> 8, blue >> 8);    return 0;}/**** *  Pan (or wrap, depending on the `vmode' field) the display using the *  `xoffset' and `yoffset' fields of the `var' structure. *  If the values don't fit, return -EINVAL. */static int mq200fb_pan_display(const struct fb_var_screeninfo* var,                              struct fb_info_gen* info){    if (var->xoffset || var->yoffset)       return -EINVAL;    else       return 0;#if 0    if (var->xoffset <= 0 && var->yoffset <= 0) {    }    else if (var->xoffset > 0 && var->yoffset > 0) {    }    else if (var->xoffset <= 0 && var->yoffset > 0) {    }    else {    }    return 0;#endif}/**** *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL *  then the caller blanks by setting the CLUT (Color Look Up Table) to all *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due *  to e.g. a video mode which doesn't support it. Implements VESA suspend *  and powerdown modes on hardware that supports disabling hsync/vsync: *    blank_mode == 2: suspend vsync *    blank_mode == 3: suspend hsync *    blank_mode == 4: powerdown */static int mq200fb_blank(int blank_mode,                        struct fb_info_gen* info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    if (! fb_info->current_par_valid)       return 1;    switch (blank_mode) {    case 0:       enable_dac(fb_info);       enable_cursor(fb_info);       return 0;    case 1:       disable_cursor(fb_info);       disable_dac(fb_info, WITH_VSYNC | WITH_HSYNC);       return 0;    case 2:       disable_cursor(fb_info);       disable_dac(fb_info, WITH_HSYNC);       return 0;    case 3:       disable_cursor(fb_info);       disable_dac(fb_info, WITH_VSYNC);       return 0;    case 4:       disable_cursor(fb_info);       disable_dac(fb_info, WITH_NONE);       return 0;    default:       printk(CHIPNAME ": unknown blank mode (%d).\n", blank_mode);       return 1;    }}/**** *  Fill in a pointer with the virtual address of the mapped frame buffer. *  Fill in a pointer to appropriate low level text console operations (and *  optionally a pointer to help data) for the video mode `par' of your *  video hardware. These can be generic software routines, or hardware *  accelerated routines specifically tailored for your hardware. *  If you don't have any appropriate operations, you must fill in a *  pointer to dummy operations, and there will be no text output. */static void mq200fb_set_disp(const void *par,                            struct display *disp,                            struct fb_info_gen *info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    disp->screen_base = (char*)fb_info->regions.v_fb;    switch (get_bits_per_pixel((struct mq200fb_par*)par)) {#ifdef FBCON_HAS_CFB8    case 8:       disp->dispsw = &mq200_cfb8;       break;#endif    default:       disp->dispsw = &fbcon_dummy;    }}/**************************************************************** * functions for struct display_switch member */#ifdef FBCON_HAS_CFB8static voidmq200fb_cursor(struct display* disp,              int mode,              int x,              int y){    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;    switch (mode) {    case CM_ERASE:       disable_cursor(fb_info);       break;    case CM_DRAW:    case CM_MOVE:       enable_cursor(fb_info);       set_cursor_pos(fb_info, x * fontwidth(disp), y * fontheight(disp));       break;    }}#endif#ifdef FBCON_HAS_CFB8static intmq200fb_set_font(struct display* disp,                int width,                int height){    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;    fb_info->cursor_info.size.x = width;    fb_info->cursor_info.size.y = height;    set_cursor_shape(fb_info);    return 1;}#endif#ifdef FBCON_HAS_CFB8static void mq200fb_clear(struct vc_data* conp, struct display* disp,                         int sy, int sx, int height, int width){    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;    u32 bgx;    bgx = attr_bgcol_ec(disp, conp);    ge_rect_fill(fb_info, sx * fontwidth(disp), sy * fontheight(disp),                width * fontwidth(disp), height * fontheight(disp), bgx);}#endif#ifdef FBCON_HAS_CFB8static voidmq200fb_clear_margins(struct vc_data* conp,                     struct display* disp,                     int bottom_only){    const struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;    unsigned int right_start = conp->vc_cols * fontwidth(disp);    unsigned int right_width = disp->var.xres - right_start;    unsigned int bottom_start = conp->vc_rows * fontheight(disp);    unsigned int bottom_width = disp->var.yres - bottom_start;    u32 bgx = attr_bgcol_ec(disp, conp);    if (! bottom_only && right_width != 0)       ge_rect_fill(fb_info, right_start, 0, right_width,                    disp->var.yres_virtual, bgx);    if (bottom_width != 0)       ge_rect_fill(fb_info, 0, disp->var.yoffset + bottom_start,                    right_start, bottom_width, bgx);}#endif#ifdef FBCON_HAS_CFB8static voidmq200fb_putc(struct vc_data* conp,            struct display* disp,            int ch,            int yy,            int xx){    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;    u32 fgx, bgx;    u8* chdat;    fgx = attr_fgcol(disp, ch);    bgx = attr_bgcol(disp, ch);    xx *= fontwidth(disp);    yy *= fontheight(disp);    chdat = disp->fontdata + (ch & disp->charmask) * fontheight(disp);    ge_bitblt_char(fb_info, xx, yy, chdat, fontwidth(disp),                  fontheight(disp), fgx, bgx);}#endif#ifdef FBCON_HAS_CFB8static voidmq200fb_putcs(struct vc_data* conp,             struct display* disp,             const unsigned short* str,             int count,             int yy,             int xx){    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;    u32 fgx, bgx;    fgx = attr_fgcol(disp, scr_readw(str));    bgx = attr_bgcol(disp, scr_readw(str));    xx *= fontwidth(disp);    yy *= fontheight(disp);    while (count-- > 0) {       u16 ch = scr_readw(str++) & disp->charmask;       u8* chdat = disp->fontdata + ch * fontheight(disp);       ge_bitblt_char(fb_info, xx, yy, chdat, fontwidth(disp),                      fontheight(disp), fgx, bgx);       xx += fontwidth(disp);    }}#endif/**************************************************************** * functions related to "struct mq200fb_par". *//**** * Is current window using color palette? */static intis_color_palette_enabled(const struct mq200fb_par* par){    switch (par->gc[0].gcd) {    case GCD_1_CP: case GCD_2_CP: case GCD_4_CP: case GCD_8_CP:    case GCD_16_CP: case GCD_24_CP: case GCD_32_RGB_CP: case GCD_32_BGR_CP:       return 1;    default:       return 0;    }}/**** * Return current window's virtual width in bytes. * * [NOTE] *     This function assumes that struct win_par.wst value is not a *     negative number. */static u32get_line_length(const struct mq200fb_par* par){    return par->gc[0].win.wst;}/**** * Return current window's width in pixels. */static u32get_width(const struct mq200fb_par* par){    return par->gc[0].win.hww /* + 1 */;}#if 0/**** * set current window's virtual width. * * [NOTE] *     This function assumes that already depth was set. */static voidset_v_width(struct mq200fb_par* par,           int width)          /* in pixels */{    int depth = get_bits_per_pixel(par);    par->gc[0].win.wst = (width * depth + 127) / 128 * 16;}#endif/**** * Return current window's virtual height. */static u32get_v_height(const struct mq200fb_par* par){    return par->gc[0].v_height;}static u32get_height(const struct mq200fb_par* par){    return par->gc[0].win.vwh;}#if 0/**** * set current window's virtual height. */static voidset_v_height(struct mq200fb_par* par,            int height){    par->gc[0].v_height = height;}#endif/**** * get current window's depth (bits / pixcel). */static intget_bits_per_pixel(const struct mq200fb_par* par){    switch (par->gc[0].gcd) {    case GCD_1_CP:       return 1;    case GCD_2_CP:       return 2;    case GCD_4_CP:       return 4;    case GCD_8_CP:       return 8;    case GCD_16_CP: case GCD_16:       return 16;    case GCD_24_CP: case GCD_24:       return 24;    default:       return 32;    }}#if 0/**** * set current window's depth. * * [NOTE] *     we do not use the following: *             GCD_16_CP, GCD_24_CP, GCD_32_RGB_CP, GCD_32_BGR_CP, *             GCD_32_BGR. */static voidset_bits_per_pixel(struct mq200fb_par* par,                  int bpp){    if (bpp <= 1)       par->gc[0].gcd = GCD_1_CP;    else if (bpp <= 2)       par->gc[0].gcd = GCD_2_CP;    else if (bpp <= 4)       par->gc[0].gcd = GCD_4_CP;    else if (bpp <= 8)       par->gc[0].gcd = GCD_8_CP;    else if (bpp <= 16)       par->gc[0].gcd = GCD_16;    else if (bpp <= 24)       par->gc[0].gcd = GCD_24;    else       par->gc[0].gcd = GCD_32_RGB;}#endifstatic u32get_right_margin(const struct mq200fb_par* par){    return par->gc[0].disp.hss;}static u32get_left_margin(const struct mq200fb_par* par){    return par->gc[0].disp.hdt + 2 - par->gc[0].disp.hse;}static u32get_lower_margin(const struct mq200fb_par* par){    return par->gc[0].disp.vss;}static u32get_upper_margin(const struct mq200fb_par* par){    return par->gc[0].disp.vdt + 1 - par->gc[0].disp.vse;}static u32get_hsync_len(const struct mq200fb_par* par){    return par->gc[0].disp.hse - par->gc[0].disp.hss;}static u32get_vsync_len(const struct mq200fb_par* par){    return par->gc[0].disp.vse - par->gc[0].disp.vss;}static u32get_xoffset(const struct mq200fb_par* par){    return (par->gc[0].win.wsa % par->gc[0].win.wst) /       ((get_bits_per_pixel(par) + 7) / 8);}static u32get_yoffset(const struct mq200fb_par* par){    return par->gc[0].win.wsa / par->gc[0].win.wst;}/**** * Return pixel clock in pico seconds. */static u32get_pixclock(const struct mq200fb_par* par){    double freq = get_pll_freq(&par->pll[1]) / get_fd_val(par) / get_sd_val(par);    return (u32)(1.0e12 / freq + 0.5);}/**** * Return specified PLL frequencey in MHz. */static doubleget_pll_freq(const struct pll_par* pll){    return 12.288e6 * (pll->m_par + 1) / (pll->n_par + 1) / (1 << pll->p_par);}/**** * Return FD value. FD is a value that is used to generate G1MCLK. */static doubleget_fd_val(const struct mq200fb_par* par){    switch (par->gc[0].fd) {    case 0:       return 1.0;    default:       return par->gc[0].fd + 0.5;    }}/**** * Return SD value. SD is a value that is used to generate G1MCLK. */static doubleget_sd_val(const struct mq200fb_par* par){    return par->gc[0].sd;}/**************************************************************** * hardware specific functions. *//**** * power state transition to "state". */static voidpower_state_transition(const struct mq200fb_info* fb_info,                      int state){    int i;    writel(state, PMCSR(fb_info));    for (i = 1; ; i++) {       udelay(100);       if ((readl(PMCSR(fb_info)) & 0x3) == state) {           PRINTK(CHIPNAME ": transition to D%d state (%d)\n\r", state, i);           break;       }    }}#if 0/**** * vertical sync enable -- falling edge.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -