From: Xiaofei Ma Date: Wed, 9 Jan 2019 22:48:45 +0000 (-0600) Subject: [9610] fimc-is2: add bu24218 OIS factory test X-Git-Tag: MMI-QSAS30.62-33-3~798 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=f5d10e84efd6cc0d0e29cfd62df3e3747bb88ec4;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git [9610] fimc-is2: add bu24218 OIS factory test Firmware version and hea test support. Change-Id: Iafdd03a47c73aadbb19ed50f71755c51f1adb9c8 Signed-off-by: Wooyeon Kim --- diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/fimc-is-interface-sensor.h b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/fimc-is-interface-sensor.h index dadc3741e2c6..2b0a77163e11 100755 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/fimc-is-interface-sensor.h +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/fimc-is-interface-sensor.h @@ -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; diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/modules/fimc-is-device-module-base.c b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/modules/fimc-is-device-module-base.c index 3d5bab5d478d..0a2dea068eb7 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/modules/fimc-is-device-module-base.c +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/modules/fimc-is-device-module-base.c @@ -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; diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Kconfig b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Kconfig index 84cd5b24fc1f..887551980812 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Kconfig +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Kconfig @@ -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 + diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Makefile b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Makefile index ce289f2350c0..59c095b88c4f 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Makefile +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/Makefile @@ -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 diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.c b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.c index f4b4495c178c..5fe7b494f80b 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.c +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.c @@ -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, diff --git a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.h b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.h index 9388c2851463..334b2c39152c 100644 --- a/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.h +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc-is-ois-bu24218gwl.h @@ -15,8 +15,11 @@ #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 index 000000000000..54000d86f23f --- /dev/null +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2019 Motorola Mobility LLC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "fimc_bu24218_factory.h" + +#define check_result(ret) {if (ret < 0) goto ERROR;} + +int fimc_is_factory_ois_get_fw_rev(struct v4l2_subdev *subdev, uint32_t *result) +{ + int ret = 0; + char version[4] = {0, }; + struct fimc_is_ois *ois = NULL; + + FIMC_BUG(!subdev); + + info("%s: E", __func__); + + ois = (struct fimc_is_ois *)v4l2_get_subdevdata(subdev); + if(!ois) { + err("%s, ois subdev is NULL", __func__); + ret = -EINVAL; + return ret; + } + + WARN_ON(!ois); + + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION, &version[0]); + check_result(ret); + + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION + 1, &version[1]); + check_result(ret); + + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION + 2, &version[2]); + check_result(ret); + + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_FW_VERSION + 3, &version[3]); + check_result(ret); + + info("%s: fw version:%d, %d, %d, %d", __func__, version[0], version[1], version[2], version[3]); + *result = version[0] | (version[1] << 8) | (version[2] << 16) | (version[3] << 24); + + return 0; +ERROR: + err("%s: Failed with %d", __func__, ret); + return -1; +} + + +int fimc_is_factory_ois_get_hea(struct v4l2_subdev *subdev, uint32_t *result) +{ + int ret = 0; + char data[4] = {0, 0, 0, 0}; + struct fimc_is_ois *ois = NULL; + + FIMC_BUG(!subdev); + + info("%s: E", __func__); + + ois = (struct fimc_is_ois *)v4l2_get_subdevdata(subdev); + if(!ois) { + err("%s, ois subdev is NULL", __func__); + ret = -EINVAL; + return ret; + } + + WARN_ON(!ois); + + // 1. change to calibration mode + ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01); + check_result(ret); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_MODE, 0x01); + ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01); + check_result(ret); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_MODE, 0x00); + ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01); + check_result(ret); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_MODE, 0x04); + ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01); + check_result(ret); + usleep_range(500, 500); + + // 2. set max postion + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH, (uint8_t) MOT_BU24218_VCM_DRV_MAX_HI); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MAX_LO); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH, (uint8_t) MOT_BU24218_VCM_DRV_MAX_HI); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MAX_LO); + usleep_range(200, 200); + + // 3. check status reg + ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01); + check_result(ret); + + // 4. read lens position + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_XCH, &data[0]); + check_result(ret); + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_YCH, &data[1]); + check_result(ret); + + // 5. set min postion + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH, (uint8_t) MOT_BU24218_VCM_DRV_MIN_HI); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_XCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MIN_LO); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH, (uint8_t) MOT_BU24218_VCM_DRV_MIN_HI); + fimc_is_ois_write(ois->client, MOT_BU24218_REG_POS_YCH + 1, (uint8_t) MOT_BU24218_VCM_DRV_MIN_LO); + usleep_range(200, 200); + + // 6. check status reg + ret = fimc_is_factory_ois_poll(ois->client, MOT_BU24218_REG_STATUS, 0x01); + check_result(ret); + + usleep_range(200, 200); + // 7. read lens position + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_XCH, &data[2]); + check_result(ret); + ret = fimc_is_ois_read(ois->client, MOT_BU24218_REG_LENS_YCH, &data[3]); + check_result(ret); + + info("%s: actual pos:(%d, %d, %d, %d)", __func__, + data[0], data[2], data[1], data[3]); + // follow the format, Xmax, Xmin, Ymax, Ymin + *result = data[0] | (data[2] << 8) | (data[1] << 16) | (data[3] << 24); + + return 0; + +ERROR: + err("%s: Failed with %d", __func__, ret); + return -1; +} + +int fimc_is_factory_ois_poll(struct i2c_client *client, + u16 addr, u8 expdata) +{ + int ret = 0, i = 0; + uint8_t data = 0; + do { + usleep_range(200, 200); + ret = fimc_is_ois_read(client, addr, &data); + check_result(ret); + } while (data != expdata && i++ < 100); + + if (i >= 100 || data != expdata) { + err("%s addr %x expdata=%d act data=%x tries=%d", __func__, + (unsigned int)addr, (unsigned int)expdata, (unsigned int)data, i); + return -1; + } + return 0; +ERROR: + err("%s: Failed with %d", __func__, ret); + return -1; +} 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 index 000000000000..9f74cfa4da79 --- /dev/null +++ b/drivers/media/platform/exynos/fimc-is2/sensor/module_framework/ois/fimc_bu24218_factory.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2019 Motorola Mobility LLC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef MOT_BU24218_FACTORY_H +#define MOT_BU24218_FACTORY_H +#include "fimc-is-core.h" +#include "fimc-is-device-sensor-peri.h" +#include "fimc-is-helper-ois-i2c.h" +#include "fimc-is-ois.h" + +#define MOT_BU24218_REG_MODE 0x6020 +#define MOT_BU24218_REG_STATUS 0x6024 +#define MOT_BU24218_REG_GYRO_ACCESS 0x6023 +#define MOT_BU24218_REG_FW_VERSION 0x6010 +#define MOT_BU24218_REG_GYRO_SELF_TEST 0x6104 +#define MOT_BU24218_REG_GYRO_RESULT 0x6105 + +#define MOT_BU24218_REG_MAX_XCH 0x6100 +#define MOT_BU24218_REG_MIN_XCH 0x6101 +#define MOT_BU24218_REG_MAX_YCH 0x6102 +#define MOT_BU24218_REG_MIN_YCH 0x6103 +#define MOT_BU24218_REG_POS_XCH 0x6064 +#define MOT_BU24218_REG_POS_YCH 0x6066 +#define MOT_BU24218_REG_LENS_XCH 0x6058 +#define MOT_BU24218_REG_LENS_YCH 0x6059 + +#define MOT_BU24218_VCM_DRV_MAX_HI 0x03 +#define MOT_BU24218_VCM_DRV_MAX_LO 0x00 +#define MOT_BU24218_VCM_DRV_MIN_HI 0x0D +#define MOT_BU24218_VCM_DRV_MIN_LO 0x00 + +int fimc_is_factory_ois_get_fw_rev(struct v4l2_subdev *subdev, uint32_t *result); +int fimc_is_factory_ois_get_hea(struct v4l2_subdev *subdev, uint32_t *result); +int fimc_is_factory_ois_poll(struct i2c_client *client, u16 addr, uint8_t expdata); +#endif diff --git a/include/uapi/linux/videodev2_exynos_camera.h b/include/uapi/linux/videodev2_exynos_camera.h index 5a09da671dca..4d83084551eb 100644 --- a/include/uapi/linux/videodev2_exynos_camera.h +++ b/include/uapi/linux/videodev2_exynos_camera.h @@ -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 */