1

I am trying to get an i2c device driver for an Atmel capacitive touchscreen controller to work in the Linux Kernel of our Android Lollipop (version 5.0.2) based system. I have added the manufacturer supplied updated source code (atmel_mxt_ts.c) to kernel/drivers/input/touchscreen, and modified the devicetree as appropriate, but when the kernel boots, i2c_device_register never gets called for this particular driver. This means I am unable to communicate with this device on the i2C bus, and consequently the touchpanel will not work. Note that this driver file was already present in the kernel, I just needed to make sure it was included in the kernel build, by running make menuconfig, and doing a full clean build. The i2c_device_register function is being called for other i2c drivers, such as the battery driver, as I can see printk output for them. Note also that the device address for this device is shown in sysfs. i.e. a directory listing for the relevant i2c bus shows the following:

root@var_mx6:/ # ls /sys/bus/i2c/devices/i2c-2/
2-000b
2-004a
2-0068
delete_device
i2c-dev
name
new_device
power
subsystem
uevent

004a is the address of the Atmel capacitive touch device, 000b is the SMBus battery, and 0068 is an RTC device.

Does anyone have any suggestions as to why the i2c_register_driver is not getting called for the Atmel capacitive touch device driver?

I have included some snippets of code below.

Here is the last part of the driver source file atmel_mxt_ts.c:

    static const struct of_device_id mxt_of_match[] = {
    { .compatible = "atmel,atmel_mxt_ts"},
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxt_of_match);

#ifdef CONFIG_ACPI
static const struct acpi_device_id mxt_acpi_id[] = {
    { "ATML0000", 0 },  /* Touchpad */
    { "ATML0001", 0 },  /* Touchscreen */
    { }
};
MODULE_DEVICE_TABLE(acpi, mxt_acpi_id);
#endif

static const struct i2c_device_id mxt_id[] = {
    { "atmel_mxt_ts", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, mxt_id);

static struct i2c_driver mxt_driver = {
    .driver = {
        .name   = "atmel_mxt_ts",
        .owner  = THIS_MODULE,
        .of_match_table = of_match_ptr(mxt_of_match),
        .acpi_match_table = ACPI_PTR(mxt_acpi_id),
        .pm = &mxt_pm_ops,
    },
    .probe      = mxt_probe,
    .remove     = mxt_remove,
    .id_table   = mxt_id,
};

module_i2c_driver(mxt_driver);

/* Module information */
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
MODULE_DESCRIPTION("Atmel maXTouch Touchscreen driver");
MODULE_LICENSE("GPL");

and here is the relevant section of the devicetree source:

&i2c3 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c3_3>;
        status = "okay";

    battery {
        compatible = "ti,bq20z75";
        reg = <0xb>;
        /* nBATT_PRES */
        battery-detect-gpios = <&expander1 4 GPIO_ACTIVE_LOW>;
        power-supplies = <&charger>;
    };

    touch@4a {
        compatible = "atmel,atmel_mxt_ts";
        reg = <0x4a>;
        interrupt-parent = <&gpio1>;
        interrupts = <4 1>; 
    };


        /* DS1307 RTC module */
        rtc@0x68 {
                 compatible = "dallas,ds1307";
                 reg = <0x68>;
        };
};
Brendan
  • 908
  • 2
  • 15
  • 30
Simon Bagley
  • 318
  • 2
  • 15
  • You never mentioned anything about the `Makefile` and `Kconfig` files in `drivers/input/touchscreen/`. Did you update them? Did you reconfigure the kernel and select the new touchscreen driver? And of course, did you rebuild and install the kernel and devicetree? – Ian Abbott Jul 15 '16 at 12:49
  • Not sure if you have a typo with a brace missing. The touch@4a entry should be within &i2c3 node. Does i2cdetect show the touchscreen on the i2c bus? Check if the probe function is getting called in addition to taking care of what Ian added. – Sanchayan Maity Jul 15 '16 at 13:16
  • @IanAbbott This driver was already part of the kernel, so is present in the Makefile and Kconfig files. I just reconfigured the kernel using make menuconfig to make sure the atmel driver was included. The atmel driver source code was updated to the latest code. I did a full clean/rebuild/install for the kernel and devicetree. – Simon Bagley Jul 15 '16 at 13:19
  • @Sanchayan The touch@4a entry is within the &i2c3 node, I just didn't show enough of the file! The probe function for this driver is definitely not being called. – Simon Bagley Jul 15 '16 at 13:22
  • @SimonBagley Is it a built-in driver or a loadable kernel module? Is it listed in the `/sys/bus/i2c/drivers` directory? – Ian Abbott Jul 15 '16 at 14:52
  • @IanAbbott It is supposed to be a built-in driver, but it is NOT listed in /sys/bus/i2c/drivers – Simon Bagley Jul 15 '16 at 15:34
  • @SimonBagley Is there any evidence that it is built into the kernel at all? – Ian Abbott Jul 15 '16 at 15:37
  • You never mentioned anything about testing the hardware. Linux is a clumsy tool for testing HW. – sawdust Jul 15 '16 at 18:37
  • @sawdust We have mostly working devices to test the capacitive touch panel on. I know the i2c master controller works, as the battery driver communicates with the battery over the same bus, and the RTC also works fine on the same bus. This would suggest the i2c hardware is working, but the capacitive touch panel i2c controller slave device is hard to test without the i2c driver working. – Simon Bagley Jul 18 '16 at 09:38
  • @IanAbbott The only evidence I have is that the object file atmel_mxt_ts.o is being created when I do a build. Since the driver doesn't appear in /sys/bus/i2c/driver though, this would suggest maybe it's not included in the kernel? – Simon Bagley Jul 18 '16 at 11:40
  • @SimonBagley The presence of the .o file without a .ko file suggests it's been built as a built-in driver. To double-check, take a look in the `modules.builtin` file, either in the top-level build directory, or a in a relevant subdirectory. You could also check the `System.map` file for the built kernel for local symbols from the driver - most of its symbols seem to begin with the string `mxt_`, so you can grep for that in `System.map`. – Ian Abbott Jul 18 '16 at 12:30
  • @IanAbbott modules.builtin does not list the atmel_mxt_ts driver file, and none of the symbols from it are listed in System.map. Presumably this means my build is not working correctly, no doubt due to user error! – Simon Bagley Jul 18 '16 at 15:22
  • *"device is hard to test without the i2c driver working"* -- Which is why you should not try to test two unknowns at the same time. Use U-Boot or a bare-metal program. – sawdust Jul 18 '16 at 22:36

1 Answers1

0

The changes that were previously made to the .config file for the kernel build to add the atmel capacitive touch driver had somehow been overwritten, on checking this file for the second time. After making sure the .config file had this driver included via make manuconfig, and rebuilding the driver now loads. So it turns out it was user error!

Simon Bagley
  • 318
  • 2
  • 15