static int ak881x_s_stream(struct v4l2_subdev *sd, int enable) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); if (enable) { u8 dac; /* For colour-bar testing set bit 6 of AK881X_VIDEO_PROCESS1 */ /* Default: composite output */ if (ak881x->pdata->flags & AK881X_COMPONENT) dac = 3; else dac = 4; /* Turn on the DAC(s) */ reg_write(client, AK881X_DAC_MODE, dac); dev_dbg(&client->dev, "chip status 0x%x\n", reg_read(client, AK881X_STATUS)); } else { /* ...and clear bit 6 of AK881X_VIDEO_PROCESS1 here */ reg_write(client, AK881X_DAC_MODE, 0); dev_dbg(&client->dev, "chip status 0x%x\n", reg_read(client, AK881X_STATUS)); } return 0; }
static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); u8 vp1; if (std == V4L2_STD_NTSC_443) { vp1 = 3; ak881x->lines = 480; } else if (std == V4L2_STD_PAL_M) { vp1 = 5; ak881x->lines = 480; } else if (std == V4L2_STD_PAL_60) { vp1 = 7; ak881x->lines = 480; } else if (std && !(std & ~V4L2_STD_PAL)) { vp1 = 0xf; ak881x->lines = 576; } else if (std && !(std & ~V4L2_STD_NTSC)) { vp1 = 0; ak881x->lines = 480; } else { /* No SECAM or PAL_N/Nc supported */ return -EINVAL; } reg_set(client, AK881X_VIDEO_PROCESS1, vp1, 0xf); return 0; }
static int ak881x_remove(struct i2c_client *client) { struct ak881x *ak881x = to_ak881x(client); v4l2_device_unregister_subdev(&ak881x->subdev); return 0; }
static int ak881x_try_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); v4l_bound_align_image(&mf->width, 0, 720, 2, &mf->height, 0, ak881x->lines, 1, 0); mf->field = V4L2_FIELD_INTERLACED; mf->code = V4L2_MBUS_FMT_YUYV8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; }
static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); a->bounds.left = 0; a->bounds.top = 0; a->bounds.width = 720; a->bounds.height = ak881x->lines; a->defrect = a->bounds; a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; a->pixelaspect.numerator = 1; a->pixelaspect.denominator = 1; return 0; }
static int ak881x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; if (id->match.addr != client->addr) return -ENODEV; id->ident = ak881x->id; id->revision = ak881x->revision; return 0; }
static int ak881x_fill_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); if (format->pad) return -EINVAL; v4l_bound_align_image(&mf->width, 0, 720, 2, &mf->height, 0, ak881x->lines, 1, 0); mf->field = V4L2_FIELD_INTERLACED; mf->code = MEDIA_BUS_FMT_YUYV8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; }