PWM. c is the driver for PWM device. This is the driver of PWM. This driver is a basic operation function for various devices that require PWM. During system initialization, all the PWM device drivers will be registered. Of course, this driver code has only one copy, according to devices. the driver is called multiple times for different IDs of device struct in C, which is the same as the method for registering I2C. No ID-table is used. It is estimated that the author and I like this direct method.
There are several PWM operations and export_symbol is used for export. All other drivers can be called directly. The reason for export is that the PWM driver serves other drivers. It is a basic driver.
Pwm_request: Use pwm_id to obtain a PWM. This function calls list_for_each_entry to traverse all PWM devices and match the devices by ID. If the devices are found, a pointer is used to bring back the device pointer, the counter use_count is referenced by the device to ensure that the PWM device is referenced only once!
Pwm_config: Set the duty cycle. This function directly operates the registers of the corresponding PWM device.
Pwm_enable: enables PWM devices. The corresponding enable bit of the PWM device will also be written.
Pwm_disable: Disable PWM devices. It will also write the corresponding blocked bit of the PWM device.
Pwm_free: the so-called free is to make the device reference counter minus 1, only that. It is only applicable to PWM devices. Since it can be referenced at most 1, free is actually used to make usr_count = 0
Xxx_pwm_bl.c
This is a Backlight Drive.
We can see a platform_device type backlight instantiated in devices. C, and its private members are directed to a pointer of the platform_pwm_backlight_data type. This type specifies the pwm id and various attributes of the backlight.
In the probe function, we can see that the driver calls pwm_request to obtain a PWM device.
Initialize and register a backlight_device device. When registering a backlight device, the backlight_device_register function is called. The first parameter of this function is the device name. I have been wondering why the name here is not provided directly, instead, the dev_name (& pdev-> Dev) function is used to obtain the device name. After tracking the function for obtaining the name, the device name is obtained, this is because the backlight driver may be called multiple times to generate multiple devices. Therefore, it is appropriate to use this function to obtain the name of the specific device currently called. Otherwise, you may need other methods to piece together a name, for example, the fprintf function I used in the I2C driver is really a little lame. I will also use this method later!
In fact, the specific device name is established in the platform_device_add function. when instantiating a device in C, a device ID and device name are provided. In the function added to this device, we can see a judgment based on this ID: if the id you gave is-1, you will tell the Add function that my device is unique in the system, then, the Add function uses the name you gave to name the device directly. If the id you give is not-1, you are telling the Add function that there may be multiple devices, but this is only one of them. The add function uses the name you gave to the device and the id you gave to the device to name the added device. For example: you gave
. Name = "ABCDE" The. ID = 3 you gave. The final name is abcde.3. Therefore, you can give a meaningful id value when instantiating the device as needed.
In backlight_device_register, we will also see another important parameter: The pwm_backlight_ops struct is implemented by the current backlight driver. It has two important members, both of which are function pointers: update_staus is used to change the brightness of the current backlight. get_brightness is used to obtain the current brightness value. The implementation of these two functions relies on PWM drives. So in their implementation, we can see that the corresponding PWM-driven enable, disable, and config functions are called.
Continue this backlight_device_register! This function is implemented in the Blacklight. C of the kernel. This is a file in the Linux Kernel framework. Its main function is to provide a unified interface to external users, shielding the underlying implementation of the driver. This is very similar to the I2C driver! Similar to the functions implemented by i2c_core.c! It is also very similar to the SPI driver we have previously done! Similar to SPI. C. This file implements the show and store functions, so we can directly use the echo and CAT commands in the terminal to change the backlight brightness!
In fact, the so-called duty cycle adjustment is not as appropriate as the empty proportion, which may have the same relationship with "meat" and "meat. Just get used to it.
The PWM output pin is high when disable. There are two parameters for setting a PWM duty cycle, one is duty and the other is period. The Unit is ns ). Duty refers to the low-level duration in a cycle, and period refers to the period. Of course, duty must be smaller than or equal to period. For the duration of high and low levels, we can set only duty. That is, we can only set the low-level duration. When the duty we set increases gradually, the proportion of the low level increases gradually, and the proportion of the high level decreases accordingly, that is, the larger the value we give, the more "null, the fewer accounts, the more suitable it is .. Haha