1. led灯又称三色灯,有R/G/B三基色。均有256(0-255)的亮度级别(用PWM波实现?),
256*256*256 = 1600w,通过设置三基色可以配出1600w种颜色,几乎包括所有颜色。
调试: 通过adb读写led亮度
ac50sax: # find /sys -name brightness
/sys/devices/platform/leds-mt65xx/leds/red/brightness
/sys/devices/platform/leds-mt65xx/leds/blue/brightness
/sys/devices/platform/leds-mt65xx/leds/green/brightness
/sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness
ac50sax: # cat /sys/devices/platform/leds-mt65xx/leds/red/brightness
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/red/brightness
ac50sax: # echo 0 > /sys/devices/platform/leds-mt65xx/leds/red/brightness
ac50sax: # echo 0 > /sys/devices/platform/leds-mt65xx/leds/blue/brightness
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/blue/brightness
ac50sax: # echo 0 > /sys/devices/platform/leds-mt65xx/leds/green/brightness
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/green/brightness
ac50sax: # cat /sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness
ac50sax: # echo 0 > /sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness
2. 驱动只负责【关机充电】的led指示灯控制,控制代码在(开机状态的控制由上层负责):
alps\vendor\mediatek\proprietary\external\charger(关机充电指示灯控制)、
alps\vendor\mediatek\proprietary\external\ipod(开启了快速启动的关机充电指示灯控制)
alps\vendor\mediatek\proprietary\external\charger\charging_control.cpp(关机充电指示灯控制)
mtk默认的控制策略:0~89亮红灯 90~100亮绿灯
on_uevent()
if (is_charging_source_available()
) // 如果正在充电(AC/USB/wireless) - 读取sysfs节点
{
bc = get_capacity(); // 获取电池电量百分比 - 读取"/sys/class/power_supply/battery/capacity"
if (bc >= 90) {
lights_full(); // 关闭red,打开green(255)- 通过 写"/sys/class/leds/green/brightness" ""/sys/class/leds/red/brightness""
} else {
lights_on(); // 关闭green,打开red(255)- 通过 写"/sys/class/leds/green/brightness" ""/sys/class/leds/red/brightness""
}
}
定制化控制策略:0~14亮红灯 15~89亮蓝灯 90~100亮绿灯
on_uevent()
if (is_charging_source_available()) // 如果正在充电(AC/USB/wireless) - 读取sysfs节点
{
bc = get_capacity(); // 获取电池电量百分比 - 读取"/sys/class/power_supply/battery/capacity"
if (bc >= 90) {
lights_full(); // 关闭red,关闭blue,打开green(255)- 通过 写"/sys/class/leds/green/brightness" "/sys/class/leds/red/brightness"
} else {
+ if((bc >= 15)&&(bc < 90))
+ lights_on_15_89(); // 关闭red,关闭green,打开blue(255)- 通过 写"/sys/class/leds/green/brightness" "/sys/class/leds/red/brightness"
+ else
lights_on(); // 关闭green,关闭blue,打开red(255)- 通过 写"/sys/class/leds/green/brightness" "/sys/class/leds/red/brightness"
}
}
3. 关闭三色灯
dts中将led_mode改为0
led0:led@0 {
compatible = "mediatek,red";
- led_mode = <3>;
+ led_mode = <0>;
led1:led@1 {
compatible = "mediatek,green";
- led_mode = <2>;
+ led_mode = <0>;
led2:led@2 {
compatible = "mediatek,blue";
- led_mode = <3>;
+ led_mode = <0>;
一、 mt6739平台(kernel-4.4)三色灯 即充电指示灯驱动实现:
1. mt6739.dts
+ charge_led: charge_led {
+ compatible = "mediatek,mt6739_leds";
+ };
mtkfb: mtkfb {
compatible = "mediatek,mtkfb";
};
2. k39tv1_bsp_1g.dts
&odm {
led0:led@0 {
compatible = "mediatek,red"; // 6739的red led接在pmic上
led_mode = <0>;
data = <1>;
pwm_config = <0 0 0 0 0>;
};
led1:led@1 {
compatible = "mediatek,green"; // GPIO122
led_mode = <2>;
data = <1>;
pwm_config = <0 0 0 0 0>;
};
led2:led@2 {
compatible = "mediatek,blue"; // GPIO17
led_mode = <2>;
data = <2>;
pwm_config = <0 0 0 0 0>;
};
+ /* LEDS GPIO Kernel Standardization start */
+ &charge_led {
+ pinctrl-names = "pinctrl_led1_low", "pinctrl_led1_high", "pinctrl_led2_low", "pinctrl_led2_high";
+ pinctrl-0 = <&pinctrl_led1_low>;
+ pinctrl-1 = <&pinctrl_led1_high>;
+ pinctrl-2 = <&pinctrl_led2_low>;
+ pinctrl-3 = <&pinctrl_led2_high>;
+ status = "okay";
+ };
+
+ &pio {
+ pinctrl_led1_low: pinctrl_led1_low {
+ pins_cmd_dat {
+ pins = ;
+ slew-rate = <1>;
+ output-low;
+ };
+ };
+
+ pinctrl_led1_high: pinctrl_led1_high {
+ pins_cmd_dat {
+ pins = ;
+ slew-rate = <1>;
+ output-high;
+ };
+ };
+
+ pinctrl_led2_low: pinctrl_led2_low {
+ pins_cmd_dat {
+ pins = ;
+ slew-rate = <1>;
+ output-low;
+ };
+ };
+
+ pinctrl_led2_high: pinctrl_led2_high {
+ pins_cmd_dat {
+ pins = ;
+ slew-rate = <1>;
+ output-high;
+ };
+ };
+ };
+ /* LEDS GPIO Kernel Standardization end */
3. dws:
EintMode|Def.Mode M0|M1|M2|M3|M4|M5|M6|M7|InPull En|InPull SelHigh|Def.Dir|In|Out|OutHigh|VarName1
GPIO17 NC
GPIO122 NC
4. kernel-4.4/drivers/misc/mediatek/leds/mt6739/mtk_leds.c
+ #include
+ #include
+ struct platform_device *led_dev;
+ struct pinctrl *led_pinctrl;
+ struct device_node *leds_node;
+ struct pinctrl_state *pinctrl_led1_low;
+ struct pinctrl_state *pinctrl_led1_high;
+ struct pinctrl_state *pinctrl_led2_low;
+ struct pinctrl_state *pinctrl_led2_high;
+ static int charge_led_get_gpio_pinctrl(void)
+ {
int ret = 0;
leds_node = of_find_compatible_node(NULL, NULL, "mediatek,mt6739_leds");
if (leds_node == NULL) {
pr_err("get mt6739_leds node failed\n");
ret = PTR_ERR(leds_node);
}
led_dev = of_find_device_by_node(leds_node);
led_pinctrl = devm_pinctrl_get(&led_dev->dev);
if (IS_ERR(led_pinctrl)) {
dev_err(&led_dev->dev, "Cannot find led_pinctrl!\n");
ret = PTR_ERR(led_pinctrl);
}
pinctrl_led1_low = pinctrl_lookup_state(led_pinctrl, "pinctrl_led1_low");
if (IS_ERR(pinctrl_led1_low)) {
pr_err("Cannot find led_pinctrl pinctrl_led1_low\n");
ret = PTR_ERR(pinctrl_led1_low);
}
pinctrl_led1_high = pinctrl_lookup_state(led_pinctrl, "pinctrl_led1_high");
if (IS_ERR(pinctrl_led1_high)) {
pr_err("Cannot find led_pinctrl pinctrl_led1_high\n");
ret = PTR_ERR(pinctrl_led1_high);
}
pinctrl_led2_low = pinctrl_lookup_state(led_pinctrl, "pinctrl_led2_low");
if (IS_ERR(pinctrl_led2_low)) {
pr_err("Cannot find led_pinctrl pinctrl_led2_low\n");
ret = PTR_ERR(pinctrl_led2_low);
}
pinctrl_led2_high = pinctrl_lookup_state(led_pinctrl, "pinctrl_led2_high");
if (IS_ERR(pinctrl_led2_high)) {
pr_err("Cannot find led_pinctrl pinctrl_led2_high\n");
ret = PTR_ERR(pinctrl_led2_high);
}
return ret;
}
int cust_set_charge_led_by_gpio(long data, u32 level)
{
pr_err("%s:line=%d,level=%d\n",__func__,__LINE__,level);
if(charge_led_get_gpio_pinctrl()){
return -1;
}
if (255 == level){
if(data == 1)
pinctrl_select_state(led_pinctrl, pinctrl_led1_high);
else if(data == 2)
pinctrl_select_state(led_pinctrl, pinctrl_led2_high);
}
else{
if(data == 1)
pinctrl_select_state(led_pinctrl, pinctrl_led1_low);
else if(data == 2)
pinctrl_select_state(led_pinctrl, pinctrl_led2_low);
}
+ return 0;
+ }
int mt_mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
{
switch (cust->mode) {
case MT65XX_LED_MODE_PWM:
case MT65XX_LED_MODE_GPIO:
LEDS_DEBUG("brightness_set_cust:go GPIO mode!!!!!\n");
- return ((cust_set_brightness) (cust->data)) (level);
+ return cust_set_charge_led_by_gpio(cust->data, level); // 改成由自己实现的gpio口控制函数
5. vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/mt_leds.c
+ int cust_set_charge_led_by_gpio(long data, u32 level)
+ {
+ if (255 == level)
+ LEDS_INFO("%s:line=%d,level=%d\n",__func__,__LINE__,level);
+ else
+ LEDS_INFO("%s:line=%d,level=%d\n",__func__,__LINE__,level);
+
+ return 0;
+ }
static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
{
...
switch (cust->mode) {
case MT65XX_LED_MODE_PWM:
case MT65XX_LED_MODE_GPIO:
- return ((cust_brightness_set)(cust->data))(level);
+ return cust_set_charge_led_by_gpio(cust->data, level);
6. red led 接在pmic上
kernel-4.4/drivers/misc/mediatek/leds/mt6739/mtk_leds_sw.h
enum mt65xx_led_pmic {
MT65XX_LED_PMIC_LCD_ISINK = 0,
- MT65XX_LED_PMIC_NLED_ISINK_MIN = MT65XX_LED_PMIC_LCD_ISINK,
+ MT65XX_LED_PMIC_NLED_ISINK_MIN
调试案例
案例一 : 三色灯只有R/G, Blue无功能 - dts中的GPIO控制脚配置不对
现象 :
平台 : androidN,MTK6737
排查过程: 1. Blue无功能,查看硬件原理图:6737的R、G、B分别接在ISINK0、ISINK1、GPIO63(AD27)
2. 修改dts中B的GPIO控制配置: GPIO58->GPIO63
/* LEDS GPIO Kernel Standardization start */
&pio {
- pinctrl_led0: pinctrl_led0@gpio58 {
+ pinctrl_led0: pinctrl_led0@gpio63 {
pins_cmd_dat {
- pins = ;
+ pins = ;
==>ok
案例二 : led三色灯(接在PMIC)亮度改为70%
平台: androidL,MTK6580
步骤: 1. 修改alps\kernel-3.10\drivers\misc\mediatek\leds\mt6580\leds.c
mt_brightness_set_pmic()中
// 将原本的16ma 改为 12ma,大概降为70%
if (pmic_type == MT65XX_LED_PMIC_LCD_ISINK)
else if(pmic_type == MT65XX_LED_PMIC_NLED_ISINK0)
else if(pmic_type == MT65XX_LED_PMIC_NLED_ISINK1) // 查看原理图: R、G、B分别接在PMIC的ISINK1、ISINK2、ISINK3
- pmic_set_register_value(PMIC_ISINK_CH1_STEP,ISINK_2);//12mA
+ pmic_set_register_value(PMIC_ISINK_CH1_STEP,ISINK_3);//16mA
else if(pmic_type == MT65XX_LED_PMIC_NLED_ISINK2)
- pmic_set_register_value(PMIC_ISINK_CH1_STEP,ISINK_2);//12mA
+ pmic_set_register_value(PMIC_ISINK_CH1_STEP,ISINK_3);//16mA
else if(pmic_type == MT65XX_LED_PMIC_NLED_ISINK3)
- pmic_set_register_value(PMIC_ISINK_CH1_STEP,ISINK_2);//12mA
+ pmic_set_register_value(PMIC_ISINK_CH1_STEP,ISINK_3);//16mA
注:根据原理图,6737的R、G、B分别接在ISINK0、ISINK1、GPIO63(AD27)【说明B无法在软件上控制亮度】
6737的R、G通过PMIC控制亮灭即亮度, B经dts通过GPIO控制亮灭
案例三 : 关机充电指示灯显示异常 - 配置的宏没生效 - 配置有遗落
现象: 0-14%红色、15-89%蓝灯、90-100%绿灯,但现在0-89%红灯、90-100%绿灯(mtk默认)
平台: androidO,MTK6737
步骤: 1. 通过adb控制led -> 均能控制,表示驱动正常
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/red/brightness
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/blue/brightness
ac50sax: # echo 255 > /sys/devices/platform/leds-mt65xx/leds/green/brightness
2. 怀疑是hal层自定义控制测量不生效
alps\vendor\mediatek\proprietary\external\charger\charging_control.cpp(关机充电指示灯控制)
on_uevent()
if (is_charging_source_available()) // 如果正在充电(AC/USB/wireless) - 读取sysfs节点
{
bc = get_capacity(); // 获取电池电量百分比 - 读取"/sys/class/power_supply/battery/capacity"
if (bc >= 90) {
lights_full(); // 关闭red,关闭blue,打开green(255)- 通过 写"/sys/class/leds/green/brightness" "/sys/class/leds/red/brightness"
} else {
#if defined(KST_POWEROFF_LED)
+ if((bc >= 15)&&(bc < 90))
+ lights_on_15_89(); // 关闭red,关闭green,打开blue(255)- 通过 写"/sys/class/leds/green/brightness" "/sys/class/leds/red/brightness"
+ else
#endif
lights_on(); // 关闭green,关闭blue,打开red(255)- 通过 写"/sys/class/leds/green/brightness" "/sys/class/leds/red/brightness"
}
}
在宏中添加语法错误-> 编译不报错
3. 检查宏的配置
device/magcomm/magc6737m_65_n/ProjectConfig.mk
+ AUTO_ADD_GLOBAL_DEFINE_BY_VALUE = KST_CAM_CUSTOM KST_MISC_CUSTOM // 缺少这一条配置 - 补上之后ok
KST_MISC_CUSTOM = KST_POWEROFF_LED
4. 此间还打了一些log
发现关机充电的时候,只跑kernel,不跑android,但是会跑一些进程,如
vendor/mediatek/proprietary/external/charger/Android.mk
LOCAL_MODULE:= kpoc_charger
即关机充电部分编译生成daemon: kpoc_charger
此daemon的log可以在串口log中查看
[ 28.471671] <0>.(0)[214:kpoc_charger]charger: on_uevent, change@/devices/platform/battery/power_supply/battery // 通过此节点读取电池电压
[180:mtk charger_hv_][na14:kpoc_charger][name:battery_common&][EM] show_ADC_Charger_Voltage : 5090 // 电池电压高达5.09v - 电流100%
[ 28.476595] charger: lights_chgfullcharger: set_int_value: /sys/class/leds/blue/brightness, 0 // 关闭red
[ 28.479869] <0>.(0)[214:kpoc_charger]charger: set_int_value: /sys/class/leds/red/brightness, 0 // 关闭blue
[ 28.482768] <0>.(0)[214:kpoc_charger]charger: set_int_value: /sys/class/leds/green/brightness, 255 // green - 255
案例四 : 39平台充电指示灯
平台: androidO,MTK6739
(1)按照原理图,把绿灯和红灯的指示灯控制配置成GPIO口的方式,会不断地重启。这种配置方式在mt6580和mt6737 android6.0以上的系统上这么配置都没有问题,但mt6739 android8.1上就会有此问题。
led0:led@0 {
compatible = "mediatek,red";
led_mode = <0>;
data = <1>;
pwm_config = <0 0 0 0 0>;
};
led1:led@1 {
compatible = "mediatek,green";
led_mode = <2>;
data = <1>;
pwm_config = <0 0 0 0 0>;
};
led2:led@2 {
compatible = "mediatek,blue";
led_mode = <2>;
data = <2>;
pwm_config = <0 0 0 0 0>;
};
(2)接出串口,打印串口信息,确实是由于绿灯的指示灯改成GPIO口控制造成,这是在lk的过程中造成的,需分析对应的代码。
[3263] [LEDS]LK: leds_deinit: LEDS off
[3264] [LEDS]LK: red level is 0
[3264] [LEDS]LK: green level is 0
[3264] prefetch abort, halting
[3265] r0 0x00000000 r1 0x0010e938 r2 0x5a5aa5a5 r3 0x00000001
[3266] r4 0x00000000 r5 0x4609128c r6 0x4607eb60 r7 0x46080044
[3266] r8 0x460912ac r9 0x00000100 r10 0x4606bd40 r11 0x00000c51
[3267] r12 0x4607eb60 usp 0x00000000 ulr 0x00000000 pc 0x00000000
(3)通过以下git grep关键字的指令,定位代码位置
git grep -n "level is" alps/vendor/mediatek/proprietary/bootable/bootloader/lk/
发现是在以下代码上打印出来的串口信息
alps/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/mt_leds.c:348: dprintf(CRITICAL,"[LEDS]LK: %s level is %d \n\r", cust_led_list[type].name, level);
代码分析如下
int mt65xx_leds_brightness_set(enum mt65xx_led_type type, enum led_brightness level)
{
struct cust_mt65xx_led *cust_led_list = get_cust_led_dtsi();
if (cust_led_list == NULL) {
cust_led_list = get_cust_led_list();
LEDS_ERR("Cannot not get the LED info from device tree. \n");
}
if (type >= MT65XX_LED_TYPE_TOTAL)
return -1;
if (level > LED_FULL)
level = LED_FULL;
// else if (level < 0) //level cannot < 0
// level = 0;
if (g_lastlevel[type] != (int)level) {
g_lastlevel[type] = level;
dprintf(CRITICAL,"[LEDS]LK: %s level is %d \n\r", cust_led_list[type].name, level);
return mt65xx_led_set_cust(&cust_led_list[type], level); //从串口打印信息来看是在此处跑飞的
} else {
return -1;
}
}
跟踪mt65xx_led_set_cust函数的定义
static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
{
unsigned int BacklightLevelSupport = Cust_GetBacklightLevelSupport_byPWM();
if (level > LED_FULL)
level = LED_FULL;
else if (level < 0)
level = 0;
switch (cust->mode) {
case MT65XX_LED_MODE_PWM:
if (level == 0) {
//LEDS_INFO("[LEDS]LK: mt65xx_leds_set_cust: enter mt_pwm_disable()\n");
mt_pwm_disable(cust->data, cust->config_data.pmic_pad);
return 1;
}
if (strcmp(cust->name,"lcd-backlight") == 0) {
if (BacklightLevelSupport == BACKLIGHT_LEVEL_PWM_256_SUPPORT)
level = brightness_mapping(level);
else
level = brightness_mapto64(level);
return brightness_set_pwm(cust->data, level,&cust->config_data);
} else {
return led_set_pwm(cust->data, level);
}
case MT65XX_LED_MODE_GPIO:
return ((cust_brightness_set)(cust->data))(level); //该函数指针没有在函数*get_cust_led_dtsi()中被赋值
case MT65XX_LED_MODE_PMIC:
return brightness_set_pmic(cust->data, level);
case MT65XX_LED_MODE_CUST_LCM:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_CUST_BLS_PWM:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_NONE:
default:
break;
}
return -1;
}
struct cust_mt65xx_led *get_cust_led_dtsi(void)
{
static bool isDTinited = false;
int i, offset;
int pwm_config[5] = {0};
#if defined(CFG_DTB_EARLY_LOADER_SUPPORT)
if ( isDTinited == true )
goto out;
for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
pled_dtsi[i].name = leds_name[i];
offset = fdt_path_offset(g_fdt, leds_node[i]);
if (offset < 0) {
LEDS_ERR("[LEDS]LK:Cannot find LED node from dts\n");
pled_dtsi[i].mode = 0;
pled_dtsi[i].data = -1;
} else {
isDTinited = true;
pled_dtsi[i].mode = led_fdt_getprop_u32(g_fdt, offset, "led_mode");
pled_dtsi[i].data = led_fdt_getprop_u32(g_fdt, offset, "data");
led_fdt_getprop_char_array(g_fdt, offset, "pwm_config", (char *)pwm_config);
pled_dtsi[i].config_data.clock_source = pwm_config[0];
pled_dtsi[i].config_data.div = pwm_config[1];
pled_dtsi[i].config_data.low_duration = pwm_config[2];
pled_dtsi[i].config_data.High_duration = pwm_config[3];
pled_dtsi[i].config_data.pmic_pad = pwm_config[4];
switch (pled_dtsi[i].mode) {
case MT65XX_LED_MODE_CUST_LCM:
pled_dtsi[i].data = (long)primary_display_setbacklight;
LEDS_ERR("[LEDS]LK:The backlight hw mode is LCM.\n");
break;
case MT65XX_LED_MODE_CUST_BLS_PWM:
pled_dtsi[i].data = (long)disp_bls_set_backlight;
LEDS_ERR("[LEDS]LK:The backlight hw mode is BLS.\n");
break;
//这里没有MT65XX_LED_MODE_GPIO这个case对pled_dtsi[i].data的赋值
default:
break;
}
LEDS_INFO("[LEDS]LK:led[%d] offset is %d,mode is %d,data is %d .\n", \
i,offset,pled_dtsi[i].mode,pled_dtsi[i].data);
}
}
#endif
if ( isDTinited == false )
return NULL;
out:
return pled_dtsi;
}
alps/vendor/mediatek/proprietary/bootable/bootloader/lk/target/k39tv1_bsp_1g/inc/cust_leds.h
typedef int (*cust_brightness_set)(int level);
struct cust_mt65xx_led {
char *name;
enum mt65xx_led_mode mode;
int data;
struct PWM_config config_data;
};
(4)解决办法:
方法一:在mt65xx_led_set_cust()函数中的MT65XX_LED_MODE_GPIO的case下,不使用函数指针的方式,而是另外定义一个函数返回整型数据,kernel的需和lk的同步修改成一样的方式;
alps/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/mt_leds.c
int cust_set_charge_led_by_gpio(long data, u32 level)
{
if (255 == level)
LEDS_INFO("%s:line=%d,level=%d\n",__func__,__LINE__,level);
else
LEDS_INFO("%s:line=%d,level=%d\n",__func__,__LINE__,level);
return 0;
}
static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
{
unsigned int BacklightLevelSupport = Cust_GetBacklightLevelSupport_byPWM();
if (level > LED_FULL)
level = LED_FULL;
else if (level < 0)
level = 0;
switch (cust->mode) {
case MT65XX_LED_MODE_PWM:
if (level == 0) {
//LEDS_INFO("[LEDS]LK: mt65xx_leds_set_cust: enter mt_pwm_disable()\n");
mt_pwm_disable(cust->data, cust->config_data.pmic_pad);
return 1;
}
if (strcmp(cust->name,"lcd-backlight") == 0) {
if (BacklightLevelSupport == BACKLIGHT_LEVEL_PWM_256_SUPPORT)
level = brightness_mapping(level);
else
level = brightness_mapto64(level);
return brightness_set_pwm(cust->data, level,&cust->config_data);
} else {
return led_set_pwm(cust->data, level);
}
case MT65XX_LED_MODE_GPIO:
//return ((cust_brightness_set)(cust->data))(level);
return cust_set_charge_led_by_gpio(cust->data, level);
case MT65XX_LED_MODE_PMIC:
return brightness_set_pmic(cust->data, level);
case MT65XX_LED_MODE_CUST_LCM:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_CUST_BLS_PWM:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_NONE:
default:
break;
}
return -1;
}
方法二:在get_cust_led_dtsi ()函数中新增MT65XX_LED_MODE_GPIO这个case对函数指针的赋值,kernel的需和lk的同步修改成一样的方式;
alps/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/mt_leds.c
static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
{
unsigned int BacklightLevelSupport = Cust_GetBacklightLevelSupport_byPWM();
if (level > LED_FULL)
level = LED_FULL;
else if (level < 0)
level = 0;
switch (cust->mode) {
case MT65XX_LED_MODE_PWM:
if (level == 0) {
//LEDS_INFO("[LEDS]LK: mt65xx_leds_set_cust: enter mt_pwm_disable()\n");
mt_pwm_disable(cust->data, cust->config_data.pmic_pad);
return 1;
}
if (strcmp(cust->name,"lcd-backlight") == 0) {
if (BacklightLevelSupport == BACKLIGHT_LEVEL_PWM_256_SUPPORT)
level = brightness_mapping(level);
else
level = brightness_mapto64(level);
return brightness_set_pwm(cust->data, level,&cust->config_data);
} else {
return led_set_pwm(cust->data, level);
}
case MT65XX_LED_MODE_GPIO:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_PMIC:
return brightness_set_pmic(cust->data, level);
case MT65XX_LED_MODE_CUST_LCM:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_CUST_BLS_PWM:
return ((cust_brightness_set)(cust->data))(level);
case MT65XX_LED_MODE_NONE:
default:
break;
}
return -1;
}
int cust_set_charge_led_by_gpio(int level)
{
if (255 == level)
LEDS_INFO("%s:line=%d,level=%d\n",__func__,__LINE__,level);
else
LEDS_INFO("%s:line=%d,level=%d\n",__func__,__LINE__,level);
return 0;
}
struct cust_mt65xx_led *get_cust_led_dtsi(void)
{
static bool isDTinited = false;
int i, offset;
int pwm_config[5] = {0};
#if defined(CFG_DTB_EARLY_LOADER_SUPPORT)
if ( isDTinited == true )
goto out;
for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
pled_dtsi[i].name = leds_name[i];
offset = fdt_path_offset(g_fdt, leds_node[i]);
if (offset < 0) {
LEDS_ERR("[LEDS]LK:Cannot find LED node from dts\n");
pled_dtsi[i].mode = 0;
pled_dtsi[i].data = -1;
} else {
isDTinited = true;
pled_dtsi[i].mode = led_fdt_getprop_u32(g_fdt, offset, "led_mode");
pled_dtsi[i].data = led_fdt_getprop_u32(g_fdt, offset, "data");
led_fdt_getprop_char_array(g_fdt, offset, "pwm_config", (char *)pwm_config);
pled_dtsi[i].config_data.clock_source = pwm_config[0];
pled_dtsi[i].config_data.div = pwm_config[1];
pled_dtsi[i].config_data.low_duration = pwm_config[2];
pled_dtsi[i].config_data.High_duration = pwm_config[3];
pled_dtsi[i].config_data.pmic_pad = pwm_config[4];
switch (pled_dtsi[i].mode) {
case MT65XX_LED_MODE_CUST_LCM:
pled_dtsi[i].data = (long)primary_display_setbacklight;
LEDS_ERR("[LEDS]LK:The backlight hw mode is LCM.\n");
break;
case MT65XX_LED_MODE_CUST_BLS_PWM:
pled_dtsi[i].data = (long)disp_bls_set_backlight;
LEDS_ERR("[LEDS]LK:The backlight hw mode is BLS.\n");
break;
//这里新增MT65XX_LED_MODE_GPIO这个case对pled_dtsi[i].data的赋值
case MT65XX_LED_MODE_GPIO:
pled_dtsi[i].data = (int) cust_set_charge_led_by_gpio;
break;
default:
break;
}
LEDS_INFO("[LEDS]LK:led[%d] offset is %d,mode is %d,data is %d .\n", \
i,offset,pled_dtsi[i].mode,pled_dtsi[i].data);
}
}
#endif
if ( isDTinited == false )
return NULL;
out:
return pled_dtsi;
}