diff --git a/hosts/modules/hal/pine64-pinephone-pro/default.nix b/hosts/modules/hal/pine64-pinephone-pro/default.nix index c81b37266..0922fa0a7 100644 --- a/hosts/modules/hal/pine64-pinephone-pro/default.nix +++ b/hosts/modules/hal/pine64-pinephone-pro/default.nix @@ -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; diff --git a/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-camera.dtso b/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-camera.dtso new file mode 100644 index 000000000..1c46c0cd8 --- /dev/null +++ b/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-camera.dtso @@ -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: +// - pmOS has IMX258 debugging info: +// - +// +// 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 +// - +// - 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 +// for GPIO_ACTIVE_LOW +#include +// for LED_FUNCTION_FLASH +#include +// for RK_PA4, other pins +#include + +/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 = ; + 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"; +}; diff --git a/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-modem.dtso b/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-modem.dtso index ba4da7780..ea49caa60 100644 --- a/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-modem.dtso +++ b/hosts/modules/hal/pine64-pinephone-pro/rk3399-pinephone-pro-modem.dtso @@ -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