Hi all,
recently my 5port EdgeSwitch (previously ToughSwitch) became unmanagable and after some debugging I came to the conclusion the flash chip was corrupt and had to replace it with a blank one. Which in terms caused led to missing eeprom
and config
partitions, ultimately making the Ubiquity's stock firmware unable to run (saying device is 'counterfeit').
So I switched to OpenWRT and despite device being 8/64, it seems to run okay without LuCI. However, for my use case it is crucial to control the PoE switches and their corresponding LEDs.
Firstly, looking at the hardware, all switches and LEDs are controlled via external shift register IC (74HC595
). The devicetree file (at v23.05.5) only describes the PoE switches correctly on "spi-gpio" using the compatible = "fairchild,74hc595";
. So I manually added the definitions for the LEDS in a similar fashion (maybe not a good way
gpio-export {
compatible = "gpio-export";
// LED on port 0
gpio_h595_0 {
gpio-export,name = "ubnt:24v-poe:gpio_0";
gpio-export,output = <0>;
gpios = <&gpio_hc595 0 GPIO_ACTIVE_HIGH>;
};
This then exposes the the IOs in the /sys/class/gpio/
so I would expect I can do echo
to turn the LED on, but this did not work.
echo '1' > /sys/class/gpio/ubnt:24v-poe:gpio_0
After debugging using gpioclt
, gpiod-tools
, io
utilities, I resorted to trusty oscilloscope probing and concluded that the ~OE
pin of the shift registers is actually never driven correctly by GPIO_7
of the AR7240
SoC.
With a bit of luck I found in the SoC's documentation that the GPIO block alternate pin configuration selection register (GPIO_FUNCTION_1
). Which conveniently has a bit EJTAG_DISABLE
that, when set, enables the "function of GPIO_5, GPIO_6 and GPIO_7 as GPIO".
Using io
I could set the bit and voila, the LEDs are now active and I can toggle them via echo
.
Now at this point I could probably automate the io
bit set in the startup scripts, but I decided to experiment setting this bit from the driver probe function (in linux-ath79_generic/linux-5.15.167/drivers/gpio/gpio-ath79.c
)
static int ath79_gpio_probe(struct platform_device *pdev)
{
....
/* Set the EJTAG_DISABLE bit to enable GPIO5,6 and 7 as GPIOs */
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_FUNCTION_1, 1, 1);
....
Example of setting port0 LED by
root@OpenWrt:/# echo '1' > /sys/class/gpio/ubnt:24v-poe:gpio_0/value
So my questions are:
- What is the proper way to control LEDs that are connected over gpio-spi device? Can the devicetree just list them as GPIO ?
- Was there a proper way to set this
EJTAG_DISABLE
bit, for example, by using some compile-time macro like CONFIG_xxx? - How should I go about the modifications I did as I wish to contribute to openwrt? I have pretty much no collaboration experience with open source projects like OpenWRT.
Regards,
Dimitar