Nội dung bài viết

Chuẩn bị

Để bắt đầu việc patch AppleHDA, bạn cần có sẵn: PlistEdit Pro hoặc Xcode, Platforms.xml, layout11.xml, layout26.xml

Dump codec

Dùng Ubuntu(bạn có thể dùng Ubuntu Live USB nếu chưa có sẵn Ubuntu trên máy) mở Terminal gõ:

cat /proc/asound/card0/codec#0 > ~/Desktop/codec_dump_0.txt 
(or)
cat /proc/asound/card0/codec1 > ~/Desktop/codec_dump_1.txt 
(or)
cat /proc/asound/card0/codec#2 > ~/Desktop/codec_dump_2.txt

Sau đó bạn copy codec_dump ở Desktop vào đâu đó để đem sang macOS nhé!

Lấy thông tin cơ bản của codec

Những thông tin chính cần trích xuất:

1. Codec
2. Address
3. Vendor Id
4. Codec verbs

Với 3 thông tin đầu tiên, bạn có thể dễ dàng lấy bằng cách mở file chứa tên codec của máy bạn trong CodecDump.zip và nhìn vào dòng 1, dòng 2 và dòng 4

Với Vendor Id bạn cần chuyển nó sang hệ decimal bằng bất kì công cụ chuyển nào

Xác định codecverbs

B1: Các bạn tìm “Pin Complex” trong file chứa tên codec của máy bạn, node nào có thì copy ra 1 nơi rồi tìm tiếp “[N/A]”, nếu node nào có thì xoá node đó đi. Với codec ALC255 của mình thì nhận lại được như sau:

Node 0x12 [Pin Complex] wcaps 0x40040b: Stereo Amp-In
   Control: name="Internal Mic Boost Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
   Amp-In vals:  [0x00 0x00]
   Pincap 0x00000020: IN
   Pin Default 0x90a60160: [Fixed] Mic at Int N/A
     Conn = Digital, Color = Unknown
     DefAssociation = 0x6, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x20: IN
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

 Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
   Control: name="Speaker Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-Out vals:  [0x00 0x00]
   Pincap 0x00010014: OUT EAPD Detect
   EAPD 0x2: EAPD
   Pin Default 0x90170120: [Fixed] Speaker at Int N/A
     Conn = Analog, Color = Unknown
     DefAssociation = 0x2, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x40: OUT
   Unsolicited: tag=00, enabled=0
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x0c

 Node 0x21 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
   Control: name="Headphone Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-Out vals:  [0x80 0x80]
   Pincap 0x0001001c: OUT HP EAPD Detect
   EAPD 0x2: EAPD
   Pin Default 0x02211030: [Jack] HP Out at Ext Front
     Conn = 1/8, Color = Black
     DefAssociation = 0x3, Sequence = 0x0
   Pin-ctls: 0xc0: OUT HP
   Unsolicited: tag=01, enabled=1
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 2
      0x0c 0x0d*

Với laptop thường chỉ có loa trong(Speaker), tai nghe(HP), mic trong(Mic at Int), mic ngoài(Mic at Ext).

Với máy mình thì dùng combojack nên chỉ có 3 node Speaker, HP, Mic at Int. Có nhiều bạn sẽ hỏi như vậy thì sẽ chấp nhận tạch Mic at Ext sao? Hmm cũng có thể đấy nhưng là khi bạn lười thực hiện nó mà thôi 🙂 Bắt đầu nào!

Trong các node chứ Pin Complex, các bạn tìm tiếp “Headset Mic Boost Volume” và “Headphone Mic Boost Volume” rồi lưu lại nhé!

Node 0x19 [Pin Complex] wcaps 0x40048b: Stereo Amp-In
   Control: name="Headset Mic Boost Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
   Amp-In vals:  [0x00 0x00]
   Pincap 0x00003724: IN Detect
     Vref caps: HIZ 50 GRD 80 100
   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
     Conn = 1/8, Color = Black
     DefAssociation = 0xf, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x24: IN VREF_80
   Unsolicited: tag=00, enabled=0
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

 Node 0x1a [Pin Complex] wcaps 0x40048b: Stereo Amp-In
   Control: name="Headphone Mic Boost Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
   Amp-In vals:  [0x00 0x00]
   Pincap 0x00003724: IN Detect
     Vref caps: HIZ 50 GRD 80 100
   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
     Conn = 1/8, Color = Black
     DefAssociation = 0xf, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x20: IN VREF_HIZ
   Unsolicited: tag=00, enabled=0
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

Và để bài viết không quá khó hiểu thêm thì việc fix combojack mình sẽ tách riêng ra 1 phần để không làm ảnh hưởng đến những ai patch máy không có combojack

B2: Xuất Verbs data, Node và Pin Default

Nhìn vào Pin Complex ở trên, ta sẽ xác định được Node + Pin Default còn để xuất verb data, bạn cần đọc 2 số từ phải sang trái của Pin Default.

Node 14 : Pin Default 0x90170120 Verb data: 20 01 17 90 
Node 21 : Pin Default 0x02211030 Verb data: 30 10 21 02
Node 12 : Pin Default 0x90a60160 Verb data: 60 01 a6 90

Với 2 node nữa máy có combojack

Node 19 : Pin Default 0x411111f0 Verb data: f0 11 11 41 
Node 1a : Pin Default 0x411111f0 Verb data: f0 11 11 41 

Vậy từng số, từng cặp verb data chứa thông tin gì? Cùng tìm hiểu nhé!

  • Cặp đầu tiên (XY): 20 30 60

– X là thông tin port. Nếu có 1 số lặp lại tới 2 hoặc 3 lần ở X, bạn cần thay đổi để tránh trùng lặp. VD: với 20 30 30 thì ta thấy có 2 số 3 trùng nhau nên ta phải đổi 1 số 3 thành bất kì số nào để không trùng với 2 số X còn lại như 20 30 50
– Y là thông tin kênh xuất ra. Ở đây bạn chỉnh hết về 0

Với các node thường ở máy mình thì không cần động đậy gì phần này rồi

Dành cho combojack: f0 f0
– Ở X thì mình đã thấy sự lập lại của f, nên mình sẽ chỉnh f của node 19 thành 7
– Ở Y thì không cần chỉnh gì hết
Như vậy kết quả là 70 f0

  • Cặp thứ hai (XY): 01 10 01

– X là màu của cổng âm thanh
– Y là thông tin jack cắm. Chỉnh thành 0 nếu là node cho Ext, còn 1 nếu node đó dành cho Ixt

Với các node thường ở máy mình thì không cần động đậy gì phần này rồi

Dành cho combojack: 11 11
– Ở X của node 19 mình sẽ giữ nguyên nó vì mình sẽ dùng node này để liên kết với node 21, còn với X ở node 1a thì mình sẽ chuyển nó về 0 để che đi nút không hợp lệ nhằm ngăn chặn tiếng ồn hoặc thiếu tiếng
– Ở Y của node 19 mình sẽ chuyển thành 0 vì đây là thiết bị Ext, còn với node 1a thì vẫn như ở X.
Như vậy kết quả là 10 00

  • Cặp thứ ba (XY): 17 21 a6

– X là thiết bị âm thanh

Line Out 0 
Speaker  1 
HP Out 2 
CD 3 
SPDIF Out 4 
Digital Other Out 5 
Modem Line Side 6 
Modem Handset Side 7 
Line In 8 
AUX 9 
Mic In A 
Telephony B 
SPDIF In C 
Digital Other In D 
Reserved E 
Other F

– Y là cổng kết nối của thiết bị âm thanh

Unknown 0  
1/8" stereo/mono 1 
1/4" stereo/mono 2 
ATAPI internal 3 
RCA 4 
Optical 5 
Other Digital 6 
Other Analog 7 
Multichannel Analog (DIN) 8 
XLR/Professional 9 
RJ-11 (Modem) A 
Combination B  
Other F

Với các node thường ở máy mình thì chỉ cần đổi Y của node 12 thành 0 nhằm mục đích bật thêm tính năng Ambient noise reduction

Dành cho combojack: 11 11
– Ở X của node 19 mình sẽ chuyển thành a để nó macOS nhận nó là Mic, còn với node 1a sẽ là 0
– Ở Y của node 19 mình sẽ chuyển thành b, tại sao thì các bạn dich ra là biết nhé! Còn node 1a thì vẫn chả khác gì
Như vậy kết quả là ab 00

  • Cột thứ tư (XY): 90 02 90

– X là giá trị giúp ứng dụng biết được là đang kết nối với Speaker hay HP, Mic,…
– Y là vị trí cổng kết nối

Với các node thường ở máy mình thì không cần động đậy gì phần này rồi

Dành cho combojack: 41 41
– Ở X của node 19 mình sẽ chuyển thành 0 còn node 1a thì giữ nguyên
– Ở Y của node 19 mình sẽ dựa vào node 21 còn node 1a thì lại về 0 thôi
Như vậy kết quá là 02 40

Tổng kết: Như vậy là ta đã có verb data chuẩn như sau

Node 14 : Verb data: 20 01 17 90 
Node 21 : Verb data: 30 10 21 02
Node 12 : Verb data: 60 01 a0 90

Với 2 node nữa máy có combojack

Node 19 : Pin Default 0x411111f0 Verb data: 70 10 ab 02 
Node 1a : Pin Default 0x411111f0 Verb data: f0 00 00 40 

B3: Tính toán verbs codec

Công thức: Codec Address + NodeID + Verb Commands + Verb data

Codec Address = 0 (Xác định ở B1)
NodeID 14, 21, 12 (Xác định ở B2)
Verb Commands = 71c, 71d, 71e, 71f và 70c dành cho EAPD
Verb data (Xác định ở B2)

VD: con ALC255 của máy mình

Node 14: 0 + 14 + 71c + 20 = 01471c20
0 + 14 + 71d + 01 = 01471d01
0 + 14 + 71e + 17 = 01471e17
0 + 14 + 71f + 90 = 01471f90
0 + 14 + 70c + 02 = 01470c02 (EDPD)

Node 21: 0 + 21 + 71c + 30 = 02171c30
0 + 21 + 71d + 10 = 02171d10
0 + 21 + 71e + 21 = 02171e21
0 + 21 + 71f + 02 = 02171f02

Node 12: 0 + 12 + 71c + 60 = 01271c60
0 + 12 + 71d + 01 = 01271d01
0 + 12 + 71e + a0 = 01271ea0
0 + 12 + 71f + 90 = 01271f90

Nếu máy bạn có thêm Node cho Line In thì bạn cũng làm tương tự như vậy nhé!

Với 2 node nữa máy có combojack

Node 19: 0 + 19 + 71c + 70 = 01971c70
0 + 19 + 71d + 10 = 01971d10
0 + 19 + 71e + ab = 01971eab
0 + 19 + 71f + 02 = 01971f02

Node 1a: 0 + 1a + 71c + f0 = 01a71cf0
0 + 1a + 71d + 00 = 01a71d00
0 + 1a + 71e + 00 = 01a71e00
0 + 1a + 71f + 40 = 01a71f40

Bây giờ chúng ta sẽ sắp chúng lại, ta được:

01471c20 01471d01 01471e17 01471f90 01470c02 02171c30 02171d10 02171e21 02171f02 01271c60 01271d01 01271ea0 01271f90 01971c70 01971d10 01971eab 01971f02 01a71cf0 01a71d00 01a71e00 01a71f40

Lưu lại 1 chỗ rồi tiếp tục làm nhé!

Ngoài lề: 1 bài viết mà chỉ có 1 vd thì chắc cũng sẽ là hơi khó với các bạn nên mình sẽ đưa thêm 1 codec vào nữa cho các bạn dễ hiểu nhé

VD: với codec CX20590

01971c40 01971d10 01971e21 01971f04
01b71c30 01b71d10 01b71ea1 01b71f04
01f71c10 01f71d01 01f71e17 01f71f92
02371c50 02371d01 02371ea6 02371f95 01b70c02

Có: Node 1f là Speaker, Node 19 là HP, Node 23 là Mic Int, Node 1b là Mic Ext. Vì macOS không hỗ trợ Mic ngoài nên ta phải chuyển “a1” thành “81” để chuyển thành LineIn ở node 1b, còn ở node 23 ta cần chuyển “a6” thành “a0” để kích hoạt được Ambient noise reduction. Sau khi chỉnh ta được:

01971c40 01971d10 01971e21 01971f04 01b71c30 01b71d10 01b71e81 01b71f04
01f71c10 01f71d01 01f71e17 01f71f92 01b70c02 02371c50 02371d01 02371ea6 02371f95 

Xác định pathmap

Thủ công:

B1: Các bạn tìm “Audio Mixer/Selector” trong file chứa tên codec của máy bạn, node nào có thì copy ra 1 nơi rồi làm tương tự với “Audio Output” và “Audio Input“. Với codec ALC255 của mình thì nhận lại được như sau:

  • Audio Mixer/Selector
Node 0x0b [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Control: name="Headset Mic Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=1, ofs=0
   Control: name="Headset Mic Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=1, ofs=0
   Control: name="Headphone Mic Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=2, ofs=0
   Control: name="Headphone Mic Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=2, ofs=0
   Control: name="Beep Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=4, ofs=0
   Control: name="Beep Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=4, ofs=0
   Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
   Connection: 5
      0x18 0x19 0x1a 0x1b 0x1d
 Node 0x0c [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x00 0x00] [0x80 0x80]
   Connection: 2
      0x02 0x0b
 Node 0x0d [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x00 0x00] [0x80 0x80]
   Connection: 2
      0x03 0x0b
 Node 0x0f [Audio Mixer] wcaps 0x20010a: Mono Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x00 0x00]
   Connection: 1
      0x0d
Node 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
   Connection: 6
      0x18 0x19 0x1a 0x1b 0x1d 0x0b
 Node 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x00 0x00]
   Connection: 7
      0x18 0x19 0x1a 0x1b 0x1d 0x0b 0x12
  • Audio Output
Node 0x02 [Audio Output] wcaps 0x41d: Stereo Amp-Out
   Control: name="Speaker Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
   Amp-Out vals:  [0x3c 0x3c]
   Converter: stream=1, channel=0
   PCM:
     rates [0x60]: 44100 48000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
 Node 0x03 [Audio Output] wcaps 0x41d: Stereo Amp-Out
   Control: name="Headphone Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Device: name="ALC3234 Analog", type="Audio", device=0
   Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
   Amp-Out vals:  [0x00 0x00]
   Converter: stream=1, channel=0
   PCM:
     rates [0x60]: 44100 48000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
 Node 0x06 [Audio Output] wcaps 0x611: Stereo Digital
   Converter: stream=0, channel=0
   Digital:
   Digital category: 0x0
   IEC Coding Type: 0x0
   PCM:
     rates [0x5e0]: 44100 48000 88200 96000 192000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
  • Audio Input
Node 0x08 [Audio Input] wcaps 0x10051b: Stereo Amp-In
   Control: name="Capture Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Control: name="Capture Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Device: name="ALC3234 Analog", type="Audio", device=0
   Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
   Amp-In vals:  [0x27 0x27]
   Converter: stream=0, channel=0
   SDI-Select: 0
   PCM:
     rates [0x560]: 44100 48000 96000 192000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x23
 Node 0x09 [Audio Input] wcaps 0x10051b: Stereo Amp-In
   Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
   Amp-In vals:  [0x97 0x97]
   Converter: stream=0, channel=0
   SDI-Select: 0
   PCM:
     rates [0x560]: 44100 48000 96000 192000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x22

Để bắt đầu, chúng ta cần phải nắm công thức sau:

  • Với Speaker và HP: Pin Complex->(Audio Mixer)->Audio Output
  • Với Mic và LineIn: Audio Input->(Audio Selector/Mixer)->Pin Complex

Lưu ý: Nếu có 2 dấu “(” và “)” tức là có thể có hoặc có thể không

1. Speaker:

Đầu tiên bạn mở lại file chứa Pin Complex, tìm “Speaker

 Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
   Control: name="Speaker Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-Out vals:  [0x00 0x00]
   Pincap 0x00010014: OUT EAPD Detect
   EAPD 0x2: EAPD
   Pin Default 0x90170120: [Fixed] Speaker at Int N/A
     Conn = Analog, Color = Unknown
     DefAssociation = 0x2, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x40: OUT
   Unsolicited: tag=00, enabled=0
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x0c

Như vậy ta xác định được Pin Complex của Speaker là 0x14, nhìn xuống phần Connection của node 0x14 ta thấy 0x0c. Lại tìm “0x0c” ở file chứa Audio Mixer

Node 0x0c [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x00 0x00] [0x80 0x80]
   Connection: 2
      0x02 0x0b

Như vậy Speaker có kết nối qua Audio Mixer nhưng ở Connection lại có 2 node nhưng không hề có dấu hiệu ưu tiên vậy phải chọn node nào. Đến giờ thử nghiệm rồi đây, mình sẽ chọn node 0x02 rồi tìm ở file chứa Audio Output

Node 0x02 [Audio Output] wcaps 0x41d: Stereo Amp-Out
   Control: name="Speaker Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
   Amp-Out vals:  [0x3c 0x3c]
   Converter: stream=1, channel=0
   PCM:
     rates [0x60]: 44100 48000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

Thật vui mừng khi chỉ có 1 node 0x02 là có, còn 0x0b thì không. Như vậy ta đã xác định được pathmap của Speaker: 0x14 -> 0x0c -> 0x02, chuyển hết sang hệ decimal ta được: 20 -> 12 -> 2

2. HP: Mở lại file chứa Pin Complex, tìm “HP

Node 0x21 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
   Control: name="Headphone Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-Out vals:  [0x80 0x80]
   Pincap 0x0001001c: OUT HP EAPD Detect
   EAPD 0x2: EAPD
   Pin Default 0x02211030: [Jack] HP Out at Ext Front
     Conn = 1/8, Color = Black
     DefAssociation = 0x3, Sequence = 0x0
   Pin-ctls: 0xc0: OUT HP
   Unsolicited: tag=01, enabled=1
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 2
      0x0c 0x0d*

Như vậy ta xác định được Pin Complex của Speaker là 0x21, nhìn xuống phần Connection ta sẽ thấy 0x0d có 1 dấu * đằng sau tức đây là kết nối ưu tiên. Lại tìm “0x0d” ở file chứa Audio Mixer

Node 0x0d [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x00 0x00] [0x80 0x80]
   Connection: 2
      0x03 0x0b

Lại gặp tương tự trường hợp như ở Speaker, nhưng vì đã xác định được Speaker rồi nên chúng ta cần tránh sự lặp lại kết nối cho nên ta xác định được pathmap của HP: 0x21 -> 0x0d -> 0x03, chuyển hết sang hệ decimal ta được: 33 -> 13 -> 3

3. Mic: Mở lại file chứa Pin Complex, tìm “Mic

Node 0x12 [Pin Complex] wcaps 0x40040b: Stereo Amp-In
   Control: name="Internal Mic Boost Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
   Amp-In vals:  [0x00 0x00]
   Pincap 0x00000020: IN
   Pin Default 0x90a60160: [Fixed] Mic at Int N/A
     Conn = Digital, Color = Unknown
     DefAssociation = 0x6, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x20: IN
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

Như vậy không hề có thông tin kết nối trực tiếp vào, ta sẽ phải xác định từ Audio Input/Mixer/Selector. Ở Audio Mixer mình đã tìm được node có kết nối với 0x12

Node 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x00 0x00]
   Connection: 7
      0x18 0x19 0x1a 0x1b 0x1d 0x0b 0x12

Như vậy Audio Mixer là 0x23, ta tìm tiếp “0x23” ở file chứa Audio Input. Nhận lại được node 0x08

Node 0x08 [Audio Input] wcaps 0x10051b: Stereo Amp-In
   Control: name="Capture Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Control: name="Capture Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Device: name="ALC3234 Analog", type="Audio", device=0
   Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
   Amp-In vals:  [0x27 0x27]
   Converter: stream=0, channel=0
   SDI-Select: 0
   PCM:
     rates [0x560]: 44100 48000 96000 192000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x23

Như vậy chúng ta đã xác định được pathmap của Mic: 0x08 -> 0x23 -> 0x12, chuyển hết sang hệ decimal ta được: 8 -> 35 -> 18

Có vẻ như những thứ làm mất nhiều thời gian của chúng ta đã 1 cái 1 nơi nhỉ? Cùng góp nó vào 1 chỗ nhé!

  • Speaker: 20 -> 12 -> 2
  • HP: 33 -> 13 -> 3
  • Mic: 8 -> 35 -> 18

Nếu có thêm LineIn thì việc xác định cũng tương tự như trên nhé!

Đối với combojack: Công thức sẽ giống với công thức của Mic và LineIn

1. Headset: Hãy bắt đầu với Pin Complex

Node 0x19 [Pin Complex] wcaps 0x40048b: Stereo Amp-In
   Control: name="Headset Mic Boost Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
   Amp-In vals:  [0x00 0x00]
   Pincap 0x00003724: IN Detect
     Vref caps: HIZ 50 GRD 80 100
   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
     Conn = 1/8, Color = Black
     DefAssociation = 0xf, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x24: IN VREF_80
   Unsolicited: tag=00, enabled=0
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

Như vậy là chúng ta không thấy bất kì node được kết nối trực tiếp nào nên mình đành phải tìm từ Audio Input/Mixer/Selector và rồi mình đã tìm được 3 node có kết nối với node 19 này ở Audio Mixer.

Node 0x0b [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Control: name="Headset Mic Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=1, ofs=0
   Control: name="Headset Mic Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=1, ofs=0
   Control: name="Headphone Mic Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=2, ofs=0
   Control: name="Headphone Mic Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=2, ofs=0
   Control: name="Beep Playback Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=4, ofs=0
   Control: name="Beep Playback Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=4, ofs=0
   Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
   Connection: 5
      0x18 0x19 0x1a 0x1b 0x1d
 Node 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
   Connection: 6
      0x18 0x19 0x1a 0x1b 0x1d 0x0b
 Node 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
   Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x00 0x00]
   Connection: 7
      0x18 0x19 0x1a 0x1b 0x1d 0x0b 0x12

Oh, có tới 3 Audio Mixer thì bây giờ ta phải làm như nào để biết được node cần tìm đây? Cách đơn giản nhất là lấy node đó đi tìm tiếp thôi

Mình thử đầu tiên với node 0b thì mình chợt nhận ra nó lại được kết nối tới 2 node còn lại là node 22 và node 23 nên chắc rằng chúng ta sẽ loại nó đi vì không cần dựa vào nó. Còn với 2 node còn lại thì node 22 được kết nối với node 09 và node 23 được kết nối với node 08

Node 0x08 [Audio Input] wcaps 0x10051b: Stereo Amp-In
   Control: name="Capture Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Control: name="Capture Switch", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Device: name="ALC3234 Analog", type="Audio", device=0
   Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
   Amp-In vals:  [0x27 0x27]
   Converter: stream=0, channel=0
   SDI-Select: 0
   PCM:
     rates [0x560]: 44100 48000 96000 192000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x23

 Node 0x09 [Audio Input] wcaps 0x10051b: Stereo Amp-In
   Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
   Amp-In vals:  [0x97 0x97]
   Converter: stream=0, channel=0
   SDI-Select: 0
   PCM:
     rates [0x560]: 44100 48000 96000 192000
     bits [0xe]: 16 20 24
     formats [0x1]: PCM
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0
   Connection: 1
      0x22

Như vậy pathmap của Headset sẽ là: 0x08 -> 0x23 -> 0x19 0x09 -> 0x22 -> 0x19, chuyển hết sang hệ decimal ta được: 8 -> 35 -> 25 9 -> 34 -> 25

2. Headphone: Hãy bắt đầu với Pin Complex

 Node 0x1a [Pin Complex] wcaps 0x40048b: Stereo Amp-In
   Control: name="Headphone Mic Boost Volume", index=0, device=0
     ControlAmp: chs=3, dir=In, idx=0, ofs=0
   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
   Amp-In vals:  [0x00 0x00]
   Pincap 0x00003724: IN Detect
     Vref caps: HIZ 50 GRD 80 100
   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
     Conn = 1/8, Color = Black
     DefAssociation = 0xf, Sequence = 0x0
     Misc = NO_PRESENCE
   Pin-ctls: 0x20: IN VREF_HIZ
   Unsolicited: tag=00, enabled=0
   Power states:  D0 D1 D2 D3 EPSS
   Power: setting=D0, actual=D0

Và rồi cũng giống như ở Headset, chúng ta không thấy bất kì kết nối trực tiếp nào nên mình đành phải tìm từ Audio Input/Mixer/Selector và rồi kết quả chẳng khác gì ở Headset vậy nên mình sẽ đưa hẳn kết quả luôn nhé!

Pathmap của Headphone sẽ là: 0x08 -> 0x23 -> 0x1a 0x09 -> 0x22 -> 0x1a, chuyển hết sang hệ decimal ta được: 8 -> 35 -> 26 9 -> 34 -> 26

Như vậy là đã xong pathmap cho codec ALC255, góp lại 1 lần nữa thôi 🙂

  • Speaker: 20 -> 12 -> 2
  • HP: 33 -> 13 -> 3
  • Mic: 8 -> 35 -> 18
  • Headset: 8 -> 35 -> 25 9 -> 34 -> 25
  • Headphone: 8 -> 35 -> 26 9 -> 34 -> 26

Save lại rồi đi tiếp thôi.

  • Xác định pathmap bằng codec_dump_dec.txt.svg (sẽ có khi bạn dùng script):

Sau khi bạn mở file, bạn sẽ nhận được 1 “mạng nhện” tương tự như sau

Nhìn mà hoa cả mắt đúng không nào? Chắc mình sẽ remove phần này mà chỉ hướng dẫn làm thủ công thôi =))

Patch Platforms.xml và layoutxx.xml

  • layout#.xml: Bạn mở layout11.xml nếu bạn dùng codec của Realtek, còn 2 hãng Conexant và IDT thì bạn mở layout26.xml nhé! Dù rằng 2 file khác nhau nhưng những thứ các bạn cần làm tiếp theo thì tương tự như nhau cả thôi.

Mình dùng codec Realtek nên mình sẽ mở layout11.xml, để bài viết ngắn gọn thì mình sẽ chỉnh sửa luôn cho dễ hiểu

Các bạn cần chỉnh 1 số thứ như sau:

  • LayoutID: bạn thay đổi hoặc giữ nguyên tuỳ thích, đây mình sẽ thay thành 15
  • CodecID: bạn cần thay bằng Vendor Id của codec ở hệ decimal đã chuẩn bị trên
  • Inputs: tuỳ vào codec của bạn có LineIn hay không, nếu không có thì xoá đi
  • PatchMapID: bạn có thể cho vào đây tên codec bạn patch hoặc bất kì số nào bạn thích

Sau khi chỉnh xong bạn save nó lại để đến với file tiếp theo nhé!

  • Platforms.xml: mở Platforms.xml, kèm với 1 chút chỉnh sửa, ta được như hình dưới
  • PathMaps -> 0 -> PathMap -> 0 -> 0 là Mic
  • PathMaps -> 0 -> PathMap -> 0 -> 1 là LineIn
  • PathMaps -> 0 -> PathMap -> 1 -> 0 là HP
  • PathMaps -> 0 -> PathMap -> 1 -> 1 là Speaker
  • PathMaps -> 0 -> PathMap -> PathMapID: ở đây bạn cần điền số giống với PathMapID ở layout#.xml.

Tiếp theo bạn điền thông tin pathmap đã xác định vào như sau

Nếu trường hợp không có Audio Mixer/Selector thì bạn xoá đi key 1, chỉ điền vào key 0 và key 2 thôi nhé!

Binary Patch

B1: Clone git AppleALCLilu

B2: Build kext Lilu rồi copy vào folder đã giải nén của AppleALC repo

B3: Mở folder AppleALC vừa giải nén, vào Resources, mình xoá hết các codec khác mà thừa lại codec mình lấy làm vd cho các bạn dễ nhìn

B4: Copy layout#.xml và Platforms#.xml chuẩn bị ở trên bỏ vào folder có tên codec sound mà bạn đang patch

B5: Mở AppleALC.xcodeproj -> PinConfigs -> Info.plist -> IOKitPersonalities -> HDA Hardware Config Resource -> HDAConfigDefault, bạn có thể tự tạo hoặc edit 1 cái có sẳn

Các bạn cần chỉnh 1 số thứ sau:

  • Codec: thay đổi tuỳ thích
  • CodecID: thay bằng Vendor Id của codec ở hệ decimal đã chuẩn bị trên
  • ConfigData: bạn copy codec verb đã chuẩn bị đưa vào đây
  • LayoutID: nhập layout-id bạn đã chọn để patch ở trên

B6: Mở AppleALC.xcodeproj -> Resources -> (tên codec bạn đang patch) -> Info.plist -> Information Property List -> Files

Ở đây bạn nhìn hình chắc cũng rõ cần chỉnh gì rồi nhỉ?

Sau khi chỉnh xong bạn save lại rồi ấn build thôi

Vậy là hoàn thành phần kext, tiếp theo bạn cho kext vừa build vào EFI/CLOVER/kexts/Other/ rồi inject layout-id và cuối cùng là bạn chị việc nhấn restart và chờ kết qua thôi!

Như vậy là mình đã hướng dẫn xong cách patch AppleHDA cho các bạn rồi!

Chúc các bạn thành công và hẹn gặp lại

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments