Exemple #1
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);
};
static inline void tvp5150_reset(struct i2c_client *c)
{
	struct tvp5150 *decoder = i2c_get_clientdata(c);

	tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);

	/* Automatic offset and AGC enabled */
	tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);

	/* Normal Operation */
//      tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);

	/* Activate YCrCb output 0x9 or 0xd ? */
	tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);

	/* Activates video std autodetection for all standards */
	tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);

	/* Default format: 0x47, 4:2:2: 0x40 */
	tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);

	tvp5150_selmux(c, decoder->input);

	tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
	tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);

	tvp5150_write(c, 0x27, 0x20);	/* ?????????? */

	tvp5150_write(c, TVP5150_VIDEO_STD, 0x0);	/* Auto switch */

	tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
	tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
	tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
	tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
};
Exemple #3
0
/* Set vbi processing
 * type - one of tvp5150_vbi_types
 * line - line to gather data
 * fields: bit 0 field1, bit 1, field2
 * flags (default=0xf0) is a bitmask, were set means:
 *    bit 7: enable filtering null bytes on CC
 *    bit 6: send data also to FIFO
 *    bit 5: don't allow data with errors on FIFO
 *    bit 4: enable ECC when possible
 * pix_align = pix alignment:
 *    LSB = field1
 *    MSB = field2
 */
static int tvp5150_set_vbi(struct i2c_client *c,
            const struct i2c_vbi_ram_value *regs,
            unsigned int type,u8 flags, int line,
            const int fields)
{
    struct tvp5150 *decoder = i2c_get_clientdata(c);
    v4l2_std_id std=decoder->norm;
    u8 reg;
    int pos=0;

    if (std == V4L2_STD_ALL) {
        tvp5150_err("VBI can't be configured without knowing number of lines\n");
        return 0;
    } else if (std & V4L2_STD_625_50) {
        /* Don't follow NTSC Line number convension */
        line += 3;
    }

    if (line<6||line>27)
        return 0;

    while (regs->reg != (u16)-1 ) {
        if ((type & regs->type.vbi_type) &&
            (line>=regs->type.ini_line) &&
            (line<=regs->type.end_line)) {
            type=regs->type.vbi_type;
            break;
        }

        regs++;
        pos++;
    }
    if (regs->reg == (u16)-1)
        return 0;

    type=pos | (flags & 0xf0);
    reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;

    if (fields&1) {
        tvp5150_write(c, reg, type);
    }

    if (fields&2) {
        tvp5150_write(c, reg+1, type);
    }

    return type;
}
Exemple #4
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;
}
Exemple #5
0
static int tvp5150_write_inittab(struct i2c_client *c,
                const struct i2c_reg_value *regs)
{
    while (regs->reg != 0xff) {
        tvp5150_write(c, regs->reg, regs->value);
        regs++;
    }
    return 0;
}
Exemple #6
0
static inline void tvp5150_reset(struct i2c_client *c)
{
    u8 msb_id, lsb_id, msb_rom, lsb_rom;
    struct tvp5150 *decoder = i2c_get_clientdata(c);

    msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID);
    lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID);
    msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER);
    lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER);

    if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */
        tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id);

        /* ITU-T BT.656.4 timing */
        tvp5150_write(c,TVP5150_REV_SELECT,0);
    } else {
        if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */
            tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
        } else {
            tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id);
            tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom);
        }
    }

    /* Initializes TVP5150 to its default values */
    tvp5150_write_inittab(c, tvp5150_init_default);

    /* Initializes VDP registers */
    tvp5150_vdp_init(c, vbi_ram_default);

    /* Selects decoder input */
    tvp5150_selmux(c);

    /* Initializes TVP5150 to stream enabled values */
    tvp5150_write_inittab(c, tvp5150_init_enable);

    /* Initialize image preferences */
    tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright);
    tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast);
    tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast);
    tvp5150_write(c, TVP5150_HUE_CTL, decoder->hue);

    tvp5150_set_std(c, decoder->norm);
};
static inline void tvp5150_selmux(struct i2c_client *c,
				  enum tvp5150_input input)
{
	struct tvp5150 *decoder = i2c_get_clientdata(c);

	if (!decoder->enable)
		input |= TVP5150_BLACK_SCREEN;

	tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
};
Exemple #8
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);
};
Exemple #9
0
static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
{
/*    struct tvp5150 *decoder = i2c_get_clientdata(c); */

    switch (ctrl->id) {
    case V4L2_CID_BRIGHTNESS:
        tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value);
        return 0;
    case V4L2_CID_CONTRAST:
        tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value);
        return 0;
    case V4L2_CID_SATURATION:
        tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value);
        return 0;
    case V4L2_CID_HUE:
        tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
        return 0;
    }
    return -EINVAL;
}
Exemple #10
0
static int tvp5150_vdp_init(struct i2c_client *c,
                const struct i2c_vbi_ram_value *regs)
{
    unsigned int i;

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

    /* Before programming, Line mode should be at 0xff */
    for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++)
        tvp5150_write(c, i, 0xff);

    /* Load Ram Table */
    while (regs->reg != (u16)-1 ) {
        tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8);
        tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg);

        for (i=0;i<16;i++)
            tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]);

        regs++;
    }
    return 0;
}
Exemple #11
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;
}