mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
media: i2c: gc2093 support fastboot
Signed-off-by: Sisyphean Zhou <sisyphean.zhou@rock-chips.com> Change-Id: I3245ba187df5ddcc8c5a97e3098e1436e62d7e9d
This commit is contained in:
committed by
Tao Huang
parent
97e91ee429
commit
fc49bfda1b
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user