From ed29f894970065402e988088a19698f252b80144 Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Sat, 22 Jun 2013 05:46:34 -0300 Subject: [media] media: i2c: ths8200: support asynchronous probing This patch supports both synchronous and asynchronous ths8200 subdevice probing. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index a24f90c..cc1339a 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -21,6 +21,7 @@ #include #include +#include #include #include "ths8200_regs.h" @@ -500,6 +501,7 @@ static int ths8200_probe(struct i2c_client *client, { struct ths8200_state *state; struct v4l2_subdev *sd; + int error; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -517,6 +519,10 @@ static int ths8200_probe(struct i2c_client *client, ths8200_core_init(sd); + error = v4l2_async_register_subdev(&state->sd); + if (error) + return error; + v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); @@ -526,12 +532,13 @@ static int ths8200_probe(struct i2c_client *client, static int ths8200_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ths8200_state *decoder = to_state(sd); v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); ths8200_s_power(sd, false); - + v4l2_async_unregister_subdev(&decoder->sd); v4l2_device_unregister_subdev(sd); return 0; -- cgit v1.1 From 0fb0f8f5ed9ff1419cd59834e4d1e95d19fb2eef Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Sat, 22 Jun 2013 05:46:35 -0300 Subject: [media] media: i2c: ths8200: add OF support add OF support for the ths8200 driver. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index cc1339a..8a29810 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -550,10 +550,19 @@ static struct i2c_device_id ths8200_id[] = { }; MODULE_DEVICE_TABLE(i2c, ths8200_id); +#if IS_ENABLED(CONFIG_OF) +static const struct of_device_id ths8200_of_match[] = { + { .compatible = "ti,ths8200", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ths8200_of_match); +#endif + static struct i2c_driver ths8200_driver = { .driver = { .owner = THIS_MODULE, .name = "ths8200", + .of_match_table = of_match_ptr(ths8200_of_match), }, .probe = ths8200_probe, .remove = ths8200_remove, -- cgit v1.1 From 2576415846bcbad3c0a6885fc44f950837106364 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 29 Jul 2013 08:40:56 -0300 Subject: [media] v4l2: move dv-timings related code to v4l2-dv-timings.c v4l2-common.c contained a bunch of dv-timings related functions. Move that to the new v4l2-dv-timings.c which is a more appropriate place for them. There aren't many drivers that do HDTV, so it is a good idea to separate common code related to that into a module of its own. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 8a29810..aef7c0e 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -21,6 +21,7 @@ #include #include +#include #include #include -- cgit v1.1 From eacf8f9aa80e2231af43b589cfc18c054e417220 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 29 Jul 2013 08:40:59 -0300 Subject: [media] v4l2: use new V4L2_DV_BT_BLANKING/FRAME defines Use the new defines to calculate the full blanking and frame sizes. Signed-off-by: Hans Verkuil Acked-by: Scott Jiang Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index aef7c0e..28932e9 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -65,22 +65,22 @@ static inline struct ths8200_state *to_state(struct v4l2_subdev *sd) static inline unsigned hblanking(const struct v4l2_bt_timings *t) { - return t->hfrontporch + t->hsync + t->hbackporch; + return V4L2_DV_BT_BLANKING_WIDTH(t); } static inline unsigned htotal(const struct v4l2_bt_timings *t) { - return t->width + t->hfrontporch + t->hsync + t->hbackporch; + return V4L2_DV_BT_FRAME_WIDTH(t); } static inline unsigned vblanking(const struct v4l2_bt_timings *t) { - return t->vfrontporch + t->vsync + t->vbackporch; + return V4L2_DV_BT_BLANKING_HEIGHT(t); } static inline unsigned vtotal(const struct v4l2_bt_timings *t) { - return t->height + t->vfrontporch + t->vsync + t->vbackporch; + return V4L2_DV_BT_FRAME_HEIGHT(t); } static int ths8200_read(struct v4l2_subdev *sd, u8 reg) -- cgit v1.1 From 041649048149b3e4afa56428e6d1b081b9dd49f5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 29 Jul 2013 08:41:01 -0300 Subject: [media] ths8200/ad9389b: use new dv_timings helpers Simplify the code by using the new dv_timings helpers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 55 ++++++++++++--------------------------------- 1 file changed, 14 insertions(+), 41 deletions(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 28932e9..7a60a8f 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -44,18 +44,16 @@ struct ths8200_state { struct v4l2_dv_timings dv_timings; }; -static const struct v4l2_dv_timings ths8200_timings[] = { - V4L2_DV_BT_CEA_720X480P59_94, - V4L2_DV_BT_CEA_1280X720P24, - V4L2_DV_BT_CEA_1280X720P25, - V4L2_DV_BT_CEA_1280X720P30, - V4L2_DV_BT_CEA_1280X720P50, - V4L2_DV_BT_CEA_1280X720P60, - V4L2_DV_BT_CEA_1920X1080P24, - V4L2_DV_BT_CEA_1920X1080P25, - V4L2_DV_BT_CEA_1920X1080P30, - V4L2_DV_BT_CEA_1920X1080P50, - V4L2_DV_BT_CEA_1920X1080P60, +static const struct v4l2_dv_timings_cap ths8200_timings_cap = { + .type = V4L2_DV_BT_656_1120, + .bt = { + .max_width = 1920, + .max_height = 1080, + .min_pixelclock = 27000000, + .max_pixelclock = 148500000, + .standards = V4L2_DV_BT_STD_CEA861, + .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE, + }, }; static inline struct ths8200_state *to_state(struct v4l2_subdev *sd) @@ -411,25 +409,13 @@ static int ths8200_s_dv_timings(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings) { struct ths8200_state *state = to_state(sd); - int i; v4l2_dbg(1, debug, sd, "%s:\n", __func__); - if (timings->type != V4L2_DV_BT_656_1120) + if (!v4l2_dv_valid_timings(timings, &ths8200_timings_cap)) return -EINVAL; - /* TODO Support interlaced formats */ - if (timings->bt.interlaced) { - v4l2_dbg(1, debug, sd, "TODO Support interlaced formats\n"); - return -EINVAL; - } - - for (i = 0; i < ARRAY_SIZE(ths8200_timings); i++) { - if (v4l_match_dv_timings(&ths8200_timings[i], timings, 10)) - break; - } - - if (i == ARRAY_SIZE(ths8200_timings)) { + if (!v4l2_find_dv_timings_cap(timings, &ths8200_timings_cap, 10)) { v4l2_dbg(1, debug, sd, "Unsupported format\n"); return -EINVAL; } @@ -459,26 +445,13 @@ static int ths8200_g_dv_timings(struct v4l2_subdev *sd, static int ths8200_enum_dv_timings(struct v4l2_subdev *sd, struct v4l2_enum_dv_timings *timings) { - /* Check requested format index is within range */ - if (timings->index >= ARRAY_SIZE(ths8200_timings)) - return -EINVAL; - - timings->timings = ths8200_timings[timings->index]; - - return 0; + return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap); } static int ths8200_dv_timings_cap(struct v4l2_subdev *sd, struct v4l2_dv_timings_cap *cap) { - cap->type = V4L2_DV_BT_656_1120; - cap->bt.max_width = 1920; - cap->bt.max_height = 1080; - cap->bt.min_pixelclock = 27000000; - cap->bt.max_pixelclock = 148500000; - cap->bt.standards = V4L2_DV_BT_STD_CEA861; - cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE; - + *cap = ths8200_timings_cap; return 0; } -- cgit v1.1 From 11d034c8b60c3eebc2a12f5e99a200f55a786230 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 15 Aug 2013 08:05:59 -0300 Subject: [media] ad9389b/adv7604/ths8200: use new v4l2_print_dv_timings helper These three drivers all have code to log the dv_timings contents. Replace that code with the new helper function. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 7a60a8f..49041e5 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -133,39 +133,6 @@ static int ths8200_s_register(struct v4l2_subdev *sd, } #endif -static void ths8200_print_timings(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings, - const char *txt, bool detailed) -{ - struct v4l2_bt_timings *bt = &timings->bt; - u32 htot, vtot; - - if (timings->type != V4L2_DV_BT_656_1120) - return; - - htot = htotal(bt); - vtot = vtotal(bt); - - v4l2_info(sd, "%s %dx%d%s%d (%dx%d)", - txt, bt->width, bt->height, bt->interlaced ? "i" : "p", - (htot * vtot) > 0 ? ((u32)bt->pixelclock / (htot * vtot)) : 0, - htot, vtot); - - if (detailed) { - v4l2_info(sd, " horizontal: fp = %d, %ssync = %d, bp = %d\n", - bt->hfrontporch, - (bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-", - bt->hsync, bt->hbackporch); - v4l2_info(sd, " vertical: fp = %d, %ssync = %d, bp = %d\n", - bt->vfrontporch, - (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", - bt->vsync, bt->vbackporch); - v4l2_info(sd, - " pixelclock: %lld, flags: 0x%x, standards: 0x%x\n", - bt->pixelclock, bt->flags, bt->standards); - } -} - static int ths8200_log_status(struct v4l2_subdev *sd) { struct ths8200_state *state = to_state(sd); @@ -182,9 +149,8 @@ static int ths8200_log_status(struct v4l2_subdev *sd) ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_LSB), (ths8200_read(sd, THS8200_DTG2_LINE_CNT_MSB) & 0x07) * 256 + ths8200_read(sd, THS8200_DTG2_LINE_CNT_LSB)); - ths8200_print_timings(sd, &state->dv_timings, - "Configured format:", true); - + v4l2_print_dv_timings(sd->name, "Configured format:", + &state->dv_timings, true); return 0; } -- cgit v1.1 From fe9c2564d80d633d08a2d69fe38598c06a0ddfb2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Aug 2013 08:07:26 -0300 Subject: [media] adv7604/ad9389b/ths8200: decrease min_pixelclock to 25MHz The CEA-861 standard allows for the 640x480 format at 25.175 MHz. Ensure that that's allowed according to the struct v4l2_bt_timings_cap. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 49041e5..580bd1b 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -49,7 +49,7 @@ static const struct v4l2_dv_timings_cap ths8200_timings_cap = { .bt = { .max_width = 1920, .max_height = 1080, - .min_pixelclock = 27000000, + .min_pixelclock = 25000000, .max_pixelclock = 148500000, .standards = V4L2_DV_BT_STD_CEA861, .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE, -- cgit v1.1 From 70b654945bacd27622ef1c424f054ae04de597e0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Aug 2013 10:23:33 -0300 Subject: [media] v4l2-dv-timings: rename v4l2_dv_valid_timings to v4l2_valid_dv_timings All other functions follow the v4l2__dv_timings pattern, do the same for this function. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 580bd1b..6abf0fb 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -378,7 +378,7 @@ static int ths8200_s_dv_timings(struct v4l2_subdev *sd, v4l2_dbg(1, debug, sd, "%s:\n", __func__); - if (!v4l2_dv_valid_timings(timings, &ths8200_timings_cap)) + if (!v4l2_valid_dv_timings(timings, &ths8200_timings_cap)) return -EINVAL; if (!v4l2_find_dv_timings_cap(timings, &ths8200_timings_cap, 10)) { -- cgit v1.1 From b8f0fff4279a1b85fa4b6d7d8b538c254edcb4a1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Aug 2013 11:21:50 -0300 Subject: [media] v4l2-dv-timings: add callback to handle exceptions In most cases the v4l2_bt_timings_cap struct has all the information necessary to determine valid timings, but occasionally there are exceptions. Add a callback function to be able to test for those exceptions. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/media/i2c/ths8200.c') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 6abf0fb..a58a8f6 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -378,10 +378,12 @@ static int ths8200_s_dv_timings(struct v4l2_subdev *sd, v4l2_dbg(1, debug, sd, "%s:\n", __func__); - if (!v4l2_valid_dv_timings(timings, &ths8200_timings_cap)) + if (!v4l2_valid_dv_timings(timings, &ths8200_timings_cap, + NULL, NULL)) return -EINVAL; - if (!v4l2_find_dv_timings_cap(timings, &ths8200_timings_cap, 10)) { + if (!v4l2_find_dv_timings_cap(timings, &ths8200_timings_cap, 10, + NULL, NULL)) { v4l2_dbg(1, debug, sd, "Unsupported format\n"); return -EINVAL; } @@ -411,7 +413,8 @@ static int ths8200_g_dv_timings(struct v4l2_subdev *sd, static int ths8200_enum_dv_timings(struct v4l2_subdev *sd, struct v4l2_enum_dv_timings *timings) { - return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap); + return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap, + NULL, NULL); } static int ths8200_dv_timings_cap(struct v4l2_subdev *sd, -- cgit v1.1