From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh

---
 kernel/drivers/media/i2c/otp_eeprom.c |  131 +++++++++++++++++++++++++++++++++----------
 1 files changed, 101 insertions(+), 30 deletions(-)

diff --git a/kernel/drivers/media/i2c/otp_eeprom.c b/kernel/drivers/media/i2c/otp_eeprom.c
index 61455c9..315220e 100644
--- a/kernel/drivers/media/i2c/otp_eeprom.c
+++ b/kernel/drivers/media/i2c/otp_eeprom.c
@@ -9,8 +9,11 @@
  * 3. add version control.
  * V0.0X01.0X02
  * 1. fix otp info null issue.
+ * V0.0X01.0X03
+ * 1. add buf read optimize otp read speed.
+ * 2. add mutex for otp read.
  */
-
+//#define DEBUG
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
@@ -24,7 +27,7 @@
 #include <linux/version.h>
 #include "otp_eeprom.h"
 
-#define DRIVER_VERSION		KERNEL_VERSION(0, 0x01, 0x02)
+#define DRIVER_VERSION		KERNEL_VERSION(0, 0x01, 0x03)
 #define DEVICE_NAME			"otp_eeprom"
 
 static inline struct eeprom_device
@@ -64,6 +67,33 @@
 		return -EIO;
 
 	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+/* Read registers buffers at a time */
+static int read_reg_otp_buf(struct i2c_client *client, u16 reg,
+	unsigned int len, u8 *buf)
+{
+	struct i2c_msg msgs[2];
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = buf;
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
 
 	return 0;
 }
@@ -448,12 +478,18 @@
 	struct i2c_client *client = eeprom_dev->client;
 	struct device *dev = &eeprom_dev->client->dev;
 	u32 checksum = 0;
-	u32 temp = 0;
+	u8 *lsc_buf;
 	int i = 0;
 	int ret = 0;
 #ifdef DEBUG
 	int w, h, j;
 #endif
+
+	lsc_buf = kzalloc(LSC_DATA_SIZE, GFP_KERNEL);
+	if (!lsc_buf) {
+		dev_err(dev, "%s ENOMEM!\n", __func__);
+		return;
+	}
 
 	ret = read_reg_otp(client, base_addr,
 		4, &otp_ptr->lsc_data.size);
@@ -463,12 +499,14 @@
 		2, &otp_ptr->lsc_data.version);
 	checksum += otp_ptr->lsc_data.version;
 	base_addr += 2;
+
+	ret |= read_reg_otp_buf(client, base_addr,
+	       LSC_DATA_SIZE, lsc_buf);
+	base_addr += LSC_DATA_SIZE;
+
 	for (i = 0; i < LSC_DATA_SIZE; i++) {
-		ret |= read_reg_otp(client, base_addr,
-			1, &temp);
-		otp_ptr->lsc_data.data[i] = temp;
-		checksum += temp;
-		base_addr += 1;
+		otp_ptr->lsc_data.data[i] = lsc_buf[i];
+		checksum += lsc_buf[i];
 	}
 	otp_ptr->lsc_data.table_size = LSC_DATA_SIZE;
 #ifdef DEBUG
@@ -482,12 +520,15 @@
 			dev_info(dev, "\n");
 	}
 #endif
+
+	memset(lsc_buf, 0, LSC_DATA_SIZE);
+	ret |= read_reg_otp_buf(client, base_addr,
+	       RK_LSC_RESERVED_SIZE, lsc_buf);
+
 	for (i = 0; i < RK_LSC_RESERVED_SIZE; i++) {
-		ret |= read_reg_otp(client, base_addr,
-			1, &temp);
-		checksum += temp;
-		base_addr += 1;
+		checksum += lsc_buf[i];
 	}
+	base_addr += RK_LSC_RESERVED_SIZE;
 	ret |= read_reg_otp(client, base_addr,
 		1, &otp_ptr->lsc_data.checksum);
 	if ((checksum % 255 + 1) == otp_ptr->lsc_data.checksum && (!ret)) {
@@ -502,6 +543,7 @@
 			 (int)(checksum % 255 + 1),
 			 (int)otp_ptr->lsc_data.checksum);
 	}
+	kfree(lsc_buf);
 }
 
 static void rkotp_read_pdaf(struct eeprom_device *eeprom_dev,
@@ -511,12 +553,18 @@
 	struct i2c_client *client = eeprom_dev->client;
 	struct device *dev = &eeprom_dev->client->dev;
 	u32 checksum = 0;
-	u32 temp = 0;
+	u8 *pdaf_buf;
 	int i = 0;
 	int ret = 0;
 #ifdef DEBUG
 	int w, h, j;
 #endif
+
+	pdaf_buf = kzalloc(RK_GAINMAP_SIZE, GFP_KERNEL);
+	if (!pdaf_buf) {
+		dev_err(dev, "%s ENOMEM!\n", __func__);
+		return;
+	}
 
 	ret = read_reg_otp(client, base_addr,
 		4, &otp_ptr->pdaf_data.size);
@@ -534,11 +582,14 @@
 		1, &otp_ptr->pdaf_data.gainmap_height);
 	checksum += otp_ptr->pdaf_data.gainmap_height;
 	base_addr += 1;
+
+	ret |= read_reg_otp_buf(client, base_addr,
+	       RK_GAINMAP_SIZE, pdaf_buf);
+	base_addr += RK_GAINMAP_SIZE;
+
 	for (i = 0; i < RK_GAINMAP_SIZE; i++) {
-		ret |= read_reg_otp(client, base_addr,
-			1, &otp_ptr->pdaf_data.gainmap[i]);
+		otp_ptr->pdaf_data.gainmap[i] = pdaf_buf[i];
 		checksum += otp_ptr->pdaf_data.gainmap[i];
-		base_addr += 1;
 	}
 #ifdef DEBUG
 	w = 64;
@@ -571,12 +622,17 @@
 		1, &otp_ptr->pdaf_data.dccmap_height);
 	checksum += otp_ptr->pdaf_data.dccmap_height;
 	base_addr += 1;
+
+	memset(pdaf_buf, 0, RK_DCCMAP_SIZE);
+	ret |= read_reg_otp_buf(client, base_addr,
+	       RK_DCCMAP_SIZE, pdaf_buf);
+
 	for (i = 0; i < RK_DCCMAP_SIZE; i++) {
-		ret |= read_reg_otp(client, base_addr,
-			1, &otp_ptr->pdaf_data.dccmap[i]);
+		otp_ptr->pdaf_data.dccmap[i] = pdaf_buf[i];
 		checksum += otp_ptr->pdaf_data.dccmap[i];
-		base_addr += 1;
 	}
+	base_addr += RK_DCCMAP_SIZE;
+
 #ifdef DEBUG
 	w = 32;
 	h = 16;
@@ -592,12 +648,21 @@
 		1, &otp_ptr->pdaf_data.dccmap_checksum);
 	checksum += otp_ptr->pdaf_data.dccmap_checksum;
 	base_addr += 1;
+
+	ret |= read_reg_otp(client, base_addr,
+		2, &otp_ptr->pdaf_data.pd_offset);
+	checksum += otp_ptr->pdaf_data.pd_offset;
+	base_addr += 2;
+
+	memset(pdaf_buf, 0, RK_PDAF_RESERVED_SIZE);
+	ret |= read_reg_otp_buf(client, base_addr,
+	       RK_PDAF_RESERVED_SIZE, pdaf_buf);
+
 	for (i = 0; i < RK_PDAF_RESERVED_SIZE; i++) {
-		ret |= read_reg_otp(client, base_addr,
-			1, &temp);
-		checksum += temp;
-		base_addr += 1;
+		checksum += pdaf_buf[i];
 	}
+	base_addr += RK_PDAF_RESERVED_SIZE;
+
 	ret |= read_reg_otp(client, base_addr,
 		1, &otp_ptr->pdaf_data.checksum);
 	if ((checksum % 255 + 1) == otp_ptr->pdaf_data.checksum && (!ret)) {
@@ -612,6 +677,7 @@
 			 (int)(checksum % 255 + 1),
 			 (int)otp_ptr->pdaf_data.checksum);
 	}
+	kfree(pdaf_buf);
 }
 
 static void rkotp_read_af(struct eeprom_device *eeprom_dev,
@@ -738,6 +804,7 @@
 	u8 vendor_flag = 0;
 	struct i2c_client *client = eeprom_dev->client;
 
+	mutex_lock(&eeprom_dev->mutex);
 	vendor_flag = get_vendor_flag(client);
 	if (vendor_flag == 0x80)
 		otp_read_data(eeprom_dev);
@@ -745,8 +812,11 @@
 		rkotp_read_data(eeprom_dev);
 	else {
 		dev_warn(&client->dev, "no vendor flag infos!\n");
+		mutex_unlock(&eeprom_dev->mutex);
 		return -1;
 	}
+
+	mutex_unlock(&eeprom_dev->mutex);
 	return 0;
 }
 
@@ -866,7 +936,7 @@
 			seq_printf(p, "flag=%d;\n", dev->otp->pdaf_data.flag);
 			seq_printf(p, "gainmap_width=%d;\n", gainmap_w);
 			seq_printf(p, "gainmap_height=%d;\n", gainmap_h);
-
+			seq_printf(p, "pd_offset=%d\n", dev->otp->pdaf_data.pd_offset);
 			seq_printf(p, "gainmap_table=\n");
 			for (i = 0; i < gainmap_h; i++) {
 				for (j = 0; j < gainmap_w; j++) {
@@ -917,12 +987,11 @@
 	return single_open(file, otp_eeprom_show, data);
 }
 
-static const struct file_operations ops = {
-	.owner		= THIS_MODULE,
-	.open		= eeprom_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
+static const struct proc_ops ops = {
+	.proc_open	= eeprom_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= single_release,
 };
 
 static int eeprom_proc_init(struct eeprom_device *dev)
@@ -974,6 +1043,7 @@
 		dev_err(&client->dev, "Probe failed\n");
 		return -ENOMEM;
 	}
+	mutex_init(&eeprom_dev->mutex);
 	v4l2_i2c_subdev_init(&eeprom_dev->sd,
 		client, &eeprom_ops);
 	eeprom_dev->client = client;
@@ -995,6 +1065,7 @@
 	struct eeprom_device *eeprom_dev =
 		sd_to_eeprom(sd);
 	kfree(eeprom_dev->otp);
+	mutex_destroy(&eeprom_dev->mutex);
 	pm_runtime_disable(&client->dev);
 	eeprom_subdev_cleanup(eeprom_dev);
 	eeprom_proc_cleanup(eeprom_dev);

--
Gitblit v1.6.2