summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/v4l2-core/Kconfig1
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c59
-rw-r--r--include/media/v4l2-dv-timings.h20
3 files changed, 77 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 367523a3c774..6b1b78ff1417 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -6,6 +6,7 @@
config VIDEO_V4L2
tristate
depends on (I2C || I2C=n) && VIDEO_DEV
+ select RATIONAL
default (I2C || I2C=n) && VIDEO_DEV
config VIDEO_ADV_DEBUG
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 730a7c392c1d..5c8c49d240d1 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/rational.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-dv-timings.h>
@@ -224,6 +225,24 @@ bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t,
}
EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cap);
+bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic)
+{
+ unsigned int i;
+
+ for (i = 0; i < v4l2_dv_timings_presets[i].bt.width; i++) {
+ const struct v4l2_bt_timings *bt =
+ &v4l2_dv_timings_presets[i].bt;
+
+ if ((bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) &&
+ bt->cea861_vic == vic) {
+ *t = v4l2_dv_timings_presets[i];
+ return true;
+ }
+ }
+ return false;
+}
+EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cea861_vic);
+
/**
* v4l2_match_dv_timings - check if two timings match
* @t1 - compare this v4l2_dv_timings struct...
@@ -306,7 +325,8 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
(bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
bt->il_vsync, bt->il_vbackporch);
pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock);
- pr_info("%s: flags (0x%x):%s%s%s%s%s%s%s\n", dev_prefix, bt->flags,
+ pr_info("%s: flags (0x%x):%s%s%s%s%s%s%s%s%s%s\n",
+ dev_prefix, bt->flags,
(bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ?
" REDUCED_BLANKING" : "",
((bt->flags & V4L2_DV_FL_REDUCED_BLANKING) &&
@@ -320,16 +340,51 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
(bt->flags & V4L2_DV_FL_IS_CE_VIDEO) ?
" CE_VIDEO" : "",
(bt->flags & V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE) ?
- " FIRST_FIELD_EXTRA_LINE" : "");
+ " FIRST_FIELD_EXTRA_LINE" : "",
+ (bt->flags & V4L2_DV_FL_HAS_PICTURE_ASPECT) ?
+ " HAS_PICTURE_ASPECT" : "",
+ (bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) ?
+ " HAS_CEA861_VIC" : "",
+ (bt->flags & V4L2_DV_FL_HAS_HDMI_VIC) ?
+ " HAS_HDMI_VIC" : "");
pr_info("%s: standards (0x%x):%s%s%s%s%s\n", dev_prefix, bt->standards,
(bt->standards & V4L2_DV_BT_STD_CEA861) ? " CEA" : "",
(bt->standards & V4L2_DV_BT_STD_DMT) ? " DMT" : "",
(bt->standards & V4L2_DV_BT_STD_CVT) ? " CVT" : "",
(bt->standards & V4L2_DV_BT_STD_GTF) ? " GTF" : "",
(bt->standards & V4L2_DV_BT_STD_SDI) ? " SDI" : "");
+ if (bt->flags & V4L2_DV_FL_HAS_PICTURE_ASPECT)
+ pr_info("%s: picture aspect (hor:vert): %u:%u\n", dev_prefix,
+ bt->picture_aspect.numerator,
+ bt->picture_aspect.denominator);
+ if (bt->flags & V4L2_DV_FL_HAS_CEA861_VIC)
+ pr_info("%s: CEA-861 VIC: %u\n", dev_prefix, bt->cea861_vic);
+ if (bt->flags & V4L2_DV_FL_HAS_HDMI_VIC)
+ pr_info("%s: HDMI VIC: %u\n", dev_prefix, bt->hdmi_vic);
}
EXPORT_SYMBOL_GPL(v4l2_print_dv_timings);
+struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t)
+{
+ struct v4l2_fract ratio = { 1, 1 };
+ unsigned long n, d;
+
+ if (t->type != V4L2_DV_BT_656_1120)
+ return ratio;
+ if (!(t->bt.flags & V4L2_DV_FL_HAS_PICTURE_ASPECT))
+ return ratio;
+
+ ratio.numerator = t->bt.width * t->bt.picture_aspect.denominator;
+ ratio.denominator = t->bt.height * t->bt.picture_aspect.numerator;
+
+ rational_best_approximation(ratio.numerator, ratio.denominator,
+ ratio.numerator, ratio.denominator, &n, &d);
+ ratio.numerator = n;
+ ratio.denominator = d;
+ return ratio;
+}
+EXPORT_SYMBOL_GPL(v4l2_dv_timings_aspect_ratio);
+
/*
* CVT defines
* Based on Coordinated Video Timings Standard
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 0a7d9e1fc8c8..61a18893e004 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -101,12 +101,22 @@ bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t,
void *fnc_handle);
/**
+ * v4l2_find_dv_timings_cea861_vic() - find timings based on CEA-861 VIC
+ * @t: the timings data.
+ * @vic: CEA-861 VIC code
+ *
+ * On success it will fill in @t with the found timings and it returns true.
+ * On failure it will return false.
+ */
+bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic);
+
+/**
* v4l2_match_dv_timings() - do two timings match?
*
* @measured: the measured timings data.
* @standard: the timings according to the standard.
* @pclock_delta: maximum delta in Hz between standard->pixelclock and
- * the measured timings.
+ * the measured timings.
* @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
* match.
*
@@ -185,6 +195,14 @@ bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync,
*/
struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
+/**
+ * v4l2_dv_timings_aspect_ratio - calculate the aspect ratio based on the
+ * v4l2_dv_timings information.
+ *
+ * @t: the timings data.
+ */
+struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t);
+
/*
* reduce_fps - check if conditions for reduced fps are true.
* bt - v4l2 timing structure