Beispiel #1
0
static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
                 unsigned char value)
{
    unsigned char buffer[2];
    int rc;

    buffer[0] = addr;
    buffer[1] = value;
    tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
    if (2 != (rc = i2c_master_send(c, buffer, 2)))
        tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
}
Beispiel #2
0
static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
{
    struct tvp5150 *decoder = i2c_get_clientdata(c);
    int fmt=0;

    decoder->norm=std;

    /* First tests should be against specific std */

    if (std == V4L2_STD_ALL) {
        fmt=0;    /* Autodetect mode */
    } else if (std & V4L2_STD_NTSC_443) {
        fmt=0xa;
    } else if (std & V4L2_STD_PAL_M) {
        fmt=0x6;
    } else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) {
        fmt=0x8;
    } else {
        /* Then, test against generic ones */
        if (std & V4L2_STD_NTSC) {
            fmt=0x2;
        } else if (std & V4L2_STD_PAL) {
            fmt=0x4;
        } else if (std & V4L2_STD_SECAM) {
            fmt=0xc;
        }
    }

    tvp5150_dbg(1,"Set video std register to %d.\n",fmt);
    tvp5150_write(c, TVP5150_VIDEO_STD, fmt);

    return 0;
}
Beispiel #3
0
static inline void tvp5150_selmux(struct i2c_client *c)
{
	int opmode=0;
	struct tvp5150 *decoder = i2c_get_clientdata(c);
	int input = 0;

	if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
		input = 8;

	switch (decoder->route.input) {
	case TVP5150_COMPOSITE1:
		input |= 2;
		/* fall through */
	case TVP5150_COMPOSITE0:
		opmode=0x30;		/* TV Mode */
		break;
	case TVP5150_SVIDEO:
	default:
		input |= 1;
		opmode=0;		/* Auto Mode */
		break;
	}

	tvp5150_dbg( 1, "Selecting video route: route input=%i, output=%i "
			"=> tvp5150 input=%i, opmode=%i\n",
			decoder->route.input,decoder->route.output,
			input, opmode );

	tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode);
	tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
};
Beispiel #4
0
static int tvp5150_read(struct i2c_client *c, unsigned char addr)
{
    unsigned char buffer[1];
    int rc;

    buffer[0] = addr;
    if (1 != (rc = i2c_master_send(c, buffer, 1)))
        tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc);

    msleep(10);

    if (1 != (rc = i2c_master_recv(c, buffer, 1)))
        tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc);

    tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);

    return (buffer[0]);
}
Beispiel #5
0
static int tvp5150_detach_client(struct i2c_client *c)
{
    struct tvp5150 *decoder = i2c_get_clientdata(c);
    int err;

    tvp5150_dbg(1,
        "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
        c->addr << 1);

    err = i2c_detach_client(c);
    if (err) {
        return err;
    }

    kfree(decoder);
    kfree(c);

    return 0;
}
Beispiel #6
0
static inline void tvp5150_selmux(struct i2c_client *c)
{
    int opmode=0;
    struct tvp5150 *decoder = i2c_get_clientdata(c);
    int input = 0;
    unsigned char val;

    if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
        input = 8;

    switch (decoder->route.input) {
    case TVP5150_COMPOSITE1:
        input |= 2;
        /* fall through */
    case TVP5150_COMPOSITE0:
        opmode=0x30;        /* TV Mode */
        break;
    case TVP5150_SVIDEO:
    default:
        input |= 1;
        opmode=0;        /* Auto Mode */
        break;
    }

    tvp5150_dbg( 1, "Selecting video route: route input=%i, output=%i "
            "=> tvp5150 input=%i, opmode=%i\n",
            decoder->route.input,decoder->route.output,
            input, opmode );

    tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode);
    tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);

    /* Svideo should enable YCrCb output and disable GPCL output
     * For Composite and TV, it should be the reverse
     */
    val = tvp5150_read(c, TVP5150_MISC_CTL);
    if (decoder->route.input == TVP5150_SVIDEO)
        val = (val & ~0x40) | 0x10;
    else
        val = (val & ~0x10) | 0x40;
    tvp5150_write(c, TVP5150_MISC_CTL, val);
};
Beispiel #7
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;
}