summaryrefslogtreecommitdiff
path: root/drivers/media/i2c
diff options
context:
space:
mode:
authorDragos Bogdan <dragos.bogdan@analog.com>2019-10-18 13:29:55 +0200
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2019-12-16 10:23:58 +0100
commit961f97ab1ef3e2dbe43fac4913372f58ca4a5f74 (patch)
tree7df640869e8666ff9df3100deadc632249963f01 /drivers/media/i2c
parent69e39d40587b8d7538f966607299c360dc935b1f (diff)
media: adv7604: extend deep color mode to ADV7611
The AD7611 chip supports the same Deep Color Mode settings as the AD7604. This change extends support for this feature to the AD7611 by adding a wrapper function for the `read_hdmi_pixelclock` hook and adding the same frequency adjustment logic. Signed-off-by: Dragos Bogdan <dragos.bogdan@analog.com> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/adv7604.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 2dedd6ebb236..09004d928d11 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1503,23 +1503,14 @@ static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
{
- unsigned int freq;
int a, b;
a = hdmi_read(sd, 0x06);
b = hdmi_read(sd, 0x3b);
if (a < 0 || b < 0)
return 0;
- freq = a * 1000000 + ((b & 0x30) >> 4) * 250000;
- if (is_hdmi(sd)) {
- /* adjust for deep color mode */
- unsigned bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
-
- freq = freq * 8 / bits_per_channel;
- }
-
- return freq;
+ return a * 1000000 + ((b & 0x30) >> 4) * 250000;
}
static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
@@ -1530,9 +1521,28 @@ static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
b = hdmi_read(sd, 0x52);
if (a < 0 || b < 0)
return 0;
+
return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128;
}
+static unsigned int adv76xx_read_hdmi_pixelclock(struct v4l2_subdev *sd)
+{
+ struct adv76xx_state *state = to_state(sd);
+ const struct adv76xx_chip_info *info = state->info;
+ unsigned int freq, bits_per_channel, pixelrepetition;
+
+ freq = info->read_hdmi_pixelclock(sd);
+ if (is_hdmi(sd)) {
+ /* adjust for deep color mode and pixel repetition */
+ bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
+ pixelrepetition = (hdmi_read(sd, 0x05) & 0x0f) + 1;
+
+ freq = freq * 8 / bits_per_channel / pixelrepetition;
+ }
+
+ return freq;
+}
+
static int adv76xx_query_dv_timings(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings)
{
@@ -1579,7 +1589,7 @@ static int adv76xx_query_dv_timings(struct v4l2_subdev *sd,
bt->width = w;
bt->height = h;
- bt->pixelclock = info->read_hdmi_pixelclock(sd);
+ bt->pixelclock = adv76xx_read_hdmi_pixelclock(sd);
bt->hfrontporch = hdmi_read16(sd, 0x20, info->hfrontporch_mask);
bt->hsync = hdmi_read16(sd, 0x22, info->hsync_mask);
bt->hbackporch = hdmi_read16(sd, 0x24, info->hbackporch_mask);