mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
Merge tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm-5.4-techpack-camera into lineage-22.2
Fogos push for Android 14 * tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm-5.4-techpack-camera: (86 commits) fogo: fix tombstone when use secure camera fogo: Fix secure mode switch error (2/2) Bangkk: reset ois when read standby_flag fail fogos: Actuator noise reduction[2/2] fogor: Actuator noise reduction[2/2] bangkk: Powerup and initialize sensor early [3/4] bangkk: Fix flash request GPIO-24 failed bangkk: support dw9784 af drift bangkk: Open Camera preview will be black then camera error bangkk: open Camera preview may be black sometimes bangkk: dw9784 ois bring up bangkk: Secondary supply flash driver ic compatible Tundra: restore ois delete submit Tundra: add delay at check ois data_ready Revert "(CR): milanf: modify ois vsync irq processing flow" penang: Adjust actuator noise reduction penang: Adjust actuator noise reduction penang: Actuator noise reduction milanf: modify ois vsync irq processing flow camera: ois: avoid ois power down twice when download firmware failed ... Conflicts: techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_core.c Change-Id: I9aa733fcd4412059a267c7cb9408b05e91eba111
This commit is contained in:
commit
9ca541ecda
45 changed files with 8194 additions and 76 deletions
|
|
@ -8,3 +8,4 @@
|
|||
#define CONFIG_SPECTRA_OPE 1
|
||||
#define CONFIG_SPECTRA_TFE 1
|
||||
#define CONFIG_SPECTRA_SENSOR 1
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,9 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \
|
|||
cam_sensor_module/cam_ois/cam_ois_dev.o \
|
||||
cam_sensor_module/cam_ois/cam_ois_core.o \
|
||||
cam_sensor_module/cam_ois/cam_ois_soc.o \
|
||||
cam_sensor_module/cam_ois/cam_ois_dw9781.o \
|
||||
cam_sensor_module/cam_ois/cam_ois_dw9784.o \
|
||||
cam_sensor_module/cam_ois/cam_ois_aw86006.o \
|
||||
cam_sensor_module/cam_sensor/cam_sensor_dev.o \
|
||||
cam_sensor_module/cam_sensor/cam_sensor_core.o \
|
||||
cam_sensor_module/cam_sensor/cam_sensor_soc.o \
|
||||
|
|
@ -170,8 +173,15 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \
|
|||
cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.o \
|
||||
cam_sensor_module/cam_sensor_io/cam_sensor_spi.o \
|
||||
cam_sensor_module/cam_sensor_utils/cam_sensor_util.o \
|
||||
cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.o \
|
||||
cam_sensor_module/cam_res_mgr/cam_res_mgr.o
|
||||
|
||||
ifneq (,$(filter $(CONFIG_AF_NOISE_ELIMINATION), y m))
|
||||
camera-$(CONFIG_SPECTRA_SENSOR) += \
|
||||
cam_sensor_module/cam_actuator/mot_actuator.o \
|
||||
cam_sensor_module/cam_actuator/mot_actuator_policy.o
|
||||
endif
|
||||
|
||||
camera-$(CONFIG_LEDS_QPNP_FLASH_V2) += \
|
||||
cam_sensor_module/cam_flash/cam_flash_dev.o \
|
||||
cam_sensor_module/cam_flash/cam_flash_core.o \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_HW_MGR_INTF_H_
|
||||
|
|
@ -26,6 +27,12 @@
|
|||
/* Maximum reg dump cmd buffer entries in a context */
|
||||
#define CAM_REG_DUMP_MAX_BUF_ENTRIES 10
|
||||
|
||||
/*
|
||||
* This value should align with MAX requests supported by
|
||||
* hw modules like ICP, IFE, JPEG etc.
|
||||
*/
|
||||
#define CAM_MAX_FLUSH_REQS 40
|
||||
|
||||
/**
|
||||
* enum cam_context_dump_id -
|
||||
* context dump type
|
||||
|
|
@ -289,9 +296,9 @@ struct cam_hw_config_args {
|
|||
struct cam_hw_flush_args {
|
||||
void *ctxt_to_hw_map;
|
||||
uint32_t num_req_pending;
|
||||
void *flush_req_pending[20];
|
||||
void *flush_req_pending[CAM_MAX_FLUSH_REQS];
|
||||
uint32_t num_req_active;
|
||||
void *flush_req_active[20];
|
||||
void *flush_req_active[CAM_MAX_FLUSH_REQS];
|
||||
enum flush_type_t flush_type;
|
||||
uint32_t last_flush_req;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3350,7 +3350,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
|
|||
prepare_args->priv = ctx_data->req_list[request_idx];
|
||||
prepare_args->pf_data->packet = packet;
|
||||
prepare_args->pf_data->req = ope_req;
|
||||
CAM_INFO(CAM_REQ, "OPE req %x num_batch %d", ope_req, ope_req->num_batch);
|
||||
CAM_DBG(CAM_REQ, "OPE req %x num_batch %d", ope_req, ope_req->num_batch);
|
||||
ope_req->hang_data.packet = packet;
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) +
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@
|
|||
#include "cam_trace.h"
|
||||
#include "cam_common_util.h"
|
||||
#include "cam_packet_util.h"
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
#include "mot_actuator_policy.h"
|
||||
#include "mot_actuator.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
extern int cam_ois_get_init_info(void);
|
||||
extern int cam_ois_write_af_drift(uint32_t dac);
|
||||
#endif
|
||||
|
||||
int32_t cam_actuator_construct_default_power_setting(
|
||||
struct cam_sensor_power_ctrl_t *power_info)
|
||||
|
|
@ -160,8 +169,17 @@ static int32_t cam_actuator_i2c_modes_util(
|
|||
uint32_t i, size;
|
||||
|
||||
if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) {
|
||||
rc = camera_io_dev_write(io_master_info,
|
||||
&(i2c_list->i2c_settings));
|
||||
// if meet cci fail, retry 5 times, each time dealy 1.5ms.
|
||||
for (i = 0; i < 5; i++) {
|
||||
rc = camera_io_dev_write(io_master_info,
|
||||
&(i2c_list->i2c_settings));
|
||||
|
||||
if (rc >= 0)
|
||||
break;
|
||||
|
||||
usleep_range(1000, 1500);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ACTUATOR,
|
||||
"Failed to random write I2C settings: %d",
|
||||
|
|
@ -251,6 +269,11 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
struct i2c_settings_list *i2c_list;
|
||||
int32_t rc = 0;
|
||||
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
struct cam_sensor_i2c_reg_setting * i2c_reg = NULL;
|
||||
uint32_t dac = 0;
|
||||
#endif
|
||||
|
||||
if (a_ctrl == NULL || i2c_set == NULL) {
|
||||
CAM_ERR(CAM_ACTUATOR, "Invalid Args");
|
||||
return -EINVAL;
|
||||
|
|
@ -260,7 +283,13 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
CAM_ERR(CAM_ACTUATOR, " Invalid settings");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
/*Usually actuator initial setting will execute power down reset(PD), actuator can't respond
|
||||
CCI access for a while after PD. Add lock to avoid access actuator while PD operation.*/
|
||||
if (a_ctrl->is_multi_user_supported) {
|
||||
mot_actuator_lock();
|
||||
}
|
||||
#endif
|
||||
list_for_each_entry(i2c_list,
|
||||
&(i2c_set->list_head), list) {
|
||||
rc = cam_actuator_i2c_modes_util(
|
||||
|
|
@ -274,9 +303,47 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
CAM_DBG(CAM_ACTUATOR,
|
||||
"Success:request ID: %d",
|
||||
i2c_set->request_id);
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
if (a_ctrl->af_drift_supported == true &&
|
||||
(cam_ois_get_init_info() == 1) &&
|
||||
i2c_list != NULL) {
|
||||
|
||||
#define ADDR_ACTUATOR 0x18
|
||||
#define REG_ACTUATOR 0x00
|
||||
#define DATA_SHIFT 4
|
||||
|
||||
i2c_reg = &(i2c_list->i2c_settings);
|
||||
|
||||
if (i2c_reg != NULL &&
|
||||
i2c_reg->reg_setting != NULL &&
|
||||
a_ctrl->io_master_info.cci_client != NULL &&
|
||||
a_ctrl->io_master_info.cci_client->sid == (ADDR_ACTUATOR >> 1) &&
|
||||
i2c_reg->addr_type == CAMERA_SENSOR_I2C_TYPE_BYTE &&
|
||||
i2c_reg->data_type == CAMERA_SENSOR_I2C_TYPE_WORD &&
|
||||
i2c_reg->reg_setting[0].reg_data != 0 &&
|
||||
i2c_reg->reg_setting[0].reg_addr == REG_ACTUATOR)
|
||||
{
|
||||
dac = i2c_reg->reg_setting[0].reg_data >> DATA_SHIFT;
|
||||
|
||||
rc = cam_ois_write_af_drift(dac);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ACTUATOR, "Failed to apply af drift settings: %d", rc);
|
||||
rc = 0; // avoid broken actuator function
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
/*Usually actuator initial setting will execute power down reset(PD), actuator can't respond
|
||||
CCI access for a while after PD. Add lock to avoid access actuator while PD operation.*/
|
||||
if (a_ctrl->is_multi_user_supported) {
|
||||
mot_actuator_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -593,6 +660,15 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE &&
|
||||
a_ctrl->is_multi_user_supported == true) {
|
||||
/*exile vibrator when camera want to take control of actuator*/
|
||||
mot_actuator_handle_exile();
|
||||
mot_actuator_get(ACTUATOR_CLIENT_CAMERA);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE) {
|
||||
rc = cam_actuator_power_up(a_ctrl);
|
||||
if (rc < 0) {
|
||||
|
|
@ -606,6 +682,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
rc = cam_actuator_apply_settings(a_ctrl,
|
||||
&a_ctrl->i2c_data.init_settings);
|
||||
if (rc < 0) {
|
||||
delete_request(&a_ctrl->i2c_data.init_settings);
|
||||
CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings");
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -902,6 +979,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
}
|
||||
|
||||
if (a_ctrl->cam_act_state == CAM_ACTUATOR_CONFIG) {
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
if (a_ctrl->is_multi_user_supported == true) {
|
||||
mot_actuator_put(ACTUATOR_CLIENT_CAMERA);
|
||||
}
|
||||
#endif
|
||||
rc = cam_actuator_power_down(a_ctrl);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ACTUATOR,
|
||||
|
|
|
|||
|
|
@ -115,6 +115,12 @@ struct cam_actuator_ctrl_t {
|
|||
struct cam_actuator_query_cap act_info;
|
||||
struct actuator_intf_params bridge_intf;
|
||||
uint32_t last_flush_req;
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
bool is_multi_user_supported;
|
||||
#endif
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
bool af_drift_supported;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,6 +34,24 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl,
|
|||
|
||||
of_node = soc_info->dev->of_node;
|
||||
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
if (!of_property_read_bool(of_node, "multi-user-support")) {
|
||||
a_ctrl->is_multi_user_supported = false;
|
||||
} else {
|
||||
a_ctrl->is_multi_user_supported = true;
|
||||
}
|
||||
CAM_DBG(CAM_ACTUATOR, "multi-user-support %d", a_ctrl->is_multi_user_supported);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
if (!of_property_read_bool(of_node, "af-drift-support")) {
|
||||
a_ctrl->af_drift_supported = false;
|
||||
} else {
|
||||
a_ctrl->af_drift_supported = true;
|
||||
}
|
||||
CAM_DBG(CAM_ACTUATOR, "af-drift-support %d", a_ctrl->af_drift_supported);
|
||||
#endif
|
||||
|
||||
if (a_ctrl->io_master_info.master_type == CCI_MASTER) {
|
||||
rc = of_property_read_u32(of_node, "cci-master",
|
||||
&(a_ctrl->cci_i2c_master));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef __MOT_ACTUATOR_H__
|
||||
#define __MOT_ACTUATOR_H__
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/videodev2.h>
|
||||
#define MOT_ACTUATOR_NAME "mot_actuator"
|
||||
|
||||
#define MOT_ACTUATOR_READ \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 50, int)
|
||||
#define MOT_ACTUATOR_READ32 \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 50, int)
|
||||
|
||||
#define MOT_ACTUATOR_WRITE \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 51, int)
|
||||
#define MOT_ACTUATOR_WRITE32 \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 51, int)
|
||||
|
||||
#define MOT_ACTUATOR_INIT \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 52, int)
|
||||
#define MOT_ACTUATOR_INIT32 \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 52, int)
|
||||
|
||||
#define MOT_ACTUATOR_RELEASE \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 53, int)
|
||||
#define MOT_ACTUATOR_RELEASE32 \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 53, int)
|
||||
|
||||
#define MOT_ACTUATOR_EXIT \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 54, int)
|
||||
#define MOT_ACTUATOR_EXIT32 \
|
||||
_IOWR('X', BASE_VIDIOC_PRIVATE + 54, int)
|
||||
|
||||
void mot_actuator_handle_exile(void);
|
||||
int mot_actuator_driver_init(void);
|
||||
void mot_actuator_driver_exit(void);
|
||||
#endif /*__MOT_ACTUATOR_H__*/
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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 <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include "cam_debug_util.h"
|
||||
#include "mot_actuator_policy.h"
|
||||
|
||||
extern int mot_actuator_on_vibrate_start(void);
|
||||
extern int mot_actuator_on_vibrate_stop(void);
|
||||
|
||||
static atomic_t mot_actuator_ref_count = ATOMIC_INIT(0);
|
||||
static unsigned long mot_actuator_consumers = ATOMIC_INIT(0);
|
||||
static struct mutex actuator_res_lock = __MUTEX_INITIALIZER(actuator_res_lock);
|
||||
|
||||
int mot_actuator_get(mot_actuator_client user)
|
||||
{
|
||||
if (user <= ACTUATOR_CLIENT_INVALID || user >= ACTUATOR_CLIENT_MAX) {
|
||||
CAM_ERR(CAM_ACTUATOR, "INVALID CLIENT!!!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ACTUATOR, "Obtain actuator from: %d", user);
|
||||
|
||||
test_and_set_bit(user, &mot_actuator_consumers);
|
||||
|
||||
return atomic_add_return(1, &mot_actuator_ref_count);
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_get);
|
||||
|
||||
int mot_actuator_put(mot_actuator_client user)
|
||||
{
|
||||
unsigned long consumers = 0;
|
||||
if (user <= ACTUATOR_CLIENT_INVALID || user >= ACTUATOR_CLIENT_MAX) {
|
||||
CAM_ERR(CAM_ACTUATOR, "INVALID CLIENT!!!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ACTUATOR, "Release actuator from: %d", user);
|
||||
|
||||
test_and_clear_bit(user, &mot_actuator_consumers);
|
||||
|
||||
consumers = mot_actuator_get_consumers();
|
||||
if (((consumers & CLINET_VIBRATOR_MASK) == CLINET_VIBRATOR_MASK) &&
|
||||
(user != ACTUATOR_CLIENT_VIBRATOR)) {
|
||||
//If only vibrator noise eliminator exists, move lens to required position
|
||||
CAM_DBG(CAM_ACTUATOR, "Set actuator pos for vibrator");
|
||||
mot_actuator_on_vibrate_start();
|
||||
if ((mot_actuator_get_consumers() & CLINET_VIBRATOR_MASK) == 0) {
|
||||
mot_actuator_on_vibrate_stop();
|
||||
}
|
||||
}
|
||||
|
||||
return atomic_sub_return(1, &mot_actuator_ref_count);
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_put);
|
||||
|
||||
int mot_actuator_get_ref_count(void)
|
||||
{
|
||||
return atomic_read(&mot_actuator_ref_count);
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_get_ref_count);
|
||||
|
||||
unsigned int mot_actuator_get_consumers(void)
|
||||
{
|
||||
return mot_actuator_consumers;
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_get_consumers);
|
||||
|
||||
void mot_actuator_lock(void)
|
||||
{
|
||||
mutex_lock(&actuator_res_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_lock);
|
||||
|
||||
void mot_actuator_unlock(void)
|
||||
{
|
||||
mutex_unlock(&actuator_res_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_unlock);
|
||||
|
||||
ssize_t mot_actuator_dump(char *buf)
|
||||
{
|
||||
int item_len = 0;
|
||||
unsigned int consumers = mot_actuator_get_consumers();
|
||||
|
||||
item_len += sprintf(buf+item_len, "refCount: %d\n", mot_actuator_get_ref_count());
|
||||
item_len += sprintf(buf+item_len, "Consumers (0x%x):\n", consumers);
|
||||
|
||||
if (consumers & CLINET_CAMERA_MASK) {
|
||||
item_len += sprintf(buf+item_len, "camera");
|
||||
}
|
||||
|
||||
if (consumers & CLINET_VIBRATOR_MASK) {
|
||||
item_len += sprintf(buf+item_len, " vibrator");
|
||||
}
|
||||
|
||||
item_len += sprintf(buf+item_len, "\n");
|
||||
|
||||
CAM_DBG(CAM_ACTUATOR, "ref cnt:%d, consumers:0x%x", mot_actuator_get_ref_count(), mot_actuator_get_consumers());
|
||||
return item_len;
|
||||
}
|
||||
EXPORT_SYMBOL(mot_actuator_dump);
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __MOT_ACTUATOR_POLICY_H__
|
||||
#define __MOT_ACTUATOR_POLICY_H__
|
||||
|
||||
typedef enum {
|
||||
ACTUATOR_CLIENT_INVALID,
|
||||
ACTUATOR_CLIENT_CAMERA,
|
||||
ACTUATOR_CLIENT_VIBRATOR,
|
||||
ACTUATOR_CLIENT_MAX
|
||||
} mot_actuator_client;
|
||||
|
||||
#define CLINET_CAMERA_MASK (0x01 << ACTUATOR_CLIENT_CAMERA)
|
||||
#define CLINET_VIBRATOR_MASK (0x01 << ACTUATOR_CLIENT_VIBRATOR)
|
||||
|
||||
int mot_actuator_get(mot_actuator_client user);
|
||||
int mot_actuator_put(mot_actuator_client user);
|
||||
void mot_actuator_lock(void);
|
||||
void mot_actuator_unlock(void);
|
||||
ssize_t mot_actuator_dump(char *buf);
|
||||
unsigned int mot_actuator_get_consumers(void);
|
||||
#endif /*__MOT_ACTUATOR_POLICY_H__*/
|
||||
|
|
@ -212,7 +212,7 @@ void cam_cci_dump_registers(struct cci_device *cci_dev,
|
|||
uint32_t reg_offset = 0;
|
||||
void __iomem *base = cci_dev->soc_info.reg_map[0].mem_base;
|
||||
|
||||
dump_en = cci_dev->dump_en;
|
||||
dump_en = cci_dev->dump_en = 6;
|
||||
if (!(dump_en & CAM_CCI_NACK_DUMP_EN) &&
|
||||
!(dump_en & CAM_CCI_TIMEOUT_DUMP_EN)) {
|
||||
CAM_DBG(CAM_CCI,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index)
|
|||
return sub_device;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cam_cci_get_subdev);
|
||||
|
||||
static long cam_cci_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
/* Mask to enable skew calibration registers */
|
||||
#define SKEW_CAL_MASK 0x2
|
||||
|
||||
#ifdef CONFIG_MOT_SECURE_CAMERA
|
||||
#define QCOM_SCM_EBUSY_MAX_RETRY 5
|
||||
#endif
|
||||
|
||||
static DEFINE_MUTEX(active_csiphy_cnt_mutex);
|
||||
|
||||
static int csiphy_dump;
|
||||
|
|
@ -1097,6 +1101,10 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||
struct cam_control *cmd = (struct cam_control *)arg;
|
||||
int32_t rc = 0;
|
||||
|
||||
#ifdef CONFIG_MOT_SECURE_CAMERA
|
||||
int32_t retry_count = 0;
|
||||
#endif
|
||||
|
||||
if (!csiphy_dev || !cmd) {
|
||||
CAM_ERR(CAM_CSIPHY, "Invalid input args");
|
||||
return -EINVAL;
|
||||
|
|
@ -1293,7 +1301,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||
cam_csiphy_update_lane(csiphy_dev, offset, false);
|
||||
goto release_mutex;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_MOT_SECURE_CAMERA
|
||||
if (csiphy_dev->csiphy_info[offset].secure_mode)
|
||||
cam_csiphy_notify_secure_mode(
|
||||
csiphy_dev,
|
||||
|
|
@ -1301,6 +1309,28 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||
|
||||
csiphy_dev->csiphy_info[offset].secure_mode =
|
||||
CAM_SECURE_MODE_NON_SECURE;
|
||||
#else
|
||||
retry_count = 0;
|
||||
retry_a:
|
||||
retry_count++;
|
||||
|
||||
if (csiphy_dev->csiphy_info[offset].secure_mode) {
|
||||
rc = cam_csiphy_notify_secure_mode(
|
||||
csiphy_dev,
|
||||
CAM_SECURE_MODE_NON_SECURE, offset);
|
||||
if (rc <0 && retry_count <= QCOM_SCM_EBUSY_MAX_RETRY) {
|
||||
CAM_INFO(CAM_CSIPHY, "CAM_STOP_PHYDEV: scm call with count: %d,",retry_count);
|
||||
goto retry_a;
|
||||
} else if (rc <0 && retry_count > QCOM_SCM_EBUSY_MAX_RETRY){
|
||||
CAM_INFO(CAM_CSIPHY, "CAM_STOP_PHYDEV: notify secure mode finally failed scm call with count: %d,",retry_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
csiphy_dev->csiphy_info[offset].secure_mode =
|
||||
CAM_SECURE_MODE_NON_SECURE;
|
||||
|
||||
#endif
|
||||
|
||||
csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask = 0x0;
|
||||
|
||||
|
|
@ -1356,6 +1386,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||
goto release_mutex;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_MOT_SECURE_CAMERA
|
||||
if (csiphy_dev->csiphy_info[offset].secure_mode)
|
||||
cam_csiphy_notify_secure_mode(
|
||||
csiphy_dev,
|
||||
|
|
@ -1363,6 +1394,26 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||
|
||||
csiphy_dev->csiphy_info[offset].secure_mode =
|
||||
CAM_SECURE_MODE_NON_SECURE;
|
||||
#else
|
||||
retry_count = 0;
|
||||
retry_b:
|
||||
retry_count++;
|
||||
|
||||
if (csiphy_dev->csiphy_info[offset].secure_mode) {
|
||||
rc = cam_csiphy_notify_secure_mode(
|
||||
csiphy_dev,
|
||||
CAM_SECURE_MODE_NON_SECURE, offset);
|
||||
if (rc <0 && retry_count <= QCOM_SCM_EBUSY_MAX_RETRY) {
|
||||
CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: scm call with count: %d,",retry_count);
|
||||
goto retry_b;
|
||||
} else if (rc <0 && retry_count > QCOM_SCM_EBUSY_MAX_RETRY){
|
||||
CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: notify secure mode finally failed scm call with count: %d,",retry_count);
|
||||
}
|
||||
}
|
||||
|
||||
csiphy_dev->csiphy_info[offset].secure_mode =
|
||||
CAM_SECURE_MODE_NON_SECURE;
|
||||
#endif
|
||||
|
||||
csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0;
|
||||
|
||||
|
|
|
|||
|
|
@ -376,12 +376,22 @@ struct data_rate_settings_t data_rate_delta_table_1_2_3 = {
|
|||
{
|
||||
.lane_identifier = CPHY_LANE_0,
|
||||
.csiphy_data_rate_regs = {
|
||||
#ifdef CONFIG_CAM_CTLE_ENABLE
|
||||
{0x144, 0xB2, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#else
|
||||
{0x144, 0xA2, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#endif
|
||||
{0x988, 0x05, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#ifdef CONFIG_CAM_CTLE_ENABLE
|
||||
{0x980, 0x60, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#else
|
||||
{0x980, 0x61, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#endif
|
||||
{0x9B4, 0x08, 0x0A,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
|
|
@ -389,12 +399,22 @@ struct data_rate_settings_t data_rate_delta_table_1_2_3 = {
|
|||
{
|
||||
.lane_identifier = CPHY_LANE_1,
|
||||
.csiphy_data_rate_regs = {
|
||||
#ifdef CONFIG_CAM_CTLE_ENABLE
|
||||
{0x344, 0xB2, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#else
|
||||
{0x344, 0xA2, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#endif
|
||||
{0xA88, 0x05, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#ifdef CONFIG_CAM_CTLE_ENABLE
|
||||
{0xA80, 0x60, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#else
|
||||
{0xA80, 0x61, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#endif
|
||||
{0xAB4, 0x08, 0x0A,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
|
|
@ -402,12 +422,22 @@ struct data_rate_settings_t data_rate_delta_table_1_2_3 = {
|
|||
{
|
||||
.lane_identifier = CPHY_LANE_2,
|
||||
.csiphy_data_rate_regs = {
|
||||
#ifdef CONFIG_CAM_CTLE_ENABLE
|
||||
{0x544, 0xB2, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#else
|
||||
{0x544, 0xA2, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#endif
|
||||
{0xB88, 0x05, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#ifdef CONFIG_CAM_CTLE_ENABLE
|
||||
{0xB80, 0x60, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#else
|
||||
{0xB80, 0x61, 0x00,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
#endif
|
||||
{0xBB4, 0x08, 0x0A,
|
||||
CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,9 +13,58 @@
|
|||
#include "cam_packet_util.h"
|
||||
#include <linux/math64.h>
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
#include "cam_sensor_util.h"
|
||||
#include "../cam_flash_pm6125_gpio/pm6125_flash_gpio.h"
|
||||
#endif
|
||||
|
||||
static uint default_on_timer = 2;
|
||||
module_param(default_on_timer, uint, 0644);
|
||||
|
||||
static int flash_initstate = 0;
|
||||
static struct i2c_settings_list* i2c_flash_off = NULL;
|
||||
static struct i2c_settings_list*
|
||||
cam_flash_get_i2c_ptr(struct i2c_settings_list *pi2c_list)
|
||||
{
|
||||
struct i2c_settings_list *tmp;
|
||||
struct cam_sensor_i2c_reg_array *i2c_reg_settings =
|
||||
pi2c_list->i2c_settings.reg_setting;
|
||||
uint32_t size = pi2c_list->i2c_settings.size;
|
||||
int i = 0;
|
||||
|
||||
tmp = kzalloc(sizeof(struct i2c_settings_list), GFP_KERNEL);
|
||||
if (tmp == NULL) {
|
||||
CAM_WARN(CAM_FLASH, "kzalloc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp->i2c_settings.reg_setting = (struct cam_sensor_i2c_reg_array *)
|
||||
vzalloc(size * sizeof(struct cam_sensor_i2c_reg_array));
|
||||
if (tmp->i2c_settings.reg_setting == NULL) {
|
||||
kfree(tmp);
|
||||
CAM_WARN(CAM_FLASH, "vzalloc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp->i2c_settings.size = size;
|
||||
tmp->op_code = pi2c_list->op_code;
|
||||
tmp->i2c_settings.addr_type = pi2c_list->i2c_settings.addr_type;
|
||||
tmp->i2c_settings.data_type = pi2c_list->i2c_settings.data_type;
|
||||
|
||||
for( i = 0; i < size ; i++ ) {
|
||||
tmp->i2c_settings.reg_setting[i].reg_addr =
|
||||
i2c_reg_settings[i].reg_addr;
|
||||
tmp->i2c_settings.reg_setting[i].reg_data =
|
||||
i2c_reg_settings[i].reg_data;
|
||||
tmp->i2c_settings.reg_setting[i].data_mask =
|
||||
i2c_reg_settings[i].data_mask;
|
||||
tmp->i2c_settings.reg_setting[i].delay =
|
||||
i2c_reg_settings[i].delay;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int cam_flash_led_prepare(struct led_trigger *trigger, int options,
|
||||
int *max_current, bool is_wled)
|
||||
{
|
||||
|
|
@ -290,6 +339,7 @@ int cam_flash_i2c_flush_request(struct cam_flash_ctrl *fctrl,
|
|||
int i = 0;
|
||||
uint32_t cancel_req_id_found = 0;
|
||||
struct i2c_settings_array *i2c_set = NULL;
|
||||
struct i2c_settings_list *i2c_list = NULL;
|
||||
|
||||
if (!fctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Device data is NULL");
|
||||
|
|
@ -310,6 +360,17 @@ int cam_flash_i2c_flush_request(struct cam_flash_ctrl *fctrl,
|
|||
continue;
|
||||
|
||||
if (i2c_set->is_settings_valid == 1) {
|
||||
list_for_each_entry(i2c_list,
|
||||
&(i2c_set->list_head), list) {
|
||||
rc = cam_sensor_util_i2c_apply_setting(
|
||||
&(fctrl->io_master_info),
|
||||
i2c_list);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"Failed to apply settings: %d",
|
||||
rc);
|
||||
}
|
||||
}
|
||||
rc = delete_request(i2c_set);
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_FLASH,
|
||||
|
|
@ -462,6 +523,11 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
|
|||
{
|
||||
int rc = 0;
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
struct cam_hw_soc_info soc_info = flash_ctrl->soc_info;
|
||||
struct cam_flash_private_soc *soc_private = (struct cam_flash_private_soc *)soc_info.soc_private;
|
||||
#endif
|
||||
|
||||
if (!flash_ctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Flash control Null");
|
||||
return -EINVAL;
|
||||
|
|
@ -480,6 +546,19 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
|
|||
"cannot apply streamoff settings");
|
||||
}
|
||||
}
|
||||
|
||||
if(i2c_flash_off)
|
||||
{
|
||||
CAM_DBG(CAM_FLASH, "i2c Flash OFF Triggered");
|
||||
cam_sensor_util_i2c_apply_setting(&(flash_ctrl->io_master_info),
|
||||
i2c_flash_off);
|
||||
}
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
CAM_ERR(CAM_SENSOR,"cam_flash_off");
|
||||
cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 0);
|
||||
cam_res_mgr_gpio_free(soc_info.dev, soc_private->flash_gpio_enable);
|
||||
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND, CAMERA_SENSOR_FLASH_OP_OFF, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -489,6 +568,11 @@ static int cam_flash_low(
|
|||
{
|
||||
int i = 0, rc = 0;
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
struct cam_hw_soc_info soc_info = flash_ctrl->soc_info;
|
||||
struct cam_flash_private_soc *soc_private = (struct cam_flash_private_soc *)soc_info.soc_private;
|
||||
#endif
|
||||
|
||||
if (!flash_data) {
|
||||
CAM_ERR(CAM_FLASH, "Flash Data Null");
|
||||
return -EINVAL;
|
||||
|
|
@ -505,6 +589,19 @@ static int cam_flash_low(
|
|||
if (rc)
|
||||
CAM_ERR(CAM_FLASH, "Fire Torch failed: %d", rc);
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
CAM_DBG(CAM_FLASH, "Flash low Triggered flash_data->led_current_ma[0] = %u", flash_data->led_current_ma[0]);
|
||||
rc = cam_res_mgr_gpio_request(soc_info.dev, soc_private->flash_gpio_enable, 0, "CUSTOM_GPIO1");
|
||||
if(rc) {
|
||||
CAM_ERR(CAM_FLASH, "gpio %d request fails", soc_private->flash_gpio_enable);
|
||||
return rc;
|
||||
}
|
||||
cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 0);
|
||||
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIRELOW, FLASH_FIRE_LOW_MAXCURRENT);
|
||||
usleep_range(5000,6000);
|
||||
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIRELOW, flash_data->led_current_ma[0]);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -514,6 +611,11 @@ static int cam_flash_high(
|
|||
{
|
||||
int i = 0, rc = 0;
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
struct cam_hw_soc_info soc_info = flash_ctrl->soc_info;
|
||||
struct cam_flash_private_soc *soc_private = (struct cam_flash_private_soc *)soc_info.soc_private;
|
||||
#endif
|
||||
|
||||
if (!flash_data) {
|
||||
CAM_ERR(CAM_FLASH, "Flash Data Null");
|
||||
return -EINVAL;
|
||||
|
|
@ -530,6 +632,17 @@ static int cam_flash_high(
|
|||
if (rc)
|
||||
CAM_ERR(CAM_FLASH, "Fire Flash Failed: %d", rc);
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
CAM_DBG(CAM_FLASH, "Flash high Triggered flash_data->led_current_ma[0] = %u", flash_data->led_current_ma[0]);
|
||||
rc = cam_res_mgr_gpio_request(soc_info.dev, soc_private->flash_gpio_enable, 0, "CUSTOM_GPIO1");
|
||||
if(rc) {
|
||||
CAM_ERR(CAM_FLASH, "gpio %d request fails", soc_private->flash_gpio_enable);
|
||||
return rc;
|
||||
}
|
||||
cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 1);
|
||||
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIREHIGH, flash_data->led_current_ma[0]);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -706,6 +819,8 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl,
|
|||
CAM_DBG(CAM_FLASH, "req_id=%llu", req_id);
|
||||
if (req_id == 0) {
|
||||
/* NonRealTime Init settings*/
|
||||
|
||||
|
||||
if (fctrl->apply_streamoff == true) {
|
||||
fctrl->apply_streamoff = false;
|
||||
i2c_set = &fctrl->i2c_data.streamoff_settings;
|
||||
|
|
@ -722,6 +837,9 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl,
|
|||
break;
|
||||
}
|
||||
} else if (fctrl->i2c_data.init_settings.is_settings_valid == true) {
|
||||
if(flash_initstate)
|
||||
goto config_setting;
|
||||
|
||||
list_for_each_entry(i2c_list,
|
||||
&(fctrl->i2c_data.init_settings.list_head),
|
||||
list) {
|
||||
|
|
@ -743,8 +861,14 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl,
|
|||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if((NULL != i2c_list) && (NULL == i2c_flash_off)) {
|
||||
i2c_flash_off = cam_flash_get_i2c_ptr(i2c_list);
|
||||
}
|
||||
}
|
||||
flash_initstate = CAM_FLASH_STATE_CONFIG;
|
||||
}
|
||||
config_setting:
|
||||
/* NonRealTime (Widget/RER/INIT_FIRE settings) */
|
||||
if (fctrl->i2c_data.config_settings.is_settings_valid == true) {
|
||||
list_for_each_entry(i2c_list,
|
||||
|
|
@ -1258,7 +1382,12 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
|
|||
CAM_DBG(CAM_FLASH, "settings already valid");
|
||||
i2c_reg_settings->request_id = 0;
|
||||
i2c_reg_settings->is_settings_valid = false;
|
||||
goto update_req_mgr;
|
||||
//goto update_req_mgr;
|
||||
rc = delete_request(i2c_reg_settings);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH, "Error deleting req: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
i2c_reg_settings->is_settings_valid = true;
|
||||
i2c_reg_settings->request_id =
|
||||
|
|
@ -2009,6 +2138,18 @@ int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
|
|||
}
|
||||
}
|
||||
|
||||
if(i2c_flash_off != NULL)
|
||||
{
|
||||
if(i2c_flash_off->i2c_settings.reg_setting != NULL) {
|
||||
vfree(i2c_flash_off->i2c_settings.reg_setting);
|
||||
i2c_flash_off->i2c_settings.reg_setting = NULL;
|
||||
}
|
||||
|
||||
kfree(i2c_flash_off);
|
||||
i2c_flash_off = NULL;
|
||||
flash_initstate = 0;
|
||||
}
|
||||
|
||||
if (fctrl->bridge_intf.device_hdl != 1) {
|
||||
rc = cam_destroy_device_hdl(fctrl->bridge_intf.device_hdl);
|
||||
if (rc)
|
||||
|
|
@ -2078,3 +2219,98 @@ int cam_flash_apply_request(struct cam_req_mgr_apply_request *apply)
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE
|
||||
static int cam_flash_construct_power_vio_setting(
|
||||
struct cam_sensor_power_ctrl_t *power_info)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
power_info->power_setting_size = 2;
|
||||
power_info->power_setting =
|
||||
kzalloc(sizeof(struct cam_sensor_power_setting) * 2,
|
||||
GFP_KERNEL);
|
||||
if (!power_info->power_setting)
|
||||
return -ENOMEM;
|
||||
|
||||
power_info->power_setting[0].seq_type = SENSOR_VIO;
|
||||
power_info->power_setting[0].seq_val = CAM_VIO;
|
||||
power_info->power_setting[0].config_val = 1;
|
||||
power_info->power_setting[0].delay = 2;
|
||||
power_info->power_setting[1].seq_type = SENSOR_CUSTOM_REG2;
|
||||
power_info->power_setting[1].seq_val = 0;
|
||||
power_info->power_setting[1].config_val = 1;
|
||||
power_info->power_setting[1].delay = 0;
|
||||
|
||||
power_info->power_down_setting_size = 2;
|
||||
power_info->power_down_setting =
|
||||
kzalloc(sizeof(struct cam_sensor_power_setting) * 2,
|
||||
GFP_KERNEL);
|
||||
if (!power_info->power_down_setting) {
|
||||
rc = -ENOMEM;
|
||||
goto free_power_settings;
|
||||
}
|
||||
|
||||
power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_REG2;
|
||||
power_info->power_down_setting[0].seq_val = 0;
|
||||
power_info->power_down_setting[0].config_val = 0;
|
||||
power_info->power_down_setting[1].seq_type = SENSOR_VIO;
|
||||
power_info->power_down_setting[1].seq_val = CAM_VIO;
|
||||
power_info->power_down_setting[1].config_val = 0;
|
||||
|
||||
return rc;
|
||||
|
||||
free_power_settings:
|
||||
kfree(power_info->power_setting);
|
||||
power_info->power_setting = NULL;
|
||||
power_info->power_setting_size = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_flash_fill_vreg_setting(struct cam_flash_ctrl *fctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = cam_flash_construct_power_vio_setting(
|
||||
&fctrl->power_info);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH, "Failed Flash Power VIO Setting: rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
rc = msm_camera_fill_vreg_params(&fctrl->soc_info,
|
||||
fctrl->power_info.power_setting,
|
||||
fctrl->power_info.power_setting_size);
|
||||
if(rc)
|
||||
{
|
||||
CAM_ERR(CAM_FLASH, "Failed Flash Fill Power Up Params: rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
rc = msm_camera_fill_vreg_params(&fctrl->soc_info,
|
||||
fctrl->power_info.power_down_setting,
|
||||
fctrl->power_info.power_down_setting_size);
|
||||
if(rc)
|
||||
{
|
||||
CAM_ERR(CAM_FLASH, "Failed Flash Fill Power Down Params: rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_flash_fill_i2c_default_setting(struct cam_flash_ctrl *fctrl, uint32_t slave_addr)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
struct cam_cmd_i2c_info i2c_info={0};
|
||||
i2c_info.slave_addr = slave_addr;
|
||||
i2c_info.i2c_freq_mode = I2C_STANDARD_MODE;
|
||||
|
||||
rc = cam_flash_slaveInfo_pkt_parser(
|
||||
fctrl, (uint32_t *)&i2c_info, sizeof(struct cam_cmd_i2c_info));
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"Failed parsing slave info: rc: %d",
|
||||
rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
#include "cam_flash_core.h"
|
||||
#include "cam_common_util.h"
|
||||
#include "camera_main.h"
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
#include "pm6125_flash_gpio.h"
|
||||
#endif
|
||||
|
||||
static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
||||
void *arg, struct cam_flash_private_soc *soc_private)
|
||||
|
|
@ -138,10 +141,17 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
}
|
||||
case CAM_QUERY_CAP: {
|
||||
struct cam_flash_query_cap_info flash_cap = {0};
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE
|
||||
uint32_t flash_iic_supplier[3];
|
||||
uint32_t flashid=0;
|
||||
#endif
|
||||
CAM_DBG(CAM_FLASH, "CAM_QUERY_CAP");
|
||||
flash_cap.slot_info = fctrl->soc_info.index;
|
||||
flash_cap.flash_type = soc_private->flash_type;
|
||||
CAM_DBG(CAM_FLASH, "dts flash_type is %d, it should same with camx&chi flash_type", soc_private->flash_type);
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
CAM_DBG(CAM_FLASH, "get flash_enabel_gpio %d", soc_private->flash_gpio_enable);
|
||||
#endif
|
||||
for (i = 0; i < fctrl->flash_num_sources; i++) {
|
||||
flash_cap.max_current_flash[i] =
|
||||
soc_private->flash_max_current[i];
|
||||
|
|
@ -152,7 +162,39 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
for (i = 0; i < fctrl->torch_num_sources; i++)
|
||||
flash_cap.max_current_torch[i] =
|
||||
soc_private->torch_max_current[i];
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE
|
||||
rc = of_property_read_u32_array(fctrl->of_node, "distinguish-flash-supplier",
|
||||
flash_iic_supplier, 3);
|
||||
if (!rc) {
|
||||
CAM_DBG(CAM_FLASH, "Distinguish IIC Flash Supplier dev:0x%x addr:0x%x data:0x%x",
|
||||
flash_iic_supplier[0],flash_iic_supplier[1],flash_iic_supplier[2]);
|
||||
if (cam_flash_fill_vreg_setting(fctrl)){
|
||||
CAM_ERR(CAM_FLASH, "Flash Fill Vreg Failed");
|
||||
goto release_mutex;
|
||||
}
|
||||
if (cam_flash_fill_i2c_default_setting(fctrl, flash_iic_supplier[0])){
|
||||
CAM_ERR(CAM_FLASH, "Failed Flash Fill I2C Setting rc =%d",rc);
|
||||
goto release_mutex;
|
||||
}
|
||||
if (fctrl->func_tbl.power_ops(fctrl, true)){
|
||||
CAM_ERR(CAM_FLASH, "Power Up Failed");
|
||||
goto release_mutex;
|
||||
}
|
||||
rc = camera_io_dev_read(&(fctrl->io_master_info),
|
||||
flash_iic_supplier[1],&flashid,
|
||||
CAMERA_SENSOR_I2C_TYPE_BYTE,
|
||||
CAMERA_SENSOR_I2C_TYPE_BYTE);
|
||||
CAM_DBG(CAM_FLASH, "flashid=%d",flashid);
|
||||
if ((!rc) && (flashid == flash_iic_supplier[2]))
|
||||
flash_cap.flash_supplier = 1;
|
||||
else
|
||||
flash_cap.flash_supplier = 0;
|
||||
if (fctrl->func_tbl.power_ops(fctrl, false)){
|
||||
CAM_ERR(CAM_FLASH, "Power Down Failed");
|
||||
goto release_mutex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (copy_to_user(u64_to_user_ptr(cmd->handle),
|
||||
&flash_cap, sizeof(struct cam_flash_query_cap_info))) {
|
||||
CAM_ERR(CAM_FLASH, "Failed Copy to User");
|
||||
|
|
@ -440,6 +482,9 @@ static int cam_flash_component_bind(struct device *dev,
|
|||
fctrl->soc_info.dev_name = pdev->name;
|
||||
|
||||
platform_set_drvdata(pdev, fctrl);
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
dev_set_drvdata(&pdev->dev, fctrl);
|
||||
#endif
|
||||
|
||||
rc = cam_flash_get_dt_data(fctrl, &fctrl->soc_info);
|
||||
if (rc) {
|
||||
|
|
@ -482,8 +527,9 @@ static int cam_flash_component_bind(struct device *dev,
|
|||
rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
|
||||
&fctrl->power_info.gpio_num_info);
|
||||
if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) {
|
||||
CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs");
|
||||
return -EINVAL;
|
||||
//CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs");
|
||||
//return -EINVAL;
|
||||
CAM_WARN(CAM_FLASH, "No/Error Flash GPIOs");
|
||||
}
|
||||
rc = cam_sensor_util_regulator_powerup(soc_info);
|
||||
if (rc < 0) {
|
||||
|
|
@ -539,6 +585,9 @@ static int cam_flash_component_bind(struct device *dev,
|
|||
|
||||
fctrl->flash_state = CAM_FLASH_STATE_INIT;
|
||||
CAM_DBG(CAM_FLASH, "Component bound successfully");
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
pm6125_flash_control_create_device(&pdev->dev);
|
||||
#endif
|
||||
return rc;
|
||||
|
||||
free_cci_resource:
|
||||
|
|
@ -561,6 +610,10 @@ static void cam_flash_component_unbind(struct device *dev,
|
|||
struct cam_flash_ctrl *fctrl;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
pm6125_flash_control_remove_device(&pdev->dev);
|
||||
#endif
|
||||
|
||||
fctrl = platform_get_drvdata(pdev);
|
||||
if (!fctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Flash device is NULL");
|
||||
|
|
@ -573,6 +626,9 @@ static void cam_flash_component_unbind(struct device *dev,
|
|||
cam_unregister_subdev(&(fctrl->v4l2_dev_str));
|
||||
cam_flash_put_source_node_data(fctrl);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
#endif
|
||||
v4l2_set_subdevdata(&fctrl->v4l2_dev_str.sd, NULL);
|
||||
kfree(fctrl);
|
||||
CAM_INFO(CAM_FLASH, "Flash Sensor component unbind");
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ struct cam_flash_private_soc {
|
|||
uint32_t torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
bool is_wled_flash;
|
||||
uint32_t flash_type;
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
uint32_t flash_gpio_enable;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cam_flash_func_tbl {
|
||||
|
|
@ -239,7 +242,10 @@ int cam_flash_pmic_flush_request(struct cam_flash_ctrl *fctrl,
|
|||
enum cam_flash_flush_type, uint64_t req_id);
|
||||
void cam_flash_shutdown(struct cam_flash_ctrl *fctrl);
|
||||
int cam_flash_release_dev(struct cam_flash_ctrl *fctrl);
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE
|
||||
int cam_flash_fill_i2c_default_setting(struct cam_flash_ctrl *fctrl, uint32_t slave_addr);
|
||||
int cam_flash_fill_vreg_setting(struct cam_flash_ctrl *fctrl);
|
||||
#endif
|
||||
/**
|
||||
* @brief : API to register FLASH hw to platform framework.
|
||||
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ static int32_t cam_get_source_node_info(
|
|||
struct device_node *flash_src_node = NULL;
|
||||
struct device_node *torch_src_node = NULL;
|
||||
struct device_node *switch_src_node = NULL;
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
int16_t gpio_array_size = 0;
|
||||
uint16_t *gpio_array = NULL;
|
||||
#endif
|
||||
|
||||
soc_private->is_wled_flash =
|
||||
of_property_read_bool(of_node, "wled-flash-support");
|
||||
|
|
@ -79,7 +83,29 @@ static int32_t cam_get_source_node_info(
|
|||
CAM_ERR(CAM_FLASH,
|
||||
"flash-type read failed rc=%d", rc);
|
||||
soc_private->flash_type = CAM_FLASH_TYPE_PMIC; // default to PMIC flash
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
} else if(soc_private->flash_type == CAM_FLASH_TYPE_GPIO) {
|
||||
gpio_array_size = of_gpio_count(of_node);
|
||||
if (gpio_array_size == 1){
|
||||
gpio_array = kcalloc(gpio_array_size, sizeof(uint16_t), GFP_KERNEL);
|
||||
if (!gpio_array) {
|
||||
CAM_ERR(CAM_FLASH, "flash gpio array alloc fail");
|
||||
} else {
|
||||
for (i = 0; i < gpio_array_size; i++) {
|
||||
gpio_array[i] = of_get_gpio(of_node, i);
|
||||
CAM_DBG(CAM_FLASH, "flash dts gpio_array[%d] = %d name is %s %s", i, gpio_array[i], of_node->name, of_node->full_name);
|
||||
}
|
||||
soc_private->flash_gpio_enable = gpio_array[0];
|
||||
CAM_DBG(CAM_FLASH, "flash gpio enable %d",soc_private->flash_gpio_enable);
|
||||
kfree(gpio_array);
|
||||
}
|
||||
} else {
|
||||
CAM_ERR(CAM_FLASH, "flash should have two gpio, first is enable in flash dts, second control by flash pm6125");
|
||||
}
|
||||
}
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
||||
switch_src_node = of_parse_phandle(of_node, "switch-source", 0);
|
||||
if (!switch_src_node) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
*Copyright (C) 2021 Motorola Mobility LLC,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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 <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/rc-core.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "pm6125_flash_gpio.h"
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
#include "cam_flash_dev.h"
|
||||
#include "cam_flash_soc.h"
|
||||
#include "cam_flash_core.h"
|
||||
#include "cam_common_util.h"
|
||||
#include "cam_res_mgr_api.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Data Structure
|
||||
*****************************************************************************/
|
||||
|
||||
struct pwm_device *pwm;
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
static unsigned int flashlight_enable = CAMERA_SENSOR_FLASH_STATUS_OFF;
|
||||
static unsigned int flashlight_brightness = 0;
|
||||
#endif/*****************************************************************************
|
||||
* Function
|
||||
*****************************************************************************/
|
||||
|
||||
void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash_opcode opcode, u64 flash_current){
|
||||
struct pwm_state pstate;
|
||||
int rc = 0;
|
||||
u64 real_current = 0;
|
||||
|
||||
pwm_get_state(pwm, &pstate);
|
||||
PM6125_FLASH_PRINT("[pm6125_flash_gpio]Status duty_cycle = %u, period = %u\n",
|
||||
pstate.duty_cycle, pstate.period);
|
||||
pstate.period = PM6125_PWM_PERIOD;
|
||||
switch (s) {
|
||||
case PM6125_FLASH_GPIO_STATE_ACTIVE:
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case CAMERA_SENSOR_FLASH_OP_FIRELOW:
|
||||
real_current = (flash_current > FLASH_FIRE_LOW_MAXCURRENT?FLASH_FIRE_LOW_MAXCURRENT:flash_current);
|
||||
pstate.duty_cycle = PM6125_PWM_PERIOD * real_current / FLASH_FIRE_LOW_MAXCURRENT;
|
||||
break;
|
||||
case CAMERA_SENSOR_FLASH_OP_FIREHIGH:
|
||||
real_current = (flash_current > FLASH_FIRE_HIGH_MAXCURRENT?FLASH_FIRE_HIGH_MAXCURRENT:flash_current);
|
||||
pstate.duty_cycle = PM6125_PWM_PERIOD * real_current / FLASH_FIRE_HIGH_MAXCURRENT;
|
||||
break;
|
||||
default:
|
||||
pstate.duty_cycle = PM6125_PWM_PERIOD;
|
||||
break;
|
||||
}
|
||||
|
||||
pstate.enabled = true;
|
||||
rc = pwm_apply_state(pwm, &pstate);
|
||||
|
||||
PM6125_FLASH_PRINT("[pm6125_flash_gpio]Active duty_cycle = %u, period = %u, opcode = %u, real_current = %u\n",
|
||||
pstate.duty_cycle, pstate.period, opcode, real_current);
|
||||
break;
|
||||
case PM6125_FLASH_GPIO_STATE_SUSPEND:
|
||||
pstate.enabled = false;
|
||||
rc = pwm_apply_state(pwm, &pstate);
|
||||
PM6125_FLASH_PRINT("[pm6125_flash_gpio]Suspend");
|
||||
break;
|
||||
default:
|
||||
PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to control PWM use a err state!\n");
|
||||
}
|
||||
|
||||
if(rc < 0) {
|
||||
PM6125_FLASH_PRINT("[pm6125_flash_gpio]Apply PWM state fail, rc = %d", rc);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
static ssize_t flashlight_enable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%u\n", flashlight_enable);
|
||||
}
|
||||
|
||||
static ssize_t flashlight_enable_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct cam_flash_ctrl *fctrl = dev_get_drvdata(dev);
|
||||
struct cam_flash_private_soc *soc_private = fctrl->soc_info.soc_private;
|
||||
unsigned long state_to_set;
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
CAM_INFO(CAM_FLASH, "Flash Enable Command: %s", buf);
|
||||
ret = kstrtoul(buf, 10, &state_to_set);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (CAMERA_SENSOR_FLASH_STATUS_OFF != state_to_set) {
|
||||
// enable flash
|
||||
if (CAMERA_SENSOR_FLASH_STATUS_OFF == flashlight_enable) {
|
||||
ret = cam_res_mgr_gpio_request(
|
||||
fctrl->soc_info.dev,
|
||||
soc_private->flash_gpio_enable, 0,
|
||||
"CUSTOM_GPIO1");
|
||||
if (ret) {
|
||||
CAM_ERR(CAM_FLASH, "gpio %d request fails",
|
||||
soc_private->flash_gpio_enable);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
flashlight_enable = state_to_set;
|
||||
cam_res_mgr_gpio_set_value(
|
||||
soc_private->flash_gpio_enable,
|
||||
flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH);
|
||||
if (flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_LOW) {
|
||||
pm6125_flash_gpio_select_state(
|
||||
PM6125_FLASH_GPIO_STATE_ACTIVE,
|
||||
CAMERA_SENSOR_FLASH_OP_FIRELOW,
|
||||
FLASH_FIRE_LOW_MAXCURRENT);
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
pm6125_flash_gpio_select_state(
|
||||
PM6125_FLASH_GPIO_STATE_ACTIVE,
|
||||
flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH ?
|
||||
CAMERA_SENSOR_FLASH_OP_FIREHIGH :
|
||||
CAMERA_SENSOR_FLASH_OP_FIRELOW,
|
||||
(u64)flashlight_brightness);
|
||||
}
|
||||
else {
|
||||
// disable flash
|
||||
if (CAMERA_SENSOR_FLASH_STATUS_OFF != flashlight_enable) {
|
||||
cam_res_mgr_gpio_set_value(
|
||||
soc_private->flash_gpio_enable, 0);
|
||||
cam_res_mgr_gpio_free(fctrl->soc_info.dev,
|
||||
soc_private->flash_gpio_enable);
|
||||
}
|
||||
flashlight_enable = CAMERA_SENSOR_FLASH_STATUS_OFF;
|
||||
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND,
|
||||
CAMERA_SENSOR_FLASH_OP_OFF, 0);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t flashlight_brightness_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%u\n", flashlight_brightness);
|
||||
}
|
||||
|
||||
static ssize_t flashlight_brightness_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct cam_flash_ctrl *fctrl = dev_get_drvdata(dev);
|
||||
struct cam_flash_private_soc *soc_private = fctrl->soc_info.soc_private;
|
||||
unsigned long brightness_to_set;
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
CAM_INFO(CAM_FLASH, "Flash Brightness Command: %s", buf);
|
||||
ret = kstrtoul(buf, 10, &brightness_to_set);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
flashlight_brightness = brightness_to_set;
|
||||
|
||||
switch (flashlight_enable)
|
||||
{
|
||||
case CAMERA_SENSOR_FLASH_STATUS_LOW: // CAMERA_SENSOR_FLASH_OP_FIRELOW
|
||||
case CAMERA_SENSOR_FLASH_STATUS_HIGH: // CAMERA_SENSOR_FLASH_OP_FIREHIGH
|
||||
|
||||
CAM_INFO(CAM_FLASH, "Flash Mode %s: %d",
|
||||
flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH ?
|
||||
"High" :
|
||||
"Low",
|
||||
flashlight_brightness);
|
||||
|
||||
// disable first
|
||||
cam_res_mgr_gpio_set_value(
|
||||
soc_private->flash_gpio_enable, 0);
|
||||
cam_res_mgr_gpio_free(fctrl->soc_info.dev,
|
||||
soc_private->flash_gpio_enable);
|
||||
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND, CAMERA_SENSOR_FLASH_OP_OFF, 0);
|
||||
|
||||
// get handle
|
||||
ret = cam_res_mgr_gpio_request(
|
||||
fctrl->soc_info.dev,
|
||||
soc_private->flash_gpio_enable, 0,
|
||||
"CUSTOM_GPIO1");
|
||||
if (ret) {
|
||||
CAM_ERR(CAM_FLASH, "gpio %d request fails",
|
||||
soc_private->flash_gpio_enable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cam_res_mgr_gpio_set_value(
|
||||
soc_private->flash_gpio_enable,
|
||||
flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH);
|
||||
if (flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_LOW) {
|
||||
pm6125_flash_gpio_select_state(
|
||||
PM6125_FLASH_GPIO_STATE_ACTIVE,
|
||||
CAMERA_SENSOR_FLASH_OP_FIRELOW,
|
||||
FLASH_FIRE_LOW_MAXCURRENT);
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
pm6125_flash_gpio_select_state(
|
||||
PM6125_FLASH_GPIO_STATE_ACTIVE,
|
||||
flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH ?
|
||||
CAMERA_SENSOR_FLASH_OP_FIREHIGH :
|
||||
CAMERA_SENSOR_FLASH_OP_FIRELOW,
|
||||
(u64)flashlight_brightness);
|
||||
break;
|
||||
default:
|
||||
CAM_INFO(CAM_FLASH, "flashlight had not been enable yet.");
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
static DEVICE_ATTR_RW(flashlight_enable);
|
||||
static DEVICE_ATTR_RW(flashlight_brightness);
|
||||
struct device_attribute *flashlight_attributes[] = {
|
||||
&dev_attr_flashlight_enable,
|
||||
&dev_attr_flashlight_brightness,
|
||||
};
|
||||
int pm6125_flash_control_create_device(struct device* dev)
|
||||
{
|
||||
int i, ret = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(flashlight_attributes); i++) {
|
||||
ret = device_create_file(dev,
|
||||
flashlight_attributes[i]);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed: sysfs file %s\n",
|
||||
flashlight_attributes[i]->attr.name);
|
||||
pm6125_flash_control_remove_device(dev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pm6125_flash_control_remove_device(struct device* dev)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(flashlight_attributes); i++) {
|
||||
device_remove_file(dev, flashlight_attributes[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static int pm6125_flash_pwm_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
pwm = devm_pwm_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(pwm))
|
||||
return PTR_ERR(pwm);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct of_device_id gpio_of_match[] = {
|
||||
{ .compatible = "qualcomm,pm6125_flash_gpio", },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver pm6125_flash_gpio_platform_driver = {
|
||||
.probe = pm6125_flash_pwm_probe,
|
||||
.driver = {
|
||||
.name = "PM6125_FLASH_GPIO_DTS",
|
||||
.of_match_table = gpio_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
int pm6125_flash_gpio_init_module(void)
|
||||
{
|
||||
if (platform_driver_register(&pm6125_flash_gpio_platform_driver)) {
|
||||
PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to register pm6125_flash_gpio_platform_driver!\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pm6125_flash_gpio_exit_module(void)
|
||||
{
|
||||
platform_driver_unregister(&pm6125_flash_gpio_platform_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("liyang <liyang14@huaqin.com>");
|
||||
MODULE_DESCRIPTION("CONTROL PM6125 FLASH GPIO Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _PM6125_FLASH_GPIO_H_
|
||||
#define _PM6125_FLASH_GPIO_H_
|
||||
|
||||
#include "../cam_sensor_utils/cam_sensor_cmn_header.h"
|
||||
|
||||
#define PM6125_FLASH_PRINT pr_info //printk
|
||||
|
||||
/* DTS state */
|
||||
typedef enum {
|
||||
PM6125_FLASH_GPIO_STATE_ACTIVE,
|
||||
PM6125_FLASH_GPIO_STATE_SUSPEND,
|
||||
PM6125_FLASH_GPIO_STATE_MAX, /* for array size */
|
||||
} PM6125_FLASH_GPIO_STATE;
|
||||
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
enum{
|
||||
CAMERA_SENSOR_FLASH_STATUS_OFF,
|
||||
CAMERA_SENSOR_FLASH_STATUS_LOW,
|
||||
CAMERA_SENSOR_FLASH_STATUS_HIGH
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#define PM6125_PWM_PERIOD 50000
|
||||
#define FLASH_FIRE_HIGH_MAXCURRENT 1200
|
||||
#define FLASH_FIRE_LOW_MAXCURRENT 150
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Prototype
|
||||
*****************************************************************************/
|
||||
extern void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash_opcode opcode, u64 flash_current);
|
||||
#ifdef CONFIG_CAMERA_FLASH_PWM
|
||||
extern int pm6125_flash_control_create_device(struct device* dev);
|
||||
extern int pm6125_flash_control_remove_device(struct device* dev);
|
||||
#endif
|
||||
int pm6125_flash_gpio_init_module(void);
|
||||
void pm6125_flash_gpio_exit_module(void);
|
||||
#endif /* _PM6125_FLASH_GPIO_H_*/
|
||||
2385
techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c
Normal file
2385
techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,224 @@
|
|||
#ifndef AW86006_OIS_H
|
||||
#define AW86006_OIS_H
|
||||
|
||||
/* Log Format */
|
||||
#define AW_LOGI(format, ...) \
|
||||
CAM_INFO(CAM_OIS, format, ##__VA_ARGS__)
|
||||
#define AW_LOGD(format, ...) \
|
||||
CAM_DBG(CAM_OIS, format, ##__VA_ARGS__)
|
||||
#define AW_LOGE(format, ...) \
|
||||
CAM_ERR(CAM_OIS, format, ##__VA_ARGS__)
|
||||
|
||||
/* I2c address */
|
||||
#define AW_SHUTDOWN_I2C_ADDR (0xC2 >> 1) /* 0x61 */
|
||||
#define AW_WAKEUP_I2C_ADDR (0xD2 >> 1) /* 0x69 */
|
||||
|
||||
/* Register detail */
|
||||
#define REG_CHIPID (0x0000)
|
||||
#define REG_OIS_ENABLE (0x0001)
|
||||
#define REG_OIS_STATUS (0x0002)
|
||||
#define REG_PACKING_RST (0x0003)
|
||||
#define REG_DATA_READY (0x0004)
|
||||
#define REG_SAMPLE_TIME (0x0005)
|
||||
#define REG_PACK_DATA (0x0006)
|
||||
#define REG_SPI_GYRO (0x0007)
|
||||
#define REG_SPI_CFG (0x0008)
|
||||
#define REG_AF_CODE_H (0x0009)
|
||||
#define REG_AF_CODE_L (0x000A)
|
||||
#define REG_AF_ARCT (0x000B)
|
||||
#define REG_AF_CFG (0x000C)
|
||||
#define REG_AF_BUSY (0x000D)
|
||||
#define REG_VERSION (0x0010)
|
||||
#define REG_STANDBY (0xFF11)
|
||||
|
||||
/* Flag */
|
||||
#define OIS_ENABLE (0x01)
|
||||
#define OIS_DISABLE (0x00)
|
||||
#define OIS_ERROR (-1)
|
||||
#define OIS_SUCCESS (0)
|
||||
#define AW_IC_STANDBY (1)
|
||||
#define AW_FLASH_WRITE_CONNECT
|
||||
/* #define AW_SOC_FLASH_READ_FLAG */
|
||||
|
||||
/* Loop */
|
||||
#define AW_STAY_ON_MOVE_LOOP (20)
|
||||
#define AW_STAY_ON_BOOT_LOOP (20)
|
||||
#define AW_ERROR_LOOP (3)
|
||||
#define AW_FLASH_WRITE_ERROR_LOOP (2)
|
||||
#define AW_FLASH_READ_ERROR_LOOP (2)
|
||||
#define AW_FLASH_ERASE_ERROR_LOOP (2)
|
||||
#define AW_JUMP_BOOT_LOOP (6)
|
||||
#define AW_JUMP_MOVE_LOOP (6)
|
||||
|
||||
/* Addr or data size */
|
||||
#define AW_SIZE_BYTE_0 (0)
|
||||
#define AW_SIZE_BYTE_1 (1)
|
||||
#define AW_SIZE_BYTE_2 (2)
|
||||
#define AW_SIZE_BYTE_3 (3)
|
||||
#define AW_SIZE_BYTE_4 (4)
|
||||
#define AW_SIZE_BYTE_12 (12)
|
||||
#define AW_SIZE_BYTE_20 (20)
|
||||
#define AW_PROTOCOL_SIZE (14)
|
||||
#define AW_DATA_SHIFT_0_BIT (0)
|
||||
#define AW_DATA_SHIFT_8_BIT (8)
|
||||
#define AW_DATA_SHIFT_16_BIT (16)
|
||||
#define AW_DATA_SHIFT_24_BIT (24)
|
||||
#define AW_I2C_WRITE_BYTE_ZERO (0x00)
|
||||
|
||||
/* Delay */
|
||||
#define AW_RESET_DELAY (50) /* ms */
|
||||
#define AW_JUMP_MOVE_DELAY (9) /* ms */
|
||||
#define AW_JUMP_MOVE_DELAY_MAX (16) /* ms */
|
||||
#define AW_JUMP_BOOT_DELAY (2) /* ms */
|
||||
#define AW_JUMP_BOOT_DELAY_MAX (6) /* ms */
|
||||
#define AW_SHUTDOWN_DELAY (2000) /* us */
|
||||
|
||||
/* Flash and firmware */
|
||||
#define AW_FLASH_BASE_ADDR (0x01000000)
|
||||
#define AW_FLASH_APP_ADDR (0x01002000)
|
||||
#define AW_FLASH_MOVE_LENGTH (AW_FLASH_APP_ADDR - AW_FLASH_BASE_ADDR)
|
||||
#define AW_FLASH_FULL_SIZE (0xB000)
|
||||
#define AW_FLASH_TOP_ADDR (AW_FLASH_BASE_ADDR + AW_FLASH_FULL_SIZE)
|
||||
#define AW_FLASH_ERASE_LEN (512)
|
||||
#define AW_FLASH_WRITE_LEN (64)
|
||||
#define AW_FLASH_READ_LEN (64)
|
||||
#define AW_FW_INFO_LENGTH (64)
|
||||
#define AW_FW_SHIFT_IDENTIFY (AW_FLASH_MOVE_LENGTH)
|
||||
#define AW_FW_SHIFT_CHECKSUM (AW_FW_SHIFT_IDENTIFY + 8)
|
||||
#define AW_FW_SHIFT_APP_CHECKSUM (AW_FW_SHIFT_CHECKSUM + 4)
|
||||
#define AW_FW_SHIFT_CHECKSUM_ADDR (AW_FW_SHIFT_APP_CHECKSUM)
|
||||
#define AW_FW_SHIFT_APP_LENGTH (AW_FW_SHIFT_APP_CHECKSUM + 4)
|
||||
#define AW_FW_SHIFT_APP_VERSION (AW_FW_SHIFT_APP_LENGTH + 4)
|
||||
#define AW_FW_SHIFT_APP_ID (AW_FW_SHIFT_APP_VERSION + 4)
|
||||
#define AW_FW_SHIFT_MOVE_CHECKSUM (AW_FW_SHIFT_APP_ID + 4)
|
||||
#define AW_FW_SHIFT_MOVE_VERSION (AW_FW_SHIFT_MOVE_CHECKSUM + 4)
|
||||
#define AW_FW_SHIFT_MOVE_LENGTH (AW_FW_SHIFT_MOVE_VERSION + 4)
|
||||
#define AW_FW_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_MOVE_LENGTH + 8)
|
||||
#define AW_ARRAY_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_UPDATE_FLAG - AW_FLASH_MOVE_LENGTH)
|
||||
|
||||
/* gyro and hall test */
|
||||
#define AW_GYROACCEL_DIFT_LIMIT 5000
|
||||
#define CHECK_DIFF(x, y) ((x > 0) ? (x - y) : (-x - y))
|
||||
|
||||
/* SOC */
|
||||
enum soc_status {
|
||||
SOC_OK = 0,
|
||||
SOC_ADDR_ERROR,
|
||||
SOC_PBUF_ERROR,
|
||||
SOC_HANK_ERROR,
|
||||
SOC_JUMP_ERROR,
|
||||
SOC_FLASH_ERROR,
|
||||
SOC_SPACE_ERROR,
|
||||
};
|
||||
|
||||
enum soc_module {
|
||||
SOC_HANK = 0x01,
|
||||
SOC_SRAM = 0x02,
|
||||
SOC_FLASH = 0x03,
|
||||
SOC_END = 0x04,
|
||||
};
|
||||
|
||||
enum soc_enum {
|
||||
SOC_VERSION = 0x01,
|
||||
SOC_CTL = 0x00,
|
||||
SOC_ACK = 0x01,
|
||||
SOC_ADDR = 0x84,
|
||||
SOC_READ_ADDR = 0x48,
|
||||
SOC_ERASE_STRUCT_LEN = 6,
|
||||
SOC_READ_STRUCT_LEN = 6,
|
||||
SOC_PROTOCAL_HEAD = 9,
|
||||
SOC_CONNECT_WRITE_LEN = 9,
|
||||
SOC_ERASE_WRITE_LEN = 15,
|
||||
SOC_READ_WRITE_LEN = 15,
|
||||
SOC_ERASE_BLOCK_DELAY = 5,
|
||||
SOC_WRITE_BLOCK_HEAD = 13,
|
||||
SOC_WRITE_BLOCK_DELAY = 600, /* us */
|
||||
SOC_READ_BLOCK_DELAY = 200, /* us */
|
||||
SOC_CONNECT_DELAY = 100, /* us */
|
||||
};
|
||||
|
||||
enum soc_flash_event {
|
||||
SOC_FLASH_WRITE = 0x01,
|
||||
SOC_FLASH_WRITE_ACK = 0x02,
|
||||
SOC_FLASH_READ = 0x11,
|
||||
SOC_FLASH_READ_ACK = 0x12,
|
||||
SOC_FLASH_ERASE_BLOCK = 0x21,
|
||||
SOC_FLASH_ERASE_BLOCK_ACK = 0x22,
|
||||
SOC_FLASH_ERASE_CHIP = 0x23,
|
||||
SOC_FLASH_ERASE_CHIP_ACK = 0x24,
|
||||
};
|
||||
|
||||
enum soc_hank_event {
|
||||
SOC_HANK_CONNECT = 0x01,
|
||||
SOC_HANK_CONNECT_ACK = 0x02,
|
||||
SOC_HANK_PROTICOL = 0x11,
|
||||
SOC_HANK_PROTICOL_ACK = 0x12,
|
||||
SOC_HANK_VERSION = 0x21,
|
||||
SOC_HANK_VERSION_ACK = 0x22,
|
||||
SOC_HANK_ID = 0x31,
|
||||
SOC_HANK_ID_ACK = 0x32,
|
||||
SOC_HANK_DATE = 0x33,
|
||||
SOC_HANK_DATA_ACK = 0x34,
|
||||
};
|
||||
|
||||
/* ISP */
|
||||
enum isp_enum {
|
||||
ISP_READ_VERSION_DELAY = 500, /* us */
|
||||
ISP_VERS_CONNECT_ACK = 0x01,
|
||||
ISP_VERSION_ACK_LEN = 5,
|
||||
ISP_EVENT_OK = 0x01,
|
||||
};
|
||||
|
||||
enum awrw_flag {
|
||||
AW_SEQ_WRITE = 0,
|
||||
AW_SEQ_READ = 1,
|
||||
};
|
||||
|
||||
enum axis_info {
|
||||
AXIS_X,
|
||||
AXIS_Y,
|
||||
AXIS_Z,
|
||||
};
|
||||
|
||||
struct accelgyro_dift {
|
||||
int16_t gyro_dift[3];
|
||||
int16_t accel_dift[3];
|
||||
};
|
||||
|
||||
/* Struct */
|
||||
struct soc_protocol {
|
||||
uint8_t checksum;
|
||||
uint8_t protocol_ver;
|
||||
uint8_t addr;
|
||||
uint8_t module;
|
||||
uint8_t event;
|
||||
uint8_t len[2];
|
||||
uint8_t ack;
|
||||
uint8_t sum;
|
||||
uint8_t reserved[3];
|
||||
uint8_t ack_juge;
|
||||
uint8_t *p_data;
|
||||
};
|
||||
|
||||
struct aw86006_fw {
|
||||
uint32_t checksum;
|
||||
uint32_t app_checksum;
|
||||
uint32_t app_length;
|
||||
uint32_t app_version;
|
||||
uint32_t app_id;
|
||||
uint32_t move_checksum;
|
||||
uint32_t move_version;
|
||||
uint32_t move_length;
|
||||
uint32_t update_flag;
|
||||
uint32_t size;
|
||||
uint8_t *data_p;
|
||||
};
|
||||
|
||||
struct aw86006_info {
|
||||
uint8_t already_update;
|
||||
uint8_t checkinfo_fw[64];
|
||||
uint8_t checkinfo_rd[64];
|
||||
struct aw86006_fw fw;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,63 @@
|
|||
#include "cam_debug_util.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
extern int aw86006_ois_init(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */
|
||||
extern int aw86006_ois_exit(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */
|
||||
|
||||
static int cam_ois_clear_data_ready(struct cam_ois_ctrl_t *o_ctrl)
|
||||
{
|
||||
struct cam_sensor_i2c_reg_setting i2c_reg_setting = {NULL,1,CAMERA_SENSOR_I2C_TYPE_WORD,CAMERA_SENSOR_I2C_TYPE_WORD,0};
|
||||
struct cam_sensor_i2c_reg_array i2c_write_settings = {0x70DA,0x0000,0,0};
|
||||
int32_t rc = 0;
|
||||
|
||||
if (!o_ctrl) {
|
||||
CAM_ERR(CAM_OIS, "Invalid Args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
i2c_reg_setting.reg_setting = &(i2c_write_settings);
|
||||
|
||||
rc = camera_io_dev_write(&(o_ctrl->io_master_info), &(i2c_reg_setting));
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "Failed in Applying i2c wrt settings");
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_OIS,"Clear data-ready success");
|
||||
return rc;
|
||||
}
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
static struct cam_ois_ctrl_t * g_o_ctrl = NULL;
|
||||
|
||||
int cam_ois_write_af_drift(uint32_t dac)
|
||||
{
|
||||
struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl;
|
||||
struct cam_sensor_i2c_reg_setting i2c_reg_setting = {NULL, 1, CAMERA_SENSOR_I2C_TYPE_WORD, CAMERA_SENSOR_I2C_TYPE_WORD, 0};
|
||||
struct cam_sensor_i2c_reg_array i2c_write_settings = {0x7070, dac, 0, 0};
|
||||
int rc = 0;
|
||||
|
||||
if (!o_ctrl) {
|
||||
CAM_ERR(CAM_OIS, "invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||
CAM_WARN(CAM_OIS, "Not in right state to write af drift: %d", o_ctrl->cam_ois_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
i2c_reg_setting.reg_setting = &(i2c_write_settings);
|
||||
|
||||
rc = camera_io_dev_write(&(o_ctrl->io_master_info), &(i2c_reg_setting));
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "fail in applying i2c wrt settings");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_OIS,"write af-drift success 0x%x", dac);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
|
|
@ -271,6 +328,255 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t cam_aw86006_ois_vsync_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct cam_ois_ctrl_t *o_ctrl = data;
|
||||
int rc = -EINVAL, handled = IRQ_NONE, sample_cnt = 0, delay_time = 0;
|
||||
uint64_t mono_time_ns;
|
||||
struct timespec64 ts;
|
||||
uint8_t *read_buff;
|
||||
uint32_t k, read_len;
|
||||
|
||||
if (!o_ctrl) {
|
||||
CAM_ERR(CAM_OIS, "Invalid Args");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||
CAM_WARN(CAM_OIS, "Not in right state to read Eis data: %d", o_ctrl->cam_ois_state);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (o_ctrl->is_video_mode == false ||
|
||||
o_ctrl->is_need_eis_data == false) {
|
||||
CAM_DBG(CAM_OIS, "No need to read Eis data: %d %d", o_ctrl->is_video_mode, o_ctrl->is_need_eis_data);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (!mutex_trylock(&o_ctrl->vsync_mutex)) {
|
||||
CAM_WARN(CAM_OIS, "try to get mutex fail, skip this irq");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec);
|
||||
|
||||
CAM_DBG(CAM_OIS, "aw86006 ois vsync sof mono timestamp is %lld", mono_time_ns);
|
||||
|
||||
o_ctrl->prev_timestamp = o_ctrl->curr_timestamp;
|
||||
o_ctrl->curr_timestamp = mono_time_ns;
|
||||
|
||||
// when the first vsync arrived, return
|
||||
if (o_ctrl->is_first_vsync) {
|
||||
o_ctrl->is_first_vsync = 0;
|
||||
rc = -EINVAL;
|
||||
goto release_mutex;
|
||||
}
|
||||
|
||||
memset(o_ctrl->ring_buff, 0, o_ctrl->ring_buff_size);
|
||||
read_buff = o_ctrl->ring_buff;
|
||||
|
||||
for (k = 0; k < RING_BUFFER_LEN/READ_BYTE + 1; k++) {
|
||||
if (k == RING_BUFFER_LEN/READ_BYTE)
|
||||
read_len = RING_BUFFER_LEN%READ_BYTE;
|
||||
else
|
||||
read_len = READ_BYTE;
|
||||
|
||||
if (read_len == 0) {
|
||||
CAM_WARN(CAM_OIS, "read length is 0, break loop read");
|
||||
break;
|
||||
}
|
||||
|
||||
rc = camera_io_dev_ois_read_seq(
|
||||
&o_ctrl->io_master_info,
|
||||
AW86006_PACKET_ADDR,
|
||||
read_buff + k*READ_BYTE,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD,
|
||||
CAMERA_SENSOR_I2C_TYPE_BYTE,
|
||||
read_len);
|
||||
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "failed to read ois data: %d", rc);
|
||||
goto release_mutex;
|
||||
}
|
||||
}
|
||||
|
||||
sample_cnt = read_buff[0];
|
||||
delay_time = read_buff[1];
|
||||
|
||||
CAM_DBG(CAM_OIS,"sample_cnt = %d, delay_time = %d (100 us)", sample_cnt, delay_time);
|
||||
|
||||
if (sample_cnt == 0 || sample_cnt > AW86006_MAX_SAMPLE) {
|
||||
CAM_WARN(CAM_OIS,"sample_cnt %d is invalid, skip the data", sample_cnt);
|
||||
rc = -EINVAL;
|
||||
goto release_mutex;
|
||||
}
|
||||
|
||||
release_mutex:
|
||||
if (rc < 0) {
|
||||
memset(o_ctrl->ring_buff, 0, o_ctrl->ring_buff_size);
|
||||
handled = IRQ_NONE;
|
||||
} else
|
||||
handled = IRQ_HANDLED;
|
||||
|
||||
mutex_unlock(&(o_ctrl->vsync_mutex));
|
||||
|
||||
if (rc >= 0)
|
||||
complete(&o_ctrl->ois_data_complete);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct cam_ois_ctrl_t *o_ctrl = data;
|
||||
int rc = 0, handled = IRQ_NONE, packet_cnt = 0, sample_cnt = 0;
|
||||
uint64_t mono_time_ns;
|
||||
struct timespec64 ts;
|
||||
uint8_t *read_buff;
|
||||
uint32_t k, read_len;
|
||||
uint32_t data_ready = 0xFFFF;
|
||||
int i = 0;
|
||||
|
||||
if (!o_ctrl) {
|
||||
CAM_ERR(CAM_OIS, "Invalid Args");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||
CAM_WARN(CAM_OIS, "Not in right state to read OIS: %d", o_ctrl->cam_ois_state);
|
||||
goto release_mutex;
|
||||
}
|
||||
|
||||
if(o_ctrl->is_video_mode == false ||
|
||||
o_ctrl->is_need_eis_data == false) {
|
||||
CAM_WARN(CAM_OIS, "No need to read Eis data %d %d", o_ctrl->is_video_mode, o_ctrl->is_need_eis_data);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (!mutex_trylock(&o_ctrl->vsync_mutex)) {
|
||||
CAM_ERR(CAM_OIS, "try lock fail, skip this irq");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec);
|
||||
|
||||
CAM_DBG(CAM_OIS, "vsync sof mono timestamp is %lld", mono_time_ns);
|
||||
|
||||
o_ctrl->prev_timestamp = o_ctrl->curr_timestamp;
|
||||
o_ctrl->curr_timestamp = mono_time_ns;
|
||||
|
||||
// when the first vsync arrived, clear data-ready, and return.
|
||||
if (o_ctrl->is_first_vsync) {
|
||||
o_ctrl->is_first_vsync = 0;
|
||||
rc = cam_ois_clear_data_ready(o_ctrl);
|
||||
udelay(1000);
|
||||
goto release_mutex;
|
||||
}
|
||||
|
||||
memset(o_ctrl->ois_data, 0, o_ctrl->ois_data_size);
|
||||
read_buff = o_ctrl->ois_data;
|
||||
|
||||
for (i = 0; i < READ_COUNT; i++) {
|
||||
rc = camera_io_dev_read(
|
||||
&o_ctrl->io_master_info,
|
||||
DATA_READY_ADDR,
|
||||
&data_ready,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "failed to read OIS 0x70da reg rc: %d", rc);
|
||||
goto release_mutex;
|
||||
}
|
||||
if (data_ready == DATA_READY) {
|
||||
CAM_DBG(CAM_OIS, "data_ready == 0x0001 i = %d", i);
|
||||
udelay(400);
|
||||
break;
|
||||
} else if (data_ready != DATA_READY && i < READ_COUNT - 1) {
|
||||
CAM_ERR(CAM_OIS, "data_ready != 0x0001 i = %d", i);
|
||||
udelay(1000);
|
||||
} else {
|
||||
CAM_ERR(CAM_OIS, "data_ready check fail i = %d", i);
|
||||
goto release_mutex;
|
||||
}
|
||||
}
|
||||
do {
|
||||
if (packet_cnt > 0 && packet_cnt < MAX_PACKET)
|
||||
read_buff += PACKET_BYTE;
|
||||
|
||||
// SM6375: CCI_VERSION_1_2_9 can only support read 0xE bytes data one time.
|
||||
for (k = 0; k < PACKET_BYTE/READ_BYTE + 1; k++) {
|
||||
if (k == PACKET_BYTE/READ_BYTE)
|
||||
read_len = PACKET_BYTE%READ_BYTE;
|
||||
else
|
||||
read_len = READ_BYTE;
|
||||
|
||||
if (read_len == 0) {
|
||||
CAM_WARN(CAM_OIS, "Read length is zero, break loop read");
|
||||
break;
|
||||
}
|
||||
|
||||
rc = camera_io_dev_ois_read_seq(
|
||||
&o_ctrl->io_master_info,
|
||||
PACKET_ADDR + k*READ_BYTE/2,
|
||||
read_buff + k*READ_BYTE,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD,
|
||||
read_len);
|
||||
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "Failed: seq read I2C settings: %d", rc);
|
||||
goto release_mutex;
|
||||
}
|
||||
|
||||
if (k == 0 && packet_cnt == 0) {
|
||||
sample_cnt = read_buff[1];
|
||||
if (sample_cnt != 0) {
|
||||
packet_cnt = (sample_cnt + 9)/10;
|
||||
CAM_DBG(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt);
|
||||
|
||||
// we only need max 30 sample.
|
||||
if (packet_cnt > MAX_PACKET || sample_cnt > MAX_SAMPLE) {
|
||||
CAM_WARN(CAM_OIS,"Too many packet, skip this read");
|
||||
rc = -EINVAL;
|
||||
goto release_mutex;
|
||||
}
|
||||
} else {
|
||||
CAM_WARN(CAM_OIS,"No-fatal: sample data is zero, break the loop read");
|
||||
goto release_mutex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sample_cnt > 10 && packet_cnt > 1) {
|
||||
CAM_WARN(CAM_OIS,"more than 1 packet, clear data-ready and read next packet");
|
||||
rc = cam_ois_clear_data_ready(o_ctrl);
|
||||
udelay(1000);
|
||||
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS,"Write failed rc: %d", rc);
|
||||
goto release_mutex;
|
||||
}
|
||||
}
|
||||
|
||||
packet_cnt--;
|
||||
} while(packet_cnt > 0);
|
||||
|
||||
release_mutex:
|
||||
if (rc < 0) {
|
||||
memset(o_ctrl->ois_data, 0, o_ctrl->ois_data_size);
|
||||
handled = IRQ_NONE;
|
||||
} else
|
||||
handled = IRQ_HANDLED;
|
||||
|
||||
mutex_unlock(&(o_ctrl->vsync_mutex));
|
||||
|
||||
complete(&o_ctrl->ois_data_complete);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static int cam_ois_component_bind(struct device *dev,
|
||||
struct device *master_dev, void *data)
|
||||
{
|
||||
|
|
@ -290,11 +596,21 @@ static int cam_ois_component_bind(struct device *dev,
|
|||
|
||||
o_ctrl->ois_device_type = MSM_CAMERA_PLATFORM_DEVICE;
|
||||
|
||||
o_ctrl->ring_buff_size = RING_BUFFER_LEN;
|
||||
o_ctrl->ring_buff = kzalloc(o_ctrl->ring_buff_size, GFP_KERNEL);
|
||||
if (!o_ctrl->ring_buff)
|
||||
goto free_o_ctrl;
|
||||
|
||||
o_ctrl->ois_data_size = PACKET_BYTE*MAX_PACKET;
|
||||
o_ctrl->ois_data = kzalloc(o_ctrl->ois_data_size, GFP_KERNEL);
|
||||
if (!o_ctrl->ois_data)
|
||||
goto free_ring_buff;
|
||||
|
||||
o_ctrl->io_master_info.master_type = CCI_MASTER;
|
||||
o_ctrl->io_master_info.cci_client = kzalloc(
|
||||
sizeof(struct cam_sensor_cci_client), GFP_KERNEL);
|
||||
if (!o_ctrl->io_master_info.cci_client)
|
||||
goto free_o_ctrl;
|
||||
goto free_ois_data;
|
||||
|
||||
soc_private = kzalloc(sizeof(struct cam_ois_soc_private),
|
||||
GFP_KERNEL);
|
||||
|
|
@ -306,8 +622,12 @@ static int cam_ois_component_bind(struct device *dev,
|
|||
soc_private->power_info.dev = &pdev->dev;
|
||||
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_init_data.list_head));
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_preprog_data.list_head));
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_precoeff_data.list_head));
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_calib_data.list_head));
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_postcalib_data.list_head));
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_mode_data.list_head));
|
||||
INIT_LIST_HEAD(&(o_ctrl->i2c_gyro_data.list_head));
|
||||
mutex_init(&(o_ctrl->ois_mutex));
|
||||
rc = cam_ois_driver_soc_init(o_ctrl);
|
||||
if (rc) {
|
||||
|
|
@ -328,6 +648,48 @@ static int cam_ois_component_bind(struct device *dev,
|
|||
|
||||
platform_set_drvdata(pdev, o_ctrl);
|
||||
o_ctrl->cam_ois_state = CAM_OIS_INIT;
|
||||
|
||||
#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT
|
||||
g_o_ctrl = o_ctrl;
|
||||
#endif
|
||||
mutex_init(&(o_ctrl->vsync_mutex));
|
||||
init_completion(&o_ctrl->ois_data_complete);
|
||||
|
||||
if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006"))
|
||||
aw86006_ois_init(o_ctrl);
|
||||
|
||||
if (o_ctrl->is_ois_vsync_irq_supported) {
|
||||
o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0);
|
||||
|
||||
if (o_ctrl->vsync_irq > 0) {
|
||||
CAM_DBG(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq);
|
||||
|
||||
if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) {
|
||||
rc = devm_request_threaded_irq(dev,
|
||||
o_ctrl->vsync_irq,
|
||||
NULL,
|
||||
cam_aw86006_ois_vsync_irq_thread,
|
||||
(IRQF_TRIGGER_RISING | IRQF_ONESHOT),
|
||||
"aw86006-vsync-irq",
|
||||
o_ctrl);
|
||||
} else {
|
||||
rc = devm_request_threaded_irq(dev,
|
||||
o_ctrl->vsync_irq,
|
||||
NULL,
|
||||
cam_ois_vsync_irq_thread,
|
||||
(IRQF_TRIGGER_RISING | IRQF_ONESHOT),
|
||||
"ois-vsync-irq",
|
||||
o_ctrl);
|
||||
}
|
||||
|
||||
if (rc != 0)
|
||||
CAM_ERR(CAM_OIS, "failed: to request ois-vsync IRQ %d, rc %d", o_ctrl->vsync_irq, rc);
|
||||
else
|
||||
CAM_DBG(CAM_OIS, "request ois-vsync IRQ success");
|
||||
} else
|
||||
CAM_ERR(CAM_OIS, "failed: to get ois-vsync IRQ");
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_OIS, "Component bound successfully");
|
||||
return rc;
|
||||
unreg_subdev:
|
||||
|
|
@ -336,6 +698,10 @@ free_soc:
|
|||
kfree(soc_private);
|
||||
free_cci_client:
|
||||
kfree(o_ctrl->io_master_info.cci_client);
|
||||
free_ois_data:
|
||||
kfree(o_ctrl->ois_data);
|
||||
free_ring_buff:
|
||||
kfree(o_ctrl->ring_buff);
|
||||
free_o_ctrl:
|
||||
kfree(o_ctrl);
|
||||
return rc;
|
||||
|
|
@ -358,6 +724,9 @@ static void cam_ois_component_unbind(struct device *dev,
|
|||
}
|
||||
|
||||
CAM_INFO(CAM_OIS, "platform driver remove invoked");
|
||||
if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006"))
|
||||
aw86006_ois_exit(o_ctrl);
|
||||
|
||||
soc_info = &o_ctrl->soc_info;
|
||||
for (i = 0; i < soc_info->num_clk; i++)
|
||||
devm_clk_put(soc_info->dev, soc_info->clk[i]);
|
||||
|
|
@ -373,6 +742,8 @@ static void cam_ois_component_unbind(struct device *dev,
|
|||
|
||||
kfree(o_ctrl->soc_info.soc_private);
|
||||
kfree(o_ctrl->io_master_info.cci_client);
|
||||
kfree(o_ctrl->ois_data);
|
||||
kfree(o_ctrl->ring_buff);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, NULL);
|
||||
kfree(o_ctrl);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,28 @@
|
|||
#define DEFINE_MSM_MUTEX(mutexname) \
|
||||
static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
|
||||
|
||||
#define MODE_ADDR 0x7014
|
||||
#define ENABLE_ADDR 0x7015
|
||||
#define PACKET_ADDR 0x70B0
|
||||
#define DATA_READY_ADDR 0x70DA
|
||||
#define DATA_READY 0x0001
|
||||
#define READ_COUNT 3
|
||||
#define PACKET_BYTE 62
|
||||
#define MAX_PACKET 5
|
||||
#define MAX_SAMPLE 30
|
||||
#define READ_BYTE 0xC
|
||||
|
||||
#define QTIMER_ADDR 0x70DB
|
||||
#define QTIMER_SAMPLE_TIME 2
|
||||
#define QTIMER_MAX_SAMPLE 20
|
||||
|
||||
/* AW86006 EIS */
|
||||
#define RING_BUFFER_LEN 42
|
||||
#define AW86006_PACKET_ENABLE 0x0003
|
||||
#define AW86006_PACKET_ADDR 0x0006
|
||||
#define AW86006_MAX_SAMPLE 10
|
||||
|
||||
|
||||
enum cam_ois_state {
|
||||
CAM_OIS_INIT,
|
||||
CAM_OIS_ACQUIRE,
|
||||
|
|
@ -82,6 +104,13 @@ struct cam_ois_intf_params {
|
|||
struct cam_req_mgr_crm_cb *crm_cb;
|
||||
};
|
||||
|
||||
struct awrw_ctrl {
|
||||
uint32_t addr[4];
|
||||
uint16_t reg_num;
|
||||
uint8_t flag;
|
||||
uint8_t *reg_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_ois_ctrl_t - OIS ctrl private data
|
||||
* @device_name : ois device_name
|
||||
|
|
@ -95,12 +124,21 @@ struct cam_ois_intf_params {
|
|||
* @i2c_init_data : ois i2c init settings
|
||||
* @i2c_mode_data : ois i2c mode settings
|
||||
* @i2c_time_data : ois i2c time write settings
|
||||
* @i2c_preprog_data : ois i2c preprog settings
|
||||
* @i2c_precoeff_data : ois i2c precoeff settings
|
||||
* @i2c_postcalib_data : ois i2c postcalib settings
|
||||
* @i2c_calib_data : ois i2c calib settings
|
||||
* @ois_device_type : ois device type
|
||||
* @cam_ois_state : ois_device_state
|
||||
* @ois_fw_flag : flag for firmware download
|
||||
* @ois_preprog_flag : flag for preprog reg settings
|
||||
* @ois_precoeff_flag : flag for precoeff reg settings
|
||||
* @is_ois_calib : flag for Calibration data
|
||||
* @ois_postcalib_flag : flag for postcalib reg settings
|
||||
* @opcode : ois opcode
|
||||
* @ois_fw_inc_addr : flag to increment address when sending fw
|
||||
* @ois_fw_addr_type : address type of fw
|
||||
* @ois_fw_txn_data_sz : num data bytes per i2c txn when sending fw
|
||||
* @device_name : Device name
|
||||
*
|
||||
*/
|
||||
|
|
@ -115,15 +153,46 @@ struct cam_ois_ctrl_t {
|
|||
struct cam_subdev v4l2_dev_str;
|
||||
struct cam_ois_intf_params bridge_intf;
|
||||
struct i2c_settings_array i2c_init_data;
|
||||
struct i2c_settings_array i2c_preprog_data;
|
||||
struct i2c_settings_array i2c_precoeff_data;
|
||||
struct i2c_settings_array i2c_calib_data;
|
||||
struct i2c_settings_array i2c_postcalib_data;
|
||||
struct i2c_settings_array i2c_mode_data;
|
||||
struct i2c_settings_array i2c_gyro_data;
|
||||
struct i2c_settings_array i2c_time_data;
|
||||
enum msm_camera_device_type_t ois_device_type;
|
||||
enum cam_ois_state cam_ois_state;
|
||||
char ois_name[32];
|
||||
uint8_t ois_fw_flag;
|
||||
uint8_t ois_preprog_flag;
|
||||
uint8_t ois_precoeff_flag;
|
||||
uint8_t is_ois_calib;
|
||||
uint8_t ois_postcalib_flag;
|
||||
uint8_t ois_fw_txn_data_sz;
|
||||
uint8_t ois_fw_inc_addr;
|
||||
uint8_t ois_fw_addr_type;
|
||||
uint8_t ois_fw_data_type;
|
||||
uint64_t prev_timestamp;
|
||||
uint64_t curr_timestamp;
|
||||
struct cam_ois_opcode opcode;
|
||||
bool is_ois_vsync_irq_supported;
|
||||
int vsync_irq;
|
||||
struct mutex vsync_mutex;
|
||||
struct completion ois_data_complete;
|
||||
bool is_first_vsync;
|
||||
uint8_t *ois_data;
|
||||
int ois_data_size;
|
||||
uint16_t q_timer_cnt;
|
||||
uint64_t mono_timestamp;
|
||||
/* awinic_add */
|
||||
const char *ic_name;
|
||||
struct work_struct aw_fw_update_work;
|
||||
struct mutex aw_ois_mutex;
|
||||
struct awrw_ctrl *awrw_ctrl;
|
||||
uint8_t *ring_buff;
|
||||
int ring_buff_size;
|
||||
bool is_video_mode;
|
||||
bool is_need_eis_data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 <linux/module.h>
|
||||
#include "cam_ois_core.h"
|
||||
#include "cam_ois_soc.h"
|
||||
#include "cam_sensor_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_common_util.h"
|
||||
|
||||
#define DW9781C_CHIP_ID_ADDRESS 0x7000
|
||||
#define DW9781C_CHECKSUM_ADDRESS 0x7007
|
||||
#define DW9781C_CHIP_ID 0x9781
|
||||
#define FW_VER_CURR_ADDR 0x7001
|
||||
#define FW_TYPE_ADDR 0x700D
|
||||
#define SET_FW 0x8001
|
||||
|
||||
#define EOK 0
|
||||
|
||||
#define FW_VERSION_OFFSET 10235
|
||||
#define FW_CHECKSUM_OFFSET 10234
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int driverIc;
|
||||
unsigned int size;
|
||||
const uint16_t *fwContentPtr;
|
||||
uint16_t version;
|
||||
uint16_t checksum;
|
||||
} FirmwareContex;
|
||||
|
||||
static FirmwareContex g_dw9781FirmwareContext;
|
||||
|
||||
static int32_t dw9781_cci_write(struct camera_io_master * io_master_info, uint16_t reg, uint16_t val)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
struct cam_sensor_i2c_reg_array reg_setting;
|
||||
struct cam_sensor_i2c_reg_setting wr_setting;
|
||||
|
||||
reg_setting.reg_addr = reg;
|
||||
reg_setting.reg_data = val;
|
||||
reg_setting.delay = 0;
|
||||
reg_setting.data_mask = 0;
|
||||
wr_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD;
|
||||
wr_setting.data_type = CAMERA_SENSOR_I2C_TYPE_WORD;
|
||||
wr_setting.reg_setting = ®_setting;
|
||||
wr_setting.size = 1;
|
||||
wr_setting.delay = 0;
|
||||
rc = camera_io_dev_write(io_master_info, &wr_setting);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t dw9781_cci_read(struct camera_io_master * io_master_info, uint16_t reg, uint16_t *val)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
uint32_t regVal = 0;
|
||||
rc = camera_io_dev_read(io_master_info, reg, ®Val, CAMERA_SENSOR_I2C_TYPE_WORD, CAMERA_SENSOR_I2C_TYPE_WORD);
|
||||
if (!rc) {
|
||||
*val = (uint16_t)regVal;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void dw9781_delay_ms(uint32_t ms)
|
||||
{
|
||||
usleep_range(ms*1000, ms*1000+10);
|
||||
return;
|
||||
}
|
||||
|
||||
void dw9781_ois_reset(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_ois_reset] ois reset");
|
||||
dw9781_cci_write(io_master_info, 0xD002, 0x0001); /* DW9781_DBGc reset */
|
||||
dw9781_delay_ms(4);
|
||||
dw9781_cci_write(io_master_info, 0xD001, 0x0001); /* Active mode (DSP ON) */
|
||||
dw9781_delay_ms(25); /* ST gyro - over wait 25ms, default Servo On */
|
||||
dw9781_cci_write(io_master_info, 0xEBF1, 0x56FA); /* User protection release */
|
||||
}
|
||||
|
||||
void dw9781_ois_ready_check(struct camera_io_master * io_master_info)
|
||||
{
|
||||
uint16_t fw_flag;
|
||||
dw9781_cci_write(io_master_info, 0xD001, 0x0000); /* dsp off mode */
|
||||
dw9781_cci_write(io_master_info, 0xFAFA, 0x98AC); /* All protection(1) */
|
||||
dw9781_cci_write(io_master_info, 0xF053, 0x70BD); /* All protection(2) */
|
||||
dw9781_cci_read(io_master_info, 0xA7F9, &fw_flag); /* check checksum flag */
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_ois_ready_check] checksum flag : 0x%04x", fw_flag);
|
||||
if(fw_flag == 0xCC33)
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_ois_ready_check] checksum flag is ok");
|
||||
dw9781_ois_reset(io_master_info); /* ois reset */
|
||||
} else {
|
||||
dw9781_cci_write(io_master_info, 0xD002, 0x0001); /* dw9781c reset */
|
||||
dw9781_delay_ms(4);
|
||||
CAM_ERR(CAM_OIS, "[dw9781c_ois_ready_check] previous firmware download fail");
|
||||
}
|
||||
}
|
||||
|
||||
void dw9781_all_protection_release(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_all_protection_release] execution");
|
||||
/* release all protection */
|
||||
dw9781_cci_write(io_master_info, 0xFAFA, 0x98AC);
|
||||
dw9781_delay_ms(1);
|
||||
dw9781_cci_write(io_master_info, 0xF053, 0x70BD);
|
||||
dw9781_delay_ms(1);
|
||||
}
|
||||
|
||||
static uint16_t dw9781_fw_checksum_verify(struct camera_io_master * io_master_info)
|
||||
{
|
||||
uint16_t data;
|
||||
|
||||
/* FW checksum command */
|
||||
dw9781_cci_write(io_master_info, 0x7011, 0x2000);
|
||||
/* command start */
|
||||
dw9781_cci_write(io_master_info, 0x7010, 0x8000);
|
||||
dw9781_delay_ms(10);
|
||||
/* calc the checksum to write the 0x7005 */
|
||||
dw9781_cci_read(io_master_info, 0x7005, &data);
|
||||
CAM_DBG(CAM_OIS, "F/W Checksum calculated value : 0x%04X", data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int dw9781_erase_mtp_rewritefw(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "dw9781c erase for rewritefw starting..");
|
||||
|
||||
/* 512 byte page */
|
||||
dw9781_cci_write(io_master_info, 0xde03, 0x0027);
|
||||
/* page erase */
|
||||
dw9781_cci_write(io_master_info, 0xde04, 0x0008);
|
||||
dw9781_delay_ms(10);
|
||||
|
||||
CAM_DBG(CAM_OIS, "dw9781c checksum flag erase : 0xCC33");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dw9781_erase_mtp(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_erase_mtp] start erasing firmware flash");
|
||||
/* 12c level adjust */
|
||||
dw9781_cci_write(io_master_info, 0xd005, 0x0001);
|
||||
dw9781_cci_write(io_master_info, 0xdd03, 0x0002);
|
||||
dw9781_cci_write(io_master_info, 0xdd04, 0x0002);
|
||||
|
||||
/* 4k Sector_0 Erase*/
|
||||
dw9781_cci_write(io_master_info, 0xde03, 0x0000);
|
||||
dw9781_cci_write(io_master_info, 0xde04, 0x0002);
|
||||
dw9781_delay_ms(10);
|
||||
/* 4k Sector_1 Erase*/
|
||||
dw9781_cci_write(io_master_info, 0xde03, 0x0008);
|
||||
dw9781_cci_write(io_master_info, 0xde04, 0x0002);
|
||||
dw9781_delay_ms(10);
|
||||
/* 4k Sector_2 Erase*/
|
||||
dw9781_cci_write(io_master_info, 0xde03, 0x0010);
|
||||
dw9781_cci_write(io_master_info, 0xde04, 0x0002);
|
||||
dw9781_delay_ms(10);
|
||||
/* 4k Sector_3 Erase*/
|
||||
dw9781_cci_write(io_master_info, 0xde03, 0x0018);
|
||||
dw9781_cci_write(io_master_info, 0xde04, 0x0002);
|
||||
dw9781_delay_ms(10);
|
||||
/* 4k Sector_4 Erase*/
|
||||
dw9781_cci_write(io_master_info, 0xde03, 0x0020);
|
||||
dw9781_cci_write(io_master_info, 0xde04, 0x0002);
|
||||
dw9781_delay_ms(10);
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_erase_mtp] complete erasing firmware flash");
|
||||
}
|
||||
|
||||
static int dw9781_prepare_fw_download(struct camera_io_master * io_master_info)
|
||||
{
|
||||
/* step 1: MTP Erase and DSP Disable for firmware 0x8000 write */
|
||||
/* step 2: MTP setup */
|
||||
/* step 3: firmware sequential write to flash */
|
||||
/* step 4: firmware sequential read from flash */
|
||||
/* step 5: firmware verify */
|
||||
dw9781_cci_write(io_master_info, 0xd001, 0x0000);
|
||||
dw9781_all_protection_release(io_master_info);
|
||||
dw9781_erase_mtp(io_master_info);
|
||||
CAM_DBG(CAM_OIS, "[dw9781c_download_fw] start firmware download");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize)
|
||||
{
|
||||
uint8_t ret;
|
||||
uint8_t needDownload = 0;
|
||||
uint16_t fwchecksum = 0;
|
||||
uint16_t first_chip_id = 0;
|
||||
uint16_t chip_checksum = 0;
|
||||
uint16_t second_chip_id = 0;
|
||||
uint16_t fw_version_current = 0;
|
||||
uint16_t fw_version_latest = 0;
|
||||
|
||||
if (io_master_info == NULL) {
|
||||
printk("FATAL: OIS CCI context error!!!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fwData == NULL || fwSize < FW_VERSION_OFFSET*sizeof(uint16_t)) {
|
||||
printk("FATAL: firmware buffer(%p) is NULL or size(%d) abnormal!!!", fwData, fwSize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_dw9781FirmwareContext.driverIc = 0x9781;
|
||||
g_dw9781FirmwareContext.fwContentPtr = (const uint16_t *)fwData;
|
||||
g_dw9781FirmwareContext.size = fwSize;
|
||||
g_dw9781FirmwareContext.version = *(g_dw9781FirmwareContext.fwContentPtr+FW_VERSION_OFFSET);
|
||||
g_dw9781FirmwareContext.version = ((g_dw9781FirmwareContext.version << 8) & 0xff00) |
|
||||
((g_dw9781FirmwareContext.version >> 8) & 0xff);
|
||||
g_dw9781FirmwareContext.checksum = *(g_dw9781FirmwareContext.fwContentPtr+FW_CHECKSUM_OFFSET);
|
||||
g_dw9781FirmwareContext.checksum = ((g_dw9781FirmwareContext.checksum << 8) & 0xff00) |
|
||||
((g_dw9781FirmwareContext.checksum >> 8) & 0xff);
|
||||
|
||||
dw9781_ois_ready_check(io_master_info);
|
||||
|
||||
dw9781_cci_read(io_master_info, DW9781C_CHIP_ID_ADDRESS, &first_chip_id);
|
||||
dw9781_cci_read(io_master_info, 0x7001, &chip_checksum);
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] FW_VER_PHONE_MAKER : 0x%x", chip_checksum);
|
||||
dw9781_cci_read(io_master_info, 0x7002, &chip_checksum);
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] FW_DATE_PHONE_MAKER : 0x%x", chip_checksum);
|
||||
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] first_chip_id : 0x%x", first_chip_id);
|
||||
if (first_chip_id != DW9781C_CHIP_ID) { /* first_chip_id verification failed */
|
||||
dw9781_all_protection_release(io_master_info);
|
||||
dw9781_cci_read(io_master_info, 0xd060, &second_chip_id); /* second_chip_id: 0x0020 */
|
||||
if ( second_chip_id == 0x0020 ) /* Check the second_chip_id*/
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] start flash download:: size:%d, version:0x%x",
|
||||
g_dw9781FirmwareContext.size, g_dw9781FirmwareContext.version);
|
||||
needDownload = 1;
|
||||
ret = dw9781_prepare_fw_download(io_master_info); /* Need to forced update OIS firmware again. */
|
||||
} else {
|
||||
dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shutdown mode */
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] second_chip_id check fail");
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode");
|
||||
return needDownload;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
dw9781_cci_read(io_master_info, FW_VER_CURR_ADDR, &fw_version_current);
|
||||
fw_version_latest = g_dw9781FirmwareContext.version; /*Firmware version read from file content.*/
|
||||
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] fw_version_current = 0x%x, fw_version_latest = 0x%x",
|
||||
fw_version_current, fw_version_latest);
|
||||
|
||||
/* download firmware, check if need update, download firmware to flash */
|
||||
if (((fw_version_current & 0xFF) != (fw_version_latest & 0xFF))) {
|
||||
|
||||
fwchecksum = dw9781_fw_checksum_verify(io_master_info);
|
||||
if(fwchecksum != g_dw9781FirmwareContext.checksum)
|
||||
{
|
||||
needDownload = 1;
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] firmware checksum error 0x%04X, 0x%04X",
|
||||
g_dw9781FirmwareContext.checksum, fwchecksum);
|
||||
}
|
||||
|
||||
if (needDownload)
|
||||
{
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] start flash download:: size:%d, version:0x%x needDownload %d",
|
||||
g_dw9781FirmwareContext.size, g_dw9781FirmwareContext.version, needDownload);
|
||||
|
||||
ret = dw9781_prepare_fw_download(io_master_info);
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] flash download::vendor_dw9781c");
|
||||
if (ret != EOK) {
|
||||
dw9781_erase_mtp_rewritefw(io_master_info);
|
||||
dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shut download mode */
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] firmware download error, ret = 0x%x", ret);
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode");
|
||||
needDownload = 1;
|
||||
}
|
||||
} else {
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] ois firmware version is updated, skip download");
|
||||
}
|
||||
} else {
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] ois firmware version is updated, skip download");
|
||||
}
|
||||
}
|
||||
return needDownload;
|
||||
}
|
||||
EXPORT_SYMBOL(dw9781c_check_fw_download);
|
||||
|
||||
void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize)
|
||||
{
|
||||
uint16_t fwchecksum = 0;
|
||||
|
||||
g_dw9781FirmwareContext.checksum = *(g_dw9781FirmwareContext.fwContentPtr+FW_CHECKSUM_OFFSET);
|
||||
g_dw9781FirmwareContext.checksum = ((g_dw9781FirmwareContext.checksum << 8) & 0xff00) |
|
||||
((g_dw9781FirmwareContext.checksum >> 8) & 0xff);
|
||||
|
||||
dw9781_ois_ready_check(io_master_info);
|
||||
|
||||
fwchecksum = dw9781_fw_checksum_verify(io_master_info);
|
||||
if(fwchecksum != g_dw9781FirmwareContext.checksum)
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] firmware checksum error 0x%04X, 0x%04X", g_dw9781FirmwareContext.checksum, fwchecksum);
|
||||
dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shutdown mode */
|
||||
dw9781_delay_ms(100);
|
||||
dw9781_cci_write(io_master_info, 0xd000, 0x0001); /* Standby mode */
|
||||
dw9781_delay_ms(100);
|
||||
dw9781_all_protection_release(io_master_info); /* Disable write protect */
|
||||
dw9781_erase_mtp_rewritefw(io_master_info);
|
||||
dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shutdown mode */
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] firmware download error");
|
||||
CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode");
|
||||
} else {
|
||||
CAM_DBG(CAM_OIS, "[dw9781c] Firmware download succes...");
|
||||
dw9781_ois_reset(io_master_info);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dw9781_post_firmware_download);
|
||||
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 <linux/module.h>
|
||||
#include "cam_ois_core.h"
|
||||
#include "cam_ois_soc.h"
|
||||
#include "cam_sensor_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_common_util.h"
|
||||
|
||||
#define DW9784_CHIP_ID_ADDRESS 0x7000
|
||||
#define DW9784_CHECKSUM_ADDRESS 0x700C
|
||||
#define DW9784_CHIP_ID 0x9784
|
||||
#define FW_VER_CURR_ADDR 0x7001
|
||||
|
||||
#define EOK 0
|
||||
|
||||
#define FW_VERSION_OFFSET 10493
|
||||
#define FW_CHECKSUM_OFFSET 10495
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int driverIc;
|
||||
unsigned int size;
|
||||
const uint16_t *fwContentPtr;
|
||||
uint16_t version;
|
||||
uint16_t checksum;
|
||||
} FirmwareContex;
|
||||
|
||||
static FirmwareContex g_dw9784FirmwareContext;
|
||||
|
||||
static int32_t dw9784_cci_write(struct camera_io_master * io_master_info, uint16_t reg, uint16_t val)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
struct cam_sensor_i2c_reg_array reg_setting;
|
||||
struct cam_sensor_i2c_reg_setting wr_setting;
|
||||
|
||||
reg_setting.reg_addr = reg;
|
||||
reg_setting.reg_data = val;
|
||||
reg_setting.delay = 0;
|
||||
reg_setting.data_mask = 0;
|
||||
wr_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD;
|
||||
wr_setting.data_type = CAMERA_SENSOR_I2C_TYPE_WORD;
|
||||
wr_setting.reg_setting = ®_setting;
|
||||
wr_setting.size = 1;
|
||||
wr_setting.delay = 0;
|
||||
rc = camera_io_dev_write(io_master_info, &wr_setting);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t dw9784_cci_read(struct camera_io_master * io_master_info, uint16_t reg, uint16_t *val)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
uint32_t regVal = 0;
|
||||
rc = camera_io_dev_read(io_master_info, reg, ®Val, CAMERA_SENSOR_I2C_TYPE_WORD, CAMERA_SENSOR_I2C_TYPE_WORD);
|
||||
if (!rc) {
|
||||
*val = (uint16_t)regVal;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void dw9784_delay_ms(uint32_t ms)
|
||||
{
|
||||
usleep_range(ms*1000, ms*1000+10);
|
||||
return;
|
||||
}
|
||||
|
||||
void dw9784_ois_reset(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_ois_reset] ois reset");
|
||||
dw9784_cci_write(io_master_info, 0xD002, 0x0001); /* DW9784_DBGc reset */
|
||||
dw9784_delay_ms(4);
|
||||
dw9784_cci_write(io_master_info, 0xD001, 0x0001); /* Active mode (DSP ON) */
|
||||
dw9784_delay_ms(25); /* ST gyro - over wait 25ms, default Servo On */
|
||||
dw9784_cci_write(io_master_info, 0xEBF1, 0x56FA); /* User protection release */
|
||||
}
|
||||
|
||||
void dw9784_code_pt_off(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_code_pt_off] start");
|
||||
/* release all protection */
|
||||
dw9784_cci_write(io_master_info, 0xFD00, 0x5252);
|
||||
dw9784_delay_ms(1);
|
||||
CAM_INFO(CAM_OIS, "[dw9784_code_pt_off] finish");
|
||||
}
|
||||
|
||||
void dw9784_pid_erase(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_pid_erase] start pid flash(IF) erase");
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0000); // page 0
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0008); // page erase
|
||||
dw9784_delay_ms(10); // need to delay after erase
|
||||
CAM_INFO(CAM_OIS, "[dw9784_pid_erase] finish");
|
||||
}
|
||||
|
||||
void dw9784_fw_eflash_erase(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_fw_eflash_erase] start fw flash erase");
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0000); // 4k Sector_0
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase
|
||||
dw9784_delay_ms(10); // need to delay after erase
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0008); // 4k Sector_1
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase
|
||||
dw9784_delay_ms(10); // need to delay after erase
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0010); // 4k Sector_2
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase
|
||||
dw9784_delay_ms(10); // need to delay after erase
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0018); // 4k Sector_3
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase
|
||||
dw9784_delay_ms(10); // need to delay after erase
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0020); // 4k Sector_4
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase
|
||||
dw9784_delay_ms(10); // need to delay after erase
|
||||
CAM_INFO(CAM_OIS, "[dw9784_fw_eflash_erase] finish");
|
||||
}
|
||||
|
||||
void dw9784_flash_acess(struct camera_io_master * io_master_info)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_flash_acess] execution");
|
||||
/* release all protection */
|
||||
dw9784_cci_write(io_master_info, 0xFAFA, 0x98AC);
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_write(io_master_info, 0xF053, 0x70BD);
|
||||
dw9784_delay_ms(1);
|
||||
}
|
||||
|
||||
int dw9784_whoami_chk(struct camera_io_master * io_master_info)
|
||||
{
|
||||
uint16_t sec_chip_id;
|
||||
dw9784_cci_write(io_master_info, 0xD000, 0x0001); /* chip enable */
|
||||
dw9784_delay_ms(4);
|
||||
dw9784_cci_write(io_master_info, 0xD001, 0x0000); /* dsp off mode */
|
||||
dw9784_delay_ms(1);
|
||||
|
||||
dw9784_flash_acess(io_master_info); /* All protection */
|
||||
|
||||
dw9784_cci_read(io_master_info, 0xD060, &sec_chip_id); /* 2nd chip id */
|
||||
CAM_INFO(CAM_OIS, "[dw9784_ois_ready_check] sec_chip_id : 0x%04x", sec_chip_id);
|
||||
if(sec_chip_id != 0x0020)
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9784] second_chip_id check fail : 0x%04X", sec_chip_id);
|
||||
CAM_ERR(CAM_OIS, "[dw9784] second_enter shutdown mode");
|
||||
dw9784_cci_write(io_master_info, 0xD000, 0x0000); /* ic */
|
||||
return -1;
|
||||
}
|
||||
|
||||
dw9784_ois_reset(io_master_info); /* ois reset */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dw9784_checksum_fw_chk(struct camera_io_master * io_master_info)
|
||||
{
|
||||
/*
|
||||
Bit [0]: FW checksum error
|
||||
Bit [1]: Module cal. checksum error
|
||||
Bit [2]: Set cal. checksum error
|
||||
*/
|
||||
uint16_t reg_fw_checksum; // 0x700C
|
||||
uint16_t reg_checksum_status; // 0x700D
|
||||
|
||||
dw9784_cci_read(io_master_info, 0x700C, ®_fw_checksum);
|
||||
dw9784_cci_read(io_master_info, 0x700D, ®_checksum_status);
|
||||
|
||||
CAM_INFO(CAM_OIS, "[dw9784_checksum_fw_chk] reg_checksum_status : 0x%04X", reg_checksum_status);
|
||||
CAM_INFO(CAM_OIS, "[dw9784_checksum_fw_chk] reg_fw_checksum : 0x%04X", reg_fw_checksum);
|
||||
|
||||
if( (reg_checksum_status & 0x0001) == 0)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_checksum_fw_chk] fw checksum pass");
|
||||
return 0;
|
||||
}else
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9784_checksum_fw_chk] fw checksum error reg_fw_checksum : 0x%04X", reg_fw_checksum);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int dw9784_erase_mtp_rewritefw(struct camera_io_master * io_master_info)
|
||||
{
|
||||
uint16_t FMC;
|
||||
CAM_INFO(CAM_OIS, "dw9784 erase for rewritefw starting..");
|
||||
dw9784_cci_write(io_master_info, 0xd001, 0x0000);
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_flash_acess(io_master_info);
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xDE01, 0x0000); // FMC block FW select
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_read(io_master_info, 0xDE01, &FMC);
|
||||
if (FMC != 0)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_download_fw] FMC register value 1st warning : %04x", FMC);
|
||||
dw9784_cci_write(io_master_info, 0xDE01, 0x0000);
|
||||
dw9784_delay_ms(1);
|
||||
FMC = 0; // initialize FMC value
|
||||
|
||||
dw9784_cci_read(io_master_info, 0xDE01, &FMC);
|
||||
if (FMC != 0)
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9784_download_fw] 2nd FMC register value 2nd warning : %04x", FMC);
|
||||
CAM_ERR(CAM_OIS, "[dw9784_download_fw] stop f/w download");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* code protection off */
|
||||
dw9784_code_pt_off(io_master_info);
|
||||
|
||||
/* 512 byte page */
|
||||
dw9784_cci_write(io_master_info, 0xde03, 0x0027);
|
||||
/* page erase */
|
||||
dw9784_cci_write(io_master_info, 0xde04, 0x0008);
|
||||
dw9784_delay_ms(10);
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xd000, 0x0000); /* Shut download mode */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw9784_prepare_fw_download(struct camera_io_master * io_master_info)
|
||||
{
|
||||
/* step 1: MTP Erase and DSP Disable for firmware 0x8000 write */
|
||||
/* step 2: MTP setup */
|
||||
/* step 3. FMC register check */
|
||||
/* step 4. code protection off */
|
||||
/* step 5. erase flash fw data */
|
||||
uint16_t FMC;
|
||||
dw9784_cci_write(io_master_info, 0xd001, 0x0000);
|
||||
dw9784_flash_acess(io_master_info);
|
||||
|
||||
dw9784_cci_write(io_master_info, 0xDE01, 0x0000); // FMC block FW select
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_read(io_master_info, 0xDE01, &FMC);
|
||||
if (FMC != 0)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_download_fw] FMC register value 1st warning : %04x", FMC);
|
||||
dw9784_cci_write(io_master_info, 0xDE01, 0x0000);
|
||||
dw9784_delay_ms(1);
|
||||
FMC = 0; // initialize FMC value
|
||||
|
||||
dw9784_cci_read(io_master_info, 0xDE01, &FMC);
|
||||
if (FMC != 0)
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9784_download_fw] 2nd FMC register value 2nd warning : %04x", FMC);
|
||||
CAM_ERR(CAM_OIS, "[dw9784_download_fw] stop f/w download");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
dw9784_code_pt_off(io_master_info);
|
||||
dw9784_fw_eflash_erase(io_master_info);
|
||||
CAM_INFO(CAM_OIS, "[dw9784_download_fw] start firmware download");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dw9784_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize)
|
||||
{
|
||||
uint8_t ret;
|
||||
uint8_t needDownload = 0;
|
||||
uint16_t fwchecksum = 0;
|
||||
uint16_t first_chip_id = 0;
|
||||
uint16_t chip_checksum = 0;
|
||||
uint16_t fw_version_current = 0;
|
||||
uint16_t fw_version_latest = 0;
|
||||
|
||||
if (io_master_info == NULL) {
|
||||
CAM_ERR(CAM_OIS, "FATAL: OIS CCI context error!!!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fwData == NULL || fwSize < FW_VERSION_OFFSET*sizeof(uint16_t)) {
|
||||
CAM_ERR(CAM_OIS, "FATAL: firmware buffer(%p) is NULL or size(%d) abnormal!!!", fwData, fwSize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_dw9784FirmwareContext.driverIc = 0x9784;
|
||||
g_dw9784FirmwareContext.fwContentPtr = (const uint16_t *)fwData;
|
||||
g_dw9784FirmwareContext.size = fwSize;
|
||||
g_dw9784FirmwareContext.version = *(g_dw9784FirmwareContext.fwContentPtr+FW_VERSION_OFFSET);
|
||||
g_dw9784FirmwareContext.version = ((g_dw9784FirmwareContext.version << 8) & 0xff00) |
|
||||
((g_dw9784FirmwareContext.version >> 8) & 0xff);
|
||||
g_dw9784FirmwareContext.checksum = *(g_dw9784FirmwareContext.fwContentPtr+FW_CHECKSUM_OFFSET);
|
||||
g_dw9784FirmwareContext.checksum = ((g_dw9784FirmwareContext.checksum << 8) & 0xff00) |
|
||||
((g_dw9784FirmwareContext.checksum >> 8) & 0xff);
|
||||
if (dw9784_whoami_chk(io_master_info) != 0) {
|
||||
CAM_ERR(CAM_OIS, "[dw9784] second chip id check fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dw9784_cci_read(io_master_info, DW9784_CHIP_ID_ADDRESS, &first_chip_id);
|
||||
dw9784_cci_read(io_master_info, 0x7001, &chip_checksum);
|
||||
CAM_INFO(CAM_OIS, "[dw9784] FW_VER_PHONE_MAKER : 0x%x", chip_checksum);
|
||||
dw9784_cci_read(io_master_info, 0x7002, &chip_checksum);
|
||||
CAM_INFO(CAM_OIS, "[dw9784] FW_DATE_PHONE_MAKER : 0x%x", chip_checksum);
|
||||
|
||||
CAM_INFO(CAM_OIS, "[dw9784] first_chip_id : 0x%x", first_chip_id);
|
||||
if (first_chip_id != DW9784_CHIP_ID) { /* first_chip_id verification failed */
|
||||
CAM_INFO(CAM_OIS, "[dw9784] start flash download:: size:%d, version:0x%x",
|
||||
g_dw9784FirmwareContext.size, g_dw9784FirmwareContext.version);
|
||||
needDownload = 1;
|
||||
ret = dw9784_prepare_fw_download(io_master_info); /* Need to forced update OIS firmware again. */
|
||||
} else {
|
||||
fwchecksum = dw9784_checksum_fw_chk(io_master_info);
|
||||
if(fwchecksum != 0)
|
||||
{
|
||||
needDownload = 1;
|
||||
CAM_INFO(CAM_OIS, "[dw9784] firmware checksum error");
|
||||
}
|
||||
|
||||
dw9784_cci_read(io_master_info, FW_VER_CURR_ADDR, &fw_version_current);
|
||||
fw_version_latest = g_dw9784FirmwareContext.version; /*Firmware version read from file content.*/
|
||||
|
||||
CAM_INFO(CAM_OIS, "[dw9784] fw_version_current = 0x%x, fw_version_latest = 0x%x",
|
||||
fw_version_current, fw_version_latest);
|
||||
|
||||
/* download firmware, check if need update, download firmware to flash */
|
||||
if (needDownload || ((fw_version_current & 0xFFFF) != (fw_version_latest & 0xFFFF))) {
|
||||
needDownload = 1;
|
||||
|
||||
CAM_INFO(CAM_OIS, "[dw9784] start flash download:: size:%d, version:0x%x needDownload %d",
|
||||
g_dw9784FirmwareContext.size, g_dw9784FirmwareContext.version, needDownload);
|
||||
|
||||
ret = dw9784_prepare_fw_download(io_master_info);
|
||||
CAM_INFO(CAM_OIS, "[dw9784] flash download::vendor_dw9784");
|
||||
if (ret != EOK) {
|
||||
dw9784_erase_mtp_rewritefw(io_master_info);
|
||||
CAM_ERR(CAM_OIS, "[dw9784] firmware download error, ret = 0x%x", ret);
|
||||
CAM_ERR(CAM_OIS, "[dw9784] change dw9784 state to shutdown mode");
|
||||
needDownload = 1;
|
||||
}
|
||||
} else {
|
||||
CAM_INFO(CAM_OIS, "[dw9784] ois firmware version is updated, skip download");
|
||||
}
|
||||
}
|
||||
return needDownload;
|
||||
}
|
||||
EXPORT_SYMBOL(dw9784_check_fw_download);
|
||||
|
||||
int dw9784_check_if_download(struct camera_io_master * io_master_info)
|
||||
{
|
||||
uint16_t FMC;
|
||||
|
||||
/* step 1. Writes 512Byte FW(PID) data to IF flash. (FMC register check) */
|
||||
dw9784_cci_write(io_master_info, 0xDE01, 0x1000);
|
||||
dw9784_delay_ms(1);
|
||||
dw9784_cci_read(io_master_info,0xDE01, &FMC);
|
||||
dw9784_delay_ms(1);
|
||||
if (FMC != 0x1000)
|
||||
{
|
||||
CAM_INFO(CAM_OIS, "[dw9784_download_fw] IF FMC register value 1st warning : %04x", FMC);
|
||||
dw9784_cci_write(io_master_info, 0xDE01, 0x1000);
|
||||
dw9784_delay_ms(1);
|
||||
FMC = 0; // initialize FMC value
|
||||
|
||||
dw9784_cci_read(io_master_info,0xDE01, &FMC);
|
||||
if (FMC != 0x1000)
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9784_download_fw] 2nd IF FMC register value 2nd fail : %04x", FMC);
|
||||
CAM_ERR(CAM_OIS, "[dw9784_download_fw] stop firmware download");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* step 2. erease IF(FW/PID) eFLASH */
|
||||
dw9784_pid_erase(io_master_info);
|
||||
|
||||
CAM_INFO(CAM_OIS, "[dw9784_download_fw] start firmware/pid download");
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dw9784_check_if_download);
|
||||
|
||||
void dw9784_post_firmware_download(struct camera_io_master * io_master_info)
|
||||
{
|
||||
uint16_t fwchecksum = 0;
|
||||
|
||||
dw9784_ois_reset(io_master_info);
|
||||
fwchecksum = dw9784_checksum_fw_chk(io_master_info);
|
||||
if(fwchecksum != 0)
|
||||
{
|
||||
CAM_ERR(CAM_OIS, "[dw9784] firmware checksum error");
|
||||
dw9784_erase_mtp_rewritefw(io_master_info);
|
||||
CAM_ERR(CAM_OIS, "[dw9784] change dw9784 state to shutdown mode");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dw9784_post_firmware_download);
|
||||
|
|
@ -34,6 +34,25 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl)
|
|||
o_ctrl->ois_device_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!of_property_read_bool(of_node, "vsync-irq-support")) {
|
||||
o_ctrl->is_ois_vsync_irq_supported = false;
|
||||
} else {
|
||||
o_ctrl->is_ois_vsync_irq_supported = true;
|
||||
}
|
||||
|
||||
rc = of_property_read_string(of_node, "ois-name", &o_ctrl->ic_name);
|
||||
if (rc) {
|
||||
CAM_DBG(CAM_OIS, "ois-name is not available in the node: %d", rc);
|
||||
o_ctrl->ic_name = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAMERA_DISABLE_VSYNC_IRQ
|
||||
o_ctrl->is_ois_vsync_irq_supported = false;
|
||||
CAM_WARN(CAM_OIS, "disable ois vsync irq in factory build");
|
||||
#endif
|
||||
CAM_DBG(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported);
|
||||
|
||||
rc = cam_soc_util_get_dt_properties(soc_info);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_OIS, "cam_soc_util_get_dt_properties rc %d",
|
||||
|
|
|
|||
|
|
@ -459,6 +459,7 @@ int cam_res_mgr_gpio_request(struct device *dev, uint gpio,
|
|||
* from the gpio_res_list
|
||||
* These two situations both need request gpio.
|
||||
*/
|
||||
CAM_DBG(CAM_RES, "shared gpio enable is %d shared gpio num is %d", cam_res->shared_gpio_enabled, cam_res->dt.num_shared_gpio);
|
||||
if (!gpio_found) {
|
||||
CAM_DBG(CAM_RES, "gpio: %u not found in gpio_res list", gpio);
|
||||
rc = gpio_request_one(gpio, flags, label);
|
||||
|
|
@ -572,7 +573,7 @@ bool cam_res_mgr_util_check_if_gpio_is_shared(
|
|||
}
|
||||
EXPORT_SYMBOL(cam_res_mgr_util_check_if_gpio_is_shared);
|
||||
|
||||
static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
|
||||
void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
|
||||
{
|
||||
bool gpio_found = false;
|
||||
bool need_free = true;
|
||||
|
|
@ -647,6 +648,7 @@ static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
|
|||
|
||||
mutex_unlock(&cam_res->gpio_res_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(cam_res_mgr_gpio_free);
|
||||
|
||||
void cam_res_mgr_gpio_free_arry(struct device *dev,
|
||||
const struct gpio *array, size_t num)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,18 @@ bool cam_res_mgr_util_check_if_gpio_is_shared(
|
|||
int cam_res_mgr_gpio_request(struct device *dev, unsigned int gpio,
|
||||
unsigned long flags, const char *label);
|
||||
|
||||
/**
|
||||
* @brief: Free a GPIO
|
||||
*
|
||||
* Free the GPIO and release corresponding gpio_res.
|
||||
*
|
||||
* @dev : Pointer to the device
|
||||
* @gpio : A GPIO number
|
||||
*
|
||||
* @return Status of operation. Negative in case of error. Zero otherwise.
|
||||
*/
|
||||
void cam_res_mgr_gpio_free(struct device *dev, uint gpio);
|
||||
|
||||
/**
|
||||
* @brief: Free a array GPIO
|
||||
*
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|||
csl_packet = (struct cam_packet *)(generic_ptr +
|
||||
(uint32_t)config.offset);
|
||||
|
||||
if (cam_packet_util_validate_packet(csl_packet,
|
||||
if ((csl_packet == NULL) || cam_packet_util_validate_packet(csl_packet,
|
||||
remain_len)) {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid packet params");
|
||||
rc = -EINVAL;
|
||||
|
|
@ -446,15 +446,90 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info,
|
|||
|
||||
s_ctrl->sensor_probe_addr_type = probe_info->addr_type;
|
||||
s_ctrl->sensor_probe_data_type = probe_info->data_type;
|
||||
|
||||
s_ctrl->probe_sub_device = probe_info->probe_sub_device;
|
||||
s_ctrl->sub_device_addr = probe_info->sub_device_addr;
|
||||
s_ctrl->sub_device_data_type = probe_info->sub_device_data_type;
|
||||
s_ctrl->sub_device_addr_type = probe_info->sub_device_addr_type;
|
||||
s_ctrl->sub_device_id_addr = probe_info->sub_device_id_addr;
|
||||
s_ctrl->expected_sub_device_id = probe_info->expected_sub_device_id;
|
||||
s_ctrl->sub_device_cci_master = probe_info->sub_device_cci_master;
|
||||
s_ctrl->sub_device_cci_device = probe_info->sub_device_cci_device;
|
||||
s_ctrl->sub_device_i2c_freq_mode = probe_info->sub_device_i2c_freq_mode;
|
||||
#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH
|
||||
s_ctrl->i2c_addr_switch = probe_info->i2c_addr_switch;
|
||||
s_ctrl->second_i2c_address = probe_info->second_i2c_address;
|
||||
s_ctrl->i2c_switch_reg_addr_Type = probe_info->i2c_switch_reg_addr_Type;
|
||||
s_ctrl->i2c_switch_reg_data_Type = probe_info->i2c_switch_reg_data_Type;
|
||||
s_ctrl->i2c_switch_reg_addr = probe_info->i2c_switch_reg_addr;
|
||||
s_ctrl->i2c_switch_reg_data = probe_info->i2c_switch_reg_data;
|
||||
s_ctrl->i2c_switch_reg_delayMs = probe_info->i2c_switch_reg_delayMs;
|
||||
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x",
|
||||
"Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x i2c_addr_switch: 0x%x second_i2c_address: 0x%x i2c_switch_reg_addr: 0x%x",
|
||||
s_ctrl->sensordata->slave_info.sensor_id_reg_addr,
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_id_mask,
|
||||
s_ctrl->pipeline_delay);
|
||||
s_ctrl->pipeline_delay,
|
||||
s_ctrl->i2c_addr_switch ,
|
||||
s_ctrl->second_i2c_address ,
|
||||
s_ctrl->i2c_switch_reg_addr);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH
|
||||
int cam_sensor_set_i2c_addr_switch_reg(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
uint16_t sensor_address = 0;
|
||||
struct cam_sensor_i2c_reg_setting wr_setting;
|
||||
struct cam_sensor_i2c_reg_array reg_setting;
|
||||
|
||||
/* if hal doesn't config i2c_addr_switch parameter in sensor xml, return success immediately */
|
||||
if (!s_ctrl->i2c_addr_switch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* save sensor i2c address */
|
||||
sensor_address = s_ctrl->io_master_info.cci_client->sid;
|
||||
|
||||
/* set sub-device i2c address */
|
||||
if (s_ctrl->second_i2c_address) {
|
||||
s_ctrl->io_master_info.cci_client->sid = s_ctrl->second_i2c_address >> 1;
|
||||
}
|
||||
|
||||
reg_setting.reg_addr = s_ctrl->i2c_switch_reg_addr;
|
||||
reg_setting.reg_data = s_ctrl->i2c_switch_reg_data;
|
||||
reg_setting.delay = s_ctrl->i2c_switch_reg_delayMs; /* delay after switch iic addr */
|
||||
reg_setting.data_mask = 0;
|
||||
wr_setting.addr_type = s_ctrl->i2c_switch_reg_addr_Type;
|
||||
wr_setting.data_type = s_ctrl->i2c_switch_reg_data_Type;
|
||||
wr_setting.reg_setting = ®_setting;
|
||||
wr_setting.size = 1;
|
||||
wr_setting.delay = 0;
|
||||
rc = camera_io_dev_write(&s_ctrl->io_master_info, &wr_setting);
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"cam_sensor_set_i2c_addr_switch_reg slot:%d, slave_addr:0x%x, sensor_id:0x%x, sensor_address:0x%x",
|
||||
s_ctrl->soc_info.index,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr,
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
sensor_address);
|
||||
/* restore sensor i2c address */
|
||||
s_ctrl->io_master_info.cci_client->sid = sensor_address;
|
||||
|
||||
if (rc == 0) {
|
||||
CAM_ERR(CAM_SENSOR, "write i2c addr switch reg success");
|
||||
}
|
||||
else {
|
||||
CAM_ERR(CAM_SENSOR, "write i2c addr switch reg fail");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf,
|
||||
struct cam_sensor_ctrl_t *s_ctrl,
|
||||
int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len)
|
||||
|
|
@ -685,6 +760,10 @@ void cam_sensor_shutdown(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
#ifdef CONFIG_CAM_SENSOR_PROBE_RETRY
|
||||
int retries = 5;
|
||||
bool matched = false;
|
||||
#endif
|
||||
uint32_t chipid = 0;
|
||||
struct cam_camera_slave_info *slave_info;
|
||||
|
||||
|
|
@ -696,6 +775,28 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAM_SENSOR_PROBE_RETRY
|
||||
while (retries-- && !matched) {
|
||||
rc = camera_io_dev_read(
|
||||
&(s_ctrl->io_master_info),
|
||||
slave_info->sensor_id_reg_addr,
|
||||
&chipid,
|
||||
s_ctrl->sensor_probe_addr_type,
|
||||
s_ctrl->sensor_probe_data_type);
|
||||
|
||||
CAM_INFO(CAM_SENSOR, "read id: 0x%x expected id 0x%x:",
|
||||
chipid, slave_info->sensor_id);
|
||||
|
||||
if (cam_sensor_id_by_mask(s_ctrl, chipid) == slave_info->sensor_id)
|
||||
matched = true;
|
||||
|
||||
if (!matched && !retries) {
|
||||
CAM_ERR(CAM_SENSOR, "Failed read id: 0x%x expected id 0x%x:",
|
||||
chipid, slave_info->sensor_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
#else
|
||||
rc = camera_io_dev_read(
|
||||
&(s_ctrl->io_master_info),
|
||||
slave_info->sensor_id_reg_addr,
|
||||
|
|
@ -711,6 +812,114 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
chipid, slave_info->sensor_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
int ret = 0;
|
||||
uint32_t sub_device_id = 0;
|
||||
uint16_t sensor_address = 0;
|
||||
uint16_t sensor_freq_mode = 0;
|
||||
uint8_t sensor_cci_master = 0;
|
||||
uint8_t sensor_cci_device = 0;
|
||||
|
||||
/* if hal doesn't config ProbeSubDevice parameter in sensor xml, return success immediately */
|
||||
if (!s_ctrl->probe_sub_device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* save sensor i2c address */
|
||||
sensor_address = s_ctrl->io_master_info.cci_client->sid;
|
||||
|
||||
/* set sub-device i2c address */
|
||||
if (s_ctrl->sub_device_addr) {
|
||||
s_ctrl->io_master_info.cci_client->sid = s_ctrl->sub_device_addr >> 1;
|
||||
}
|
||||
|
||||
/*if need change cci master*/
|
||||
if (s_ctrl->need_change_cci_master) {
|
||||
sensor_cci_master = s_ctrl->io_master_info.cci_client->cci_i2c_master;
|
||||
sensor_freq_mode = s_ctrl->io_master_info.cci_client->i2c_freq_mode;
|
||||
sensor_cci_device = s_ctrl->io_master_info.cci_client->cci_device;
|
||||
|
||||
ret = camera_io_release(&(s_ctrl->io_master_info));
|
||||
if (ret != 0) {
|
||||
CAM_ERR(CAM_SENSOR, "release sensor cci failed!");
|
||||
}
|
||||
|
||||
s_ctrl->io_master_info.cci_client->cci_i2c_master = s_ctrl->sub_device_cci_master;
|
||||
s_ctrl->io_master_info.cci_client->i2c_freq_mode = s_ctrl->sub_device_i2c_freq_mode;
|
||||
|
||||
if(s_ctrl->io_master_info.cci_client->cci_device != s_ctrl->sub_device_cci_device)
|
||||
{
|
||||
s_ctrl->io_master_info.cci_client->cci_device = s_ctrl->sub_device_cci_device;
|
||||
}
|
||||
rc = camera_io_init(&(s_ctrl->io_master_info));
|
||||
if(rc != 0) {
|
||||
ret = camera_io_release(&(s_ctrl->io_master_info));
|
||||
CAM_ERR(CAM_SENSOR, "init sensor cci failed! rc=%d, release ret=%d, try again!", rc, ret);
|
||||
usleep_range(100000, 100000);
|
||||
rc = camera_io_init(&(s_ctrl->io_master_info));
|
||||
if (rc != 0) {
|
||||
ret = camera_io_release(&(s_ctrl->io_master_info));
|
||||
CAM_ERR(CAM_SENSOR, "try again init sensor cci failed again! rc=%d, release ret=%d", rc, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = camera_io_dev_read(
|
||||
&(s_ctrl->io_master_info),
|
||||
s_ctrl->sub_device_id_addr,
|
||||
&sub_device_id,
|
||||
s_ctrl->sub_device_addr_type,
|
||||
s_ctrl->sub_device_data_type);
|
||||
|
||||
CAM_INFO(CAM_SENSOR, "Read sub device id: 0x%x expected sub device id 0x%x:",
|
||||
sub_device_id, s_ctrl->expected_sub_device_id);
|
||||
|
||||
/* restore sensor i2c address */
|
||||
s_ctrl->io_master_info.cci_client->sid = sensor_address;
|
||||
|
||||
/* reset cci master */
|
||||
if (s_ctrl->need_change_cci_master) {
|
||||
ret = camera_io_release(&(s_ctrl->io_master_info));
|
||||
if (ret != 0) {
|
||||
CAM_ERR(CAM_SENSOR, "release flash cci failed! ");
|
||||
}
|
||||
|
||||
s_ctrl->io_master_info.cci_client->cci_i2c_master = sensor_cci_master;
|
||||
s_ctrl->io_master_info.cci_client->i2c_freq_mode = sensor_freq_mode;
|
||||
s_ctrl->io_master_info.cci_client->cci_device = sensor_cci_device;
|
||||
|
||||
rc = camera_io_init(&(s_ctrl->io_master_info));
|
||||
if(rc != 0) {
|
||||
ret = camera_io_release(&(s_ctrl->io_master_info));
|
||||
CAM_ERR(CAM_SENSOR, "init sensor cci failed! rc=%d, release ret=%d, try again!", rc, ret);
|
||||
usleep_range(100000, 100000);
|
||||
rc = camera_io_init(&(s_ctrl->io_master_info));
|
||||
if (rc != 0) {
|
||||
ret = camera_io_release(&(s_ctrl->io_master_info));
|
||||
CAM_ERR(CAM_SENSOR, "try again init sensor cci failed again! rc=%d, release ret=%d", rc, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sub_device_id == s_ctrl->expected_sub_device_id) {
|
||||
CAM_INFO(CAM_SENSOR,
|
||||
"Probe sub device success,slot:%d,sub_device_addr:0x%x,sub_device_id:0x%x",
|
||||
s_ctrl->soc_info.index,
|
||||
s_ctrl->sub_device_addr,
|
||||
s_ctrl->expected_sub_device_id);
|
||||
rc = 0;
|
||||
}
|
||||
else {
|
||||
CAM_ERR(CAM_SENSOR, "Probe sub device fail");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -789,6 +998,20 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||
goto free_power_settings;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH
|
||||
/* load probe setting before read sensorID */
|
||||
rc = cam_sensor_set_i2c_addr_switch_reg(s_ctrl);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"set i2c addr switch reg failed ! slot:%d, slave_addr:0x%x, sensor_id:0x%x",
|
||||
s_ctrl->soc_info.index,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr,
|
||||
s_ctrl->sensordata->slave_info.sensor_id);
|
||||
cam_sensor_power_down(s_ctrl);
|
||||
msleep(20);
|
||||
goto free_power_settings;
|
||||
}
|
||||
#endif
|
||||
/* Match sensor ID */
|
||||
rc = cam_sensor_match_id(s_ctrl);
|
||||
if (rc < 0) {
|
||||
|
|
@ -797,6 +1020,14 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||
goto free_power_settings;
|
||||
}
|
||||
|
||||
/* Match sub-device ID */
|
||||
rc = cam_sensor_match_sub_device_id(s_ctrl);
|
||||
if (rc < 0) {
|
||||
cam_sensor_power_down(s_ctrl);
|
||||
usleep_range(20000,20000);
|
||||
goto free_power_settings;
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_SENSOR,
|
||||
"Probe success,slot:%d,slave_addr:0x%x,sensor_id:0x%x",
|
||||
s_ctrl->soc_info.index,
|
||||
|
|
@ -814,6 +1045,9 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||
*/
|
||||
s_ctrl->is_probe_succeed = 1;
|
||||
s_ctrl->sensor_state = CAM_SENSOR_INIT;
|
||||
#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP
|
||||
s_ctrl->sensor_power_up_done = 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case CAM_ACQUIRE_DEV: {
|
||||
|
|
@ -1103,6 +1337,69 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||
}
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP
|
||||
case CAM_MOT_PRE_POWER_UP: {
|
||||
if (!s_ctrl->sensor_power_up_done)
|
||||
{
|
||||
rc = cam_sensor_power_up(s_ctrl);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"MotPreAct - Sensor Power up failed for sensor_id:0x%x, slave_addr:0x%x",
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr);
|
||||
goto release_mutex;
|
||||
}
|
||||
s_ctrl->sensor_power_up_done = 1;
|
||||
CAM_DBG(CAM_SENSOR, "MotPreAct - Camera sensor_id:0x%x, slave_addr:0x%x, pre power on done = %d",
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr,
|
||||
s_ctrl->sensor_power_up_done);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAM_MOT_PRE_POWER_DOWN: {
|
||||
if (s_ctrl->sensor_power_up_done)
|
||||
{
|
||||
rc = cam_sensor_power_down(s_ctrl);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Sensor Power Down failed sensor_id: 0x%x, slave_addr:0x%x",
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr);
|
||||
goto release_mutex;
|
||||
}
|
||||
CAM_DBG(CAM_SENSOR, "MotPreAct - Camera sensor_id:0x%x, slave_addr:0x%x, pre power on done = %d",
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr,
|
||||
s_ctrl->sensor_power_up_done);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAM_MOT_QUERY_SENSOR_STATUS: {
|
||||
uint32_t isSensorActive = 0;
|
||||
|
||||
if (s_ctrl->sensor_power_up_done)
|
||||
{
|
||||
isSensorActive = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
isSensorActive = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user(u64_to_user_ptr(cmd->handle),
|
||||
&isSensorActive, sizeof(uint32_t))) {
|
||||
CAM_ERR(CAM_SENSOR, "MotPreAct - Failed Copy to User");
|
||||
rc = -EFAULT;
|
||||
goto release_mutex;
|
||||
}
|
||||
CAM_DBG(CAM_SENSOR, "MotPreAct - Query camera sensor_id:0x%x, slave_addr:0x%x, status = %d",
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr,
|
||||
isSensorActive);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Opcode: %d", cmd->op_code);
|
||||
rc = -EINVAL;
|
||||
|
|
@ -1205,6 +1502,16 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP
|
||||
if (s_ctrl->sensor_power_up_done)
|
||||
{
|
||||
CAM_INFO(CAM_SENSOR, "MotPreAct - sensor has power on done for sensor_id:0x%x, slave_addr:0x%x",
|
||||
s_ctrl->sensordata->slave_info.sensor_id,
|
||||
s_ctrl->sensordata->slave_info.sensor_slave_addr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
power_info = &s_ctrl->sensordata->power_info;
|
||||
slave_info = &(s_ctrl->sensordata->slave_info);
|
||||
|
||||
|
|
@ -1279,6 +1586,9 @@ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
}
|
||||
|
||||
camera_io_release(&(s_ctrl->io_master_info));
|
||||
#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP
|
||||
s_ctrl->sensor_power_up_done = 0;
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,26 @@ struct cam_sensor_ctrl_t {
|
|||
bool bob_pwm_switch;
|
||||
uint32_t last_flush_req;
|
||||
uint16_t pipeline_delay;
|
||||
uint8_t probe_sub_device;
|
||||
uint16_t sub_device_addr;
|
||||
uint8_t sub_device_data_type;
|
||||
uint8_t sub_device_addr_type;
|
||||
uint16_t sub_device_id_addr;
|
||||
uint16_t expected_sub_device_id;
|
||||
uint8_t sub_device_cci_master;
|
||||
uint8_t sub_device_cci_device;
|
||||
uint8_t sub_device_i2c_freq_mode;
|
||||
bool need_change_cci_master;
|
||||
uint8_t i2c_addr_switch;
|
||||
uint16_t second_i2c_address;
|
||||
uint8_t i2c_switch_reg_addr_Type;
|
||||
uint8_t i2c_switch_reg_data_Type;
|
||||
uint16_t i2c_switch_reg_addr;
|
||||
uint16_t i2c_switch_reg_data;
|
||||
uint16_t i2c_switch_reg_delayMs;
|
||||
#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP
|
||||
bool sensor_power_up_done;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -187,6 +187,13 @@ static int32_t cam_sensor_driver_get_dt_data(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
CAM_DBG(CAM_SENSOR, "cci-index %d", s_ctrl->cci_num);
|
||||
}
|
||||
|
||||
if (of_property_read_bool(of_node, "need-change-cci-master")) {
|
||||
CAM_DBG(CAM_SENSOR, "need-change-cci-master found in this imgsensor");
|
||||
s_ctrl->need_change_cci_master = true;
|
||||
} else {
|
||||
s_ctrl->need_change_cci_master = false;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(of_node, "sensor-position-pitch",
|
||||
&sensordata->pos_pitch) < 0) {
|
||||
CAM_DBG(CAM_SENSOR, "Invalid sensor position");
|
||||
|
|
|
|||
|
|
@ -93,6 +93,39 @@ int32_t cam_camera_cci_i2c_read_seq(struct cam_sensor_cci_client *cci_client,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int32_t cam_camera_cci_i2c_ois_read_seq(struct cam_sensor_cci_client *cci_client,
|
||||
uint32_t addr, uint8_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type,
|
||||
uint32_t num_byte)
|
||||
{
|
||||
int32_t rc = -EFAULT;
|
||||
struct cam_cci_ctrl cci_ctrl;
|
||||
|
||||
if ((addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX)
|
||||
|| (data_type >= CAMERA_SENSOR_I2C_TYPE_MAX)
|
||||
|| (num_byte > I2C_REG_DATA_MAX)) {
|
||||
CAM_ERR(CAM_SENSOR, "addr_type %d num_byte %d", addr_type,
|
||||
num_byte);
|
||||
return rc;
|
||||
}
|
||||
|
||||
cci_ctrl.cmd = MSM_CCI_I2C_READ;
|
||||
cci_ctrl.cci_info = cci_client;
|
||||
cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
|
||||
cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = addr_type;
|
||||
cci_ctrl.cfg.cci_i2c_read_cfg.data_type = data_type;
|
||||
cci_ctrl.cfg.cci_i2c_read_cfg.data = data;
|
||||
cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = num_byte;
|
||||
cci_ctrl.status = -EFAULT;
|
||||
rc = v4l2_subdev_call(cci_client->cci_subdev,
|
||||
core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
|
||||
rc = cci_ctrl.status;
|
||||
CAM_DBG(CAM_SENSOR, "addr = 0x%x, rc = %d", addr, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t cam_cci_i2c_write_table_cmd(
|
||||
struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting,
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ int32_t cam_camera_cci_i2c_read_seq(struct cam_sensor_cci_client *client,
|
|||
enum camera_sensor_i2c_type data_type,
|
||||
uint32_t num_byte);
|
||||
|
||||
int32_t cam_camera_cci_i2c_ois_read_seq(struct cam_sensor_cci_client *client,
|
||||
uint32_t addr, uint8_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type,
|
||||
uint32_t num_byte);
|
||||
|
||||
/**
|
||||
* @client: CCI client structure
|
||||
* @write_setting: I2C register setting
|
||||
|
|
|
|||
|
|
@ -6,6 +6,27 @@
|
|||
#include "cam_sensor_io.h"
|
||||
#include "cam_sensor_i2c.h"
|
||||
|
||||
#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION
|
||||
|
||||
#define SPECIAL_SENSOR_ID 0x5041
|
||||
#define SPECIAL_SENSOR_ADDR_ID 0x300B
|
||||
#define SPECIAL_SENSOR_ADDR_VERSION 0x900E
|
||||
#define SPECIAL_SENSOR_IIC_ADDR 0x10
|
||||
|
||||
static uint32_t s_r900e_val = 0;
|
||||
|
||||
struct cam_sensor_i2c_reg_array special_on_write_settings = {0x0100, 0x01, 0x05, 0xFF};
|
||||
struct cam_sensor_i2c_reg_array special_off_write_settings = {0x0100, 0x00, 0x00, 0xFF};
|
||||
|
||||
struct cam_sensor_i2c_reg_array special_streamon_write_settings[] =
|
||||
{
|
||||
{0x7278, 0x00, 0x00, 0xFF},
|
||||
{0x727a, 0x01, 0x00, 0xFF},
|
||||
{0x7280, 0x07, 0x00, 0xFF},
|
||||
{0x0100, 0x01, 0x00, 0xFF}
|
||||
};
|
||||
#endif
|
||||
|
||||
int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
|
||||
uint32_t addr, uint16_t data, uint32_t data_mask,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
|
|
@ -68,14 +89,25 @@ int32_t camera_io_dev_read(struct camera_io_master *io_master_info,
|
|||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type)
|
||||
{
|
||||
#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION
|
||||
int32_t retval = 0;
|
||||
uint32_t r900e = 0;
|
||||
struct cam_sensor_i2c_reg_setting write_setting = {0};
|
||||
#endif
|
||||
|
||||
if (!io_master_info) {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION
|
||||
retval = cam_cci_i2c_read(io_master_info->cci_client,
|
||||
addr, data, addr_type, data_type);
|
||||
#else
|
||||
return cam_cci_i2c_read(io_master_info->cci_client,
|
||||
addr, data, addr_type, data_type);
|
||||
#endif
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
return cam_qup_i2c_read(io_master_info->client,
|
||||
addr, data, addr_type, data_type);
|
||||
|
|
@ -87,7 +119,50 @@ int32_t camera_io_dev_read(struct camera_io_master *io_master_info,
|
|||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION
|
||||
if (retval == 0 &&
|
||||
data != NULL &&
|
||||
*data == SPECIAL_SENSOR_ID &&
|
||||
addr == SPECIAL_SENSOR_ADDR_ID &&
|
||||
io_master_info->cci_client != NULL &&
|
||||
io_master_info->cci_client->cci_i2c_master == 0 &&
|
||||
io_master_info->cci_client->sid == SPECIAL_SENSOR_IIC_ADDR)
|
||||
{
|
||||
write_setting.size = 1;
|
||||
write_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD;
|
||||
write_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE;
|
||||
write_setting.delay = 21;
|
||||
write_setting.read_buff = NULL;
|
||||
write_setting.read_buff_len = 0;
|
||||
write_setting.reg_setting = &special_on_write_settings;
|
||||
retval = cam_cci_i2c_write_table(io_master_info, &write_setting);
|
||||
|
||||
retval = cam_cci_i2c_read(io_master_info->cci_client,
|
||||
SPECIAL_SENSOR_ADDR_VERSION,
|
||||
&r900e,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD,
|
||||
CAMERA_SENSOR_I2C_TYPE_BYTE);
|
||||
|
||||
CAM_INFO(CAM_SENSOR, "retval = %d, r900e = %d", retval, r900e);
|
||||
|
||||
if(retval == 0)
|
||||
s_r900e_val = r900e;
|
||||
|
||||
write_setting.size = 1;
|
||||
write_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD;
|
||||
write_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE;
|
||||
write_setting.delay = 0;
|
||||
write_setting.read_buff = NULL;
|
||||
write_setting.read_buff_len = 0;
|
||||
write_setting.reg_setting = &special_off_write_settings;
|
||||
retval = cam_cci_i2c_write_table(io_master_info, &write_setting);
|
||||
}
|
||||
|
||||
return retval;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info,
|
||||
|
|
@ -115,9 +190,38 @@ int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_ois_read_seq(struct camera_io_master *io_master_info,
|
||||
uint32_t addr, uint8_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type, int32_t num_bytes)
|
||||
{
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
return cam_camera_cci_i2c_ois_read_seq(io_master_info->cci_client,
|
||||
addr, data, addr_type, data_type, num_bytes);
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
return cam_qup_i2c_read_seq(io_master_info->client,
|
||||
addr, data, addr_type, num_bytes);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_read_seq(io_master_info,
|
||||
addr, data, addr_type, num_bytes);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_write_seq(io_master_info,
|
||||
addr, data, addr_type, num_bytes);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_write(struct camera_io_master *io_master_info,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting)
|
||||
{
|
||||
#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION
|
||||
int32_t retval = 0;
|
||||
#endif
|
||||
|
||||
if (!write_setting || !io_master_info) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Input parameters not valid ws: %pK ioinfo: %pK",
|
||||
|
|
@ -130,6 +234,44 @@ int32_t camera_io_dev_write(struct camera_io_master *io_master_info,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION
|
||||
if (io_master_info->cci_client != NULL &&
|
||||
io_master_info->cci_client->sid== SPECIAL_SENSOR_IIC_ADDR &&
|
||||
io_master_info->cci_client->cci_device == 1 &&
|
||||
io_master_info->cci_client->cci_i2c_master == 0 &&
|
||||
write_setting->reg_setting->reg_addr == 0x0100 &&
|
||||
write_setting->reg_setting->reg_data == 0x01)
|
||||
{
|
||||
CAM_INFO(CAM_SENSOR, "Detect stream on setting, r900e = %d", s_r900e_val);
|
||||
|
||||
if (s_r900e_val == 0x02)
|
||||
{
|
||||
write_setting->reg_setting->reg_addr = special_streamon_write_settings[0].reg_addr;
|
||||
write_setting->reg_setting->reg_data = special_streamon_write_settings[0].reg_data;
|
||||
write_setting->reg_setting->delay = special_streamon_write_settings[0].delay;
|
||||
write_setting->reg_setting->data_mask = special_streamon_write_settings[0].data_mask;
|
||||
retval = cam_cci_i2c_write_table(io_master_info, write_setting);
|
||||
|
||||
write_setting->reg_setting->reg_addr = special_streamon_write_settings[1].reg_addr;
|
||||
write_setting->reg_setting->reg_data = special_streamon_write_settings[1].reg_data;
|
||||
write_setting->reg_setting->delay = special_streamon_write_settings[1].delay;
|
||||
write_setting->reg_setting->data_mask = special_streamon_write_settings[1].data_mask;
|
||||
retval = cam_cci_i2c_write_table(io_master_info, write_setting);
|
||||
|
||||
write_setting->reg_setting->reg_addr = special_streamon_write_settings[2].reg_addr;
|
||||
write_setting->reg_setting->reg_data = special_streamon_write_settings[2].reg_data;
|
||||
write_setting->reg_setting->delay = special_streamon_write_settings[2].delay;
|
||||
write_setting->reg_setting->data_mask = special_streamon_write_settings[2].data_mask;
|
||||
retval = cam_cci_i2c_write_table(io_master_info, write_setting);
|
||||
|
||||
write_setting->reg_setting->reg_addr = special_streamon_write_settings[3].reg_addr;
|
||||
write_setting->reg_setting->reg_data = special_streamon_write_settings[3].reg_data;
|
||||
write_setting->reg_setting->delay = special_streamon_write_settings[3].delay;
|
||||
write_setting->reg_setting->data_mask = special_streamon_write_settings[3].data_mask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
return cam_cci_i2c_write_table(io_master_info,
|
||||
write_setting);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,12 @@ int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info,
|
|||
enum camera_sensor_i2c_type data_type,
|
||||
int32_t num_bytes);
|
||||
|
||||
int32_t camera_io_dev_ois_read_seq(struct camera_io_master *io_master_info,
|
||||
uint32_t addr, uint8_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type,
|
||||
int32_t num_bytes);
|
||||
|
||||
/**
|
||||
* @io_master_info: I2C/SPI master information
|
||||
*
|
||||
|
|
|
|||
|
|
@ -174,7 +174,12 @@ enum cam_ois_packet_opcodes {
|
|||
CAM_OIS_PACKET_OPCODE_INIT,
|
||||
CAM_OIS_PACKET_OPCODE_OIS_CONTROL,
|
||||
CAM_OIS_PACKET_OPCODE_READ,
|
||||
CAM_OIS_PACKET_OPCODE_WRITE_TIME
|
||||
CAM_OIS_PACKET_OPCODE_WRITE_TIME,
|
||||
CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_ROHM,
|
||||
CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON,
|
||||
CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON_QTIMER,
|
||||
CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_AW86006,
|
||||
CAM_OIS_PACKET_OPCODE_OIS_GYRO_OFFSET
|
||||
};
|
||||
|
||||
enum msm_bus_perf_setting {
|
||||
|
|
|
|||
|
|
@ -1231,6 +1231,11 @@ static int cam_soc_util_get_dt_regulator_info
|
|||
{
|
||||
int rc = 0, count = 0, i = 0;
|
||||
struct device_node *of_node = NULL;
|
||||
#ifdef CONFIG_CAMERA_VOLTAGE_COMPATIBLE
|
||||
int idpin_gpio = 0, idpin_value = 0;
|
||||
unsigned int second_vol_range[2];
|
||||
const char *rgltr_name = "";
|
||||
#endif
|
||||
|
||||
if (!soc_info || !soc_info->dev) {
|
||||
CAM_ERR(CAM_UTIL, "Invalid parameters");
|
||||
|
|
@ -1295,6 +1300,63 @@ static int cam_soc_util_get_dt_regulator_info
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAMERA_VOLTAGE_COMPATIBLE
|
||||
idpin_gpio = of_get_named_gpio(of_node, "volt-compat-gpio",0);
|
||||
if (idpin_gpio < 0) {
|
||||
CAM_ERR(CAM_UTIL, "Not volt-compat-gpio found ,gpio=%d",idpin_gpio);
|
||||
} else {
|
||||
if(gpio_is_valid(idpin_gpio)) {
|
||||
if(!gpio_request(idpin_gpio,"volt-compat-gpio")) {
|
||||
gpio_direction_input(idpin_gpio);
|
||||
CAM_DBG(CAM_UTIL, "volt-compat-gpio:%d =%d ", idpin_gpio, gpio_get_value(idpin_gpio));
|
||||
|
||||
rc = of_property_read_u32_array(of_node, "volt-compat-range", second_vol_range, 2);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "No volt-compat-range found, rc=%d", rc);
|
||||
gpio_free(idpin_gpio);
|
||||
idpin_gpio = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_property_read_string(of_node,"volt-compat-rgltr-name",&rgltr_name);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "No volt-compat-rgltr-name found, rc=%d", rc);
|
||||
gpio_free(idpin_gpio);
|
||||
idpin_gpio = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(of_node,"volt-compat-gpio-value",&idpin_value);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "No volt-compat-gpio-value found, rc=%d", rc);
|
||||
gpio_free(idpin_gpio);
|
||||
idpin_gpio = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(soc_info->index == 0 && idpin_gpio > 0) {
|
||||
for (i = 0; i < soc_info->num_rgltr; i++) {
|
||||
if((strcmp(soc_info->rgltr_name[i], rgltr_name)== 0)) {
|
||||
int val = 1;
|
||||
val = gpio_get_value(idpin_gpio);
|
||||
if(val == idpin_value) {
|
||||
soc_info->rgltr_min_volt [i]= second_vol_range[0];
|
||||
soc_info->rgltr_max_volt[i]= second_vol_range[1];
|
||||
}
|
||||
CAM_ERR(CAM_UTIL, "cam:%d, %s, voltage range: min:%d max:%d",
|
||||
soc_info->index,soc_info->rgltr_name[i], soc_info->rgltr_min_volt [i],soc_info->rgltr_max_volt[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
CAM_ERR(CAM_UTIL, "volt-compat-gpio request failed");
|
||||
}
|
||||
}else{
|
||||
CAM_ERR(CAM_UTIL, "volt-compat-gpio is not vaild");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,13 @@
|
|||
#include "cam_cci_dev.h"
|
||||
#include "cam_sensor_dev.h"
|
||||
#include "cam_actuator_dev.h"
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
#include "mot_actuator.h"
|
||||
#endif
|
||||
#include "cam_csiphy_dev.h"
|
||||
#include "cam_eeprom_dev.h"
|
||||
#include "cam_ois_dev.h"
|
||||
#include "pm6125_flash_gpio.h"
|
||||
|
||||
#if IS_REACHABLE(CONFIG_LEDS_QPNP_FLASH_V2) || \
|
||||
IS_REACHABLE(CONFIG_LEDS_QTI_FLASH)
|
||||
|
|
@ -105,6 +109,9 @@ static const struct camera_submodule_component camera_sensor[] = {
|
|||
{&cam_cci_init_module, &cam_cci_exit_module},
|
||||
{&cam_csiphy_init_module, &cam_csiphy_exit_module},
|
||||
{&cam_actuator_driver_init, &cam_actuator_driver_exit},
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
{&mot_actuator_driver_init, &mot_actuator_driver_exit},
|
||||
#endif
|
||||
{&cam_sensor_driver_init, &cam_sensor_driver_exit},
|
||||
{&cam_eeprom_driver_init, &cam_eeprom_driver_exit},
|
||||
{&cam_ois_driver_init, &cam_ois_driver_exit},
|
||||
|
|
@ -112,6 +119,9 @@ static const struct camera_submodule_component camera_sensor[] = {
|
|||
IS_REACHABLE(CONFIG_LEDS_QTI_FLASH)
|
||||
{&cam_flash_init_module, &cam_flash_exit_module},
|
||||
#endif
|
||||
#if IS_REACHABLE(CONFIG_CAMERA_FLASH_PWM)
|
||||
{&pm6125_flash_gpio_init_module, &pm6125_flash_gpio_exit_module},
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ extern struct platform_driver cam_ois_platform_driver;
|
|||
IS_REACHABLE(CONFIG_LEDS_QTI_FLASH)
|
||||
extern struct platform_driver cam_flash_platform_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
extern struct platform_driver mot_actuator_platform_driver;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_SPECTRA_ICP
|
||||
extern struct platform_driver cam_a5_driver;
|
||||
|
|
@ -102,6 +105,7 @@ static struct platform_driver *const cam_component_drivers[] = {
|
|||
&cci_driver,
|
||||
&csiphy_driver,
|
||||
&cam_actuator_platform_driver,
|
||||
|
||||
&cam_sensor_platform_driver,
|
||||
&cam_eeprom_platform_driver,
|
||||
&cam_ois_platform_driver,
|
||||
|
|
@ -109,6 +113,10 @@ static struct platform_driver *const cam_component_drivers[] = {
|
|||
IS_REACHABLE(CONFIG_LEDS_QTI_FLASH)
|
||||
&cam_flash_platform_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_AF_NOISE_ELIMINATION
|
||||
&mot_actuator_platform_driver,
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_SPECTRA_ICP
|
||||
&cam_a5_driver,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@
|
|||
#define CAM_EXT_OPCODE_BASE 0x200
|
||||
#define CAM_CONFIG_DEV_EXTERNAL (CAM_EXT_OPCODE_BASE + 0x1)
|
||||
|
||||
/* CONFIG_MOT_SENSOR_PRE_POWERUP */
|
||||
#define CAM_MOT_OPCODE_BASE 0x250
|
||||
#define CAM_MOT_PRE_POWER_UP (CAM_MOT_OPCODE_BASE + 0x1)
|
||||
#define CAM_MOT_PRE_POWER_DOWN (CAM_MOT_OPCODE_BASE + 0x2)
|
||||
#define CAM_MOT_QUERY_SENSOR_STATUS (CAM_MOT_OPCODE_BASE + 0x3)
|
||||
|
||||
/* camera handle type */
|
||||
#define CAM_HANDLE_USER_POINTER 1
|
||||
#define CAM_HANDLE_MEM_HANDLE 2
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#define CAM_CUSTOM_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 14)
|
||||
#define CAM_OPE_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 15)
|
||||
#define CAM_TFE_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 16)
|
||||
#define CAM_MOT_ACTUATOR_TYPE (CAM_DEVICE_TYPE_BASE + 17)
|
||||
|
||||
/* cam_req_mgr hdl info */
|
||||
#define CAM_REQ_MGR_HDL_IDX_POS 8
|
||||
|
|
|
|||
|
|
@ -137,6 +137,13 @@ struct cam_cmd_ois_info {
|
|||
__u8 cmd_type;
|
||||
__u8 ois_fw_flag;
|
||||
__u8 is_ois_calib;
|
||||
__u8 ois_preprog_flag;
|
||||
__u8 ois_precoeff_flag;
|
||||
__u8 ois_postcalib_flag;
|
||||
__u8 ois_fw_txn_data_sz;
|
||||
__u8 ois_fw_inc_addr;
|
||||
__u8 ois_fw_addr_type;
|
||||
__u8 ois_fw_data_type;
|
||||
char ois_name[MAX_OIS_NAME_SIZE];
|
||||
struct cam_ois_opcode opcode;
|
||||
} __attribute__((packed));
|
||||
|
|
@ -165,6 +172,22 @@ struct cam_cmd_probe {
|
|||
__u32 data_mask;
|
||||
__u16 camera_id;
|
||||
__u16 reserved;
|
||||
__u8 probe_sub_device;
|
||||
__u32 sub_device_addr;
|
||||
__u8 sub_device_data_type;
|
||||
__u8 sub_device_addr_type;
|
||||
__u32 sub_device_id_addr;
|
||||
__u32 expected_sub_device_id;
|
||||
__u8 sub_device_cci_master;
|
||||
__u8 sub_device_cci_device;
|
||||
__u8 sub_device_i2c_freq_mode;
|
||||
__u8 i2c_addr_switch;
|
||||
__u32 second_i2c_address;
|
||||
__u8 i2c_switch_reg_addr_Type;
|
||||
__u8 i2c_switch_reg_data_Type;
|
||||
__u32 i2c_switch_reg_addr;
|
||||
__u32 i2c_switch_reg_data;
|
||||
__u32 i2c_switch_reg_delayMs;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
|
|
@ -485,6 +508,7 @@ struct cam_flash_query_cap_info {
|
|||
__u32 max_duration_flash[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
__u32 max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
__u32 flash_type;
|
||||
__u32 flash_supplier;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue