Gemeinsame Grundlage ist das chinesische RK-KF-YF-079 V1.1.0 (8 Seiten); nur im englischen V1.0.0 (7 Seiten) vorhandene Details werden separat ergänzt. Chinesischer Geltungsbereich: Rockchip/Linux 4.4, 4.19, 5.10 und 6.1. Diese Plattformreferenz bestätigt weder SARADC-Generation noch Pins, Referenzspannung oder Testschnittstelle eines bestimmten ArmSoM-Boards. SoC-TRM, BSP und DTS prüfen; Beispiel-IRQs und Kanalnummern nicht ungeprüft übernehmen. Beide Quellen enthalten keine eigenständigen technischen Abbildungen. Keine Hardware-Abtasttests durchgeführt.
Quellenüberblick: 6 Kanäle, 10bit, 1MSPS bei 13MHz; der chinesische Text bezeichnet das Gerät als Digital-Analog-Wandler. Diese Formulierung sowie die späteren Testkanäle 0–7 anhand des konkreten Chips prüfen, statt Quellwerte stillschweigend zu ändern. Beide DTS-Beispiele verwenden io-channel-cells ohne # und ordnen 1.8V dem Wert 1024 zu; tatsächliches Binding und Auflösung prüfen. Abschnitt 6 enthält 537 und 538 im Protokoll, obwohl die Erklärung nur 537 nennt; beides bleibt erhalten.
1. SARADC-Treiber
1.1 Treiberdatei
Treiberpfad: drivers/iio/adc/rockchip_saradc.c
1.2 DTS-Knotenkonfiguration
Siehe Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt. Parameter:
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH 0>;: Interrupt nach Abschluss der Wandlung.io-channel-cells = <1>;: muss 1 sein; siehe iio-bindings.txt.vref-supply = <&vccadc_ref>;: Referenzspannung passend zur Hardware setzen. Die Quelle nennt maximal 1.8V entsprechend SARADC-Wert 1024 und einen linearen Zusammenhang zwischen Spannung und ADC-Wert.
2. SARADC verwenden
2.1 Überblick
Als IIO-Instanz benötigt SARADC eine initialisierte struct iio_dev und Registrierung durch iio_device_register(indio_dev); siehe rockchip_saradc_probe.
Ein wichtiger Einsatz ist adc-key. Der Tastentreiber verwendet das Input-Framework: struct input_polled_dev initialisieren und mit input_register_polled_device(poll_dev); registrieren; siehe adc_keys_probe in drivers/input/keyboard/adc-keys.c.
Tasten mit getevent testen. Ist adc-key event0, durchläuft getevent -s /dev/input/event0 folgende Aufrufkette:
adc_keys_poll -> iio_read_channel_processed -> iio_channel_read -> chan->indio_dev
->info->read_raw(rockchip_saradc_read_raw) -> iio_convert_raw_to_processed_unlocked
Dies ist der vollständige adc-key-Abtastpfad zur Nachverfolgung des SARADC-Ablaufs.
2.2 Ablauf
2.2.1 Abtastkonfiguration
rockchip_saradc_read_raw konfiguriert die Abtastung. Im Treiber erfolgt dies hauptsächlich über den start-Callback von struct rockchip_saradc_data; dort liegen die wesentlichen Unterschiede der drei Versionen.
2.2.1.1 rockchip_saradc_start_v1
writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
Verzögerung zwischen Einschalten und Abtastbeginn setzen.
writel(SARADC_CTRL_POWER_CTRL | (chan->channel & SARADC_CTRL_CHN_MASK) |
SARADC_CTRL_IRQ_ENABLE,info->regs + SARADC_CTRL);
Abtastkanal setzen, Interrupts aktivieren und Abtastung starten. Dies sind die wesentlichen V1-Konfigurationsschritte.
2.2.1.2 rockchip_saradc_start_v2
writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC);
writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
PHY-Kompatibilität konfigurieren.
val = FIELD_PREP(SARADC2_EN_END_INT, 1);
val |= SARADC2_EN_END_INT << 16;
writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
END_INT-Interrupt aktivieren.
val = FIELD_PREP(SARADC2_START, 1) |
FIELD_PREP(SARADC2_SINGLE_MODE, 1) |
FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
val |= (SARADC2_START | SARADC2_SINGLE_MODE | SARADC2_CONV_CHANNELS) << 16;
writel(val, info->regs + SARADC2_CONV_CON);
Abtastmodus und Kanal setzen, dann Abtastung starten.
2.2.1.3 rockchip_saradc_start_v3
Die V3-Konfiguration ohne DMA entspricht V2. Der V3-DMA-Modus ruft rockchip_saradc_start_v3_dma auf.
2.2.1.3.1 rockchip_saradc_start_v3_dma
writel_relaxed(0x11, info->regs + SARADC_T_DAS_SOC);
writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
writel_relaxed(0x0, info->regs + SARADC_T_SEL_SOC);
PHY-Kompatibilität konfigurieren.
val = FIELD_PREP(SARADC3_PMASTER_EN, 1);
val |= SARADC3_PMASTER_EN << 16;
writel_relaxed(val, info->regs + SARADC3_FIFO_CON);
FIFO aktivieren.
writel_relaxed((u64)info->dma_phys >> 32, info->regs + SARADC3_PADDR_BASE_H);
writel_relaxed(((u32)info->dma_phys) >> 2, info->regs + SARADC3_PADDR_BASE_L);
Zielpufferadresse für DMA konfigurieren.
writel_relaxed((SARADC3_DMA_SIZE >> 2) - 1, info->regs + SARADC3_PADDR_OFF_MAX);
Größe des DMA-Schreibpuffers konfigurieren.
val = FIELD_PREP(SARADC3_EN_END_MAX_INT, 1);
val |= SARADC3_EN_END_MAX_INT << 16;
writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
MAX_INT-Interrupt konfigurieren.
val = BIT(chn) << 16 | BIT(chn);
writel_relaxed(val, info->regs + SARADC3_AUTO_CH_EN);
Gewählten Kanal auf auto-Modus setzen.
val = FIELD_PREP(SARADC2_START, 1) |
FIELD_PREP(SARADC3_AUTO_MODE, 1) |
FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
val |= (SARADC2_START | SARADC3_AUTO_MODE | SARADC2_CONV_CHANNELS) << 16;
writel(val, info->regs + SARADC2_CONV_CON);
Kontinuierlichen Abtastmodus konfigurieren und starten.
2.2.2 Auf Abtastende warten
wait_for_completion_timeout(&info->completion, SARADC_TIMEOUT)
2.2.3 Daten lesen
Nach Abschluss wird ein Interrupt ausgelöst. rockchip_saradc_isr ruft rockchip_saradc_read auf, speichert den Messwert in info->last_val, weckt rockchip_saradc_read_raw und gibt ihn über *val = info->last_val zurück. Versionsabhängige read-Implementierungen:
rockchip_saradc_read_v1
rockchip_saradc_read_v2
rockchip_saradc_read_v3
Die read-Funktionen sind einfach und werden in der Quelle nicht weiter analysiert.
2.2.4 SARADC abschalten
Die folgende Funktion schaltet SARADC ab. Nur V1 muss manuell abgeschaltet werden; V2/V3 schalten nach der Abtastung automatisch ab.
rockchip_saradc_power_down
2.2.5 Zusammenfassung
Ein vollständiger Zyklus konfiguriert und aktiviert SARADC über rockchip_saradc_read_raw, startet die Abtastung und wartet auf einen Interrupt. Der Handler löscht den Interrupt, liest den Messwert, weckt rockchip_saradc_read_raw, gibt den Wert zurück und schaltet SARADC ab.
3. Kernelkonfiguration
Symbol: ROCKCHIP_SARADC [=y]
Type : tristate
Prompt: Rockchip SARADC driver
Location:
-> Device Drivers
-> Industrial I/O support (IIO [=y])
(1) -> Analog to digital converters
Defined at drivers/iio/adc/Kconfig:319
Depends on: IIO [=y] && (ARCH_ROCKCHIP [=y] || ARM && COMPILE_TEST [=n]) &&
RESET_CONTROLLER [=y]
4. Übliche SARADC-Schnittstellen
- ADC-Werte im Userspace lesen; * ist die Kanalnummer:
cat /sys/bus/iio/devices/iio\:device0/in_voltage*_raw
Beispielsweise channel0:
cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
- Kernelschnittstellen:
iio_read_channel_raw()liest den ADC-Wert,iio_read_channel_processed()die Spannung.
5. V2/V3-Verbesserungen
V2 ist nicht mit V1 kompatibel und ergänzt Schwellwert-Interrupts sowie automatische Abtastung.
V3 ist mit V2 kompatibel und ergänzt DMA-Schreibzugriffe auf externen Speicher.
6. Testschnittstelle
Aktivieren:
CONFIG_ROCKCHIP_SARADC_TEST_CHN
Dadurch entsteht ein saradc_test_chn-Knoten unter sys. Den vollständigen Pfad suchen:
echo chn > /sys/full_path_of_saradc_test_chn/saradc_test_chn
Bei chn 0–7 wird der jeweilige Kanal kontinuierlich abgetastet; die serielle Ausgabe lautet:
chn[0] val = 537
chn[0] val = 537
chn[0] val = 538
Die Quelle beschreibt dieses Protokoll als Messwert 537 für Kanal 0.
echo 8 > /sys/full_path_of_saradc_test_chn/saradc_test_chn
Zum Stoppen einen Wert oberhalb der höchsten gültigen Kanalnummer schreiben, beispielsweise 8.
Ergänzung aus Englisch V1.0.0: ältere V1-Implementierung
Englische Seiten 5–6 nennen 8 sclk-Zyklen Verzögerung sowie Einschalten, Kanalwahl, Interruptfreigabe und Abtaststart. Nach Abschluss und Interrupt wird der Wert val zugewiesen; iio_convert_raw_to_processed_unlocked wandelt ihn in Spannung um. Der ältere ISR liest SARADC_DATA direkt und schreibt anschließend 0 zum Löschen des Interrupts und Abschalten:
*val = info->last_val;
info->last_val = readl_relaxed(info->regs + SARADC_DATA);
writel_relaxed(0, info->regs + SARADC_CTRL);
