Build new kernel module

Hi I'm looking to add a new kernel module/ driver to OpenWrt to support monochromatic Led's

I have never built a kernel module before but Ill take a stab at it but I have a few questions:

Am I best to link to remote Git sources or store sources in the tree?

If I require depends on another kmod can I jam them in the same package and submit?

I'm guessing I setup my package in packages/kernel some think like below: below:

  kmod-group-multicolour
               | -- Makefile
               | -- src
               |      | -- Makefile
               |      | -- kmod-group-multicolour.c
               |      | -- includes.c
               | -- Patches
                           | -- My patch.patch

Out of tree packages have their files in package directory cf openvpn chilicoova
One source file can be put in package, maybe 10, but if it is unmanageable better to have git or checksummed tarball.

1 Like

I want modify the driver slightly so I can drive led colors directly from linux triggers without scripts or as such.

The plan is to include a priority element in the DTS so that only the led with the highest priority is displayed, or that a led with a same priority is staged one after the other or something?

It would enable a single binding to a led or mix led color without complicated user space scripts or as such and enable one to one binding and would work with aliases direct from the DTS and standard linux triggers without sripting.

For example, consider the below DTS sample as a potential configuration for the LED's, offering priority and heartbeat.

All lower priority statuses would be ignored by the driver and it would mean just what is important is showed so you don't get a flickering light show waiting 30 seconds for it to flash through all cycles to obtain the info you want.

monochromatic-leds {
    compatible = "gpio-leds";

    led-0 {
        gpios = <&&tlmm 50 GPIO_ACTIVE_HIGH>;; // green
    };

    led-1 {
        gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>; // red
    };

    led-2 {
        gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>; // blue
    };
};

multicolor-led-group {
    compatible = "leds-group-multicolor";

    multi-led {
      color = <LED_COLOR_ID_RGB>;
      function = LED_FUNCTION_INDICATOR;
      max-brightness = <256>;

      led_system_green: led0 {
        color = <LED_COLOR_ID_GREEN>;
        leds = <&led-0>;
        priority = <0>  //top priority override everything
        linux,default-trigger = "heartbeat";      
      };
    
      led_system_red: led1 {
        color = <LED_COLOR_ID_RED>;
        leds = <&led-1>;
        priority = <1>      
      };
    
      led_system_blue: led2 {
        color = <LED_COLOR_ID_BLUE>;]
        leds = <&led-2>;
        priority = <1>      
      };
    
      led_system_yellow: led3 {
        color = <LED_COLOR_ID_YELLOW>;
        leds = <&led-0>,<&led-1>;
        priority = <1>
      };
    
      led_system_magenta: led4 {
        color = <LED_COLOR_ID_MAGENTA>;
        leds = <&led-1>,<&led-2>;
        priority = <2>  
      };
    
      led_system_cyan: led5 {
        color = <LED_COLOR_ID_CYAN>;
        leds = <&led-0>,<&led-2>;
        priority = <2>  
      };
    
      led_system_white: led6 {
        color = <LED_COLOR_ID_WHITE>;
        leds = <&led-0>,<&led-1>,<&led-2>;
        priority = <3> 
      };
    };
};

If someone has an Idea or better suggestion but I think it will good to make better use of RGB led's as a status as opposed to a glorified power light

Ok so I have setup a PR to try make it work.

add support for led-group-multicolor · professor-jonny/pj_openwrt@9b661c8 (github.com)

I was also suggested that Maybe a better way would be to implement a custom trigger for the LEDs.
This trigger would offer knobs in sysfs so that the user space can indicate what is happening, only problem that is beyond my programing skill as it will require more work.

ok so i built the kernel module and modified a dts for a target but I have a question:
How do I debug the kernel module?
as I don't know what to expect but I thought the grouped led's would show up in sys/class/leds
but i get the below error which means invalid argument i believe.

leds_group_multicolor multicolor-led-group: error -EINVAL: failed to register multicolor LED for (null).
leds_group_multicolor: probe of multicolor-led-group failed with error -22

ok I was having a think about things and implementing priority via the device tree is probably not the best idea but if I was to implement priority of the led's via sysfs eg:

 "echo 1 sys/class/leds/system_led:yellow/priority"
 "echo 2 sys/class/leds/system_led:cyan/priority"

i could also do a debug level sort of thing to hide trivial led statuses:

 "echo 1 sys/class/leds/system_led:yellow/debug_level"
 "echo 2 sys/class/leds/system_led:cyan/debug_level"

I could also implement the colors the same way by having multiple triggers for each primary and secondary color under the same group in sysfs rather than virtual led's within the device tree.

echo heartbeat > /sys/class/leds /system_led:colorfull/yellow/trigger"
echo heartbeat > /sys/class/leds/system_led:colorfull/cyan/trigger"

echo 1 > /sys/class/leds /system_led:colorfull/yellow/priority"
echo 2 > /sys/class/leds/system_led:colorfull/cyan/priority"