diff options
-rw-r--r-- | src/rhd.h | 1 | ||||
-rw-r--r-- | src/rhd_atomout.c | 10 | ||||
-rw-r--r-- | src/rhd_audio.c | 32 | ||||
-rw-r--r-- | src/rhd_audio.h | 1 | ||||
-rw-r--r-- | src/rhd_dig.c | 11 | ||||
-rw-r--r-- | src/rhd_driver.c | 4 | ||||
-rw-r--r-- | src/rhd_hdmi.c | 116 | ||||
-rw-r--r-- | src/rhd_hdmi.h | 10 | ||||
-rw-r--r-- | src/rhd_lvtma.c | 10 | ||||
-rw-r--r-- | src/rhd_output.c | 19 | ||||
-rw-r--r-- | src/rhd_output.h | 3 | ||||
-rw-r--r-- | src/rhd_randr.c | 52 | ||||
-rw-r--r-- | src/rhd_regs.h | 1 | ||||
-rw-r--r-- | src/rhd_tmds.c | 10 |
14 files changed, 237 insertions, 43 deletions
@@ -247,6 +247,7 @@ typedef struct RHDRec { | |||
247 | RHDOpt scaleTypeOpt; | 247 | RHDOpt scaleTypeOpt; |
248 | RHDOpt unverifiedFeatures; | 248 | RHDOpt unverifiedFeatures; |
249 | RHDOpt audio; | 249 | RHDOpt audio; |
250 | RHDOpt audioWorkaround; | ||
250 | RHDOpt hdmi; | 251 | RHDOpt hdmi; |
251 | RHDOpt coherent; | 252 | RHDOpt coherent; |
252 | RHDOpt lowPowerMode; | 253 | RHDOpt lowPowerMode; |
diff --git a/src/rhd_atomout.c b/src/rhd_atomout.c index b88b1bd..9d50ade 100644 --- a/src/rhd_atomout.c +++ b/src/rhd_atomout.c | |||
@@ -745,6 +745,7 @@ atomTMDSPropertyControl(struct rhdOutput *Output, | |||
745 | switch (Property) { | 745 | switch (Property) { |
746 | case RHD_OUTPUT_COHERENT: | 746 | case RHD_OUTPUT_COHERENT: |
747 | case RHD_OUTPUT_HDMI: | 747 | case RHD_OUTPUT_HDMI: |
748 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
748 | return TRUE; | 749 | return TRUE; |
749 | default: | 750 | default: |
750 | return FALSE; | 751 | return FALSE; |
@@ -757,6 +758,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output, | |||
757 | case RHD_OUTPUT_HDMI: | 758 | case RHD_OUTPUT_HDMI: |
758 | val->Bool = atomIsHdmiEnabled(Output); | 759 | val->Bool = atomIsHdmiEnabled(Output); |
759 | return TRUE; | 760 | return TRUE; |
761 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
762 | val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi); | ||
763 | return TRUE; | ||
760 | default: | 764 | default: |
761 | return FALSE; | 765 | return FALSE; |
762 | } | 766 | } |
@@ -769,6 +773,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output, | |||
769 | case RHD_OUTPUT_HDMI: | 773 | case RHD_OUTPUT_HDMI: |
770 | atomSetHdmiEnabled(Output, val->Bool); | 774 | atomSetHdmiEnabled(Output, val->Bool); |
771 | break; | 775 | break; |
776 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
777 | RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool); | ||
778 | break; | ||
772 | default: | 779 | default: |
773 | return FALSE; | 780 | return FALSE; |
774 | } | 781 | } |
@@ -780,6 +787,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output, | |||
780 | Output->Mode(Output, Private->Mode); | 787 | Output->Mode(Output, Private->Mode); |
781 | Output->Power(Output, RHD_POWER_ON); | 788 | Output->Power(Output, RHD_POWER_ON); |
782 | break; | 789 | break; |
790 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
791 | RHDHdmiCommitAudioWorkaround(Private->Hdmi); | ||
792 | break; | ||
783 | default: | 793 | default: |
784 | return FALSE; | 794 | return FALSE; |
785 | } | 795 | } |
diff --git a/src/rhd_audio.c b/src/rhd_audio.c index de5f5ce..5e3c4e2 100644 --- a/src/rhd_audio.c +++ b/src/rhd_audio.c | |||
@@ -90,14 +90,16 @@ AudioRate(struct rhdAudio* Audio) | |||
90 | return result; | 90 | return result; |
91 | } | 91 | } |
92 | 92 | ||
93 | #if 0 | ||
93 | /* | 94 | /* |
94 | * something playing ? | 95 | * something playing ? (not used anymore) |
95 | */ | 96 | */ |
96 | static Bool | 97 | static Bool |
97 | AudioPlaying(struct rhdAudio* Audio) | 98 | AudioPlaying(struct rhdAudio* Audio) |
98 | { | 99 | { |
99 | return (RHDRegRead(Audio, AUDIO_PLAYING) >> 4) & 1; | 100 | return (RHDRegRead(Audio, AUDIO_PLAYING) >> 4) & 1; |
100 | } | 101 | } |
102 | #endif | ||
101 | 103 | ||
102 | /* | 104 | /* |
103 | * iec 60958 status bits | 105 | * iec 60958 status bits |
@@ -124,35 +126,36 @@ static CARD32 | |||
124 | AudioUpdateHdmi(OsTimerPtr timer, CARD32 time, pointer ptr) | 126 | AudioUpdateHdmi(OsTimerPtr timer, CARD32 time, pointer ptr) |
125 | { | 127 | { |
126 | struct rhdAudio *Audio = (struct rhdAudio*)ptr; | 128 | struct rhdAudio *Audio = (struct rhdAudio*)ptr; |
127 | Bool playing = AudioPlaying(Audio); | ||
128 | int channels = AudioChannels(Audio); | 129 | int channels = AudioChannels(Audio); |
129 | int rate = AudioRate(Audio); | 130 | int rate = AudioRate(Audio); |
130 | int bps = AudioBitsPerSample(Audio); | 131 | int bps = AudioBitsPerSample(Audio); |
131 | CARD8 status_bits = AudioStatusBits(Audio); | 132 | CARD8 status_bits = AudioStatusBits(Audio); |
132 | CARD8 category_code = AudioCategoryCode(Audio); | 133 | CARD8 category_code = AudioCategoryCode(Audio); |
133 | 134 | ||
135 | Bool changes = FALSE; | ||
136 | |||
134 | struct rhdHdmi* hdmi; | 137 | struct rhdHdmi* hdmi; |
135 | 138 | ||
136 | if(playing != Audio->SavedPlaying || | 139 | changes |= channels != Audio->SavedChannels; |
137 | channels != Audio->SavedChannels || | 140 | changes |= rate != Audio->SavedRate; |
138 | rate != Audio->SavedRate || | 141 | changes |= bps != Audio->SavedBitsPerSample; |
139 | bps != Audio->SavedBitsPerSample || | 142 | changes |= status_bits != Audio->SavedStatusBits; |
140 | status_bits != Audio->SavedStatusBits || | 143 | changes |= category_code != Audio->SavedCategoryCode; |
141 | category_code != Audio->SavedCategoryCode) { | ||
142 | 144 | ||
143 | Audio->SavedPlaying = playing; | 145 | if(changes) { |
144 | Audio->SavedChannels = channels; | 146 | Audio->SavedChannels = channels; |
145 | Audio->SavedRate = rate; | 147 | Audio->SavedRate = rate; |
146 | Audio->SavedBitsPerSample = bps; | 148 | Audio->SavedBitsPerSample = bps; |
147 | Audio->SavedStatusBits = status_bits; | 149 | Audio->SavedStatusBits = status_bits; |
148 | Audio->SavedCategoryCode = category_code; | 150 | Audio->SavedCategoryCode = category_code; |
151 | } | ||
149 | 152 | ||
150 | for(hdmi=Audio->Registered; hdmi != NULL; hdmi=hdmi->Next) | 153 | for(hdmi=Audio->Registered; hdmi != NULL; hdmi=hdmi->Next) |
154 | if(changes || RHDHdmiBufferStatusChanged(hdmi)) | ||
151 | RHDHdmiUpdateAudioSettings( | 155 | RHDHdmiUpdateAudioSettings( |
152 | hdmi, playing, channels, | 156 | hdmi, channels, |
153 | rate, bps, status_bits, | 157 | rate, bps, status_bits, |
154 | category_code); | 158 | category_code); |
155 | } | ||
156 | 159 | ||
157 | return AUDIO_TIMER_INTERVALL; | 160 | return AUDIO_TIMER_INTERVALL; |
158 | } | 161 | } |
@@ -303,6 +306,9 @@ RHDAudioRegisterHdmi(RHDPtr rhdPtr, struct rhdHdmi* rhdHdmi) | |||
303 | if(!rhdHdmi) | 306 | if(!rhdHdmi) |
304 | return; | 307 | return; |
305 | 308 | ||
309 | /* make shure the HDMI interface is not registered */ | ||
310 | RHDAudioUnregisterHdmi(rhdPtr, rhdHdmi); | ||
311 | |||
306 | rhdHdmi->Next = Audio->Registered; | 312 | rhdHdmi->Next = Audio->Registered; |
307 | Audio->Registered = rhdHdmi; | 313 | Audio->Registered = rhdHdmi; |
308 | } | 314 | } |
@@ -318,7 +324,7 @@ void RHDAudioUnregisterHdmi(RHDPtr rhdPtr, struct rhdHdmi* rhdHdmi) | |||
318 | if (!Audio) return; | 324 | if (!Audio) return; |
319 | RHDFUNC(Audio); | 325 | RHDFUNC(Audio); |
320 | 326 | ||
321 | for(hdmiPtr=&Audio->Registered; hdmiPtr!=NULL;hdmiPtr=&(*hdmiPtr)->Next) | 327 | for(hdmiPtr=&Audio->Registered; *hdmiPtr!=NULL;hdmiPtr=&(*hdmiPtr)->Next) |
322 | if(*hdmiPtr == rhdHdmi) { | 328 | if(*hdmiPtr == rhdHdmi) { |
323 | *hdmiPtr = rhdHdmi->Next; | 329 | *hdmiPtr = rhdHdmi->Next; |
324 | rhdHdmi->Next = NULL; | 330 | rhdHdmi->Next = NULL; |
diff --git a/src/rhd_audio.h b/src/rhd_audio.h index d74016c..82932e9 100644 --- a/src/rhd_audio.h +++ b/src/rhd_audio.h | |||
@@ -34,7 +34,6 @@ struct rhdAudio { | |||
34 | struct rhdHdmi* Registered; | 34 | struct rhdHdmi* Registered; |
35 | OsTimerPtr Timer; | 35 | OsTimerPtr Timer; |
36 | 36 | ||
37 | Bool SavedPlaying; | ||
38 | int SavedChannels; | 37 | int SavedChannels; |
39 | int SavedRate; | 38 | int SavedRate; |
40 | int SavedBitsPerSample; | 39 | int SavedBitsPerSample; |
diff --git a/src/rhd_dig.c b/src/rhd_dig.c index 6e75fd0..782c8db 100644 --- a/src/rhd_dig.c +++ b/src/rhd_dig.c | |||
@@ -262,6 +262,7 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output, | |||
262 | switch (Property) { | 262 | switch (Property) { |
263 | case RHD_OUTPUT_COHERENT: | 263 | case RHD_OUTPUT_COHERENT: |
264 | case RHD_OUTPUT_HDMI: | 264 | case RHD_OUTPUT_HDMI: |
265 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
265 | return TRUE; | 266 | return TRUE; |
266 | default: | 267 | default: |
267 | return FALSE; | 268 | return FALSE; |
@@ -274,6 +275,9 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output, | |||
274 | case RHD_OUTPUT_HDMI: | 275 | case RHD_OUTPUT_HDMI: |
275 | val->Bool = Private->EncoderMode == TMDS_HDMI; | 276 | val->Bool = Private->EncoderMode == TMDS_HDMI; |
276 | return TRUE; | 277 | return TRUE; |
278 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
279 | val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi); | ||
280 | return TRUE; | ||
277 | default: | 281 | default: |
278 | return FALSE; | 282 | return FALSE; |
279 | } | 283 | } |
@@ -286,6 +290,9 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output, | |||
286 | case RHD_OUTPUT_HDMI: | 290 | case RHD_OUTPUT_HDMI: |
287 | Private->EncoderMode = val->Bool ? TMDS_HDMI : TMDS_DVI; | 291 | Private->EncoderMode = val->Bool ? TMDS_HDMI : TMDS_DVI; |
288 | break; | 292 | break; |
293 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
294 | RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool); | ||
295 | break; | ||
289 | default: | 296 | default: |
290 | return FALSE; | 297 | return FALSE; |
291 | } | 298 | } |
@@ -297,6 +304,9 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output, | |||
297 | Output->Mode(Output, Private->Mode); | 304 | Output->Mode(Output, Private->Mode); |
298 | Output->Power(Output, RHD_POWER_ON); | 305 | Output->Power(Output, RHD_POWER_ON); |
299 | break; | 306 | break; |
307 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
308 | RHDHdmiCommitAudioWorkaround(Private->Hdmi); | ||
309 | break; | ||
300 | default: | 310 | default: |
301 | return FALSE; | 311 | return FALSE; |
302 | } | 312 | } |
@@ -1472,6 +1482,7 @@ DigPropertyControl(struct rhdOutput *Output, | |||
1472 | case RHD_OUTPUT_COHERENT: | 1482 | case RHD_OUTPUT_COHERENT: |
1473 | case RHD_OUTPUT_BACKLIGHT: | 1483 | case RHD_OUTPUT_BACKLIGHT: |
1474 | case RHD_OUTPUT_HDMI: | 1484 | case RHD_OUTPUT_HDMI: |
1485 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
1475 | { | 1486 | { |
1476 | if (!Private->Transmitter.Property) | 1487 | if (!Private->Transmitter.Property) |
1477 | return FALSE; | 1488 | return FALSE; |
diff --git a/src/rhd_driver.c b/src/rhd_driver.c index 649cadb..e502c5f 100644 --- a/src/rhd_driver.c +++ b/src/rhd_driver.c | |||
@@ -261,6 +261,7 @@ typedef enum { | |||
261 | #endif | 261 | #endif |
262 | OPTION_UNVERIFIED_FEAT, | 262 | OPTION_UNVERIFIED_FEAT, |
263 | OPTION_AUDIO, | 263 | OPTION_AUDIO, |
264 | OPTION_AUDIO_WORKAROUND, | ||
264 | OPTION_HDMI, | 265 | OPTION_HDMI, |
265 | OPTION_COHERENT, | 266 | OPTION_COHERENT, |
266 | OPTION_FORCE_LOW_POWER, | 267 | OPTION_FORCE_LOW_POWER, |
@@ -292,6 +293,7 @@ static const OptionInfoRec RHDOptions[] = { | |||
292 | #endif | 293 | #endif |
293 | { OPTION_UNVERIFIED_FEAT, "UnverifiedFeatures", OPTV_BOOLEAN, {0}, FALSE }, | 294 | { OPTION_UNVERIFIED_FEAT, "UnverifiedFeatures", OPTV_BOOLEAN, {0}, FALSE }, |
294 | { OPTION_AUDIO, "Audio", OPTV_BOOLEAN, {0}, FALSE }, | 295 | { OPTION_AUDIO, "Audio", OPTV_BOOLEAN, {0}, FALSE }, |
296 | { OPTION_AUDIO_WORKAROUND, "AudioStreamSilence", OPTV_ANYSTR, {0}, FALSE }, | ||
295 | { OPTION_HDMI, "HDMI", OPTV_ANYSTR, {0}, FALSE }, | 297 | { OPTION_HDMI, "HDMI", OPTV_ANYSTR, {0}, FALSE }, |
296 | { OPTION_COHERENT, "COHERENT", OPTV_ANYSTR, {0}, FALSE }, | 298 | { OPTION_COHERENT, "COHERENT", OPTV_ANYSTR, {0}, FALSE }, |
297 | { OPTION_FORCE_LOW_POWER, "ForceLowPowerMode", OPTV_BOOLEAN, {0}, FALSE }, | 299 | { OPTION_FORCE_LOW_POWER, "ForceLowPowerMode", OPTV_BOOLEAN, {0}, FALSE }, |
@@ -2844,6 +2846,8 @@ rhdProcessOptions(ScrnInfoPtr pScrn) | |||
2844 | &rhdPtr->unverifiedFeatures, FALSE); | 2846 | &rhdPtr->unverifiedFeatures, FALSE); |
2845 | RhdGetOptValBool (rhdPtr->Options, OPTION_AUDIO, | 2847 | RhdGetOptValBool (rhdPtr->Options, OPTION_AUDIO, |
2846 | &rhdPtr->audio, TRUE); | 2848 | &rhdPtr->audio, TRUE); |
2849 | RhdGetOptValString (rhdPtr->Options, OPTION_AUDIO_WORKAROUND, | ||
2850 | &rhdPtr->audioWorkaround, "none"); | ||
2847 | RhdGetOptValString (rhdPtr->Options, OPTION_HDMI, | 2851 | RhdGetOptValString (rhdPtr->Options, OPTION_HDMI, |
2848 | &rhdPtr->hdmi, "none"); | 2852 | &rhdPtr->hdmi, "none"); |
2849 | RhdGetOptValString(rhdPtr->Options, OPTION_COHERENT, | 2853 | RhdGetOptValString(rhdPtr->Options, OPTION_COHERENT, |
diff --git a/src/rhd_hdmi.c b/src/rhd_hdmi.c index 62ab861..c786fcd 100644 --- a/src/rhd_hdmi.c +++ b/src/rhd_hdmi.c | |||
@@ -229,26 +229,16 @@ HdmiAudioInfoFrame( | |||
229 | } | 229 | } |
230 | 230 | ||
231 | /* | 231 | /* |
232 | * it's unknown what these bits do excatly, but it's indeed quite usefull for debugging | 232 | * test if audio buffer is filled enough to start playing |
233 | */ | 233 | */ |
234 | static void | 234 | static Bool |
235 | HdmiAudioDebugWorkaround(struct rhdHdmi* hdmi, Bool Enable) | 235 | IsAudioBufferFilled(struct rhdHdmi *hdmi) |
236 | { | 236 | { |
237 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0, 0x00FFFFFF); | 237 | return (RHDRegRead(hdmi, hdmi->Offset+HDMI_STATUS) & 0x10) != 0; |
238 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1, 0x007FFFFF); | ||
239 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2, 0x00000001); | ||
240 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3, 0x00000001); | ||
241 | |||
242 | if(Enable) { | ||
243 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x1000, 0x1000); | ||
244 | } else { | ||
245 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0, 0x1000); | ||
246 | } | ||
247 | } | 238 | } |
248 | 239 | ||
249 | /* | 240 | /* |
250 | * allocate/initialize the HDMI structure | 241 | * allocate/initialize the HDMI structure |
251 | * and register with audio engine | ||
252 | * output selects which engine is used | 242 | * output selects which engine is used |
253 | */ | 243 | */ |
254 | struct rhdHdmi* | 244 | struct rhdHdmi* |
@@ -291,7 +281,6 @@ RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output) | |||
291 | break; | 281 | break; |
292 | } | 282 | } |
293 | hdmi->Stored = FALSE; | 283 | hdmi->Stored = FALSE; |
294 | RHDAudioRegisterHdmi(rhdPtr, hdmi); | ||
295 | return hdmi; | 284 | return hdmi; |
296 | } else | 285 | } else |
297 | return NULL; | 286 | return NULL; |
@@ -308,8 +297,6 @@ RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode) | |||
308 | 297 | ||
309 | RHDAudioSetClock(RHDPTRI(hdmi), hdmi->Output, Mode->Clock); | 298 | RHDAudioSetClock(RHDPTRI(hdmi), hdmi->Output, Mode->Clock); |
310 | 299 | ||
311 | HdmiAudioDebugWorkaround(hdmi, FALSE); | ||
312 | |||
313 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, 0x1000); | 300 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, 0x1000); |
314 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x0); | 301 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x0); |
315 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x1000); | 302 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x1000); |
@@ -323,20 +310,45 @@ RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode) | |||
323 | HdmiVideoInfoFrame(hdmi, RGB, FALSE, 0, 0, 0, | 310 | HdmiVideoInfoFrame(hdmi, RGB, FALSE, 0, 0, 0, |
324 | 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0); | 311 | 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
325 | 312 | ||
313 | /* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */ | ||
314 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0, 0x00FFFFFF); | ||
315 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1, 0x007FFFFF); | ||
316 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2, 0x00000001); | ||
317 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3, 0x00000001); | ||
318 | |||
319 | RHDHdmiCommitAudioWorkaround(hdmi); | ||
320 | |||
326 | /* audio packets per line, does anyone know how to calc this ? */ | 321 | /* audio packets per line, does anyone know how to calc this ? */ |
327 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x020000, 0x1F0000); | 322 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00040000, 0x001F0000); |
328 | 323 | ||
329 | /* update? reset? don't realy know */ | 324 | /* update? reset? don't realy know */ |
330 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x14000000, 0x14000000); | 325 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x14000000, 0x14000000); |
331 | } | 326 | } |
332 | 327 | ||
333 | /* | 328 | /* |
329 | * have buffer status changed since last call? | ||
330 | */ | ||
331 | Bool | ||
332 | RHDHdmiBufferStatusChanged(struct rhdHdmi* hdmi) | ||
333 | { | ||
334 | Bool status, result; | ||
335 | |||
336 | if(!hdmi) return FALSE; | ||
337 | RHDFUNC(hdmi); | ||
338 | |||
339 | status = IsAudioBufferFilled(hdmi); | ||
340 | result = hdmi->SavedBufferStatus != status; | ||
341 | hdmi->SavedBufferStatus = status; | ||
342 | |||
343 | return result; | ||
344 | } | ||
345 | |||
346 | /* | ||
334 | * update settings with current parameters from audio engine | 347 | * update settings with current parameters from audio engine |
335 | */ | 348 | */ |
336 | void | 349 | void |
337 | RHDHdmiUpdateAudioSettings( | 350 | RHDHdmiUpdateAudioSettings( |
338 | struct rhdHdmi* hdmi, | 351 | struct rhdHdmi* hdmi, |
339 | Bool playing, | ||
340 | int channels, | 352 | int channels, |
341 | int rate, | 353 | int rate, |
342 | int bps, | 354 | int bps, |
@@ -351,13 +363,11 @@ RHDHdmiUpdateAudioSettings( | |||
351 | 363 | ||
352 | xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: %s with " | 364 | xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: %s with " |
353 | "%d channels, %d Hz sampling rate, %d bits per sample,\n", | 365 | "%d channels, %d Hz sampling rate, %d bits per sample,\n", |
354 | __func__, playing ? "playing" : "stopped", channels, rate, bps); | 366 | __func__, IsAudioBufferFilled(hdmi) ? "playing" : "stopped", |
367 | channels, rate, bps); | ||
355 | xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: " | 368 | xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: " |
356 | "0x%02x IEC60958 status bits and 0x%02x category code\n", | 369 | "0x%02x IEC60958 status bits and 0x%02x category code\n", |
357 | __func__, (int)status_bits, (int)category_code); | 370 | __func__, (int)status_bits, (int)category_code); |
358 | |||
359 | /* start delivering audio frames */ | ||
360 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, playing ? 1 : 0, 0x1); | ||
361 | 371 | ||
362 | iec = 0; | 372 | iec = 0; |
363 | if(status_bits & AUDIO_STATUS_PROFESSIONAL) iec |= 1 << 0; | 373 | if(status_bits & AUDIO_STATUS_PROFESSIONAL) iec |= 1 << 0; |
@@ -395,12 +405,15 @@ RHDHdmiUpdateAudioSettings( | |||
395 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, 0x31); | 405 | RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, 0x31); |
396 | HdmiAudioInfoFrame(hdmi, channels-1, 0, 0, 0, 0, 0, 0, FALSE); | 406 | HdmiAudioInfoFrame(hdmi, channels-1, 0, 0, 0, 0, 0, 0, FALSE); |
397 | 407 | ||
398 | /* RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x4000000, 0x4000000); */ | 408 | RHDHdmiCommitAudioWorkaround(hdmi); |
399 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x400000, 0x400000); | 409 | |
410 | /* update? reset? don't realy know */ | ||
411 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x04000000, 0x04000000); | ||
400 | } | 412 | } |
401 | 413 | ||
402 | /* | 414 | /* |
403 | * enable/disable the HDMI engine | 415 | * enable/disable the HDMI engine |
416 | * and register with audio engine | ||
404 | */ | 417 | */ |
405 | void | 418 | void |
406 | RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable) | 419 | RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable) |
@@ -432,6 +445,57 @@ RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable) | |||
432 | xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__); | 445 | xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__); |
433 | break; | 446 | break; |
434 | } | 447 | } |
448 | if(Enable) | ||
449 | RHDAudioRegisterHdmi(RHDPTRI(hdmi), hdmi); | ||
450 | else | ||
451 | RHDAudioUnregisterHdmi(RHDPTRI(hdmi), hdmi); | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * enable/disable the audio workaround function | ||
456 | */ | ||
457 | void | ||
458 | RHDHdmiSetAudioWorkaround(struct rhdHdmi* hdmi, Bool Enable) | ||
459 | { | ||
460 | if(!hdmi) return; | ||
461 | RHDFUNC(hdmi); | ||
462 | |||
463 | hdmi->AudioDebugWorkaround = Enable; | ||
464 | } | ||
465 | |||
466 | /* | ||
467 | * get status of the audio workaround function | ||
468 | */ | ||
469 | Bool | ||
470 | RHDHdmiGetAudioWorkaround(struct rhdHdmi* hdmi) | ||
471 | { | ||
472 | if(!hdmi) return FALSE; | ||
473 | RHDFUNC(hdmi); | ||
474 | |||
475 | return hdmi->AudioDebugWorkaround; | ||
476 | } | ||
477 | |||
478 | /* | ||
479 | * commit the audio workaround status to the hardware | ||
480 | */ | ||
481 | void | ||
482 | RHDHdmiCommitAudioWorkaround(struct rhdHdmi* hdmi) | ||
483 | { | ||
484 | if(!hdmi) return; | ||
485 | RHDFUNC(hdmi); | ||
486 | |||
487 | if(IsAudioBufferFilled(hdmi)) { | ||
488 | /* disable audio workaround and start delivering of audio frames */ | ||
489 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00000001, 0x00001001); | ||
490 | |||
491 | } else if(hdmi->AudioDebugWorkaround) { | ||
492 | /* enable audio workaround and start delivering of audio frames */ | ||
493 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00001001, 0x00001001); | ||
494 | |||
495 | } else { | ||
496 | /* disable audio workaround and stop delivering of audio frames */ | ||
497 | RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00000000, 0x00001001); | ||
498 | } | ||
435 | } | 499 | } |
436 | 500 | ||
437 | /* | 501 | /* |
diff --git a/src/rhd_hdmi.h b/src/rhd_hdmi.h index 5b1e8f0..e86b5e2 100644 --- a/src/rhd_hdmi.h +++ b/src/rhd_hdmi.h | |||
@@ -35,6 +35,9 @@ struct rhdHdmi { | |||
35 | struct rhdOutput* Output; | 35 | struct rhdOutput* Output; |
36 | CARD16 Offset; | 36 | CARD16 Offset; |
37 | 37 | ||
38 | Bool SavedBufferStatus; | ||
39 | Bool AudioDebugWorkaround; | ||
40 | |||
38 | Bool Stored; | 41 | Bool Stored; |
39 | CARD32 StoreEnable; | 42 | CARD32 StoreEnable; |
40 | CARD32 StoreControl; | 43 | CARD32 StoreControl; |
@@ -63,9 +66,10 @@ struct rhdHdmi* RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output); | |||
63 | 66 | ||
64 | void RHDHdmiSetMode(struct rhdHdmi* rhdHdmi, DisplayModePtr Mode); | 67 | void RHDHdmiSetMode(struct rhdHdmi* rhdHdmi, DisplayModePtr Mode); |
65 | void RHDHdmiEnable(struct rhdHdmi* rhdHdmi, Bool Enable); | 68 | void RHDHdmiEnable(struct rhdHdmi* rhdHdmi, Bool Enable); |
69 | |||
70 | Bool RHDHdmiBufferStatusChanged(struct rhdHdmi* hdmi); | ||
66 | void RHDHdmiUpdateAudioSettings( | 71 | void RHDHdmiUpdateAudioSettings( |
67 | struct rhdHdmi* rhdHdmi, | 72 | struct rhdHdmi* rhdHdmi, |
68 | Bool playing, | ||
69 | int channels, | 73 | int channels, |
70 | int rate, | 74 | int rate, |
71 | int bps, | 75 | int bps, |
@@ -73,6 +77,10 @@ void RHDHdmiUpdateAudioSettings( | |||
73 | CARD8 catgory_code | 77 | CARD8 catgory_code |
74 | ); | 78 | ); |
75 | 79 | ||
80 | void RHDHdmiSetAudioWorkaround(struct rhdHdmi* rhdHdmi, Bool Enabled); | ||
81 | Bool RHDHdmiGetAudioWorkaround(struct rhdHdmi* rhdHdmi); | ||
82 | void RHDHdmiCommitAudioWorkaround(struct rhdHdmi* rhdHdmi); | ||
83 | |||
76 | void RHDHdmiSave(struct rhdHdmi* rhdHdmi); | 84 | void RHDHdmiSave(struct rhdHdmi* rhdHdmi); |
77 | void RHDHdmiRestore(struct rhdHdmi* rhdHdmi); | 85 | void RHDHdmiRestore(struct rhdHdmi* rhdHdmi); |
78 | 86 | ||
diff --git a/src/rhd_lvtma.c b/src/rhd_lvtma.c index 685aef6..a4aeb9e 100644 --- a/src/rhd_lvtma.c +++ b/src/rhd_lvtma.c | |||
@@ -1069,6 +1069,7 @@ TMDSBPropertyControl(struct rhdOutput *Output, | |||
1069 | switch (Property) { | 1069 | switch (Property) { |
1070 | case RHD_OUTPUT_COHERENT: | 1070 | case RHD_OUTPUT_COHERENT: |
1071 | case RHD_OUTPUT_HDMI: | 1071 | case RHD_OUTPUT_HDMI: |
1072 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
1072 | return TRUE; | 1073 | return TRUE; |
1073 | default: | 1074 | default: |
1074 | return FALSE; | 1075 | return FALSE; |
@@ -1081,6 +1082,9 @@ TMDSBPropertyControl(struct rhdOutput *Output, | |||
1081 | case RHD_OUTPUT_HDMI: | 1082 | case RHD_OUTPUT_HDMI: |
1082 | val->Bool = Private->HdmiEnabled; | 1083 | val->Bool = Private->HdmiEnabled; |
1083 | return TRUE; | 1084 | return TRUE; |
1085 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
1086 | val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi); | ||
1087 | return TRUE; | ||
1084 | default: | 1088 | default: |
1085 | return FALSE; | 1089 | return FALSE; |
1086 | } | 1090 | } |
@@ -1093,6 +1097,9 @@ TMDSBPropertyControl(struct rhdOutput *Output, | |||
1093 | case RHD_OUTPUT_HDMI: | 1097 | case RHD_OUTPUT_HDMI: |
1094 | Private->HdmiEnabled = val->Bool; | 1098 | Private->HdmiEnabled = val->Bool; |
1095 | break; | 1099 | break; |
1100 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
1101 | RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool); | ||
1102 | break; | ||
1096 | default: | 1103 | default: |
1097 | return FALSE; | 1104 | return FALSE; |
1098 | } | 1105 | } |
@@ -1104,6 +1111,9 @@ TMDSBPropertyControl(struct rhdOutput *Output, | |||
1104 | Output->Mode(Output, Private->Mode); | 1111 | Output->Mode(Output, Private->Mode); |
1105 | Output->Power(Output, RHD_POWER_ON); | 1112 | Output->Power(Output, RHD_POWER_ON); |
1106 | break; | 1113 | break; |
1114 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
1115 | RHDHdmiCommitAudioWorkaround(Private->Hdmi); | ||
1116 | break; | ||
1107 | default: | 1117 | default: |
1108 | return FALSE; | 1118 | return FALSE; |
1109 | } | 1119 | } |
diff --git a/src/rhd_output.c b/src/rhd_output.c index 2219582..0e33d4e 100644 --- a/src/rhd_output.c +++ b/src/rhd_output.c | |||
@@ -260,6 +260,25 @@ RHDOutputAttachConnector(struct rhdOutput *Output, struct rhdConnector *Connecto | |||
260 | if(!Output->Property(Output, rhdPropertySet, RHD_OUTPUT_HDMI, &val)) | 260 | if(!Output->Property(Output, rhdPropertySet, RHD_OUTPUT_HDMI, &val)) |
261 | xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "Failed to %s HDMI on %s\n", val.Bool ? "disable" : "enable", Output->Name); | 261 | xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "Failed to %s HDMI on %s\n", val.Bool ? "disable" : "enable", Output->Name); |
262 | } | 262 | } |
263 | |||
264 | /* check config option if we should enable audio workaround */ | ||
265 | if (Output->Property(Output, rhdPropertyCheck, RHD_OUTPUT_AUDIO_WORKAROUND, NULL)) { | ||
266 | union rhdPropertyData val; | ||
267 | switch(RhdParseBooleanOption(&rhdPtr->audioWorkaround, Connector->Name)) { | ||
268 | case RHD_OPTION_NOT_SET: | ||
269 | case RHD_OPTION_OFF: | ||
270 | val.Bool = FALSE; | ||
271 | break; | ||
272 | case RHD_OPTION_ON: | ||
273 | case RHD_OPTION_DEFAULT: | ||
274 | val.Bool = TRUE; | ||
275 | break; | ||
276 | } | ||
277 | if(!Output->Property(Output, rhdPropertySet, RHD_OUTPUT_AUDIO_WORKAROUND, &val)) | ||
278 | xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, | ||
279 | "Failed to %s audio workaorund on %s\n", | ||
280 | val.Bool ? "disable" : "enable", Output->Name); | ||
281 | } | ||
263 | } | 282 | } |
264 | 283 | ||
265 | /* | 284 | /* |
diff --git a/src/rhd_output.h b/src/rhd_output.h index 0e7b6a2..4862478 100644 --- a/src/rhd_output.h +++ b/src/rhd_output.h | |||
@@ -59,7 +59,8 @@ typedef enum rhdSensedOutput { | |||
59 | enum rhdOutputProperty { | 59 | enum rhdOutputProperty { |
60 | RHD_OUTPUT_BACKLIGHT, | 60 | RHD_OUTPUT_BACKLIGHT, |
61 | RHD_OUTPUT_COHERENT, | 61 | RHD_OUTPUT_COHERENT, |
62 | RHD_OUTPUT_HDMI | 62 | RHD_OUTPUT_HDMI, |
63 | RHD_OUTPUT_AUDIO_WORKAROUND | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | enum rhdOutputAllocation { | 66 | enum rhdOutputAllocation { |
diff --git a/src/rhd_randr.c b/src/rhd_randr.c index 568c0cd..956119b 100644 --- a/src/rhd_randr.c +++ b/src/rhd_randr.c | |||
@@ -130,11 +130,12 @@ struct rhdRandrCrtc { | |||
130 | #define ATOM_BACKLIGHT "Backlight" | 130 | #define ATOM_BACKLIGHT "Backlight" |
131 | #define ATOM_COHERENT "_Coherent" | 131 | #define ATOM_COHERENT "_Coherent" |
132 | #define ATOM_HDMI "_HDMI" | 132 | #define ATOM_HDMI "_HDMI" |
133 | #define ATOM_AUDIO_WORKAROUND "_AudioStreamSilence" | ||
133 | #define ATOM_ATOMBIOS "_AtomBIOS" | 134 | #define ATOM_ATOMBIOS "_AtomBIOS" |
134 | 135 | ||
135 | static Atom atom_SignalFormat, atom_ConnectorType, atom_ConnectorNumber, | 136 | static Atom atom_SignalFormat, atom_ConnectorType, atom_ConnectorNumber, |
136 | atom_OutputNumber, atom_PanningArea, atom_Backlight, atom_Coherent, | 137 | atom_OutputNumber, atom_PanningArea, atom_Backlight, atom_Coherent, |
137 | atom_HdmiProperty; | 138 | atom_HdmiProperty, atom_AudioWorkaround; |
138 | static Atom atom_unknown, atom_VGA, atom_TMDS, atom_LVDS, atom_DisplayPort, atom_TV; | 139 | static Atom atom_unknown, atom_VGA, atom_TMDS, atom_LVDS, atom_DisplayPort, atom_TV; |
139 | static Atom atom_DVI, atom_DVII, atom_DVID, atom_DVIA, atom_HDMI, atom_Panel; | 140 | static Atom atom_DVI, atom_DVII, atom_DVID, atom_DVIA, atom_HDMI, atom_Panel; |
140 | static Atom atom_EDID, atom_EDID2, atom_AtomBIOS; | 141 | static Atom atom_EDID, atom_EDID2, atom_AtomBIOS; |
@@ -713,6 +714,30 @@ rhdRROutputCreateResources(xf86OutputPtr out) | |||
713 | __func__, err); | 714 | __func__, err); |
714 | } | 715 | } |
715 | } | 716 | } |
717 | if (rout->Output->Property(rout->Output, rhdPropertyCheck, RHD_OUTPUT_AUDIO_WORKAROUND, NULL)) { | ||
718 | atom_AudioWorkaround = MakeAtom(ATOM_AUDIO_WORKAROUND, sizeof(ATOM_AUDIO_WORKAROUND)-1, TRUE); | ||
719 | |||
720 | range[0] = 0; | ||
721 | range[1] = 1; | ||
722 | err = RRConfigureOutputProperty(out->randr_output, atom_AudioWorkaround, | ||
723 | FALSE, TRUE, FALSE, 2, range); | ||
724 | if (err != 0) | ||
725 | xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, | ||
726 | "RRConfigureOutputProperty error: %d\n", err); | ||
727 | else { | ||
728 | union rhdPropertyData val; | ||
729 | |||
730 | if (!rout->Output->Property(rout->Output, rhdPropertyGet, RHD_OUTPUT_AUDIO_WORKAROUND, &val)) | ||
731 | val.Bool = 1; | ||
732 | err = RRChangeOutputProperty(out->randr_output, atom_AudioWorkaround, | ||
733 | XA_INTEGER, 32, PropModeReplace, | ||
734 | 1, &val.Bool, FALSE, FALSE); | ||
735 | if (err != 0) | ||
736 | xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, | ||
737 | "In %s RRChangeOutputProperty error: %d\n", | ||
738 | __func__, err); | ||
739 | } | ||
740 | } | ||
716 | 741 | ||
717 | } | 742 | } |
718 | } | 743 | } |
@@ -1408,6 +1433,20 @@ rhdRROutputSetProperty(xf86OutputPtr out, Atom property, | |||
1408 | RHD_OUTPUT_HDMI, NULL); | 1433 | RHD_OUTPUT_HDMI, NULL); |
1409 | } | 1434 | } |
1410 | return FALSE; | 1435 | return FALSE; |
1436 | } else if (property == atom_AudioWorkaround) { | ||
1437 | if (value->type != XA_INTEGER || value->format != 32) { | ||
1438 | xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: wrong value\n", __func__); | ||
1439 | return FALSE; | ||
1440 | } | ||
1441 | if (rout->Output->Property) { | ||
1442 | union rhdPropertyData val; | ||
1443 | val.Bool = *(int*)(value->data); | ||
1444 | if(rout->Output->Property(rout->Output, rhdPropertySet, | ||
1445 | RHD_OUTPUT_AUDIO_WORKAROUND, &val)) | ||
1446 | return rout->Output->Property(rout->Output, rhdPropertyCommit, | ||
1447 | RHD_OUTPUT_AUDIO_WORKAROUND, NULL); | ||
1448 | } | ||
1449 | return FALSE; | ||
1411 | #if ENABLE_PROPERTY_ATOMBIOS | 1450 | #if ENABLE_PROPERTY_ATOMBIOS |
1412 | } else if (property == atom_AtomBIOS) { | 1451 | } else if (property == atom_AtomBIOS) { |
1413 | if (value->type != XA_STRING || value->format != 8) | 1452 | if (value->type != XA_STRING || value->format != 8) |
@@ -1585,6 +1624,17 @@ rhdRROutputGetProperty(xf86OutputPtr out, Atom property) | |||
1585 | err = RRChangeOutputProperty(out->randr_output, atom_HdmiProperty, | 1624 | err = RRChangeOutputProperty(out->randr_output, atom_HdmiProperty, |
1586 | XA_INTEGER, 32, PropModeReplace, | 1625 | XA_INTEGER, 32, PropModeReplace, |
1587 | 1, &val.Bool, FALSE, FALSE); | 1626 | 1, &val.Bool, FALSE, FALSE); |
1627 | } else if (property == atom_AudioWorkaround) { | ||
1628 | if (rout->Output->Property == NULL) | ||
1629 | return FALSE; | ||
1630 | |||
1631 | if (!rout->Output->Property(rout->Output, rhdPropertyGet, | ||
1632 | RHD_OUTPUT_AUDIO_WORKAROUND, &val)) | ||
1633 | return FALSE; | ||
1634 | |||
1635 | err = RRChangeOutputProperty(out->randr_output, atom_AudioWorkaround, | ||
1636 | XA_INTEGER, 32, PropModeReplace, | ||
1637 | 1, &val.Bool, FALSE, FALSE); | ||
1588 | } | 1638 | } |
1589 | 1639 | ||
1590 | RHDDebug(rhdPtr->scrnIndex, "%s 0x%x returns %d\n", __func__, property, err); | 1640 | RHDDebug(rhdPtr->scrnIndex, "%s 0x%x returns %d\n", __func__, property, err); |
diff --git a/src/rhd_regs.h b/src/rhd_regs.h index 3ca5e98..0e75d06 100644 --- a/src/rhd_regs.h +++ b/src/rhd_regs.h | |||
@@ -1119,6 +1119,7 @@ enum AGP_STATUS_BITS { | |||
1119 | enum { | 1119 | enum { |
1120 | /* HDMI registers */ | 1120 | /* HDMI registers */ |
1121 | HDMI_ENABLE = 0x00, | 1121 | HDMI_ENABLE = 0x00, |
1122 | HDMI_STATUS = 0x04, | ||
1122 | HDMI_CNTL = 0x08, | 1123 | HDMI_CNTL = 0x08, |
1123 | HDMI_UNKNOWN_0 = 0x0C, | 1124 | HDMI_UNKNOWN_0 = 0x0C, |
1124 | HDMI_AUDIOCNTL = 0x10, | 1125 | HDMI_AUDIOCNTL = 0x10, |
diff --git a/src/rhd_tmds.c b/src/rhd_tmds.c index 77529a5..7148ff5 100644 --- a/src/rhd_tmds.c +++ b/src/rhd_tmds.c | |||
@@ -243,6 +243,7 @@ TMDSAPropertyControl(struct rhdOutput *Output, | |||
243 | switch (Property) { | 243 | switch (Property) { |
244 | case RHD_OUTPUT_COHERENT: | 244 | case RHD_OUTPUT_COHERENT: |
245 | case RHD_OUTPUT_HDMI: | 245 | case RHD_OUTPUT_HDMI: |
246 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
246 | return TRUE; | 247 | return TRUE; |
247 | default: | 248 | default: |
248 | return FALSE; | 249 | return FALSE; |
@@ -255,6 +256,9 @@ TMDSAPropertyControl(struct rhdOutput *Output, | |||
255 | case RHD_OUTPUT_HDMI: | 256 | case RHD_OUTPUT_HDMI: |
256 | val->Bool = Private->HdmiEnabled; | 257 | val->Bool = Private->HdmiEnabled; |
257 | return TRUE; | 258 | return TRUE; |
259 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
260 | val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi); | ||
261 | return TRUE; | ||
258 | default: | 262 | default: |
259 | return FALSE; | 263 | return FALSE; |
260 | } | 264 | } |
@@ -267,6 +271,9 @@ TMDSAPropertyControl(struct rhdOutput *Output, | |||
267 | case RHD_OUTPUT_HDMI: | 271 | case RHD_OUTPUT_HDMI: |
268 | Private->HdmiEnabled = val->Bool; | 272 | Private->HdmiEnabled = val->Bool; |
269 | break; | 273 | break; |
274 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
275 | RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool); | ||
276 | break; | ||
270 | default: | 277 | default: |
271 | return FALSE; | 278 | return FALSE; |
272 | } | 279 | } |
@@ -278,6 +285,9 @@ TMDSAPropertyControl(struct rhdOutput *Output, | |||
278 | Output->Mode(Output, Private->Mode); | 285 | Output->Mode(Output, Private->Mode); |
279 | Output->Power(Output, RHD_POWER_ON); | 286 | Output->Power(Output, RHD_POWER_ON); |
280 | break; | 287 | break; |
288 | case RHD_OUTPUT_AUDIO_WORKAROUND: | ||
289 | RHDHdmiCommitAudioWorkaround(Private->Hdmi); | ||
290 | break; | ||
281 | default: | 291 | default: |
282 | return FALSE; | 292 | return FALSE; |
283 | } | 293 | } |