酷德网

Kx-m3酷自造发布!
查看: 56|回复: 0

IMX6移植Linux3.0.35内核时需要添加的矩阵按键的平台设备信息

[复制链接]
  • TA的每日心情
    奋斗
    2017-12-16 07:07
  • 签到天数: 30 天

    [LV.5]常住居民I

    发表于 2018-10-24 10:01:19 | 显示全部楼层 |阅读模式
      本文记录在IMX6开发板上移植鼎芯Linux3.0.35内核时,需要配置的矩阵按键的信息。本设备使用的矩阵按键是一个5*5的矩阵按键。
      1、IMX6移植3.0.35内核时需要配置的按键的信息
      首先我们要知道我们的按键接的核心板的引脚都有哪些:
    20181024002345767.png
      3.0.35内核中使用的矩阵按键驱动源码在”drivers/input/keyboard/matrix_keypad.c”中。
      里面是一个平台驱动,我们只要写平台设备,描述硬件的资源与此驱动匹配即可。
      驱动中有代码如下:

    [AppleScript] 纯文本查看 复制代码
     static struct platform_driver matrix_keypad_driver = {
    probe      = matrix_keypad_probe,
    remove     = __devexit_p(matrix_keypad_remove),
    driver     = {
    name   = "matrix-keypad",
    owner  = THIS_MODULE,
    #ifdef CONFIG_PM
    pm = &matrix_keypad_pm_ops,
    #endif
    },
    };
    module_platform_driver(matrix_keypad_driver);
    

      通过阅读平台驱动的probe函数,可得知我们写的平台设备应提供具本哪些硬件信息.
     
    [C++] 纯文本查看 复制代码
    static int __devinit matrix_keypad_probe(struct platform_device *pdev)
    {
    const struct matrix_keypad_platform_data *pdata; //平台设备提供的platform_data
    const struct matrix_keymap_data *keymap_data;
    struct matrix_keypad *keypad;
    struct input_dev *input_dev;
    unsigned short *keycodes;
    unsigned int row_shift;
    int err;
    
    pdata = pdev->dev.platform_data;
        ... .....
    keymap_data = pdata->keymap_data;
    
        ... .....
    matrix_keypad_build_keymap(keymap_data, row_shift,
    input_dev->keycode, input_dev->keybit); //从keymap_data里分解出行列键对应的键码
        ... .....
    err = init_matrix_gpio(pdev, keypad); //注册行线的中断号
        ... .....
    err = input_register_device(keypad->input_dev); //输入设备对象注册
        ... .....
    return err;
    }
    

      通过probe函数,可以确定我们写平台设备时只需通过platform_data成员提供平台驱动所需的信息,无需再提供resource.
      再确定结构体matrix_keypad_platform_data的每个成员的作用即可,如不清楚具体用途,可以在驱动代码里通过查看对成员值的访问反推出用途.
      在"include/linux/input/matrix_keypad.h"中有
    [C++] 纯文本查看 复制代码
    #define KEY(row, col, val)  ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
                     (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
                     ((val) & 0xffff))
    .....
    #define KEY_ROW(k)      (((k) >> 24) & 0xff)
    #define KEY_COL(k)      (((k) >> 16) & 0xff)
    #define KEY_VAL(k)      ((k) & 0xffff)
    .....
    .....
    #define MATRIX_SCAN_CODE(row, col, row_shift)   (((row) << (row_shift)) + (col))
    
    
    ......
    ......
    struct matrix_keymap_data {
        const uint32_t *keymap; //装载按键对应的键码数组, 注意每个键码需要使用宏KEY来写。也就是一个32位数据里,行,列,键码各占用8, 8, 16位.
        unsigned int    keymap_size; //键码数组的元素个数
    };
    ......
    ......
    struct matrix_keypad_platform_data {
        const struct matrix_keymap_data *keymap_data; //键码数据对象的首地址
    
        const unsigned int *row_gpios; //行线用的IO口
        const unsigned int *col_gpios; //列线用的IO口
    
        unsigned int    num_row_gpios; //多少个行线
        unsigned int    num_col_gpios; //多少个列线
    
        unsigned int    col_scan_delay_us; //扫描列线时间隔时间
    
        unsigned int    debounce_ms; //防抖动的间隔时间
    
        unsigned int    clustered_irq; //行线是否共用一个中断, 设0则每个行线的中断是独立的
        unsigned int    clustered_irq_flags;
    
        bool        active_low; //键按下时,行线是否为低电平
        bool        wakeup;
        bool        no_autorepeat; //按键按下时是否重复提交按键, 设1就是不重复,设0重复
    };
    
    

      根据我们的原理图:
      行线接: KEY_ROW0, KEY_ROW1, KEY_ROW2, KEY_ROW4,KEY_ROW5
      列线接: KEY_ROW0, KEY_ROW1, KEY_ROW2, KEY_ROW4,KEY_ROW5
      2、添加设备信息的具体步骤
      Imx_keypad平台层函数的添加
      1.在board-mx6q_sabresd.c中添加
     
    [C++] 纯文本查看 复制代码
    //注意键值,可以根据自己项目的需求自己更改
    static int mx6_sabresd_keymap[] = {
                       KEY(0, 0, KEY_UP),
                       KEY(0, 1, KEY_F9),
                       KEY(0, 2, KEY_F3),
                       KEY(0, 4, KEY_DOWN),
                       KEY(0, 5, KEY_PRINT),
            
            
                       KEY(1, 0, KEY_RIGHT),
                       KEY(1, 1, KEY_F8),
                       KEY(1, 2, KEY_F4),
                       KEY(1, 4, KEY_HOME),
                       KEY(1, 5, KEY_PAGEDOWN),
            
            
                       KEY(2, 0, KEY_F12),
                       KEY(2, 1, KEY_F7),
                       KEY(2, 2, KEY_F5),
                       KEY(2, 4, KEY_END),
                       KEY(2, 5, KEY_PAGEUP),
            
            
                       KEY(4, 0, KEY_F11),
                       KEY(4, 1, KEY_F1),
                       KEY(4, 2, KEY_F6),
                       KEY(4, 4, KEY_NUMLOCK),
                       KEY(4, 5, KEY_ESC),
            
            
                       KEY(5, 0, KEY_F10),
                       KEY(5, 1, KEY_F2),
                       KEY(5, 2, KEY_LEFT),
                       KEY(5, 4, KEY_SCROLLLOCK),
                       KEY(5, 5, KEY_PAUSE),
            
    };
    
    static const struct matrix_keymap_data mx6_sabresd_map_data __initconst= {
            .keymap                = mx6_sabresd_keymap,
            .keymap_size        = ARRAY_SIZE(mx6_sabresd_keymap),
    };
    
    
      2.在mx6_sabresd_board_init函数中添加:
    [C++] 纯文本查看 复制代码
      imx6q_add_imx_keypad(&mx6_sabresd_map_data);   //KEYBOARD 

      这个函数是在Platfprm-imx-keypad.c定义的,需要在Devices-imx6q.h中添加宏定义:
      
    [C++] 纯文本查看 复制代码
    extern const struct imx_imx_keypad_data imx6q_imx_keypad_data ;  //lyy 
    #define imx6q_add_imx_keypad(pdata)   \
            imx_add_imx_keypad(&imx6q_imx_keypad_data,pdata);
    

      3.在Platfprm-imx-keypad.c中添加:
    [C++] 纯文本查看 复制代码
    //lyy
    #ifdef CONFIG_SOC_IMX6Q
    const struct imx_imx_keypad_data imx6q_imx_keypad_data __initconst =
            imx_imx_keypad_data_entry_single(MX6SL, SZ_16);
    #endif /* ifdef CONFIG_SOC_IMX6Q */
    

      4.在Board-mx6_sabresd.h中添加并将所有复用引脚注释掉
      有可能有其它设备复用了下面这些引脚,一定要先将他们注释掉
      /* keyboaed lyy */      
               MX6Q_PAD_KEY_COL0__KPP_COL_0,
               MX6Q_PAD_KEY_ROW0__KPP_ROW_0,
               MX6Q_PAD_KEY_COL1__KPP_COL_1,
               MX6Q_PAD_KEY_ROW1__KPP_ROW_1,
               MX6Q_PAD_KEY_COL2__KPP_COL_2,
               MX6Q_PAD_KEY_ROW2__KPP_ROW_2,
        MX6Q_PAD_KEY_COL4__KPP_COL_4,
        MX6Q_PAD_KEY_ROW4__KPP_ROW_4,
        MX6Q_PAD_CSI0_DAT4__KPP_COL_5,
        MX6Q_PAD_CSI0_DAT5__KPP_ROW_5,

      5.在arch\arm\mach-mx6\Clock.c中的lookups[]中加入:
    [C++] 纯文本查看 复制代码
    static struct clk_lookup lookups[] = {
    。。。。。。。
    。。。。。。。
    _REGISTER_CLOCK(NULL, "kpp", dummy_clk),  //这是加入的
    };
    

      3、测试
      重新编译内核后,烧写到开发板,然后测试按键是否可以正常使用:
      首先在板子启动后,在板子的终端输入;
    [C++] 纯文本查看 复制代码
    $ cat /proc/bus/input/devices

      查看当前的设备,找到我们的按键设备,假设为evet0。
      则在终端中输入
    [C++] 纯文本查看 复制代码
    $ hexdump /dev/input/event0

      所有按键都按一遍,会发现终端中打印了按键的值(显示的内容好像是某一种编码,不知道怎么转换为按键的值)


    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

    本版积分规则

    
    顶部qrcode底部
    关注酷德网订阅号,获取更多资讯!

    QQ|小黑屋|手机版|Archiver|酷德论坛 ( 苏ICP备16065247号 )|网站地图

    GMT+8, 2018-11-15 22:42 , Processed in 0.271244 second(s), 22 queries , MemCache On.

    酷德网

    © 2001-2013 Hicodesys. 技术支持 by 酷德网

    快速回复 返回顶部 返回列表