aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/adv7604.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/adv7604.c')
-rw-r--r--drivers/media/i2c/adv7604.c393
1 files changed, 285 insertions, 108 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 109bc9b12e74..f47555b1000a 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -53,8 +53,7 @@ MODULE_LICENSE("GPL");
53/* ADV7604 system clock frequency */ 53/* ADV7604 system clock frequency */
54#define ADV7604_fsc (28636360) 54#define ADV7604_fsc (28636360)
55 55
56#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \ 56#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI)
57 (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR))
58 57
59/* 58/*
60 ********************************************************************** 59 **********************************************************************
@@ -68,7 +67,7 @@ struct adv7604_state {
68 struct v4l2_subdev sd; 67 struct v4l2_subdev sd;
69 struct media_pad pad; 68 struct media_pad pad;
70 struct v4l2_ctrl_handler hdl; 69 struct v4l2_ctrl_handler hdl;
71 enum adv7604_prim_mode prim_mode; 70 enum adv7604_mode mode;
72 struct v4l2_dv_timings timings; 71 struct v4l2_dv_timings timings;
73 u8 edid[256]; 72 u8 edid[256];
74 unsigned edid_blocks; 73 unsigned edid_blocks;
@@ -77,6 +76,7 @@ struct adv7604_state {
77 struct workqueue_struct *work_queues; 76 struct workqueue_struct *work_queues;
78 struct delayed_work delayed_work_enable_hotplug; 77 struct delayed_work delayed_work_enable_hotplug;
79 bool connector_hdmi; 78 bool connector_hdmi;
79 bool restart_stdi_once;
80 80
81 /* i2c clients */ 81 /* i2c clients */
82 struct i2c_client *i2c_avlink; 82 struct i2c_client *i2c_avlink;
@@ -106,7 +106,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
106 V4L2_DV_BT_CEA_720X576P50, 106 V4L2_DV_BT_CEA_720X576P50,
107 V4L2_DV_BT_CEA_1280X720P24, 107 V4L2_DV_BT_CEA_1280X720P24,
108 V4L2_DV_BT_CEA_1280X720P25, 108 V4L2_DV_BT_CEA_1280X720P25,
109 V4L2_DV_BT_CEA_1280X720P30,
110 V4L2_DV_BT_CEA_1280X720P50, 109 V4L2_DV_BT_CEA_1280X720P50,
111 V4L2_DV_BT_CEA_1280X720P60, 110 V4L2_DV_BT_CEA_1280X720P60,
112 V4L2_DV_BT_CEA_1920X1080P24, 111 V4L2_DV_BT_CEA_1920X1080P24,
@@ -115,6 +114,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
115 V4L2_DV_BT_CEA_1920X1080P50, 114 V4L2_DV_BT_CEA_1920X1080P50,
116 V4L2_DV_BT_CEA_1920X1080P60, 115 V4L2_DV_BT_CEA_1920X1080P60,
117 116
117 /* sorted by DMT ID */
118 V4L2_DV_BT_DMT_640X350P85, 118 V4L2_DV_BT_DMT_640X350P85,
119 V4L2_DV_BT_DMT_640X400P85, 119 V4L2_DV_BT_DMT_640X400P85,
120 V4L2_DV_BT_DMT_720X400P85, 120 V4L2_DV_BT_DMT_720X400P85,
@@ -164,6 +164,89 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
164 { }, 164 { },
165}; 165};
166 166
167struct adv7604_video_standards {
168 struct v4l2_dv_timings timings;
169 u8 vid_std;
170 u8 v_freq;
171};
172
173/* sorted by number of lines */
174static const struct adv7604_video_standards adv7604_prim_mode_comp[] = {
175 /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */
176 { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
177 { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 },
178 { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 },
179 { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
180 { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
181 { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
182 { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
183 { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
184 /* TODO add 1920x1080P60_RB (CVT timing) */
185 { },
186};
187
188/* sorted by number of lines */
189static const struct adv7604_video_standards adv7604_prim_mode_gr[] = {
190 { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
191 { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
192 { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
193 { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
194 { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
195 { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
196 { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
197 { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
198 { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
199 { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
200 { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
201 { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
202 { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
203 { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
204 { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
205 { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 },
206 { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 },
207 { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 },
208 { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 },
209 { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */
210 /* TODO add 1600X1200P60_RB (not a DMT timing) */
211 { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 },
212 { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */
213 { },
214};
215
216/* sorted by number of lines */
217static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = {
218 { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 },
219 { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
220 { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 },
221 { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 },
222 { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
223 { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
224 { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
225 { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
226 { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
227 { },
228};
229
230/* sorted by number of lines */
231static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = {
232 { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
233 { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
234 { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
235 { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
236 { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
237 { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
238 { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
239 { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
240 { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
241 { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
242 { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
243 { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
244 { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
245 { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
246 { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
247 { },
248};
249
167/* ----------------------------------------------------------------------- */ 250/* ----------------------------------------------------------------------- */
168 251
169static inline struct adv7604_state *to_state(struct v4l2_subdev *sd) 252static inline struct adv7604_state *to_state(struct v4l2_subdev *sd)
@@ -403,9 +486,19 @@ static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val)
403 struct i2c_client *client = state->i2c_edid; 486 struct i2c_client *client = state->i2c_edid;
404 u8 msgbuf0[1] = { 0 }; 487 u8 msgbuf0[1] = { 0 };
405 u8 msgbuf1[256]; 488 u8 msgbuf1[256];
406 struct i2c_msg msg[2] = { { client->addr, 0, 1, msgbuf0 }, 489 struct i2c_msg msg[2] = {
407 { client->addr, 0 | I2C_M_RD, len, msgbuf1 } 490 {
408 }; 491 .addr = client->addr,
492 .len = 1,
493 .buf = msgbuf0
494 },
495 {
496 .addr = client->addr,
497 .flags = I2C_M_RD,
498 .len = len,
499 .buf = msgbuf1
500 },
501 };
409 502
410 if (i2c_transfer(client->adapter, msg, 2) < 0) 503 if (i2c_transfer(client->adapter, msg, 2) < 0)
411 return -EIO; 504 return -EIO;
@@ -672,64 +765,144 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
672 ((io_read(sd, 0x6f) & 0x10) >> 4)); 765 ((io_read(sd, 0x6f) & 0x10) >> 4));
673} 766}
674 767
675static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings) 768static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
769 u8 prim_mode,
770 const struct adv7604_video_standards *predef_vid_timings,
771 const struct v4l2_dv_timings *timings)
676{ 772{
773 struct adv7604_state *state = to_state(sd);
774 int i;
775
776 for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
777 if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings,
778 DIGITAL_INPUT ? 250000 : 1000000))
779 continue;
780 io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
781 io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) +
782 prim_mode); /* v_freq and prim mode */
783 return 0;
784 }
785
786 return -1;
787}
788
789static int configure_predefined_video_timings(struct v4l2_subdev *sd,
790 struct v4l2_dv_timings *timings)
791{
792 struct adv7604_state *state = to_state(sd);
793 int err;
794
795 v4l2_dbg(1, debug, sd, "%s", __func__);
796
797 /* reset to default values */
798 io_write(sd, 0x16, 0x43);
799 io_write(sd, 0x17, 0x5a);
800 /* disable embedded syncs for auto graphics mode */
801 cp_write_and_or(sd, 0x81, 0xef, 0x00);
802 cp_write(sd, 0x8f, 0x00);
803 cp_write(sd, 0x90, 0x00);
804 cp_write(sd, 0xa2, 0x00);
805 cp_write(sd, 0xa3, 0x00);
806 cp_write(sd, 0xa4, 0x00);
807 cp_write(sd, 0xa5, 0x00);
808 cp_write(sd, 0xa6, 0x00);
809 cp_write(sd, 0xa7, 0x00);
810 cp_write(sd, 0xab, 0x00);
811 cp_write(sd, 0xac, 0x00);
812
813 switch (state->mode) {
814 case ADV7604_MODE_COMP:
815 case ADV7604_MODE_GR:
816 err = find_and_set_predefined_video_timings(sd,
817 0x01, adv7604_prim_mode_comp, timings);
818 if (err)
819 err = find_and_set_predefined_video_timings(sd,
820 0x02, adv7604_prim_mode_gr, timings);
821 break;
822 case ADV7604_MODE_HDMI:
823 err = find_and_set_predefined_video_timings(sd,
824 0x05, adv7604_prim_mode_hdmi_comp, timings);
825 if (err)
826 err = find_and_set_predefined_video_timings(sd,
827 0x06, adv7604_prim_mode_hdmi_gr, timings);
828 break;
829 default:
830 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
831 __func__, state->mode);
832 err = -1;
833 break;
834 }
835
836
837 return err;
838}
839
840static void configure_custom_video_timings(struct v4l2_subdev *sd,
841 const struct v4l2_bt_timings *bt)
842{
843 struct adv7604_state *state = to_state(sd);
677 struct i2c_client *client = v4l2_get_subdevdata(sd); 844 struct i2c_client *client = v4l2_get_subdevdata(sd);
678 u32 width = htotal(timings); 845 u32 width = htotal(bt);
679 u32 height = vtotal(timings); 846 u32 height = vtotal(bt);
680 u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ? 847 u16 cp_start_sav = bt->hsync + bt->hbackporch - 4;
681 ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0; 848 u16 cp_start_eav = width - bt->hfrontporch;
849 u16 cp_start_vbi = height - bt->vfrontporch;
850 u16 cp_end_vbi = bt->vsync + bt->vbackporch;
851 u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ?
852 ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0;
853 const u8 pll[2] = {
854 0xc0 | ((width >> 8) & 0x1f),
855 width & 0xff
856 };
682 857
683 v4l2_dbg(2, debug, sd, "%s\n", __func__); 858 v4l2_dbg(2, debug, sd, "%s\n", __func__);
684 859
685 cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */ 860 switch (state->mode) {
686 cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */ 861 case ADV7604_MODE_COMP:
687 cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */ 862 case ADV7604_MODE_GR:
688 cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */ 863 /* auto graphics */
689 /* TODO support interlaced */ 864 io_write(sd, 0x00, 0x07); /* video std */
690 cp_write(sd, 0x91, 0x10); /* INTERLACED */ 865 io_write(sd, 0x01, 0x02); /* prim mode */
691 866 /* enable embedded syncs for auto graphics mode */
692 /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */ 867 cp_write_and_or(sd, 0x81, 0xef, 0x10);
693 if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) {
694 u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi;
695 const u8 pll[2] = {
696 (0xc0 | ((width >> 8) & 0x1f)),
697 (width & 0xff)
698 };
699 868
869 /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
700 /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ 870 /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
701 /* IO-map reg. 0x16 and 0x17 should be written in sequence */ 871 /* IO-map reg. 0x16 and 0x17 should be written in sequence */
702 if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { 872 if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) {
703 v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); 873 v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
704 return; 874 break;
705 } 875 }
706 876
707 /* active video - horizontal timing */ 877 /* active video - horizontal timing */
708 cp_start_sav = timings->hsync + timings->hbackporch - 4;
709 cp_start_eav = width - timings->hfrontporch;
710 cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff); 878 cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff);
711 cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f)); 879 cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) |
880 ((cp_start_eav >> 8) & 0x0f));
712 cp_write(sd, 0xa4, cp_start_eav & 0xff); 881 cp_write(sd, 0xa4, cp_start_eav & 0xff);
713 882
714 /* active video - vertical timing */ 883 /* active video - vertical timing */
715 cp_start_vbi = height - timings->vfrontporch;
716 cp_end_vbi = timings->vsync + timings->vbackporch;
717 cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff); 884 cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
718 cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf)); 885 cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) |
886 ((cp_end_vbi >> 8) & 0xf));
719 cp_write(sd, 0xa7, cp_end_vbi & 0xff); 887 cp_write(sd, 0xa7, cp_end_vbi & 0xff);
720 } else { 888 break;
721 /* reset to default values */ 889 case ADV7604_MODE_HDMI:
722 io_write(sd, 0x16, 0x43); 890 /* set default prim_mode/vid_std for HDMI
723 io_write(sd, 0x17, 0x5a); 891 accoring to [REF_03, c. 4.2] */
724 cp_write(sd, 0xa2, 0x00); 892 io_write(sd, 0x00, 0x02); /* video std */
725 cp_write(sd, 0xa3, 0x00); 893 io_write(sd, 0x01, 0x06); /* prim mode */
726 cp_write(sd, 0xa4, 0x00); 894 break;
727 cp_write(sd, 0xa5, 0x00); 895 default:
728 cp_write(sd, 0xa6, 0x00); 896 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
729 cp_write(sd, 0xa7, 0x00); 897 __func__, state->mode);
898 break;
730 } 899 }
731}
732 900
901 cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);
902 cp_write(sd, 0x90, ch1_fr_ll & 0xff);
903 cp_write(sd, 0xab, (height >> 4) & 0xff);
904 cp_write(sd, 0xac, (height & 0x0f) << 4);
905}
733 906
734static void set_rgb_quantization_range(struct v4l2_subdev *sd) 907static void set_rgb_quantization_range(struct v4l2_subdev *sd)
735{ 908{
@@ -738,12 +911,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
738 switch (state->rgb_quantization_range) { 911 switch (state->rgb_quantization_range) {
739 case V4L2_DV_RGB_RANGE_AUTO: 912 case V4L2_DV_RGB_RANGE_AUTO:
740 /* automatic */ 913 /* automatic */
741 if ((hdmi_read(sd, 0x05) & 0x80) || 914 if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) {
742 (state->prim_mode == ADV7604_PRIM_MODE_COMP) ||
743 (state->prim_mode == ADV7604_PRIM_MODE_RGB)) {
744 /* receiving HDMI or analog signal */
745 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
746 } else {
747 /* receiving DVI-D signal */ 915 /* receiving DVI-D signal */
748 916
749 /* ADV7604 selects RGB limited range regardless of 917 /* ADV7604 selects RGB limited range regardless of
@@ -756,6 +924,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
756 /* RGB full range (0-255) */ 924 /* RGB full range (0-255) */
757 io_write_and_or(sd, 0x02, 0x0f, 0x10); 925 io_write_and_or(sd, 0x02, 0x0f, 0x10);
758 } 926 }
927 } else {
928 /* receiving HDMI or analog signal, set automode */
929 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
759 } 930 }
760 break; 931 break;
761 case V4L2_DV_RGB_RANGE_LIMITED: 932 case V4L2_DV_RGB_RANGE_LIMITED:
@@ -967,8 +1138,10 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
967 state->aspect_ratio, timings)) 1138 state->aspect_ratio, timings))
968 return 0; 1139 return 0;
969 1140
970 v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n", 1141 v4l2_dbg(2, debug, sd,
971 __func__, stdi->lcf, stdi->bl); 1142 "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n",
1143 __func__, stdi->lcvs, stdi->lcf, stdi->bl,
1144 stdi->hs_pol, stdi->vs_pol);
972 return -1; 1145 return -1;
973} 1146}
974 1147
@@ -1123,7 +1296,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1123 adv7604_fill_optional_dv_timings_fields(sd, timings); 1296 adv7604_fill_optional_dv_timings_fields(sd, timings);
1124 } else { 1297 } else {
1125 /* find format 1298 /* find format
1126 * Since LCVS values are inaccurate (REF_03, page 275-276), 1299 * Since LCVS values are inaccurate [REF_03, p. 275-276],
1127 * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails. 1300 * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
1128 */ 1301 */
1129 if (!stdi2dv_timings(sd, &stdi, timings)) 1302 if (!stdi2dv_timings(sd, &stdi, timings))
@@ -1135,9 +1308,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1135 stdi.lcvs -= 2; 1308 stdi.lcvs -= 2;
1136 v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs); 1309 v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
1137 if (stdi2dv_timings(sd, &stdi, timings)) { 1310 if (stdi2dv_timings(sd, &stdi, timings)) {
1311 /*
1312 * The STDI block may measure wrong values, especially
1313 * for lcvs and lcf. If the driver can not find any
1314 * valid timing, the STDI block is restarted to measure
1315 * the video timings again. The function will return an
1316 * error, but the restart of STDI will generate a new
1317 * STDI interrupt and the format detection process will
1318 * restart.
1319 */
1320 if (state->restart_stdi_once) {
1321 v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
1322 /* TODO restart STDI for Sync Channel 2 */
1323 /* enter one-shot mode */
1324 cp_write_and_or(sd, 0x86, 0xf9, 0x00);
1325 /* trigger STDI restart */
1326 cp_write_and_or(sd, 0x86, 0xf9, 0x04);
1327 /* reset to continuous mode */
1328 cp_write_and_or(sd, 0x86, 0xf9, 0x02);
1329 state->restart_stdi_once = false;
1330 return -ENOLINK;
1331 }
1138 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); 1332 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
1139 return -ERANGE; 1333 return -ERANGE;
1140 } 1334 }
1335 state->restart_stdi_once = true;
1141 } 1336 }
1142found: 1337found:
1143 1338
@@ -1166,6 +1361,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
1166{ 1361{
1167 struct adv7604_state *state = to_state(sd); 1362 struct adv7604_state *state = to_state(sd);
1168 struct v4l2_bt_timings *bt; 1363 struct v4l2_bt_timings *bt;
1364 int err;
1169 1365
1170 if (!timings) 1366 if (!timings)
1171 return -EINVAL; 1367 return -EINVAL;
@@ -1178,12 +1374,20 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
1178 __func__, (u32)bt->pixelclock); 1374 __func__, (u32)bt->pixelclock);
1179 return -ERANGE; 1375 return -ERANGE;
1180 } 1376 }
1377
1181 adv7604_fill_optional_dv_timings_fields(sd, timings); 1378 adv7604_fill_optional_dv_timings_fields(sd, timings);
1182 1379
1183 state->timings = *timings; 1380 state->timings = *timings;
1184 1381
1185 /* freerun */ 1382 cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10);
1186 configure_free_run(sd, bt); 1383
1384 /* Use prim_mode and vid_std when available */
1385 err = configure_predefined_video_timings(sd, timings);
1386 if (err) {
1387 /* custom settings when the video format
1388 does not have prim_mode/vid_std */
1389 configure_custom_video_timings(sd, bt);
1390 }
1187 1391
1188 set_rgb_quantization_range(sd); 1392 set_rgb_quantization_range(sd);
1189 1393
@@ -1203,24 +1407,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
1203 return 0; 1407 return 0;
1204} 1408}
1205 1409
1206static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) 1410static void enable_input(struct v4l2_subdev *sd)
1207{ 1411{
1208 switch (prim_mode) { 1412 struct adv7604_state *state = to_state(sd);
1209 case ADV7604_PRIM_MODE_COMP: 1413
1210 case ADV7604_PRIM_MODE_RGB: 1414 switch (state->mode) {
1415 case ADV7604_MODE_COMP:
1416 case ADV7604_MODE_GR:
1211 /* enable */ 1417 /* enable */
1212 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ 1418 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
1213 break; 1419 break;
1214 case ADV7604_PRIM_MODE_HDMI_COMP: 1420 case ADV7604_MODE_HDMI:
1215 case ADV7604_PRIM_MODE_HDMI_GR:
1216 /* enable */ 1421 /* enable */
1217 hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */ 1422 hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
1218 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ 1423 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
1219 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ 1424 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
1220 break; 1425 break;
1221 default: 1426 default:
1222 v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", 1427 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
1223 __func__, prim_mode); 1428 __func__, state->mode);
1224 break; 1429 break;
1225 } 1430 }
1226} 1431}
@@ -1233,17 +1438,13 @@ static void disable_input(struct v4l2_subdev *sd)
1233 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ 1438 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
1234} 1439}
1235 1440
1236static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) 1441static void select_input(struct v4l2_subdev *sd)
1237{ 1442{
1238 switch (prim_mode) { 1443 struct adv7604_state *state = to_state(sd);
1239 case ADV7604_PRIM_MODE_COMP:
1240 case ADV7604_PRIM_MODE_RGB:
1241 /* set mode and select free run resolution */
1242 io_write(sd, 0x00, 0x07); /* video std */
1243 io_write(sd, 0x01, 0x02); /* prim mode */
1244 /* enable embedded syncs for auto graphics mode */
1245 cp_write_and_or(sd, 0x81, 0xef, 0x10);
1246 1444
1445 switch (state->mode) {
1446 case ADV7604_MODE_COMP:
1447 case ADV7604_MODE_GR:
1247 /* reset ADI recommended settings for HDMI: */ 1448 /* reset ADI recommended settings for HDMI: */
1248 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ 1449 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
1249 hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */ 1450 hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
@@ -1271,16 +1472,7 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
1271 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ 1472 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
1272 break; 1473 break;
1273 1474
1274 case ADV7604_PRIM_MODE_HDMI_COMP: 1475 case ADV7604_MODE_HDMI:
1275 case ADV7604_PRIM_MODE_HDMI_GR:
1276 /* set mode and select free run resolution */
1277 /* video std */
1278 io_write(sd, 0x00,
1279 (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e);
1280 io_write(sd, 0x01, prim_mode); /* prim mode */
1281 /* disable embedded syncs for auto graphics mode */
1282 cp_write_and_or(sd, 0x81, 0xef, 0x00);
1283
1284 /* set ADI recommended settings for HDMI: */ 1476 /* set ADI recommended settings for HDMI: */
1285 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ 1477 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
1286 hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ 1478 hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */
@@ -1309,7 +1501,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
1309 1501
1310 break; 1502 break;
1311 default: 1503 default:
1312 v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode); 1504 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
1505 __func__, state->mode);
1313 break; 1506 break;
1314 } 1507 }
1315} 1508}
@@ -1321,26 +1514,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
1321 1514
1322 v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); 1515 v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input);
1323 1516
1324 switch (input) { 1517 state->mode = input;
1325 case 0:
1326 /* TODO select HDMI_COMP or HDMI_GR */
1327 state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP;
1328 break;
1329 case 1:
1330 state->prim_mode = ADV7604_PRIM_MODE_RGB;
1331 break;
1332 case 2:
1333 state->prim_mode = ADV7604_PRIM_MODE_COMP;
1334 break;
1335 default:
1336 return -EINVAL;
1337 }
1338 1518
1339 disable_input(sd); 1519 disable_input(sd);
1340 1520
1341 select_input(sd, state->prim_mode); 1521 select_input(sd);
1342 1522
1343 enable_input(sd, state->prim_mode); 1523 enable_input(sd);
1344 1524
1345 return 0; 1525 return 0;
1346} 1526}
@@ -1549,8 +1729,9 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
1549 v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); 1729 v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true");
1550 v4l2_info(sd, "CP free run: %s\n", 1730 v4l2_info(sd, "CP free run: %s\n",
1551 (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off")); 1731 (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off"));
1552 v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n", 1732 v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n",
1553 io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f); 1733 io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f,
1734 (io_read(sd, 0x01) & 0x70) >> 4);
1554 1735
1555 v4l2_info(sd, "-----Video Timings-----\n"); 1736 v4l2_info(sd, "-----Video Timings-----\n");
1556 if (read_stdi(sd, &stdi)) 1737 if (read_stdi(sd, &stdi))
@@ -1712,9 +1893,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
1712 cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */ 1893 cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */
1713 cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */ 1894 cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */
1714 cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold - 1895 cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold -
1715 ADI recommended setting [REF_01 c. 2.3.3] */ 1896 ADI recommended setting [REF_01, c. 2.3.3] */
1716 cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold - 1897 cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold -
1717 ADI recommended setting [REF_01 c. 2.3.3] */ 1898 ADI recommended setting [REF_01, c. 2.3.3] */
1718 cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution 1899 cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution
1719 for digital formats */ 1900 for digital formats */
1720 1901
@@ -1724,11 +1905,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
1724 afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ 1905 afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
1725 io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); 1906 io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4);
1726 1907
1727 state->prim_mode = pdata->prim_mode;
1728 select_input(sd, pdata->prim_mode);
1729
1730 enable_input(sd, pdata->prim_mode);
1731
1732 /* interrupts */ 1908 /* interrupts */
1733 io_write(sd, 0x40, 0xc2); /* Configure INT1 */ 1909 io_write(sd, 0x40, 0xc2); /* Configure INT1 */
1734 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ 1910 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
@@ -1883,6 +2059,7 @@ static int adv7604_probe(struct i2c_client *client,
1883 v4l2_err(sd, "failed to create all i2c clients\n"); 2059 v4l2_err(sd, "failed to create all i2c clients\n");
1884 goto err_i2c; 2060 goto err_i2c;
1885 } 2061 }
2062 state->restart_stdi_once = true;
1886 2063
1887 /* work queues */ 2064 /* work queues */
1888 state->work_queues = create_singlethread_workqueue(client->name); 2065 state->work_queues = create_singlethread_workqueue(client->name);