"Devon push for Android 13"

* tag 'MMI-T2SN33.73-22-3' of https://github.com/MotorolaMobilityLLC/kernel-msm-techpack-camera:
  Low flashlight brightness bugfix
  devon4g: read sensorid failed,but return success
  devon: Add retries for sensor id matching
  devon: Actuator noise reduction
  hawao: Fix flash compatible
  rhode: Del an invalid log
  hawao: Actuator noise reduction
  Rhode: Actuator noise reduction
  hawao: Flash compatible
  rhode: Actuator noise reduction
  Rhode: flash node control
  Rhode: add flash current ma control
  Rhode: flash bring up(2/3)
  Rhode4G: main eeprom bring up(3/3)
  Caprip: add wakelock for the actuator noise reduction.
  cam: Add actuator standalone diver for vibrator.
  guamna:[camera] Fix capture failed when set exposure time 1s
  msm: camera: req_mgr: Decrease device handles in hdl_tbl
  guamna: Add eeprom operation READ_LOOP
  guamna: add eeprom name and add hi556 otp read method
  guam: EXPORT_SYMBOL cam_cci_get_subdev

 Conflicts:
	techpack/camera-bengal/drivers/cam_req_mgr/cam_req_mgr_util.c
	techpack/camera-bengal/drivers/cam_sensor_module/cam_flash/Makefile

Change-Id: I141fc90b9c8f08ea3e2f2e38d73f1e91c03d9ad6
This commit is contained in:
Michael Bestas committed 2024-01-03 01:21:29 +02:00
commit e0d512421b
33 files changed
+2169 -20

No files matched your search

@@ -1363,8 +1363,6 @@ static void cam_hw_cdm_work(struct work_struct *work)
CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK))
clear_bit(CAM_CDM_ERROR_HW_STATUS,
&core->cdm_status);
} else {
CAM_ERR(CAM_CDM, "NULL payload");
}
kfree(payload);
payload = NULL;
@@ -14,7 +14,7 @@
#define CAM_REQ_MGR_MAX_LINKED_DEV 16
#define MAX_REQ_SLOTS 48
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT 1000
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT 5000
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT_DEFAULT 5000
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX 50000
#define CAM_REQ_MGR_SCHED_REQ_TIMEOUT 1000
@@ -37,7 +37,7 @@ int cam_req_mgr_util_init(void)
rc = -ENOMEM;
goto hdl_tbl_alloc_failed;
}
bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES_V2) * sizeof(long);
bitmap_size = BITS_TO_LONGS(CAM_REQ_MGR_MAX_HANDLES) * sizeof(long);
hdl_tbl_local->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!hdl_tbl_local->bitmap) {
rc = -ENOMEM;
@@ -95,7 +95,7 @@ int cam_req_mgr_util_free_hdls(void)
return -EINVAL;
}
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++) {
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES; i++) {
if (hdl_tbl->hdl[i].state == HDL_ACTIVE) {
CAM_WARN(CAM_CRM, "Dev handle = %x session_handle = %x",
hdl_tbl->hdl[i].hdl_value,
@@ -104,7 +104,7 @@ int cam_req_mgr_util_free_hdls(void)
clear_bit(i, hdl_tbl->bitmap);
}
}
bitmap_zero(hdl_tbl->bitmap, CAM_REQ_MGR_MAX_HANDLES_V2);
bitmap_zero(hdl_tbl->bitmap, CAM_REQ_MGR_MAX_HANDLES);
spin_unlock_bh(&hdl_tbl_lock);
return 0;
@@ -116,7 +116,7 @@ static int32_t cam_get_free_handle_index(void)
idx = find_first_zero_bit(hdl_tbl->bitmap, hdl_tbl->bits);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0) {
if (idx >= CAM_REQ_MGR_MAX_HANDLES || idx < 0) {
CAM_ERR(CAM_CRM, "No free index found idx: %d", idx);
return -ENOSR;
}
@@ -130,9 +130,9 @@ static void cam_dump_tbl_info(void)
{
int i;
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++)
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES; i++)
CAM_INFO_RATE_LIMIT_CUSTOM(CAM_CRM, CAM_RATE_LIMIT_INTERVAL_5SEC,
CAM_REQ_MGR_MAX_HANDLES_V2,
CAM_REQ_MGR_MAX_HANDLES,
"session_hdl=%x hdl_value=%x type=%d state=%d dev_id=%lld",
hdl_tbl->hdl[i].session_hdl, hdl_tbl->hdl[i].hdl_value,
hdl_tbl->hdl[i].type, hdl_tbl->hdl[i].state, hdl_tbl->hdl[i].dev_id);
@@ -266,7 +266,7 @@ void *cam_get_priv(int32_t dev_hdl, int handle_type)
}
idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) {
if (idx >= CAM_REQ_MGR_MAX_HANDLES) {
CAM_ERR_RATE_LIMIT(CAM_CRM, "Invalid idx: %d", idx);
goto device_priv_fail;
}
@@ -338,7 +338,7 @@ void *cam_get_device_ops(int32_t dev_hdl)
}
idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) {
if (idx >= CAM_REQ_MGR_MAX_HANDLES) {
CAM_ERR(CAM_CRM, "Invalid idx");
goto device_ops_fail;
}
@@ -381,7 +381,7 @@ static int cam_destroy_hdl(int32_t dev_hdl, int dev_hdl_type)
}
idx = CAM_REQ_MGR_GET_HDL_IDX(dev_hdl);
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2) {
if (idx >= CAM_REQ_MGR_MAX_HANDLES) {
CAM_ERR(CAM_CRM, "Invalid idx %d", idx);
goto destroy_hdl_fail;
}
@@ -62,7 +62,7 @@ struct handle {
* @bits: size of bit map in bits
*/
struct cam_req_mgr_util_hdl_tbl {
struct handle hdl[CAM_REQ_MGR_MAX_HANDLES_V2];
struct handle hdl[CAM_REQ_MGR_MAX_HANDLES];
void *bitmap;
size_t bits;
};
@@ -10,3 +10,4 @@ obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_eeprom/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_ois/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_flash/
obj-$(CONFIG_CAMERA_FLASH_PWM) += cam_flash_pm6125_gpio/
@@ -12,3 +12,4 @@ ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += cam_actuator_dev.o cam_actuator_core.o cam_actuator_soc.o
obj-$(CONFIG_AF_NOISE_ELIMINATION) += mot_actuator.o mot_actuator_policy.o
@@ -11,6 +11,9 @@
#include "cam_trace.h"
#include "cam_common_util.h"
#include "cam_packet_util.h"
#ifdef CONFIG_AF_NOISE_ELIMINATION
#include "mot_actuator_policy.h"
#endif
int32_t cam_actuator_construct_default_power_setting(
struct cam_sensor_power_ctrl_t *power_info)
@@ -253,7 +256,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(
@@ -270,6 +279,14 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
}
}
#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;
}
@@ -567,6 +584,13 @@ 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) {
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) {
@@ -860,6 +884,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,9 @@ struct cam_actuator_ctrl_t {
struct cam_actuator_query_cap act_info;
struct intf_params bridge_intf;
uint32_t last_flush_req;
#ifdef CONFIG_AF_NOISE_ELIMINATION
bool is_multi_user_supported;
#endif
};
#endif /* _CAM_ACTUATOR_DEV_H_ */
@@ -34,6 +34,15 @@ 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
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,32 @@
#ifndef __CAM_ACTUATOR_STANDALONE_H__
#define __CAM_ACTUATOR_STANDALONE_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)
#endif /*__CAM_ACTUATOR_STANDALONE_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__*/
@@ -27,6 +27,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)
{
@@ -61,8 +61,8 @@
#define CCI_READ_MAX 256
#define CCI_READ_MAX_V_1_2 0xE
#define CCI_I2C_READ_MAX_RETRIES 3
#define CCI_I2C_MAX_READ 8192
#define CCI_I2C_MAX_WRITE 8192
#define CCI_I2C_MAX_READ 20480
#define CCI_I2C_MAX_WRITE 20480
#define CCI_I2C_MAX_BYTE_COUNT 65535
#define CAMX_CCI_DEV_NAME "cam-cci-driver"
@@ -34,6 +34,7 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
struct cam_eeprom_memory_map_t *emap = block->map;
struct cam_eeprom_soc_private *eb_info = NULL;
uint8_t *memptr = block->mapdata;
uint32_t sz, sz_read;
if (!e_ctrl) {
CAM_ERR(CAM_EEPROM, "e_ctrl is NULL");
@@ -109,7 +110,7 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
emap[j].mem.addr_type,
emap[j].mem.data_type,
emap[j].mem.valid_size);
if (rc < 0) {
if (rc) {
CAM_ERR(CAM_EEPROM, "read failed rc %d",
rc);
return rc;
@@ -117,6 +118,22 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
memptr += emap[j].mem.valid_size;
}
if (emap[j].mem_rl.valid_size) {
for (sz = 0; sz < emap[j].mem_rl.valid_size; sz++) {
rc = camera_io_dev_read(&e_ctrl->io_master_info,
emap[j].mem_rl.addr, &sz_read,
emap[j].mem_rl.addr_type,
emap[j].mem_rl.data_type);
if (rc) {
CAM_ERR(CAM_EEPROM, "read failed rc %d",
rc);
return rc;
}
*memptr = (uint8_t)sz_read;
memptr++;
}
}
if (emap[j].pageen.valid_size) {
i2c_reg_settings.addr_type = emap[j].pageen.addr_type;
i2c_reg_settings.data_type = emap[j].pageen.data_type;
@@ -426,6 +443,7 @@ static int32_t cam_eeprom_parse_memory_map(
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_random_wr *i2c_random_wr = NULL;
struct cam_cmd_i2c_continuous_rd *i2c_cont_rd = NULL;
struct cam_cmd_i2c_random_rd *i2c_random_rd = NULL;
struct cam_cmd_conditional_wait *i2c_poll = NULL;
struct cam_cmd_unconditional_wait *i2c_uncond_wait = NULL;
size_t validate_size = 0;
@@ -436,6 +454,8 @@ static int32_t cam_eeprom_parse_memory_map(
validate_size = sizeof(struct cam_cmd_i2c_random_wr);
else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD)
validate_size = sizeof(struct cam_cmd_i2c_continuous_rd);
else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD)
validate_size = sizeof(struct cam_cmd_i2c_random_rd);
else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT)
validate_size = sizeof(struct cam_cmd_unconditional_wait);
@@ -502,6 +522,25 @@ static int32_t cam_eeprom_parse_memory_map(
cmd_length_in_bytes;
data->num_data += map[*num_map].mem.valid_size;
break;
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD:
i2c_random_rd = (struct cam_cmd_i2c_random_rd *)cmd_buf;
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_rd) - sizeof(int32_t);
if (i2c_random_rd->header.count >= U32_MAX - data->num_data) {
CAM_ERR(CAM_EEPROM,
"int overflow on eeprom memory block");
return -EINVAL;
}
map[*num_map].mem_rl.addr = i2c_random_rd->data_read[0].reg_data;
map[*num_map].mem_rl.addr_type = i2c_random_rd->header.addr_type;
map[*num_map].mem_rl.data_type = i2c_random_rd->header.data_type;
map[*num_map].mem_rl.valid_size =
i2c_random_rd->header.count;
cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
processed_size +=
cmd_length_in_bytes;
data->num_data += map[*num_map].mem_rl.valid_size;
break;
case CAMERA_SENSOR_CMD_TYPE_WAIT:
if (generic_op_code ==
CAMERA_SENSOR_WAIT_OP_HW_UCND ||
@@ -1034,6 +1073,7 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl,
break;
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD:
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD:
case CAMERA_SENSOR_CMD_TYPE_WAIT:
num_map++;
rc = cam_eeprom_parse_memory_map(
@@ -63,6 +63,7 @@ struct cam_eeprom_map_t {
* @pageen : pageen memory
* @poll : poll memory
* @mem : mem
* @mem_rl : mem_rl: used for operation READ_LOOP
* @saddr : slave addr
*
*/
@@ -71,6 +72,7 @@ struct cam_eeprom_memory_map_t {
struct cam_eeprom_map_t pageen;
struct cam_eeprom_map_t poll;
struct cam_eeprom_map_t mem;
struct cam_eeprom_map_t mem_rl;
uint32_t saddr;
};
@@ -6,6 +6,7 @@ ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_core
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_cpas/include
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_req_mgr
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_sensor_module/cam_cci
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_sensor_module/cam_flash_pm6125_gpio
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_sensor_module/cam_res_mgr
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_sensor_module/cam_sensor_io
ccflags-y += -I$(srctree)/techpack/camera-bengal/drivers/cam_sensor_module/cam_sensor_utils
@@ -11,6 +11,10 @@
#include "cam_res_mgr_api.h"
#include "cam_common_util.h"
#include "cam_packet_util.h"
#ifdef CONFIG_CAMERA_FLASH_PWM
#include "cam_sensor_util.h"
#include "../cam_flash_pm6125_gpio/pm6125_flash_gpio.h"
#endif
static int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
bool regulator_enable)
@@ -507,6 +511,10 @@ static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl,
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");
@@ -530,6 +538,13 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
flash_ctrl->flash_state = CAM_FLASH_STATE_CONFIG;
}
#ifdef CONFIG_CAMERA_FLASH_PWM
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;
}
@@ -538,6 +553,10 @@ static int cam_flash_low(
struct cam_flash_frame_setting *flash_data)
{
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");
@@ -555,6 +574,28 @@ 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);
#ifdef CONFIG_DEVON_CAMERA_FLASH
cam_res_mgr_gpio_request(soc_info.dev, DEVON_CAMERA_PWM_GPIO, 0, "torch_enable");
cam_res_mgr_gpio_set_value(DEVON_CAMERA_PWM_GPIO, 1);
usleep_range(5000,6000);
cam_res_mgr_gpio_set_value(DEVON_CAMERA_PWM_GPIO, 0);
cam_res_mgr_gpio_free(soc_info.dev, DEVON_CAMERA_PWM_GPIO);
#else
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIRELOW, FLASH_FIRE_LOW_MAXCURRENT);
usleep_range(5000,6000);
#endif
pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIRELOW, flash_data->led_current_ma[0]);
#endif
return rc;
}
@@ -563,6 +604,10 @@ static int cam_flash_high(
struct cam_flash_frame_setting *flash_data)
{
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");
@@ -580,6 +625,18 @@ 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;
}
@@ -1219,12 +1276,23 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
return rc;
}
#ifdef CONFIG_CAMERA_FLASH_PWM
if (fctrl->func_tbl.power_ops) {
rc = fctrl->func_tbl.power_ops(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
return rc;
}
}
#else
rc = fctrl->func_tbl.power_ops(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
return rc;
}
#endif
rc = fctrl->func_tbl.apply_setting(fctrl, 0);
if (rc) {
@@ -1501,13 +1569,23 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
fctrl->is_regulator_enabled = false;
fctrl->nrt_info.cmn_attr.cmd_type =
CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_INFO;
#ifdef CONFIG_CAMERA_FLASH_PWM
if (fctrl->func_tbl.power_ops) {
rc = fctrl->func_tbl.power_ops(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
return rc;
}
}
#else
rc = fctrl->func_tbl.power_ops(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
return rc;
}
#endif
fctrl->flash_state =
CAM_FLASH_STATE_CONFIG;
@@ -1943,10 +2021,19 @@ void cam_flash_shutdown(struct cam_flash_ctrl *fctrl)
"LED OFF FAILED: %d",
rc);
}
#ifdef CONFIG_CAMERA_FLASH_PWM
if (fctrl->func_tbl.power_ops) {
rc = fctrl->func_tbl.power_ops(fctrl, false);
if (rc)
CAM_ERR(CAM_FLASH, "Power Down Failed rc: %d",
rc);
}
#else
rc = fctrl->func_tbl.power_ops(fctrl, false);
if (rc)
CAM_ERR(CAM_FLASH, "Power Down Failed rc: %d",
rc);
#endif
}
rc = cam_flash_release_dev(fctrl);
@@ -1979,3 +2066,104 @@ 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 = 3;
power_info->power_setting =
kzalloc(sizeof(struct cam_sensor_power_setting)*3,
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_GPIO1;
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_setting[2].seq_type = SENSOR_CUSTOM_GPIO2;
power_info->power_setting[2].seq_val = 0;
power_info->power_setting[2].config_val = 1;
power_info->power_setting[2].delay = 0;
power_info->power_down_setting_size = 3;
power_info->power_down_setting =
kzalloc(sizeof(struct cam_sensor_power_setting)*3,
GFP_KERNEL);
if (!power_info->power_down_setting) {
rc = -ENOMEM;
goto free_power_settings;
}
power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_GPIO2;
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_CUSTOM_GPIO1;
power_info->power_down_setting[1].seq_val = 0;
power_info->power_down_setting[1].config_val = 0;
power_info->power_down_setting[2].seq_type = SENSOR_VIO;
power_info->power_down_setting[2].seq_val = CAM_VIO;
power_info->power_down_setting[2].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
@@ -6,6 +6,10 @@
#ifndef _CAM_FLASH_CORE_H_
#define _CAM_FLASH_CORE_H_
#ifdef CONFIG_DEVON_CAMERA_FLASH
#define DEVON_CAMERA_PWM_GPIO 1165
#endif
#include <media/cam_sensor.h>
#include "cam_flash_dev.h"
@@ -8,6 +8,9 @@
#include "cam_flash_soc.h"
#include "cam_flash_core.h"
#include "cam_common_util.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)
@@ -126,8 +129,15 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
CAM_WARN(CAM_FLASH,
"Failed in destroying the device Handle");
#ifdef CONFIG_CAMERA_FLASH_PWM
if (fctrl->func_tbl.power_ops) {
if (fctrl->func_tbl.power_ops(fctrl, false))
CAM_WARN(CAM_FLASH, "Power Down Failed");
}
#else
if (fctrl->func_tbl.power_ops(fctrl, false))
CAM_WARN(CAM_FLASH, "Power Down Failed");
#endif
fctrl->streamoff_count = 0;
fctrl->flash_state = CAM_FLASH_STATE_INIT;
@@ -135,6 +145,10 @@ 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;
@@ -150,6 +164,40 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
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 (fctrl->func_tbl.power_ops(fctrl, true)){
CAM_ERR(CAM_FLASH, "Power Up 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;
}
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");
@@ -316,6 +364,10 @@ static int cam_flash_platform_remove(struct platform_device *pdev)
{
struct cam_flash_ctrl *fctrl;
#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");
@@ -328,6 +380,9 @@ static int cam_flash_platform_remove(struct platform_device *pdev)
mutex_unlock(&fctrl->flash_mutex);
cam_unregister_subdev(&(fctrl->v4l2_dev_str));
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);
@@ -431,6 +486,9 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
fctrl->of_node = pdev->dev.of_node;
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) {
@@ -512,7 +570,11 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
/* PMIC Flash */
fctrl->func_tbl.parser = cam_flash_pmic_pkt_parser;
fctrl->func_tbl.apply_setting = cam_flash_pmic_apply_setting;
#ifdef CONFIG_CAMERA_FLASH_PWM
fctrl->func_tbl.power_ops = NULL;
#else
fctrl->func_tbl.power_ops = cam_flash_pmic_power_ops;
#endif
fctrl->func_tbl.flush_req = cam_flash_pmic_flush_request;
}
@@ -536,6 +598,10 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
fctrl->flash_state = CAM_FLASH_STATE_INIT;
CAM_DBG(CAM_FLASH, "Probe success");
#ifdef CONFIG_CAMERA_FLASH_PWM
pm6125_flash_control_create_device(&pdev->dev);
#endif
return rc;
free_cci_resource:
@@ -146,6 +146,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 {
@@ -232,5 +235,9 @@ 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
#endif /*_CAM_FLASH_DEV_H_*/
@@ -16,6 +16,10 @@ static int32_t cam_get_source_node_info(
{
int32_t rc = 0;
uint32_t count = 0, i = 0;
#ifdef CONFIG_CAMERA_FLASH_PWM
int16_t gpio_array_size = 0;
uint16_t *gpio_array = NULL;
#endif
struct device_node *flash_src_node = NULL;
struct device_node *torch_src_node = NULL;
struct device_node *switch_src_node = NULL;
@@ -29,6 +33,27 @@ 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;
}
#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");
}
}
#endif
switch_src_node = of_parse_phandle(of_node, "switch-source", 0);
if (!switch_src_node) {
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(srctree)/techpack/camera/include/uapi
ccflags-y += -I$(srctree)/techpack/camera/include/uapi
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_cpas/include
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_req_mgr
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_sensor_module/cam_cci
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_sensor_module/cam_flash
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_sensor_module/cam_res_mgr
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_sensor_module/cam_sensor_io
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_sensor_module/cam_sensor_utils
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils
obj-$(CONFIG_CAMERA_FLASH_PWM) += pm6125_flash_gpio.o
@@ -0,0 +1,309 @@
/*
*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,
},
};
static int __init 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;
}
static void __exit pm6125_flash_gpio_exit_module(void)
{
platform_driver_unregister(&pm6125_flash_gpio_platform_driver);
}
module_init(pm6125_flash_gpio_init_module);
module_exit(pm6125_flash_gpio_exit_module);
MODULE_AUTHOR("liyang <liyang14@huaqin.com>");
MODULE_DESCRIPTION("CONTROL PM6125 FLASH GPIO Driver");
MODULE_LICENSE("GPL");
@@ -0,0 +1,42 @@
#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
#ifdef CONFIG_DEVON_CAMERA_FLASH
#define PM6125_PWM_PERIOD 50000
#define FLASH_FIRE_HIGH_MAXCURRENT 1750
#define FLASH_FIRE_LOW_MAXCURRENT 285
#else
#define PM6125_PWM_PERIOD 50000
#define FLASH_FIRE_HIGH_MAXCURRENT 1200
#define FLASH_FIRE_LOW_MAXCURRENT 150
#endif
/*****************************************************************************
* 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
#endif /* _PM6125_FLASH_GPIO_H_*/
@@ -477,7 +477,11 @@ int cam_res_mgr_gpio_request(struct device *dev, uint gpio,
}
EXPORT_SYMBOL(cam_res_mgr_gpio_request);
#ifdef CONFIG_CAMERA_FLASH_PWM
void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
#else
static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
#endif
{
bool found = false;
bool need_free = true;
@@ -535,6 +539,9 @@ static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
if (need_free)
gpio_free(gpio);
}
#ifdef CONFIG_CAMERA_FLASH_PWM
EXPORT_SYMBOL(cam_res_mgr_gpio_free);
#endif
void cam_res_mgr_gpio_free_arry(struct device *dev,
const struct gpio *array, size_t num)
@@ -100,6 +100,20 @@ int cam_res_mgr_shared_pinctrl_post_init(void);
int cam_res_mgr_gpio_request(struct device *dev, unsigned int gpio,
unsigned long flags, const char *label);
#ifdef CONFIG_CAMERA_FLASH_PWM
/**
* @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);
#endif
/**
* @brief: Free a array GPIO
*
@@ -617,6 +617,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;
@@ -627,7 +631,28 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl)
slave_info);
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,
@@ -643,6 +668,7 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl)
chipid, slave_info->sensor_id);
return -ENODEV;
}
#endif
return rc;
}
@@ -18,7 +18,7 @@
#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1
#define I2C_REG_DATA_MAX (8*1024)
#define I2C_REG_DATA_MAX (20*1024)
/**
* @client: CCI client structure
@@ -7,7 +7,7 @@
#include "cam_sensor_i2c.h"
#include "cam_sensor_io.h"
#define I2C_REG_DATA_MAX (8*1024)
#define I2C_REG_DATA_MAX (20*1024)
#define I2C_REG_MAX_BUF_SIZE 8
static int32_t cam_qup_i2c_rxdata(
@@ -32,6 +32,9 @@
#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)
#ifdef CONFIG_AF_NOISE_ELIMINATION
#define CAM_MOT_ACTUATOR_TYPE (CAM_DEVICE_TYPE_BASE + 17)
#endif
/* cam_req_mgr hdl info */
#define CAM_REQ_MGR_HDL_IDX_POS 8
@@ -483,6 +483,9 @@ struct cam_flash_query_cap_info {
uint32_t max_duration_flash[CAM_FLASH_MAX_LED_TRIGGERS];
uint32_t max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS];
uint32_t flash_type;
#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE
uint32_t flash_supplier;
#endif
} __attribute__ ((packed));
#endif