打印
[i.MX]

tca8418 矩阵键盘问题求助

[复制链接]
1122|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gxlsunday|  楼主 | 2016-1-7 13:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是我的探测函数:
       static int tca8418_keypad_probe(struct i2c_client *client,
                                          const struct i2c_device_id *id)
{

    struct device *dev = &client->dev;  
    const struct tca8418_keypad_platform_data *pdata =  
                        dev_get_platdata(dev);  
    struct tca8418_keypad *keypad_data;  
    struct input_dev *input;  
    const struct matrix_keymap_data *keymap_data = NULL;  
    u32 rows = 0, cols = 0;  
    bool rep = false;  
    bool irq_is_gpio = false;  
    int irq;  
    int error, row_shift, max_keys,i;  

    /* Copy the platform data */  
    if (pdata) {  
        if (!pdata->keymap_data) {  
            dev_err(dev, "no keymap data defined\n");  
            return -EINVAL;  
        }  
        keymap_data = pdata->keymap_data;  
        rows = pdata->rows;  
        cols = pdata->cols;  
        rep  = pdata->rep;  
        irq_is_gpio = pdata->irq_is_gpio;  
    }  
    if (!rows || rows > TCA8418_MAX_ROWS) {  
        dev_err(dev, "invalid rows\n");  
        return -EINVAL;  
    }  

    if (!cols || cols > TCA8418_MAX_COLS) {  
        dev_err(dev, "invalid columns\n");  
        return -EINVAL;  
    }  
    /* Check i2c driver capabilities */  
    if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {  
        dev_err(dev, "%s adapter not supported\n",  
            dev_driver_string(&client->adapter->dev));  
        return -ENODEV;  
    }  
    row_shift = get_count_order(cols);  
    max_keys = rows << row_shift;  

    /* Allocate memory for keypad_data and input device */  
    keypad_data = kzalloc(sizeof(*keypad_data), GFP_KERNEL);
    if (!keypad_data)
         return -ENOMEM;

    keypad_data->client = client;
    keypad_data->row_shift = row_shift;

    i2c_set_clientdata(client, keypad_data);
    /* Initialize the chip or fail if chip isn't present */
    error = tca8418_configure(keypad_data, rows, cols);
    if (error < 0)  
        return error;
    /* Configure input device*/
    input = input_allocate_device();  
    if (!input) {  
        error = -ENOMEM;  
        return error;  
    }
    printk("2-----row = %d,cols = %d\n",rows,cols);
    keypad_data->input = input;
    input->phys = "tca8418_keys/input0";
    input->name = client->name;  
    input->dev.parent = &client->dev;  
    input->id.bustype = BUS_I2C;  
    input->id.vendor  = 0x0001;  
    input->id.product = 0x0001;  
    //input->id.version = 0x0100;
    input->id.version = 0x0001;
    input->keycode = keymap_data->keymap;

    input->keycodesize = sizeof(keymap_data->keymap[0]);
    input->keycodemax = ARRAY_SIZE(keymap_data->keymap);
    if (rep)  
        __set_bit(EV_REP, input->evbit);
    __set_bit(EV_KEY, input->evbit);

    //导入键盘键值映射表
#if 0
    matrix_keypad_build_keymap(keymap_data, row_shift, input->keycode, input->keybit);  
#else
    matrix_keypad_build_keymaptest(keymap_data, row_shift, input->keycode, input->keybit);


#endif   
    if (!input->keybit) {  
        dev_err(dev, "Failed to build keymap\n");  
        return error;  
    }
    input_set_capability(input, EV_MSC, MSC_SCAN); //test for gxl
    input_set_drvdata(input, keypad_data);         //test for gxl
    //申请中断,这里有的input驱动用到的是工作队列的方式,是隔一段时间去自动检测,有兴趣的可以了解一下
    irq = client->irq;  
    //if (irq_is_gpio)  
    //    irq = gpio_to_irq(irq);   
    error = request_threaded_irq(irq,NULL, tca8418_irq_handler,
                                    IRQF_ONESHOT|IRQF_SHARED,
                                    client->name, keypad_data);
    if (error) {
                dev_err(dev, "Unable to claim irq %d; error %d\n",
                        client->irq, error);
                return error;
    }
    //第三步:将设备注册到input子设备中
    error = input_register_device(input);      
    if (error) {  
        dev_err(dev, "Unable to register input device, error: %d\n",  
            error);
        return error;  
    }  
    return 0;  
}

这是中断函数 :
static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
{
        struct tca8418_keypad *keypad_data = (struct tca8418_keypad *)dev_id;
        u8 reg;
        int error;
        unsigned short  *trans_key_third;

        trans_key_third = keypad_data->input->keycode;
        printk("(keypad_data->input->keycode)address0 = %x\n",trans_key_third);
        printk("(keypad_data->input->keycode)address1 = %x\n",trans_key_third[1]);
        printk("(keypad_data->input->keycode)address2 = %x\n",trans_key_third[2]);
        printk("(keypad_data->input->keycode)address3 = %x\n",trans_key_third[3]);   
      
        error = tca8418_read_byte(keypad_data, REG_INT_STAT, &reg);

        printk("REG_INT_STAT1 = %d\n",reg);

        if (error) {
                dev_err(&keypad_data->client->dev,
                        "unable to read REG_INT_STAT\n");
                return IRQ_NONE;
        }

        if (!reg)
                return IRQ_NONE;

        if (reg & INT_STAT_OVR_FLOW_INT)
                dev_warn(&keypad_data->client->dev, "overflow occurred\n");

        if (reg & INT_STAT_K_INT)
          {                     
               tca8418_read_keypad(keypad_data);
          }

        /* Clear all interrupts, even IRQs we didn't check (GPI, CAD, LCK) */
        reg = 0xff;

        error = tca8418_write_byte(keypad_data, REG_INT_STAT, reg);
        if (error)
                dev_err(&keypad_data->client->dev,
                        "unable to clear REG_INT_STAT\n");
        return IRQ_HANDLED;
}


发生中断后中断函数打印的keypad_data->input->keycode没有按键值,


bsp端的函数:
static uint32_t tca8418_mkdata[] __initdata = {
    /* KEY(row, col, keycode) */
    KEY(7, 0, KEY_F1), KEY(7, 1, KEY_F2), KEY(7, 2, KEY_F3),KEY(7, 3, KEY_F4),KEY(7, 4, KEY_HOME),KEY(7, 5, KEY_UP),KEY(7, 6, KEY_BACK),
    KEY(6, 0, KEY_8), KEY(6, 1, KEY_UP), KEY(6, 2, KEY_A),KEY(6, 3, KEY_B),KEY(6, 4, KEY_C),KEY(6, 5, KEY_D),KEY(6, 6, KEY_E),
    KEY(5, 0, KEY_LEFT), KEY(5, 1, KEY_DOWN), KEY(5, 2, KEY_RIGHT),KEY(5, 3, KEY_4),KEY(5, 4, KEY_5),KEY(5, 5, KEY_6),KEY(5, 6, KEY_7),
    KEY(4, 0, KEY_1), KEY(4, 1, KEY_2), KEY(4, 2, KEY_3),KEY(4, 3, KEY_BRIGHTNESSDOWN),KEY(4, 4, KEY_BRIGHTNESSUP),KEY(4, 5, KEY_BRIGHTNESSUP),KEY(4, 5, KEY_BRIGHTNESSUP),
#endif
};


static struct matrix_keymap_data tca8418_keymap_data __initdata = {
        .keymap                = tca8418_mkdata,
        .keymap_size        = ARRAY_SIZE(tca8418_mkdata),
};
static struct tca8418_keypad_platform_data tca8418_date = {
        .keymap_data = &tca8418_keymap_data,
        .rows=4,
        .cols=7,
        .rep=1,
        .irq_is_gpio=1,
};

static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
        {
                I2C_BOARD_INFO("tca8418_keypad", 0x34),
                //.type = "tca8418_keypad" ,
                .irq = gpio_to_irq(SABRESD_SD2_WP),
                .platform_data = (void *)&tca8418_date,
        },
};

发生中断后中断函数打印的keypad_data->input->keycode没有按键值,这个地址全是零,大家知道什么原因!!!

相关帖子

沙发
史迪威将军| | 2016-1-10 19:02 | 只看该作者
一个矩阵键盘就这么多的程序啊,好复杂

使用特权

评论回复
板凳
mini1986| | 2016-1-12 11:19 | 只看该作者
本帖最后由 mini1986 于 2016-1-12 11:34 编辑

它有个映射表,你仔细读读源码文件......我没有搞过这个片子,我搞过max的片子......还有就是看看报上来的行列值对不对......

使用特权

评论回复
地板
energyplants| | 2016-1-12 20:05 | 只看该作者
这个矩阵键盘是几乘以几的啊

使用特权

评论回复
5
zzyege| | 2016-1-29 08:44 | 只看该作者
楼主你好,我也刚开始在stm32上用tca8418做矩阵按键,刚开始研究datasheet。您有它完美驱动这方面的例程吗,研究研究。zzyege@126.com。 谢谢楼主了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

87

帖子

2

粉丝