On Sat, Mar 15, 2014 at 11:29 AM, Ivan Kozic <[email protected]> wrote:
> Hi John,
>
> Wow thanks - this looks quite cool - it seems that they've started working
> on YUV422 16bit and CCIR656 as well. May I ask where did you find the
> driver?

It is from the current Allwinner Android tree. The CSI driver in sunxi
is about two years old.

sunxi kernel needs to be updated to use this driver.

> One crucial file is missing - sun4i_csi_core.h or sunxi_csi_core.h I guess,
> as it's not for A10 anymore.
>
>
> On Saturday, March 15, 2014 1:37:13 AM UTC+1, Jon Smirl wrote:
>>
>> I copied from the A10 manual.
>>
>> Here's a more recent driver....
>>
>> On Fri, Mar 14, 2014 at 7:36 PM, Ivan Kozic <[email protected]> wrote:
>> > Hi John - just saw your post. I think you're looking at a wrong
>> > document, as
>> > for A20, the register setting 100 for bits 22:20 is YUV422 16bit - it's
>> > written in the A20 User Manual on page 371. The problem is in fact this
>> > very
>> > vague information in the User Manual - it's almost useless. This is why
>> > I'm
>> > asking for help from someone who maybe knows the kernel a bit more - for
>> > instance, I'm not even sure which DMA is used for transfers from CSI to
>> > memory, because I have to figure it out from the driver.
>> >
>> > I'm also not sure where to search for the driver or more help. This
>> > group
>> > seems most professional of all by far - I have tried to contact
>> > Allwinner,
>> > but to no avail so far. As for sunxi kernel and drivers, I only know of
>> > the
>> > Git branch, but noone there has touched CSI driver for 8 months.
>> > Although I
>> > did always look in the 3.4 branch, maybe I should check out mainline...
>> >
>> > Anyway, I'll search for the actual solution myself and if I find it post
>> > back - If anyone can speed me up, I'll be most grateful.
>> >
>> >
>> > On Saturday, March 15, 2014 12:01:41 AM UTC+1, Jon Smirl wrote:
>> >>
>> >> I haven't tried any of this...
>> >>
>> >> Look like you would set the input format...
>> >>
>> >> 22:20 R/W 3 INPUT_FMT
>> >> Input data format
>> >> 000: RAW stream
>> >> 001: reserved
>> >> 010: CCIR656(one channel)
>> >> 011: YUV422
>> >> 100: YUV444({R, B, G} or {Pr, Pb, Y})
>> >>
>> >> When the input format is set YUV444
>> >> 1100: field planar YUV 444
>> >> 1101: field planar YUV 422 UV combined
>> >> 1110: frame planar YUV 444
>> >> 1111: frame planar YUV 422 UV combined
>> >>
>> >> The the output format is always 24b, right?
>> >>
>> >> You're going to have to read the user manual. I don't believe anyone
>> >> has played with this before. But it looks like the hardware supports
>> >> it.
>> >>
>> >> Also - the CSI driver in the sunxi tree is quite old. First thing I'd
>> >> do is update it using the most recent Allwinner CSI driver we can
>> >> locate. You might even get lucky and the newer Allwinner drivers could
>> >> support 16b.
>> >>
>> >>
>> >> On Fri, Mar 14, 2014 at 3:57 PM, Martin Collins <[email protected]>
>> >> wrote:
>> >> > On 2014-03-14 10:42, Ivan Kozic wrote:
>> >> >>
>> >> >> If someone knows something, please share - if I had some more
>> >> >> documentation, I would have probably already made the whole thing
>> >> >> work,
>> >> >
>> >> > I don't know anything, but by chance I was looking here today:
>> >> > http://dl.linux-sunxi.org/A10/
>> >> > My impression was that there is an 8 bit channel and a 24 bit
>> >> > channel.
>> >> > So perhaps it won't do 16 bits?
>> >> >
>> >> > Martin
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups "linux-sunxi" group.
>> >> > To unsubscribe from this group and stop receiving emails from it,
>> >> > send
>> >> > an email to [email protected].
>> >> > For more options, visit https://groups.google.com/d/optout.
>> >>
>> >>
>> >>
>> >> --
>> >> Jon Smirl
>> >> [email protected]
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "linux-sunxi" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an
>> > email to [email protected].
>> > For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
>> --
>> Jon Smirl
>> [email protected]
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.



-- 
Jon Smirl
[email protected]

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
/*
 * sun7i Camera core header file
 * Author:raymonxiu
*/
#ifndef _SUN7I_CSI_CORE_H_
#define _SUN7I_CSI_CORE_H_

#include <linux/types.h>
#include <media/videobuf-core.h>
#include <media/v4l2-device.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-mediabus.h>//linux-3.0
#include <mach/sys_config.h>

//for internel driver debug
#define DBG_EN   		0 	
//debug level 0~3
#define DBG_LEVEL 	3

//for internel driver debug
#if(DBG_EN==1)		
#define csi_dbg(l,x,arg...) if(l <= DBG_LEVEL) printk("[CSI_DEBUG]"x,##arg)
#else
#define csi_dbg(l,x,arg...) 
#endif

//print when error happens
#define csi_err(x,arg...) printk(KERN_INFO"[CSI_ERR]"x,##arg)

//print unconditional, for important info
#define csi_print(x,arg...) printk(KERN_INFO"[CSI]"x,##arg)

#define MAX_NUM_INPUTS 2

struct csi_subdev_info {
	const char *name;
	struct i2c_board_info board_info;
};

/*
 * input data format
 */
typedef enum tag_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_input_fmt_t;

/*
 * output data format
 */
typedef enum tag_CSI_OUTPUT_FMT
{
    /* only when input is raw */
    CSI_PASS_THROUTH = 0,                /* raw */

    /* only when input is bayer */
    CSI_PLANAR_RGB242 = 0,               /* planar rgb242 */

    /* only when input is ccir656 */
    CSI_FIELD_PLANAR_YUV422 = 0,         /* parse a field(odd or even) into planar yuv420 */
    CSI_FIELD_PLANAR_YUV420 = 1,         /* parse a field(odd or even) into planar yuv420 */
    CSI_FRAME_PLANAR_YUV420 = 2,
    CSI_FRAME_PLANAR_YUV422 = 3,
    CSI_FIELD_UV_CB_YUV422  = 4,         /* parse and reconstruct evry 2 fields(odd and even) into a frame, format is planar yuv420 */
    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_YUV422     = 10,
    CSI_FRAME_MB_YUV420     = 11,
    CSI_INTLC_INTLV_YUV422  = 15,

    /* only when input is yuv422 */
    CSI_PLANAR_YUV422=0,                /* parse yuv422 into planar yuv422 */
    CSI_PLANAR_YUV420=1,                /* parse yuv422 into planar yuv420 */
    CSI_UV_CB_YUV422=4,
    CSI_UV_CB_YUV420=5,
    CSI_MB_YUV422=8,
    CSI_MB_YUV420=9,
    
    /* only when input is yuv444 */
    CSI_FIELD_PLANAR_YUV444 			 = 0,         /* parse a field(odd or even) into planar yuv444 */
    CSI_FIELD_UV_CB_YUV444_YUV422 = 1,         /* parse a field(odd or even) into planar yuv422 */
    CSI_FRAME_PLANAR_YUV444 			 = 2,				
    CSI_FRAME_UV_CB_YUV444_YUV422 = 3,
    
}__csi_output_fmt_t;

/*
 * input field selection, only when input is ccir656
 */
typedef enum tag_CSI_FIELD_SEL
{
    CSI_ODD,    /* odd field */
    CSI_EVEN,   /* even field */
    CSI_EITHER, /* either field */
}__csi_field_sel_t;

/*
 * input data sequence
 */
typedef enum tag_CSI_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... */
}__csi_seq_t;

/*
 * input reference signal polarity
 */
typedef enum tag_CSI_REF
{
    CSI_LOW,    /* active low */
    CSI_HIGH,   /* active high */
}__csi_ref_t;

/*
 * input data valid of the input clock edge type
 */
typedef enum tag_CSI_CLK
{
    CSI_FALLING,    /* active falling */
    CSI_RISING,     /* active rising */
}__csi_clk_t;

/*
 * csi mode configuration
 */
typedef struct tag_CSI_CONF
{
    __csi_input_fmt_t  input_fmt;   /* input data format */
    __csi_output_fmt_t output_fmt;  /* output data format */
    __csi_field_sel_t  field_sel;   /* input field selection */
    __csi_seq_t        seq;         /* input data sequence */
    __csi_ref_t        vref;        /* input vref signal polarity */
    __csi_ref_t        href;        /* input href signal polarity */
    __csi_clk_t        clock;       /* input data valid of the input clock edge type */
}__csi_conf_t;



/*
 * csi buffer
 */

typedef enum tag_CSI_BUF
{
    CSI_BUF_0_A,    /* 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_buf_t;

/*
 * csi capture status
 */
typedef struct tag_CSI_CAPTURE_STATUS
{
    _Bool picture_in_progress;  
    _Bool video_in_progress;    
}__csi_capture_status;


/*
 * csi double buffer
 */
typedef enum tag_CSI_DOUBLE_BUF
{
    CSI_BUF_A,  
    CSI_BUF_B,
}__csi_double_buf_t;

/*
 * csi double buffer status
 */
typedef struct tag_CSI_DOUBLE_BUF_STATUS
{
    _Bool             enable;   /* double buffer enable */
    __csi_double_buf_t cur;     /* current frame selected output type, buffer A or B*/
    __csi_double_buf_t next;    /* next frame output type, buffer A or B */
}__csi_double_buf_status_t;

/*
 * csi interrupt
 */
typedef enum tag_CSI_INT
{
    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_t;

/*
 * csi interrupt status
 */
typedef struct tag_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;
}__csi_int_status_t;

typedef enum tag_CSI_IF
{
		CSI_IF_HV8 					= 0,
		CSI_IF_CCIR656_16 	= 1,
		CSI_IF_HV24 				= 2,
		CSI_IF_CCIR656			= 3,
		CSI_IF_CCIR656_2CH	= 4,
		CSI_IF_CCIR656_4CH 	= 5,
}__csi_if_t;

/*
 * csi sub device info
 */
typedef struct tag_CSI_SUBDEV_INFO
{
    int								 mclk;				/* the mclk frequency for sensor module in HZ unit*/
    __csi_ref_t        vref;        /* input vref signal polarity */
    __csi_ref_t        href;        /* input href signal polarity */
    __csi_clk_t        clock;       /* input data valid of the input clock edge type */
    int								 iocfg;				/*0 for csi back , 1 for csi front*/				
    int 							 stby_mode;			
}__csi_subdev_info_t;

struct csi_buf_addr {
	dma_addr_t	y;
	dma_addr_t	cb;
	dma_addr_t	cr;
};

struct csi_fmt {
	u8					name[32];
	__csi_if_t									csi_if;
	enum v4l2_mbus_pixelcode		ccm_fmt;//linux-3.0
	u32   											fourcc;          /* v4l2 format id */
	enum v4l2_field							field;
	__csi_input_fmt_t						input_fmt;	
	__csi_output_fmt_t 					output_fmt;	
	__csi_field_sel_t						csi_field;
	int   				depth;
	u16	  				planes_cnt;
};

struct csi_size{
	u32		csi_width;
	u32		csi_height;
};

/* buffer for one video frame */
struct csi_buffer {
	struct videobuf_buffer vb;
	struct csi_fmt        *fmt;
};

struct csi_dmaqueue {
	struct list_head active;
	
	/* Counters to control fps rate */
	int frame;
	int ini_jiffies;
};

static LIST_HEAD(csi_devlist);

struct ccm_config {
	char ccm[I2C_NAME_SIZE];
	char iovdd_str[32];
	char avdd_str[32];
	char dvdd_str[32];
	int twi_id;
	uint i2c_addr;
	int vflip;
	int hflip;
	int stby_mode;
	int interface;
	int flash_pol;		
//	user_gpio_set_t reset_io;
//	user_gpio_set_t standby_io;
//	user_gpio_set_t power_io;
//	user_gpio_set_t flash_io;
//	user_gpio_set_t af_power_io;
	//modified to 33
	struct gpio_config reset_io;
	struct gpio_config standby_io;
	struct gpio_config power_io;
	struct gpio_config flash_io;
	struct gpio_config af_power_io;
	
	struct regulator 	 *iovdd;		  /*interface voltage source of sensor module*/
	struct regulator 	 *avdd;			/*anlog voltage source of sensor module*/
	struct regulator 	 *dvdd;			/*core voltage source of sensor module*/

    //add by heyihang.Jan 15, 2013	
	uint vol_iovdd;
	uint vol_avdd;
	uint vol_dvdd;
	
	__csi_subdev_info_t ccm_info;  
	struct v4l2_subdev			*sd;
};

struct csi_dev {
	struct list_head       	csi_devlist;
	struct v4l2_device 	   	v4l2_dev;
	struct v4l2_subdev			*sd;
	struct platform_device	*pdev;

	int						id;
	
	spinlock_t              slock;

	/* various device info */
	struct video_device     *vfd;

	struct csi_dmaqueue     vidq;

	/* Several counters */
	unsigned 		   		ms;
	unsigned long           jiffies;

	/* Input Number */
	int			   			input;

	/* video capture */
	struct csi_fmt          *fmt;
	unsigned int            width;
	unsigned int            height;
	unsigned int						frame_size;
	struct videobuf_queue   vb_vidq;
	unsigned int 						capture_mode;
	
	/*working state*/
	unsigned long 		   	generating;
	int						opened;

	/*pin,clock,irq resource*/
	int							csi_pin_hd;

    //add by heyihang.Jan 17, 2013
    script_item_u     *csi_pin_list;
	int               csi_pin_cnt;
    
	struct clk				*csi_clk_src;
	struct clk				*csi_ahb_clk;
	struct clk				*csi_module_clk;
	struct clk				*csi_dram_clk;
	struct clk				*csi_isp_src_clk;
	struct clk				*csi_isp_clk;
	int						irq;
	void __iomem			*regs;
	struct resource			*regs_res;
	
	/*power issue*/
	
	int								 stby_mode;
	struct regulator 	 *iovdd;		  /*interface voltage source of sensor module*/
  struct regulator 	 *avdd;			/*anlog voltage source of sensor module*/
  struct regulator 	 *dvdd;			/*core voltage source of sensor module*/

    //add by heyihang.Jan 15, 2013
    uint vol_iovdd;
	uint vol_avdd;
	uint vol_dvdd;
    
	/* attribution */
	int interface;
	int vflip;
	int hflip;
	int flash_pol;
	
	/* csi io */
//	user_gpio_set_t reset_io;
//	user_gpio_set_t standby_io;
//	user_gpio_set_t power_io;
//	user_gpio_set_t flash_io;
//	user_gpio_set_t af_power_io;
	//modified to 33
	struct gpio_config reset_io;
	struct gpio_config standby_io;
	struct gpio_config power_io;
	struct gpio_config flash_io;
	struct gpio_config af_power_io;
	
	/*parameters*/
	__csi_conf_t			csi_mode;
	struct csi_buf_addr		csi_buf_addr;
	
	/* ccm config */
  int dev_qty;
	int module_flag;
	__csi_subdev_info_t *ccm_info;  /*current config*/
	struct ccm_config *ccm_cfg[MAX_NUM_INPUTS];
};

void  bsp_csi_open(struct csi_dev *dev);
void  bsp_csi_close(struct csi_dev *dev);
void  bsp_csi_configure(struct csi_dev *dev,__csi_conf_t *mode);
void	inline  bsp_csi_set_buffer_address(struct csi_dev *dev,__csi_buf_t buf, u32 addr);
u32		inline  bsp_csi_get_buffer_address(struct csi_dev *dev,__csi_buf_t buf);
void  bsp_csi_double_buffer_enable(struct csi_dev *dev);
void  bsp_csi_double_buffer_disable(struct csi_dev *dev);
void	inline  bsp_csi_double_buffer_select_next(struct csi_dev *dev,__csi_double_buf_t type);
void	inline  bsp_csi_double_buffer_get_status(struct csi_dev *dev,__csi_double_buf_status_t * status);
void  bsp_csi_capture_video_start(struct csi_dev *dev);
void  bsp_csi_capture_video_stop(struct csi_dev *dev);
void  bsp_csi_capture_picture(struct csi_dev *dev);
void  bsp_csi_capture_get_status(struct csi_dev *dev,__csi_capture_status * status);
void 	bsp_csi_set_size(struct csi_dev *dev, u32 length_h, u32 length_v, u32 buf_length_h);
void 	bsp_csi_set_offset(struct csi_dev *dev,u32 start_h, u32 start_v);
void  bsp_csi_int_enable(struct csi_dev *dev,__csi_int_t interrupt);
void  bsp_csi_int_disable(struct csi_dev *dev,__csi_int_t interrupt);
void 	inline 	bsp_csi_int_get_status(struct csi_dev *dev,__csi_int_status_t * status);
void 	inline bsp_csi_int_clear_status(struct csi_dev *dev,__csi_int_t interrupt);

#endif  /* _CSI_H_ */
#ifndef __DEV_CSI_H__
#define __DEV_CSI_H__


/*
 * ioctl to proccess sub device
 */
typedef enum tag_CSI_SUBDEV_CMD
{
	CSI_SUBDEV_CMD_GET_INFO = 0x01,
	CSI_SUBDEV_CMD_SET_INFO = 0x02,

    //add by heyihang.Jan 15, 2013
    CSI_SUBDEV_CMD_DETECT   = 0x03,
}__csi_subdev_cmd_t;

/*
 * control id
 */

typedef enum tag_CSI_SUBDEV_CTL_ID
{
	CSI_SUBDEV_INIT_FULL = 0x01,
	CSI_SUBDEV_INIT_SIMP = 0x02,
	CSI_SUBDEV_RST_ON = 0x03,
	CSI_SUBDEV_RST_OFF = 0x04,
	CSI_SUBDEV_RST_PUL = 0x05,
	CSI_SUBDEV_STBY_ON = 0x06,
	CSI_SUBDEV_STBY_OFF = 0x07,
	CSI_SUBDEV_PWR_ON = 0x08,
	CSI_SUBDEV_PWR_OFF = 0x09,
}__csi_subdev_ctl_id_t;
#endif

Reply via email to