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

📄 s1d13706fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	u8 r, g, b;	s1d13706_write_reg(regno, S1D13706_LUT_RD_ADDR_REG);	r = s1d13706_read_reg(S1D13706_LUT_R_RD_DATA_REG);	g = s1d13706_read_reg(S1D13706_LUT_G_RD_DATA_REG);	b = s1d13706_read_reg(S1D13706_LUT_B_RD_DATA_REG);	*red = r << 8;	*green = g << 8;	*blue = b << 8;#ifdef DBUG	printk("s1d13706_getcolreg done\n");#endif	return 0;}/* * Changes: 2002/12/13 adapted to s1d13706 */static int s1d13706_setcolreg(unsigned regno, unsigned red, unsigned green,			   unsigned blue, unsigned transp,			   struct fb_info *info){	u8 r = (red >> 8) & 0xfc;	u8 g = (green>>8) & 0xfc;	u8 b = (blue>> 8) & 0xfc;	s1d13706_write_reg(r, S1D13706_LUT_R_WR_DATA_REG);	s1d13706_write_reg(g, S1D13706_LUT_G_WR_DATA_REG);	s1d13706_write_reg(b, S1D13706_LUT_B_WR_DATA_REG);	s1d13706_write_reg(regno, S1D13706_LUT_WR_ADDR_REG);#ifdef DBUG	printk("s1d13706_setcolreg done\n");#endif	return 0;}static int s1d13706_pan_display(const struct fb_var_screeninfo *var,			     struct fb_info_gen *info){#ifdef DBUG	printk("s1d13706_pan_display done\n");#endif	BUG();	return -EINVAL;}#undef AERO_HACKSstatic int s1d13706_blank(int blank_mode, struct fb_info_gen *info){	u8 disp;	switch (blank_mode) {	case VESA_NO_BLANKING:		disp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);		disp |= 1;		s1d13706_write_reg(disp, S1D13706_DISPLAY_MODE_REG);		break;	case VESA_VSYNC_SUSPEND:	case VESA_HSYNC_SUSPEND:	case VESA_POWERDOWN:		disp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);		disp &= ~1;		s1d13706_write_reg(disp, S1D13706_DISPLAY_MODE_REG);		break;	default:		return -EINVAL;	}#ifdef DBUG	printk("s1d13706_blank done\n");#endif	return 0;}static struct display_switch s1d13706_dispsw;static void s1d13706_set_disp(const void *unused, struct display *disp,			   struct fb_info_gen *info){	struct display_switch *d;	disp->screen_base = (void *)S1D13706_FB_BASE;	disp->dispsw = &s1d13706_dispsw;	switch(disp->var.bits_per_pixel) {#ifdef FBCON_HAS_MFB	case 1:		d = &fbcon_mfb; break;#endif#ifdef FBCON_HAS_CFB8	case 8:		d = &fbcon_cfb8; break;#endif	default:		BUG(); break;	}	memcpy(&s1d13706_dispsw, d, sizeof *d);#ifdef DBUG	printk("s1d13706_set_disp done\n");#endif}int __init s1d13706fb_setup(char *str){#ifdef DBUG	printk("s1d13706fb_setup done\n");#endif	return 0;}int __init s1d13706fb_init(void){  u8 * pRegs = (u8 *)S1D_PHYSICAL_REG_ADDR;  unsigned int idx=0;  unsigned int tmp, tmp1;#ifdef DBUG	printk("s1d13706fb_init started\n");#endif  /*   * all according to s1d13xxxfb.c   *   ** Initialize the chip according to the following steps:  ** 1. Blank display (REG[70h] bit 7 = 1)  **    (This is not necessary if the chip powers up for the first time)  ** 2. If the system implementation uses a clock chip instead of a fixed  **    oscillator, program the clock chip.  ** 3. Write to all S1D13706 registers  ** 4. Update LookUp Table  ** 5. Power Up LCD:  **   a. If s/w power save mode is on (REG[A0h] bit 0 = 1), turn off s/w  **      power save mode.  **   b. If LCD power is off (REG[ADh] bit 7=0), delay for xx milli-seconds  **     (depending on panel specifications).  **   c. Turn on LCD power (REG[ADh] bit 7=1).  ** 6. Disable "blanking" display  (set REG[70h] bit 7 to 0)  */  /* Step 1 -> blank display*/	s1d13706_write_reg((s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG) | 0x80), S1D13706_DISPLAY_MODE_REG);	/* Step 2 -> there is no clock chip, so here's nothing to do*/	/* Step 3 -> Write to all S1D13706 registers*/	while (1)	{		if ( (aS1DRegs[idx].Index==0xff) && (aS1DRegs[idx].Value==0xff) )         break;      *(pRegs + aS1DRegs[idx].Index) = (u8)(aS1DRegs[idx].Value);      idx++;  }  /* Step 4: Update LookUp Table  ** Note that the data can be arranged such that one dword write will  ** initialize red, green, blue, and also set the LUT address at the  ** same time. However, some systems may reverse the bytes (big versus  ** little-endian systems), so the code below is designed to work for  ** both big and little-endian systems.  */  for (idx = 0; idx < 256; idx++)  {		s1d13706_write_reg(LUT8_Color[3*idx], S1D13706_LUT_R_WR_DATA_REG);		s1d13706_write_reg(LUT8_Color[3*idx+1], S1D13706_LUT_G_WR_DATA_REG);		s1d13706_write_reg(LUT8_Color[3*idx+2], S1D13706_LUT_B_WR_DATA_REG);		s1d13706_write_reg(LUT8_Color[idx], S1D13706_LUT_WR_ADDR_REG);  }  /* Step 5: Power Up LCD  **   a. If s/w power save mode is on (REG[A0h] bit 0 = 1), turn off  **      s/w power save mode.  **   b. If LCD power is off (REG[ADh] bit 7 = 0), delay for xx   **      milli-seconds (depending on panel specification).  **   c. Turn on LCD power (REG[ADh] bit 7 = 1).  */	tmp = s1d13706_read_reg(S1D13706_POWER_SAVE_CONFIG_REG);	if ( tmp & 0x01 ){		s1d13706_write_reg((u8)(tmp & ~0x01), S1D13706_POWER_SAVE_CONFIG_REG);	}  if ( !( s1d13706_read_reg(S1D13706_GPIO_CTL1_REG) & 0x80) )  {   /* delay at least 2 vertical periods for this panel */		tmp1 = s1d13706_read_reg(S1D13706_POWER_SAVE_CONFIG_REG) & 0x80;      for ( idx=0; idx<5; idx++)      {         tmp = tmp1;         while (1)         {				tmp1 = s1d13706_read_reg(S1D13706_POWER_SAVE_CONFIG_REG) & 0x80;            if ( tmp1 != tmp )               break;			}		}	}	s1d13706_write_reg(s1d13706_read_reg(S1D13706_GPIO_CTL1_REG) | 0x80, S1D13706_GPIO_CTL1_REG);  /* Step 6: Disable "blanking" display  (set REG[70h] bit 7 to 0) */	tmp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);	s1d13706_write_reg((u8) (tmp & ~0x80), S1D13706_DISPLAY_MODE_REG);	/* End of initializing the s1d13706 controller chip*/	fb_info.gen.fbhw = &s1d13706_switch;	fb_info.gen.fbhw->detect();	strcpy(fb_info.gen.info.modename, "S1D13706");	fb_info.gen.info.changevar = NULL;	fb_info.gen.info.node = -1;	fb_info.gen.info.fbops = &s1d13706fb_ops;	fb_info.gen.info.disp = &disp;	fb_info.gen.parsize = sizeof(struct s1d13706_par);	fb_info.gen.info.switch_con = &fbgen_switch;	fb_info.gen.info.updatevar = &fbgen_update_var;	fb_info.gen.info.blank = &fbgen_blank;	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;	/* This should give a reasonable default video mode */	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);	fbgen_set_disp(-1, &fb_info.gen);	if (disp.var.bits_per_pixel > 1)		fbgen_install_cmap(0, &fb_info.gen);	if (register_framebuffer(&fb_info.gen.info) < 0)		return -EINVAL;	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),	       fb_info.gen.info.modename);	return 0;}    /*     *  Cleanup     */void s1d13706fb_cleanup(struct fb_info *info){	/*	 *  If your driver supports multiple boards, you should unregister and	 *  clean up all instances.	 */#ifdef DBUG	printk("s1d13706fb_cleanup done\n");#endif	unregister_framebuffer(info);	/* ... */}static void set_color_bitfields(struct fb_var_screeninfo *var){    switch (var->bits_per_pixel) {	case 1:	    var->red.offset = 0;	    var->red.length = 1;	    var->green.offset = 0;	    var->green.length = 1;	    var->blue.offset = 0;	    var->blue.length = 1;	    var->transp.offset = 0;	    var->transp.length = 0;	    break;	case 8:	    var->red.offset = 0;	    var->red.length = 8;	    var->green.offset = 0;	    var->green.length = 8;	    var->blue.offset = 0;	    var->blue.length = 8;	    var->transp.offset = 0;	    var->transp.length = 0;	    break;	case 16:	/* RGB 565 */	    var->red.offset = 0;	    var->red.length = 5;	    var->green.offset = 5;	    var->green.length = 6;	    var->blue.offset = 11;	    var->blue.length = 5;	    var->transp.offset = 0;	    var->transp.length = 0;	    break;	case 24:	/* RGB 888 */	    var->red.offset = 0;	    var->red.length = 8;	    var->green.offset = 8;	    var->green.length = 8;	    var->blue.offset = 16;	    var->blue.length = 8;	    var->transp.offset = 0;	    var->transp.length = 0;	    break;	case 32:	/* RGBA 8888 */	    var->red.offset = 0;	    var->red.length = 8;	    var->green.offset = 8;	    var->green.length = 8;	    var->blue.offset = 16;	    var->blue.length = 8;	    var->transp.offset = 24;	    var->transp.length = 8;	    break;    }    var->red.msb_right = 0;    var->green.msb_right = 0;    var->blue.msb_right = 0;    var->transp.msb_right = 0;}static int s1d13706_get_fix(struct fb_fix_screeninfo *fix, int con,		       struct fb_info *info){#ifdef DBUG	printk(KERN_DEBUG "fb%d: start: s1d13706_get_fix\n",		GET_FB_IDX(fb_info.gen.info.node));#endif    /* we only have one mode, so our fix_screeninfo struct       always has the same values, just throw it back to the user       current_fix was initialized earlier in init */#ifdef DBUG	printk(KERN_DEBUG "fb: info: getting fix for console %d\n", con);#endif    memcpy(fix, &current_fix, sizeof(struct fb_fix_screeninfo));    return 0;}    /*     *  Get the User Defined Part of the Display     */static int s1d13706_get_var(struct fb_var_screeninfo *var, int con,		       struct fb_info *info){#ifdef DBUG	printk(KERN_DEBUG "fb%d: start: s1d13706_get_var\n",		GET_FB_IDX(fb_info.gen.info.node));	printk(KERN_DEBUG "fb: info: getting var for console %d\n", con);#endif    if (con == -1)	*var = default_var;    else	*var = fb_display[con].var;    set_color_bitfields(var);    return 0;}    /*     *  Set the User Defined Part of the Display     */static int s1d13706_set_var(struct fb_var_screeninfo *var, int con,		       struct fb_info *info){    int activate = var->activate;    struct display *display;#ifdef DBUG	printk(KERN_DEBUG "fb%d: start: s1d13706_set_var\n",		GET_FB_IDX(fb_info.gen.info.node));#endif    if (con >= 0)    {		display = &fb_display[con];    }    else		display = &disp;	/* used during initialization */    /*     *  We are working with an LCD, which means that we     *  can't allow for modifications of many of the screen's     *  usually updateable parameters     */    if (var->xres != display->var.xres ||        var->yres != display->var.yres ||        var->xres_virtual != var->xres ||  /* virtual is not supported yet */        var->yres_virtual != var->yres ||        (var->xoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||        (var->yoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||        (var->bits_per_pixel != display->var.bits_per_pixel))    {	return -EINVAL;    }    set_color_bitfields(var);  /* Since we don't allow anything to change anyways,	there's no need to update the display var, makes	our lifes much easier :-)*/    return 0;}    /*     *  Get the Colormap     */static int s1d13706_get_cmap(struct fb_cmap *cmap, int kspc, int con,			struct fb_info *info){    if (con == currcon) /* current console? */	return fb_get_cmap(cmap, kspc, s1d13706_getcolreg, info);    else if (fb_display[con].cmap.len) /* non default colormap? */	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);    else	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),		     cmap, kspc ? 0 : 2);    return 0;}    /*     *  Set the Colormap     */static int s1d13706_set_cmap(struct fb_cmap *cmap, int kspc, int con,			struct fb_info *info){    int err;    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */	if ((err = fb_alloc_cmap(&fb_display[con].cmap,			      1<<fb_display[con].var.bits_per_pixel, 0)))	    return err;    }    if (con == currcon)			/* current console? */	return fb_set_cmap(cmap, kspc, s1d13706_setcolreg, info);    else	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);    return 0;}MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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