hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/drivers/media/i2c/otp_eeprom.c
....@@ -9,8 +9,11 @@
99 * 3. add version control.
1010 * V0.0X01.0X02
1111 * 1. fix otp info null issue.
12
+ * V0.0X01.0X03
13
+ * 1. add buf read optimize otp read speed.
14
+ * 2. add mutex for otp read.
1215 */
13
-
16
+//#define DEBUG
1417 #include <linux/delay.h>
1518 #include <linux/i2c.h>
1619 #include <linux/module.h>
....@@ -24,7 +27,7 @@
2427 #include <linux/version.h>
2528 #include "otp_eeprom.h"
2629
27
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02)
30
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x03)
2831 #define DEVICE_NAME "otp_eeprom"
2932
3033 static inline struct eeprom_device
....@@ -64,6 +67,33 @@
6467 return -EIO;
6568
6669 *val = be32_to_cpu(data_be);
70
+
71
+ return 0;
72
+}
73
+
74
+/* Read registers buffers at a time */
75
+static int read_reg_otp_buf(struct i2c_client *client, u16 reg,
76
+ unsigned int len, u8 *buf)
77
+{
78
+ struct i2c_msg msgs[2];
79
+ __be16 reg_addr_be = cpu_to_be16(reg);
80
+ int ret;
81
+
82
+ /* Write register address */
83
+ msgs[0].addr = client->addr;
84
+ msgs[0].flags = 0;
85
+ msgs[0].len = 2;
86
+ msgs[0].buf = (u8 *)&reg_addr_be;
87
+
88
+ /* Read data from register */
89
+ msgs[1].addr = client->addr;
90
+ msgs[1].flags = I2C_M_RD;
91
+ msgs[1].len = len;
92
+ msgs[1].buf = buf;
93
+
94
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
95
+ if (ret != ARRAY_SIZE(msgs))
96
+ return -EIO;
6797
6898 return 0;
6999 }
....@@ -448,12 +478,18 @@
448478 struct i2c_client *client = eeprom_dev->client;
449479 struct device *dev = &eeprom_dev->client->dev;
450480 u32 checksum = 0;
451
- u32 temp = 0;
481
+ u8 *lsc_buf;
452482 int i = 0;
453483 int ret = 0;
454484 #ifdef DEBUG
455485 int w, h, j;
456486 #endif
487
+
488
+ lsc_buf = kzalloc(LSC_DATA_SIZE, GFP_KERNEL);
489
+ if (!lsc_buf) {
490
+ dev_err(dev, "%s ENOMEM!\n", __func__);
491
+ return;
492
+ }
457493
458494 ret = read_reg_otp(client, base_addr,
459495 4, &otp_ptr->lsc_data.size);
....@@ -463,12 +499,14 @@
463499 2, &otp_ptr->lsc_data.version);
464500 checksum += otp_ptr->lsc_data.version;
465501 base_addr += 2;
502
+
503
+ ret |= read_reg_otp_buf(client, base_addr,
504
+ LSC_DATA_SIZE, lsc_buf);
505
+ base_addr += LSC_DATA_SIZE;
506
+
466507 for (i = 0; i < LSC_DATA_SIZE; i++) {
467
- ret |= read_reg_otp(client, base_addr,
468
- 1, &temp);
469
- otp_ptr->lsc_data.data[i] = temp;
470
- checksum += temp;
471
- base_addr += 1;
508
+ otp_ptr->lsc_data.data[i] = lsc_buf[i];
509
+ checksum += lsc_buf[i];
472510 }
473511 otp_ptr->lsc_data.table_size = LSC_DATA_SIZE;
474512 #ifdef DEBUG
....@@ -482,12 +520,15 @@
482520 dev_info(dev, "\n");
483521 }
484522 #endif
523
+
524
+ memset(lsc_buf, 0, LSC_DATA_SIZE);
525
+ ret |= read_reg_otp_buf(client, base_addr,
526
+ RK_LSC_RESERVED_SIZE, lsc_buf);
527
+
485528 for (i = 0; i < RK_LSC_RESERVED_SIZE; i++) {
486
- ret |= read_reg_otp(client, base_addr,
487
- 1, &temp);
488
- checksum += temp;
489
- base_addr += 1;
529
+ checksum += lsc_buf[i];
490530 }
531
+ base_addr += RK_LSC_RESERVED_SIZE;
491532 ret |= read_reg_otp(client, base_addr,
492533 1, &otp_ptr->lsc_data.checksum);
493534 if ((checksum % 255 + 1) == otp_ptr->lsc_data.checksum && (!ret)) {
....@@ -502,6 +543,7 @@
502543 (int)(checksum % 255 + 1),
503544 (int)otp_ptr->lsc_data.checksum);
504545 }
546
+ kfree(lsc_buf);
505547 }
506548
507549 static void rkotp_read_pdaf(struct eeprom_device *eeprom_dev,
....@@ -511,12 +553,18 @@
511553 struct i2c_client *client = eeprom_dev->client;
512554 struct device *dev = &eeprom_dev->client->dev;
513555 u32 checksum = 0;
514
- u32 temp = 0;
556
+ u8 *pdaf_buf;
515557 int i = 0;
516558 int ret = 0;
517559 #ifdef DEBUG
518560 int w, h, j;
519561 #endif
562
+
563
+ pdaf_buf = kzalloc(RK_GAINMAP_SIZE, GFP_KERNEL);
564
+ if (!pdaf_buf) {
565
+ dev_err(dev, "%s ENOMEM!\n", __func__);
566
+ return;
567
+ }
520568
521569 ret = read_reg_otp(client, base_addr,
522570 4, &otp_ptr->pdaf_data.size);
....@@ -534,11 +582,14 @@
534582 1, &otp_ptr->pdaf_data.gainmap_height);
535583 checksum += otp_ptr->pdaf_data.gainmap_height;
536584 base_addr += 1;
585
+
586
+ ret |= read_reg_otp_buf(client, base_addr,
587
+ RK_GAINMAP_SIZE, pdaf_buf);
588
+ base_addr += RK_GAINMAP_SIZE;
589
+
537590 for (i = 0; i < RK_GAINMAP_SIZE; i++) {
538
- ret |= read_reg_otp(client, base_addr,
539
- 1, &otp_ptr->pdaf_data.gainmap[i]);
591
+ otp_ptr->pdaf_data.gainmap[i] = pdaf_buf[i];
540592 checksum += otp_ptr->pdaf_data.gainmap[i];
541
- base_addr += 1;
542593 }
543594 #ifdef DEBUG
544595 w = 64;
....@@ -571,12 +622,17 @@
571622 1, &otp_ptr->pdaf_data.dccmap_height);
572623 checksum += otp_ptr->pdaf_data.dccmap_height;
573624 base_addr += 1;
625
+
626
+ memset(pdaf_buf, 0, RK_DCCMAP_SIZE);
627
+ ret |= read_reg_otp_buf(client, base_addr,
628
+ RK_DCCMAP_SIZE, pdaf_buf);
629
+
574630 for (i = 0; i < RK_DCCMAP_SIZE; i++) {
575
- ret |= read_reg_otp(client, base_addr,
576
- 1, &otp_ptr->pdaf_data.dccmap[i]);
631
+ otp_ptr->pdaf_data.dccmap[i] = pdaf_buf[i];
577632 checksum += otp_ptr->pdaf_data.dccmap[i];
578
- base_addr += 1;
579633 }
634
+ base_addr += RK_DCCMAP_SIZE;
635
+
580636 #ifdef DEBUG
581637 w = 32;
582638 h = 16;
....@@ -592,12 +648,21 @@
592648 1, &otp_ptr->pdaf_data.dccmap_checksum);
593649 checksum += otp_ptr->pdaf_data.dccmap_checksum;
594650 base_addr += 1;
651
+
652
+ ret |= read_reg_otp(client, base_addr,
653
+ 2, &otp_ptr->pdaf_data.pd_offset);
654
+ checksum += otp_ptr->pdaf_data.pd_offset;
655
+ base_addr += 2;
656
+
657
+ memset(pdaf_buf, 0, RK_PDAF_RESERVED_SIZE);
658
+ ret |= read_reg_otp_buf(client, base_addr,
659
+ RK_PDAF_RESERVED_SIZE, pdaf_buf);
660
+
595661 for (i = 0; i < RK_PDAF_RESERVED_SIZE; i++) {
596
- ret |= read_reg_otp(client, base_addr,
597
- 1, &temp);
598
- checksum += temp;
599
- base_addr += 1;
662
+ checksum += pdaf_buf[i];
600663 }
664
+ base_addr += RK_PDAF_RESERVED_SIZE;
665
+
601666 ret |= read_reg_otp(client, base_addr,
602667 1, &otp_ptr->pdaf_data.checksum);
603668 if ((checksum % 255 + 1) == otp_ptr->pdaf_data.checksum && (!ret)) {
....@@ -612,6 +677,7 @@
612677 (int)(checksum % 255 + 1),
613678 (int)otp_ptr->pdaf_data.checksum);
614679 }
680
+ kfree(pdaf_buf);
615681 }
616682
617683 static void rkotp_read_af(struct eeprom_device *eeprom_dev,
....@@ -738,6 +804,7 @@
738804 u8 vendor_flag = 0;
739805 struct i2c_client *client = eeprom_dev->client;
740806
807
+ mutex_lock(&eeprom_dev->mutex);
741808 vendor_flag = get_vendor_flag(client);
742809 if (vendor_flag == 0x80)
743810 otp_read_data(eeprom_dev);
....@@ -745,8 +812,11 @@
745812 rkotp_read_data(eeprom_dev);
746813 else {
747814 dev_warn(&client->dev, "no vendor flag infos!\n");
815
+ mutex_unlock(&eeprom_dev->mutex);
748816 return -1;
749817 }
818
+
819
+ mutex_unlock(&eeprom_dev->mutex);
750820 return 0;
751821 }
752822
....@@ -866,7 +936,7 @@
866936 seq_printf(p, "flag=%d;\n", dev->otp->pdaf_data.flag);
867937 seq_printf(p, "gainmap_width=%d;\n", gainmap_w);
868938 seq_printf(p, "gainmap_height=%d;\n", gainmap_h);
869
-
939
+ seq_printf(p, "pd_offset=%d\n", dev->otp->pdaf_data.pd_offset);
870940 seq_printf(p, "gainmap_table=\n");
871941 for (i = 0; i < gainmap_h; i++) {
872942 for (j = 0; j < gainmap_w; j++) {
....@@ -917,12 +987,11 @@
917987 return single_open(file, otp_eeprom_show, data);
918988 }
919989
920
-static const struct file_operations ops = {
921
- .owner = THIS_MODULE,
922
- .open = eeprom_open,
923
- .read = seq_read,
924
- .llseek = seq_lseek,
925
- .release = single_release,
990
+static const struct proc_ops ops = {
991
+ .proc_open = eeprom_open,
992
+ .proc_read = seq_read,
993
+ .proc_lseek = seq_lseek,
994
+ .proc_release = single_release,
926995 };
927996
928997 static int eeprom_proc_init(struct eeprom_device *dev)
....@@ -974,6 +1043,7 @@
9741043 dev_err(&client->dev, "Probe failed\n");
9751044 return -ENOMEM;
9761045 }
1046
+ mutex_init(&eeprom_dev->mutex);
9771047 v4l2_i2c_subdev_init(&eeprom_dev->sd,
9781048 client, &eeprom_ops);
9791049 eeprom_dev->client = client;
....@@ -995,6 +1065,7 @@
9951065 struct eeprom_device *eeprom_dev =
9961066 sd_to_eeprom(sd);
9971067 kfree(eeprom_dev->otp);
1068
+ mutex_destroy(&eeprom_dev->mutex);
9981069 pm_runtime_disable(&client->dev);
9991070 eeprom_subdev_cleanup(eeprom_dev);
10001071 eeprom_proc_cleanup(eeprom_dev);