Fix trackpad
Tìm hiểu chung
Vẫn có một số máy gen 8 dùng ps2, ở trên chỉ mang tính chất khái quát
PS2 trackpad
Các bạn hãy patch pin trước khi làm bất cứ điều gì theo guide này
Synaptics PS2
B1: Download kext VoodooPS2controller.kext theo link sau: Releases
B2: Download kext VoodooRMI.kext theo link sau: Releases
B3: Vào folder Contents/Plugins của VoodooPS2Controller.kext, xóa VoodooPS2Mouse và xóa VoodooPS2Input, thêm kext VoodooSMBus.kext
nếu cần mới thêm, lấy theo link sau: Releases
B4: Dùng ProperTree để mở config.plist và chọn OC Snapshot
B5: Kéo xuống phần Kernel để tìm và Enable VoodooInput của VoodooRMI.kext và RMI SMBus
Có thể xóa
VoodooRMI I2Cnếu các bạn không cầnNếu là Synaptics I2C thì không cần xoá
B6: Khởi động lại máy.
Elan PS2
B1: Tải xuống kext từ nguồn tại đây
B2: Snaphot config bằng ProperTree
B3: Restart máy
Hầu hết các giao thức khác bạn chỉ việc patch cho hiển thị phần trăm pin và thêm kext voodoops2 là sẽ lên được
Fix i2c trackpad
Tìm Hiểu Chung
Gắp GPI0
Gắn ACPI ID
Pin List
À còn 1 phần nữa đó chế độ chạy của i2c gồm 2 chế độ:
Polling mode: loại sử dụng về phần cứng nên nó sẽ ăn tài nguyên nhiều hơnInterrupt mode: loại sử dụng về phần cứng nên nó ăn tài nguyên ít hơn
Nhiều hackintosher thích interrupt hơn polling nên ở cuối bài viết mình sẽ hướng dẫn cách chuyển từ polling mode sang Interrupt mode các bạn kiên nhẫn đọc hết bài từ trên xuống dưới để hiểu hết nội dung nhé.
Tiếp đó là Satelite type của i2c bao gồm các loại:
SynapticsHIDFTEELANAtmelMXT
Trong đó HID là loại phổ biến nhất. Bạn cần xác định Satelite type chính xác để sử dụng kext voodooi2c thích hợp
Gắn GPI0
GPI0B1: Tải ioreg tại đây
B2: Mở Ioreg lên và tiến hành Search GPIO

Như này là
GPIOđã được gắn
Nếu
GPIOchưa được gắn các bạn sẽ tiến hành làm như sau
B2: Dump DSDT theo hướng dẫn tại đây
B3: Search Device (GPI0)

Ở đây mình sẽ chia làm 2 mục nhỏ là đối với những bạn hot patch và static patch
Static Patch
Static Patchcác bạn sẽ tiến hành apply patch sau
into method label _STA parent_label GPI0 replace_content begin
Return (0x0F)
end;
into_all method code_regex If\s+\([\\]?_OSI\s+\(\"Windows\s2015\"\)\) replace_matched begin If(LOr(_OSI("Darwin"),_OSI("Windows 2015"))) end;HotPatch
HotPatchB1: các bạn sẽ cần quan sát method _sta ở device GPIO trong DSDT
Method (_STA, 0, NotSerialized)
{
If ((SBRG == Zero))
{
Return (Zero)
}
If ((GPEN == Zero))
{
Return (Zero)
}
Return (0x0F)
}Ở đây ta sẽ thấy có 2 method là
GPENVÀSBGRta chỉ cần sửa giá trị của 1 trong 2 method này thì Method_Stasẽ hoạt động. Bởi ta cần Method_statrả về giá trị là 0x0f nhưng nhìn vào đoạn ví dụ trên ta sẽ thấy
Nếu
SBRG=zerothìmethod _Stasẽ trả về giá trị làzeroNếu
GPEN=zerothìmethod _Stasẽ trả về giá trị làZero
Do đó để Method
_Statrả về0x0fthì ta phải chỉnh sửa giá trị của methodSBRGvàGPENTuy nhiên để đảm bảoGPIOhoạt động bình thường ta sẽ không nên đụng chạm vàoSBRGvậy ta sẽ tiến hành chỉnh sửa giá trị củaGPENcụ thể ở đây là ta sẽ chỉnh cho giá trịGPENthành 1 thì method_stasẽ trả về là0x0f
Nhưng không phải máy nào cũng vậy. Để cho các bạn hình dung rõ hơn mình sẽ cho thêm 1 ví dụ nữa

Method (_STA, 0, NotSerialized)
{
If ((GPHD == One))
{
Return (0x03)
}
Return (0x0F)
}Ở đây ta sẽ thấy sự khác biệt
Nếu method
GPHDtrả về giá trị là 1 thì method_stasẽ trả về là 0x03 nhưng giá trị để enable là0x0fVậy ta sẽ cần chỉnh method
GPHDvềzerothì method_stasẽ trả về là0x0f
B2: Ta sẽ edit SSDT-GPIO

// Source: https://github.com/daliansky/OC-little
DefinitionBlock("", "SSDT", 2, "DRTNIA", "GPI0", 0)
{
External(\GPEN, FieldUnitObj)
If (_OSI("Darwin"))
{
\GPEN = One
}
}Ở đây ta sẽ cần phải chỉnh mục này
If (_OSI ("Darwin"))
{
\GPEN = One
}Nếu như method _sta call qua 1 method khác không phải
GPENthì các bạn sẽ tiến hành đổi tên thành method đấyTiếp theo các bạn sẽ cần đọc DSDT để chỉnh giá trị tương ứng
như ở ví dụ 1 ta sẽ set là
oneVí dụ 2 sẽ set là
zero
If (_OSI ("Darwin"))
{
\GPHD = Zero
}B3: Thông thường các thiết bị i2c sẽ kiểm tra chúng có đang chạy trong Windows hay không trước khi tự kích hoạt. Tương tự như GPIO ở đây chúng ta cũng sẽ làm việc trên method _sta
Còn 1 các nữa là
Create OSYS Variable Under I2C Scopenhưng mình thấy không cần thiết nên mình sẽ không hướng dẫn cách này
1 lưu ý nữa là nếu các bạn đã làm đúng mà GPIO vẫn ko được gắn thì các bạn có thể thử add boot-arg sau vào
-vi2c-force-pollingnhằm force polling mode khi dùng arg này bạn sẽ không thể chuyển quanInterrupt mode
Gắn ACPI ID i2c device
Tiến hành
B1: Các bạn cần xác định xem i2c của bạn đang thuộc Satelite type nào xem hướng dẫn chi tiết tại đây
B2: Tải voodooi2c tại đây
B3: Các bạn sẽ tiến hành thêm kext những kext sau vào EFI ==> OC ==> Kext và snapshot
Hoặc
EFI ==> Clover ==> Kext ==> Other
VoodooI2C.kext
VoodooI2cSatelite.kext
Những kext voodoo i2c có tên trùng với Satelite type của bạn
B4: reboot
Kiểm tra gắn ACPI ID
Các bạn sẽ cần boot vào win tìm đến mục Device Manager ==> Human Interfaces Device ==> I2C HID device để xác định ACPI ID

Ở đây ta có ACPI ID là TPL0
// Các ACPI ID phổ biến:
1. Touchpads - TPDX, ELAN, SYNA, CYPR
2. Touchscreen - TPLX, ELAN, ETPD, SYNA, ATML
3. Sensor Hubs - SHUB
Force patch ACPI ID i2c device
Các bạn mở DSDT ra tìm đến ACPI ID i2c device của các bạn và chú ý vào method _sta chúng ta sẽ tiến hành xoá các dòng if để method _sta luôn trả về 0x0f tức là luôn bật

Thông thường khi làm như trên các bạn đã có thể gắn ACPI ID nếu vẫn chưa gắn được ACPI ID thì các bạn bắt buộc phải tự đọc DSDT và tự tìm hiểu
Cách ở trên là
Static PatchđểHot Patchđược cách này các bạn có thể theo hướng dẫn tại đây
Cách xác định i2c mode
i2c modeNhư đã nói ở trên i2c có 2 loại là Polling và Interrupt vậy làm sao đê biết thiết bị của bạn đang ở loại nào
Dùng Ioreg
IoregB1: Mở ioreg ra
B2: Tìm đến ACPI ID i2c device đã xác định ở trên
B3: Chú ý vào mục interupt mode và để ý giá trị của nó bạn sẽ xác định được trackpad mình đang ở loại nào


Dùng Gen i2c
B1 Tải app Gen i2c tại đây
B2: mở app ra và chú ý vào mục mode


Pin List
Phần này rất hiếm người cần dùng đến. Tuy nhiên nếu bạn cần dùng thì hãy đọc thật chậm và kỹ lưỡng nhé
Nếu bạn đọc phần này tức là thiết bị của bạn đang là interrupt
B1: Check xem Pin Number của bạn. Mở ioreg và tìm đến ACPI-ID của các bạn, chú ý vào dòng IOInterruptSpecifiers. Nếu như không có dòng đó hoặc giá trị nhỏ hơn 0X2F (47) thì không cần làm gì nữa

Như ở đây ta có
Pin numberlà0x33. Tại sao là0x33vì ta chỉ lấy hai chữ số đầu của dãy số.0x33lớn hơn0x27nên tả sẽ phải tiến hành patch pin list cho nó.

Việc đầu tiên cần làm là xác định name SBFX mà như hình là SBFG ta có 2 loại pin 1 là pin crs hai là pin root:
Pin root:name SBFXđược tìm thấy ở ngayACPI-IDPin CRS:name SBFXđược tìm thấy ởmethod crs
Ở đây ta sẽ chú ý vào dòng note //pin list nếu giá trị khác 0x0000 thì thiết bị của bạn đang được pin tốt. Tuy nhiên nếu là 0x0000 thì đừng vội lo lắng bạn hãy tiến hành kiểm tra dòng return của method crs nếu nó có call tới method crs thì thiết bị của bạn vẫn đang được pin tốt ở đây ta có

If (LEqual (TPDM, Zero))
{
Return (ConcatenateResTemplate (SBFB, SBFG))
}
Return (ConcatenateResTemplate (SBFB, SBFI))2 dòng return ta có:
SBFGcó nghĩa làinterrupt modeSBFIcó nghĩa làpolling mode
Mà GPIO pin patch đòi hỏi bạn phải ở interrupt mode ta sẽ tieén hành edit method crs để cho nó luôn trả về là interrupt mode
Return (ConcatenateResTemplate (SBFB, SBFG))
Ở đây ta có
//pin listnếu là0x00000thì các bạn làm như vầy để cho nó trở thành pin tốt nếu khác0x0000thì các bạn cũng cần làm bước này để cho nó luôn trả vềinterrupt
Nhưng nếu bạn không tìm thấy
name SBFXở cả ACPI ID i2c device và methodcrsthì có nghĩa là i2c device của bạn chưa được pin. Nếu như vậy bạn sẽ cần phải tiến hành gắn pin thủ công xem ở bước 2
B2: Các bạn sẽ tiến hành add Name SBFX vào ACPI id i2c device (đây gọi là gắn pin thủ công chỉ khi thiết bị của bạn không được pịn mới cần làm)
Name (SBFG, ResourceTemplate ()
{
GpioInt (Level, ActiveLow, ExclusiveAndWake, PullDefault, 0x0000,
"\\_SB.PCI0.GPI0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0000
}
})
B3: các bạn sẽ cần mở ioreg lên và search GPIO

Ta có thể thấy ở đây là CannonLakeH, tiến hành tra nó theo bảng sau
CannonLakeHcó thể dùng củaCannon Point-H
B4: mở file text bên text 1 và search Pin number đã xác định được ở ioreg

Ở đây ta sẽ copy mục name và search bên text 2

Ta sẽ copy giá trị nhận được là 43 và dùng hackintool
convert decimal to hex

Ta có
GPIO numberở đây là 0x2B
Ta tiến hành edit DSDT như sau

Ngoài ra khi
Pin numbercủa bạn có nhiều giá trị chân GPIO bạn sẽ cần phải thử từng cái một

Đối với các dòng
Cannon Pointtrở lên có sự không khớp giữaGPIO Pin numbervàhardware pin number. Nếu bạn sử dụng loại phần cúng này thì bạn sẽ cần converthardware pin numberthànhGPIO number
Nếu bạn không biết mình có đang sử dụng phần cứng này không thì bạn cứ thử từng cái thử cách bình thường trước
B1: mở file text1 ra và search Pin number nhận được ở ioreg sau đó copy phần name tương ứng như hướng dẫn ở trên
B2: mở file text 2′ lên và xem phần tôi khoanh đỏ

Ở đây ta có thể sẽ thấy được ý nghĩa các dòng trong file text
B3: search name đã lấy được ở file 1 trong text 2′
B4: ta sẽ lấy Pin number lấy được ở ioreg (ở decimal) trừ đi cho base cộng cho gpio_base
Tức là Pin number - s + gB5: convert GPIO number vừa nhận được thành hex
B6: edit DSDT theo hướng dẫn ở trên
Chú ý vị trị nằm của r s e g
Force Polling mode
Đối với các máy ở chế độ polling mode mà không native thì các bạn có thể tiến hành force polling mode
Edit DSDT
B1: Mở DSDT lên và tìm đến mục ACPI ID ở DSDT sau đó chú ý vào method crs ta có:
SBFI: làpolling modeSBFG: làinterrupt
Do đó việc bạn cần làm chỉ đơn giản là xoá return của SBFG đi và chỉ để lại return của SBFI

Lưu ý ngoài name
SBFIra thì bạn cũng có thể sử dụng nameSBFBKhi dòng return có name khác đứng cùng name
SBFIthì sẽ tiến hành rename nó thànhSBFB
Add boot-arg
B1: mở config
B2: thêm boot-arg -vi2c-force-polling
B3: save lại và reboot
Force interrupt mode
B1: Các bạn tìm ACPI-id của các bạn trong DSDT sau đó kéo lên mục scope bạn sẽ có thể thấy name SBFB và một name SBFX nào đó theo sau nó như hình

B2: Chúng ta sẽ cần xem name SBFX đó có dòng nào đại loại như
Interrupt (ResourceConsumer, Level, ActiveLow, ExclusiveAndWake, ,, _Y3A)Thì tiến hành xoá cả phần đó đi
Ngoài ra có trường hợp bạn sẽ không tìm thấy name
SBFBmà sẽ tìm thấy 1 nameSPFXđại loại như là
Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings
{
Name (SBFI, ResourceTemplate ()
{
I2cSerialBusV2 (0x0015, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C1",
0x00, ResourceConsumer, , Exclusive,
)
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, )
{
0x0000006D,
}
})
Return (SBFI)
}B3: các bạn cần chuyển SBFX to SBFB
B4: xóa dòng này đi nếu có
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, )
{
0x0000006D,
}B5: Nếu bạn đang ở polling mode muốn force sang interrupt mode thì các bạn cần xem DSDT đã có pin chưa và nếu đã có pin thì chú ý vào name của pin đó nếu là SBFB hoặc SBFG thì bỏ qua nếu là SBFI hoặc các SBFX khác thì rename nó sang SBFG
B6: Các bạn sẽ tiến hành chỉnh method CRS. xoá hết các dòng return đi chỉ chừa lại dòng có name SBFG. Nếu name khai báo cùng SBFG không phải SBFB thì bạn sẽ cần rename nó là SBFB


Tổng kết I2C
I2C Đối với các thiết bị laptop dell hoặc HP khi patch trackpad nếu bị giật lag hãy thêm kext AlpsHID.kext vào nhé
Chú ý rằng khi force từ
polling modesanginterrupt modethì bạn có thể sẽ cần phải pin list nếu như không tìm thấy nameSBFX
Source tham khảo: GPIO Pinning (voodooi2c.github.io) | Trackpad on Hackintosh với giao thức I2C – Hackintosh Vietnam – Chuyên trang cung cấp hướng dẫn cài hackintosh | Fixing Trackpads: Manual | Getting Started With ACPI (dortania.github.io) | Polling Mode (voodooi2c.github.io)
Thanks you
Last updated