Skip to content

Commit

Permalink
allwinner: Support for H2+ and H3 (OrangePiZero) (#23)
Browse files Browse the repository at this point in the history
* Support for Allwinner H2+ and H3 (OrangePiSZero)

Add support for the Allwinner H2+ and H3 CPUs, which are almost
identical. The H2+ has no GBit MAC and no 4h HDMI, but the rest is
completely identical. For this library tho, it is not relevant, so we
can combine these two CPU types into one single H3 and detect the H2+ as
a H3 CPU.

Support for detecting Orange Pi Zero boards are added, which uses the H3
SOC. The Pinouts are from the Orange Pi manual.

Fixes #1
  • Loading branch information
f0086 authored Dec 16, 2022
1 parent de9a57f commit 339d73c
Show file tree
Hide file tree
Showing 10 changed files with 389 additions and 4 deletions.
5 changes: 4 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
# This does not necessarily list everyone who has contributed code, since in
# some cases, their employer may be the copyright holder. To see the full list
# of contributors, see the revision history in source control.

# Please keep the list sorted.

Aaron Fischer <mail@aaron-fischer.net>
Cássio Botaro <cassiobotaro@gmail.com>
Fractal Industries, Inc
Google Inc.
Expand All @@ -12,4 +16,3 @@ Max Ekman <max@looplab.se>
Rifiniti, Inc
Stephan Sperber
Thorsten von Eicken <tve@voneicken.com>

1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

# Please keep the list sorted.

Aaron Fischer <mail@aaron-fischer.net>
Cássio Botaro <cassiobotaro@gmail.com>
Eugene Dzhurynsky <jdevelop@gmail.com>
Hidetoshi Shimokawa <smkwhdts@gmail.com>
Expand Down
18 changes: 16 additions & 2 deletions allwinner/detect.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016 The Periph Authors. All rights reserved.
// Copyright 2022 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.

Expand Down Expand Up @@ -44,6 +44,14 @@ func IsA64() bool {
return detection.isA64
}

// IsH3 detects whether the host CPU is an Allwinner H3/H2+ Plus CPU.
//
// It looks for the string "sun8i-h2-plus" or "sun8i-h3" in /proc/device-tree/compatible.
func IsH3() bool {
detection.do()
return detection.isH3
}

// IsH5 detects whether the host CPU is an Allwinner H5 CPU.
//
// It looks for the string "sun50i-h5" in /proc/device-tree/compatible.
Expand All @@ -61,6 +69,7 @@ type detectionS struct {
isR8 bool
isA20 bool
isA64 bool
isH3 bool
isH5 bool
}

Expand All @@ -87,11 +96,16 @@ func (d *detectionS) do() {
if strings.Contains(c, "sun7i-a20") {
d.isA20 = true
}
// H2+ is a subtype of H3 and nearly compatible (only lacks GBit MAC and
// 4k HDMI Output), so it is safe to map H2+ as an H3.
if strings.Contains(c, "sun8i-h2-plus") || strings.Contains(c, "sun8i-h3") {
d.isH3 = true
}
if strings.Contains(c, "sun50i-h5") {
d.isH5 = true
}
}
d.isAllwinner = d.isA64 || d.isR8 || d.isA20 || d.isH5
d.isAllwinner = d.isA64 || d.isR8 || d.isA20 || d.isH3 || d.isH5

if !d.isAllwinner {
// The kernel in the image that comes pre-installed on the pcDuino3 Nano
Expand Down
6 changes: 5 additions & 1 deletion allwinner/gpio.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016 The Periph Authors. All rights reserved.
// Copyright 2022 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.

Expand Down Expand Up @@ -1020,6 +1020,10 @@ func (d *driverGPIO) Init() (bool, error) {
if err := mapA20Pins(); err != nil {
return true, err
}
case IsH3():
if err := mapH3Pins(); err != nil {
return true, err
}
case IsH5():
if err := mapH5Pins(); err != nil {
return true, err
Expand Down
153 changes: 153 additions & 0 deletions allwinner/h3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright 2022 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.

// This file contains pin mapping information that is specific to the Allwinner
// H2+ and H3 model.

package allwinner

import (
"strings"

"periph.io/x/conn/v3/pin"
"periph.io/x/host/v3/sysfs"
)

// mappingH3 describes the mapping of the H3 processor GPIO pins to their
// functions. The mappings source is the official H3 Datasheet, version 1.0,
// page 74 (chapter 3.2 GPIO Multiplexing Functions).
// http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf
var mappingH3 = map[string][5]pin.Func{
"PA0": {"UART2_TX", "JTAG_MS", "", "", "PA_EINT0"},
"PA1": {"UART2_RX", "JTAG_CK", "", "", "PA_EINT1"},
"PA2": {"UART2_RTS", "JTAG_DO", "", "", "PA_EINT2"},
"PA3": {"UART2_CTS", "JTAG_DI", "", "", "PA_EINT3"},
"PA4": {"UART0_TX", "", "", "", "PA_EINT4"},
"PA5": {"UART0_RX", "PWM0", "", "", "PA_EINT5"},
"PA6": {"SIM_PWREN", "PWM1", "", "", "PA_EINT6"},
"PA7": {"SIM_CK", "", "", "", "PA_EINT7"},
"PA8": {"SIM_DATA", "", "", "", "PA_EINT8"},
"PA9": {"SIM_RST", "", "", "", "PA_EINT9"},
"PA10": {"SIM_DET", "", "", "", "PA_EINT10"},
"PA11": {"TWI0_SCK", "DI_TX", "", "", "PA_EINT11"},
"PA12": {"TWI0_SDA", "DI_RX", "", "", "PA_EINT12"},
"PA13": {"SPI1_CS", "UART3_TX", "", "", "PA_EINT13"},
"PA14": {"SPI1_CLK", "UART3_RX", "", "", "PA_EINT14"},
"PA15": {"SPI1_MOSI", "UART3_RTS", "", "", "PA_EINT15"},
"PA16": {"SPI1_MOSI", "UART3_CTS", "", "", "PA_EINT16"},
"PA17": {"OWA_OUT", "", "", "", "PA_EINT17"},
"PA18": {"PCM0_SYNC", "TWI1_SCK", "", "", "PA_EINT18"},
"PA19": {"PCM0_CLK", "TWI1_SDA", "", "", "PA_EINT19"},
"PA20": {"PCM0_DOUT", "SIM_VPPEN", "", "", "PA_EINT20"},
"PA21": {"PCM0_DIN", "SIM_VPPPP", "", "", "PA_EINT21"},

"PC0": {"NAND_WE", "SPI0_MOSI"},
"PC1": {"NAND_ALE", "SPI0_MISO"},
"PC2": {"NAND_CLE", "SPI0_CLK"},
"PC3": {"NAND_CE1", "SPI0_CS"},
"PC4": {"NAND_CE0"},
"PC5": {"NAND_RE", "SDC2_CLK"},
"PC6": {"NAND_RB0", "SDC2_CMD"},
"PC7": {"NAND_RB1"},
"PC8": {"NAND_DQ0", "SDC2_D0"},
"PC9": {"NAND_DQ1", "SDC2_D1"},
"PC10": {"NAND_DQ2", "SDC2_D2"},
"PC11": {"NAND_DQ3", "SDC2_D3"},
"PC12": {"NAND_DQ4", "SDC2_D4"},
"PC13": {"NAND_DQ5", "SDC2_D5"},
"PC14": {"NAND_DQ6", "SDC2_D6"},
"PC15": {"NAND_DQ7", "SDC2_D7"},
"PC16": {"NAND_DQS", "SDC2_RST"},

"PD0": {"RGMII_RXD3"},
"PD1": {"RGMII_RXD2"},
"PD2": {"RGMII_RXD1"},
"PD3": {"RGMII_RXD0"},
"PD4": {"RGMII_RXCK"},
"PD5": {"RGMII_RXCTL"},
"PD6": {"RGMII_NULL"},
"PD7": {"RGMII_TXD3"},
"PD8": {"RGMII_TXD2"},
"PD9": {"RGMII_TXD1"},
"PD10": {"RGMII_TXD0"},
"PD11": {"RGMII_NULL"},
"PD12": {"RGMII_TXCK"},
"PD13": {"RGMII_TXCTL"},
"PD14": {"RGMII_NULL"},
"PD15": {"RGMII_CLKIN"},
"PD16": {"MDC"},
"PD17": {"MDIO"},

"PE0": {"CSI_PCLK", "TS_CLK"},
"PE1": {"CSI_MCLK", "TS_ERR"},
"PE2": {"CSI_HSYNC", "TS_SYNC"},
"PE3": {"CSI_VSYNC", "TS_DVLD"},
"PE4": {"CSI_D0", "TS_D0"},
"PE5": {"CSI_D1", "TS_D1"},
"PE6": {"CSI_D2", "TS_D2"},
"PE7": {"CSI_D3", "TS_D3"},
"PE8": {"CSI_D4", "TS_D4"},
"PE9": {"CSI_D5", "TS_D5"},
"PE10": {"CSI_D6", "TS_D6"},
"PE11": {"CSI_D7", "TS_D7"},
"PE12": {"CSI_SCK", "TWI2_SCK"},
"PE13": {"CSI_SDA", "TWI2_SDA"},
"PE14": {""},
"PE15": {""},

"PF0": {"SDC0_D1", "JTAG_MS"},
"PF1": {"SDC0_D0", "JTAG_DI"},
"PF2": {"SDC0_CLK", "UART0_TX"},
"PF3": {"SDC0_CMD", "JTAG_DO"},
"PF4": {"SDC0_D3", "UART0_RX"},
"PF5": {"SDC0_D2", "JTAG_CK"},
"PF6": {"SDC0_DET"},

"PG0": {"SDC1_CLK", "", "", "", "PG_EINT0"},
"PG1": {"SDC1_CMD", "", "", "", "PG_EINT1"},
"PG2": {"SDC1_D0", "", "", "", "PG_EINT2"},
"PG3": {"SDC1_D1", "", "", "", "PG_EINT3"},
"PG4": {"SDC1_D2", "", "", "", "PG_EINT4"},
"PG5": {"SDC1_D3", "", "", "", "PG_EINT5"},
"PG6": {"UART1_TX", "", "", "", "PG_EINT6"},
"PG7": {"UART1_RX", "", "", "", "PG_EINT7"},
"PG8": {"UART1_RTS", "", "", "", "PG_EINT8"},
"PG9": {"UART1_CTS", "", "", "", "PG_EINT9"},
"PG10": {"PCM1_SYNC", "", "", "", "PG_EINT10"},
"PG11": {"PCM1_CLK", "", "", "", "PG_EINT11"},
"PG12": {"PCM1_DOUT", "", "", "", "PG_EINT12"},
"PG13": {"PCM1_DIN", "", "", "", "PG_EINT13"},

"PL0": {"S_TWI_SCK", "", "", "", "S_PL_EINT0"},
"PL1": {"S_TWI_SDA", "", "", "", "S_PL_EINT1"},
"PL2": {"S_UART_TX", "", "", "", "S_PL_EINT2"},
"PL3": {"S_UART_RX", "", "", "", "S_PL_EINT3"},
"PL4": {"S_JTAG_MS", "", "", "", "S_PL_EINT4"},
"PL5": {"S_JTAG_CK", "", "", "", "S_PL_EINT5"},
"PL6": {"S_JTAG_DO", "", "", "", "S_PL_EINT6"},
"PL7": {"S_JTAG_DI", "", "", "", "S_PL_EINT7"},
"PL8": {"", "", "", "", "S_PL_EINT8"},
"PL9": {"", "", "", "", "S_PL_EINT9"},
"PL10": {"S_PWM", "", "", "", "S_PL_EINT10"},
"PL11": {"S_CIR_RX", "", "", "", "S_PL_EINT12"},
}

// mapH3Pins uses mappingH3 to set the altFunc fields of all the GPIO pings and
// mark them as available. This is called if the generic allwinner processor
// code detects a H2+ or H3 processor.
func mapH3Pins() error {
for name, altFuncs := range mappingH3 {
pin := cpupins[name]
pin.altFunc = altFuncs
pin.available = true
if strings.Contains(string(altFuncs[4]), "_EINT") ||
strings.Contains(string(altFuncs[3]), "_EINT") {
pin.supportEdge = true
}

// Initializes the sysfs corresponding pin right away.
pin.sysfsPin = sysfs.Pins[pin.Number()]
}
return nil
}
12 changes: 12 additions & 0 deletions orangepi/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2022 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.

// Package orangepi contains Orange Pi hardware logic.
//
// Requires armbian jessie server.
//
// # Physical
//
// http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/index.html
package orangepi
Loading

0 comments on commit 339d73c

Please sign in to comment.