Vollständiger technischer Inhalt des chinesischen V1.1.0. Kein englisches PDF; EN/RU/DE sind vollständige Übersetzungen. Alle fünf Bilder stammen aus der chinesischen Quelle; interne Beschriftungen bleiben chinesisch. Quellengeltung: RV1109/RV1126 und RK356X Linux4.19; RK3588, RK3576, RV1106/RV1103, RV1106B/RV1103B Linux5.10; RV1126B Linux6.1. Nur ArmSoM-Plattformreferenz: Board, Kameramodul, SDK/BSP, Versorgung/IOMUX und Kernel-APIs einzeln anpassen. Keine pauschale Boardunterstützung. Startzeiten/Fehleranteile sind Quellenangaben, keine ArmSoM-Messungen. Keine Hardwarebefehle ausgeführt.
Quellenfragen: probe/remove/ioctl-Signaturen unterscheiden sich zwischen Definitionen und Tabellen; beide bleiben erhalten. Doppeltes SC200AI_LGAIN, denominato/Ctrol/intput und falsche Querverweise nicht erraten. Vertikales Flip ist keine180°-Drehung.90%/9%/1%, MIPI-Grenzen sowie Augen-/Slew-/Abschlusswerte aus6.5 sind keine verifizierten Universalnormen. „50Ω nach Masse“ nicht direkt anwenden; Hardwareingenieure müssen PHY, Referenzdesign und Spezifikation prüfen, um Schäden zu vermeiden. Nennwerte einhalten, stromlos umstecken und temporäre power_off-Änderungen zurücknehmen. Interne Muster allein bestätigen keine optischen Pixelfehlerfreiheit.
2. Vorbereitung der Fehlersuche
Vor der Fehlersuche am Camera-Treiber folgende Unterlagen vorbereiten:
2.1 Host-Spezifikationen prüfen
Maximale Auflösung, obere Eingangsfrequenz, maximale Datenrate je Lane, unterstützte Lane-Anzahl und Eingangs-Schnittstellentyp der Host-Plattform für diesen Sensor prüfen.
2.2 Sensor DataSheet
Datenblatt des Sensorherstellers beschaffen: Versorgungsspannungen und Ein-/Ausschaltfolge, Chip ID für die probe-Prüfung, Belichtungszeit-/Verstärkungseinstellung und Bildratenänderung, Slave-Unterstützung sowie Mehrkamera-Verkabelung und Register, Testmodus und HDR sowie Mirror/Flip-Konfiguration prüfen.
2.3 Sensor Initialize Settings
Registerliste normalerweise vom Sensorhersteller beschaffen. Auflösung, Bildrate, Lane-Anzahl, Rate je Lane, VTS, HTS, Bitbreite und Haupttakt festlegen. Mindestens Standardauflösungen vorbereiten; Binning-/Crop-Sequenzen nach Projektbedarf. SmartSens-Beispiel: cleaned_0x2b_SC530AI_27Minput_1080Mbps_2lane_10bit_1920x1080_60fps.ini. Dateiname: SC530AI, Host-MCLK 27Mhz, MIPI zum Host 1080Mbps je Lane, 2 Lanes, 10bit, 1920x1080 (1080p), Bildrate 60pfs (Originalschreibweise).
Folgende Vorlage dient zur Konfigurationsanfrage beim Sensorhersteller; Einträge nach Projektbedarf auswählen.
sensor: XXXX
mclk: 24MHz/27Mhz/37.5Mhz
mode: raw8/raw10/raw12/raw16
output: 720p/1080p/1440p/... (Auflösung)
Schnittstelle: mipi 1/2/4 Lane
Bildrate: 30/60/120 fps
Host: RK3588/RV1106/RV1103B/RV1126B/...
Produkt: Türklingel/Türklingel/IPC/... (optional; Quellenwiederholung)
3. Treiberentwicklung
3.1 Treibercode schreiben
Einen neuen Sensortreiber auf einem ähnlich spezifizierten Sensor unter kernel/drivers/media/i2c/ oder einem ähnlichen Modell desselben Herstellers aufbauen. Die folgenden Kapitel erläutern den RK-Prozess anhand von SmartSens SC200AI.
3.1.1 Wichtige Sensorparameter
Die mode-Struktur definiert wichtige Sensorparameter. Für jede Auflösung korrekt ausfüllen.
struct XXXX_mode {
u32 bus_fmt; //输出像素格式
u32 width; //输出宽度
u32 height; //输出⾼度
struct v4l2_fract max_fps; //最⼤输出帧率
u32 hts_def; //默认⾏总周期
u32 vts_def; //默认帧总周期
u32 exp_def; //默认曝光值
u32 mipi_freq_idx;//链接频率索引值
u32 bpp; //每像素所⽤bit数
const struct regval *reg_list; //寄存器列表
u32 hdr_mode; //宽动态模式
u32 vc[PAD_MAX];//虚拟通道数组
};
Das Array supported_modes enthält mode-Strukturen unterstützter Auflösungen, die bei probe oder Auflösungswechsel durchlaufen und zugeordnet werden. SC200AI-Beispiel:
static const struct sc200ai_mode supported_modes[] = {
{ // 1080p 30fps 线性配置参数
.width = 1920,
.height = 1080,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x0080,
.hts_def = 0x44C * 2,
.vts_def = 0x0465,
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
.reg_list = sc200ai_linear_10_1920x1080_30fps_regs,
.hdr_mode = NO_HDR,
.bpp = 10,
.mipi_freq_idx = 1,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
},
{ // 540p 120fps 线性配置参数
.width = 960,
.height = 540,
.max_fps = {
.numerator = 10000,
.denominator = 1200000,
},
.exp_def = 0x0080,
.hts_def = 0x420,
.vts_def = 0x249,
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
.reg_list = sc200ai_linear_10_960x540_120fps_regs,
.hdr_mode = NO_HDR,
.bpp = 10,
.mipi_freq_idx = 0,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
},
{ // 1080p 30fps 宽动态配置参数
.width = 1920,
.height = 1080,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x0080,
.hts_def = 0x44C * 2,
.vts_def = 0x08CC,
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
.reg_list = sc200ai_hdr_10_1920x1080_regs,
.hdr_mode = HDR_X2,
.bpp = 10,
.mipi_freq_idx = 1,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
},
}
Parameter:
bus_fmt beschreibt die Pixelausgabe. Die Herstellersequenz nennt gewöhnlich die Bitbreite (etwa 10bit); BGGR ist die Bayer-Reihenfolge. Eine falsche Reihenfolge verhindert das Bild nicht, verursacht aber einen Farbstich.
width und height sind die aktiven Ausgabemaße und wichtigsten Parameter, meist kleiner als hts und vts.
max_fps ist die maximale Bildrate des Modus: denominato / numerator (Originalschreibweise). numerator bleibt gewöhnlich unverändert; bei genau 30 Bildern/s ist denominator 300000.
exp_def ist die Standardbelichtung, hts_def die Gesamtpunktzahl je Zeile, vts_def die Gesamtzeilenzahl je Bild. Aus Initialisierungsregistern übernehmen. Ein falsches vts_def verändert die Bildrate.
global_reg_list enthält allgemeine Initialisierungsregister und darf leer sein; reg_list ist die Herstellersequenz. hdr_mode: NO_HDR für linear, HDR_X2/HDR_X3 für HDR-Fusion aus zwei/drei Bildern.
link_freq_idx indiziert link_freq_menu_items. Hersteller nennen gewöhnlich Mbps je Lane; MIPI tastet beide Flanken ab, daher ist die Frequenz die halbe Übertragungsrate. Erste lineare Sequenz: 720Mbps, somit MIPI/link_freq 360M. Falsche Werte verhindern leicht die Aufnahme; mehrfach prüfen. bpp ist Bit je Pixel.
Linear und HDR unterscheiden sich in hdr_mode und im virtuellen Kanalarray vc. Linear: hdr_mode = NO_HDR, vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0. HDR: hdr_mode = HDR_X2/HDR_X3; vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0; vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0; vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1; vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1.
3.1.2 Wichtige Sensorregister
Folgende wichtige Register können bei der Treiberentwicklung verwendet werden; Einzelheiten variieren nach Hersteller und Modell.
3.1.2.1 Chip id
Chip ID identifiziert den Sensor beim Treiberladen. probe prüft die ID; die Quelle wertet eine korrekte ID als Hinweis auf Erkennung, I2C-Kommunikation und Versorgungsspannungen.
#define CHIP_ID 0xcb1c
#define SC200AI_REG_CHIP_ID 0x3107
Manche Sensoren besitzen keine Chip ID. Zur Erkennungs-/Anbindungsprüfung ein oder mehrere Nur-Lese-Register auslesen und mit Standardwerten vergleichen.
3.1.2.2 Ctrol mode
Das Stream-Start/Stopp-Register wird normalerweise nach erfolgreichem Schreiben aller anderen Sensorregister gesetzt.
#define SC200AI_REG_CTRL_MODE 0x0100
#define SC200AI_MODE_SW_STANDBY 0x0
#define SC200AI_MODE_STREAMING BIT(0)
Dieses Register nicht in der Registersequenz setzen. Start-/Stopp-Schnittstellen steuern es gesondert.
3.1.2.3 Exposure reg
Belichtungsregister können sich zwischen linearem und HDR-Modus unterscheiden; Sensorhandbuch beachten.
#define SC200AI_REG_EXPOSURE_H 0x3e00 //⻓曝光最⾼位
#define SC200AI_REG_EXPOSURE_M 0x3e01 //⻓曝光中间位
#define SC200AI_REG_EXPOSURE_L 0x3e02 //⻓曝光最低位
#define SC200AI_REG_SEXPOSURE_H 0x3e22 //短曝光最⾼位
#define SC200AI_REG_SEXPOSURE_M 0x3e04 //短曝光中间位
#define SC200AI_REG_SEXPOSURE_L 0x3e05 //短曝光最低位
#define SC200AI_EXPOSURE_MIN 1 //最新曝光⾏,⼀般不改,除⾮sensor有最⼩曝光限制
#define SC200AI_EXPOSURE_STEP 1 //曝光步进,⼀般不⽤修改
Belichtungsregister können mehr als 16bit umfassen: 24bit bestehen aus hohem, mittlerem und niedrigem Byte und erfordern mehrere Schreibvorgänge. Lange/kurze Bilder können gesonderte Werte benötigen. Verstärkungen können Formeln erfordern: analog linear oder tabelliert; digital ein Gleitkommafaktor, der als Festkomma etwa Q8.8 geschrieben wird.
3.1.2.4 Gain reg
Register steuern analoge und digitale Verstärkung. Beide können Grobverstärkung (gewöhnlich Ganzzahlteil) und Feinverstärkung (gewöhnlich Bruchteil) besitzen.
Analogverstärkung verstärkt die Sensorspannung vor dem ADC. Sie beeinflusst das Rauschen weniger als digitale Verstärkung, hat aber einen begrenzten Bereich; zu hohe Werte erhöhen Rauschen und nichtlineare Verzerrung. Register: ANA_GAIN (grob), ANA_FINE_GAIN (fein).
Digitalverstärkung multipliziert Rohwerte wie 10bit/12bit nach dem ADC. Sie ist einfach und flexibel, verstärkt aber Rauschen und Quantisierungsfehler, besonders Farbrauschen bei wenig Licht. Register: DIG_GAIN (grob), DIG_FINE_GAIN (fein).
Ziele: Helligkeit bei wenig Licht erhöhen; AE passt Verstärkung und Belichtungszeit (shutter/line count) dynamisch an die Zielhelligkeit an; SNR und Dynamikbereich steuern.
#define SC200AI_REG_DIG_GAIN 0x3e06 //数字主增益
#define SC200AI_REG_DIG_FINE_GAIN 0x3e07 //数组精增益
#define SC200AI_REG_ANA_GAIN 0x3e08 //模拟主增益
#define SC200AI_REG_ANA_FINE_GAIN 0x3e09 //模拟精增益
#define SC200AI_REG_SDIG_GAIN 0x3e10 //短帧的数字主增益
#define SC200AI_REG_SDIG_FINE_GAIN 0x3e11 //短帧的数组精增益
#define SC200AI_REG_SANA_GAIN 0x3e12 //短帧的模拟主增益
#define SC200AI_REG_SANA_FINE_GAIN 0x3e13 //短帧的模拟精增益
#define SC200AI_GAIN_MIN 0x0040 //增益最⼩值
#define SC200AI_GAIN_MAX (54 * 32 * 64) //53.975*31.75*64 增益最⼤值
#define SC200AI_GAIN_STEP 1 //增益步进
#define SC200AI_GAIN_DEFAULT 0x0800 //默认增益值
#define SC200AI_LGAIN 0 //⻓帧增益
#define SC200AI_SGAIN 1 //短帧增益
HDR kann getrennte Verstärkungen für lange/kurze Bilder benötigen. Die Quelle nennt beide SC200AI_LGAIN und SC200AI_LGAIN; die doppelte Kennung bleibt bis zur Prüfung erhalten.
3.1.2.5 Group hold
Group Hold synchronisiert CMOS-Updates von Belichtung (shutter), Verstärkung und weiteren Parametern. Während eines Bildes müssen analoge/digitale Verstärkung und Zeilenbelichtung konsistent bleiben, sonst entstehen Streifen, ungleichmäßige Helligkeit oder teilweise Über-/Unterbelichtung. Registeränderungen wirken gewöhnlich erst an der nächsten Bild-/Zeilengrenze. Änderungen während der Aufnahme können Teile mit alten und neuen Werten erzeugen. Group Hold friert den Update-Zeitpunkt ein und aktiviert alle Änderungen gemeinsam zu einem festgelegten Zeitpunkt.
#define SC200AI_REG_GROUP_HOLD 0x3812 //group hold 控制寄存器
#define SC200AI_GROUP_HOLD_START 0x00 //开启Group Hold(冻结参数更新)即:Group Hold Start
#define SC200AI_GROUP_HOLD_END 0x30 //关闭Group Hold(释放参数更新)即:Group Hold End
3.1.2.6 Test pattern
Ein Testmusterregister aktiviert einen CMOS-/CCD-Modus mit intern erzeugten Mustern statt optischer Aufnahmen. Das synthetische Bild dient Test, Fehlersuche und Verifikation. Typisch sind Farbbalken, Verläufe, Schachbrett, Rot/Grün/Blau/Schwarz/Weiß-Flächen, Raster und Fixed Pattern Noise (FPN).
3.1.2.6.1 Anwendungen von Testmustern
- Sensorprüfung/Fehlersuche. Testmuster prüfen schnell Datenausgabe, MIPI CSI-2/Datenpfad, Auflösung und RAW-/RGB-/YUV-Format sowie ISP-/nachgelagerten Empfang und Verarbeitung. Nach dem ersten Einschalten lässt sich der Sensor beispielsweise ohne Objektiv oder Lichtquelle prüfen.
Erscheinen nach Aktivierung Farbbalken oder Verläufe auf Display/Debug-Werkzeug, funktionieren Sensor und Datenpfad grundsätzlich.
-
ISP-Fehlersuche und Algorithmusprüfung. Demosaic, 3A, Gamma, CSC, Sharpening und weitere Blöcke, Verarbeitung verschiedener Eingaben sowie Farbwiedergabe, Helligkeit, Kontrast und Rauschunterdrückung prüfen. Bekannte steuerbare Eingaben eignen sich für quantitative Analyse und Abstimmung. Eine rote Fläche sollte rot bleiben und zeigt Weißabgleich-/Farbkorrekturprobleme; Verläufe prüfen Gamma, Dynamikbereich und Tone Mapping.
-
Kameramodul-Fehlersuche/Kalibrierung. Bei Fertigung/Kalibrierung den Pfad Objektivmodul + Sensor + ISP prüfen, AF-/AE-/AWB-Tests simulieren und Grundfunktionen ohne reale Beleuchtung prüfen.
-
Fehlereingrenzung. Bei Farbstich, Bildfehlern, Streifen oder ganz schwarzem/weißem Bild das Muster aktivieren. Ein normales Muster deutet auf Optik (schmutziges Objektiv/kein Licht) oder Szeneneingang; ein fehlerhaftes auf Sensor, MIPI, ISP oder Versorgung. So lassen sich optische von elektrischen/Datenverarbeitungsfehlern trennen.
-
Fertigungstest. Die Quelle nennt automatische Sensorausgabeprüfung, Prüfung toter/heißer Pixel und festen Rauschens sowie Datenintegrität, Farbgenauigkeit und Dynamikbereich.
3.1.2.6.2 Übliche Testmustertypen
| Testmuster | Beschreibung | Verwendung |
|---|---|---|
| Solid Color | Ganzes Bild rot/grün/blau/schwarz/weiß | Farbkanäle, defekte Pixel |
| Color Bars | TV-Farbbalken: Rot/Grün/Blau/Schwarz/Weiß-Kombinationen | Farbausgabe, ISP |
| Gradient | Glatter Schwarz-Weiß- oder RGB-Verlauf | Dynamikbereich, Gamma, Tone Mapping |
| Checkerboard | Schwarz-weiße Felder | Schärfe, Kantenverarbeitung, Kompression |
| Moving Pattern | Veränderliche Muster mancher Sensoren | Timing, Puffer, Latenz |
| Random / Noise Pattern | Simuliertes Rauschen | Rauschunterdrückung |
| Cross Hatch / Grid | Gekreuzte Linien | Geometrieverzerrung, Ausrichtung |
#define SC200AI_REG_TEST_PATTERN 0x4501 //测试图案控制寄存器
#define SC200AI_TEST_PATTERN_BIT_MASK BIT(3) //测试图案开启掩码
3.1.2.7 VTS
HTS und VTS sind zentrale Timingparameter von CMOS-Bildsensoren (CIS) und Kameramodulen. VTS bedeutet Vertical Total Time/Lines: gesamte Zeilen/Zeit eines Bildes einschließlich aktiver und Austastzeilen. Meist in Zeilen, anhand von Bildrate/VTS auch in Zeit (z. B. ms) umrechenbar. Bestandteile:
-
Active Lines: tatsächliche Bilddatenzeilen, etwa 1080 bei 1920x1080.
-
VSYNC (Vertikalsynchronisation)
-
Vertikale Austastung/vordere und hintere Schwarzschulter für Bildwechsel und interne Verarbeitung. VTS = aktive Zeilen + vertikale Austastzeilen. Zusammenhang mit Auflösung/Bildrate:
-
Bildratenberechnung (FPS). Grundformel:
FPS = PCLK / (HTS × VTS)
PCLK ist Pixel Clock, gewöhnlich in MHz oder Hz: übertragene Pixeltaktzyklen je Sekunde.
HTS ist die Gesamtzahl Takte je Zeile (Zeilendauer), VTS die Zeilenzahl je Bild. Gemeinsam bestimmen sie die Bildrate. FPS durch weniger VTS/Austastung oder höheren PCLK erhöhen. Für geringere FPS, etwa längere Belichtung bei wenig Licht, VTS erhöhen oder PCLK senken. Zentrale Unterschiede:
| Punkt | HTS (Horizontal Total) | VTS (Vertical Total) |
|---|---|---|
| Richtung | Horizontal innerhalb einer Zeile | Vertikal innerhalb eines Bildes |
| Bedeutung | Zeilentakte: aktive Pixel + Austastung | Bildzeilen: aktiv + Austastung |
| Enthält | Aktive Pixel + HSYNC + horizontale Austastung | Aktive Zeilen + VSYNC + vertikale Austastung |
| Einfluss | Zeilenfrequenz, Datentiming | Bildrate, Bilddauer |
| Bildrate | FPS = PCLK / (HTS × VTS) | Mehr VTS senkt FPS; weniger erhöht FPS |
| Einheit | Taktzyklen/Pixeltakte | Zeilen |
| Konfiguration | Sensor-Zeilentimingregister | Sensor-Bildtimingregister |
#define SC200AI_REG_VTS_H 0x320e
#define SC200AI_REG_VTS_L 0x320f
3.1.2.8 Mirror / Flip
Mirror-/Flip-Register steuern die Sensorausgabeorientierung: geometrische Links/Rechts- oder Oben/Unten-Spiegelung.
-
Mirror vertauscht links und rechts entlang X wie ein Spiegel. Mirror/Horizontal Flip setzen, wenn horizontale Montage oder Objektivausrichtung das Bild umkehrt.
-
Flip vertauscht oben und unten entlang Y. Die Quelle vergleicht dies mit einer 180°-Drehung oder einem Blick von der Decke; die Analogie bleibt dokumentiert, reine vertikale Spiegelung ist jedoch keine 180°-Drehung. Sensorfunktion:
Flip/Vertical Flip aktiviert vertikale Spiegelung, typischerweise bei umgekehrter Montage oder zur Displayausrichtung. Kombinationen von Mirror/Flip:
| Einstellung | Effekt | Erscheinung |
|---|---|---|
| Kein Mirror / Flip | Normal | Unverändert, normale Richtung (Standard) |
| Mirror | Links/rechts vertauscht | Wie ein Spiegel |
| Flip | Oben/unten vertauscht | Kopfüber stehendes Foto |
| Mirror + Flip | Beide Spiegelungen = 180°-Drehung | Alle Richtungen umgekehrt; 180° gedreht |
Die meisten CMOS-Sensoren, darunter Sony, OmniVision, SmartSens, GalaxyCore und Onsemi, konfigurieren Mirror/Flip über Register.
#define SC200AI_FLIP_MIRROR_REG 0x3221 // 镜像翻转控制寄存器
#define SC200AI_FETCH_MIRROR(VAL, ENABLE) (ENABLE ? VAL | 0x06 : VAL & 0xf9)//设置镜像
#define SC200AI_FETCH_FLIP(VAL, ENABLE) (ENABLE ? VAL | 0x60 : VAL & 0x9f)//设置翻转
- Spiegelung mit v4l2-ctl einstellen
// /dev/v4l-subdev2节点对应 Sensor ⼦设备节点。参考5.4 章节
v4l2-ctl --set-ctrl=horizontal_flip=1 -d /dev/v4l-subdev2 # 启⽤⽔平镜像
v4l2-ctl --set-ctrl=horizontal_flip=0 -d /dev/v4l-subdev2 # 禁⽤⽔平镜像
v4l2-ctl --set-ctrl=vertical_flip=1 -d /dev/v4l-subdev2 # 启⽤垂直翻转
v4l2-ctl --set-ctrl=vertical_flip=0 -d /dev/v4l-subdev2 # 禁⽤垂直翻转
v4l2-ctl --set-ctrl=horizontal_flip=1 --set-ctrl=vertical_flip=1 -d /dev/v4l-subdev2
# 同时启⽤镜像和翻转
v4l2-ctl --set-ctrl=horizontal_flip=0 --set-ctrl=vertical_flip=0 -d /dev/v4l-subdev2#
同时禁⽤镜像和翻转
3.2 Treiberframework
Der Sensor kommuniziert über I2C mit dem Host. Sein Treiber ist ein I2C-Gerätetreiber und verwendet V4L2 subdev zur Interaktion mit dem Host-Treiber.
3.2.1 Datentypen
3.2.1.1 struct i2c_driver
Beschreibung: I2C-Gerätetreiberinformationen. Definition:
struct i2c_driver {
...
/* Standard driver model interfaces */
int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *client);
...
struct device_driver driver;
const struct i2c_device_id *id_table;
...
};
Wichtige Mitglieder:
| Mitglied | Datentyp | Beschreibung |
|---|---|---|
| probe | int (*)(struct i2c_client *) | Geräteerkennung; wird aufgerufen, wenn Treiber und Gerät übereinstimmen |
| remove | void (*)(struct i2c_client *) | Bereinigung beim Entfernen des Geräts |
| driver | struct device_driver | Kerntreiberstruktur; .probe wird aufgerufen, wenn compatible in of_match_table mit compatible in der DTS-Datei übereinstimmt |
| id_table | const struct i2c_device_id * | Geräteabgleichstabelle; verwendet, wenn der Kernel nicht über of_match_table und DTS-registrierte Geräte abgleicht |
Beispiel:
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id sc200ai_of_match[] = {
{ .compatible = "smartsens,sc200ai" },
{},
};
MODULE_DEVICE_TABLE(of, sc200ai_of_match);
#endif
static const struct i2c_device_id sc200ai_match_id[] = {
{ "smartsens,sc200ai", 0 },
{ },
};
static struct i2c_driver sc200ai_i2c_driver = {
.driver = {
.name = SC200AI_NAME,
.pm = &sc200ai_pm_ops,
.of_match_table = of_match_ptr(sc200ai_of_match),
},
.probe = &sc200ai_probe,
.remove = &sc200ai_remove,
.id_table = sc200ai_match_id,
};
static int __init sensor_mod_init(void)
{
return i2c_add_driver(&sc200ai_i2c_driver);
}
static void __exit sensor_mod_exit(void)
{
i2c_del_driver(&sc200ai_i2c_driver);
}
3.2.1.2 struct v4l2_subdev_ops
Beschreibung: struct v4l2_subdev_ops ist die zentrale V4L2-Untergeräte-Operationsstruktur für Schnittstellen von Sensoren, ISPs und Decodern. Definition:
struct v4l2_subdev_ops {
const struct v4l2_subdev_core_ops *core;
const struct v4l2_subdev_video_ops *video;
const struct v4l2_subdev_pad_ops *pad;
...
};
Wichtige Mitglieder:
| Mitgliedstyp | Struktur | Funktion | Hardware |
|---|---|---|---|
| Kernoperationen | const struct v4l2_subdev_core_ops *core | Grundsteuerung: Versorgung, Interrupts, Protokolle usw. | Alle Untergeräte |
| Videostreamsteuerung | const struct v4l2_subdev_video_ops *video | Streamparameter: Bildrate, Format, HDR usw. | Sensor/ISP/Encoder |
| Pad-Steuerung | const struct v4l2_subdev_pad_ops *pad | Pixelformat, Auflösung, Zuschnitt (entscheidend) | Sensor/ISP/MIPI-CSI-Empfänger |
Beispiel:
static const struct v4l2_subdev_ops sc200ai_subdev_ops = {
.core = &sc200ai_core_ops,
.video = &sc200ai_video_ops,
.pad = &sc200ai_pad_ops,
};
3.2.1.3 struct v4l2_subdev_core_ops
Beschreibung: Operationen für Kernsteuerfunktionen eines V4L2-Untergerätetreibers. Definition:
struct v4l2_subdev_core_ops {
...
long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
#ifdef CONFIG_COMPAT
long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd,
unsigned long arg);
#endif
int (*s_power)(struct v4l2_subdev *sd, int on);
...
};
Wichtige Mitglieder:
| Mitgliedsfunktion | Prototyp | Funktion | Typische RK-Sensor-Implementierung |
|---|---|---|---|
| s_power | int (*)(struct v4l2_subdev *sd, int on) | Versorgungszustand: Gerät ein-/ausschalten | PWDN-/RESET-Pegelfolgen und PMIC-Versorgungszeitfolge steuern: on=1 einschalten, on=0 ausschalten |
| compat_ioctl32 | long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg) | Private Funktionen für 32-Bit-Anwendungen auf einem 64-Bit-Kernel; Datenübertragung vom/zum Userspace behandeln | |
| ioctl | int (*)(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | Private benutzerdefinierte Befehle, keine Standard-V4L2-Befehle | Spezifische Funktionen implementieren und System-ioctl-Aufrufe beantworten |
Beispiel:
static const struct v4l2_subdev_core_ops sc200ai_core_ops = {
.s_power = sc200ai_s_power,
.ioctl = sc200ai_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl32 = sc200ai_compat_ioctl32,
#endif
};c
Folgende private ioctl-Befehle fragen Modulinformationen ab und lesen/konfigurieren OTP-Informationen.
| Privater ioctl | Beschreibung |
|---|---|
| RKMODULE_GET_MODULE_INFO | Modulinformationen abfragen |
| PREISP_CMD_SET_HDRAE_EXP | HDR-Belichtung setzen |
| RKMODULE_SET_HDR_CFG | HDR-Modus setzen; normal/linear und HDR wechseln. Treiber muss beide Konfigurationen unterstützen |
| RKMODULE_GET_HDR_CFG | Aktuellen HDR-Modus abfragen |
| RKMODULE_SET_CONVERSION_GAIN | Linearen Conversion Gain setzen, etwa imx347/os04a10; bei fehlender Sensorunterstützung optional |
3.2.1.4 struct v4l2_subdev_video_ops
Beschreibung: Videogeräte-Steuerschnittstelle. Definition:
struct v4l2_subdev_video_ops {
...
int (*s_stream)(struct v4l2_subdev *sd, int enable);
int (*g_frame_interval)(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval);
int (*s_frame_interval)(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval);
...
};
Wichtige Mitglieder:
| Mitglied | Beschreibung |
|---|---|
| .g_frame_interval | Callback für VIDIOC_SUBDEV_G_FRAME_INTERVAL ioctl |
| .s_stream | Zentrale Schnittstelle zum Video-Start/Stopp |
| .s_frame_interval | Sensorbildrate/-intervall dynamisch ändern; zentraler Anpassungscallback |
Beispiel:
static const struct v4l2_subdev_video_ops sc200ai_video_ops = {
.s_stream = sc200ai_s_stream,
.g_frame_interval = sc200ai_g_frame_interval,
.s_frame_interval = sc200ai_s_frame_interval,
};
3.2.1.5 struct v4l2_subdev_pad_ops
Beschreibung: Rückrufe für Pixelformataushandlung, Zuschnitt, Skalierung und Bildlayout. In RK-Sensortreibern zentrale Schnittstelle zur Pipeline Sensor → ISP → Speicher. Definition:
struct v4l2_subdev_pad_ops {
...
int (*enum_mbus_code)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code);
int (*enum_frame_size)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse);
int (*enum_frame_interval)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_interval_enum *fie);
int (*get_fmt)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *format);
int (*set_fmt)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *format);
int (*get_selection)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel);
int (*set_selection)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel);
int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*dv_timings_cap)(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap);
int (*enum_dv_timings)(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings);
...
int (*get_mbus_config)(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_config *config);
int (*set_mbus_config)(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_config *config);
};
Wichtige Mitglieder:
| Mitglied | Beschreibung |
|---|---|
| enum_mbus_code | Medienbus-Pixelformate aufzählen; Sensor-RAW/YUV melden, z. B. MEDIA_BUS_FMT_SRGGB10_1X10. |
| get_fmt | Aktuelle Auflösung/Pixelformat, z. B. 1920x1080@SRGGB10. |
| set_fmt | Auflösung/Pixelformat setzen; wichtigste Funktion. Etwa 1920x1080 und NV12 konfigurieren; beeinflusst MIPI. |
| enum_frame_size | Auflösungen eines Pixelformats, etwa 640x480/1280x720 für UYVY. |
| enum_frame_interval | Bildraten für Format/Auflösung aufzählen; aktuelle Modusauflösungen/-raten melden. |
| get_selection | Zuschnitt-/Skalierregionen (Lese-/Schreibbereich, Ausgabegröße); Digitalzoom oder kleiner Stromsparbereich. |
| set_selection | Zuschnitt-/Skalierbereiche setzen;1080p-Vorschau verwenden. |
| get_edid/set_edid | EDID behandeln; HDMI-Empfänger, von Sensortreibern meist ignoriert. |
| dv_timings_cap | Unterstützte digitale Videotimingstandards; nur HDMITX/RX. |
| enum_dv_timings | Digitale Videotimings aufzählen; nur HDMITX/RX. |
| get_mbus_config | Medienbuskonfiguration, etwa MIPI D-PHY; Lane-Zahl V4L2_MBUS_CSI2_4LANE und Taktmodus V4L2_MBUS_CSI2_CONTINUOUS_CLOCK melden. |
| set_mbus_config | Buskonfiguration setzen; MIPI dynamisch ändern, z. B.2-lane/4-lane. |
Beispiel:
static const struct v4l2_subdev_pad_ops sc200ai_pad_ops = {
.enum_mbus_code = sc200ai_enum_mbus_code,
.enum_frame_size = sc200ai_enum_frame_sizes,
.enum_frame_interval = sc200ai_enum_frame_interval,
.get_fmt = sc200ai_get_fmt,
.set_fmt = sc200ai_set_fmt,
.get_mbus_config = sc200ai_g_mbus_config,
};
3.2.1.6 struct v4l2_ctrl_ops
Beschreibung: struct v4l2_ctrl_ops ist der Kernoperationssatz des V4L2-Steuerframeworks für dynamische Belichtung, Verstärkung, Weißabgleich und weitere Sensorparameter. Auf Rockchip standardisiert er Anwendungskonfigurationen und verbindet Userspace-Steuerung mit Hardwareregistern. Definition:
struct v4l2_ctrl_ops {
...
int (*s_ctrl)(struct v4l2_ctrl *ctrl);
};
Wichtige Mitglieder:
| Mitglied | Funktion | Typische Rockchip-Implementierung |
|---|---|---|
| s_ctrl | Steuerwert setzen (wichtigste Funktion) | Userspace-Werte in Register schreiben, etwa Belichtung/Verstärkung |
Beispiel:
static int sc200ai_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct sc200ai *sc200ai = container_of(ctrl->handler,
struct sc200ai, ctrl_handler);
struct i2c_client *client = sc200ai->client;
...
if (!pm_runtime_get_if_in_use(&client->dev))
return 0;
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
dev_dbg(&client->dev, "set exposure value 0x%x\n", ctrl->val);
...
break;
case V4L2_CID_ANALOGUE_GAIN:
dev_dbg(&client->dev, "set gain value 0x%x\n", ctrl->val);
...
break;
case V4L2_CID_VBLANK:
dev_dbg(&client->dev, "set blank value 0x%x\n", ctrl->val);
...
break;
case V4L2_CID_TEST_PATTERN:
...
break;
case V4L2_CID_HFLIP:
...
break;
case V4L2_CID_VFLIP:
...
break;
default:
dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
__func__, ctrl->id, ctrl->val);
break;
}
pm_runtime_put(&client->dev);
return ret;
}
static const struct v4l2_ctrl_ops sc200ai_ctrl_ops = {
.s_ctrl = sc200ai_set_ctrl,
};
3.2.2 APIs
3.2.2.1 xxxx_set_fmt
Beschreibung: Sensorausgabeformat setzen. Ein Treiber kann mehrere Auflösungen unterstützen; set_fmt übergibt die gewünschte, der Treiber sucht die beste Übereinstimmung. Linear/HDR wird über einen privaten ioctl-Befehl statt dieser Funktion umgeschaltet. Beide Modi müssen dieselbe Auflösung besitzen. Syntax:
static int xxxx_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *fmt)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| *cfg | Zeiger auf subdev pad information | Eingabe |
| *fmt | Zeiger auf Pad-level media bus format | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
Hinweis: Kernel 6.1 ersetzt struct v4l2_subdev_pad_config *cfg durch struct v4l2_subdev_state *sd_state.
3.2.2.2 xxxx_get_fmt
Beschreibung: aktuelles Sensorausgabeformat abfragen. struct xxx_mode kann mehrere Auflösungen enthalten; Initialisierung oder set_fmt wählt eine aus. get_fmt bestätigt die aktuelle Konfiguration. Vor RK3588 meldet fmt->reserved[0] zusätzlich den virtuellen Kanal, der damit statt des Standardwerts angegeben werden kann. RK3588 und neuer verwenden ioctl RKMODULE_GET_CHANNEL_INFO. Syntax:
static int xxxx_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *fmt)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| *cfg | Zeiger auf subdev pad information | Eingabe |
| *fmt | Zeiger auf Pad-level media bus format | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
Hinweis: Kernel 6.1 ersetzt struct v4l2_subdev_pad_config *cfg durch struct v4l2_subdev_state *sd_state.
3.2.2.3 xxxx_enum_mbus_code
Beschreibung: Sensorausgabe-Busformate aufzählen. Eine statische struct xxx_mode-Variable enthält unterstützte Auflösungen; die Funktion liefert deren Busformat als Aufzählungswert. Syntax:
static int xxxx_enum_m bus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| *cfg | Zeiger auf subdev pad information | Eingabe |
| *code | Zeiger auf media bus format enumeration | Ausgabe c (Quellenschreibweise) |
Rückgabewerte:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| *cfg | Zeiger auf subdev pad information | Eingabe |
| *code | Zeiger auf media bus format enumeration | Ausgabe |
Hinweis: Kernel 6.1 ersetzt struct v4l2_subdev_pad_config *cfg durch struct v4l2_subdev_state *sd_state.
3.2.2.4 xxxx_enum_frame_sizes
Beschreibung: Sensorausgabegrößen aufzählen. Eine statische struct xxx_mode-Variable enthält unterstützte Auflösungen; die Funktion liefert die entsprechenden Aufzählungswerte. Syntax:
static int xxxx_enum_frame_sizes(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| *cfg | Zeiger auf subdev pad information | Eingabe |
| *fse | Zeiger auf media bus frame size | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
Hinweis: Kernel 6.1 ersetzt struct v4l2_subdev_pad_config *cfg durch struct v4l2_subdev_state *sd_state.
3.2.2.5 xxxx_g_frame_interval
Beschreibung: Sensorausgabe-Bildintervall abfragen. Die statische struct xxx_mode-Konfiguration nennt die maximale Bildrate. Der Treiber senkt sie durch erhöhtes vblank. Für die tatsächliche Rate Standard- und aktuelles vblank umrechnen und das aktualisierte Intervall an die Anwendung liefern. Syntax:
static int xxxx_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| *fi | Zeiger auf pad-level frame rate | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
3.2.2.6 xxxx_s_stream
Beschreibung: Stream-Ein-/Ausgabe konfigurieren. on wählt start_stream oder stop_stream. start_stream programmiert das Initialisierungsregisterarray, initialisiert Belichtungsparameter und startet den Datenstrom; stop_stream schreibt Stream-Off-Register. Syntax:
static int xxxx_s_stream(struct v4l2_subdev *sd, int on)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Zeiger auf v4l2-subdev-Struktur | Eingabe |
| on | 1: Stream starten; 0: stoppen | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
3.2.2.7 xxxx_runtime_resume
Beschreibung: Sensor-Einschaltcallback. So können andere Treiberteile oder übergeordnete Treiber den Sensor mit pm_runtime_get_sync einschalten. Syntax:
static int xxxx_runtime_resume(struct device *dev)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Zeiger auf device-Struktur | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
3.2.2.8 xxxx_runtime_suspend
Beschreibung: Sensor-Ausschaltcallback. Andere Treiberteile oder übergeordnete Treiber schalten über pm_runtime_put aus. Syntax:
static int xxxx_runtime_suspend(struct device *dev)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Zeiger auf device-Struktur | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
3.2.2.9 xxxx_set_ctrl
Beschreibung: V4L2-Steuerwerte setzen. Diesen Callback für Steuerbefehle registrieren; Anwendungsänderungen konfigurieren darüber den Sensor. Controls nach Abschnitt 3.2.1.6, struct v4l2_ctrl_ops, implementieren. Syntax:
static int xxxx_set_ctrl(struct v4l2_ctrl *ctrl)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *ctrl | Zeiger auf v4l2_ctrl-Struktur | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
3.2.2.10 xxx_enum_frame_interval
Beschreibung: unterstützte Bildintervalle der Auflösungen aus der statischen struct xxx_mode-Variable aufzählen. Meist begrenzter Nutzen; die eigentliche Bildratenanpassung erfolgt weiterhin über vblank. Syntax:
static int xxxx_enum_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_interval_enum *fie)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Untergeräteinstanz | Eingabe |
| *cfg | Pad-Konfiguration | Eingabe |
| *fie | Bildintervallparameter | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
Hinweis: Kernel 6.1 ersetzt struct v4l2_subdev_pad_config *cfg durch struct v4l2_subdev_state *sd_state.
3.2.2.11 xxxx_g_mbus_config
Beschreibung: Buskonfiguration abfragen. Busse umfassen parallel, MIPI und LVDS; parallel BT601/BT656/BT1120, MIPI DPHY/CPHY. Der Controller bestimmt anhand aktueller Sensorbusparameter den Aufnahmemodus. Bei mehreren MIPI-Modi die Parameter des aktiven Modus melden. Syntax:
static int xxxx_g_m bus_config(struct v4l2_subdev *sd,
struct v4l2_m bus_config *config)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *config | Buskonfiguration | Ausgabe c (Quellenschreibweise) |
Rückgabewerte:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *config | Buskonfiguration | Ausgabe |
3.2.2.12 xxxx_get_selection
Beschreibung: Zuschnitt konfigurieren. ISP-Eingangsbreite muss auf 16, Höhe auf 8 ausgerichtet sein. Nicht ausgerichtete oder nicht standardmäßige Sensorausgaben vor dem ISP mit dieser Funktion zuschneiden. Syntax:
static int xxxx_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Untergeräteinstanz | Eingabe |
| *cfg | Pad-Konfiguration | Eingabe |
| *sel | Zuschnittparameter | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
Hinweis: Kernel 6.1 ersetzt struct v4l2_subdev_pad_config *cfg durch struct v4l2_subdev_state *sd_state.
3.2.2.13 xxxx_ioctl
Beschreibung: private ioctl-Befehle implementieren. Syntax:
static long xxxx_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *sd | Untergeräteinstanz | Eingabe |
| cmd | Privater Befehlswert (Quelle: Namenswert) | Eingabe |
| * arg | Übergebene Parameter | Ein-/Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 |
3.3 Ablauf der Treiberportierung
3.3.1 Standard-I2C-Untergerätetreiber
-
Diese struct i2c_driver-Mitglieder implementieren: struct driver.name, struct driver.pm, struct driver.of_match_table, probe und remove. Unterschiedliche Rückgabewerte zwischen Kernel 5.10 und 6.1 beachten.
-
probe: CIS-Ressourcen vor allem aus DTS ermitteln. Private RK-Ressourcen heißen rockchip,camera-module-xxx und werden an Userspace-camera_engine zur Auswahl passender IQ-Parameter übergeben. RK-Referenztreiber definieren gewöhnlich folgende CIS-Ressourcen:
| Mitglied | Beschreibung |
|---|---|
| CIS reference clock | Bei unabhängigem Quarz keine Ressource nötig. RK-Referenzdesigns verwenden meist AP-Ausgangstakt xvclk, der angefordert werden muss. |
| CIS control GPIO | Beispielsweise Resst (Quellenschreibweise) und Powerdown. |
| CIS power resources | Zur Hardware passende Software-Versorgungsressourcen anfordern, etwa gpio/regulator. |
Nach der Ressourcenabfrage wird das Lesen der CIS-ID zur Hardwareprüfung empfohlen, ist aber optional. CIS-V4L2-Gerät und Media-Entity initialisieren. Für das Untergerät v4l2_i2c_subdev_init verwenden. RK benötigt einen eigenen subdev-Geräteknoten für rk_aiq-Belichtungssteuerung. Media-Entity mit media_entity_init initialisieren.
3.3.2 V4L2-Untergerätetreiber
Im Wesentlichen diese drei Mitglieder implementieren:
struct v4l2_subdev_core_ops
struct v4l2_subdev_video_ops
struct v4l2_subdev_pad_ops
- Callbacks gemäß struct v4l2_subdev_core_ops implementieren. s_power schaltet ein/aus. Bei langen Registerarrays gemeinsame Register nach dem Einschalten schreiben; s_stream setzt nur auflösungsspezifische Register für schnelleres Umschalten. Außerdem .compat_ioctl32 und .ioctl implementieren; ioctl stellt private RK-Steuerung bereit:
| Mitglied | Beschreibung |
|---|---|
| RKMODULE_GET_MODULE_INFO | DTS-Modulinformationen wie Name zur Zuordnung an camera_engine übergeben. |
| RKMODULE_AWB_CFG | Bei aktivem OTP übergibt camera_engine typische AWB-Kalibrierung. CIS vergleicht aktuelle Modulkalibrierung und berechnet R/B Gain für MWB. |
| RKMODULE_LSC_CFG | Bei OTP aktiviert camera_engine die LSC-Kalibrierungsanwendung. |
| PREISP_CMD_SET_HDRAE_EXP | HDR-Belichtung |
| RKMODULE_SET_HDR_CFG | HDR/normal umschalten; Treiber unterstützt beide Konfigurationen. |
| RKMODULE_GET_HDR_CFG | Aktuellen HDR-Modus abfragen |
| RKMODULE_SET_CONVERSION_GAIN | Linearen Conversion Gain setzen, etwa imx347/os04a10. Hoher Conversion Gain verbessert Schwachlicht-SNR. Ohne Unterstützung optional. |
| RKMODULE_SET_QUICK_STREAM | Stream-On/Off-Register für Fehlerreset, synchronen Mehrkamerastart (siehe Mechanismus), Schnellstart und AOV setzen. |
| RKMODULE_GET_CHANNEL_INFO | Kanalinformationen abfragen. Standard vicap id0–id3 entspricht vc0–vc3; für SPD/EBD anpassbar. Vor RK3588 weiterhin get_fmt. |
| RKMODULE_GET_SYNC_MODE, RKMODULE_SET_SYNC_MODE | Synchronisationsmodus lesen/setzen; siehe Mehrkamera-Synchronisation. |
- Nach struct v4l2_subdev_core_ops (Quellenverweis) folgende Callbacks implementieren:
| Mitglied | Beschreibung |
|---|---|
| .s_stream | Stream starten/stoppen. Bei kontinuierlichem MIPI CLK hier starten; früherer Start verhindert MIPI-LP-Erkennung. |
| .g_frame_interval | Bildintervall/-rate abfragen |
| .g_mbus_config | Buskonfiguration abfragen. Bei mehreren Lane-Zahlen/HDR MIPI-Werte des aktiven Modus melden. |
- Nach struct v4l2_subdev_pad_ops folgende Callbacks implementieren:
| Mitglied | Beschreibung |
|---|---|
| .enum_mbus_code | Formate aufzählen; siehe xxxx_enum_mbus_code. |
| .enum_frame_size | Auflösungen aufzählen; siehe xxxx_enum_frame_sizes. |
| .get_fmt | Erforderlich: RKISP liest CIS-Format. MEDIA_BUS_FMT für Bayer raw/SoC YUV/BW raw, struct v4l2_mbus_framefmt für Field-Ausgabe; xxxx_get_fmt. |
| .set_fmt | Erforderlich: CIS-Format/Auflösung setzen; xxxx_set_fmt. |
| .enum_frame_interval | Bildintervalle einschließlich Auflösung aufzählen; xxx_enum_frame_interval. |
| .get_selection | Zuschnitt: ISP-Breite auf16, Höhe auf8 ausrichten; xxxx_get_selection. |
- Nach struct v4l2_ctrl_ops folgende Callbacks implementieren:
| Mitglied | Beschreibung |
|---|---|
| .s_ctrl | RKISP-Treiber und camera_engine steuern CIS-Belichtung mit verschiedenen Befehlen. |
Folgende IDs liefern Informationen und werden als standard integer menu controls implementiert:
| Mitglied | Beschreibung |
|---|---|
| V4L2_CID_LINK_FREQ | Standarddefinition in CIS-V4L2-Controls; RKISP ermittelt damit MIPI-Frequenz. |
| V4L2_CID_PIXEL_RATE | MIPI: pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample |
| V4L2_CID_HBLANK | Siehe CIS-V4L2-Controls-Standarddefinition. |
| V4L2_CID_VBLANK | Siehe CIS-V4L2-Controls-Standarddefinition. |
RK camera_engine erhält über diese Befehle Informationen für die Belichtungsberechnung. Formeln:
line_time = HTS / PIXEL_RATE;
PIXEL_RATE = HTS * VTS * FPS
HTS = sensor_width_out + HBLANK;
VTS = sensor_height_out + VBLANK;
Über folgende Steuer-IDs konfiguriert RK camera_engine den CIS:
| Mitglied | Beschreibung |
|---|---|
| V4L2_CID_VBLANK | VBLANK und damit Bildrate/maximale Belichtungszeit ändern. |
| V4L2_CID_EXPOSURE | Belichtungszeit in Belichtungszeilen. |
| V4L2_CID_ANALOGUE_GAIN | Belichtungsverstärkung; tatsächlich total gain = analog gain*digital gain, in Registereinheiten. |
| V4L2_CID_HFLIP | Horizontal spiegeln; ISP besitzt keine Spiegelung, Sensor verwenden. |
| V4L2_CID_VFLIP | Vertikal spiegeln; ISP besitzt keine Spiegelung, Sensor verwenden. |
| V4L2_CID_TEST_PATTERN | Optionales Testmuster zur Fehlersuche nach Bedarf. |
- HDR-Anforderungen. Linear verwenden Belichtung/Verstärkung Standard-V4L2-Controls. HDR übergibt Parameter über PREISP_CMD_SET_HDRAE_EXP; V4L2_CID_EXPOSURE und V4L2_CID_ANALOGUE_GAIN werden nicht verwendet. Der private Befehl muss Parameter zwischenspeichern. Nach dem Initialisierungsarray in start_stream die Anfangsbelichtung erneut schreiben, um Standardwerte zu überschreiben; so passt das erste Bild zur Belichtung und AE konvergiert schnell. Stream-Enable-Register nicht ins Array aufnehmen, sondern vor Rückkehr von start_stream setzen. HDR-Sensoren müssen RKMODULE_SET_HDR_CFG/RKMODULE_GET_HDR_CFG für HDR/LINEAR-Austausch und Moduswechsel implementieren.
3.4 Makefile ändern
Neuen Sensor in kernel/drivers/media/i2c/Makefile zur Kompilierung hinzufügen. SC200AI-Beispiel:
......
obj-$(CONFIG_VIDEO_SC200AI) += sc200ai.o
......
Einträge nach Hersteller gruppieren und Sensornamen alphabetisch sortieren.
3.5 Kconfig ändern
Konfiguration und Beschreibung des neuen Sensors in kernel/drivers/media/i2c/Kconfig hinzufügen. SC200AI-Beispiel:
config VIDEO_SC200AI
tristate "SmartSens SC200AI sensor support"
depends on I2C && VIDEO_V4L2
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
select V4L2_FWNODE
help
This is a Video4Linux2 sensor driver for the SmartSens
SC200AI camera.
Einträge nach Hersteller gruppieren und Sensornamen alphabetisch sortieren.
4. Schnellstart
4.1 Konzept
Sensor-Schnellstart minimiert Einschalten, Initialisierung und Zeit bis zum gültigen Bild für schnellen Start, geringe Latenz und Echtzeit. Embedded-, Verbraucher-, Fahrzeug- und Industrieanwendungen benötigen sofortige Aufnahme, Ausgabe in <100ms/300ms, schnelles Aufwachen, Mehrkamera-Umschaltung/Synchronstart oder Echtzeitkommunikation/Überwachung. Herkömmlicher Start kann Hunderte Millisekunden oder über eine Sekunde dauern, einschließlich:
-
Einschalten
-
Interne PLL-/Taktstabilisierung
-
Registerinitialisierung
-
Stabilisierung analoger Schaltungen
-
Aufbau des Zeilen-/Bildtimings
-
Erstes gültiges Bild. Schnellstart optimiert interne Abläufe, überspringt unnötige Initialisierung oder konfiguriert wichtige Register vorab. Vergleich typischer Startzeiten:
| Startmodus | Typische Zeit bis Bild | Anwendung |
|---|---|---|
| Normal Boot | 300ms ~ 1000ms | Ohne strenge Startzeitforderung |
| Fast Boot | 10ms ~ 200ms | Schnelle Aufnahme, Echtzeitvorschau, geringe Latenz |
| Low-power Wakeup aus Standby | 10ms ~ 50ms | Schnelle Energiespar-Rückkehr, besser mit Fast Boot |
RK RV1103, RV1103B/RV1106B, RV1126B und verwandte Hosts besitzen einen leistungsfähigen RISC-V-MCU-Kern. Teile von ISP-AE/AWB laufen dort und unterstützen ARM-Kamera-/ISP-Initialisierung und schnelle Konvergenz. Während Linux startet, konvergiert der MCU parallel AE und bestimmt Tag-/Nachtmodus. Bei Registrierung des Kernel-ISP-Treibers verwendet der Sensor MCU-Belichtung und Bildparameter für ein erstes gültiges, weitgehend konvergiertes Bild. Grundablauf:

MCU-gestützte schnelle Bildkonvergenz:

Stream-Ausgabe in der ARM-Phase:

4.2 Treiberänderungen
4.2.1 Kerneltreiber
- Diese beiden Header einbinden:
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
#include "cam-tb-setup.h"
- is_thunderboot zur Sensorstruktur hinzufügen, um Schnellstart zu kennzeichnen.
struct sc200ai {
......
bool is_thunderboot;
......
};
In probe CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP prüfen. Ist es im Kernel aktiviert, ist is_thunderboot true.
sc200ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
- Stream-Start/Stopp-Schnittstellen
static int __sc200ai_start_stream(struct sc200ai *sc200ai)
{
int ret = 0;
......
if (!sc200ai->is_thunderboot) { //⾮快启,写⼊完整寄存器配置
ret = sc200ai_write_array(sc200ai->client, sc200ai->cur_mode->reg_list);
if (ret)
return ret;
......
}
if (sc200ai->sync_mode == NO_SYNC_MODE)//否则,配置起流
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
return ret;
}
static int __sc200ai_stop_stream(struct sc200ai *sc200ai)
{
int ret = 0;
sc200ai->has_init_exp = false;
if (sc200ai->is_thunderboot) {
sc200ai->is_first_streamoff = true;
pm_runtime_put(&sc200ai->client->dev);
}
......
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
return ret;
}
4.2.2 MCU-Treiber
Siehe Kameratreiber-Portierung.
4.3 MCU-Schnellstart konfigurieren
4.3.1 Treiberframework
Die folgenden Abschnitte zeigen RK-MCU-Sensortreiberentwicklung anhand von SmartSens SC450AI.
4.3.1.1 Datentypen
4.3.1.1.1 struct rk_camera_ops
Beschreibung: struct rk_camera_ops definiert Kamerageräte-Operationen. Definition:
struct rk_camera_ops {
ret_err_t (*init)(struct rk_camera_device *dev); // 初始化相机设备
ret_err_t (*open)(struct rk_camera_device *dev, rt_uint16_t oflag); // 打开相机设备
ret_err_t (*close)(struct rk_camera_device *dev); // 关闭相机设备
ret_err_t (*control)(struct rk_camera_device *dev, int cmd, void *args); // 控制相机设备
};
Mitglieder:
| Mitglied | Beschreibung |
|---|---|
| init | Gerät initialisieren |
| open | Gerät öffnen |
| close | Gerät schließen |
| control | Gerät steuern |
Beispiel:
struct rk_camera_ops rk_sc450ai_ops =
{
rk_sc450ai_init,
rk_sc450ai_open,
NULL,
rk_sc450ai_control
};
4.3.1.1.2 struct xxx_mode
Beschreibung: Informationen unterstützter Sensormodi; Mitglieder nach Bedarf ergänzen. Definition:
struct xxxx_mode
{
struct v4l2_fract max_fps;
uint16_t bus_fmt;
uint16_t width;
uint16_t height;
uint16_t hts_def;
uint16_t vts_def;
uint16_t exp_def;
uint32_t xvclk;
uint32_t link_freq;
#ifndef REG_LIST_CONVERSION_DEBUG
const uint8_t *reg_list;
#else
const struct sc450ai_sensor_reg *reg_list;
#endif
const int reg_list_size;
uint8_t hdr_mode;
} __attribute__((__packed__));
Mitglieder:
| Mitglied | Beschreibung |
|---|---|
| .max_fps | Bildrate: denominator/numerator = fps |
| .bus_fmt | Sensorausgabeformat |
| .width | Aktive Breite; muss aktueller Sensorausgabe entsprechen. |
| .height | Aktive Höhe; muss aktueller Sensorausgabe entsprechen. |
| .hts_def | Standard-HTS = aktive Breite + HBLANK |
| .vts_def | Standard-VTS = aktive Höhe + VBLANK |
| .exp_def | Standardbelichtungszeit |
| .xvclk | Externer Sensortakt/MCLK |
| .link_freq | MIPI_DPHY-Abtastfrequenz in MHz, halbe MIPI-Rate |
| *reg_list | Registerliste |
| .reg_list_size | Registerarraygröße |
| .hdr_mode | Linearer, Zwei-/Drei-Bild-HDR-Modus |
Beispiel:
static const struct sc450ai_mode supported_modes_4lane[] =
{
{
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
.width = 1344,
.height = 760,
.max_fps = {
.numerator = 10000,
.denominator = 1200000,
},
.exp_def = 0x80,
.hts_def = 0x03a8,
.vts_def = 0x030c,
.xvclk = 27000000,
.link_freq = 360000000,
.reg_list = g_sc450ai_1344x760_4lane_120fps_reg_table,
.reg_list_size = ARRAY_SIZE(g_sc450ai_1344x760_4lane_120fps_reg_table),
.hdr_mode = NO_HDR,
},
{/* */},
}
4.3.1.1.3 struct xxx_dev
Beschreibung: zentrale Kameragerätestruktur mit Konfiguration, Status und Funktionszeigern. In rk_xxx_init konfiguriert. Definition:
struct xxx_dev
{
struct rk_camera_device parent;
char name[RK_CAMERA_DEVICE_NAME_SIZE];
uint8_t time_valid_delay;
uint8_t gain_valid_delay;
char i2c_name[RK_CAMERA_I2C_NAME_SIZE];
struct rt_i2c_bus_device *i2c_bus;
uint8_t i2c_addr;
uint8_t flip;
struct rt_mutex mutex_lock;
struct rk_camera_exp_val init_exp;
uint8_t modes_num;
const struct sc450ai_mode *supported_modes;
const struct sc450ai_mode *cur_mode;
const struct sc450ai_mode *pdst_mode;
struct sc450ai_mode dst_mode;
bool has_init_exp;
bool streaming;
};
Mitglieder:
| Mitglied | Beschreibung |
|---|---|
| parent | Kamera-Elterngerät |
| name[RK_CAMERA_DEVICE_NAME_SIZE] | Kameraname |
| time_valid_delay | Belichtungszeit wirkt in Bild N + time_valid_delay |
| gain_valid_delay | Verstärkung wirkt in Bild N + gain_valid_delay |
| i2c_name[RK_CAMERA_I2C_NAME_SIZE] | I2C-Busname |
| *i2c_bus | I2C-Busgerät |
| i2c_addr | I2C-Adresse |
| flip | Flip-/Mirror-Einstellung |
| mutex_lock | Mutex |
| init_exp | Anfangsbelichtung |
| modes_num | Zahl Initialisierungskonfigurationen |
| *supported_modes | Modusliste entsprechend Lane-Zahl //todo (Quelle) |
| *cur_mode | Aktuelle Modusparameter |
| *dst_mode | Zielmodusparameter |
| has_init_exp | Anfangsbelichtung gesetzt? |
| streaming | Stream aktiv? |
4.3.1.2 APIs
4.3.1.2.1 rk_xxx_control
Beschreibung: allgemeine Schnittstelle für Gerätesteuerbefehle von Anwendungen/ISP. Syntax:
ret_err_t rk_sc450ai_control(struct rk_camera_device *dev,
dt_cmd_t cmd,
void *args);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| cmd | Kamerasteuerbefehl | Eingabe |
| *args | Befehlsargumente | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
Beispiel:
ret_err_t rk_sc450ai_control(struct rk_camera_device *dev,
dt_cmd_t cmd,
void *args)
{
...
switch (cmd)
{
case RK_DEVICE_CTRL_DEVICE_INIT:
{
ret = rk_sc450ai_init(dev);
}
break;
...
default:
sc450ai_dbg("exit CMD %d\n", cmd);
break;
}
return ret;
}
4.3.1.2.2 rk_xxx_init
Beschreibung: Controller fragt Kamerabusparameter ab, um den Aufnahmemodus festzulegen. Syntax:
ret_err_t rk_xxx_init(struct rk_camera_device *dev);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.3 xxx_stream_on
Beschreibung: Kamera-Initialisierungsregister programmieren; RT_USING_CAM_STREAM_ON_LATE bestimmt frühe Stream-Aktivierung. Syntax:
static void xxx_stream_on(struct xxx_dev *dev);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.4 xxx_stream_off
Beschreibung: Kamerastream stoppen. Syntax:
static void xxx_stream_off(struct xxx_dev *dev);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.5 rk_xxx_get_expinf
Beschreibung: Belichtungsinformationen abfragen. Syntax:
static ret_err_t rk_xxx_get_expinf(struct xxx_dev *dev, struct rk_camera_exp_info *exp);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| *exp | Kamerabelichtungsparameter | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.6 rk_xxx_set_expval
Beschreibung: Belichtungszeit und Verstärkung setzen. Syntax:
static ret_err_t rk_xxx_set_expval(struct xxx_dev *dev, struct rk_camera_exp_val *exp);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| *exp | Kamerabelichtungsparameter | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.7 rk_xxx_set_vts
Beschreibung: Kamera-VTS setzen. Syntax:
static ret_err_t rk_xxx_set_vts(struct xxx_dev *dev, uint32_t dst_vts);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| dst_vts | Ziel-VTS | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.8 rk_xxx_get_intput_fmt
Beschreibung: aktuelles Kameraausgabeformat abfragen. struct xxx_mode kann mehrere Auflösungen enthalten, eine wird initial ausgewählt. Nach set_intput_fmt bestätigt get_intput_fmt das aktive Format. Syntax:
static ret_err_t rk_xxx_get_intput_fmt(struct xxx_dev *dev, struct rk_camera_mbus_framefmt
*mbus_fmt);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| *mbus_fmt | Kameraausgabeformat | Ausgabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.9 rk_xxx_set_intput_fmt
Beschreibung: Kameraausgabeformat und Controller-Aufnahmeparameter setzen. Syntax:
static ret_err_t rk_xxx_set_intput_fmt(struct xxx_dev *dev, struct rk_camera_mbus_framefmt
*mbus_fmt);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| *mbus_fmt | Kameraausgabeformat | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.10 rk_xxx_match_dst_config
Beschreibung: supported_modes nach Zielauflösung/-format durchsuchen. Bei reduzierter Bildrate Ziel-VTS anpassen. Syntax:
static ret_err_t rk_xxx_match_dst_config(struct xxx_dev *dev, struct rk_camera_dst_config
*dst_config);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| *dst_config | Zielausgabeformat | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.11 rk_xxx_set_flip_mirror
Beschreibung: Kamera-Flip/Mirror setzen. Syntax:
static ret_err_t rk_xxx_set_flip_mirror(struct xxx_dev *dev, uint32_t flip)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| flip | 0: keines; 1: nur Flip; 2: nur Mirror; 3: beide | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.12 xxx_stream_on_late
Beschreibung: Anfangsbelichtung, Mirror und Flip setzen und Kamerastream starten. Syntax:
static void xxx_stream_on_late(struct xxx_dev *dev);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.13 xxx_quick_stream
Beschreibung: Kamerastream ein-/ausschalten. Syntax:
static void xxx_quick_stream(struct xxx_dev *dev, int on);
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
| on | 1: Stream starten; 0: stoppen | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.1.2.14 rk_camera_xxx_init
Beschreibung: Sensor-I2C-Gerät gemäß Einschaltfolge im Datenblatt registrieren. Syntax:
int rk_xxx_check_sensor_id(struct xxx_dev *dev)
Parameter:
| Parameter | Beschreibung | Richtung |
|---|---|---|
| *dev | Kameragerätedeskriptor | Eingabe |
Rückgabewerte:
| Rückgabewert | Beschreibung |
|---|---|
| 0 | Erfolg |
| Nicht 0 | Fehler |
4.3.2 Kameratreiber portieren
Neuen Treiber auf ähnlich spezifiziertem Sensor in rt-thread/bsp/rockchip/camera/ oder ähnlichem Modell desselben Herstellers aufbauen.
4.3.2.1 Build-Optionen ergänzen
Folgende Ergänzungen in rt-thread/bsp/rockchip/common/drivers/Kconfig vornehmen.
@@ -506,6 +506,8 @@ menu "supported camera"
bool "Enable GC2053"
config RT_USING_F37
bool "Enable F37"
config RT_USING_SC230AI
bool "Enable SC230AI"
+ config RT_USING_SC450AI
+ bool "Enable SC450AI"
config RT_USING_SC850SL
bool "Enable SC850SL"
4.3.2.2 Registersequenz konvertieren
MCU-Schnellstarttreiber initialisieren über kontinuierliche I2C-Schreibvorgänge. Herstellersequenzen sind gewöhnlich nicht kontinuierlich und müssen per Skript ins Treiberformat konvertiert werden.
4.3.2.2.1 Konvertierungsschritte
-
Initialisierungssequenz nach <sdk>/sysdrv/source/mcu/project/scripts/camera_reg_convert/reg.txt formatieren.
-
Inhalt von <sdk>/sysdrv/source/mcu/project/scripts/camera_reg_convert/reg.txt durch die Sequenz ersetzen.
-
Mit diesem Befehl konvertieren:
cd <sdk>/sysdrv/source/mcu/project/scripts/camera_reg_convert/
python2 reg_conver.py
- Entsprechende Treiberregistersequenz durch das Ergebnis ersetzen. Beispiel:
/*
* Xclk 27Mhz
* max_framerate 30fps
* mipi_datarate per lane 720Mbps, 4lane
* full resolution
*/
static const uint8_t g_sc450ai_2688x1520_4lane_30fps_reg_table[] =
{
0x3, 0x01, 0x00, 0x00,
0x3, 0x36, 0xe9, 0x80,
0x3, 0x36, 0xf9, 0x80,
0x3, 0x30, 0x1c, 0x78,
0x3, 0x30, 0x1f, 0x01,
0x3, 0x30, 0x2e, 0x00,
0xa, 0x32, 0x08, 0x0a, 0x80, 0x05, 0xf0, 0x02, 0xee, 0x06, 0x18,
0x4, 0x32, 0x14, 0x11, 0x11,
0x8,
};
Kontinuierliches Format: Spalte 1 ist I2C-DATA-Bytezahl je Schreibvorgang, 2–3 Registeradresse, 4–n aufeinanderfolgende Registerwerte. Letzte Zeile: Gesamtzahl I2C-Schreibvorgänge. Stream nicht in der Sequenz aktivieren, sondern separat in xxx_stream_on_late.
4.3.2.3 Grundfunktionen
Alle rk_camera_ops-Funktionen einschließlich sämtlicher Controls in rk_xxx_control sowie rk_camera_xxx_init implementieren.
4.3.3 MCU-Boardkonfiguration
4.3.3.1 CIS (CMOS image sensor) registrieren
4.3.3.1.1 struct gpio_desc
Definition:
struct gpio_desc
{
uint32_t gpio_pin;
struct GPIO_REG *gpio_group;
};
4.3.3.1.2 camera_board_desc
Beschreibung: boardhardwarebezogene Sensorkonfiguration. Definition:
struct camera_board_desc
{
struct gpio_desc rst_gpio;
struct gpio_desc pwdn_gpio;
struct gpio_desc pwren_gpio;
eCLOCK_Name mclk_id;
uint32_t mclk_out_gate_id;
char isp_subdev_name[RK_CAMERA_DEVICE_NAME_SIZE];
char i2c_bus[RK_CAMERA_I2C_NAME_SIZE];
uint8_t i2c_addr;
uint8_t time_valid_delay;
uint8_t gain_valid_delay;
uint8_t mode_id;
uint32_t width;
uint32_t height;
uint32_t pixelcode;
uint32_t maxfps;
uint32_t lanes;
uint32_t hdr_mode;
uint32_t dst_width;
uint32_t dst_height;
uint32_t dst_pixelcode;
uint32_t dst_maxfps;
uint32_t dst_hdr_mode;
bool rst_active;
bool pwdn_active;
bool pwren_active;
};
Mitglieder:
| Mitglied | Beschreibung |
|---|---|
| rst_gpio | Hardware-Reset-Pin gemäß gpio_desc |
| pwdn_gpio | Stromspar-Pin gemäß gpio_desc |
| pwren_gpio | Einschalt-Pin gemäß gpio_desc |
| mclk_id | 0 wählt mclk0; 1 mclk1 |
| isp_subdev_name | ISP-Hauptsensor: RK_ISP_MAIN_SUBDEV_NAME; Assistenz: RK_ISP_ASSIST_SUBDEV_NAME |
| i2c_bus | Sensor-I2C-Bus wählen |
| i2c_addr | 7-Bit-Sensor-I2C-Adresse |
| time_valid_delay | Bilder bis Belichtungszeit wirkt |
| gain_valid_delay | Bilder bis Verstärkung wirkt |
| mode_id | Sensorauflösung gemäß camera.h |
| width | MCU-Kleinbildbreite |
| height | MCU-Kleinbildhöhe |
| pixelcode | MCU-Kleinbildformat |
| maxfps | Maximale FPS aller Kleinbild-Initialisierungskonfigurationen |
| lanes | Sensor-Lane-Zahl |
| hdr_mode | Kleinbild-HDR (NO_HDR: 0 HDR_X2: 5 HDR_X3: 6) |
| dst_width | MCU-Großbildbreite |
| dst_height | MCU-Großbildhöhe |
| dst_pixelcode | MCU-Großbildformat |
| dst_maxfps | Maximale FPS aller Großbild-Initialisierungskonfigurationen |
| dst_hdr_mode | Großbild-HDR (NO_HDR: 0 HDR_X2: 5 HDR_X3: 6) |
| rst_active | Aktiver Hardware-Reset-Pegel |
| pwdn_active | Aktiver Stromspar-Pegel |
| pwren_active | Aktiver Einschaltpegel |
4.3.3.1.3 cif_hw_config
data_lanes: Sensor-Lane-Anzahl. Verbindungen Sensor/csi_dphy/csi_host:
| Hauptkamera–DPHY-Verdrahtung | dphy1.enable | dphy2.enable | csi_host_0.enable | csi_host_1.enable |
|---|---|---|---|---|
| lane0 < - > MIPI_CSI_RX_D0N/P | 1 | 0 | 1 | 0 |
| lane1 < - > MIPI_CSI_RX_D1N/P | 1 | 0 | 1 | 0 |
| lane2 < - > MIPI_CSI_RX_D2N/P | 0 | 1 | 0 | 1 |
| lane3 < - > MIPI_CSI_RX_D3N/P | 0 | 1 | 0 | 1 |
4.3.3.1.4 Einzelkamera registrieren
Beispiel:
const struct camera_board_desc camera_sc450ai =
{
.i2c_addr = 0x30,
.rst_gpio =
{
.gpio_pin = GPIO_PIN_A7,
.gpio_group = GPIO4,
},
.pwdn_gpio =
{
.gpio_pin = GPIO_PIN_A2,
.gpio_group = GPIO4,
},
.time_valid_delay = 2,
.gain_valid_delay = 2,
.width = 1344,
.height = 760,
.maxfps = 120,
.lanes = 4,
.pixelcode = MEDIA_BUS_FMT_SBGGR10_1X10,
.hdr_mode = NO_HDR,
.dst_width = 2688,
.dst_height = 1520,
.dst_maxfps = 60,
.dst_pixelcode = MEDIA_BUS_FMT_SBGGR10_1X10,
.dst_hdr_mode = NO_HDR,
.isp_subdev_name = RK_ISP_MAIN_SUBDEV_NAME,
.i2c_bus = "i2c3",
.rst_active = 0,
.pwdn_active = 1,
.mclk_id = CLK_MIPI0_OUT2IO,
.mclk_out_gate_id = CLK_MIPI0_OUT2IO_GATE,
};
void cif_hw_config(void)
{
struct dphy_board_desc *csi2_dphy = (struct dphy_board_desc *)&csi2_dphy_board;
struct csi2_board_desc *csi_host_0 = (struct csi2_board_desc *)&csi2_host0_board;
struct vicap_board_desc *vicap = (struct vicap_board_desc *)&vicap_board;
csi2_dphy->enable = true;
csi2_dphy->csi2_dphy1.enable = true;
csi2_dphy->csi2_dphy1.csi_host_idx = 0;
csi2_dphy->csi2_dphy1.isp_subdev_name = RK_ISP_MAIN_SUBDEV_NAME;
csi_host_0->enable = true;
vicap->enable = true;
}
4.3.4 Boardkonfiguration ergänzen
-
camera_board_desc und cif_hw_config in bsp/rockchip/xxx_mcu/board/xxx/board.c implementieren; siehe CIS-Registrierung.
-
Peripherie-IOMUX in bsp/rockchip/xxx_mcu/board/xxx/iomux.c gemäß Schaltplan ergänzen.
5. Neue Funktionen
5.1 AOV
AOV (Always On Video) verwendet Schlaf-/Aufwachzyklen für durchgehende 24-Stunden-Aufzeichnung mit niedriger Bildrate. KI-, PIR- oder WLAN-Ereignisse können zur normalen Rate zurückschalten.
5.1.1 Szenarien
Drei Szenarien: normale Bildrate für Fernvorschau, PIR oder Personenerkennung mit Aufnahme/Netzwerk; AOV bei Leerlauf und ausreichendem Akku mit niedrigfrequenter Hauptstream-Aufzeichnung und WLAN-/4G-Keepalive; energiesparendes Keepalive bei niedrigem Akku, SoC aus und WLAN/4G aktiv.

5.1.2 Ablauf

5.1.3 Begriffe
AOV nutzt Sensor-Standby als Schlaf oder Reset zur Verbrauchssenkung. Schlaf stoppt Bilddaten, reduziert Leistung und erhält Register. SC200AI bietet zwei Wege:
-
PWDN auf Low ziehen; I2C-Lesen/Schreiben ist nicht verfügbar.
-
0 ins Stream-Steuerregister schreiben; I2C bleibt verfügbar. Reset stoppt Bilddaten, senkt Verbrauch und setzt alle Register zurück. Zwei SC200AI-Resetwege:
-
XSHUTDN auf Low ziehen; I2C ist nicht verfügbar.
-
1 ins Software-Reset-Enable-Register schreiben; Reset dauert 150ns.
5.1.3.1 Hardware-Standby
Hardware-Standby zieht PWDN auf Low für stromsparenden Schlaf; I2C ist nicht nutzbar. Für SC200AI rockchip,camera-module-stb = <1> im DTS-Sensorknoten ergänzen. 1 bedeutet Unterstützung, 0 keine Unterstützung.
sc200ai: sc200ai@30 {
compatible = "smartsens,sc200ai";
status = "okay";
reg = <0x30>;
...
rockchip,camera-module-stb = <1>;
port {
sc200ai_out: endpoint {
remote-endpoint = <&csi_dphy_input1>;
data-lanes = <1 2>;
};
};
};
Eigenschaft in probe auswerten und in sc200ai->standby_hw speichern. Bei Unterstützung steuert ioctl RKMODULE_SET_QUICK_STREAM PWDN GPIO gemäß Streamzustand. Schlaf/Aufwachen setzt Belichtung/Verstärkung per V4L2 ioctl neu. Treiberreferenz:
Die Quelle verweist auf „4.2.4 Treiberimplementierung“, Hardware-Standby-Beispiel.
5.1.3.2 Software-Standby
Nach dem Aufwachen schreibt Software-Standby die gesamte Sensorregisterkonfiguration neu. Sensor-ioctl RKMODULE_SET_QUICK_STREAM setzt anschließend direkt das Streamregister. Quellenverweis: „4.2.4 Treiberimplementierung“, Software-Standby-Beispiel.
5.1.4 Treiberimplementierung
Hardware-Standby-Referenzcode:
static long sc200ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
......
switch (cmd) {
case RKMODULE_SET_QUICK_STREAM:
stream = *((u32 *)arg);
if (sc200ai->standby_hw) { // hardware standby
if (stream) {
if (!IS_ERR(sc200ai->pwdn_gpio))
gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 1);
// Make sure __v4l2_ctrl_handler_setup can be called correctly
sc200ai->is_standby = false;
ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_MIPI_CTRL,
SC200AI_REG_VALUE_08BIT, SC200AI_MIPI_CTRL_ON);
#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
if (__v4l2_ctrl_handler_setup(&sc200ai->ctrl_handler))
dev_err(&sc200ai->client->dev, "__v4l2_ctrl_handler_setup fail!");
if (sc200ai->cur_mode->hdr_mode != NO_HDR) {
if (sc200ai->cam_sw_inf) {
ret = sc200ai_ioctl(&sc200ai->subdev,
PREISP_CMD_SET_HDRAE_EXP,
&sc200ai->cam_sw_inf->hdr_ae);
if (ret) {
dev_err(&sc200ai->client->dev,
"init exp fail in hdr mode\n");
return ret;
}
}
}
#endif
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
dev_info(&sc200ai->client->dev, "quickstream, streaming on: exit hw
standby mode\n");
} else {
ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_MIPI_CTRL,
SC200AI_REG_VALUE_08BIT, SC200AI_MIPI_CTRL_OFF);
if (!IS_ERR(sc200ai->pwdn_gpio))
gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 0);
dev_info(&sc200ai->client->dev, "quickstream, streaming off: enter hw
standby mode\n");
sc200ai->is_standby = true;
}
}
......
}
Software-Standby-Referenzimplementierung:
static long sc200ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
......
switch (cmd) {
case RKMODULE_SET_QUICK_STREAM:
stream = *((u32 *)arg);
......
else { // software standby
if (stream) {
ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_MIPI_CTRL,
SC200AI_REG_VALUE_08BIT, SC200AI_MIPI_CTRL_ON);
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
dev_info(&sc200ai->client->dev, "quickstream, streaming on: exit soft
standby mode\n");
} else {
ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_MIPI_CTRL,
SC200AI_REG_VALUE_08BIT, SC200AI_MIPI_CTRL_OFF);
dev_info(&sc200ai->client->dev, "quickstream, streaming off: enter soft
standby mode\n");
}
}
break;
......
}
5.1.5 Referenzen
Für AOV-Entwicklung siehe Rockchip_Trouble_Shooting_Linux5.10_Camera_CN.pdf und Rockchip_RV1106_Developer_Guide_Linux_AOV_CN.pdf.
5.2 Synchronisation (Master/Slave)
Ein einzelner Sensor arbeitet meist einfach als Master. Zwei oder mehr Sensoren mit synchroner Ausgabe/Belichtung benötigen eine Moduskonfiguration, gewöhnlich Master/Slave. Folgende Anwendungen erfordern gleichzeitige Belichtung/Ausgabe mit strenger zeitlicher Ausrichtung:
| Mitglied | Beschreibung |
|---|---|
| 3D / binocular / stereo vision | Synchronisation zwingend, sonst falsche Tiefe. |
| Multicamera stitching / panorama | Bildsynchronisation für genaue Ausrichtung. |
| Machine vision / industrial inspection | Synchrone Abtastung mehrerer Blickwinkel. |
| Autonomous driving / ADAS | Zeitliche Synchronisation entscheidend. |
| Video conferencing / multiple cameras | Strenge Synchronisation meist unnötig, verbessert aber Nutzung. |
Üblich ist ein globales FSYNC/EFSYNC/TRIGGER/SYNC_IN-Signal. Der Host-SoC löst Belichtung/Auslesen aller Sensoren gleichzeitig aus und richtet die Bildströme zeitlich aus.
5.2.1 Sensor-Slave-Modus
Im Slave-Modus steuert ein externer MCU/SoC/DSP Kommunikation, Timing und Übertragung durch Takt, Synchronisation und I2C/MIPI. Der Sensor reagiert, statt selbst zu initiieren. Bei mehreren Sensoren sendet SoC/FPGA FSYNC gleichzeitig an alle; Belichtung oder Bildauslesen beginnen gemeinsam für gleiche Zeitstempel und synchronen Inhalt.
| Mitglied | Beschreibung |
|---|---|
| FSYNC (Frame SYNC) | Bildsync-Eingang: externes Digitalsignal, meist GPIO/CMOS, startet Belichtung/Auslesen mehrerer Sensoren gemeinsam. |
| EFSYNC (External Frame SYNC) | Externer Bildsync, Herstellerbezeichnung variiert. Wie FSYNC: Host sendet, alle Slaves reagieren synchron. |
| TRIGGER / SYNC_IN / STROBE | Alternative Sensornamen für externe Trigger-Synchronisationseingänge. |
RK konfiguriert aktuell einen Master und die übrigen Sensoren als Slaves. Nach Abschluss des Masterbildes startet externes FSYNC/EFSYNC Belichtung/Auslesen der Slaves gleichzeitig zur zeitlichen Ausrichtung.
5.2.2 Treiberimplementierung
- Master-/Slave-Register aus Datenblatt oder vom Hersteller-FAE beschaffen.
/* sync mode regs */
static __maybe_unused const struct regval sc200ai_interal_sync_master_start_regs[] = {
{0x300a, 0x24}, //sync as output PAD
{0x3032, 0xa0},
{0x3222, 0x00}, //master mode
{0x3216, 0x00},
{0x3217, 0x04},
{REG_NULL, 0x00},
};
static __maybe_unused const struct regval sc200ai_interal_sync_master_stop_regs[] = {
{REG_NULL, 0x00},
};
static __maybe_unused const struct regval sc200ai_interal_sync_slaver_start_regs[] = {
{0x3222, 0x02}, //slave mode
{0x3230, 0x00},
{0x3231, 0x04}, //Rows Before Read
{0x3224, 0x82}, //fsync trigger
{REG_NULL, 0x00},
};
static __maybe_unused const struct regval sc200ai_interal_sync_slaver_stop_regs[] = {
{REG_NULL, 0x00},
};
- Synchronisationsmodusvariablen ergänzen
struct sc200ai {
......
enum rkmodule_sync_mode sync_mode;
......
};
Übliche Synchronisationsmodusdefinitionen:
/*
* sensor exposure sync mode
*/
enum rkmodule_sync_mode {
NO_SYNC_MODE = 0,
EXTERNAL_MASTER_MODE,
INTERNAL_MASTER_MODE,
SLAVE_MODE,
SOFT_SYNC_MODE,
};
Synchronisationseigenschaften im DTS-Sensorknoten auswerten, um den aktiven Modus zu bestimmen.
static int sc200ai_probe(struct i2c_client *client,
const struct i2c_device_id *id)
......
ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
&sync_mode_name);
if (ret) {
sc200ai->sync_mode = NO_SYNC_MODE;
dev_err(dev, "could not get sync mode!\n");
} else {
if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0) {
sc200ai->sync_mode = EXTERNAL_MASTER_MODE;
dev_info(dev, "sync_mode = [EXTERNAL_MASTER_MODE]\n");
} else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0) {
sc200ai->sync_mode = INTERNAL_MASTER_MODE;
dev_info(dev, "sync_mode = [INTERNAL_MASTER_MODE]\n");
} else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0) {
sc200ai->sync_mode = SLAVE_MODE;
dev_info(dev, "sync_mode = [SLAVE_MODE]\n");
} else if (strcmp(sync_mode_name, RKMODULE_SOFT_SYNC_MODE) == 0) {
sc200ai->sync_mode = SOFT_SYNC_MODE;
dev_info(dev, "sync_mode = [SOFT_SYNC_MODE]\n");
} else {
dev_info(dev, "sync_mode = [NO_SYNC_MODE]\n");
}
}
......
Zugehörige Makros:
#define RKMODULE_CAMERA_SYNC_MODE "rockchip,camera-module-sync-mode"
#define RKMODULE_INTERNAL_MASTER_MODE "internal_master"
#define RKMODULE_EXTERNAL_MASTER_MODE "external_master"
#define RKMODULE_SLAVE_MODE "slave"
#define RKMODULE_SOFT_SYNC_MODE "soft_sync"
- Beim Streamstart Register passend zum Synchronisationsmodus programmieren.
static int __sc200ai_start_stream(struct sc200ai *sc200ai)
{
int ret = 0;
......
if (!sc200ai->is_thunderboot) {
ret = sc200ai_write_array(sc200ai->client, sc200ai->cur_mode->reg_list);
if (ret)
return ret;
......
if (sc200ai->sync_mode == INTERNAL_MASTER_MODE ||
sc200ai->sync_mode == SOFT_SYNC_MODE) {
ret |= sc200ai_write_array(sc200ai->client,
sc200ai_interal_sync_master_start_regs);
} else if (sc200ai->sync_mode == EXTERNAL_MASTER_MODE) {
ret |= sc200ai_write_array(sc200ai->client,
sc200ai_interal_sync_slaver_start_regs);
} else if (sc200ai->sync_mode == SLAVE_MODE) {
ret |= sc200ai_write_array(sc200ai->client,
sc200ai_interal_sync_slaver_start_regs);
}
if (ret) {
dev_err(&sc200ai->client->dev,
"write sync regs failed\n");
return ret;
}
}
if (sc200ai->sync_mode == NO_SYNC_MODE)
ret |= sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
return ret;
}
- Synchronisationsmodus in RKAIQ setzen/abfragen. Ohne DTS-Konfiguration können RKAIQ-Schnittstellen Mehrkamera-Synchronisation über ioctl setzen.
static long sc200ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
......
case RKMODULE_GET_SYNC_MODE:
sync_mode = (u32 *)arg;
*sync_mode = sc200ai->sync_mode;
break;
case RKMODULE_SET_SYNC_MODE:
sync_mode = (u32 *)arg;
if (sync_mode) {
sc200ai->sync_mode = *sync_mode;
dev_info(&sc200ai->client->dev, "set sync mode is: %s\n",
((*sync_mode == EXTERNAL_MASTER_MODE) ||
(*sync_mode == SLAVE_MODE)) ? "secondary" : "primary");
} else {
dev_info(&sc200ai->client->dev, "set sync mode is: NO_SYNC_MODE\n");
}
break;
......
}
5.3 Blitzsteuerung
Der Sensortreiber kann PWM-/GPIO-Blitze steuern. Zugehörige Parameter für Ein-/Ausschalten aus der Anwendung korrekt konfigurieren.
5.3.1 Treiberimplementierung
- Header
#include "light_ctl.h"
- Steuervariablen ergänzen
struct xxxx {
......
bool enable_light_ctl;
struct rk_light_param light_param;
......
};
- ioctl RKCIS_CMD_FLASH_LIGHT_CTRL behandeln
static long xxxx_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
......
struct rk_light_param *light_param;
......
case RKCIS_CMD_FLASH_LIGHT_CTRL:
dev_info(&mis5001->client->dev, "set flash light param\n");
light_param = (struct rk_light_param *)arg;
if (light_param->light_enable) {
memcpy(&mis5001->light_param, light_param, sizeof(struct rk_light_param));
mis5001->enable_light_ctl = true;
} else {
mis5001->enable_light_ctl = false;
}
ret = light_ctl_write(mis5001->module_index, light_param);
break;
......
};
static long xxxx_compat_ioctl32(struct v4l2_subdev *sd,
unsigned int cmd, unsigned long arg)
{
......
struct rk_light_param *light_param;
......
switch (cmd) {
......
case RKCIS_CMD_FLASH_LIGHT_CTRL:
light_param = kzalloc(sizeof(*light_param), GFP_KERNEL);
if (!light_param) {
ret = -ENOMEM;
return ret;
}
ret = copy_from_user(light_param, up, sizeof(*light_param));
if (!ret)
ret = mis5001_ioctl(sd, cmd, light_param);
else
ret = -EFAULT;
kfree(light_param);
break;
}
.....
}
5.3.2 Referenzen
Implementierungsdetails in Abschnitt 7.2 zur Zusatzlichtsteuerung in Rockchip_Trouble_Shooting_Linux5.10_Camera_CN.pdf.
5.4 Auflösung wechseln
Anwendungen können je nach Szenario unterschiedliche Auflösungen verwenden. Der Treiber schaltet auf Befehl der oberen Ebene um.
5.4.1 Treiberimplementierung
Referenzcode:
static int sc200ai_set_setting(struct sc200ai *sc200ai, struct rk_sensor_setting *setting)
{
int i = 0;
int cur_fps = 0;
s64 h_blank, vblank_def;
u64 pixel_rate = 0;
const struct sc200ai_mode *mode = NULL;
const struct sc200ai_mode *match = NULL;
dev_info(&sc200ai->client->dev,
"sensor setting: %d x %d, fps:%d fmt:%d, mode:%d\n",
setting->width, setting->height,
setting->fps, setting->fmt, setting->mode);
for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
mode = &supported_modes[i];
if (mode->width == setting->width &&
mode->height == setting->height &&
mode->hdr_mode == setting->mode &&
mode->bus_fmt == setting->fmt) {
cur_fps = DIV_ROUND_CLOSEST(mode->max_fps.denominator, mode->max_fps.numerator);
if (cur_fps == setting->fps) {
match = mode;
break;
}
}
}
if (match) {
dev_info(&sc200ai->client->dev, "-----%s: match the support mode, mode idx:%d-----
\n",
__func__, i);
sc200ai->cur_mode = mode;
h_blank = mode->hts_def - mode->width;
__v4l2_ctrl_modify_range(sc200ai->hblank, h_blank,
h_blank, 1, h_blank);
vblank_def = mode->vts_def - mode->height;
__v4l2_ctrl_modify_range(sc200ai->vblank, vblank_def,
SC200AI_VTS_MAX - mode->height,
1, vblank_def);
__v4l2_ctrl_s_ctrl(sc200ai->link_freq, mode->mipi_freq_idx);
pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] /
mode->bpp * 2 * SC200AI_LANES;
__v4l2_ctrl_s_ctrl_int64(sc200ai->pixel_rate, pixel_rate);
dev_info(&sc200ai->client->dev, "freq_idx:%d pixel_rate:%lld\n",
mode->mipi_freq_idx, pixel_rate);
sc200ai->cur_vts = mode->vts_def;
sc200ai->cur_fps = mode->max_fps;
dev_info(&sc200ai->client->dev, "hts_def:%d cur_vts:%d cur_fps:%d\n",
mode->hts_def, mode->vts_def,
sc200ai->cur_fps.denominator / sc200ai->cur_fps.numerator);
} else {
dev_err(&sc200ai->client->dev, "couldn't match the support modes\n");
return -EINVAL;
}
return 0;
}
static long sc200ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
......
struct rk_sensor_setting *setting;
......
switch (cmd) {
......
case RKCIS_CMD_SELECT_SETTING:
setting = (struct rk_sensor_setting *)arg;
ret = sc200ai_set_setting(sc200ai, setting);
break;
......
}
}
5.5 Mehrere Lane-Konfigurationen unterstützen
Host-Plattform, Sensoranzahl, Leistung und Verkabelung können Sequenzen für unterschiedliche Lane-Zahlen erfordern. Der Treiber unterstützt dies.
5.5.1 Treiberimplementierung
Referenzcode:
// 4 Lane 寄存器配置⽀持列表
static const struct sc450ai_mode supported_modes_4lane[] = {
{
...
},
{
...
},
};
// 2 Lane 寄存器配置⽀持列表
static const struct sc450ai_mode supported_modes_2lane[] = {
{
...
},
{
...
},
}
static int sc450ai_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device_node *node = dev->of_node;
struct device_node *endpoint;
......
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
if (!endpoint) {
dev_err(dev, "Failed to get endpoint\n");
return -EINVAL;
}
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
&sc450ai->bus_cfg);
of_node_put(endpoint);
if (ret) {
dev_err(dev, "Failed to get bus config\n");
return -EINVAL;
}
// 根据dts配置的lane数选择不同的寄存器⽀持列表数组
if (sc450ai->bus_cfg.bus.mipi_csi2.num_data_lanes == 4) {
sc450ai->supported_modes = supported_modes_4lane;
sc450ai->cfg_num = ARRAY_SIZE(supported_modes_4lane);
dev_info(dev, "detect sc450ai lane: %d\n",
sc450ai->bus_cfg.bus.mipi_csi2.num_data_lanes);
} else {
sc450ai->supported_modes = supported_modes_2lane;
sc450ai->cfg_num = ARRAY_SIZE(supported_modes_2lane);
dev_info(dev, "detect sc450ai lane: %d\n",
sc450ai->bus_cfg.bus.mipi_csi2.num_data_lanes);
}
......
}
Für 2Lane-/4Lane-supported_modes liest probe die DTS-Lane-Zahl nach bus_cfg.bus.mipi_csi2.num_data_lanes und initialisiert passende Modi und cfg_num-Anzahl.
5.6 Sonstiges
6. Fehleranalyse und Lösungen
6.1 Sensor nicht erkannt, probe-/I2C-Fehler
Die Quelle führt eine nicht erkannte Sensor-ID auf Einschaltanforderungen statt RKISP/RKCIF zurück. In dieser Reihenfolge prüfen:
-
Korrekte 7-Bit-I2C-Slave-ID statt 8-Bit-Wert.
-
MCLK-Ausgabe und korrekte Amplitude; meist 24Mhz, teils 27Mhz.
-
Einschaltfolge: avdd, dovdd, dvdd gemäß Datenblatt und korrekte PWDN-/RESET-GPIO-Konfiguration.
6.1.1 MCLK/VDD nicht messbar
Treiber aktivieren MCLK/Versorgung gewöhnlich nur bei Bedarf; nach dem Boot sind sie aus. Für Messungen schlägt die Quelle vor, power_off() vorübergehend auszukommentieren. Oszilloskopbandbreite prüfen; mindestens 48M empfohlen.
-
MCLK nicht korrekt aktiviert: siehe drivers/media/i2c/ov5695.c.
-
GPIO von anderem Modul belegt: normalerweise im Kernelprotokoll gemeldet. Mit io lassen sich pin-ctrl-Register prüfen.
6.1.2 Sensor-Einschaltfolge prüfen
Mit dem Oszilloskop Reihenfolge und Verzögerungen jeder Versorgung gemäß Datenblatt prüfen. Manche Sensoren wie ov5695 benötigen keine VDD-Reihenfolge und verwenden regulator_bulk. Andere wie ov2685.c benötigen einzeln geordnete avdd_regulator/dovdd_regulator. Nach tatsächlichen Anforderungen wählen.
6.2 Standardwerte exp_def, hts_def und vts_def
Wenn möglich Hersteller fragen. Andernfalls Register im Datenblatt und Initialisierungswerte in der Registerliste ermitteln. SC200AI-Beispiel:
#define SC200AI_REG_VTS_H 0x320e
#define SC200AI_REG_VTS_L 0x320f
...
static const struct regval sc200ai_linear_10_1920x1080_30fps_regs[] = {
...
//HTS=1100*2=2200
{0x320c, 0x04},
{0x320d, 0x4c},
//VTS=1125
{0x320e, 0x04},
{0x320f, 0x65},
...
};
static const struct sc200ai_mode supported_modes[] = {
{
.width = 1920,
.height = 1080,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x0080, // exp曝光默认值,⼀般应⼩于vts默认值,最⼤vts_def - 8 (曝光⾏,具体减去
多少,参考 Sensor ⼿册,可能4/8/10)
.hts_def = 0x44C * 2,// hts默认值填写对应寄存器列表中给出的默认值(可乘倍数)
.vts_def = 0x0465, // vts默认值填对应寄存器列表中给出的默认值
...
},
...
};
6.3 Werte für link_freq und pixel_rate
link_freq ist die tatsächliche MIPI-Taktfrequenz, nicht 24M-MCLK, sondern MIPI dn/dp clk. Hersteller-/Datenblattangaben bevorzugen. Der tatsächliche Wert ist gewöhnlich nicht kleiner als folgendes Ergebnis in Hz:
link_freq = width * height * fps * bits_per_pixel / lanes / 2
Unbekanntes link_freq mit dem Oszilloskop messen. pixel_rate sind übertragene Pixel je Sekunde; nach Ermittlung von link_freq wie folgt berechnen:
pclk = link_freq * 2 * lanes / bits_per_pixel
6.4 Wann funktioniert ein Sensor?
Zuerst Sensor-ID und I2C-Lesen/Schreiben prüfen. media-ctl -p -d /dev/media0 sollte Name, Auflösung und weitere Angaben zeigen:
# media-ctl -p -d /dev/media0 | tail -n 30
-> "rkcif_tools_id2":0 []
pad11: Source
-> "stream_cif_mipi_id0":0 []
-> "stream_cif_mipi_id1":0 []
-> "stream_cif_mipi_id2":0 []
-> "stream_cif_mipi_id3":0 []
-> "rkcif_scale_ch0":0 []
-> "rkcif_scale_ch1":0 []
-> "rkcif_scale_ch2":0 []
-> "rkcif_scale_ch3":0 []
-> "rkcif_tools_id0":0 []
-> "rkcif_tools_id1":0 []
-> "rkcif_tools_id2":0 [ENABLED]
- entity 58: rockchip-csi2-dphy0 (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev1
pad0: Sink
[fmt:SBGGR10_1X10/1920x1080@10000/300000 field:none]
<- "m00_b_sc200ai 4-0030":0 [ENABLED]
pad1: Source
-> "rockchip-mipi-csi2":0 [ENABLED]
- entity 63: m00_b_sc200ai 4-0030 (1 pad, 1 link)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev2
pad0: Source
[fmt:SBGGR10_1X10/1920x1080@10000/300000 field:none]
-> "rockchip-csi2-dphy0":0 [ENABLED]
Fehlen media-ctl/v4l2-ctl im System, Sensorerkennung per dmesg prüfen. Bei Aufnahme muss MIPI Daten ohne MIPI-/ISP-Fehler liefern und die Anwendung Bilder empfangen.
6.5 Stream mit CRC-/ECC-Fehlern
6.5.1 Fehlerquelle und Protokolldetails
In dmesg/Kernelprotokollen gezielt ERR1, ERR2, CRC, ECC, mipi, csi2 und phy suchen. Rockchip-CSI-/PHY-Treiber protokollieren gewöhnlich Registerzustände. ERR1-/ERR2-Fehlercodes und VC-Nummern (Virtual Channel) notieren. Typisches Protokoll:
[ 126.741234] rockchip-mipi-csi2 feaa0000.csi2-dphy: ERR1: 0x00000040 (ECC Error,
VC1), FIFO overflow? Check timings!
[ 126.741259] rockchip-mipi-csi2 feaa0000.csi2-dphy: ERR2: 0x00000010 (CRC Error,
VC0)
Fehlertypen: ERR1 (CSIS_ERR1) meist Protokollfehler wie ECC, Bildformat oder Paketheaderprüfung. ERR2 (CSIS_ERR2) meist Transportfehler: FIFO-Überlauf, Timeout, Synchroncode. CRC Error: falsche Prüfsumme/Bitfehler. ECC Error: fehlgeschlagene Header-Fehlererkennung/-korrektur, meist schwerwiegender und physikalisch bedingt. Overflow: Empfangs-FIFO-Überlauf, meist Timingabweichung.
6.5.2 Softwarekonfiguration (Treiber/DTS)
Sensortiming abgleichen: HTS (Total Width) und VTS (Total Height) müssen zur SoC-CSI2-DPHY-Empfangskonfiguration passen. Abweichungen können ERR2 Overflow verursachen. Prüfen mit:
media-ctl -p -d /dev/mediaX # 查看 Entity 之间的链路和当前格式
v4l2-ctl -d /dev/v4l-subdevY --get-fmt-video # 查看 Sensor 输出格式
v4l2-ctl -d /dev/v4l-subdevZ --get-fmt-video # 查看 CSI-DPHY 输⼊格式
MIPI-Ausgaberate innerhalb des SoC-CSI-DPHY-Maximums halten; die Quelle nennt etwa 2.5Gbps/lane für RK3566/RK3588. Sensor-VC (etwa 0/1) muss zu csi2_dphy/rkcif_mipi_lvds in DTS passen; die Quelle verbindet Abweichungen mit CRC-Fehlern. csi2_dphy-Knoten prüfen:
csi2_dphy_hw: csi2-dphy@fedc0000 {
compatible = "rockchip,rk3588-csi2-dphy-hw";
clocks = ...; // 时钟配置必须正确
resets = ...;
rockchip,hw = <&csi2_dphy0>; // 硬件版本
};
csi2_dphy0: csi2-dphy0 {
compatible = "rockchip,rk3568-csi2-dphy";
phys = <&mipi_dphy0>; // 指向正确的PHY
phy-names = "dphy";
ports {
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
// 关键点: CSI 接收 VC 设置
endpoint {
remote-endpoint = <&sensor_out>;
data-lanes = <1 2 3 4>; // Lane数量必须匹配Sensor
virtual-channel-index = <0>; // 必须等于Sensor输出VC
};
};
};
};
Takt/Versorgung prüfen: korrekte konfliktfreie Frequenzen von Sensor, MIPI DPHY und CSI2 Host Controller. DOVDD/AVDD/DVDD innerhalb Spezifikation; Ripple <50mV mit Oszilloskop messen.
6.5.3 Hardwarepfad (Quelle behauptet über 90% physikalische Ursachen)
Verbindungen: FPC neu einsetzen und verriegeln, anschließend bekannt gutes Kabel testen. Kontakte auf Oxidation/Schmutz prüfen und mit Elektronikreiniger reinigen. Quellenwert für Differenzimpedanz: 100Ω ±10%; schlechte Kabel sind häufige Ursachen.
Signalintegrität mit Oszilloskop/Protokollanalysator prüfen. Alle Sensorversorgungen, besonders 1.2V-/1.8V-DVDD: Rauschen <50mV pk-pk. An CLK+/CLK- und DATA+/DATA- nennt die Quelle: Augenhöhe ≥100mV, Breite ≥0.4 UI, klare monotone Flanken (geschlossenes/unscharfes Auge kritisch); Slew Rate 1.5–4V/ns je D-PHY-Version; Überschwingen/Ringing <20% Vdiff pp; Gleichtaktrauschen <100mV; Data-to-Clock-Skew <0.3 UI. Niedrige MIPI-Rate etwa 500Mbps testen.
MCLK meist 24MHz/27MHz: Stabilität ±50ppm, Phasenjitter <50ps RMS. Geschirmte Kabel und minimale Tastkopf-Masseschleifen verwenden. Quellenwert für Masseimpedanz Sensorboard–SoC-Board: <1Ω. Abstand zu WLAN/DC-DC, Motoren und starken Magnetfeldern.
6.5.4 Systemprüfung/Fehlersuche
data-lanes-Reihenfolge/-Zahl mit Verdrahtung abgleichen, besonders Polaritätsumkehr und lane-polarities. Auf etwa 320x240 @10fps reduzieren; verschwindende Fehler deuten auf Bandbreite/Signalqualität. Internes Color Bar/Checkerboard umgeht analoge Aufnahme und testet MIPI direkt. rkisp_3A_server in /etc/init.d/ für ausführliche Logs aktivieren. Mit v4l2-ctl überwachen:
v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=100 --stream-skip=100
Temperatur: hohe Temperaturen verschlechtern Signalqualität. Prüfen, ob Fehlerrate steigt (Quellenbeispiel Umgebung >85°C).
6.5.5 Sofortige Fehlersuchmaßnahmen
-
Zuerst MIPI für Tests auf <1.5Gbps/lane reduzieren.
-
Nur 1 Lane testen.
-
Unbeteiligte Peripherie entfernen und CPU-/GPU-Takte senken.
-
Sensormodul, Core-Board oder Hauptplatine tauschen, besonders bei Verdacht auf PCB-Impedanz.
6.5.6 Typische Abhilfen
Physikalische Ursachen (Quelle 90%): hochwertiges 100Ω±5%-MIPI-Kabel, kürzere Differenzleitungen, keine Via-Stubs, mehr Paarabstand; Quelle schlägt außerdem 50Ω-Abschluss nach Masse vor. Software (9%): VTS/HTS/Pixel Clock exakt abgleichen, VC/Lane-Map korrigieren, Treiber/Firmware besonders MIPI PHY aktualisieren.
Hardwarefehler (Quelle 1%): Versorgungsbaum überarbeiten/LDO-Filterung ergänzen, präzisen Quarz/Taktpuffer verwenden, ESD-Schutz/TVS-Auswahl verbessern.
6.5.7 Sensorindex
rockchip,camera-module-index in DTS setzen. librkaiq/rockit bevorzugen diesen Geräteindex; auch tool_server sucht danach. Ohne explizites -d gilt 0. Empfehlung: Einzelkamera 0, zwei 0/1, mehrere 0/1/2/3…
7. Referenzdokumente
Sensortreibercode ist nur ein Schritt. Für Plattform-DTS, Schnellstart/AOV und Bildprobleme siehe:
-
Rockchip_Driver_Guide_VI_CN.pdf, last ver: v1.2.0
-
Rockchip Quick Start For Camera.pdf, last ver: v1.0.0
-
Rockchip_Trouble_Shooting_Linux5.10_Camera_CN.pdf
-
Rockchip_Developer_Guide_Linux_AOV_CN.pdf
8. Anhänge
8.1 CIS-V4L2-Controls
| Mitglied | Beschreibung |
|---|---|
| V4L2_CID_VBLANK | Vertikale Austastung: Leerlauf nach jedem Bild ohne Daten, Einheit Zeilen. Zeilenlänge ist Bildbreite plus horizontale Austastung bei V4L2_CID_PIXEL_RATE desselben Untergeräts. |
| Mitglied | Beschreibung |
|---|---|
| V4L2_CID_HBLANK | Horizontale Austastung: Leerlauf nach jeder Datenzeile ohne Ausgabe, Einheit Pixel. |
| V4L2_CID_EXPOSURE | Sensorbelichtungszeit, durch Bildintervall begrenzt. |
| V4L2_CID_ANALOGUE_GAIN | Verstärkung aller Farbkomponenten der Pixelmatrix im Analogbereich vor A/D-Wandlung. |
| V4L2_CID_PIXEL_RATE | Nur lesbare Pixelrate an subdev-Quellpads, Pixel/s. MIPI: pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample |
| V4L2_CID_LINK_FREQ | Datenbusfrequenz in Hz. Mit Medienbus-Pixelcode und Bustyp (Takte/Abtastung) definiert sie V4L2_CID_PIXEL_RATE im Pixelarray bzw. anderswo bei Nicht-Sensoren. Bildrate folgt Pixeltakt, Breite/Höhe und beiden Austastungen. Pixelrate außerhalb des Array-Untergeräts reicht nicht zur Bildratenberechnung: Nur im Array sind Austastwerte exakt, da dort keine weitere Austastung zulässig ist. Bildrate über gewünschte horizontale/vertikale Austastung wählen. |
8.2 MEDIA_BUS_FMT-Liste
| CIS-Sensortyp | Sensorausgabeformat |
|---|---|
| Bayer RAW | MEDIA_BUS_FMT_SBGGR10_1X10 MEDIA_BUS_FMT_SRGGB10_1X10 MEDIA_BUS_FMT_SGBRG10_1X10 MEDIA_BUS_FMT_SGRBG10_1X10 MEDIA_BUS_FMT_SRGGB12_1X12 MEDIA_BUS_FMT_SBGGR12_1X12 MEDIA_BUS_FMT_SGBRG12_1X12 MEDIA_BUS_FMT_SGRBG12_1X12 MEDIA_BUS_FMT_SRGGB8_1X8 MEDIA_BUS_FMT_SBGGR8_1X8 MEDIA_BUS_FMT_SGBRG8_1X8 MEDIA_BUS_FMT_SGRBG8_1X8 |
| YUV | MEDIA_BUS_FMT_YUYV8_2X8 MEDIA_BUS_FMT_YVYU8_2X8 MEDIA_BUS_FMT_UYVY8_2X8 MEDIA_BUS_FMT_VYUY8_2X8 MEDIA_BUS_FMT_YUYV10_2X10 MEDIA_BUS_FMT_YVYU10_2X10 MEDIA_BUS_FMT_UYVY10_2X10 MEDIA_BUS_FMT_VYUY10_2X10 MEDIA_BUS_FMT_YUYV12_2X12 MEDIA_BUS_FMT_YVYU12_2X12 MEDIA_BUS_FMT_UYVY12_2X12 MEDIA_BUS_FMT_VYUY12_2X12 |
| Nur Y (monochrom), Raw-BW-Sensor | MEDIA_BUS_FMT_Y8_1X8 MEDIA_BUS_FMT_Y10_1X10 MEDIA_BUS_FMT_Y12_1X12 |
8.3 Kamera-Referenztreiber
| CIS-Datenschnittstelle | CIS-Ausgabedatentyp | Frame/Field | Referenztreiber |
|---|---|---|---|
| MIPI | Bayer RAW | frame | 0.3M ov7750.c gc0403.c 0.9M jx_h62.c jx_h63p 1.2M ov9750.c jx-h65.c mia1321.c 2M jx_f37.c mis20s1.c mis2031.c ov2685.c ov2680.c ov2735.c ov02g10.c ov02b10.c gc2385.c gc2355.c gc2053.c gc2093.c sc2232.c sc2239.c sc223a.c sc2310.c sc2336.c sc2336p.c sc230ai.c sc231hai.c sc235hai.c sc210iot.c sp250a.c 4M gc4c33.c jx_k04.c jx_k17.c mis4001.c mis40c1.c mis40h1.c ov4686.c ov4688.c ov4689.c os04c10.c os04a10.c sc401ai.c sc4236.c sc450ai.c sc485sl.c imx347.c 5M mis5001.c os05a20.c ov5695.c ov5648.c ov5670.c gc5024.c gc5025.c gc5035.c hm5040.c sc5239.c hynix_hi556.c 8M ar0822.c gc8613.c mis8001.c ov8858.c os08a10.c os08a20.c sc8220.c sc830ai.c sc835hai.c sc850sl.c imx378.c imx317.c imx219.c gc8034.c hynix_hi846.c s5kgm1sp.c s5k4h7yx.c 13M ov13850.c ov13b10.c imx258.c ov12d2q.c |
| MIPI | Bayer raw hdr | frame | 2M imx307.c imx327.c imx462.c gc2093.c ov02k10.c ov2718.c sc200ai.c sc2310.c jx-f37.c 4M ov4689.c os04a10.c imx347.c imx464.c sc4238.c 5M imx335.c os05a20.c sc500ai.c 8M imx334.c imx415.c |
| MIPI | YUV | frame | 2M gc2145.c |
| MIPI | RAW BW | frame | 0.3M ov7251.c 1M ov9281.c 1.3M sc132gs.c |
| MIPI | YUV | field | tc35874x.c |
| ITU.BT60 | Bayer RAW | 2M imx323.c ar0230.c |
|
| ITU.BT601 | YUV | 0.3M gc0329.c gc0312.c gc032a.c 2M gc2145.c gc2155.c gc2035.c bf3925.c |
|
| ITU.BT601 | RAW BW | 0.3M sc031gs.c 1.3M sc032gs.c |
|
| ITU.BT656 | Bayer RAW | 2M imx323.c (kann unterstützt werden) |
