RE: [PATCH] mt9t031 - migration to sub device frame work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>-----Original Message-----
>From: linux-media-owner@xxxxxxxxxxxxxxx [mailto:linux-media-
>owner@xxxxxxxxxxxxxxx] On Behalf Of Guennadi Liakhovetski
>Sent: Thursday, June 25, 2009 1:46 PM
>To: Karicheri, Muralidharan
>Cc: linux-media@xxxxxxxxxxxxxxx; davinci-linux-open-
>source@xxxxxxxxxxxxxxxxxxxx
>Subject: Re: [PATCH] mt9t031 - migration to sub device frame work
>
>On Wed, 24 Jun 2009, m-karicheri2@xxxxxx wrote:
>
>> From: Muralidharan Karicheri <m-karicheri2@xxxxxx>
>>
>> This patch migrates mt9t031 driver from SOC Camera interface to
>> sub device interface. This is sent to get a feedback about the
>> changes done since I am not sure if some of the functionality
>> that is removed works okay with SOC Camera bridge driver or
>> not. Following functions are to be discussed and added as needed:-
>>
>>      1) query bus parameters
>>      2) set bus parameters
>>      3) set crop
>>
>> I have tested this with vpfe capture driver and I could capture
>> 640x480@17fps and 2048x1536@12fps resolution frames from the sensor.
>>
>> Reviewed by: Hans Verkuil <hverkuil@xxxxxxxxx>
>> Reviewed by: Guennadi Liakhovetski <g.liakhovetski@xxxxxx>
>
>Excuse me? This is the first time I see this patch. FYI, "Reviewed-by"
>means that the respective person has actually reviewed the patch and
>submitted that line _him_ or _her_self!
>
>Thanks
>Guennadi
>
My mistake. I was assuming that by adding this line, I can get it reviewed by the mandatory reviewers. Is there a way to provide this information in the patch description?

Could you please review this patch and give me the comments? I had exchanged emails with you in the past agreeing to do this migration. I remember you had accepted the same.

Murali
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2@xxxxxx>
>> ---
>>  drivers/media/video/mt9t031.c |  596 ++++++++++++++++++++---------------
>------
>>  1 files changed, 293 insertions(+), 303 deletions(-)
>>
>> diff --git a/drivers/media/video/mt9t031.c
>b/drivers/media/video/mt9t031.c
>> index f72aeb7..0f32ff2 100644
>> --- a/drivers/media/video/mt9t031.c
>> +++ b/drivers/media/video/mt9t031.c
>> @@ -13,9 +13,9 @@
>>  #include <linux/i2c.h>
>>  #include <linux/log2.h>
>>
>> +#include <media/v4l2-device.h>
>>  #include <media/v4l2-common.h>
>>  #include <media/v4l2-chip-ident.h>
>> -#include <media/soc_camera.h>
>>
>>  /* mt9t031 i2c address 0x5d
>>   * The platform has to define i2c_board_info
>> @@ -52,33 +52,108 @@
>>  #define MT9T031_VERTICAL_BLANK              25
>>  #define MT9T031_COLUMN_SKIP         32
>>  #define MT9T031_ROW_SKIP            20
>> +#define MT9T031_DEFAULT_WIDTH               640
>> +#define MT9T031_DEFAULT_HEIGHT              480
>>
>>  #define MT9T031_BUS_PARAM   (SOCAM_PCLK_SAMPLE_RISING |     \
>>      SOCAM_PCLK_SAMPLE_FALLING | SOCAM_HSYNC_ACTIVE_HIGH |   \
>>      SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH |      \
>>      SOCAM_MASTER | SOCAM_DATAWIDTH_10)
>>
>> -static const struct soc_camera_data_format mt9t031_colour_formats[] = {
>> +
>> +/* Debug functions */
>> +static int debug;
>> +module_param(debug, bool, 0644);
>> +MODULE_PARM_DESC(debug, "Debug level (0-1)");
>> +
>> +static const struct v4l2_fmtdesc mt9t031_formats[] = {
>> +    {
>> +            .index = 0,
>> +            .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
>> +            .description = "Bayer (sRGB) 10 bit",
>> +            .pixelformat = V4L2_PIX_FMT_SGRBG10,
>> +    },
>> +};
>> +static const unsigned int mt9t031_num_formats =
>ARRAY_SIZE(mt9t031_formats);
>> +
>> +static const struct v4l2_queryctrl mt9t031_controls[] = {
>>      {
>> -            .name           = "Bayer (sRGB) 10 bit",
>> -            .depth          = 10,
>> -            .fourcc         = V4L2_PIX_FMT_SGRBG10,
>> -            .colorspace     = V4L2_COLORSPACE_SRGB,
>> +            .id             = V4L2_CID_VFLIP,
>> +            .type           = V4L2_CTRL_TYPE_BOOLEAN,
>> +            .name           = "Flip Vertically",
>> +            .minimum        = 0,
>> +            .maximum        = 1,
>> +            .step           = 1,
>> +            .default_value  = 0,
>> +    }, {
>> +            .id             = V4L2_CID_HFLIP,
>> +            .type           = V4L2_CTRL_TYPE_BOOLEAN,
>> +            .name           = "Flip Horizontally",
>> +            .minimum        = 0,
>> +            .maximum        = 1,
>> +            .step           = 1,
>> +            .default_value  = 0,
>> +    }, {
>> +            .id             = V4L2_CID_GAIN,
>> +            .type           = V4L2_CTRL_TYPE_INTEGER,
>> +            .name           = "Gain",
>> +            .minimum        = 0,
>> +            .maximum        = 127,
>> +            .step           = 1,
>> +            .default_value  = 64,
>> +            .flags          = V4L2_CTRL_FLAG_SLIDER,
>> +    }, {
>> +            .id             = V4L2_CID_EXPOSURE,
>> +            .type           = V4L2_CTRL_TYPE_INTEGER,
>> +            .name           = "Exposure",
>> +            .minimum        = 1,
>> +            .maximum        = 255,
>> +            .step           = 1,
>> +            .default_value  = 255,
>> +            .flags          = V4L2_CTRL_FLAG_SLIDER,
>> +    }, {
>> +            .id             = V4L2_CID_EXPOSURE_AUTO,
>> +            .type           = V4L2_CTRL_TYPE_BOOLEAN,
>> +            .name           = "Automatic Exposure",
>> +            .minimum        = 0,
>> +            .maximum        = 1,
>> +            .step           = 1,
>> +            .default_value  = 1,
>>      }
>>  };
>> +static const unsigned int mt9t031_num_controls =
>ARRAY_SIZE(mt9t031_controls);
>>
>>  struct mt9t031 {
>> -    struct i2c_client *client;
>> -    struct soc_camera_device icd;
>> +    struct v4l2_subdev sd;
>>      int model;      /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
>>      unsigned char autoexposure;
>>      u16 xskip;
>>      u16 yskip;
>> +    u32 width;
>> +    u32 height;
>> +    unsigned short x_min;           /* Camera capabilities */
>> +    unsigned short y_min;
>> +    unsigned short x_current;       /* Current window location */
>> +    unsigned short y_current;
>> +    unsigned short width_min;
>> +    unsigned short width_max;
>> +    unsigned short height_min;
>> +    unsigned short height_max;
>> +    unsigned short y_skip_top;      /* Lines to skip at the top */
>> +    unsigned short gain;
>> +    unsigned short exposure;
>>  };
>>
>> +static inline struct mt9t031 *to_mt9t031(struct v4l2_subdev *sd)
>> +{
>> +    return container_of(sd, struct mt9t031, sd);
>> +}
>> +
>>  static int reg_read(struct i2c_client *client, const u8 reg)
>>  {
>> -    s32 data = i2c_smbus_read_word_data(client, reg);
>> +    s32 data;
>> +
>> +    data = i2c_smbus_read_word_data(client, reg);
>>      return data < 0 ? data : swab16(data);
>>  }
>>
>> @@ -110,8 +185,9 @@ static int reg_clear(struct i2c_client *client, const
>u8 reg,
>>      return reg_write(client, reg, ret & ~data);
>>  }
>>
>> -static int set_shutter(struct i2c_client *client, const u32 data)
>> +static int set_shutter(struct v4l2_subdev *sd, const u32 data)
>>  {
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>>      int ret;
>>
>>      ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
>> @@ -122,9 +198,10 @@ static int set_shutter(struct i2c_client *client,
>const u32 data)
>>      return ret;
>>  }
>>
>> -static int get_shutter(struct i2c_client *client, u32 *data)
>> +static int get_shutter(struct v4l2_subdev *sd, u32 *data)
>>  {
>>      int ret;
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>>
>>      ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER);
>>      *data = ret << 16;
>> @@ -136,20 +213,10 @@ static int get_shutter(struct i2c_client *client,
>u32 *data)
>>      return ret < 0 ? ret : 0;
>>  }
>>
>> -static int mt9t031_init(struct soc_camera_device *icd)
>> +static int mt9t031_init(struct v4l2_subdev *sd, u32 val)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -    struct soc_camera_link *icl = client->dev.platform_data;
>>      int ret;
>> -
>> -    if (icl->power) {
>> -            ret = icl->power(&client->dev, 1);
>> -            if (ret < 0) {
>> -                    dev_err(icd->vdev->parent,
>> -                            "Platform failed to power-on the camera.\n");
>> -                    return ret;
>> -            }
>> -    }
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>>
>>      /* Disable chip output, synchronous option update */
>>      ret = reg_write(client, MT9T031_RESET, 1);
>> @@ -158,99 +225,67 @@ static int mt9t031_init(struct soc_camera_device
>*icd)
>>      if (ret >= 0)
>>              ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
>>
>> -    if (ret < 0 && icl->power)
>> -            icl->power(&client->dev, 0);
>> -
>>      return ret >= 0 ? 0 : -EIO;
>>  }
>>
>> -static int mt9t031_release(struct soc_camera_device *icd)
>> -{
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -    struct soc_camera_link *icl = client->dev.platform_data;
>> -
>> -    /* Disable the chip */
>> -    reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
>> -
>> -    if (icl->power)
>> -            icl->power(&client->dev, 0);
>> -
>> -    return 0;
>> -}
>> -
>> -static int mt9t031_start_capture(struct soc_camera_device *icd)
>> +static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>>
>>      /* Switch to master "normal" mode */
>> -    if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
>> -            return -EIO;
>> -    return 0;
>> -}
>> -
>> -static int mt9t031_stop_capture(struct soc_camera_device *icd)
>> -{
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -
>> -    /* Stop sensor readout */
>> -    if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
>> -            return -EIO;
>> +    if (enable) {
>> +            if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
>> +                    return -EIO;
>> +    } else {
>> +    /* Switch to master "" mode */
>> +            if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
>> +                    return -EIO;
>> +    }
>>      return 0;
>>  }
>>
>> -static int mt9t031_set_bus_param(struct soc_camera_device *icd,
>> -                             unsigned long flags)
>> +/* Round up minima and round down maxima */
>> +static void recalculate_limits(struct mt9t031 *mt9t031,
>> +                           u16 xskip, u16 yskip)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -
>> -    /* The caller should have queried our parameters, check anyway */
>> -    if (flags & ~MT9T031_BUS_PARAM)
>> -            return -EINVAL;
>> -
>> -    if (flags & SOCAM_PCLK_SAMPLE_FALLING)
>> -            reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
>> -    else
>> -            reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
>> -
>> -    return 0;
>> +    mt9t031->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
>> +    mt9t031->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
>> +    mt9t031->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
>> +    mt9t031->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
>> +    mt9t031->width_max = MT9T031_MAX_WIDTH / xskip;
>> +    mt9t031->height_max = MT9T031_MAX_HEIGHT / yskip;
>>  }
>>
>> -static unsigned long mt9t031_query_bus_param(struct soc_camera_device
>*icd)
>> +const struct v4l2_queryctrl *mt9t031_find_qctrl(u32 id)
>>  {
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> -    struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
>> +    int i;
>>
>> -    return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
>> -}
>> -
>> -/* Round up minima and round down maxima */
>> -static void recalculate_limits(struct soc_camera_device *icd,
>> -                           u16 xskip, u16 yskip)
>> -{
>> -    icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
>> -    icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
>> -    icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
>> -    icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
>> -    icd->width_max = MT9T031_MAX_WIDTH / xskip;
>> -    icd->height_max = MT9T031_MAX_HEIGHT / yskip;
>> +    for (i = 0; i < mt9t031_num_controls; i++) {
>> +            if (mt9t031_controls[i].id == id)
>> +                    return &mt9t031_controls[i];
>> +    }
>> +    return NULL;
>>  }
>>
>> -static int mt9t031_set_params(struct soc_camera_device *icd,
>> +static int mt9t031_set_params(struct v4l2_subdev *sd,
>>                            struct v4l2_rect *rect, u16 xskip, u16 yskip)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>> +
>>      int ret;
>>      u16 xbin, ybin, width, height, left, top;
>>      const u16 hblank = MT9T031_HORIZONTAL_BLANK,
>>              vblank = MT9T031_VERTICAL_BLANK;
>>
>>      /* Make sure we don't exceed sensor limits */
>> -    if (rect->left + rect->width > icd->width_max)
>> -            rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
>> +    if (rect->left + rect->width > mt9t031->width_max)
>> +            rect->left =
>> +            (mt9t031->width_max - rect->width) / 2 + mt9t031->x_min;
>>
>> -    if (rect->top + rect->height > icd->height_max)
>> -            rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
>> +    if (rect->top + rect->height > mt9t031->height_max)
>> +            rect->top =
>> +            (mt9t031->height_max - rect->height) / 2 + mt9t031->y_min;
>>
>>      width = rect->width * xskip;
>>      height = rect->height * yskip;
>> @@ -260,8 +295,9 @@ static int mt9t031_set_params(struct
>soc_camera_device *icd,
>>      xbin = min(xskip, (u16)3);
>>      ybin = min(yskip, (u16)3);
>>
>> -    dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n",
>> -            xskip, width, rect->width, yskip, height, rect->height);
>> +    v4l2_dbg(1, debug, sd, "xskip %u, width %u/%u, yskip %u,"
>> +            "height %u/%u\n", xskip, width, rect->width, yskip,
>> +            height, rect->height);
>>
>>      /* Could just do roundup(rect->left, [xy]bin * 2); but this is
>cheaper */
>>      switch (xbin) {
>> @@ -299,7 +335,7 @@ static int mt9t031_set_params(struct
>soc_camera_device *icd,
>>                      ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
>>                                      ((ybin - 1) << 4) | (yskip - 1));
>>      }
>> -    dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
>> +    v4l2_dbg(1, debug, sd, "new physical left %u, top %u\n", left, top);
>>
>>      /* The caller provides a supported format, as guaranteed by
>>       * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap()
>*/
>> @@ -311,46 +347,41 @@ static int mt9t031_set_params(struct
>soc_camera_device *icd,
>>              ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1);
>>      if (ret >= 0)
>>              ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
>> -                            height + icd->y_skip_top - 1);
>> +                            height + mt9t031->y_skip_top - 1);
>>      if (ret >= 0 && mt9t031->autoexposure) {
>> -            ret = set_shutter(client, height + icd->y_skip_top + vblank);
>> +            ret = set_shutter(sd, height + mt9t031->y_skip_top + vblank);
>>              if (ret >= 0) {
>>                      const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
>>                      const struct v4l2_queryctrl *qctrl =
>> -                            soc_camera_find_qctrl(icd->ops,
>> -                                                  V4L2_CID_EXPOSURE);
>> -                    icd->exposure = (shutter_max / 2 + (height +
>> -                                     icd->y_skip_top + vblank - 1) *
>> +                            mt9t031_find_qctrl(V4L2_CID_EXPOSURE);
>> +                    mt9t031->exposure = (shutter_max / 2 + (height +
>> +                                     mt9t031->y_skip_top + vblank - 1) *
>>                                       (qctrl->maximum - qctrl->minimum)) /
>>                              shutter_max + qctrl->minimum;
>>              }
>>      }
>>
>>      /* Re-enable register update, commit all changes */
>> -    if (ret >= 0)
>> +    if (ret >= 0) {
>>              ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
>> -
>> +            /* update the values */
>> +            mt9t031->width  = rect->width,
>> +            mt9t031->height = rect->height,
>> +            mt9t031->x_current = rect->left;
>> +            mt9t031->y_current = rect->top;
>> +    }
>>      return ret < 0 ? ret : 0;
>>  }
>>
>> -static int mt9t031_set_crop(struct soc_camera_device *icd,
>> -                        struct v4l2_rect *rect)
>> -{
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> -
>> -    /* CROP - no change in scaling, or in limits */
>> -    return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
>> -}
>> -
>> -static int mt9t031_set_fmt(struct soc_camera_device *icd,
>> +static int mt9t031_set_fmt(struct v4l2_subdev *sd,
>>                         struct v4l2_format *f)
>>  {
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>>      int ret;
>>      u16 xskip, yskip;
>>      struct v4l2_rect rect = {
>> -            .left   = icd->x_current,
>> -            .top    = icd->y_current,
>> +            .left   = mt9t031->x_current,
>> +            .top    = mt9t031->y_current,
>>              .width  = f->fmt.pix.width,
>>              .height = f->fmt.pix.height,
>>      };
>> @@ -369,18 +400,17 @@ static int mt9t031_set_fmt(struct soc_camera_device
>*icd,
>>              if (rect.height * yskip <= MT9T031_MAX_HEIGHT)
>>                      break;
>>
>> -    recalculate_limits(icd, xskip, yskip);
>> +    recalculate_limits(mt9t031, xskip, yskip);
>>
>> -    ret = mt9t031_set_params(icd, &rect, xskip, yskip);
>> +    ret = mt9t031_set_params(sd, &rect, xskip, yskip);
>>      if (!ret) {
>>              mt9t031->xskip = xskip;
>>              mt9t031->yskip = yskip;
>>      }
>> -
>>      return ret;
>>  }
>>
>> -static int mt9t031_try_fmt(struct soc_camera_device *icd,
>> +static int mt9t031_try_fmt(struct v4l2_subdev *sd,
>>                         struct v4l2_format *f)
>>  {
>>      struct v4l2_pix_format *pix = &f->fmt.pix;
>> @@ -396,19 +426,19 @@ static int mt9t031_try_fmt(struct soc_camera_device
>*icd,
>>
>>      pix->width &= ~0x01; /* has to be even */
>>      pix->height &= ~0x01; /* has to be even */
>> -
>>      return 0;
>>  }
>>
>> -static int mt9t031_get_chip_id(struct soc_camera_device *icd,
>> +static int mt9t031_get_chip_id(struct v4l2_subdev *sd,
>>                             struct v4l2_dbg_chip_ident *id)
>>  {
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);;
>>
>>      if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
>>              return -EINVAL;
>>
>> -    if (id->match.addr != mt9t031->client->addr)
>> +    if (id->match.addr != client->addr)
>>              return -ENODEV;
>>
>>      id->ident       = mt9t031->model;
>> @@ -418,10 +448,11 @@ static int mt9t031_get_chip_id(struct
>soc_camera_device *icd,
>>  }
>>
>>  #ifdef CONFIG_VIDEO_ADV_DEBUG
>> -static int mt9t031_get_register(struct soc_camera_device *icd,
>> +static int mt9t031_get_register(struct v4l2_subdev *sd,
>>                              struct v4l2_dbg_register *reg)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);;
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>>
>>      if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
>>              return -EINVAL;
>> @@ -437,10 +468,11 @@ static int mt9t031_get_register(struct
>soc_camera_device *icd,
>>      return 0;
>>  }
>>
>> -static int mt9t031_set_register(struct soc_camera_device *icd,
>> +static int mt9t031_set_register(struct v4l2_subdev *sd,
>>                              struct v4l2_dbg_register *reg)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>>
>>      if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
>>              return -EINVAL;
>> @@ -455,85 +487,53 @@ static int mt9t031_set_register(struct
>soc_camera_device *icd,
>>  }
>>  #endif
>>
>> -static const struct v4l2_queryctrl mt9t031_controls[] = {
>> -    {
>> -            .id             = V4L2_CID_VFLIP,
>> -            .type           = V4L2_CTRL_TYPE_BOOLEAN,
>> -            .name           = "Flip Vertically",
>> -            .minimum        = 0,
>> -            .maximum        = 1,
>> -            .step           = 1,
>> -            .default_value  = 0,
>> -    }, {
>> -            .id             = V4L2_CID_HFLIP,
>> -            .type           = V4L2_CTRL_TYPE_BOOLEAN,
>> -            .name           = "Flip Horizontally",
>> -            .minimum        = 0,
>> -            .maximum        = 1,
>> -            .step           = 1,
>> -            .default_value  = 0,
>> -    }, {
>> -            .id             = V4L2_CID_GAIN,
>> -            .type           = V4L2_CTRL_TYPE_INTEGER,
>> -            .name           = "Gain",
>> -            .minimum        = 0,
>> -            .maximum        = 127,
>> -            .step           = 1,
>> -            .default_value  = 64,
>> -            .flags          = V4L2_CTRL_FLAG_SLIDER,
>> -    }, {
>> -            .id             = V4L2_CID_EXPOSURE,
>> -            .type           = V4L2_CTRL_TYPE_INTEGER,
>> -            .name           = "Exposure",
>> -            .minimum        = 1,
>> -            .maximum        = 255,
>> -            .step           = 1,
>> -            .default_value  = 255,
>> -            .flags          = V4L2_CTRL_FLAG_SLIDER,
>> -    }, {
>> -            .id             = V4L2_CID_EXPOSURE_AUTO,
>> -            .type           = V4L2_CTRL_TYPE_BOOLEAN,
>> -            .name           = "Automatic Exposure",
>> -            .minimum        = 0,
>> -            .maximum        = 1,
>> -            .step           = 1,
>> -            .default_value  = 1,
>> -    }
>> -};
>>
>> -static int mt9t031_video_probe(struct soc_camera_device *);
>> -static void mt9t031_video_remove(struct soc_camera_device *);
>> -static int mt9t031_get_control(struct soc_camera_device *, struct
>v4l2_control *);
>> -static int mt9t031_set_control(struct soc_camera_device *, struct
>v4l2_control *);
>> -
>> -static struct soc_camera_ops mt9t031_ops = {
>> -    .owner                  = THIS_MODULE,
>> -    .probe                  = mt9t031_video_probe,
>> -    .remove                 = mt9t031_video_remove,
>> -    .init                   = mt9t031_init,
>> -    .release                = mt9t031_release,
>> -    .start_capture          = mt9t031_start_capture,
>> -    .stop_capture           = mt9t031_stop_capture,
>> -    .set_crop               = mt9t031_set_crop,
>> -    .set_fmt                = mt9t031_set_fmt,
>> -    .try_fmt                = mt9t031_try_fmt,
>> -    .set_bus_param          = mt9t031_set_bus_param,
>> -    .query_bus_param        = mt9t031_query_bus_param,
>> -    .controls               = mt9t031_controls,
>> -    .num_controls           = ARRAY_SIZE(mt9t031_controls),
>> -    .get_control            = mt9t031_get_control,
>> -    .set_control            = mt9t031_set_control,
>> -    .get_chip_id            = mt9t031_get_chip_id,
>> +static int mt9t031_get_control(struct v4l2_subdev *, struct v4l2_control
>*);
>> +static int mt9t031_set_control(struct v4l2_subdev *, struct v4l2_control
>*);
>> +static int mt9t031_queryctrl(struct v4l2_subdev *, struct v4l2_queryctrl
>*);
>> +
>> +static const struct v4l2_subdev_core_ops mt9t031_core_ops = {
>> +    .g_chip_ident = mt9t031_get_chip_id,
>> +    .init = mt9t031_init,
>> +    .queryctrl = mt9t031_queryctrl,
>> +    .g_ctrl = mt9t031_get_control,
>> +    .s_ctrl = mt9t031_set_control,
>>  #ifdef CONFIG_VIDEO_ADV_DEBUG
>> -    .get_register           = mt9t031_get_register,
>> -    .set_register           = mt9t031_set_register,
>> +    .get_register = mt9t031_get_register,
>> +    .set_register = mt9t031_set_register,
>>  #endif
>>  };
>>
>> -static int mt9t031_get_control(struct soc_camera_device *icd, struct
>v4l2_control *ctrl)
>> +static const struct v4l2_subdev_video_ops mt9t031_video_ops = {
>> +    .s_fmt = mt9t031_set_fmt,
>> +    .try_fmt = mt9t031_try_fmt,
>> +    .s_stream = mt9t031_s_stream,
>> +};
>> +
>> +static const struct v4l2_subdev_ops mt9t031_ops = {
>> +    .core = &mt9t031_core_ops,
>> +    .video = &mt9t031_video_ops,
>> +};
>> +
>> +static int mt9t031_queryctrl(struct v4l2_subdev *sd,
>> +                        struct v4l2_queryctrl *qctrl)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> +    const struct v4l2_queryctrl *temp_qctrl;
>> +
>> +    temp_qctrl = mt9t031_find_qctrl(qctrl->id);
>> +    if (!temp_qctrl) {
>> +            v4l2_err(sd, "control id %d not supported", qctrl->id);
>> +            return -EINVAL;
>> +    }
>> +    memcpy(qctrl, temp_qctrl, sizeof(*qctrl));
>> +    return 0;
>> +}
>> +
>> +static int mt9t031_get_control(struct v4l2_subdev *sd,
>> +                           struct v4l2_control *ctrl)
>> +{
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>>      int data;
>>
>>      switch (ctrl->id) {
>> @@ -556,17 +556,22 @@ static int mt9t031_get_control(struct
>soc_camera_device *icd, struct v4l2_contro
>>      return 0;
>>  }
>>
>> -static int mt9t031_set_control(struct soc_camera_device *icd, struct
>v4l2_control *ctrl)
>> +static int mt9t031_set_control(struct v4l2_subdev *sd,
>> +                           struct v4l2_control *ctrl)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> -    const struct v4l2_queryctrl *qctrl;
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>> +    const struct v4l2_queryctrl *qctrl = NULL;
>>      int data;
>> +    struct i2c_client *client = v4l2_get_subdevdata(sd);
>>
>> -    qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id);
>> +    if (NULL == ctrl)
>> +            return -EINVAL;
>>
>> -    if (!qctrl)
>> +    qctrl = mt9t031_find_qctrl(ctrl->id);
>> +    if (!qctrl) {
>> +            v4l2_err(sd, "control id %d not supported", ctrl->id);
>>              return -EINVAL;
>> +    }
>>
>>      switch (ctrl->id) {
>>      case V4L2_CID_VFLIP:
>> @@ -594,7 +599,7 @@ static int mt9t031_set_control(struct
>soc_camera_device *icd, struct v4l2_contro
>>                      unsigned long range = qctrl->default_value - qctrl-
>>minimum;
>>                      data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) /
>range;
>>
>> -                    dev_dbg(&icd->dev, "Setting gain %d\n", data);
>> +                    v4l2_dbg(1, debug, sd, "Setting gain %d\n", data);
>>                      data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
>>                      if (data < 0)
>>                              return -EIO;
>> @@ -606,40 +611,51 @@ static int mt9t031_set_control(struct
>soc_camera_device *icd, struct v4l2_contro
>>                      unsigned long gain = ((ctrl->value - qctrl->default_value
>- 1) *
>>                                             1015 + range / 2) / range + 9;
>>
>> -                    if (gain <= 32)         /* calculated gain 9..32 -> 9..32
>*/
>> +                    if (gain <= 32)
>> +                            /* calculated gain 9..32 -> 9..32 */
>>                              data = gain;
>> -                    else if (gain <= 64)    /* calculated gain 33..64 ->
>0x51..0x60 */
>> +                    else if (gain <= 64)
>> +                            /* calculated gain 33..64 -> 0x51..0x60 */
>>                              data = ((gain - 32) * 16 + 16) / 32 + 80;
>>                      else
>> -                            /* calculated gain 65..1024 -> (1..120) << 8 + 0x60
>*/
>> +                            /*
>> +                             * calculated gain 65..1024 -> (1..120) << 8 +
>> +                             * 0x60
>> +                             */
>>                              data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
>>
>> -                    dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
>> -                            reg_read(client, MT9T031_GLOBAL_GAIN), data);
>> +                    v4l2_dbg(1, debug, sd, "Setting gain from 0x%x to"
>> +                             "0x%x\n",
>> +                             reg_read(client, MT9T031_GLOBAL_GAIN), data);
>> +
>>                      data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
>>                      if (data < 0)
>>                              return -EIO;
>>              }
>>
>>              /* Success */
>> -            icd->gain = ctrl->value;
>> +            mt9t031->gain = ctrl->value;
>>              break;
>>      case V4L2_CID_EXPOSURE:
>>              /* mt9t031 has maximum == default */
>> -            if (ctrl->value > qctrl->maximum || ctrl->value < qctrl-
>>minimum)
>> +            if (ctrl->value > qctrl->maximum ||
>> +                ctrl->value < qctrl->minimum)
>>                      return -EINVAL;
>>              else {
>> -                    const unsigned long range = qctrl->maximum - qctrl-
>>minimum;
>> -                    const u32 shutter = ((ctrl->value - qctrl->minimum) *
>1048 +
>> -                                         range / 2) / range + 1;
>> +                    const unsigned long range =
>> +                            qctrl->maximum - qctrl->minimum;
>> +                    const u32 shutter =
>> +                            ((ctrl->value - qctrl->minimum) * 1048 +
>> +                                    range / 2) / range + 1;
>>                      u32 old;
>>
>> -                    get_shutter(client, &old);
>> -                    dev_dbg(&icd->dev, "Setting shutter width from %u
>to %u\n",
>> +                    get_shutter(sd, &old);
>> +                    v4l2_dbg(1, debug, sd,
>> +                            "Setting shutter width from %u to %u\n",
>>                              old, shutter);
>> -                    if (set_shutter(client, shutter) < 0)
>> +                    if (set_shutter(sd, shutter) < 0)
>>                              return -EIO;
>> -                    icd->exposure = ctrl->value;
>> +                    mt9t031->exposure = ctrl->value;
>>                      mt9t031->autoexposure = 0;
>>              }
>>              break;
>> @@ -647,13 +663,15 @@ static int mt9t031_set_control(struct
>soc_camera_device *icd, struct v4l2_contro
>>              if (ctrl->value) {
>>                      const u16 vblank = MT9T031_VERTICAL_BLANK;
>>                      const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
>> -                    if (set_shutter(client, icd->height +
>> -                                    icd->y_skip_top + vblank) < 0)
>> +                    if (set_shutter(sd, mt9t031->height +
>> +                                    mt9t031->y_skip_top + vblank) < 0)
>>                              return -EIO;
>> -                    qctrl = soc_camera_find_qctrl(icd->ops,
>V4L2_CID_EXPOSURE);
>> -                    icd->exposure = (shutter_max / 2 + (icd->height +
>> -                                     icd->y_skip_top + vblank - 1) *
>> -                                     (qctrl->maximum - qctrl->minimum)) /
>> +
>> +                    qctrl = mt9t031_find_qctrl(V4L2_CID_EXPOSURE);
>> +                    mt9t031->exposure =
>> +                            (shutter_max / 2 + (mt9t031->height +
>> +                            mt9t031->y_skip_top + vblank - 1) *
>> +                            (qctrl->maximum - qctrl->minimum)) /
>>                              shutter_max + qctrl->minimum;
>>                      mt9t031->autoexposure = 1;
>>              } else
>> @@ -665,130 +683,102 @@ static int mt9t031_set_control(struct
>soc_camera_device *icd, struct v4l2_contro
>>
>>  /* 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 mt9t031_video_probe(struct soc_camera_device *icd)
>> +static int mt9t031_detect(struct i2c_client *client, int *model)
>>  {
>> -    struct i2c_client *client = to_i2c_client(icd->control);
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>>      s32 data;
>> -    int ret;
>> -
>> -    /* We must have a parent by now. And it cannot be a wrong one.
>> -     * So this entire test is completely redundant. */
>> -    if (!icd->dev.parent ||
>> -        to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
>> -            return -ENODEV;
>>
>>      /* Enable the chip */
>>      data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
>> -    dev_dbg(&icd->dev, "write: %d\n", data);
>> +    dev_dbg(&client->dev, "write: %d\n", data);
>>
>>      /* Read out the chip version register */
>>      data = reg_read(client, MT9T031_CHIP_VERSION);
>>
>>      switch (data) {
>>      case 0x1621:
>> -            mt9t031->model = V4L2_IDENT_MT9T031;
>> -            icd->formats = mt9t031_colour_formats;
>> -            icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
>> +            *model = V4L2_IDENT_MT9T031;
>>              break;
>>      default:
>> -            ret = -ENODEV;
>> -            dev_err(&icd->dev,
>> +            dev_err(&client->dev,
>>                      "No MT9T031 chip detected, register read %x\n", data);
>> -            goto ei2c;
>> +            return -ENODEV;
>>      }
>>
>> -    dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data);
>> -
>> -    /* Now that we know the model, we can start video */
>> -    ret = soc_camera_video_start(icd);
>> -    if (ret)
>> -            goto evstart;
>> -
>> +    dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
>>      return 0;
>> -
>> -evstart:
>> -ei2c:
>> -    return ret;
>> -}
>> -
>> -static void mt9t031_video_remove(struct soc_camera_device *icd)
>> -{
>> -    struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
>> -
>> -    dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9t031->client-
>>addr,
>> -            icd->dev.parent, icd->vdev);
>> -    soc_camera_video_stop(icd);
>>  }
>>
>>  static int mt9t031_probe(struct i2c_client *client,
>>                       const struct i2c_device_id *did)
>>  {
>>      struct mt9t031 *mt9t031;
>> -    struct soc_camera_device *icd;
>> -    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
>> -    struct soc_camera_link *icl = client->dev.platform_data;
>> +    struct v4l2_subdev *sd;
>> +    int pclk_pol;
>>      int ret;
>>
>> -    if (!icl) {
>> -            dev_err(&client->dev, "MT9T031 driver needs platform data\n");
>> -            return -EINVAL;
>> -    }
>> -
>> -    if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
>> -            dev_warn(&adapter->dev,
>> +    if (!i2c_check_functionality(client->adapter,
>> +                                 I2C_FUNC_SMBUS_WORD_DATA)) {
>> +            dev_warn(&client->dev,
>>                       "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
>>              return -EIO;
>>      }
>>
>> +    if (!client->dev.platform_data) {
>> +            dev_err(&client->dev, "No platform data!!\n");
>> +            return -ENODEV;
>> +    }
>> +
>> +    pclk_pol = (int)client->dev.platform_data;
>> +
>>      mt9t031 = kzalloc(sizeof(struct mt9t031), GFP_KERNEL);
>>      if (!mt9t031)
>>              return -ENOMEM;
>>
>> -    mt9t031->client = client;
>> -    i2c_set_clientdata(client, mt9t031);
>> -
>> -    /* Second stage probe - when a capture adapter is there */
>> -    icd = &mt9t031->icd;
>> -    icd->ops        = &mt9t031_ops;
>> -    icd->control    = &client->dev;
>> -    icd->x_min      = MT9T031_COLUMN_SKIP;
>> -    icd->y_min      = MT9T031_ROW_SKIP;
>> -    icd->x_current  = icd->x_min;
>> -    icd->y_current  = icd->y_min;
>> -    icd->width_min  = MT9T031_MIN_WIDTH;
>> -    icd->width_max  = MT9T031_MAX_WIDTH;
>> -    icd->height_min = MT9T031_MIN_HEIGHT;
>> -    icd->height_max = MT9T031_MAX_HEIGHT;
>> -    icd->y_skip_top = 0;
>> -    icd->iface      = icl->bus_id;
>> -    /* Simulated autoexposure. If enabled, we calculate shutter width
>> -     * ourselves in the driver based on vertical blanking and frame width
>*/
>> +    ret = mt9t031_detect(client, &mt9t031->model);
>> +    if (ret)
>> +            goto clean;
>> +
>> +    mt9t031->x_min          = MT9T031_COLUMN_SKIP;
>> +    mt9t031->y_min          = MT9T031_ROW_SKIP;
>> +    mt9t031->width          = MT9T031_DEFAULT_WIDTH;
>> +    mt9t031->height         = MT9T031_DEFAULT_WIDTH;
>> +    mt9t031->x_current      = mt9t031->x_min;
>> +    mt9t031->y_current      = mt9t031->y_min;
>> +    mt9t031->width_min      = MT9T031_MIN_WIDTH;
>> +    mt9t031->width_max      = MT9T031_MAX_WIDTH;
>> +    mt9t031->height_min     = MT9T031_MIN_HEIGHT;
>> +    mt9t031->height_max     = MT9T031_MAX_HEIGHT;
>> +    mt9t031->y_skip_top     = 0;
>>      mt9t031->autoexposure = 1;
>> -
>>      mt9t031->xskip = 1;
>>      mt9t031->yskip = 1;
>>
>> -    ret = soc_camera_device_register(icd);
>> -    if (ret)
>> -            goto eisdr;
>> +    /* Register with V4L2 layer as slave device */
>> +    sd = &mt9t031->sd;
>> +    v4l2_i2c_subdev_init(sd, client, &mt9t031_ops);
>> +    if (!pclk_pol)
>> +            reg_clear(v4l2_get_subdevdata(sd),
>> +                      MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
>> +    else
>> +            reg_set(v4l2_get_subdevdata(sd),
>> +                    MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
>>
>> +    v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
>>      return 0;
>>
>> -eisdr:
>> -    i2c_set_clientdata(client, NULL);
>> +clean:
>>      kfree(mt9t031);
>>      return ret;
>>  }
>>
>>  static int mt9t031_remove(struct i2c_client *client)
>>  {
>> -    struct mt9t031 *mt9t031 = i2c_get_clientdata(client);
>> +    struct v4l2_subdev *sd = i2c_get_clientdata(client);
>> +    struct mt9t031 *mt9t031 = to_mt9t031(sd);
>>
>> -    soc_camera_device_unregister(&mt9t031->icd);
>> -    i2c_set_clientdata(client, NULL);
>> -    kfree(mt9t031);
>> +    v4l2_device_unregister_subdev(sd);
>>
>> +    kfree(mt9t031);
>>      return 0;
>>  }
>>
>> --
>> 1.6.0.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-media" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
>---
>Guennadi Liakhovetski, Ph.D.
>Freelance Open-Source Software Developer
>http://www.open-technology.de/
>--
>To unsubscribe from this list: send the line "unsubscribe linux-media" in
>the body of a message to majordomo@xxxxxxxxxxxxxxx
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux