Hi Barnabás, Thanks for your review. On Sun, Dec 27, 2020 at 6:41 AM Barnabás Pőcze <pobrn@xxxxxxxxxxxxxx> wrote: > > Hi > > > 2020. december 19., szombat 7:23 keltezéssel, Roderick Colenbrander írta: > > > [...] > > diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c > > index 0b62bcb28d8a..f8cf82a27d43 100644 > > [...] > > +/* Create a DualSense/DualShock4 RGB lightbar represented by a multicolor LED. */ > > +static struct led_classdev_mc *ps_lightbar_create(struct ps_device *ps_dev, > > + int (*brightness_set)(struct led_classdev *, enum led_brightness)) > > +{ > > + struct hid_device *hdev = ps_dev->hdev; > > + struct led_classdev_mc *lightbar_mc_dev; > > + struct mc_subled *mc_led_info; > > + struct led_classdev *led_cdev; > > + int ret; > > + > > + lightbar_mc_dev = devm_kzalloc(&hdev->dev, sizeof(*lightbar_mc_dev), GFP_KERNEL); > > + if (!lightbar_mc_dev) > > + return ERR_PTR(-ENOMEM); > > + > > + mc_led_info = devm_kzalloc(&hdev->dev, 3*sizeof(*mc_led_info), GFP_KERNEL); > > + if (!mc_led_info) > > + return ERR_PTR(-ENOMEM); > > + > > Is there any reason why these are dynamically allocated? No particular reason. I should probably at least not dynamically allocate 'mc_dev' and pass it in similar to regular LED registration (previously I had my regular LEDs dynamically allocated). The mc_led_info I will probably keep dynamic. It feels a bit nasty to have the caller be aware of these internal details. > > > > + mc_led_info[0].color_index = LED_COLOR_ID_RED; > > + mc_led_info[0].channel = 0; > > + mc_led_info[1].color_index = LED_COLOR_ID_GREEN; > > + mc_led_info[1].channel = 1; > > + mc_led_info[2].color_index = LED_COLOR_ID_BLUE; > > + mc_led_info[2].channel = 2; > > + > > + lightbar_mc_dev->subled_info = mc_led_info; > > + lightbar_mc_dev->num_colors = 3; > > + > > + led_cdev = &lightbar_mc_dev->led_cdev; > > + led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "playstation::%pMR::rgb", > > + ps_dev->mac_address); > > I guess the double colons are used because the MAC address has ':' in it; but > as far as I know this doesn't follow the naming scheme for LED devices, so I'm > not sure if this is the best way to go about it. Actually it was Benjamin who suggested this type of naming. He wasn't a fan of the previous hid-sony device naming (neither was I). This was the main idea so far. > > > + led_cdev->brightness = 255; > > + led_cdev->max_brightness = 255; > > + led_cdev->brightness_set_blocking = brightness_set; > > + > > + ret = devm_led_classdev_multicolor_register(&hdev->dev, lightbar_mc_dev); > > + if (ret < 0) { > > + hid_err(hdev, "Cannot register multicolor LED device\n"); > > + return ERR_PTR(ret); > > + } > > + > > + return lightbar_mc_dev; > > +} > > [...] > > +static int dualsense_reset_leds(struct dualsense *ds) > > +{ > > + struct dualsense_output_report report; > > + uint8_t *buf; > > + > > + buf = kzalloc(sizeof(struct dualsense_output_report_bt), GFP_KERNEL); > > + if (!buf) > > + return -ENOMEM; > > + > > + dualsense_init_output_report(ds, &report, buf); > > + /* On Bluetooth the DualSense outputs an animation on the lightbar > > + * during startup and maintains a color afterwards. We need to explicitly > > + * reconfigure the lightbar before we can do any programming later on. > > + * In USB the lightbar is not on by default, but redoing the setup there > > + * doesn't hurt. > > + */ > > + report.common->valid_flag2 = DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE; > > + report.common->lightbar_setup = 2; /* Fade light out. */ > > Maybe it'd be better to name that '2'? Will document this one. > > > > + dualsense_send_output_report(ds, &report); > > + > > + kfree(buf); > > + return 0; > > +} > > [...] > > > Regards, > Barnabás Pőcze Thanks, Roderick