Is there anyway we can find the physical address of the BBB's LEDs? I am new to this, but I am trying to write a device driver that access hardware directly. Thank you :).
1 Answers
Yes, you can consult the BBB schematics to find the pins connecting LEDs here. Let me help you with that.
And here are the actual chipset pins.
So, you need to access and control the pins GPIO1_21, GPIO1_22, GPIO1_23 and GPIO1_24. For this, you need to make sure no other driver is configuring/using these pins. Most probably these pins are already being controlled by the existing "gpio-leds" driver. See the device tree node for gpio-led driver below (source)
leds {
pinctrl-names = "default";
pinctrl-0 = <&user_leds_s0>;
compatible = "gpio-leds";
led@2 {
label = "beaglebone:green:heartbeat";
gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
led@3 {
label = "beaglebone:green:mmc0";
gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc0";
default-state = "off";
};
led@4 {
label = "beaglebone:green:usr2";
gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "cpu0";
default-state = "off";
};
led@5 {
label = "beaglebone:green:usr3";
gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc1";
default-state = "off";
};
};
You need to either disable or override the above node to use your own driver. Also make sure to select the correct pinmux setting for your driver so these pins are in gpio mode. You can reuse the default "user_leds_s0" pin group shown below.
&am33xx_pinmux {
pinctrl-names = "default";
pinctrl-0 = <&clkout2_pin>;
user_leds_s0: user_leds_s0 {
pinctrl-single,pins = <
0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */
0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */
0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */
>;
};
Finally, instead of using the physical address of the GPIO pin directly, you should use Linux's GPIO interface as it has already taken control of the GPIO registers. Your final devicetree node for your custom driver could look something like this:
leds {
pinctrl-names = "default";
pinctrl-0 = <&user_leds_s0>;
compatible = "my-gpio-led-driver";
userled-gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>, /* USR0 */
<&gpio1 22 GPIO_ACTIVE_HIGH>, /* USR1 */
<&gpio1 23 GPIO_ACTIVE_HIGH>; /* USR2 */
<&gpio1 24 GPIO_ACTIVE_HIGH>; /* USR3 */
}
In the driver code, you can refer to these GPIO pins as below
struct gpio_desc *usr_led0, *usr_led1, *usr_led2, *usr_led3;
usr_led0 = gpiod_get_index(dev, "userled", 0, GPIOD_OUT_HIGH);
usr_led1 = gpiod_get_index(dev, "userled", 1, GPIOD_OUT_HIGH);
usr_led2 = gpiod_get_index(dev, "userled", 2, GPIOD_OUT_HIGH);
usr_led3 = gpiod_get_index(dev, "userled", 3, GPIOD_OUT_HIGH);
Then you can use linux gpio consumer interface (gpiod_* API) to control the leds.
Follow these links for more details: