• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3/*
4 * Include this file into a mainboard's DSDT _SB device tree and it will
5 * expose the SCH5545 SuperIO and some of its functionality.
6 *
7 * It allows the change of IO ports, IRQs and DMA settings on logical
8 * devices, disabling and reenabling logical devices and controlling power
9 * saving mode on logical devices or the whole chip.
10 *
11 *   LDN		State
12 * 0x0 FDC		Not implemented
13 * 0x3 PP		Not implemented
14 * 0x4 UARTA		Implemented and tested
15 * 0x5 UARTB		Implemented
16 * 0x7 KBC		Implemented and tested
17 *
18 * Controllable through preprocessor defines:
19 * SUPERIO_PNP_BASE	I/O address of the first PnP configuration register
20 * SCH5545_SHOW_UARTA	If defined, UARTA will be exposed.
21 * SCH5545_SHOW_UARTB	If defined, UARTB will be exposed.
22 * SCH5545_SHOW_KBC	If defined, the KBC will be exposed.
23 * SCH5545_EMI_BASE	If defined, the Embedded Memory Interface resource will be exposed.
24 * SCH5545_RUNTIME_BASE	If defined, The Runtime Registers resource will be exposed.
25 */
26
27#undef SUPERIO_CHIP_NAME
28#define SUPERIO_CHIP_NAME SCH5545
29#include <superio/acpi/pnp.asl>
30
31#undef PNP_DEFAULT_PSC
32#define PNP_DEFAULT_PSC Return (0) /* no power management */
33
34/*
35* Common helpers will not work on this chip. IO, DMA and IRQ resources.
36* These are accessed via LPC interface LDN 0xC.
37*/
38#undef PNP_READ_IO
39#undef PNP_READ_IRQ
40#undef PNP_READ_DMA
41#undef PNP_WRITE_IO
42#undef PNP_WRITE_IRQ
43#undef PNP_WRITE_DMA
44
45Device(SIO1) {
46	Name (_HID, EisaId("PNP0A05"))
47	Name (_STR, Unicode("SMSC SCH5545 Super I/O"))
48	Name (_UID, SUPERIO_UID(SIO1,))
49
50#ifdef SCH5545_EMI_BASE
51	Name (IO1B, SCH5545_EMI_BASE)
52#endif
53#ifdef SCH5545_RUNTIME_BASE
54	Name (IO2B, SCH5545_RUNTIME_BASE)
55#endif
56	Name (IOST, 0x0001) /* IO decoding status */
57	Name (MSFG, 1) /* Mouse wake config */
58	Name (KBFG, 1) /* Keyboard wake config */
59
60	/* SuperIO configuration ports */
61	OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02)
62	Field (CREG, ByteAcc, NoLock, Preserve)
63	{
64		PNP_ADDR_REG,	8,
65		PNP_DATA_REG,	8
66	}
67	IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve)
68	{
69		Offset (0x07),
70		PNP_LOGICAL_DEVICE,	8, /* Logical device selector */
71
72		Offset (0x30),
73		PNP_DEVICE_ACTIVE,	1, /* Logical device activation */
74
75		Offset (0x69),
76		CR69,	8,	/* UART1 Base address Registers */
77		CR6A,	8,
78		CR6B,	8,
79		Offset (0x6D),
80		CR6D,	8,	/* UART2 Base address Registers */
81		CR6E,	8,
82		CR6F,	8,
83		Offset (0x7D),
84		CR7D,	8,	/* FD Base address Registers */
85		CR7E,	8,
86		CR7F,	8,
87		Offset (0x81),
88		CR81,	8,	/* LPT Base address Registers */
89		CR82,	8,
90		CR83,	8,
91		Offset (0xF0),
92		OPT0,	8,	/* MISC registers */
93		OPT1,	8,
94		OPT2,	8,
95		OPT3,	8,
96		OPT4,	8,
97		OPT5,	8
98	}
99
100#ifdef SCH5545_RUNTIME_BASE
101	/* Runtime registers */
102	OperationRegion (RNTR, SystemIO, SCH5545_RUNTIME_BASE, 0x40)
103	Field (RNTR, ByteAcc, NoLock, Preserve)
104	{
105		PMES,	1,	/* PME Global Status */
106		Offset (0x01),
107		PMEN,	1,	/* PME Global Enable */
108		Offset (0x02),
109		PMS1,	8,	/* PME Status 1 for KBD and PS2M */
110		PMS2,	8,	/* PME Status 2 for EC, WDT, Bat, Intruder */
111		PMS3,	8,	/* PME Status 3 for GPIOs */
112		PME1,	8,	/* PME Enable 1 for KBD and PS2M */
113		PME2,	8,	/* PME Enable 2 for EC, WDT, Bat, Intruder */
114		PME3,	8,	/* PME Enable 3 for GPIOs */
115		Offset (0x10),
116		SOIS,	1,	/* SMI Global Status*/
117		Offset (0x11),
118		SOIE,	1,	/* SMI Global Enable */
119		Offset (0x12),
120		SST1,	8,	/* SMI Status 1 for UARTs, LPT, FD, EC, Bat */
121		SST2,	8,	/* SMI Status 2 for KBD, PS2M, WDT, Intruder */
122		SST3,	8,	/* SMI Status 3 for GPIOs */
123		Offset (0x16),
124		SEN1,	8,	/* SMI Enable 1 for UARTs, LPT, FD, EC, Bat */
125		SEN2,	8,	/* SMI Enable 2 for KBD, PS2M, WDT, Intruder */
126		SEN3,	8,	/* SMI Enable 3 for GPIOs */
127		Offset (0x25),
128		LED1,	8,	/* LED control register */
129		Offset (0x28),
130		GPSR,	8,	/* GPIO Select Register  */
131		GPRR,	8	/* GPIO Read Register */
132	}
133#endif
134	Name (CRS, ResourceTemplate ()
135	{
136		IO (Decode16,
137			0x0000,
138			0x0000,
139			0x00,
140			0x00,
141			_Y11)
142#ifdef SCH5545_EMI_BASE
143		IO (Decode16,
144			0x0000,
145			0x0000,
146			0x00,
147			0x00,
148			_Y12)
149#endif
150#ifdef SCH5545_RUNTIME_BASE
151		IO (Decode16,
152			0x0000,
153			0x0000,
154			0x00,
155			0x00,
156			_Y13)
157#endif
158	})
159	Method (_CRS, 0, NotSerialized)
160	{
161		If (SUPERIO_PNP_BASE)
162		{
163			CreateWordField (CRS, \_SB.PCI0.LPCB.SIO1._Y11._MIN, GPI0)
164			CreateWordField (CRS, \_SB.PCI0.LPCB.SIO1._Y11._MAX, GPI1)
165			CreateByteField (CRS, \_SB.PCI0.LPCB.SIO1._Y11._LEN, GPIL)
166			GPI0 = SUPERIO_PNP_BASE
167			GPI1 = SUPERIO_PNP_BASE
168			GPIL = 0x02
169		}
170#ifdef SCH5545_EMI_BASE
171		If (IO1B)
172		{
173			CreateWordField (CRS, \_SB.PCI0.LPCB.SIO1._Y12._MIN, GP10)
174			CreateWordField (CRS, \_SB.PCI0.LPCB.SIO1._Y12._MAX, GP11)
175			CreateByteField (CRS, \_SB.PCI0.LPCB.SIO1._Y12._LEN, GPL1)
176			GP10 = SCH5545_EMI_BASE
177			GP11 = SCH5545_EMI_BASE
178			GPL1 = 0x10
179		}
180#endif
181#ifdef SCH5545_RUNTIME_BASE
182		If (IO2B)
183		{
184			CreateWordField (CRS, \_SB.PCI0.LPCB.SIO1._Y13._MIN, GP20)
185			CreateWordField (CRS, \_SB.PCI0.LPCB.SIO1._Y13._MAX, GP21)
186			CreateByteField (CRS, \_SB.PCI0.LPCB.SIO1._Y13._LEN, GPL2)
187			GP20 = SCH5545_RUNTIME_BASE
188			GP21 = SCH5545_RUNTIME_BASE
189			GPL2 = 0x40
190		}
191#endif
192		Return (CRS)
193	}
194
195	#undef PNP_ENTER_MAGIC_1ST
196	#undef PNP_ENTER_MAGIC_2ND
197	#undef PNP_ENTER_MAGIC_3RD
198	#undef PNP_ENTER_MAGIC_4TH
199	#undef PNP_EXIT_MAGIC_1ST
200	#undef PNP_EXIT_SPECIAL_REG
201	#undef PNP_EXIT_SPECIAL_VAL
202	#define PNP_ENTER_MAGIC_1ST	0x55
203	#define PNP_EXIT_MAGIC_1ST	0xaa
204	#include <superio/acpi/pnp_config.asl>
205	#define SUPERIO_LPC_LDN 0x0C
206	#include "resource_helpers.asl"
207
208#ifdef SCH5545_SHOW_KBC
209	Device (PS2K)
210	{
211		Name (_HID, EisaId ("PNP0303"))
212		Name (_CID, EisaId ("PNP030B"))
213		Method (_STA, 0, NotSerialized)
214		{
215			Return (DSTA (0xa))
216		}
217
218		Name (_CRS, ResourceTemplate ()
219		{
220			IO (Decode16,
221				0x0060,
222				0x0060,
223				0x00,
224				0x01,
225				)
226			IO (Decode16,
227				0x0064,
228				0x0064,
229				0x00,
230				0x01,
231				)
232			IRQ (Edge, ActiveHigh, Exclusive) {1}
233		})
234		Method (_PSW, 1, NotSerialized)  // _PSW: Power State Wake
235		{
236			KBFG = Arg0
237		}
238		Name (_PRW, Package() { 8, 3 })
239	}
240
241	Device (PS2M)
242	{
243		Name (_HID, EisaId ("PNP0F13"))
244		Method (_STA, 0, NotSerialized)
245		{
246			Return (DSTA (0xe))
247		}
248
249		Name (_CRS, ResourceTemplate ()
250		{
251			IRQ (Edge, ActiveHigh, Exclusive) {12}
252		})
253
254		Method (_PSW, 1, NotSerialized)
255		{
256			MSFG = Arg0
257		}
258
259		Name (_PRW, Package() { 8, 3 })
260	}
261
262	OperationRegion (IOKP, SystemIO, 0x60, 0x05)
263	Field (IOKP, ByteAcc, NoLock, Preserve)
264	{
265		KP60,	8,
266		Offset (0x04),
267		KP64,	8
268	}
269
270	OperationRegion (KB64, SystemIO, 0x64, 1)
271	Field (KB64, ByteAcc, NoLock, Preserve)
272	{
273		,	1,
274		KRDY,	1,
275		Offset (0x01)
276	}
277#ifdef SCH5545_RUNTIME_BASE
278	/* SIO prepare to sleep */
279	Method (SIOS, 1, NotSerialized)
280	{
281		If ((Arg0 == 0x03) | (Arg0 == 1))
282		{
283			ENTER_CONFIG_MODE (1)
284			Local0 = OPT0
285			OPT0 = (Local0 | 0x60)
286			EXIT_CONFIG_MODE ()
287			Local0 = PMS1
288			PMS1 = (Local0 | 0x18)
289			Local0 = PMES
290			PMES = (Local0 | 1)
291
292			Local0 = PME1
293			If (KBFG)
294			{
295				PME1 = (Local0 | 0x08)
296			}
297			Else
298			{
299				PME1 = (Local0 & 0xF7)
300			}
301
302			Local0 = PME1
303			If (MSFG)
304			{
305				PME1 = (Local0 | 0x10)
306			}
307			Else
308			{
309				PME1 = (Local0 & 0xEF)
310			}
311
312			Local0 = PMEN
313			PMEN = (Local0 | 1)
314
315			While (KRDY) {}
316			KP60 = 0xED
317			While (KRDY) {}
318			KP60 = 0
319			While (KRDY) {}
320			KP60 = 0xF4
321			Sleep (1)
322		}
323	}
324
325	Method (GPKM, 0, NotSerialized)
326	{
327		Local0 = PME1
328		PME1 = (Local0 & 0xE7)
329		Local0 = PMEN
330		PMEN = (Local0 & 0xFE)
331		Local0 = PMS1
332		PMS1 = (Local0 & 0x18)
333		Local0 = PMES
334		PMES = (Local0 & 1)
335	}
336
337	/* SIO wake method */
338	Method (SIOW, 1, NotSerialized)
339	{
340		If (Arg0 == 1)
341		{
342			GPKM ()
343			ENTER_CONFIG_MODE (1)
344			Local0 = OPT0
345			OPT0 = (Local0 & 0x9F)
346			EXIT_CONFIG_MODE ()
347		}
348
349		If (Arg0 == 0x03)
350		{
351			GPKM ()
352			ENTER_CONFIG_MODE (1)
353			Local0 = OPT0
354			OPT0 = (Local0 & 0x9F)
355			OPT2 |= 1
356			OPT2 &= 0xFE
357			EXIT_CONFIG_MODE ()
358		}
359	}
360
361	Method (SIOH, 0, NotSerialized)
362	{
363		Local0 = PMS1
364
365		If (Local0 & 0x08)
366		{
367			PMS1 = 0x08
368			Notify (PS2K, 0x02) // Device Wake
369		}
370
371		If (Local0 & 0x10)
372		{
373			PMS1 = 0x10
374			Notify (PS2M, 0x02) // Device Wake
375		}
376
377		If (Local0 & 0x04)
378		{
379			PMS1 = 0x04
380#ifdef SCH5545_SHOW_UARTA
381			Notify (UAR1, 0x02) // Device Wake
382#endif
383		}
384
385		If (Local0 & 0x02)
386		{
387			PMS1 = 0x02
388#ifdef SCH5545_SHOW_UARTB
389			Notify (UAR2, 0x02) // Device Wake
390#endif
391		}
392
393		Local0 = PMES
394		PMES = (Local0 & 1)
395	}
396#endif // SCH5545_RUNTIME_BASE
397#endif // SCH5545_SHOW_KBC
398
399#ifdef SCH5545_SHOW_UARTA
400#define SUPERIO_UARTA_LDN 7
401	Device (UAR1)
402	{
403		Name (_HID, EisaId ("PNP0501"))
404		Name (_UID, SUPERIO_UID(SER, SUPERIO_UARTA_LDN))
405		Method (_STA, 0, NotSerialized)
406		{
407			Return (DSTA (0))
408		}
409
410		Method (_DIS, 0, NotSerialized)
411		{
412			DCNT (0, 0)
413		}
414
415		Method (_CRS, 0, NotSerialized)
416		{
417			Return (DCRS (0, 0))
418		}
419
420		Method (_SRS, 1, NotSerialized)
421		{
422			CreateWordField (Arg0, 0x02, IO11)
423			CreateWordField (Arg0, 0x09, IRQM)
424			ENTER_CONFIG_MODE (SUPERIO_LPC_LDN)
425			STIO (0x6A, IO11)
426			SIRQ (0, IRQM)
427			EXIT_CONFIG_MODE ()
428			DCNT (0, 1)
429		}
430
431		Name (_PRS, ResourceTemplate ()
432		{
433			StartDependentFn (0x00, 0x00)
434			{
435				IO (Decode16,
436					0x03F8,
437					0x03F8,
438					0x01,
439					0x08,
440					)
441				IRQNoFlags ()
442					{4}
443				DMA (Compatibility, NotBusMaster, Transfer8, )
444					{}
445			}
446			StartDependentFn (0x00, 0x00)
447			{
448				IO (Decode16,
449					0x02F8,
450					0x02F8,
451					0x01,
452					0x08,
453					)
454				IRQNoFlags ()
455					{3}
456				DMA (Compatibility, NotBusMaster, Transfer8, )
457					{}
458			}
459			StartDependentFn (0x00, 0x00)
460			{
461				IO (Decode16,
462					0x03E8,
463					0x03E8,
464					0x01,
465					0x08,
466					)
467				IRQNoFlags ()
468					{4}
469				DMA (Compatibility, NotBusMaster, Transfer8, )
470					{}
471			}
472			StartDependentFn (0x00, 0x00)
473			{
474				IO (Decode16,
475					0x02E8,
476					0x02E8,
477					0x01,
478					0x08,
479					)
480				IRQNoFlags ()
481					{3}
482				DMA (Compatibility, NotBusMaster, Transfer8, )
483					{}
484			}
485			EndDependentFn ()
486		})
487
488		Name (_PRW, Package() { 8, 3 })
489	}
490#endif
491
492#ifdef SCH5545_SHOW_UARTB
493#define SUPERIO_UARTB_LDN 8
494	Device (UAR2)
495	{
496		Name (_HID, EisaId ("PNP0501"))
497		Name (_UID, SUPERIO_UID(SER, SUPERIO_UARTB_LDN))
498		Method (_STA, 0, NotSerialized)
499		{
500			Return (DSTA (1))
501		}
502
503		Method (_DIS, 0, NotSerialized)
504		{
505			DCNT (1, 0)
506		}
507
508		Method (_CRS, 0, NotSerialized)
509		{
510			Return (DCRS (1, 0))
511		}
512
513		Method (_SRS, 1, NotSerialized)
514		{
515			CreateWordField (Arg0, 0x02, IO11)
516			CreateWordField (Arg0, 0x09, IRQM)
517			ENTER_CONFIG_MODE (SUPERIO_LPC_LDN)
518			STIO (0x6E, IO11)
519			SIRQ (1, IRQM)
520			EXIT_CONFIG_MODE ()
521			DCNT (1, 1)
522		}
523
524		Name (_PRS, ResourceTemplate ()
525		{
526			StartDependentFn (0x00, 0x00)
527			{
528				IO (Decode16,
529					0x03F8,
530					0x03F8,
531					0x01,
532					0x08,
533					)
534				IRQNoFlags ()
535					{4}
536				DMA (Compatibility, NotBusMaster, Transfer8, )
537					{}
538			}
539			StartDependentFn (0x00, 0x00)
540			{
541				IO (Decode16,
542					0x02F8,
543					0x02F8,
544					0x01,
545					0x08,
546					)
547				IRQNoFlags ()
548					{3}
549				DMA (Compatibility, NotBusMaster, Transfer8, )
550					{}
551			}
552			StartDependentFn (0x00, 0x00)
553			{
554				IO (Decode16,
555					0x03E8,
556					0x03E8,
557					0x01,
558					0x08,
559					)
560				IRQNoFlags ()
561					{4}
562				DMA (Compatibility, NotBusMaster, Transfer8, )
563					{}
564			}
565			StartDependentFn (0x00, 0x00)
566			{
567				IO (Decode16,
568					0x02E8,
569					0x02E8,
570					0x01,
571					0x08,
572					)
573				IRQNoFlags ()
574					{3}
575				DMA (Compatibility, NotBusMaster, Transfer8, )
576					{}
577			}
578			EndDependentFn ()
579		})
580
581		Name (_PRW, Package() { 8, 3 })
582	}
583
584#endif
585}
586