1 /* $NetBSD: sequoia.c,v 1.17 2022/10/15 21:53:21 andvar Exp $ */
2
3 /*
4 * Copyright 1997
5 * Digital Equipment Corporation. All rights reserved.
6 *
7 * This software is furnished under license and may be used and
8 * copied only in accordance with the following terms and conditions.
9 * Subject to these conditions, you may download, copy, install,
10 * use, modify and distribute this software in source and/or binary
11 * form. No title or ownership is transferred hereby.
12 *
13 * 1) Any source code used, modified or distributed must reproduce
14 * and retain this copyright notice and list of conditions as
15 * they appear in the source file.
16 *
17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Digital Equipment Corporation. Neither the "Digital Equipment
19 * Corporation" name nor any trademark or logo of Digital Equipment
20 * Corporation may be used to endorse or promote products derived
21 * from this software without the prior written permission of
22 * Digital Equipment Corporation.
23 *
24 * 3) This software is provided "AS-IS" and any express or implied
25 * warranties, including but not limited to, any implied warranties
26 * of merchantability, fitness for a particular purpose, or
27 * non-infringement are disclaimed. In no event shall DIGITAL be
28 * liable for any damages whatsoever, and in particular, DIGITAL
29 * shall not be liable for special, indirect, consequential, or
30 * incidental damages or damages for lost profits, loss of
31 * revenue or loss of use, whether such damages arise in contract,
32 * negligence, tort, under statute, in equity, at law or otherwise,
33 * even if advised of the possibility of such damage.
34 */
35
36 /*
37 **
38 ** INCLUDE FILES
39 **
40 */
41
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: sequoia.c,v 1.17 2022/10/15 21:53:21 andvar Exp $");
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/callout.h>
48 #include <sys/device.h>
49 #include <sys/syslog.h>
50 #include <sys/types.h>
51 #include <sys/bus.h>
52 #include <sys/time.h>
53 #include <sys/kernel.h>
54
55 #include <dev/isa/isareg.h>
56 #include <dev/ofisa/ofisavar.h>
57 #include <machine/isa_machdep.h>
58 #include <shark/shark/sequoia.h>
59 #include <shark/shark/shark_fiq.h>
60 #include <arm/cpufunc.h>
61
62 #include <dev/ofw/openfirm.h>
63
64
65
66 /*
67 **
68 ** MACROS
69 **
70 */
71
72 /* define registers on sequoia used by pins */
73 #define SEQUOIA_1GPIO PMC_GPCR_REG /* reg 0x007 gpio 0-3 */
74 #define SEQUOIA_2GPIO SEQ2_OGPIOCR_REG /* reg 0x304 gpio 4.8 */
75
76 /* define pins on sequoia that talk to smart card reader */
77 #define SCR_DETECT_DIR GPIOCR2_M_GPIOBDIR0
78 #define SCR_DETECT GPIOCR2_M_GPIOBDATA0
79
80
81 #define SCR_POWER_DIR GPCR_M_GPIODIR0
82 #define SCR_POWER GPCR_M_GPIODATA0
83
84 #define SCR_RESET_DIR GPCR_M_GPIODIR1
85 #define SCR_RESET GPCR_M_GPIODATA1
86
87 #define SCR_CLOCK_DIR OGPIOCR_M_GPIODIR6
88 #define SCR_CLOCK OGPIOCR_M_GPIODATA6
89
90 #define SCR_DATA_IN_DIR GPCR_M_GPIODIR2
91 #define SCR_DATA_IN GPCR_M_GPIODATA2
92
93 #define SCR_DATA_OUT_DIR OGPIOCR_M_GPIODIR5
94 #define SCR_DATA_OUT OGPIOCR_M_GPIODATA5
95
96 #define SCR_BUGA_DIR OGPIOCR_M_GPIODIR4
97 #define SCR_BUGA OGPIOCR_M_GPIODATA4
98
99 #define SCR_BUGB_DIR OGPIOCR_M_GPIODIR7
100 #define SCR_BUGB OGPIOCR_M_GPIODATA7
101
102
103
104 /* define pins on sequoia that talk to leds */
105 #define LED_BILED_YELLOW_BIT FOMPCR_M_PCON5
106 #define LED_BILED_GREEN_BIT FOMPCR_M_PCON6
107
108 #define LED_DEBUG_YELLOW_BIT FOMPCR_M_PCON7
109 #define LED_DEBUG_GREEN_BIT FOMPCR_M_PCON8
110
111
112 /* define biled colors */
113 #define LED_BILED_NONE 0
114 #define LED_BILED_GREEN 1
115 #define LED_BILED_YELLOW 2
116 #define LED_BILED_RED 3
117
118
119 #define LED_TIMEOUT hz / 20 /* 20 times a second */
120 #define LED_NET_ACTIVE (1000000/hz) * LED_TIMEOUT /* delay in us for net activity */
121
122
123
124
125 /*
126 **
127 ** DATA
128 **
129 */
130 static bus_space_handle_t sequoia_ioh;
131
132 static struct timeval ledLastActive; /* last time we get net activity */
133 static int ledColor; /* present color of led */
134 static int ledBlockCount; /* reference count of block calles */
135 int sequoia_index_cache = -1; /* set to silly value so that we dont cache on init */
136
137 static callout_t led_timo_ch;
138
139 static u_int sequoiaLock_savedints;
140 static bool sequoiaLock_held;
141
142 /*
143 **
144 ** FUNCTIONAL PROTOTYPES
145 **
146 */
147 static void ledSetBiled(int color);
148 static void ledTimeout(void *arg);
149
150 /*
151 **
152 ** FUNCTIONS
153 **
154 */
sequoiaInit(void)155 void sequoiaInit(void)
156 {
157 u_int16_t seqReg;
158
159 /* map the sequoia registers */
160 if (bus_space_map(&isa_io_bs_tag, SEQUOIA_BASE, SEQUOIA_NPORTS, 0, &sequoia_ioh))
161 {
162 panic("SequoiaInit: io mapping failed");
163 }
164
165 sequoiaLock();
166
167 /*
168 **
169 ** setup the pins associated with the X server
170 **
171 */
172 /* seems power on sets them correctly */
173
174
175
176 /*
177 ** setup the pins associated with the led
178 */
179 sequoiaRead(SEQR_SEQPSR1_REG,&seqReg);
180 SET(seqReg,SEQPSR1_M_TAGDEN); /* enable pc[4:9] */
181 sequoiaWrite(SEQR_SEQPSR1_REG,seqReg);
182
183
184 sequoiaRead(SEQR_SEQPSR3_REG,&seqReg);
185 CLR(seqReg,SEQPSR3_M_PC5PINEN); /* enable pc5, biled */
186 CLR(seqReg,SEQPSR3_M_PC6PINEN); /* enable pc6, biled */
187 CLR(seqReg,SEQPSR3_M_PC7PINEN); /* enable pc7, debug led yellow */
188 CLR(seqReg,SEQPSR3_M_PC8PINEN); /* enable pc8, debug led green */
189 sequoiaWrite(SEQR_SEQPSR3_REG,seqReg);
190
191 sequoiaRead (PMC_FOMPCR_REG, &seqReg);
192 CLR(seqReg,LED_BILED_YELLOW_BIT);
193 CLR(seqReg,LED_BILED_GREEN_BIT);
194 SET(seqReg,LED_DEBUG_YELLOW_BIT);
195 CLR(seqReg,LED_DEBUG_GREEN_BIT);
196 sequoiaWrite(PMC_FOMPCR_REG, seqReg);
197
198
199 /*
200 **
201 ** setup the pins associated with the smart card reader *
202 **
203 */
204 /* sequoia 1 direction & data */
205
206 sequoiaRead(SEQUOIA_1GPIO,&seqReg);
207
208 SET(seqReg,SCR_POWER_DIR); /* output */
209 SET(seqReg,SCR_RESET_DIR); /* output */
210 CLR(seqReg,SCR_DATA_IN_DIR); /* input */
211
212 CLR(seqReg,SCR_POWER); /* 0V to card */
213 SET(seqReg,SCR_RESET); /* 0V to card */
214
215 sequoiaWrite(SEQUOIA_1GPIO,seqReg);
216
217
218
219
220 /* sequoia 2 pin enables */
221 sequoiaRead(SEQ2_SEQ2PSR_REG,&seqReg);
222
223 SET(seqReg,SEQ2PSR_M_DPBUSEN);
224 CLR(seqReg,SEQ2PSR_M_GPIOPINEN);
225
226 sequoiaWrite(SEQ2_SEQ2PSR_REG,seqReg);
227
228
229
230 /* sequoia 2 direction & data */
231 sequoiaRead(SEQUOIA_2GPIO,&seqReg);
232
233 SET(seqReg,SCR_BUGA_DIR); /* output */
234 SET(seqReg,SCR_DATA_OUT_DIR); /* output */
235 SET(seqReg,SCR_CLOCK_DIR); /* output */
236 SET(seqReg,SCR_BUGB_DIR); /* output */
237
238 CLR(seqReg,SCR_BUGA); /* 0 */
239 CLR(seqReg,SCR_BUGB); /* 0 */
240 CLR(seqReg,SCR_CLOCK); /* 0 */
241 sequoiaWrite(SEQUOIA_2GPIO,seqReg);
242
243 /* setup the wak0 pin to be detect */
244 sequoiaRead(SEQR_SEQPSR2_REG,&seqReg);
245
246 SET(seqReg,SEQPSR2_M_DIRTYPINEN);
247 SET(seqReg,SEQPSR2_M_GPIOB0PINEN);
248
249 sequoiaWrite(SEQR_SEQPSR2_REG,seqReg);
250
251
252 sequoiaRead(PMC_GPIOCR2_REG,&seqReg);
253
254 CLR(seqReg,SCR_DETECT_DIR); /* input */
255
256 sequoiaWrite(PMC_GPIOCR2_REG,seqReg);
257
258 /* don't delay when setting PC bits. this is particularly important
259 for using PC[4] to clear the FIQ. */
260 sequoiaRead(PMC_SCCR_REG, &seqReg);
261 sequoiaWrite(PMC_SCCR_REG, seqReg | SCCR_M_PCSTGDIS);
262
263 sequoiaUnlock();
264
265 /* setup the biled info */
266 ledColor = LED_BILED_GREEN;
267 ledLastActive.tv_usec = 0;
268 ledLastActive.tv_sec = 0;
269 ledBlockCount = 0;
270 callout_init(&led_timo_ch, 0);
271 callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL);
272 }
273
274 void
sequoiaLock(void)275 sequoiaLock(void)
276 {
277 sequoiaLock_savedints = disable_interrupts(I32_bit | F32_bit);
278 KASSERT(!sequoiaLock_held);
279 sequoiaLock_held = true;
280 }
281
282 void
sequoiaUnlock(void)283 sequoiaUnlock(void)
284 {
285 KASSERT(sequoiaLock_held);
286 sequoiaLock_held = false;
287 restore_interrupts(sequoiaLock_savedints);
288 }
289
290 bool
sequoiaIsLocked(void)291 sequoiaIsLocked(void)
292 {
293 return sequoiaLock_held;
294 }
295
296 /* X console functions */
consXTvOn(void)297 void consXTvOn(void)
298 {
299 u_int16_t savedPSR3;
300 u_int16_t savedFMPCR;
301 /*
302 ** Switch on TV output on the Sequoia, data indicates mode,
303 ** but we are currently hardwired to NTSC, so ignore it.
304 */
305
306 sequoiaLock();
307
308 sequoiaRead (SEQR_SEQPSR3_REG, &savedPSR3);
309 sequoiaWrite(SEQR_SEQPSR3_REG, (savedPSR3 | SEQPSR3_M_PC3PINEN));
310
311 sequoiaRead (PMC_FOMPCR_REG, &savedFMPCR);
312 sequoiaWrite(PMC_FOMPCR_REG, (savedFMPCR | FOMPCR_M_PCON3));
313
314 sequoiaUnlock();
315 }
316
consXTvOff(void)317 void consXTvOff(void)
318 {
319 u_int16_t savedPSR3;
320 u_int16_t savedFMPCR;
321 /*
322 ** Switch off TV output on the Seqoia
323 */
324
325 sequoiaLock();
326
327 sequoiaRead (SEQR_SEQPSR3_REG, &savedPSR3);
328 sequoiaWrite(SEQR_SEQPSR3_REG, (savedPSR3 & ~SEQPSR3_M_PC3PINEN));
329
330 sequoiaRead (PMC_FOMPCR_REG, &savedFMPCR);
331 sequoiaWrite(PMC_FOMPCR_REG, (savedFMPCR & ~FOMPCR_M_PCON3));
332
333 sequoiaUnlock();
334 }
335
336
337
338
339 /* smart card routines */
340
scrGetDetect(void)341 int scrGetDetect (void)
342 {
343 int r;
344 u_int16_t seqReg;
345
346 sequoiaLock();
347 sequoiaRead(PMC_GPIOCR2_REG,&seqReg);
348 sequoiaUnlock();
349
350 /* inverse logic, so invert */
351 if (ISSET(seqReg,SCR_DETECT))
352 {
353 r = 0;
354 } else
355 {
356 r = 1;
357 }
358
359 return r;
360 }
361
362
scrSetPower(int value)363 void scrSetPower (int value)
364 {
365 u_int16_t seqReg;
366
367 sequoiaLock();
368
369 sequoiaRead(SEQUOIA_1GPIO,&seqReg);
370
371 if (value)
372 {
373 SET(seqReg,SCR_POWER);
374 } else
375 {
376 CLR(seqReg,SCR_POWER);
377 }
378 sequoiaWrite(SEQUOIA_1GPIO,seqReg);
379
380 sequoiaUnlock();
381 }
382
scrSetClock(int value)383 void scrSetClock (int value)
384 {
385 u_int16_t seqReg;
386
387 sequoiaLock();
388
389 sequoiaRead(SEQUOIA_2GPIO,&seqReg);
390
391 if (value)
392 {
393 SET(seqReg,SCR_CLOCK);
394 } else
395 {
396 CLR(seqReg,SCR_CLOCK);
397 }
398 sequoiaWrite(SEQUOIA_2GPIO,seqReg);
399
400 sequoiaUnlock();
401 }
402
scrSetReset(int value)403 void scrSetReset (int value)
404 {
405 u_int16_t seqReg;
406
407 sequoiaLock();
408
409 sequoiaRead(SEQUOIA_1GPIO,&seqReg);
410
411 if (value)
412 {
413 SET(seqReg,SCR_RESET);
414 } else
415 {
416 CLR(seqReg,SCR_RESET);
417 }
418 sequoiaWrite(SEQUOIA_1GPIO,seqReg);
419
420 sequoiaUnlock();
421 }
422
423
scrSetDataHighZ(void)424 void scrSetDataHighZ (void)
425 {
426 u_int16_t seqReg;
427
428 sequoiaLock();
429
430 sequoiaRead(SEQUOIA_2GPIO,&seqReg);
431
432 /* set data to 5V, io pin is inverse logic */
433 CLR(seqReg,SCR_DATA_OUT);
434
435 sequoiaWrite(SEQUOIA_2GPIO,seqReg);
436
437 sequoiaUnlock();
438 }
439
scrSetData(int value)440 void scrSetData (int value)
441 {
442 u_int16_t seqReg;
443
444 sequoiaLock();
445
446 sequoiaRead(SEQUOIA_2GPIO,&seqReg);
447 /* inverse logic */
448 if (value )
449 {
450 CLR(seqReg,SCR_DATA_OUT);
451 } else
452 {
453 SET(seqReg,SCR_DATA_OUT);
454 }
455 sequoiaWrite(SEQUOIA_2GPIO,seqReg);
456
457 sequoiaUnlock();
458 }
459
scrGetData(void)460 int scrGetData (void)
461 {
462 int r;
463 u_int16_t seqReg;
464
465 sequoiaLock();
466 sequoiaRead(SEQUOIA_1GPIO,&seqReg);
467 sequoiaUnlock();
468
469 if (ISSET(seqReg,SCR_DATA_IN))
470 {
471 r = 1;
472 } else
473 {
474 r = 0;
475 }
476 return r;
477 }
478
479
480
481
482
483
484
485
ledNetActive(void)486 void ledNetActive (void)
487 {
488 getmicrotime(&ledLastActive);
489 }
490
ledNetBlock(void)491 void ledNetBlock (void)
492 {
493 ledBlockCount++;
494 }
495
ledNetUnblock(void)496 void ledNetUnblock (void)
497 {
498 ledBlockCount--;
499 }
500
ledPanic(void)501 void ledPanic (void)
502 {
503 /* we are in panic, timeout wont happen, so set led */
504 ledSetBiled(LED_BILED_RED);
505 }
506
ledTimeout(void * arg)507 static void ledTimeout(void *arg)
508 {
509 int timeSpan; /* in usec */
510 struct timeval now;
511
512 getmicrotime(&now);
513 if(now.tv_sec == ledLastActive.tv_sec)
514 {
515 timeSpan = now.tv_usec - ledLastActive.tv_usec;
516 }
517
518 else if (now.tv_sec - 10 < ledLastActive.tv_sec) /* stop rollover problems */
519 {
520 timeSpan = (1000000 + now.tv_usec) - ledLastActive.tv_usec;
521 }
522
523 else
524 {
525 timeSpan = LED_NET_ACTIVE * 2; /* ie big number */
526 }
527
528
529
530 /* check if we are blocked */
531 if(ledBlockCount)
532 {
533 if(ledColor == LED_BILED_YELLOW)
534 {
535 ledSetBiled(LED_BILED_NONE);
536 }
537 else
538 {
539 ledSetBiled(LED_BILED_YELLOW);
540 }
541 }
542
543
544 /* check if we have network activity */
545 else if (timeSpan < LED_NET_ACTIVE)
546 {
547 if(ledColor == LED_BILED_GREEN)
548 {
549 ledSetBiled(LED_BILED_NONE);
550 }
551 else
552 {
553 ledSetBiled(LED_BILED_GREEN);
554 }
555 }
556
557 /* normal operating mode */
558 else
559 {
560 if(ledColor != LED_BILED_GREEN)
561 {
562 ledSetBiled(LED_BILED_GREEN);
563 }
564 }
565
566 /* resubmint the timeout */
567 callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL);
568
569 }
570
571
ledSetBiled(int color)572 static void ledSetBiled(int color)
573 {
574 u_int16_t seqReg;
575
576 sequoiaLock();
577
578 ledColor = color;
579
580 sequoiaRead (PMC_FOMPCR_REG, &seqReg);
581 switch(color)
582 {
583 case LED_BILED_NONE:
584 SET(seqReg,LED_BILED_YELLOW_BIT);
585 SET(seqReg,LED_BILED_GREEN_BIT);
586 break;
587
588 case LED_BILED_YELLOW:
589 CLR(seqReg,LED_BILED_YELLOW_BIT);
590 SET(seqReg,LED_BILED_GREEN_BIT);
591 break;
592
593 case LED_BILED_GREEN:
594 SET(seqReg,LED_BILED_YELLOW_BIT);
595 CLR(seqReg,LED_BILED_GREEN_BIT);
596 break;
597
598 case LED_BILED_RED:
599 CLR(seqReg,LED_BILED_YELLOW_BIT);
600 CLR(seqReg,LED_BILED_GREEN_BIT);
601 break;
602
603 default:
604 panic("invalid color %x",color);
605 break;
606 }
607 sequoiaWrite(PMC_FOMPCR_REG, seqReg);
608
609 sequoiaUnlock();
610 }
611
612
hwGetRev(void)613 int hwGetRev(void)
614 {
615 u_int16_t seqReg;
616
617 sequoiaLock();
618 sequoiaRead(SR_POR_REG,&seqReg);
619 sequoiaUnlock();
620
621 seqReg = seqReg >> POR_V_MISCCF0;
622 seqReg = seqReg & 0x7;
623
624 return seqReg;
625 }
626
627
628
629
630
631 /* routines to read/write to sequoia registers */
sequoiaWrite(int reg,u_int16_t seqReg)632 void sequoiaWrite(int reg,u_int16_t seqReg)
633 {
634
635 KASSERT(sequoiaLock_held);
636
637 /*
638 On SHARK, the fiq comes from the pmi/smi. After receiving
639 a FIQ, the SMI must be cleared. The SMI gets cleared by
640 changing to sleep mode, thereby lowering PC[4]. */
641 // need to do the right thing with the cache if this is going to work */
642 if (reg == PMC_FOMPCR_REG) {
643 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg);
644 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,
645 seqReg | (FOMPCR_M_PCON4));
646 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,
647 PMC_SLPMPCR_REG);
648 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,
649 seqReg & ~(SLPMPCR_M_PCSLP4));
650 sequoia_index_cache = PMC_SLPMPCR_REG;
651 } else {
652 /* normal case: just do the write */
653 if(sequoia_index_cache != reg)
654 {
655 sequoia_index_cache = reg;
656 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg);
657 }
658 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,seqReg);
659 }
660 }
661
sequoiaRead(int reg,u_int16_t * seqReg_ptr)662 void sequoiaRead (int reg,u_int16_t * seqReg_ptr)
663 {
664
665 KASSERT(sequoiaLock_held);
666
667 if(sequoia_index_cache != reg)
668 {
669 sequoia_index_cache = reg;
670 bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg);
671 }
672 *seqReg_ptr = bus_space_read_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET);
673 }
674
ledSetDebug(int command)675 void ledSetDebug(int command)
676 {
677 u_int16_t seqReg;
678
679 sequoiaLock();
680
681 sequoiaRead (PMC_FOMPCR_REG, &seqReg);
682
683
684 switch (command)
685 {
686 case LED_DEBUG_STATE_0:
687 CLR(seqReg,LED_DEBUG_YELLOW_BIT);
688 CLR(seqReg,LED_DEBUG_GREEN_BIT);
689 break;
690
691 case LED_DEBUG_STATE_1:
692 SET(seqReg,LED_DEBUG_YELLOW_BIT);
693 CLR(seqReg,LED_DEBUG_GREEN_BIT);
694 break;
695
696 case LED_DEBUG_STATE_2:
697 CLR(seqReg,LED_DEBUG_YELLOW_BIT);
698 SET(seqReg,LED_DEBUG_GREEN_BIT);
699 break;
700
701 case LED_DEBUG_STATE_3:
702 SET(seqReg,LED_DEBUG_YELLOW_BIT);
703 SET(seqReg,LED_DEBUG_GREEN_BIT);
704 break;
705
706 case LED_DEBUG_YELLOW_ON:
707 SET(seqReg,LED_DEBUG_YELLOW_BIT);
708 break;
709
710 case LED_DEBUG_YELLOW_OFF:
711 CLR(seqReg,LED_DEBUG_YELLOW_BIT);
712 break;
713
714 case LED_DEBUG_GREEN_ON:
715 SET(seqReg,LED_DEBUG_GREEN_BIT);
716 break;
717
718 case LED_DEBUG_GREEN_OFF:
719 CLR(seqReg,LED_DEBUG_GREEN_BIT);
720 break;
721
722 default:
723 panic("ledSetDebug: invalid command %d",command);
724 break;
725 }
726 sequoiaWrite(PMC_FOMPCR_REG, seqReg);
727
728 sequoiaUnlock();
729 }
730
731
732 int testPin=0;
scrToggleTestPin(void)733 void scrToggleTestPin (void)
734 {
735 u_int16_t seqReg;
736
737 sequoiaLock();
738
739 sequoiaRead(SEQUOIA_2GPIO,&seqReg);
740
741 if (testPin)
742 {
743 testPin = 0;
744 CLR(seqReg,SCR_BUGA);
745 }
746 else
747 {
748 SET(seqReg,SCR_BUGA);
749 testPin = 1;
750 }
751 sequoiaWrite(SEQUOIA_2GPIO,seqReg);
752
753 sequoiaUnlock();
754 }
755
756 static const struct device_compatible_entry compat_data[] = {
757 { .compat = "sequoia" },
758 DEVICE_COMPAT_EOL
759 };
760
761 static int
sequoia_cfprint(void * aux,const char * pnp)762 sequoia_cfprint(void *aux, const char *pnp)
763 {
764 struct ofbus_attach_args *oba = aux;
765
766 if (pnp != NULL) {
767 aprint_normal("%s at %s", oba->oba_ofname, pnp);
768 }
769 return UNCONF;
770 }
771
772 static int
sequoia_match(device_t parent,cfdata_t cf,void * aux)773 sequoia_match(device_t parent, cfdata_t cf, void *aux)
774 {
775 struct ofbus_attach_args *oba = aux;
776
777 /* beat ofisa */
778 return of_compatible_match(oba->oba_phandle, compat_data) ? 100 : 0;
779 }
780
781 static void
sequoia_attach(device_t parent,device_t self,void * aux)782 sequoia_attach(device_t parent, device_t self, void *aux)
783 {
784 const struct ofbus_attach_args *oba = aux;
785 struct ofbus_attach_args noba = *oba;
786
787 aprint_naive("\n");
788 aprint_normal("\n");
789
790 noba.oba_busname = "sequoia";
791
792 /* attach the i2c bus connected to the DRAM banks slots */
793 strlcpy(noba.oba_ofname, "dec,dnard-i2c", sizeof(noba.oba_ofname));
794 config_found(self, &noba, sequoia_cfprint,
795 CFARGS(.iattr = "sequoia"));
796
797 /* attach the ofisa instance at the same OFW node */
798 config_found(self, aux, ofisaprint,
799 CFARGS(.iattr = "ofisa_subclass"));
800 }
801
802 CFATTACH_DECL_NEW(sequoia, 0,
803 sequoia_match, sequoia_attach, NULL, NULL);
804