Skip to content

Commit

Permalink
Allwinner: Implement nanopi neo air (#30)
Browse files Browse the repository at this point in the history
* Implement nanopi neo air
* Support for PL pins

Co-authored-by: Marc-Antoine Ruel <[email protected]>
  • Loading branch information
biotinker and maruel authored Mar 31, 2023
1 parent 2dfc6ee commit 9f0d9f7
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 10 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Google Inc.
Josh Gardiner
Matt Aimonetti <[email protected]>
Max Ekman <[email protected]>
Peter LoVerso <[email protected]>
Rifiniti, Inc
Stephan Sperber
Thorsten von Eicken <[email protected]>
31 changes: 22 additions & 9 deletions allwinner/h3.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package allwinner

import (
"strconv"
"strings"

"periph.io/x/conn/v3/pin"
Expand Down Expand Up @@ -138,16 +139,28 @@ var mappingH3 = map[string][5]pin.Func{
// 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
}
if strings.HasPrefix(name, "PL") {
pinNumStr := name[2:]
pinNum, err := strconv.Atoi(pinNumStr)
if err != nil {
return err
}
pin := &cpuPinsPL[pinNum]
pin.available = true

// Initializes the sysfs corresponding pin right away.
pin.sysfsPin = sysfs.Pins[pin.Number()]
// Initializes the sysfs corresponding pin right away.
pin.sysfsPin = sysfs.Pins[pin.Number()]
} else {
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
}
2 changes: 1 addition & 1 deletion cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func getMaxSpeedLinux() int64 {
if maxSpeed == -1 {
maxSpeed = 0
if f, err := openFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", os.O_RDONLY); err == nil {
defer f.Close()
defer f.Close() //#nosec G307 -- File is opened readonly so errors on file close cannot cause write errors
if b, err := io.ReadAll(f); err == nil {
s := strings.TrimSpace(string(b))
if i, err := strconv.ParseInt(s, 10, 64); err == nil {
Expand Down
10 changes: 10 additions & 0 deletions nanopi/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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 nanopi contains nanoPi hardware logic.
//
// Requires armbian jessie server.
//
// # Physical
package nanopi
184 changes: 184 additions & 0 deletions nanopi/nanopi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// 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.

// nanoPi pin out.

package nanopi

import (
"errors"
"fmt"
"strings"

"periph.io/x/conn/v3/driver/driverreg"
"periph.io/x/conn/v3/gpio"
"periph.io/x/conn/v3/pin"
"periph.io/x/conn/v3/pin/pinreg"
"periph.io/x/host/v3/allwinner"
"periph.io/x/host/v3/distro"
)

// Present return true if a NanoPi board is detected.
func Present() bool {
if isArm {
// This works for the NanoPi Neo Air, not sure if other NAnoPi boards
// match the same DTModel prefix.
return strings.HasPrefix(distro.DTModel(), "FriendlyARM")
}

return false
}

const (
boardNeoAir string = "NanoPi NEO Air" // + LTS (H2/H3 have identical pinouts)
)

var (
PA1_1 pin.Pin = pin.DC_IN // VCC 3v3 Ext
PA1_2 pin.Pin = pin.V5
PA1_3 gpio.PinIO = allwinner.PA12
PA1_4 pin.Pin = pin.V5
PA1_5 gpio.PinIO = allwinner.PA11
PA1_6 pin.Pin = pin.GROUND
PA1_7 gpio.PinIO = allwinner.PG11
PA1_8 gpio.PinIO = allwinner.PG6
PA1_9 pin.Pin = pin.GROUND
PA1_10 gpio.PinIO = allwinner.PG7
PA1_11 gpio.PinIO = allwinner.PA0
PA1_12 gpio.PinIO = allwinner.PA6
PA1_13 gpio.PinIO = allwinner.PA2
PA1_14 pin.Pin = pin.GROUND
PA1_15 gpio.PinIO = allwinner.PA3
PA1_16 gpio.PinIO = allwinner.PA8
PA1_17 pin.Pin = pin.DC_IN // VCC 3v3 Ext
PA1_18 gpio.PinIO = allwinner.PG9
PA1_19 gpio.PinIO = allwinner.PC0
PA1_20 pin.Pin = pin.GROUND
PA1_21 gpio.PinIO = allwinner.PC1
PA1_22 gpio.PinIO = allwinner.PA1
PA1_23 gpio.PinIO = allwinner.PC2
PA1_24 gpio.PinIO = allwinner.PC3

FUN1_1 pin.Pin = pin.V5
FUN1_2 pin.Pin = gpio.INVALID // USB-DP2
FUN1_3 pin.Pin = gpio.INVALID // USB-DM2
FUN1_4 pin.Pin = gpio.INVALID // USB-DP3
FUN1_5 pin.Pin = gpio.INVALID // USB-DM3
FUN1_6 pin.Pin = allwinner.PL11 // IR-RX
FUN1_7 pin.Pin = allwinner.PA17 // SPDIF-OUT
FUN1_8 pin.Pin = allwinner.PA18 // PCM0_SYNC/I2S0_LRC
FUN1_9 pin.Pin = allwinner.PA19 // PCM0_CLK/I2S0_BCK
FUN1_10 pin.Pin = allwinner.PA20 // PCM0_DOUT/I2S0_SDOUT
FUN1_11 pin.Pin = allwinner.PA21 // PCM0_DIN/I2S0_SDIN
FUN1_12 pin.Pin = pin.GROUND //

FUN2_1 pin.Pin = allwinner.HP_LEFT // LINEOUTL
FUN2_2 pin.Pin = allwinner.HP_RIGHT // LINEOUT
FUN2_3 pin.Pin = allwinner.MIC_GND // MIC GND
FUN2_4 pin.Pin = allwinner.MIC_IN // MIC IN

FUN3_1 pin.Pin = pin.GROUND
FUN3_2 pin.Pin = pin.V5
FUN3_3 pin.Pin = allwinner.PA4 // UART TX
FUN3_4 pin.Pin = allwinner.PA5 // UART RX

)

// registerHeaders registers the headers for various NanoPi boards. Currently
// only NanoPi NEO Air is supported.
func registerHeaders(model string) error {
if strings.Contains(model, boardNeoAir) {
// 24pin expansion port
if err := pinreg.Register("PA", [][]pin.Pin{
{PA1_1, PA1_2},
{PA1_3, PA1_4},
{PA1_5, PA1_6},
{PA1_7, PA1_8},
{PA1_9, PA1_10},
{PA1_11, PA1_12},
{PA1_13, PA1_14},
{PA1_15, PA1_16},
{PA1_17, PA1_18},
{PA1_19, PA1_20},
{PA1_21, PA1_22},
{PA1_23, PA1_24},
}); err != nil {
return err
}

// 12pin function interface
if err := pinreg.Register("FUN", [][]pin.Pin{
{FUN1_1},
{FUN1_2},
{FUN1_3},
{FUN1_4},
{FUN1_5},
{FUN1_6},
{FUN1_7},
{FUN1_8},
{FUN1_9},
{FUN1_10},
{FUN1_11},
{FUN1_12},
{FUN2_1},
{FUN2_2},
{FUN2_3},
{FUN2_4},
{FUN3_1},
{FUN3_2},
{FUN3_3},
{FUN3_4},
}); err != nil {
return err
}
}

return nil
}

// driver implements periph.Driver.
type driver struct {
}

// String is the text representation of the board.
func (d *driver) String() string {
return "nanopi"
}

// Prerequisites load drivers before the actual driver is loaded. For
// these boards, we do not need any prerequisites.
func (d *driver) Prerequisites() []string {
return nil
}

// After this driver is loaded, we need to load generic Allwinner drivers
// for the GPIO pins which are identical on all Allwinner CPUs.
func (d *driver) After() []string {
return []string{"allwinner-gpio", "allwinner-gpio-pl"}
}

// Init initializes the driver by checking its presence and if found, the
// driver will be registered.
func (d *driver) Init() (bool, error) {
if !Present() {
return false, errors.New("NanoPi board not detected")
}

model := distro.DTModel()
if model == "<unknown>" {
return true, fmt.Errorf("nanopi: failed to obtain model")
}

err := registerHeaders(model)
return true, err
}

// init register the driver.
func init() {
if isArm {
driverreg.MustRegister(&drv)
}
}

var drv driver
7 changes: 7 additions & 0 deletions nanopi/nanopi_arm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// 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 nanopi

const isArm = true
10 changes: 10 additions & 0 deletions nanopi/nanopi_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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.

//go:build arm64
// +build arm64

package nanopi

const isArm = true
10 changes: 10 additions & 0 deletions nanopi/nanopi_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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.

//go:build !arm && !arm64
// +build !arm,!arm64

package nanopi

const isArm = false

0 comments on commit 9f0d9f7

Please sign in to comment.