On Fri, 10 Jun 2011 16:38:10 +0800
"He, Yong M" <yong.m...@intel.com> wrote:

> 
> From: Yong He <yong.m...@intel.com>
> Subject: [PATCH] MRST Tablet camera driver ver-0.952, fix 8917 and 9552
> 
> =====This patch is going to fix these bugs ===
> 
> Bug 8112<https://bugzilla.otcshare.org/show_bug.cgi?id=8112> - ISP driver 
> doesn't support AF (auto-focus) controlling function for 5M camera sensor 
> (OV5640).
> Bug_8917<https://bugzilla.otcshare.org/show_bug.cgi?id=8917> -[MM-camera]: a 
> cropped line appears on both camera previewing.
> Bug 9552<https://bugzilla.otcshare.org/show_bug.cgi?id=9552> - Back camera 
> doesn't support advanced ioctl

Hi,
First of all, this patch is applied against a patch that was rejected,
so it doesn't apply.  Secondly, I need you to break down your patch
into smaller functional patches.  We don't want a single patch which
addresses multiple issues, because then when we have regressions (like
with the power) it winds up being an all or nothing accept/reject.
Not to mention a large patch like this is really hard for me to
review.

So, you need to do the following:

1.  refresh your patches against the current kernel source (which
    does not include your previous patches)
2.  break patch into smaller patch sets which address a single bug.

These instructions apply to the second patch you sent as well, and
all future patches.

Thanks,
Kristen

> 
> =====solution ===
> 
> Bug 8112<https://bugzilla.otcshare.org/show_bug.cgi?id=8112> change default 
> mode to reduce initial time.
> 
> Bug_8917<https://bugzilla.otcshare.org/show_bug.cgi?id=8917> solution is to 
> add a empty frame buffer space. If the in-queue is empty, all dropped frames 
> goes to this empty buffer.
> 
> Bug 9552<https://bugzilla.otcshare.org/show_bug.cgi?id=9552>  solution is to 
> add new sensor driver Control IDs to support focus operations:
> Auto Exposure Mode
> Auto Exposure Position/Window Size
> Exposure Level Detect (for auto-flash)
> Flash Manual ON/OFF
> Scene Mode (AWB / Gamma)
> SPE Mode
> Exposure Compensation
> color tuning (contrast, brightness, saturation, hues) (-2 ~ +2)
> Sharpness
> 
> Signed-off-by: He, Yong <yong.m...@intel.com<mailto:yong.m...@intel.com>>
> ---
> Index: a/drivers/staging/mrstci/mrstisp/mrstisp_main.c
> ===================================================================
> --- a/drivers/staging/mrstci/mrstisp/mrstisp_main.c    (revision 80)
> +++ a/drivers/staging/mrstci/mrstisp/mrstisp_main.c (revision 87)
> @@ -19,6 +19,7 @@
>   *
>   *
>   * Xiaolin Zhang <xiaolin.zh...@intel.com>
> + * Yong He <yong.m...@intel.com>
>   */
>  #include <linux/pm_runtime.h>
> @@ -61,6 +62,8 @@
> static struct timer_list prevent_sleep_timer  = 
> TIMER_INITIALIZER(prevent_sleep_func, 0, 0);
> #endif
> +static void * addr_for_skipped_frame;
> +static dma_addr_t dma_addr_for_skipped_frame;
>  void intel_timer_start(void)
> {
> @@ -1258,7 +1261,9 @@
>                           bufbase = videobuf_to_dma_contig(vb);
>                           mrst_isp_update_marvinvfaddr(isp, bufbase, 0);
>                           /* mrst_isp_enable_interrupt(isp); */
> +                    dprintk(1, "ISP set to write to buffer %d    
> <---------", vb->i);
>                 } else {
> +               dprintk(1, "no active queue stopflag=1");
>                           isp->active = vb;
>                           mrst_isp_enable_interrupt(isp);
>                           /*
> @@ -2463,10 +2468,10 @@
>        WARN_ON(priv != file->private_data);
>         DBG_entering;
> +    dprintk(1, "q-ed index = %d <-----------------------------", buf->index);
> +    isp  = fh->dev;
>        ret = videobuf_qbuf(&fh->vb_q, buf);
> -        isp  = fh->dev;
> -
>        /* call the mrst_ci_capture() in process context without
>        *  the protection of spinlock.
>        */
> @@ -2476,8 +2481,13 @@
>        }
>        /* identify which video buffer was q-ed */
>        if (ret == 0)
> +       {
>                 fh->qbuf_flag |= (1<<buf->index);
> -        dprintk(1, "q-ed index = %d", buf->index);
> +       }
> +       else
> +       {
> +           dprintk(1, "q-ed index = %d  <---- Failed, this buffer is NOT 
> available!", buf->index);
> +       }
>         DBG_leaving;
> @@ -2518,8 +2528,13 @@
>        ret = videobuf_dqbuf(&fh->vb_q, b, 0);
>        /* identify which video buffer was dq-ed */
>        if (ret == 0)
> +       {
>                 fh->qbuf_flag &= ~(1<<b->index);
> -
> +       }
> +       else
> +       {
> +           dprintk(1, "dqbuf Failed!\n");
> +       }
>        /*XXX zheng*/
>        ++frame_cnt;
>        /*
> @@ -2529,7 +2544,7 @@
>                        frame_cnt * 1000 / intel_get_micro_sec());
>                        */
> -        dprintk(1, "dq-ed index = %d", b->index);
> +    dprintk(1, "dq-ed index = %d  ============================>", b->index);
>        DBG_leaving;
>        return ret;
> }
> @@ -2988,10 +3003,15 @@
>                           bufbase = videobuf_to_dma_contig(isp->next);
>                           mrst_isp_update_marvinvfaddr(isp, bufbase,
>                                                  
> CI_ISP_CFG_UPDATE_FRAME_SYNC);
> -                           dprintk(1, "updating new addr, next = %d",
> -                                    isp->next->i);
> +               dprintk(1, "updating new addr, next = %d",
> +                       isp->next->i);
> +               dprintk(1, "ISP set to write to buffer %d    <---------", 
> isp->next->i);
>                 } else {
>                           isp->stopflag = 1;
> +            mrst_isp_update_marvinvfaddr(isp, dma_addr_for_skipped_frame,
> +                    CI_ISP_CFG_UPDATE_FRAME_SYNC);
> +            dprintk(1, "ISP set to write to a skipped buffer (0x%08x)    
> <---------",
> +                    dma_addr_for_skipped_frame);
>                           dprintk(0, "stop isp");
>                 }
> @@ -3024,7 +3044,7 @@
>                 vb->field_count++;
>                  isp->active = NULL;
> -                 dprintk(1, "buf %d size = %lx", vb->i, vb->size);
> +                dprintk(1, "buf %d completed, size = %lx  =======> ", vb->i, 
> vb->size);
>                 do_gettimeofday(&vb->ts);
>                 wake_up(&vb->done);
> @@ -3034,7 +3054,7 @@
>                                                        struct 
> videobuf_buffer, queue);
>                                    list_del_init(&isp->active->queue);
>                                    isp->active->state = VIDEOBUF_ACTIVE;
> -                                    dprintk(3, "start next frame %d",
> +                                   dprintk(3, "got a buf in isp->capture 
> queue, start next frame %d",
>                                             isp->active->i);
>                                    mrst_isp_to_do_mblk_line = 1;
>                                    REG_SET_SLICE(mrv_reg->mi_imsc,
> @@ -3044,7 +3064,7 @@
>                                    REG_SET_SLICE(mrv_reg->mi_imsc,
>                                                   MRV_MI_MBLK_LINE, ON);
>                                    mrst_isp_disable_interrupt(isp);
> -                                    dprintk(3, "no frame right now");
> +                                   dprintk(3, "no frame right now, waiting 
> for mrst_isp_to_do_mblk_line");
>                           }
>                 } else {
>                           isp->active = isp->next;
> @@ -3197,6 +3217,16 @@
>         dprintk(1, "isp mb1 = %lx, mb1_size = %lx", isp->mb1, isp->mb1_size);
> +    addr_for_skipped_frame = dma_alloc_coherent(&pdev->dev, isp->mb1_size,
> +                      &dma_addr_for_skipped_frame,
> +                      GFP_KERNEL);
> +
> +    if (!addr_for_skipped_frame) {
> +        dprintk(0, "failed to declare dma memory for skipped frame");
> +        ret = -ENXIO;
> +        goto exit_iounmap;
> +    }
> +
>        ret = dma_declare_coherent_memory(&pdev->dev, start,
>                                               /* start, len - 640 * 480 * 2, 
> */
>                                               start, len,
> @@ -3208,7 +3238,7 @@
>        if (!ret) {
>                 dprintk(0, "failed to declare dma memory");
>                 ret = -ENXIO;
> -                 goto exit_iounmap;
> +                goto exit_dma_skipframe_release;
>        }
>         /* init device struct */
> @@ -3267,7 +3297,7 @@
>        mrst_isp_to_do_mblk_line = 0;
>         isp->need_to_capture = 0;
> -        dprintk(0, "mrstisp driver module successfully loaded");
> +       dprintk(0, "mrstisp driver module successfully loaded. 
> (Version-0.951)");
>        pm_runtime_put_noidle(&pdev->dev);
>        pm_runtime_allow(&pdev->dev);
>        return 0;
> @@ -3276,6 +3306,9 @@
>        video_unregister_device(isp->vdev);
> exit_dma_release:
>        dma_release_declared_memory(&pdev->dev);
> +exit_dma_skipframe_release:
> +       dma_free_coherent(&pdev->dev,isp->mb1_size,
> +         addr_for_skipped_frame,dma_addr_for_skipped_frame);
> exit_iounmap:
>        iounmap(isp->regs);
> exit_release_regions:
> Index: a/drivers/staging/mrstci/mrstov5640/mrstov5640.c
> ===================================================================
> --- a/drivers/staging/mrstci/mrstov5640/mrstov5640.c         (revision 80)
> +++ a/drivers/staging/mrstci/mrstov5640/mrstov5640.c      (revision 87)
> @@ -44,11 +44,12 @@
> #include <media/v4l2-device.h>
> #include <media/v4l2-chip-ident.h>
> #include <asm/div64.h>
> +#include <asm/mrst.h>
>  #include "ci_sensor_common.h"
> #include "ov5640.h"
> -#define DRIVER_VERSION "0.95"
> +#define DRIVER_VERSION "0.952"
>  static int mrstov5640_debug=5;
> module_param(mrstov5640_debug, int, 0644);
> @@ -218,7 +219,16 @@
>        int anti_banding;
>        int iso_mode;
>        int iso_val;
> +    int brightness_val;
> +    int contrast_val;
> +    int hue_val;
> +    int sharpness_val;
> +    int saturation_val;
> +    int scene_val;
> +    int spe_val;
> +    int exp_comp_val;
>        int af_x, af_y, af_mode;
> +    int ae_x, ae_y, ae_w, ae_h,ae_mode;
>         // hw status
>        u8 REG20;
> @@ -369,15 +379,31 @@
>      return ret;
> }
> +#define OV5640_AF_TO_MS 100
> +
> static int ov5640_af_center(struct i2c_client *c)
> {
>      int ret = 0;
> +    u8 val = 1;
> +    int af_time_out = OV5640_AF_TO_MS;
>      DBG_entering;
>      ret += ov5640_write(c, 0x3023, 0x01);
>      ret += ov5640_write(c, 0x3022, 0x80);
> -    udelay(100);
> +    while (val != 0)
> +    {
> +        if (af_time_out-- <= 0)
> +        {
> +            dprintk(3, "%s() Time out.\n",__FUNCTION__);
> +            return 1;
> +        }
> +
> +        udelay(1000);
> +        ret += ov5640_read(c, 0x3023, &val);
> +    }
> +
> +
>      DBG_leaving;
>      return ret;
> }
> @@ -385,12 +411,25 @@
> static int ov5640_af_change_res(struct i2c_client *c)
> {
>      int ret = 0;
> +    u8 val = 1;
> +    int af_time_out = 3*OV5640_AF_TO_MS;
>      DBG_entering;
>      ret += ov5640_write(c, 0x3023, 0x01);
>      ret += ov5640_write(c, 0x3022, 0x12);
> -    udelay(100);
> +    while (val != 0)
> +    {
> +        if (af_time_out-- <= 0)
> +        {
> +            dprintk(3, "%s() Time out.\n",__FUNCTION__);
> +            return 1;
> +        }
> +
> +        udelay(1000);
> +        ret += ov5640_read(c, 0x3023, &val);
> +    }
> +
>      DBG_leaving;
>      return ret;
> }
> @@ -400,6 +439,8 @@
> static int ov5640_af_change_pos(struct i2c_client *c, unsigned int x, 
> unsigned int y)
> {
>      int ret = 0;
> +    u8 val = 1;
> +    int af_time_out = OV5640_AF_TO_MS;
>      DBG_entering;
>      if (x > OV5640_FOCUS_NORMALIZED_W)
> @@ -420,8 +461,19 @@
>      ret += ov5640_write(c, 0x3025, y);
>      ret += ov5640_write(c, 0x3023, 0x01);
>      ret += ov5640_write(c, 0x3022, 0x81);
> -    udelay(100);
> +    while (val != 0)
> +    {
> +        if (af_time_out-- <= 0)
> +        {
> +            dprintk(3, "%s() Time out.\n",__FUNCTION__);
> +            return 1;
> +        }
> +
> +        udelay(1000);
> +        ret += ov5640_read(c, 0x3023, &val);
> +    }
> +
>      DBG_leaving;
>      return ret;
> }
> @@ -429,12 +481,25 @@
> static int ov5640_af_do_focus(struct i2c_client *c)
> {
>      int ret = 0;
> +    u8 val = 1;
> +    int af_time_out = 3*OV5640_AF_TO_MS;
>      DBG_entering;
>      ret += ov5640_write(c, 0x3023, 0x01);
>      ret += ov5640_write(c, 0x3022, 0x03);
> -    udelay(100);
> +    while (val != 0)
> +    {
> +        if (af_time_out-- <= 0)
> +        {
> +            dprintk(3, "%s() Time out.\n",__FUNCTION__);
> +            return 1;
> +        }
> +
> +        udelay(1000);
> +        ret += ov5640_read(c, 0x3023, &val);
> +    }
> +
>      DBG_leaving;
>      return ret;
> }
> @@ -467,12 +532,25 @@
> static int ov5640_af_release(struct i2c_client *c)
> {
>      int ret = 0;
> +    u8 val = 1;
> +    int af_time_out = 3*OV5640_AF_TO_MS;
>      DBG_entering;
>      ret += ov5640_write(c, 0x3023, 0x01);
>      ret += ov5640_write(c, 0x3022, 0x08);
> -    udelay(100);
> +    while (val != 0)
> +    {
> +        if (af_time_out-- <= 0)
> +        {
> +            dprintk(3, "%s() Time out.\n",__FUNCTION__);
> +            return 1;
> +        }
> +
> +        udelay(1000);
> +        ret += ov5640_read(c, 0x3023, &val);
> +    }
> +
>      DBG_leaving;
>      return ret;
> }
> @@ -490,7 +568,6 @@
>      msleep(100);
>      ret += ov5640_af_center(c);
>      ov5640_status.fw_inited = OV5640_FW_INITED;
> -    ov5640_af_do_focus(c);
>      DBG_leaving;
>      return ret;
> @@ -498,7 +575,7 @@
>  static int ov5640_hw_init (struct i2c_client *c)
> {
> -        int ret, af_fw_status;
> +       int ret;
>      DBG_entering;
>      if (ov5640_status.reg_inited !=  OV5640_REG_RESET) {
> @@ -529,6 +606,7 @@
>      if (ov5640_status.reg_inited == OV5640_REG_INITED)
>      {
>          struct i2c_client *c = v4l2_get_subdevdata(sd);
> +        ov5640_save_hw_status(c);
>          ov5640_af_release(c);
>          ov5640_status.reg_inited = OV5640_REG_RESET;
>      }
> @@ -555,7 +633,6 @@
>      if (hw_reinit)
>      {
>          struct i2c_client *c = v4l2_get_subdevdata(sd);
> -        ov5640_save_hw_status(c);
>          ov5640_hw_init(c);
>          ov5640_restore_hw_status(c);
>      }
> @@ -1178,26 +1255,34 @@
>        return err;
> }
> -static int ov5640_t_flash(struct i2c_client *c, int value)
> +static int ov5640_t_flash(struct v4l2_subdev *sd, int value)
> {
>        int ret;
> -        if(value!=0&&value!=1)
> -                 return -EINVAL;
> -        if(ret == 0)
> -        {
> -                 ret = gpio_direction_output(GPIO_FLASH,value);
> -                 if(ret == 0)
> -                           ov5640_flash = value;
> -                 gpio_free(GPIO_FLASH);
> -        }
> +
> +    if((value!=0) && (value!=1))
> +    {
> +        return -EINVAL;
> +    }
> +
> +    ret = gpio_direction_output(GPIO_FLASH,value);
> +
> +    if(ret == 0)
> +    {
> +        ov5640_flash = value;
> +    }
> +
> +       gpio_free(GPIO_FLASH);
> +
>        return ret;
> -
> }
> -static int ov5640_q_flash(struct i2c_client *c, int *value)
> +static int ov5640_q_flash(struct v4l2_subdev *sd, int *value)
> {
>        if(!value)
> +       {
>                 return -EINVAL;
> +       }
> +
>        *value=ov5640_flash;
>        return 0;
> }
> @@ -1307,7 +1392,7 @@
>      gain = ov5640_iso_gain_tbl[index];
>      ret += ov5640_read(c, 0x3518, &v);
>      ret += ov5640_write(c, 0x3518, ((gain>>8)&0x3) | (v & 0xfc));
> -    ret += ov5640_write(c, 0x3519, gain | 0xff);
> +    ret += ov5640_write(c, 0x3519, gain & 0xff);
>      ov5640_status.iso_val = value;
>      return ret;
> @@ -1320,7 +1405,7 @@
>      *value = ov5640_status.iso_val;
>      return ret;
> }
> -
> +/*
> #define ISO_MODE_AUTO 0
> #define ISO_MODE_MANUAL 1
> static int ov5640_t_iso_mode(struct v4l2_subdev *sd, int value)
> @@ -1363,75 +1448,293 @@
>      dprintk( 3, "ov5640_q_iso_mode    (%d)",*value);
>      return ret;
> }
> +*/
>  static int ov5640_t_brightness(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> -    // TODO: will be added soon
> +    u8 v,reg_5587,reg_5588;
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +
> +    switch (value)
> +    {
> +    case -2:
> +        reg_5587 = 0x20;
> +        reg_5588 = 0x8;
> +        break;
> +    case -1:
> +        reg_5587 = 0x10;
> +        reg_5588 = 0x8;
> +        break;
> +    case 0:
> +        reg_5587 = 0x0;
> +        reg_5588 = 0x0;
> +        break;
> +    case 1:
> +        reg_5587 = 0x10;
> +        reg_5588 = 0x0;
> +        break;
> +    case 2:
> +        reg_5587 = 0x20;
> +        reg_5588 = 0x0;
> +        break;
> +    default:
> +        return 1;
> +    }
> +
> +    ret += ov5640_read(c, 0x5001, &v);
> +    ret += ov5640_write(c, 0x5001, (v | 0x80));
> +
> +    ret += ov5640_write(c, 0x5587, reg_5587);
> +
> +    ret += ov5640_read(c, 0x5580, &v);
> +    ret += ov5640_write(c, 0x5580, (v | 0x4));
> +
> +    ret += ov5640_read(c, 0x5588, &v);
> +    v = v & 0xf7;
> +    ret += ov5640_write(c, 0x5588, (v | reg_5588));
> +
> +
> +    ov5640_status.brightness_val = value;
>      return ret;
> }
> +
> static int ov5640_q_brightness(struct v4l2_subdev *sd, int *value)
> {
>      int ret=0;
> -    // TODO: will be added soon
> +    *value = ov5640_status.brightness_val;
>      return ret;
> }
> +
> static int ov5640_t_contrast(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> -    // TODO: will be added soon
> +    u8 v,reg_5585,reg_5586;
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +
> +    switch (value)
> +    {
> +    case -2:
> +        reg_5585 = 0x18;
> +        reg_5586 = 0x18;
> +        break;
> +    case -1:
> +        reg_5585 = 0x1c;
> +        reg_5586 = 0x1c;
> +        break;
> +    case 0:
> +        reg_5585 = 0x0;
> +        reg_5586 = 0x20;
> +        break;
> +    case 1:
> +        reg_5585 = 0x10;
> +        reg_5586 = 0x24;
> +        break;
> +    case 2:
> +        reg_5585 = 0x18;
> +        reg_5586 = 0x28;
> +        break;
> +    default:
> +        return 1;
> +    }
> +
> +    ret += ov5640_read(c, 0x5001, &v);
> +    ret += ov5640_write(c, 0x5001, (v | 0x80));
> +    ret += ov5640_read(c, 0x5580, &v);
> +    ret += ov5640_write(c, 0x5580, (v | 0x4));
> +
> +    ret += ov5640_write(c, 0x5586, reg_5586);
> +    ret += ov5640_write(c, 0x5585, reg_5585);
> +
> +    ret += ov5640_read(c, 0x5588, &v);
> +    ret += ov5640_write(c, 0x5588, (v & 0xbf));
> +
> +    ov5640_status.contrast_val = value;
> +
>      return ret;
> }
> static int ov5640_q_contrast(struct v4l2_subdev *sd, int *value)
> {
>      int ret=0;
> -    // TODO: will be added soon
> +    *value = ov5640_status.contrast_val;
>      return ret;
> }
> +
> static int ov5640_t_saturation(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> -    // TODO: will be added soon
> +    u8 v,reg_5583;
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +
> +    switch (value)
> +    {
> +    case -2:
> +        reg_5583 = 0x20;
> +        break;
> +    case -1:
> +        reg_5583 = 0x30;
> +        break;
> +    case 0:
> +        reg_5583 = 0x40;
> +        break;
> +    case 1:
> +        reg_5583 = 0x50;
> +        break;
> +    case 2:
> +        reg_5583 = 0x60;
> +        break;
> +    default:
> +        return 1;
> +    }
> +
> +    ret += ov5640_read(c, 0x5001, &v);
> +    ret += ov5640_write(c, 0x5001, (v | 0x80));
> +
> +    ret += ov5640_write(c, 0x5583, reg_5583);
> +    ret += ov5640_write(c, 0x5584, reg_5583);
> +
> +    ret += ov5640_read(c, 0x5580, &v);
> +    ret += ov5640_write(c, 0x5580, (v | 0x2));
> +
> +    ret += ov5640_read(c, 0x5588, &v);
> +    ret += ov5640_write(c, 0x5588, (v | 0x40));
> +
> +    ov5640_status.saturation_val = value;
> +
>      return ret;
> }
> static int ov5640_q_saturation(struct v4l2_subdev *sd, int *value)
> {
>      int ret=0;
> -    // TODO: will be added soon
> +    *value = ov5640_status.saturation_val;
>      return ret;
> }
> static int ov5640_t_hue(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> -    // TODO: will be added soon
> +    u8 v,reg_1,reg_2,reg_3;
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +
> +    switch (value)
> +    {
> +    case -2:
> +        reg_1 = 0x40;
> +        reg_2 = 0x6f;
> +        reg_3 = 2;
> +        break;
> +    case -1:
> +        reg_1 = 0x6f;
> +        reg_2 = 0x40;
> +        reg_3 = 2;
> +        break;
> +    case 0:
> +        reg_1 = 0x80;
> +        reg_2 = 0x0;
> +        reg_3 = 1;
> +        break;
> +    case 1:
> +        reg_1 = 0x6f;
> +        reg_2 = 0x40;
> +        reg_3 = 1;
> +        break;
> +    case 2:
> +        reg_1 = 0x40;
> +        reg_2 = 0x6f;
> +        reg_3 = 1;
> +        break;
> +    default:
> +        return 1;
> +    }
> +
> +    ret += ov5640_read(c, 0x5001, &v);
> +    ret += ov5640_write(c, 0x5001, (v | 0x80));
> +    ret += ov5640_read(c, 0x5580, &v);
> +    ret += ov5640_write(c, 0x5580, (v | 0x1));
> +
> +    ret += ov5640_write(c, 0x5581, reg_1);
> +    ret += ov5640_write(c, 0x5582, reg_2);
> +
> +    ret += ov5640_read(c, 0x5588, &v);
> +    v = v & 0xcc;
> +    ret += ov5640_write(c, 0x5588, (v | reg_3));
> +
> +    ov5640_status.hue_val = value;
>      return ret;
> }
> static int ov5640_q_hue(struct v4l2_subdev *sd, int *value)
> {
>      int ret=0;
> -    // TODO: will be added soon
> +    *value = ov5640_status.hue_val;
>      return ret;
> }
> +
> static int ov5640_t_sharpness(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> -    // TODO: will be added soon
> +    u8 v,reg_1;
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +
> +    switch (value)
> +    {
> +    case 99:
> +        ret += ov5640_read(c, 0x5308, &v);
> +        ret += ov5640_write(c, 0x5308, (v & 0xbf));
> +        ret += ov5640_write(c, 0x5300, 0x08);
> +        ret += ov5640_write(c, 0x5301, 0x30);
> +        ret += ov5640_write(c, 0x5302, 0x10);
> +        ret += ov5640_write(c, 0x5303, 0x00);
> +        ret += ov5640_write(c, 0x5309, 0x08);
> +        ret += ov5640_write(c, 0x530a, 0x30);
> +        ret += ov5640_write(c, 0x530b, 0x04);
> +        ret += ov5640_write(c, 0x530c, 0x06);
> +        ov5640_status.sharpness_val = value;
> +        return ret;
> +    case 1:
> +        reg_1 = 0x2;
> +        break;
> +    case 2:
> +        reg_1 = 0x4;
> +        break;
> +    case 3:
> +        reg_1 = 0x8;
> +        break;
> +    case 4:
> +        reg_1 = 0xc;
> +        break;
> +    case 5:
> +        reg_1 = 0x10;
> +        break;
> +    case 0:
> +    default:
> +        reg_1 = 0;
> +        break;
> +    }
> +    ret += ov5640_read(c, 0x5308, &v);
> +    ret += ov5640_write(c, 0x5308, (v | 0x40));
> +    ret += ov5640_write(c, 0x5302, reg_1);
> +
> +    ov5640_status.sharpness_val = value;
>      return ret;
> }
> static int ov5640_q_sharpness(struct v4l2_subdev *sd, int *value)
> {
>      int ret=0;
> -    // TODO: will be added soon
> +    *value = ov5640_status.sharpness_val;
>      return ret;
> }
> @@ -1484,15 +1787,15 @@
>          ret += ov5640_af_release(c);
>          break;
>      case OV5640_FOCUS_MODE_WINDOW:
> -        break;
> +        ret += ov5640_af_do_focus(c);
> +       break;
>      case OV5640_FOCUS_MODE_CENTERED:
>      default:
>          ret += ov5640_af_center(c);
> -        break;
> +        ret += ov5640_af_do_focus(c);
> +       break;
>      };
> -    ret += ov5640_af_do_focus(c);
> -
>      return ret;
> }
> @@ -1504,32 +1807,379 @@
>      return ret;
> }
> +#define OV5640_AE_MODE_AUTO                0
> +#define OV5640_AE_MODE_WINDOW_AVG          1
> +#define OV5640_AE_MODE_WINDOW_CENTERED     2
> +#define OV5640_AE_MODE_WINDOW_LANDSCAPE    3
> +
> static int ov5640_t_exposure(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> -    // TODO: will be added soon
> +    u8 reg_1,reg_2,reg_3,reg_4,reg_5,reg_6,reg_7,reg_8;
> +    dprintk( 3, "%s Mode (%d) - X = %d, Y = %d, W = %d, H = %d",
> +            __FUNCTION__,value, ov5640_status.ae_x,ov5640_status.ae_y,
> +            ov5640_status.ae_w, ov5640_status.ae_h);
> +
> +    ov5640_status.ae_mode = value;
> +
> +    switch (value)
> +    {
> +    case OV5640_AE_MODE_WINDOW_AVG:
> +        reg_1 = 0x11;
> +        reg_2 = 0x11;
> +        reg_3 = 0x11;
> +        reg_4 = 0x11;
> +        reg_5 = 0x11;
> +        reg_6 = 0x11;
> +        reg_7 = 0x11;
> +        reg_8 = 0x11;
> +        break;
> +    case OV5640_AE_MODE_WINDOW_CENTERED:
> +        reg_1 = 0;
> +        reg_2 = 0;
> +        reg_3 = 0x10;
> +        reg_4 = 0x01;
> +        reg_5 = 0x10;
> +        reg_6 = 0x01;
> +        reg_7 = 0;
> +        reg_8 = 0;
> +        break;
> +    case OV5640_AE_MODE_WINDOW_LANDSCAPE:
> +        reg_1 = 0x62;
> +        reg_2 = 0x26;
> +        reg_3 = 0xe6;
> +        reg_4 = 0x6e;
> +        reg_5 = 0xea;
> +        reg_6 = 0xae;
> +        reg_7 = 0xa6;
> +        reg_8 = 0x6a;
> +        break;
> +    case OV5640_AE_MODE_AUTO:
> +    default:
> +        ret += ov5640_write(c, 0x501d, 0);
> +        return ret;
> +    }
> +
> +    ret += ov5640_write(c, 0x5688, reg_1);
> +    ret += ov5640_write(c, 0x5689, reg_2);
> +    ret += ov5640_write(c, 0x568a, reg_3);
> +    ret += ov5640_write(c, 0x568b, reg_4);
> +    ret += ov5640_write(c, 0x568c, reg_5);
> +    ret += ov5640_write(c, 0x568d, reg_6);
> +    ret += ov5640_write(c, 0x568e, reg_7);
> +    ret += ov5640_write(c, 0x568f, reg_8);
> +
> +    reg_1 = (ov5640_status.ae_x >> 8);
> +    reg_2 = ov5640_status.ae_x & 0xff;
> +    reg_3 = (ov5640_status.ae_y >> 8);
> +    reg_4 = ov5640_status.ae_y & 0xff;
> +    reg_5 = ((ov5640_status.ae_x + ov5640_status.ae_w) >> 8);
> +    reg_6 = (ov5640_status.ae_x + ov5640_status.ae_w) & 0xff;
> +    reg_7 = ((ov5640_status.ae_y + ov5640_status.ae_h) >> 8);
> +    reg_8 = (ov5640_status.ae_y + ov5640_status.ae_h) & 0xff;
> +
> +    ret += ov5640_write(c, 0x5680, reg_1);
> +    ret += ov5640_write(c, 0x5681, reg_2);
> +    ret += ov5640_write(c, 0x5682, reg_3);
> +    ret += ov5640_write(c, 0x5683, reg_4);
> +    ret += ov5640_write(c, 0x5684, reg_5);
> +    ret += ov5640_write(c, 0x5685, reg_6);
> +    ret += ov5640_write(c, 0x5686, reg_7);
> +    ret += ov5640_write(c, 0x5687, reg_8);
> +
> +    ret += ov5640_write(c, 0x501d, 0x10);
> +
>      return ret;
> }
> static int ov5640_q_exposure(struct v4l2_subdev *sd, int *value)
> {
>      int ret=0;
> -    // TODO: will be added soon
> +    *value = ov5640_status.ae_mode;
>      return ret;
> }
> -static int ov5640_t_flash_detect(struct v4l2_subdev *sd, int value)
> +
> +#define OV5640_EXPOSURE_NORMALIZED_W 800
> +#define OV5640_EXPOSURE_NORMALIZED_H 384
> +
> +static int ov5640_t_exposure_window(struct v4l2_subdev *sd, int value)
> {
> +    unsigned int tmp_y,tmp_x;
>      int ret=0;
> -    // TODO: will be added soon
> +    u32 v = (u32)value;
> +    dprintk( 3, "%s (0x%08x)",  __FUNCTION__,v);
> +
> +    if (v & (1UL<<30))
> +    {
> +        tmp_y = v & 0xffff;
> +        tmp_x = (v>>16) & 0x3fff;
> +        ov5640_status.ae_x = (tmp_x * OV5640_EXPOSURE_NORMALIZED_W) / 
> ov5640_res[ov5640_status.current_res_i].width;
> +        ov5640_status.ae_y = (tmp_y * OV5640_EXPOSURE_NORMALIZED_H) / 
> ov5640_res[ov5640_status.current_res_i].height;
> +    } else {
> +        tmp_y = v & 0xffff;
> +        tmp_x = (v>>16) & 0x3fff;
> +        ov5640_status.ae_w = (tmp_x * OV5640_EXPOSURE_NORMALIZED_W) / 
> ov5640_res[ov5640_status.current_res_i].width;
> +        ov5640_status.ae_h = (tmp_y * OV5640_EXPOSURE_NORMALIZED_H) / 
> ov5640_res[ov5640_status.current_res_i].height;
> +    }
> +
>      return ret;
> }
> +static int ov5640_q_exposure_window(struct v4l2_subdev *sd, int *value)
> +{
> +    int ret=0;
> +    if ((u32)(*value) & (1UL<<31))
> +    {
> +        *value = ((ov5640_status.ae_x << 16) | ov5640_status.ae_y);
> +    } else {
> +        *value = ((ov5640_status.ae_w << 16) | ov5640_status.ae_h);
> +    }
> -static int ov5640_q_flash_detect(struct v4l2_subdev *sd, int *value)
> +    return ret;
> +}
> +
> +#define OV5640_WB_AUTO 0
> +#define OV5640_WB_CLOUD 1
> +#define OV5640_WB_DAYLIGHT 2
> +#define OV5640_WB_INCANDESCENT 3
> +#define OV5640_WB_FLUORESCENT 4
> +#define OV5640_WB_TUNGSTEN 5
> +
> +static int ov5640_t_scene_mode(struct v4l2_subdev *sd, int value)
> {
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int ret=0;
> +    u8 v,reg_1,reg_2,reg_3,reg_4,reg_5,reg_6;
> +
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +    ov5640_status.scene_val = value;
> +
> +    switch (value)
> +    {
> +    case OV5640_WB_CLOUD:
> +        reg_1 = 0x7;
> +        reg_2 = 0x88;
> +        reg_3 = 0x4;
> +        reg_4 = 0x0;
> +        reg_5 = 0x5;
> +        reg_6 = 0x0;
> +        break;
> +    case OV5640_WB_DAYLIGHT:
> +        reg_1 = 0x7;
> +        reg_2 = 0x2;
> +        reg_3 = 0x4;
> +        reg_4 = 0x0;
> +        reg_5 = 0x5;
> +        reg_6 = 0x15;
> +        break;
> +    case OV5640_WB_INCANDESCENT:
> +        reg_1 = 0x4;
> +        reg_2 = 0x88;
> +        reg_3 = 4;
> +        reg_4 = 0x0;
> +        reg_5 = 0x8;
> +        reg_6 = 0xb6;
> +        break;
> +    case OV5640_WB_FLUORESCENT:
> +        reg_1 = 0x6;
> +        reg_2 = 0x2a;
> +        reg_3 = 4;
> +        reg_4 = 0x0;
> +        reg_5 = 0x7;
> +        reg_6 = 0x24;
> +        break;
> +    case OV5640_WB_TUNGSTEN:
> +        reg_1 = 0x4;
> +        reg_2 = 0x58;
> +        reg_3 = 4;
> +        reg_4 = 0x0;
> +        reg_5 = 0x8;
> +        reg_6 = 0x40;
> +        break;
> +    case OV5640_WB_AUTO:
> +    default:
> +        ret += ov5640_read(c, 0x3406, &v);
> +        ret += ov5640_write(c, 0x3406, v & 0xfe);
> +        return ret;
> +    }
> +
> +    ret += ov5640_read(c, 0x3406, &v);
> +    ret += ov5640_write(c, 0x3406, v | 1);
> +
> +    ret += ov5640_write(c, 0x3400, reg_1);
> +    ret += ov5640_write(c, 0x3401, reg_2);
> +    ret += ov5640_write(c, 0x3402, reg_3);
> +    ret += ov5640_write(c, 0x3403, reg_4);
> +    ret += ov5640_write(c, 0x3404, reg_5);
> +    ret += ov5640_write(c, 0x3405, reg_6);
> +
> +    return ret;
> +}
> +static int ov5640_q_scene_mode(struct v4l2_subdev *sd, int *value)
> +{
> +    int ret=0;
> +
> +    *value = ov5640_status.scene_val;
> +    return ret;
> +}
> +
> +#define OV5640_SPE_NORMAL 0
> +#define OV5640_SPE_BLACKWHITE 1
> +#define OV5640_SPE_BLUISH 2
> +#define OV5640_SPE_SEPIA 3
> +#define OV5640_SPE_REDDISH 4
> +#define OV5640_SPE_GREENISH 5
> +#define OV5640_SPE_NEGATIVE 6
> +
> +static int ov5640_t_spe_mode(struct v4l2_subdev *sd, int value)
> +{
>      struct i2c_client *c = v4l2_get_subdevdata(sd);
> +    int ret=0;
> +    u8 v,reg_1,reg_2;
> +
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +    ov5640_status.spe_val = value;
> +
> +    switch (value)
> +    {
> +    case OV5640_SPE_BLACKWHITE:
> +        reg_1 = 0x80;
> +        reg_2 = 0x80;
> +        break;
> +    case OV5640_SPE_BLUISH:
> +        reg_1 = 0xa0;
> +        reg_2 = 0x40;
> +        break;
> +    case OV5640_SPE_SEPIA:
> +        reg_1 = 0x40;
> +        reg_2 = 0xa0;
> +        break;
> +    case OV5640_SPE_REDDISH:
> +        reg_1 = 0x80;
> +        reg_2 = 0xc0;
> +        break;
> +    case OV5640_SPE_GREENISH:
> +        reg_1 = 0x60;
> +        reg_2 = 0x60;
> +        break;
> +    case OV5640_SPE_NEGATIVE:
> +        ret += ov5640_read(c, 0x5001, &v);
> +        ret += ov5640_write(c, 0x5001, v | 0x80);
> +        ret += ov5640_read(c, 0x5580, &v);
> +        ret += ov5640_write(c, 0x5580, (v & 0xa7)|0x40);
> +        return ret;
> +    case OV5640_SPE_NORMAL:
> +    default:
> +        ret += ov5640_read(c, 0x5001, &v);
> +        ret += ov5640_write(c, 0x5001, v & 0x7f);
> +        ret += ov5640_read(c, 0x5580, &v);
> +        ret += ov5640_write(c, 0x5580, v & 0xa7);
> +        return ret;
> +    }
> +
> +    ret += ov5640_read(c, 0x5001, &v);
> +    ret += ov5640_write(c, 0x5001, v | 0x80);
> +    ret += ov5640_read(c, 0x5580, &v);
> +    ret += ov5640_write(c, 0x5580, (v & 0xa7)|0x18);
> +
> +    ret += ov5640_write(c, 0x5583, reg_1);
> +    ret += ov5640_write(c, 0x5584, reg_2);
> +
> +    return ret;
> +}
> +static int ov5640_q_spe_mode(struct v4l2_subdev *sd, int *value)
> +{
> +    int ret=0;
> +
> +    *value = ov5640_status.spe_val;
> +    return ret;
> +}
> +
> +static int ov5640_t_exp_comp(struct v4l2_subdev *sd, int value)
> +{
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
> +    int ret=0;
> +    u8 reg_1,reg_2,reg_3,reg_4,reg_5,reg_6;
> +
> +    dprintk( 3, "%s (%d)",__FUNCTION__,value);
> +    ov5640_status.exp_comp_val = value;
> +
> +    switch (value)
> +    {
> +    case -2:
> +        reg_1 = 0x28;
> +        reg_2 = 0x20;
> +        reg_3 = 0x51;
> +        reg_4 = 0x28;
> +        reg_5 = 0x20;
> +        reg_6 = 0x10;
> +        break;
> +    case -1:
> +        reg_1 = 0x30;
> +        reg_2 = 0x28;
> +        reg_3 = 0x61;
> +        reg_4 = 0x30;
> +        reg_5 = 0x28;
> +        reg_6 = 0x10;
> +        break;
> +    case 1:
> +        reg_1 = 0x40;
> +        reg_2 = 0x38;
> +        reg_3 = 0x71;
> +        reg_4 = 0x40;
> +        reg_5 = 0x38;
> +        reg_6 = 0x10;
> +        break;
> +    case 2:
> +        reg_1 = 0x48;
> +        reg_2 = 0x40;
> +        reg_3 = 0x80;
> +        reg_4 = 0x48;
> +        reg_5 = 0x40;
> +        reg_6 = 0x20;
> +        break;
> +    case 0:
> +    default:
> +        reg_1 = 0x38;
> +        reg_2 = 0x30;
> +        reg_3 = 0x61;
> +        reg_4 = 0x38;
> +        reg_5 = 0x30;
> +        reg_6 = 0x10;
> +        break;
> +    }
> +
> +    ret += ov5640_write(c, 0x3a0f, reg_1);
> +    ret += ov5640_write(c, 0x3a10, reg_2);
> +    ret += ov5640_write(c, 0x3a11, reg_3);
> +    ret += ov5640_write(c, 0x3a1b, reg_4);
> +    ret += ov5640_write(c, 0x3a1e, reg_5);
> +    ret += ov5640_write(c, 0x3a1f, reg_6);
> +
> +    return ret;
> +}
> +static int ov5640_q_exp_comp(struct v4l2_subdev *sd, int *value)
> +{
> +    int ret=0;
> +
> +    *value = ov5640_status.exp_comp_val;
> +    return ret;
> +}
> +
> +static int ov5640_t_exposure_level_detect(struct v4l2_subdev *sd, int value)
> +{
> +    int ret=0;
> +    // this CID is RO
> +
> +    return ret;
> +}
> +
> +static int ov5640_q_exposure_level_detect(struct v4l2_subdev *sd, int *value)
> +{
> +    int ret=0;
> +    struct i2c_client *c = v4l2_get_subdevdata(sd);
>      int exposure,gain;
>      u8 v;
> @@ -1690,15 +2340,16 @@
>          .qc = {
>              .id = V4L2_CID_GAIN,
>              .type = V4L2_CTRL_TYPE_INTEGER,
> -            .name = "ISO Manual Val",
> -            .minimum = 100,
> +            .name = "ISO",
> +            .minimum = 0,
>              .maximum = 1600,
>              .step = 100,
> -            .default_value = 100,
> +            .default_value = 0,
>          },
>          .tweak = ov5640_t_iso_val,
>          .query = ov5640_q_iso_val,
>      },
> +    /*
>      {
>          .qc = {
>              .id = V4L2_CID_AUTOGAIN,
> @@ -1711,7 +2362,7 @@
>          },
>          .tweak = ov5640_t_iso_mode,
>          .query = ov5640_q_iso_mode,
> -    },
> +    },*/
>      {
>          .qc = {
>              .id = V4L2_CID_BRIGHTNESS,
> @@ -1769,8 +2420,8 @@
>              .id = V4L2_CID_SHARPNESS,
>              .type = V4L2_CTRL_TYPE_INTEGER,
>              .name = "Sharpness",
> -            .minimum = -2,
> -            .maximum = 2,
> +            .minimum = 0,
> +            .maximum = 99,
>              .step = 1,
>              .default_value = 0,
>          },
> @@ -1782,7 +2433,13 @@
> #define CID_FOCUS_POSITION         (V4L2_CID_PRIVATE_BASE + 0)
> #define CID_FOCUS_MODE_STATUS      (V4L2_CID_PRIVATE_BASE + 1)
> #define CID_EXPOSURE_MODE_STATUS   (V4L2_CID_PRIVATE_BASE + 2)
> -#define CID_AUTO_FLASH_DETECT      (V4L2_CID_PRIVATE_BASE + 3)
> +#define CID_EXPOSURE_WINDOW        (V4L2_CID_PRIVATE_BASE + 3)
> +#define CID_EXPOSURE_LEVEL_DETECT  (V4L2_CID_PRIVATE_BASE + 4)
> +#define CID_FLASH_SWITCH           (V4L2_CID_PRIVATE_BASE + 5)
> +#define CID_SCENE_MODE             (V4L2_CID_PRIVATE_BASE + 6)
> +#define CID_SPE_MODE               (V4L2_CID_PRIVATE_BASE + 7)
> +#define CID_EXPOSURE_COMPENSATION  (V4L2_CID_PRIVATE_BASE + 8)
> +
>     {
>          .qc = {
>              .id = CID_FOCUS_POSITION,
> @@ -1824,17 +2481,84 @@
>       },
>       {
>            .qc = {
> -              .id = CID_AUTO_FLASH_DETECT ,
> +              .id = CID_EXPOSURE_WINDOW,
>                .type = V4L2_CTRL_TYPE_INTEGER,
> -              .name = "Auto Flash Detect",
> +              .name = "Exposure Window",
>                .minimum = 0,
>                .maximum = 0x7fffffff,
>                .step = 1,
> +              // default window, 320x240 of a total 1280x720 prevew screen
> +              .default_value = 0x014000f0,
> +          },
> +          .tweak = ov5640_t_exposure_window,
> +          .query = ov5640_q_exposure_window,
> +      },
> +     {
> +          .qc = {
> +              .id = CID_EXPOSURE_LEVEL_DETECT,
> +              .type = V4L2_CTRL_TYPE_INTEGER,
> +              .name = "Exposure Level Detect",
> +              .minimum = 0,
> +              .maximum = 0x7fffffff,
> +              .step = 1,
>                .default_value = 0,
>            },
> -          .tweak = ov5640_t_flash_detect,
> -          .query = ov5640_q_flash_detect,
> +          .tweak = ov5640_t_exposure_level_detect,
> +          .query = ov5640_q_exposure_level_detect,
>        },
> +      {
> +           .qc = {
> +               .id = CID_FLASH_SWITCH ,
> +               .type = V4L2_CTRL_TYPE_BOOLEAN,
> +               .name = "Flash Switch",
> +               .minimum = 0,
> +               .maximum = 1,
> +               .step = 1,
> +               .default_value = 0,
> +           },
> +           .tweak = ov5640_t_flash,
> +           .query = ov5640_q_flash,
> +       },
> +       {
> +            .qc = {
> +                .id =  CID_SCENE_MODE,
> +                .type = V4L2_CTRL_TYPE_INTEGER,
> +                .name = "Scene Mode",
> +                .minimum = 0,
> +                .maximum = 5,
> +                .step = 1,
> +                .default_value = 0,
> +            },
> +            .tweak = ov5640_t_scene_mode,
> +            .query = ov5640_q_scene_mode,
> +        },
> +        {
> +             .qc = {
> +                 .id = CID_SPE_MODE ,
> +                 .type = V4L2_CTRL_TYPE_INTEGER,
> +                 .name = "SPE Mode",
> +                 .minimum = 0,
> +                 .maximum = 6,
> +                 .step = 1,
> +                 .default_value = 0,
> +             },
> +             .tweak = ov5640_t_spe_mode,
> +             .query = ov5640_q_spe_mode,
> +         },
> +        {
> +             .qc = {
> +                 .id = CID_EXPOSURE_COMPENSATION,
> +                 .type = V4L2_CTRL_TYPE_INTEGER,
> +                 .name = "Exposure Compensation",
> +                 .minimum = -2,
> +                 .maximum = 2,
> +                 .step = 1,
> +                 .default_value = 0,
> +              },
> +
> +             .tweak = ov5640_t_exp_comp,
> +             .query = ov5640_q_exp_comp,
> +         },
> #if 0 //BUGBUG
>        {
>                 .qc = {
> @@ -2217,6 +2941,8 @@
>        struct ci_sensor_config *info;
>        struct v4l2_subdev *sd;
>        int ret = -1;
> +#define LANGWELL_GPIO_BASE_ADDR 0xff12c000
> +    u32 __iomem *mem = ioremap_nocache(LANGWELL_GPIO_BASE_ADDR, 64);
>         DBG_entering;
> @@ -2240,11 +2966,14 @@
>        sd = &info->sd;
>        v4l2_i2c_subdev_init(sd, client, &ov5640_ops);
> +    // change LANGWELL GPIO-45 mux to GPIO Funtion
> +    gpio_direction_output(GPIO_FLASH,0);
> +    *(mem + 16) &= 0xf3ffffff;
> +
>        /*
>         * TODO: Need to check if this can be here.
>         * Turn into standby mode
>         */
> -        /* ov5640_standby(); */
>        ret += ov5640_init(client);
>        ov5640_standby(sd);
> 
> 
> Best Regards,
> 
> Yong He
> Software Engineer, PCSD SW Solutions,
> Intel Asia-Pacific R&D Ltd.
> Phone (+86) 21-61166334
> Lab (+86) 21-61167881
> 

_______________________________________________
MeeGo-kernel mailing list
MeeGo-kernel@lists.meego.com
http://lists.meego.com/listinfo/meego-kernel

Reply via email to