📄 s3c2410_sm501.c
字号:
int result = 0; sm501_device_id = FIELD_GET(regRead32(DEVICE_ID), DEVICE_ID, DEVICE_ID); if (sm501_device_id != 0x0501) { printk(KERN_WARNING "he:Silicon Motion 501 not detected\n"); printk(KERN_WARNING "he:sm501_BWSCON = 0x%08lx\n", BWSCON); printk(KERN_WARNING "he:sm501_BANKCON4 = 0x%08lx\n", BANKCON4); printk(KERN_WARNING "he:sm501_device_id = 0x%08lx\n", regRead32(sm501Reg+DEVICE_ID)); result = -1; return result; } //printk(KERN_WARNING "he:sm501_BWSCON = 0x%08lx\n", BWSCON); //printk(KERN_WARNING "he:sm501_BANKCON4 = 0x%08lx\n", BANKCON4); return result;}static u_long sm501_last_power_mode = POWER_MODE_CTRL_MODE_MODE1;/*void (*sm501_blank_helper)(int blank);EXPORT_SYMBOL(sm501_blank_helper);*/static struct sm501_rgb rgb_8 = {red: { offset: 0, length: 4, },green: { offset: 0, length: 4, },blue: { offset: 0, length: 4, },transp: { offset: 0, length: 0, },};static struct sm501_rgb rgb_16 = {red: { offset: 11, length: 5, },green: { offset: 5, length: 6, },blue: { offset: 0, length: 5, },transp: { offset: 0, length: 0, },};static struct sm501_rgb rgb_32 = {red: { offset: 16, length: 8, },green: { offset: 8, length: 8, },blue: { offset: 0, length: 8, },transp: { offset: 24, length: 8, },};static void set_ctrlr_state(struct sm501_info *fbi, u_int state);static inline void sm501_schedule_task(struct sm501_info *fbi, u_int state){ unsigned long flags; local_irq_save(flags); /* * We need to handle two requests being made at the same time. * There are two important cases: * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) * We must perform the unblanking, which will do our REENABLE for us. * 2. When we are blanking, but immediately unblank before we have * blanked. We do the "REENABLE" thing here as well, just to be sure. */ if (fbi->task_state == C_ENABLE && state == C_REENABLE) state = (u_int) -1; if (fbi->task_state == C_DISABLE && state == C_ENABLE) state = C_REENABLE; if (state != (u_int)-1) { fbi->task_state = state; schedule_task(&fbi->task); } local_irq_restore(flags);}/** Get the VAR structure pointer for the specified console*/static inline struct fb_var_screeninfo *get_con_var(struct fb_info *info, int con){ struct sm501_info *fbi = (struct sm501_info *)info; return (con == fbi->currcon || con == -1) ? &fbi->fb.var : &fb_display[con].var;}/** Get the DISPLAY structure pointer for the specified console*/static inline struct display *get_con_display(struct fb_info *info, int con){ struct sm501_info *fbi = (struct sm501_info *)info; return (con < 0) ? fbi->fb.disp : &fb_display[con];}/** Get the CMAP pointer for the specified console*/static inline struct fb_cmap *get_con_cmap(struct fb_info *info, int con){ struct sm501_info *fbi = (struct sm501_info *)info; return (con == fbi->currcon || con == -1) ? &fbi->fb.cmap : &fb_display[con].cmap;}static inline u_intchan_to_field(u_int chan, struct fb_bitfield *bf){ chan &= 0xffff; chan >>= 16 - bf->length; return chan << bf->offset;}voidsm501_hwinit(void){ BWSCON = (BWSCON & ~(BWSCON_ST4| BWSCON_WS4| BWSCON_DW4)) | (BWSCON_ST4| BWSCON_WS4 | BWSCON_DW(4, BWSCON_DW_32)); //printk("BWSCON=%x\n",BWSCON); BANKCON4= BANKCON_Tacs0 | BANKCON_Tcos4 | BANKCON_Tacc14 | BANKCON_Toch1 | BANKCON_Tcah4 | BANKCON_Tacp6 | BANKCON_PMC1; //printk("BANKCON4=%x\n",BANKCON4);}static intsm501_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct sm501_info *fbi = (struct sm501_info *)info; u_int val, ret = 1; if (regno < fbi->palette_size) { val = ((red << 8) & 0xff0000); val |= ((green >> 0) & 0x00ff00); val |= ((blue >> 8) & 0x0000ff); fbi->palette[regno] = val; ret = 0; } return ret;}static intsm501_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct sm501_info *fbi = (struct sm501_info *)info; u_int val; int ret = 1; /* * If greyscale is true, then we convert the RGB value * to greyscale no mater what visual we are using. */ if (fbi->fb.var.grayscale) red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16; switch (fbi->fb.disp->visual) { case FB_VISUAL_TRUECOLOR: case FB_VISUAL_DIRECTCOLOR: /* * 16-bit or 32-bit True Colour. We encode the RGB value * according to the RGB bitfield information. */ if (regno < 16) { val = chan_to_field(red, &fbi->fb.var.red); val |= chan_to_field(green, &fbi->fb.var.green); val |= chan_to_field(blue, &fbi->fb.var.blue); if (fbi->bpp == 16) { *(((u16 *) fbi->fb.pseudo_palette) + regno) = val; } else { *(((u32 *) fbi->fb.pseudo_palette) + regno) = val; } ret = 0; } break; case FB_VISUAL_PSEUDOCOLOR: ret = sm501_setpalettereg(regno, red, green, blue, trans, info); break; } return ret;}/** sm501_decode_var():* Get the video params out of 'var'. If a value is wrong return -EINVAL.**/static int sm501_validate_var(struct fb_var_screeninfo *var,struct sm501_info *fbi){ int ret = -EINVAL; if (var->xres < MIN_XRES) return ret; if (var->yres < MIN_YRES) return ret; if (var->xres > fbi->xres) return ret; if (var->yres > fbi->yres) return ret; DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB8case 8: ret = 0; break;#endif#ifdef FBCON_HAS_CFB16case 16: ret = 0; break;#endif#ifdef FBCON_HAS_CFB32case 32: ret = 0; break;#endifdefault: break; } return ret;}/** sm501_set_var():* Set the user defined part of the display for the specified console*/static intsm501_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct sm501_info *fbi = (struct sm501_info *)info; struct fb_var_screeninfo *dvar = get_con_var(&fbi->fb, con); struct display *display = get_con_display(&fbi->fb, con); int err, chgvar = 0, rgbidx; DPRINTK("set_var\n"); /* * Decode var contents into a par structure, adjusting any * out of range values. */ err = sm501_validate_var(var, fbi); if (err) { DPRINTK("var invalid\n"); return err; } if (var->activate & FB_ACTIVATE_TEST) return 0; if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) return -EINVAL; if (dvar->xres != var->xres) chgvar = 1; if (dvar->yres != var->yres) chgvar = 1; if (dvar->xres_virtual != var->xres_virtual) chgvar = 1; if (dvar->yres_virtual != var->yres_virtual) chgvar = 1; if (dvar->bits_per_pixel != var->bits_per_pixel) chgvar = 1; if (con < 0) chgvar = 0; switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB8case 8: display->visual = FB_VISUAL_PSEUDOCOLOR; display->line_length = var->xres; display->dispsw = &fbcon_cfb8; rgbidx = RGB_8; break;#endif#ifdef FBCON_HAS_CFB16case 16: display->visual = FB_VISUAL_TRUECOLOR; display->line_length = var->xres * 2; display->dispsw = &fbcon_cfb16; display->dispsw_data = fbi->fb.pseudo_palette; rgbidx = RGB_16; break;#endif#ifdef FBCON_HAS_CFB32case 32: display->visual = FB_VISUAL_TRUECOLOR; display->line_length = var->xres * 4; display->dispsw = &fbcon_cfb32; display->dispsw_data = fbi->fb.pseudo_palette; rgbidx = RGB_32; break;#endifdefault: rgbidx = 0; display->dispsw = &fbcon_dummy; break; } display->screen_base = fbi->fb_virt; display->next_line = display->line_length; display->type = fbi->fb.fix.type; display->type_aux = fbi->fb.fix.type_aux; display->ypanstep = fbi->fb.fix.ypanstep; display->ywrapstep = fbi->fb.fix.ywrapstep; display->can_soft_blank = 1; display->inverse = 0; *dvar = *var; dvar->activate &= ~FB_ACTIVATE_ALL; /* * Copy the RGB parameters for this display * from the machine specific parameters. */ dvar->red = fbi->rgb[rgbidx]->red; dvar->green = fbi->rgb[rgbidx]->green; dvar->blue = fbi->rgb[rgbidx]->blue; dvar->transp = fbi->rgb[rgbidx]->transp; DPRINTK("RGBT length = %d:%d:%d:%d\n", dvar->red.length, dvar->green.length, dvar->blue.length, dvar->transp.length); DPRINTK("RGBT offset = %d:%d:%d:%d\n", dvar->red.offset, dvar->green.offset, dvar->blue.offset, dvar->transp.offset); /* * Update the old var. The fbcon drivers still use this. * Once they are using fbi->fb.var, this can be dropped. */ display->var = *dvar; /* * If we are setting all the virtual consoles, also set the * defaults used to create new consoles. */ if (var->activate & FB_ACTIVATE_ALL) fbi->fb.disp->var = *dvar; /* * If the console has changed and the console has defined * a changevar function, call that function. */ if (chgvar && info && fbi->fb.changevar) fbi->fb.changevar(con); /* If the current console is selected, activate the new var. */ if (con != fbi->currcon) return 0; fb_set_cmap(&fbi->fb.cmap, 1, sm501_setcolreg, &fbi->fb); return 0;}static int__do_set_cmap(struct fb_cmap *cmap, int kspc, int con,struct fb_info *info){ struct sm501_info *fbi = (struct sm501_info *)info; struct fb_cmap *dcmap = get_con_cmap(info, con); int err = 0; if (con == -1) con = fbi->currcon; /* no colormap allocated? (we always have "this" colour map allocated) */ if (con >= 0) err = fb_alloc_cmap(&fb_display[con].cmap, fbi->palette_size, 0); if (!err && con == fbi->currcon) err = fb_set_cmap(cmap, kspc, sm501_setcolreg, info); if (!err) { DPRINTK("before fb_copy_cmap(0x%p, 0x%p, %d ? 0 : 1)\n", cmap, dcmap, kspc); fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1); } return err;}static intsm501_set_cmap(struct fb_cmap *cmap, int kspc, int con,struct fb_info *info){ struct display *disp = get_con_display(info, con); if (disp->visual == FB_VISUAL_TRUECOLOR) return -EINVAL; return __do_set_cmap(cmap, kspc, con, info);}static intsm501_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct display *display = get_con_display(info, con); *fix = info->fix; fix->line_length = display->line_length; fix->visual = display->visual; return 0;}static intsm501_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ *var = *get_con_var(info, con); return 0;}static intsm501_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ struct fb_cmap *dcmap = get_con_cmap(info, con); fb_copy_cmap(dcmap, cmap, kspc ? 0 : 2); return 0;}static struct fb_ops sm501_ops = {owner: THIS_MODULE,fb_get_fix: sm501_get_fix,fb_get_var: sm501_get_var,fb_set_var: sm501_set_var,fb_get_cmap: sm501_get_cmap,fb_set_cmap: sm501_set_cmap,};/** sm501_switch():* Change to the specified console. Palette and video mode* are changed to the console's stored parameters.** Uh oh, this can be called from a tasklet (IRQ)*/static int sm501_switch(int con, struct fb_info *info){ struct sm501_info *fbi = (struct sm501_info *)info; struct display *disp; struct fb_cmap *cmap; DPRINTK("con=%d info->modename=%s\n", con, fbi->fb.modename); if (con == fbi->currcon) return 0; if (fbi->currcon >= 0) { disp = fb_display + fbi->currcon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -