Search code examples
androidkernellednexus-5

Nexus 5: cannot change LED colour through sysfs interface


On other devices, I can write values to LED brightness control interfaces like /sys/class/leds/red/brightness to turn the LED on/off. However it's not working on Nexus 5.

I'm writing an app that constantly changes the led brightness, so setting via notification is not an option for me.

I've read the kernel driver source leds-qpnp.c. It's a bit different from that for Xperia Z2 in that:

  1. duty_pcts length is increased to 20. Which is good to have smoother transition in LPG mode;
  2. I see interpolation code in code setting brightness.
  3. start, calibrated_max, on_ms and off_ms in rgb_config_data: never seen this before.
  4. N5 doesn't have PWM_DIRECT_MODE and LPG_SYNC_MODE. This results in that N5 has rgb_duration_config and Z2 has qpnp_rgb_set_direct.
  5. schedule_work doesn't call qpnp_rgb_set! It is only called in qpnp_rgb_start_set. It seems to be a trigger that starts the LED.

From these information, I came up with a plan:

  1. echo TARGET_BRIGHTNESS > brightness
  2. echo SOME_u8_VALUE > rgb_start

Yet it still refuse to power up the led. And my rgb_start was cleared back to 0.

Looking at the code for doing this:

/* Checking lut flags is used to glean if the led really was started */ if (!(led_array[i].rgb_cfg->pwm_cfg->lut_params.flags & PM_PWM_LUT_RAMP_UP)) led_array[i].rgb_cfg->start = 0;

I know that lut_params.flags are already set to leverage LPG. But at this point I don't know how to clear the flags in the clean way without dirty hacks in the kernel.

Anyone?


Solution

  • Alright. I just found out the answer.

    Simply set the brightness, then set on_off_ms, then trigger via rgb_start. Note that two transactions will need different numbers to be sent to rgb_start