--- /dev/null
+/*\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
--- /dev/null
+/*\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