Skip to content

Device driver

Zubeen Tolani edited this page Aug 23, 2016 · 4 revisions

Why device driver ?

If you have read the "Why platform driver" section in the "Platform driver" page, with similar reasoning, its impractical for the developer of the core bus driver to accommodate limitations and features of all the device present in the market in one single driver. As a result, we need to have different drivers for different devices on the bus. These drivers are called device drivers.

How does it fit in the software stack ?

While the core bus driver is designed, a well documented API interface for the device driver is also designed. The developer implementing the device driver uses this documentation to take benefit of all the APIs. Its the job of the developer to deploy all the features of the hardware using the available APIs and ask the concerned maintainer if he needs more features in the core bus driver.

Okay, I got it. So how to implement a device driver ?

NOTE : As the GSoC time period ends, not all the APIs of the parallel interface has been designed. Only a few of them, that are used for driver registration have been designed. This section just describes those APIs. The project will still be under development and newer APIs will be added.

The parallel interface is being developed like a bus. As a result, developing device driver will be simple enough. For now the driver just needs to register itself to the bus core driver.

For the device driver to work, the driver:

  1. Include the header file parallel_interface.h.
  2. Must register itself to the core bus driver using the API pi_register_driver() and the struct pi_driver and struct pi_device_id.
  3. Should at least provide with a member for probe, remove, id_table and driver member fields of the struct pi_driver while registering to the core bus driver.
  4. Should use the API pi_unregister_driver() in its __exit method to unregister the driver.
  5. If the device driver does nothing more than registering and unregistering in its __inti and __exit method, it can simply use the module_pi_driver() API. There will be no need to use the __init and __exit functions if this API is used.

Relate it to the project now :

As already stated, the device driver will be very simple and only registration APIs have been developed by now. To test these APIs, some simple modification in the older beaglescop_driver were made. Looking at the source file, you will find that it in-fact does all the required things mentioned in the previous section.

From the source file :

  1. Include the parallel_interface.c header file.

    #include "parallel_interface.h"

  2. Declares an object of type struct pi_device_id.

     static const struct pi_device_id dc782a_id[] = {
         {"dc782a", 0},
         {}
     };
     MODULE_DEVICE_TABLE(pi, dc782a_id);
    
  3. Defines functions the probe and remove fields of the struct pi_driver.

     static int dc782a_probe (struct pi_device *dev)
     {
          log_debug("dc782a_probe");
          return 0;
     }
     
     static void dc782a_remove (struct pi_device *dev)
     {
          log_debug("dc782a_probe");
     }
    
  4. Defines an object of type struct pi_driver.

     static struct pi_driver dc782a_driver= {
      .driver = {
              .name = KBUILD_MODNAME,
              .owner = THIS_MODULE,
          },
          .id_table	= dc782a_id,
          .probe	= dc782a_probe,
          .remove	= dc782a_remove,
     };
    
  5. Uses the module_pi_driver() API to register the driver.

     module_pi_driver(dc782a_driver);
    
Clone this wiki locally