• Implementing Your Own Driver (Driver Template)
  • Keymaps and Keyboard Input
  • Selection of a Key Layout Map
  • Example of a Key Layout Map File
  • Selection of a Key Character Map
  • Example of a Key Character Map File
  • Resource Binary File Format
  • Display Drivers In this document




    Download 1,28 Mb.
    bet6/95
    Sana22.12.2019
    Hajmi1,28 Mb.
    #4580
    1   2   3   4   5   6   7   8   9   ...   95

    Display Drivers

    In this document


    • Functionality

    • Implementing Your Own Driver (Driver Template)

    • Troubleshooting

    This section describes how the display driver functions and offers a functional template designed to help you build your own device-specific driver.

    Android relies on the standard frame buffer device (/dev/fb0 or /dev/graphics/fb0) and driver as described in the linux/fb.h kernel header file. For more information regarding the standard Linux frame buffer, please see The Frame Buffer Device at http://kernel.org.


    Functionality


    In Android, every window gets implemented with an underlying Surface object, an object that gets placed on the framebuffer by SurfaceFlinger, the system-wide screen composer. Each Surface is double-buffered. The back buffer is where drawing takes place and the front buffer is used for composition.

    When unlockCanvas() is called, the back buffer is posted, which means that it gets displayed and  becomes available again. Android flips the front and back buffers, ensuring a minimal amount of buffer copying and that there is always a buffer for SurfaceFlinger to use for composition (which ensures that the screen never flickers or shows artifacts).

    Android makes two requirements of the driver: a linear address space of mappable memory that it can write to directly and support for the rgb_565 pixel format. A typical frame display includes:


    • accessing the driver by calling open on /dev/fb0

    • using the FBIOGET_FSCREENINFO and FBIOGET_VSCREENINFO Input / Output Control (ioctl) calls to retrieve information about the screen

    • using FBIOPUT_VSCREENINFO ioctl to attempt to create a virtual display twice the size of the physical screen and to set the pixel format to rgb_565. If this succeeds, double buffering is accomplished with video memory.

    When a page flip is required, Android makes another FBIOPUT_VSCREENINFO ioctl call with a new y-offset pointing to the other buffer in video memory. This ioctl, in turn, invokes the driver's .fb_pan_display function in order to do the actual flip. If there isn't sufficient video memory, regular memory is used and is just copied into the video memory when it is time do the flip. After allocating the video memory and setting the pixel format, Android uses mmap() to map the memory into the process's address space. All writes to the frame buffer are done through this mmaped memory.

    To maintain adequate performance, framebuffer memory should be cacheable. If you use write-back, flush the cache before the frame buffer is written from DMA to the LCD. If that isn't possible, you may use write-through. As a last resort, you can also use uncached memory with the write-bugger enabled, but performance will suffer.


    Implementing Your Own Driver (Driver Template)


    The following sample driver offers a functional example to help you build your own display driver. Modify PGUIDE_FB... macros as desired to match the requirements of your own device hardware.

    /*

    * pguidefb.c



    *

    * Copyright 2007, Google Inc.

    *

    * This program is free software; you can redistribute it and/or modify



    * it under the terms of the GNU General Public License version 2 as

    * published by the Free Software Foundation.

    */

    /*

    * ANDROID PORTING GUIDE: FRAME BUFFER DRIVER TEMPLATE



    *

    * This template is designed to provide the minimum frame buffer

    * functionality necessary for Android to display properly on a new

    * device. The PGUIDE_FB macros are meant as pointers indicating

    * where to implement the hardware specific code necessary for the new

    * device. The existence of the macros is not meant to trivialize the

    * work required, just as an indication of where the work needs to be

    * done.


    */
    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    /* Android currently only uses rgb565 in the hardware framebuffer */

    #define ANDROID_BYTES_PER_PIXEL 2


    /* Android will use double buffer in video if there is enough */

    #define ANDROID_NUMBER_OF_BUFFERS 2


    /* Modify these macros to suit the hardware */
    #define PGUIDE_FB_ROTATE

    /* Do what is necessary to cause the rotation */


    #define PGUIDE_FB_PAN

    /* Do what is necessary to cause the panning */


    #define PGUIDE_FB_PROBE_FIRST

    /* Do any early hardware initialization */


    #define PGUIDE_FB_PROBE_SECOND

    /* Do any later hardware initialization */


    #define PGUIDE_FB_WIDTH 320

    /* Return the width of the screen */


    #define PGUIDE_FB_HEIGHT 240

    /* Return the heighth of the screen */


    #define PGUIDE_FB_SCREEN_BASE 0

    /* Return the virtual address of the start of fb memory */


    #define PGUIDE_FB_SMEM_START PGUIDE_FB_SCREEN_BASE

    /* Return the physical address of the start of fb memory */


    #define PGUIDE_FB_REMOVE

    /* Do any hardware shutdown */


    struct pguide_fb {

    int rotation;

    struct fb_info fb;

    u32 cmap[16];

    };
    static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)

    {

    unsigned int mask = (1 << bf->length) - 1;


    return (val >> (16 - bf->length) & mask) << bf->offset;

    }

    /* set the software color map. Probably doesn't need modifying. */



    static int

    pguide_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,

    unsigned int blue, unsigned int transp, struct fb_info *info)

    {

    struct pguide_fb *fb = container_of(info, struct pguide_fb, fb);


    if (regno < 16) {

    fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |

    convert_bitfield(blue, &fb->fb.var.blue) |

    convert_bitfield(green, &fb->fb.var.green) |

    convert_bitfield(red, &fb->fb.var.red);

    return 0;

    }

    else {


    return 1;

    }

    }


    /* check var to see if supported by this device. Probably doesn't

    * need modifying.

    */

    static int pguide_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)



    {

    if((var->rotate & 1) != (info->var.rotate & 1)) {

    if((var->xres != info->var.yres) ||

    (var->yres != info->var.xres) ||

    (var->xres_virtual != info->var.yres) ||

    (var->yres_virtual >

    info->var.xres * ANDROID_NUMBER_OF_BUFFERS) ||

    (var->yres_virtual < info->var.xres )) {

    return -EINVAL;

    }

    }



    else {

    if((var->xres != info->var.xres) ||

    (var->yres != info->var.yres) ||

    (var->xres_virtual != info->var.xres) ||

    (var->yres_virtual >

    info->var.yres * ANDROID_NUMBER_OF_BUFFERS) ||

    (var->yres_virtual < info->var.yres )) {

    return -EINVAL;

    }

    }

    if((var->xoffset != info->var.xoffset) ||



    (var->bits_per_pixel != info->var.bits_per_pixel) ||

    (var->grayscale != info->var.grayscale)) {

    return -EINVAL;

    }

    return 0;



    }

    /* Handles screen rotation if device supports it. */

    static int pguide_fb_set_par(struct fb_info *info)

    {

    struct pguide_fb *fb = container_of(info, struct pguide_fb, fb);



    if(fb->rotation != fb->fb.var.rotate) {

    info->fix.line_length =

    info->var.xres * ANDROID_BYTES_PER_PIXEL;

    fb->rotation = fb->fb.var.rotate;

    PGUIDE_FB_ROTATE;

    }

    return 0;



    }

    /* Pan the display if device supports it. */

    static int pguide_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)

    {

    struct pguide_fb *fb __attribute__ ((unused))



    = container_of(info, struct pguide_fb, fb);
    /* Set the frame buffer base to something like:

    fb->fb.fix.smem_start + fb->fb.var.xres *

    ANDROID_BYTES_PER_PIXEL * var->yoffset

    */

    PGUIDE_FB_PAN;


    return 0;

    }

    static struct fb_ops pguide_fb_ops = {



    .owner = THIS_MODULE,

    .fb_check_var = pguide_fb_check_var,

    .fb_set_par = pguide_fb_set_par,

    .fb_setcolreg = pguide_fb_setcolreg,

    .fb_pan_display = pguide_fb_pan_display,
    /* These are generic software based fb functions */

    .fb_fillrect = cfb_fillrect,

    .fb_copyarea = cfb_copyarea,

    .fb_imageblit = cfb_imageblit,

    };

    static int pguide_fb_probe(struct platform_device *pdev)



    {

    int ret;


    struct pguide_fb *fb;

    size_t framesize;

    uint32_t width, height;
    fb = kzalloc(sizeof(*fb), GFP_KERNEL);

    if(fb == NULL) {

    ret = -ENOMEM;

    goto err_fb_alloc_failed;

    }

    platform_set_drvdata(pdev, fb);


    PGUIDE_FB_PROBE_FIRST;

    width = PGUIDE_FB_WIDTH;

    height = PGUIDE_FB_HEIGHT;

    fb->fb.fbops = &pguide_fb_ops;


    /* These modes are the ones currently required by Android */
    fb->fb.flags = FBINFO_FLAG_DEFAULT;

    fb->fb.pseudo_palette = fb->cmap;

    fb->fb.fix.type = FB_TYPE_PACKED_PIXELS;

    fb->fb.fix.visual = FB_VISUAL_TRUECOLOR;

    fb->fb.fix.line_length = width * ANDROID_BYTES_PER_PIXEL;

    fb->fb.fix.accel = FB_ACCEL_NONE;

    fb->fb.fix.ypanstep = 1;
    fb->fb.var.xres = width;

    fb->fb.var.yres = height;

    fb->fb.var.xres_virtual = width;

    fb->fb.var.yres_virtual = height * ANDROID_NUMBER_OF_BUFFERS;

    fb->fb.var.bits_per_pixel = 16;

    fb->fb.var.activate = FB_ACTIVATE_NOW;

    fb->fb.var.height = height;

    fb->fb.var.width = width;


    fb->fb.var.red.offset = 11;

    fb->fb.var.red.length = 5;

    fb->fb.var.green.offset = 5;

    fb->fb.var.green.length = 6;

    fb->fb.var.blue.offset = 0;

    fb->fb.var.blue.length = 5;


    framesize = width * height *

    ANDROID_BYTES_PER_PIXEL * ANDROID_NUMBER_OF_BUFFERS;

    fb->fb.screen_base = PGUIDE_FB_SCREEN_BASE;

    fb->fb.fix.smem_start = PGUIDE_FB_SMEM_START;

    fb->fb.fix.smem_len = framesize;
    ret = fb_set_var(&fb->fb, &fb->fb.var);

    if(ret)


    goto err_fb_set_var_failed;
    PGUIDE_FB_PROBE_SECOND;
    ret = register_framebuffer(&fb->fb);

    if(ret)


    goto err_register_framebuffer_failed;
    return 0;

    err_register_framebuffer_failed:

    err_fb_set_var_failed:

    kfree(fb);

    err_fb_alloc_failed:

    return ret;

    }
    static int pguide_fb_remove(struct platform_device *pdev)

    {

    struct pguide_fb *fb = platform_get_drvdata(pdev);


    PGUIDE_FB_REMOVE;
    kfree(fb);

    return 0;

    }

    static struct platform_driver pguide_fb_driver = {



    .probe = pguide_fb_probe,

    .remove = pguide_fb_remove,

    .driver = {

    .name = "pguide_fb"

    }

    };
    static int __init pguide_fb_init(void)



    {

    return platform_driver_register(&pguide_fb_driver);

    }
    static void __exit pguide_fb_exit(void)

    {

    platform_driver_unregister(&pguide_fb_driver);



    }
    module_init(pguide_fb_init);

    module_exit(pguide_fb_exit);


    MODULE_LICENSE("GPL");

    Troubleshooting


    Both of the following problems have a similar cause:

    • Number keys: In the dialer application, when a number key is pressed to dial a phone number, the number doesn't display on the screen until after the next number has been pressed.

    • Arrow keys: When an arrow key is pressed, the desired icon doesn't get highlighted. For example, if you browse through icons in the Applications menu, you might notice that icons aren't highlighted as expected when you use the arrow key to navigate between options.

    Both problems are caused by an incorrect implementation of the frame buffer's page flipping. Key events are captured, but the graphical interface appears to drop every other frame.

    Android relies on a double buffer to smoothly render page flips (please see Functionality for details).


    Keymaps and Keyboard Input

    In this document


    • Functionality

    • Key Layout Map

    • Key Character Map

    • Implementing Your Own Driver (Driver Template)

    • Sample Implementation

    This document describes how keyboard input gets translated into Android actions and how you can customize key layout and key character maps to match the needs of your own device.

    Android uses the standard Linux input event device (/dev/event0) and driver as described in the linux/input.h kernel header file. For more information regarding standard Linux input drivers, please see Linux Input drivers at http://kernel.org.


    Functionality


    Android's input event device is structured around an interrupt or polling routine that captures the device-specific scancode and converts it to a standard form acceptable to Linux (as defined in input.h) before passing it to the kernel with input_event().

    The keymap driver's other primary function is to establish a probe function that sets up the interrupt or polling function, handles hardware initialization, and attaches the driver to the input subsystem with input_register_device().

    The table below describes the steps required to translate from keyboard input to application action:

    Step

    Action

    Explanation

    1.

    Window manager reads key event from Linux keyboard driver.

    Events are typically positional. For example, the top-left position on a keypad returns 16 regardless of whether that key is printed with a Q (as on a QWERTY keypad) or an A (as on an AZERTY keypads). This first conversion by the Linux Keyboard Driver yields a scancode (for example, 16).

    2.

    Window manager maps scancode to keycode.

    When the window manager reads a key event out of the driver, it maps the scancode to a keycode using a key layout map file. Typically, the keycode is the primary symbol screen-printed on a key. For example, KEYCODE_DPAD_CENTER is the center button on the five-way navigation control. Even though ALT + G generates a "?" character, KEYCODE_G is the keycode.

    3.

    Window manager sends both the scancode and the keycode to the application.

    Both the scancode and keycode are handled by the view with focus. How the application interprets both depend on the application.

    Key Layout Map

    Selection of a Key Layout Map


    Key layout maps are installed in /system/usr/keylayout and /data/usr/keylayout.

    For each keyboard device xxx, set the android.keylayout.xxx system property (see Building New Device for help setting system properties). If you don't specify a keylayout file, Android will default to /system/usr/keylayout/qwerty.kl.


    File Format


    Key layout maps are stored on the device as UTF-8 text files and have the following characteristics:

    • Comments: The pound symbol (#) denotes a comment and everything after the pound symbol on a line is ignored.

    • Whitespace: All empty lines are ignored.

    • Key definitions: Key definitions follow the syntax key SCANCODE KEYCODE [FLAGS...], where SCANCODE is a number, KEYCODE is defined in your specific keylayout file (android.keylayout.xxx), and potential FLAGS are defined as follows:

      • SHIFT: While pressed, the shift key modifier is set

      • ALT: While pressed, the alt key modifier is set

      • CAPS: While pressed, the caps lock key modifier is set

      • WAKE: When this key is pressed while the device is asleep, the device will wake up and the key event gets sent to the app.

      • WAKE_DROPPED: When this key is pressed while the device is asleep, the device will wake up and the key event does not get sent to the app.

    Example of a Key Layout Map File


    The following code comes from android/src/device/product/generic/tuttle2.kl and is an example of a complete key layout file:

    # Copyright 2007 Google Inc.


    key 2 1

    key 3 2


    key 4 3

    key 5 4


    key 6 5

    key 7 6


    key 8 7

    key 9 8


    key 10 9

    key 11 0


    key 158 BACK WAKE_DROPPED

    key 230 SOFT_RIGHT WAKE

    key 60 SOFT_RIGHT WAKE

    key 107 ENDCALL WAKE_DROPPED

    key 62 ENDCALL WAKE_DROPPED

    key 229 MENU WAKE_DROPPED

    key 59 MENU WAKE_DROPPED

    key 228 POUND

    key 227 STAR

    key 231 CALL WAKE_DROPPED

    key 61 CALL WAKE_DROPPED

    key 232 DPAD_CENTER WAKE_DROPPED

    key 108 DPAD_DOWN WAKE_DROPPED

    key 103 DPAD_UP WAKE_DROPPED

    key 102 HOME WAKE

    key 105 DPAD_LEFT WAKE_DROPPED

    key 106 DPAD_RIGHT WAKE_DROPPED

    key 115 VOLUME_UP

    key 114 VOLUME_DOWN

    key 116 POWER WAKE

    key 212 SLASH
    key 16 Q

    key 17 W


    key 18 E

    key 19 R


    key 20 T

    key 21 Y


    key 22 U

    key 23 I


    key 24 O

    key 25 P
    key 30 A

    key 31 S

    key 32 D


    key 33 F

    key 34 G


    key 35 H

    key 36 J


    key 37 K

    key 38 L


    key 14 DEL

    key 44 Z


    key 45 X

    key 46 C


    key 47 V

    key 48 B


    key 49 N

    key 50 M


    key 51 COMMA

    key 52 PERIOD

    key 28 NEWLINE

    key 56 ALT_LEFT

    key 42 SHIFT_LEFT

    key 215 AT

    key 57 SPACE

    key 53 SLASH

    key 127 SYM

    key 100 ALT_LEFT


    key 399 GRAVE

    Key Character Map

    Selection of a Key Character Map


    Key character maps are installed in /system/usr/keychars and /data/usr/keychars.

    For each keyboard device xxx, set the android.keychar.xxx system property to the full path of the desired keychar file. If you don't specify a keychar file, Android will default to /system/usr/keychar/qwerty.kl.


    File Format


    Key character maps are stored on the device as binary resources in order to reduce loading time. Key character maps have the following characteristics:

    • Comments: The pound symbol (#) denotes a comment and everything after the pound symbol on a line is ignored.

    • Whitespace: All empty lines are ignored.

    • Column definitions: Column definitions follow the syntax columns MODIFIERS [...], where MODIFIERS are defined as follows:

      Character in MODIFIERS

      Corresponding bit in the modifiers

      O

      no modifiers

      S

      MODIFIER_SHIFT

      C

      MODIFIER_CONTROL

      L

      MODIFIER_CAPS_LOCK

      A

      MODIFIER_ALT

    • Key definitions: Key definitions have the syntax key SCANCODE CHARACTER [...] where SCANCODE is a number and CHARACTER values are either UTF-8 characters in quotation marks (for example, "a") or a numeric value that strtol can parse.

    Example of a Key Character Map File


    The following code comes from android/src/device/product/generic/tuttle2.kcm and represents a complete key character file:

    The type line indicates what kind of keyboard your device implements. Possible types include:



    • NUMERIC: A numeric (12-key) keyboard.

    • Q14: A keyboard that includes all letters but multiple letters per key.

    • QWERTY: A keyboard with all letters and possibly numbers. This option applies to all full keyboard configurations, such as AZERTY.

    # Copyright 2007 Google Inc.
    [type=QWERTY]
    # keycode base caps fn caps_fn number display_label
    A 'a' 'A' '%' 0x00 '%' 'A'

    B 'b' 'B' '=' 0x00 '=' 'B'

    C 'c' 'C' '8' 0x00E7 '8' 'C'

    D 'd' 'D' '5' 0x00 '5' 'D'

    E 'e' 'E' '2' 0x0301 '2' 'E'

    F 'f' 'F' '6' 0x00A5 '6' 'F'

    G 'g' 'G' '-' '_' '-' 'G'

    H 'h' 'H' '[' '{' '[' 'H'

    I 'i' 'I' '$' 0x0302 '$' 'I'

    J 'j' 'J' ']' '}' ']' 'J'

    K 'k' 'K' '"' '~' '"' 'K'

    L 'l' 'L' ''' '`' ''' 'L'

    M 'm' 'M' '>' 0x00 '>' 'M'

    N 'n' 'N' '<' 0x0303 '<' 'N'

    O 'o' 'O' '(' 0x00 '(' 'O'

    P 'p' 'P' ')' 0x00 ')' 'P'

    Q 'q' 'Q' '*' 0x0300 '*' 'Q'

    R 'r' 'R' '3' 0x20AC '3' 'R'

    S 's' 'S' '4' 0x00DF '4' 'S'

    T 't' 'T' '+' 0x00A3 '+' 'T'

    U 'u' 'U' '&' 0x0308 '&' 'U'

    V 'v' 'V' '9' '^' '9' 'V'

    W 'w' 'W' '1' 0x00 '1' 'W'

    X 'x' 'X' '7' 0xEF00 '7' 'X'

    Y 'y' 'Y' '!' 0x00A1 '!' 'Y'

    Z 'z' 'Z' '#' 0x00 '#' 'Z'


    COMMA ',' ';' ';' '|' ',' ','

    PERIOD '.' ':' ':' 0x2026 '.' '.'

    AT '@' '0' '0' 0x2022 '0' '@'

    SLASH '/' '?' '?' '\' '/' '/'


    SPACE 0x20 0x20 0x9 0x9 0x20 0x20

    NEWLINE 0xa 0xa 0xa 0xa 0xa 0xa


    # on pc keyboards

    TAB 0x9 0x9 0x9 0x9 0x9 0x9

    0 '0' ')' ')' ')' '0' '0'

    1 '1' '!' '!' '!' '1' '1'

    2 '2' '@' '@' '@' '2' '2'

    3 '3' '#' '#' '#' '3' '3'

    4 '4' '$' '$' '$' '4' '4'

    5 '5' '%' '%' '%' '5' '5'

    6 '6' '^' '^' '^' '6' '6'

    7 '7' '&' '&' '&' '7' '7'

    8 '8' '*' '*' '*' '8' '8'

    9 '9' '(' '(' '(' '9' '9'


    GRAVE '`' '~' '`' '~' '`' '`'

    MINUS '-' '_' '-' '_' '-' '-'

    EQUALS '=' '+' '=' '+' '=' '='

    LEFT_BRACKET '[' '{' '[' '{' '[' '['

    RIGHT_BRACKET ']' '}' ']' '}' ']' ']'

    BACKSLASH '\' '|' '\' '|' '\' '\'

    SEMICOLON ';' ':' ';' ':' ';' ';'

    APOSTROPHE ''' '"' ''' '"' ''' '''

    STAR '*' '*' '*' '*' '*' '*'

    POUND '#' '#' '#' '#' '#' '#'

    PLUS '+' '+' '+' '+' '+' '+'

    Resource Binary File Format


    The file snippet above gets converted to the following by the makekcharmap tool as part of the build process. You can mmap this file in and share the approximately 4k of memory that it uses between processes to minimize load time.

    Offset

    Size (bytes)

    Description

    0x00-0x0b




    The ascii value "keycharmap1" including the null character

    0x0c-0x0f




    padding

    0x10-0x13




    The number of entries in the modifiers table (COLS)

    0x14-0x17




    The number of entries in the characters table (ROWS)

    0x18-0x1f




    padding




    4*COLS

    Modifiers table. The modifier mask values that each of the columns in the characters table correspond to.







    padding to the next 16 byte boundary




    4*COLS*ROWS

    Characters table. The modifier mask values that each of the columns correspond to.

    Implementing Your Own Driver (Driver Template)


    The following file, pguide_events.c, illustrates how to implement an Android keymap driver.

    /*

    * pguide_events.c



    *

    * ANDROID PORTING GUIDE: INPUT EVENTS DRIVER TEMPLATE

    *

    * This template is designed to an example of the functionality



    * necessary for Android to recieve input events. The PGUIDE_EVENT

    * macros are meant as pointers indicating where to implement the

    * hardware specific code necessary for the new device. The existence

    * of the macros is not meant to trivialize the work required, just as

    * an indication of where the work needs to be done.

    *

    * Copyright 2007, Google Inc.



    * Based on goldfish-events.c

    *

    */


    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #define PGUIDE_EVENTS_INTERRUPT do{} while(0)

    #define PGUIDE_EVENTS_PROBE do{} while(0)
    struct event_dev {

    struct input_dev *input;

    int irq;

    };
    static irqreturn_t pguide_events_interrupt(int irq, void *dev_id)

    {

    struct event_dev *edev = dev_id;



    unsigned type=0, code=0, value=0;
    /* Set up type, code, and value per input.h

    */

    PGUIDE_EVENTS_INTERRUPT;


    input_event(edev->input, type, code, value);

    return IRQ_HANDLED;

    }
    static int pguide_events_probe(struct platform_device *pdev)

    {

    struct input_dev *input_dev;



    struct event_dev *edev;

    printk("*** pguide events probe ***\n");


    edev = kzalloc(sizeof(struct event_dev), GFP_KERNEL);

    input_dev = input_allocate_device();


    /* Setup edev->irq and do any hardware init */

    PGUIDE_EVENTS_PROBE;


    if(request_irq(edev->irq, pguide_events_interrupt, 0,

    "pguide_events", edev) < 0) {

    goto fail;

    }

    /* indicate that we generate key events */



    set_bit(EV_KEY, input_dev->evbit);

    set_bit(EV_REL, input_dev->evbit);

    set_bit(EV_ABS, input_dev->evbit);
    /* indicate that we generate *any* key event */
    bitmap_fill(input_dev->keybit, KEY_MAX);

    bitmap_fill(input_dev->relbit, REL_MAX);

    bitmap_fill(input_dev->absbit, ABS_MAX);

    platform_set_drvdata(pdev, edev);


    input_dev->name = "pguide_events";

    input_dev->private = edev;

    input_dev->cdev.dev = &pdev->dev;

    input_register_device(input_dev);

    return 0;
    fail:

    kfree(edev);

    input_free_device(input_dev);

    return -EINVAL;

    }
    static struct platform_driver pguide_events_driver = {

    .probe = pguide_events_probe,

    .driver = {

    .name = "pguide_events",

    },

    };
    static int __devinit pguide_events_init(void)



    {

    return platform_driver_register(&pguide_events_driver);

    }

    static void __exit pguide_events_exit(void)



    {

    }
    module_init(pguide_events_init);

    module_exit(pguide_events_exit);
    MODULE_DESCRIPTION("Pguide Event Device");

    MODULE_LICENSE("GPL");


    Sample Implementation


    Assume the following for the setup of a new keypad device:

    android.keylayout.partnerxx_keypad = /system/usr/keylayout/partnerxx_keypad.kl

    android.keychar.partnerxx_keypad = /system/usr/keychars/partnerxx.kcm

    The following example log file indicates that you have correctly registered the new keypad:

    I/EventHub( 1548): New device: path=/dev/input/event0 name=partnerxx_keypad id=0x10000 (of 0x1) index=1 fd=30

    I/EventHub( 1548): new keyboard input device added, name = partnerxx_keypad

    D/WindowManager( 1548): Starting input thread.

    D/WindowManager( 1548): Startup complete!

    I/EventHub( 1548): New keyboard: name=partnerxx_keypad

    keymap=partnerxx_keypad.kl

    keymapPath=/system/usr/keychars/partnerxx_keypad.kcm.bin

    I/ServiceManager( 1535): ServiceManager: addService(window, 0x13610)

    I/EventHub( 1548): Reporting device opened: id=0x10000, name=/dev/input/event0

    I/KeyInputQueue( 1548): Device added: id=0x10000, name=partnerxx_keypad, classes=1

    I/KeyInputQueue( 1548): Keymap: partnerxx_keypad.kl

    The snippet above contains artificial line breaks to maintain a print-friendly document.



    Download 1,28 Mb.
    1   2   3   4   5   6   7   8   9   ...   95




    Download 1,28 Mb.