mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
Merge commit 'dddd9eb669ee835e62a13c1ac6703efa77776fb2'
* commit 'dddd9eb669ee835e62a13c1ac6703efa77776fb2': drm/rockchip: vop2: Clear vcstate output_type when crtc disable ARM: dts: rockchip: rk3506: Set mac_ptp_ref clocks rate 62.5M defaultly firmware: rockchip_sip: allocate a separate stack for fiq-debugger callback firmware: rockchip_sip: don't update fiq_target_cpu in sip_fiq_debugger_uart_irq_tf_init pinctrl: rockchip: add debug information when switching pinctrl to gpio. media: rockchip: isp: add RKISP_VICAP_CMD_SOF cmd include: rkcif-config: add commands to support get sensor exp media: i2c: imx415 support get exp info from sensor register include: rk-camera-module.h add cmd to get sensor exp and delay info ARM: dts: rockchip: rk3506g-iotest: add IR transmit mode for pwm test pwm: rockchip: add support for IR NEC transmit Change-Id: I930dd167377e51bfa1027dfd667a5f687159e498
This commit is contained in:
@@ -79,6 +79,9 @@
|
||||
resets = <&cru SRST_A_MAC0>;
|
||||
reset-names = "stmmaceth";
|
||||
|
||||
assigned-clocks = <&cru CLK_MAC0_PTP>;
|
||||
assigned-clock-rates = <62500000>;
|
||||
|
||||
snps,mixed-burst;
|
||||
snps,tso;
|
||||
|
||||
@@ -130,6 +133,9 @@
|
||||
resets = <&cru SRST_A_MAC1>;
|
||||
reset-names = "stmmaceth";
|
||||
|
||||
assigned-clocks = <&cru CLK_MAC1_PTP>;
|
||||
assigned-clock-rates = <62500000>;
|
||||
|
||||
snps,mixed-burst;
|
||||
snps,tso;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef IR_TRANSMIT_TEST
|
||||
/ {
|
||||
pwm_rockchip_test: pwm-rockchip-test {
|
||||
compatible = "pwm-rockchip-test";
|
||||
@@ -32,6 +33,7 @@
|
||||
"pwm1_7";
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
/* use GPIO0_B0 ~ GPIO0_C3(rm_io8 ~ rm_io19) by default */
|
||||
&pwm0_4ch_0 {
|
||||
@@ -159,3 +161,37 @@
|
||||
assigned-clock-rates = <100000000>;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef IR_TRANSMIT_TEST
|
||||
&pwm1_8ch_0 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_1 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_2 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_3 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_4 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_5 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_6 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
|
||||
&pwm1_8ch_7 {
|
||||
rockchip,pwm-ir-transmit;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -366,13 +366,17 @@ EXPORT_SYMBOL_GPL(sip_hdcp_config);
|
||||
*/
|
||||
#ifdef CONFIG_ARM64
|
||||
#define SIP_UARTDBG_FN SIP_UARTDBG_CFG64
|
||||
#define SIP_FIQ_DBG_STACK_SIZE IRQ_STACK_SIZE
|
||||
#else
|
||||
#define SIP_UARTDBG_FN SIP_UARTDBG_CFG
|
||||
#define SIP_FIQ_DBG_STACK_SIZE SZ_8K
|
||||
|
||||
static int firmware_64_32bit;
|
||||
#endif
|
||||
|
||||
static int fiq_sip_enabled;
|
||||
static int fiq_target_cpu;
|
||||
static unsigned long fiq_stack_top;
|
||||
static phys_addr_t ft_fiq_mem_phy;
|
||||
static void __iomem *ft_fiq_mem_base;
|
||||
static sip_fiq_debugger_uart_irq_tf_cb_t sip_fiq_debugger_uart_irq_tf;
|
||||
@@ -481,13 +485,26 @@ int sip_fiq_debugger_uart_irq_tf_init(u32 irq_id, sip_fiq_debugger_uart_irq_tf_c
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
fiq_target_cpu = 0;
|
||||
/* Alloc a page for fiq_debugger's stack */
|
||||
if (fiq_stack_top == 0) {
|
||||
fiq_stack_top = __get_free_pages(GFP_KERNEL | __GFP_ZERO,
|
||||
get_order(SIP_FIQ_DBG_STACK_SIZE));
|
||||
if (fiq_stack_top) {
|
||||
fiq_stack_top += SIP_FIQ_DBG_STACK_SIZE;
|
||||
} else {
|
||||
pr_err("%s: alloc stack failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* init fiq debugger callback */
|
||||
sip_fiq_debugger_uart_irq_tf = callback_fn;
|
||||
res = __invoke_sip_fn_smc(SIP_UARTDBG_FN, irq_id,
|
||||
(unsigned long)sip_fiq_debugger_uart_irq_tf_cb,
|
||||
UARTDBG_CFG_INIT);
|
||||
arm_smccc_smc(SIP_UARTDBG_FN,
|
||||
irq_id,
|
||||
(unsigned long)sip_fiq_debugger_uart_irq_tf_cb,
|
||||
UARTDBG_CFG_INIT,
|
||||
fiq_stack_top, 0, 0, 0, &res);
|
||||
|
||||
if (IS_SIP_ERROR(res.a0)) {
|
||||
pr_err("%s error: %d\n", __func__, (int)res.a0);
|
||||
return res.a0;
|
||||
|
||||
@@ -5267,6 +5267,7 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
vop2->active_display_mask &= ~BIT(vp->id);
|
||||
vcstate->splice_mode = false;
|
||||
vcstate->output_flags = 0;
|
||||
vcstate->output_type = 0;
|
||||
vp->splice_mode_right = false;
|
||||
vp->loader_protect = false;
|
||||
splice_vp->splice_mode_right = false;
|
||||
|
||||
@@ -247,6 +247,11 @@ struct imx415 {
|
||||
struct cam_sw_info *cam_sw_inf;
|
||||
int rhs1_old;
|
||||
int rhs2_old;
|
||||
u32 cur_exposure[3];
|
||||
u32 cur_gain[3];
|
||||
u32 pclk;
|
||||
u32 tline;
|
||||
bool is_tline_init;
|
||||
};
|
||||
|
||||
static struct rkmodule_csi_dphy_param dcphy_param = {
|
||||
@@ -1626,6 +1631,123 @@ static void imx415_get_module_inf(struct imx415 *imx415,
|
||||
strlcpy(inf->base.lens, imx415->len_name, sizeof(inf->base.lens));
|
||||
}
|
||||
|
||||
static void imx415_get_pclk_and_tline(struct imx415 *imx415)
|
||||
{
|
||||
const struct imx415_mode *mode = imx415->cur_mode;
|
||||
|
||||
imx415->pclk = (u32)div_u64((u64)mode->hts_def * mode->vts_def *
|
||||
mode->max_fps.denominator, mode->max_fps.numerator);
|
||||
imx415->tline = (u32)div_u64((u64)mode->hts_def * 1000000000, imx415->pclk);
|
||||
}
|
||||
|
||||
static void imx415_hdr_exposure_readback(struct imx415 *imx415)
|
||||
{
|
||||
u32 shr, shr_l, shr_m, shr_h;
|
||||
u32 rhs, rhs_l, rhs_m, rhs_h;
|
||||
u32 gain, gain_l, gain_h;
|
||||
int ret = 0;
|
||||
|
||||
if (!imx415->is_tline_init) {
|
||||
imx415_get_pclk_and_tline(imx415);
|
||||
imx415->is_tline_init = true;
|
||||
}
|
||||
|
||||
ret = imx415_read_reg(imx415->client, IMX415_LF_EXPO_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &shr_l);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_LF_EXPO_REG_M,
|
||||
IMX415_REG_VALUE_08BIT, &shr_m);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_LF_EXPO_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &shr_h);
|
||||
if (!ret) {
|
||||
shr = (shr_h << 16) | (shr_m << 8) | shr_l;
|
||||
imx415->cur_exposure[0] = (imx415->cur_vts - shr) * imx415->tline;
|
||||
} else {
|
||||
dev_err(&imx415->client->dev,
|
||||
"imx415 get exposure of long frame failed!\n");
|
||||
}
|
||||
ret = imx415_read_reg(imx415->client, IMX415_LF_GAIN_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &gain_h);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_LF_GAIN_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &gain_l);
|
||||
if (!ret) {
|
||||
gain = (gain_h << 8) | gain_l;
|
||||
imx415->cur_gain[0] = gain * 300;//step=0.3db,factor=1000
|
||||
} else {
|
||||
dev_err(&imx415->client->dev,
|
||||
"imx415 get gain of long frame failed!\n");
|
||||
}
|
||||
|
||||
ret = imx415_read_reg(imx415->client, IMX415_SF1_EXPO_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &shr_l);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_SF1_EXPO_REG_M,
|
||||
IMX415_REG_VALUE_08BIT, &shr_m);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_SF1_EXPO_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &shr_h);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_RHS1_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &rhs_l);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_RHS1_REG_M,
|
||||
IMX415_REG_VALUE_08BIT, &rhs_m);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_RHS1_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &rhs_h);
|
||||
if (!ret) {
|
||||
shr = (shr_h << 16) | (shr_m << 8) | shr_l;
|
||||
rhs = (rhs_h << 16) | (rhs_m << 8) | rhs_l;
|
||||
imx415->cur_exposure[1] = (rhs - shr) * imx415->tline;
|
||||
} else {
|
||||
dev_err(&imx415->client->dev,
|
||||
"imx415 get exposure of %s frame failed!\n",
|
||||
imx415->cur_mode->hdr_mode == HDR_X2 ?
|
||||
"short" : "middle");
|
||||
}
|
||||
ret = imx415_read_reg(imx415->client, IMX415_SF1_GAIN_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &gain_h);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_SF1_GAIN_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &gain_l);
|
||||
if (!ret) {
|
||||
gain = (gain_h << 8) | gain_l;
|
||||
imx415->cur_gain[1] = gain * 300;//step=0.3db,factor=1000
|
||||
} else {
|
||||
dev_err(&imx415->client->dev,
|
||||
"imx415 get gain of %s frame failed!\n",
|
||||
imx415->cur_mode->hdr_mode == HDR_X2 ?
|
||||
"short" : "middle");
|
||||
}
|
||||
|
||||
if (imx415->cur_mode->hdr_mode == HDR_X3) {
|
||||
ret = imx415_read_reg(imx415->client, IMX415_SF2_EXPO_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &shr_l);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_SF2_EXPO_REG_M,
|
||||
IMX415_REG_VALUE_08BIT, &shr_m);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_SF2_EXPO_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &shr_h);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_RHS2_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &rhs_l);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_RHS2_REG_M,
|
||||
IMX415_REG_VALUE_08BIT, &rhs_m);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_RHS2_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &rhs_h);
|
||||
if (!ret) {
|
||||
shr = (shr_h << 16) | (shr_m << 8) | shr_l;
|
||||
rhs = (rhs_h << 16) | (rhs_m << 8) | rhs_l;
|
||||
imx415->cur_exposure[2] = (rhs - shr) * imx415->tline;
|
||||
} else {
|
||||
dev_err(&imx415->client->dev,
|
||||
"imx415 get exposure of short frame failed!\n");
|
||||
}
|
||||
ret = imx415_read_reg(imx415->client, IMX415_SF2_GAIN_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &gain_h);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_SF2_GAIN_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &gain_l);
|
||||
if (!ret) {
|
||||
gain = (gain_h << 8) | gain_l;
|
||||
imx415->cur_gain[2] = gain * 300;//step=0.3db,factor=1000
|
||||
} else {
|
||||
dev_err(&imx415->client->dev,
|
||||
"imx415 get gain of short frame failed!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int imx415_set_hdrae_3frame(struct imx415 *imx415,
|
||||
struct preisp_hdrae_exp_s *ae)
|
||||
{
|
||||
@@ -1877,6 +1999,7 @@ static int imx415_set_hdrae_3frame(struct imx415 *imx415,
|
||||
|
||||
ret |= imx415_write_reg(client, IMX415_GROUP_HOLD_REG,
|
||||
IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_END);
|
||||
imx415_hdr_exposure_readback(imx415);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2035,6 +2158,7 @@ static int imx415_set_hdrae(struct imx415 *imx415,
|
||||
|
||||
ret |= imx415_write_reg(client, IMX415_GROUP_HOLD_REG,
|
||||
IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_END);
|
||||
imx415_hdr_exposure_readback(imx415);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2060,6 +2184,9 @@ static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
u64 pixel_rate = 0;
|
||||
struct rkmodule_csi_dphy_param *dphy_param;
|
||||
u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
struct rkmodule_exp_delay *exp_delay;
|
||||
struct rkmodule_exp_info *exp_info;
|
||||
int idx_max = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case PREISP_CMD_SET_HDRAE_EXP:
|
||||
@@ -2152,6 +2279,30 @@ static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
} else
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
case RKMODULE_GET_EXP_DELAY:
|
||||
exp_delay = (struct rkmodule_exp_delay *)arg;
|
||||
exp_delay->exp_delay = 2;
|
||||
exp_delay->gain_delay = 2;
|
||||
exp_delay->vts_delay = 1;
|
||||
break;
|
||||
case RKMODULE_GET_EXP_INFO:
|
||||
exp_info = (struct rkmodule_exp_info *)arg;
|
||||
if (imx415->cur_mode->hdr_mode == NO_HDR)
|
||||
idx_max = 1;
|
||||
else if (imx415->cur_mode->hdr_mode == HDR_X2)
|
||||
idx_max = 2;
|
||||
else
|
||||
idx_max = 3;
|
||||
for (i = 0; i < idx_max; i++) {
|
||||
exp_info->exp[i] = imx415->cur_exposure[i];
|
||||
exp_info->gain[i] = imx415->cur_gain[i];
|
||||
}
|
||||
exp_info->hts = imx415->cur_mode->hts_def;
|
||||
exp_info->vts = imx415->cur_vts;
|
||||
exp_info->pclk = imx415->pclk;
|
||||
exp_info->gain_mode.gain_mode = RKMODULE_GAIN_MODE_DB;
|
||||
exp_info->gain_mode.factor = 1000;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
@@ -2174,6 +2325,8 @@ static long imx415_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
u32 stream;
|
||||
u32 brl = 0;
|
||||
struct rkmodule_csi_dphy_param *dphy_param;
|
||||
struct rkmodule_exp_delay *exp_delay;
|
||||
struct rkmodule_exp_info *exp_info;
|
||||
|
||||
switch (cmd) {
|
||||
case RKMODULE_GET_MODULE_INFO:
|
||||
@@ -2292,7 +2445,36 @@ static long imx415_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
}
|
||||
kfree(dphy_param);
|
||||
break;
|
||||
case RKMODULE_GET_EXP_DELAY:
|
||||
exp_delay = kzalloc(sizeof(*exp_delay), GFP_KERNEL);
|
||||
if (!exp_delay) {
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = imx415_ioctl(sd, cmd, exp_delay);
|
||||
if (!ret) {
|
||||
ret = copy_to_user(up, exp_delay, sizeof(*exp_delay));
|
||||
if (ret)
|
||||
ret = -EFAULT;
|
||||
}
|
||||
kfree(exp_delay);
|
||||
break;
|
||||
case RKMODULE_GET_EXP_INFO:
|
||||
exp_info = kzalloc(sizeof(*exp_info), GFP_KERNEL);
|
||||
if (!exp_info) {
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = imx415_ioctl(sd, cmd, exp_info);
|
||||
if (!ret) {
|
||||
ret = copy_to_user(up, exp_info, sizeof(*exp_info));
|
||||
if (ret)
|
||||
ret = -EFAULT;
|
||||
}
|
||||
kfree(exp_info);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
@@ -2302,7 +2484,6 @@ static long imx415_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int __imx415_start_stream(struct imx415 *imx415)
|
||||
{
|
||||
int ret;
|
||||
@@ -2315,6 +2496,7 @@ static int __imx415_start_stream(struct imx415 *imx415)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
imx415_get_pclk_and_tline(imx415);
|
||||
|
||||
/* In case these controls are set before streaming */
|
||||
ret = __v4l2_ctrl_handler_setup(&imx415->ctrl_handler);
|
||||
@@ -2340,6 +2522,7 @@ static int __imx415_stop_stream(struct imx415 *imx415)
|
||||
imx415->has_init_exp = false;
|
||||
if (imx415->is_thunderboot)
|
||||
imx415->is_first_streamoff = true;
|
||||
imx415->is_tline_init = false;
|
||||
return imx415_write_reg(imx415->client, IMX415_REG_CTRL_MODE,
|
||||
IMX415_REG_VALUE_08BIT, 1);
|
||||
}
|
||||
@@ -2697,6 +2880,48 @@ static const struct v4l2_subdev_ops imx415_subdev_ops = {
|
||||
.pad = &imx415_pad_ops,
|
||||
};
|
||||
|
||||
static void imx415_exposure_readback(struct imx415 *imx415)
|
||||
{
|
||||
u32 shr, shr_l, shr_m, shr_h;
|
||||
int ret = 0;
|
||||
|
||||
if (!imx415->is_tline_init) {
|
||||
imx415_get_pclk_and_tline(imx415);
|
||||
imx415->is_tline_init = true;
|
||||
}
|
||||
|
||||
ret = imx415_read_reg(imx415->client, IMX415_LF_EXPO_REG_L,
|
||||
IMX415_REG_VALUE_08BIT, &shr_l);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_LF_EXPO_REG_M,
|
||||
IMX415_REG_VALUE_08BIT, &shr_m);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_LF_EXPO_REG_H,
|
||||
IMX415_REG_VALUE_08BIT, &shr_h);
|
||||
if (!ret) {
|
||||
shr = (shr_h << 16) | (shr_m << 8) | shr_l;
|
||||
imx415->cur_exposure[0] = (imx415->cur_vts - shr) * imx415->tline;
|
||||
}
|
||||
}
|
||||
|
||||
static void imx415_gain_readback(struct imx415 *imx415)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 gain, gain_l, gain_h;
|
||||
|
||||
if (!imx415->is_tline_init) {
|
||||
imx415_get_pclk_and_tline(imx415);
|
||||
imx415->is_tline_init = true;
|
||||
}
|
||||
|
||||
ret = imx415_read_reg(imx415->client, IMX415_LF_GAIN_REG_H,
|
||||
IMX415_REG_VALUE_08BIT,
|
||||
&gain_h);
|
||||
ret |= imx415_read_reg(imx415->client, IMX415_LF_GAIN_REG_L,
|
||||
IMX415_REG_VALUE_08BIT,
|
||||
&gain_l);
|
||||
gain = (gain_h << 8) | gain_l;
|
||||
imx415->cur_gain[0] = gain * 300;//step=0.3db,factor=1000
|
||||
}
|
||||
|
||||
static int imx415_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct imx415 *imx415 = container_of(ctrl->handler,
|
||||
@@ -2738,6 +2963,7 @@ static int imx415_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
ret |= imx415_write_reg(imx415->client, IMX415_LF_EXPO_REG_H,
|
||||
IMX415_REG_VALUE_08BIT,
|
||||
IMX415_FETCH_EXP_H(shr0));
|
||||
imx415_exposure_readback(imx415);
|
||||
dev_dbg(&client->dev, "set exposure(shr0) %d = cur_vts(%d) - val(%d)\n",
|
||||
shr0, imx415->cur_vts, ctrl->val);
|
||||
break;
|
||||
@@ -2750,6 +2976,7 @@ static int imx415_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
ret |= imx415_write_reg(imx415->client, IMX415_LF_GAIN_REG_L,
|
||||
IMX415_REG_VALUE_08BIT,
|
||||
IMX415_FETCH_GAIN_L(ctrl->val));
|
||||
imx415_gain_readback(imx415);
|
||||
dev_dbg(&client->dev, "set analog gain 0x%x\n",
|
||||
ctrl->val);
|
||||
break;
|
||||
@@ -2871,12 +3098,10 @@ static int imx415_initialize_controls(struct imx415 *imx415)
|
||||
V4L2_CID_EXPOSURE, IMX415_EXPOSURE_MIN,
|
||||
exposure_max, IMX415_EXPOSURE_STEP,
|
||||
mode->exp_def);
|
||||
|
||||
imx415->anal_a_gain = v4l2_ctrl_new_std(handler, &imx415_ctrl_ops,
|
||||
V4L2_CID_ANALOGUE_GAIN, IMX415_GAIN_MIN,
|
||||
IMX415_GAIN_MAX, IMX415_GAIN_STEP,
|
||||
IMX415_GAIN_DEFAULT);
|
||||
|
||||
v4l2_ctrl_new_std(handler, &imx415_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
v4l2_ctrl_new_std(handler, &imx415_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
|
||||
@@ -2889,6 +3114,7 @@ static int imx415_initialize_controls(struct imx415 *imx415)
|
||||
|
||||
imx415->subdev.ctrl_handler = handler;
|
||||
imx415->has_init_exp = false;
|
||||
imx415->is_tline_init = false;
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#define RKISP_VICAP_CMD_HW_LINK \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 6, int)
|
||||
|
||||
#define RKISP_VICAP_CMD_SOF \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 7, struct rkisp_vicap_sof)
|
||||
|
||||
#define RKISP_VICAP_BUF_CNT 3
|
||||
#define RKISP_VICAP_BUF_CNT_MAX 8
|
||||
#define RKISP_RX_BUF_POOL_MAX (RKISP_VICAP_BUF_CNT_MAX * 3)
|
||||
@@ -90,4 +93,19 @@ struct rkisp_rx_buf {
|
||||
bool is_uncompact;
|
||||
};
|
||||
|
||||
struct rkisp_vicap_sof {
|
||||
u64 timestamp;
|
||||
u32 sequence;
|
||||
u32 exp[3];
|
||||
u32 gain[3];
|
||||
u32 hts;
|
||||
u32 vts;
|
||||
u32 pclk;
|
||||
__u32 dcg_used;
|
||||
__u32 dcg_val[3];
|
||||
struct rkmodule_dcg_ratio dcg_ratio;
|
||||
struct rkmodule_gain_mode gain_mode;
|
||||
bool is_exp_active;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4238,8 +4238,19 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct rockchip_pin_bank *bank;
|
||||
struct pin_desc *desc;
|
||||
int mux, pin = offset % 32;
|
||||
static unsigned long bitmap[BITS_TO_LONGS(2048)];
|
||||
|
||||
bank = pin_to_bank(info, offset);
|
||||
mux = rockchip_get_mux(bank, pin);
|
||||
desc = pin_desc_get(pctldev, offset);
|
||||
if (offset < 2048 && !test_bit(offset, bitmap) && desc->mux_owner && mux) {
|
||||
set_bit(offset, bitmap);
|
||||
WARN(1, "pin %u already requested by %s; switch mux %d to GPIO\n",
|
||||
offset, desc->mux_owner, mux);
|
||||
}
|
||||
|
||||
return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/pwm-rockchip.h>
|
||||
#include <linux/time.h>
|
||||
#include <media/rc-core.h>
|
||||
#include "pwm-rockchip-irq-callbacks.h"
|
||||
|
||||
#define PWM_MAX_CHANNEL_NUM 8
|
||||
|
||||
#define PWM_IR_TRANSMIT_BUFFER_SIZE 7
|
||||
|
||||
/*
|
||||
* regs for pwm v1-v3
|
||||
*/
|
||||
@@ -101,6 +104,9 @@
|
||||
#define CLK_PRESCALE(v) HIWORD_UPDATE(v, 0, 2)
|
||||
#define CLK_SCALE(v) HIWORD_UPDATE(v, 4, 12)
|
||||
#define CLK_SRC_SEL(v) HIWORD_UPDATE(v, 13, 14)
|
||||
#define SRC_CLK_PWM 0
|
||||
#define SRC_CLK_PWM_OSC 1
|
||||
#define SRC_CLK_PWM_RC 2
|
||||
#define CLK_GLOBAL_SEL(v) HIWORD_UPDATE(v, 15, 15)
|
||||
/* CTRL */
|
||||
#define CTRL_V4 0xc
|
||||
@@ -220,6 +226,46 @@
|
||||
#define GLOBAL_CTRL 0xc4
|
||||
#define GLOBAL_PWM_EN(v) HIWORD_UPDATE(v, 0, 0)
|
||||
#define GLOBAL_PWM_UPDATE_EN(v) HIWORD_UPDATE(v, 1, 1)
|
||||
/* IR_TRANS_ARBITER */
|
||||
#define IR_TRANS_ARBITER 0x180
|
||||
#define IR_TRANS_GRANT_SHIFT 0
|
||||
#define IR_TRANS_READ_LOCK_SHIFT 16
|
||||
/* IR_TRANS_CTRL0 */
|
||||
#define IR_TRANS_CTRL0 0x184
|
||||
#define IR_TRANS_OUT_ENABLE(v) HIWORD_UPDATE(v, 0, 0)
|
||||
#define IR_TRANS_DUTY_POL(v) HIWORD_UPDATE(v, 1, 1)
|
||||
#define IR_TRANS_INACTIVE_POL(v) HIWORD_UPDATE(v, 2, 2)
|
||||
#define IR_TRANS_MODE(v) HIWORD_UPDATE(v, 3, 3)
|
||||
#define IR_TRANS_FORMAT(v) HIWORD_UPDATE(v, 4, 7)
|
||||
#define NEC_WITH_SIMPLE_REPEAT_CODE 0
|
||||
#define NEC_WITH_FULL_REPEAT_CODE 1
|
||||
#define TC9012 2
|
||||
#define SONY 3
|
||||
/* IR_TRANS_CTRL1 */
|
||||
#define IR_TRANS_CTRL1 0x188
|
||||
#define IR_TRANS_RPT(v) HIWORD_UPDATE(v, 0, 15)
|
||||
/* IR_TRANS_PRE */
|
||||
#define IR_TRANS_PRE 0x18c
|
||||
#define IR_TRANS_OUT_LOW_PRELOAD_SHIFT 0
|
||||
#define IR_TRANS_OUT_HIGH_PRELOAD_SHIFT 16
|
||||
/* IR_TRANS_SPRE */
|
||||
#define IR_TRANS_SPRE 0x190
|
||||
#define IR_TRANS_OUT_HIGH_SIMPLE_PRELOAD_SHIFT 0
|
||||
/* IR_TRANS_LD */
|
||||
#define IR_TRANS_LD 0x194
|
||||
#define IR_TRANS_OUT_DATA_LOW_PERIOD_SHIFT 0
|
||||
/* IR_TRANS_HD */
|
||||
#define IR_TRANS_HD 0x198
|
||||
#define IR_TRANS_OUT_HIGH_PERIOD_FOR_ZERO_SHIFT 0
|
||||
#define IR_TRANS_OUT_HIGH_PERIOD_FOR_ONE_SHIFT 16
|
||||
/* IR_TRANS_BURST_FRAME */
|
||||
#define IR_TRANS_BURST_FRAME 0x19c
|
||||
#define IR_TRANS_OUT_FRAME_PERIOD_SHIFT 0
|
||||
#define IR_TRANS_OUT_FRAME_PERIOD_MASK (0x3ffff << IR_TRANS_OUT_FRAME_PERIOD_SHIFT)
|
||||
#define IR_TRANS_OUT_BURST_PERIOD_SHIFT 20
|
||||
/* IR_TRANS_DATA_VALUE */
|
||||
#define IR_TRANS_DATA_VALUE 0x1a0
|
||||
#define IR_TRANS_OUT_VALUE_SHIFT 0
|
||||
/* FREQ_ARBITER */
|
||||
#define FREQ_ARBITER 0x1c0
|
||||
#define FREQ_GRANT_SHIFT 0
|
||||
@@ -264,6 +310,7 @@ struct rockchip_pwm_chip {
|
||||
const struct rockchip_pwm_biphasic_config *biphasic_config;
|
||||
struct resource *res;
|
||||
struct dentry *debugfs;
|
||||
struct completion ir_trans_completion;
|
||||
void __iomem *base;
|
||||
unsigned long clk_rate;
|
||||
unsigned long is_clk_enabled;
|
||||
@@ -273,6 +320,7 @@ struct rockchip_pwm_chip {
|
||||
bool capture_en;
|
||||
bool wave_en;
|
||||
bool global_ctrl_grant;
|
||||
bool ir_trans_support;
|
||||
bool freq_meter_support;
|
||||
bool counter_support;
|
||||
bool wave_support;
|
||||
@@ -322,6 +370,7 @@ struct rockchip_pwm_funcs {
|
||||
struct rockchip_pwm_biphasic_config *config);
|
||||
int (*get_biphasic_result)(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
unsigned long *biphasic_res);
|
||||
int (*ir_transmit)(struct pwm_chip *chip, unsigned int *txbuf, unsigned int count);
|
||||
irqreturn_t (*irq_handler)(int irq, void *data);
|
||||
};
|
||||
|
||||
@@ -713,6 +762,13 @@ static irqreturn_t rockchip_pwm_irq_v4(int irq, void *data)
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (val & IR_TRANS_END_INT) {
|
||||
writel_relaxed(IR_TRANS_END_INT, pc->base + INTSTS);
|
||||
complete(&pc->ir_trans_completion);
|
||||
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1844,6 +1900,143 @@ int rockchip_pwm_get_biphasic_result(struct pwm_device *pwm, unsigned long *biph
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rockchip_pwm_get_biphasic_result);
|
||||
|
||||
#ifdef CONFIG_RC_CORE
|
||||
static int rockchip_pwm_ir_transmit_v4(struct pwm_chip *chip, unsigned int *txbuf,
|
||||
unsigned int count)
|
||||
{
|
||||
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
|
||||
u32 arbiter;
|
||||
u32 preload, spreload;
|
||||
u32 low_period, high_period;
|
||||
u32 tx_value;
|
||||
u32 timeout_ms;
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
|
||||
if (count != PWM_IR_TRANSMIT_BUFFER_SIZE) {
|
||||
dev_err(chip->dev, "Unsupported ir transmit buf size: %d\n", count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = clk_enable(pc->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
arbiter = BIT(pc->channel_id) << IR_TRANS_READ_LOCK_SHIFT |
|
||||
BIT(pc->channel_id) << IR_TRANS_GRANT_SHIFT;
|
||||
writel_relaxed(arbiter, pc->base + IR_TRANS_ARBITER);
|
||||
val = readl_relaxed(pc->base + IR_TRANS_ARBITER);
|
||||
if (!(val & arbiter)) {
|
||||
dev_err(chip->dev, "Failed to abtain ir transmit arbitration for PWM%d\n",
|
||||
pc->channel_id);
|
||||
ret = -EINVAL;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
reinit_completion(&pc->ir_trans_completion);
|
||||
|
||||
/*
|
||||
* Each value in the txbuf[] is in microseconds(us).
|
||||
* txbuf[0]: the low duration of NEC leader code.
|
||||
* txbuf[1]: the high duration of NEC leader code.
|
||||
* txbuf[2]: the high duration of NEC repeat code.
|
||||
* txbuf[3]: the low duration of NEC logic '0' and '1'.
|
||||
* txbuf[4]: the high duration of NEC logic '0'.
|
||||
* txbuf[5]: the high duration of NEC logic '1'.
|
||||
* txbuf[6]:
|
||||
* bit[31:24] bit[23:16] bit[15:8] bit[7:0]
|
||||
* address code address inverted code command code command inverted code
|
||||
*/
|
||||
preload = txbuf[0] << IR_TRANS_OUT_LOW_PRELOAD_SHIFT |
|
||||
txbuf[1] << IR_TRANS_OUT_HIGH_PRELOAD_SHIFT;
|
||||
spreload = txbuf[2] << IR_TRANS_OUT_HIGH_SIMPLE_PRELOAD_SHIFT;
|
||||
low_period = txbuf[3] << IR_TRANS_OUT_DATA_LOW_PERIOD_SHIFT;
|
||||
high_period = txbuf[4] << IR_TRANS_OUT_HIGH_PERIOD_FOR_ZERO_SHIFT |
|
||||
txbuf[5] << IR_TRANS_OUT_HIGH_PERIOD_FOR_ONE_SHIFT;
|
||||
tx_value = txbuf[6] << IR_TRANS_OUT_VALUE_SHIFT;
|
||||
|
||||
/* Set the dclk to 1M */
|
||||
writel_relaxed(CLK_SCALE(0x32), pc->base + CLK_CTRL);
|
||||
writel_relaxed(PWM_CLK_EN(true), pc->base + ENABLE);
|
||||
writel_relaxed(IR_TRANS_END_INT_EN(true), pc->base + INT_EN);
|
||||
|
||||
writel_relaxed(preload, pc->base + IR_TRANS_PRE);
|
||||
writel_relaxed(spreload, pc->base + IR_TRANS_SPRE);
|
||||
writel_relaxed(low_period, pc->base + IR_TRANS_LD);
|
||||
writel_relaxed(high_period, pc->base + IR_TRANS_HD);
|
||||
writel_relaxed(tx_value, pc->base + IR_TRANS_DATA_VALUE);
|
||||
|
||||
val = readl_relaxed(pc->base + IR_TRANS_BURST_FRAME);
|
||||
timeout_ms = ((val & IR_TRANS_OUT_FRAME_PERIOD_MASK) >>
|
||||
IR_TRANS_OUT_FRAME_PERIOD_SHIFT) / 1000;
|
||||
|
||||
writel_relaxed(IR_TRANS_INACTIVE_POL(true) | IR_TRANS_OUT_ENABLE(true),
|
||||
pc->base + IR_TRANS_CTRL0);
|
||||
|
||||
ret = wait_for_completion_timeout(&pc->ir_trans_completion,
|
||||
msecs_to_jiffies(timeout_ms * 3 / 2));
|
||||
if (!ret) {
|
||||
dev_err(chip->dev, "Failed to wait for PWM%d ir transmit to complete\n",
|
||||
pc->channel_id);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
writel_relaxed(IR_TRANS_OUT_ENABLE(false), pc->base + IR_TRANS_CTRL0);
|
||||
writel_relaxed(IR_TRANS_END_INT_EN(false), pc->base + INT_EN);
|
||||
writel_relaxed(PWM_CLK_EN(false), pc->base + ENABLE);
|
||||
writel_relaxed(0, pc->base + IR_TRANS_ARBITER);
|
||||
|
||||
err_clk:
|
||||
clk_disable(pc->clk);
|
||||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
|
||||
static int rockchip_pwm_ir_transmit(struct rc_dev *dev, unsigned int *txbuf, unsigned int count)
|
||||
{
|
||||
struct rockchip_pwm_chip *pc = dev->priv;
|
||||
struct pwm_chip *chip = &pc->chip;
|
||||
struct pwm_state curstate;
|
||||
int ret;
|
||||
|
||||
if (!pc->data->funcs.ir_transmit) {
|
||||
dev_err(chip->dev, "Unsupported ir transmit mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pwm_get_state(&pc->chip.pwms[0], &curstate);
|
||||
if (curstate.enabled) {
|
||||
dev_err(chip->dev, "Failed to enable ir transmit mode because PWM%d is busy\n",
|
||||
pc->channel_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
|
||||
if (ret) {
|
||||
dev_err(chip->dev, "Failed to select pinctrl state\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(pc->pclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pc->data->funcs.ir_transmit(chip, txbuf, count);
|
||||
if (ret < 0)
|
||||
dev_err(chip->dev, "Failed to transmit ir buf\n");
|
||||
|
||||
clk_disable(pc->pclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rockchip_pwm_ir_transmit_v4(struct pwm_chip *chip, unsigned int *txbuf,
|
||||
unsigned int count)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int rockchip_pwm_debugfs_show(struct seq_file *s, void *data)
|
||||
{
|
||||
@@ -2034,6 +2227,7 @@ static const struct rockchip_pwm_data pwm_data_v4 = {
|
||||
.set_wave = rockchip_pwm_set_wave_v4,
|
||||
.set_biphasic = rockchip_pwm_set_biphasic_v4,
|
||||
.get_biphasic_result = rockchip_pwm_get_biphasic_result_v4,
|
||||
.ir_transmit = rockchip_pwm_ir_transmit_v4,
|
||||
.irq_handler = rockchip_pwm_irq_v4,
|
||||
},
|
||||
};
|
||||
@@ -2140,6 +2334,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
|
||||
if (pc->main_version >= 4) {
|
||||
version = readl_relaxed(pc->base + pc->data->regs.version);
|
||||
pc->channel_id = (version & CHANNLE_INDEX_MASK) >> CHANNLE_INDEX_SHIFT;
|
||||
pc->ir_trans_support = !!(version & IR_TRANS_SUPPORT);
|
||||
pc->freq_meter_support = !!(version & FREQ_METER_SUPPORT);
|
||||
pc->counter_support = !!(version & COUNTER_SUPPORT);
|
||||
pc->wave_support = !!(version & WAVE_SUPPORT);
|
||||
@@ -2218,6 +2413,27 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RC_CORE
|
||||
if (pc->ir_trans_support &&
|
||||
device_property_present(&pdev->dev, "rockchip,pwm-ir-transmit")) {
|
||||
struct rc_dev *rcdev;
|
||||
|
||||
init_completion(&pc->ir_trans_completion);
|
||||
|
||||
rcdev = devm_rc_allocate_device(&pdev->dev, RC_DRIVER_IR_RAW_TX);
|
||||
if (!rcdev)
|
||||
goto err_pclk;
|
||||
|
||||
rcdev->priv = pc;
|
||||
rcdev->driver_name = "rockchip-pwm-ir-tx";
|
||||
rcdev->device_name = "Rockchip IR TX";
|
||||
rcdev->tx_ir = rockchip_pwm_ir_transmit;
|
||||
ret = devm_rc_register_device(&pdev->dev, rcdev);
|
||||
if (ret < 0)
|
||||
goto err_pclk;
|
||||
}
|
||||
#endif
|
||||
|
||||
rockchip_pwm_debugfs_init(pc);
|
||||
|
||||
/* Keep the PWM clk enabled if the PWM appears to be up and running. */
|
||||
|
||||
@@ -198,6 +198,12 @@
|
||||
#define RKCIS_CMD_SELECT_SETTING \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 44, struct rk_sensor_setting)
|
||||
|
||||
#define RKMODULE_GET_EXP_DELAY \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 45, struct rkmodule_exp_delay)
|
||||
|
||||
#define RKMODULE_GET_EXP_INFO \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 46, struct rkmodule_exp_info)
|
||||
|
||||
struct rkmodule_i2cdev_info {
|
||||
__u8 slave_addr;
|
||||
} __attribute__ ((packed));
|
||||
@@ -856,4 +862,37 @@ struct rk_sensor_setting {
|
||||
__u32 mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rkmodule_exp_delay {
|
||||
__u32 exp_delay;
|
||||
__u32 gain_delay;
|
||||
__u32 vts_delay;
|
||||
__u32 dcg_delay;
|
||||
__u32 reserved[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum rkmodule_gain_mode_e {
|
||||
RKMODULE_GAIN_MODE_LINEAR,
|
||||
RKMODULE_GAIN_MODE_DB,
|
||||
};
|
||||
|
||||
struct rkmodule_gain_mode {
|
||||
__u32 gain_mode;
|
||||
__u32 factor;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rkmodule_exp_info {
|
||||
__u32 exp[3];
|
||||
__u32 gain[3];
|
||||
__u32 exp_reg[3];
|
||||
__u32 gain_reg[3];
|
||||
__u32 hts;
|
||||
__u32 vts;
|
||||
__u32 pclk;
|
||||
__u32 dcg_used;
|
||||
__u32 dcg_val[3];
|
||||
struct rkmodule_dcg_ratio dcg_ratio;
|
||||
struct rkmodule_gain_mode gain_mode;
|
||||
__u32 reserved[6];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* _UAPI_RKMODULE_CAMERA_H */
|
||||
|
||||
@@ -83,6 +83,9 @@
|
||||
#define RKCIF_CMD_SET_SENSOR_FLIP_END \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE + 21, int)
|
||||
|
||||
#define RKCIF_CMD_SUPPORT_GET_EXP \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE + 22, int)
|
||||
|
||||
/* cif memory mode
|
||||
* 0: raw12/raw10/raw8 8bit memory compact
|
||||
* 1: raw12/raw10 16bit memory one pixel
|
||||
|
||||
Reference in New Issue
Block a user