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 *)®_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