summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYauhen Kharuzhy <jekhor@gmail.com>2012-10-16 18:15:13 +0300
committerJustin Waters <justin.waters@timesys.com>2013-11-07 12:19:17 -0500
commit6a8d5e31cfbda7badbc399c06275294e56d699bd (patch)
tree6a8f815d946cba9f4d69a4a69ec40ec59523dfdd
parente931ef1741fa54626700cdc3c9d21ba5d7db741b (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.c958
-rw-r--r--drivers/media/video/mxc/capture/mt9m111.h458
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_ */