pinephone-pro: WIP support for camera

i can't get images out of it, but the ov8858 appears to be detected by media-ctl (?)
This commit is contained in:
2024-11-25 21:32:55 +00:00
parent 6be6c08e7c
commit 04315d35b8
3 changed files with 274 additions and 0 deletions

View File

@@ -80,6 +80,10 @@ in
name = "rk3399-pinephone-pro-battery";
dtsFile = ./rk3399-pinephone-pro-battery.dtso;
}
{
name = "rk3399-pinephone-pro-camera";
dtsFile = ./rk3399-pinephone-pro-camera.dtso;
}
{
name = "rk3399-pinephone-pro-flash-led";
dtsFile = ./rk3399-pinephone-pro-flash-led.dtso;

View File

@@ -0,0 +1,269 @@
// STATUS (2024-11-25):
// - can't get an image
// - ov8858 shows up in `media-ctl -d 1 --print-topology`
// - imx258 doesn't show up in any `media-ctl` or `v4l2-ctl` commands, but does show in `modprobe` and `dmesg`
// - pmOS claims it should work in megapixels 2.x and snapshot/gnome camera: <https://wiki.postmarketos.org/wiki/PINE64_PinePhone_Pro_(pine64-pinephonepro)#Camera>
// - pmOS has IMX258 debugging info: <https://wiki.pine64.org/wiki/PinePhone_Pro/IMX258_Camera_Debugging>
// - <https://elinux.org/images/9/94/ISP-presentation.pdf>
//
// this is taken mostly verbatim from pine64-org / megi.
// only minimal checking against the datasheet.
// see pine64-org/linux commits:
// - 41742e56f573b90c002293a1d12d0e5ecee7ec87 for device-tree
// - 43243704827563df8410431da6d73ed25e379de8 for SCLK_CIF_OUT_SRC export (touches drivers/clk/rockchip/clk-rk3399.c)
//
// overview:
// - front cam: OV8858 (ucam = "user-facing camera" (i'm guessing))
// - rear cam: IMX258 (wcam = "world-facing camera")
// MIPI = Mobile Industry Processor Interface
// MIPI-DSI = MIPI Display Serial Interface
// MIPI-CSI = MIPI Camera Serial Interface
// - <https://en.wikipedia.org/wiki/Camera_Serial_Interface>
// - 1 clock lane + N data lanes (PPP cameras use 4 data lanes)
// - each data line is two wires, because it uses differential signalling
// CCS = Camera Command Set
// - defines standard set of functionalities for CSI-2 devices
// DVP = Digital Video Port
//
// IMX258:
// - MIPI_RX0_D{0,1,2,3}{P,N}
// - MIPI_RX0_CLK{P,N}
// - MIPI_MCLK0
// - MIPI_RST0
// - DVP_PDN1_H1
// - I2C1_SDA
// - (I2C1_SCL)
// :: power:
// - VCC1V8_DVP
// - DVDD_DVP
// - VCC2V8_DVP
// - AVDD2V8_DVP
//
// OV8858:
// - identical wiring to IMC258, but uses MIPI 1 instead of MIPI 0.
// - uses same I2C1_{SDA,SCL}
// - uses same power rails
//
// - MIPI_MCLK0, MIPI_MCLK1 are tied to CIF_CLKO via 22ohm resistors
// - DVDD_DVP = VCC1V2_DVP
//
// STATUS:
// - power:
// - [x] VCC1V8_DVP: enabled in mainline
// - [?] DVDD_DVP (VCC1V2_DVP)
// - [?] VCC2V8_DVP: PROBABLY enabled in mainline, as "vcc2v8_lcd"
// other DTS files reference `vcc2v8_dvp`, but pine64-org's dts does *not*, nor does mainline's
// - [?] AVDD2V8_DVP: NOT ENABLED
// but seemingly not used in megi or pine64-org DTS
// for SCLK_CIF_OUT
#include <dt-bindings/clock/rk3399-cru.h>
// for GPIO_ACTIVE_LOW
#include <dt-bindings/gpio/gpio.h>
// for LED_FUNCTION_FLASH
#include <dt-bindings/leds/common.h>
// for RK_PA4, other pins
#include <dt-bindings/pinctrl/rockchip.h>
/dts-v1/;
/plugin/;
/ {
/* ensure this overlay applies only to the correct board */
compatible = "pine64,pinephone-pro";
};
&{/} {
sgm3140: led-controller {
compatible = "sgmicro,sgm3140";
vin-supply = <&vcc3v3_sys>;
pinctrl-names = "default";
pinctrl-0 = <&flash_pins>;
enable-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
flash-gpios = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
sgm3140_flash: led {
function = LED_FUNCTION_FLASH;
color = <LED_COLOR_ID_WHITE>;
flash-max-timeout-us = <250000>;
};
};
};
/* MEGI CLAIMS:
* ============
* Cameras:
*
* cif clk out = gpio2 B3 / CIF_CLKOUTA_u
*
* both on i2c1 GPIO4_A1 (SDA) / GPIO4_A2 (SCL)
*
* both share power:
* VCC1V8_DVP - LDO7 - supplied by VCC7 (VCC3V3_SYS)
* DVDD_DVP 1.5V - autoenabled by VCC2V8_DVP depends on VCC1V8_S3 (U118 supplies 1.2V, though, not 1.5V)
* VCC2V8_DVP af - autoenabled by VCC1V8_DVP depends on VCC3V3_SYS
* AVDD2V8_DVP - autoenabled by VCC1V8_DVP depends on VCC3V3_SYS
*
* isp1 = imx258
* reset = GPIO1_A0
* powerdown = GPIO2_B4
*
* isp0 = OV8858
* powerdown = GPIO2_D4
* reset = GPIO1_A4
*/
&i2c1 {
status = "okay";
clock-frequency = <400000>;
i2c-scl-rising-time-ns = <300>;
i2c-scl-falling-time-ns = <15>;
pinctrl-0 = <&i2c1_xfer &cif_clkouta>;
assigned-clocks = <&cru SCLK_CIF_OUT>;
assigned-clock-rates = <24000000>;
// assigned-clocks = <&cru SCLK_CIF_OUT &cru SCLK_CIF_OUT_SRC>;
// assigned-clock-parents = <&cru SCLK_CIF_OUT_SRC &cru PLL_GPLL>;
// assigned-clock-rates = <19200000 0>;
wcam: camera@1a {
compatible = "sony,imx258";
reg = <0x1a>;
pinctrl-names = "default";
pinctrl-0 = <&wcam_rst>; //< megi (2024-05-25)
// pinctrl-0 = <&wcam_rst &wcam_pdn>; //< pine64-org
clocks = <&cru SCLK_CIF_OUT>;
clock-names = "xvclk";
vif-supply = <&vcc1v8_dvp>;
i2c-supply = <&vcca1v8_codec>;
/*XXX: also depends on vcca1v8_codec for I2C bus power (currently always on) */
reset-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>;
// powerdown-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; //< megi removed this (2024-05-25)
orientation = <1>;
rotation = <270>;
lens-focus = <&wcam_lens>;
flash-leds = <&sgm3140_flash>;
port {
wcam_out: endpoint {
remote-endpoint = <&mipi_in_wcam>;
data-lanes = <1 2 3 4>;
link-frequencies = /bits/ 64 <636000000>; //< seems to be optional
};
};
};
wcam_lens: camera-lens@c {
compatible = "dongwoon,dw9714";
reg = <0x0c>;
/*XXX: also depends on vcca1v8_codec for I2C bus power */
vcc-supply = <&vcc1v8_dvp>;
};
ucam: camera@36 {
compatible = "ovti,ov8858";
reg = <0x36>;
pinctrl-names = "default";
pinctrl-0 = <&ucam_pdn &ucam_rst>;
clocks = <&cru SCLK_CIF_OUT>;
clock-names = "xvclk";
dovdd-supply = <&vcc1v8_dvp>;
/*XXX: also depends on vcca1v8_codec for I2C bus power */
reset-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_LOW>;
powerdown-gpios = <&gpio2 RK_PB4 GPIO_ACTIVE_LOW>;
/* we're using forward ported BSP driver, thus: */
rockchip,camera-module-index = <0x00>;
rockchip,camera-module-facing = "front";
rockchip,camera-module-name = "CameraKing";
rockchip,camera-module-lens-name = "Largan-9569A2";
orientation = <0>;
rotation = <90>;
port {
ucam_out: endpoint {
remote-endpoint = <&mipi_in_ucam>;
data-lanes = <1 2 3 4>;
};
};
};
};
&pinctrl {
camera {
wcam_rst: wcam-rst {
rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
};
// wcam_pdn: wcam-pdn { //< megi removed this (2024-05-25)
// rockchip,pins = <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
// };
ucam_rst: ucam-rst {
rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
};
ucam_pdn: ucam-pdn {
rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
leds {
flash_pins: flash-pins {
rockchip,pins =
<1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>,
<4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&isp1 {
status = "okay";
ports {
port@0 {
mipi_in_wcam: endpoint@0 {
reg = <0>;
remote-endpoint = <&wcam_out>;
data-lanes = <1 2 3 4>;
};
};
};
};
&mipi_dphy_rx0 {
status = "okay";
};
&isp0 {
status = "okay";
ports {
port@0 {
mipi_in_ucam: endpoint@0 {
reg = <0>;
remote-endpoint = <&ucam_out>;
data-lanes = <1 2 3 4>;
};
};
};
};
&isp0_mmu {
status = "okay";
};
&isp1_mmu {
status = "okay";
};
&mipi_dsi1 {
status = "okay";
};

View File

@@ -103,6 +103,7 @@
};
// rk3399-pinephone-pro-sound sets this 'okay', but do that here also to avoid implicit dependencies.
// TODO: how can the modem require i2c1 if i'm not hanging any devices off of it here??
&i2c1 {
status = "okay";
// N.B.: these values are duplicated in rk3399-pinephone-pro-sound.dtso