Merge cherrypicks of [9304298, 9304299, 9304364, 9304365, 9304415, 9304416, 9304417] into oc-mr1-1.11-iot-release

Change-Id: Ic4837f6a313e73173d5fe62a0efc9e953c0ffba2
diff --git a/arch/arm64/boot/dts/mediatek/mt8167s_sp2.dts b/arch/arm64/boot/dts/mediatek/mt8167s_sp2.dts
index 90bf5b6..d82bc9a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8167s_sp2.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8167s_sp2.dts
@@ -30,6 +30,10 @@
 	};
 };
 
+&disp_pwm0 {
+	offset-backlight;
+};
+
 &i2c0 {
 	status = "okay";
 	clock-frequency = <400000>;
@@ -146,6 +150,15 @@
 
 &led6 {
 	status = "okay";
+	/* If this exceeds 10 entries then
+	 * change PWM_LEVEL_SIZE in ddp_pwm.c */
+	pwm_level_remap =
+	<
+	/* level <= [0] then level * [1] + [2]*/
+	30 1 0 /* map to 0 - 30 */
+	65 2 (-30) /* map to 32 - 100 */
+	249 5 (-255) /* map to 105 - 1020 */
+	>;
 };
 
 &mt6392keys {
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668-usb/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668-usb/mgmt/rlm_domain.c
index 799f174..75b28aa 100755
--- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668-usb/mgmt/rlm_domain.c
+++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668-usb/mgmt/rlm_domain.c
@@ -1892,7 +1892,10 @@
 	kalMemZero(pucConfigBuf, WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE);
 	u4ConfigReadLen = 0;
 
-	if (wlanGetFileContent(prAdapter, WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
+	if (wlanGetFileContent(prAdapter, "/oem/firmware/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
+				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, FALSE) == 0) {
+		/* ToDo:: Nothing */
+	}else if (wlanGetFileContent(prAdapter, WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
 				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, TRUE) == 0) {
 		/* ToDo:: Nothing */
 	} else if (wlanGetFileContent(prAdapter, "/storage/sdcard0/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
@@ -1904,10 +1907,7 @@
 	} else if (wlanGetFileContent(prAdapter, "/data/misc/wifi/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
 				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, FALSE) == 0) {
 		/* ToDo:: Nothing */
-	} else if (wlanGetFileContent(prAdapter, "/oem/firmware/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
-				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, FALSE) == 0) {
-		/* ToDo:: Nothing */
-	}  else {
+	} else {
 		bRet = FALSE;
 		goto error;
 	}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/rlm_domain.c
index 799f174..75b28aa 100755
--- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/rlm_domain.c
+++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/rlm_domain.c
@@ -1892,7 +1892,10 @@
 	kalMemZero(pucConfigBuf, WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE);
 	u4ConfigReadLen = 0;
 
-	if (wlanGetFileContent(prAdapter, WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
+	if (wlanGetFileContent(prAdapter, "/oem/firmware/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
+				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, FALSE) == 0) {
+		/* ToDo:: Nothing */
+	}else if (wlanGetFileContent(prAdapter, WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
 				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, TRUE) == 0) {
 		/* ToDo:: Nothing */
 	} else if (wlanGetFileContent(prAdapter, "/storage/sdcard0/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
@@ -1904,10 +1907,7 @@
 	} else if (wlanGetFileContent(prAdapter, "/data/misc/wifi/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
 				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, FALSE) == 0) {
 		/* ToDo:: Nothing */
-	} else if (wlanGetFileContent(prAdapter, "/oem/firmware/" WLAN_TX_PWR_LIMIT_FILE_NAME, pucConfigBuf,
-				 WLAN_TX_PWR_LIMIT_FILE_BUF_SIZE, &u4ConfigReadLen, FALSE) == 0) {
-		/* ToDo:: Nothing */
-	}  else {
+	} else {
 		bRet = FALSE;
 		goto error;
 	}
diff --git a/drivers/misc/mediatek/video/common/pwm10/ddp_pwm.c b/drivers/misc/mediatek/video/common/pwm10/ddp_pwm.c
index c8a580e..302032e 100644
--- a/drivers/misc/mediatek/video/common/pwm10/ddp_pwm.c
+++ b/drivers/misc/mediatek/video/common/pwm10/ddp_pwm.c
@@ -122,6 +122,18 @@
 #endif		/* CONFIG_FPGA_EARLY_PORTING */
 static int g_pwm_log_num = PWM_LOG_BUFFER_SIZE;
 
+#define PWM_LEVEL_SIZE 10
+struct PWM_LEVEL {
+	u32 level;
+	u32 step;
+	u32 offset;
+};
+static struct PWM_LEVEL pwm_level_remap_data[PWM_LEVEL_SIZE] = {{ 0 }};
+static int pwm_level_remap_data_count = 0;
+static void disp_pwm_get_mapping_config(struct device_node *);
+static bool read_offset_backlight(void);
+static bool is_offset_backlight = false;
+
 int disp_pwm_get_cust_led(unsigned int *clocksource, unsigned int *clockdiv)
 {
 	struct device_node *led_node = NULL;
@@ -154,7 +166,9 @@
 				PWM_ERR("led dts can not get led mode data.\n");
 			}
 		}
+		disp_pwm_get_mapping_config(led_node);
 	}
+        is_offset_backlight = read_offset_backlight();
 
 	if (ret)
 		PWM_ERR("get pwm cust info fail");
@@ -292,6 +306,47 @@
 	return ret;
 }
 
+static bool read_offset_backlight() {
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, ddp_get_reg_module_name(DISP_REG_PWM));
+	if (np == NULL) {
+		PWM_MSG("DT %s is not found from DTS\n", ddp_get_reg_module_name(DISP_REG_PWM));
+		return false;
+	}
+
+	return of_property_read_bool(np, "offset-backlight");
+}
+
+static void disp_pwm_get_mapping_config(struct device_node *led_node) {
+	int elements = 0;
+	int ret;
+
+	PWM_NOTICE("Reading mapping data from dts.\n");
+	elements = of_property_count_elems_of_size(
+			led_node, "pwm_level_remap", sizeof(struct PWM_LEVEL));
+	if (elements <= 0) {
+		PWM_ERR("Failed to get size of pwm_level_data: %d\n", elements);
+		return;
+	}
+	if (elements > PWM_LEVEL_SIZE) {
+		elements = PWM_LEVEL_SIZE;
+	}
+	PWM_NOTICE("Reading %d records of PWM level remap data\n", elements);
+	ret = of_property_read_u32_array(
+			led_node,
+			"pwm_level_remap",
+			(u32 *)&pwm_level_remap_data,
+			elements * sizeof(struct PWM_LEVEL) / sizeof(u32));
+	if (ret == 0) {
+		pwm_level_remap_data_count = elements;
+	} else {
+		pwm_level_remap_data_count = 0;
+		PWM_ERR("Failed to read pwm_level_data. No mapping will take place.\n");
+		return;
+	}
+}
+
 static void disp_pwm_trigger_refresh(enum disp_pwm_id_t id, int quick)
 {
 	if (g_ddp_notify != NULL) {
@@ -390,6 +445,28 @@
  */
 static int disp_pwm_level_remap(enum disp_pwm_id_t id, int level_1024)
 {
+	int i;
+	int max_level_1024 = disp_pwm_get_max_backlight(id);
+	// Convert to AT's 1-256 levels then remap to 1024 because we have the
+	// technology to adjust the mapping concentrating on the dimmer end.
+	int level = level_1024 / 4;
+	if (level_1024 != 0 && level < 1) {
+		level = 1;
+	}
+	// Now map back to 1024 smoothly.
+	for (i=0; i < pwm_level_remap_data_count; i++) {
+		struct PWM_LEVEL *data = &pwm_level_remap_data[i];
+		if (level <= data->level) {
+			level_1024 = level * data->step + data->offset;
+			break;
+		}
+	}
+	// Clamp the values, just in case
+	if (level_1024 < 0) {
+		level_1024 = 0;
+	} else if (level_1024 > max_level_1024) {
+		level_1024 = max_level_1024;
+	}
 	return level_1024;
 }
 
@@ -551,10 +628,20 @@
 		reg_base = pwm_get_reg_base(id);
 		DISP_REG_MASK(cmdq, reg_base + DISP_PWM_CON_1_OFF, level_1024 << 16, 0x1fff << 16);
 
-		if (level_1024 > 0)
+		if (level_1024 > 0) {
+                        if (level_1024 == 1 && is_offset_backlight) {
+                                DISP_REG_MASK(cmdq, reg_base + DISP_PWM_CON_1_OFF, 4095, 0xfff);
+                                PWM_NOTICE("1==level_1024=%d DISP_PWM_CON_1_OFF=0x%x",
+                                           level_1024, DISP_REG_GET(reg_base + DISP_PWM_CON_1_OFF));
+                        } else {
+                                DISP_REG_MASK(cmdq, reg_base + DISP_PWM_CON_1_OFF, 1023, 0xfff);
+                                PWM_NOTICE("1!=level_1024=%d DISP_PWM_CON_1_OFF=0x%x",
+                                           level_1024, DISP_REG_GET(reg_base + DISP_PWM_CON_1_OFF));
+                        }
 			disp_pwm_set_enabled(cmdq, id, 1);
-		else
+		} else {
 			disp_pwm_set_enabled(cmdq, id, 0);	/* To save power */
+		}
 
 		DISP_REG_MASK(cmdq, reg_base + DISP_PWM_COMMIT_OFF, 1, ~0);
 		DISP_REG_MASK(cmdq, reg_base + DISP_PWM_COMMIT_OFF, 0, ~0);
@@ -697,7 +784,7 @@
 };
 
 /* ---------------------------------------------------------------------- */
-/* disp pwm clock source query api                                                              */
+/* disp pwm clock source query api                                        */
 /* ---------------------------------------------------------------------- */
 
 bool disp_pwm_is_osc(void)