Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
955 serge 1
/*
2
 * Copyright 2008  Christian König 
3
 * Copyright 2007  Luc Verhaegen 
4
 * Copyright 2007  Matthias Hopf 
5
 * Copyright 2007  Egbert Eich   
6
 * Copyright 2007  Advanced Micro Devices, Inc.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the "Software"),
10
 * to deal in the Software without restriction, including without limitation
11
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 * and/or sell copies of the Software, and to permit persons to whom the
13
 * Software is furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
 * OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
 
27
#ifdef HAVE_CONFIG_H
28
#include "config.h"
29
#endif
30
 
31
#include "xf86.h"
32
 
33
#include "rhd.h"
34
#include "rhd_audio.h"
35
#include "rhd_connector.h"
36
#include "rhd_output.h"
37
#include "rhd_hdmi.h"
38
#include "rhd_regs.h"
39
 
40
enum HdmiColorFormat {
41
    RGB = 0,
42
    YCC_422 = 1,
43
    YCC_444 = 2
44
};
45
 
46
struct {
47
    CARD32 Clock;
48
 
49
    int N_32kHz;
50
    int CTS_32kHz;
51
 
52
    int N_44_1kHz;
53
    int CTS_44_1kHz;
54
 
55
    int N_48kHz;
56
    int CTS_48kHz;
57
 
58
} AudioClockRegeneration[] = {
59
    /*             32kHz          44.1kHz        48kHz    */
60
    /* Clock      N     CTS      N     CTS      N     CTS */
61
    {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 MHz */
62
    {  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
63
    {  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
64
    {  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
65
    {  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
66
    {  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
67
    {  74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /*  74.25/1.001 MHz */
68
    {  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
69
    { 148351, 11648, 421875,  8918, 234375,  5824, 140625 }, /* 148.50/1.001 MHz */
70
    { 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
71
    {      0,  4096,      0,  6272,      0,  6144,      0 }  /* Other */
72
};
73
 
74
/*
75
 * calculate CTS value if it's not found in the table
76
 */
77
static void
78
HdmiCalcCTS(struct rhdHdmi *hdmi, CARD32 Clock, int* CTS, int N, int freq)
79
{
80
    if(*CTS == 0) *CTS = Clock*1000*N/(128*freq);
81
    xf86DrvMsg(hdmi->scrnIndex, X_INFO, "Using ACR timing N=%d CTS=%d for frequency %d\n",N,*CTS,freq);
82
}
83
 
84
/*
85
 * update the N and CTS parameters for a given clock rate
86
 */
87
static void
88
HdmiAudioClockRegeneration(struct rhdHdmi *hdmi, CARD32 Clock)
89
{
90
    int CTS;
91
    int N;
92
    int i;
93
    for(i=0; AudioClockRegeneration[i].Clock != Clock && AudioClockRegeneration[i].Clock != 0; i++);
94
 
95
    CTS = AudioClockRegeneration[i].CTS_32kHz;
96
    N = AudioClockRegeneration[i].N_32kHz;
97
    HdmiCalcCTS(hdmi, Clock, &CTS, N, 32000);
98
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_CTS, CTS << 12);
99
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_N, N);
100
 
101
    CTS = AudioClockRegeneration[i].CTS_44_1kHz;
102
    N = AudioClockRegeneration[i].N_44_1kHz;
103
    HdmiCalcCTS(hdmi, Clock, &CTS, N, 44100);
104
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_CTS, CTS << 12);
105
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_N, N);
106
 
107
    CTS = AudioClockRegeneration[i].CTS_48kHz;
108
    N = AudioClockRegeneration[i].N_48kHz;
109
    HdmiCalcCTS(hdmi, Clock, &CTS, N, 48000);
110
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_CTS, CTS << 12);
111
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_N, N);
112
}
113
 
114
/*
115
 * calculate the crc for a given info frame
116
 */
117
static void
118
HdmiInfoFrameChecksum(CARD8 packetType, CARD8 versionNumber, CARD8 length, CARD8* frame)
119
{
120
    int i;
121
    frame[0] = packetType + versionNumber + length;
122
    for(i=1;i<=length;i++)
123
	frame[0] += frame[i];
124
    frame[0] = 0x100 - frame[0];
125
}
126
 
127
/*
128
 * build a HDMI Video Info Frame
129
 */
130
static void
131
HdmiVideoInfoFrame(
132
    struct rhdHdmi *hdmi,
133
    enum HdmiColorFormat ColorFormat,
134
    Bool ActiveInformationPresent,
135
    CARD8 ActiveFormatAspectRatio,
136
    CARD8 ScanInformation,
137
    CARD8 Colorimetry,
138
    CARD8 ExColorimetry,
139
    CARD8 Quantization,
140
    Bool ITC,
141
    CARD8 PictureAspectRatio,
142
    CARD8 VideoFormatIdentification,
143
    CARD8 PixelRepetition,
144
    CARD8 NonUniformPictureScaling,
145
    CARD8 BarInfoDataValid,
146
    CARD16 TopBar,
147
    CARD16 BottomBar,
148
    CARD16 LeftBar,
149
    CARD16 RightBar
150
)
151
{
152
    CARD8 frame[14];
153
 
154
    frame[0x0] = 0;
155
    frame[0x1] =
156
	(ScanInformation & 0x3) |
157
	((BarInfoDataValid & 0x3) << 2) |
158
	((ActiveInformationPresent & 0x1) << 4) |
159
	((ColorFormat & 0x3) << 5);
160
    frame[0x2] =
161
	(ActiveFormatAspectRatio & 0xF) |
162
	((PictureAspectRatio & 0x3) << 4) |
163
	((Colorimetry & 0x3) << 6);
164
    frame[0x3] =
165
	(NonUniformPictureScaling & 0x3) |
166
	((Quantization & 0x3) << 2) |
167
	((ExColorimetry & 0x7) << 4) |
168
	((ITC & 0x1) << 7);
169
    frame[0x4] = (VideoFormatIdentification & 0x7F);
170
    frame[0x5] = (PixelRepetition & 0xF);
171
    frame[0x6] = (TopBar & 0xFF);
172
    frame[0x7] = (TopBar >> 8);
173
    frame[0x8] = (BottomBar & 0xFF);
174
    frame[0x9] = (BottomBar >> 8);
175
    frame[0xA] = (LeftBar & 0xFF);
176
    frame[0xB] = (LeftBar >> 8);
177
    frame[0xC] = (RightBar & 0xFF);
178
    frame[0xD] = (RightBar >> 8);
179
 
180
    HdmiInfoFrameChecksum(0x82, 0x02, 0x0D, frame);
181
 
182
 
183
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_0,
184
	frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
185
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_1,
186
	frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
187
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_2,
188
	frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
189
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_3,
190
	frame[0xC] | (frame[0xD] << 8));
191
}
192
 
193
/*
194
 * build a Audio Info Frame
195
 */
196
static void
197
HdmiAudioInfoFrame(
198
    struct rhdHdmi *hdmi,
199
    CARD8 ChannelCount,
200
    CARD8 CodingType,
201
    CARD8 SampleSize,
202
    CARD8 SampleFrequency,
203
    CARD8 Format,
204
    CARD8 ChannelAllocation,
205
    CARD8 LevelShift,
206
    Bool DownmixInhibit
207
)
208
{
209
    CARD8 frame[11];
210
 
211
    frame[0x0] = 0;
212
    frame[0x1] = (ChannelCount & 0x7) | ((CodingType & 0xF) << 4);
213
    frame[0x2] = (SampleSize & 0x3) | ((SampleFrequency & 0x7) << 2);
214
    frame[0x3] = Format;
215
    frame[0x4] = ChannelAllocation;
216
    frame[0x5] = ((LevelShift & 0xF) << 3) | ((DownmixInhibit & 0x1) << 7);
217
    frame[0x6] = 0;
218
    frame[0x7] = 0;
219
    frame[0x8] = 0;
220
    frame[0x9] = 0;
221
    frame[0xA] = 0;
222
 
223
    HdmiInfoFrameChecksum(0x84, 0x01, 0x0A, frame);
224
 
225
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_0,
226
	frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
227
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_1,
228
	frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
229
}
230
 
231
/*
232
 * it's unknown what these bits do excatly, but it's indeed quite usefull for debugging
233
 */
234
static void
235
HdmiAudioDebugWorkaround(struct rhdHdmi* hdmi, Bool Enable)
236
{
237
    if(Enable) {
238
	RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x1000, 0x1000);
239
	RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG, 0xffffff);
240
    } else {
241
	RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0, 0x1000);
242
    }
243
}
244
 
245
/*
246
 * allocate/initialize the HDMI structure
247
 * and register with audio engine
248
 * output selects which engine is used
249
 */
250
struct rhdHdmi*
251
RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output)
252
{
253
    struct rhdHdmi *hdmi;
254
    RHDFUNC(rhdPtr);
255
 
256
    if(rhdPtr->ChipSet >= RHD_R600) {
257
	hdmi = (struct rhdHdmi *) xnfcalloc(sizeof(struct rhdHdmi), 1);
258
	hdmi->scrnIndex = rhdPtr->scrnIndex;
259
	hdmi->Output = Output;
260
	switch(Output->Id) {
261
	    case RHD_OUTPUT_TMDSA:
262
		hdmi->Offset = HDMI_TMDS;
263
		break;
264
 
265
	    case RHD_OUTPUT_LVTMA:
266
		hdmi->Offset = HDMI_LVTMA;
267
		break;
268
 
269
	    case RHD_OUTPUT_UNIPHYA:
270
		hdmi->Offset = HDMI_TMDS;
271
		break;
272
 
273
	    case RHD_OUTPUT_KLDSKP_LVTMA:
274
		hdmi->Offset = HDMI_DIG;
275
		break;
276
 
277
	    /*case RHD_OUTPUT_UNIPHYB: */
278
 
279
	    default:
280
		xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__);
281
		xfree(hdmi);
282
		return NULL;
283
		break;
284
	}
285
	hdmi->Stored = FALSE;
286
//    RHDAudioRegisterHdmi(rhdPtr, hdmi);
287
	return hdmi;
288
    } else
289
	return NULL;
290
}
291
 
292
/*
293
 * update the info frames with the data from the current display mode
294
 */
295
void
296
RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode)
297
{
298
    if(!hdmi) return;
299
    RHDFUNC(hdmi);
300
 
301
//    RHDAudioSetClock(RHDPTRI(hdmi), hdmi->Output, Mode->Clock);
302
 
303
    HdmiAudioDebugWorkaround(hdmi, FALSE);
304
 
305
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, 0x1000);
306
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x0);
307
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x1000);
308
 
309
    HdmiAudioClockRegeneration(hdmi, Mode->Clock);
310
 
311
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, 0x13);
312
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VERSION, 0x202);
313
 
314
    HdmiVideoInfoFrame(hdmi, RGB, FALSE, 0, 0, 0,
315
	0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0);
316
 
317
    /* audio packets per line, does anyone know how to calc this ? */
318
    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x020000, 0x1F0000);
319
 
320
    /* update? reset? don't realy know */
321
    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x14000000, 0x14000000);
322
}
323
 
324
/*
325
 * update settings whith current parameters from audio engine
326
 */
327
void
328
RHDHdmiUpdateAudioSettings(
329
    struct rhdHdmi* hdmi,
330
    Bool playing,
331
    int channels,
332
    int rate,
333
    int bps,
334
    CARD8 status_bits,
335
    CARD8 category_code
336
)
337
{
338
    CARD32 iec;
339
 
340
    if(!hdmi) return;
341
    RHDFUNC(hdmi);
342
 
343
    xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: %s with "
344
	"%d channels, %d Hz sampling rate, %d bits per sample,\n",
345
	 __func__, playing ? "playing" : "stoped", channels, rate, bps);
346
    xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: "
347
	"0x%02x IEC60958 status bits and 0x%02x category code\n",
348
	 __func__, (int)status_bits, (int)category_code);
349
 
350
    /* start delivering audio frames */
351
    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, playing ? 1 : 0, 0x1);
352
 
353
    iec = 0;
354
    if(status_bits & AUDIO_STATUS_PROFESSIONAL)	iec |= 1 << 0;
355
    if(status_bits & AUDIO_STATUS_NONAUDIO)	iec |= 1 << 1;
356
    if(status_bits & AUDIO_STATUS_COPYRIGHT)	iec |= 1 << 2;
357
    if(status_bits & AUDIO_STATUS_EMPHASIS)	iec |= 1 << 3;
358
 
359
    iec |= category_code << 8;
360
 
361
    switch(rate)
362
    {
363
        case  32000: iec |= 0x3 << 24; break;
364
        case  44100: iec |= 0x0 << 24; break;
365
        case  88200: iec |= 0x8 << 24; break;
366
        case 176400: iec |= 0xc << 24; break;
367
        case  48000: iec |= 0x2 << 24; break;
368
        case  96000: iec |= 0xa << 24; break;
369
        case 192000: iec |= 0xe << 24; break;
370
    }
371
 
372
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_IEC60958_1, iec);
373
 
374
    iec = 0;
375
    switch(bps)
376
    {
377
	case 16: iec |= 0x2; break;
378
	case 20: iec |= 0x3; break;
379
	case 24: iec |= 0xb; break;
380
    }
381
    if(status_bits & AUDIO_STATUS_V) iec |= 0x5 << 16;
382
 
383
    RHDRegMask(hdmi, hdmi->Offset+HDMI_IEC60958_2, iec, 0x5000f);
384
 
385
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, 0x31);
386
    HdmiAudioInfoFrame(hdmi, channels-1, 0, 0, 0, 0, 0, 0, FALSE);
387
 
388
    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x400000, 0x400000);
389
}
390
 
391
/*
392
 * enable/disable the HDMI engine
393
 */
394
void
395
RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable)
396
{
397
    if(!hdmi) return;
398
    RHDFUNC(hdmi);
399
 
400
    /* some version of atombios ignore the enable HDMI flag
401
     * so enabling/disabling HDMI was moved here for TMDSA and LVTMA */
402
    switch(hdmi->Output->Id) {
403
	case RHD_OUTPUT_TMDSA:
404
	     RHDRegMask(hdmi, TMDSA_CNTL, Enable ? 0x4 : 0x0, 0x4);
405
	     RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x101 : 0x0);
406
	     break;
407
 
408
	case RHD_OUTPUT_LVTMA:
409
	     RHDRegMask(hdmi, LVTMA_CNTL, Enable ? 0x4 : 0x0, 0x4);
410
	     RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x105 : 0x0);
411
	     break;
412
 
413
	case RHD_OUTPUT_UNIPHYA:
414
	case RHD_OUTPUT_UNIPHYB:
415
	case RHD_OUTPUT_KLDSKP_LVTMA:
416
	    RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x110 : 0x0);
417
	    break;
418
 
419
	default:
420
	    xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__);
421
	    break;
422
    }
423
}
424
 
425
/*
426
 * save the current config of HDMI engine
427
 */
428
void
429
RHDHdmiSave(struct rhdHdmi *hdmi)
430
{
431
    if(!hdmi) return;
432
    RHDFUNC(hdmi);
433
 
434
    hdmi->StoreEnable = RHDRegRead(hdmi, hdmi->Offset+HDMI_ENABLE);
435
    hdmi->StoreControl = RHDRegRead(hdmi, hdmi->Offset+HDMI_CNTL);
436
    hdmi->StoredAudioDebugWorkaround = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG);
437
 
438
    hdmi->StoredFrameVersion = RHDRegRead(hdmi, hdmi->Offset+HDMI_VERSION);
439
 
440
    hdmi->StoredVideoControl = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOCNTL);
441
    hdmi->StoreVideoInfoFrame[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_0);
442
    hdmi->StoreVideoInfoFrame[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_1);
443
    hdmi->StoreVideoInfoFrame[0x2] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_2);
444
    hdmi->StoreVideoInfoFrame[0x3] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_3);
445
 
446
    hdmi->StoredAudioControl = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIOCNTL);
447
    hdmi->StoreAudioInfoFrame[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_0);
448
    hdmi->StoreAudioInfoFrame[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_1);
449
 
450
    hdmi->Store_32kHz_N = RHDRegRead(hdmi, hdmi->Offset+HDMI_32kHz_N);
451
    hdmi->Store_32kHz_CTS = RHDRegRead(hdmi, hdmi->Offset+HDMI_32kHz_CTS);
452
 
453
    hdmi->Store_44_1kHz_N = RHDRegRead(hdmi, hdmi->Offset+HDMI_44_1kHz_N);
454
    hdmi->Store_44_1kHz_CTS = RHDRegRead(hdmi, hdmi->Offset+HDMI_44_1kHz_CTS);
455
 
456
    hdmi->Store_48kHz_N = RHDRegRead(hdmi, hdmi->Offset+HDMI_48kHz_N);
457
    hdmi->Store_48kHz_CTS = RHDRegRead(hdmi, hdmi->Offset+HDMI_48kHz_CTS);
458
 
459
    hdmi->StoreIEC60958[0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_IEC60958_1);
460
    hdmi->StoreIEC60958[1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_IEC60958_2);
461
 
462
    hdmi->StoreUnknown[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_UNKNOWN_0);
463
    hdmi->StoreUnknown[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_UNKNOWN_1);
464
    hdmi->StoreUnknown[0x2] = RHDRegRead(hdmi, hdmi->Offset+HDMI_UNKNOWN_2);
465
 
466
    hdmi->Stored = TRUE;
467
}
468
 
469
/*
470
 * restore the saved config of HDMI engine
471
 */
472
void
473
RHDHdmiRestore(struct rhdHdmi *hdmi)
474
{
475
    if(!hdmi) return;
476
    RHDFUNC(hdmi);
477
 
478
    if (!hdmi->Stored) {
479
        xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: trying to restore "
480
                   "uninitialized values.\n", __func__);
481
        return;
482
    }
483
 
484
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, hdmi->StoreEnable);
485
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_CNTL, hdmi->StoreControl);
486
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG, hdmi->StoredAudioDebugWorkaround);
487
 
488
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VERSION, hdmi->StoredFrameVersion);
489
 
490
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, hdmi->StoredVideoControl);
491
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_0, hdmi->StoreVideoInfoFrame[0x0]);
492
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_1, hdmi->StoreVideoInfoFrame[0x1]);
493
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_2, hdmi->StoreVideoInfoFrame[0x2]);
494
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_3, hdmi->StoreVideoInfoFrame[0x3]);
495
 
496
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, hdmi->StoredAudioControl);
497
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_0, hdmi->StoreAudioInfoFrame[0x0]);
498
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_1, hdmi->StoreAudioInfoFrame[0x1]);
499
 
500
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_N, hdmi->Store_32kHz_N);
501
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_CTS, hdmi->Store_32kHz_CTS);
502
 
503
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_N, hdmi->Store_44_1kHz_N);
504
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_CTS, hdmi->Store_44_1kHz_CTS);
505
 
506
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_N, hdmi->Store_48kHz_N);
507
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_CTS, hdmi->Store_48kHz_CTS);
508
 
509
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_IEC60958_1, hdmi->StoreIEC60958[0]);
510
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_IEC60958_2, hdmi->StoreIEC60958[1]);
511
 
512
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, hdmi->StoreUnknown[0x0]);
513
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, hdmi->StoreUnknown[0x1]);
514
    RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, hdmi->StoreUnknown[0x2]);
515
}
516
 
517
/*
518
 * unregister with audio engine and release memory
519
 */
520
void
521
RHDHdmiDestroy(struct rhdHdmi *hdmi)
522
{
523
    if(!hdmi) return;
524
    RHDFUNC(hdmi);
525
 
526
//    RHDAudioUnregisterHdmi(RHDPTRI(hdmi), hdmi);
527
 
528
    xfree(hdmi);
529
}