Linux-driven LCD

Source: Internet
Author: User

LCD program steps: 1. Assign a Fb_info 2. Set 3. Hardware-related Operations 4. Register Register_framebuffer 5. Entry function 6. Export function

#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/clk.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/div64.h>

#include <asm/mach/map.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/fb.h>

static int S3c_lcdfb_setcolreg (unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue,
unsigned int transp, struct fb_info *info);


struct Lcd_regs {
unsigned longlcdcon1;
unsigned longlcdcon2;
unsigned longlcdcon3;
unsigned longlcdcon4;
unsigned longlcdcon5;
unsigned longlcdsaddr1;
unsigned longlcdsaddr2;
unsigned LONGLCDSADDR3;
unsigned longredlut;
unsigned longgreenlut;
unsigned longbluelut;
unsigned longreserved[9];
unsigned longdithmode;
unsigned longtpal;
unsigned longlcdintpnd;
unsigned longlcdsrcpnd;
unsigned Longlcdintmsk;
unsigned longlpcsel;
};//LCD Controller Register, register is 4 bytes, so to add unsigned long reserved[9];

static struct Fb_ops S3c_lcdfb_ops = {
. owner= This_module,
. fb_setcolreg= S3c_lcdfb_setcolreg,
. fb_fillrect= Cfb_fillrect,
. fb_copyarea= Cfb_copyarea,
. fb_imageblit= Cfb_imageblit,
};


static struct Fb_info *s3c_lcd;
Static volatile unsigned long *gpbcon;
Static volatile unsigned long *gpbdat;
Static volatile unsigned long *gpccon;
Static volatile unsigned long *gpdcon;
Static volatile unsigned long *gpgcon;
Static volatile struct lcd_regs* lcd_regs;
Static U32 pseudo_palette[16];


/* FROM PXAFB.C */
static inline unsigned int chan_to_field (unsigned int chan, struct Fb_bitfield *bf)
{
Chan &= 0xFFFF;
Chan >>= 16-bf->length;
Return Chan << bf->offset;
}


static int S3c_lcdfb_setcolreg (unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue,
unsigned int transp, struct fb_info *info)
{
unsigned int val;

if (Regno > 16)
return 1;

/* Construct Val * with Red,green,blue primaries */
val = Chan_to_field (red,&info->var.red);
Val |= Chan_to_field (Green, &info->var.green);
Val |= Chan_to_field (Blue,&info->var.blue);

((U32 *) (Info->pseudo_palette)) [Regno] = val;
Pseudo_palette[regno] = val;
return 0;
}

static int lcd_init (void)
{
/* 1. Assign a fb_info */
S3C_LCD = Framebuffer_alloc (0, NULL);

/* 2. Set */
/* 2.1 Set the fixed parameters */
strcpy (s3c_lcd->fix.id, "MYLCD");
S3c_lcd->fix.smem_len = 240*320*16/8; Video memory Length = Resolution * Number of bytes per pixel
S3c_lcd->fix.type = Fb_type_packed_pixels; /* Packed Pixels */
S3c_lcd->fix.visual = Fb_visual_truecolor; /* TFT */
S3c_lcd->fix.line_length = 240*2; The length of each line, in bytes

/* 2.2 Set Variable parameters */
S3c_lcd->var.xres = 240; X-Directional resolution
S3c_lcd->var.yres = 320; Y-Direction resolution
S3c_lcd->var.xres_virtual = 240; X-Directional Virtual resolution
S3c_lcd->var.yres_virtual = 320; Virtual resolution in Y-direction
S3c_lcd->var.bits_per_pixel = 16; How many bits per pixel are used

/* rgb:565 */
S3c_lcd->var.red.offset = 11; Red Offset value is 11
S3c_lcd->var.red.length = 5;//Red bit length is 5

S3c_lcd->var.green.offset = 5;//Green offset value is 5
S3c_lcd->var.green.length = 6;//Green bit length is 6

S3c_lcd->var.blue.offset = 0;//Green offset value is 0
S3c_lcd->var.blue.length = 5;//Blue bit length is 5

S3c_lcd->var.activate = Fb_activate_now; Make the value of the setting effective immediately


/* 2.3 Set the action function */
S3c_lcd->fbops = &s3c_lcdfb_ops;

/* 2.4 Other Settings */
S3c_lcd->pseudo_palette = Pseudo_palette; The array that holds the color palette
S3c_lcd->screen_base =; /* Virtual Address of memory */
S3c_lcd->screen_size = size of 240*324*16/8;//memory

/* 3. Hardware-related Operations */
/* 3.1 Configure GPIO for LCD */
Gpbcon = Ioremap (0x56000010, 8);
Gpbdat = gpbcon+1;
Gpccon = Ioremap (0x56000020, 4);
Gpdcon = Ioremap (0x56000030, 4);
Gpgcon = Ioremap (0x56000060, 4);

*gpccon = 0XAAAAAAAA; /* Gpio pins for Vd[7:0],lcdvf[2:0],vm,vframe,vline,vclk,lend */
*gpdcon = 0XAAAAAAAA; /* Gpio pins for vd[23:8] */

*gpbcon &= ~ (3); /* GPB0 set to output pin */
*gpbcon |= 1;
*gpbdat &=; /* Output Low Level */

*gpgcon |= (3<<8); /* GPG4 as Lcd_pwren */

/* 3.2 Set LCD controller according to LCD manual, such as frequency of VCLK, etc. */
Lcd_regs = Ioremap (0x4d000000, sizeof (struct lcd_regs)); Map each LCD control register,

/* Bit[17:8]: VCLK = HCLK/[(CLKVAL+1) x 2], LCD manual P14
* 10MHZ (100NS) = 100MHz/[(CLKVAL+1) x 2]
* Clkval = 4
* Bit[6:5]: 0b11, TFT LCD
* Bit[4:1]: 0b1100, + BPP for TFT
* Bit[0]: 0 = Disable The video output and the LCD control signal.
*/
Lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0c<<1);

/* Time parameter in vertical direction
* Bit[31:24]: vbpd, vsync after a long time to issue the 1th row of data
* LCD Manual t0-t2-t1=4
* vbpd=3
* Bit[23:14]: How many lines, 320, so lineval=320-1=319
* Bit[13:6]: VFPD, after sending the last line of data, it takes too long to issue VSync
* LCD manual t2-t5=322-320=2, so vfpd=2-1=1
* bit[5:0]: VSPW, pulse width of vsync signal, LCD manual t1=1, so vspw=1-1=0
*/
Lcd_regs->lcdcon2 = (3<<24) | (319<<14) | (1<<6) | (0<<0);

/* Time parameter in horizontal direction
* Bit[25:19]: hbpd, vsync after a long time to issue the 1th row of data
* LCD Manual t6-t7-t8=17
* HBPD=16
* Bit[18:8]: How many columns, 240, so hozval=240-1=239
* bit[7:0]: HFPD, after sending the last pixel data in the last line, it takes too long to emit hsync
* LCD manual t8-t11=251-240=11, so hfpd=11-1=10
*/
Lcd_regs->lcdcon3 = (16<<19) | (239<<8) | (10<<0);

/* Sync signal in horizontal direction
* bit[7:0]: HSPW, pulse width of hsync signal, LCD manual t7=5, so hspw=5-1=4
*/
Lcd_regs->lcdcon4 = 4;

/ * Polarity of signal
* BIT[11]: 1=565 format
* BIT[10]: 0 = The video data is fetched at VCLK falling edge
* Bit[9]: 1 = hsync signal to be reversed, i.e. low active
* Bit[8]: 1 = vsync signal to be reversed, i.e. low active
* Bit[6]: 0 = Vden do not invert
* Bit[3]: 0 = pwren Output 0
* Bit[1]: 0 = bswp
* Bit[0]: 1 = hwswp 2440 manual P413
*/
Lcd_regs->lcdcon5 = (1<<11) | (0&LT;&LT;10) | (1<<9) | (1<<8) | (1<<0);

/* 3.3 Allocate memory (framebuffer) and tell the address to the LCD controller */
S3c_lcd->screen_base = Dma_alloc_writecombine (NULL, S3c_lcd->fix.smem_len, &s3c_lcd->fix.smem_start, Gfp_kernel);

LCD_REGS-&GT;LCDSADDR1 = (S3c_lcd->fix.smem_start >> 1) & ~ (3<<30);//Store start address
LCD_REGS-&GT;LCDSADDR2 = ((S3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & 0x1fffff;//Storage End Address
LCD_REGS-&GT;LCDSADDR3 = (240*16/16); /* Length of a line (in 2 bytes) */

S3c_lcd->fix.smem_start/* Physical Address of memory */
/ * Start LCD * /
Lcd_regs->lcdcon1 |= (1<<0); /* Enable LCD Controller */
Lcd_regs->lcdcon5 |= (1<<3); /* Enable the LCD itself */
*gpbdat |= 1; /* Output high level, enable backlight */

/* 4. Register */
Register_framebuffer (S3C_LCD);

return 0;
}

static void Lcd_exit (void)
{
Unregister_framebuffer (S3C_LCD);
Lcd_regs->lcdcon1 &= ~ (1<<0); /* Turn off the LCD itself */
*gpbdat &=; /* Turn off backlight */
Dma_free_writecombine (NULL, S3c_lcd->fix.smem_len, S3c_lcd->screen_base, S3c_lcd->fix.smem_start);
Iounmap (Lcd_regs);
Iounmap (Gpbcon);
Iounmap (Gpccon);
Iounmap (Gpdcon);
Iounmap (Gpgcon);
Framebuffer_release (S3C_LCD);
}

Module_init (Lcd_init);
Module_exit (Lcd_exit);

Module_license ("GPL");

Linux-driven LCD

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.