summaryrefslogtreecommitdiff
path: root/util/pinmap/pm/generate.go
diff options
context:
space:
mode:
Diffstat (limited to 'util/pinmap/pm/generate.go')
-rw-r--r--util/pinmap/pm/generate.go172
1 files changed, 172 insertions, 0 deletions
diff --git a/util/pinmap/pm/generate.go b/util/pinmap/pm/generate.go
new file mode 100644
index 0000000000..0548a4a4db
--- /dev/null
+++ b/util/pinmap/pm/generate.go
@@ -0,0 +1,172 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package pm
+
+import (
+ "fmt"
+ "io"
+ "sort"
+ "strings"
+ "time"
+)
+
+const header = `/* Copyright %d The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * This file is auto-generated - do not edit!
+ */
+
+/ {
+`
+
+// Generate creates the DTS configuration from the pins using the chip as a
+// reference and writes the DTS to the output.
+func Generate(out io.Writer, pins *Pins, chip Chip) {
+ // Write header with date.
+ fmt.Fprintf(out, header, time.Now().Year())
+ pinConfig(out, "named-adc-channels", pins.Adc, chip, adcConfig)
+ pinConfig(out, "named-gpios", pins.Gpio, chip, gpioConfig)
+ pinConfig(out, "named-i2c-ports", pins.I2c, chip, i2cConfig)
+ pinConfig(out, "named-pwms", pins.Pwm, chip, pwmConfig)
+ fmt.Fprintf(out, "};\n")
+ // Retrieve the enabled nodes, sort, de-dup and
+ // generate overlays.
+ en := chip.EnabledNodes()
+ if len(en) != 0 {
+ sort.Strings(en)
+ var prev string
+ for _, s := range en {
+ if s == prev {
+ continue
+ }
+ fmt.Fprintf(out, "\n&%s {\n", s)
+ fmt.Fprintf(out, "\tstatus = \"okay\";\n")
+ fmt.Fprintf(out, "};\n")
+ prev = s
+ }
+ }
+}
+
+// pinConfig creates the DTS for a single pin.
+func pinConfig(out io.Writer, block string, pins []*Pin, chip Chip, cfunc func(io.Writer, *Pin, Chip)) {
+ if len(pins) == 0 {
+ return
+ }
+ // Sort the pins into alphbetical order.
+ sort.Slice(pins, func(i, j int) bool {
+ return pins[j].Signal > pins[i].Signal
+ })
+ // Generate start of block.
+ fmt.Fprintf(out, "\n\t%s {\n", block)
+ fmt.Fprintf(out, "\t\tcompatible = \"%s\";\n\n", block)
+ for _, p := range pins {
+ cfunc(out, p, chip)
+ }
+ fmt.Fprintf(out, "\t};\n")
+}
+
+// adcConfig is the handler for ADC pins.
+func adcConfig(out io.Writer, pin *Pin, chip Chip) {
+ if pin.PinType != ADC {
+ fmt.Printf("Unknown ADC type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin)
+ return
+ }
+ c := chip.Adc(pin.Pin)
+ if len(c) == 0 {
+ fmt.Printf("No matching ADC for pin %s, ignored\n", pin.Pin)
+ return
+ }
+ lc := strings.ToLower(pin.Signal)
+ fmt.Fprintf(out, "\t\tadc_%s: %s {\n", lc, lc)
+ fmt.Fprintf(out, "\t\t\tlabel = \"%s\";\n", pin.Signal)
+ if len(pin.Enum) > 0 {
+ fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum)
+ }
+ fmt.Fprintf(out, "\t\t\tchannel = <%s>;\n", c)
+ fmt.Fprintf(out, "\t\t};\n")
+}
+
+// gpioConfig is the handler for GPIO pins.
+func gpioConfig(out io.Writer, pin *Pin, chip Chip) {
+ c := chip.Gpio(pin.Pin)
+ if len(c) == 0 {
+ fmt.Printf("No matching GPIO for pin %s, ignored\n", pin.Pin)
+ return
+ }
+ var gtype string
+ switch pin.PinType {
+ default:
+ fmt.Printf("Unknown GPIO type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin)
+ return
+ case Input:
+ gtype = "GPIO_INPUT"
+ case InputPU:
+ gtype = "GPIO_INPUT_PULL_UP"
+ case InputPD:
+ gtype = "GPIO_INPUT_PULL_DOWN"
+ case Output:
+ gtype = "GPIO_OUTPUT"
+ case OutputOD:
+ gtype = "GPIO_ODR_HIGH"
+ case OutputODL:
+ gtype = "GPIO_ODR_LOW"
+ }
+ lc := strings.ToLower(pin.Signal)
+ fmt.Fprintf(out, "\t\tgpio_%s: %s {\n", lc, lc)
+ fmt.Fprintf(out, "\t\t\t#gpio-cells = <0>;\n")
+ fmt.Fprintf(out, "\t\t\tgpios = <&%s %s>;\n", c, gtype)
+ if len(pin.Enum) > 0 {
+ fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum)
+ }
+ fmt.Fprintf(out, "\t\t};\n")
+}
+
+// i2cConfig is the handler for I2C pins.
+func i2cConfig(out io.Writer, pin *Pin, chip Chip) {
+ if pin.PinType != I2C {
+ fmt.Printf("Unknown I2C type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin)
+ return
+ }
+ c := chip.I2c(pin.Pin)
+ if len(c) == 0 {
+ fmt.Printf("No matching I2C for pin %s, ignored\n", pin.Pin)
+ return
+ }
+ // Trim off trailing clock name (if any)
+ lc := strings.TrimRight(strings.ToLower(pin.Signal), "_scl")
+ fmt.Fprintf(out, "\t\ti2c_%s: %s {\n", lc, lc)
+ fmt.Fprintf(out, "\t\t\ti2c-port = <&%s>;\n", c)
+ if len(pin.Enum) > 0 {
+ fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum)
+ }
+ fmt.Fprintf(out, "\t\t};\n")
+}
+
+// pwmConfig is the handler for PWM pins.
+func pwmConfig(out io.Writer, pin *Pin, chip Chip) {
+ var inv string
+ switch pin.PinType {
+ default:
+ fmt.Printf("Unknown PWM type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin)
+ return
+ case PWM:
+ inv = "0"
+ case PWM_INVERT:
+ inv = "1"
+ }
+ c := chip.Pwm(pin.Pin)
+ if len(c) == 0 {
+ fmt.Printf("No matching PWM for pin %s, ignored\n", pin.Pin)
+ return
+ }
+ lc := strings.ToLower(pin.Signal)
+ fmt.Fprintf(out, "\t\tpwm_%s: %s {\n", lc, lc)
+ fmt.Fprintf(out, "\t\t\tpwms = <&%s %s>;\n", c, inv)
+ if len(pin.Enum) > 0 {
+ fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum)
+ }
+ fmt.Fprintf(out, "\t\t};\n")
+}