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

📄 mq200fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
       /* save cursor images */       image = fb_info->regions.v_fb + CURSOR_OFFSET;       for (i = 0; i < 2; i++) {           int j;           for (j = 0; j < 256; j++, image += 4)               cursor_images[i][j] = readl(image);       }       spin_unlock_irqrestore(&fb_info->lock, flags);       already_created = 1;    }    else {       int i;       /* restore cursor images */       image = fb_info->regions.v_fb + CURSOR_OFFSET;       spin_lock_irqsave(&fb_info->lock, flags);       for (i = 0; i < 2; i++) {           int j;           for (j = 0; j < 256; j++, image += 4)               writel(cursor_images[i][j], image);       }       spin_unlock_irqrestore(&fb_info->lock, flags);    }}/**** * turn on hardware cursor. */static voidenable_cursor(struct mq200fb_info* fb_info){    unsigned long flags;    union gc00r gc00r;    spin_lock_irqsave(&fb_info->lock, flags);    gc00r.whole = readl(GC00R(fb_info));    if (gc00r.part.hc_enbl == 0) {       set_cursor_shape(fb_info);       gc00r.part.hc_enbl = 1;       writel(gc00r.whole, GC00R(fb_info));    }    spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * turn off hardware cursor. */static voiddisable_cursor(struct mq200fb_info* fb_info){    unsigned long flags;    union gc00r gc00r;    spin_lock_irqsave(&fb_info->lock, flags);    gc00r.whole = readl(GC00R(fb_info));    if (gc00r.part.hc_enbl == 1) {       gc00r.part.hc_enbl = 0;       writel(gc00r.whole, GC00R(fb_info));    }    spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * Set current window's cursor position. * * [RETURN] *     1: when cursor position has been moved. */static intset_cursor_pos(const struct mq200fb_info* fb_info,              unsigned x,      /* horizontal pos in pixels */              unsigned y)      /* vertical pos in pixels */{    int ret;    unsigned long flags;    union gc10r gc10r;    spin_lock_irqsave(&fb_info->lock, flags);    gc10r.whole = readl(GC10R(fb_info));    if (gc10r.part.hc1s == x && gc10r.part.vc1s == y)       ret = 0;    else {       gc10r.whole = 0;       gc10r.part.hc1s = x;       gc10r.part.vc1s = y;       writel(gc10r.whole, GC10R(fb_info));       ret = 1;    }    spin_unlock_irqrestore(&fb_info->lock, flags);    return ret;}/**** * blink cursor. */static voidcursor_timer_handler(unsigned long data){    unsigned long flags;    struct mq200fb_info* fb_info = (struct mq200fb_info*)data;    union gc11r gc11r;    spin_lock_irqsave(&fb_info->lock, flags);    gc11r.whole = readl(GC11R(fb_info));    if (gc11r.part.hc1sa == CURSOR_OFFSET >> 10)       gc11r.part.hc1sa += 1;    else       gc11r.part.hc1sa = CURSOR_OFFSET >> 10;    writel(gc11r.whole, GC11R(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);    add_cursor_timer(&fb_info->cursor_info);}static voidget_color_palette(const struct mq200fb_info* fb_info,                 unsigned indx,                 unsigned* red,                 unsigned* green,                 unsigned* blue){    unsigned long flags;    union c1xxr c1xxr;    spin_lock_irqsave(&fb_info->lock, flags);    c1xxr.whole = readl(C1xxR(fb_info, indx));    spin_unlock_irqrestore(&fb_info->lock, flags);    *red = c1xxr.part.red;    *green = c1xxr.part.green;    *blue = c1xxr.part.blue;}static voidset_color_palette(const struct mq200fb_info* fb_info,                 unsigned indx,                 unsigned red,                 unsigned green,                 unsigned blue){    unsigned long flags;    union c1xxr c1xxr;    c1xxr.whole = 0;    c1xxr.part.red = red;    c1xxr.part.green = green;    c1xxr.part.blue = blue;    spin_lock_irqsave(&fb_info->lock, flags);    writel(c1xxr.whole, C1xxR(fb_info, indx));    spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * enable CRT DAC. */static voidenable_dac(const struct mq200fb_info* fb_info){    unsigned long flags;    union gc01r gc01r;    spin_lock_irqsave(&fb_info->lock, flags);    gc01r.whole = readl(GC01R(fb_info));    gc01r.part.dac_enbl = 1;    writel(gc01r.whole, GC01R(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * disable CRT DAC. */static voiddisable_dac(const struct mq200fb_info* fb_info,           unsigned sync_mode) /* specify SYNC that output while DAC is                                  disabled */{    unsigned long flags;    union gc01r gc01r;    spin_lock_irqsave(&fb_info->lock, flags);    gc01r.whole = readl(GC01R(fb_info));    gc01r.part.dac_enbl = 0;    gc01r.part.hsync_out = (sync_mode & WITH_HSYNC) != 0;    gc01r.part.vsync_out = (sync_mode & WITH_VSYNC) != 0;    writel(gc01r.whole, GC01R(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * Return true if command FIFO . */static int __inline__is_enough_cmd_fifo(const struct mq200fb_info* fb_info,                  int num){    union cc01r cc01r;    cc01r.whole = readl(CC01R(fb_info));    return cc01r.part.cmd_fifo >= num;}/**** * */static int __inline__is_enough_src_fifo(const struct mq200fb_info* fb_info,                  int num){    union cc01r cc01r;    cc01r.whole = readl(CC01R(fb_info));    return cc01r.part.src_fifo >= num;}/**** * wait until command FIFO space is enough. */static voidwait_cmd_fifo(const struct mq200fb_info* fb_info,             int num){    int i;    for (i = 0; i < 0x00100000; i++)       if (is_enough_cmd_fifo(fb_info, num))           return;    printk(CHIPNAME ": Command FIFO is full.\n");}/**** * */static voidwait_src_fifo(const struct mq200fb_info* fb_info,             int num){    int i;    for (i = 0; i < 0x00100000; i++)       if (is_enough_src_fifo(fb_info, num))           return;    printk(CHIPNAME ": Source FIFO is full.\n");}/**************************************************************** *  Frame buffer operations *//**** * rectangle fill (solid fill) */static voidge_rect_fill(const struct mq200fb_info* fb_info,            int x,            int y,            int width,            int height,            u32 bgcol){    unsigned long flags;    union ge01r ge01r;    union ge02r ge02r;    union ge00r ge00r;    ge01r.whole = 0;    ge01r.bitblt.width = width;    ge01r.bitblt.height = height;    ge02r.whole = 0;    ge02r.window.dst_x = x;    ge02r.window.dst_y = y;    ge00r.whole = 0;    ge00r.part.rop = ROP_PATCOPY;    ge00r.part.cmd_typ = 2;    /* BitBLT */    ge00r.part.mon_ptn = 1;    ge00r.part.sol_col = 1;    wait_cmd_fifo(fb_info, 4);    spin_lock_irqsave(&fb_info->lock, flags);    writel(ge01r.whole, GE01R(fb_info));    writel(ge02r.whole, GE02R(fb_info));    writel(bgcol, GE42R(fb_info));    writel(ge00r.whole, GE00R(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);}#if 0/**** * bitblt screen to screen. */static voidge_bitblt_scr_to_scr(const struct mq200fb_info* fb_info,                    int src_x,                    int src_y,                    int dst_x,                    int dst_y,                    int width,                    int height){    unsigned long flags;    union ge00r ge00r;    union ge01r ge01r;    union ge02r ge02r;    union ge03r ge03r;    ge01r.whole = 0;    ge01r.bitblt.width = width;    ge01r.bitblt.height = height;    ge02r.whole = 0;    ge02r.window.dst_x = dst_x;    ge02r.window.dst_y = dst_y;    ge03r.whole = 0;    ge03r.window.src_x = src_x;    ge03r.window.src_y = src_y;    ge00r.whole = 0;    ge00r.part.rop = ROP_SRCCOPY;    ge00r.part.cmd_typ = 2;    /* BitBLT */    if (src_x >= dst_x) {       if (src_y < dst_y)           ge00r.part.y_dir = 1;    }    else if (src_y >= dst_y)       ge00r.part.x_dir = 1;    else {       ge00r.part.x_dir = 1;       ge00r.part.y_dir = 1;    }    wait_cmd_fifo(fb_info, 4);    spin_lock_irqsave(&fb_info->lock, flags);    writel(ge01r.whole, GE01R(fb_info));    writel(ge02r.whole, GE02R(fb_info));    writel(ge03r.whole, GE03R(fb_info));    writel(ge00r.whole, GE00R(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);}#endif/**** * draw mono text image. */static voidge_bitblt_char(const struct mq200fb_info* fb_info,              int dst_x, int dst_y,              u8* image,              int width, int height,              u32 fgcol, u32 bgcol) /* foreground and background color */{    unsigned long flags;    int i;    union ge00r ge00r;    union ge01r ge01r;    union ge02r ge02r;    union ge09r ge09r;    int offset = ((u32)image & 0x3) * 8;    ge01r.whole = 0;    ge01r.bitblt.width = width;    ge01r.bitblt.height = height;    ge02r.whole = 0;    ge02r.window.dst_x = dst_x;    ge02r.window.dst_y = dst_y;    ge09r.whole = 0;    ge09r.pack_mono.strt_bit = offset;    ge09r.pack_mono.amount = 0;    ge09r.pack_mono.bit_spc = 0;    ge00r.whole = 0;    ge00r.part.rop = ROP_SRCCOPY;    ge00r.part.cmd_typ = 2;    /* bitblt */    ge00r.part.src_mem = 1;    ge00r.part.mon_src = 1;    ge00r.part.mod_sel = 1;    /* packed mode */    wait_cmd_fifo(fb_info, 6);    spin_lock_irqsave(&fb_info->lock, flags);    writel(ge01r.whole, GE01R(fb_info));    writel(ge02r.whole, GE02R(fb_info));    writel(fgcol, GE07R(fb_info));   writel(bgcol, GE08R(fb_info));    writel(ge09r.whole, GE09R(fb_info));    writel(ge00r.whole, GE00R(fb_info));    /* ---- */    for (i = 0; i < height; i += 4) {       u32 src_data = *(u32*)(image + i);       wait_src_fifo(fb_info, 8);       writel(src_data, PSF(fb_info));    }    spin_unlock_irqrestore(&fb_info->lock, flags);}/**************************************************************** * Hardware Independent Functions. *//**** *  Initialization * * [RETURN] *         0: success *     minus: fail */int __initmq200fb_init(void){#if 0    int irqval;#endif    memset(&mq200fb_info, 0, sizeof mq200fb_info);    mq200fb_info.current_par = mq200fb_options.par;    if (! mq200fb_conf(&mq200fb_info))       return -ENXIO;    mq200_reset(&mq200fb_info);    mq200fb_info.disp.scrollmode = SCROLL_YNOMOVE;    mq200fb_info.gen.parsize = sizeof(struct mq200fb_par);    mq200fb_info.gen.fbhw = &mq200_switch;    strcpy(mq200fb_info.gen.info.modename, CHIPNAME);    mq200fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;    mq200fb_info.gen.info.fbops = &mq200fb_ops;    mq200fb_info.gen.info.disp = &mq200fb_info.disp;    strcpy(mq200fb_info.gen.info.fontname, mq200fb_options.font);    mq200fb_info.gen.info.switch_con = &fbgen_switch;    mq200fb_info.gen.info.updatevar = &fbgen_update_var;    mq200fb_info.gen.info.blank = &fbgen_blank;    spin_lock_init(&mq200fb_info.lock);    fbgen_get_var(&mq200fb_info.disp.var, -1, &mq200fb_info.gen.info);    fbgen_do_set_var(&mq200fb_info.disp.var, 1, &mq200fb_info.gen);    fbgen_set_disp(-1, &mq200fb_info.gen);    fbgen_install_cmap(0, &mq200fb_info.gen);    if (register_framebuffer(&mq200fb_info.gen.info) < 0) {       printk(KERN_ERR DEVICE_DRIVER_NAME ": unable to register.\n");       return -EINVAL;    }    printk(       KERN_INFO "fb%d: %s, using %uK of video memory.\n",       GET_FB_IDX(mq200fb_info.gen.info.node),       CHIPNAME,       (u32)(mq200fb_info.regions.fb_size >> 10)    );#if 0    if ((irqval = request_irq(MQ200_IRQ, mq200_interrupt, 0, CHIPNAME,                             NULL)) != 0) {       printk(CHIPNAME ": unable to get IRQ %d (irqval=%d).\n",              MQ200_IRQ, irqval);       return -EAGAIN;    }    mq200_enable_irq(&mq200fb_info);#endif    return 0;}/**** *  Cleanup */void mq200fb_cleanup(struct fb_info *info){    /*     *  If your driver supports multiple boards, you should unregister and     *  clean up all instances.     */    unregister_framebuffer(info);    /* ... */}/**** *  Setup */int __init mq200fb_setup(char *options){    /* Parse user speficied options (`video=mq200fb:') */    return 0;}/**** * add cursor timer to timer_list. */static voidadd_cursor_timer(struct mq200fb_cursor_info* cursor_info){    cursor_info->timer.expires = jiffies + CURSOR_BLINK_RATE;    add_timer(&cursor_info->timer);}/**************************************************************** *  Modularization */#ifdef MODULEintinit_module(void){    return mq200fb_init();}void cleanup_module(void){    mq200fb_cleanup(void);}#endif /* MODULE *//* * Local variables: *  c-basic-offset: 4 * End: */

⌨️ 快捷键说明

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