[Desire Android Development] tobi01001:
This MOD/FIX is only for Sense Kernels and ROMs/Frameworks

This is only for Kernel and ROM developers. (And maybe some framework tweakers.)

If you wan't to make use out of it, ask your favorite ROM and7or kernel developer.

The mod I describe here, should work with GB as well as Froyo (Desire/Bravo of course).

At first, big thanks to snq- for implementing the kernel mod and making it available for testing and further development.

Thanks to Leedroid for his great ROM in which I am using this MOD/FIX.

Further, thanks to anderl78 for pointing me to adjust the autobrighness in the framework and to sloppy for providing the howto on how to actually change the brightness in the framework.

Big thanks to ivicask who actually patched services.jar to make autobrightness together with the fixed/improved sensor driver work like a charm (see here and here)

If I forgot someone, just let me now.

So as many of you who like to use the autobrightness setting to automatically get the best brighness setting in every light condition I was not quite happy with the way HTC implemented it. Reason for that is, that the autobrightness in the stock framework was at far too high levels leading in to bright screens and unnecessary battery drain.

I will describe both changes in the Kernel and one (optional but recommended) mod in android itself - namely services.jar.

Let's start with the Kernel:

Kernel Mod:

While adjusting the values in the framework and during some testing I realized that not all sensor levels stated in the framework are reported by the lightsensor driver. Most importantly, Level 0 (which refers to absolutely darkness) was never reported by the driver. This made me look into the kernel sources and I finally found a solution.

I will not go into detail and explain the code for you. Every kernel developer should be able to understand and to follow the changes I provide.

First of all, the lightsensor driver uses a loop to report lightlevels for a range of sensor raw data. The lightsensor driver can be found in drivers/input/misc/cm3602_lightsensor_microp.c. In order to make the mod work, there would actually no need in changing the driver itself. But snq- provided a change that makes it even more simple.

Original Code: (drivers/input/misc/cm3602_lightsensor_microp.c)

static int get_ls_adc_level(uint8_t *data)
{
[B]...[/B]
for (i = 0; i < 10; i++) {
if (adc_value <=
li->ls_config->levels[i]) {
adc_level = i;
[I][B]if (li->ls_config->levels[i])
break;[/B][/I]
}
}
ILS("ALS value: 0x%X, level: %d #\n",
adc_value, adc_level);
data[2] = adc_level;
}
[B]...[/B]
}

Changed Code: (drivers/input/misc/cm3602_lightsensor_microp.c)

static int get_ls_adc_level(uint8_t *data)
{
[B]...[/B]
for (i = 0; i < 10; i++) {
if (adc_value <=
li->ls_config->levels[i]) {
adc_level = i;
[I][B]break;[/B][/I]
}
}
ILS("ALS value: 0x%X, level: %d #\n",
adc_value, adc_level);
data[2] = adc_level;
}
[B]...[/B]
}

Now for the "real" kernel tweak:

The lightsensor values are stored in the bravo board file: arch/arm/mach-msm/board-bravo.c

Original Code: (arch/arm/mach-msm/board-bravo.c)

static struct microp_function_config microp_lightsensor_function = {
.name = "light_sensor",
.category = MICROP_FUNCTION_LSENSOR,
[B][I].levels = { 0, 0x21, 0x4D, 0xDC, 0x134, 0x18D, 0x1E5, 0x3FF, 0x3FF, 0x3FF },[/I][/B]
.channel = 6,
.int_pin = 1 << 9,
.golden_adc = 0xC0,
.ls_power = capella_cm3602_power,
};

Changed Code: (arch/arm/mach-msm/board-bravo.c)

static struct microp_function_config microp_lightsensor_function = {
.name = "light_sensor",
.category = MICROP_FUNCTION_LSENSOR,
[B][I].levels = { 0x04, 0x21, 0x4D, 0xDC, 0x134, 0x18D, 0x1E5, 0x280, 0x340, 0x3FF },[/I][/B]
.channel = 6,
.int_pin = 1 << 9,
.golden_adc = 0xC0,
.ls_power = capella_cm3602_power,
};

I changed the values again (just took the ones from bravoc which has all levels defined) to the following - which is working great:

static struct microp_function_config microp_lightsensor_function = {
.name = "light_sensor",
.category = MICROP_FUNCTION_LSENSOR,
[B][I].levels = { 0, 10, 15, 21, 60, 209, 362, 488, 560, 0x3FF },[/I][/B]
.channel = 6,
.int_pin = 1 << 9,
.golden_adc = 0xC0,
.ls_power = capella_cm3602_power,
};

the final code - especially the lightsensor driver - looks a little bit different (few more tweaks).

They are implemented in snq-'s current kernel and from what I've seen even in bananacakes and tristans...

Those changes enable level 0 (since it is no longer skipped from the driver) and enables levels 7 to 9 (since 0x3FF is the last one and the previous ones are adjusted to lower values).

So, if you have a kernel with the changes implemented you can easily verify with

cat /sys/devices/i2c-0/0-0066/ls_adc

(and proper light conditions) all sensor levels from 0 to 9 are reported. You can even use a sensor app to verify that all light levels are reported (in lux within those apps).

Here comes the first and (in my opinion) only downside:

I have no idea if HTC implemented the driver the way they did by purpose. And I have no idea if the new reported sensor values in any way report the "right" lux values for the environment brightness. But I actually do not care about that, because I can adjust the framework and do not rely on exactly reported lux values (which is anyway only possible in a quite large range between the levels).

Framework:

Now for the framework / android:

I was quite happy to have all sensor levels enabled. And with proper adjusted autobrightness levels in the framework (framework-res.apk) it works quite well.

I adjusted my framework to tweak the values a little bit further (especially to have the screen quite dimmed in low light conditions). I tried to verify my changes with simply logging sensor data and screen brightness. I do this with a simple script:

#!/bin/bash
#

while :
do
sleep 1
echo.
adb shell cat /sys/class/leds/lcd-backlight/brightness
adb shell cat /sys/devices/i2c-0/0-0066/ls_adc

done

The script showed me, that even with all levels being reported, the value I set for the lowest level was not applied if you wake up the screen. On screen wakeup, what I saw was either the value for level one, or the maximum brightness (this only happens if you turn off and on again very quickly using the power button). Further, without changines in the environmental light conditions, no new values were applied. This is still annoying if you get max brightness in the middle of the night. :-) Fortunately I was not the only one with that experience. The solution seems to be the (maybe poorly implemented) services.jar in the desire rom. So ivicask patched services.jar with the PowerManager related stuff from the Sensation to make autobrightness together with the fixed/improved sensor driver work like a charm (see here and here).

I flashed this on on my LeeDrOiD 3.3.3 (HD Mod) and it works perfectly.

With those changes in the services.jar (and the "config_autoBrightnessLcdBacklightValues" etc) adjusted accordingly, I now get all levels and the corresponding brightness which feels good and will hopefully add some highly appreciated hours to my battery life. :D

So, that's all in short. If you have any specific (development related) questions, just let me know.

Please do not ask how to implement it or where to get it - since despite the references below - I have no information on who has implemented or ever will implement this. Use the search function or ask your ROM/Kernel developer.

Update: Information for Brightness / Gamma settings for Amoled (not SLCD)

- max brightness value is 250

- min value is 10 but anything <31 will be set to 20

- gamma steps are 30 and there are actually 9 levels. But that doesn't matter. any value between 30 an 250 should be (more or less).

So if you take those "restrictions" into account while changing your framework, it could add a bit of smoothness (yet not sure about it).

References:

I do not know of any ROM with the mod applied. I personally use

LeeDrOiD HD V3.3.3-Port-R5

snq-'s kernel thread where we tried and made sure it works. I currently use 110918-lsmod1

HowTo change Autobrightness in framework:

Desire HD (Ace) (where I learned to tweak it) Lower Auto-Brightness Settings for DEODEXED FROYO / GINGERBREAD Sense ROMs

Classic Desire specific (Bravo) [How to] Adjust auto-brightness on GB Sense ROM

Question:

Has anyone been successfull to do the same for the hardware button backlights? (meaning to turn them off at higher levels). Seems the changes I applied so far do not work like I expect it.

So, I hope that this mod is of any use for Sense Rom's and kernels. I am more than happy with it and just wanted to share it with you.

Best regards,

Toby

Finally, if any mod thinks this is the wrong section or has no reason to be here, just let me know.