#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)
{ … }
static void tvp5150_selmux(struct v4l2_subdev *sd)
{
int opmode = 0;
struct tvp5150 *decoder = to_tvp5150(sd);
unsigned int mask, val;
int input = 0;
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);
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 { … };
static const struct i2c_reg_value tvp5150_init_default[] = …;
static const struct i2c_reg_value tvp5150_init_enable[] = …;
struct tvp5150_vbi_type { … };
struct i2c_vbi_ram_value { … };
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)
{ … }
static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
struct v4l2_sliced_vbi_cap *cap)
{ … }
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;
tvp5150_write_inittab(sd, tvp5150_init_enable);
if (decoder->norm == V4L2_STD_ALL)
std = tvp5150_read_std(sd);
else
std = decoder->norm;
tvp5150_set_std(sd, std);
switch (decoder->mbus_type) {
case V4L2_MBUS_PARALLEL:
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)
{ … }
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)
{ … }
#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
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 = …;
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
static inline int tvp5150_mc_init(struct tvp5150 *decoder)
{
return 0;
}
#endif
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(…) …;