/* * Header for M5MOLS 8M Pixel camera sensor with ISP * * Copyright (C) 2011 Samsung Electronics Co., Ltd. * Author: HeungJun Kim * * Copyright (C) 2009 Samsung Electronics Co., Ltd. * Author: Dongsoo Nathaniel Kim * * 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 #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 */