A practical link of platform bus for Linux device driver Model (IV.)

Source: Internet
Author: User

A pointer to the S5pv210_led_pladata type is obtained by a pointer of type Led_classdev, which is the part of the device data that we define ourselves as the S5pv210_led_pladata type struct. Static inline struct s5pv210_gpio_led *to_gpio (Struct led_classdev *led_cdev) { Return container_of (Led_cdev, struct s5pv210_gpio_led, cdev);} #define &NBSP;X210_LED_OFF&NBSP;1#DEFINE&NBSP;X210_LED_ON&NBSP;0//get S5pv210_gpio_ from Platform_device's pointer LED Pointer Static inline struct s5pv210_gpio_led *pdev_to_gpio (struct platform_device  *dev) {return platform_get_drvdata (dev);} Defines a large structural body framework that contains the structure of the data portion of the Led_classdev and the device struct s5pv210_gpio_led {struct led_classdev cdev; struct s5pv210_led_platdata*pdata;};/ /In order for the driver of this operation led to be generic, the function can be s5pv210_gpio_led by a pointer of the parameter Struct led_classdev type//To know through this pointer s5pv210_led_ Platdata This member, this type of member is the data part of the device that we define ourselves. Static void whyx210_led_set (struct led_classdev *led_cdev, enum led_brightness  value) {&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (kern_info  "whYx210_led_set\n ");          struct s5pv210_gpio_led *p  = to_gpio (led_cdev)     //s5pv210_gpio_led pointer back from Led_classdev pointer           if  (value == led_off)  { //user input 0 o'clock kill          the user input is echo 0 > brightness              //writel (Readl (Gpj0dat)  |  (1 <<  3),  gpj0dat);         gpio_set_value (P->pdata->gpio,  x210_led_off)     //through the s5pv210_gpio_led pdata to know what the Gpio number is, pdata is the device data section, we write                                               &nbSp;                //platform_ Device is already populated with good              }else if  ( Value == led_full) {   //user input 255 light       corresponding user input is echo 255  > brightness                       //writel (Readl (Gpj0dat)  & ~ (1 <<  3),  gpj0dat);  //This operation keeps the other bit values constant         gpio_set_value (P- &GT;PDATA-&GT;GPIO,&NBSP;X210_LED_ON);     }}static int why_led_probe (struct  platform_device *dev) {    int ret = -1;     struct s5pv210_led_platdata *pdata = dev->platform_data;    // Get the data part of the match on the device     struct s5pv210_gpio_led *led; //the previous chapter of the blog that brightness bound functions can not be written to death, so using this design logic, this structure contains the Led_ Classdev Structural Body                                       //also contains the structure of the data portion of the device we define &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;LED&NBSP;=&NBSP;KZALLOC ( sizeof (struct s3c24xx_gpio_led),  gfp_kernel);    if  (Led == NULL)  {            dev_err (&dev->dev,  "no memory for device\n");     return -enomem;}     platform_set_drvdata (dev, led);//This function is to have led this contains led_ A pointer to a struct variable in the Classdev and Device data section gives a pointer to the data part of its driver                                      //, is the LED structure by the driver can point to any type of pointer pointing , the LED is passed to the driver that represents the part of the device data.         //fill the structure of the Struct led_classdev type we want to register      //myled.name = pdata->name; //the name of the LED device on the current match     //myled.brightness  = 255;    //myled.brightness_set = whyx210_led1_set;// This myled Brightness_set method binding can not actually be fixed whyx210_led1_set this method, because we                                                    //driver and equipment matching is not fixed is led1, it is possible to led2 equipment and this driver matching on the total can not led2                                                    //How to use the Led1 method           // Because the LEDs contain Led_classdev, the above code changes as follows, using this method to populate the LEDs with the data of the device, and because the LEDs are already in the Drvier member's Pointer      / /point, so it is equal to fill the data for driver.      led->cdev.name = pdata->name;    // The member Cdev in the LED is the top myled     led->cdev.brightness = 255;   .   led->cdev.brightness_set = whyx210_led_set;    //This set function cannot be written to death, According to the actual device hardware data changes come and go to operate the LED light off. So                                                        //This function from the new, the name changed to Why210_led_set, with a frame larger idea to operate the LED, through real-time access to set                                                           //hardware data to operate the LED, so that the operation of the LED driver method has a general , you only need to change the set                                                            //data, you can achieve control of different LEDs.          //to call the LED registration function provided in the LED driver frame led_classdev_register to register the driver     //in LED-CLASS.C int led_classdev_register (struct device *pArent, struct led_classdev *led_cdev)         ret =  led_classdev_register (&dev->dev, &led->cdev);         led->pdata = pdata;    //will get the data part from the device and populate the Pdata member in this led structure, LED because the front has been pointed by the pointer in the driver member, so is equal to                             //data transfer to drive           if  (ret < 0)  {      &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (KERN_ERR  "led_classdev_ register errro\n ");        return ret;     }         return 0;} Static int why_led_remove (struct platform_device *dev) {struct s5pv210_gpio_led *led = pdev_to_gpio (dev);     //from Platform The pointer of the _device type is reversed to get s5pv210_gpio_led pointer Led_classdev_unregister (&AMP;LED-&GT;CDEV);     // Unregister this device kfree (LED); return 0;} static struct platform_driver why_led_driver = {    .probe       = why_led_probe,    .remove      = why_led_remove,    .driver     = {         .name       =  "Why_led",         .owner      = THIS_MODULE,     },};static int __init whyx210_led_init (void) {    return  platform_driver_register (&why_led_driver);}   static void __init whyx210_Led_exit (void) {    platform_driver_unregister (&why_led_driver);}     module_init (Whyx210_led_init); Module_exit (whyx210_led_exit);  MODULE_AUTHOR ("Why  <[email protected]> "); Module_description ("Whyx210 led driver"); Module_license ("GPL"); Module_alias ("whyx210_led"

After the implementation of the general driver code, make compile, load into the system, the device and the driver can be matched, the kernel code written a few led devices, then the driver will match on several led devices, echo 0 or 1 to/sys/class/leds/ledx/ The brightness file can also control the LED's light-out, proving that the drive is working.


To use the LED device file in the LEDs directory in the class directory, you need to use the Led_classdev_register function to register the LED device and the drive data structure body.

To get the data part of the device in real-time to the driver, and to give the operation method of driving operation led to be general, it is necessary to use the s5pv210_gpio_led structure to create the framework of the above implementation.


This code is done by imitation of the/DRIVER/LEDS/LEDS-S3C24XX.C code in the Samsung kernel, almost the same.

There are some details in the code, no processing, only for the frame of thought on the record, so that their understanding of the platform bus can be more in-depth.

This article from "Whylinux" blog, declined reprint!

A practical link of platform bus for Linux device driver Model (IV.)

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.