这是我的探测函数:
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, ®);
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没有按键值,这个地址全是零,大家知道什么原因!!!
|