5

I am attempting to use a TCA8418 keypad (which operates over I2C) and I have the driver loaded into the kernel, but the device was not recognized so I am instantiating it myself and am unable to bind the driver. I get the following error:

# echo -n "1-0034" > /sys/bus/i2c/drivers/tca8418_keypad/bind
-bash: echo: write error: No such device

This is after having tried the following (as root):

# echo -n "tca8418_keypad" 0x34 > /sys/bus/i2c/devices/i2c-1/new_device

I have the following device and driver trees, respectively:

/sys/bus/i2c/devices/1-0034
|-- modalias
|-- name
|-- power
|   |-- autosuspend_delay_ms
|   |-- control
|   |-- runtime_active_time
|   |-- runtime_status
|   `-- runtime_suspended_time
|-- subsystem -> ../../../../../bus/i2c
`-- uevent

/sys/bus/i2c/drivers/tca8418_keypad
|-- bind
|-- module -> ../../../../module/tca8418_keypad
|-- uevent
`-- unbind

I have used the following for reference thus far, but neither seems to work completely:

I have run out of ideas and could use some suggestions. Am I even approaching this the right way?

I'm running Debian on an ARM single board computer if that matters.

Edit:

I have since discovered that I am receiving the following error when I instantiate the new device:

tca8418_keypad: probe of 1-0034 failed with error -22
2

I was missing platform data for this device.

I was able to get it working by inserting the platform data directly into the code for the driver module:

static uint32_t tca8418_km_data[] = {
    KEY(0, 0, KEY_F1),
    KEY(0, 1, KEY_F2),
    KEY(0, 2, KEY_F3),
    ...
};

static const struct matrix_keymap_data tca8418_mk_data = {
    .keymap         = tca8418_km_data,
    .keymap_size    = ARRAY_SIZE(tca8418_km_data),
};

static struct tca8418_keypad_platform_data my_tca8418_plat_data = {
    .keymap_data    = &tca8418_mk_data,
    .rows           = 6,
    .cols           = 8,
    .rep            = 1,
    .irq_is_gpio    = 1,
};

static struct i2c_board_info tca8418_board_info __initdata = {
    I2C_BOARD_INFO("tca8418_keypad", 0x34),
    .platform_data  = &my_tca8418_plat_data,
    .irq            = 16, // GPIO pin 16
};

Then adding this to the __init function:

static int __init tca8418_keypad_init(void)
{
    struct i2c_adapter *i2c_adap;
    i2c_adap = i2c_get_adapter(1);
    i2c_new_device(i2c_adap, &tca8418_board_info);
    ...
}

This is not the most elegant of fixes, but it worked for me. I would have preferred a userspace solution, but I was unable to find one.

  • It should be done via DT or ACPI. – 0andriy Nov 17 '19 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.