BPF List
 help / color / mirror / Atom feed
* [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
@ 2025-01-21 22:31 Werner Sembach
  2025-02-01  4:39 ` Armin Wolf
  0 siblings, 1 reply; 7+ messages in thread
From: Werner Sembach @ 2025-01-21 22:31 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen, wse, bentiss
  Cc: dri-devel, jelle, jikos, lee, linux-input, linux-kernel,
	linux-leds, miguel.ojeda.sandonis, ojeda, onitake, pavel, cs,
	platform-driver-x86, bpf

Hi,
after some other work, picked this up again.
Only coding style changes vs v4.


I now got my feet a little wet with hid-bpf regarding something else, and
with that knowledge I would leave the long arrays in the beginning in the
kernel code for the time being:

sirius_16_ansii_kbl_mapping and sirius_16_iso_kbl_mapping are required
during initialization so they have to exist in the kernel code anyway.

report_descriptor will most likly not change even for future models and
afaik having report_descriptors in kernel drivers is not unheard of.

So the only things that could be meaningfully moved to a hid-bpf program
are the sirius_16_*_kbl_mapping_pos_* arrays. But for these is have to give
out some fallback value anyway for the case where a hid-bpf file is missing
or fails to load. So why not use real world values from my test device for
these values?

As soon as there is a future device that can use the same driver with just
these pos arrays different, then I would implement that change via a bpf
program instead of a change to the kernel driver.

Let me know if you too think this is a sensefull approach?


Another question: Would this patch need to wait for a userspace
implementation of lamp array before it can get accepted?


The folder structure and naming scheme with nb04 is im preparation for
other parts of tuxedo-drivers to be upstreamed. NB04 is one of the
board_vendor dmi strings on TUXEDO devices that aligns with which part of
tuxedo-drivers implements the features of that device. They are independent
of each other so I plan to put them in different subfolders to reflect
that.

Best regards,
Werner Sembach

Werner Sembach (1):
  platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices

 MAINTAINERS                                   |   6 +
 drivers/platform/x86/Kconfig                  |   2 +
 drivers/platform/x86/Makefile                 |   3 +
 drivers/platform/x86/tuxedo/Kbuild            |   6 +
 drivers/platform/x86/tuxedo/Kconfig           |   6 +
 drivers/platform/x86/tuxedo/nb04/Kbuild       |   9 +
 drivers/platform/x86/tuxedo/nb04/Kconfig      |  14 +
 .../platform/x86/tuxedo/nb04/wmi_ab_init.c    | 103 +++
 .../platform/x86/tuxedo/nb04/wmi_ab_init.h    |  18 +
 .../x86/tuxedo/nb04/wmi_ab_virt_lamparray.c   | 772 ++++++++++++++++++
 .../x86/tuxedo/nb04/wmi_ab_virt_lamparray.h   |  18 +
 .../platform/x86/tuxedo/nb04/wmi_xx_util.c    |  97 +++
 .../platform/x86/tuxedo/nb04/wmi_xx_util.h    | 112 +++
 13 files changed, 1166 insertions(+)
 create mode 100644 drivers/platform/x86/tuxedo/Kbuild
 create mode 100644 drivers/platform/x86/tuxedo/Kconfig
 create mode 100644 drivers/platform/x86/tuxedo/nb04/Kbuild
 create mode 100644 drivers/platform/x86/tuxedo/nb04/Kconfig
 create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_init.c
 create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_init.h
 create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_virt_lamparray.c
 create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_virt_lamparray.h
 create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_xx_util.c
 create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_xx_util.h

-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
  2025-01-21 22:31 [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices Werner Sembach
@ 2025-02-01  4:39 ` Armin Wolf
  2025-02-01  8:48   ` Pavel Machek
  2025-02-01 19:49   ` Werner Sembach
  0 siblings, 2 replies; 7+ messages in thread
From: Armin Wolf @ 2025-02-01  4:39 UTC (permalink / raw)
  To: Werner Sembach, hdegoede, ilpo.jarvinen, bentiss
  Cc: dri-devel, jelle, jikos, lee, linux-input, linux-kernel,
	linux-leds, miguel.ojeda.sandonis, ojeda, onitake, pavel, cs,
	platform-driver-x86, bpf

Am 21.01.25 um 23:31 schrieb Werner Sembach:

> Hi,
> after some other work, picked this up again.
> Only coding style changes vs v4.
>
>
> I now got my feet a little wet with hid-bpf regarding something else, and
> with that knowledge I would leave the long arrays in the beginning in the
> kernel code for the time being:
>
> sirius_16_ansii_kbl_mapping and sirius_16_iso_kbl_mapping are required
> during initialization so they have to exist in the kernel code anyway.
>
> report_descriptor will most likly not change even for future models and
> afaik having report_descriptors in kernel drivers is not unheard of.
>
> So the only things that could be meaningfully moved to a hid-bpf program
> are the sirius_16_*_kbl_mapping_pos_* arrays. But for these is have to give
> out some fallback value anyway for the case where a hid-bpf file is missing
> or fails to load. So why not use real world values from my test device for
> these values?
>
> As soon as there is a future device that can use the same driver with just
> these pos arrays different, then I would implement that change via a bpf
> program instead of a change to the kernel driver.
>
> Let me know if you too think this is a sensefull approach?
>
>
> Another question: Would this patch need to wait for a userspace
> implementation of lamp array before it can get accepted?

It would be nice if you could test the LampArray implementation. But other than that
userspace can catch up later.

Still, i am interested in the opinion of the LED maintainers regarding the fake HID interface.

Thanks,
Armin Wolf

>
> The folder structure and naming scheme with nb04 is im preparation for
> other parts of tuxedo-drivers to be upstreamed. NB04 is one of the
> board_vendor dmi strings on TUXEDO devices that aligns with which part of
> tuxedo-drivers implements the features of that device. They are independent
> of each other so I plan to put them in different subfolders to reflect
> that.
>
> Best regards,
> Werner Sembach
>
> Werner Sembach (1):
>    platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
>
>   MAINTAINERS                                   |   6 +
>   drivers/platform/x86/Kconfig                  |   2 +
>   drivers/platform/x86/Makefile                 |   3 +
>   drivers/platform/x86/tuxedo/Kbuild            |   6 +
>   drivers/platform/x86/tuxedo/Kconfig           |   6 +
>   drivers/platform/x86/tuxedo/nb04/Kbuild       |   9 +
>   drivers/platform/x86/tuxedo/nb04/Kconfig      |  14 +
>   .../platform/x86/tuxedo/nb04/wmi_ab_init.c    | 103 +++
>   .../platform/x86/tuxedo/nb04/wmi_ab_init.h    |  18 +
>   .../x86/tuxedo/nb04/wmi_ab_virt_lamparray.c   | 772 ++++++++++++++++++
>   .../x86/tuxedo/nb04/wmi_ab_virt_lamparray.h   |  18 +
>   .../platform/x86/tuxedo/nb04/wmi_xx_util.c    |  97 +++
>   .../platform/x86/tuxedo/nb04/wmi_xx_util.h    | 112 +++
>   13 files changed, 1166 insertions(+)
>   create mode 100644 drivers/platform/x86/tuxedo/Kbuild
>   create mode 100644 drivers/platform/x86/tuxedo/Kconfig
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/Kbuild
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/Kconfig
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_init.c
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_init.h
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_virt_lamparray.c
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_virt_lamparray.h
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_xx_util.c
>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_xx_util.h
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
  2025-02-01  4:39 ` Armin Wolf
@ 2025-02-01  8:48   ` Pavel Machek
  2025-02-06 16:18     ` Werner Sembach
  2025-02-01 19:49   ` Werner Sembach
  1 sibling, 1 reply; 7+ messages in thread
From: Pavel Machek @ 2025-02-01  8:48 UTC (permalink / raw)
  To: Armin Wolf
  Cc: Werner Sembach, hdegoede, ilpo.jarvinen, bentiss, dri-devel,
	jelle, jikos, lee, linux-input, linux-kernel, linux-leds,
	miguel.ojeda.sandonis, ojeda, onitake, cs, platform-driver-x86,
	bpf

[-- Attachment #1: Type: text/plain, Size: 1892 bytes --]

Hi!

> > I now got my feet a little wet with hid-bpf regarding something else, and
> > with that knowledge I would leave the long arrays in the beginning in the
> > kernel code for the time being:
> > 
> > sirius_16_ansii_kbl_mapping and sirius_16_iso_kbl_mapping are required
> > during initialization so they have to exist in the kernel code anyway.
> > 
> > report_descriptor will most likly not change even for future models and
> > afaik having report_descriptors in kernel drivers is not unheard of.
> > 
> > So the only things that could be meaningfully moved to a hid-bpf program
> > are the sirius_16_*_kbl_mapping_pos_* arrays. But for these is have to give
> > out some fallback value anyway for the case where a hid-bpf file is missing
> > or fails to load. So why not use real world values from my test device for
> > these values?
> > 
> > As soon as there is a future device that can use the same driver with just
> > these pos arrays different, then I would implement that change via a bpf
> > program instead of a change to the kernel driver.
> > 
> > Let me know if you too think this is a sensefull approach?
> > 
> > 
> > Another question: Would this patch need to wait for a userspace
> > implementation of lamp array before it can get accepted?
> 
> It would be nice if you could test the LampArray implementation. But other than that
> userspace can catch up later.
> 
> Still, i am interested in the opinion of the LED maintainers
> regarding the fake HID interface.

Comments from previous review were not addressed.

Most importantly, this is not a way to do kernel interface. We want
reasonable interface that can be documented and modified as needed. We
want to pass /dev/input to userspace, not raw HID. This is not ok.

Best regards,
								Pavel
-- 
People of Russia, stop Putin before his war on Ukraine escalates.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
  2025-02-01  4:39 ` Armin Wolf
  2025-02-01  8:48   ` Pavel Machek
@ 2025-02-01 19:49   ` Werner Sembach
  1 sibling, 0 replies; 7+ messages in thread
From: Werner Sembach @ 2025-02-01 19:49 UTC (permalink / raw)
  To: Armin Wolf, hdegoede, ilpo.jarvinen, bentiss
  Cc: dri-devel, jelle, jikos, lee, linux-input, linux-kernel,
	linux-leds, miguel.ojeda.sandonis, ojeda, onitake, pavel, cs,
	platform-driver-x86, bpf

[-- Attachment #1: Type: text/plain, Size: 4007 bytes --]


Am 01.02.25 um 05:39 schrieb Armin Wolf:
> Am 21.01.25 um 23:31 schrieb Werner Sembach:
>
>> Hi,
>> after some other work, picked this up again.
>> Only coding style changes vs v4.
>>
>>
>> I now got my feet a little wet with hid-bpf regarding something else, and
>> with that knowledge I would leave the long arrays in the beginning in the
>> kernel code for the time being:
>>
>> sirius_16_ansii_kbl_mapping and sirius_16_iso_kbl_mapping are required
>> during initialization so they have to exist in the kernel code anyway.
>>
>> report_descriptor will most likly not change even for future models and
>> afaik having report_descriptors in kernel drivers is not unheard of.
>>
>> So the only things that could be meaningfully moved to a hid-bpf program
>> are the sirius_16_*_kbl_mapping_pos_* arrays. But for these is have to give
>> out some fallback value anyway for the case where a hid-bpf file is missing
>> or fails to load. So why not use real world values from my test device for
>> these values?
>>
>> As soon as there is a future device that can use the same driver with just
>> these pos arrays different, then I would implement that change via a bpf
>> program instead of a change to the kernel driver.
>>
>> Let me know if you too think this is a sensefull approach?
>>
>>
>> Another question: Would this patch need to wait for a userspace
>> implementation of lamp array before it can get accepted?
>
> It would be nice if you could test the LampArray implementation. But other 
> than that
> userspace can catch up later.
I tested with the attached programs (I directly edited the source files to test 
different things, this is just a snapshot).
>
> Still, i am interested in the opinion of the LED maintainers regarding the 
> fake HID interface.
>
> Thanks,
> Armin Wolf
>
>>
>> The folder structure and naming scheme with nb04 is im preparation for
>> other parts of tuxedo-drivers to be upstreamed. NB04 is one of the
>> board_vendor dmi strings on TUXEDO devices that aligns with which part of
>> tuxedo-drivers implements the features of that device. They are independent
>> of each other so I plan to put them in different subfolders to reflect
>> that.
>>
>> Best regards,
>> Werner Sembach
>>
>> Werner Sembach (1):
>>    platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
>>
>>   MAINTAINERS                                   |   6 +
>>   drivers/platform/x86/Kconfig                  |   2 +
>>   drivers/platform/x86/Makefile                 |   3 +
>>   drivers/platform/x86/tuxedo/Kbuild            |   6 +
>>   drivers/platform/x86/tuxedo/Kconfig           |   6 +
>>   drivers/platform/x86/tuxedo/nb04/Kbuild       |   9 +
>>   drivers/platform/x86/tuxedo/nb04/Kconfig      |  14 +
>>   .../platform/x86/tuxedo/nb04/wmi_ab_init.c    | 103 +++
>>   .../platform/x86/tuxedo/nb04/wmi_ab_init.h    |  18 +
>>   .../x86/tuxedo/nb04/wmi_ab_virt_lamparray.c   | 772 ++++++++++++++++++
>>   .../x86/tuxedo/nb04/wmi_ab_virt_lamparray.h   |  18 +
>>   .../platform/x86/tuxedo/nb04/wmi_xx_util.c    |  97 +++
>>   .../platform/x86/tuxedo/nb04/wmi_xx_util.h    | 112 +++
>>   13 files changed, 1166 insertions(+)
>>   create mode 100644 drivers/platform/x86/tuxedo/Kbuild
>>   create mode 100644 drivers/platform/x86/tuxedo/Kconfig
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/Kbuild
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/Kconfig
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_init.c
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_init.h
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_virt_lamparray.c
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_ab_virt_lamparray.h
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_xx_util.c
>>   create mode 100644 drivers/platform/x86/tuxedo/nb04/wmi_xx_util.h
>>

[-- Attachment #2: CMakeLists.txt --]
[-- Type: text/plain, Size: 339 bytes --]

cmake_minimum_required(VERSION 3.5)

project(LampArrayPlayground)

add_executable(lap lap.cpp)
target_compile_features(lap PRIVATE cxx_std_17)

add_executable(laploop laploop.cpp)
target_compile_features(laploop PRIVATE cxx_std_17)

add_executable(laploopsingle laploopsingle.cpp)
target_compile_features(laploopsingle PRIVATE cxx_std_17)

[-- Attachment #3: lap.cpp --]
[-- Type: text/x-c++src, Size: 7559 bytes --]

#include <iostream>
#include <iomanip>

#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/hidraw.h>
#include <cstdlib>
#include <cstdint>

using std::cout, std::cerr, std::endl, std::hex, std::setw, std::setfill, std::ios;

struct __attribute__ ((packed)) lamp_array_attributes_report {
    const uint8_t report_id = 1;
    uint16_t lamp_count;
    uint32_t bounding_box_width_in_micrometers;
    uint32_t bounding_box_height_in_micrometers;
    uint32_t bounding_box_depth_in_micrometers;
    uint32_t lamp_array_kind;
    uint32_t min_update_interval_in_microseconds;
};

struct __attribute__ ((packed)) lamp_attributes_request_report {
    const uint8_t report_id = 2;
    uint16_t lamp_id;
};

struct __attribute__ ((packed)) lamp_attributes_response_report {
    const uint8_t report_id = 3;
    uint16_t lamp_id;
    uint32_t position_x_in_micrometers;
    uint32_t position_y_in_micrometers;
    uint32_t position_z_in_micrometers;
    uint32_t update_latency_in_microseconds;
    uint32_t lamp_purpose;
    uint8_t red_level_count;
    uint8_t green_level_count;
    uint8_t blue_level_count;
    uint8_t intensity_level_count;
    uint8_t is_programmable;
    uint8_t input_binding;
};

struct __attribute__ ((packed)) lamp_multi_update_report {
    const uint8_t report_id = 4;
    uint8_t lamp_count;
    uint8_t lamp_update_flags;
    uint16_t lamp_id[8];
    struct {
        uint8_t red_update_channel;
        uint8_t green_update_channel;
        uint8_t blue_update_channel;
        uint8_t intensity_update_channel;
    } update_channels[8];
};

struct __attribute__ ((packed)) lamp_range_update_report {
    const uint8_t report_id = 5;
    uint8_t lamp_update_flags;
    uint16_t lamp_id_start;
    uint16_t lamp_id_end;
    uint8_t red_update_channel;
    uint8_t green_update_channel;
    uint8_t blue_update_channel;
    uint8_t intensity_update_channel;
};

struct __attribute__ ((packed)) lamp_array_control_report {
    const uint8_t report_id = 6;
    uint8_t autonomous_mode;
};

int main(int argc, char *argv[])
{
    if (argc < 2) {
        cout << "Usage: " << argv[0] << "<hidraw_path>" << endl;
        return EXIT_SUCCESS;
    }

    int hidraw = open(argv[1], O_WRONLY|O_NONBLOCK);
    if (hidraw < 0) {
        cerr << "main: open(\"" << argv[1] << "\", O_WRONLY|O_NONBLOCK) failed." << endl;
        return hidraw;
    }

    struct hidraw_report_descriptor report_descriptor;

    int result = ioctl(hidraw, HIDIOCGRDESCSIZE, &report_descriptor.size);
    if (result < 0) {
        cerr << "main: ioctl(hidraw, HIDIOCGRDESCSIZE, &report_descriptor.size) failed." << endl;
        close(hidraw);
        return result;
    }

    result = ioctl(hidraw, HIDIOCGRDESC, &report_descriptor);
    if (result < 0) {
        cerr << "main: ioctl(hidraw, HIDIOCGRDESC, &report_descriptor) failed." << endl;
        close(hidraw);
        return result;
    }

    ios default_cout_state(nullptr);
    default_cout_state.copyfmt(cout);

    cout << "Report descriptor:" << endl;
    cout << hex << setfill('0');
    for (int i = 0; i < report_descriptor.size; ++i) {
        if (i % 8 != 7 && i != report_descriptor.size - 1) {
            cout << setw(2) << (int)report_descriptor.value[i] << " ";
        }
        else {
            cout << setw(2) << (int)report_descriptor.value[i] << endl;
        }
    }
    cout << endl;
    cout.copyfmt(default_cout_state);

    struct lamp_array_attributes_report lamp_array_attributes_report;
    result = ioctl(hidraw, HIDIOCGFEATURE(sizeof(struct lamp_array_attributes_report)), &lamp_array_attributes_report);
    if (result < 0) {
        cerr << "ioctl(hidraw, HIDIOCGFEATURE(sizeof(struct lamp_array_attributes_report)) failed." << endl;
        close(hidraw);
        return result;
    }

    cout << "lamp count: " << lamp_array_attributes_report.lamp_count << endl;
    cout << "bounding box depth: " <<  lamp_array_attributes_report.bounding_box_depth_in_micrometers << endl;
    cout << "bounding box height: " <<  lamp_array_attributes_report.bounding_box_height_in_micrometers << endl;
    cout << "bounding box width: " <<  lamp_array_attributes_report.bounding_box_width_in_micrometers << endl;
    cout << endl;

    cout << "Attributes Report:" << endl;
    cout << hex << setfill('0');
    for (int i = 0; i < sizeof(struct lamp_array_attributes_report); ++i) {
        if (i % 8 != 7 && i != sizeof(struct lamp_array_attributes_report) - 1) {
            cout << setw(2) << (int)((uint8_t *)&lamp_array_attributes_report)[i] << " ";
        }
        else {
            cout << setw(2) << (int)((uint8_t *)&lamp_array_attributes_report)[i] << endl;
        }
    }
    cout.copyfmt(default_cout_state);

    struct lamp_array_control_report lamp_array_control_report;
    lamp_array_control_report.autonomous_mode = 0;
    result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_array_control_report)), &lamp_array_control_report);
    if (result < 0) {
        cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_array_control_report)), lamp_array_control_report) failed." << endl;
        close(hidraw);
        return result;
    }

    struct lamp_range_update_report lamp_range_update_report;
    lamp_range_update_report.red_update_channel = 0xff;
    lamp_range_update_report.green_update_channel = 0xff;
    lamp_range_update_report.blue_update_channel = 0xff;
    lamp_range_update_report.intensity_update_channel = 0xff;
    lamp_range_update_report.lamp_update_flags = 0x01;
    lamp_range_update_report.lamp_id_start = 0;
    lamp_range_update_report.lamp_id_end = lamp_array_attributes_report.lamp_count - 1;
    result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), &lamp_range_update_report);
    if (result < 0) {
        cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), lamp_range_update_report) failed." << endl;
        close(hidraw);
        return result;
    }

    struct lamp_multi_update_report lamp_multi_update_report;
    lamp_multi_update_report.lamp_count = 3;
    lamp_multi_update_report.lamp_id[0] = 0;
    lamp_multi_update_report.update_channels[0].red_update_channel = 0xff;
    lamp_multi_update_report.update_channels[0].green_update_channel = 0;
    lamp_multi_update_report.update_channels[0].blue_update_channel = 0;
    lamp_multi_update_report.update_channels[0].intensity_update_channel = 0xff;
    lamp_multi_update_report.lamp_id[1] = 1;
    lamp_multi_update_report.update_channels[1].red_update_channel = 0;
    lamp_multi_update_report.update_channels[1].green_update_channel = 0xff;
    lamp_multi_update_report.update_channels[1].blue_update_channel = 0;
    lamp_multi_update_report.update_channels[1].intensity_update_channel = 0xff;
    lamp_multi_update_report.lamp_id[2] = 2;
    lamp_multi_update_report.update_channels[2].red_update_channel = 0;
    lamp_multi_update_report.update_channels[2].green_update_channel = 0;
    lamp_multi_update_report.update_channels[2].blue_update_channel = 0xff;
    lamp_multi_update_report.update_channels[2].intensity_update_channel = 0xff;
    lamp_multi_update_report.lamp_update_flags = 0x01;
    result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), &lamp_multi_update_report);
    if (result < 0) {
        cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), lamp_multi_update_report) failed." << endl;
        close(hidraw);
        return result;
    }

    close(hidraw);

    return EXIT_SUCCESS;
}

[-- Attachment #4: laploop.cpp --]
[-- Type: text/x-c++src, Size: 4334 bytes --]

#include <iostream>
#include <iomanip>

#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/hidraw.h>
#include <cstdlib>
#include <cstdint>

using std::cout, std::cerr, std::endl, std::hex, std::setw, std::setfill, std::ios;

struct __attribute__ ((packed)) lamp_array_attributes_report {
    const uint8_t report_id = 1;
    uint16_t lamp_count;
    uint32_t bounding_box_width_in_micrometers;
    uint32_t bounding_box_height_in_micrometers;
    uint32_t bounding_box_depth_in_micrometers;
    uint32_t lamp_array_kind;
    uint32_t min_update_interval_in_microseconds;
};

struct __attribute__ ((packed)) lamp_attributes_request_report {
    const uint8_t report_id = 2;
    uint16_t lamp_id;
};

struct __attribute__ ((packed)) lamp_attributes_response_report {
    const uint8_t report_id = 3;
    uint16_t lamp_id;
    uint32_t position_x_in_micrometers;
    uint32_t position_y_in_micrometers;
    uint32_t position_z_in_micrometers;
    uint32_t update_latency_in_microseconds;
    uint32_t lamp_purpose;
    uint8_t red_level_count;
    uint8_t green_level_count;
    uint8_t blue_level_count;
    uint8_t intensity_level_count;
    uint8_t is_programmable;
    uint8_t input_binding;
};

struct __attribute__ ((packed)) lamp_multi_update_report {
    const uint8_t report_id = 4;
    uint8_t lamp_count;
    uint8_t lamp_update_flags;
    uint16_t lamp_id[8];
    struct {
        uint8_t red_update_channel;
        uint8_t green_update_channel;
        uint8_t blue_update_channel;
        uint8_t intensity_update_channel;
    } update_channels[8];
};

struct __attribute__ ((packed)) lamp_range_update_report {
    const uint8_t report_id = 5;
    uint8_t lamp_update_flags;
    uint16_t lamp_id_start;
    uint16_t lamp_id_end;
    uint8_t red_update_channel;
    uint8_t green_update_channel;
    uint8_t blue_update_channel;
    uint8_t intensity_update_channel;
};

struct __attribute__ ((packed)) lamp_array_control_report {
    const uint8_t report_id = 6;
    uint8_t autonomous_mode;
};

int main(int argc, char *argv[])
{
    if (argc < 2) {
        cout << "Usage: " << argv[0] << "<hidraw_path>" << endl;
        return EXIT_SUCCESS;
    }

    int hidraw = open(argv[1], O_WRONLY|O_NONBLOCK);
    if (hidraw < 0) {
        cerr << "main: open(\"" << argv[1] << "\", O_WRONLY|O_NONBLOCK) failed." << endl;
        return hidraw;
    }

    int result = 0;

    struct lamp_range_update_report lamp_range_update_report;
    lamp_range_update_report.intensity_update_channel = 0xff;
    lamp_range_update_report.lamp_update_flags = 0x01;
    lamp_range_update_report.lamp_id_start = 0;
    lamp_range_update_report.lamp_id_end = 101;

    while (true) {
        lamp_range_update_report.red_update_channel = 0xff;
        lamp_range_update_report.green_update_channel = 0;
        lamp_range_update_report.blue_update_channel = 0;
        result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), &lamp_range_update_report);
        if (result < 0) {
            cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), lamp_range_update_report) failed." << endl;
            close(hidraw);
            return result;
        }

        lamp_range_update_report.red_update_channel = 0;
        lamp_range_update_report.green_update_channel = 0xff;
        lamp_range_update_report.blue_update_channel = 0;
        result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), &lamp_range_update_report);
        if (result < 0) {
            cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), lamp_range_update_report) failed." << endl;
            close(hidraw);
            return result;
        }

        lamp_range_update_report.red_update_channel = 0;
        lamp_range_update_report.green_update_channel = 0;
        lamp_range_update_report.blue_update_channel = 0xff;
        result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), &lamp_range_update_report);
        if (result < 0) {
            cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), lamp_range_update_report) failed." << endl;
            close(hidraw);
            return result;
        }
    }

    close(hidraw);

    return EXIT_SUCCESS;
}

[-- Attachment #5: laploopsingle.cpp --]
[-- Type: text/x-c++src, Size: 4518 bytes --]

#include <iostream>
#include <iomanip>

#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/hidraw.h>
#include <cstdlib>
#include <cstdint>

using std::cout, std::cerr, std::endl, std::hex, std::setw, std::setfill, std::ios;

struct __attribute__ ((packed)) lamp_array_attributes_report {
    const uint8_t report_id = 1;
    uint16_t lamp_count;
    uint32_t bounding_box_width_in_micrometers;
    uint32_t bounding_box_height_in_micrometers;
    uint32_t bounding_box_depth_in_micrometers;
    uint32_t lamp_array_kind;
    uint32_t min_update_interval_in_microseconds;
};

struct __attribute__ ((packed)) lamp_attributes_request_report {
    const uint8_t report_id = 2;
    uint16_t lamp_id;
};

struct __attribute__ ((packed)) lamp_attributes_response_report {
    const uint8_t report_id = 3;
    uint16_t lamp_id;
    uint32_t position_x_in_micrometers;
    uint32_t position_y_in_micrometers;
    uint32_t position_z_in_micrometers;
    uint32_t update_latency_in_microseconds;
    uint32_t lamp_purpose;
    uint8_t red_level_count;
    uint8_t green_level_count;
    uint8_t blue_level_count;
    uint8_t intensity_level_count;
    uint8_t is_programmable;
    uint8_t input_binding;
};

struct __attribute__ ((packed)) lamp_multi_update_report {
    const uint8_t report_id = 4;
    uint8_t lamp_count;
    uint8_t lamp_update_flags;
    uint16_t lamp_id[8];
    struct {
        uint8_t red_update_channel;
        uint8_t green_update_channel;
        uint8_t blue_update_channel;
        uint8_t intensity_update_channel;
    } update_channels[8];
};

struct __attribute__ ((packed)) lamp_range_update_report {
    const uint8_t report_id = 5;
    uint8_t lamp_update_flags;
    uint16_t lamp_id_start;
    uint16_t lamp_id_end;
    uint8_t red_update_channel;
    uint8_t green_update_channel;
    uint8_t blue_update_channel;
    uint8_t intensity_update_channel;
};

struct __attribute__ ((packed)) lamp_array_control_report {
    const uint8_t report_id = 6;
    uint8_t autonomous_mode;
};

int main(int argc, char *argv[])
{
    if (argc < 2) {
        cout << "Usage: " << argv[0] << "<hidraw_path>" << endl;
        return EXIT_SUCCESS;
    }

    int hidraw = open(argv[1], O_WRONLY|O_NONBLOCK);
    if (hidraw < 0) {
        cerr << "main: open(\"" << argv[1] << "\", O_WRONLY|O_NONBLOCK) failed." << endl;
        return hidraw;
    }

    int result = 0;

    struct lamp_multi_update_report lamp_multi_update_report;
    lamp_multi_update_report.lamp_count = 1;
    lamp_multi_update_report.lamp_id[0] = 0;
    lamp_multi_update_report.update_channels[0].intensity_update_channel = 0xff;
    lamp_multi_update_report.lamp_update_flags = 0x01;

    while (true) {
        lamp_multi_update_report.update_channels[0].red_update_channel = 0xff;
        lamp_multi_update_report.update_channels[0].green_update_channel = 0;
        lamp_multi_update_report.update_channels[0].blue_update_channel = 0;
        result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), &lamp_multi_update_report);
        if (result < 0) {
            cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), lamp_multi_update_report) failed." << endl;
            close(hidraw);
            return result;
        }

        lamp_multi_update_report.update_channels[0].red_update_channel = 0;
        lamp_multi_update_report.update_channels[0].green_update_channel = 0xff;
        lamp_multi_update_report.update_channels[0].blue_update_channel = 0;
        result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), &lamp_multi_update_report);
        if (result < 0) {
            cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), lamp_multi_update_report) failed." << endl;
            close(hidraw);
            return result;
        }

        lamp_multi_update_report.update_channels[0].red_update_channel = 0;
        lamp_multi_update_report.update_channels[0].green_update_channel = 0;
        lamp_multi_update_report.update_channels[0].blue_update_channel = 0xff;
        result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), &lamp_multi_update_report);
        if (result < 0) {
            cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), lamp_multi_update_report) failed." << endl;
            close(hidraw);
            return result;
        }
    }

    close(hidraw);

    return EXIT_SUCCESS;
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
  2025-02-01  8:48   ` Pavel Machek
@ 2025-02-06 16:18     ` Werner Sembach
  2025-02-21 11:39       ` Werner Sembach
  2025-03-14 21:06       ` Pavel Machek
  0 siblings, 2 replies; 7+ messages in thread
From: Werner Sembach @ 2025-02-06 16:18 UTC (permalink / raw)
  To: Pavel Machek, Armin Wolf
  Cc: hdegoede, ilpo.jarvinen, bentiss, dri-devel, jelle, jikos, lee,
	linux-input, linux-kernel, linux-leds, miguel.ojeda.sandonis,
	ojeda, onitake, cs, platform-driver-x86, bpf

Hi,

Am 01.02.25 um 09:48 schrieb Pavel Machek:
> Hi!
>
>>> I now got my feet a little wet with hid-bpf regarding something else, and
>>> with that knowledge I would leave the long arrays in the beginning in the
>>> kernel code for the time being:
>>>
>>> sirius_16_ansii_kbl_mapping and sirius_16_iso_kbl_mapping are required
>>> during initialization so they have to exist in the kernel code anyway.
>>>
>>> report_descriptor will most likly not change even for future models and
>>> afaik having report_descriptors in kernel drivers is not unheard of.
>>>
>>> So the only things that could be meaningfully moved to a hid-bpf program
>>> are the sirius_16_*_kbl_mapping_pos_* arrays. But for these is have to give
>>> out some fallback value anyway for the case where a hid-bpf file is missing
>>> or fails to load. So why not use real world values from my test device for
>>> these values?
>>>
>>> As soon as there is a future device that can use the same driver with just
>>> these pos arrays different, then I would implement that change via a bpf
>>> program instead of a change to the kernel driver.
>>>
>>> Let me know if you too think this is a sensefull approach?
>>>
>>>
>>> Another question: Would this patch need to wait for a userspace
>>> implementation of lamp array before it can get accepted?
>> It would be nice if you could test the LampArray implementation. But other than that
>> userspace can catch up later.
>>
>> Still, i am interested in the opinion of the LED maintainers
>> regarding the fake HID interface.
> Comments from previous review were not addressed.
>
> Most importantly, this is not a way to do kernel interface. We want
> reasonable interface that can be documented and modified as needed. We
> want to pass /dev/input to userspace, not raw HID. This is not ok.

There are already 2 endless discussions about this:

https://lore.kernel.org/all/1fb08a74-62c7-4d0c-ba5d-648e23082dcb@tuxedocomputers.com/

https://lore.kernel.org/all/73c36418-34d6-46cf-9f10-6ca5e569274f@tuxedocomputers.com/

And a shorter one before that:

https://lore.kernel.org/all/30cbbf20-08cf-a69b-4f58-359a9802e86f@tuxedocomputers.com/

The brief:

- LampArray is a standard that will hit the Linux world anyway.

- The alternative proposal via a led matrix does not even really fit keyboards, 
and does not at all fit all other device types.

Hans and Benjamin already agree with me that LampArray is the way to go.

So after over 2 years can I please have a final decision on how to implement this?

Regards,

Werner

>
> Best regards,
> 								Pavel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
  2025-02-06 16:18     ` Werner Sembach
@ 2025-02-21 11:39       ` Werner Sembach
  2025-03-14 21:06       ` Pavel Machek
  1 sibling, 0 replies; 7+ messages in thread
From: Werner Sembach @ 2025-02-21 11:39 UTC (permalink / raw)
  To: Pavel Machek, Armin Wolf, Benjamin Tissoires, Hans de Goede
  Cc: ilpo.jarvinen, dri-devel, jelle, jikos, lee, linux-input,
	linux-kernel, linux-leds, miguel.ojeda.sandonis, ojeda, onitake,
	cs, platform-driver-x86, bpf

Hi,

Am 06.02.25 um 17:18 schrieb Werner Sembach:
> Hi,
>
> Am 01.02.25 um 09:48 schrieb Pavel Machek:
>> Hi!
>>
>>>> I now got my feet a little wet with hid-bpf regarding something else, and
>>>> with that knowledge I would leave the long arrays in the beginning in the
>>>> kernel code for the time being:
>>>>
>>>> sirius_16_ansii_kbl_mapping and sirius_16_iso_kbl_mapping are required
>>>> during initialization so they have to exist in the kernel code anyway.
>>>>
>>>> report_descriptor will most likly not change even for future models and
>>>> afaik having report_descriptors in kernel drivers is not unheard of.
>>>>
>>>> So the only things that could be meaningfully moved to a hid-bpf program
>>>> are the sirius_16_*_kbl_mapping_pos_* arrays. But for these is have to give
>>>> out some fallback value anyway for the case where a hid-bpf file is missing
>>>> or fails to load. So why not use real world values from my test device for
>>>> these values?
>>>>
>>>> As soon as there is a future device that can use the same driver with just
>>>> these pos arrays different, then I would implement that change via a bpf
>>>> program instead of a change to the kernel driver.
>>>>
>>>> Let me know if you too think this is a sensefull approach?
>>>>
>>>>
>>>> Another question: Would this patch need to wait for a userspace
>>>> implementation of lamp array before it can get accepted?
>>> It would be nice if you could test the LampArray implementation. But other 
>>> than that
>>> userspace can catch up later.
>>>
>>> Still, i am interested in the opinion of the LED maintainers
>>> regarding the fake HID interface.
>> Comments from previous review were not addressed.
>>
>> Most importantly, this is not a way to do kernel interface. We want
>> reasonable interface that can be documented and modified as needed. We
>> want to pass /dev/input to userspace, not raw HID. This is not ok.
>
> There are already 2 endless discussions about this:
>
> https://lore.kernel.org/all/1fb08a74-62c7-4d0c-ba5d-648e23082dcb@tuxedocomputers.com/ 
>
>
> https://lore.kernel.org/all/73c36418-34d6-46cf-9f10-6ca5e569274f@tuxedocomputers.com/ 
>
>
> And a shorter one before that:
>
> https://lore.kernel.org/all/30cbbf20-08cf-a69b-4f58-359a9802e86f@tuxedocomputers.com/ 
>
>
> The brief:
>
> - LampArray is a standard that will hit the Linux world anyway.
>
> - The alternative proposal via a led matrix does not even really fit 
> keyboards, and does not at all fit all other device types.
>
> Hans and Benjamin already agree with me that LampArray is the way to go.
>
> So after over 2 years can I please have a final decision on how to implement 
> this?

Any update?

Best regards,

Werner Sembach

>
> Regards,
>
> Werner
>
>>
>> Best regards,
>>                                 Pavel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices
  2025-02-06 16:18     ` Werner Sembach
  2025-02-21 11:39       ` Werner Sembach
@ 2025-03-14 21:06       ` Pavel Machek
  1 sibling, 0 replies; 7+ messages in thread
From: Pavel Machek @ 2025-03-14 21:06 UTC (permalink / raw)
  To: Werner Sembach
  Cc: Armin Wolf, hdegoede, ilpo.jarvinen, bentiss, dri-devel, jelle,
	jikos, lee, linux-input, linux-kernel, linux-leds,
	miguel.ojeda.sandonis, ojeda, onitake, cs, platform-driver-x86,
	bpf

[-- Attachment #1: Type: text/plain, Size: 2031 bytes --]

Hi!

> > Comments from previous review were not addressed.
> > 
> > Most importantly, this is not a way to do kernel interface. We want
> > reasonable interface that can be documented and modified as needed. We
> > want to pass /dev/input to userspace, not raw HID. This is not ok.
> 
> There are already 2 endless discussions about this:
> 
> https://lore.kernel.org/all/1fb08a74-62c7-4d0c-ba5d-648e23082dcb@tuxedocomputers.com/
> 
> https://lore.kernel.org/all/73c36418-34d6-46cf-9f10-6ca5e569274f@tuxedocomputers.com/
> 
> And a shorter one before that:
> 
> https://lore.kernel.org/all/30cbbf20-08cf-a69b-4f58-359a9802e86f@tuxedocomputers.com/
> 
> The brief:
> 
> - LampArray is a standard that will hit the Linux world anyway.

Maybe. Still have to see device implementing that. LampArray will
still need /sys/class/leds for compatibility. LampArray still does not
solve effects. More importantly, it is not okay to say "kernel
interface is specified by that crazy document from 3rd party".

> - The alternative proposal via a led matrix does not even really fit
> keyboards, and does not at all fit all other device types.

We are solving keyboards, not the other device types. The other devices
can likely be handled by existing /sys/class/leds interfaces.

> Hans and Benjamin already agree with me that LampArray is the way to go.
> 
> So after over 2 years can I please have a final decision on how to implement this?

For final decisions, you'd have to talk to Linus.

(And sorry for the delay, btw).

If you want to move this forward, place a driver in
drivers/leds/keyboard. Implement /sys/class/leds interface, but make
sure interface is clearly separated from the code talking to the
firmware. Then we can review that, perhaps merge, so users will have
something, and decide what interface to use for per-key control.

LampArray is no-go. Other options are open.

Best regards,
								Pavel
-- 
People of Russia, stop Putin before his war on Ukraine escalates.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-03-14 21:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-21 22:31 [PATCH v5 0/1] platform/x86/tuxedo: Add virtual LampArray for TUXEDO NB04 devices Werner Sembach
2025-02-01  4:39 ` Armin Wolf
2025-02-01  8:48   ` Pavel Machek
2025-02-06 16:18     ` Werner Sembach
2025-02-21 11:39       ` Werner Sembach
2025-03-14 21:06       ` Pavel Machek
2025-02-01 19:49   ` Werner Sembach

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox