linux/drivers/media/i2c/tvp5150.c

// SPDX-License-Identifier: GPL-2.0
//
// tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver
//
// Copyright (c) 2005,2006 Mauro Carvalho Chehab <[email protected]>

#include <dt-bindings/media/tvp5150.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
#include <media/v4l2-rect.h>

#include "tvp5150_reg.h"

#define TVP5150_H_MAX
#define TVP5150_V_MAX_525_60
#define TVP5150_V_MAX_OTHERS
#define TVP5150_MAX_CROP_LEFT
#define TVP5150_MAX_CROP_TOP
#define TVP5150_CROP_SHIFT
#define TVP5150_MBUS_FMT
#define TVP5150_FIELD
#define TVP5150_COLORSPACE
#define TVP5150_STD_MASK

#define TVP5150_MAX_CONNECTORS

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();


static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC();

#define dprintk0(__dev, __arg...)

enum tvp5150_pads {};

struct tvp5150_connector {};

struct tvp5150 {};

static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
{}

static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{}

static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
{}

static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
				const u8 end, int max_line)
{}

static int tvp5150_log_status(struct v4l2_subdev *sd)
{}

/****************************************************************************
			Basic functions
 ****************************************************************************/

static void tvp5150_selmux(struct v4l2_subdev *sd)
{
	int opmode = 0;
	struct tvp5150 *decoder = to_tvp5150(sd);
	unsigned int mask, val;
	int input = 0;

	/* Only tvp5150am1 and tvp5151 have signal generator support */
	if ((decoder->dev_id == 0x5150 && decoder->rom_ver == 0x0400) ||
	    (decoder->dev_id == 0x5151 && decoder->rom_ver == 0x0100)) {
		if (!decoder->enable)
			input = 8;
	}

	switch (decoder->input) {
	case TVP5150_COMPOSITE1:
		input |= 2;
		fallthrough;
	case TVP5150_COMPOSITE0:
		break;
	case TVP5150_SVIDEO:
	default:
		input |= 1;
		break;
	}

	dev_dbg_lvl(sd->dev, 1, debug,
		    "Selecting video route: route input=%s, output=%s => tvp5150 input=0x%02x, opmode=0x%02x\n",
		    decoder->input == 0 ? "aip1a" :
		    decoder->input == 2 ? "aip1b" : "svideo",
		    decoder->output == 0 ? "normal" : "black-frame-gen",
		    input, opmode);

	regmap_write(decoder->regmap, TVP5150_OP_MODE_CTL, opmode);
	regmap_write(decoder->regmap, TVP5150_VD_IN_SRC_SEL_1, input);

	/*
	 * Setup the FID/GLCO/VLK/HVLK and INTREQ/GPCL/VBLK output signals. For
	 * S-Video we output the vertical lock (VLK) signal on FID/GLCO/VLK/HVLK
	 * and set INTREQ/GPCL/VBLK to logic 0. For composite we output the
	 * field indicator (FID) signal on FID/GLCO/VLK/HVLK and set
	 * INTREQ/GPCL/VBLK to logic 1.
	 */
	mask = TVP5150_MISC_CTL_GPCL | TVP5150_MISC_CTL_HVLK;
	if (decoder->input == TVP5150_SVIDEO)
		val = TVP5150_MISC_CTL_HVLK;
	else
		val = TVP5150_MISC_CTL_GPCL;
	regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val);
};

struct i2c_reg_value {};

/* Default values as sugested at TVP5150AM1 datasheet */
static const struct i2c_reg_value tvp5150_init_default[] =;

/* Default values as sugested at TVP5150AM1 datasheet */
static const struct i2c_reg_value tvp5150_init_enable[] =;

struct tvp5150_vbi_type {};

struct i2c_vbi_ram_value {};

/* This struct have the values for each supported VBI Standard
 * by
 tvp5150_vbi_types should follow the same order as vbi_ram_default
 * value 0 means rom position 0x10, value 1 means rom position 0x30
 * and so on. There are 16 possible locations from 0 to 15.
 */

static const struct i2c_vbi_ram_value vbi_ram_default[] =;

static int tvp5150_write_inittab(struct v4l2_subdev *sd,
				const struct i2c_reg_value *regs)
{}

static int tvp5150_vdp_init(struct v4l2_subdev *sd)
{}

/* Fills VBI capabilities based on i2c_vbi_ram_value struct */
static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
				struct v4l2_sliced_vbi_cap *cap)
{}

/* Set vbi processing
 * type - one of tvp5150_vbi_types
 * line - line to gather data
 * fields: bit 0 field1, bit 1, field2
 * flags (default=0xf0) is a bitmask, were set means:
 *	bit 7: enable filtering null bytes on CC
 *	bit 6: send data also to FIFO
 *	bit 5: don't allow data with errors on FIFO
 *	bit 4: enable ECC when possible
 * pix_align = pix alignment:
 *	LSB = field1
 *	MSB = field2
 */
static int tvp5150_set_vbi(struct v4l2_subdev *sd,
			unsigned int type, u8 flags, int line,
			const int fields)
{}

static int tvp5150_get_vbi(struct v4l2_subdev *sd, int line)
{}

static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
{}

static int tvp5150_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
{}

static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{}

static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
{}

static int query_lock(struct v4l2_subdev *sd)
{}

static int tvp5150_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
{}

static const struct v4l2_event tvp5150_ev_fmt =;

static irqreturn_t tvp5150_isr(int irq, void *dev_id)
{}

static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
{}

static int tvp5150_enable(struct v4l2_subdev *sd)
{
	struct tvp5150 *decoder = to_tvp5150(sd);
	v4l2_std_id std;

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

	if (decoder->norm == V4L2_STD_ALL)
		std = tvp5150_read_std(sd);
	else
		std = decoder->norm;

	/* Disable autoswitch mode */
	tvp5150_set_std(sd, std);

	/*
	 * Enable the YCbCr and clock outputs. In discrete sync mode
	 * (non-BT.656) additionally enable the sync outputs.
	 */
	switch (decoder->mbus_type) {
	case V4L2_MBUS_PARALLEL:
		/* 8-bit 4:2:2 YUV with discrete sync output */
		regmap_update_bits(decoder->regmap, TVP5150_DATA_RATE_SEL,
				   0x7, 0x0);
		decoder->oe = TVP5150_MISC_CTL_YCBCR_OE |
			      TVP5150_MISC_CTL_CLOCK_OE |
			      TVP5150_MISC_CTL_SYNC_OE;
		break;
	case V4L2_MBUS_BT656:
		decoder->oe = TVP5150_MISC_CTL_YCBCR_OE |
			      TVP5150_MISC_CTL_CLOCK_OE;
		break;
	default:
		return -EINVAL;
	}

	return 0;
};

static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop)
{}

static struct v4l2_rect *
tvp5150_get_pad_crop(struct tvp5150 *decoder,
		     struct v4l2_subdev_state *sd_state, unsigned int pad,
		     enum v4l2_subdev_format_whence which)
{}

static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
			    struct v4l2_subdev_state *sd_state,
			    struct v4l2_subdev_format *format)
{}

static unsigned int tvp5150_get_hmax(struct v4l2_subdev *sd)
{}

static void tvp5150_set_hw_selection(struct v4l2_subdev *sd,
				     struct v4l2_rect *rect)
{}

static int tvp5150_set_selection(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_selection *sel)
{}

static int tvp5150_get_selection(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_selection *sel)
{}

static int tvp5150_get_mbus_config(struct v4l2_subdev *sd,
				   unsigned int pad,
				   struct v4l2_mbus_config *cfg)
{}

/****************************************************************************
			V4L2 subdev pad ops
 ****************************************************************************/
static int tvp5150_init_state(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *sd_state)
{}

static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
		struct v4l2_subdev_state *sd_state,
		struct v4l2_subdev_mbus_code_enum *code)
{}

static int tvp5150_enum_frame_size(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *sd_state,
				   struct v4l2_subdev_frame_size_enum *fse)
{}

/****************************************************************************
 *			Media entity ops
 ****************************************************************************/
#if defined(CONFIG_MEDIA_CONTROLLER)
static int tvp5150_set_link(struct media_pad *connector_pad,
			    struct media_pad *tvp5150_pad, u32 flags)
{}

static int tvp5150_disable_all_input_links(struct tvp5150 *decoder)
{}

static int tvp5150_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
			     u32 config);

static int tvp5150_link_setup(struct media_entity *entity,
			      const struct media_pad *tvp5150_pad,
			      const struct media_pad *remote, u32 flags)
{}

static const struct media_entity_operations tvp5150_sd_media_ops =;
#endif
/****************************************************************************
			I2C Command
 ****************************************************************************/
static int __maybe_unused tvp5150_runtime_suspend(struct device *dev)
{}

static int __maybe_unused tvp5150_runtime_resume(struct device *dev)
{}

static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
{}

static int tvp5150_s_routing(struct v4l2_subdev *sd,
			     u32 input, u32 output, u32 config)
{}

static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
{}

static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
{}

static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
{}

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{}

static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{}
#endif

static int tvp5150_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
				   struct v4l2_event_subscription *sub)
{}

static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{}

static int tvp5150_registered(struct v4l2_subdev *sd)
{}

static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{}

static int tvp5150_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{}

/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops tvp5150_ctrl_ops =;

static const struct v4l2_subdev_core_ops tvp5150_core_ops =;

static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops =;

static const struct v4l2_subdev_video_ops tvp5150_video_ops =;

static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops =;

static const struct v4l2_subdev_pad_ops tvp5150_pad_ops =;

static const struct v4l2_subdev_ops tvp5150_ops =;

static const struct v4l2_subdev_internal_ops tvp5150_internal_ops =;

/****************************************************************************
			I2C Client & Driver
 ****************************************************************************/

static const struct regmap_range tvp5150_readable_ranges[] =;

static bool tvp5150_volatile_reg(struct device *dev, unsigned int reg)
{}

static const struct regmap_access_table tvp5150_readable_table =;

static const struct regmap_config tvp5150_config =;

static int tvp5150_detect_version(struct tvp5150 *core)
{}

static int tvp5150_init(struct i2c_client *c)
{}

#if defined(CONFIG_MEDIA_CONTROLLER)
static int tvp5150_mc_init(struct tvp5150 *decoder)
{}

#else /* !defined(CONFIG_MEDIA_CONTROLLER) */

static inline int tvp5150_mc_init(struct tvp5150 *decoder)
{
	return 0;
}
#endif /* defined(CONFIG_MEDIA_CONTROLLER) */

static int tvp5150_validate_connectors(struct tvp5150 *decoder)
{}

static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
{}

static const char * const tvp5150_test_patterns[2] =;

static int tvp5150_probe(struct i2c_client *c)
{}

static void tvp5150_remove(struct i2c_client *c)
{}

/* ----------------------------------------------------------------------- */

static const struct dev_pm_ops tvp5150_pm_ops =;

static const struct i2c_device_id tvp5150_id[] =;
MODULE_DEVICE_TABLE(i2c, tvp5150_id);

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id tvp5150_of_match[] =;
MODULE_DEVICE_TABLE(of, tvp5150_of_match);
#endif

static struct i2c_driver tvp5150_driver =;

module_i2c_driver();