mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 15:28:50 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
6
drivers/media/i2c/m5mols/Kconfig
Normal file
6
drivers/media/i2c/m5mols/Kconfig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
config VIDEO_M5MOLS
|
||||
tristate "Fujitsu M-5MOLS 8MP sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This driver supports Fujitsu M-5MOLS camera sensor with ISP
|
||||
3
drivers/media/i2c/m5mols/Makefile
Normal file
3
drivers/media/i2c/m5mols/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
m5mols-objs := m5mols_core.o m5mols_controls.o m5mols_capture.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_M5MOLS) += m5mols.o
|
||||
348
drivers/media/i2c/m5mols/m5mols.h
Normal file
348
drivers/media/i2c/m5mols/m5mols.h
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* Header for M-5MOLS 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 <linux/sizes.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include "m5mols_reg.h"
|
||||
|
||||
|
||||
/* An amount of data transmitted in addition to the value
|
||||
* determined by CAPP_JPEG_SIZE_MAX register.
|
||||
*/
|
||||
#define M5MOLS_JPEG_TAGS_SIZE 0x20000
|
||||
#define M5MOLS_MAIN_JPEG_SIZE_MAX (5 * SZ_1M)
|
||||
|
||||
extern int m5mols_debug;
|
||||
|
||||
enum m5mols_restype {
|
||||
M5MOLS_RESTYPE_MONITOR,
|
||||
M5MOLS_RESTYPE_CAPTURE,
|
||||
M5MOLS_RESTYPE_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct m5mols_resolution - structure for the resolution
|
||||
* @type: resolution type according to the pixel code
|
||||
* @width: width of the resolution
|
||||
* @height: height of the resolution
|
||||
* @reg: resolution preset register value
|
||||
*/
|
||||
struct m5mols_resolution {
|
||||
u8 reg;
|
||||
enum m5mols_restype type;
|
||||
u16 width;
|
||||
u16 height;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct m5mols_exif - structure for the EXIF information of M-5MOLS
|
||||
* @exposure_time: exposure time register value
|
||||
* @shutter_speed: speed of the shutter register value
|
||||
* @aperture: aperture register value
|
||||
* @exposure_bias: it calls also EV bias
|
||||
* @iso_speed: ISO register value
|
||||
* @flash: status register value of the flash
|
||||
* @sdr: status register value of the Subject Distance Range
|
||||
* @qval: not written exact meaning in document
|
||||
*/
|
||||
struct m5mols_exif {
|
||||
u32 exposure_time;
|
||||
u32 shutter_speed;
|
||||
u32 aperture;
|
||||
u32 brightness;
|
||||
u32 exposure_bias;
|
||||
u16 iso_speed;
|
||||
u16 flash;
|
||||
u16 sdr;
|
||||
u16 qval;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct m5mols_capture - Structure for the capture capability
|
||||
* @exif: EXIF information
|
||||
* @buf_size: internal JPEG frame buffer size, in bytes
|
||||
* @main: size in bytes of the main image
|
||||
* @thumb: size in bytes of the thumb image, if it was accompanied
|
||||
* @total: total size in bytes of the produced image
|
||||
*/
|
||||
struct m5mols_capture {
|
||||
struct m5mols_exif exif;
|
||||
unsigned int buf_size;
|
||||
u32 main;
|
||||
u32 thumb;
|
||||
u32 total;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct m5mols_scenemode - structure for the scenemode capability
|
||||
* @metering: metering light register value
|
||||
* @ev_bias: EV bias register value
|
||||
* @wb_mode: mode which means the WhiteBalance is Auto or Manual
|
||||
* @wb_preset: whitebalance preset register value in the Manual mode
|
||||
* @chroma_en: register value whether the Chroma capability is enabled or not
|
||||
* @chroma_lvl: chroma's level register value
|
||||
* @edge_en: register value Whether the Edge capability is enabled or not
|
||||
* @edge_lvl: edge's level register value
|
||||
* @af_range: Auto Focus's range
|
||||
* @fd_mode: Face Detection mode
|
||||
* @mcc: Multi-axis Color Conversion which means emotion color
|
||||
* @light: status of the Light
|
||||
* @flash: status of the Flash
|
||||
* @tone: Tone color which means Contrast
|
||||
* @iso: ISO register value
|
||||
* @capt_mode: Mode of the Image Stabilization while the camera capturing
|
||||
* @wdr: Wide Dynamic Range register value
|
||||
*
|
||||
* The each value according to each scenemode is recommended in the documents.
|
||||
*/
|
||||
struct m5mols_scenemode {
|
||||
u8 metering;
|
||||
u8 ev_bias;
|
||||
u8 wb_mode;
|
||||
u8 wb_preset;
|
||||
u8 chroma_en;
|
||||
u8 chroma_lvl;
|
||||
u8 edge_en;
|
||||
u8 edge_lvl;
|
||||
u8 af_range;
|
||||
u8 fd_mode;
|
||||
u8 mcc;
|
||||
u8 light;
|
||||
u8 flash;
|
||||
u8 tone;
|
||||
u8 iso;
|
||||
u8 capt_mode;
|
||||
u8 wdr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct m5mols_version - firmware version information
|
||||
* @customer: customer information
|
||||
* @project: version of project information according to customer
|
||||
* @fw: firmware revision
|
||||
* @hw: hardware revision
|
||||
* @param: version of the parameter
|
||||
* @awb: Auto WhiteBalance algorithm version
|
||||
* @str: information about manufacturer and packaging vendor
|
||||
* @af: Auto Focus version
|
||||
*
|
||||
* The register offset starts the customer version at 0x0, and it ends
|
||||
* the awb version at 0x09. The customer, project information occupies 1 bytes
|
||||
* each. And also the fw, hw, param, awb each requires 2 bytes. The str is
|
||||
* unique string associated with firmware's version. It includes information
|
||||
* about manufacturer and the vendor of the sensor's packaging. The least
|
||||
* significant 2 bytes of the string indicate packaging manufacturer.
|
||||
*/
|
||||
#define VERSION_STRING_SIZE 22
|
||||
struct m5mols_version {
|
||||
u8 customer;
|
||||
u8 project;
|
||||
u16 fw;
|
||||
u16 hw;
|
||||
u16 param;
|
||||
u16 awb;
|
||||
u8 str[VERSION_STRING_SIZE];
|
||||
u8 af;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct m5mols_info - M-5MOLS driver data structure
|
||||
* @pdata: platform data
|
||||
* @sd: v4l-subdev instance
|
||||
* @pad: media pad
|
||||
* @irq_waitq: waitqueue for the capture
|
||||
* @irq_done: set to 1 in the interrupt handler
|
||||
* @handle: control handler
|
||||
* @auto_exposure: auto/manual exposure control
|
||||
* @exposure_bias: exposure compensation control
|
||||
* @exposure: manual exposure control
|
||||
* @metering: exposure metering control
|
||||
* @auto_iso: auto/manual ISO sensitivity control
|
||||
* @iso: manual ISO sensitivity control
|
||||
* @auto_wb: auto white balance control
|
||||
* @lock_3a: 3A lock control
|
||||
* @colorfx: color effect control
|
||||
* @saturation: saturation control
|
||||
* @zoom: zoom control
|
||||
* @wdr: wide dynamic range control
|
||||
* @stabilization: image stabilization control
|
||||
* @jpeg_quality: JPEG compression quality control
|
||||
* @set_power: optional power callback to the board code
|
||||
* @lock: mutex protecting the structure fields below
|
||||
* @ffmt: current fmt according to resolution type
|
||||
* @res_type: current resolution type
|
||||
* @ver: information of the version
|
||||
* @cap: the capture mode attributes
|
||||
* @isp_ready: 1 when the ISP controller has completed booting
|
||||
* @power: current sensor's power status
|
||||
* @ctrl_sync: 1 when the control handler state is restored in H/W
|
||||
* @resolution: register value for current resolution
|
||||
* @mode: register value for current operation mode
|
||||
*/
|
||||
struct m5mols_info {
|
||||
const struct m5mols_platform_data *pdata;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
|
||||
wait_queue_head_t irq_waitq;
|
||||
atomic_t irq_done;
|
||||
|
||||
struct v4l2_ctrl_handler handle;
|
||||
struct {
|
||||
/* exposure/exposure bias/auto exposure cluster */
|
||||
struct v4l2_ctrl *auto_exposure;
|
||||
struct v4l2_ctrl *exposure_bias;
|
||||
struct v4l2_ctrl *exposure;
|
||||
struct v4l2_ctrl *metering;
|
||||
};
|
||||
struct {
|
||||
/* iso/auto iso cluster */
|
||||
struct v4l2_ctrl *auto_iso;
|
||||
struct v4l2_ctrl *iso;
|
||||
};
|
||||
struct v4l2_ctrl *auto_wb;
|
||||
|
||||
struct v4l2_ctrl *lock_3a;
|
||||
struct v4l2_ctrl *colorfx;
|
||||
struct v4l2_ctrl *saturation;
|
||||
struct v4l2_ctrl *zoom;
|
||||
struct v4l2_ctrl *wdr;
|
||||
struct v4l2_ctrl *stabilization;
|
||||
struct v4l2_ctrl *jpeg_quality;
|
||||
|
||||
int (*set_power)(struct device *dev, int on);
|
||||
|
||||
struct mutex lock;
|
||||
|
||||
struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
|
||||
int res_type;
|
||||
|
||||
struct m5mols_version ver;
|
||||
struct m5mols_capture cap;
|
||||
|
||||
unsigned int isp_ready:1;
|
||||
unsigned int power:1;
|
||||
unsigned int ctrl_sync:1;
|
||||
|
||||
u8 resolution;
|
||||
u8 mode;
|
||||
};
|
||||
|
||||
#define is_available_af(__info) (__info->ver.af)
|
||||
#define is_code(__code, __type) (__code == m5mols_default_ffmt[__type].code)
|
||||
#define is_manufacturer(__info, __manufacturer) \
|
||||
(__info->ver.str[0] == __manufacturer[0] && \
|
||||
__info->ver.str[1] == __manufacturer[1])
|
||||
/*
|
||||
* I2C operation of the M-5MOLS
|
||||
*
|
||||
* The I2C read operation of the M-5MOLS requires 2 messages. The first
|
||||
* message sends the information about the command, command category, and total
|
||||
* message size. The second message is used to retrieve the data specifed in
|
||||
* the first message
|
||||
*
|
||||
* 1st message 2nd message
|
||||
* +-------+---+----------+-----+-------+ +------+------+------+------+
|
||||
* | size1 | R | category | cmd | size2 | | d[0] | d[1] | d[2] | d[3] |
|
||||
* +-------+---+----------+-----+-------+ +------+------+------+------+
|
||||
* - size1: message data size(5 in this case)
|
||||
* - size2: desired buffer size of the 2nd message
|
||||
* - d[0..3]: according to size2
|
||||
*
|
||||
* The I2C write operation needs just one message. The message includes
|
||||
* category, command, total size, and desired data.
|
||||
*
|
||||
* 1st message
|
||||
* +-------+---+----------+-----+------+------+------+------+
|
||||
* | size1 | W | category | cmd | d[0] | d[1] | d[2] | d[3] |
|
||||
* +-------+---+----------+-----+------+------+------+------+
|
||||
* - d[0..3]: according to size1
|
||||
*/
|
||||
int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
|
||||
int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
|
||||
int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
|
||||
int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
|
||||
|
||||
int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
|
||||
int timeout);
|
||||
|
||||
/* Mask value for busy waiting until M-5MOLS I2C interface is initialized */
|
||||
#define M5MOLS_I2C_RDY_WAIT_FL (1 << 16)
|
||||
/* ISP state transition timeout, in ms */
|
||||
#define M5MOLS_MODE_CHANGE_TIMEOUT 200
|
||||
#define M5MOLS_BUSY_WAIT_DEF_TIMEOUT 250
|
||||
|
||||
/*
|
||||
* Mode operation of the M-5MOLS
|
||||
*
|
||||
* Changing the mode of the M-5MOLS is needed right executing order.
|
||||
* There are three modes(PARAMETER, MONITOR, CAPTURE) which can be changed
|
||||
* by user. There are various categories associated with each mode.
|
||||
*
|
||||
* +============================================================+
|
||||
* | mode | category |
|
||||
* +============================================================+
|
||||
* | FLASH | FLASH(only after Stand-by or Power-on) |
|
||||
* | SYSTEM | SYSTEM(only after sensor arm-booting) |
|
||||
* | PARAMETER | PARAMETER |
|
||||
* | MONITOR | MONITOR(preview), Auto Focus, Face Detection |
|
||||
* | CAPTURE | Single CAPTURE, Preview(recording) |
|
||||
* +============================================================+
|
||||
*
|
||||
* The available executing order between each modes are as follows:
|
||||
* PARAMETER <---> MONITOR <---> CAPTURE
|
||||
*/
|
||||
int m5mols_set_mode(struct m5mols_info *info, u8 mode);
|
||||
|
||||
int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
|
||||
int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout);
|
||||
int m5mols_restore_controls(struct m5mols_info *info);
|
||||
int m5mols_start_capture(struct m5mols_info *info);
|
||||
int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
|
||||
int m5mols_lock_3a(struct m5mols_info *info, bool lock);
|
||||
int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
|
||||
int m5mols_init_controls(struct v4l2_subdev *sd);
|
||||
|
||||
/* The firmware function */
|
||||
int m5mols_update_fw(struct v4l2_subdev *sd,
|
||||
int (*set_power)(struct m5mols_info *, bool));
|
||||
|
||||
static inline struct m5mols_info *to_m5mols(struct v4l2_subdev *subdev)
|
||||
{
|
||||
return container_of(subdev, struct m5mols_info, sd);
|
||||
}
|
||||
|
||||
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct m5mols_info *info = container_of(ctrl->handler,
|
||||
struct m5mols_info, handle);
|
||||
return &info->sd;
|
||||
}
|
||||
|
||||
static inline void m5mols_set_ctrl_mode(struct v4l2_ctrl *ctrl,
|
||||
unsigned int mode)
|
||||
{
|
||||
ctrl->priv = (void *)(uintptr_t)mode;
|
||||
}
|
||||
|
||||
static inline unsigned int m5mols_get_ctrl_mode(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return (unsigned int)(uintptr_t)ctrl->priv;
|
||||
}
|
||||
|
||||
#endif /* M5MOLS_H */
|
||||
158
drivers/media/i2c/m5mols/m5mols_capture.c
Normal file
158
drivers/media/i2c/m5mols/m5mols_capture.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
|
||||
/*
|
||||
* The Capture code for Fujitsu M-5MOLS 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.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/m5mols.h>
|
||||
#include <media/exynos-fimc.h>
|
||||
|
||||
#include "m5mols.h"
|
||||
#include "m5mols_reg.h"
|
||||
|
||||
/**
|
||||
* m5mols_read_rational - I2C read of a rational number
|
||||
*
|
||||
* Read numerator and denominator from registers @addr_num and @addr_den
|
||||
* respectively and return the division result in @val.
|
||||
*/
|
||||
static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
|
||||
u32 addr_den, u32 *val)
|
||||
{
|
||||
u32 num, den;
|
||||
|
||||
int ret = m5mols_read_u32(sd, addr_num, &num);
|
||||
if (!ret)
|
||||
ret = m5mols_read_u32(sd, addr_den, &den);
|
||||
if (ret)
|
||||
return ret;
|
||||
*val = den == 0 ? 0 : num / den;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* m5mols_capture_info - Gather captured image information
|
||||
*
|
||||
* For now it gathers only EXIF information and file size.
|
||||
*/
|
||||
static int m5mols_capture_info(struct m5mols_info *info)
|
||||
{
|
||||
struct m5mols_exif *exif = &info->cap.exif;
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
int ret;
|
||||
|
||||
ret = m5mols_read_rational(sd, EXIF_INFO_EXPTIME_NU,
|
||||
EXIF_INFO_EXPTIME_DE, &exif->exposure_time);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = m5mols_read_rational(sd, EXIF_INFO_TV_NU, EXIF_INFO_TV_DE,
|
||||
&exif->shutter_speed);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = m5mols_read_rational(sd, EXIF_INFO_AV_NU, EXIF_INFO_AV_DE,
|
||||
&exif->aperture);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = m5mols_read_rational(sd, EXIF_INFO_BV_NU, EXIF_INFO_BV_DE,
|
||||
&exif->brightness);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = m5mols_read_rational(sd, EXIF_INFO_EBV_NU, EXIF_INFO_EBV_DE,
|
||||
&exif->exposure_bias);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
|
||||
if (!ret)
|
||||
ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
|
||||
if (!ret)
|
||||
ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
|
||||
if (!ret)
|
||||
ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ret)
|
||||
ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
|
||||
if (!ret)
|
||||
ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
|
||||
if (!ret)
|
||||
info->cap.total = info->cap.main + info->cap.thumb;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int m5mols_start_capture(struct m5mols_info *info)
|
||||
{
|
||||
unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE;
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Synchronize the controls, set the capture frame resolution and color
|
||||
* format. The frame capture is initiated during switching from Monitor
|
||||
* to Capture mode.
|
||||
*/
|
||||
ret = m5mols_set_mode(info, REG_MONITOR);
|
||||
if (!ret)
|
||||
ret = m5mols_restore_controls(info);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize);
|
||||
if (!ret)
|
||||
ret = m5mols_set_mode(info, REG_CAPTURE);
|
||||
if (!ret)
|
||||
/* Wait until a frame is captured to ISP internal memory */
|
||||
ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Initiate the captured data transfer to a MIPI-CSI receiver.
|
||||
*/
|
||||
ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
|
||||
if (!ret) {
|
||||
bool captured = false;
|
||||
unsigned int size;
|
||||
|
||||
/* Wait for the capture completion interrupt */
|
||||
ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
|
||||
if (!ret) {
|
||||
captured = true;
|
||||
ret = m5mols_capture_info(info);
|
||||
}
|
||||
size = captured ? info->cap.main : 0;
|
||||
v4l2_dbg(1, m5mols_debug, sd, "%s: size: %d, thumb.: %d B\n",
|
||||
__func__, size, info->cap.thumb);
|
||||
|
||||
v4l2_subdev_notify(sd, S5P_FIMC_TX_END_NOTIFY, &size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
628
drivers/media/i2c/m5mols/m5mols_controls.c
Normal file
628
drivers/media/i2c/m5mols/m5mols_controls.c
Normal file
|
|
@ -0,0 +1,628 @@
|
|||
/*
|
||||
* Controls for M-5MOLS 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.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
||||
#include "m5mols.h"
|
||||
#include "m5mols_reg.h"
|
||||
|
||||
static struct m5mols_scenemode m5mols_default_scenemode[] = {
|
||||
[REG_SCENE_NORMAL] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_NORMAL, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
5, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_PORTRAIT] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 4,
|
||||
REG_AF_NORMAL, BIT_FD_EN | BIT_FD_DRAW_FACE_FRAME,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_LANDSCAPE] = {
|
||||
REG_AE_ALL, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 4, REG_EDGE_ON, 6,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_SPORTS] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_PARTY_INDOOR] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_200, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_BEACH_SNOW] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_10_POS, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_SUNSET] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
|
||||
REG_AWB_DAYLIGHT,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_DAWN_DUSK] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
|
||||
REG_AWB_FLUORESCENT_1,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_FALL] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 5, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_NIGHT] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_AGAINST_LIGHT] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_FIRE] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
[REG_SCENE_TEXT] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 7,
|
||||
REG_AF_MACRO, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_ANTI_SHAKE, REG_WDR_ON,
|
||||
},
|
||||
[REG_SCENE_CANDLE] = {
|
||||
REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
|
||||
REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
|
||||
REG_AF_NORMAL, REG_FD_OFF,
|
||||
REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
|
||||
6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* m5mols_do_scenemode() - Change current scenemode
|
||||
* @mode: Desired mode of the scenemode
|
||||
*
|
||||
* WARNING: The execution order is important. Do not change the order.
|
||||
*/
|
||||
int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
|
||||
{
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
|
||||
int ret;
|
||||
|
||||
if (mode > REG_SCENE_CANDLE)
|
||||
return -EINVAL;
|
||||
|
||||
ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AE_EV_PRESET_CAPTURE, mode);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AE_MODE, scenemode.metering);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AE_INDEX, scenemode.ev_bias);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AWB_MODE, scenemode.wb_mode);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AWB_MANUAL, scenemode.wb_preset);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_CHROMA_EN, scenemode.chroma_en);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_CHROMA_LVL, scenemode.chroma_lvl);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_EDGE_EN, scenemode.edge_en);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_EDGE_LVL, scenemode.edge_lvl);
|
||||
if (!ret && is_available_af(info))
|
||||
ret = m5mols_write(sd, AF_MODE, scenemode.af_range);
|
||||
if (!ret && is_available_af(info))
|
||||
ret = m5mols_write(sd, FD_CTL, scenemode.fd_mode);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_TONE_CTL, scenemode.tone);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, AE_ISO, scenemode.iso);
|
||||
if (!ret)
|
||||
ret = m5mols_set_mode(info, REG_CAPTURE);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_MCC_MODE, scenemode.mcc);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_LIGHT_CTRL, scenemode.light);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPP_FLASH_CTRL, scenemode.flash);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
|
||||
if (!ret)
|
||||
ret = m5mols_set_mode(info, REG_MONITOR);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m5mols_3a_lock(struct m5mols_info *info, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
|
||||
int ret = 0;
|
||||
|
||||
if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
|
||||
bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
|
||||
|
||||
ret = m5mols_write(&info->sd, AE_LOCK, ae_lock ?
|
||||
REG_AE_LOCK : REG_AE_UNLOCK);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
|
||||
&& info->auto_wb->val) {
|
||||
bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
|
||||
|
||||
ret = m5mols_write(&info->sd, AWB_LOCK, awb_lock ?
|
||||
REG_AWB_LOCK : REG_AWB_UNLOCK);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!info->ver.af || !af_lock)
|
||||
return ret;
|
||||
|
||||
if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
|
||||
ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m5mols_set_metering_mode(struct m5mols_info *info, int mode)
|
||||
{
|
||||
unsigned int metering;
|
||||
|
||||
switch (mode) {
|
||||
case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
|
||||
metering = REG_AE_CENTER;
|
||||
break;
|
||||
case V4L2_EXPOSURE_METERING_SPOT:
|
||||
metering = REG_AE_SPOT;
|
||||
break;
|
||||
default:
|
||||
metering = REG_AE_ALL;
|
||||
break;
|
||||
}
|
||||
|
||||
return m5mols_write(&info->sd, AE_MODE, metering);
|
||||
}
|
||||
|
||||
static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
|
||||
{
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
int ret = 0;
|
||||
|
||||
if (exposure == V4L2_EXPOSURE_AUTO) {
|
||||
/* Unlock auto exposure */
|
||||
info->lock_3a->val &= ~V4L2_LOCK_EXPOSURE;
|
||||
m5mols_3a_lock(info, info->lock_3a);
|
||||
|
||||
ret = m5mols_set_metering_mode(info, info->metering->val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
v4l2_dbg(1, m5mols_debug, sd,
|
||||
"%s: exposure bias: %#x, metering: %#x\n",
|
||||
__func__, info->exposure_bias->val,
|
||||
info->metering->val);
|
||||
|
||||
return m5mols_write(sd, AE_INDEX, info->exposure_bias->val);
|
||||
}
|
||||
|
||||
if (exposure == V4L2_EXPOSURE_MANUAL) {
|
||||
ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
|
||||
if (ret == 0)
|
||||
ret = m5mols_write(sd, AE_MAN_GAIN_MON,
|
||||
info->exposure->val);
|
||||
if (ret == 0)
|
||||
ret = m5mols_write(sd, AE_MAN_GAIN_CAP,
|
||||
info->exposure->val);
|
||||
|
||||
v4l2_dbg(1, m5mols_debug, sd, "%s: exposure: %#x\n",
|
||||
__func__, info->exposure->val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m5mols_set_white_balance(struct m5mols_info *info, int val)
|
||||
{
|
||||
static const unsigned short wb[][2] = {
|
||||
{ V4L2_WHITE_BALANCE_INCANDESCENT, REG_AWB_INCANDESCENT },
|
||||
{ V4L2_WHITE_BALANCE_FLUORESCENT, REG_AWB_FLUORESCENT_1 },
|
||||
{ V4L2_WHITE_BALANCE_FLUORESCENT_H, REG_AWB_FLUORESCENT_2 },
|
||||
{ V4L2_WHITE_BALANCE_HORIZON, REG_AWB_HORIZON },
|
||||
{ V4L2_WHITE_BALANCE_DAYLIGHT, REG_AWB_DAYLIGHT },
|
||||
{ V4L2_WHITE_BALANCE_FLASH, REG_AWB_LEDLIGHT },
|
||||
{ V4L2_WHITE_BALANCE_CLOUDY, REG_AWB_CLOUDY },
|
||||
{ V4L2_WHITE_BALANCE_SHADE, REG_AWB_SHADE },
|
||||
{ V4L2_WHITE_BALANCE_AUTO, REG_AWB_AUTO },
|
||||
};
|
||||
int i;
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wb); i++) {
|
||||
int awb;
|
||||
if (wb[i][0] != val)
|
||||
continue;
|
||||
|
||||
v4l2_dbg(1, m5mols_debug, sd,
|
||||
"Setting white balance to: %#x\n", wb[i][0]);
|
||||
|
||||
awb = wb[i][0] == V4L2_WHITE_BALANCE_AUTO;
|
||||
ret = m5mols_write(sd, AWB_MODE, awb ? REG_AWB_AUTO :
|
||||
REG_AWB_PRESET);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!awb)
|
||||
ret = m5mols_write(sd, AWB_MANUAL, wb[i][1]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m5mols_set_saturation(struct m5mols_info *info, int val)
|
||||
{
|
||||
int ret = m5mols_write(&info->sd, MON_CHROMA_LVL, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return m5mols_write(&info->sd, MON_CHROMA_EN, REG_CHROMA_ON);
|
||||
}
|
||||
|
||||
static int m5mols_set_color_effect(struct m5mols_info *info, int val)
|
||||
{
|
||||
unsigned int m_effect = REG_COLOR_EFFECT_OFF;
|
||||
unsigned int p_effect = REG_EFFECT_OFF;
|
||||
unsigned int cfix_r = 0, cfix_b = 0;
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
int ret = 0;
|
||||
|
||||
switch (val) {
|
||||
case V4L2_COLORFX_BW:
|
||||
m_effect = REG_COLOR_EFFECT_ON;
|
||||
break;
|
||||
case V4L2_COLORFX_NEGATIVE:
|
||||
p_effect = REG_EFFECT_NEGA;
|
||||
break;
|
||||
case V4L2_COLORFX_EMBOSS:
|
||||
p_effect = REG_EFFECT_EMBOSS;
|
||||
break;
|
||||
case V4L2_COLORFX_SEPIA:
|
||||
m_effect = REG_COLOR_EFFECT_ON;
|
||||
cfix_r = REG_CFIXR_SEPIA;
|
||||
cfix_b = REG_CFIXB_SEPIA;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = m5mols_write(sd, PARM_EFFECT, p_effect);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_EFFECT, m_effect);
|
||||
|
||||
if (ret == 0 && m_effect == REG_COLOR_EFFECT_ON) {
|
||||
ret = m5mols_write(sd, MON_CFIXR, cfix_r);
|
||||
if (!ret)
|
||||
ret = m5mols_write(sd, MON_CFIXB, cfix_b);
|
||||
}
|
||||
|
||||
v4l2_dbg(1, m5mols_debug, sd,
|
||||
"p_effect: %#x, m_effect: %#x, r: %#x, b: %#x (%d)\n",
|
||||
p_effect, m_effect, cfix_r, cfix_b, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m5mols_set_iso(struct m5mols_info *info, int auto_iso)
|
||||
{
|
||||
u32 iso = auto_iso ? 0 : info->iso->val + 1;
|
||||
|
||||
return m5mols_write(&info->sd, AE_ISO, iso);
|
||||
}
|
||||
|
||||
static int m5mols_set_wdr(struct m5mols_info *info, int wdr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = m5mols_write(&info->sd, MON_TONE_CTL, wdr ? 9 : 5);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = m5mols_set_mode(info, REG_CAPTURE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return m5mols_write(&info->sd, CAPP_WDR_EN, wdr);
|
||||
}
|
||||
|
||||
static int m5mols_set_stabilization(struct m5mols_info *info, int val)
|
||||
{
|
||||
struct v4l2_subdev *sd = &info->sd;
|
||||
unsigned int evp = val ? 0xe : 0x0;
|
||||
int ret;
|
||||
|
||||
ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, evp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return m5mols_write(sd, AE_EV_PRESET_CAPTURE, evp);
|
||||
}
|
||||
|
||||
static int m5mols_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct v4l2_subdev *sd = to_sd(ctrl);
|
||||
struct m5mols_info *info = to_m5mols(sd);
|
||||
int ret = 0;
|
||||
u8 status;
|
||||
|
||||
v4l2_dbg(1, m5mols_debug, sd, "%s: ctrl: %s (%d)\n",
|
||||
__func__, ctrl->name, info->isp_ready);
|
||||
|
||||
if (!info->isp_ready)
|
||||
return -EBUSY;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_ISO_SENSITIVITY_AUTO:
|
||||
ret = m5mols_read_u8(sd, AE_ISO, &status);
|
||||
if (ret == 0)
|
||||
ctrl->val = !status;
|
||||
if (status != REG_ISO_AUTO)
|
||||
info->iso->val = status - 1;
|
||||
break;
|
||||
|
||||
case V4L2_CID_3A_LOCK:
|
||||
ctrl->val &= ~0x7;
|
||||
|
||||
ret = m5mols_read_u8(sd, AE_LOCK, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (status)
|
||||
info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
|
||||
|
||||
ret = m5mols_read_u8(sd, AWB_LOCK, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (status)
|
||||
info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
|
||||
|
||||
ret = m5mols_read_u8(sd, AF_EXECUTE, &status);
|
||||
if (!status)
|
||||
info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
unsigned int ctrl_mode = m5mols_get_ctrl_mode(ctrl);
|
||||
struct v4l2_subdev *sd = to_sd(ctrl);
|
||||
struct m5mols_info *info = to_m5mols(sd);
|
||||
int last_mode = info->mode;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* If needed, defer restoring the controls until
|
||||
* the device is fully initialized.
|
||||
*/
|
||||
if (!info->isp_ready) {
|
||||
info->ctrl_sync = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
v4l2_dbg(1, m5mols_debug, sd, "%s: %s, val: %d, priv: %p\n",
|
||||
__func__, ctrl->name, ctrl->val, ctrl->priv);
|
||||
|
||||
if (ctrl_mode && ctrl_mode != info->mode) {
|
||||
ret = m5mols_set_mode(info, ctrl_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_3A_LOCK:
|
||||
ret = m5mols_3a_lock(info, ctrl);
|
||||
break;
|
||||
|
||||
case V4L2_CID_ZOOM_ABSOLUTE:
|
||||
ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_EXPOSURE_AUTO:
|
||||
ret = m5mols_set_exposure(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_ISO_SENSITIVITY:
|
||||
ret = m5mols_set_iso(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
|
||||
ret = m5mols_set_white_balance(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_SATURATION:
|
||||
ret = m5mols_set_saturation(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_COLORFX:
|
||||
ret = m5mols_set_color_effect(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_WIDE_DYNAMIC_RANGE:
|
||||
ret = m5mols_set_wdr(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_IMAGE_STABILIZATION:
|
||||
ret = m5mols_set_stabilization(info, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_JPEG_COMPRESSION_QUALITY:
|
||||
ret = m5mols_write(sd, CAPP_JPEG_RATIO, ctrl->val);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0 && info->mode != last_mode)
|
||||
ret = m5mols_set_mode(info, last_mode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
|
||||
.g_volatile_ctrl = m5mols_g_volatile_ctrl,
|
||||
.s_ctrl = m5mols_s_ctrl,
|
||||
};
|
||||
|
||||
/* Supported manual ISO values */
|
||||
static const s64 iso_qmenu[] = {
|
||||
/* AE_ISO: 0x01...0x07 (ISO: 50...3200) */
|
||||
50000, 100000, 200000, 400000, 800000, 1600000, 3200000
|
||||
};
|
||||
|
||||
/* Supported Exposure Bias values, -2.0EV...+2.0EV */
|
||||
static const s64 ev_bias_qmenu[] = {
|
||||
/* AE_INDEX: 0x00...0x08 */
|
||||
-2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
|
||||
};
|
||||
|
||||
int m5mols_init_controls(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct m5mols_info *info = to_m5mols(sd);
|
||||
u16 exposure_max;
|
||||
u16 zoom_step;
|
||||
int ret;
|
||||
|
||||
/* Determine the firmware dependent control range and step values */
|
||||
ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
zoom_step = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
|
||||
v4l2_ctrl_handler_init(&info->handle, 20);
|
||||
|
||||
info->auto_wb = v4l2_ctrl_new_std_menu(&info->handle,
|
||||
&m5mols_ctrl_ops, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
|
||||
9, ~0x3fe, V4L2_WHITE_BALANCE_AUTO);
|
||||
|
||||
/* Exposure control cluster */
|
||||
info->auto_exposure = v4l2_ctrl_new_std_menu(&info->handle,
|
||||
&m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
|
||||
1, ~0x03, V4L2_EXPOSURE_AUTO);
|
||||
|
||||
info->exposure = v4l2_ctrl_new_std(&info->handle,
|
||||
&m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
|
||||
0, exposure_max, 1, exposure_max / 2);
|
||||
|
||||
info->exposure_bias = v4l2_ctrl_new_int_menu(&info->handle,
|
||||
&m5mols_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
|
||||
ARRAY_SIZE(ev_bias_qmenu) - 1,
|
||||
ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
|
||||
ev_bias_qmenu);
|
||||
|
||||
info->metering = v4l2_ctrl_new_std_menu(&info->handle,
|
||||
&m5mols_ctrl_ops, V4L2_CID_EXPOSURE_METERING,
|
||||
2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
|
||||
|
||||
/* ISO control cluster */
|
||||
info->auto_iso = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_ISO_SENSITIVITY_AUTO, 1, ~0x03, 1);
|
||||
|
||||
info->iso = v4l2_ctrl_new_int_menu(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
|
||||
ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
|
||||
|
||||
info->saturation = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_SATURATION, 1, 5, 1, 3);
|
||||
|
||||
info->zoom = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_ZOOM_ABSOLUTE, 1, 70, zoom_step, 1);
|
||||
|
||||
info->colorfx = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_COLORFX, 4, 0, V4L2_COLORFX_NONE);
|
||||
|
||||
info->wdr = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
|
||||
|
||||
info->stabilization = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
|
||||
|
||||
info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
|
||||
|
||||
info->lock_3a = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
|
||||
V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
|
||||
|
||||
if (info->handle.error) {
|
||||
int ret = info->handle.error;
|
||||
v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
|
||||
v4l2_ctrl_handler_free(&info->handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
v4l2_ctrl_auto_cluster(4, &info->auto_exposure, 1, false);
|
||||
info->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
|
||||
V4L2_CTRL_FLAG_UPDATE;
|
||||
v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false);
|
||||
|
||||
info->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
|
||||
m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER);
|
||||
m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER);
|
||||
m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR);
|
||||
|
||||
sd->ctrl_handler = &info->handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
1048
drivers/media/i2c/m5mols/m5mols_core.c
Normal file
1048
drivers/media/i2c/m5mols/m5mols_core.c
Normal file
File diff suppressed because it is too large
Load diff
363
drivers/media/i2c/m5mols/m5mols_reg.h
Normal file
363
drivers/media/i2c/m5mols/m5mols_reg.h
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* Register map for M-5MOLS 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_REG_H
|
||||
#define M5MOLS_REG_H
|
||||
|
||||
#define M5MOLS_I2C_MAX_SIZE 4
|
||||
#define M5MOLS_BYTE_READ 0x01
|
||||
#define M5MOLS_BYTE_WRITE 0x02
|
||||
|
||||
#define I2C_CATEGORY(__cat) ((__cat >> 16) & 0xff)
|
||||
#define I2C_COMMAND(__comm) ((__comm >> 8) & 0xff)
|
||||
#define I2C_SIZE(__reg_s) ((__reg_s) & 0xff)
|
||||
#define I2C_REG(__cat, __cmd, __reg_s) ((__cat << 16) | (__cmd << 8) | __reg_s)
|
||||
|
||||
/*
|
||||
* Category section register
|
||||
*
|
||||
* The category means set including relevant command of M-5MOLS.
|
||||
*/
|
||||
#define CAT_SYSTEM 0x00
|
||||
#define CAT_PARAM 0x01
|
||||
#define CAT_MONITOR 0x02
|
||||
#define CAT_AE 0x03
|
||||
#define CAT_WB 0x06
|
||||
#define CAT_EXIF 0x07
|
||||
#define CAT_FD 0x09
|
||||
#define CAT_LENS 0x0a
|
||||
#define CAT_CAPT_PARM 0x0b
|
||||
#define CAT_CAPT_CTRL 0x0c
|
||||
#define CAT_FLASH 0x0f /* related to FW, revisions, booting */
|
||||
|
||||
/*
|
||||
* Category 0 - SYSTEM mode
|
||||
*
|
||||
* The SYSTEM mode in the M-5MOLS means area available to handle with the whole
|
||||
* & all-round system of sensor. It deals with version/interrupt/setting mode &
|
||||
* even sensor's status. Especially, the M-5MOLS sensor with ISP varies by
|
||||
* packaging & manufacturer, even the customer and project code. And the
|
||||
* function details may vary among them. The version information helps to
|
||||
* determine what methods shall be used in the driver.
|
||||
*
|
||||
* There is many registers between customer version address and awb one. For
|
||||
* more specific contents, see definition if file m5mols.h.
|
||||
*/
|
||||
#define SYSTEM_VER_CUSTOMER I2C_REG(CAT_SYSTEM, 0x00, 1)
|
||||
#define SYSTEM_VER_PROJECT I2C_REG(CAT_SYSTEM, 0x01, 1)
|
||||
#define SYSTEM_VER_FIRMWARE I2C_REG(CAT_SYSTEM, 0x02, 2)
|
||||
#define SYSTEM_VER_HARDWARE I2C_REG(CAT_SYSTEM, 0x04, 2)
|
||||
#define SYSTEM_VER_PARAMETER I2C_REG(CAT_SYSTEM, 0x06, 2)
|
||||
#define SYSTEM_VER_AWB I2C_REG(CAT_SYSTEM, 0x08, 2)
|
||||
|
||||
#define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, 0x0b, 1)
|
||||
#define REG_SYSINIT 0x00 /* SYSTEM mode */
|
||||
#define REG_PARAMETER 0x01 /* PARAMETER mode */
|
||||
#define REG_MONITOR 0x02 /* MONITOR mode */
|
||||
#define REG_CAPTURE 0x03 /* CAPTURE mode */
|
||||
|
||||
#define SYSTEM_CMD(__cmd) I2C_REG(CAT_SYSTEM, cmd, 1)
|
||||
#define SYSTEM_VER_STRING I2C_REG(CAT_SYSTEM, 0x0a, 1)
|
||||
#define REG_SAMSUNG_ELECTRO "SE" /* Samsung Electro-Mechanics */
|
||||
#define REG_SAMSUNG_OPTICS "OP" /* Samsung Fiber-Optics */
|
||||
#define REG_SAMSUNG_TECHWIN "TB" /* Samsung Techwin */
|
||||
/* SYSTEM mode status */
|
||||
#define SYSTEM_STATUS I2C_REG(CAT_SYSTEM, 0x0c, 1)
|
||||
|
||||
/* Interrupt pending register */
|
||||
#define SYSTEM_INT_FACTOR I2C_REG(CAT_SYSTEM, 0x10, 1)
|
||||
/* interrupt enable register */
|
||||
#define SYSTEM_INT_ENABLE I2C_REG(CAT_SYSTEM, 0x11, 1)
|
||||
#define REG_INT_MODE (1 << 0)
|
||||
#define REG_INT_AF (1 << 1)
|
||||
#define REG_INT_ZOOM (1 << 2)
|
||||
#define REG_INT_CAPTURE (1 << 3)
|
||||
#define REG_INT_FRAMESYNC (1 << 4)
|
||||
#define REG_INT_FD (1 << 5)
|
||||
#define REG_INT_LENS_INIT (1 << 6)
|
||||
#define REG_INT_SOUND (1 << 7)
|
||||
#define REG_INT_MASK 0x0f
|
||||
|
||||
/*
|
||||
* category 1 - PARAMETER mode
|
||||
*
|
||||
* This category supports function of camera features of M-5MOLS. It means we
|
||||
* can handle with preview(MONITOR) resolution size/frame per second/interface
|
||||
* between the sensor and the Application Processor/even the image effect.
|
||||
*/
|
||||
|
||||
/* Resolution in the MONITOR mode */
|
||||
#define PARM_MON_SIZE I2C_REG(CAT_PARAM, 0x01, 1)
|
||||
|
||||
/* Frame rate */
|
||||
#define PARM_MON_FPS I2C_REG(CAT_PARAM, 0x02, 1)
|
||||
#define REG_FPS_30 0x02
|
||||
|
||||
/* Video bus between the sensor and a host processor */
|
||||
#define PARM_INTERFACE I2C_REG(CAT_PARAM, 0x00, 1)
|
||||
#define REG_INTERFACE_MIPI 0x02
|
||||
|
||||
/* Image effects */
|
||||
#define PARM_EFFECT I2C_REG(CAT_PARAM, 0x0b, 1)
|
||||
#define REG_EFFECT_OFF 0x00
|
||||
#define REG_EFFECT_NEGA 0x01
|
||||
#define REG_EFFECT_EMBOSS 0x06
|
||||
#define REG_EFFECT_OUTLINE 0x07
|
||||
#define REG_EFFECT_WATERCOLOR 0x08
|
||||
|
||||
/*
|
||||
* Category 2 - MONITOR mode
|
||||
*
|
||||
* The MONITOR mode is same as preview mode as we said. The M-5MOLS has another
|
||||
* mode named "Preview", but this preview mode is used at the case specific
|
||||
* vider-recording mode. This mmode supports only YUYV format. On the other
|
||||
* hand, the JPEG & RAW formats is supports by CAPTURE mode. And, there are
|
||||
* another options like zoom/color effect(different with effect in PARAMETER
|
||||
* mode)/anti hand shaking algorithm.
|
||||
*/
|
||||
|
||||
/* Target digital zoom position */
|
||||
#define MON_ZOOM I2C_REG(CAT_MONITOR, 0x01, 1)
|
||||
|
||||
/* CR value for color effect */
|
||||
#define MON_CFIXR I2C_REG(CAT_MONITOR, 0x0a, 1)
|
||||
/* CB value for color effect */
|
||||
#define MON_CFIXB I2C_REG(CAT_MONITOR, 0x09, 1)
|
||||
#define REG_CFIXB_SEPIA 0xd8
|
||||
#define REG_CFIXR_SEPIA 0x18
|
||||
|
||||
#define MON_EFFECT I2C_REG(CAT_MONITOR, 0x0b, 1)
|
||||
#define REG_COLOR_EFFECT_OFF 0x00
|
||||
#define REG_COLOR_EFFECT_ON 0x01
|
||||
|
||||
/* Chroma enable */
|
||||
#define MON_CHROMA_EN I2C_REG(CAT_MONITOR, 0x10, 1)
|
||||
/* Chroma level */
|
||||
#define MON_CHROMA_LVL I2C_REG(CAT_MONITOR, 0x0f, 1)
|
||||
#define REG_CHROMA_OFF 0x00
|
||||
#define REG_CHROMA_ON 0x01
|
||||
|
||||
/* Sharpness on/off */
|
||||
#define MON_EDGE_EN I2C_REG(CAT_MONITOR, 0x12, 1)
|
||||
/* Sharpness level */
|
||||
#define MON_EDGE_LVL I2C_REG(CAT_MONITOR, 0x11, 1)
|
||||
#define REG_EDGE_OFF 0x00
|
||||
#define REG_EDGE_ON 0x01
|
||||
|
||||
/* Set color tone (contrast) */
|
||||
#define MON_TONE_CTL I2C_REG(CAT_MONITOR, 0x25, 1)
|
||||
|
||||
/*
|
||||
* Category 3 - Auto Exposure
|
||||
*
|
||||
* The M-5MOLS exposure capbility is detailed as which is similar to digital
|
||||
* camera. This category supports AE locking/various AE mode(range of exposure)
|
||||
* /ISO/flickering/EV bias/shutter/meteoring, and anything else. And the
|
||||
* maximum/minimum exposure gain value depending on M-5MOLS firmware, may be
|
||||
* different. So, this category also provide getting the max/min values. And,
|
||||
* each MONITOR and CAPTURE mode has each gain/shutter/max exposure values.
|
||||
*/
|
||||
|
||||
/* Auto Exposure locking */
|
||||
#define AE_LOCK I2C_REG(CAT_AE, 0x00, 1)
|
||||
#define REG_AE_UNLOCK 0x00
|
||||
#define REG_AE_LOCK 0x01
|
||||
|
||||
/* Auto Exposure algorithm mode */
|
||||
#define AE_MODE I2C_REG(CAT_AE, 0x01, 1)
|
||||
#define REG_AE_OFF 0x00 /* AE off */
|
||||
#define REG_AE_ALL 0x01 /* calc AE in all block integral */
|
||||
#define REG_AE_CENTER 0x03 /* calc AE in center weighted */
|
||||
#define REG_AE_SPOT 0x06 /* calc AE in specific spot */
|
||||
|
||||
#define AE_ISO I2C_REG(CAT_AE, 0x05, 1)
|
||||
#define REG_ISO_AUTO 0x00
|
||||
#define REG_ISO_50 0x01
|
||||
#define REG_ISO_100 0x02
|
||||
#define REG_ISO_200 0x03
|
||||
#define REG_ISO_400 0x04
|
||||
#define REG_ISO_800 0x05
|
||||
|
||||
/* EV (scenemode) preset for MONITOR */
|
||||
#define AE_EV_PRESET_MONITOR I2C_REG(CAT_AE, 0x0a, 1)
|
||||
/* EV (scenemode) preset for CAPTURE */
|
||||
#define AE_EV_PRESET_CAPTURE I2C_REG(CAT_AE, 0x0b, 1)
|
||||
#define REG_SCENE_NORMAL 0x00
|
||||
#define REG_SCENE_PORTRAIT 0x01
|
||||
#define REG_SCENE_LANDSCAPE 0x02
|
||||
#define REG_SCENE_SPORTS 0x03
|
||||
#define REG_SCENE_PARTY_INDOOR 0x04
|
||||
#define REG_SCENE_BEACH_SNOW 0x05
|
||||
#define REG_SCENE_SUNSET 0x06
|
||||
#define REG_SCENE_DAWN_DUSK 0x07
|
||||
#define REG_SCENE_FALL 0x08
|
||||
#define REG_SCENE_NIGHT 0x09
|
||||
#define REG_SCENE_AGAINST_LIGHT 0x0a
|
||||
#define REG_SCENE_FIRE 0x0b
|
||||
#define REG_SCENE_TEXT 0x0c
|
||||
#define REG_SCENE_CANDLE 0x0d
|
||||
|
||||
/* Manual gain in MONITOR mode */
|
||||
#define AE_MAN_GAIN_MON I2C_REG(CAT_AE, 0x12, 2)
|
||||
/* Maximum gain in MONITOR mode */
|
||||
#define AE_MAX_GAIN_MON I2C_REG(CAT_AE, 0x1a, 2)
|
||||
/* Manual gain in CAPTURE mode */
|
||||
#define AE_MAN_GAIN_CAP I2C_REG(CAT_AE, 0x26, 2)
|
||||
|
||||
#define AE_INDEX I2C_REG(CAT_AE, 0x38, 1)
|
||||
#define REG_AE_INDEX_20_NEG 0x00
|
||||
#define REG_AE_INDEX_15_NEG 0x01
|
||||
#define REG_AE_INDEX_10_NEG 0x02
|
||||
#define REG_AE_INDEX_05_NEG 0x03
|
||||
#define REG_AE_INDEX_00 0x04
|
||||
#define REG_AE_INDEX_05_POS 0x05
|
||||
#define REG_AE_INDEX_10_POS 0x06
|
||||
#define REG_AE_INDEX_15_POS 0x07
|
||||
#define REG_AE_INDEX_20_POS 0x08
|
||||
|
||||
/*
|
||||
* Category 6 - White Balance
|
||||
*/
|
||||
|
||||
/* Auto Whitebalance locking */
|
||||
#define AWB_LOCK I2C_REG(CAT_WB, 0x00, 1)
|
||||
#define REG_AWB_UNLOCK 0x00
|
||||
#define REG_AWB_LOCK 0x01
|
||||
|
||||
#define AWB_MODE I2C_REG(CAT_WB, 0x02, 1)
|
||||
#define REG_AWB_AUTO 0x01 /* AWB off */
|
||||
#define REG_AWB_PRESET 0x02 /* AWB preset */
|
||||
|
||||
/* Manual WB (preset) */
|
||||
#define AWB_MANUAL I2C_REG(CAT_WB, 0x03, 1)
|
||||
#define REG_AWB_INCANDESCENT 0x01
|
||||
#define REG_AWB_FLUORESCENT_1 0x02
|
||||
#define REG_AWB_FLUORESCENT_2 0x03
|
||||
#define REG_AWB_DAYLIGHT 0x04
|
||||
#define REG_AWB_CLOUDY 0x05
|
||||
#define REG_AWB_SHADE 0x06
|
||||
#define REG_AWB_HORIZON 0x07
|
||||
#define REG_AWB_LEDLIGHT 0x09
|
||||
|
||||
/*
|
||||
* Category 7 - EXIF information
|
||||
*/
|
||||
#define EXIF_INFO_EXPTIME_NU I2C_REG(CAT_EXIF, 0x00, 4)
|
||||
#define EXIF_INFO_EXPTIME_DE I2C_REG(CAT_EXIF, 0x04, 4)
|
||||
#define EXIF_INFO_TV_NU I2C_REG(CAT_EXIF, 0x08, 4)
|
||||
#define EXIF_INFO_TV_DE I2C_REG(CAT_EXIF, 0x0c, 4)
|
||||
#define EXIF_INFO_AV_NU I2C_REG(CAT_EXIF, 0x10, 4)
|
||||
#define EXIF_INFO_AV_DE I2C_REG(CAT_EXIF, 0x14, 4)
|
||||
#define EXIF_INFO_BV_NU I2C_REG(CAT_EXIF, 0x18, 4)
|
||||
#define EXIF_INFO_BV_DE I2C_REG(CAT_EXIF, 0x1c, 4)
|
||||
#define EXIF_INFO_EBV_NU I2C_REG(CAT_EXIF, 0x20, 4)
|
||||
#define EXIF_INFO_EBV_DE I2C_REG(CAT_EXIF, 0x24, 4)
|
||||
#define EXIF_INFO_ISO I2C_REG(CAT_EXIF, 0x28, 2)
|
||||
#define EXIF_INFO_FLASH I2C_REG(CAT_EXIF, 0x2a, 2)
|
||||
#define EXIF_INFO_SDR I2C_REG(CAT_EXIF, 0x2c, 2)
|
||||
#define EXIF_INFO_QVAL I2C_REG(CAT_EXIF, 0x2e, 2)
|
||||
|
||||
/*
|
||||
* Category 9 - Face Detection
|
||||
*/
|
||||
#define FD_CTL I2C_REG(CAT_FD, 0x00, 1)
|
||||
#define BIT_FD_EN 0
|
||||
#define BIT_FD_DRAW_FACE_FRAME 4
|
||||
#define BIT_FD_DRAW_SMILE_LVL 6
|
||||
#define REG_FD(shift) (1 << shift)
|
||||
#define REG_FD_OFF 0x0
|
||||
|
||||
/*
|
||||
* Category A - Lens Parameter
|
||||
*/
|
||||
#define AF_MODE I2C_REG(CAT_LENS, 0x01, 1)
|
||||
#define REG_AF_NORMAL 0x00 /* Normal AF, one time */
|
||||
#define REG_AF_MACRO 0x01 /* Macro AF, one time */
|
||||
#define REG_AF_POWEROFF 0x07
|
||||
|
||||
#define AF_EXECUTE I2C_REG(CAT_LENS, 0x02, 1)
|
||||
#define REG_AF_STOP 0x00
|
||||
#define REG_AF_EXE_AUTO 0x01
|
||||
#define REG_AF_EXE_CAF 0x02
|
||||
|
||||
#define AF_STATUS I2C_REG(CAT_LENS, 0x03, 1)
|
||||
#define REG_AF_FAIL 0x00
|
||||
#define REG_AF_SUCCESS 0x02
|
||||
#define REG_AF_IDLE 0x04
|
||||
#define REG_AF_BUSY 0x05
|
||||
|
||||
#define AF_VERSION I2C_REG(CAT_LENS, 0x0a, 1)
|
||||
|
||||
/*
|
||||
* Category B - CAPTURE Parameter
|
||||
*/
|
||||
#define CAPP_YUVOUT_MAIN I2C_REG(CAT_CAPT_PARM, 0x00, 1)
|
||||
#define REG_YUV422 0x00
|
||||
#define REG_BAYER10 0x05
|
||||
#define REG_BAYER8 0x06
|
||||
#define REG_JPEG 0x10
|
||||
|
||||
#define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1)
|
||||
#define CAPP_JPEG_SIZE_MAX I2C_REG(CAT_CAPT_PARM, 0x0f, 4)
|
||||
#define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1)
|
||||
|
||||
#define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1)
|
||||
#define REG_MCC_OFF 0x00
|
||||
#define REG_MCC_NORMAL 0x01
|
||||
|
||||
#define CAPP_WDR_EN I2C_REG(CAT_CAPT_PARM, 0x2c, 1)
|
||||
#define REG_WDR_OFF 0x00
|
||||
#define REG_WDR_ON 0x01
|
||||
#define REG_WDR_AUTO 0x02
|
||||
|
||||
#define CAPP_LIGHT_CTRL I2C_REG(CAT_CAPT_PARM, 0x40, 1)
|
||||
#define REG_LIGHT_OFF 0x00
|
||||
#define REG_LIGHT_ON 0x01
|
||||
#define REG_LIGHT_AUTO 0x02
|
||||
|
||||
#define CAPP_FLASH_CTRL I2C_REG(CAT_CAPT_PARM, 0x41, 1)
|
||||
#define REG_FLASH_OFF 0x00
|
||||
#define REG_FLASH_ON 0x01
|
||||
#define REG_FLASH_AUTO 0x02
|
||||
|
||||
/*
|
||||
* Category C - CAPTURE Control
|
||||
*/
|
||||
#define CAPC_MODE I2C_REG(CAT_CAPT_CTRL, 0x00, 1)
|
||||
#define REG_CAP_NONE 0x00
|
||||
#define REG_CAP_ANTI_SHAKE 0x02
|
||||
|
||||
/* Select single- or multi-shot capture */
|
||||
#define CAPC_SEL_FRAME I2C_REG(CAT_CAPT_CTRL, 0x06, 1)
|
||||
|
||||
#define CAPC_START I2C_REG(CAT_CAPT_CTRL, 0x09, 1)
|
||||
#define REG_CAP_START_MAIN 0x01
|
||||
#define REG_CAP_START_THUMB 0x03
|
||||
|
||||
#define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, 0x0d, 4)
|
||||
#define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, 0x11, 4)
|
||||
|
||||
/*
|
||||
* Category F - Flash
|
||||
*
|
||||
* This mode provides functions about internal flash stuff and system startup.
|
||||
*/
|
||||
|
||||
/* Starts internal ARM core booting after power-up */
|
||||
#define FLASH_CAM_START I2C_REG(CAT_FLASH, 0x12, 1)
|
||||
#define REG_START_ARM_BOOT 0x01 /* write value */
|
||||
#define REG_IN_FLASH_MODE 0x00 /* read value */
|
||||
|
||||
#endif /* M5MOLS_REG_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue