1111#include <linux/i2c.h>
1212#include <linux/interrupt.h>
1313#include <linux/kernel.h>
14+ #include <linux/math64.h>
1415#include <linux/mfd/rk628.h>
1516#include <linux/module.h>
1617#include <linux/of_graph.h>
@@ -104,6 +105,7 @@ struct rk628_csi {
104105 struct regmap * csi_regmap ;
105106 struct delayed_work delayed_work_enable_hotplug ;
106107 struct delayed_work delayed_work_res_change ;
108+ struct delayed_work delayed_work_audio ;
107109 struct timer_list timer ;
108110 struct work_struct work_i2c_poll ;
109111 struct phy * rxphy ;
@@ -118,12 +120,14 @@ struct rk628_csi {
118120 u64 lane_mbps ;
119121 u8 csi_lanes_in_use ;
120122 u32 mbus_fmt_code ;
123+ u64 fs_audio ;
121124 int hdmirx_irq ;
122125 int plugin_irq ;
123126 bool nosignal ;
124127 bool rxphy_pwron ;
125128 bool txphy_pwron ;
126129 bool enable_hdcp ;
130+ bool audio_present ;
127131};
128132
129133struct rk628_csi_mode {
@@ -257,6 +261,7 @@ static void rk628_csi_enable_edid(struct v4l2_subdev *sd);
257261static void rk628_csi_disable_edid (struct v4l2_subdev * sd );
258262static void rk628_csi_format_change (struct v4l2_subdev * sd );
259263static void enable_stream (struct v4l2_subdev * sd , bool enable );
264+ static void rk628_hdmirx_audio_setup (struct v4l2_subdev * sd );
260265
261266static inline struct rk628_csi * to_csi (struct v4l2_subdev * sd )
262267{
@@ -283,17 +288,19 @@ static inline bool no_signal(struct v4l2_subdev *sd)
283288
284289static inline bool audio_present (struct v4l2_subdev * sd )
285290{
286- return true;
291+ struct rk628_csi * csi = to_csi (sd );
292+
293+ return csi -> audio_present ;
287294}
288295
289296static int get_audio_sampling_rate (struct v4l2_subdev * sd )
290297{
291- static const int code_to_rate [] = { 44100 } ;
298+ struct rk628_csi * csi = to_csi ( sd ) ;
292299
293300 if (no_signal (sd ))
294301 return 0 ;
295302
296- return code_to_rate [ 0 ] ;
303+ return csi -> fs_audio ;
297304}
298305
299306static int rk628_csi_get_detected_timings (struct v4l2_subdev * sd ,
@@ -420,12 +427,18 @@ static void rk628_csi_delayed_work_enable_hotplug(struct work_struct *work)
420427
421428 csi -> nosignal = false;
422429 rk628_csi_enable_interrupts (sd , true);
430+ regmap_update_bits (csi -> grf , GRF_SYSTEM_CON0 ,
431+ SW_I2S_DATA_OEN_MASK , SW_I2S_DATA_OEN (0 ));
432+ schedule_delayed_work (& csi -> delayed_work_audio , 0 );
423433 } else {
424434 rk628_csi_enable_interrupts (sd , false);
425435 enable_stream (sd , false);
426436 cancel_delayed_work (& csi -> delayed_work_res_change );
427437 rk628_csi_disable_edid (sd );
428438 csi -> nosignal = true;
439+ regmap_update_bits (csi -> grf , GRF_SYSTEM_CON0 ,
440+ SW_I2S_DATA_OEN_MASK , SW_I2S_DATA_OEN (1 ));
441+ cancel_delayed_work (& csi -> delayed_work_audio );
429442 }
430443}
431444
@@ -931,6 +944,165 @@ static void rk628_hdmirx_controller_reset(struct v4l2_subdev *sd)
931944 regmap_write (csi -> hdmirx_regmap , HDMI_RX_DMI_DISABLE_IF , 0x000101ff );
932945}
933946
947+ static void rk628_hdmirx_audio_setup (struct v4l2_subdev * sd )
948+ {
949+ struct rk628_csi * csi = to_csi (sd );
950+ u32 audio_pll_n , audio_pll_cts ;
951+
952+ audio_pll_n = 5644 ;
953+ audio_pll_cts = 148500 ;
954+
955+ clk_set_rate (csi -> clk_hdmirx_aud , 5644800 );
956+
957+ /* manual aud CTS */
958+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_AUDPLL_GEN_CTS , audio_pll_cts );
959+ /* manual aud N */
960+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_AUDPLL_GEN_N , audio_pll_n );
961+
962+ /* aud CTS N en manual */
963+ regmap_update_bits (csi -> hdmirx_regmap , HDMI_RX_AUD_CLK_CTRL ,
964+ CTS_N_REF_MASK , CTS_N_REF (1 ));
965+ /* aud pll ctrl */
966+ regmap_update_bits (csi -> hdmirx_regmap , HDMI_RX_AUD_PLL_CTRL ,
967+ PLL_LOCK_TOGGLE_DIV_MASK , PLL_LOCK_TOGGLE_DIV (0 ));
968+ regmap_update_bits (csi -> hdmirx_regmap , HDMI_RX_AUD_FIFO_TH ,
969+ AFIF_TH_START_MASK |
970+ AFIF_TH_MAX_MASK |
971+ AFIF_TH_MIN_MASK ,
972+ AFIF_TH_START (64 ) |
973+ AFIF_TH_MAX (8 ) |
974+ AFIF_TH_MIN (8 ));
975+
976+ /* AUTO_VMUTE */
977+ regmap_update_bits (csi -> hdmirx_regmap , HDMI_RX_AUD_FIFO_CTRL ,
978+ AFIF_SUBPACKET_DESEL_MASK |
979+ AFIF_SUBPACKETS_MASK ,
980+ AFIF_SUBPACKET_DESEL (0 ) |
981+ AFIF_SUBPACKETS (1 ));
982+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_AUD_SAO_CTRL ,
983+ I2S_LPCM_BPCUV (0 ) |
984+ I2S_32_16 (1 ));
985+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_AUD_MUTE_CTRL ,
986+ APPLY_INT_MUTE (0 ) |
987+ APORT_SHDW_CTRL (3 ) |
988+ AUTO_ACLK_MUTE (2 ) |
989+ AUD_MUTE_SPEED (1 ) |
990+ AUD_AVMUTE_EN (1 ) |
991+ AUD_MUTE_SEL (1 ) |
992+ AUD_MUTE_MODE (1 ));
993+
994+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_AUD_PAO_CTRL ,
995+ PAO_RATE (0 ));
996+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_AUD_CHEXTR_CTRL ,
997+ AUD_LAYOUT_CTRL (1 ));
998+
999+ /* audio detect */
1000+ regmap_write (csi -> hdmirx_regmap , HDMI_RX_PDEC_AUDIODET_CTRL ,
1001+ AUDIODET_THRESHOLD (0 ));
1002+ }
1003+
1004+ static void rk628_csi_delayed_work_audio (struct work_struct * work )
1005+ {
1006+ struct delayed_work * dwork = to_delayed_work (work );
1007+ struct rk628_csi * csi = container_of (dwork , struct rk628_csi ,
1008+ delayed_work_audio );
1009+ struct v4l2_subdev * sd = & csi -> sd ;
1010+ u32 val ;
1011+ static int hdmirx_aud_clkrate = 5644800 ,
1012+ init_state = 256 , pre_state , cur_state ;
1013+ u32 clkrate = 0 , cts_decoded = 0 , n_decoded = 0 ;
1014+ u64 tmdsclk = 0 , fs_audio = 0 ;
1015+ static u64 pre_fs_audio ;
1016+
1017+ /* fout=128*fs=ftmds*N/CTS */
1018+ regmap_read (csi -> hdmirx_regmap , HDMI_RX_HDMI_CKM_RESULT , & clkrate );
1019+ clkrate = clkrate & 0xfff ;
1020+ /* tmdsclk = (clkrate/1000) * 49500000 */
1021+ tmdsclk = clkrate * (49500000 / 1000 );
1022+ regmap_read (csi -> hdmirx_regmap , HDMI_RX_PDEC_ACR_CTS , & cts_decoded );
1023+ regmap_read (csi -> hdmirx_regmap , HDMI_RX_PDEC_ACR_N , & n_decoded );
1024+ /* fs_audio = ((tmdsclk * n_decoded) / cts_decoded ) / 128 */
1025+ if (cts_decoded != 0 ) {
1026+ fs_audio = div_u64 ((tmdsclk * n_decoded ), cts_decoded );
1027+ fs_audio = div_u64 (fs_audio , 128 );
1028+ }
1029+ v4l2_dbg (1 , debug , sd ,
1030+ "%s: clkrate:%d tmdsclk:%llu, n_decoded:%d, cts_decoded:%d, fs_audio:%llu\n" ,
1031+ __func__ , clkrate , tmdsclk , n_decoded , cts_decoded , fs_audio );
1032+ if ((fs_audio != 0 ) && (abs (fs_audio - pre_fs_audio ) > 1000 )) {
1033+ hdmirx_aud_clkrate = 128 * fs_audio ;
1034+ switch (fs_audio ) {
1035+ case 88200 :
1036+ hdmirx_aud_clkrate = 11111000 ;
1037+ break ;
1038+ case 96000 :
1039+ hdmirx_aud_clkrate = 12121000 ;
1040+ break ;
1041+ case 176400 :
1042+ hdmirx_aud_clkrate = 22222000 ;
1043+ break ;
1044+ case 192000 :
1045+ hdmirx_aud_clkrate = 23529000 ;
1046+ break ;
1047+ default :
1048+ break ;
1049+ }
1050+ clk_set_rate (csi -> clk_hdmirx_aud , hdmirx_aud_clkrate );
1051+ v4l2_dbg (1 , debug , sd ,
1052+ "%s: audo switch clk_hdmirx_aud to %d fs_audio:%llu pre_fs_audio:%llu\n" ,
1053+ __func__ , hdmirx_aud_clkrate , fs_audio , pre_fs_audio );
1054+ if (pre_fs_audio != 0 ) {
1055+ regmap_write (csi -> hdmirx_regmap ,
1056+ HDMI_RX_AUD_FIFO_ICLR , 0x1f );
1057+ regmap_write (csi -> hdmirx_regmap ,
1058+ HDMI_RX_AUD_FIFO_CTRL , 0x10001 );
1059+ regmap_write (csi -> hdmirx_regmap ,
1060+ HDMI_RX_AUD_FIFO_CTRL , 0x10000 );
1061+ }
1062+ pre_fs_audio = fs_audio ;
1063+ csi -> fs_audio = fs_audio ;
1064+ }
1065+
1066+ regmap_read (csi -> hdmirx_regmap , HDMI_RX_AUD_FIFO_FILLSTS1 , & cur_state );
1067+ v4l2_dbg (1 , debug , sd ,
1068+ "%s: HDMI_RX_AUD_FIFO_FILLSTS1:%#x, single offset:%d, total offset:%d\n" ,
1069+ __func__ , cur_state , cur_state - pre_state , cur_state - init_state );
1070+ if (cur_state != 0 )
1071+ csi -> audio_present = true;
1072+ else
1073+ csi -> audio_present = false;
1074+ if ((cur_state - init_state ) > 16 && (cur_state - pre_state ) > 0 ) {
1075+ hdmirx_aud_clkrate += 10 ;
1076+ clk_set_rate (csi -> clk_hdmirx_aud , hdmirx_aud_clkrate );
1077+ v4l2_dbg (1 , debug , sd , "%s: (cur_state-init_state) > 16 hdmirx_aud_clkrate:%d\n" ,
1078+ __func__ , hdmirx_aud_clkrate );
1079+ } else if ((cur_state != 0 ) && (cur_state - init_state ) < -16 && (cur_state - pre_state ) < 0 ) {
1080+ hdmirx_aud_clkrate -= 10 ;
1081+ clk_set_rate (csi -> clk_hdmirx_aud , hdmirx_aud_clkrate );
1082+ v4l2_dbg (1 , debug , sd , "%s: (cur_state-init_state) < -16 hdmirx_aud_clkrate:%d\n" ,
1083+ __func__ , hdmirx_aud_clkrate );
1084+ }
1085+ pre_state = cur_state ;
1086+
1087+ regmap_read (csi -> hdmirx_regmap , HDMI_RX_AUD_FIFO_ISTS , & val );
1088+ v4l2_dbg (1 , debug , sd , "%s: HDMI_RX_AUD_FIFO_ISTS:%#x\n" , __func__ , val );
1089+ if ((val != 0x9 ) && ((val & 0x10 ) || (val & 0x8 ))) {
1090+ regmap_write (csi -> hdmirx_regmap ,
1091+ HDMI_RX_AUD_FIFO_ICLR , 0x1f );
1092+ regmap_write (csi -> hdmirx_regmap ,
1093+ HDMI_RX_AUD_FIFO_CTRL , 0x10001 );
1094+ /*msleep(1);*/
1095+ regmap_write (csi -> hdmirx_regmap ,
1096+ HDMI_RX_AUD_FIFO_CTRL , 0x10000 );
1097+ pre_state = cur_state = 0 ;
1098+
1099+ v4l2_err (sd , "%s: HDMI_RX_AUD_FIFO_ISTS:%#x, underflow or overflow\n" ,
1100+ __func__ , val );
1101+ }
1102+
1103+ schedule_delayed_work (& csi -> delayed_work_audio , msecs_to_jiffies (1000 ));
1104+ }
1105+
9341106static void rk628_hdmirx_controller_setup (struct v4l2_subdev * sd )
9351107{
9361108 struct rk628_csi * csi = to_csi (sd );
@@ -1078,12 +1250,17 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
10781250 def_edid .edid = edid_init_data ;
10791251 rk628_csi_s_edid (sd , & def_edid );
10801252 rk628_csi_set_hdmi_hdcp (sd , csi -> enable_hdcp );
1253+ rk628_hdmirx_audio_setup (sd );
10811254
10821255 if (tx_5v_power_present (sd )) {
10831256 rk628_hdmirx_controller_setup (sd );
10841257 ret = rk628_hdmirx_phy_setup (sd );
10851258 if (ret >= 0 )
10861259 rk628_csi_format_change (sd );
1260+
1261+ regmap_update_bits (csi -> grf , GRF_SYSTEM_CON0 ,
1262+ SW_I2S_DATA_OEN_MASK , SW_I2S_DATA_OEN (0 ));
1263+ schedule_delayed_work (& csi -> delayed_work_audio , msecs_to_jiffies (1000 ));
10871264 }
10881265}
10891266
@@ -2204,11 +2381,23 @@ static const struct regmap_range rk628_hdmirx_readable_ranges[] = {
22042381 regmap_reg_range (HDMI_RX_MD_VCTRL , HDMI_RX_MD_VSC ),
22052382 regmap_reg_range (HDMI_RX_MD_VOL , HDMI_RX_MD_VTL ),
22062383 regmap_reg_range (HDMI_RX_MD_IL_POL , HDMI_RX_MD_STS ),
2384+ regmap_reg_range (HDMI_RX_AUD_CTRL , HDMI_RX_AUD_CTRL ),
2385+ regmap_reg_range (HDMI_RX_AUD_PLL_CTRL , HDMI_RX_AUD_PLL_CTRL ),
2386+ regmap_reg_range (HDMI_RX_AUD_CLK_CTRL , HDMI_RX_AUD_CLK_CTRL ),
2387+ regmap_reg_range (HDMI_RX_AUD_FIFO_CTRL , HDMI_RX_AUD_FIFO_TH ),
2388+ regmap_reg_range (HDMI_RX_AUD_CHEXTR_CTRL , HDMI_RX_AUD_PAO_CTRL ),
2389+ regmap_reg_range (HDMI_RX_AUD_FIFO_STS , HDMI_RX_AUD_FIFO_STS ),
2390+ regmap_reg_range (HDMI_RX_AUDPLL_GEN_CTS , HDMI_RX_AUDPLL_GEN_N ),
2391+ regmap_reg_range (HDMI_RX_PDEC_AUDIODET_CTRL , HDMI_RX_PDEC_AUDIODET_CTRL ),
22072392 regmap_reg_range (HDMI_RX_PDEC_ERR_FILTER , HDMI_RX_PDEC_ASP_CTRL ),
2393+ regmap_reg_range (HDMI_RX_PDEC_ACR_CTS , HDMI_RX_PDEC_ACR_N ),
2394+ regmap_reg_range (HDMI_RX_PDEC_AIF_CTRL , HDMI_RX_PDEC_AIF_PB0 ),
22082395 regmap_reg_range (HDMI_RX_PDEC_AVI_PB , HDMI_RX_PDEC_AVI_PB ),
22092396 regmap_reg_range (HDMI_RX_HDMI20_CONTROL , HDMI_RX_CHLOCK_CONFIG ),
22102397 regmap_reg_range (HDMI_RX_SCDC_REGS1 , HDMI_RX_SCDC_REGS2 ),
22112398 regmap_reg_range (HDMI_RX_SCDC_WRDATA0 , HDMI_RX_SCDC_WRDATA0 ),
2399+ regmap_reg_range (HDMI_RX_AUD_FIFO_ISTS , HDMI_RX_AUD_FIFO_IEN ),
2400+ regmap_reg_range (HDMI_RX_DMI_DISABLE_IF , HDMI_RX_DMI_DISABLE_IF ),
22122401 regmap_reg_range (HDMI_RX_MD_ISTS , HDMI_RX_MD_IEN ),
22132402 regmap_reg_range (HDMI_RX_HDMI_ISTS , HDMI_RX_HDMI_IEN ),
22142403 regmap_reg_range (HDMI_RX_DMI_DISABLE_IF , HDMI_RX_DMI_DISABLE_IF ),
@@ -2395,6 +2584,8 @@ static int rk628_csi_probe(struct platform_device *pdev)
23952584 rk628_csi_delayed_work_enable_hotplug );
23962585 INIT_DELAYED_WORK (& csi -> delayed_work_res_change ,
23972586 rk628_delayed_work_res_change );
2587+ INIT_DELAYED_WORK (& csi -> delayed_work_audio ,
2588+ rk628_csi_delayed_work_audio );
23982589 rk628_csi_initial_setup (sd );
23992590
24002591 if (csi -> hdmirx_irq ) {
@@ -2450,6 +2641,7 @@ static int rk628_csi_probe(struct platform_device *pdev)
24502641 flush_work (& csi -> work_i2c_poll );
24512642 cancel_delayed_work (& csi -> delayed_work_enable_hotplug );
24522643 cancel_delayed_work (& csi -> delayed_work_res_change );
2644+ cancel_delayed_work (& csi -> delayed_work_audio );
24532645err_hdl :
24542646 mutex_destroy (& csi -> confctl_mutex );
24552647 media_entity_cleanup (& sd -> entity );
@@ -2468,6 +2660,7 @@ static int rk628_csi_remove(struct platform_device *pdev)
24682660 }
24692661 cancel_delayed_work_sync (& csi -> delayed_work_enable_hotplug );
24702662 cancel_delayed_work_sync (& csi -> delayed_work_res_change );
2663+ cancel_delayed_work_sync (& csi -> delayed_work_audio );
24712664
24722665 if (csi -> rxphy_pwron )
24732666 phy_power_off (csi -> rxphy );
0 commit comments