Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/adafruit_blinka/board/particle/tachyon.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# SPDX-License-Identifier: MIT
"""Pin definitions for the Tachyon."""

import re as _re

from adafruit_blinka.microcontroller.quectel.qcm6490 import pin

for it in pin.i2cPorts:
Expand Down Expand Up @@ -51,3 +53,16 @@
UART_RX = D15

PWM1 = D13

# Expose raw GPIO line-number names (GPIO_6, GPIO_24, GPIO_44, …) so that
# scripts and demo files can use them directly instead of the D-number aliases.


def _export_gpio_names():
for name in dir(pin):
if _re.match(r"^GPIO_\d+$", name):
globals()[name] = getattr(pin, name)


_export_gpio_names()
del _export_gpio_names, _re
131 changes: 98 additions & 33 deletions src/adafruit_blinka/microcontroller/quectel/qcm6490/pin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,121 +5,186 @@

from adafruit_blinka.microcontroller.generic_linux.libgpiod_pin import Pin

# Use with libgpiod_pin
GPIO_BASE = 0

GPIO_6 = Pin(GPIO_BASE + 6)
# The QCM6490's main 40-pin header GPIO bank (f100000.pinctrl, 176 lines) may
# appear as different gpiochip numbers depending on the kernel/BSP version:
#
# Ubuntu 20.04 BSP : f100000.pinctrl == gpiochip0 → plain Pin(n) works
# Current BSP : f100000.pinctrl == gpiochip4 → must use Pin((4, n))
#
# Both Blinka libgpiod layers (1.x and 2.x) support the (chip, line) tuple
# form, so we use it unconditionally once we know the chip number. We detect
# the chip at import time by scanning /sys/class/gpio labels so the same file
# works on both BSP generations without modification.

_TARGET_LABEL = "f100000.pinctrl"


def _find_qcm6490_chip():
"""Return the gpiochip number whose label is 'f100000.pinctrl'.

Tries gpiod.ChipIter() (gpiod 1.x) first, then falls back to probing
/dev/gpiochipN directly (gpiod 2.x). Returns 0 if the main bank is
not found — preserves Ubuntu 20.04 behaviour where f100000.pinctrl
was enumerated as gpiochip0.
"""
try:
import gpiod as _gpiod
except ImportError:
return 0

if hasattr(_gpiod, "ChipIter"):
# gpiod 1.x: iterate all chips cheaply
try:
for _chip in _gpiod.ChipIter():
try:
if _chip.label() == _TARGET_LABEL:
return int(_chip.name().replace("gpiochip", ""))
finally:
_chip.close()
except (AttributeError, OSError):
return 0
return 0

# gpiod 2.x: probe /dev/gpiochipN until the device is missing
for _n in range(16):
try:
_chip = _gpiod.Chip(f"/dev/gpiochip{_n}")
try:
if _chip.get_info().label == _TARGET_LABEL:
return _n
finally:
_chip.close()
except (AttributeError, OSError):
break
return 0 # fallback: chip 0 (Ubuntu 20.04 layout)


GPIO_CHIP = _find_qcm6490_chip()
GPIO_BASE = 0 # kept for reference only


def _pin(line):
"""Return the correct Pin for a QCM6490 GPIO line number.

Uses Pin((GPIO_CHIP, line)) so both gpiod 1.x (OPEN_BY_NUMBER) and
2.x (/dev/gpiochipN path) open the right chip regardless of whether
the main bank landed on chip 0 or chip 4.
"""
return Pin((GPIO_CHIP, line))


GPIO_6 = _pin(6)
UART01_TXD = GPIO_6
PWM1 = GPIO_6

GPIO_8 = Pin(GPIO_BASE + 8)
GPIO_8 = _pin(8)
I2C02_SDA = GPIO_8
SDA = GPIO_8

GPIO_9 = Pin(GPIO_BASE + 9)
GPIO_9 = _pin(9)
I2C02_SCL = GPIO_9
SCL = GPIO_9

GPIO_18 = Pin(GPIO_BASE + 18)
GPIO_18 = _pin(18)
UART04_TXD = GPIO_18
SPI04_CLK = GPIO_18

GPIO_19 = Pin(GPIO_BASE + 19)
GPIO_19 = _pin(19)
UART04_RXD = GPIO_19
SPI04_CS0 = GPIO_19

GPIO_24 = Pin(GPIO_BASE + 24)
GPIO_24 = _pin(24)

GPIO_32 = Pin(GPIO_BASE + 32)
GPIO_32 = _pin(32)
UART10_CTS = GPIO_32
CTS = GPIO_32

GPIO_33 = Pin(GPIO_BASE + 33)
GPIO_33 = _pin(33)
UART10_RTS = GPIO_33
RTS = GPIO_33

GPIO_34 = Pin(GPIO_BASE + 34)
GPIO_34 = _pin(34)
UART10_TXD = GPIO_34

GPIO_35 = Pin(GPIO_BASE + 35)
GPIO_35 = _pin(35)
UART10_RXD = GPIO_35

GPIO_36 = Pin(GPIO_BASE + 36)
GPIO_36 = _pin(36)
UART11_CTS = GPIO_36
SPI11_MISO = GPIO_36
I2C11_SDA = GPIO_36
EEPROM_SDA = GPIO_36

GPIO_37 = Pin(GPIO_BASE + 37)
GPIO_37 = _pin(37)
UART11_RTS = GPIO_37
SPI11_MOSI = GPIO_37
I2C11_SCL = GPIO_37
EEPROM_SCL = GPIO_37

GPIO_40 = Pin(GPIO_BASE + 40)
GPIO_40 = _pin(40)
QWIIC_I2C12_SDA = GPIO_40

GPIO_41 = Pin(GPIO_BASE + 41)
GPIO_41 = _pin(41)
QWIIC_I2C12_SCL = GPIO_41

GPIO_44 = Pin(GPIO_BASE + 44)
GPIO_44 = _pin(44)

GPIO_56 = Pin(GPIO_BASE + 56)
GPIO_56 = _pin(56)
SPI16_MISO = GPIO_56
I2C16_SDA = GPIO_56
UART16_CTS = GPIO_56
MISO = GPIO_56

GPIO_57 = Pin(GPIO_BASE + 57)
GPIO_57 = _pin(57)
SPI16_MOSI = GPIO_57
I2C16_SCL = GPIO_57
UART16_RTS = GPIO_57
MOSI = GPIO_57

GPIO_58 = Pin(GPIO_BASE + 58)
GPIO_58 = _pin(58)
SPI16_CLK = GPIO_58
UART16_TXD = GPIO_58
SCK = GPIO_58

GPIO_59 = Pin(GPIO_BASE + 59)
GPIO_59 = _pin(59)
SPI16_CS0 = GPIO_59
UART16_RXD = GPIO_59
CE0 = GPIO_59

GPIO_61 = Pin(GPIO_BASE + 61)
GPIO_61 = _pin(61)

GPIO_62 = Pin(GPIO_BASE + 62)
GPIO_62 = _pin(62)
SPI16_CS1 = GPIO_62
CE1 = GPIO_62

GPIO_78 = Pin(GPIO_BASE + 78)
GPIO_78 = _pin(78)
PWM0 = GPIO_78

GPIO_106 = Pin(GPIO_BASE + 106)
GPIO_106 = _pin(106)
MI2S1_SCLK = GPIO_106
PWM = GPIO_106
PWM1 = GPIO_106

GPIO_144 = Pin(GPIO_BASE + 144)
GPIO_144 = _pin(144)
LPI_MI2S_SCLK = GPIO_144

GPIO_145 = Pin(GPIO_BASE + 145)
GPIO_145 = _pin(145)
LPI_MI2S_WS = GPIO_145
MISO1 = GPIO_145

GPIO_146 = Pin(GPIO_BASE + 146)
GPIO_146 = _pin(146)
LPI_MI2S_DATA0 = GPIO_146
MOSI1 = GPIO_146

GPIO_147 = Pin(GPIO_BASE + 147)
GPIO_147 = _pin(147)
LPI_MI2S_DATA1 = GPIO_147
SCK1 = GPIO_147

GPIO_158 = Pin(GPIO_BASE + 158)
GPIO_158 = _pin(158)

GPIO_165 = Pin(GPIO_BASE + 165)
GPIO_165 = _pin(165)

GPIO_166 = Pin(GPIO_BASE + 166)
GPIO_166 = _pin(166)

# ordered as i2cId, i2cSclId, i2cSdaId
i2cPorts = (
Expand Down
Loading