media: i2c: tc35874x: allow run out-of-box

This driver are desgined to be take control by userspace
but i'd like to make it support run out-of-box
to act as a normal UVC..

Change-Id: I03f4d29efce12e36334e4819cd4323fe4b0d0408
Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com>
This commit is contained in:
Jacob Chen
2017-08-28 13:40:35 +08:00
committed by Huang, Tao
parent f4b996231d
commit 6488bce942

View File

@@ -79,6 +79,25 @@ static const struct v4l2_dv_timings_cap tc35874x_timings_cap = {
V4L2_DV_BT_CAP_CUSTOM)
};
static u8 EDID_1920x1080_60[] = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x52, 0x62, 0x88, 0x88, 0x00, 0x88, 0x88, 0x88,
0x1C, 0x15, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78,
0x0A, 0x0D, 0xC9, 0xA0, 0x57, 0x47, 0x98, 0x27,
0x12, 0x48, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
0x45, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E,
0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20,
0x6E, 0x28, 0x55, 0x00, 0xC4, 0x8E, 0x21, 0x00,
0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x54,
0x6F, 0x73, 0x68, 0x69, 0x62, 0x61, 0x2D, 0x48,
0x32, 0x44, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD,
0x00, 0x17, 0x3D, 0x0F, 0x8C, 0x17, 0x00, 0x0A,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x92,
};
struct tc35874x_state {
struct tc35874x_platform_data pdata;
struct v4l2_fwnode_bus_mipi_csi2 bus;
@@ -112,6 +131,8 @@ struct tc35874x_state {
static void tc35874x_enable_interrupts(struct v4l2_subdev *sd,
bool cable_connected);
static int tc35874x_s_ctrl_detect_tx_5v(struct v4l2_subdev *sd);
static int tc35874x_s_dv_timings(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings);
static inline struct tc35874x_state *to_state(struct v4l2_subdev *sd)
{
@@ -845,13 +866,15 @@ static void tc35874x_format_change(struct v4l2_subdev *sd)
v4l2_dbg(1, debug, sd, "%s: No signal\n",
__func__);
} else {
if (!v4l2_match_dv_timings(&state->timings, &timings, 0))
if (!v4l2_match_dv_timings(&state->timings, &timings, 0)) {
enable_stream(sd, false);
/* automaticly set timing rather than set by userspace */
tc35874x_s_dv_timings(sd, &timings);
}
if (debug)
v4l2_print_dv_timings(sd->name,
"tc35874x_format_change: New format: ",
&timings, false);
v4l2_print_dv_timings(sd->name,
"tc35874x_format_change: New format: ",
&timings, false);
}
if (sd->devnode)
@@ -1471,10 +1494,6 @@ static int tc35874x_g_mbus_config(struct v4l2_subdev *sd,
static int tc35874x_s_stream(struct v4l2_subdev *sd, int enable)
{
enable_stream(sd, enable);
if (!enable) {
/* Put all lanes in PL-11 state (STOPSTATE) */
tc35874x_set_csi(sd);
}
return 0;
}
@@ -1505,9 +1524,6 @@ static int tc35874x_get_fmt(struct v4l2_subdev *sd,
struct tc35874x_state *state = to_state(sd);
u8 vi_rep = i2c_rd8(sd, VI_REP);
if (format->pad != 0)
return -EINVAL;
format->format.code = state->mbus_fmt_code;
format->format.width = state->timings.bt.width;
format->format.height = state->timings.bt.height;
@@ -1852,6 +1868,7 @@ static int tc35874x_probe(struct i2c_client *client,
struct tc35874x_state *state;
struct tc35874x_platform_data *pdata = client->dev.platform_data;
struct v4l2_subdev *sd;
struct v4l2_subdev_edid def_edid;
int err, data;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -1923,7 +1940,7 @@ static int tc35874x_probe(struct i2c_client *client,
if (err < 0)
goto err_hdl;
state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
state->mbus_fmt_code = MEDIA_BUS_FMT_UYVY8_1X16;
sd->dev = &client->dev;
err = v4l2_async_register_subdev(sd);
@@ -1941,6 +1958,13 @@ static int tc35874x_probe(struct i2c_client *client,
tc35874x_set_csi_color_space(sd);
def_edid.pad = 0;
def_edid.start_block = 0;
def_edid.blocks = 1;
def_edid.edid = EDID_1920x1080_60;
tc35874x_s_edid(sd, &def_edid);
tc35874x_init_interrupts(sd);
if (state->i2c_client->irq) {