Linux/Linux_Device_Drivers

Linux input device driver (인풋 디바이스 드라이버)

Roien 2015. 3. 10.
반응형
input driver

    components
        1. input core
        2. input event driver
        3. input device driver
        
    input device driver structure
        +--------------+
        | Event Driver | input event driver
        +--------------+
              ^
              |
              v
         +------------+
         | Input Core | input core
         +------------+
              ^
              |
              v
       +---------------+
       | Device Driver | input device driver
       +---------------+
    
    structure
     - input_event
     - input_dev
     - input_handler
     - psmouse_protocol
     - psmouse
     
     kernel programming interfaces
     - input_register_device     : register a input device to input core
     - input_unregister_device
     - input_report_rel          : create an event (relative move)
     - input_report_abs
     - input_report_key
     - input_sync                : collect events into evdev packet and pass it /dev/input/inputX
     - input_register_handler    : register a special event driver
     - sysfs_create_group        : create a sysfs node group
     - sysfs_remove_group
     - tty_insert_flip_char      : send a character to tty
     - platform_device_register_simple
     - platform_device_unregister

                                       +---------+
                                       | console |
                                       +---------+
                                            ^
                                            |
    ----------------------------------------+-----------
    KERNEL                                  |
                                 +--------------------+
                                 |  virtual terminal  |
                                 +--------------------+
                                             ^
                                             |
          +---------------+        +--------------------+
          | INPUT CORE | ---> | Input Event Driver |
          +---------------+        +--------------------+
                  |
                  v
          +--------------------+
          | INPUT DEV DRV |
          +--------------------+
                ^
                 |
            +--+---+
            |    |     |
          Serio ... SPI.. GPIO

evdev interface
    evdev : general input event driver
    
        /include/linux/input.h
    
        struct input_event {
            struct timeval time;
            __u16 type;         <- event type for an input device (in touch screen case, "EV_SYN | EV_KEY | EV_ABS")
            __u16 code;
            __s32 value;
        };

    1. register
        input_register_device
    
    2. @ INTR. hdlr
        input_event  (throughout such as input_report_key)
        ...
        input_sync --> input_event(dev, EV_SYN, SYN_REPORT, 0) --> input_pass_event --> handler->event
    to see event interface & device info.
    use files under
        - /proc
        - /sys
        ex.
            ls -al /proc/bus/input
            
                ...
                H: Handler=kdb event0       <-- device file node
            
            ls -al /dev/input/-             <-- to see event interface devices
                ..../dev/input/event0
                ...

ex. virtual mouse
    app (coord.c) ------> sysfs (/dev/devices/platform/vms/coordinates) ----> vms.c (virtual mouse driver)
    
    
    To see the kind of an event driver, 
        application have to use ioctl of /dev/input/eventX to check what kind of this event is.
    
    coord.c application                                     console - gpm
       |                                                         ^
       v                                                         |
    /sys/.../vms/coordinates                                /dev/input/eventX
    ------------------------------------------------------------------------------
       |                                                         ^      Kernel
       v                                                         |
    +--------------------------+        +------------+        +-------+
    | vms.c (virtual mouse drv)| <----- | input core | -----> | evdev |
    +--------------------------+        +------------+        +-------+
                                                          drivers/input/evdev.c  
                                                         (@ init, input_register_handler(input_handler evdev_handler))
                                                         into input_table[]
                                                         
                                                         input_inject_event(client->evdev->handle, EV_REP, REP_DELAY, ...)
                                                         input_inject_event(client->evdev->handle, EV_REP, REP_PERIOD, ...)
    ex. vms.c
    
    struct input_dev *vms_input_dev;
    struct platform_device *vms_dev;
    
    
    ssize_t
    write_vmx(...)
    {
        sscanf(buffer, "%d%d", &x, &y);
        input_report_rel(vms_input_dev, REL_X, x);  --> input_event --> input_handle_event
        ...
        input_sync();  --> input_pass_event (have multiple event be one set <- used by /dev/input/eventX)
                           : use evdev input_handler (already input_indect_event was called at evdev.c)
                           evdev_event @ evdev.c (pass incoming event to all connected clients)
    }
    DEVICE_ATTR(coordinates, 0644, NULL, write_vms);
    
    @ init
        vms_dev = platform_device_register_simple("vms", -1, NULL, 0);
        
        sysfs_create_group(&vms_dev->dev.kobj, &vms_attr_group);
        ...
        vms_input_dev = input_allocate_device();
        set_bit(EV_REL, vms_input_dev->evbit);
        
        input_register_device(vms_input_dev);       <-- create input_handler
        
    @ cleanup
        input_unregister_device(vms_input_dev);
        
        sysfs_remove_group(&vms_dev->dev.kobj, &vms_attr_group);
        platform_device_unregister(vms_dev);

verificaton program
    use this program to verify an input device driver, before using it by any application, 
    
    int main(..)
    {
        struct input_event event_buf[EVENT_BUF_NUM];  // 64        
        char *str_device = "/dev/input/event0"; // or event1
        
        int evt_fd = open(str_device, O_RDONLY);        
        read_byte = read(evt_fd, event_buf, sizeof(struct input_event)*EVENT_BUF_NUM);
        
        for EVENT_BUF_NUM
            check
                print event_buf[i].type/value/code
    }
    
    when pressing key, touch or some other input devices,
        then, type/value/code are shown
        (refer 138p)


Touch ex.
    @ touch driver handler
    
    input_event --> input_handle_event --> dev->event or input_pass_event
evdev event interface를 사용하지 않고 
전용 event driver로 처리되는 키보드, mouse등은, input_register_handler로 input_handler를 등록해야 함.
    static struct input_handler my_evt_hdr = {
        .event = evt_hdr,
        .name = "mydrv",
        ...
    };
    
    @ init
        input_register_handler(&my_evt_hdr);
        ...


evbug module
    /drivers/input/evbug.c
    
    dump input event set (struct input_event)


keyword.c
    keyboard event driver (drivers/char/keyboard.c)
    
    character driver..
    because
        linked to virtual terminal


반응형

댓글