160 | | Linux Touchscreen Driver Support: |
161 | | * touchscreen's are typically I2C or USB based devices with drivers in the {{{drivers/input/touchscreen}}} directory |
162 | | |
163 | | [=#troubleshooting] |
164 | | === Troubleshooting Backlight Portion === |
165 | | In some cases the device tree node used by the linux {{{pwm-backlight}}} driver may need to be adjusted if |
166 | | "flickering" exists ([https://i.stack.imgur.com/LF3Y4.jpg example]). This phenomenon is caused by a pwm frequency setting that is too low for the connected display's backlight which creates a visual artifact that may be detectable by the human eye. |
167 | | |
168 | | As described in the pwm device tree bindings [https://raw.githubusercontent.com/torvalds/linux/master/Documentation/devicetree/bindings/pwm/pwm.txt documentation], the backlight node of the device tree has a property labelled {{{pwms}}}. This property has includes the {{{pwm-specifier}}} which typically encodes the chip-relative PWM number and the PWM |
169 | | period in nanoseconds. |
170 | | {{{ |
171 | | backlight { |
172 | | compatible = "pwm-backlight"; |
173 | | pwms = <&pwm1 0 5000000>; /* 1 / (5000000 / 1000000000) = 200 Hz */ |
174 | | brightness-levels = < |
175 | | 0 1 2 3 4 5 6 7 8 9 |
176 | | 10 11 12 13 14 15 16 17 18 19 |
177 | | 20 21 22 23 24 25 26 27 28 29 |
178 | | 30 31 32 33 34 35 36 37 38 39 |
179 | | 40 41 42 43 44 45 46 47 48 49 |
180 | | 50 51 52 53 54 55 56 57 58 59 |
181 | | 60 61 62 63 64 65 66 67 68 69 |
182 | | 70 71 72 73 74 75 76 77 78 79 |
183 | | 80 81 82 83 84 85 86 87 88 89 |
184 | | 90 91 92 93 94 95 96 97 98 99 |
185 | | 100 |
186 | | >; |
187 | | default-brightness-level = <100>; |
| 173 | |
| 174 | ==== Touch |
| 175 | Linux Touchscreen controllers are typically I2C or USB based devices with drivers in the {{{drivers/input/touchscreen}}} directory. The driver for the specific controller device on your touchscreen must be enabled which also requires enabling the Linux Input subsystem. |
| 176 | |
| 177 | I2C based touch controllers are configured via Linux device-tree and each driver can have its own set of properties (device-tree bindings) which are documented in the kernel's Documentation/devicetree/bindings/input/touchscreen directory. There is a set of common properties supported for all I2C based touch controllers as well to handle mapping of touch sensor coordinates to display coordinates. |
| 178 | |
| 179 | Note that the display coordinate system may differ from the touch controller coordinate system and that the display coordinate system is dependent upon any library or framework you are using and for the orientation of the device. For example for raw kernel Linux display coordinate 0,0 is at the top-left of the screen. The touch controller will report x and y coordinates depending on its physical sensors and orientation and depending on screen orientation this could be such that 0,0 is at the bottom-left of the screen. Additionally the resolution of the display may be 1024x768 yet the touch controller resolution may be 1024x1024. Therefore most likely you will need to map and translate the touch coordinates to the display coordinates. This mapping and translation can be performed by the Linux kernel in modern kernels. |
| 180 | |
| 181 | Example: |
| 182 | * The Gateworks GW17047 DLC0700XDP21LF 7" WSVGA Touchscreen Display has a display resolution of 1024x600 and a touch controller of matching 1024x600 resolution. However when oriented such that its display 0,0 is at the top left the touch controller reports this as 1024,600 and reports the bot right as 0,0. In this case the touch controller x and y axis need to be inverted to match the display. The device-tree for this would look like: |
| 183 | - GW54xx (where touch IRQ is on the IMX pad GPIO_17__GPIO7_IO12) |
| 184 | {{{#!bash |
| 185 | &i2c3 { |
| 186 | clock-frequency = <100000>; |
| 187 | pinctrl-names = "default"; |
| 188 | pinctrl-0 = <&pinctrl_i2c3>; |
| 189 | status = "okay"; |
| 190 | |
| 191 | touchscreen: touchscreen@38 { |
| 192 | compatible = "edt,edt-ft5406", "edt,edt-ft5x06"; |
| 193 | pinctrl-names = "default"; |
| 194 | pinctrl-0 = <&pinctrl_touch>; |
| 195 | reg = <0x38>; |
| 196 | interrupt-parent = <&gpio7>; |
| 197 | interrupts = <12 IRQ_TYPE_EDGE_FALLING>; |
| 198 | touchscreen-inverted-x; |
| 199 | touchscreen-inverted-y; |
| 200 | touchscreen-size-x = <1024>; |
| 201 | touchscreen-size-y = <600>; |
| 202 | }; |
189 | | }}} |
190 | | |
191 | | If you want to make an adjustment to this frequency, you can use the {{{fixfdt}}} script in the bootloader. For example, to change the backlight frequency to {{{10kHz}}} you would run the following command from the bootloader: |
192 | | {{{#!bash |
193 | | # The third value of the pwms property is in nanoseconds so to convert to Hz: |
194 | | # 1 / (100000 / 1000000000) = 10 kHz |
195 | | setenv fixfdt "fdt addr ${fdt_addr}; fdt set /backlight pwms <0x3d 0 100000>" |
196 | | }}} |
197 | | |
198 | | === Troubleshooting Touchscreen Portion === |
199 | | There is a command line tool called {{{evtest}}} that can be used to check for touch events. |
200 | | |
201 | | An example is shown below: |
| 204 | |
| 205 | &iomuxc { |
| 206 | pinctrl_touch: touchgrp { |
| 207 | fsl,pins = < |
| 208 | MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 |
| 209 | >; |
| 210 | }; |
| 211 | }; |
| 212 | }}} |
| 213 | |
| 214 | |
| 215 | You must also ensure the Linux input driver compatible with your device is enabled in the kernel. For example a FT5406 I2C based touch controller is enabled via kernel CONFIG_TOUCHSCREEN_EDT_FT5X06: |
| 216 | {{{#!bash |
| 217 | # zcat /proc/config.gz | grep EDT |
| 218 | CONFIG_TOUCHSCREEN_EDT_FT5X06=y |
| 219 | }}} |
| 220 | |
| 221 | One your kernel has the proper driver enabled, and any required device-tree nodes and properties are configured boot that kernel with the proper device tree and verify you have a Linux input device registered: |
| 222 | * check /proc/bus/input/devices |
| 223 | {{{#!bash |
| 224 | # cat /proc/bus/input/devices |
| 225 | I: Bus=0018 Vendor=0000 Product=0000 Version=0000 |
| 226 | N: Name="generic ft5x06 (81)" |
| 227 | P: Phys= |
| 228 | S: Sysfs=/devices/soc0/soc/2100000.aips-bus/21a8000.i2c/i2c-2/2-0038/input/input0 |
| 229 | U: Uniq= |
| 230 | H: Handlers=event0 |
| 231 | B: PROP=2 |
| 232 | B: EV=b |
| 233 | B: KEY=400 0 0 0 0 0 0 0 0 0 0 |
| 234 | B: ABS=2608000 3 |
| 235 | }}} |
| 236 | * check /sys/class/input |
| 237 | {{{#!bash |
| 238 | # ls -l /sys/class/input/ |
| 239 | total 0 |
| 240 | lrwxrwxrwx 1 root root 0 Jan 1 01:22 event0 -> ../../devices/soc0/soc/2100000.aips-bus/21a8000.i2c/i2c-2/2-0038/input/input0/event0 |
| 241 | lrwxrwxrwx 1 root root 0 Jan 1 01:22 input0 -> ../../devices/soc0/soc/2100000.aips-bus/21a8000.i2c/i2c-2/2-0038/input/input0 |
| 242 | }}} |
| 243 | |
| 244 | For interrupt based controllers such as an I2C controller you should also see interrupts increasing for the interrupt registered by that driver. For example for the edt-ft5406 I2C device/driver: |
| 245 | {{{#!bash |
| 246 | # cat /proc/interrupts | grep edt-ft |
| 247 | 283: 149 0 0 0 gpio-mxc 12 Edge edt-ft5406 |
| 248 | }}} |
| 249 | - the interrupt number and name vary depending on the kernel and the device/driver you have. The above is for a FT5406 I2C based touch controller which shows 149 interrupt events (which should increase as you touch/release the touchscreen |
| 250 | |
| 251 | Once you verify you have a Linux input device registered and interrupts are firing you can use either {{{evtest}}} (standard Linux) or {{{getevent}}} (Android) to verify input events are occuring: |
| 252 | * evtest: |
252 | | |
253 | | }}} |
254 | | |
255 | | It is important verify the touchscreen is detected by running the following command in the example example: |
256 | | |
257 | | {{{#!bash |
258 | | root@ventana:/ # cat /proc/bus/input/devices |
259 | | I: Bus=0018 Vendor=0416 Product=1001 Version=28bb |
260 | | N: Name="Goodix Capacitive TouchScreen" |
261 | | P: Phys=input/ts |
262 | | S: Sysfs=/devices/soc0/soc.1/2100000.aips-bus/21a8000.i2c/i2c-2/2-0014/input/input0 |
263 | | U: Uniq= |
264 | | H: Handlers=mouse0 event0 |
265 | | B: PROP=2 |
266 | | B: EV=b |
267 | | B: KEY=400 0 0 0 0 0 0 0 0 0 0 |
268 | | B: ABS=2658000 3 |
269 | | }}} |
270 | | |
271 | | ==== Interrupts ==== |
272 | | You can see if interrupts are being sent to the touchscreen controller. |
273 | | |
274 | | Run the command: |
275 | | {{{ |
276 | | cat /proc/interrupts |
277 | | }}} |
278 | | |
279 | | Find the touch controller in the list. |
280 | | |
281 | | Note the number of interrupts it currently has. |
282 | | |
283 | | Then touch the screen a few times. |
284 | | |
285 | | Then check the interrupts again to verify if it has increased. |
286 | | |
287 | | |
288 | | ==== Android Touchscreen ==== |
289 | | In addition to the above information, here is some more information that may be relevant to Android. |
290 | | |
291 | | To detect touch events on Android, where {{{evtest}}} may not exist, try using the {{{getevent}}} command. |
292 | | |
293 | | Example shown below, adjust command as necessary. |
294 | | |
295 | | Note that values should appear on the serial console when the screen is touched. |
296 | | |
297 | | This verifies the touchscreen is getting events. |
| 303 | }}} |
| 304 | * Android {{{getevent}}}: |
| 325 | ==== Backlight |
| 326 | Linux backlight controllers exist for various devices under the kernel menu of Device Drivers -> Graphics support -> Backlight & LCD device support. |
| 327 | |
| 328 | Most commonly used are: |
| 329 | * a pulse width modulated (PWM) signal is used to vary a backlight between 0 and 100% |
| 330 | * a general purpose IO (GPIO) signal is used to enable/disable a backlight |
| 331 | |
| 332 | In the above cases the Linux device-tree bindings must specify the details which can vary greatly |
| 333 | |
| 334 | |
| 335 | ===== PWM |
| 336 | For PWM based backlight controllers you must configure CONFIG_BACKLIGHT_PWM to enable the drivers/video/backlight/pwm_bl.c driver which provides you with a way to control brightness between 0 and 100%. Note that you also need the driver for your PWM controller which in the case of an IMX pin supporting PWM is CONFIG_PWM_IMX27. |
| 337 | |
| 338 | This requires also configuring a device-tree node specifying the PWM, a set of brightness levels, and the default brightness. See [https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml Documentation/devicetree/bindings/leds/backlight/pwm-backlight] for details. |
| 339 | |
| 340 | Example: |
| 341 | * The Gateworks GW17047 DLC0700XDP21LF 7" WSVGA Touchscreen Display has an on-board PWM based backlight controller: |
| 342 | - GW54xx: |
| 343 | * J5.5: BACK_ADJ: MX6QDL_PAD_SD1_CMD (this is our PWM) |
| 344 | * J5.1: BACK_EN#: MX6QDL_PAD_SD2_CLK (this is a GPIO enable) |
| 345 | {{{ |
| 346 | / { |
| 347 | backlight { |
| 348 | compatible = "pwm-backlight"; |
| 349 | pwms = <&pwm4 0 5000000>; /* 1 / (5000000 / 1000000000) = 200 Hz */ |
| 350 | brightness-levels = < |
| 351 | 0 1 2 3 4 5 6 7 8 9 |
| 352 | 10 11 12 13 14 15 16 17 18 19 |
| 353 | 20 21 22 23 24 25 26 27 28 29 |
| 354 | 30 31 32 33 34 35 36 37 38 39 |
| 355 | 40 41 42 43 44 45 46 47 48 49 |
| 356 | 50 51 52 53 54 55 56 57 58 59 |
| 357 | 60 61 62 63 64 65 66 67 68 69 |
| 358 | 70 71 72 73 74 75 76 77 78 79 |
| 359 | 80 81 82 83 84 85 86 87 88 89 |
| 360 | 90 91 92 93 94 95 96 97 98 99 |
| 361 | 100 |
| 362 | >; |
| 363 | default-brightness-level = <100>; |
| 364 | enable-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; |
| 365 | }; |
| 366 | }; |
| 367 | |
| 368 | &pwm4 { |
| 369 | pinctrl-names = "default"; |
| 370 | pinctrl-0 = <&pinctrl_pwm4_backlight>; |
| 371 | status = "okay"; |
| 372 | }; |
| 373 | |
| 374 | &iomuxc { |
| 375 | pinctrl_pwm4_backlight: pwm4grpbacklight { |
| 376 | fsl,pins = < |
| 377 | /* J5.1: BACK_EN# */ |
| 378 | MX6QDL_PAD_SD2_CLK__GPIO1_IO10 0x1b0b1 |
| 379 | /* J5.5: BACK_ADJ */ |
| 380 | MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 |
| 381 | >; |
| 382 | }; |
| 383 | }; |
| 384 | }}} |
| 385 | - PWM4 with a 200Hz frequency with 100 levels of brightness. You can specify as many brightness levels as you wish each with a cooresponding PWM value from 0 to 255 (where 255 is 100% duty cycle). |
| 386 | - IMX6 pad SD1_CMD configured as PWM4 - this is J5.5 BACK_ADJ |
| 387 | - IMX6 pad SD2_CLK configured as GPIO1_IO10 - this is J5.1 BACK_EN# |
| 388 | |
| 389 | In some cases the device tree node used by the linux {{{pwm-backlight}}} driver may need to be adjusted if |
| 390 | "flickering" exists ([https://i.stack.imgur.com/LF3Y4.jpg example]). This phenomenon is caused by a PWM frequency setting that is too low for the connected display's backlight which creates a visual artifact that may be detectable by the human eye. The {{{pwms}}} property above includes the {{{pwm-specifier}}} which although PWM controller dependent, typically encodes the chip-relative PWM number and the PWM period in nanoseconds. Therefore in the above example you could alter the 5000000 value to come up with a different backlight frequency. |
| 391 | |
| 392 | If you want to make an adjustment to this frequency, you could alter your device-tree or you can use the {{{fixfdt}}} script in the bootloader. For example, to change the backlight frequency to {{{10kHz}}} you would run the following command from the bootloader: |
| 393 | {{{#!bash |
| 394 | # The third value of the pwms property is in nanoseconds so to convert to Hz: |
| 395 | # 1 / (100000 / 1000000000) = 10 kHz |
| 396 | setenv fixfdt "fdt addr ${fdt_addr}; fdt set /backlight pwms <0x3d 0 100000>" |
| 397 | }}} |
| 398 | |
| 399 | The Linux backlight core provides sysfs attributes: |
| 400 | - brightness R/W, set the requested brightness level |
| 401 | - actual_brightness RO, the brightness level used by the HW |
| 402 | - max_brightness RO, the maximum brightness level supported |
| 403 | |
| 404 | For full documentation see: |
| 405 | * [https://www.kernel.org/doc/html/latest/gpu/backlight.html Backlight core API] |
| 406 | * [https://www.kernel.org/doc/html/latest/admin-guide/abi-stable.html#abi-file-stable-sysfs-class-backlight sysfs-class-backlight] |
| 407 | |
| 408 | Example: |
| 409 | {{{#!bash |
| 410 | # ls /sys/class/backlight/ |
| 411 | backlight |
| 412 | # cat /sys/class/backlight/backlight/max_brightness # show max brightness value |
| 413 | 100 |
| 414 | # echo 0 > /sys/class/backlight/backlight/brightness # set 0% |
| 415 | # echo 50 > /sys/class/backlight/backlight/brightness # set 50% |
| 416 | # echo 100 > /sys/class/backlight/backlight/brightness # set 100% |
| 417 | }}} |
| 418 | |
| 419 | ===== GPIO |
| 420 | For GPIO based backlight controllers you must configure CONFIG_BACKLIGHT_GPIO to enable the drivers/video/backlight/gpio_backlight.c driver which provides you with just a basic on/off control. Note that you also need the driver for your GPIO controller which in the case of an IMX GPIO is CONFIG_GPIO_MXC. |
| 421 | |
| 422 | This requires also configuring a device-tree node specifying the GPIO. See [https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/leds/backlight/gpio-backlight.yaml Documentation/devicetree/bindings/leds/backlight/gpio-backlight] for details |
| 423 | |
| 424 | Example: |
| 425 | * A backlight controller with a GPIO enable connected to J5.1 BACK_EN# signal: |
| 426 | - GW54xx: |
| 427 | * J5.1: BACK_EN#: MX6QDL_PAD_SD2_CLK |
| 428 | {{{ |
| 429 | / { |
| 430 | backlight { |
| 431 | compatible = "gpio-backlight"; |
| 432 | pinctrl-names = "default"; |
| 433 | pinctrl-0 = <&pinctrl_backlight>; |
| 434 | gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; |
| 435 | default-on; |
| 436 | }; |
| 437 | }; |
| 438 | |
| 439 | &iomuxc { |
| 440 | pinctrl_backlight: backlightgrp { |
| 441 | fsl,pins = < |
| 442 | /* J5.1: BACK_EN# */ |
| 443 | MX6QDL_PAD_SD2_CLK__GPIO1_IO10 0x1b0b1 |
| 444 | >; |
| 445 | }; |
| 446 | }; |
| 447 | }}} |
| 448 | - IMX6 pad SD2_CLK configured as GPIO1_IO10 - this is J5.1 BACK_EN# |
| 449 | |
| 450 | The Linux backlight core provides sysfs attributes: |
| 451 | - brightness R/W, set the requested brightness level |
| 452 | - actual_brightness RO, the brightness level used by the HW |
| 453 | - max_brightness RO, the maximum brightness level supported |
| 454 | |
| 455 | For full documentation see: |
| 456 | * [https://www.kernel.org/doc/html/latest/gpu/backlight.html Backlight core API] |
| 457 | * [https://www.kernel.org/doc/html/latest/admin-guide/abi-stable.html#abi-file-stable-sysfs-class-backlight sysfs-class-backlight] |
| 458 | |
| 459 | Example: |
| 460 | {{{#!bash |
| 461 | # ls /sys/class/backlight/ |
| 462 | backlight |
| 463 | # cat /sys/class/backlight/backlight/max_brightness # show max brightness value |
| 464 | 1 |
| 465 | # echo 0 > /sys/class/backlight/backlight/brightness # set off |
| 466 | # echo 1 > /sys/class/backlight/backlight/brightness # set on |
| 467 | }}} |
| 468 | |
| 469 | |