393 lines
10 KiB
C
393 lines
10 KiB
C
/*
|
|
* sunxi csi register read/write interface header file
|
|
*
|
|
* Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
|
|
*
|
|
* Authors: Zhao Wei <zhaowei@allwinnertech.com>
|
|
* Yang Feng <yangfeng@allwinnertech.com>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef __CSI__REG__H__
|
|
#define __CSI__REG__H__
|
|
|
|
#include <linux/types.h>
|
|
#include <media/sunxi_camera_v2.h>
|
|
|
|
#define MAX_CSI 2
|
|
/*
|
|
* CSI configure
|
|
*/
|
|
|
|
/*
|
|
* if format
|
|
*/
|
|
enum csi_if {
|
|
CSI_IF_INTLV = 0x00, /* 1SEG DATA in one channel */
|
|
CSI_IF_SPL = 0x01, /* 2SEG Y in one ch, UV in second ch */
|
|
CSI_IF_PL = 0x02, /* 3SEG YUV444 */
|
|
CSI_IF_PL_SPL = 0x03, /* 3SEG YUV444 to 2SEG YUV422 */
|
|
|
|
CSI_IF_CCIR656_1CH = 0x04, /* 1SEG ccir656 1ch */
|
|
CSI_IF_CCIR656_1CH_SPL = 0x05, /* 2SEG ccir656 1ch */
|
|
CSI_IF_CCIR656_1CH_PL = 0x06, /* 3SEG ccir656 1ch */
|
|
CSI_IF_CCIR656_1CH_PL_SPL = 0x07, /* 3SEG to 2SEG ccir656 1ch */
|
|
CSI_IF_CCIR656_16BIT = 0x08, /* 16BIT ccir656 1ch */
|
|
|
|
CSI_IF_CCIR656_2CH = 0x0c, /* D7~D0:ccir656 2ch */
|
|
CSI_IF_CCIR656_4CH = 0x0d, /* D7~D0:ccir656 4ch */
|
|
|
|
CSI_IF_MIPI = 0x80, /* MIPI CSI */
|
|
};
|
|
|
|
/*
|
|
* data width
|
|
*/
|
|
enum csi_data_width {
|
|
CSI_8BIT = 0,
|
|
CSI_10BIT = 1,
|
|
CSI_12BIT = 2,
|
|
};
|
|
|
|
/*
|
|
* input data format
|
|
*/
|
|
enum csi_input_fmt {
|
|
CSI_RAW = 0, /* raw stream */
|
|
CSI_BAYER, /* byer rgb242 */
|
|
CSI_CCIR656, /* ccir656 */
|
|
CSI_YUV422, /* yuv422 */
|
|
CSI_YUV422_16 = 4, /* yuv422 16 bit */
|
|
CSI_YUV444 = 4, /* yuv444 24 bit */
|
|
CSI_YUV420 = 4, /* yuv420 */
|
|
CSI_CCIR656_2CH = 5, /* ccir656 2 channel */
|
|
CSI_CCIR656_4CH = 7, /* ccir656 4 channel */
|
|
};
|
|
|
|
/*
|
|
* output data format
|
|
*/
|
|
enum csi_output_fmt {
|
|
/* only when input is raw */
|
|
CSI_FIELD_RAW_8 = 0,
|
|
CSI_FIELD_RAW_10 = 1,
|
|
CSI_FIELD_RAW_12 = 2,
|
|
CSI_FIELD_RGB565 = 4,
|
|
CSI_FIELD_RGB888 = 5,
|
|
CSI_FIELD_PRGB888 = 6,
|
|
CSI_FRAME_RAW_8 = 8,
|
|
CSI_FRAME_RAW_10 = 9,
|
|
CSI_FRAME_RAW_12 = 10,
|
|
CSI_FRAME_RGB565 = 12,
|
|
CSI_FRAME_RGB888 = 13,
|
|
CSI_FRAME_PRGB888 = 14,
|
|
|
|
/* only when input is bayer */
|
|
|
|
/* only when input is yuv422/yuv420 */
|
|
CSI_FIELD_PLANAR_YUV422 = 0, /* parse 1 field (odd or even) */
|
|
CSI_FIELD_PLANAR_YUV420 = 1,
|
|
CSI_FRAME_PLANAR_YUV420 = 2, /* parse 2 fields (odd and even) */
|
|
CSI_FRAME_PLANAR_YUV422 = 3,
|
|
CSI_FIELD_UV_CB_YUV422 = 4,
|
|
CSI_FIELD_UV_CB_YUV420 = 5,
|
|
CSI_FRAME_UV_CB_YUV420 = 6,
|
|
CSI_FRAME_UV_CB_YUV422 = 7,
|
|
CSI_FIELD_MB_YUV422 = 8,
|
|
CSI_FIELD_MB_YUV420 = 9,
|
|
CSI_FRAME_MB_YUV420 = 10,
|
|
CSI_FRAME_MB_YUV422 = 11,
|
|
CSI_FIELD_UV_CB_YUV422_10 = 12,
|
|
CSI_FIELD_UV_CB_YUV420_10 = 13,
|
|
};
|
|
|
|
/*
|
|
* field sequenc or polarity
|
|
*/
|
|
|
|
enum csi_field {
|
|
/* For Embedded Sync timing */
|
|
CSI_FIELD_TF = 0, /* top filed first */
|
|
CSI_FIELD_BF = 1, /* bottom field first */
|
|
|
|
/* For External Sync timing */
|
|
CSI_FIELD_NEG = 0, /* field negtive indicates odd field */
|
|
CSI_FIELD_POS = 1, /* field postive indicates odd field */
|
|
};
|
|
|
|
/*
|
|
* input field selection, only when input is ccir656
|
|
*/
|
|
enum csi_field_sel {
|
|
CSI_ODD, /* odd field */
|
|
CSI_EVEN, /* even field */
|
|
CSI_EITHER, /* either field */
|
|
};
|
|
|
|
/*
|
|
* input source type
|
|
*/
|
|
enum csi_src_type {
|
|
CSI_PROGRESSIVE = 0, /* progressive */
|
|
CSI_INTERLACE = 1, /* interlace */
|
|
};
|
|
|
|
/*
|
|
* input data sequence
|
|
*/
|
|
enum csi_input_seq {
|
|
/* only when input is yuv422 */
|
|
CSI_YUYV = 0,
|
|
CSI_YVYU,
|
|
CSI_UYVY,
|
|
CSI_VYUY,
|
|
|
|
/* only when input is byer */
|
|
CSI_RGRG = 0, /* first line sequence is RGRG... */
|
|
CSI_GRGR, /* first line sequence is GRGR... */
|
|
CSI_BGBG, /* first line sequence is BGBG... */
|
|
CSI_GBGB, /* first line sequence is GBGB... */
|
|
};
|
|
|
|
/*
|
|
* input reference signal polarity
|
|
*/
|
|
enum csi_ref_pol {
|
|
CSI_LOW, /* active low */
|
|
CSI_HIGH, /* active high */
|
|
};
|
|
|
|
/*
|
|
* input data valid of the input clock edge type
|
|
*/
|
|
enum csi_edge_pol {
|
|
CSI_FALLING, /* active falling */
|
|
CSI_RISING, /* active rising */
|
|
};
|
|
|
|
/*
|
|
* csi interface configuration
|
|
*/
|
|
struct csi_if_cfg {
|
|
enum csi_src_type src_type; /* interlaced or progressive */
|
|
enum csi_data_width data_width; /* csi data width */
|
|
enum csi_if interface; /* csi interface */
|
|
};
|
|
|
|
/*
|
|
* csi timing configuration
|
|
*/
|
|
struct csi_timing_cfg {
|
|
enum csi_field field; /* top or bottom field first / field polarity */
|
|
enum csi_ref_pol vref; /* input vref signal polarity */
|
|
enum csi_ref_pol href; /* input href signal polarity */
|
|
enum csi_edge_pol sample; /* the valid input clock edge */
|
|
};
|
|
|
|
/*
|
|
* csi size and offset configuration
|
|
*/
|
|
struct csi_size_offset_cfg {
|
|
unsigned int length_h;
|
|
unsigned int length_v;
|
|
unsigned int length_y;
|
|
unsigned int length_c;
|
|
unsigned int start_h;
|
|
unsigned int start_v;
|
|
};
|
|
|
|
/*
|
|
* csi mode configuration
|
|
*/
|
|
struct csi_fmt_cfg {
|
|
enum csi_input_fmt input_fmt; /* input data format */
|
|
enum csi_output_fmt output_fmt; /* output data format */
|
|
enum csi_field_sel field_sel; /* input field selection */
|
|
enum csi_input_seq input_seq; /* input data sequence */
|
|
enum csi_data_width data_width; /* csi data width */
|
|
};
|
|
|
|
/*
|
|
* csi buffer
|
|
*/
|
|
|
|
enum csi_buf_sel {
|
|
CSI_BUF_0_A = 0, /* FIFO for Y address A */
|
|
CSI_BUF_0_B, /* FIFO for Y address B */
|
|
CSI_BUF_1_A, /* FIFO for Cb address A */
|
|
CSI_BUF_1_B, /* FIFO for Cb address B */
|
|
CSI_BUF_2_A, /* FIFO for Cr address A */
|
|
CSI_BUF_2_B, /* FIFO for Cr address B */
|
|
};
|
|
|
|
/*
|
|
* csi buffer configs
|
|
*/
|
|
|
|
struct csi_buf_cfg {
|
|
enum csi_buf_sel buf_sel;
|
|
unsigned long addr;
|
|
};
|
|
|
|
/*
|
|
* csi capture status
|
|
*/
|
|
struct csi_capture_status {
|
|
_Bool picture_in_progress;
|
|
_Bool video_in_progress;
|
|
};
|
|
|
|
enum csi_cap_mode {
|
|
CSI_SCAP = 1,
|
|
CSI_VCAP,
|
|
};
|
|
|
|
/*
|
|
* csi interrupt
|
|
*/
|
|
enum csi_int_sel {
|
|
CSI_INT_CAPTURE_DONE = 0X1,
|
|
CSI_INT_FRAME_DONE = 0X2,
|
|
CSI_INT_BUF_0_OVERFLOW = 0X4,
|
|
CSI_INT_BUF_1_OVERFLOW = 0X8,
|
|
CSI_INT_BUF_2_OVERFLOW = 0X10,
|
|
CSI_INT_PROTECTION_ERROR = 0X20,
|
|
CSI_INT_HBLANK_OVERFLOW = 0X40,
|
|
CSI_INT_VSYNC_TRIG = 0X80,
|
|
CSI_INT_ALL = 0XFF,
|
|
};
|
|
|
|
/*
|
|
* csi interrupt status
|
|
*/
|
|
struct csi_int_status {
|
|
_Bool capture_done;
|
|
_Bool frame_done;
|
|
_Bool buf_0_overflow;
|
|
_Bool buf_1_overflow;
|
|
_Bool buf_2_overflow;
|
|
_Bool protection_error;
|
|
_Bool hblank_overflow;
|
|
_Bool vsync_trig;
|
|
};
|
|
|
|
struct vin_csi_fmt_cfg {
|
|
unsigned long ch;
|
|
struct csi_fmt_cfg fmt;
|
|
struct csi_size_offset_cfg so;
|
|
};
|
|
|
|
struct vin_csi_buf_cfg {
|
|
unsigned long ch;
|
|
unsigned long set;
|
|
struct csi_buf_cfg buf;
|
|
};
|
|
|
|
struct vin_csi_cap_mode {
|
|
unsigned long total_ch;
|
|
unsigned long on;
|
|
enum csi_cap_mode mode;
|
|
};
|
|
|
|
struct vin_csi_cap_status {
|
|
unsigned long ch;
|
|
struct csi_capture_status status;
|
|
};
|
|
|
|
struct vin_csi_int_cfg {
|
|
unsigned long ch;
|
|
unsigned long en;
|
|
enum csi_int_sel sel;
|
|
};
|
|
|
|
#if defined CONFIG_ARCH_SUN8IW11P1
|
|
|
|
#define CSI_REG_EN (0x00)
|
|
#define CSI_REG_CONF (0x04)
|
|
#define CSI_REG_CTRL (0x08)
|
|
#define CSI_REG_SCALE (0x0C)
|
|
#define CSI_REG_BUF_0_A (0x10)
|
|
#define CSI_REG_BUF_0_B (0x14)
|
|
#define CSI_REG_BUF_1_A (0x18)
|
|
#define CSI_REG_BUF_1_B (0x1C)
|
|
#define CSI_REG_BUF_2_A (0x20)
|
|
#define CSI_REG_BUF_2_B (0x24)
|
|
#define CSI_REG_BUF_CTRL (0x28)
|
|
#define CSI_REG_STATUS (0x2C)
|
|
#define CSI_REG_INT_EN (0x30)
|
|
#define CSI_REG_INT_STATUS (0x34)
|
|
#define CSI_REG_RESIZE_H (0x40)
|
|
#define CSI_REG_RESIZE_V (0x44)
|
|
#define CSI_REG_BUF_LENGTH (0x48)
|
|
|
|
#define CSI_CH_OFF (0x0100)
|
|
|
|
int csi_set_base_addr(unsigned int sel, unsigned long addr);
|
|
void csi_enable(unsigned int sel);
|
|
void csi_disable(unsigned int sel);
|
|
void csi_if_cfg(unsigned int sel, struct csi_if_cfg *csi_if_cfg);
|
|
void csi_timing_cfg(unsigned int sel, struct csi_timing_cfg *csi_tmg_cfg);
|
|
void csi_fmt_cfg(unsigned int sel, unsigned int ch,
|
|
struct csi_fmt_cfg *csi_fmt_cfg);
|
|
void csi_set_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf, u64 addr);
|
|
u64 csi_get_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf);
|
|
void csi_capture_start(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode);
|
|
void csi_capture_stop(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode);
|
|
void csi_capture_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_capture_status *status);
|
|
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);
|
|
void csi_set_offset(unsigned int sel, unsigned int ch, unsigned int start_h,
|
|
unsigned int start_v);
|
|
void csi_int_enable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt);
|
|
void csi_int_disable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt);
|
|
void csi_int_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_int_status *status);
|
|
void csi_int_clear_status(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt);
|
|
|
|
#else
|
|
|
|
int csi_set_base_addr(unsigned int sel, unsigned long addr);
|
|
void csi_enable(unsigned int sel);
|
|
void csi_disable(unsigned int sel);
|
|
void csi_if_cfg(unsigned int sel, struct csi_if_cfg *csi_if_cfg);
|
|
void csi_timing_cfg(unsigned int sel, struct csi_timing_cfg *csi_tmg_cfg);
|
|
void csi_fmt_cfg(unsigned int sel, unsigned int ch,
|
|
struct csi_fmt_cfg *csi_fmt_cfg);
|
|
void csi_set_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf, u64 addr);
|
|
u64 csi_get_buffer_address(unsigned int sel, unsigned int ch,
|
|
enum csi_buf_sel buf);
|
|
void csi_capture_start(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode);
|
|
void csi_capture_stop(unsigned int sel, unsigned int ch_total_num,
|
|
enum csi_cap_mode csi_cap_mode);
|
|
void csi_capture_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_capture_status *status);
|
|
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);
|
|
void csi_set_offset(unsigned int sel, unsigned int ch, unsigned int start_h,
|
|
unsigned int start_v);
|
|
void csi_int_enable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt);
|
|
void csi_int_disable(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt);
|
|
void csi_int_get_status(unsigned int sel, unsigned int ch,
|
|
struct csi_int_status *status);
|
|
void csi_int_clear_status(unsigned int sel, unsigned int ch,
|
|
enum csi_int_sel interrupt);
|
|
#endif
|
|
|
|
#endif
|