8. LED调试日志

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;
}
	
	
	
	
	
	
	
	
	





你可能感兴趣的:(mtk驱动)