Exemple #1
0
/****************************************************************************
            I2C Command
 ****************************************************************************/
static int tvp5150_command(struct i2c_client *c,
               unsigned int cmd, void *arg)
{
    struct tvp5150 *decoder = i2c_get_clientdata(c);

    switch (cmd) {

    case 0:
    case VIDIOC_INT_RESET:
        tvp5150_reset(c);
        break;
    case VIDIOC_INT_G_VIDEO_ROUTING:
    {
        struct v4l2_routing *route = arg;

        *route = decoder->route;
        break;
    }
    case VIDIOC_INT_S_VIDEO_ROUTING:
    {
        struct v4l2_routing *route = arg;

        decoder->route = *route;
        tvp5150_selmux(c);
        break;
    }
    case VIDIOC_S_STD:
        if (decoder->norm == *(v4l2_std_id *)arg)
            break;
        return tvp5150_set_std(c, *(v4l2_std_id *)arg);
    case VIDIOC_G_STD:
        *(v4l2_std_id *)arg = decoder->norm;
        break;

    case VIDIOC_G_SLICED_VBI_CAP:
    {
        struct v4l2_sliced_vbi_cap *cap = arg;
        tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n");

        tvp5150_vbi_get_cap(vbi_ram_default, cap);
        break;
    }
    case VIDIOC_S_FMT:
    {
        struct v4l2_format *fmt;
        struct v4l2_sliced_vbi_format *svbi;
        int i;

        fmt = arg;
        if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
            return -EINVAL;
        svbi = &fmt->fmt.sliced;
        if (svbi->service_set != 0) {
            for (i = 0; i <= 23; i++) {
                svbi->service_lines[1][i] = 0;

                svbi->service_lines[0][i]=tvp5150_set_vbi(c,
                     vbi_ram_default,
                     svbi->service_lines[0][i],0xf0,i,3);
            }
            /* Enables FIFO */
            tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1);
        } else {
            /* Disables FIFO*/
            tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0);

            /* Disable Full Field */
            tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0);

            /* Disable Line modes */
            for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++)
                tvp5150_write(c, i, 0xff);
        }
        break;
    }
    case VIDIOC_G_FMT:
    {
        struct v4l2_format *fmt;
        struct v4l2_sliced_vbi_format *svbi;

        int i, mask=0;

        fmt = arg;
        if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
            return -EINVAL;
        svbi = &fmt->fmt.sliced;
        memset(svbi, 0, sizeof(*svbi));

        for (i = 0; i <= 23; i++) {
            svbi->service_lines[0][i]=tvp5150_get_vbi(c,
                vbi_ram_default,i);
            mask|=svbi->service_lines[0][i];
        }
        svbi->service_set=mask;
        break;
    }

#ifdef CONFIG_VIDEO_ADV_DEBUG
    case VIDIOC_DBG_G_REGISTER:
    case VIDIOC_DBG_S_REGISTER:
    {
        struct v4l2_register *reg = arg;

        if (!v4l2_chip_match_i2c_client(c, reg->match_type, reg->match_chip))
            return -EINVAL;
        if (!capable(CAP_SYS_ADMIN))
            return -EPERM;
        if (cmd == VIDIOC_DBG_G_REGISTER)
            reg->val = tvp5150_read(c, reg->reg & 0xff);
        else
            tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
        break;
    }
#endif

    case VIDIOC_LOG_STATUS:
        dump_reg(c);
        break;

    case VIDIOC_G_TUNER:
        {
            struct v4l2_tuner *vt = arg;
            int status = tvp5150_read(c, 0x88);

            vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0;
            break;
        }
    case VIDIOC_QUERYCTRL:
        {
            struct v4l2_queryctrl *qc = arg;
            int i;

            tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n");

            for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
                if (qc->id && qc->id == tvp5150_qctrl[i].id) {
                    memcpy(qc, &(tvp5150_qctrl[i]),
                           sizeof(*qc));
                    return 0;
                }

            return -EINVAL;
        }
    case VIDIOC_G_CTRL:
        {
            struct v4l2_control *ctrl = arg;
            tvp5150_dbg(1, "VIDIOC_G_CTRL called\n");

            return tvp5150_get_ctrl(c, ctrl);
        }
    case VIDIOC_S_CTRL:
        {
            struct v4l2_control *ctrl = arg;
            u8 i, n;
            n = ARRAY_SIZE(tvp5150_qctrl);
            for (i = 0; i < n; i++)
                if (ctrl->id == tvp5150_qctrl[i].id) {
                    if (ctrl->value <
                        tvp5150_qctrl[i].minimum
                        || ctrl->value >
                        tvp5150_qctrl[i].maximum)
                        return -ERANGE;
                    tvp5150_dbg(1,
                        "VIDIOC_S_CTRL: id=%d, value=%d\n",
                        ctrl->id, ctrl->value);
                    return tvp5150_set_ctrl(c, ctrl);
                }
            return -EINVAL;
        }

    default:
        return -EINVAL;
    }

    return 0;
}
/****************************************************************************
			I2C Command
 ****************************************************************************/
static int tvp5150_command(struct i2c_client *client,
			   unsigned int cmd, void *arg)
{
	struct tvp5150 *decoder = i2c_get_clientdata(client);

	switch (cmd) {

	case 0:
	case DECODER_INIT:
		tvp5150_reset(client);
		break;

	case DECODER_DUMP:
		dump_reg(client);
		break;

	case DECODER_GET_CAPABILITIES:
		{
			struct video_decoder_capability *cap = arg;

			cap->flags = VIDEO_DECODER_PAL |
			    VIDEO_DECODER_NTSC |
			    VIDEO_DECODER_SECAM |
			    VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
			cap->inputs = 3;
			cap->outputs = 1;
			break;
		}
	case DECODER_GET_STATUS:
		{
			break;
		}

	case DECODER_SET_GPIO:
		break;

	case DECODER_SET_VBI_BYPASS:
		break;

	case DECODER_SET_NORM:
		{
			int *iarg = arg;

			switch (*iarg) {

			case VIDEO_MODE_NTSC:
				break;

			case VIDEO_MODE_PAL:
				break;

			case VIDEO_MODE_SECAM:
				break;

			case VIDEO_MODE_AUTO:
				break;

			default:
				return -EINVAL;

			}
			decoder->norm = *iarg;
			break;
		}
	case DECODER_SET_INPUT:
		{
			int *iarg = arg;
			if (*iarg < 0 || *iarg > 3) {
				return -EINVAL;
			}

			decoder->input = *iarg;
			tvp5150_selmux(client, decoder->input);

			break;
		}
	case DECODER_SET_OUTPUT:
		{
			int *iarg = arg;

			/* not much choice of outputs */
			if (*iarg != 0) {
				return -EINVAL;
			}
			break;
		}
	case DECODER_ENABLE_OUTPUT:
		{
			int *iarg = arg;

			decoder->enable = (*iarg != 0);

			tvp5150_selmux(client, decoder->input);

			break;
		}
	case VIDIOC_QUERYCTRL:
		{
			struct v4l2_queryctrl *qc = arg;
			u8 i, n;

			dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");

			n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
			for (i = 0; i < n; i++)
				if (qc->id && qc->id == tvp5150_qctrl[i].id) {
					memcpy(qc, &(tvp5150_qctrl[i]),
					       sizeof(*qc));
					return 0;
				}

			return -EINVAL;
		}
	case VIDIOC_G_CTRL:
		{
			struct v4l2_control *ctrl = arg;
			dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");

			return tvp5150_get_ctrl(client, ctrl);
		}
	case VIDIOC_S_CTRL_OLD:	/* ??? */
	case VIDIOC_S_CTRL:
		{
			struct v4l2_control *ctrl = arg;
			u8 i, n;
			dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
			n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
			for (i = 0; i < n; i++)
				if (ctrl->id == tvp5150_qctrl[i].id) {
					if (ctrl->value <
					    tvp5150_qctrl[i].minimum
					    || ctrl->value >
					    tvp5150_qctrl[i].maximum)
						return -ERANGE;
					dprintk(1,
						KERN_DEBUG
						"VIDIOC_S_CTRL: id=%d, value=%d",
						ctrl->id, ctrl->value);
					return tvp5150_set_ctrl(client, ctrl);
				}
			return -EINVAL;
		}

	case DECODER_SET_PICTURE:
		{
			struct video_picture *pic = arg;
			if (decoder->bright != pic->brightness) {
				/* We want 0 to 255 we get 0-65535 */
				decoder->bright = pic->brightness;
				tvp5150_write(client, TVP5150_BRIGHT_CTL,
					      decoder->bright >> 8);
			}
			if (decoder->contrast != pic->contrast) {
				/* We want 0 to 255 we get 0-65535 */
				decoder->contrast = pic->contrast;
				tvp5150_write(client, TVP5150_CONTRAST_CTL,
					      decoder->contrast >> 8);
			}
			if (decoder->sat != pic->colour) {
				/* We want 0 to 255 we get 0-65535 */
				decoder->sat = pic->colour;
				tvp5150_write(client, TVP5150_SATURATION_CTL,
					      decoder->contrast >> 8);
			}