gxlsunday 发表于 2016-1-7 13:45

tca8418 矩阵键盘问题求助


这是我的探测函数:
       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);
    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);
      printk("(keypad_data->input->keycode)address2 = %x\n",trans_key_third);
      printk("(keypad_data->input->keycode)address3 = %x\n",trans_key_third);
      
      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),

};


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没有按键值,这个地址全是零,大家知道什么原因!!!
发生中断后中断函数打印的keypad_data->input->keycode没有按键值,全是零,我打印了这个地址内容确实全为零!!!,

zzyege 发表于 2016-1-28 17:35

楼主你好,我也刚开始在stm32上用tca8418做矩阵按键,刚开始研究datasheet。您有它完美驱动这方面的例程吗,研究研究。zzyege@126.com。 谢谢楼主了。
页: [1]
查看完整版本: tca8418 矩阵键盘问题求助