media: i2c: gc2093 support fastboot

Signed-off-by: Sisyphean Zhou <sisyphean.zhou@rock-chips.com>
Change-Id: I3245ba187df5ddcc8c5a97e3098e1436e62d7e9d
This commit is contained in:
Sisyphean Zhou
2022-09-06 10:50:50 +08:00
committed by Tao Huang
parent 97e91ee429
commit fc49bfda1b

View File

@@ -32,6 +32,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02)
#define GC2093_NAME "gc2093"
@@ -151,6 +152,8 @@ struct gc2093 {
u32 cur_vts;
bool has_init_exp;
bool is_thunderboot;
bool is_first_streamoff;
struct preisp_hdrae_exp_s init_hdrae_exp;
};
@@ -717,6 +720,9 @@ static int __gc2093_power_on(struct gc2093 *gc2093)
return ret;
}
if (gc2093->is_thunderboot)
return 0;
ret = regulator_bulk_enable(GC2093_NUM_SUPPLIES, gc2093->supplies);
if (ret < 0) {
dev_err(dev, "Failed to enable regulators\n");
@@ -744,6 +750,16 @@ disable_clk:
static void __gc2093_power_off(struct gc2093 *gc2093)
{
clk_disable_unprepare(gc2093->xvclk);
if (gc2093->is_thunderboot) {
if (gc2093->is_first_streamoff) {
gc2093->is_thunderboot = false;
gc2093->is_first_streamoff = false;
} else {
return;
}
}
if (!IS_ERR(gc2093->reset_gpio))
gpiod_set_value_cansleep(gc2093->reset_gpio, 1);
if (!IS_ERR(gc2093->pwdn_gpio))
@@ -755,10 +771,16 @@ static void __gc2093_power_off(struct gc2093 *gc2093)
static int gc2093_check_sensor_id(struct gc2093 *gc2093)
{
struct device *dev = gc2093->dev;
u8 id_h = 0, id_l = 0;
u16 id = 0;
int ret = 0;
if (gc2093->is_thunderboot) {
dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
return 0;
}
ret = gc2093_read_reg(gc2093, GC2093_REG_CHIP_ID_H, &id_h);
ret |= gc2093_read_reg(gc2093, GC2093_REG_CHIP_ID_L, &id_l);
if (ret) {
@@ -933,26 +955,27 @@ static int __gc2093_start_stream(struct gc2093 *gc2093)
{
int ret;
ret = regmap_multi_reg_write(gc2093->regmap,
gc2093->cur_mode->reg_list,
gc2093->cur_mode->reg_num);
if (ret)
return ret;
/* Apply customized control from user */
mutex_unlock(&gc2093->lock);
v4l2_ctrl_handler_setup(&gc2093->ctrl_handler);
mutex_lock(&gc2093->lock);
if (gc2093->has_init_exp && gc2093->cur_mode->hdr_mode != NO_HDR) {
ret = gc2093_ioctl(&gc2093->subdev, PREISP_CMD_SET_HDRAE_EXP,
&gc2093->init_hdrae_exp);
if (ret) {
dev_err(gc2093->dev, "init exp fail in hdr mode\n");
if (!gc2093->is_thunderboot) {
ret = regmap_multi_reg_write(gc2093->regmap,
gc2093->cur_mode->reg_list,
gc2093->cur_mode->reg_num);
if (ret)
return ret;
/* Apply customized control from user */
mutex_unlock(&gc2093->lock);
v4l2_ctrl_handler_setup(&gc2093->ctrl_handler);
mutex_lock(&gc2093->lock);
if (gc2093->has_init_exp && gc2093->cur_mode->hdr_mode != NO_HDR) {
ret = gc2093_ioctl(&gc2093->subdev, PREISP_CMD_SET_HDRAE_EXP,
&gc2093->init_hdrae_exp);
if (ret) {
dev_err(gc2093->dev, "init exp fail in hdr mode\n");
return ret;
}
}
}
return gc2093_write_reg(gc2093, GC2093_REG_CTRL_MODE,
GC2093_MODE_STREAMING);
}
@@ -960,6 +983,10 @@ static int __gc2093_start_stream(struct gc2093 *gc2093)
static int __gc2093_stop_stream(struct gc2093 *gc2093)
{
gc2093->has_init_exp = false;
if (gc2093->is_thunderboot) {
gc2093->is_first_streamoff = true;
return 0;
}
return gc2093_write_reg(gc2093, GC2093_REG_CTRL_MODE,
GC2093_MODE_SW_STANDBY);
}
@@ -1070,6 +1097,10 @@ static int gc2093_s_stream(struct v4l2_subdev *sd, int on)
goto unlock_and_return;
if (on) {
if (gc2093->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
gc2093->is_thunderboot = false;
__gc2093_power_on(gc2093);
}
ret = pm_runtime_get_sync(gc2093->dev);
if (ret < 0) {
pm_runtime_put_noidle(gc2093->dev);
@@ -1395,17 +1426,19 @@ static int gc2093_probe(struct i2c_client *client,
return -EINVAL;
}
gc2093->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
gc2093->xvclk = devm_clk_get(gc2093->dev, "xvclk");
if (IS_ERR(gc2093->xvclk)) {
dev_err(gc2093->dev, "Failed to get xvclk\n");
return -EINVAL;
}
gc2093->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
gc2093->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
if (IS_ERR(gc2093->reset_gpio))
dev_warn(dev, "Failed to get reset-gpios\n");
gc2093->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_HIGH);
gc2093->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
if (IS_ERR(gc2093->pwdn_gpio))
dev_warn(dev, "Failed to get pwdn-gpios\n");
@@ -1535,7 +1568,11 @@ static void __exit sensor_mod_exit(void)
i2c_del_driver(&gc2093_i2c_driver);
}
#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
subsys_initcall(sensor_mod_init);
#else
device_initcall_sync(sensor_mod_init);
#endif
module_exit(sensor_mod_exit);
MODULE_DESCRIPTION("Galaxycore GC2093 Image Sensor driver");