forked from google/periph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rpi.go
657 lines (633 loc) · 20.4 KB
/
rpi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
// Copyright 2016 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
// Raspberry Pi pin out.
package rpi
import (
"errors"
"fmt"
"os"
"strconv"
"periph.io/x/periph"
"periph.io/x/periph/conn/gpio"
"periph.io/x/periph/conn/pin"
"periph.io/x/periph/conn/pin/pinreg"
"periph.io/x/periph/host/bcm283x"
"periph.io/x/periph/host/distro"
)
// Present returns true if running on a Raspberry Pi board.
//
// https://www.raspberrypi.org/
func Present() bool {
if isArm {
// This is iffy at best.
_, err := os.Stat("/sys/bus/platform/drivers/raspberrypi-firmware")
return err == nil
}
return false
}
// Pin as connect on the 40 pins extension header.
//
// Schematics are useful to know what is connected to what:
// https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/README.md
//
// The actual pin mapping depends on the board revision! The default values are
// set as the 40 pins header on Raspberry Pi 2 and Raspberry Pi 3.
//
// Some header info here: http://elinux.org/RPi_Low-level_peripherals
//
// P1 is also known as J8 on A+, B+, 2 and later.
var (
// Raspberry Pi A and B, 26 pin header:
P1_1 pin.Pin = pin.V3_3 // max 30mA
P1_2 pin.Pin = pin.V5 // (filtered)
P1_3 gpio.PinIO = bcm283x.GPIO2 // High, I2C1_SDA
P1_4 pin.Pin = pin.V5 //
P1_5 gpio.PinIO = bcm283x.GPIO3 // High, I2C1_SCL
P1_6 pin.Pin = pin.GROUND //
P1_7 gpio.PinIO = bcm283x.GPIO4 // High, CLK0
P1_8 gpio.PinIO = bcm283x.GPIO14 // Low, UART0_TX, UART1_TX
P1_9 pin.Pin = pin.GROUND //
P1_10 gpio.PinIO = bcm283x.GPIO15 // Low, UART0_RX, UART1_RX
P1_11 gpio.PinIO = bcm283x.GPIO17 // Low, UART0_RTS, SPI1_CS1, UART1_RTS
P1_12 gpio.PinIO = bcm283x.GPIO18 // Low, I2S_SCK, SPI1_CS0, PWM0
P1_13 gpio.PinIO = bcm283x.GPIO27 // Low,
P1_14 pin.Pin = pin.GROUND //
P1_15 gpio.PinIO = bcm283x.GPIO22 // Low,
P1_16 gpio.PinIO = bcm283x.GPIO23 // Low,
P1_17 pin.Pin = pin.V3_3 //
P1_18 gpio.PinIO = bcm283x.GPIO24 // Low,
P1_19 gpio.PinIO = bcm283x.GPIO10 // Low, SPI0_MOSI
P1_20 pin.Pin = pin.GROUND //
P1_21 gpio.PinIO = bcm283x.GPIO9 // Low, SPI0_MISO
P1_22 gpio.PinIO = bcm283x.GPIO25 // Low,
P1_23 gpio.PinIO = bcm283x.GPIO11 // Low, SPI0_CLK
P1_24 gpio.PinIO = bcm283x.GPIO8 // High, SPI0_CS0
P1_25 pin.Pin = pin.GROUND //
P1_26 gpio.PinIO = bcm283x.GPIO7 // High, SPI0_CS1
// Raspberry Pi A+, B+, 2 and later, 40 pin header (also named J8):
P1_27 gpio.PinIO = bcm283x.GPIO0 // High, I2C0_SDA used to probe for HAT EEPROM, see https://github.com/raspberrypi/hats
P1_28 gpio.PinIO = bcm283x.GPIO1 // High, I2C0_SCL
P1_29 gpio.PinIO = bcm283x.GPIO5 // High, CLK1
P1_30 pin.Pin = pin.GROUND //
P1_31 gpio.PinIO = bcm283x.GPIO6 // High, CLK2
P1_32 gpio.PinIO = bcm283x.GPIO12 // Low, PWM0
P1_33 gpio.PinIO = bcm283x.GPIO13 // Low, PWM1
P1_34 pin.Pin = pin.GROUND //
P1_35 gpio.PinIO = bcm283x.GPIO19 // Low, I2S_WS, SPI1_MISO, PWM1
P1_36 gpio.PinIO = bcm283x.GPIO16 // Low, UART0_CTS, SPI1_CS2, UART1_CTS
P1_37 gpio.PinIO = bcm283x.GPIO26 //
P1_38 gpio.PinIO = bcm283x.GPIO20 // Low, I2S_DIN, SPI1_MOSI, CLK0
P1_39 pin.Pin = pin.GROUND //
P1_40 gpio.PinIO = bcm283x.GPIO21 // Low, I2S_DOUT, SPI1_CLK, CLK1
// P5 header on Raspberry Pi A and B, PCB v2:
P5_1 pin.Pin = pin.V5
P5_2 pin.Pin = pin.V3_3
P5_3 gpio.PinIO = bcm283x.GPIO28 // Float, I2C0_SDA, I2S_SCK
P5_4 gpio.PinIO = bcm283x.GPIO29 // Float, I2C0_SCL, I2S_WS
P5_5 gpio.PinIO = bcm283x.GPIO30 // Low, I2S_DIN, UART0_CTS, UART1_CTS
P5_6 gpio.PinIO = bcm283x.GPIO31 // Low, I2S_DOUT, UART0_RTS, UART1_RTS
P5_7 pin.Pin = pin.GROUND
P5_8 pin.Pin = pin.GROUND
AUDIO_RIGHT = bcm283x.GPIO40 // Low, PWM0, SPI2_MISO, UART1_TX
AUDIO_LEFT = bcm283x.GPIO41 // Low, PWM1, SPI2_MOSI, UART1_RX
HDMI_HOTPLUG_DETECT = bcm283x.GPIO46 // High,
)
// Pin as connected on the SODIMM header.
//
// Documentation is https://www.raspberrypi.org/documentation/hardware/computemodule/datasheets/rpi_DATA_CM_1p0.pdf
//
// There are some differences for CM3-Lite and CM1.
var (
SO_1 pin.Pin = pin.GROUND // GND
SO_2 pin.Pin = pin.INVALID // EMMC_DISABLE_N
SO_3 gpio.PinIO = bcm283x.GPIO0 // GPIO0
SO_4 pin.Pin = pin.INVALID // NC, SDX_VDD, NC
SO_5 gpio.PinIO = bcm283x.GPIO1 // GPIO1
SO_6 pin.Pin = pin.INVALID // NC, SDX_VDD, NC
SO_7 pin.Pin = pin.GROUND // GND
SO_8 pin.Pin = pin.GROUND // GND
SO_9 gpio.PinIO = bcm283x.GPIO2 // GPIO2
SO_10 pin.Pin = pin.INVALID // NC, SDX_CLK, NC
SO_11 gpio.PinIO = bcm283x.GPIO3 // GPIO3
SO_12 pin.Pin = pin.INVALID // NC, SDX_CMD, NC
SO_13 pin.Pin = pin.GROUND // GND
SO_14 pin.Pin = pin.GROUND // GND
SO_15 gpio.PinIO = bcm283x.GPIO4 // GPIO4
SO_16 pin.Pin = pin.INVALID // NC, SDX_D0, NC
SO_17 gpio.PinIO = bcm283x.GPIO5 // GPIO5
SO_18 pin.Pin = pin.INVALID // NC, SDX_D1, NC
SO_19 pin.Pin = pin.GROUND // GND
SO_20 pin.Pin = pin.GROUND // GND
SO_21 gpio.PinIO = bcm283x.GPIO6 // GPIO6
SO_22 pin.Pin = pin.INVALID // NC, SDX_D2, NC
SO_23 gpio.PinIO = bcm283x.GPIO7 // GPIO7
SO_24 pin.Pin = pin.INVALID // NC, SDX_D3, NC
SO_25 pin.Pin = pin.GROUND // GND
SO_26 pin.Pin = pin.GROUND // GND
SO_27 gpio.PinIO = bcm283x.GPIO8 // GPIO8
SO_28 gpio.PinIO = bcm283x.GPIO28 // GPIO28
SO_29 gpio.PinIO = bcm283x.GPIO9 // GPIO9
SO_30 gpio.PinIO = bcm283x.GPIO29 // GPIO29
SO_31 pin.Pin = pin.GROUND // GND
SO_32 pin.Pin = pin.GROUND // GND
SO_33 gpio.PinIO = bcm283x.GPIO10 // GPIO10
SO_34 gpio.PinIO = bcm283x.GPIO30 // GPIO30
SO_35 gpio.PinIO = bcm283x.GPIO11 // GPIO11
SO_36 gpio.PinIO = bcm283x.GPIO31 // GPIO31
SO_37 pin.Pin = pin.GROUND // GND
SO_38 pin.Pin = pin.GROUND // GND
SO_39 pin.Pin = pin.DC_IN // GPIO0-27_VDD
SO_40 pin.Pin = pin.DC_IN // GPIO0-27_VDD
SO_41 pin.Pin = pin.DC_IN // GPIO28-45_VDD
SO_42 pin.Pin = pin.DC_IN // GPIO28-45_VDD
SO_43 pin.Pin = pin.GROUND // GND
SO_44 pin.Pin = pin.GROUND // GND
SO_45 gpio.PinIO = bcm283x.GPIO12 // GPIO12
SO_46 gpio.PinIO = bcm283x.GPIO32 // GPIO32
SO_47 gpio.PinIO = bcm283x.GPIO13 // GPIO13
SO_48 gpio.PinIO = bcm283x.GPIO33 // GPIO33
SO_49 pin.Pin = pin.GROUND // GND
SO_50 pin.Pin = pin.GROUND // GND
SO_51 gpio.PinIO = bcm283x.GPIO14 // GPIO14
SO_52 gpio.PinIO = bcm283x.GPIO34 // GPIO34
SO_53 gpio.PinIO = bcm283x.GPIO15 // GPIO15
SO_54 gpio.PinIO = bcm283x.GPIO35 // GPIO35
SO_55 pin.Pin = pin.GROUND // GND
SO_56 pin.Pin = pin.GROUND // GND
SO_57 gpio.PinIO = bcm283x.GPIO16 // GPIO16
SO_58 gpio.PinIO = bcm283x.GPIO36 // GPIO36
SO_59 gpio.PinIO = bcm283x.GPIO17 // GPIO17
SO_60 gpio.PinIO = bcm283x.GPIO37 // GPIO37
SO_61 pin.Pin = pin.GROUND // GND
SO_62 pin.Pin = pin.GROUND // GND
SO_63 gpio.PinIO = bcm283x.GPIO18 // GPIO18
SO_64 gpio.PinIO = bcm283x.GPIO38 // GPIO38
SO_65 gpio.PinIO = bcm283x.GPIO19 // GPIO19
SO_66 gpio.PinIO = bcm283x.GPIO39 // GPIO39
SO_67 pin.Pin = pin.GROUND // GND
SO_68 pin.Pin = pin.GROUND // GND
SO_69 gpio.PinIO = bcm283x.GPIO20 // GPIO20
SO_70 gpio.PinIO = bcm283x.GPIO40 // GPIO40
SO_71 gpio.PinIO = bcm283x.GPIO21 // GPIO21
SO_72 gpio.PinIO = bcm283x.GPIO41 // GPIO41
SO_73 pin.Pin = pin.GROUND // GND
SO_74 pin.Pin = pin.GROUND // GND
SO_75 gpio.PinIO = bcm283x.GPIO22 // GPIO22
SO_76 gpio.PinIO = bcm283x.GPIO42 // GPIO42
SO_77 gpio.PinIO = bcm283x.GPIO23 // GPIO23
SO_78 gpio.PinIO = bcm283x.GPIO43 // GPIO43
SO_79 pin.Pin = pin.GROUND // GND
SO_80 pin.Pin = pin.GROUND // GND
SO_81 gpio.PinIO = bcm283x.GPIO24 // GPIO24
SO_82 gpio.PinIO = bcm283x.GPIO44 // GPIO44
SO_83 gpio.PinIO = bcm283x.GPIO25 // GPIO25
SO_84 gpio.PinIO = bcm283x.GPIO45 // GPIO45
SO_85 pin.Pin = pin.GROUND // GND
SO_86 pin.Pin = pin.GROUND // GND
SO_87 gpio.PinIO = bcm283x.GPIO26 // GPIO26
SO_88 pin.Pin = pin.INVALID // HDMI_HPD_N_1V8, HDMI_HPD_N_1V8, GPIO46_1V8
SO_89 gpio.PinIO = bcm283x.GPIO27 // GPIO27
SO_90 pin.Pin = pin.INVALID // EMMC_EN_N_1V8, EMMC_EN_N_1V8, GPIO47_1V8
SO_91 pin.Pin = pin.GROUND // GND
SO_92 pin.Pin = pin.GROUND // GND
SO_93 pin.Pin = pin.INVALID // DSI0_DN1
SO_94 pin.Pin = pin.INVALID // DSI1_DP0
SO_95 pin.Pin = pin.INVALID // DSI0_DP1
SO_96 pin.Pin = pin.INVALID // DSI1_DN0
SO_97 pin.Pin = pin.GROUND // GND
SO_98 pin.Pin = pin.GROUND // GND
SO_99 pin.Pin = pin.INVALID // DSI0_DN0
SO_100 pin.Pin = pin.INVALID // DSI1_CP
SO_101 pin.Pin = pin.INVALID // DSI0_DP0
SO_102 pin.Pin = pin.INVALID // DSI1_CN
SO_103 pin.Pin = pin.GROUND // GND
SO_104 pin.Pin = pin.GROUND // GND
SO_105 pin.Pin = pin.INVALID // DSI0_CN
SO_106 pin.Pin = pin.INVALID // DSI1_DP3
SO_107 pin.Pin = pin.INVALID // DSI0_CP
SO_108 pin.Pin = pin.INVALID // DSI1_DN3
SO_109 pin.Pin = pin.GROUND // GND
SO_110 pin.Pin = pin.GROUND // GND
SO_111 pin.Pin = pin.INVALID // HDMI_CLK_N
SO_112 pin.Pin = pin.INVALID // DSI1_DP2
SO_113 pin.Pin = pin.INVALID // HDMI_CLK_P
SO_114 pin.Pin = pin.INVALID // DSI1_DN2
SO_115 pin.Pin = pin.GROUND // GND
SO_116 pin.Pin = pin.GROUND // GND
SO_117 pin.Pin = pin.INVALID // HDMI_D0_N
SO_118 pin.Pin = pin.INVALID // DSI1_DP1
SO_119 pin.Pin = pin.INVALID // HDMI_D0_P
SO_120 pin.Pin = pin.INVALID // DSI1_DN1
SO_121 pin.Pin = pin.GROUND // GND
SO_122 pin.Pin = pin.GROUND // GND
SO_123 pin.Pin = pin.INVALID // HDMI_D1_N
SO_124 pin.Pin = pin.INVALID // NC
SO_125 pin.Pin = pin.INVALID // HDMI_D1_P
SO_126 pin.Pin = pin.INVALID // NC
SO_127 pin.Pin = pin.GROUND // GND
SO_128 pin.Pin = pin.INVALID // NC
SO_129 pin.Pin = pin.INVALID // HDMI_D2_N
SO_130 pin.Pin = pin.INVALID // NC
SO_131 pin.Pin = pin.INVALID // HDMI_D2_P
SO_132 pin.Pin = pin.INVALID // NC
SO_133 pin.Pin = pin.GROUND // GND
SO_134 pin.Pin = pin.GROUND // GND
SO_135 pin.Pin = pin.INVALID // CAM1_DP3
SO_136 pin.Pin = pin.INVALID // CAM0_DP0
SO_137 pin.Pin = pin.INVALID // CAM1_DN3
SO_138 pin.Pin = pin.INVALID // CAM0_DN0
SO_139 pin.Pin = pin.GROUND // GND
SO_140 pin.Pin = pin.GROUND // GND
SO_141 pin.Pin = pin.INVALID // CAM1_DP2
SO_142 pin.Pin = pin.INVALID // CAM0_CP
SO_143 pin.Pin = pin.INVALID // CAM1_DN2
SO_144 pin.Pin = pin.INVALID // CAM0_CN
SO_145 pin.Pin = pin.GROUND // GND
SO_146 pin.Pin = pin.GROUND // GND
SO_147 pin.Pin = pin.INVALID // CAM1_CP
SO_148 pin.Pin = pin.INVALID // CAM0_DP1
SO_149 pin.Pin = pin.INVALID // CAM1_CN
SO_150 pin.Pin = pin.INVALID // CAM0_DN1
SO_151 pin.Pin = pin.GROUND // GND
SO_152 pin.Pin = pin.GROUND // GND
SO_153 pin.Pin = pin.INVALID // CAM1_DP1
SO_154 pin.Pin = pin.INVALID // NC
SO_155 pin.Pin = pin.INVALID // CAM1_DN1
SO_156 pin.Pin = pin.INVALID // NC
SO_157 pin.Pin = pin.GROUND // GND
SO_158 pin.Pin = pin.INVALID // NC
SO_159 pin.Pin = pin.INVALID // CAM1_DP0
SO_160 pin.Pin = pin.INVALID // NC
SO_161 pin.Pin = pin.INVALID // CAM1_DN0
SO_162 pin.Pin = pin.INVALID // NC
SO_163 pin.Pin = pin.GROUND // GND
SO_164 pin.Pin = pin.GROUND // GND
SO_165 pin.Pin = pin.INVALID // USB_DP
SO_166 pin.Pin = pin.INVALID // TVDAC
SO_167 pin.Pin = pin.INVALID // USB_DM
SO_168 pin.Pin = pin.INVALID // USB_OTGID
SO_169 pin.Pin = pin.GROUND // GND
SO_170 pin.Pin = pin.GROUND // GND
SO_171 pin.Pin = pin.INVALID // HDMI_CEC
SO_172 pin.Pin = pin.INVALID // VC_TRST_N
SO_173 pin.Pin = pin.INVALID // HDMI_SDA
SO_174 pin.Pin = pin.INVALID // VC_TDI
SO_175 pin.Pin = pin.INVALID // HDMI_SCL
SO_176 pin.Pin = pin.INVALID // VC_TMS
SO_177 pin.Pin = pin.INVALID // RUN
SO_178 pin.Pin = pin.INVALID // VC_TDO
SO_179 pin.Pin = pin.INVALID // VDD_CORE (DO NOT CONNECT)
SO_180 pin.Pin = pin.INVALID // VC_TCK
SO_181 pin.Pin = pin.GROUND // GND
SO_182 pin.Pin = pin.GROUND // GND
SO_183 pin.Pin = pin.V1_8 // 1V8
SO_184 pin.Pin = pin.V1_8 // 1V8
SO_185 pin.Pin = pin.V1_8 // 1V8
SO_186 pin.Pin = pin.V1_8 // 1V8
SO_187 pin.Pin = pin.GROUND // GND
SO_188 pin.Pin = pin.GROUND // GND
SO_189 pin.Pin = pin.DC_IN // VDAC
SO_190 pin.Pin = pin.DC_IN // VDAC
SO_191 pin.Pin = pin.V3_3 // 3V3
SO_192 pin.Pin = pin.V3_3 // 3V3
SO_193 pin.Pin = pin.V3_3 // 3V3
SO_194 pin.Pin = pin.V3_3 // 3V3
SO_195 pin.Pin = pin.GROUND // GND
SO_196 pin.Pin = pin.GROUND // GND
SO_197 pin.Pin = pin.DC_IN // VBAT
SO_198 pin.Pin = pin.DC_IN // VBAT
SO_199 pin.Pin = pin.DC_IN // VBAT
SO_200 pin.Pin = pin.DC_IN // VBAT
)
// driver implements periph.Driver.
type driver struct {
}
func (d *driver) String() string {
return "rpi"
}
func (d *driver) Prerequisites() []string {
return nil
}
func (d *driver) After() []string {
return []string{"bcm283x-gpio"}
}
func (d *driver) Init() (bool, error) {
if !Present() {
return false, errors.New("Raspberry Pi board not detected")
}
// Setup headers based on board revision.
//
// This code is not futureproof, it will error out on a Raspberry Pi 4
// whenever it comes out.
// Revision codes from: http://elinux.org/RPi_HardwareHistory
has26PinP1Header := false
has40PinP1Header := false
hasP5Header := false
hasAudio := false
hasNewAudio := false
hasHDMI := false
hasSODimm := false
rev := distro.CPUInfo()["Revision"]
if i, err := strconv.ParseInt(rev, 16, 32); err == nil {
// Ignore the overclock bit.
i &= 0xFFFFFF
switch i {
case 0x0002, 0x0003: // B v1.0
has26PinP1Header = true
hasAudio = true
case 0x0004, 0x0005, 0x0006, // B v2.0
0x0007, 0x0008, 0x0009, // A v2.0
0x000d, 0x000e, 0x000f: // B v2.0
has26PinP1Header = true
// Only the v2 PCB has the P5 header.
hasP5Header = true
hasAudio = true
hasHDMI = true
case 0x0010, // B+ v1.0
0x0012, // A+ v1.1
0x0013, // B+ v1.2
0x0015, // A+ v1.1
0x90021, // A+ v1.1
0x90032, // B+ v1.2
0xa01040, // 2 Model B v1.0
0xa01041, 0xa21041, // 2 Model B v1.1
0xa22042: // 2 Model B v1.2
has40PinP1Header = true
hasAudio = true
hasHDMI = true
case 0x900092, // Zero v1.2
0x900093, // Zero v1.3
0x920093, // Zero v1.3
0x9000c1: // Zero W v1.1
has40PinP1Header = true
hasHDMI = true
case 0x0011, // Compute Module 1
0x0014: // Compute Module 1
// SODIMM not defined
case 0xa020a0: // Compute Module 3 v1.0
hasSODimm = true
// tell CM3 and CM3-Lite apart, if possible
case 0xa02082, 0xa22082, 0xa32082, 0xa020d3: // 3 Model B v1.2, B+
has40PinP1Header = true
hasAudio = true
hasNewAudio = true
hasHDMI = true
default:
return true, fmt.Errorf("rpi: unknown hardware version: 0x%x", i)
}
} else {
return true, fmt.Errorf("rpi: failed to read cpu_info: %v", err)
}
if has26PinP1Header {
if err := pinreg.Register("P1", [][]pin.Pin{
{P1_1, P1_2},
{P1_3, P1_4},
{P1_5, P1_6},
{P1_7, P1_8},
{P1_9, P1_10},
{P1_11, P1_12},
{P1_13, P1_14},
{P1_15, P1_16},
{P1_17, P1_18},
{P1_19, P1_20},
{P1_21, P1_22},
{P1_23, P1_24},
{P1_25, P1_26},
}); err != nil {
return true, err
}
// TODO(maruel): Models from 2012 and earlier have P1_3=GPIO0, P1_5=GPIO1 and P1_13=GPIO21.
// P2 and P3 are not useful.
// P6 has a RUN pin for reset but it's not available after Pi version 1.
P1_27 = gpio.INVALID
P1_28 = gpio.INVALID
P1_29 = gpio.INVALID
P1_30 = pin.INVALID
P1_31 = gpio.INVALID
P1_32 = gpio.INVALID
P1_33 = gpio.INVALID
P1_34 = pin.INVALID
P1_35 = gpio.INVALID
P1_36 = gpio.INVALID
P1_37 = gpio.INVALID
P1_38 = gpio.INVALID
P1_39 = pin.INVALID
P1_40 = gpio.INVALID
} else if has40PinP1Header {
if err := pinreg.Register("P1", [][]pin.Pin{
{P1_1, P1_2},
{P1_3, P1_4},
{P1_5, P1_6},
{P1_7, P1_8},
{P1_9, P1_10},
{P1_11, P1_12},
{P1_13, P1_14},
{P1_15, P1_16},
{P1_17, P1_18},
{P1_19, P1_20},
{P1_21, P1_22},
{P1_23, P1_24},
{P1_25, P1_26},
{P1_27, P1_28},
{P1_29, P1_30},
{P1_31, P1_32},
{P1_33, P1_34},
{P1_35, P1_36},
{P1_37, P1_38},
{P1_39, P1_40},
}); err != nil {
return true, err
}
} else {
P1_1 = pin.INVALID
P1_2 = pin.INVALID
P1_3 = gpio.INVALID
P1_4 = pin.INVALID
P1_5 = gpio.INVALID
P1_6 = pin.INVALID
P1_7 = gpio.INVALID
P1_8 = gpio.INVALID
P1_9 = pin.INVALID
P1_10 = gpio.INVALID
P1_11 = gpio.INVALID
P1_12 = gpio.INVALID
P1_13 = gpio.INVALID
P1_14 = pin.INVALID
P1_15 = gpio.INVALID
P1_16 = gpio.INVALID
P1_17 = pin.INVALID
P1_18 = gpio.INVALID
P1_19 = gpio.INVALID
P1_20 = pin.INVALID
P1_21 = gpio.INVALID
P1_22 = gpio.INVALID
P1_23 = gpio.INVALID
P1_24 = gpio.INVALID
P1_25 = pin.INVALID
P1_26 = gpio.INVALID
P1_27 = gpio.INVALID
P1_28 = gpio.INVALID
P1_29 = gpio.INVALID
P1_30 = pin.INVALID
P1_31 = gpio.INVALID
P1_32 = gpio.INVALID
P1_33 = gpio.INVALID
P1_34 = pin.INVALID
P1_35 = gpio.INVALID
P1_36 = gpio.INVALID
P1_37 = gpio.INVALID
P1_38 = gpio.INVALID
P1_39 = pin.INVALID
P1_40 = gpio.INVALID
}
// Only the A and B v2 PCB has the P5 header.
if hasP5Header {
if err := pinreg.Register("P5", [][]pin.Pin{
{P5_1, P5_2},
{P5_3, P5_4},
{P5_5, P5_6},
{P5_7, P5_8},
}); err != nil {
return true, err
}
} else {
P5_1 = pin.INVALID
P5_2 = pin.INVALID
P5_3 = gpio.INVALID
P5_4 = gpio.INVALID
P5_5 = gpio.INVALID
P5_6 = gpio.INVALID
P5_7 = pin.INVALID
P5_8 = pin.INVALID
}
if hasSODimm {
if err := pinreg.Register("SO", [][]pin.Pin{
{SO_1, SO_2},
{SO_3, SO_4},
{SO_5, SO_6},
{SO_7, SO_8},
{SO_9, SO_10},
{SO_11, SO_12},
{SO_13, SO_14},
{SO_15, SO_16},
{SO_17, SO_18},
{SO_19, SO_20},
{SO_21, SO_22},
{SO_23, SO_24},
{SO_25, SO_26},
{SO_27, SO_28},
{SO_29, SO_30},
{SO_31, SO_32},
{SO_33, SO_34},
{SO_35, SO_36},
{SO_37, SO_38},
{SO_39, SO_40},
{SO_41, SO_42},
{SO_43, SO_44},
{SO_45, SO_46},
{SO_47, SO_48},
{SO_49, SO_50},
{SO_51, SO_52},
{SO_53, SO_54},
{SO_55, SO_56},
{SO_57, SO_58},
{SO_59, SO_60},
{SO_61, SO_62},
{SO_63, SO_64},
{SO_65, SO_66},
{SO_67, SO_68},
{SO_69, SO_70},
{SO_71, SO_72},
{SO_73, SO_74},
{SO_75, SO_76},
{SO_77, SO_78},
{SO_79, SO_80},
{SO_81, SO_82},
{SO_83, SO_84},
{SO_85, SO_86},
{SO_87, SO_88},
{SO_89, SO_90},
{SO_91, SO_92},
{SO_93, SO_94},
{SO_95, SO_96},
{SO_97, SO_98},
{SO_99, SO_100},
{SO_101, SO_102},
{SO_103, SO_104},
{SO_105, SO_106},
{SO_107, SO_108},
{SO_109, SO_110},
{SO_111, SO_112},
{SO_113, SO_114},
{SO_115, SO_116},
{SO_117, SO_118},
{SO_119, SO_120},
{SO_121, SO_122},
{SO_123, SO_124},
{SO_125, SO_126},
{SO_127, SO_128},
{SO_129, SO_130},
{SO_131, SO_132},
{SO_133, SO_134},
{SO_135, SO_136},
{SO_137, SO_138},
{SO_139, SO_140},
{SO_141, SO_142},
{SO_143, SO_144},
{SO_145, SO_146},
{SO_147, SO_148},
{SO_149, SO_150},
{SO_151, SO_152},
{SO_153, SO_154},
{SO_155, SO_156},
{SO_157, SO_158},
{SO_159, SO_160},
{SO_161, SO_162},
{SO_163, SO_164},
{SO_165, SO_166},
{SO_167, SO_168},
{SO_169, SO_170},
{SO_171, SO_172},
{SO_173, SO_174},
{SO_175, SO_176},
{SO_177, SO_178},
{SO_179, SO_180},
{SO_181, SO_182},
{SO_183, SO_184},
{SO_185, SO_186},
{SO_187, SO_188},
{SO_189, SO_190},
{SO_191, SO_192},
{SO_193, SO_194},
{SO_195, SO_196},
{SO_197, SO_198},
{SO_199, SO_200},
}); err != nil {
return true, err
}
}
if hasAudio {
if !hasNewAudio {
AUDIO_LEFT = bcm283x.GPIO45 // PWM1
}
if err := pinreg.Register("AUDIO", [][]pin.Pin{
{AUDIO_LEFT},
{AUDIO_RIGHT},
}); err != nil {
return true, err
}
}
if hasHDMI {
if err := pinreg.Register("HDMI", [][]pin.Pin{{HDMI_HOTPLUG_DETECT}}); err != nil {
return true, err
}
}
return true, nil
}
func init() {
if isArm {
periph.MustRegister(&drv)
}
}
var drv driver