460 lines
14 KiB
C
460 lines
14 KiB
C
/*
|
|
* linux-3.10/drivers/media/platform/sunxi-vin/vin-csi/csi_reg.c
|
|
*
|
|
* Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
******************************************************************************
|
|
*
|
|
* csi_reg.c
|
|
*
|
|
* Hawkview ISP - csi_reg.c module
|
|
*
|
|
* Copyright (c) 2014 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
|
|
*
|
|
* Version Author Date Description
|
|
*
|
|
* 2.0 Yang Feng 2014/07/15 Second Version
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include "csi_reg_i.h"
|
|
#include "csi_reg.h"
|
|
|
|
#include "../utility/vin_io.h"
|
|
|
|
|
|
#if defined CONFIG_ARCH_SUN8IW11P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 0 /*0:RISING, 1:FAILING*/
|
|
|
|
volatile void __iomem *csi_base_addr[2];
|
|
enum csi_input_fmt input_fmt;
|
|
|
|
int csi_set_base_addr(unsigned int sel, unsigned long addr)
|
|
{
|
|
if (sel > MAX_CSI - 1)
|
|
return -1;
|
|
csi_base_addr[sel] = (volatile void __iomem *)addr;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* open module */
|
|
void csi_enable(unsigned int sel)
|
|
{
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_EN, 0x1);
|
|
}
|
|
|
|
void csi_disable(unsigned int sel)
|
|
{
|
|
vin_reg_clr(csi_base_addr[sel] + CSI_REG_EN, 0X1 << 0);
|
|
}
|
|
|
|
/* configure */
|
|
void csi_if_cfg(unsigned int sel, struct csi_if_cfg *csi_if_cfg)
|
|
{
|
|
if (csi_if_cfg->interface == CSI_IF_CCIR656_16BIT) {
|
|
input_fmt = CSI_YUV422_16;
|
|
} else if (csi_if_cfg->interface == CSI_IF_CCIR656_1CH) {
|
|
input_fmt = CSI_CCIR656;
|
|
} else if (csi_if_cfg->interface == CSI_IF_CCIR656_2CH) {
|
|
input_fmt = CSI_CCIR656_2CH;
|
|
} else if (csi_if_cfg->interface == CSI_IF_CCIR656_4CH) {
|
|
input_fmt = CSI_CCIR656_4CH;
|
|
}
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_REG_CONF,
|
|
0x7 << 20,
|
|
input_fmt << 20);/*[22:20]*/
|
|
}
|
|
|
|
void csi_timing_cfg(unsigned int sel, struct csi_timing_cfg *csi_tmg_cfg)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_REG_CONF, 0x7,
|
|
csi_tmg_cfg->vref << 2 | /* [2] */
|
|
csi_tmg_cfg->href << 1 | /* [1] */
|
|
(csi_tmg_cfg->sample == CLK_POL)); /* [0] */
|
|
}
|
|
|
|
void csi_fmt_cfg(unsigned int sel, unsigned int ch,
|
|
struct csi_fmt_cfg *csi_fmt_cfg)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_REG_CONF,
|
|
0x7 << 20 | 0xf << 16 | 0x3 << 10 | 0x3 << 8,
|
|
csi_fmt_cfg->input_fmt << 20 | /* [21:20] */
|
|
csi_fmt_cfg->output_fmt << 16 | /* [18:16] */
|
|
csi_fmt_cfg->field_sel << 10 | /* [11:10] */
|
|
csi_fmt_cfg->input_seq << 8); /* [9:8] */
|
|
input_fmt = csi_fmt_cfg->input_fmt;
|
|
}
|
|
|
|
/* buffer */
|
|
void csi_set_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf, u64 addr)
|
|
{
|
|
/*bufer0a +4 = buffer0b, bufer0a +8 = buffer1a*/
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_BUF_0_A + (buf << 2), addr);
|
|
}
|
|
|
|
u64 csi_get_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf)
|
|
{
|
|
u32 t;
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_BUF_0_A + (buf << 2));
|
|
return t;
|
|
}
|
|
|
|
/* capture */
|
|
void csi_capture_start(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode)
|
|
{
|
|
if (CSI_VCAP == csi_cap_mode)
|
|
vin_reg_set(csi_base_addr[sel] + CSI_REG_CTRL, 0X1 << 1);
|
|
else
|
|
vin_reg_set(csi_base_addr[sel] + CSI_REG_CTRL, 0X1 << 0);
|
|
}
|
|
|
|
void csi_capture_stop(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode)
|
|
{
|
|
vin_reg_clr(csi_base_addr[sel] + CSI_REG_CTRL, 0X3);
|
|
}
|
|
|
|
void csi_capture_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_capture_status *status)
|
|
{
|
|
u32 t;
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_STATUS);
|
|
status->picture_in_progress = t & 0x1;
|
|
status->video_in_progress = (t >> 1) & 0x1;
|
|
}
|
|
|
|
/* size */
|
|
void csi_set_size(unsigned int sel, unsigned int ch, unsigned int length_h,
|
|
unsigned int length_v, unsigned int buf_length_h,
|
|
unsigned int buf_length_c)
|
|
{
|
|
u32 t;
|
|
|
|
switch (input_fmt) {
|
|
case CSI_CCIR656:
|
|
case CSI_CCIR656_2CH:
|
|
case CSI_CCIR656_4CH:
|
|
case CSI_YUV422_16:
|
|
case CSI_YUV422:
|
|
length_h = length_h * 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_RESIZE_H + ch * CSI_CH_OFF);
|
|
t = (t & 0x0000ffff) | (length_h << 16);
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_RESIZE_H + ch * CSI_CH_OFF, t);
|
|
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_RESIZE_V + ch * CSI_CH_OFF);
|
|
t = (t & 0x0000ffff) | (length_v << 16);
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_RESIZE_V + ch * CSI_CH_OFF, t);
|
|
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_BUF_LENGTH + ch * CSI_CH_OFF, buf_length_h);
|
|
|
|
}
|
|
|
|
/* offset */
|
|
void csi_set_offset(unsigned int sel, unsigned int ch, unsigned int start_h,
|
|
unsigned int start_v)
|
|
{
|
|
u32 t;
|
|
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_RESIZE_H + ch * CSI_CH_OFF);
|
|
t = (t & 0xffff0000) | start_h;
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_RESIZE_H + ch * CSI_CH_OFF, t);
|
|
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_RESIZE_V + ch * CSI_CH_OFF);
|
|
t = (t & 0xffff0000) | start_v;
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_RESIZE_V + ch * CSI_CH_OFF, t);
|
|
}
|
|
|
|
/* interrupt */
|
|
void csi_int_enable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt)
|
|
{
|
|
vin_reg_set(csi_base_addr[sel] + CSI_REG_INT_EN, interrupt);
|
|
}
|
|
|
|
void csi_int_disable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt)
|
|
{
|
|
vin_reg_clr(csi_base_addr[sel] + CSI_REG_INT_EN, interrupt);
|
|
}
|
|
|
|
inline void csi_int_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_int_status *status)
|
|
{
|
|
u32 t;
|
|
t = vin_reg_readl(csi_base_addr[sel] + CSI_REG_INT_STATUS);
|
|
|
|
status->capture_done = t & CSI_INT_CAPTURE_DONE;
|
|
status->frame_done = t & CSI_INT_FRAME_DONE;
|
|
status->buf_0_overflow = t & CSI_INT_BUF_0_OVERFLOW;
|
|
status->buf_1_overflow = t & CSI_INT_BUF_1_OVERFLOW;
|
|
status->buf_2_overflow = t & CSI_INT_BUF_2_OVERFLOW;
|
|
status->protection_error = t & CSI_INT_PROTECTION_ERROR;
|
|
status->hblank_overflow = t & CSI_INT_HBLANK_OVERFLOW;
|
|
status->vsync_trig = t & CSI_INT_VSYNC_TRIG;
|
|
}
|
|
|
|
inline void csi_int_clear_status(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt)
|
|
{
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_REG_INT_STATUS, interrupt);
|
|
}
|
|
|
|
#else
|
|
|
|
#if defined CONFIG_ARCH_SUN8IW1P1
|
|
#define ADDR_BIT_R_SHIFT 0
|
|
#define CLK_POL 0
|
|
#elif defined CONFIG_ARCH_SUN8IW3P1
|
|
#define ADDR_BIT_R_SHIFT 0
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN9IW1P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN8IW5P1
|
|
#define ADDR_BIT_R_SHIFT 0
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN8IW6P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN8IW7P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN8IW8P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN8IW9P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN50IW1P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#elif defined CONFIG_ARCH_SUN8IW10P1
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#else
|
|
#define ADDR_BIT_R_SHIFT 2
|
|
#define CLK_POL 1
|
|
#endif
|
|
|
|
volatile void __iomem *csi_base_addr[2];
|
|
|
|
int csi_set_base_addr(unsigned int sel, unsigned long addr)
|
|
{
|
|
if (sel > MAX_CSI - 1)
|
|
return -1;
|
|
csi_base_addr[sel] = (volatile void __iomem *)addr;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* open module */
|
|
void csi_enable(unsigned int sel)
|
|
{
|
|
vin_reg_set(csi_base_addr[sel] + CSI_EN_REG_OFF,
|
|
1 << CSI_EN_REG_CSI_EN);
|
|
}
|
|
|
|
void csi_disable(unsigned int sel)
|
|
{
|
|
vin_reg_clr(csi_base_addr[sel] + CSI_EN_REG_OFF,
|
|
1 << CSI_EN_REG_CSI_EN);
|
|
}
|
|
|
|
/* configure */
|
|
void csi_if_cfg(unsigned int sel, struct csi_if_cfg *csi_if_cfg)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_SRC_TYPE_MASK,
|
|
csi_if_cfg->src_type << CSI_IF_CFG_REG_SRC_TYPE);
|
|
|
|
if (csi_if_cfg->interface < 0x80)
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_CSI_IF_MASK,
|
|
csi_if_cfg->interface << CSI_IF_CFG_REG_CSI_IF);
|
|
else
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_MIPI_IF_MASK,
|
|
1 << CSI_IF_CFG_REG_MIPI_IF);
|
|
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_IF_DATA_WIDTH_MASK,
|
|
csi_if_cfg->data_width << CSI_IF_CFG_REG_IF_DATA_WIDTH);
|
|
}
|
|
|
|
void csi_timing_cfg(unsigned int sel, struct csi_timing_cfg *csi_tmg_cfg)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_VREF_POL_MASK,
|
|
csi_tmg_cfg->vref << CSI_IF_CFG_REG_VREF_POL);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_HREF_POL_MASK,
|
|
csi_tmg_cfg->href << CSI_IF_CFG_REG_HREF_POL);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_CLK_POL_MASK,
|
|
((csi_tmg_cfg->sample ==
|
|
CLK_POL) ? 1 : 0) << CSI_IF_CFG_REG_CLK_POL);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_IF_CFG_REG_OFF,
|
|
CSI_IF_CFG_REG_FIELD_MASK,
|
|
csi_tmg_cfg->field << CSI_IF_CFG_REG_FIELD);
|
|
}
|
|
|
|
void csi_fmt_cfg(unsigned int sel, unsigned int ch,
|
|
struct csi_fmt_cfg *csi_fmt_cfg)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_CFG_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_CFG_REG_INPUT_FMT_MASK,
|
|
csi_fmt_cfg->input_fmt << CSI_CH_CFG_REG_INPUT_FMT);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_CFG_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_CFG_REG_OUTPUT_FMT_MASK,
|
|
csi_fmt_cfg->output_fmt << CSI_CH_CFG_REG_OUTPUT_FMT);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_CFG_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_CFG_REG_FIELD_SEL_MASK,
|
|
csi_fmt_cfg->field_sel << CSI_CH_CFG_REG_FIELD_SEL);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_CFG_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_CFG_REG_INPUT_SEQ_MASK,
|
|
csi_fmt_cfg->input_seq << CSI_CH_CFG_REG_INPUT_SEQ);
|
|
}
|
|
|
|
/* buffer */
|
|
void csi_set_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf, u64 addr)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_F0_BUFA_REG_OFF +
|
|
ch * CSI_CH_OFF + (buf << 2), 0xffffffff,
|
|
addr >> ADDR_BIT_R_SHIFT);
|
|
}
|
|
|
|
u64 csi_get_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf)
|
|
{
|
|
unsigned int reg_val =
|
|
vin_reg_readl(csi_base_addr[sel] + CSI_CH_F0_BUFA_REG_OFF +
|
|
ch * CSI_CH_OFF + (buf << 2));
|
|
return reg_val << ADDR_BIT_R_SHIFT;
|
|
}
|
|
|
|
/* capture */
|
|
void csi_capture_start(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode)
|
|
{
|
|
u32 reg_val = (((ch_total_num >= 4) ? csi_cap_mode : 0) << 24) +
|
|
(((ch_total_num >= 3) ? csi_cap_mode : 0) << 16) +
|
|
(((ch_total_num >= 2) ? csi_cap_mode : 0) << 8) +
|
|
(((ch_total_num >= 1) ? csi_cap_mode : 0));
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_CAP_REG_OFF, reg_val);
|
|
}
|
|
|
|
void csi_capture_stop(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode)
|
|
{
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_CAP_REG_OFF, 0);
|
|
}
|
|
|
|
void csi_capture_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_capture_status *status)
|
|
{
|
|
unsigned int reg_val =
|
|
vin_reg_readl(csi_base_addr[sel] + CSI_CH_STA_REG_OFF +
|
|
ch * CSI_CH_OFF);
|
|
status->picture_in_progress =
|
|
(reg_val >> CSI_CH_STA_REG_SCAP_STA) & 0x1;
|
|
status->video_in_progress = (reg_val >> CSI_CH_STA_REG_VCAP_STA) & 0x1;
|
|
}
|
|
|
|
/* size */
|
|
void csi_set_size(unsigned int sel, unsigned int ch, unsigned int length_h,
|
|
unsigned int length_v, unsigned int buf_length_y,
|
|
unsigned int buf_length_c)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_HSIZE_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_HSIZE_REG_HOR_LEN_MASK,
|
|
length_h << CSI_CH_HSIZE_REG_HOR_LEN);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_VSIZE_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_VSIZE_REG_VER_LEN_MASK,
|
|
length_v << CSI_CH_VSIZE_REG_VER_LEN);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_BUF_LEN_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_BUF_LEN_REG_BUF_LEN_MASK,
|
|
buf_length_y << CSI_CH_BUF_LEN_REG_BUF_LEN);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_BUF_LEN_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_BUF_LEN_REG_BUF_LEN_C_MASK,
|
|
buf_length_c << CSI_CH_BUF_LEN_REG_BUF_LEN_C);
|
|
}
|
|
|
|
/* offset */
|
|
void csi_set_offset(unsigned int sel, unsigned int ch, unsigned int start_h,
|
|
unsigned int start_v)
|
|
{
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_HSIZE_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_HSIZE_REG_HOR_START_MASK,
|
|
start_h << CSI_CH_HSIZE_REG_HOR_START);
|
|
vin_reg_clr_set(csi_base_addr[sel] + CSI_CH_VSIZE_REG_OFF +
|
|
ch * CSI_CH_OFF, CSI_CH_VSIZE_REG_VER_START_MASK,
|
|
start_v << CSI_CH_VSIZE_REG_VER_START);
|
|
}
|
|
|
|
/* interrupt */
|
|
void csi_int_enable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt)
|
|
{
|
|
vin_reg_set(csi_base_addr[sel] + CSI_CH_INT_EN_REG_OFF +
|
|
ch * CSI_CH_OFF, interrupt);
|
|
}
|
|
|
|
void csi_int_disable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt)
|
|
{
|
|
vin_reg_clr(csi_base_addr[sel] + CSI_CH_INT_EN_REG_OFF +
|
|
ch * CSI_CH_OFF, interrupt);
|
|
}
|
|
|
|
void csi_int_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_int_status *status)
|
|
{
|
|
unsigned int reg_val =
|
|
vin_reg_readl(csi_base_addr[sel] + CSI_CH_INT_STA_REG_OFF +
|
|
ch * CSI_CH_OFF);
|
|
status->capture_done = (reg_val >> CSI_CH_INT_STA_REG_CD_PD) & 0x1;
|
|
status->frame_done = (reg_val >> CSI_CH_INT_STA_REG_FD_PD) & 0x1;
|
|
status->buf_0_overflow =
|
|
(reg_val >> CSI_CH_INT_STA_REG_FIFO0_OF_PD) & 0x1;
|
|
status->buf_1_overflow =
|
|
(reg_val >> CSI_CH_INT_STA_REG_FIFO1_OF_PD) & 0x1;
|
|
status->buf_2_overflow =
|
|
(reg_val >> CSI_CH_INT_STA_REG_FIFO2_OF_PD) & 0x1;
|
|
status->protection_error =
|
|
(reg_val >> CSI_CH_INT_STA_REG_PRTC_ERR_PD) & 0x1;
|
|
status->hblank_overflow =
|
|
(reg_val >> CSI_CH_INT_STA_REG_HB_OF_PD) & 0x1;
|
|
status->vsync_trig = (reg_val >> CSI_CH_INT_STA_REG_VS_PD) & 0x1;
|
|
}
|
|
|
|
void csi_int_clear_status(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt)
|
|
{
|
|
vin_reg_writel(csi_base_addr[sel] + CSI_CH_INT_STA_REG_OFF, interrupt);
|
|
}
|
|
#endif
|