^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);