| 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 | |