Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * drivers/media/i2c/tvp514x.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * TI TVP5146/47 decoder driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (C) 2008 Texas Instruments Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Author: Vaibhav Hiremath <hvaibhav@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *     Sivaraj R <sivaraj@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *     Brijesh R Jadav <brijesh.j@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *     Hardik Shah <hardik.shah@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *     Manjunath Hadli <mrh@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *     Karicheri Muralidharan <m-karicheri2@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *     Prabhakar Lad <prabhakar.lad@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/v4l2-mediabus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <media/v4l2-async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <media/v4l2-mediabus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <media/v4l2-fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <media/i2c/tvp514x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <media/media-entity.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include "tvp514x_regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) /* Private macros for TVP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define I2C_RETRY_COUNT                 (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define LOCK_RETRY_COUNT                (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define LOCK_RETRY_DELAY                (200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /* Debug functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static bool debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) module_param(debug, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) MODULE_PARM_DESC(debug, "Debug level (0-1)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) MODULE_AUTHOR("Texas Instruments");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) MODULE_DESCRIPTION("TVP514X linux decoder driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) /* enum tvp514x_std - enum for supported standards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) enum tvp514x_std {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	STD_NTSC_MJ = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	STD_PAL_BDGHIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	STD_INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)  * struct tvp514x_std_info - Structure to store standard information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62)  * @width: Line width in pixels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63)  * @height:Number of active lines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  * @video_std: Value to write in REG_VIDEO_STD register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  * @standard: v4l2 standard structure information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) struct tvp514x_std_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	unsigned long width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	unsigned long height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	u8 video_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	struct v4l2_standard standard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static struct tvp514x_reg tvp514x_reg_list_default[0x40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * struct tvp514x_decoder - TVP5146/47 decoder object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * @sd: Subdevice Slave handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * @hdl: embedded &struct v4l2_ctrl_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * @tvp514x_regs: copy of hw's regs with preset values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  * @pdata: Board specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  * @ver: Chip version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * @streaming: TVP5146/47 decoder streaming - enabled or disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * @pix: Current pixel format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * @num_fmts: Number of formats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  * @fmt_list: Format list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  * @current_std: Current standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)  * @num_stds: Number of standards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)  * @std_list: Standards list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91)  * @input: Input routing at chip level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92)  * @output: Output routing at chip level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93)  * @pad: subdev media pad associated with the decoder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94)  * @format: media bus frame format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * @int_seq: driver's register init sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) struct tvp514x_decoder {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	struct v4l2_ctrl_handler hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	const struct tvp514x_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	int ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	int streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	struct v4l2_pix_format pix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	int num_fmts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	const struct v4l2_fmtdesc *fmt_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	enum tvp514x_std current_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	int num_stds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	const struct tvp514x_std_info *std_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	/* Input and Output Routing parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	u32 input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	u32 output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	/* mc related members */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	struct v4l2_mbus_framefmt format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	struct tvp514x_reg *int_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) /* TVP514x default register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) static struct tvp514x_reg tvp514x_reg_list_default[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	/* Composite selected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	{TOK_WRITE, REG_INPUT_SEL, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	/* Auto mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	{TOK_WRITE, REG_VIDEO_STD, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	{TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	{TOK_WRITE, REG_COLOR_KILLER, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	{TOK_WRITE, REG_LUMA_CONTROL1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	{TOK_WRITE, REG_LUMA_CONTROL2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	{TOK_WRITE, REG_LUMA_CONTROL3, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	{TOK_WRITE, REG_BRIGHTNESS, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	{TOK_WRITE, REG_CONTRAST, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	{TOK_WRITE, REG_SATURATION, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	{TOK_WRITE, REG_HUE, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	{TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	{TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	{TOK_SKIP, 0x0F, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	{TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	{TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	{TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	{TOK_SKIP, 0x13, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	{TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	{TOK_SKIP, 0x15, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	/* NTSC timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	{TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	{TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	{TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	{TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	/* NTSC timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	{TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	{TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	/* NTSC timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	{TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	{TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	{TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	{TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	/* NTSC timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	{TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	{TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	{TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	{TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	{TOK_SKIP, 0x26, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	{TOK_SKIP, 0x27, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	{TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	{TOK_SKIP, 0x29, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	{TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	{TOK_SKIP, 0x2B, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	{TOK_SKIP, REG_SCART_DELAY, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	{TOK_SKIP, REG_CTI_DELAY, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	{TOK_SKIP, REG_CTI_CONTROL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	{TOK_SKIP, 0x2F, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	{TOK_SKIP, 0x30, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	{TOK_SKIP, 0x31, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	/* HS, VS active high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	{TOK_WRITE, REG_SYNC_CONTROL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	/* 10-bit BT.656 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	{TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	/* Enable clk & data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	{TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	/* Enable AVID & FLD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	{TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	/* Enable VS & HS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	{TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	{TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	{TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	/* Clear status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	{TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	{TOK_TERM, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210)  * List of image formats supported by TVP5146/47 decoder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211)  * Currently we are using 8 bit mode only, but can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)  * extended to 10/20 bit mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	 .index		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	 .type		= V4L2_BUF_TYPE_VIDEO_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	 .flags		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	 .description	= "8-bit UYVY 4:2:2 Format",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	 .pixelformat	= V4L2_PIX_FMT_UYVY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)  * Supported standards -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  * Currently supports two standards only, need to add support for rest of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  * modes, like SECAM, etc...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) static const struct tvp514x_std_info tvp514x_std_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	/* Standard: STD_NTSC_MJ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	[STD_NTSC_MJ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	 .width = NTSC_NUM_ACTIVE_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	 .height = NTSC_NUM_ACTIVE_LINES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	 .video_std = VIDEO_STD_NTSC_MJ_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	 .standard = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		      .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		      .id = V4L2_STD_NTSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		      .name = "NTSC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		      .frameperiod = {1001, 30000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		      .framelines = 525
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	/* Standard: STD_PAL_BDGHIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	[STD_PAL_BDGHIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	 .width = PAL_NUM_ACTIVE_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	 .height = PAL_NUM_ACTIVE_LINES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	 .video_std = VIDEO_STD_PAL_BDGHIN_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	 .standard = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		      .index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		      .id = V4L2_STD_PAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		      .name = "PAL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		      .frameperiod = {1, 25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		      .framelines = 625
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	/* Standard: need to add for additional standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	return container_of(sd, struct tvp514x_decoder, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	return &container_of(ctrl->handler, struct tvp514x_decoder, hdl)->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273)  * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274)  * @sd: ptr to v4l2_subdev struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275)  * @reg: TVP5146/47 register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277)  * Returns value read if successful, or non-zero (-1) otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	int err, retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) read_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	err = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		if (retry <= I2C_RETRY_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 			v4l2_warn(sd, "Read: retry ... %d\n", retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 			retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			goto read_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300)  * dump_reg() - dump the register content of TVP5146/47.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301)  * @sd: ptr to v4l2_subdev struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302)  * @reg: TVP5146/47 register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) static void dump_reg(struct v4l2_subdev *sd, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	val = tvp514x_read_reg(sd, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	v4l2_info(sd, "Reg(0x%.2X): 0x%.2X\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)  * tvp514x_write_reg() - Write a value to a register in TVP5146/47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314)  * @sd: ptr to v4l2_subdev struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  * @reg: TVP5146/47 register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  * @val: value to be written to the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  * Write a value to a register in an TVP5146/47 decoder device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  * Returns zero if successful, or non-zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static int tvp514x_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	int err, retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) write_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	err = i2c_smbus_write_byte_data(client, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		if (retry <= I2C_RETRY_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			v4l2_warn(sd, "Write: retry ... %d\n", retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 			retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			goto write_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342)  * tvp514x_write_regs() : Initializes a list of TVP5146/47 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343)  * @sd: ptr to v4l2_subdev struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344)  * @reglist: list of TVP5146/47 registers and values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346)  * Initializes a list of TVP5146/47 registers:-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347)  *		if token is TOK_TERM, then entire write operation terminates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)  *		if token is TOK_DELAY, then a delay of 'val' msec is introduced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349)  *		if token is TOK_SKIP, then the register write is skipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350)  *		if token is TOK_WRITE, then the register write is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351)  * Returns zero if successful, or non-zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) static int tvp514x_write_regs(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			      const struct tvp514x_reg reglist[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	const struct tvp514x_reg *next = reglist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	for (; next->token != TOK_TERM; next++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		if (next->token == TOK_DELAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 			msleep(next->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		if (next->token == TOK_SKIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		err = tvp514x_write_reg(sd, next->reg, (u8) next->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			v4l2_err(sd, "Write failed. Err[%d]\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378)  * tvp514x_query_current_std() : Query the current standard detected by TVP5146/47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379)  * @sd: ptr to v4l2_subdev struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  * Returns the current standard detected by TVP5146/47, STD_INVALID if there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  * standard detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) static enum tvp514x_std tvp514x_query_current_std(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	u8 std, std_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	std = tvp514x_read_reg(sd, REG_VIDEO_STD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		/* use the standard status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		std_status = tvp514x_read_reg(sd, REG_VIDEO_STD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		/* use the standard register itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		std_status = std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	switch (std_status & VIDEO_STD_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	case VIDEO_STD_NTSC_MJ_BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		return STD_NTSC_MJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	case VIDEO_STD_PAL_BDGHIN_BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		return STD_PAL_BDGHIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		return STD_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	return STD_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) /* TVP5146/47 register dump function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) static void tvp514x_reg_dump(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	dump_reg(sd, REG_INPUT_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	dump_reg(sd, REG_AFE_GAIN_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	dump_reg(sd, REG_VIDEO_STD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	dump_reg(sd, REG_OPERATION_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	dump_reg(sd, REG_COLOR_KILLER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	dump_reg(sd, REG_LUMA_CONTROL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	dump_reg(sd, REG_LUMA_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	dump_reg(sd, REG_LUMA_CONTROL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	dump_reg(sd, REG_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	dump_reg(sd, REG_CONTRAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	dump_reg(sd, REG_SATURATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	dump_reg(sd, REG_HUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	dump_reg(sd, REG_CHROMA_CONTROL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	dump_reg(sd, REG_CHROMA_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	dump_reg(sd, REG_COMP_PR_SATURATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	dump_reg(sd, REG_COMP_Y_CONTRAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	dump_reg(sd, REG_COMP_PB_SATURATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	dump_reg(sd, REG_COMP_Y_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	dump_reg(sd, REG_AVID_START_PIXEL_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	dump_reg(sd, REG_AVID_START_PIXEL_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	dump_reg(sd, REG_AVID_STOP_PIXEL_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	dump_reg(sd, REG_AVID_STOP_PIXEL_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	dump_reg(sd, REG_HSYNC_START_PIXEL_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	dump_reg(sd, REG_HSYNC_START_PIXEL_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	dump_reg(sd, REG_HSYNC_STOP_PIXEL_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	dump_reg(sd, REG_HSYNC_STOP_PIXEL_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	dump_reg(sd, REG_VSYNC_START_LINE_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	dump_reg(sd, REG_VSYNC_START_LINE_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	dump_reg(sd, REG_VSYNC_STOP_LINE_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	dump_reg(sd, REG_VSYNC_STOP_LINE_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	dump_reg(sd, REG_VBLK_START_LINE_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	dump_reg(sd, REG_VBLK_START_LINE_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	dump_reg(sd, REG_VBLK_STOP_LINE_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	dump_reg(sd, REG_VBLK_STOP_LINE_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	dump_reg(sd, REG_SYNC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	dump_reg(sd, REG_OUTPUT_FORMATTER1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	dump_reg(sd, REG_OUTPUT_FORMATTER2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	dump_reg(sd, REG_OUTPUT_FORMATTER3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	dump_reg(sd, REG_OUTPUT_FORMATTER4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	dump_reg(sd, REG_OUTPUT_FORMATTER5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	dump_reg(sd, REG_OUTPUT_FORMATTER6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	dump_reg(sd, REG_CLEAR_LOST_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)  * tvp514x_configure() - Configure the TVP5146/47 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)  * @sd: ptr to v4l2_subdev struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460)  * @decoder: ptr to tvp514x_decoder structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  * Returns zero if successful, or non-zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int tvp514x_configure(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		struct tvp514x_decoder *decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	/* common register initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	    tvp514x_write_regs(sd, decoder->tvp514x_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		tvp514x_reg_dump(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482)  * tvp514x_detect() - Detect if an tvp514x is present, and if so which revision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484)  * @decoder: pointer to tvp514x_decoder structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486)  * A device is considered to be detected if the chip ID (LSB and MSB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487)  * registers match the expected values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488)  * Any value of the rom version register is accepted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  * Returns ENODEV error number if no device is detected, or zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  * if a device is detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) static int tvp514x_detect(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		struct tvp514x_decoder *decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	u8 chip_id_msb, chip_id_lsb, rom_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	chip_id_msb = tvp514x_read_reg(sd, REG_CHIP_ID_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	chip_id_lsb = tvp514x_read_reg(sd, REG_CHIP_ID_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	rom_ver = tvp514x_read_reg(sd, REG_ROM_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	v4l2_dbg(1, debug, sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		 chip_id_msb, chip_id_lsb, rom_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		|| ((chip_id_lsb != TVP5146_CHIP_ID_LSB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		&& (chip_id_lsb != TVP5147_CHIP_ID_LSB))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		/* We didn't read the values we expected, so this must not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		 * an TVP5146/47.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		v4l2_err(sd, "chip id mismatch msb:0x%x lsb:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 				chip_id_msb, chip_id_lsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	decoder->ver = rom_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	v4l2_info(sd, "%s (Version - 0x%.2x) found at 0x%x (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 			client->name, decoder->ver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			client->addr << 1, client->adapter->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525)  * tvp514x_querystd() - V4L2 decoder interface handler for querystd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527)  * @std_id: standard V4L2 std_id ioctl enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529)  * Returns the current standard detected by TVP5146/47. If no active input is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530)  * detected then *std_id is set to 0 and the function returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	enum tvp514x_std current_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	enum tvp514x_input input_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	u8 sync_lock_status, lock_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (std_id == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	/* To query the standard the TVP514x must power on the ADCs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	if (!decoder->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		tvp514x_s_stream(sd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		msleep(LOCK_RETRY_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	/* query the current standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	current_std = tvp514x_query_current_std(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	if (current_std == STD_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		*std_id = V4L2_STD_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	input_sel = decoder->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	switch (input_sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	case INPUT_CVBS_VI1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	case INPUT_CVBS_VI1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	case INPUT_CVBS_VI1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	case INPUT_CVBS_VI2A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	case INPUT_CVBS_VI2B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	case INPUT_CVBS_VI2C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	case INPUT_CVBS_VI3A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	case INPUT_CVBS_VI3B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	case INPUT_CVBS_VI3C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	case INPUT_CVBS_VI4A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 			STATUS_HORZ_SYNC_LOCK_BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 			STATUS_VIRT_SYNC_LOCK_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	case INPUT_SVIDEO_VI2A_VI1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	case INPUT_SVIDEO_VI2B_VI1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	case INPUT_SVIDEO_VI2C_VI1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	case INPUT_SVIDEO_VI2A_VI3A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	case INPUT_SVIDEO_VI2B_VI3B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	case INPUT_SVIDEO_VI2C_VI3C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	case INPUT_SVIDEO_VI4A_VI1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	case INPUT_SVIDEO_VI4A_VI1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	case INPUT_SVIDEO_VI4A_VI1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	case INPUT_SVIDEO_VI4A_VI3A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	case INPUT_SVIDEO_VI4A_VI3B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	case INPUT_SVIDEO_VI4A_VI3C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 			STATUS_VIRT_SYNC_LOCK_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		/*Need to add other interfaces*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	/* check whether signal is locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	if (lock_mask != (sync_lock_status & lock_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		*std_id = V4L2_STD_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		return 0;	/* No input detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	*std_id &= decoder->std_list[current_std].standard.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	v4l2_dbg(1, debug, sd, "Current STD: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			decoder->std_list[current_std].standard.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)  * tvp514x_s_std() - V4L2 decoder interface handler for s_std
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609)  * @std_id: standard V4L2 v4l2_std_id ioctl enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611)  * If std_id is supported, sets the requested standard. Otherwise, returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612)  * -EINVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	for (i = 0; i < decoder->num_stds; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		if (std_id & decoder->std_list[i].standard.id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	if ((i == decoder->num_stds) || (i == STD_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	err = tvp514x_write_reg(sd, REG_VIDEO_STD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 				decoder->std_list[i].video_std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	decoder->current_std = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	decoder->tvp514x_regs[REG_VIDEO_STD].val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		decoder->std_list[i].video_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	v4l2_dbg(1, debug, sd, "Standard set to: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			decoder->std_list[i].standard.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)  * tvp514x_s_routing() - V4L2 decoder interface handler for s_routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  * @input: input selector for routing the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644)  * @output: output selector for routing the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645)  * @config: config value. Not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647)  * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648)  * the input is not supported or there is no active signal present in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649)  * selected input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) static int tvp514x_s_routing(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				u32 input, u32 output, u32 config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	enum tvp514x_input input_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	enum tvp514x_output output_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	if ((input >= INPUT_INVALID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			(output >= OUTPUT_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		/* Index out of bound */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	input_sel = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	output_sel = output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	err = tvp514x_write_reg(sd, REG_INPUT_SEL, input_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	output_sel |= tvp514x_read_reg(sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			REG_OUTPUT_FORMATTER1) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	err = tvp514x_write_reg(sd, REG_OUTPUT_FORMATTER1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			output_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	decoder->input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	decoder->output = output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	v4l2_dbg(1, debug, sd, "Input set to: %d\n", input_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)  * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)  * @ctrl: pointer to v4l2_ctrl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)  * If the requested control is supported, sets the control's current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693)  * value in HW. Otherwise, returns -EINVAL if the control is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	struct v4l2_subdev *sd = to_sd(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	int err = -EINVAL, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	value = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		err = tvp514x_write_reg(sd, REG_BRIGHTNESS, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	case V4L2_CID_CONTRAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		err = tvp514x_write_reg(sd, REG_CONTRAST, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			decoder->tvp514x_regs[REG_CONTRAST].val = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	case V4L2_CID_SATURATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		err = tvp514x_write_reg(sd, REG_SATURATION, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			decoder->tvp514x_regs[REG_SATURATION].val = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	case V4L2_CID_HUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		if (value == 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			value = 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		else if (value == -180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			value = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		err = tvp514x_write_reg(sd, REG_HUE, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			decoder->tvp514x_regs[REG_HUE].val = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	case V4L2_CID_AUTOGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value ? 0x0f : 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			ctrl->id, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741)  * tvp514x_g_frame_interval() - V4L2 decoder interface handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743)  * @ival: pointer to a v4l2_subdev_frame_interval structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745)  * Returns the decoder's video CAPTURE parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) tvp514x_g_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			 struct v4l2_subdev_frame_interval *ival)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	enum tvp514x_std current_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	/* get the current standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	current_std = decoder->current_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	ival->interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		decoder->std_list[current_std].standard.frameperiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765)  * tvp514x_s_frame_interval() - V4L2 decoder interface handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767)  * @ival: pointer to a v4l2_subdev_frame_interval structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769)  * Configures the decoder to use the input parameters, if possible. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770)  * not possible, returns the appropriate error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) tvp514x_s_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			 struct v4l2_subdev_frame_interval *ival)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	struct v4l2_fract *timeperframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	enum tvp514x_std current_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	timeperframe = &ival->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	/* get the current standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	current_std = decoder->current_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	*timeperframe =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	    decoder->std_list[current_std].standard.frameperiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)  * tvp514x_s_stream() - V4L2 decoder i/f handler for s_stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795)  * @enable: streaming enable or disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797)  * Sets streaming to enable or disable, if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (decoder->streaming == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	switch (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		/* Power Down Sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		err = tvp514x_write_reg(sd, REG_OPERATION_MODE, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			v4l2_err(sd, "Unable to turn off decoder\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		decoder->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		/* Power Up Sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		err = tvp514x_write_regs(sd, decoder->int_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			v4l2_err(sd, "Unable to turn on decoder\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		/* Detect if not already detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		err = tvp514x_detect(sd, decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			v4l2_err(sd, "Unable to detect decoder\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		err = tvp514x_configure(sd, decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 			v4l2_err(sd, "Unable to configure decoder\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		decoder->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	.s_ctrl = tvp514x_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854)  * tvp514x_enum_mbus_code() - V4L2 decoder interface handler for enum_mbus_code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856)  * @cfg: pad configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857)  * @code: pointer to v4l2_subdev_mbus_code_enum structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859)  * Enumertaes mbus codes supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 				  struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	u32 pad = code->pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	u32 index = code->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	memset(code, 0, sizeof(*code));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	code->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	code->pad = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	code->code = MEDIA_BUS_FMT_UYVY8_2X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881)  * tvp514x_get_pad_format() - V4L2 decoder interface handler for get pad format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883)  * @cfg: pad configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884)  * @format: pointer to v4l2_subdev_format structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886)  * Retrieves pad format which is active or tried based on requirement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) static int tvp514x_get_pad_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 				  struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	__u32 which = format->which;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	if (format->pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		format->format = decoder->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	format->format.code = MEDIA_BUS_FMT_UYVY8_2X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	format->format.width = tvp514x_std_list[decoder->current_std].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	format->format.height = tvp514x_std_list[decoder->current_std].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	format->format.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	format->format.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)  * tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  * @sd: pointer to standard V4L2 sub-device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)  * @cfg: pad configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  * @fmt: pointer to v4l2_subdev_format structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918)  * Set pad format for the output pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static int tvp514x_set_pad_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 				  struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	if (fmt->format.field != V4L2_FIELD_INTERLACED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	    fmt->format.code != MEDIA_BUS_FMT_UYVY8_2X8 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	    fmt->format.colorspace != V4L2_COLORSPACE_SMPTE170M ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	    fmt->format.width != tvp514x_std_list[decoder->current_std].width ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	    fmt->format.height != tvp514x_std_list[decoder->current_std].height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	decoder->format = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	.s_std = tvp514x_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	.s_routing = tvp514x_s_routing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	.querystd = tvp514x_querystd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	.g_frame_interval = tvp514x_g_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	.s_frame_interval = tvp514x_s_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	.s_stream = tvp514x_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) static const struct v4l2_subdev_pad_ops tvp514x_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	.enum_mbus_code = tvp514x_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	.get_fmt = tvp514x_get_pad_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	.set_fmt = tvp514x_set_pad_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) static const struct v4l2_subdev_ops tvp514x_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	.video = &tvp514x_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	.pad = &tvp514x_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) static const struct tvp514x_decoder tvp514x_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	.streaming = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	.fmt_list = tvp514x_fmt_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	.num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	.pix = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		/* Default to NTSC 8-bit YUV 422 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		.width		= NTSC_NUM_ACTIVE_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		.height		= NTSC_NUM_ACTIVE_LINES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		.pixelformat	= V4L2_PIX_FMT_UYVY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		.field		= V4L2_FIELD_INTERLACED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		.bytesperline	= NTSC_NUM_ACTIVE_PIXELS * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		.sizeimage	= NTSC_NUM_ACTIVE_PIXELS * 2 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 					NTSC_NUM_ACTIVE_LINES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	.current_std = STD_NTSC_MJ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	.std_list = tvp514x_std_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	.num_stds = ARRAY_SIZE(tvp514x_std_list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) static struct tvp514x_platform_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) tvp514x_get_pdata(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	struct tvp514x_platform_data *pdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	struct device_node *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		return client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	if (!endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	flags = bus_cfg.bus.parallel.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		pdata->hs_polarity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		pdata->vs_polarity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		pdata->clk_polarity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	of_node_put(endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)  * tvp514x_probe() - decoder driver i2c probe handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)  * @client: i2c driver client device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)  * @id: i2c driver id table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)  * Register decoder as an i2c client device and V4L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)  * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	struct tvp514x_platform_data *pdata = tvp514x_get_pdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	struct tvp514x_decoder *decoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	struct v4l2_subdev *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	if (pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		dev_err(&client->dev, "No platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	/* Check if the adapter supports the needed features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (!decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	/* Initialize the tvp514x_decoder with default configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	*decoder = tvp514x_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	/* Copy default register configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			sizeof(tvp514x_reg_list_default));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	decoder->int_seq = (struct tvp514x_reg *)id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	/* Copy board specific information here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	decoder->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	/**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	 * Fetch platform specific data, and configure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	 * tvp514x_reg_list[] accordingly. Since this is one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	 * time configuration, no need to preserve.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		(decoder->pdata->clk_polarity << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		((decoder->pdata->hs_polarity << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		 (decoder->pdata->vs_polarity << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	/* Set default standard to auto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	decoder->tvp514x_regs[REG_VIDEO_STD].val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		VIDEO_STD_AUTO_SWITCH_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	/* Register with V4L2 layer as slave device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	sd = &decoder->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) #if defined(CONFIG_MEDIA_CONTROLLER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	decoder->sd.entity.function = MEDIA_ENT_F_ATV_DECODER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	ret = media_entity_pads_init(&decoder->sd.entity, 1, &decoder->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		v4l2_err(sd, "%s decoder driver failed to register !!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			 sd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	v4l2_ctrl_handler_init(&decoder->hdl, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		V4L2_CID_CONTRAST, 0, 255, 1, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		V4L2_CID_SATURATION, 0, 255, 1, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		V4L2_CID_HUE, -180, 180, 180, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	sd->ctrl_handler = &decoder->hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	if (decoder->hdl.error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		ret = decoder->hdl.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	v4l2_ctrl_handler_setup(&decoder->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	ret = v4l2_async_register_subdev(&decoder->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		v4l2_ctrl_handler_free(&decoder->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		media_entity_cleanup(&decoder->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)  * tvp514x_remove() - decoder driver i2c remove handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)  * @client: i2c driver client device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)  * Unregister decoder as an i2c client device and V4L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)  * device. Complement of tvp514x_probe().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static int tvp514x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	struct tvp514x_decoder *decoder = to_decoder(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	v4l2_async_unregister_subdev(&decoder->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	media_entity_cleanup(&decoder->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	v4l2_ctrl_handler_free(&decoder->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* TVP5146 Init/Power on Sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	{TOK_TERM, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /* TVP5147 Init/Power on Sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static const struct tvp514x_reg tvp5147_init_reg_seq[] =	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xA0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	{TOK_TERM, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) /* TVP5146M2/TVP5147M1 Init/Power on Sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	{TOK_TERM, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)  * I2C Device Table -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)  * name - Name of the actual device/chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)  * driver_data - Driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static const struct i2c_device_id tvp514x_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	{"tvp5146", (unsigned long)tvp5146_init_reg_seq},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	{"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	{"tvp5147", (unsigned long)tvp5147_init_reg_seq},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	{"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) MODULE_DEVICE_TABLE(i2c, tvp514x_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) #if IS_ENABLED(CONFIG_OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static const struct of_device_id tvp514x_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	{ .compatible = "ti,tvp5146", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	{ .compatible = "ti,tvp5146m2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	{ .compatible = "ti,tvp5147", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	{ .compatible = "ti,tvp5147m1", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	{ /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) MODULE_DEVICE_TABLE(of, tvp514x_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static struct i2c_driver tvp514x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		.of_match_table = of_match_ptr(tvp514x_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		.name = TVP514X_MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	.probe = tvp514x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	.remove = tvp514x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	.id_table = tvp514x_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) module_i2c_driver(tvp514x_driver);