Adding touch screen driver to Wandboard, i2c device registration - linux

First I must to tell you, I am not really from electronics background, I have very rough knowledge about Linux drivers, I2C, touch screens, etc.
Problem background
My Wandboard was previously working with Fusion 7 touch display worked with Prism touch screen driver, already provided by Wandboard.
As per my new requirement, I have got Ilitek touch screen which I am trying get it working with my Wandboard dual (i.MX6-Cortex-A9, Linux Kernel:3.0.35).
I got following Ilitek touch screen driver files under folder ilitek_limv3_0_9.
ilitek_lim.c
ilitek.h
ilitek_update.c
ilitek_i2c.idc
I compiled the driver into Linux kerenl as a built-in module, tried to run on the board but failed. The driver doesn't appear in /dev/input.
I debuged the kerenl code a bit, and found that the code doesn't reach to driver's probe function, instead it fails in device binding (i2c device registration). Just then I come to know about Device tree.
I looked into following dts files (which I believe my Wandboard is using), putting little i2c configuration present in the files here.
imx6qdl.dtsi
i2c1: i2c#021a0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a0000 0x4000>;
interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C1>;
status = "disabled";
};
i2c2: i2c#021a4000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a4000 0x4000>;
interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C2>;
status = "disabled";
};
i2c3: i2c#021a8000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a8000 0x4000>;
interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C3>;
status = "disabled";
};
imx6qdl-wandboard.dtsi
&hdmi {
ddc-i2c-bus = <&i2c1>;
status = "okay";
};
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
codec: sgtl5000#0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&clks 201>;
VDDA-supply = <&reg_2p5v>;
VDDIO-supply = <&reg_3p3v>;
};
};
I see dts note entry for sgtl5000 which is audio codec which then appears as /dev/input/event0. But I don't find any entry for 'prism' driver, which actually runs perfectly on the board. Neither dts files nor board-files have entry for 'prism' driver. But I am sure it's using 'device-tree' approach.
Questions
As my Wandboard works fine with 'prism' driver and touch device, why I don't see device node entry for 'prism' in dts files ?
Is there any other way for 'i2c device registration' other than 'device-tree' and 'earlier board-file' approach ?
How could I get past with ilitek touch driver not getting i2c-matched/registered problem ?
Thanks in advance.

Related

gpio-keys not working in combination with I/O expander driver gpio-pca953x (TCA6416A)

I want to integrate/load the gpio-pca953x driver in my Raspberry Pi3 B+ Linux with the help of an DT overlay. This driver is a general I²C controlled I/O expander gpio driver for various chips i.e. TCA6416. I managed to create an dts overlay which enables the driver.
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
fragment#0 {
target = <&i2c1>;
__overlay__ {
status = "okay";
};
};
fragment#1 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
tca6416: tca6416#20 {
compatible = "ti,tca6416";
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&gpio>;
interrupts = <18 0x02>; //IRQ_TYPE_EDGE_FALLING
};
};
};
};
There is a new gpiochip /sys/class/gpio/gpiochip488 and also interrupts seems to work.
I thought the next easy step would be to create a virtual input device with the help of the gpio-keys module. But it seems I was wrong.
I created another DT overlay like this:
fragment#1 {
target-path = "/soc";
__overlay__ {
gpio: gpio-button {
compatible = "gpio-keys";
autorepeat;
button#14 {
label = "TestKey";
linux,code = <14>;
gpios = <&tca6416 0 1>;
};
};
};
};
But this time this overlay can never be loaded. The error I got is always that symbol tca6416 can not be found in live device tree symbol table. What am I doing wrong here? Are there any working examples? I also tried to replace tca6416 in gpios above with gpio488 or any other possible name. Neither works.
It seems that the problem is the DTS overlay mechanism it self in some way. tca6416 gets never export as symbol in live tree. My solution is not using the overlay but including an DTS file in one of the main DTS files like bcm2710-rpi-3-b-plus.dts instead.
This include file contains:
&i2c1 {
tca6416_20: tca6416#20 {
compatible = "ti,tca6416";
#gpio-cells = <2>;
reg = <0x20>;
gpio-controller;
interrupt-parent = <&gpio>;
interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
};
This works as intended so does gpio-keys.

Enable RS485 mode for max310x SPI-UART converter

In my application I need RS485 interfaces. I am using some UARTs from am3352 but I need few more, so I'm trying to expand using SPI and max3109 chip.
I have successfully added max3109 to my device tree using module max310x - it shows two devices: /dev/ttyMAX0 and /dev/ttyMAX1. Here is the device tree fragment:
&spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
num_cs = <1>;
cs-gpios = <&gpio2 17 0>;
ti,pindir-d0-out-d1-in;
max310x_0: max0#0 {
compatible = "maxim,max3109";
reg = <0>;
spi-max-frequency = <24000000>;
clocks = <&clk1m8>;
clock-names = "xtal";
interrupt-parent = <&gpio2>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
clk1m8: clk1m8 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1843200>;
};
};
};
and the pins:
spi1_pins: pinmux_spi1_pins {
pinctrl-single,pins = <
0x108 (PIN_INPUT_PULLUP | MUX_MODE2) /* (H16) gmii1_col.spi1_sclk */
0x10c (PIN_INPUT_PULLUP | MUX_MODE2) /* (H17) gmii1_crs.spi1_d0 */
0x110 (PIN_INPUT_PULLUP | MUX_MODE2) /* (J15) gmii1_rxer.spi1_d1 */
>;
};
UARTs from max3109 are connected to rs232/rs485 converter with max3109's RTSn pins conected to both DE and RE pins.
The problem: UARTS on max3109 seems to work fine - both rs485 are transmitting data, but not reciving. Problem is that RTS is always at 0V level...
In UARTs from am3352 I am using in device tree the following property: "linux,rs485-enabled-at-boot-time". But adding it to main max310x_0 node is not giving any effect - this node is the expander node (containing 2 UARTs and gpio-controller), not the UART itself.
My idea is that I need to add a child-nodes for each UART and in it place the property "linux,rs485-enabled-at-boot-time". But I don't have a clue how to do it. I tried something like this:
&spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
num_cs = <1>;
cs-gpios = <&gpio2 17 0>;
ti,pindir-d0-out-d1-in;
max310x_0: max0#0 {
compatible = "maxim,max3109";
reg = <0>;
spi-max-frequency = <24000000>;
clocks = <&clk1m8>;
clock-names = "xtal";
interrupt-parent = <&gpio2>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
clk1m8: clk1m8 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1843200>;
};
ttyMAX0 {
linux,rs485-enabled-at-boot-time;
};
ttyMAX1 {
linux,rs485-enabled-at-boot-time;
};
};
};
but it didn't worked.
My question: How am I supposed to add those child-nodes (if that's the proper way) and what should I place in them to make RTS work?
EDIT:
after sawdust suggestion it seems it's impossible to add rs485 mode in device tree.
So I tried to add this functionality to device tree and I think I'm starting to understand how things work down in here. To start with something I'm printing port.flags value to dmesg and it seems my little insertion works (a bit) - it changes the value depending on presence of linux,rs485-enabled-at-boot-time parameter in device tree.
Here is the code I have inserted:
if (of_property_read_bool(dev->of_node, "linux,rs485-enabled-at-boot-time"))
s->p[i].port.flags |= SER_RS485_ENABLED;
printk("s->p[i].port.flags is: %d\n",s->p[i].port.flags);
The value of port.flags toggles from 134225920 to 134225921 depending on presence of linux,rs485-enabled-at-boot-time.
but the RTS pin still have constant 0V on my oscilloscope...
I'm trying to figure out if SER_RS485_RTS_ON_SEND and SER_RS485_RTS_AFTER_SEND have something to do with this, but I'm prete sure it's only for reverting RTS signal.
After few attempts IOCTL was the best and easiest solution. Here is some example code that helped me much. https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995
It's basic example how to turn RS485 mode on and off using IOCTL and read it's current mode. Works with both CPUs internal UARTS and MAX3109.

Linux Kernel Platform Driver: Modifications to _probe() for multiple Devices

What modifications must be done to a Linux kernel driver to support (equal) multiple devices(myipcore) on a SoC (defined in the device tree) instead of only one?
In my application: only one process will open the appropriate /dev/myipcoreX file!
Device Tree:
amba: amba {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
axi_myipcore1: myipcore#A0001000 {
compatible = "xy,my-ip-core-1.00";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 89 1>;
reg = <0x0 0xA0001000 0x0 0x14>;
};
axi_myipcore2: myipcore#A0002000 {
compatible = "xy,my-ip-core-1.00";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 90 1>;
reg = <0x0 0xA0002000 0x0 0x14>;
};
....
}
For each device tree entry the _probe() function of the driver is called. How to get dynamically the next minor number for alloc_chrdev_region() and how to execute class_create() only once?
Or do I have to modify the device tree?
You see, I'm looking for the central theme....

issue on interfacing adt7410 with yocto

I am trying to interface an I2C device ADT7410 with yocto but i am getting this error
adt7410: probe of 4-0048 failed with error -5
and my device tree modification is
TempSen: adt7410#48 {
compatible = "adt7410","adt7x10";
reg = <0x48>;
pinctrl-names = "default";
pinctrl-1 = <&pinctrl_edt_ft5x06_pins>;
interrupt-parent = <&gpio3>;
interrupts = <1 2>;
};
please help me to resolve this issue.

How to configure the multiplexer select of the ADC ad7266 in the device tree?

I am using a Freescale i.mx28 board. There is a ad7266 that communicate with the cpu over SPI. The ad7266 has a multiplexer that works with three GPIOs. (A0, A1, A2). In the past I configure this GPIOs directly in the driver. Now I want to use a second ad7266 over another SPI-Bus. Now, of course cannot config the multiplexer directly in the driver. So my question is, how can I config this Pins in the device tree? Is that possible? Here the code snippet:
ssp2: ssp#80014000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx28-spi";
pinctrl-names = "default";
pinctrl-0 = <&spi2_pins_pwr003>;
status = "okay";
flash: m25p80#0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "sst,sst25vf016b";
spi-max-frequency = <40000000>;
reg = <0>;
};
AD7266_PWR003: AD7266#0 {
compatible = "adi,ad7266";
spi-max-frequency = <1000000>;
spi-cpol;
vref-supply = <&reg_vref_2p5v>;
reg = <1>;
};
};
Thanks
As I found out the driver don't does not have devicetree support. – eddi

Resources