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);
Previous article:Module cannot be rmmod after insmod
Next article:Kernel transplantation and file system production (4): Summary of UBIFS root file system production
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- [Review of Arteli Development Board AT32F421] 2. Read the MCU model
- TE official WeChat manual customer service function is now online. You can communicate directly with TE technical experts via WeChat!
- What do you need to prepare for TI's hands-on wireless training session on June 4?
- STM32 may crash, and it will work normally after rewriting the program
- CH549EVT development board test - driving LCD5110 display
- EEWORLD University ---- Live playback: The most important component of the analog world - Signal chain and power supply: Interface special
- EEWORLD University Hall----Live Replay: ADI Digital Active Noise Cancelling Headphone Solution
- If the number of 1 bits in the accumulator is odd, P is set (odd parity); otherwise, P is cleared.
- [Flower carving hands-on] Interesting and fun music visualization project (09) - X Music Spectrum
- Fudan Micro FM33LC046N Review Summary