Starting from Linux 2.6, a new set of driver management and registration mechanisms have been introduced: platform_device and piatform_driver. (platform represents platform); the device is represented by platform_device, and the driver is registered with piatform_driver.
Compared with the traditional devicedriver mechanism (registered through the driver_register function), a very obvious advantage of the Linux platform driver mechanism is that the platform mechanism registers the resources of the device itself into the kernel, which is managed uniformly by the kernel. When these resources are used in the driver, they are provided through platform device. Apply and use the standard interface. This improves the independence of driver and resource management, and has better portability and security (these standard interfaces are safe).
The use of the Platform mechanism itself is not complicated and consists of two parts: platform_device and platformfrom_driver.
The general process of developing the underlying driver through the Platform mechanism is: define resoucre->define platform_device->define platform_driver->register platform_driver.
There is already a very complete LCD driver in the kernel. We only need to make simple modifications according to the LCD used. The first thing to confirm is the device's resource information, such as the device's address, interrupt number, etc.
In the 2.6 kernel, the platform device is described by the structure platform_device, which is defined in
kernelincludelinuxplatform_device.h
middle.
Struct platform_device{
const char *name; u32 id;
struct device dev; u32 num_resources;
struct resource *resource;
};
An important element of this structure is resource, which stores the most important device resource information and is defined in
kernelincludelinuxioport.h中。 struct resource{
resource_size_tstart; //Describes the linear starting physical address of the device entity on the cpu bus;
resource_size_tend; // Describes the linear ending physical address of the device entity on the cpu bus;
const char *name; // Describes the name of this device entity. Developers can choose this name at will;
unsigned long flags; //Flag bits that describe some commonalities and characteristics of this device entity; (marked as LCD controller IO port, refer to this in the driver.
Reference IO port)
struct resource *parent, *sibling, *child;// pointers parent, sibling and child: respectively
Pointers to parent, sibling, and child resources.
};
For example:
1. Modify the linux-2.6.32.2archarmpalt-s3c24xxdevs.c file: add the resources occupied by the platform device LCD. Open devs.c
/* LCD Controller */
static struct resource s3c_lcd_resource[ ] = {
[0] = { .start = S3C24XX_PA_LCD, //(Controller IO port start address)
.end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1, // (controller IO port end address)
.flags = IORESOURCE_MEM, //(marked as LCD controller IO port, reference this in the driver
It means referencing the IO port)
}, [1] = { .start = IRQ_LCD, .end = IRQ_LCD, .flags = IORESOURCE_IRQ, } };
With resource information, platform_device can be defined:
2. Modify the linux-2.6.32.2archarmplat-s3c24xxdevs.c file: add the platform device s3c_devce_lcd. As shown below, if it already exists, there is no need to add it.
static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
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 = &s3c_device_lcd_dmamask, .coherent_dma_mask = 0xffffffffUL } };
Here is some information for defining your own device. After defining the platform_device structure, you can call the function platform_add_devices to add the device to the system, and then call platform_device_register() to register the device. When the registration is successful, the platform_driver structure element probe function pointer will be called, here
It is s3c24xx_i2c_probe. After entering the probe function, you need to obtain the resource information of the device. The commonly used functions for obtaining resources are mainly:
struct resource *platform_get_resource ( struct platform_device *dev, unsigned int type, unsigned int num);
Obtain the specified resource according to the type specified by the parameter type, such as IORESOURCE_MEM.
struct int platform_get_irq (struct platform_device *dev,unsigned int num);//Get the interrupt number in the resource. (You don’t need to read it here) Export the defined LCD platform device and add it to the platform device list in smdk2440_devices[] of mach-smdk2440.c.
EXPORT_SYMBOL(s3c_device_lcd);
(Linux also defines a s3c2410fb_mach_info structure for the LCD platform device in /arch/arm/mach-s3c2410/include/mach/fb.h). This structure mainly records the hardware parameter information of the LCD (such as the The s3c2410fb_display member structure is used to record the LCD screen size, screen information, variable screen parameters, LCD configuration registers, etc.), so that this structure can be used directly when writing the driver. Next, let's take a look at how the kernel uses this structure. In /arch/arm/mach-s3c2440/mach-smdk2440.c (Look at the file you define here. Mine is mach-mini2440.c. I will use mini2440 from now on);
3. Modify archarmmach-s3c2440mach-smdk2440.c: configure the s3c2440_devices platform device data and register the s3c2440_devices platform device.
static struct platform_device *mini2440_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, (this structure has been defined in the previous step 2) &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, &s3c_device_nand, &mini2440_device_eth,
};
4. Modify archarmmach-s3c2440mach-mini2440.c: configure mini2440_devices_lcd platform device data. /* LCD driver info */
static struct s3c2410fb_display mini2440_lcd_cfg __initdata = { #if !defined (LCD_CON5) .lcdcon5 = S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_PWREN | S3C2410_LCDCON5_HWSWP, #else .lcdcon5 = LCD_CON5, #endif .type = S3C2410_LCDCON1_TFT, .width = LCD_WIDTH, .height = LCD_HEIGHT, .pixclock =LCD_PIXCLOCK, /* HCLK 60 MHz, divisor 10 */ .xres = LCD_WIDTH, .yres =LCD_HEIGHT, .bpp = 16, .left_margin = LCD_LEFT_MARGIN +1, .right_margin =LCD_RIGHT_MARGIN +1, .hsync_len = LCD_HSYNC_LEN+1, .upper_margin = LCD_UPPER_MARGIN+1, .lower_margin = LCD_LOWER_MARGIN+1, .vsync_len =LCD_VSYNC_LEN+1 , };
5. Modify mach-mini2440.c to add X35 screen support. (This part should be placed before step 4) #define LCD_WIDTH 240 //Screen width #define LCD_HEIGHT 320 //Screen height
#define LCD_PIXCLOCK 170000 //clock #define LCD_RIGHT_MARGIN 25 //left margin
#define LCD_LEFT_MARGIN 0 //Right border #define LCD_HSYNC_LEN 4 //Line synchronization #define LCD_UPPER_MARGIN 0 //Upper border #define LCD_LOWER_MARGIN 4 //Lower border #define LCD_VSYNC_LEN 9 //Frame synchronization
#define LCD_CON5 (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_INVVDEN | S3C2410_LCDCON5_PWREN | S3C2410_LCDCON5_BSWP )
6. Modify archarmmach-s3c2440mach-mini2440.c: configure s3c2440_devices platform device data, register s3c2440_devices platform device, and add LCD backlight
(Because the backlight of the 3.5-inch LCD display of mini2440 is controlled by the GPG4 pin of s3c2440,) static struct s3c2410fb_mach_info mini2440_fb_info __initdata ={ .displays = &mini2440_lcd_cfg,// (mini2440_lcd_cfg has been set in step 5) .num_displays = 1 , .default_display = 0, // (Note: default is not implemented) .gpccon= 0xaa955699, .gpccon_mask= 0xffc003cc, .gpcup= 0x0000ffff, .gpcup_mask= 0xffffffff, .gpdcon= 0xaa95aaa1, .gpdcon_mask= 0xffc0fff0, .gpdup= 0x0000faff, .gpdup_mask= 0xffffffff, .lpcsel =0xf82, };
static void __init mini2440_machine_init(void) {
s3c24xx_fb_set_platdata(&mini2440_fb_info); (Set s3c2440_devices platform device data)
s3c_i2c0_set_platdata(NULL);
s3c2410_gpio_cfgpin(S3C2410_GPG(4),S3C2410_GPIO_OUTPUT); (Configure lcd pin) (To add #include s3c2410_gpio_setpin(S3C2410_GPG(4),1); s3c_device_nand.dev.platform_data = &mini2440_nand_info; //s3c_device_sdi.dev.platform_data=&s3c2410_mmc_cfg; platform_add_devices (mini2440_devices, ARRAY_SIZE(mini2440_devices)); (Register the LCD platform device to the kernel) //s3c_pm_init(); //mini2440_machine_init();(These unused ones can be blocked) } 7. Modify the linux-2.6.32.2/drivers/video/Kconfig file. config FB_S3C2410_X240320 boolean"3.5 inch 240X320 SONY LCD (X35-ACX502BMU) " depends on FB_S3C2410 help 3.5 inch 240X320 SONY LCD (X35-ACX502BMU) 8.make menuconfig Device Driver: <*>support for frame buffer devices - [* ] Enable frameware EDID [* ] Enable Vidoe Mode Handling Helpers <*>S3C24X0 LCD framebuffer support Console display driver support -- <*> Framebuffer Console Support [* ] Bootup Logo -- <*> Standard 224-color Linux logo After finally starting the kernel, you can see the penguin.
Previous article:s3c2440 external interrupt
Next article:2440 serial port linux programming, related configuration of S3C2440 serial port communication
- Popular Resources
- Popular amplifiers
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
- Ranking of installed capacity of smart driving suppliers from January to September 2024: Rise of independent manufacturers and strong growth of LiDAR market
- Industry first! Xiaopeng announces P7 car chip crowdfunding is completed: upgraded to Snapdragon 8295, fluency doubled
- P22-009_Butterfly E3106 Cord Board Solution
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- It’s too difficult for beginners.
- Help converting brd file to AD pcbdoc file
- Fuman Electronics responded to a real-name report and said it had no direct supply relationship
- MSP430 interrupt priority and interrupt nesting
- A novice asks about the selection of optocouplers for PWM isolation control of MOS tubes
- Signal Generator and DA Conversion FPGA Case Tutorial
- [Amway] Excellent electronic engineers must read classic books Amway
- IAR Mini Classroom | How to place a group of functions or variables in a specific segment
- Are there any FPGA weekend training courses in Xi'an?
- LM25119 has no output