FL2440 driver addition (3) LCD driver addition study notes

Publisher:心灵之舞Latest update time:2024-07-24 Source: elecfansKeywords:FL2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

FL2440 LCD built-in controller, 320*240 TFT LCD.


Two add-drive modes summarized by self-understanding:

Adding drivers in non-platform mode:


Load the driver:

1. Hardware initialization, memory application, and address mapping

2. Allocate device number and structure

3. Register the device

Uninstall the driver:

1. Release memory

2. Release the structure and return the device number

3. Unregister the device

Add driver by platform bus mode (mainstream mode):

1. Write a device chain


struct platform_device

{

const chat *name;

u32 id;

struct device dev;

u32 num_resources;

struct resources * resources;

};


2. Write the drive chain


static struct platform_driver

{

int (*probe)( struct platform_device*), //detection function

int (*remove)( structplatform_device*), //delete function

……

struct device_driver driver;

};


3. Register the device in the device chain and register the driver in the driver chain


int __init xxx_init()

{

.....

platform_device_register();

platform_driver_register();

.....

}


4. Reversely, cancel the driver in the driver chain and cancel the device in the device chain


void __exit  xxx_exit()

{

.....

platform_driver_unregister();

platform_device_unregister();

.....

}



Start adding LCD driver: kernel version linux-3.8.0


1. Modify the relevant information platform data in arch/arm/mach-s3c24xx/mach-smdk2440.c

/* LCD driver info */

static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {

.lcdcon5   = S3C2410_LCDCON5_FRM565|

S3C2410_LCDCON5_INVVLINE |

S3C2410_LCDCON5_INVVFRAME |

S3C2410_LCDCON5_PWREN |

S3C2410_LCDCON5_HWSWP,

.type      = S3C2410_LCDCON1_TFT,

.width     = 320,

.height    = 240,

.pixclock  = 111111, /* HCLK 60 MHz, divisor 10 */

.xres = 480,

.yres = 272,

.bpp       = 16,

.left_margin    = 38,

.right_margin   = 20,

.hsync_len = 30,

.upper_margin   = 15,

.lower_margin   = 12,

.vsync_len = 3,

};

static struct s3c2410fb_mach_info smdk2440_fb_info  __initdata = {

.displays  = &smdk2440_lcd_cfg,

.num_displays   = 1,

.default_display = 0,

#if 0
/* currently setup by downloader */
.gpccon     = 0xaa940659,
.gpccon_mask    = 0xffffffff,
.gpcup      = 0x0000ffff,
.gpcup_mask = 0xffffffff,
.gpdcon     = 0xaa84aaa0,
.gpdcon_mask    = 0xffffffff,
.gpdup      = 0x0000faff,
.gpdup_mask = 0xffffffff,
#endif

.lpcsel    = ((0xCE6) & ~7) | 1<<1,

};



2. Since the LCD device and platform addition functions have been defined in arch/arm/plat-samsung/devs.c, as follows

/* LCD Controller */

#ifdef CONFIG_PLAT_S3C24XX

static struct resource s3c_lcd_resource[]= {

[0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),

[1] = DEFINE_RES_IRQ(IRQ_LCD),

};

struct platform_device s3c_device_lcd= {

.name      = "s3c2410-lcd",

.id    = -1,

.num_resources  = ARRAY_SIZE(s3c_lcd_resource),

.resource  = s3c_lcd_resource,

.dev       = {

.dma_mask       = &samsung_device_dma_mask,

.coherent_dma_mask  = DMA_BIT_MASK(32),

}

};


//Platform add function

void __init s3c24xx_fb_set_platdata(structs3c2410fb_mach_info *pd)

{

struct s3c2410fb_mach_info *npd;

npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);

if (npd) {

npd->displays =kmemdup(pd->displays,

sizeof(struct s3c2410fb_display) * npd->num_displays,

GFP_KERNEL);

if (!npd->displays)

printk(KERN_ERR "no memory forLCD display data");

} else {

printk(KERN_ERR "no memory for LCDplatform datan");

}

}

#endif /*CONFIG_PLAT_S3C24XX */

So in arch/arm/mach-s3c24xx/mach-smdk2440.c just register the device:

static struct platform_device *smdk2440_devices[] __initdata = {

&s3c_device_ohci,

&s3c_device_lcd,

&s3c_device_wdt,

&s3c_device_i2c0,

&s3c_device_iis,

&s3c_device_dm9000,

&s3c_device_adc,

&s3c_device_ts,

&s3c_device_rtc,

&globalfifo_device

};

Add to the device chain by calling smdk2440_machine_init,

static void __init smdk2440_machine_init(void)

{

// Call this function to save the LCD hardware information defined above into the platform data

s3c24xx_fb_set_platdata(&smdk2440_fb_info);

s3c_i2c0_set_platdata(NULL);

platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));

smdk_machine_init();

}

Tracing the platform_add_devices function, it actually calls the platform_device_register and platform_device_unregister functions, as follows:

Defined in drivers/base/platform.c:

int platform_add_devices(struct platform_device **devs, int num)
{
int i, ret = 0;

for (i = 0; i < num; i++) {
ret = platform_device_register(devs[i]);
if (ret) {
while (--i >= 0)
platform_device_unregister(devs[i]);
break;
}
}

return ret;
}
EXPORT_SYMBOL_GPL(platform_add_devices);


Keywords:FL2440 Reference address:FL2440 driver addition (3) LCD driver addition study notes

Previous article:Module cannot be rmmod after insmod
Next article:Kernel transplantation and file system production (4): Summary of UBIFS root file system production

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号