Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176852
b: refs/heads/master
c: 760697b
h: refs/heads/master
v: v3
  • Loading branch information
Guennadi Liakhovetski authored and Mauro Carvalho Chehab committed Dec 16, 2009
1 parent 2d1ef68 commit 1baee7d
Show file tree
Hide file tree
Showing 18 changed files with 1,384 additions and 981 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9a74251d8bee7a25fee89a0be3ccea73e01c1a05
refs/heads/master: 760697beca338599a65484389c7abbe54aedb664
3 changes: 2 additions & 1 deletion trunk/arch/sh/boards/mach-ap325rxa/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ static struct soc_camera_platform_info camera_info = {
.format_name = "UYVY",
.format_depth = 16,
.format = {
.pixelformat = V4L2_PIX_FMT_UYVY,
.code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
.field = V4L2_FIELD_NONE,
.width = 640,
.height = 480,
},
Expand Down
141 changes: 85 additions & 56 deletions trunk/drivers/media/video/mt9m001.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,41 +48,46 @@
#define MT9M001_COLUMN_SKIP 20
#define MT9M001_ROW_SKIP 12

static const struct soc_camera_data_format mt9m001_colour_formats[] = {
/* MT9M001 has only one fixed colorspace per pixelcode */
struct mt9m001_datafmt {
enum v4l2_mbus_pixelcode code;
enum v4l2_colorspace colorspace;
};

/* Find a data format by a pixel code in an array */
static const struct mt9m001_datafmt *mt9m001_find_datafmt(
enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt,
int n)
{
int i;
for (i = 0; i < n; i++)
if (fmt[i].code == code)
return fmt + i;

return NULL;
}

static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
/*
* Order important: first natively supported,
* second supported with a GPIO extender
*/
{
.name = "Bayer (sRGB) 10 bit",
.depth = 10,
.fourcc = V4L2_PIX_FMT_SBGGR16,
.colorspace = V4L2_COLORSPACE_SRGB,
}, {
.name = "Bayer (sRGB) 8 bit",
.depth = 8,
.fourcc = V4L2_PIX_FMT_SBGGR8,
.colorspace = V4L2_COLORSPACE_SRGB,
}
{V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
{V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
};

static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
/* Order important - see above */
{
.name = "Monochrome 10 bit",
.depth = 10,
.fourcc = V4L2_PIX_FMT_Y16,
}, {
.name = "Monochrome 8 bit",
.depth = 8,
.fourcc = V4L2_PIX_FMT_GREY,
},
{V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
{V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
};

struct mt9m001 {
struct v4l2_subdev subdev;
struct v4l2_rect rect; /* Sensor window */
__u32 fourcc;
const struct mt9m001_datafmt *fmt;
const struct mt9m001_datafmt *fmts;
int num_fmts;
int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
unsigned int gain;
unsigned int exposure;
Expand Down Expand Up @@ -209,8 +214,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
const u16 hblank = 9, vblank = 25;
unsigned int total_h;

if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
if (mt9m001->fmts == mt9m001_colour_fmts)
/*
* Bayer format - even number of rows for simplicity,
* but let the user play with the top row.
Expand Down Expand Up @@ -290,61 +294,72 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}

static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
static int mt9m001_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct v4l2_pix_format *pix = &f->fmt.pix;

pix->width = mt9m001->rect.width;
pix->height = mt9m001->rect.height;
pix->pixelformat = mt9m001->fourcc;
pix->field = V4L2_FIELD_NONE;
pix->colorspace = V4L2_COLORSPACE_SRGB;
mf->width = mt9m001->rect.width;
mf->height = mt9m001->rect.height;
mf->code = mt9m001->fmt->code;
mf->colorspace = mt9m001->fmt->colorspace;
mf->field = V4L2_FIELD_NONE;

return 0;
}

static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
static int mt9m001_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_crop a = {
.c = {
.left = mt9m001->rect.left,
.top = mt9m001->rect.top,
.width = pix->width,
.height = pix->height,
.width = mf->width,
.height = mf->height,
},
};
int ret;

/* No support for scaling so far, just crop. TODO: use skipping */
ret = mt9m001_s_crop(sd, &a);
if (!ret) {
pix->width = mt9m001->rect.width;
pix->height = mt9m001->rect.height;
mt9m001->fourcc = pix->pixelformat;
mf->width = mt9m001->rect.width;
mf->height = mt9m001->rect.height;
mt9m001->fmt = mt9m001_find_datafmt(mf->code,
mt9m001->fmts, mt9m001->num_fmts);
mf->colorspace = mt9m001->fmt->colorspace;
}

return ret;
}

static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
static int mt9m001_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct v4l2_pix_format *pix = &f->fmt.pix;
const struct mt9m001_datafmt *fmt;

v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
MT9M001_MAX_WIDTH, 1,
&pix->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
&mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);

if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
pix->height = ALIGN(pix->height - 1, 2);
if (mt9m001->fmts == mt9m001_colour_fmts)
mf->height = ALIGN(mf->height - 1, 2);

fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
mt9m001->num_fmts);
if (!fmt) {
fmt = mt9m001->fmt;
mf->code = fmt->code;
}

mf->colorspace = fmt->colorspace;

return 0;
}
Expand Down Expand Up @@ -608,19 +623,19 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
case 0x8411:
case 0x8421:
mt9m001->model = V4L2_IDENT_MT9M001C12ST;
icd->formats = mt9m001_colour_formats;
mt9m001->fmts = mt9m001_colour_fmts;
break;
case 0x8431:
mt9m001->model = V4L2_IDENT_MT9M001C12STM;
icd->formats = mt9m001_monochrome_formats;
mt9m001->fmts = mt9m001_monochrome_fmts;
break;
default:
dev_err(&client->dev,
"No MT9M001 chip detected, register read %x\n", data);
return -ENODEV;
}

icd->num_formats = 0;
mt9m001->num_fmts = 0;

/*
* This is a 10bit sensor, so by default we only allow 10bit.
Expand All @@ -633,14 +648,14 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
flags = SOCAM_DATAWIDTH_10;

if (flags & SOCAM_DATAWIDTH_10)
icd->num_formats++;
mt9m001->num_fmts++;
else
icd->formats++;
mt9m001->fmts++;

if (flags & SOCAM_DATAWIDTH_8)
icd->num_formats++;
mt9m001->num_fmts++;

mt9m001->fourcc = icd->formats->fourcc;
mt9m001->fmt = &mt9m001->fmts[0];

dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
data == 0x8431 ? "C12STM" : "C12ST");
Expand Down Expand Up @@ -686,14 +701,28 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
#endif
};

static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index,
enum v4l2_mbus_pixelcode *code)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);

if ((unsigned int)index >= mt9m001->num_fmts)
return -EINVAL;

*code = mt9m001->fmts[index].code;
return 0;
}

static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
.s_stream = mt9m001_s_stream,
.s_fmt = mt9m001_s_fmt,
.g_fmt = mt9m001_g_fmt,
.try_fmt = mt9m001_try_fmt,
.s_mbus_fmt = mt9m001_s_fmt,
.g_mbus_fmt = mt9m001_g_fmt,
.try_mbus_fmt = mt9m001_try_fmt,
.s_crop = mt9m001_s_crop,
.g_crop = mt9m001_g_crop,
.cropcap = mt9m001_cropcap,
.enum_mbus_fmt = mt9m001_enum_fmt,
};

static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
Expand Down
Loading

0 comments on commit 1baee7d

Please sign in to comment.