| | 192 | |
| | 193 | 2. repurpose the I2C3 and SPI2 pins on a GW730x to GPIO's to be used in userspace via gpiod/sysfs: |
| | 194 | - the dts framgment here has C style includes required for the pinmux definitions and the gpio definitions so we use cpp to pre-process it before compiling |
| | 195 | - the includes here are from the Linux kernel so you must have the linux kernel source to compile this, place the file in the proper directory per the includes (imx8mm-pinfunc.h is in arch/arm64/boot/dts/freescale so that is where we put the file in our example), and compile from the correct directory such that the includes can be found |
| | 196 | {{{#!bash |
| | 197 | # get the kernel source |
| | 198 | git clone https://github.com/Gateworks/linux-venice.git |
| | 199 | cd linux-venice |
| | 200 | cat << EOF > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts |
| | 201 | /* |
| | 202 | * GW73xx GPIO: |
| | 203 | * - repurpose ecspi2 CLK/MISO/MOSI/CS0 as GPIO |
| | 204 | * - repurpose i2c3 CLK/DATA as GPIO |
| | 205 | */ |
| | 206 | |
| | 207 | #include <dt-bindings/gpio/gpio.h> |
| | 208 | |
| | 209 | #include "imx8mm-pinfunc.h" |
| | 210 | |
| | 211 | /dts-v1/; |
| | 212 | /plugin/; |
| | 213 | |
| | 214 | &{/} { |
| | 215 | compatible = "gw,imx8mm-gw73xx-0x"; |
| | 216 | }; |
| | 217 | |
| | 218 | &gpio5 { |
| | 219 | pinctrl-names = "default"; |
| | 220 | pinctrl-0 = <&pinctrl_gpio5_hog>; |
| | 221 | |
| | 222 | /* gpio-hog nodes allow you to give gpios a name and a default state: |
| | 223 | * define one of 'input', 'output-low', or 'output-high' properties |
| | 224 | */ |
| | 225 | gpio5_io10 { |
| | 226 | gpio-hog; |
| | 227 | gpios = <10 GPIO_ACTIVE_HIGH>; |
| | 228 | input; |
| | 229 | line-name = "gpio5_io10"; |
| | 230 | }; |
| | 231 | |
| | 232 | gpio5_io11 { |
| | 233 | gpio-hog; |
| | 234 | gpios = <11 GPIO_ACTIVE_HIGH>; |
| | 235 | input; |
| | 236 | line-name = "gpio5_io11"; |
| | 237 | }; |
| | 238 | |
| | 239 | gpio5_io12 { |
| | 240 | gpio-hog; |
| | 241 | gpios = <12 GPIO_ACTIVE_HIGH>; |
| | 242 | input; |
| | 243 | line-name = "gpio5_io12"; |
| | 244 | }; |
| | 245 | |
| | 246 | gpio5_io13 { |
| | 247 | gpio-hog; |
| | 248 | gpios = <13 GPIO_ACTIVE_HIGH>; |
| | 249 | input; |
| | 250 | line-name = "gpio5_io13"; |
| | 251 | }; |
| | 252 | |
| | 253 | gpio5_io18 { |
| | 254 | gpio-hog; |
| | 255 | gpios = <18 GPIO_ACTIVE_HIGH>; |
| | 256 | input; |
| | 257 | line-name = "gpio5_io18"; |
| | 258 | }; |
| | 259 | |
| | 260 | gpio5_io19 { |
| | 261 | gpio-hog; |
| | 262 | gpios = <19 GPIO_ACTIVE_HIGH>; |
| | 263 | input; |
| | 264 | line-name = "gpio5_io19"; |
| | 265 | }; |
| | 266 | }; |
| | 267 | |
| | 268 | &i2c3 { |
| | 269 | status = "disabled"; |
| | 270 | }; |
| | 271 | |
| | 272 | &ecspi2 { |
| | 273 | status = "disabled"; |
| | 274 | }; |
| | 275 | |
| | 276 | &iomuxc { |
| | 277 | /* pinmux: refer to IMX8M Reference Manuals for the bit configuration |
| | 278 | * - the first definition comes from imx8mm-pinfunc.h and sets the |
| | 279 | * pins NUX_CTL register and input select |
| | 280 | * - the second definition sets the PAD_CTL register that configures |
| | 281 | * things like drive strength, slew rate, pull-up, pull-down, and hysteresis. |
| | 282 | * If you want to be able to read back the pin state you need to set the SION |
| | 283 | * bit by setting bit 30 (as is done below) |
| | 284 | */ |
| | 285 | pinctrl_gpio5_hog: gpio5hoggrp { |
| | 286 | fsl,pins = < |
| | 287 | MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x40000146 /* SION, pull-up, 6x drive str */ |
| | 288 | MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x40000106 /* SION, pull-down, 6x drive str */ |
| | 289 | MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x40000006 /* SION, 6x drive-str */ |
| | 290 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x40000146 |
| | 291 | MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x40000146 |
| | 292 | MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x40000146 |
| | 293 | >; |
| | 294 | }; |
| | 295 | }; |
| | 296 | EOF |
| | 297 | # run through the C pre-processor to handle the includes/macros/defines |
| | 298 | cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp \ |
| | 299 | arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts \ |
| | 300 | imx8mm-venice-gw73xx-0x-gpio.dts.tmp |
| | 301 | # compile with Device Tree Compiler |
| | 302 | dtc -@ -i include/ -I dts -O dtb -o imx8mm-venice-gw73xx-0x-gpio.dtbo \ |
| | 303 | imx8mm-venice-gw73xx-0x-gpio.dts.tmp |
| | 304 | }}} |
| | 305 | - And to use it on a Venice imx8mm-gw73xx-0x make sure the dtbo exits alongside the kernel in the directory the bootscript resides (ie /boot) |
| | 306 | {{{#!bash |
| | 307 | setenv fdt_overlays "imx8mm-venice-gw73xx-0x-gpio.dtbo" |
| | 308 | saveenv |
| | 309 | }}} |
| | 310 | |
| | 311 | 3. repurpose the I2C3 and SPI2 pins on a GW730x to GPIO's (like above) but bind 4 of them to the gpio-keys driver to use as up/down/right/left buttons and bind 2 of them to the gpio-led driver to use as leds via /sys/class/led |
| | 312 | - the dts framgment here has C style includes required for the pinmux definitions and the gpio definitions so we use cpp to pre-process it before compiling |
| | 313 | - we use gpio-keys1 and led-controller1 node names so as not to collide with gpio-keys and led-controller nodes already defined in the gw73xx-0x device-tree |
| | 314 | - the includes here are from the Linux kernel so you must have the linux kernel source to compile this, place the file in the proper directory per the includes (imx8mm-pinfunc.h is in arch/arm64/boot/dts/freescale so that is where we put the file in our example), and compile from the correct directory such that the includes can be found |
| | 315 | {{{#!bash |
| | 316 | # get the kernel source |
| | 317 | git clone https://github.com/Gateworks/linux-venice.git |
| | 318 | cd linux-venice |
| | 319 | cat << EOF > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts |
| | 320 | /* |
| | 321 | * GW73xx GPIO: |
| | 322 | * - repurpose ecspi2 CLK/MISO/MOSI/CS0 as GPIO buttons tied to linux input events |
| | 323 | * - repurpose i2c3 CLK/DATA as GPIO controlled LED's tied to led class |
| | 324 | */ |
| | 325 | |
| | 326 | #include <dt-bindings/gpio/gpio.h> |
| | 327 | #include <dt-bindings/input/linux-event-codes.h> |
| | 328 | #include <dt-bindings/leds/common.h> |
| | 329 | |
| | 330 | #include "imx8mm-pinfunc.h" |
| | 331 | |
| | 332 | /dts-v1/; |
| | 333 | /plugin/; |
| | 334 | |
| | 335 | &{/} { |
| | 336 | compatible = "gw,imx8mm-gw73xx-0x"; |
| | 337 | |
| | 338 | gpio-keys1 { |
| | 339 | compatible = "gpio-keys"; |
| | 340 | pinctrl-names = "default"; |
| | 341 | pinctrl-0 = <&pinctrl_gpio_keys1>; |
| | 342 | |
| | 343 | key-left { |
| | 344 | label = "left"; |
| | 345 | gpios = <&gpio5 10 GPIO_ACTIVE_LOW>; |
| | 346 | linux,code = <KEY_LEFT>; |
| | 347 | }; |
| | 348 | |
| | 349 | key-right { |
| | 350 | label = "right"; |
| | 351 | gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; |
| | 352 | linux,code = <KEY_RIGHT>; |
| | 353 | }; |
| | 354 | |
| | 355 | key-up { |
| | 356 | label = "up"; |
| | 357 | gpios = <&gpio5 12 GPIO_ACTIVE_LOW>; |
| | 358 | linux,code = <KEY_UP>; |
| | 359 | }; |
| | 360 | |
| | 361 | key-down { |
| | 362 | label = "down"; |
| | 363 | gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; |
| | 364 | linux,code = <KEY_DOWN>; |
| | 365 | }; |
| | 366 | }; |
| | 367 | |
| | 368 | led-controller1 { |
| | 369 | compatible = "gpio-leds"; |
| | 370 | pinctrl-names = "default"; |
| | 371 | pinctrl-0 = <&pinctrl_gpio_leds1>; |
| | 372 | |
| | 373 | led-0 { |
| | 374 | function = LED_FUNCTION_STATUS; |
| | 375 | color = <LED_COLOR_ID_GREEN>; |
| | 376 | gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>; |
| | 377 | default-state = "on"; |
| | 378 | linux,default-trigger = "heartbeat"; |
| | 379 | }; |
| | 380 | |
| | 381 | led-1 { |
| | 382 | function = LED_FUNCTION_STATUS; |
| | 383 | color = <LED_COLOR_ID_RED>; |
| | 384 | gpios = <&gpio5 19 GPIO_ACTIVE_HIGH>; |
| | 385 | default-state = "off"; |
| | 386 | }; |
| | 387 | }; |
| | 388 | }; |
| | 389 | |
| | 390 | &i2c3 { |
| | 391 | status = "disabled"; |
| | 392 | }; |
| | 393 | |
| | 394 | &ecspi2 { |
| | 395 | status = "disabled"; |
| | 396 | }; |
| | 397 | |
| | 398 | &iomuxc { |
| | 399 | /* pinmux: refer to IMX8M Reference Manuals for the bit configuration |
| | 400 | * - the first definition comes from imx8mm-pinfunc.h and sets the |
| | 401 | * pins NUX_CTL register and input select |
| | 402 | * - the second definition sets the PAD_CTL register that configures |
| | 403 | * things like drive strength, slew rate, pull-up, pull-down, and hys |
| | 404 | teresis. |
| | 405 | * If you want to be able to read back the pin state you need to set |
| | 406 | the SION |
| | 407 | * bit by setting bit 30 (as is done below) |
| | 408 | * below the pins are configured with internal pull-up and 6x drive str |
| | 409 | */ |
| | 410 | pinctrl_gpio_keys1: gpiokeys1grp { |
| | 411 | fsl,pins = < |
| | 412 | MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x146 |
| | 413 | MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x146 |
| | 414 | MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x146 |
| | 415 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x146 |
| | 416 | >; |
| | 417 | }; |
| | 418 | |
| | 419 | pinctrl_gpio_leds1: gpioleds1grp { |
| | 420 | fsl,pins = < |
| | 421 | MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x146 |
| | 422 | MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x146 |
| | 423 | >; |
| | 424 | }; |
| | 425 | }; |
| | 426 | EOF |
| | 427 | # run through the C pre-processor to handle the includes/macros/defines |
| | 428 | cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp \ |
| | 429 | arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts \ |
| | 430 | imx8mm-venice-gw73xx-0x-gpio.dts.tmp |
| | 431 | # compile with Device Tree Compiler |
| | 432 | dtc -@ -i include/ -I dts -O dtb -o imx8mm-venice-gw73xx-0x-gpio.dtbo \ |
| | 433 | imx8mm-venice-gw73xx-0x-gpio.dts.tmp |
| | 434 | }}} |
| | 435 | - And to use it on a Venice imx8mm-gw73xx-0x make sure the dtbo exits alongside the kernel in the directory the bootscript resides (ie /boot) |
| | 436 | {{{#!bash |
| | 437 | setenv fdt_overlays "imx8mm-venice-gw73xx-0x-gpio.dtbo" |
| | 438 | saveenv |
| | 439 | }}} |
| | 440 | |