Remork that said, is there any way to permanently alter the mode to default to, say, output/pulldown aka 0x07?
Short answer is no.
Long answer:
When the board powers up, pins are in an undefined state. A couple of seconds later, uboot will have parsed the device tree, added any overlays and passed it on to the kernel, which will have started booting and set the pins to the desired configuration. This configuration - as specified at the bottom of the P8/P9 documents - pertains to:
- mode: which of several signals is connected to the pin via the multiplexer. This can be GPIO or any of the other pin-specific ones.
- input enable: is the input receiver enabled? This tells you whether you can receive an input signal on that pin (i.e.: is the input stage enabled). The only penalty of enabling this is slightly more noise on the pin when using it as an output. This is mostly a non-issue, so it can be always be enabled.
- Internal pullup/pulldown. These are "weak" resistors (in the 50k range I think, although I don't think I ever found the specs anywhere) which set the state (high or low) of the pin in absence of an externally or internally applied voltage. For instance, when a GPIO is set to input and an external switch is connected, then you can avoid wiring an external pullup/pulldown resistor and simply have a switch between the pin and gnd using an internal pullup (e.g.: P9_27), or having the switch between the pin and 3.3V using an internal pulldown. I wouldn't rely on this internal resistor to be able to drive your external transistor.
- slew control. I never played around with this one. I assume it could be useful for debouncing? In most (all?) settings it is set to "fast"
Once the pin settings is applied, at some later point the driver for the peripheral will be loaded and will read input values and/or apply internal signals to the pin. For instance, when the Bela program starts, the audio peripheral pins will be used to transmit data and clocks to and from the audio codec.
When in GPIO mode with "input enable", a signal from the GPIO peripheral is connected to the pin. The GPIO peripheral can then set that channel to input or output. When in output mode, the peripheral will apply an internal voltage to the pin, either 0 or 3.3V, and this value will be made available on the pin with decent current driving capabilities (between 6ma and 8ma). When the GPIO is an output, the presence of a pullup/pulldown is irrelevant, because you will be actively setting the output buffer. I don't think it's straightforward to set a GPIO to an output and set its value from the device tree, so that will have to be done at some later point at system boot (e.g.: by running a script which writes to /sys/class/gpio/...
).
So, there is a delay of a couple of seconds between power on and being able to set the pin MODE and then there is an extra delay in setting the actual pin value if you want it to be a GPIO output. This is why I suggest using an external pullup/pulldown. If it's of the order of 10k or less, it should be small enough to counteract any internal pullup/pulldown. Then, as long as the pullup/pulldown is large enough, when the pin is in your control, you can set it high or low via the GPIO peripheral regardless the value and polarity of any of the internal and/or external pullup/pulldown.