diff options
| author | Yauhen Kharuzhy <jekhor@gmail.com> | 2012-10-16 18:15:13 +0300 |
|---|---|---|
| committer | Justin Waters <justin.waters@timesys.com> | 2013-11-07 12:19:17 -0500 |
| commit | 6a8d5e31cfbda7badbc399c06275294e56d699bd (patch) | |
| tree | 6a8f815d946cba9f4d69a4a69ec40ec59523dfdd | |
| parent | e931ef1741fa54626700cdc3c9d21ba5d7db741b (diff) | |
mt9m111 slave driver was ported from mainline one to Freescale's framework
Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com>
Signed-off-by: Christian Hemp <c.hemp@phytec.de>
| -rw-r--r-- | drivers/media/video/mxc/capture/mt9m111.c | 958 | ||||
| -rw-r--r-- | drivers/media/video/mxc/capture/mt9m111.h | 458 |
2 files changed, 577 insertions, 839 deletions
diff --git a/drivers/media/video/mxc/capture/mt9m111.c b/drivers/media/video/mxc/capture/mt9m111.c index 73808e5fb97c..f557b24e00c6 100644 --- a/drivers/media/video/mxc/capture/mt9m111.c +++ b/drivers/media/video/mxc/capture/mt9m111.c @@ -18,6 +18,9 @@ * * @ingroup Camera */ + +#define DEBUG + #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -28,6 +31,8 @@ #include <linux/i2c.h> #include <linux/clk.h> #include <media/v4l2-int-device.h> +#include <linux/v4l2-mediabus.h> +#include <media/v4l2-chip-ident.h> #include "mxc_v4l2_capture.h" #include "mt9m111.h" @@ -35,14 +40,18 @@ static u16 testpattern; #endif -static mt9m111_conf mt9m111_device; - /*! * Holds the current frame rate. */ static int reset_frame_rate = MT9M111_FRAME_RATE; -struct sensor { +/* MT9M111 has only one fixed colorspace per pixelcode */ +struct mt9m111_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +struct mt9m111_data { const struct mt9m111_platform_data *platform_data; struct v4l2_int_device *v4l2_int_device; struct i2c_client *i2c_client; @@ -60,420 +69,357 @@ struct sensor { int blue; int ae_mode; -} mt9m111_data; + u32 mclk; + u8 mclk_source; + int csi; + + void (*io_init)(void); + + int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code + * from v4l2-chip-ident.h */ + enum mt9m111_context context; + struct v4l2_rect rect; + const struct mt9m111_datafmt *fmt; + unsigned int gain; + unsigned char autoexposure; + unsigned char datawidth; + unsigned int powered:1; + unsigned int hflip:1; + unsigned int vflip:1; + unsigned int swap_rgb_even_odd:1; + unsigned int swap_rgb_red_blue:1; + unsigned int swap_yuv_y_chromas:1; + unsigned int swap_yuv_cb_cr:1; + unsigned int autowhitebalance:1; + +}; extern void gpio_sensor_active(void); extern void gpio_sensor_inactive(void); -static int mt9m111_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int mt9m111_remove(struct i2c_client *client); - -static const struct i2c_device_id mt9m111_id[] = { - {"mt9m111", 0}, - {}, -}; - -MODULE_DEVICE_TABLE(i2c, mt9m111_id); - -static struct i2c_driver mt9m111_i2c_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "mt9m111", - }, - .probe = mt9m111_probe, - .remove = mt9m111_remove, - .id_table = mt9m111_id, -/* To add power management add .suspend and .resume functions */ -}; +#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg) +#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val)) +#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val)) +#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) /* * Function definitions */ -#ifdef MT9M111_DEBUG -static inline int mt9m111_read_reg(u8 reg) +static struct mt9m111_data *to_mt9m111(const struct i2c_client *client) { - printk("::: mt9m111_read_reg\n"); - - int val = i2c_smbus_read_word_data(mt9m111_data.i2c_client, reg); - if (val != -1) - val = cpu_to_be16(val); + return i2c_get_clientdata(client); +} - printk("::: mt9m111_read_reg (END, ret=%d)\n", val); - return val; +static struct mt9m111_data *v4l2_to_mt9m111(const struct v4l2_int_device *dev) +{ + return dev->priv; } -#endif -/*! - * Writes to the register via I2C. - */ -static inline int mt9m111_write_reg(u8 reg, u16 val) +static int reg_page_map_set(struct i2c_client *client, const u16 reg) { - printk("::: mt9m111_write_reg\n"); - - pr_debug("In mt9m111_write_reg (0x%x, 0x%x)\n", reg, val); - pr_debug(" write reg %x val %x.\n", reg, val); + int ret; + u16 page; + static int lastpage = -1; /* PageMap cache value */ + + page = (reg >> 8); + if (page == lastpage) + return 0; + if (page > 2) + return -EINVAL; + + ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); + if (!ret) + lastpage = page; + return ret; +} - int ret = i2c_smbus_write_word_data(mt9m111_data.i2c_client, - reg, cpu_to_be16(val)); - - printk("::: mt9m111_write_reg (END, ret=%d)\n", ret); - +static int mt9m111_reg_read(struct i2c_client *client, const u16 reg) +{ + int ret; + + ret = reg_page_map_set(client, reg); + if (!ret) + ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff)); + + dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); return ret; } -/*! - * Initialize mt9m111_sensor_lib - * Libarary for Sensor configuration through I2C - * - * @param coreReg Core Registers - * @param ifpReg IFP Register - * - * @return status - */ -static u8 mt9m111_sensor_lib(mt9m111_coreReg *coreReg, mt9m111_IFPReg *ifpReg) +static int mt9m111_reg_write(struct i2c_client *client, const u16 reg, + const u16 data) { - printk("::: mt9m111_sensor_lib\n"); - - u8 reg; - u16 data; - u8 error = 0; + int ret; - pr_debug("In mt9m111_sensor_lib\n"); + ret = reg_page_map_set(client, reg); + if (!ret) + ret = i2c_smbus_write_word_data(client, reg & 0xff, + swab16(data)); + dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); + return ret; +} - /* - * setup to IFP registers - */ - reg = MT9M111I_ADDR_SPACE_SEL; - data = ifpReg->addrSpaceSel; - mt9m111_write_reg(reg, data); - - /* Operation Mode Control */ - reg = MT9M111I_MODE_CONTROL; - data = ifpReg->modeControl; - mt9m111_write_reg(reg, data); - - /* Output format */ - reg = MT9M111I_FORMAT_CONTROL; - data = ifpReg->formatControl; /* Set bit 12 */ - mt9m111_write_reg(reg, data); - - /* AE limit 4 */ - reg = MT9M111I_SHUTTER_WIDTH_LIMIT_AE; - data = ifpReg->gainLimitAE; - mt9m111_write_reg(reg, data); - - reg = MT9M111I_OUTPUT_FORMAT_CTRL2; - data = ifpReg->outputFormatCtrl2; - mt9m111_write_reg(reg, data); - - reg = MT9M111I_AE_SPEED; - data = ifpReg->AESpeed; - mt9m111_write_reg(reg, data); - - /* output image size */ - reg = MT9M111i_H_PAN; - data = 0x8000 | ifpReg->HPan; - mt9m111_write_reg(reg, data); - - reg = MT9M111i_H_ZOOM; - data = 0x8000 | ifpReg->HZoom; - mt9m111_write_reg(reg, data); - - reg = MT9M111i_H_SIZE; - data = 0x8000 | ifpReg->HSize; - mt9m111_write_reg(reg, data); - - reg = MT9M111i_V_PAN; - data = 0x8000 | ifpReg->VPan; - mt9m111_write_reg(reg, data); - - reg = MT9M111i_V_ZOOM; - data = 0x8000 | ifpReg->VZoom; - mt9m111_write_reg(reg, data); - - reg = MT9M111i_V_SIZE; - data = 0x8000 | ifpReg->VSize; - mt9m111_write_reg(reg, data); - - reg = MT9M111i_H_PAN; - data = ~0x8000 & ifpReg->HPan; - mt9m111_write_reg(reg, data); -#if 0 - reg = MT9M111I_UPPER_SHUTTER_DELAY_LIM; - data = ifpReg->upperShutterDelayLi; - mt9m111_write_reg(reg, data); - - reg = MT9M111I_SHUTTER_60; - data = ifpReg->shutter_width_60; - mt9m111_write_reg(reg, data); - - reg = MT9M111I_SEARCH_FLICK_60; - data = ifpReg->search_flicker_60; - mt9m111_write_reg(reg, data); -#endif +static int mt9m111_reg_set(struct i2c_client *client, const u16 reg, + const u16 data) +{ + int ret; - /* - * setup to sensor core registers - */ - reg = MT9M111I_ADDR_SPACE_SEL; - data = coreReg->addressSelect; - mt9m111_write_reg(reg, data); - - /* enable changes and put the Sync bit on */ - reg = MT9M111S_OUTPUT_CTRL; - data = MT9M111S_OUTCTRL_SYNC | MT9M111S_OUTCTRL_CHIP_ENABLE | 0x3000; - mt9m111_write_reg(reg, data); - - /* min PIXCLK - Default */ - reg = MT9M111S_PIXEL_CLOCK_SPEED; - data = coreReg->pixelClockSpeed; - mt9m111_write_reg(reg, data); - - /* Setup image flipping / Dark rows / row/column skip */ - reg = MT9M111S_READ_MODE; - data = coreReg->readMode; - mt9m111_write_reg(reg, data); - - /* zoom 0 */ - reg = MT9M111S_DIGITAL_ZOOM; - data = coreReg->digitalZoom; - mt9m111_write_reg(reg, data); - - /* min H-blank */ - reg = MT9M111S_HOR_BLANKING; - data = coreReg->horizontalBlanking; - mt9m111_write_reg(reg, data); - - /* min V-blank */ - reg = MT9M111S_VER_BLANKING; - data = coreReg->verticalBlanking; - mt9m111_write_reg(reg, data); - - reg = MT9M111S_SHUTTER_WIDTH; - data = coreReg->shutterWidth; - mt9m111_write_reg(reg, data); - - reg = MT9M111S_SHUTTER_DELAY; - data = ifpReg->upperShutterDelayLi; - mt9m111_write_reg(reg, data); - - /* changes become effective */ - reg = MT9M111S_OUTPUT_CTRL; - data = MT9M111S_OUTCTRL_CHIP_ENABLE | 0x3000; - mt9m111_write_reg(reg, data); - - printk("::: mt9m111_sensor_lib (END, error=%d)\n", error); - - return error; + ret = mt9m111_reg_read(client, reg); + if (ret >= 0) + ret = mt9m111_reg_write(client, reg, ret | data); + return ret; } -/*! - * MT9M111 frame rate calculate - * - * @param frame_rate int * - * @param mclk int - * @return None - */ -static void mt9m111_rate_cal(int *frame_rate, int mclk) +static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg, + const u16 data) { - printk("::: mt9m111_rate_cal\n"); - - int num_clock_per_row; - int max_rate = 0; + int ret; - pr_debug("In mt9m111_rate_cal\n"); + ret = mt9m111_reg_read(client, reg); + return mt9m111_reg_write(client, reg, ret & ~data); +} - num_clock_per_row = (MT9M111_MAX_WIDTH + 114 + MT9M111_HORZBLANK_MIN) - * 2; - max_rate = mclk / (num_clock_per_row * - (MT9M111_MAX_HEIGHT + MT9M111_VERTBLANK_DEFAULT)); +static int mt9m111_set_context(struct i2c_client *client, + enum mt9m111_context ctxt) +{ + int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B + | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B + | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B + | MT9M111_CTXT_CTRL_VBLANK_SEL_B + | MT9M111_CTXT_CTRL_HBLANK_SEL_B; + int valA = MT9M111_CTXT_CTRL_RESTART; + + if (ctxt == HIGHPOWER) + return reg_write(CONTEXT_CONTROL, valB); + else + return reg_write(CONTEXT_CONTROL, valA); +} + +static int mt9m111_setup_rect(struct i2c_client *client, + struct v4l2_rect *rect) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int ret, is_raw_format; + int width = rect->width; + int height = rect->height; + + if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || + mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) + is_raw_format = 1; + else + is_raw_format = 0; + + ret = reg_write(COLUMN_START, rect->left); + if (!ret) + ret = reg_write(ROW_START, rect->top); - if ((*frame_rate > max_rate) || (*frame_rate == 0)) { - *frame_rate = max_rate; + if (is_raw_format) { + if (!ret) + ret = reg_write(WINDOW_WIDTH, width); + if (!ret) + ret = reg_write(WINDOW_HEIGHT, height); + } else { + if (!ret) + ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); + if (!ret) + ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); + if (!ret) + ret = reg_write(REDUCER_XSIZE_B, width); + if (!ret) + ret = reg_write(REDUCER_YSIZE_B, height); + if (!ret) + ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); + if (!ret) + ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); + if (!ret) + ret = reg_write(REDUCER_XSIZE_A, width); + if (!ret) + ret = reg_write(REDUCER_YSIZE_A, height); } - mt9m111_device.coreReg->verticalBlanking - = mclk / (*frame_rate * num_clock_per_row) - MT9M111_MAX_HEIGHT; + return ret; +} - reset_frame_rate = *frame_rate; +static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) +{ + int ret; + u16 mask = MT9M111_OUTFMT_PROCESSED_BAYER | MT9M111_OUTFMT_RGB | + MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_SWAP_RGB_EVEN | + MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_RGB555 | + MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr | + MT9M111_OUTFMT_SWAP_YCbCr_C_Y; + + ret = reg_read(OUTPUT_FORMAT_CTRL2_A); + if (ret >= 0) + ret = reg_write(OUTPUT_FORMAT_CTRL2_A, (ret & ~mask) | outfmt); + if (!ret) + ret = reg_read(OUTPUT_FORMAT_CTRL2_B); + if (ret >= 0) + ret = reg_write(OUTPUT_FORMAT_CTRL2_B, (ret & ~mask) | outfmt); - printk("::: mt9m111_rate_cal (END)\n"); + return ret; } -/*! - * MT9M111 sensor configuration - */ -void mt9m111_config(void) +static int mt9m111_setfmt_bayer8(struct i2c_client *client) { - printk("::: mt9m111_config\n"); - - pr_debug("In mt9m111_config\n"); - - mt9m111_device.coreReg->addressSelect = MT9M111I_SEL_SCA; - mt9m111_device.ifpReg->addrSpaceSel = MT9M111I_SEL_IFP; - - mt9m111_device.coreReg->windowHeight = MT9M111_WINHEIGHT; - mt9m111_device.coreReg->windowWidth = MT9M111_WINWIDTH; - mt9m111_device.coreReg->zoomColStart = 0; - mt9m111_device.coreReg->zomRowStart = 0; - mt9m111_device.coreReg->digitalZoom = 0x0; - - mt9m111_device.coreReg->verticalBlanking = MT9M111_VERTBLANK_DEFAULT; - mt9m111_device.coreReg->horizontalBlanking = MT9M111_HORZBLANK_MIN; - mt9m111_device.coreReg->pixelClockSpeed = 0; - mt9m111_device.coreReg->readMode = 0xd0a1; - - mt9m111_device.ifpReg->outputFormatCtrl2 = 0; - mt9m111_device.ifpReg->gainLimitAE = 0x300; - mt9m111_device.ifpReg->AESpeed = 0x80; - - /* here is the default value */ - mt9m111_device.ifpReg->formatControl = 0xc800; - mt9m111_device.ifpReg->modeControl = 0x708e; - mt9m111_device.ifpReg->awbSpeed = 0x4514; - mt9m111_device.coreReg->shutterWidth = 0xf8; - - /* output size */ - mt9m111_device.ifpReg->HPan = 0; - mt9m111_device.ifpReg->HZoom = MT9M111_MAX_WIDTH; - mt9m111_device.ifpReg->HSize = MT9M111_MAX_WIDTH; - mt9m111_device.ifpReg->VPan = 0; - mt9m111_device.ifpReg->VZoom = MT9M111_MAX_HEIGHT; - mt9m111_device.ifpReg->VSize = MT9M111_MAX_HEIGHT; - - printk("::: mt9m111_config (END)\n"); + return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER | + MT9M111_OUTFMT_RGB); } -/*! - * mt9m111 sensor set saturtionn - * - * @param saturation int +static int mt9m111_setfmt_bayer10(struct i2c_client *client) +{ + return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP); +} - * @return Error code of 0. - */ -static int mt9m111_set_saturation(int saturation) +static int mt9m111_setfmt_rgb565(struct i2c_client *client) { - printk("::: mt9m111_set_saturation\n"); - - u8 reg; - u16 data; - pr_debug("In mt9m111_set_saturation(%d)\n", - saturation); + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int val = 0; - switch (saturation) { - case 150: - mt9m111_device.ifpReg->awbSpeed = 0x6D14; - break; - case 100: - mt9m111_device.ifpReg->awbSpeed = 0x4514; - break; - case 75: - mt9m111_device.ifpReg->awbSpeed = 0x4D14; - break; - case 50: - mt9m111_device.ifpReg->awbSpeed = 0x5514; - break; - case 37: - mt9m111_device.ifpReg->awbSpeed = 0x5D14; - break; - case 25: - mt9m111_device.ifpReg->awbSpeed = 0x6514; - break; - default: - mt9m111_device.ifpReg->awbSpeed = 0x4514; - break; + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; + + return mt9m111_setup_pixfmt(client, val); +} + +static int mt9m111_setfmt_rgb555(struct i2c_client *client) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; + + return mt9m111_setup_pixfmt(client, val); +} + +static int mt9m111_setfmt_yuv(struct i2c_client *client) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int val = 0; + + if (mt9m111->swap_yuv_cb_cr) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_yuv_y_chromas) + val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; + + return mt9m111_setup_pixfmt(client, val); +} + +static int mt9m111_enable(struct i2c_client *client) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int ret; + + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); + if (!ret) + mt9m111->powered = 1; + return ret; +} + +static int mt9m111_reset(struct i2c_client *client) +{ + int ret; + + ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); + if (!ret) + ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); + if (!ret) + ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE + | MT9M111_RESET_RESET_SOC); + + return ret; +} + +static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int ret; + + if (mt9m111->context == HIGHPOWER) { + if (flip) + ret = reg_set(READ_MODE_B, mask); + else + ret = reg_clear(READ_MODE_B, mask); + } else { + if (flip) + ret = reg_set(READ_MODE_A, mask); + else + ret = reg_clear(READ_MODE_A, mask); } - reg = MT9M111I_ADDR_SPACE_SEL; - data = mt9m111_device.ifpReg->addrSpaceSel; - mt9m111_write_reg(reg, data); + return ret; +} - /* Operation Mode Control */ - reg = MT9M111I_AWB_SPEED; - data = mt9m111_device.ifpReg->awbSpeed; - mt9m111_write_reg(reg, data); +static int mt9m111_get_global_gain(struct i2c_client *client) +{ + int data; - printk("::: mt9m111_set_saturation (END)\n"); - - return 0; + data = reg_read(GLOBAL_GAIN); + if (data >= 0) + return (data & 0x2f) * (1 << ((data >> 10) & 1)) * + (1 << ((data >> 9) & 1)); + return data; } -/*! - * mt9m111 sensor set Auto Exposure measurement window mode configuration - * - * @param ae_mode int - * @return Error code of 0 (no Error) - */ -static int mt9m111_set_ae_mode(int ae_mode) +static int mt9m111_set_global_gain(struct i2c_client *client, int gain) { - printk("::: mt9m111_set_ae_mode\n"); - - u8 reg; - u16 data; + struct mt9m111_data *mt9m111 = to_mt9m111(client); + u16 val; - pr_debug("In mt9m111_set_ae_mode(%d)\n", - ae_mode); + if (gain > 63 * 2 * 2) + return -EINVAL; - /* Currently this driver only supports auto and manual exposure - * modes. */ - if ((ae_mode > 1) || (ae_mode << 0)) - { - printk("::: mt9m111_set_ae_mode (END, error=-EPERM)\n"); - - return -EPERM; - } - - /* - * The auto exposure is set in bit 14. - * Other values are set for: - * -on the fly defect correction is on (bit 13). - * -aperature correction knee enabled (bit 12). - * -ITU_R BT656 synchronization codes are embedded in the image (bit 7) - * -AE measurement window is weighted sum of large and center windows - * (bits 2-3). - * -auto white balance is on (bit 1). - * -normal color processing (bit 4 = 0). - */ - /* V4L2_EXPOSURE_AUTO = 0; needs register setting of 0x708E */ - /* V4L2_EXPOSURE_MANUAL = 1 needs register setting of 0x308E */ - mt9m111_device.ifpReg->modeControl &= 0x3fff; - mt9m111_device.ifpReg->modeControl |= (ae_mode & 0x03) << 14; - mt9m111_data.ae_mode = ae_mode; + mt9m111->gain = gain; + if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) + val = (1 << 10) | (1 << 9) | (gain / 4); + else if ((gain >= 64) && (gain < 64 * 2)) + val = (1 << 9) | (gain / 2); + else + val = gain; - reg = MT9M111I_ADDR_SPACE_SEL; - data = mt9m111_device.ifpReg->addrSpaceSel; - mt9m111_write_reg(reg, data); + return reg_write(GLOBAL_GAIN, val); +} - reg = MT9M111I_MODE_CONTROL; - data = mt9m111_device.ifpReg->modeControl; - mt9m111_write_reg(reg, data); +static int mt9m111_set_autoexposure(struct i2c_client *client, int on) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int ret; - printk("::: mt9m111_set_ae_mode (END)\n"); - - return 0; + if (on) + ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + else + ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + + if (!ret) + mt9m111->autoexposure = on; + + return ret; } -/*! - * mt9m111 sensor get AE measurement window mode configuration - * - * @param ae_mode int * - * @return None - */ -static void mt9m111_get_ae_mode(int *ae_mode) +static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on) { - printk("::: mt9m111_get_ae_mode\n"); - - pr_debug("In mt9m111_get_ae_mode(%d)\n", *ae_mode); + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int ret; - if (ae_mode != NULL) { - *ae_mode = (mt9m111_device.ifpReg->modeControl & 0xc) >> 2; - } + if (on) + ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN); + else + ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN); + + if (!ret) + mt9m111->autowhitebalance = on; - printk("::: mt9m111_get_ae_mode (END)\n"); + return ret; } + #ifdef MT9M111_DEBUG /*! * Set sensor to test mode, which will generate test pattern. @@ -515,6 +461,24 @@ static void mt9m111_test_pattern(bool flag) } #endif +static int mt9m111_sensor_init(struct i2c_client *client) +{ + struct mt9m111_data *mt9m111 = to_mt9m111(client); + int ret; + + mt9m111->context = HIGHPOWER; + ret = mt9m111_enable(client); + if (!ret) + ret = mt9m111_reset(client); + if (!ret) + ret = mt9m111_set_context(client, mt9m111->context); + if (!ret) + ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure); + if (ret) + dev_err(&client->dev, "mt9m111 init failed: %d\n", ret); + return ret; +} + /* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */ @@ -538,8 +502,6 @@ static void mt9m111_test_pattern(bool flag) */ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) { - printk("::: ioctl_g_ifparm\n"); - pr_debug("In mt9m111:ioctl_g_ifparm\n"); if (s == NULL) { @@ -556,8 +518,6 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) p->u.bt656.clock_min = MT9M111_CLK_MIN; p->u.bt656.clock_max = MT9M111_CLK_MAX; - printk("::: ioctl_g_ifparm (END)\n"); - return 0; } @@ -576,21 +536,17 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) */ static int ioctl_s_power(struct v4l2_int_device *s, int on) { - printk("::: ioctl_s_power\n"); - - struct sensor *sensor = s->priv; + struct mt9m111_data *sensor = s->priv; pr_debug("In mt9m111:ioctl_s_power\n"); - sensor->on = on; + sensor->powered = on; if (on) gpio_sensor_active(); else gpio_sensor_inactive(); - printk("::: ioctl_s_power (END)\n"); - return 0; } @@ -603,8 +559,7 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on) */ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) { - printk("::: ioctl_g_parm\n"); - + struct mt9m111_data *mt9m111 = v4l2_to_mt9m111(s); int ret = 0; struct v4l2_captureparm *cparm = &a->parm.capture; /* s->priv points to mt9m111_data */ @@ -617,10 +572,10 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); memset(a, 0, sizeof(*a)); a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cparm->capability = mt9m111_data.streamcap.capability; + cparm->capability = mt9m111->streamcap.capability; cparm->timeperframe = - mt9m111_data.streamcap.timeperframe; - cparm->capturemode = mt9m111_data.streamcap.capturemode; + mt9m111->streamcap.timeperframe; + cparm->capturemode = mt9m111->streamcap.capturemode; ret = 0; break; @@ -642,8 +597,6 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) break; } - printk("::: ioctl_g_parm (END, ret=%d)\n", ret); - return ret; } @@ -658,8 +611,7 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) */ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) { - printk("::: ioctl_s_parm\n"); - + struct mt9m111_data *mt9m111 = v4l2_to_mt9m111(s); int ret = 0; struct v4l2_captureparm *cparm = &a->parm.capture; /* s->priv points to mt9m111_data */ @@ -675,13 +627,13 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) * Changing the frame rate is not allowed on this *camera. */ if (cparm->timeperframe.denominator != - mt9m111_data.streamcap.timeperframe.denominator) { + mt9m111->streamcap.timeperframe.denominator) { pr_err("ERROR: mt9m111: ioctl_s_parm: " \ "This camera does not allow frame rate " "changes.\n"); ret = -EINVAL; } else { - mt9m111_data.streamcap.timeperframe = + mt9m111->streamcap.timeperframe = cparm->timeperframe; /* Call any camera functions to match settings. */ } @@ -693,7 +645,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) "unsupported capture mode\n"); ret = -EINVAL; } else { - mt9m111_data.streamcap.capturemode = + mt9m111->streamcap.capturemode = cparm->capturemode; /* Call any camera functions to match settings. */ /* Right now this camera only supports 1 mode. */ @@ -718,9 +670,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) break; } - printk("::: ioctl_s_parm (END, ret=%d)\n", ret); - - return 0; // TODO: wtf, must return 'ret' + return ret; } /*! @@ -733,9 +683,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) */ static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) { - printk("::: ioctl_g_fmt_cap\n"); - - struct sensor *sensor = s->priv; + struct mt9m111_data *sensor = s->priv; /* s->priv points to mt9m111_data */ pr_debug("In mt9m111:ioctl_g_fmt_cap.\n"); @@ -744,8 +692,6 @@ static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) f->fmt.pix = sensor->pix; - printk("::: ioctl_g_fmt_cap (END)\n"); - return 0; } @@ -760,12 +706,8 @@ static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) */ static int ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qc) { - printk("::: ioctl_queryctrl\n"); - pr_debug("In mt9m111:ioctl_queryctrl\n"); - printk("::: ioctl_queryctrl (END)\n"); - return 0; } @@ -780,31 +722,33 @@ static int ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qc) */ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) { - printk("::: ioctl_g_ctrl\n"); + struct mt9m111_data *mt9m111 = v4l2_to_mt9m111(s); + struct i2c_client *client = mt9m111->i2c_client; + int data; pr_debug("In mt9m111:ioctl_g_ctrl\n"); switch (vc->id) { case V4L2_CID_BRIGHTNESS: pr_debug(" V4L2_CID_BRIGHTNESS\n"); - vc->value = mt9m111_data.brightness; + vc->value = 0; break; case V4L2_CID_CONTRAST: pr_debug(" V4L2_CID_CONTRAST\n"); - vc->value = mt9m111_data.contrast; + vc->value = 0; break; case V4L2_CID_SATURATION: pr_debug(" V4L2_CID_SATURATION\n"); - vc->value = mt9m111_data.saturation; + vc->value = 0; break; case V4L2_CID_HUE: pr_debug(" V4L2_CID_HUE\n"); - vc->value = mt9m111_data.hue; + vc->value = 0; break; case V4L2_CID_AUTO_WHITE_BALANCE: pr_debug( " V4L2_CID_AUTO_WHITE_BALANCE\n"); - vc->value = 0; + vc->value = mt9m111->autowhitebalance; break; case V4L2_CID_DO_WHITE_BALANCE: pr_debug( @@ -813,11 +757,11 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) break; case V4L2_CID_RED_BALANCE: pr_debug(" V4L2_CID_RED_BALANCE\n"); - vc->value = mt9m111_data.red; + vc->value = 0; break; case V4L2_CID_BLUE_BALANCE: pr_debug(" V4L2_CID_BLUE_BALANCE\n"); - vc->value = mt9m111_data.blue; + vc->value = 0; break; case V4L2_CID_GAMMA: pr_debug(" V4L2_CID_GAMMA\n"); @@ -825,7 +769,11 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) break; case V4L2_CID_EXPOSURE: pr_debug(" V4L2_CID_EXPOSURE\n"); - vc->value = mt9m111_data.ae_mode; + vc->value = 0; + break; + case V4L2_CID_EXPOSURE_AUTO: + pr_debug(" V4L2_CID_EXPOSURE_AUTO\n"); + vc->value = mt9m111->autoexposure; break; case V4L2_CID_AUTOGAIN: pr_debug(" V4L2_CID_AUTOGAIN\n"); @@ -833,25 +781,40 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) break; case V4L2_CID_GAIN: pr_debug(" V4L2_CID_GAIN\n"); - vc->value = 0; + data = mt9m111_get_global_gain(client); + if (data < 0) + return data; + vc->value = data; break; case V4L2_CID_HFLIP: pr_debug(" V4L2_CID_HFLIP\n"); - vc->value = 0; + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + vc->value = !!(data & MT9M111_RMB_MIRROR_COLS); break; case V4L2_CID_VFLIP: pr_debug(" V4L2_CID_VFLIP\n"); - vc->value = 0; + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + vc->value = !!(data & MT9M111_RMB_MIRROR_ROWS); break; default: pr_debug(" Default case\n"); - printk("::: ioctl_g_ctrl (END, error=-EPERM)\n"); - return -EPERM; + printk("::: ioctl_g_ctrl (END, error=-EINVAL)\n"); + return -EINVAL; break; } - printk("::: ioctl_g_ctrl (END)\n"); - return 0; } @@ -866,8 +829,8 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) */ static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) { - printk("::: ioctl_s_ctrl\n"); - + struct mt9m111_data *mt9m111 = v4l2_to_mt9m111(s); + struct i2c_client *client = mt9m111->i2c_client; int retval = 0; pr_debug("In mt9m111:ioctl_s_ctrl %d\n", @@ -882,7 +845,6 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) break; case V4L2_CID_SATURATION: pr_debug(" V4L2_CID_SATURATION\n"); - retval = mt9m111_set_saturation(vc->value); break; case V4L2_CID_HUE: pr_debug(" V4L2_CID_HUE\n"); @@ -890,6 +852,7 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) case V4L2_CID_AUTO_WHITE_BALANCE: pr_debug( " V4L2_CID_AUTO_WHITE_BALANCE\n"); + retval = mt9m111_set_autowhitebalance(client, vc->value); break; case V4L2_CID_DO_WHITE_BALANCE: pr_debug( @@ -906,27 +869,37 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) break; case V4L2_CID_EXPOSURE: pr_debug(" V4L2_CID_EXPOSURE\n"); - retval = mt9m111_set_ae_mode(vc->value); + break; + case V4L2_CID_EXPOSURE_AUTO: + pr_debug(" V4L2_CID_EXPOSURE_AUTO\n"); + retval = mt9m111_set_autoexposure(client, vc->value); break; case V4L2_CID_AUTOGAIN: pr_debug(" V4L2_CID_AUTOGAIN\n"); break; case V4L2_CID_GAIN: pr_debug(" V4L2_CID_GAIN\n"); + retval = mt9m111_set_global_gain(client, vc->value); break; case V4L2_CID_HFLIP: pr_debug(" V4L2_CID_HFLIP\n"); + mt9m111->hflip = vc->value; + retval = mt9m111_set_flip(client, vc->value, + MT9M111_RMB_MIRROR_COLS); break; case V4L2_CID_VFLIP: pr_debug(" V4L2_CID_VFLIP\n"); + mt9m111->vflip = vc->value; + retval = mt9m111_set_flip(client, vc->value, + MT9M111_RMB_MIRROR_ROWS); break; default: pr_debug(" Default case\n"); - retval = -EPERM; + retval = -EINVAL; break; } - printk("::: ioctl_s_ctrl (END, ret=%d)\n", retval); + pr_debug(" ioctl_s_ctrl (END, ret=%d)\n", retval); return retval; } @@ -946,6 +919,48 @@ static int ioctl_init(struct v4l2_int_device *s) return 0; } +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int mt9m111_video_probe(struct mt9m111_data *mt9m111) +{ + struct i2c_client *client = mt9m111->i2c_client; + s32 data; + int ret; + + mt9m111->autoexposure = 1; + mt9m111->autowhitebalance = 1; + + mt9m111->swap_rgb_even_odd = 1; + mt9m111->swap_rgb_red_blue = 1; + + data = reg_read(CHIP_VERSION); + + switch (data) { + case 0x143a: /* MT9M111 or MT9M131 */ + mt9m111->model = V4L2_IDENT_MT9M111; + dev_info(&client->dev, + "Detected a MT9M111/MT9M131 chip ID %x\n", data); + break; + case 0x148c: /* MT9M112 */ + mt9m111->model = V4L2_IDENT_MT9M112; + dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data); + break; + default: + ret = -ENODEV; + dev_err(&client->dev, + "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n", + data); + goto ei2c; + } + + ret = mt9m111_sensor_init(client); + +ei2c: + return ret; +} + /*! * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num * @s: pointer to standard V4L2 device structure @@ -954,20 +969,17 @@ static int ioctl_init(struct v4l2_int_device *s) */ static int ioctl_dev_init(struct v4l2_int_device *s) { - printk("::: ioctl_dev_init\n"); - uint32_t clock_rate = MT9M111_MCLK; + struct mt9m111_data *mt9m111 = v4l2_to_mt9m111(s); pr_debug("In mt9m111:ioctl_dev_init\n"); gpio_sensor_active(); set_mclk_rate(&clock_rate, 0); // TODO: unhardcode '0' csi - mt9m111_rate_cal(&reset_frame_rate, clock_rate); - mt9m111_sensor_lib(mt9m111_device.coreReg, mt9m111_device.ifpReg); - printk("::: ioctl_dev_init (END)\n"); - + mt9m111_video_probe(mt9m111); + return 0; } @@ -1046,38 +1058,41 @@ static struct v4l2_int_device mt9m111_int_device = { static int mt9m111_probe(struct i2c_client *client, const struct i2c_device_id *id) { - printk("::: mt9m111_probe\n"); - int retval; + struct mt9m111_data *mt9m111; pr_debug("In mt9m111_probe device id is %s\n", id->name); + mt9m111 = kzalloc(sizeof(struct mt9m111_data), GFP_KERNEL); + if (!mt9m111) + return -ENOMEM; + /* Set initial values for the sensor struct. */ - memset(&mt9m111_data, 0, sizeof(mt9m111_data)); - mt9m111_data.i2c_client = client; + mt9m111->i2c_client = client; + i2c_set_clientdata(client, mt9m111); + pr_debug(" client name is %s\n", client->name); - mt9m111_data.pix.pixelformat = V4L2_PIX_FMT_UYVY; - mt9m111_data.pix.width = MT9M111_MAX_WIDTH; - mt9m111_data.pix.height = MT9M111_MAX_HEIGHT; - mt9m111_data.streamcap.capability = 0; /* No higher resolution or frame + mt9m111->pix.pixelformat = V4L2_PIX_FMT_UYVY; + mt9m111->pix.width = MT9M111_MAX_WIDTH; + mt9m111->pix.height = MT9M111_MAX_HEIGHT; + mt9m111->streamcap.capability = 0; /* No higher resolution or frame * frame rate changes supported. */ - mt9m111_data.streamcap.timeperframe.denominator = MT9M111_FRAME_RATE; - mt9m111_data.streamcap.timeperframe.numerator = 1; + mt9m111->streamcap.timeperframe.denominator = MT9M111_FRAME_RATE; + mt9m111->streamcap.timeperframe.numerator = 1; - mt9m111_int_device.priv = &mt9m111_data; + + mt9m111_int_device.priv = mt9m111; pr_debug(" type is %d (expect %d)\n", - mt9m111_int_device.type, v4l2_int_type_slave); + mt9m111_int_device.type, v4l2_int_type_slave); pr_debug(" num ioctls is %d\n", - mt9m111_int_device.u.slave->num_ioctls); + mt9m111_int_device.u.slave->num_ioctls); /* This function attaches this structure to the /dev/video0 device. * The pointer in priv points to the mt9m111_data structure here.*/ retval = v4l2_int_device_register(&mt9m111_int_device); - printk("::: mt9m111_probe (END, ret=%d)\n", retval); - return retval; } @@ -1087,17 +1102,32 @@ static int mt9m111_probe(struct i2c_client *client, */ static int mt9m111_remove(struct i2c_client *client) { - printk("====:: mt9m111_remove\n"); - pr_debug("In mt9m111_remove\n"); v4l2_int_device_unregister(&mt9m111_int_device); - printk("====:: mt9m111_remove (END)\n"); - return 0; } +static const struct i2c_device_id mt9m111_id[] = { + {"mt9m111", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, mt9m111_id); + +static struct i2c_driver mt9m111_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "mt9m111", + }, + .probe = mt9m111_probe, + .remove = mt9m111_remove, + .id_table = mt9m111_id, +/* To add power management add .suspend and .resume functions */ +}; + + /*! * MT9M111 init function. * Called by insmod mt9m111_camera.ko. @@ -1106,43 +1136,14 @@ static int mt9m111_remove(struct i2c_client *client) */ static __init int mt9m111_init(void) { - printk("::: mt9m111_init\n"); - u8 err; - pr_debug("In mt9m111_init\n"); - - /* Allocate memory for state structures. */ - mt9m111_device.coreReg = (mt9m111_coreReg *) - kmalloc(sizeof(mt9m111_coreReg), GFP_KERNEL); - if (!mt9m111_device.coreReg) - { - printk("::: mt9m111_init (END, error-0)\n"); - return -1; - } - memset(mt9m111_device.coreReg, 0, sizeof(mt9m111_coreReg)); - - mt9m111_device.ifpReg = (mt9m111_IFPReg *) - kmalloc(sizeof(mt9m111_IFPReg), GFP_KERNEL); - if (!mt9m111_device.ifpReg) { - kfree(mt9m111_device.coreReg); - mt9m111_device.coreReg = NULL; - printk("::: mt9m111_init (END, error-1)\n"); - return -1; - } - memset(mt9m111_device.ifpReg, 0, sizeof(mt9m111_IFPReg)); - - /* Set contents of the just created structures. */ - mt9m111_config(); - /* Tells the i2c driver what functions to call for this driver. */ err = i2c_add_driver(&mt9m111_i2c_driver); if (err != 0) - pr_err("%s:driver registration failed, error=%d \n", - __func__, err); + pr_err("%s: driver registration failed, error=%d \n", + __func__, err); - printk("::: mt9m111_init (END, ret=%d)\n", err); - return err; } @@ -1154,24 +1155,9 @@ static __init int mt9m111_init(void) */ static void __exit mt9m111_clean(void) { - printk("::: mt9m111_clean\n"); - - pr_debug("In mt9m111_clean()\n"); - i2c_del_driver(&mt9m111_i2c_driver); - gpio_sensor_inactive(); - - if (mt9m111_device.coreReg) { - kfree(mt9m111_device.coreReg); - mt9m111_device.coreReg = NULL; - } - if (mt9m111_device.ifpReg) { - kfree(mt9m111_device.ifpReg); - mt9m111_device.ifpReg = NULL; - } - - printk("::: mt9m111_clean (END)\n"); + gpio_sensor_inactive(); } module_init(mt9m111_init); diff --git a/drivers/media/video/mxc/capture/mt9m111.h b/drivers/media/video/mxc/capture/mt9m111.h index 80bba1345992..ffc583cbf511 100644 --- a/drivers/media/video/mxc/capture/mt9m111.h +++ b/drivers/media/video/mxc/capture/mt9m111.h @@ -1,5 +1,4 @@ /* - * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -20,8 +19,7 @@ * * @brief MT9M111 Camera Header file * - * This header file contains defines and structures for the iMagic mi8012 - * aka the Micron mt9m111 camera. + * This header file contains defines and structures for the Micron mt9m111 camera. * * @ingroup Camera */ @@ -29,193 +27,114 @@ #ifndef MT9M111_H_ #define MT9M111_H_ +#include <media/v4l2-common.h> +#include <linux/v4l2-mediabus.h> + /*! * Basic camera values */ #define MT9M111_FRAME_RATE 30 -#define MT9M111_MCLK 27000000 /* Desired clock rate */ -#define MT9M111_CLK_MIN 12000000 /* This clock rate yields 15 fps */ -#define MT9M111_CLK_MAX 27000000 -#define MT9M111_MAX_WIDTH 640 /* Max width for this camera */ -#define MT9M111_MAX_HEIGHT 480 /* Max height for this camera */ +#define MT9M111_MCLK 54000000 /* Desired clock rate */ +#define MT9M111_CLK_MIN 12000000 /* This clock rate yields 15 fps */ +#define MT9M111_CLK_MAX 54000000 +#define MT9M111_MAX_WIDTH 1280 /* Max width for this camera */ +#define MT9M111_MAX_HEIGHT 1024 /* Max height for this camera */ -/*! - * mt9m111 IFP REGISTER BANK MAP +/* + * MT9M111, MT9M112 and MT9M131: + * i2c address is 0x48 or 0x5d (depending on SADDR pin) + * The platform has to define i2c_board_info and call i2c_register_board_info() */ -#define MT9M111I_ADDR_SPACE_SEL 0x1 -#define MT9M111I_BASE_MAXTRIX_SIGN 0x2 -#define MT9M111I_BASE_MAXTRIX_SCALE15 0x3 -#define MT9M111I_BASE_MAXTRIX_SCALE69 0x4 -#define MT9M111I_APERTURE_GAIN 0x5 -#define MT9M111I_MODE_CONTROL 0x6 -#define MT9M111I_SOFT_RESET 0x7 -#define MT9M111I_FORMAT_CONTROL 0x8 -#define MT9M111I_BASE_MATRIX_CFK1 0x9 -#define MT9M111I_BASE_MATRIX_CFK2 0xa -#define MT9M111I_BASE_MATRIX_CFK3 0xb -#define MT9M111I_BASE_MATRIX_CFK4 0xc -#define MT9M111I_BASE_MATRIX_CFK5 0xd -#define MT9M111I_BASE_MATRIX_CFK6 0xe -#define MT9M111I_BASE_MATRIX_CFK7 0xf -#define MT9M111I_BASE_MATRIX_CFK8 0x10 -#define MT9M111I_BASE_MATRIX_CFK9 0x11 -#define MT9M111I_AWB_POSITION 0x12 -#define MT9M111I_AWB_RED_GAIN 0x13 -#define MT9M111I_AWB_BLUE_GAIN 0x14 -#define MT9M111I_DELTA_MATRIX_CF_SIGN 0x15 -#define MT9M111I_DELTA_MATRIX_CF_D1 0x16 -#define MT9M111I_DELTA_MATRIX_CF_D2 0x17 -#define MT9M111I_DELTA_MATRIX_CF_D3 0x18 -#define MT9M111I_DELTA_MATRIX_CF_D4 0x19 -#define MT9M111I_DELTA_MATRIX_CF_D5 0x1a -#define MT9M111I_DELTA_MATRIX_CF_D6 0x1b -#define MT9M111I_DELTA_MATRIX_CF_D7 0x1c -#define MT9M111I_DELTA_MATRIX_CF_D8 0x1d -#define MT9M111I_DELTA_MATRIX_CF_D9 0x1e -#define MT9M111I_LUMINANCE_LIMIT_WB 0x20 -#define MT9M111I_RBG_MANUUAL_WB 0x21 -#define MT9M111I_AWB_RED_LIMIT 0x22 -#define MT9M111I_AWB_BLUE_LIMIT 0x23 -#define MT9M111I_MATRIX_ADJUST_LIMIT 0x24 -#define MT9M111I_AWB_SPEED 0x25 -#define MT9M111I_H_BOUND_AE 0x26 -#define MT9M111I_V_BOUND_AE 0x27 -#define MT9M111I_H_BOUND_AE_CEN_WIN 0x2b -#define MT9M111I_V_BOUND_AE_CEN_WIN 0x2c -#define MT9M111I_BOUND_AWB_WIN 0x2d -#define MT9M111I_AE_PRECISION_TARGET 0x2e -#define MT9M111I_AE_SPEED 0x2f -#define MT9M111I_RED_AWB_MEASURE 0x30 -#define MT9M111I_LUMA_AWB_MEASURE 0x31 -#define MT9M111I_BLUE_AWB_MEASURE 0x32 -#define MT9M111I_LIMIT_SHARP_SATU_CTRL 0x33 -#define MT9M111I_LUMA_OFFSET 0x34 -#define MT9M111I_CLIP_LIMIT_OUTPUT_LUMI 0x35 -#define MT9M111I_GAIN_LIMIT_AE 0x36 -#define MT9M111I_SHUTTER_WIDTH_LIMIT_AE 0x37 -#define MT9M111I_UPPER_SHUTTER_DELAY_LIM 0x39 -#define MT9M111I_OUTPUT_FORMAT_CTRL2 0x3a -#define MT9M111I_IPF_BLACK_LEVEL_SUB 0x3b -#define MT9M111I_IPF_BLACK_LEVEL_ADD 0x3c -#define MT9M111I_ADC_LIMIT_AE_ADJ 0x3d -#define MT9M111I_GAIN_THRE_CCAM_ADJ 0x3e -#define MT9M111I_LINEAR_AE 0x3f -#define MT9M111I_THRESHOLD_EDGE_DEFECT 0x47 -#define MT9M111I_LUMA_SUM_MEASURE 0x4c -#define MT9M111I_TIME_ADV_SUM_LUMA 0x4d -#define MT9M111I_MOTION 0x52 -#define MT9M111I_GAMMA_KNEE_Y12 0x53 -#define MT9M111I_GAMMA_KNEE_Y34 0x54 -#define MT9M111I_GAMMA_KNEE_Y56 0x55 -#define MT9M111I_GAMMA_KNEE_Y78 0x56 -#define MT9M111I_GAMMA_KNEE_Y90 0x57 -#define MT9M111I_GAMMA_VALUE_Y0 0x58 -#define MT9M111I_SHUTTER_60 0x59 -#define MT9M111I_SEARCH_FLICK_60 0x5c -#define MT9M111I_RATIO_IMAGE_GAIN_BASE 0x5e -#define MT9M111I_RATIO_IMAGE_GAIN_DELTA 0x5f -#define MT9M111I_SIGN_VALUE_REG5F 0x60 -#define MT9M111I_AE_GAIN 0x62 -#define MT9M111I_MAX_GAIN_AE 0x67 -#define MT9M111I_LENS_CORRECT_CTRL 0x80 -#define MT9M111I_SHADING_PARAMETER1 0x81 -#define MT9M111I_SHADING_PARAMETER2 0x82 -#define MT9M111I_SHADING_PARAMETER3 0x83 -#define MT9M111I_SHADING_PARAMETER4 0x84 -#define MT9M111I_SHADING_PARAMETER5 0x85 -#define MT9M111I_SHADING_PARAMETER6 0x86 -#define MT9M111I_SHADING_PARAMETER7 0x87 -#define MT9M111I_SHADING_PARAMETER8 0x88 -#define MT9M111I_SHADING_PARAMETER9 0x89 -#define MT9M111I_SHADING_PARAMETER10 0x8A -#define MT9M111I_SHADING_PARAMETER11 0x8B -#define MT9M111I_SHADING_PARAMETER12 0x8C -#define MT9M111I_SHADING_PARAMETER13 0x8D -#define MT9M111I_SHADING_PARAMETER14 0x8E -#define MT9M111I_SHADING_PARAMETER15 0x8F -#define MT9M111I_SHADING_PARAMETER16 0x90 -#define MT9M111I_SHADING_PARAMETER17 0x91 -#define MT9M111I_SHADING_PARAMETER18 0x92 -#define MT9M111I_SHADING_PARAMETER19 0x93 -#define MT9M111I_SHADING_PARAMETER20 0x94 -#define MT9M111I_SHADING_PARAMETER21 0x95 -#define MT9M111i_FLASH_CTRL 0x98 -#define MT9M111i_LINE_COUNTER 0x99 -#define MT9M111i_FRAME_COUNTER 0x9A -#define MT9M111i_H_PAN 0xA5 -#define MT9M111i_H_ZOOM 0xA6 -#define MT9M111i_H_SIZE 0xA7 -#define MT9M111i_V_PAN 0xA8 -#define MT9M111i_V_ZOOM 0xA9 -#define MT9M111i_V_SIZE 0xAA -#define MT9M111I_SEL_IFP 0x1 -#define MT9M111I_SEL_SCA 0x4 -#define MT9M111I_FC_RGB_OR_YUV 0x1000 - -/*! - * Mt9m111 SENSOR CORE REGISTER BANK MAP +/* + * Sensor core register addresses (0x000..0x0ff) */ -#define MT9M111S_ADDR_SPACE_SEL 0x1 -#define MT9M111S_COLUMN_START 0x2 -#define MT9M111S_WIN_HEIGHT 0x3 -#define MT9M111S_WIN_WIDTH 0x4 -#define MT9M111S_HOR_BLANKING 0x5 -#define MT9M111S_VER_BLANKING 0x6 -#define MT9M111S_OUTPUT_CTRL 0x7 -#define MT9M111S_ROW_START 0x8 -#define MT9M111S_SHUTTER_WIDTH 0x9 -#define MT9M111S_PIXEL_CLOCK_SPEED 0xa -#define MT9M111S_RESTART 0xb -#define MT9M111S_SHUTTER_DELAY 0xc -#define MT9M111S_RESET 0xd -#define MT9M111S_COLUMN_START_IN_ZOOM 0x12 -#define MT9M111S_ROW_START_IN_ZOOM 0x13 -#define MT9M111S_DIGITAL_ZOOM 0x1e -#define MT9M111S_READ_MODE 0x20 -#define MT9M111S_DAC_CTRL 0x27 -#define MT9M111S_GREEN1_GAIN 0x2b -#define MT9M111S_BLUE_GAIN 0x2c -#define MT9M111S_READ_GAIN 0x2d -#define MT9M111S_GREEN2_GAIN 0x2e -#define MT9M111S_ROW_NOISE_CTRL 0x30 -#define MT9M111S_DARK_TARGET_W 0x31 -#define MT9M111S_TEST_DATA 0x32 -#define MT9M111S_GLOBAL_GAIN 0x35 -#define MT9M111S_SENSOR_CORE_VERSION 0x36 -#define MT9M111S_DARK_TARGET_WO 0x37 -#define MT9M111S_VERF_DAC 0x41 -#define MT9M111S_VCM_VCL 0x42 -#define MT9M111S_DISABLE_BYPASS 0x58 -#define MT9M111S_CALIB_MEAN_TEST 0x59 -#define MT9M111S_DARK_G1_AVE 0x5B -#define MT9M111S_DARK_G2_AVE 0x5C -#define MT9M111S_DARK_R_AVE 0x5D -#define MT9M111S_DARK_B_AVE 0x5E -#define MT9M111S_CAL_THRESHOLD 0x5f -#define MT9M111S_CAL_G1 0x60 -#define MT9M111S_CAL_G2 0x61 -#define MT9M111S_CAL_CTRL 0x62 -#define MT9M111S_CAL_R 0x63 -#define MT9M111S_CAL_B 0x64 -#define MT9M111S_CHIP_ENABLE 0xF1 -#define MT9M111S_CHIP_VERSION 0xFF +#define MT9M111_CHIP_VERSION 0x000 +#define MT9M111_ROW_START 0x001 +#define MT9M111_COLUMN_START 0x002 +#define MT9M111_WINDOW_HEIGHT 0x003 +#define MT9M111_WINDOW_WIDTH 0x004 +#define MT9M111_HORIZONTAL_BLANKING_B 0x005 +#define MT9M111_VERTICAL_BLANKING_B 0x006 +#define MT9M111_HORIZONTAL_BLANKING_A 0x007 +#define MT9M111_VERTICAL_BLANKING_A 0x008 +#define MT9M111_SHUTTER_WIDTH 0x009 +#define MT9M111_ROW_SPEED 0x00a +#define MT9M111_EXTRA_DELAY 0x00b +#define MT9M111_SHUTTER_DELAY 0x00c +#define MT9M111_RESET 0x00d +#define MT9M111_READ_MODE_B 0x020 +#define MT9M111_READ_MODE_A 0x021 +#define MT9M111_FLASH_CONTROL 0x023 +#define MT9M111_GREEN1_GAIN 0x02b +#define MT9M111_BLUE_GAIN 0x02c +#define MT9M111_RED_GAIN 0x02d +#define MT9M111_GREEN2_GAIN 0x02e +#define MT9M111_GLOBAL_GAIN 0x02f +#define MT9M111_CONTEXT_CONTROL 0x0c8 +#define MT9M111_PAGE_MAP 0x0f0 +#define MT9M111_BYTE_WISE_ADDR 0x0f1 + +#define MT9M111_RESET_SYNC_CHANGES (1 << 15) +#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9) +#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8) +#define MT9M111_RESET_RESET_SOC (1 << 5) +#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4) +#define MT9M111_RESET_CHIP_ENABLE (1 << 3) +#define MT9M111_RESET_ANALOG_STANDBY (1 << 2) +#define MT9M111_RESET_RESTART_FRAME (1 << 1) +#define MT9M111_RESET_RESET_MODE (1 << 0) + +#define MT9M111_RMB_MIRROR_COLS (1 << 1) +#define MT9M111_RMB_MIRROR_ROWS (1 << 0) +#define MT9M111_CTXT_CTRL_RESTART (1 << 15) +#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12) +#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10) +#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9) +#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8) +#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7) +#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3) +#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2) +#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1) +#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0) -/* OUTPUT_CTRL */ -#define MT9M111S_OUTCTRL_SYNC 0x1 -#define MT9M111S_OUTCTRL_CHIP_ENABLE 0x2 -#define MT9M111S_OUTCTRL_TEST_MODE 0x40 - -/* READ_MODE */ -#define MT9M111S_RM_NOBADFRAME 0x1 -#define MT9M111S_RM_NODESTRUCT 0x2 -#define MT9M111S_RM_COLUMNSKIP 0x4 -#define MT9M111S_RM_ROWSKIP 0x8 -#define MT9M111S_RM_BOOSTEDRESET 0x1000 -#define MT9M111S_RM_COLUMN_LATE 0x10 -#define MT9M111S_RM_ROW_LATE 0x80 -#define MT9M111S_RM_RIGTH_TO_LEFT 0x4000 -#define MT9M111S_RM_BOTTOM_TO_TOP 0x8000 +/* + * Colorpipe register addresses (0x100..0x1ff) + */ +#define MT9M111_OPER_MODE_CTRL 0x106 +#define MT9M111_OUTPUT_FORMAT_CTRL 0x108 +#define MT9M111_REDUCER_XZOOM_B 0x1a0 +#define MT9M111_REDUCER_XSIZE_B 0x1a1 +#define MT9M111_REDUCER_YZOOM_B 0x1a3 +#define MT9M111_REDUCER_YSIZE_B 0x1a4 +#define MT9M111_REDUCER_XZOOM_A 0x1a6 +#define MT9M111_REDUCER_XSIZE_A 0x1a7 +#define MT9M111_REDUCER_YZOOM_A 0x1a9 +#define MT9M111_REDUCER_YSIZE_A 0x1aa + +#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a +#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b + +#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14) +#define MT9M111_OPMODE_AUTOWHITEBAL_EN (1 << 1) + +#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14) +#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) +#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) +#define MT9M111_OUTFMT_RGB (1 << 8) +#define MT9M111_OUTFMT_RGB565 (0 << 6) +#define MT9M111_OUTFMT_RGB555 (1 << 6) +#define MT9M111_OUTFMT_RGB444x (2 << 6) +#define MT9M111_OUTFMT_RGBx444 (3 << 6) +#define MT9M111_OUTFMT_TST_RAMP_OFF (0 << 4) +#define MT9M111_OUTFMT_TST_RAMP_COL (1 << 4) +#define MT9M111_OUTFMT_TST_RAMP_ROW (2 << 4) +#define MT9M111_OUTFMT_TST_RAMP_FRAME (3 << 4) +#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) +#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) +#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) +#define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 << 1) +#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr (1 << 0) /*! I2C Slave Address */ #define MT9M111_I2C_ADDRESS 0x48 @@ -249,178 +168,10 @@ enum { MT9M111_VERTBLANK_MAX = 0xFFF, }; -/*! - * Mt9m111 Core Register structure. - */ -typedef struct { - u32 addressSelect; /*!< select address bank for Core Register 0x4 */ - u32 columnStart; /*!< Starting Column */ - u32 windowHeight; /*!< Window Height */ - u32 windowWidth; /*!< Window Width */ - u32 horizontalBlanking; /*!< Horizontal Blank time, in pixels */ - u32 verticalBlanking; /*!< Vertical Blank time, in pixels */ - u32 outputControl; /*!< Register to control sensor output */ - u32 rowStart; /*!< Starting Row */ - u32 shutterWidth; - u32 pixelClockSpeed; /*!< pixel date rate */ - u32 restart; /*!< Abandon the readout of current frame */ - u32 shutterDelay; - u32 reset; /*!< reset the sensor to the default mode */ - u32 zoomColStart; /*!< Column start in the Zoom mode */ - u32 zomRowStart; /*!< Row start in the Zoom mode */ - u32 digitalZoom; /*!< 1 means zoom by 2 */ - u32 readMode; /*!< Readmode: aspects of the readout of the sensor */ - u32 dACStandbyControl; - u32 green1Gain; /*!< Gain Settings */ - u32 blueGain; - u32 redGain; - u32 green2Gain; - u32 rowNoiseControl; - u32 darkTargetwNC; - u32 testData; /*!< test mode */ - u32 globalGain; - u32 chipVersion; - u32 darkTargetwoNC; - u32 vREFDACs; - u32 vCMandVCL; - u32 disableBypass; - u32 calibMeanTest; - u32 darkG1average; - u32 darkG2average; - u32 darkRaverage; - u32 darkBaverage; - u32 calibThreshold; - u32 calibGreen1; - u32 calibGreen2; - u32 calibControl; - u32 calibRed; - u32 calibBlue; - u32 chipEnable; /*!< Image core Registers written by image flow processor */ -} mt9m111_coreReg; - -/*! - * Mt9m111 IFP Register structure. - */ -typedef struct { - u32 addrSpaceSel; /*!< select address bank for Core Register 0x1 */ - u32 baseMaxtrixSign; /*!< sign of coefficient for base color correction matrix */ - u32 baseMaxtrixScale15; /*!< scaling of color correction coefficient K1-5 */ - u32 baseMaxtrixScale69; /*!< scaling of color correction coefficient K6-9 */ - u32 apertureGain; /*!< sharpening */ - u32 modeControl; /*!< bit 7 CCIR656 sync codes are embedded in the image */ - u32 softReset; /*!< Image processing mode: 1 reset mode, 0 operational mode */ - u32 formatControl; /*!< bit12 1 for RGB565, 0 for YcrCb */ - u32 baseMatrixCfk1; /*!< K1 Color correction coefficient */ - u32 baseMatrixCfk2; /*!< K2 Color correction coefficient */ - u32 baseMatrixCfk3; /*!< K3 Color correction coefficient */ - u32 baseMatrixCfk4; /*!< K4 Color correction coefficient */ - u32 baseMatrixCfk5; /*!< K5 Color correction coefficient */ - u32 baseMatrixCfk6; /*!< K6 Color correction coefficient */ - u32 baseMatrixCfk7; /*!< K7 Color correction coefficient */ - u32 baseMatrixCfk8; /*!< K8 Color correction coefficient */ - u32 baseMatrixCfk9; /*!< K9 Color correction coefficient */ - u32 awbPosition; /*!< Current position of AWB color correction matrix */ - u32 awbRedGain; /*!< Current value of AWB red channel gain */ - u32 awbBlueGain; /*!< Current value of AWB blue channel gain */ - u32 deltaMatrixCFSign; /*!< Sign of coefficients of delta color correction matrix register */ - u32 deltaMatrixCFD1; /*!< D1 Delta coefficient */ - u32 deltaMatrixCFD2; /*!< D2 Delta coefficient */ - u32 deltaMatrixCFD3; /*!< D3 Delta coefficient */ - u32 deltaMatrixCFD4; /*!< D4 Delta coefficient */ - u32 deltaMatrixCFD5; /*!< D5 Delta coefficient */ - u32 deltaMatrixCFD6; /*!< D6 Delta coefficient */ - u32 deltaMatrixCFD7; /*!< D7 Delta coefficient */ - u32 deltaMatrixCFD8; /*!< D8 Delta coefficient */ - u32 deltaMatrixCFD9; /*!< D9 Delta coefficient */ - u32 lumLimitWB; /*!< Luminance range of pixels considered in WB statistics */ - u32 RBGManualWB; /*!< Red and Blue color channel gains for manual white balance */ - u32 awbRedLimit; /*!< Limits on Red channel gain adjustment through AWB */ - u32 awbBlueLimit; /*!< Limits on Blue channel gain adjustment through AWB */ - u32 matrixAdjLimit; /*!< Limits on color correction matrix adjustment through AWB */ - u32 awbSpeed; /*!< AWB speed and color saturation control */ - u32 HBoundAE; /*!< Horizontal boundaries of AWB measurement window */ - u32 VBoundAE; /*!< Vertical boundaries of AWB measurement window */ - u32 HBoundAECenWin; /*!< Horizontal boundaries of AE measurement window for backlight compensation */ - u32 VBoundAECenWin; /*!< Vertical boundaries of AE measurement window for backlight compensation */ - u32 boundAwbWin; /*!< Boundaries of AWB measurement window */ - u32 AEPrecisionTarget; /*!< Auto exposure target and precision control */ - u32 AESpeed; /*!< AE speed and sensitivity control register */ - u32 redAWBMeasure; /*!< Measure of the red channel value used by AWB */ - u32 lumaAWBMeasure; /*!< Measure of the luminance channel value used by AWB */ - u32 blueAWBMeasure; /*!< Measure of the blue channel value used by AWB */ - u32 limitSharpSatuCtrl; /*!< Automatic control of sharpness and color saturation */ - u32 lumaOffset; /*!< Luminance offset control (brightness control) */ - u32 clipLimitOutputLumi; /*!< Clipping limits for output luminance */ - u32 gainLimitAE; /*!< Imager gain limits for AE adjustment */ - u32 shutterWidthLimitAE; /*!< Shutter width (exposure time) limits for AE adjustment */ - u32 upperShutterDelayLi; /*!< Upper Shutter Delay Limit */ - u32 outputFormatCtrl2; /*!< Output Format Control 2 - 00 = 16-bit RGB565. - 01 = 15-bit RGB555. - 10 = 12-bit RGB444x. - 11 = 12-bit RGBx444. */ - u32 ipfBlackLevelSub; /*!< IFP black level subtraction */ - u32 ipfBlackLevelAdd; /*!< IFP black level addition */ - u32 adcLimitAEAdj; /*!< ADC limits for AE adjustment */ - u32 agimnThreCamAdj; /*!< Gain threshold for CCM adjustment */ - u32 linearAE; - u32 thresholdEdgeDefect; /*!< Edge threshold for interpolation and defect correction */ - u32 lumaSumMeasure; /*!< Luma measured by AE engine */ - u32 timeAdvSumLuma; /*!< Time-averaged luminance value tracked by auto exposure */ - u32 motion; /*!< 1 when motion is detected */ - u32 gammaKneeY12; /*!< Gamma knee points Y1 and Y2 */ - u32 gammaKneeY34; /*!< Gamma knee points Y3 and Y4 */ - u32 gammaKneeY56; /*!< Gamma knee points Y5 and Y6 */ - u32 gammaKneeY78; /*!< Gamma knee points Y7 and Y8 */ - u32 gammaKneeY90; /*!< Gamma knee points Y9 and Y10 */ - u32 gammaKneeY0; /*!< Gamma knee point Y0 */ - u32 shutter_width_60; - u32 search_flicker_60; - u32 ratioImageGainBase; - u32 ratioImageGainDelta; - u32 signValueReg5F; - u32 aeGain; - u32 maxGainAE; - u32 lensCorrectCtrl; - u32 shadingParameter1; /*!< Shade Parameters */ - u32 shadingParameter2; - u32 shadingParameter3; - u32 shadingParameter4; - u32 shadingParameter5; - u32 shadingParameter6; - u32 shadingParameter7; - u32 shadingParameter8; - u32 shadingParameter9; - u32 shadingParameter10; - u32 shadingParameter11; - u32 shadingParameter12; - u32 shadingParameter13; - u32 shadingParameter14; - u32 shadingParameter15; - u32 shadingParameter16; - u32 shadingParameter17; - u32 shadingParameter18; - u32 shadingParameter19; - u32 shadingParameter20; - u32 shadingParameter21; - u32 flashCtrl; /*!< Flash control */ - u32 lineCounter; /*!< Line counter */ - u32 frameCounter; /*!< Frame counter */ - u32 HPan; /*!< Horizontal pan in decimation */ - u32 HZoom; /*!< Horizontal zoom in decimation */ - u32 HSize; /*!< Horizontal output size iIn decimation */ - u32 VPan; /*!< Vertical pan in decimation */ - u32 VZoom; /*!< Vertical zoom in decimation */ - u32 VSize; /*!< Vertical output size in decimation */ -} mt9m111_IFPReg; - -/*! - * mt9m111 Config structure - */ -typedef struct { - mt9m111_coreReg *coreReg; /*!< Sensor Core Register Bank */ - mt9m111_IFPReg *ifpReg; /*!< IFP Register Bank */ -} mt9m111_conf; +enum mt9m111_context { + HIGHPOWER = 0, + LOWPOWER, +}; typedef struct { u8 index; @@ -428,4 +179,5 @@ typedef struct { u16 height; } mt9m111_image_format; + #endif /* MT9M111_H_ */ |
