aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/media/video/m5mols/m5mols.h
blob: 94022e27b3e3e926292808947df3e5d2f8741bf9 (plain) (tree)
1
2
3
4
5
6
7
8
  
                                                    

                                                   
                                                  

                                                   
                                                            












                                                                       



                                                                                          
 


                                                                 
 








                        






                               


















































                                           
                          



                                       

  


                                        

  





                       

  
















                                                                                 

  
                       





                                                       
  
 
                    
                                           
                             
                     


                                                            
 
                                               
                



                                                                         
          
























                                                       


                                                     

                                            
 








                                                                       

  
                   
   



                                                                   
 








































































































































































                                                                               
 
                                 
 

                                                    
                      
/*
 * Header for M5MOLS 8M Pixel camera sensor with ISP
 *
 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
 * Author: HeungJun Kim <riverful.kim@samsung.com>
 *
 * Copyright (C) 2009 Samsung Electronics Co., Ltd.
 * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#ifndef M5MOLS_H
#define M5MOLS_H

#include <media/v4l2-subdev.h>
#include "m5mols_reg.h"

#define M5MO_JPEG_MAXSIZE	0x3A0000
#define M5MO_THUMB_MAXSIZE	0xFC00
#define M5MO_POST_MAXSIZE	0xBB800
#define M5MO_JPEG_MEMSIZE	M5MO_JPEG_MAXSIZE + M5MO_THUMB_MAXSIZE + M5MO_POST_MAXSIZE

#define v4l2msg(fmt, arg...)	do {				\
	v4l2_dbg(1, m5mols_debug, &info->sd, fmt, ## arg);	\
} while (0)

extern int m5mols_debug;

enum m5mols_mode {
	MODE_SYSINIT,
	MODE_PARMSET,
	MODE_MONITOR,
	MODE_CAPTURE,
	MODE_UNKNOWN,
};

enum m5mols_restype {
	M5MOLS_RESTYPE_MONITOR,
	M5MOLS_RESTYPE_CAPTURE,
	M5MOLS_RESTYPE_MAX,
};

enum m5mols_status {
	STATUS_SYSINIT,
	STATUS_PARMSET,
	STATUS_MONITOR,
	STATUS_AUTO_FOCUS,
	STATUS_FACE_DETECTION,
	STATUS_DUAL_CAPTURE,
	STATUS_SINGLE_CAPTURE,
	STATUS_PREVIEW,
	STATUS_UNKNOWN,
};

enum m5mols_intterrupt_bit {
	INT_BIT_MODE,
	INT_BIT_AF,
	INT_BIT_ZOOM,
	INT_BIT_CAPTURE,
	INT_BIT_FRAME_SYNC,
	INT_BIT_FD,
	INT_BIT_LENS_INIT,
	INT_BIT_SOUND,
};

enum m5mols_i2c_size {
	I2C_8BIT	= 1,
	I2C_16BIT	= 2,
	I2C_32BIT	= 4,
	I2C_MAX		= 4,
};

enum m5mols_fps {
	M5MOLS_FPS_AUTO	= 0,
	M5MOLS_FPS_10	= 10,
	M5MOLS_FPS_12	= 12,
	M5MOLS_FPS_15	= 15,
	M5MOLS_FPS_20	= 20,
	M5MOLS_FPS_21	= 21,
	M5MOLS_FPS_22	= 22,
	M5MOLS_FPS_23	= 23,
	M5MOLS_FPS_24	= 24,
	M5MOLS_FPS_30	= 30,
	M5MOLS_FPS_MAX	= M5MOLS_FPS_30,
};

enum m5mols_res_type {
	M5MOLS_RES_MON,
	/* It's not supported below yet. */
	M5MOLS_RES_CAPTURE,
	M5MOLS_RES_MAX,
};

struct m5mols_resolution {
	u8			value;
	enum m5mols_res_type	type;
	u16			width;
	u16			height;
};

struct m5mols_format {
	enum v4l2_mbus_pixelcode code;
	enum v4l2_colorspace colorspace;
};

struct m5mols_control {
	u32	id;
	s32	min;
	s32	max;
	u32	step;
	s32	def;
};

struct m5mols_exif {
	u32	exposure_time;
	u32	shutter_speed;
	u32	aperture;
	u32	brightness;
	u32	exposure_bias;
	u16	iso_speed;
	u16	flash;
	u16	sdr;		/* subject(object) distance range */
	u16	qval;		/* This is not written precisely in datasheet. */
};

struct m5mols_capture {
	struct m5mols_exif		exif;
	u32				main;
	u32				thumb;
	u32				total;
};

struct m5mols_version {
	u8	ctm_code;	/* customer code */
	u8	pj_code;	/* project code */
	u16	fw;		/* firmware version */
	u16	hw;		/* hardware version */
	u16	parm;		/* parameter version */
	u16	awb;		/* AWB version */
};

struct m5mols_info {
	struct v4l2_subdev		sd;
	struct media_pad pad;
	int res_type;
	u8 resolution;
	struct v4l2_mbus_framefmt	fmt[M5MOLS_RES_MAX];
	struct v4l2_fract		tpf;

	struct v4l2_ctrl_handler	handle;
	struct {
		/* support only AE of the Monitor Mode in this version */
		struct v4l2_ctrl	*autoexposure;
		struct v4l2_ctrl	*exposure;
		bool			is_ae_lock;
	};
	struct v4l2_ctrl		*autofocus;
	bool				is_focus;
	struct v4l2_ctrl		*autowb;
	bool				is_awb_lock;
	struct v4l2_ctrl		*colorfx;
	struct v4l2_ctrl		*saturation;
	struct v4l2_ctrl		*zoom;
	struct v4l2_ctrl		*jpeg_size;
	struct v4l2_ctrl		*encoded_size;

	enum m5mols_mode		mode;
	enum m5mols_mode		mode_backup;
	enum m5mols_status		status;
	enum v4l2_mbus_pixelcode	code;

	struct m5mols_capture		cap;
	wait_queue_head_t		cap_wait;
	bool				captured;

	const struct m5mols_platform_data	*pdata;
	struct m5mols_version		ver;
	struct work_struct		work;
	bool				power;

	/* for additional power if needed. */
	int (*set_power)(struct device *dev, int on);
};

/* control functions */
int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);

/* I2C functions - referenced by below I2C helper functions */
int m5mols_read_reg(struct v4l2_subdev *sd, enum m5mols_i2c_size size,
		u8 category, u8 cmd, u32 *val);
int m5mols_write_reg(struct v4l2_subdev *sd, enum m5mols_i2c_size size,
		u8 category, u8 cmd, u32 val);
int m5mols_check_busy(struct v4l2_subdev *sd,
		u8 category, u8 cmd, u32 value);
int m5mols_set_mode(struct v4l2_subdev *sd, enum m5mols_mode mode);
enum m5mols_status m5mols_get_status(struct v4l2_subdev *sd);

/*
 * helper functions
 */
static inline struct m5mols_info *to_m5mols(struct v4l2_subdev *sd)
{
	return container_of(sd, struct m5mols_info, sd);
}

static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{
	return &container_of(ctrl->handler, struct m5mols_info, handle)->sd;
}

static inline bool is_streaming(struct v4l2_subdev *sd)
{
	struct m5mols_info *info = to_m5mols(sd);
	return (info->mode == MODE_MONITOR) || (info->mode == MODE_CAPTURE);
}

static inline bool is_stoped(struct v4l2_subdev *sd)
{
	struct m5mols_info *info = to_m5mols(sd);
	return (info->mode != MODE_MONITOR) && (info->mode != MODE_CAPTURE);
}

static inline bool is_powerup(struct v4l2_subdev *sd)
{
	struct m5mols_info *info = to_m5mols(sd);
	return info->power;
}

static inline int m5mols_set_mode_backup(struct v4l2_subdev *sd,
		enum m5mols_mode mode)
{
	struct m5mols_info *info = to_m5mols(sd);

	info->mode_backup = info->mode;
	return m5mols_set_mode(sd, mode);
}

static inline int m5mols_set_mode_restore(struct v4l2_subdev *sd)
{
	struct m5mols_info *info = to_m5mols(sd);
	int ret;

	ret = m5mols_set_mode(sd, info->mode_backup);
	if (!ret)
		info->mode = info->mode_backup;
	return ret;
}

static inline int __must_check i2c_w8_system(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_SYSTEM, cmd, val);
}

static inline int __must_check i2c_w8_param(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_PARAM, cmd, val);
}

static inline int __must_check i2c_w8_mon(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_MON, cmd, val);
}

static inline int __must_check i2c_w8_ae(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_AE, cmd, val);
}

static inline int __must_check i2c_w16_ae(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_16BIT, CAT_AE, cmd, val);
}

static inline int __must_check i2c_w8_wb(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_WB, cmd, val);
}

static inline int __must_check i2c_w8_lens(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_LENS, cmd, val);
}

static inline int __must_check i2c_w8_capt_parm(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_CAPTURE_PARAMETER, cmd, val);
}

static inline int __must_check i2c_w8_capt_ctrl(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_CAPTURE_CONTROL, cmd, val);
}

static inline int __must_check i2c_w8_flash(struct v4l2_subdev *sd,
		u8 cmd, u32 val)
{
	return m5mols_write_reg(sd, I2C_8BIT, CAT_FLASH, cmd, val);
}

static inline int __must_check i2c_r8_system(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_8BIT, CAT_SYSTEM, cmd, val);
}

static inline int __must_check i2c_r8_param(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_8BIT, CAT_PARAM, cmd, val);
}

static inline int __must_check i2c_r8_mon(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_8BIT, CAT_MON, cmd, val);
}

static inline int __must_check i2c_r8_ae(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_8BIT, CAT_AE, cmd, val);
}

static inline int __must_check i2c_r16_ae(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_16BIT, CAT_AE, cmd, val);
}

static inline int __must_check i2c_r8_lens(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_8BIT, CAT_LENS, cmd, val);
}

static inline int __must_check i2c_r32_capt_ctrl(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_32BIT, CAT_CAPTURE_CONTROL, cmd, val);
}

static inline int __must_check i2c_r16_exif(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_16BIT, CAT_EXIF, cmd, val);
}

static inline int __must_check i2c_r32_exif(struct v4l2_subdev *sd,
		u8 cmd, u32 *val)
{
	return m5mols_read_reg(sd, I2C_32BIT, CAT_EXIF, cmd, val);
}

static int m5mols_set_ae_lock(struct m5mols_info *info, bool lock)
{
	struct v4l2_subdev *sd = &info->sd;

	info->is_ae_lock = lock;

	return i2c_w8_ae(sd, CAT3_AE_LOCK, !!lock);
}

static int m5mols_set_awb_lock(struct m5mols_info *info, bool lock)
{
	struct v4l2_subdev *sd = &info->sd;

	info->is_awb_lock = lock;

	return i2c_w8_wb(sd, CAT6_AWB_LOCK, !!lock);
}
#endif	/* M5MOLS_H */