aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMats Randgaard <matrandg@cisco.com>2013-12-10 09:24:35 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 03:34:22 -0500
commit7de6fab1fdc81381834db690ec0511ec87acc4d3 (patch)
tree305f66640d798ee78909200cc4f5a661d6d0485a
parent77a09f8bf16c66c4875abe4d51939287df044242 (diff)
[media] adv7842: Use defines to select EDID port
Signed-off-by: Mats Randgaard <matrandg@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/i2c/adv7842.c77
-rw-r--r--include/media/adv7842.h4
2 files changed, 38 insertions, 43 deletions
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index ab448970bbd8..a26c70ca581c 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -22,8 +22,8 @@
22 * References (c = chapter, p = page): 22 * References (c = chapter, p = page):
23 * REF_01 - Analog devices, ADV7842, Register Settings Recommendations, 23 * REF_01 - Analog devices, ADV7842, Register Settings Recommendations,
24 * Revision 2.5, June 2010 24 * Revision 2.5, June 2010
25 * REF_02 - Analog devices, Register map documentation, Documentation of 25 * REF_02 - Analog devices, Software User Guide, UG-206,
26 * the register maps, Software manual, Rev. F, June 2010 26 * ADV7842 I2C Register Maps, Rev. 0, November 2010
27 */ 27 */
28 28
29 29
@@ -587,10 +587,10 @@ static void adv7842_delayed_work_enable_hotplug(struct work_struct *work)
587 v4l2_dbg(2, debug, sd, "%s: enable hotplug on ports: 0x%x\n", 587 v4l2_dbg(2, debug, sd, "%s: enable hotplug on ports: 0x%x\n",
588 __func__, present); 588 __func__, present);
589 589
590 if (present & 0x1) 590 if (present & (0x04 << ADV7842_EDID_PORT_A))
591 mask |= 0x20; /* port A */ 591 mask |= 0x20;
592 if (present & 0x2) 592 if (present & (0x04 << ADV7842_EDID_PORT_B))
593 mask |= 0x10; /* port B */ 593 mask |= 0x10;
594 io_write_and_or(sd, 0x20, 0xcf, mask); 594 io_write_and_or(sd, 0x20, 0xcf, mask);
595} 595}
596 596
@@ -679,14 +679,12 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
679 struct i2c_client *client = v4l2_get_subdevdata(sd); 679 struct i2c_client *client = v4l2_get_subdevdata(sd);
680 struct adv7842_state *state = to_state(sd); 680 struct adv7842_state *state = to_state(sd);
681 const u8 *val = state->hdmi_edid.edid; 681 const u8 *val = state->hdmi_edid.edid;
682 u8 cur_mask = rep_read(sd, 0x77) & 0x0c;
683 u8 mask = port == 0 ? 0x4 : 0x8;
684 int spa_loc = edid_spa_location(val); 682 int spa_loc = edid_spa_location(val);
685 int err = 0; 683 int err = 0;
686 int i; 684 int i;
687 685
688 v4l2_dbg(2, debug, sd, "%s: write EDID on port %d (spa at 0x%x)\n", 686 v4l2_dbg(2, debug, sd, "%s: write EDID on port %c (spa at 0x%x)\n",
689 __func__, port, spa_loc); 687 __func__, (port == ADV7842_EDID_PORT_A) ? 'A' : 'B', spa_loc);
690 688
691 /* HPA disable on port A and B */ 689 /* HPA disable on port A and B */
692 io_write_and_or(sd, 0x20, 0xcf, 0x00); 690 io_write_and_or(sd, 0x20, 0xcf, 0x00);
@@ -703,44 +701,32 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
703 if (err) 701 if (err)
704 return err; 702 return err;
705 703
706 if (spa_loc > 0) { 704 if (spa_loc < 0)
707 if (port == 0) { 705 spa_loc = 0xc0; /* Default value [REF_02, p. 199] */
708 /* port A SPA */ 706
709 rep_write(sd, 0x72, val[spa_loc]); 707 if (port == ADV7842_EDID_PORT_A) {
710 rep_write(sd, 0x73, val[spa_loc + 1]); 708 rep_write(sd, 0x72, val[spa_loc]);
711 } else { 709 rep_write(sd, 0x73, val[spa_loc + 1]);
712 /* port B SPA */
713 rep_write(sd, 0x74, val[spa_loc]);
714 rep_write(sd, 0x75, val[spa_loc + 1]);
715 }
716 rep_write(sd, 0x76, spa_loc);
717 } else { 710 } else {
718 /* Edid values for SPA location */ 711 rep_write(sd, 0x74, val[spa_loc]);
719 if (port == 0) { 712 rep_write(sd, 0x75, val[spa_loc + 1]);
720 /* port A */
721 rep_write(sd, 0x72, val[0xc0]);
722 rep_write(sd, 0x73, val[0xc1]);
723 } else {
724 /* port B */
725 rep_write(sd, 0x74, val[0xc0]);
726 rep_write(sd, 0x75, val[0xc1]);
727 }
728 rep_write(sd, 0x76, 0xc0);
729 } 713 }
730 rep_write_and_or(sd, 0x77, 0xbf, 0x00); 714 rep_write(sd, 0x76, spa_loc & 0xff);
715 rep_write_and_or(sd, 0x77, 0xbf, (spa_loc >> 2) & 0x40);
731 716
732 /* Calculates the checksums and enables I2C access to internal 717 /* Calculates the checksums and enables I2C access to internal
733 * EDID ram from HDMI DDC ports 718 * EDID ram from HDMI DDC ports
734 */ 719 */
735 rep_write_and_or(sd, 0x77, 0xf3, mask | cur_mask); 720 rep_write_and_or(sd, 0x77, 0xf3, state->hdmi_edid.present);
736 721
737 for (i = 0; i < 1000; i++) { 722 for (i = 0; i < 1000; i++) {
738 if (rep_read(sd, 0x7d) & mask) 723 if (rep_read(sd, 0x7d) & state->hdmi_edid.present)
739 break; 724 break;
740 mdelay(1); 725 mdelay(1);
741 } 726 }
742 if (i == 1000) { 727 if (i == 1000) {
743 v4l_err(client, "error enabling edid on port %d\n", port); 728 v4l_err(client, "error enabling edid on port %c\n",
729 (port == ADV7842_EDID_PORT_A) ? 'A' : 'B');
744 return -EIO; 730 return -EIO;
745 } 731 }
746 732
@@ -1888,7 +1874,7 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
1888 struct adv7842_state *state = to_state(sd); 1874 struct adv7842_state *state = to_state(sd);
1889 int err = 0; 1875 int err = 0;
1890 1876
1891 if (e->pad > 2) 1877 if (e->pad > ADV7842_EDID_PORT_VGA)
1892 return -EINVAL; 1878 return -EINVAL;
1893 if (e->start_block != 0) 1879 if (e->start_block != 0)
1894 return -EINVAL; 1880 return -EINVAL;
@@ -1901,20 +1887,25 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
1901 state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], 1887 state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
1902 e->edid[0x16]); 1888 e->edid[0x16]);
1903 1889
1904 if (e->pad == 2) { 1890 switch (e->pad) {
1891 case ADV7842_EDID_PORT_VGA:
1905 memset(&state->vga_edid.edid, 0, 256); 1892 memset(&state->vga_edid.edid, 0, 256);
1906 state->vga_edid.present = e->blocks ? 0x1 : 0x0; 1893 state->vga_edid.present = e->blocks ? 0x1 : 0x0;
1907 memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks); 1894 memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks);
1908 err = edid_write_vga_segment(sd); 1895 err = edid_write_vga_segment(sd);
1909 } else { 1896 break;
1910 u32 mask = 0x1<<e->pad; 1897 case ADV7842_EDID_PORT_A:
1898 case ADV7842_EDID_PORT_B:
1911 memset(&state->hdmi_edid.edid, 0, 256); 1899 memset(&state->hdmi_edid.edid, 0, 256);
1912 if (e->blocks) 1900 if (e->blocks)
1913 state->hdmi_edid.present |= mask; 1901 state->hdmi_edid.present |= 0x04 << e->pad;
1914 else 1902 else
1915 state->hdmi_edid.present &= ~mask; 1903 state->hdmi_edid.present &= ~(0x04 << e->pad);
1916 memcpy(&state->hdmi_edid.edid, e->edid, 128*e->blocks); 1904 memcpy(&state->hdmi_edid.edid, e->edid, 128 * e->blocks);
1917 err = edid_write_hdmi_segment(sd, e->pad); 1905 err = edid_write_hdmi_segment(sd, e->pad);
1906 break;
1907 default:
1908 return -EINVAL;
1918 } 1909 }
1919 if (err < 0) 1910 if (err < 0)
1920 v4l2_err(sd, "error %d writing edid on port %d\n", err, e->pad); 1911 v4l2_err(sd, "error %d writing edid on port %d\n", err, e->pad);
diff --git a/include/media/adv7842.h b/include/media/adv7842.h
index 24fed1198ce8..a4851bff8fae 100644
--- a/include/media/adv7842.h
+++ b/include/media/adv7842.h
@@ -225,4 +225,8 @@ struct adv7842_platform_data {
225 * deinterlacer. */ 225 * deinterlacer. */
226#define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE) 226#define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE)
227 227
228#define ADV7842_EDID_PORT_A 0
229#define ADV7842_EDID_PORT_B 1
230#define ADV7842_EDID_PORT_VGA 2
231
228#endif 232#endif