From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198

---
 kernel/drivers/mfd/display-serdes/serdes-i2c.c |   93 ++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/kernel/drivers/mfd/display-serdes/serdes-i2c.c b/kernel/drivers/mfd/display-serdes/serdes-i2c.c
index 317126e..951d40d 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-i2c.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-i2c.c
@@ -9,6 +9,8 @@
 
 #include "core.h"
 
+static struct serdes *g_serdes_ser_split[MAX_NUM_SERDES_SPLIT];
+
 int serdes_i2c_set_sequence(struct serdes *serdes)
 {
 	struct device *dev = serdes->dev;
@@ -52,6 +54,42 @@
 	return ret;
 }
 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence);
+
+static int serdes_set_i2c_address(struct serdes *serdes, u32 reg_hw, u32 reg_use, int link)
+{
+	int ret = 0;
+	struct i2c_client *client_split;
+	struct serdes *serdes_split = serdes->g_serdes_bridge_split;
+
+	if (!serdes_split) {
+		pr_info("%s: serdes_split is null\n", __func__);
+		return -1;
+	}
+
+	client_split = to_i2c_client(serdes->regmap->dev);
+	SERDES_DBG_MFD("%s: %s-%s addr=0x%x reg_hw=0x%x, reg_use=0x%x serdes_split=0x%p\n",
+		       __func__, dev_name(serdes_split->dev), client_split->name,
+		       client_split->addr, serdes->reg_hw, serdes->reg_use, serdes_split);
+
+	client_split->addr = serdes->reg_hw;
+
+	if (serdes_split && serdes_split->chip_data->split_ops &&
+	    serdes_split->chip_data->split_ops->select)
+		ret = serdes_split->chip_data->split_ops->select(serdes_split, link);
+
+	if (serdes->chip_data->split_ops && serdes->chip_data->split_ops->set_i2c_addr)
+		serdes->chip_data->split_ops->set_i2c_addr(serdes, reg_use, link);
+
+	if (serdes_split && serdes_split->chip_data->split_ops &&
+	    serdes_split->chip_data->split_ops->select)
+		ret = serdes_split->chip_data->split_ops->select(serdes_split, SER_SPLITTER_MODE);
+
+	client_split->addr = serdes->reg_use;
+
+	serdes_i2c_set_sequence(serdes);
+
+	return ret;
+}
 
 static void serdes_mfd_work(struct work_struct *work)
 {
@@ -125,8 +163,11 @@
 
 	/* init ser register(not des register) more early if uboot logo disabled */
 	serdes->route_enable = of_property_read_bool(dev->of_node, "route-enable");
-	if ((!serdes->route_enable) && (serdes->chip_data->serdes_type == TYPE_SER))
+	if ((!serdes->route_enable) && (serdes->chip_data->serdes_type == TYPE_SER)) {
+		if (serdes->chip_data->chip_init)
+			serdes->chip_data->chip_init(serdes);
 		ret = serdes_i2c_set_sequence(serdes);
+	}
 
 	return ret;
 }
@@ -146,7 +187,8 @@
 	serdes->chip_data = (struct serdes_chip_data *)of_device_get_match_data(dev);
 	i2c_set_clientdata(client, serdes);
 
-	dev_info(dev, "serdes %s probe start\n", serdes->chip_data->name);
+	dev_info(dev, "serdes %s probe start, id=%d\n", serdes->chip_data->name,
+		 serdes->chip_data->serdes_id);
 
 	serdes->type = serdes->chip_data->serdes_type;
 	serdes->regmap = devm_regmap_init_i2c(client, serdes->chip_data->regmap_config);
@@ -171,7 +213,6 @@
 	if (IS_ERR(serdes->vpower)) {
 		if (PTR_ERR(serdes->vpower) != -ENODEV)
 			return PTR_ERR(serdes->vpower);
-		dev_info(dev, "no vpower regulator found\n");
 	}
 
 	if (!IS_ERR(serdes->vpower)) {
@@ -194,8 +235,7 @@
 
 	ret = serdes_get_init_seq(serdes);
 	if (ret)
-		return dev_err_probe(dev, ret,
-				     "failed to write serdes register with i2c\n");
+		dev_err(dev, "failed to write serdes register with i2c\n");
 
 	mutex_init(&serdes->io_lock);
 	dev_set_drvdata(serdes->dev, serdes);
@@ -203,6 +243,31 @@
 	if (ret != 0) {
 		serdes_irq_exit(serdes);
 		return ret;
+	}
+
+	of_property_read_u32(dev->of_node, "id-serdes-bridge-split",
+			     &serdes->id_serdes_bridge_split);
+	if ((serdes->id_serdes_bridge_split < MAX_NUM_SERDES_SPLIT) && (serdes->type == TYPE_SER)) {
+		g_serdes_ser_split[serdes->id_serdes_bridge_split] = serdes;
+		SERDES_DBG_MFD("%s: %s-%s g_serdes_split[%d]=0x%p\n", __func__,
+			       dev_name(serdes->dev), serdes->chip_data->name,
+			       serdes->id_serdes_bridge_split, serdes);
+	}
+
+	of_property_read_u32(dev->of_node, "reg-hw", &serdes->reg_hw);
+	of_property_read_u32(dev->of_node, "reg", &serdes->reg_use);
+	of_property_read_u32(dev->of_node, "link", &serdes->link_use);
+	of_property_read_u32(dev->of_node, "id-serdes-panel-split", &serdes->id_serdes_panel_split);
+	if ((serdes->id_serdes_panel_split) && (serdes->type == TYPE_DES)) {
+		serdes->g_serdes_bridge_split = g_serdes_ser_split[serdes->id_serdes_panel_split];
+		SERDES_DBG_MFD("%s: id=%d p=0x%p\n", __func__,
+			       serdes->id_serdes_panel_split, serdes->g_serdes_bridge_split);
+	}
+
+	if (serdes->reg_hw) {
+		SERDES_DBG_MFD("%s: %s start change i2c address from 0x%x to 0x%x\n",
+			       __func__, dev->of_node->name, serdes->reg_hw, serdes->reg_use);
+		serdes_set_i2c_address(serdes, serdes->reg_hw, serdes->reg_use, serdes->link_use);
 	}
 
 	serdes->use_delay_work = of_property_read_bool(dev->of_node, "use-delay-work");
@@ -215,14 +280,22 @@
 		queue_delayed_work(serdes->mfd_wq, &serdes->mfd_delay_work, msecs_to_jiffies(300));
 		SERDES_DBG_MFD("%s: use_delay_work=%d\n", __func__, serdes->use_delay_work);
 	} else {
-		ret = serdes_device_init(serdes);
+		serdes_device_init(serdes);
 		SERDES_DBG_MFD("%s: use_delay_work=%d\n", __func__, serdes->use_delay_work);
 	}
 
 	dev_info(dev, "serdes %s serdes_i2c_probe successful version %s\n",
 		 serdes->chip_data->name, MFD_SERDES_DISPLAY_VERSION);
 
-	return ret;
+	return 0;
+}
+
+static void serdes_i2c_shutdown(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct serdes *serdes = dev_get_drvdata(dev);
+
+	serdes_device_shutdown(serdes);
 }
 
 static int serdes_i2c_prepare(struct device *dev)
@@ -266,7 +339,7 @@
 {
 	struct serdes *serdes = dev_get_drvdata(dev);
 
-	serdes_device_shutdown(serdes);
+	serdes_device_poweroff(serdes);
 
 	return 0;
 }
@@ -289,6 +362,9 @@
 #endif
 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772)
 	{ .compatible = "maxim,max96772", .data = &serdes_max96772_data },
+#endif
+#if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96789)
+	{ .compatible = "maxim,max96789", .data = &serdes_max96789_data },
 #endif
 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX111)
 	{ .compatible = "rockchip,rkx111", .data = &serdes_rkx111_data },
@@ -317,6 +393,7 @@
 		.of_match_table = of_match_ptr(serdes_of_match),
 	},
 	.probe = serdes_i2c_probe,
+	.shutdown = serdes_i2c_shutdown,
 };
 
 static int __init serdes_i2c_init(void)

--
Gitblit v1.6.2