[9610] fimc-is2: add bu24218 OIS factory test
authorXiaofei Ma <xiaofei@motorola.com>
Wed, 9 Jan 2019 22:48:45 +0000 (16:48 -0600)
committerKim Gunho <gunho.kim@samsung.com>
Wed, 7 Aug 2019 13:00:15 +0000 (22:00 +0900)
Firmware version and hea test support.

Change-Id: Iafdd03a47c73aadbb19ed50f71755c51f1adb9c8
Signed-off-by: Wooyeon Kim <wooy88.kim@samsung.com>
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/fimc-is-interface-sensor.h
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/modules/fimc-is-device-module-base.c
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Kconfig
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Makefile
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.c
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.h
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.c [new file with mode: 0644]
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.h [new file with mode: 0644]
include/uapi/linux/videodev2_exynos_camera.h

index dadc3741e2c66bd27f97fa422ad7a5ac82418915..2b0a77163e114dc3ba063fd61cc3a83510a92538 100755 (executable)
@@ -695,6 +695,10 @@ struct fimc_is_ois_ops {
        int (*ois_center_shift)(struct v4l2_subdev *subdev);
        int (*ois_set_center)(struct v4l2_subdev *subdev);
        u8 (*ois_read_mode)(struct v4l2_subdev *subdev);
+#ifdef CONFIG_OIS_BU24218_FACTORY_TEST
+       int (*ois_factory_fw_ver)(struct v4l2_subdev *subdev, u32* result);
+       int (*ois_factory_hea)(struct v4l2_subdev *subdev, u32* result);
+#endif
 };
 
 struct fimc_is_sensor_interface;
index 3d5bab5d478de7abe249aa6c3f6fd5caa549333c..0a2dea068eb7c8130e0da0f846420f62fd6ab105 100644 (file)
@@ -651,6 +651,26 @@ int sensor_module_g_ctrl(struct v4l2_subdev *subdev, struct v4l2_control *ctrl)
                        goto p_err;
                }
                break;
+#ifdef CONFIG_OIS_BU24218_FACTORY_TEST
+       case V4L2_CID_IS_FACTORY_OIS_FW_VER:
+               ret = CALL_OISOPS(sensor_peri->ois, ois_factory_fw_ver,
+                        sensor_peri->subdev_ois, &ctrl->value);
+               if (ret < 0) {
+                       err("err!!! ret(%d)", ret);
+                       ret = -EINVAL;
+                       goto p_err;
+               }
+               break;
+       case V4L2_CID_IS_FACTORY_OIS_HEA:
+               ret = CALL_OISOPS(sensor_peri->ois, ois_factory_hea,
+                        sensor_peri->subdev_ois, &ctrl->value);
+               if (ret < 0) {
+                       err("err!!! ret(%d)", ret);
+                       ret = -EINVAL;
+                       goto p_err;
+               }
+               break;
+#endif
        default:
                err("err!!! Unknown CID(%#x)", ctrl->id);
                ret = -EINVAL;
index 84cd5b24fc1f1d3ebb0f46b9293689ce27625c96..887551980812cfe9e7c03a66e040b1fac0f3612c 100644 (file)
@@ -28,3 +28,10 @@ config OIS_DIRECT_FW_CONTROL
         help
           Use to ois direct FW control.
 
+config OIS_BU24218_FACTORY_TEST
+        bool "Use BU24218 factory test"
+        depends on CAMERA_OIS_BU24218GWL_OBJ
+        default n
+        help
+            Use to support BU24218 factory
+
index ce289f2350c0804ab5e6ded59151ab3db0d731d9..59c095b88c4f8897255c23552cecf5f3b62c513e 100644 (file)
@@ -3,6 +3,7 @@ obj-$(CONFIG_CAMERA_OIS_SELECT) += fimc-is-helper-ois-i2c.o \
 
 obj-$(CONFIG_CAMERA_OIS_IDG2030_OBJ) += fimc-is-ois-idg2030.o
 obj-$(CONFIG_CAMERA_OIS_BU24218GWL_OBJ) += fimc-is-ois-bu24218gwl.o
+obj-$(CONFIG_OIS_BU24218_FACTORY_TEST) += fimc_bu24218_factory.o
 
 EXTRA_CFLAGS += -Idrivers/media/platform/exynos/fimc-is2/sensor/module_framework
 EXTRA_CFLAGS += -Idrivers/media/platform/exynos/fimc-is2/sensor
index f4b4495c178c0f1fc3575c26b092cda42e508e18..5fe7b494f80b1142401a3772c806ef5298536925 100644 (file)
@@ -579,6 +579,10 @@ static struct fimc_is_ois_ops ois_ops = {
 #ifdef CONFIG_OIS_DIRECT_FW_CONTROL
        .ois_fw_update = fimc_is_ois_fw_update,
 #endif
+#ifdef CONFIG_OIS_BU24218_FACTORY_TEST
+       .ois_factory_fw_ver = fimc_is_factory_ois_get_fw_rev,
+       .ois_factory_hea = fimc_is_factory_ois_get_hea,
+#endif
 };
 
 static int sensor_ois_bu24218gwl_probe(struct i2c_client *client,
index 9388c28514630961b8e125b435cf305c06dc9b92..334b2c39152cf12decb1d25d6924cf39e616ae4e 100644 (file)
 #ifndef FIMC_IS_DEVICE_OIS_H
 #define FIMC_IS_DEVICE_OIS_H
 
+#ifdef CONFIG_OIS_BU24218_FACTORY_TEST
+#include "fimc_bu24218_factory.h"
+#endif
+
 #define OIS_FW_SIZE                    2136
 #define FW_TRANS_SIZE                  256
-
 #endif
 
diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.c b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.c
new file mode 100644 (file)
index 0000000..54000d8
--- /dev/null
@@ -0,0 +1,160 @@
+/*\r
+ * Copyright (C) 2019 Motorola Mobility LLC.\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+\r
+#include "fimc_bu24218_factory.h"\r
+\r
+#define check_result(ret) {if (ret < 0) goto ERROR;}\r
+\r
+int fimc_is_factory_ois_get_fw_rev(struct v4l2_subdev *subdev, uint32_t *result)\r
+{\r
+       int ret = 0;\r
+       char version[4] = {0, };\r
+       struct fimc_is_ois *ois = NULL;\r
+\r
+       FIMC_BUG(!subdev);\r
+\r
+       info("%s: E", __func__);\r
+\r
+       ois = (struct fimc_is_ois *)v4l2_get_subdevdata(subdev);\r
+       if(!ois) {\r
+               err("%s, ois subdev is NULL", __func__);\r
+               ret = -EINVAL;\r
+               return ret;\r
+       }\r
+\r
+       WARN_ON(!ois);\r
+\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION, &version[0]);\r
+       check_result(ret);\r
+\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION + 1, &version[1]);\r
+       check_result(ret);\r
+\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION + 2, &version[2]);\r
+       check_result(ret);\r
+\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION + 3, &version[3]);\r
+       check_result(ret);\r
+\r
+       info("%s: fw version:%d, %d, %d, %d",  __func__, version[0], version[1], version[2], version[3]);\r
+       *result = version[0] | (version[1] << 8) | (version[2] << 16) | (version[3] << 24);\r
+\r
+       return 0;\r
+ERROR:\r
+       err("%s: Failed with %d", __func__, ret);\r
+       return -1;\r
+}\r
+\r
+\r
+int fimc_is_factory_ois_get_hea(struct v4l2_subdev  *subdev, uint32_t *result)\r
+{\r
+       int ret = 0;\r
+       char data[4] = {0, 0, 0, 0};\r
+       struct fimc_is_ois *ois = NULL;\r
+\r
+       FIMC_BUG(!subdev);\r
+\r
+       info("%s: E", __func__);\r
+\r
+       ois = (struct fimc_is_ois *)v4l2_get_subdevdata(subdev);\r
+       if(!ois) {\r
+               err("%s, ois subdev is NULL", __func__);\r
+               ret = -EINVAL;\r
+               return ret;\r
+       }\r
+\r
+       WARN_ON(!ois);\r
+\r
+       // 1. change to calibration mode\r
+       ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01);\r
+       check_result(ret);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_MODE, 0x01);\r
+       ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01);\r
+       check_result(ret);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_MODE, 0x00);\r
+       ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01);\r
+       check_result(ret);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_MODE, 0x04);\r
+       ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01);\r
+       check_result(ret);\r
+       usleep_range(500, 500);\r
+\r
+       // 2. set max postion\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH,     (uint8_t) MOT_BU24218_VCM_DRV_MAX_HI);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MAX_LO);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH,     (uint8_t) MOT_BU24218_VCM_DRV_MAX_HI);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MAX_LO);\r
+       usleep_range(200, 200);\r
+\r
+       // 3. check status reg\r
+       ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01);\r
+       check_result(ret);\r
+\r
+       // 4. read lens position\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_XCH, &data[0]);\r
+       check_result(ret);\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_YCH, &data[1]);\r
+       check_result(ret);\r
+\r
+       // 5. set min postion\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH,     (uint8_t) MOT_BU24218_VCM_DRV_MIN_HI);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MIN_LO);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH,     (uint8_t) MOT_BU24218_VCM_DRV_MIN_HI);\r
+       fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MIN_LO);\r
+       usleep_range(200, 200);\r
+\r
+       // 6. check status reg\r
+       ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01);\r
+       check_result(ret);\r
+\r
+       usleep_range(200, 200);\r
+       // 7. read lens position\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_XCH, &data[2]);\r
+       check_result(ret);\r
+       ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_YCH, &data[3]);\r
+       check_result(ret);\r
+\r
+       info("%s: actual pos:(%d, %d, %d, %d)", __func__,\r
+               data[0], data[2], data[1], data[3]);\r
+       // follow the format, Xmax, Xmin, Ymax, Ymin\r
+       *result = data[0] | (data[2] << 8) | (data[1] << 16) | (data[3] << 24);\r
+\r
+       return 0;\r
+\r
+ERROR:\r
+       err("%s: Failed with %d", __func__, ret);\r
+       return -1;\r
+}\r
+\r
+int fimc_is_factory_ois_poll(struct i2c_client *client,\r
+               u16 addr, u8 expdata)\r
+{\r
+       int ret = 0, i = 0;\r
+       uint8_t data = 0;\r
+       do {\r
+               usleep_range(200, 200);\r
+               ret = fimc_is_ois_read(client, addr, &data);\r
+               check_result(ret);\r
+       } while (data != expdata && i++ < 100);\r
+\r
+       if (i >= 100 || data != expdata) {\r
+               err("%s addr %x expdata=%d act data=%x tries=%d", __func__,\r
+               (unsigned int)addr, (unsigned int)expdata, (unsigned int)data, i);\r
+               return -1;\r
+       }\r
+       return 0;\r
+ERROR:\r
+       err("%s: Failed with %d", __func__, ret);\r
+       return -1;\r
+}\r
diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.h b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.h
new file mode 100644 (file)
index 0000000..9f74cfa
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * Copyright (C) 2019 Motorola Mobility LLC.\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+\r
+#ifndef MOT_BU24218_FACTORY_H\r
+#define MOT_BU24218_FACTORY_H\r
+#include "fimc-is-core.h"\r
+#include "fimc-is-device-sensor-peri.h"\r
+#include "fimc-is-helper-ois-i2c.h"\r
+#include "fimc-is-ois.h"\r
+\r
+#define  MOT_BU24218_REG_MODE                   0x6020\r
+#define  MOT_BU24218_REG_STATUS                 0x6024\r
+#define  MOT_BU24218_REG_GYRO_ACCESS            0x6023\r
+#define  MOT_BU24218_REG_FW_VERSION             0x6010\r
+#define  MOT_BU24218_REG_GYRO_SELF_TEST         0x6104\r
+#define  MOT_BU24218_REG_GYRO_RESULT            0x6105\r
+\r
+#define  MOT_BU24218_REG_MAX_XCH                0x6100\r
+#define  MOT_BU24218_REG_MIN_XCH                0x6101\r
+#define  MOT_BU24218_REG_MAX_YCH                0x6102\r
+#define  MOT_BU24218_REG_MIN_YCH                0x6103\r
+#define  MOT_BU24218_REG_POS_XCH                0x6064\r
+#define  MOT_BU24218_REG_POS_YCH                0x6066\r
+#define  MOT_BU24218_REG_LENS_XCH               0x6058\r
+#define  MOT_BU24218_REG_LENS_YCH               0x6059\r
+\r
+#define  MOT_BU24218_VCM_DRV_MAX_HI             0x03\r
+#define  MOT_BU24218_VCM_DRV_MAX_LO             0x00\r
+#define  MOT_BU24218_VCM_DRV_MIN_HI             0x0D\r
+#define  MOT_BU24218_VCM_DRV_MIN_LO             0x00\r
+\r
+int fimc_is_factory_ois_get_fw_rev(struct v4l2_subdev  *subdev, uint32_t *result);\r
+int fimc_is_factory_ois_get_hea(struct v4l2_subdev  *subdev, uint32_t *result);\r
+int fimc_is_factory_ois_poll(struct i2c_client *client, u16 addr, uint8_t expdata);\r
+#endif\r
index 5a09da671dca47ae860547934b00485b69d21272..4d83084551eb9375a9c09eb930a8f9470521b842 100644 (file)
@@ -190,6 +190,8 @@ enum is_set_stream {
 #define V4L2_CID_IS_FDAE                       (V4L2_CID_FIMC_IS_BASE + 73)
 #define V4L2_CID_IS_FACTORY_APERTURE_CONTROL   (V4L2_CID_FIMC_IS_BASE + 74)
 #define V4L2_CID_IS_G_SENSOR_FACTORY_RESULT    (V4L2_CID_FIMC_IS_BASE + 76)
+#define V4L2_CID_IS_FACTORY_OIS_FW_VER          (V4L2_CID_FIMC_IS_BASE + 77)
+#define V4L2_CID_IS_FACTORY_OIS_HEA             (V4L2_CID_FIMC_IS_BASE + 78)
 
 enum is_fw_boot_mode {
        IS_COLD_BOOT = 0,  /* FrontCamera, 3rd-Party Camera */