Merge commit 'a2d0c7f12f'
* commit 'a2d0c7f12f': (49 commits)
ASoC: rockchip: i2s: Use add_component_controls
ASoC: rockchip: i2s-tdm: Add support for PCM R/W Wait Time
ASoC: rockchip: i2s-tdm: Add support for PATHx controls
ASoC: rockchip: i2s-tdm: Use add_component_controls
ASoC: rockchip: multi-dais: Fix component's name_prefix
ASoC: rockchip: sai: Fix Transmit SDOx Select
ASoC: rockchip: sai: Reduce FIFO XRUN warning prompt
media: rockchip: hdmirx: avoid PKTDEC_AVIIF_CHG_IRQ mistrigger.
video: rockchip: mpp: rkvenc2: fix slice mode poll failed
arm64: dts: rockchip: px30: Add reboot_mode label for Android
ARM: dts: rockchip: add rv1106g-evb1-v11-nofastae-spi-nand
PCI: rockchip: dw: Use handle_level_irq for legacy irq
arm64: dts: rockchip: rk3562-amp: Move the rpmsg node backwards.
arm64: dts: rockchip: rk3568-amp: Move the rpmsg node backwards.
arm64: dts: rockchip: rk3588-amp: support ap rpmsg
rpmsg: rockchip: use rockchip,rpmsg for all rockchip platform
arm64: dts: rockchip: rk3588-vehicle-evb: add v22 dts files and use serdes-mfd-display default
mailbox: rockchip: Add Rockchip MBOX Demo
arm64: dts: rockchip: add rk3588 evb1 lp4 v10 linux amp dts
arm64: dts: rockchip: rk3588-amp: support ap core for amp
...
Change-Id: I13bb9ab1c3def29f25b18c67ee73d915b17ec817
Conflicts:
drivers/gpio/Kconfig
drivers/media/i2c/maxim4c/Kconfig
This commit is contained in:
commit
dfd3eeaf2b
60 changed files with 11207 additions and 601 deletions
|
|
@ -0,0 +1,80 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/gpio/novo,nca9539-gpio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Novosense I2C GPIO controller
|
||||
|
||||
maintainers:
|
||||
- Cody Xie <cody.xie@rock-chips.com>
|
||||
|
||||
description: |
|
||||
This controller is A GPIO expander with I2C interface and one interrupt pin.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: novo,nca9539-gpio
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: the I2C address containing the GPIO controller registers.
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
ngpios:
|
||||
minimum: 0
|
||||
maximum: 32
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 2
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
- description: the regulator for the VDD supplier.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#gpio-cells"
|
||||
- gpio-controller
|
||||
- vdd-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
dependencies:
|
||||
interrupt-controller: [ interrupts ]
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
/ {
|
||||
nca9539_vdd: nca9539-vdd {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "nca9539_vdd";
|
||||
enable-active-high;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
|
||||
nca9539_gpio: gpio@74 {
|
||||
compatible = "novo,nca9539-gpio";
|
||||
reg = <0x74>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
vdd-supply = <&nca9539_vdd>;
|
||||
};
|
||||
|
||||
|
||||
...
|
||||
|
|
@ -1145,6 +1145,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
|
|||
rv1106g-evb1-v11-facial-gate.dtb \
|
||||
rv1106g-evb1-v10-spi-nand.dtb \
|
||||
rv1106g-evb1-v10-spi-nor.dtb \
|
||||
rv1106g-evb1-v11-nofastae-spi-nand.dtb \
|
||||
rv1106g-evb2-v10.dtb \
|
||||
rv1106g-evb2-v10-dual-camera.dtb \
|
||||
rv1106g-evb2-v11-emmc.dtb \
|
||||
|
|
|
|||
29
arch/arm/boot/dts/rv1106g-evb1-v11-nofastae-spi-nand.dts
Normal file
29
arch/arm/boot/dts/rv1106g-evb1-v11-nofastae-spi-nand.dts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "rv1106g-evb1-v11.dts"
|
||||
#include "rv1106-tb-nofastae.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RV1106G EVB1 V11 Board";
|
||||
compatible = "rockchip,rv1106g-evb1-v11", "rockchip,rv1106";
|
||||
chosen {
|
||||
bootargs = "loglevel=0 rootfstype=erofs rootflags=dax console=ttyFIQ0 root=/dev/rd0 snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=0 driver_async_probe=dwmmc_rockchip";
|
||||
};
|
||||
};
|
||||
|
||||
&fiq_debugger {
|
||||
rockchip,baudrate = <1500000>;
|
||||
};
|
||||
|
||||
&ramdisk_r {
|
||||
reg = <0x800000 (15 * 0x00100000)>;
|
||||
};
|
||||
|
||||
&ramdisk_c {
|
||||
reg = <0x1700000 (10 * 0x00100000)>;
|
||||
};
|
||||
|
|
@ -145,6 +145,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-k108.dtb
|
|||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-rkg11.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-channel-lvds.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-lvds.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-camera.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux.dtb
|
||||
|
|
@ -211,6 +213,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10.dtb
|
|||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-dsi-dsc-MV2100UZ1.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-ipc-6x-linux.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-amp.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-ipc.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-lt6911uxe.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb2-lp4-v10.dtb
|
||||
|
|
@ -248,6 +251,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0-linux.dtb
|
|||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v20.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v21.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v22.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-s66-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb1-lp4x-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb1-lp4x-v10-linux.dtb
|
||||
|
|
|
|||
|
|
@ -652,7 +652,7 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
reboot-mode {
|
||||
reboot_mode: reboot-mode {
|
||||
compatible = "syscon-reboot-mode";
|
||||
offset = <0x200>;
|
||||
mode-bootloader = <BOOT_BL_DOWNLOAD>;
|
||||
|
|
|
|||
|
|
@ -22,18 +22,6 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
rpmsg: rpmsg@7c00000 {
|
||||
compatible = "rockchip,rk3562-rpmsg";
|
||||
mbox-names = "rpmsg-rx", "rpmsg-tx";
|
||||
mboxes = <&mailbox 0 &mailbox 3>;
|
||||
rockchip,vdev-nums = <1>;
|
||||
rockchip,link-id = <0x04>;
|
||||
reg = <0x0 0x7c00000 0x0 0x20000>;
|
||||
memory-region = <&rpmsg_dma_reserved>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
|
@ -63,6 +51,18 @@
|
|||
};
|
||||
|
||||
};
|
||||
|
||||
rpmsg: rpmsg@7c00000 {
|
||||
compatible = "rockchip,rpmsg";
|
||||
mbox-names = "rpmsg-rx", "rpmsg-tx";
|
||||
mboxes = <&mailbox 0 &mailbox 3>;
|
||||
rockchip,vdev-nums = <1>;
|
||||
rockchip,link-id = <0x04>;
|
||||
reg = <0x0 0x7c00000 0x0 0x20000>;
|
||||
memory-region = <&rpmsg_dma_reserved>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&mailbox {
|
||||
|
|
|
|||
|
|
@ -2266,6 +2266,7 @@
|
|||
&i2s0m0_sdo2
|
||||
&i2s0m0_sdo3>;
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "SAI0";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
@ -2293,6 +2294,7 @@
|
|||
&i2s1m0_sdo2
|
||||
&i2s1m0_sdo3>;
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "SAI1";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
@ -2314,6 +2316,7 @@
|
|||
&i2s2m0_sdi
|
||||
&i2s2m0_sdo>;
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "SAI2";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
#include "rk3567-evb2-lp4x-v10.dtsi"
|
||||
#include "rk3568-android.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RK3567 EVB2 LP4X V10 Board";
|
||||
compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
|
||||
|
||||
panel {
|
||||
compatible = "simple-panel";
|
||||
backlight = <&backlight>;
|
||||
power-supply = <&vcc3v3_lcd0_n>;
|
||||
enable-delay-ms = <20>;
|
||||
prepare-delay-ms = <20>;
|
||||
unprepare-delay-ms = <20>;
|
||||
disable-delay-ms = <20>;
|
||||
bus-format = <MEDIA_BUS_FMT_RGB888_1X7X4_SPWG>;
|
||||
width-mm = <217>;
|
||||
height-mm = <136>;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
|
||||
timing0: timing0 {
|
||||
clock-frequency = <148500000>;
|
||||
hactive = <1920>;
|
||||
vactive = <1080>;
|
||||
hback-porch = <96>;
|
||||
hfront-porch = <120>;
|
||||
vback-porch = <16>;
|
||||
vfront-porch = <64>;
|
||||
hsync-len = <64>;
|
||||
vsync-len = <16>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dual-lvds-odd-pixels;
|
||||
panel_in_lvds0: endpoint {
|
||||
remote-endpoint = <&lvds0_out_panel>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dual-lvds-even-pixels;
|
||||
panel_in_lvds1: endpoint {
|
||||
remote-endpoint = <&lvds1_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&backlight1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds {
|
||||
status = "okay";
|
||||
dual-channel;
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds0_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds1 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds1_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&lvds1_in_vp2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* enable hdmi */
|
||||
&hdmi_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* enable video phy */
|
||||
&video_phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video_phy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* disable other encoder output */
|
||||
&dsi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&edp_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&rgb_in_vp2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
&vcc3v3_lcd0_n {
|
||||
gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
&vcc3v3_lcd1_n {
|
||||
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
172
arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
Normal file
172
arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
#include "rk3567-evb2-lp4x-v10.dtsi"
|
||||
#include "rk3568-android.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RK3567 EVB2 LP4X V10 Board";
|
||||
compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
|
||||
|
||||
panel {
|
||||
compatible = "simple-panel";
|
||||
backlight = <&backlight>;
|
||||
power-supply = <&vcc3v3_lcd0_n>;
|
||||
enable-delay-ms = <20>;
|
||||
prepare-delay-ms = <20>;
|
||||
unprepare-delay-ms = <20>;
|
||||
disable-delay-ms = <20>;
|
||||
bus-format = <MEDIA_BUS_FMT_RGB666_1X7X3_SPWG>;
|
||||
width-mm = <217>;
|
||||
height-mm = <136>;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
|
||||
timing0: timing0 {
|
||||
clock-frequency = <134000000>;
|
||||
hactive = <1600>;
|
||||
vactive = <1280>;
|
||||
hback-porch = <60>;
|
||||
hfront-porch = <60>;
|
||||
vback-porch = <4>;
|
||||
vfront-porch = <2>;
|
||||
hsync-len = <8>;
|
||||
vsync-len = <2>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/**
|
||||
* Panel <----> LVDS0
|
||||
* Panel <----> LVDS1
|
||||
*/
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dual-lvds-left-pixels;
|
||||
panel_in_lvds0: endpoint {
|
||||
remote-endpoint = <&lvds0_out_panel>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dual-lvds-right-pixels;
|
||||
panel_in_lvds1: endpoint {
|
||||
remote-endpoint = <&lvds1_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&backlight1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&backlight {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds {
|
||||
status = "okay";
|
||||
dual-channel;
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds0_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds1 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
lvds1_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_lvds1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lvds_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lvds1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&lvds1_in_vp2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* enable hdmi */
|
||||
&hdmi_in_vp1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* enable video phy */
|
||||
&video_phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video_phy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* disable other encoder output */
|
||||
&dsi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi0_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&dsi1_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&edp_in_vp1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&rgb_in_vp2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
&vcc3v3_lcd0_n {
|
||||
gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
&vcc3v3_lcd1_n {
|
||||
gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
|
@ -24,18 +24,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
rpmsg: rpmsg@7c00000 {
|
||||
compatible = "rockchip,rk3568-rpmsg";
|
||||
mbox-names = "rpmsg-rx", "rpmsg-tx";
|
||||
mboxes = <&mailbox 0 &mailbox 3>;
|
||||
rockchip,vdev-nums = <1>;
|
||||
rockchip,link-id = <0x03>;
|
||||
reg = <0x0 0x7c00000 0x0 0x20000>;
|
||||
memory-region = <&rpmsg_dma_reserved>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
|
@ -64,6 +52,18 @@
|
|||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
rpmsg: rpmsg@7c00000 {
|
||||
compatible = "rockchip,rpmsg";
|
||||
mbox-names = "rpmsg-rx", "rpmsg-tx";
|
||||
mboxes = <&mailbox 0 &mailbox 3>;
|
||||
rockchip,vdev-nums = <1>;
|
||||
rockchip,link-id = <0x03>;
|
||||
reg = <0x0 0x7c00000 0x0 0x20000>;
|
||||
memory-region = <&rpmsg_dma_reserved>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&mailbox {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@
|
|||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/soc/rockchip-amp.h>
|
||||
|
||||
/ {
|
||||
rockchip_amp: rockchip-amp {
|
||||
compatible = "rockchip,mcu-amp";
|
||||
compatible = "rockchip,amp";
|
||||
clocks = <&cru HCLK_PMU_CM0_ROOT>, <&cru FCLK_PMU_CM0_CORE>,
|
||||
<&cru CLK_PMU_CM0_RTC>, <&cru PCLK_PMUCM0_INTMUX>,
|
||||
<&cru SCLK_UART5>, <&cru PCLK_UART5>,
|
||||
<&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER4>, <&cru CLK_BUSTIMER5>,
|
||||
<&cru PCLK_BUSTIMER1>, <&cru CLK_BUSTIMER10>, <&cru CLK_BUSTIMER11>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
|
|
@ -22,10 +25,44 @@
|
|||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
/* remote amp core address */
|
||||
amp_shmem_reserved: amp-shmem@7800000 {
|
||||
reg = <0x0 0x7800000 0x0 0x400000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
rpmsg_reserved: rpmsg@7c00000 {
|
||||
reg = <0x0 0x07c00000 0x0 0x400000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
rpmsg_dma_reserved: rpmsg-dma@8000000 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x0 0x08000000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
/* mcu address */
|
||||
mcu_reserved: mcu@8200000 {
|
||||
reg = <0x0 0x8200000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
rpmsg: rpmsg@7c00000 {
|
||||
compatible = "rockchip,rpmsg";
|
||||
mbox-names = "rpmsg-rx", "rpmsg-tx";
|
||||
mboxes = <&mailbox0 0 &mailbox0 3>;
|
||||
rockchip,vdev-nums = <1>;
|
||||
rockchip,link-id = <0x03>;
|
||||
reg = <0x0 0x7c00000 0x0 0x20000>;
|
||||
memory-region = <&rpmsg_dma_reserved>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&mailbox0 {
|
||||
rockchip,txpoll-period-ms = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "rk3588-evb1-lp4.dtsi"
|
||||
#include "rk3588-evb1-imx415.dtsi"
|
||||
#include "rk3588-linux.dtsi"
|
||||
#include "rk3588-amp.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RK3588 EVB1 LP4 V10 Board";
|
||||
compatible = "rockchip,rk3588-evb1-lp4-v10", "rockchip,rk3588";
|
||||
|
||||
cpus {
|
||||
cpu-map {
|
||||
cluster0 {
|
||||
/delete-node/ core3;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x02000000 0x0 0x06400000>,
|
||||
<0x0 0x09400000 0x0 0xe6c00000>,
|
||||
<0x1 0x00000000 0x1 0x00000000>,
|
||||
<0x2 0xf0000000 0x0 0x10000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&arm_pmu {
|
||||
interrupt-affinity = <&cpu_l0>, <&cpu_l1>, <&cpu_l2>,
|
||||
<&cpu_b0>, <&cpu_b1>, <&cpu_b2>, <&cpu_b3>;
|
||||
};
|
||||
|
||||
/delete-node/ &cpu_l3;
|
||||
|
||||
&route_hdmi0 {
|
||||
status = "okay";
|
||||
connect = <&vp0_out_hdmi0>;
|
||||
/delete-property/ force-output;
|
||||
/delete-node/ force_timing;
|
||||
};
|
||||
|
||||
&route_hdmi1 {
|
||||
status = "okay";
|
||||
connect = <&vp1_out_hdmi1>;
|
||||
/delete-property/ force-output;
|
||||
/delete-node/ force_timing;
|
||||
};
|
||||
|
||||
&vcc_1v8_s0 {
|
||||
/delete-property/ regulator-state-mem;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
&vcc_3v3_s0 {
|
||||
/delete-property/ regulator-state-mem;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,696 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
|
||||
/ {
|
||||
max96712_dcphy0_osc: max96712-dcphy0-oscillator {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "max96712-dcphy0-osc";
|
||||
};
|
||||
};
|
||||
|
||||
&mipi_dcphy0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&csi2_dcphy0 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi_dcphy0_in_max96712: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&max96712_dcphy0_out>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csidcphy0_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi0_csi2_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c8 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c8m2_xfer>;
|
||||
|
||||
max96712_dcphy0: max96712@29 {
|
||||
compatible = "maxim4c,max96712";
|
||||
status = "okay";
|
||||
reg = <0x29>;
|
||||
clock-names = "xvclk";
|
||||
clocks = <&max96712_dcphy0_osc 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&max96712_dcphy0_pwdn>, <&max96712_dcphy0_errb>, <&max96712_dcphy0_lock>;
|
||||
power-domains = <&power RK3588_PD_VI>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
pwdn-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
|
||||
pocen-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>;
|
||||
lock-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "max96712";
|
||||
rockchip,camera-module-lens-name = "max96712";
|
||||
|
||||
port {
|
||||
max96712_dcphy0_out: endpoint {
|
||||
remote-endpoint = <&mipi_dcphy0_in_max96712>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
|
||||
/* support mode config start */
|
||||
support-mode-config {
|
||||
status = "okay";
|
||||
|
||||
bus-format = <MEDIA_BUS_FMT_UYVY8_2X8>;
|
||||
sensor-width = <1280>;
|
||||
sensor-height = <800>;
|
||||
max-fps-numerator = <10000>;
|
||||
max-fps-denominator = <300000>;
|
||||
bpp = <16>;
|
||||
link-freq-idx = <12>;
|
||||
vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
|
||||
};
|
||||
/* support mode config end */
|
||||
|
||||
/* serdes local device start */
|
||||
serdes-local-device {
|
||||
status = "okay";
|
||||
|
||||
/* GMSL LINK config start */
|
||||
gmsl-links {
|
||||
status = "okay";
|
||||
|
||||
link-vdd-ldo1-en = <1>;
|
||||
link-vdd-ldo2-en = <1>;
|
||||
|
||||
// Link A: link-id = 0
|
||||
gmsl-link-config-0 {
|
||||
status = "okay";
|
||||
link-id = <0>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dcphy0_link0_in: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_remote0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
14 D1 03 00 00 // VGAHiGain
|
||||
14 45 00 00 00 // Disable SSC
|
||||
0B 06 ef 00 00 // HIM on
|
||||
0B 07 84 00 00 // Enable HVEN and DBL
|
||||
0B 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link B: link-id = 1
|
||||
gmsl-link-config-1 {
|
||||
status = "okay";
|
||||
link-id = <1>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dcphy0_link1_in: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_remote1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
15 D1 03 00 00 // VGAHiGain
|
||||
15 45 00 00 00 // Disable SSC
|
||||
0C 06 ef 00 00 // HIM on
|
||||
0C 07 84 00 00 // Enable HVEN and DBL
|
||||
0C 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link C: link-id = 2
|
||||
gmsl-link-config-2 {
|
||||
status = "okay";
|
||||
link-id = <2>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dcphy0_link2_in: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_remote2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
16 D1 03 00 00 // VGAHiGain
|
||||
16 45 00 00 00 // Disable SSC
|
||||
0D 06 ef 00 00 // HIM on
|
||||
0D 07 84 00 00 // Enable HVEN and DBL
|
||||
0D 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link D: link-id = 3
|
||||
gmsl-link-config-3 {
|
||||
status = "okay";
|
||||
link-id = <3>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dcphy0_link3_in: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_remote3_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
17 D1 03 00 00 // VGAHiGain
|
||||
17 45 00 00 00 // Disable SSC
|
||||
0E 06 ef 00 00 // HIM on
|
||||
0E 07 84 00 00 // Enable HVEN and DBL
|
||||
0E 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* GMSL LINK config end */
|
||||
|
||||
/* VIDEO PIPE config start */
|
||||
video-pipes {
|
||||
status = "okay";
|
||||
|
||||
// Video Pipe 0
|
||||
video-pipe-config-0 {
|
||||
status = "okay";
|
||||
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 0
|
||||
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 2D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
|
||||
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
|
||||
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 1
|
||||
video-pipe-config-1 {
|
||||
status = "okay";
|
||||
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 0
|
||||
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 6D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
|
||||
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
|
||||
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 2
|
||||
video-pipe-config-2 {
|
||||
status = "okay";
|
||||
pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <2>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 2 to Controller 0
|
||||
09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 AD 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit
|
||||
09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 90 80 00 00 // DST1 VC = 2, DT = Frame Start
|
||||
09 91 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 92 81 00 00 // DST2 VC = 2, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 3
|
||||
video-pipe-config-3 {
|
||||
status = "okay";
|
||||
pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <3>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 3 to Controller 0
|
||||
09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 ED 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit
|
||||
09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start
|
||||
09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Software override for parallel mode
|
||||
parallel-mode-config {
|
||||
status = "okay";
|
||||
|
||||
parallel-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8)
|
||||
04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode
|
||||
04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00
|
||||
04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00
|
||||
04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit
|
||||
04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit
|
||||
04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit
|
||||
04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 15 c0 c0 00 // pipe 0/1 enable software overide
|
||||
04 18 c0 c0 00 // pipe 2/3 enable software overide
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* VIDEO PIPE config end */
|
||||
|
||||
/* MIPI TXPHY config start */
|
||||
mipi-txphys {
|
||||
status = "okay";
|
||||
|
||||
phy-mode = <1>;
|
||||
phy-force-clock-out = <1>;
|
||||
phy-force-clk0-en = <0>;
|
||||
phy-force-clk3-en = <0>;
|
||||
|
||||
// MIPI TXPHY A: phy-id = 0
|
||||
mipi-txphy-config-0 {
|
||||
status = "okay";
|
||||
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x00>;
|
||||
data-lane-num = <2>;
|
||||
data-lane-map = <0x4>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
};
|
||||
/* MIPI TXPHY config end */
|
||||
|
||||
/* local device extra init sequence */
|
||||
extra-init-sequence {
|
||||
status = "disabled";
|
||||
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// common init sequence such as fsync / gpio and so on
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes local device end */
|
||||
|
||||
/* serdes remote device start */
|
||||
serdes-remote-device-0 {
|
||||
compatible = "maxim4c,link0,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <0>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x41>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dcphy0_remote0_out: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_link0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-1 {
|
||||
compatible = "maxim4c,link1,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <1>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x42>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dcphy0_remote1_out: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_link1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-2 {
|
||||
compatible = "maxim4c,link2,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <2>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x43>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dcphy0_remote2_out: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_link2_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-3 {
|
||||
compatible = "maxim4c,link3,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <3>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x44>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dcphy0_remote3_out: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy0_link3_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes remote device end */
|
||||
};
|
||||
};
|
||||
|
||||
&mipi0_csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi0_csi2_input: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&csidcphy0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi0_csi2_output: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&cif_mipi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif_mipi_lvds {
|
||||
status = "okay";
|
||||
/* parameters for do cif reset detecting:
|
||||
* index0: monitor mode,
|
||||
0 for idle,
|
||||
1 for continue,
|
||||
2 for trigger,
|
||||
3 for hotplug (for nextchip)
|
||||
* index1: the frame id to start timer,
|
||||
min is 2
|
||||
* index2: frame num of monitoring cycle
|
||||
* index3: err time for keep monitoring
|
||||
after finding out err (ms)
|
||||
* index4: csi2 err reference val for resetting
|
||||
*/
|
||||
rockchip,cif-monitor = <3 2 1 1000 5>;
|
||||
|
||||
port {
|
||||
cif_mipi0_in: endpoint {
|
||||
remote-endpoint = <&mipi0_csi2_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif {
|
||||
status = "okay";
|
||||
rockchip,android-usb-camerahal-enable;
|
||||
};
|
||||
|
||||
&rkcif_mmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
max96712-dcphy0 {
|
||||
max96712_dcphy0_pwdn: max96712-dcphy0-pwdn {
|
||||
rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dcphy0_errb: max96712-dcphy0-errb {
|
||||
rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dcphy0_lock: max96712-dcphy0-lock {
|
||||
rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,466 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
|
||||
/ {
|
||||
max96712_dcphy1_osc: max96712-dcphy1-oscillator {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "max96712-dcphy1-osc";
|
||||
};
|
||||
};
|
||||
|
||||
&mipi_dcphy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&csi2_dcphy1 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi_dcphy1_in_max96712: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&max96712_dcphy1_out>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csidcphy1_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi1_csi2_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c2m4_xfer>;
|
||||
|
||||
max96712_dcphy1: max96712@29 {
|
||||
compatible = "maxim4c,max96712";
|
||||
status = "okay";
|
||||
reg = <0x29>;
|
||||
clock-names = "xvclk";
|
||||
clocks = <&max96712_dcphy1_osc 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&max96712_dcphy1_pwdn>, <&max96712_dcphy1_errb>, <&max96712_dcphy1_lock>;
|
||||
power-domains = <&power RK3588_PD_VI>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
pwdn-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>;
|
||||
pocen-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
|
||||
lock-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "max96712";
|
||||
rockchip,camera-module-lens-name = "max96712";
|
||||
|
||||
port {
|
||||
max96712_dcphy1_out: endpoint {
|
||||
remote-endpoint = <&mipi_dcphy1_in_max96712>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
|
||||
/* support mode config start */
|
||||
support-mode-config {
|
||||
status = "okay";
|
||||
|
||||
bus-format = <MEDIA_BUS_FMT_UYVY8_2X8>;
|
||||
sensor-width = <1600>;
|
||||
sensor-height = <1300>;
|
||||
max-fps-numerator = <10000>;
|
||||
max-fps-denominator = <300000>;
|
||||
bpp = <16>;
|
||||
link-freq-idx = <20>;
|
||||
vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
|
||||
};
|
||||
/* support mode config end */
|
||||
|
||||
/* serdes local device start */
|
||||
serdes-local-device {
|
||||
status = "okay";
|
||||
|
||||
/* GMSL LINK config start */
|
||||
gmsl-links {
|
||||
status = "okay";
|
||||
|
||||
link-vdd-ldo1-en = <1>;
|
||||
link-vdd-ldo2-en = <1>;
|
||||
|
||||
// Link A: link-id = 0
|
||||
gmsl-link-config-0 {
|
||||
status = "okay";
|
||||
link-id = <0>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dcphy1_link0_in: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy1_remote0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
14 D1 03 00 00 // VGAHiGain
|
||||
14 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link B: link-id = 1
|
||||
gmsl-link-config-1 {
|
||||
status = "okay";
|
||||
link-id = <1>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dcphy1_link1_in: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy1_remote1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
15 D1 03 00 00 // VGAHiGain
|
||||
15 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* GMSL LINK config end */
|
||||
|
||||
/* VIDEO PIPE config start */
|
||||
video-pipes {
|
||||
status = "okay";
|
||||
|
||||
// Video Pipe 0
|
||||
video-pipe-config-0 {
|
||||
status = "okay";
|
||||
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 0
|
||||
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 2D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
|
||||
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
|
||||
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
|
||||
// pipe Cross
|
||||
01 D9 59 00 00 // pipe 0: Inverts Cross VS
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 1
|
||||
video-pipe-config-1 {
|
||||
status = "okay";
|
||||
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 0
|
||||
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 6D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
|
||||
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
|
||||
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
|
||||
// pipe Cross
|
||||
01 F9 59 00 00 // pipe 1: Inverts Cross VS
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Software override for parallel mode
|
||||
parallel-mode-config {
|
||||
status = "okay";
|
||||
|
||||
parallel-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8)
|
||||
04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode
|
||||
04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00
|
||||
04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00
|
||||
04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit
|
||||
04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit
|
||||
04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit
|
||||
04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 15 c0 c0 00 // pipe 0/1 enable software overide
|
||||
04 18 c0 c0 00 // pipe 2/3 enable software overide
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* VIDEO PIPE config end */
|
||||
|
||||
/* MIPI TXPHY config start */
|
||||
mipi-txphys {
|
||||
status = "okay";
|
||||
|
||||
phy-mode = <1>;
|
||||
phy-force-clock-out = <1>;
|
||||
phy-force-clk0-en = <0>;
|
||||
phy-force-clk3-en = <0>;
|
||||
|
||||
// MIPI TXPHY A: phy-id = 0
|
||||
mipi-txphy-config-0 {
|
||||
status = "okay";
|
||||
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x00>;
|
||||
data-lane-num = <2>;
|
||||
data-lane-map = <0x4>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
};
|
||||
/* MIPI TXPHY config end */
|
||||
|
||||
/* local device extra init sequence */
|
||||
extra-init-sequence {
|
||||
status = "disabled";
|
||||
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// common init sequence such as fsync / gpio and so on
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes local device end */
|
||||
|
||||
/* serdes remote device start */
|
||||
serdes-remote-device-0 {
|
||||
compatible = "maxim4c,link0,max9295";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <0>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x41>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dcphy1_remote0_out: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy1_link0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps
|
||||
00 11 03 00 00 // Coax Drive
|
||||
02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1
|
||||
03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL
|
||||
00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL
|
||||
00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected
|
||||
02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0
|
||||
02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup
|
||||
00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable
|
||||
00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled
|
||||
00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE
|
||||
01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high
|
||||
01 01 50 00 00 // Video X, BPP = 0x10
|
||||
00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel
|
||||
00 02 13 00 00 // Video transmit enable for Port X
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-1 {
|
||||
compatible = "maxim4c,link1,max9295";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <1>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x42>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dcphy1_remote1_out: endpoint {
|
||||
remote-endpoint = <&max96712_dcphy1_link1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps
|
||||
00 11 03 00 00 // Coax Drive
|
||||
02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1
|
||||
03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL
|
||||
00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL
|
||||
00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected
|
||||
02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0
|
||||
02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup
|
||||
00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable
|
||||
00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled
|
||||
00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE
|
||||
01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high
|
||||
01 01 50 00 00 // Video X, BPP = 0x10
|
||||
00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel
|
||||
00 02 13 00 00 // Video transmit enable for Port X
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes remote device end */
|
||||
};
|
||||
};
|
||||
|
||||
&mipi1_csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi1_csi2_input: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&csidcphy1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi1_csi2_output: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&cif_mipi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif_mipi_lvds1 {
|
||||
status = "okay";
|
||||
/* parameters for do cif reset detecting:
|
||||
* index0: monitor mode,
|
||||
0 for idle,
|
||||
1 for continue,
|
||||
2 for trigger,
|
||||
3 for hotplug (for nextchip)
|
||||
* index1: the frame id to start timer,
|
||||
min is 2
|
||||
* index2: frame num of monitoring cycle
|
||||
* index3: err time for keep monitoring
|
||||
after finding out err (ms)
|
||||
* index4: csi2 err reference val for resetting
|
||||
*/
|
||||
rockchip,cif-monitor = <3 2 1 1000 5>;
|
||||
|
||||
port {
|
||||
cif_mipi1_in: endpoint {
|
||||
remote-endpoint = <&mipi1_csi2_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif {
|
||||
status = "okay";
|
||||
rockchip,android-usb-camerahal-enable;
|
||||
};
|
||||
|
||||
&rkcif_mmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
max96712-dcphy1 {
|
||||
max96712_dcphy1_pwdn: max96712-dcphy1-pwdn {
|
||||
rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dcphy1_errb: max96712-dcphy1-errb {
|
||||
rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dcphy1_lock: max96712-dcphy1-lock {
|
||||
rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,708 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
|
||||
/ {
|
||||
max96712_dphy0_osc0: max96712-dphy0-oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "max96712-dphy0-osc0";
|
||||
};
|
||||
};
|
||||
|
||||
&csi2_dphy0_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&csi2_dphy0 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi_dphy0_in_max96712: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&max96712_dphy0_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csidphy0_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi2_csi2_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c7 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c7m3_xfer>;
|
||||
|
||||
max96712_dphy0: max96712@29 {
|
||||
compatible = "maxim4c,max96712";
|
||||
status = "okay";
|
||||
reg = <0x29>;
|
||||
clock-names = "xvclk";
|
||||
clocks = <&max96712_dphy0_osc0 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&max96712_dphy0_pwdn>, <&max96712_dphy0_errb>, <&max96712_dphy0_lock>;
|
||||
power-domains = <&power RK3588_PD_VI>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
|
||||
pocen-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
|
||||
lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "max96712";
|
||||
rockchip,camera-module-lens-name = "max96712";
|
||||
|
||||
port {
|
||||
max96712_dphy0_out: endpoint {
|
||||
remote-endpoint = <&mipi_dphy0_in_max96712>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
|
||||
/* support mode config start */
|
||||
support-mode-config {
|
||||
status = "okay";
|
||||
|
||||
bus-format = <MEDIA_BUS_FMT_UYVY8_2X8>;
|
||||
sensor-width = <1280>;
|
||||
sensor-height = <800>;
|
||||
max-fps-numerator = <10000>;
|
||||
max-fps-denominator = <300000>;
|
||||
bpp = <16>;
|
||||
link-freq-idx = <20>;
|
||||
vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
|
||||
};
|
||||
/* support mode config end */
|
||||
|
||||
/* serdes local device start */
|
||||
serdes-local-device {
|
||||
status = "okay";
|
||||
|
||||
/* GMSL LINK config start */
|
||||
gmsl-links {
|
||||
status = "okay";
|
||||
|
||||
link-vdd-ldo1-en = <1>;
|
||||
link-vdd-ldo2-en = <1>;
|
||||
|
||||
// Link A: link-id = 0
|
||||
gmsl-link-config-0 {
|
||||
status = "okay";
|
||||
link-id = <0>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy0_link0_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_remote0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
14 D1 03 00 00 // VGAHiGain
|
||||
14 45 00 00 00 // Disable SSC
|
||||
0B 06 ef 00 00 // HIM on
|
||||
0B 07 84 00 00 // Enable HVEN and DBL
|
||||
0B 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link B: link-id = 1
|
||||
gmsl-link-config-1 {
|
||||
status = "okay";
|
||||
link-id = <1>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy0_link1_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_remote1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
15 D1 03 00 00 // VGAHiGain
|
||||
15 45 00 00 00 // Disable SSC
|
||||
0C 06 ef 00 00 // HIM on
|
||||
0C 07 84 00 00 // Enable HVEN and DBL
|
||||
0C 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link C: link-id = 2
|
||||
gmsl-link-config-2 {
|
||||
status = "okay";
|
||||
link-id = <2>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy0_link2_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_remote2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
16 D1 03 00 00 // VGAHiGain
|
||||
16 45 00 00 00 // Disable SSC
|
||||
0D 06 ef 00 00 // HIM on
|
||||
0D 07 84 00 00 // Enable HVEN and DBL
|
||||
0D 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link D: link-id = 3
|
||||
gmsl-link-config-3 {
|
||||
status = "okay";
|
||||
link-id = <3>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy0_link3_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_remote3_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
17 D1 03 00 00 // VGAHiGain
|
||||
17 45 00 00 00 // Disable SSC
|
||||
0E 06 ef 00 00 // HIM on
|
||||
0E 07 84 00 00 // Enable HVEN and DBL
|
||||
0E 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* GMSL LINK config end */
|
||||
|
||||
/* VIDEO PIPE config start */
|
||||
video-pipes {
|
||||
status = "okay";
|
||||
|
||||
// Video Pipe 0
|
||||
video-pipe-config-0 {
|
||||
status = "okay";
|
||||
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 1
|
||||
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
|
||||
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
|
||||
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 1
|
||||
video-pipe-config-1 {
|
||||
status = "okay";
|
||||
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 1
|
||||
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
|
||||
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
|
||||
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 2
|
||||
video-pipe-config-2 {
|
||||
status = "okay";
|
||||
pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <2>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 2 to Controller 1
|
||||
09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit
|
||||
09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 90 80 00 00 // DST1 VC = 2, DT = Frame Start
|
||||
09 91 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 92 81 00 00 // DST2 VC = 2, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 3
|
||||
video-pipe-config-3 {
|
||||
status = "okay";
|
||||
pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <3>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 3 to Controller 1
|
||||
09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit
|
||||
09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start
|
||||
09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Software override for parallel mode
|
||||
parallel-mode-config {
|
||||
status = "okay";
|
||||
|
||||
parallel-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8)
|
||||
04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode
|
||||
04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00
|
||||
04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00
|
||||
04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit
|
||||
04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit
|
||||
04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit
|
||||
04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 15 c0 c0 00 // pipe 0/1 enable software overide
|
||||
04 18 c0 c0 00 // pipe 2/3 enable software overide
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* VIDEO PIPE config end */
|
||||
|
||||
/* MIPI TXPHY config start */
|
||||
mipi-txphys {
|
||||
status = "okay";
|
||||
|
||||
phy-mode = <0>;
|
||||
phy-force-clock-out = <1>;
|
||||
phy-force-clk0-en = <1>;
|
||||
phy-force-clk3-en = <0>;
|
||||
|
||||
// MIPI TXPHY A: phy-id = 0
|
||||
mipi-txphy-config-0 {
|
||||
status = "okay";
|
||||
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0x4>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
|
||||
// MIPI TXPHY B: phy-id = 1
|
||||
mipi-txphy-config-1 {
|
||||
status = "okay";
|
||||
phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0xe>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
};
|
||||
/* MIPI TXPHY config end */
|
||||
|
||||
/* local device extra init sequence */
|
||||
extra-init-sequence {
|
||||
status = "disabled";
|
||||
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// common init sequence such as fsync / gpio and so on
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes local device end */
|
||||
|
||||
/* serdes remote device start */
|
||||
serdes-remote-device-0 {
|
||||
compatible = "maxim4c,link0,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <0>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x41>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy0_remote0_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_link0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-1 {
|
||||
compatible = "maxim4c,link1,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <1>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x42>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy0_remote1_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_link1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-2 {
|
||||
compatible = "maxim4c,link2,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <2>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x43>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy0_remote2_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_link2_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-3 {
|
||||
compatible = "maxim4c,link3,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <3>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x44>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy0_remote3_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy0_link3_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes remote device end */
|
||||
};
|
||||
};
|
||||
|
||||
&mipi2_csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi2_csi2_input: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&csidphy0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi2_csi2_output: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&cif_mipi2_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif_mipi_lvds2 {
|
||||
status = "okay";
|
||||
/* parameters for do cif reset detecting:
|
||||
* index0: monitor mode,
|
||||
0 for idle,
|
||||
1 for continue,
|
||||
2 for trigger,
|
||||
3 for hotplug (for nextchip)
|
||||
* index1: the frame id to start timer,
|
||||
min is 2
|
||||
* index2: frame num of monitoring cycle
|
||||
* index3: err time for keep monitoring
|
||||
after finding out err (ms)
|
||||
* index4: csi2 err reference val for resetting
|
||||
*/
|
||||
rockchip,cif-monitor = <3 2 1 1000 5>;
|
||||
|
||||
port {
|
||||
cif_mipi2_in: endpoint {
|
||||
remote-endpoint = <&mipi2_csi2_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif {
|
||||
status = "okay";
|
||||
rockchip,android-usb-camerahal-enable;
|
||||
};
|
||||
|
||||
&rkcif_mmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
max96712-dphy0 {
|
||||
max96712_dphy0_pwdn: max96712-dphy0-pwdn {
|
||||
rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dphy0_errb: max96712-dphy0-errb {
|
||||
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dphy0_lock: max96712-dphy0-lock {
|
||||
rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,613 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
|
||||
/ {
|
||||
max96712_dphy3_osc0: max96712-dphy3-oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "max96712-dphy3-osc0";
|
||||
};
|
||||
};
|
||||
|
||||
&csi2_dphy1_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&csi2_dphy3 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi_dphy3_in_max96712: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&max96712_dphy3_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csidphy3_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi4_csi2_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c6 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c6m3_xfer>;
|
||||
|
||||
max96712_dphy3: max96712@29 {
|
||||
compatible = "maxim4c,max96712";
|
||||
status = "okay";
|
||||
reg = <0x29>;
|
||||
clock-names = "xvclk";
|
||||
clocks = <&max96712_dphy3_osc0 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&max96712_dphy3_pwdn>, <&max96712_dphy3_errb>, <&max96712_dphy3_lock>;
|
||||
power-domains = <&power RK3588_PD_VI>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
pwdn-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
|
||||
pocen-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
|
||||
lock-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "max96712";
|
||||
rockchip,camera-module-lens-name = "max96712";
|
||||
|
||||
port {
|
||||
max96712_dphy3_out: endpoint {
|
||||
remote-endpoint = <&mipi_dphy3_in_max96712>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
|
||||
/* support mode config start */
|
||||
support-mode-config {
|
||||
status = "okay";
|
||||
|
||||
bus-format = <MEDIA_BUS_FMT_UYVY8_2X8>;
|
||||
sensor-width = <1920>;
|
||||
sensor-height = <1440>;
|
||||
max-fps-numerator = <10000>;
|
||||
max-fps-denominator = <300000>;
|
||||
bpp = <16>;
|
||||
link-freq-idx = <20>;
|
||||
vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
|
||||
};
|
||||
/* support mode config end */
|
||||
|
||||
/* serdes local device start */
|
||||
serdes-local-device {
|
||||
status = "okay";
|
||||
|
||||
/* GMSL LINK config start */
|
||||
gmsl-links {
|
||||
status = "okay";
|
||||
|
||||
link-vdd-ldo1-en = <1>;
|
||||
link-vdd-ldo2-en = <1>;
|
||||
|
||||
// Link A: link-id = 0
|
||||
gmsl-link-config-0 {
|
||||
status = "okay";
|
||||
link-id = <0>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <1>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy3_link0_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_remote0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
14 D1 03 00 00 // VGAHiGain
|
||||
14 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link B: link-id = 1
|
||||
gmsl-link-config-1 {
|
||||
status = "okay";
|
||||
link-id = <1>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <1>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy3_link1_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_remote1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
15 D1 03 00 00 // VGAHiGain
|
||||
15 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link C: link-id = 2
|
||||
gmsl-link-config-2 {
|
||||
status = "okay";
|
||||
link-id = <2>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <1>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy3_link2_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_remote2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
16 D1 03 00 00 // VGAHiGain
|
||||
16 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link D: link-id = 3
|
||||
gmsl-link-config-3 {
|
||||
status = "okay";
|
||||
link-id = <3>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <1>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96712_dphy3_link3_in: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_remote3_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
17 D1 03 00 00 // VGAHiGain
|
||||
17 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* GMSL LINK config end */
|
||||
|
||||
/* VIDEO PIPE config start */
|
||||
video-pipes {
|
||||
status = "okay";
|
||||
|
||||
// Video Pipe 0
|
||||
video-pipe-config-0 {
|
||||
status = "okay";
|
||||
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 1
|
||||
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
|
||||
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
|
||||
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 1
|
||||
video-pipe-config-1 {
|
||||
status = "okay";
|
||||
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
|
||||
|
||||
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 1
|
||||
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
|
||||
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
|
||||
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 2
|
||||
video-pipe-config-2 {
|
||||
status = "okay";
|
||||
pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <2>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 2 to Controller 1
|
||||
09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit
|
||||
09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 90 80 00 00 // DST1 VC = 2, DT = Frame Start
|
||||
09 91 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 92 81 00 00 // DST2 VC = 2, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 3
|
||||
video-pipe-config-3 {
|
||||
status = "okay";
|
||||
pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <3>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 3 to Controller 1
|
||||
09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit
|
||||
09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start
|
||||
09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* VIDEO PIPE config end */
|
||||
|
||||
/* MIPI TXPHY config start */
|
||||
mipi-txphys {
|
||||
status = "okay";
|
||||
|
||||
phy-mode = <0>;
|
||||
phy-force-clock-out = <1>;
|
||||
phy-force-clk0-en = <1>;
|
||||
phy-force-clk3-en = <0>;
|
||||
|
||||
// MIPI TXPHY A: phy-id = 0
|
||||
mipi-txphy-config-0 {
|
||||
status = "okay";
|
||||
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0x4>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
|
||||
// MIPI TXPHY B: phy-id = 1
|
||||
mipi-txphy-config-1 {
|
||||
status = "okay";
|
||||
phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0xe>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
};
|
||||
/* MIPI TXPHY config end */
|
||||
|
||||
/* local device extra init sequence */
|
||||
extra-init-sequence {
|
||||
status = "disabled";
|
||||
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// common init sequence such as fsync / gpio and so on
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes local device end */
|
||||
|
||||
/* serdes remote device start */
|
||||
serdes-remote-device-0 {
|
||||
compatible = "maxim4c,link0,max96717";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <0>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x41>; // 0: disable remap
|
||||
|
||||
// Camera i2c 7bit address remap
|
||||
cam-i2c-addr-def = <0x30>;
|
||||
cam-i2c-addr-map = <0x31>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy3_remote0_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_link0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
03 02 10 00 00
|
||||
14 17 00 00 00
|
||||
14 32 7f 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-1 {
|
||||
compatible = "maxim4c,link1,max96717";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <1>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x42>; // 0: disable remap
|
||||
|
||||
// Camera i2c 7bit address remap
|
||||
cam-i2c-addr-def = <0x30>;
|
||||
cam-i2c-addr-map = <0x32>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy3_remote1_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_link1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
03 02 10 00 00
|
||||
14 17 00 00 00
|
||||
14 32 7f 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-2 {
|
||||
compatible = "maxim4c,link2,max96717";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <2>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x43>; // 0: disable remap
|
||||
|
||||
// Camera i2c 7bit address remap
|
||||
cam-i2c-addr-def = <0x30>;
|
||||
cam-i2c-addr-map = <0x33>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy3_remote2_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_link2_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
03 02 10 00 00
|
||||
14 17 00 00 00
|
||||
14 32 7f 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-3 {
|
||||
compatible = "maxim4c,link3,max96717";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <3>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x44>; // 0: disable remap
|
||||
|
||||
// Camera i2c 7bit address remap
|
||||
cam-i2c-addr-def = <0x30>;
|
||||
cam-i2c-addr-map = <0x34>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96712_dphy3_remote3_out: endpoint {
|
||||
remote-endpoint = <&max96712_dphy3_link3_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
03 02 10 00 00
|
||||
14 17 00 00 00
|
||||
14 32 7f 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes remote device end */
|
||||
};
|
||||
};
|
||||
|
||||
&mipi4_csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi4_csi2_input: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&csidphy3_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi4_csi2_output: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&cif_mipi4_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif_mipi_lvds4 {
|
||||
status = "okay";
|
||||
/* parameters for do cif reset detecting:
|
||||
* index0: monitor mode,
|
||||
0 for idle,
|
||||
1 for continue,
|
||||
2 for trigger,
|
||||
3 for hotplug (for nextchip)
|
||||
* index1: the frame id to start timer,
|
||||
min is 2
|
||||
* index2: frame num of monitoring cycle
|
||||
* index3: err time for keep monitoring
|
||||
after finding out err (ms)
|
||||
* index4: csi2 err reference val for resetting
|
||||
*/
|
||||
rockchip,cif-monitor = <3 2 1 1000 5>;
|
||||
|
||||
port {
|
||||
cif_mipi4_in: endpoint {
|
||||
remote-endpoint = <&mipi4_csi2_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif {
|
||||
status = "okay";
|
||||
rockchip,android-usb-camerahal-enable;
|
||||
};
|
||||
|
||||
&rkcif_mmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
max96712-dphy3 {
|
||||
max96712_dphy3_pwdn: max96712-dphy3-pwdn {
|
||||
rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dphy3_errb: max96712-dphy3-errb {
|
||||
rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dphy3_lock: max96712-dphy3-lock {
|
||||
rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,708 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
|
||||
/ {
|
||||
max96722_dphy0_osc0: max96722-dphy0-oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "max96722-dphy0-osc0";
|
||||
};
|
||||
};
|
||||
|
||||
&csi2_dphy0_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&csi2_dphy0 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi_dphy0_in_max96722: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&max96722_dphy0_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csidphy0_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi2_csi2_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c7 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c7m3_xfer>;
|
||||
|
||||
max96722_dphy0: max96722@29 {
|
||||
compatible = "maxim4c,max96722";
|
||||
status = "okay";
|
||||
reg = <0x29>;
|
||||
clock-names = "xvclk";
|
||||
clocks = <&max96722_dphy0_osc0 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&max96722_dphy0_pwdn>, <&max96722_dphy0_errb>, <&max96722_dphy0_lock>;
|
||||
power-domains = <&power RK3588_PD_VI>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
|
||||
pocen-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
|
||||
lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "max96722";
|
||||
rockchip,camera-module-lens-name = "max96722";
|
||||
|
||||
port {
|
||||
max96722_dphy0_out: endpoint {
|
||||
remote-endpoint = <&mipi_dphy0_in_max96722>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
|
||||
/* support mode config start */
|
||||
support-mode-config {
|
||||
status = "okay";
|
||||
|
||||
bus-format = <MEDIA_BUS_FMT_UYVY8_2X8>;
|
||||
sensor-width = <1280>;
|
||||
sensor-height = <800>;
|
||||
max-fps-numerator = <10000>;
|
||||
max-fps-denominator = <300000>;
|
||||
bpp = <16>;
|
||||
link-freq-idx = <20>;
|
||||
vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
|
||||
};
|
||||
/* support mode config end */
|
||||
|
||||
/* serdes local device start */
|
||||
serdes-local-device {
|
||||
status = "okay";
|
||||
|
||||
/* GMSL LINK config start */
|
||||
gmsl-links {
|
||||
status = "okay";
|
||||
|
||||
link-vdd-ldo1-en = <1>;
|
||||
link-vdd-ldo2-en = <1>;
|
||||
|
||||
// Link A: link-id = 0
|
||||
gmsl-link-config-0 {
|
||||
status = "okay";
|
||||
link-id = <0>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96722_dphy0_link0_in: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_remote0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
14 D1 03 00 00 // VGAHiGain
|
||||
14 45 00 00 00 // Disable SSC
|
||||
0B 06 ef 00 00 // HIM on
|
||||
0B 07 84 00 00 // Enable HVEN and DBL
|
||||
0B 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link B: link-id = 1
|
||||
gmsl-link-config-1 {
|
||||
status = "okay";
|
||||
link-id = <1>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96722_dphy0_link1_in: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_remote1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
15 D1 03 00 00 // VGAHiGain
|
||||
15 45 00 00 00 // Disable SSC
|
||||
0C 06 ef 00 00 // HIM on
|
||||
0C 07 84 00 00 // Enable HVEN and DBL
|
||||
0C 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link C: link-id = 2
|
||||
gmsl-link-config-2 {
|
||||
status = "okay";
|
||||
link-id = <2>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96722_dphy0_link2_in: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_remote2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
16 D1 03 00 00 // VGAHiGain
|
||||
16 45 00 00 00 // Disable SSC
|
||||
0D 06 ef 00 00 // HIM on
|
||||
0D 07 84 00 00 // Enable HVEN and DBL
|
||||
0D 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link D: link-id = 3
|
||||
gmsl-link-config-3 {
|
||||
status = "okay";
|
||||
link-id = <3>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <0>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96722_dphy0_link3_in: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_remote3_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
17 D1 03 00 00 // VGAHiGain
|
||||
17 45 00 00 00 // Disable SSC
|
||||
0E 06 ef 00 00 // HIM on
|
||||
0E 07 84 00 00 // Enable HVEN and DBL
|
||||
0E 0F 01 00 00 // Disable processing DE signals
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* GMSL LINK config end */
|
||||
|
||||
/* VIDEO PIPE config start */
|
||||
video-pipes {
|
||||
status = "okay";
|
||||
|
||||
// Video Pipe 0
|
||||
video-pipe-config-0 {
|
||||
status = "okay";
|
||||
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 1
|
||||
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
|
||||
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
|
||||
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 1
|
||||
video-pipe-config-1 {
|
||||
status = "okay";
|
||||
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 1
|
||||
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
|
||||
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
|
||||
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 2
|
||||
video-pipe-config-2 {
|
||||
status = "okay";
|
||||
pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <2>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 2 to Controller 1
|
||||
09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit
|
||||
09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 90 80 00 00 // DST1 VC = 2, DT = Frame Start
|
||||
09 91 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 92 81 00 00 // DST2 VC = 2, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 3
|
||||
video-pipe-config-3 {
|
||||
status = "okay";
|
||||
pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <3>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 3 to Controller 1
|
||||
09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit
|
||||
09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start
|
||||
09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Software override for parallel mode
|
||||
parallel-mode-config {
|
||||
status = "okay";
|
||||
|
||||
parallel-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8)
|
||||
04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode
|
||||
04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00
|
||||
04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00
|
||||
04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit
|
||||
04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit
|
||||
04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit
|
||||
04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 15 c0 c0 00 // pipe 0/1 enable software overide
|
||||
04 18 c0 c0 00 // pipe 2/3 enable software overide
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* VIDEO PIPE config end */
|
||||
|
||||
/* MIPI TXPHY config start */
|
||||
mipi-txphys {
|
||||
status = "okay";
|
||||
|
||||
phy-mode = <0>;
|
||||
phy-force-clock-out = <1>;
|
||||
phy-force-clk0-en = <1>;
|
||||
phy-force-clk3-en = <0>;
|
||||
|
||||
// MIPI TXPHY A: phy-id = 0
|
||||
mipi-txphy-config-0 {
|
||||
status = "okay";
|
||||
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0x4>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
|
||||
// MIPI TXPHY B: phy-id = 1
|
||||
mipi-txphy-config-1 {
|
||||
status = "okay";
|
||||
phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0xe>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
};
|
||||
/* MIPI TXPHY config end */
|
||||
|
||||
/* local device extra init sequence */
|
||||
extra-init-sequence {
|
||||
status = "disabled";
|
||||
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// common init sequence such as fsync / gpio and so on
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes local device end */
|
||||
|
||||
/* serdes remote device start */
|
||||
serdes-remote-device-0 {
|
||||
compatible = "maxim4c,link0,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <0>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x41>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96722_dphy0_remote0_out: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_link0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-1 {
|
||||
compatible = "maxim4c,link1,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <1>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x42>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96722_dphy0_remote1_out: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_link1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-2 {
|
||||
compatible = "maxim4c,link2,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <2>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x43>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96722_dphy0_remote2_out: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_link2_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-3 {
|
||||
compatible = "maxim4c,link3,max96715";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <3>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x44>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96722_dphy0_remote3_out: endpoint {
|
||||
remote-endpoint = <&max96722_dphy0_link3_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <1>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
07 84 00 00
|
||||
67 c4 00 00
|
||||
0F bf 00 00
|
||||
3F 08 00 00
|
||||
40 2d 00 00
|
||||
20 10 00 00
|
||||
21 11 00 00
|
||||
22 12 00 00
|
||||
23 13 00 00
|
||||
24 14 00 00
|
||||
25 15 00 00
|
||||
26 16 00 00
|
||||
27 17 00 00
|
||||
30 00 00 00
|
||||
31 01 00 00
|
||||
32 02 00 00
|
||||
33 03 00 00
|
||||
34 04 00 00
|
||||
35 05 00 00
|
||||
36 06 00 00
|
||||
37 07 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes remote device end */
|
||||
};
|
||||
};
|
||||
|
||||
&mipi2_csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi2_csi2_input: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&csidphy0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi2_csi2_output: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&cif_mipi2_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif_mipi_lvds2 {
|
||||
status = "okay";
|
||||
/* parameters for do cif reset detecting:
|
||||
* index0: monitor mode,
|
||||
0 for idle,
|
||||
1 for continue,
|
||||
2 for trigger,
|
||||
3 for hotplug (for nextchip)
|
||||
* index1: the frame id to start timer,
|
||||
min is 2
|
||||
* index2: frame num of monitoring cycle
|
||||
* index3: err time for keep monitoring
|
||||
after finding out err (ms)
|
||||
* index4: csi2 err reference val for resetting
|
||||
*/
|
||||
rockchip,cif-monitor = <3 2 1 1000 5>;
|
||||
|
||||
port {
|
||||
cif_mipi2_in: endpoint {
|
||||
remote-endpoint = <&mipi2_csi2_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif {
|
||||
status = "okay";
|
||||
rockchip,android-usb-camerahal-enable;
|
||||
};
|
||||
|
||||
&rkcif_mmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
max96722-dphy0 {
|
||||
max96722_dphy0_pwdn: max96722-dphy0-pwdn {
|
||||
rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96722_dphy0_errb: max96722-dphy0-errb {
|
||||
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96722_dphy0_lock: max96722-dphy0-lock {
|
||||
rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
#include <dt-bindings/display/media-bus-format.h>
|
||||
|
||||
/ {
|
||||
max96722_dphy3_osc0: max96722-dphy3-oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "max96722-dphy3-osc0";
|
||||
};
|
||||
};
|
||||
|
||||
&csi2_dphy1_hw {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&csi2_dphy3 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi_dphy3_in_max96722: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&max96722_dphy3_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csidphy3_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi4_csi2_input>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c6 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c6m3_xfer>;
|
||||
|
||||
max96722_dphy3: max96722@29 {
|
||||
compatible = "maxim4c,max96722";
|
||||
status = "okay";
|
||||
reg = <0x29>;
|
||||
clock-names = "xvclk";
|
||||
clocks = <&max96722_dphy3_osc0 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&max96722_dphy3_pwdn>, <&max96722_dphy3_errb>, <&max96722_dphy3_lock>;
|
||||
power-domains = <&power RK3588_PD_VI>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
pwdn-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
|
||||
pocen-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
|
||||
lock-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "max96722";
|
||||
rockchip,camera-module-lens-name = "max96722";
|
||||
|
||||
port {
|
||||
max96722_dphy3_out: endpoint {
|
||||
remote-endpoint = <&mipi_dphy3_in_max96722>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
|
||||
/* support mode config start */
|
||||
support-mode-config {
|
||||
status = "okay";
|
||||
|
||||
bus-format = <MEDIA_BUS_FMT_UYVY8_2X8>;
|
||||
sensor-width = <1600>;
|
||||
sensor-height = <1300>;
|
||||
max-fps-numerator = <10000>;
|
||||
max-fps-denominator = <300000>;
|
||||
bpp = <16>;
|
||||
link-freq-idx = <20>;
|
||||
vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
|
||||
};
|
||||
/* support mode config end */
|
||||
|
||||
/* serdes local device start */
|
||||
serdes-local-device {
|
||||
status = "okay";
|
||||
|
||||
/* GMSL LINK config start */
|
||||
gmsl-links {
|
||||
status = "okay";
|
||||
|
||||
link-vdd-ldo1-en = <1>;
|
||||
link-vdd-ldo2-en = <1>;
|
||||
|
||||
// Link A: link-id = 0
|
||||
gmsl-link-config-0 {
|
||||
status = "okay";
|
||||
link-id = <0>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96722_dphy3_link0_in: endpoint {
|
||||
remote-endpoint = <&max96722_dphy3_remote0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
14 D1 03 00 00 // VGAHiGain
|
||||
14 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Link B: link-id = 1
|
||||
gmsl-link-config-1 {
|
||||
status = "okay";
|
||||
link-id = <1>; // Link ID: 0/1/2/3
|
||||
|
||||
link-type = <1>;
|
||||
link-rx-rate = <0>;
|
||||
link-tx-rate = <0>;
|
||||
|
||||
port {
|
||||
max96722_dphy3_link1_in: endpoint {
|
||||
remote-endpoint = <&max96722_dphy3_remote1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
link-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
15 D1 03 00 00 // VGAHiGain
|
||||
15 45 00 00 00 // Disable SSC
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* GMSL LINK config end */
|
||||
|
||||
/* VIDEO PIPE config start */
|
||||
video-pipes {
|
||||
status = "okay";
|
||||
|
||||
// Video Pipe 0
|
||||
video-pipe-config-0 {
|
||||
status = "okay";
|
||||
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 1
|
||||
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
|
||||
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
|
||||
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
|
||||
// pipe Cross
|
||||
01 D9 59 00 00 // pipe 0: Inverts Cross VS
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Video Pipe 1
|
||||
video-pipe-config-1 {
|
||||
status = "okay";
|
||||
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
|
||||
|
||||
pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3
|
||||
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
|
||||
|
||||
pipe-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 1
|
||||
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
|
||||
09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
|
||||
// For the following MSB 2 bits = VC, LSB 6 bits = DT
|
||||
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
|
||||
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
|
||||
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
|
||||
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
|
||||
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
|
||||
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
|
||||
// pipe Cross
|
||||
01 F9 59 00 00 // pipe 1: Inverts Cross VS
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
// Software override for parallel mode
|
||||
parallel-mode-config {
|
||||
status = "okay";
|
||||
|
||||
parallel-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8)
|
||||
04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode
|
||||
04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00
|
||||
04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00
|
||||
04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit
|
||||
04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit
|
||||
04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit
|
||||
04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37
|
||||
04 15 c0 c0 00 // pipe 0/1 enable software overide
|
||||
04 18 c0 c0 00 // pipe 2/3 enable software overide
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
/* VIDEO PIPE config end */
|
||||
|
||||
/* MIPI TXPHY config start */
|
||||
mipi-txphys {
|
||||
status = "okay";
|
||||
|
||||
phy-mode = <0>;
|
||||
phy-force-clock-out = <1>;
|
||||
phy-force-clk0-en = <1>;
|
||||
phy-force-clk3-en = <0>;
|
||||
|
||||
// MIPI TXPHY A: phy-id = 0
|
||||
mipi-txphy-config-0 {
|
||||
status = "okay";
|
||||
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0x4>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
|
||||
// MIPI TXPHY B: phy-id = 1
|
||||
mipi-txphy-config-1 {
|
||||
status = "okay";
|
||||
phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3
|
||||
|
||||
phy-type = <0>;
|
||||
auto-deskew = <0x80>;
|
||||
data-lane-num = <4>;
|
||||
data-lane-map = <0xe>;
|
||||
vc-ext-en = <0>;
|
||||
};
|
||||
};
|
||||
/* MIPI TXPHY config end */
|
||||
|
||||
/* local device extra init sequence */
|
||||
extra-init-sequence {
|
||||
status = "disabled";
|
||||
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
// common init sequence such as fsync / gpio and so on
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes local device end */
|
||||
|
||||
/* serdes remote device start */
|
||||
serdes-remote-device-0 {
|
||||
compatible = "maxim4c,link0,max9295";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <0>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x41>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96722_dphy3_remote0_out: endpoint {
|
||||
remote-endpoint = <&max96722_dphy3_link0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps
|
||||
00 11 03 00 00 // Coax Drive
|
||||
02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1
|
||||
03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL
|
||||
00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL
|
||||
00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected
|
||||
02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0
|
||||
02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup
|
||||
00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable
|
||||
00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled
|
||||
00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE
|
||||
01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high
|
||||
01 01 50 00 00 // Video X, BPP = 0x10
|
||||
00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel
|
||||
00 02 13 00 00 // Video transmit enable for Port X
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
serdes-remote-device-1 {
|
||||
compatible = "maxim4c,link1,max9295";
|
||||
status = "okay";
|
||||
|
||||
remote-id = <1>; // Same as Link ID: 0/1/2/3
|
||||
|
||||
// Serializer i2c 7bit address remap
|
||||
ser-i2c-addr-def = <0x40>;
|
||||
ser-i2c-addr-map = <0x42>; // 0: disable remap
|
||||
|
||||
port {
|
||||
max96722_dphy3_remote1_out: endpoint {
|
||||
remote-endpoint = <&max96722_dphy3_link1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
remote-init-sequence {
|
||||
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
|
||||
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
|
||||
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
|
||||
|
||||
// reg_addr reg_val val_mask delay
|
||||
init-sequence = [
|
||||
00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps
|
||||
00 11 03 00 00 // Coax Drive
|
||||
02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1
|
||||
03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL
|
||||
00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL
|
||||
00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected
|
||||
02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0
|
||||
02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup
|
||||
00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable
|
||||
00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled
|
||||
00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE
|
||||
01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high
|
||||
01 01 50 00 00 // Video X, BPP = 0x10
|
||||
00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel
|
||||
00 02 13 00 00 // Video transmit enable for Port X
|
||||
];
|
||||
};
|
||||
};
|
||||
/* serdes remote device end */
|
||||
};
|
||||
};
|
||||
|
||||
&mipi4_csi2 {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi4_csi2_input: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&csidphy3_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mipi4_csi2_output: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&cif_mipi4_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif_mipi_lvds4 {
|
||||
status = "okay";
|
||||
/* parameters for do cif reset detecting:
|
||||
* index0: monitor mode,
|
||||
0 for idle,
|
||||
1 for continue,
|
||||
2 for trigger,
|
||||
3 for hotplug (for nextchip)
|
||||
* index1: the frame id to start timer,
|
||||
min is 2
|
||||
* index2: frame num of monitoring cycle
|
||||
* index3: err time for keep monitoring
|
||||
after finding out err (ms)
|
||||
* index4: csi2 err reference val for resetting
|
||||
*/
|
||||
rockchip,cif-monitor = <3 2 1 1000 5>;
|
||||
|
||||
port {
|
||||
cif_mipi4_in: endpoint {
|
||||
remote-endpoint = <&mipi4_csi2_output>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rkcif {
|
||||
status = "okay";
|
||||
rockchip,android-usb-camerahal-enable;
|
||||
};
|
||||
|
||||
&rkcif_mmu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
max96722-dphy3 {
|
||||
max96722_dphy3_pwdn: max96722-dphy3-pwdn {
|
||||
rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96722_dphy3_errb: max96722-dphy3-errb {
|
||||
rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96722_dphy3_lock: max96722-dphy3-lock {
|
||||
rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include "rk3588-vehicle-evb-v21.dtsi"
|
||||
#include "rk3588-vehicle-evb-maxim-max96712.dtsi"
|
||||
#include "rk3588-vehicle-serdes-display-v21.dtsi"
|
||||
#include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi"
|
||||
#include "rk3588-vehicle-serdes-mfd-display-rohm.dtsi"
|
||||
#include "rk3588-android.dtsi"
|
||||
|
||||
/ {
|
||||
|
|
@ -55,6 +55,32 @@
|
|||
};
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
himax@48 {
|
||||
himax,irq-gpio = <&gpio1 RK_PB0 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
himax@48 {
|
||||
himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c5 {
|
||||
ilitek@41 {
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
|
||||
reset-gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c6 {
|
||||
himax@48 {
|
||||
himax,irq-gpio = <&gpio1 RK_PB7 IRQ_TYPE_EDGE_FALLING>; //use rst as int
|
||||
};
|
||||
};
|
||||
|
||||
&i2s2_2ch {
|
||||
pinctrl-0 = <&i2s2m1_lrck
|
||||
&i2s2m1_sclk
|
||||
|
|
@ -63,6 +89,78 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
&pinctrl {
|
||||
|
||||
bl {
|
||||
bl0_enable_pin: bl0-enable-pin {
|
||||
rockchip,pins =
|
||||
<1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>,
|
||||
<4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>,
|
||||
<4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
|
||||
};
|
||||
|
||||
bl1_enable_pin: bl1-enable-pin {
|
||||
rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl2_enable_pin: bl2-enable-pin {
|
||||
rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl3_enable_pin: bl3-enable-pin {
|
||||
rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl4_enable_pin: bl4-enable-pin {
|
||||
rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl5_enable_pin: bl5-enable-pin {
|
||||
rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
};
|
||||
|
||||
serdes {
|
||||
//dsi0
|
||||
ser0_rst_pin: ser0-rst-pin {
|
||||
rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
//dsi1
|
||||
ser1_rst_pin: ser1-rst-pin {
|
||||
rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
};
|
||||
|
||||
touch {
|
||||
//dsi0-i2c2
|
||||
touch_gpio_dsi0: touch-gpio-dsi0 {
|
||||
rockchip,pins =
|
||||
<1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; //rst
|
||||
};
|
||||
//dsi1-i2c6
|
||||
touch_gpio_dsi1: touch-gpio-dsi1 {
|
||||
rockchip,pins =
|
||||
<1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, //rst
|
||||
<1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; //int
|
||||
};
|
||||
//dp0-i2c4
|
||||
touch_gpio_dp0: touch-gpio-dp0 {
|
||||
rockchip,pins =
|
||||
<3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>, //rst
|
||||
<0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>; //int
|
||||
};
|
||||
//edp0-i2c5
|
||||
touch_gpio_edp0: touch-gpio-edp0 {
|
||||
rockchip,pins =
|
||||
<0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>, //rst
|
||||
<0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; //int
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rockchip_suspend {
|
||||
rockchip,sleep-mode-config = <
|
||||
(0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
/ {
|
||||
nca9539_vdd: nca9539-vdd3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "nca9539_vdd";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
startup-delay-us = <20>; // NCA9539 POR
|
||||
vin-supply = <&vcc_3v3_s0>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&i2c5 {
|
||||
clock-frequency = <400000>;
|
||||
status = "okay";
|
||||
|
||||
nca9539_gpio: gpio@74 {
|
||||
status = "okay";
|
||||
compatible = "novo,nca9539-gpio";
|
||||
reg = <0x74>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <16>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
vdd-supply = <&nca9539_vdd>;
|
||||
};
|
||||
};
|
||||
594
arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts
Normal file
594
arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts
Normal file
|
|
@ -0,0 +1,594 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "rk3588-vehicle-evb-v21.dtsi"
|
||||
#include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi"
|
||||
#include "rk3588-vehicle-serdes-mfd-display-rohm.dtsi"
|
||||
#include "rk3588-android.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RK3588 VEHICLE EVB V22 Board";
|
||||
compatible = "rockchip,rk3588-vehicle-evb-v22", "rockchip,rk3588";
|
||||
|
||||
vcc5v0_buck: vcc5v0-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc5v0_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
enable-active-high;
|
||||
gpio = <&gpio4 RK_PC3 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vcc5v0_buck_en>;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <5000000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc4v0_sys_mode: vcc4v0-sys-mode {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc4v0_sys_mode";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <4000000>;
|
||||
regulator-max-microvolt = <4000000>;
|
||||
enable-active-high;
|
||||
gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&vcc4v0_sys_mode_en>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <4000000>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd1_vcc12v_buck: lcd1_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lcd1_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
//regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 0 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd2_vcc12v_buck: lcd2_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lcd2_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
//regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 1 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd3_vcc12v_buck: lcd3_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lcd3_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
//regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 2 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd4_vcc12v_buck: lcd4_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lcd4_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
//regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 3 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd5_vcc12v_buck: lcd5_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lcd5_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
//regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 4 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd6_vcc12v_buck: lcd6_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lcd6_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
//regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 5 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
camera1_vcc12v_buck: camera1_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera1_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 6 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
camera2_vcc12v_buck: camera2_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera2_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 7 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
camera3_vcc12v_buck: camera3_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera3_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 8 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
camera4_vcc12v_buck: camera4_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "camera4_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 9 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc5v0_host_usb20: vcc5v0-host-usb20 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc5v0_host_usb20";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 10 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc5v0_usb>;
|
||||
};
|
||||
|
||||
vcc5v0_host_usb30: vcc5v0-host-usb30 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc5v0_host_usb30";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 11 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc5v0_usb>;
|
||||
};
|
||||
|
||||
adsp_vcc12v_buck: adsp_vcc12v-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "adsp_vcc12v_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 12 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc12v_dcin>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
minipcie_power_buck: minipcie_power-buck {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "minipcie_power_buck";
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
enable-active-high;
|
||||
gpio = <&i2c5_nca9539_gpio 13 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vcc5v0_usb>;
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <12000000>;
|
||||
};
|
||||
};
|
||||
|
||||
bt-sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,format = "dsp_a";
|
||||
simple-audio-card,bitclock-inversion = <1>;
|
||||
simple-audio-card,mclk-fs = <256>;
|
||||
simple-audio-card,name = "rockchip,bt";
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&i2s2_2ch>;
|
||||
};
|
||||
|
||||
simple-audio-card,codec {
|
||||
sound-dai = <&bt_sco 1>;
|
||||
};
|
||||
};
|
||||
|
||||
bt_sco: bt-sco {
|
||||
compatible = "delta,dfbmcs320";
|
||||
#sound-dai-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
autorepeat;
|
||||
|
||||
reverse {
|
||||
label = "GPIO Key Reverse";
|
||||
linux,code = <KEY_CAMERA_DOWN>;
|
||||
gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <100>;
|
||||
};
|
||||
|
||||
park {
|
||||
label = "GPIO Key Park";
|
||||
linux,code = <KEY_CAMERA>;
|
||||
gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <100>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc3v3_pcie_wifi: vcc3v3-pcie-wifi {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3_pcie_wifi";
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
enable-active-high;
|
||||
gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
|
||||
startup-delay-us = <5000>;
|
||||
vin-supply = <&vcc_3v3_s3>;
|
||||
};
|
||||
|
||||
wireless_bluetooth: wireless-bluetooth {
|
||||
BT,reset_gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
wireless_wlan: wireless-wlan {
|
||||
WIFI,poweren_gpio = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&avdd1v8_ddr_pll_s0 {
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2s2_2ch {
|
||||
pinctrl-0 = <&i2s2m1_lrck
|
||||
&i2s2m1_sclk
|
||||
&i2s2m1_sdi
|
||||
&i2s2m1_sdo>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
himax@48 {
|
||||
himax,irq-gpio = <&gpio1 RK_PB0 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c2_bu18tl82 {
|
||||
//route-enable;
|
||||
use-delay-work;
|
||||
};
|
||||
|
||||
&i2c2_bu18rl82 {
|
||||
use-delay-work;
|
||||
vpower-supply = <&lcd1_vcc12v_buck>;
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
himax@48 {
|
||||
himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c4_bu18tl82 {
|
||||
use-delay-work;
|
||||
};
|
||||
|
||||
&i2c4_bu18rl82 {
|
||||
use-delay-work;
|
||||
vpower-supply = <&lcd5_vcc12v_buck>;
|
||||
};
|
||||
|
||||
&i2c5 {
|
||||
ilitek@41 {
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <RK_PA5 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
i2c5_nca9539: i2c5-nca9539@74 {
|
||||
compatible = "novo,nca9539";
|
||||
reg = <0x74>;
|
||||
status = "okay";
|
||||
|
||||
/* P00-P07 P10-P17 output HIGH level default*/
|
||||
serdes-init-sequence = [
|
||||
0002 00ff
|
||||
0003 00ff
|
||||
0004 0000
|
||||
0005 0000
|
||||
0006 0000
|
||||
0007 0000
|
||||
];
|
||||
|
||||
i2c5_nca9539_pinctrl: i2c5-nca9539-pinctrl {
|
||||
compatible = "novo,nca9539-pinctrl";
|
||||
status = "okay";
|
||||
|
||||
i2c5_nca9539_gpio: i2c5-nca9539-gpio {
|
||||
compatible = "novo,nca9539-gpio";
|
||||
status = "okay";
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&i2c5_nca9539_pinctrl 0 256 16>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c5_bu18tl82 {
|
||||
use-delay-work;
|
||||
};
|
||||
|
||||
&i2c5_bu18rl82 {
|
||||
use-delay-work;
|
||||
vpower-supply = <&lcd3_vcc12v_buck>;
|
||||
};
|
||||
|
||||
&i2c6 {
|
||||
himax@48 {
|
||||
himax,irq-gpio = <&gpio1 RK_PB7 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c6_bu18tl82 {
|
||||
//route-enable;
|
||||
use-delay-work;
|
||||
};
|
||||
|
||||
&i2c6_bu18rl82 {
|
||||
use-delay-work;
|
||||
vpower-supply = <&lcd2_vcc12v_buck>;
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
|
||||
bl {
|
||||
bl0_enable_pin: bl0-enable-pin {
|
||||
rockchip,pins =
|
||||
<1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>,
|
||||
<4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>,
|
||||
<4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
|
||||
};
|
||||
|
||||
bl1_enable_pin: bl1-enable-pin {
|
||||
rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl2_enable_pin: bl2-enable-pin {
|
||||
rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl3_enable_pin: bl3-enable-pin {
|
||||
rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl4_enable_pin: bl4-enable-pin {
|
||||
rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
bl5_enable_pin: bl5-enable-pin {
|
||||
rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
};
|
||||
|
||||
max96712-dphy3 {
|
||||
max96712_dphy3_pwdn: max96712-dphy3-pwdn {
|
||||
rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dphy3_errb: max96712-dphy3-errb {
|
||||
rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
|
||||
max96712_dphy3_lock: max96712-dphy3-lock {
|
||||
rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
|
||||
touch {
|
||||
//dsi0-i2c2
|
||||
touch_gpio_dsi0: touch-gpio-dsi0 {
|
||||
rockchip,pins =
|
||||
<1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; //RST->V22 INT
|
||||
};
|
||||
//dsi1-i2c6
|
||||
touch_gpio_dsi1: touch-gpio-dsi1 {
|
||||
rockchip,pins =
|
||||
<1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; //RST->V22 INT
|
||||
};
|
||||
//dp0-i2c4
|
||||
touch_gpio_dp0: touch-gpio-dp0 {
|
||||
rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
//edp0-i2c5
|
||||
touch_gpio_edp0: touch-gpio-edp0 {
|
||||
rockchip,pins =
|
||||
<1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; //RST->V22 INT
|
||||
};
|
||||
};
|
||||
|
||||
vcc5v0-buck {
|
||||
vcc5v0_buck_en: vcc5v0-buck-en {
|
||||
rockchip,pins = <4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc4v0-mode {
|
||||
vcc4v0_sys_mode_en: vcc4v0-sys-mode-en {
|
||||
rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
};
|
||||
|
||||
wireless-bluetooth {
|
||||
bt_reset_gpio: bt-reset-gpio {
|
||||
rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rockchip_suspend {
|
||||
rockchip,sleep-mode-config = <
|
||||
(0
|
||||
| RKPM_SLP_ARMOFF_DDRPD
|
||||
| RKPM_SLP_PMU_PMUALIVE_32K
|
||||
| RKPM_SLP_PMU_DIS_OSC
|
||||
| RKPM_SLP_32K_EXT
|
||||
)
|
||||
>;
|
||||
rockchip,wakeup-config = <
|
||||
(0
|
||||
| RKPM_CPU0_WKUP_EN
|
||||
| RKPM_GPIO_WKUP_EN
|
||||
)
|
||||
>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&route_dsi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&route_dsi1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&u2phy1_otg {
|
||||
phy-supply = <&vcc5v0_host_usb20>;
|
||||
};
|
||||
|
||||
&u2phy2_host {
|
||||
phy-supply = <&vcc5v0_host_usb20>;
|
||||
};
|
||||
|
||||
&u2phy3_host {
|
||||
phy-supply = <&vcc5v0_host_usb30>;
|
||||
};
|
||||
|
||||
&vdd_log_s0 {
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <800000>;
|
||||
};
|
||||
};
|
||||
|
||||
&vcc_3v3_s0 {
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
&vcc_1v8_s0 {
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
&vdd_1v8_pll_s0 {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
&vcc5v0_host {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -693,6 +693,7 @@ CONFIG_SND_SOC_ROCKCHIP=y
|
|||
CONFIG_SND_SOC_ROCKCHIP_I2S=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_PDM=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_SAI=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_SPDIF=y
|
||||
|
|
|
|||
|
|
@ -389,6 +389,7 @@ CONFIG_SND_USB_AUDIO=y
|
|||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_ROCKCHIP=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_PDM=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_SAI=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_SPDIF=y
|
||||
|
|
|
|||
|
|
@ -3186,6 +3186,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
struct resource *res;
|
||||
int i, ret, irq;
|
||||
int num_chan;
|
||||
int val;
|
||||
struct device_node *np = adev->dev.of_node;
|
||||
|
||||
ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32));
|
||||
|
|
@ -3200,7 +3201,12 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
pd = &pl330->ddma;
|
||||
pd->dev = &adev->dev;
|
||||
|
||||
pl330->mcbufsz = 0;
|
||||
if (!device_property_read_u32(&adev->dev, "arm,pl330-mcbufsz-bytes", &val)) {
|
||||
if ((val > 0) && (val <= PAGE_SIZE))
|
||||
pl330->mcbufsz = val;
|
||||
|
||||
dev_info(&adev->dev, "mcbufsz: %d bytes\n", pl330->mcbufsz);
|
||||
}
|
||||
|
||||
/* get quirk */
|
||||
for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
|
||||
|
|
|
|||
|
|
@ -1056,6 +1056,14 @@ config GPIO_MAX732X_IRQ
|
|||
Say yes here to enable the max732x to be used as an interrupt
|
||||
controller. It requires the driver to be built in the kernel.
|
||||
|
||||
config GPIO_NCA9539
|
||||
tristate "NCA9539 I2C GPIO expander"
|
||||
depends on I2C || COMPILE_TEST
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say yes here to support the NCA9539 series of I2C Expanders.
|
||||
GPIO expanders used for additional digital outputs or inputs.
|
||||
|
||||
config GPIO_PCA953X
|
||||
tristate "PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports"
|
||||
select REGMAP_I2C
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o
|
|||
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
|
||||
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
|
||||
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
|
||||
obj-$(CONFIG_GPIO_NCA9539) += gpio-nca9539.o
|
||||
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
|
||||
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
|
||||
|
|
|
|||
332
drivers/gpio/gpio-nca9539.c
Normal file
332
drivers/gpio/gpio-nca9539.c
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* NCA9539 I2C Port Expander I/O
|
||||
*
|
||||
* Copyright (C) 2023 Cody Xie <cody.xie@rock-chips.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/compiler_types.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define NCA9539_REG_INPUT_PORT_BASE 0x00
|
||||
#define NCA9539_REG_INPUT_PORT0 (NCA9539_REG_INPUT_PORT_BASE + 0x0)
|
||||
#define NCA9539_REG_INPUT_PORT1 (NCA9539_REG_INPUT_PORT_BASE + 0x1)
|
||||
#define NCA9539_REG_OUTPUT_PORT_BASE 0x02
|
||||
#define NCA9539_REG_OUTPUT_PORT0 (NCA9539_REG_OUTPUT_PORT_BASE + 0x0)
|
||||
#define NCA9539_REG_OUTPUT_PORT1 (NCA9539_REG_OUTPUT_PORT_BASE + 0x1)
|
||||
#define NCA9539_REG_POLARITY_BASE 0x04
|
||||
#define NCA9539_REG_POLARITY_PORT0 (NCA9539_REG_POLARITY_BASE + 0x0)
|
||||
#define NCA9539_REG_POLARITY_PORT1 (NCA9539_REG_POLARITY_BASE + 0x1)
|
||||
#define NCA9539_REG_CONFIG_BASE 0x06
|
||||
#define NCA9539_REG_CONFIG_PORT0 (NCA9539_REG_CONFIG_BASE + 0x0)
|
||||
#define NCA9539_REG_CONFIG_PORT1 (NCA9539_REG_CONFIG_BASE + 0x1)
|
||||
|
||||
struct nca9539_chip {
|
||||
struct gpio_chip gpio_chip;
|
||||
struct regmap *regmap;
|
||||
struct regulator *regulator;
|
||||
unsigned int ngpio;
|
||||
};
|
||||
|
||||
static int nca9539_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
struct nca9539_chip *priv = gpiochip_get_data(gc);
|
||||
unsigned int port = offset / 8;
|
||||
unsigned int pin = offset % 8;
|
||||
unsigned int value;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gc->parent, "%s offset(%d)", __func__, offset);
|
||||
ret = regmap_read(priv->regmap, NCA9539_REG_CONFIG_BASE + port, &value);
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent, "%s offset(%d) read config failed",
|
||||
__func__, offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (value & BIT(pin))
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
}
|
||||
|
||||
static int nca9539_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
struct nca9539_chip *priv = gpiochip_get_data(gc);
|
||||
unsigned int port = offset / 8;
|
||||
unsigned int pin = offset % 8;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gc->parent, "%s offset(%d)", __func__, offset);
|
||||
ret = regmap_update_bits(priv->regmap, NCA9539_REG_CONFIG_BASE + port,
|
||||
BIT(pin), BIT(pin));
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent, "%s offset(%d) read config failed",
|
||||
__func__, offset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nca9539_gpio_direction_output(struct gpio_chip *gc, unsigned int offset,
|
||||
int val)
|
||||
{
|
||||
struct nca9539_chip *priv = gpiochip_get_data(gc);
|
||||
unsigned int port = offset / 8;
|
||||
unsigned int pin = offset % 8;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gc->parent, "%s offset(%d) val(%d)", __func__, offset, val);
|
||||
ret = regmap_update_bits(priv->regmap, NCA9539_REG_CONFIG_BASE + port,
|
||||
BIT(pin), 0);
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent,
|
||||
"%s offset(%d) val(%d) update config failed", __func__,
|
||||
offset, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(priv->regmap,
|
||||
NCA9539_REG_OUTPUT_PORT_BASE + port, BIT(pin),
|
||||
val ? BIT(pin) : 0);
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent,
|
||||
"%s offset(%d) val(%d) update output failed", __func__,
|
||||
offset, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nca9539_gpio_get(struct gpio_chip *gc, unsigned int offset)
|
||||
{
|
||||
struct nca9539_chip *priv = gpiochip_get_data(gc);
|
||||
unsigned int port = offset / 8;
|
||||
unsigned int pin = offset % 8;
|
||||
unsigned int reg;
|
||||
unsigned int value;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gc->parent, "%s offset(%d)", __func__, offset);
|
||||
ret = regmap_read(priv->regmap, NCA9539_REG_CONFIG_BASE + port, &value);
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent, "%s offset(%d) check config failed",
|
||||
__func__, offset);
|
||||
return ret;
|
||||
}
|
||||
if (!(BIT(pin) & value))
|
||||
reg = NCA9539_REG_OUTPUT_PORT_BASE + port;
|
||||
else
|
||||
reg = NCA9539_REG_INPUT_PORT_BASE + port;
|
||||
ret = regmap_read(priv->regmap, reg, &value);
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent, "%s offset(%d) read value failed", __func__,
|
||||
offset);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return !!(BIT(pin) & value);
|
||||
}
|
||||
|
||||
static void nca9539_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
|
||||
{
|
||||
struct nca9539_chip *priv = gpiochip_get_data(gc);
|
||||
unsigned int port = offset / 8;
|
||||
unsigned int pin = offset % 8;
|
||||
unsigned int value;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gc->parent, "%s offset(%d) val(%d)", __func__, offset, val);
|
||||
ret = regmap_read(priv->regmap, NCA9539_REG_CONFIG_BASE + port, &value);
|
||||
if (ret < 0 || !!(BIT(pin) & value)) {
|
||||
dev_err(gc->parent, "%s offset(%d) val(%d) check config failed",
|
||||
__func__, offset, val);
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(priv->regmap,
|
||||
NCA9539_REG_OUTPUT_PORT_BASE + port, BIT(pin),
|
||||
val ? BIT(pin) : 0);
|
||||
if (ret < 0) {
|
||||
dev_err(gc->parent, "%s offset(%d) val(%d) read input failed",
|
||||
__func__, offset, val);
|
||||
}
|
||||
}
|
||||
|
||||
static bool nca9539_is_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case NCA9539_REG_OUTPUT_PORT0:
|
||||
case NCA9539_REG_OUTPUT_PORT1:
|
||||
case NCA9539_REG_POLARITY_PORT0:
|
||||
case NCA9539_REG_POLARITY_PORT1:
|
||||
case NCA9539_REG_CONFIG_PORT0:
|
||||
case NCA9539_REG_CONFIG_PORT1:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool nca9539_is_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case NCA9539_REG_INPUT_PORT0:
|
||||
case NCA9539_REG_INPUT_PORT1:
|
||||
case NCA9539_REG_OUTPUT_PORT0:
|
||||
case NCA9539_REG_OUTPUT_PORT1:
|
||||
case NCA9539_REG_POLARITY_PORT0:
|
||||
case NCA9539_REG_POLARITY_PORT1:
|
||||
case NCA9539_REG_CONFIG_PORT0:
|
||||
case NCA9539_REG_CONFIG_PORT1:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool nca9539_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct reg_default nca9539_regmap_default[] = {
|
||||
{ NCA9539_REG_INPUT_PORT0, 0xFF },
|
||||
{ NCA9539_REG_INPUT_PORT1, 0xFF },
|
||||
{ NCA9539_REG_OUTPUT_PORT0, 0xFF },
|
||||
{ NCA9539_REG_OUTPUT_PORT1, 0xFF },
|
||||
{ NCA9539_REG_POLARITY_PORT0, 0x00 },
|
||||
{ NCA9539_REG_POLARITY_PORT1, 0x00 },
|
||||
{ NCA9539_REG_CONFIG_PORT0, 0xFF },
|
||||
{ NCA9539_REG_CONFIG_PORT1, 0xFF },
|
||||
};
|
||||
|
||||
static const struct regmap_config nca9539_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 7,
|
||||
.writeable_reg = nca9539_is_writeable_reg,
|
||||
.readable_reg = nca9539_is_readable_reg,
|
||||
.volatile_reg = nca9539_is_volatile_reg,
|
||||
.reg_defaults = nca9539_regmap_default,
|
||||
.num_reg_defaults = ARRAY_SIZE(nca9539_regmap_default),
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct gpio_chip template_chip = {
|
||||
.label = "nca9539-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
.get_direction = nca9539_gpio_get_direction,
|
||||
.direction_input = nca9539_gpio_direction_input,
|
||||
.direction_output = nca9539_gpio_direction_output,
|
||||
.get = nca9539_gpio_get,
|
||||
.set = nca9539_gpio_set,
|
||||
.base = -1,
|
||||
.can_sleep = true,
|
||||
};
|
||||
|
||||
static int nca9539_probe(struct i2c_client *client)
|
||||
{
|
||||
struct nca9539_chip *chip;
|
||||
struct regulator *reg;
|
||||
int ret;
|
||||
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->gpio_chip = template_chip;
|
||||
chip->gpio_chip.label = "nca9539-gpio";
|
||||
chip->gpio_chip.parent = &client->dev;
|
||||
chip->ngpio = (uintptr_t)of_device_get_match_data(&client->dev);
|
||||
chip->gpio_chip.ngpio = chip->ngpio;
|
||||
|
||||
reg = devm_regulator_get(&client->dev, "vdd");
|
||||
if (IS_ERR(reg))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(reg),
|
||||
"reg get err\n");
|
||||
|
||||
ret = regulator_enable(reg);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "reg en err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
chip->regulator = reg;
|
||||
|
||||
chip->regmap = devm_regmap_init_i2c(client, &nca9539_regmap_config);
|
||||
if (IS_ERR(chip->regmap)) {
|
||||
ret = PTR_ERR(chip->regmap);
|
||||
dev_err(&client->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
goto err_exit;
|
||||
}
|
||||
regcache_mark_dirty(chip->regmap);
|
||||
ret = regcache_sync(chip->regmap);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "Failed to sync register map: %d\n", ret);
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
// TODO(Cody): irq_chip setup
|
||||
|
||||
ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Unable to register gpiochip\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, chip);
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit:
|
||||
regulator_disable(chip->regulator);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nca9539_remove(struct i2c_client *client)
|
||||
{
|
||||
struct nca9539_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
regulator_disable(chip->regulator);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id nca9539_gpio_of_match_table[] = {
|
||||
{
|
||||
.compatible = "novo,nca9539-gpio",
|
||||
.data = (void *)16,
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, nca9539_gpio_of_match_table);
|
||||
|
||||
static const struct i2c_device_id nca9539_gpio_id_table[] = {
|
||||
{ "nca9539-gpio" },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, nca9539_gpio_id_table);
|
||||
|
||||
static struct i2c_driver nca9539_driver = {
|
||||
.driver = {
|
||||
.name = "nca9539-gpio",
|
||||
.of_match_table = nca9539_gpio_of_match_table,
|
||||
},
|
||||
.probe_new = nca9539_probe,
|
||||
.remove = nca9539_remove,
|
||||
.id_table = nca9539_gpio_id_table,
|
||||
};
|
||||
module_i2c_driver(nca9539_driver);
|
||||
|
||||
MODULE_AUTHOR("Cody Xie <cody.xie@rock-chips.com>");
|
||||
MODULE_DESCRIPTION("GPIO expander driver for Novosense nca9539");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -2179,7 +2179,9 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
|
|||
{
|
||||
struct page *prop_page;
|
||||
|
||||
if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566"))
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
gfp_flags |= GFP_DMA32;
|
||||
prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
|
||||
if (!prop_page)
|
||||
|
|
@ -2317,7 +2319,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
|||
}
|
||||
|
||||
gfp_flags = GFP_KERNEL | __GFP_ZERO;
|
||||
if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566"))
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
gfp_flags |= GFP_DMA32;
|
||||
page = alloc_pages_node(its->numa_node, gfp_flags, order);
|
||||
if (!page)
|
||||
|
|
@ -2368,6 +2372,7 @@ retry_baser:
|
|||
|
||||
if (IS_ENABLED(CONFIG_NO_GKI) &&
|
||||
(of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566") ||
|
||||
of_machine_is_compatible("rockchip,rk3588"))) {
|
||||
if (tmp & GITS_BASER_SHAREABILITY_MASK)
|
||||
|
|
@ -2958,7 +2963,9 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
|
|||
{
|
||||
struct page *pend_page;
|
||||
|
||||
if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566"))
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
gfp_flags |= GFP_DMA32;
|
||||
pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
|
||||
get_order(LPI_PENDBASE_SZ));
|
||||
|
|
@ -3117,6 +3124,7 @@ static void its_cpu_init_lpis(void)
|
|||
|
||||
if (IS_ENABLED(CONFIG_NO_GKI) &&
|
||||
(of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566") ||
|
||||
of_machine_is_compatible("rockchip,rk3588")))
|
||||
tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
|
||||
|
|
@ -3147,6 +3155,7 @@ static void its_cpu_init_lpis(void)
|
|||
|
||||
if (IS_ENABLED(CONFIG_NO_GKI) &&
|
||||
(of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566") ||
|
||||
of_machine_is_compatible("rockchip,rk3588")))
|
||||
tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
|
||||
|
|
@ -3316,7 +3325,9 @@ static bool its_alloc_table_entry(struct its_node *its,
|
|||
if (!table[idx]) {
|
||||
gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO;
|
||||
|
||||
if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566"))
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
gfp_flags |= GFP_DMA32;
|
||||
page = alloc_pages_node(its->numa_node, gfp_flags,
|
||||
get_order(baser->psz));
|
||||
|
|
@ -3424,7 +3435,9 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
|
|||
sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
|
||||
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
|
||||
gfp_flags = GFP_KERNEL;
|
||||
if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) {
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566")) {
|
||||
gfp_flags |= GFP_DMA32;
|
||||
itt = (void *)__get_free_pages(gfp_flags, get_order(sz));
|
||||
} else {
|
||||
|
|
@ -3446,6 +3459,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
|
|||
kfree(dev);
|
||||
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
free_pages((unsigned long)itt, get_order(sz));
|
||||
else
|
||||
|
|
@ -3490,6 +3504,7 @@ static void its_free_device(struct its_device *its_dev)
|
|||
kfree(its_dev->event_map.col_map);
|
||||
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
free_pages((unsigned long)its_dev->itt, get_order(its_dev->itt_sz));
|
||||
else
|
||||
|
|
@ -5122,7 +5137,9 @@ static int __init its_probe_one(struct resource *res,
|
|||
its->numa_node = numa_node;
|
||||
|
||||
gfp_flags = GFP_KERNEL | __GFP_ZERO;
|
||||
if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566"))
|
||||
if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566"))
|
||||
gfp_flags |= GFP_DMA32;
|
||||
page = alloc_pages_node(its->numa_node, gfp_flags,
|
||||
get_order(ITS_CMD_QUEUE_SZ));
|
||||
|
|
@ -5157,6 +5174,7 @@ static int __init its_probe_one(struct resource *res,
|
|||
|
||||
if (IS_ENABLED(CONFIG_NO_GKI) &&
|
||||
(of_machine_is_compatible("rockchip,rk3568") ||
|
||||
of_machine_is_compatible("rockchip,rk3567") ||
|
||||
of_machine_is_compatible("rockchip,rk3566") ||
|
||||
of_machine_is_compatible("rockchip,rk3588")))
|
||||
tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
|
||||
|
|
|
|||
|
|
@ -98,6 +98,12 @@ config ROCKCHIP_MBOX
|
|||
Please check it that the Soc you use have Mailbox hardware.
|
||||
Say Y here if you want to use the Rockchip Mailbox support.
|
||||
|
||||
config ROCKCHIP_MBOX_DEMO
|
||||
tristate "Rockchip MBOX Demo"
|
||||
depends on ROCKCHIP_MBOX
|
||||
help
|
||||
Say y here to enable Rockchip MBOX Demo.
|
||||
|
||||
config PCC
|
||||
bool "Platform Communication Channel Driver"
|
||||
depends on ACPI
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o
|
|||
|
||||
obj-$(CONFIG_ROCKCHIP_MBOX) += rockchip-mailbox.o
|
||||
|
||||
obj-$(CONFIG_ROCKCHIP_MBOX_DEMO) += rockchip-mbox-demo.o
|
||||
|
||||
obj-$(CONFIG_PCC) += pcc.o
|
||||
|
||||
obj-$(CONFIG_ALTERA_MBOX) += mailbox-altera.o
|
||||
|
|
|
|||
138
drivers/mailbox/rockchip-mbox-demo.c
Normal file
138
drivers/mailbox/rockchip-mbox-demo.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Rockchip MBOX Demo.
|
||||
*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jiahang Zheng <jiahang.zheng@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <soc/rockchip/rockchip-mailbox.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
/*
|
||||
* The Linux kernel uses the mailbox framework TXDONE_BY_POLL mechanism.
|
||||
* The minimum unit of the txpoll period interface is ms.
|
||||
* Configure rockchip,txpoll-period-ms = <1> in dts.
|
||||
* If data that is longer than MBOX_TX_QUEUE_LEN may be lost,
|
||||
* each send should be at least interval txpoll-period-ms
|
||||
*/
|
||||
#define MSG_LIMIT (100)
|
||||
#define LINUX_TEST_COMPENSATION (1)
|
||||
|
||||
struct rk_mbox_dev {
|
||||
struct platform_device *pdev;
|
||||
struct mbox_client mbox_cl;
|
||||
struct mbox_chan *mbox_rx_chan;
|
||||
struct mbox_chan *mbox_tx_chan;
|
||||
struct rockchip_mbox_msg tx_msg;
|
||||
int rx_count;
|
||||
};
|
||||
|
||||
static void rk_mbox_rx_callback(struct mbox_client *client, void *message)
|
||||
{
|
||||
struct rk_mbox_dev *test_dev = container_of(client, struct rk_mbox_dev, mbox_cl);
|
||||
struct platform_device *pdev = test_dev->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rockchip_mbox_msg *tx_msg;
|
||||
struct rockchip_mbox_msg *rx_msg;
|
||||
|
||||
rx_msg = message;
|
||||
dev_info(dev, "mbox master: rx_count:%d cmd=0x%x data=0x%x\n",
|
||||
++test_dev->rx_count, rx_msg->cmd, rx_msg->data);
|
||||
|
||||
/* test should not live forever */
|
||||
if (test_dev->rx_count >= MSG_LIMIT) {
|
||||
dev_info(dev, "Rockchip mbox test exit!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mdelay(LINUX_TEST_COMPENSATION);
|
||||
tx_msg = &test_dev->tx_msg;
|
||||
mbox_send_message(test_dev->mbox_tx_chan, tx_msg);
|
||||
}
|
||||
|
||||
static int mbox_demo_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rk_mbox_dev *test_dev = NULL;
|
||||
struct mbox_client *cl;
|
||||
struct rockchip_mbox_msg *tx_msg;
|
||||
int ret = 0;
|
||||
|
||||
test_dev = devm_kzalloc(dev, sizeof(*test_dev), GFP_KERNEL);
|
||||
if (!test_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* link_id: master core 0 and remote core 3 */
|
||||
tx_msg = &test_dev->tx_msg;
|
||||
tx_msg->cmd = 0x03U;
|
||||
tx_msg->data = 0x524D5347U;
|
||||
|
||||
dev_info(dev, "rockchip mbox demo probe.\n");
|
||||
test_dev->pdev = pdev;
|
||||
test_dev->rx_count = 0;
|
||||
|
||||
cl = &test_dev->mbox_cl;
|
||||
cl->dev = dev;
|
||||
cl->rx_callback = rk_mbox_rx_callback;
|
||||
|
||||
platform_set_drvdata(pdev, test_dev);
|
||||
test_dev->mbox_rx_chan = mbox_request_channel_byname(cl, "test-rx");
|
||||
if (IS_ERR(test_dev->mbox_rx_chan)) {
|
||||
ret = PTR_ERR(test_dev->mbox_rx_chan);
|
||||
dev_err(dev, "failed to request mbox rx chan, ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
test_dev->mbox_tx_chan = mbox_request_channel_byname(cl, "test-tx");
|
||||
if (IS_ERR(test_dev->mbox_tx_chan)) {
|
||||
ret = PTR_ERR(test_dev->mbox_tx_chan);
|
||||
dev_err(dev, "failed to request mbox tx chan, ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(dev, "mbox master: send cmd=0x%x data=0x%x\n", tx_msg->cmd, tx_msg->data);
|
||||
mbox_send_message(test_dev->mbox_tx_chan, tx_msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbox_demo_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk_mbox_dev *test_dev = platform_get_drvdata(pdev);
|
||||
|
||||
mbox_free_channel(test_dev->mbox_rx_chan);
|
||||
mbox_free_channel(test_dev->mbox_tx_chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mbox_demo_match[] = {
|
||||
{ .compatible = "rockchip,mbox-demo", },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mbox_demo_match);
|
||||
|
||||
static struct platform_driver mbox_demo_driver = {
|
||||
.probe = mbox_demo_probe,
|
||||
.remove = mbox_demo_remove,
|
||||
.driver = {
|
||||
.name = "mbox-demo",
|
||||
.of_match_table = mbox_demo_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(mbox_demo_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Rockchip MBOX Demo");
|
||||
MODULE_AUTHOR("Jiahang Zheng <jiahang.zheng@rock-chips.com>");
|
||||
|
|
@ -3,44 +3,46 @@
|
|||
# Maxim Quad GMSL deserializer and serializer devices
|
||||
#
|
||||
config VIDEO_DES_MAXIM4C
|
||||
tristate "Maxim Qual GMSL deserializer support"
|
||||
tristate "Maxim Quad GMSL deserializer support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This driver supports the Maxim Qual GMSL2/GMSL1 deserializer.
|
||||
This driver supports the Maxim Quad GMSL2/GMSL1 deserializer.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called maxim4c.
|
||||
|
||||
menu "Maxim Quad GMSL serializer devices support"
|
||||
visible if VIDEO_DES_MAXIM4C
|
||||
|
||||
config MAXIM4C_SER_MAX9295
|
||||
tristate "Maxim GMSL serializer support"
|
||||
depends on I2C
|
||||
select VIDEO_DES_MAXIM4C
|
||||
tristate "Maxim GMSL2 serializer max9295 support"
|
||||
depends on VIDEO_DES_MAXIM4C
|
||||
help
|
||||
This driver supports the Maxim GMSL2 serializer.
|
||||
This driver supports the Maxim GMSL2 max9295 serializer.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called remote_max9295.
|
||||
|
||||
config MAXIM4C_SER_MAX96715
|
||||
tristate "Maxim GMSL serializer support"
|
||||
depends on I2C
|
||||
select VIDEO_DES_MAXIM4C
|
||||
tristate "Maxim GMSL1 Serializer max96715 support"
|
||||
depends on VIDEO_DES_MAXIM4C
|
||||
help
|
||||
This driver supports the Maxim GMSL1 serializer.
|
||||
This driver supports the Maxim GMSL1 max96715 serializer.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called remote_max96715.
|
||||
|
||||
config MAXIM4C_SER_MAX96717
|
||||
tristate "Maxim GMSL serializer support"
|
||||
depends on I2C
|
||||
select VIDEO_DES_MAXIM4C
|
||||
tristate "Maxim GMSL2 Serializer max96717 support"
|
||||
depends on VIDEO_DES_MAXIM4C
|
||||
help
|
||||
This driver supports the Maxim GMSL2 serializer.
|
||||
This driver supports the Maxim GMSL2 max96717 serializer.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called remote_max96717.
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
/* Maxim Deserializer Test Pattern */
|
||||
#define MAXIM4C_TEST_PATTERN 0
|
||||
|
||||
/* Maxim Deserializer pwdn on/off enable */
|
||||
#define MAXIM4C_LOCAL_DES_ON_OFF_EN 0
|
||||
|
||||
/* maxim4c i2c api */
|
||||
int maxim4c_i2c_write_reg(struct i2c_client *client,
|
||||
u16 reg_addr, u16 reg_len, u16 val_len, u32 reg_val);
|
||||
|
|
@ -77,15 +80,22 @@ int maxim4c_remote_mfd_add_devices(maxim4c_t *maxim4c);
|
|||
int maxim4c_remote_devices_init(maxim4c_t *maxim4c, u8 link_init_mask);
|
||||
int maxim4c_remote_devices_deinit(maxim4c_t *maxim4c, u8 link_init_mask);
|
||||
int maxim4c_remote_load_init_seq(maxim4c_remote_t *remote_device);
|
||||
int maxim4c_remote_i2c_addr_select(maxim4c_remote_t *remote_device, u32 i2c_id);
|
||||
int maxim4c_remote_i2c_client_init(maxim4c_remote_t *remote_device,
|
||||
struct i2c_client *des_client);
|
||||
int maxim4c_remote_device_register(maxim4c_t *maxim4c,
|
||||
maxim4c_remote_t *remote_device);
|
||||
maxim4c_remote_t *remote_device);
|
||||
|
||||
/* maxim4c v4l2 subdev api */
|
||||
int maxim4c_v4l2_subdev_init(maxim4c_t *maxim4c);
|
||||
void maxim4c_v4l2_subdev_deinit(maxim4c_t *maxim4c);
|
||||
|
||||
int maxim4c_module_hw_init(maxim4c_t *maxim4c);
|
||||
|
||||
/* maxim4c pattern api */
|
||||
int maxim4c_pattern_init(maxim4c_t *maxim4c);
|
||||
int maxim4c_pattern_hw_init(maxim4c_t *maxim4c);
|
||||
int maxim4c_pattern_support_mode_init(maxim4c_t *maxim4c);
|
||||
int maxim4c_pattern_data_init(maxim4c_t *maxim4c);
|
||||
int maxim4c_pattern_enable(maxim4c_t *maxim4c, bool enable);
|
||||
|
||||
#endif /* __MAXIM4C_API_H__ */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Author: Cai Wenzhong <cwz@rock-chips.com>
|
||||
*
|
||||
* V2.0.00 maxim serdes qual GMSL2/GMSL1 driver framework.
|
||||
* V2.00.00 maxim serdes quad GMSL2/GMSL1 driver framework.
|
||||
* 1. local deserializer support: max96712/max96722
|
||||
* 2. remote serializer support: max9295/max96715/max96717
|
||||
* 3. support deserializer and serializer auto adaptive
|
||||
|
|
@ -14,6 +14,14 @@
|
|||
* 5. support remote serializer I2c address mapping
|
||||
* 6. support remote serializer hot plug detection and recovery
|
||||
*
|
||||
* V2.01.00
|
||||
* 1. remote device and local link are bound through link id
|
||||
* 2. support local and remote port chain check
|
||||
* 3. drivers/media/i2c/maxim4c/Kconfig support menu select
|
||||
* 4. optimize delay time and error messages
|
||||
* 5. power control: local by pwdn gpio, remote by pocen gpio
|
||||
* 6. local pwdn on/off enable depend on MAXIM4C_LOCAL_DES_ON_OFF_EN
|
||||
*
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
|
|
@ -43,14 +51,10 @@
|
|||
|
||||
#include "maxim4c_api.h"
|
||||
|
||||
#define DRIVER_VERSION KERNEL_VERSION(2, 0x00, 0x00)
|
||||
#define DRIVER_VERSION KERNEL_VERSION(2, 0x01, 0x00)
|
||||
|
||||
#define MAXIM4C_XVCLK_FREQ 25000000
|
||||
|
||||
/* device compatible */
|
||||
#define MAXIM4C_MAX96712_COMPAT "maxim4c,max96712"
|
||||
#define MAXIM4C_MAX96722_COMPAT "maxim4c,max96722"
|
||||
|
||||
static int maxim4c_check_local_chipid(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct i2c_client *client = maxim4c->client;
|
||||
|
|
@ -59,6 +63,11 @@ static int maxim4c_check_local_chipid(maxim4c_t *maxim4c)
|
|||
u8 chipid = 0;
|
||||
|
||||
for (loop = 0; loop < 5; loop++) {
|
||||
if (loop != 0) {
|
||||
dev_info(dev, "check local chipid retry (%d)", loop);
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
ret = maxim4c_i2c_read_byte(client,
|
||||
MAXIM4C_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
&chipid);
|
||||
|
|
@ -74,13 +83,10 @@ static int maxim4c_check_local_chipid(maxim4c_t *maxim4c)
|
|||
return 0;
|
||||
}
|
||||
} else {
|
||||
dev_err(dev, "Unexpected maxim chipid(%02x)\n", chipid);
|
||||
dev_err(dev, "Unexpected maxim chipid = %02x\n", chipid);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(dev, "retry (%d) to check local chipid", loop + 1);
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
dev_err(dev, "maxim check chipid error, ret(%d)\n", ret);
|
||||
|
|
@ -181,13 +187,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work)
|
|||
link_id = MAXIM4C_LINK_ID_A;
|
||||
|
||||
if (curr_lock_state & MAXIM4C_LINK_MASK_A) {
|
||||
dev_info(dev, "link A plug in\n");
|
||||
dev_info(dev, "Link A plug in\n");
|
||||
|
||||
maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_A);
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
|
||||
} else {
|
||||
dev_info(dev, "link A plug out\n");
|
||||
dev_info(dev, "Link A plug out\n");
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false);
|
||||
}
|
||||
|
|
@ -197,13 +203,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work)
|
|||
link_id = MAXIM4C_LINK_ID_B;
|
||||
|
||||
if (curr_lock_state & MAXIM4C_LINK_MASK_B) {
|
||||
dev_info(dev, "link B plug in\n");
|
||||
dev_info(dev, "Link B plug in\n");
|
||||
|
||||
maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_B);
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
|
||||
} else {
|
||||
dev_info(dev, "link B plug out\n");
|
||||
dev_info(dev, "Link B plug out\n");
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false);
|
||||
}
|
||||
|
|
@ -213,13 +219,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work)
|
|||
link_id = MAXIM4C_LINK_ID_C;
|
||||
|
||||
if (curr_lock_state & MAXIM4C_LINK_MASK_C) {
|
||||
dev_info(dev, "link C plug in\n");
|
||||
dev_info(dev, "Link C plug in\n");
|
||||
|
||||
maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_C);
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
|
||||
} else {
|
||||
dev_info(dev, "link C plug out\n");
|
||||
dev_info(dev, "Link C plug out\n");
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false);
|
||||
}
|
||||
|
|
@ -229,13 +235,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work)
|
|||
link_id = MAXIM4C_LINK_ID_D;
|
||||
|
||||
if (curr_lock_state & MAXIM4C_LINK_MASK_D) {
|
||||
dev_info(dev, "link D plug in\n");
|
||||
dev_info(dev, "Link D plug in\n");
|
||||
|
||||
maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_D);
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
|
||||
} else {
|
||||
dev_info(dev, "link D plug out\n");
|
||||
dev_info(dev, "Link D plug out\n");
|
||||
|
||||
maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false);
|
||||
}
|
||||
|
|
@ -290,10 +296,10 @@ static int maxim4c_local_device_power_on(maxim4c_t *maxim4c)
|
|||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
|
||||
if (!IS_ERR(maxim4c->power_gpio)) {
|
||||
dev_info(dev, "local device power gpio on\n");
|
||||
if (!IS_ERR(maxim4c->pwdn_gpio)) {
|
||||
dev_info(dev, "local device pwdn gpio on\n");
|
||||
|
||||
gpiod_set_value_cansleep(maxim4c->power_gpio, 1);
|
||||
gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 1);
|
||||
|
||||
usleep_range(5000, 10000);
|
||||
}
|
||||
|
|
@ -305,10 +311,10 @@ static void maxim4c_local_device_power_off(maxim4c_t *maxim4c)
|
|||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
|
||||
if (!IS_ERR(maxim4c->power_gpio)) {
|
||||
dev_info(dev, "local device power gpio off\n");
|
||||
if (!IS_ERR(maxim4c->pwdn_gpio)) {
|
||||
dev_info(dev, "local device pwdn gpio off\n");
|
||||
|
||||
gpiod_set_value_cansleep(maxim4c->power_gpio, 0);
|
||||
gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +324,7 @@ static int maxim4c_remote_device_power_on(maxim4c_t *maxim4c)
|
|||
|
||||
// remote PoC enable
|
||||
if (!IS_ERR(maxim4c->pocen_gpio)) {
|
||||
dev_info(dev, "remote device poc gpio on\n");
|
||||
dev_info(dev, "remote device pocen gpio on\n");
|
||||
|
||||
gpiod_set_value_cansleep(maxim4c->pocen_gpio, 1);
|
||||
usleep_range(5000, 10000);
|
||||
|
|
@ -333,7 +339,7 @@ static int maxim4c_remote_device_power_off(maxim4c_t *maxim4c)
|
|||
|
||||
// remote PoC enable
|
||||
if (!IS_ERR(maxim4c->pocen_gpio)) {
|
||||
dev_info(dev, "remote device poc gpio off\n");
|
||||
dev_info(dev, "remote device pocen gpio off\n");
|
||||
|
||||
gpiod_set_value_cansleep(maxim4c->pocen_gpio, 0);
|
||||
}
|
||||
|
|
@ -346,8 +352,15 @@ static int maxim4c_runtime_resume(struct device *dev)
|
|||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct maxim4c *maxim4c = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
return maxim4c_remote_device_power_on(maxim4c);
|
||||
#if MAXIM4C_LOCAL_DES_ON_OFF_EN
|
||||
ret |= maxim4c_local_device_power_on(maxim4c);
|
||||
#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
|
||||
|
||||
ret |= maxim4c_remote_device_power_on(maxim4c);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int maxim4c_runtime_suspend(struct device *dev)
|
||||
|
|
@ -355,8 +368,15 @@ static int maxim4c_runtime_suspend(struct device *dev)
|
|||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct maxim4c *maxim4c = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
return maxim4c_remote_device_power_off(maxim4c);
|
||||
ret |= maxim4c_remote_device_power_off(maxim4c);
|
||||
|
||||
#if MAXIM4C_LOCAL_DES_ON_OFF_EN
|
||||
maxim4c_local_device_power_off(maxim4c);
|
||||
#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops maxim4c_pm_ops = {
|
||||
|
|
@ -378,22 +398,26 @@ static int maxim4c_extra_init_seq_parse(maxim4c_t *maxim4c, struct device_node *
|
|||
struct maxim4c_i2c_init_seq *init_seq = NULL;
|
||||
|
||||
init_seq_node = of_get_child_by_name(node, "extra-init-sequence");
|
||||
if (!IS_ERR_OR_NULL(init_seq_node)) {
|
||||
if (!of_device_is_available(init_seq_node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", init_seq_node);
|
||||
if (IS_ERR_OR_NULL(init_seq_node)) {
|
||||
dev_dbg(dev, "%pOF no child node extra-init-sequence\n", node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_info(dev, "load extra-init-sequence\n");
|
||||
|
||||
init_seq = &maxim4c->extra_init_seq;
|
||||
maxim4c_i2c_load_init_seq(dev,
|
||||
init_seq_node, init_seq);
|
||||
if (!of_device_is_available(init_seq_node)) {
|
||||
dev_dbg(dev, "%pOF is disabled\n", init_seq_node);
|
||||
|
||||
of_node_put(init_seq_node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_info(dev, "load extra-init-sequence\n");
|
||||
|
||||
init_seq = &maxim4c->extra_init_seq;
|
||||
maxim4c_i2c_load_init_seq(dev,
|
||||
init_seq_node, init_seq);
|
||||
|
||||
of_node_put(init_seq_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -404,8 +428,12 @@ static int maxim4c_module_parse_dt(maxim4c_t *maxim4c)
|
|||
|
||||
// maxim serdes local
|
||||
node = of_get_child_by_name(dev->of_node, "serdes-local-device");
|
||||
if (IS_ERR_OR_NULL(node))
|
||||
if (IS_ERR_OR_NULL(node)) {
|
||||
dev_err(dev, "%pOF has no child node: serdes-local-device\n",
|
||||
dev->of_node);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", node);
|
||||
|
|
@ -492,36 +520,51 @@ static int maxim4c_module_hw_postinit(maxim4c_t *maxim4c)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int maxim4c_module_hw_init(maxim4c_t *maxim4c)
|
||||
int maxim4c_module_hw_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
int ret = 0;
|
||||
|
||||
ret = maxim4c_module_hw_previnit(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: hw prev init error\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_link_hw_init(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: hw link init error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_video_pipe_hw_init(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: hw pipe init error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_mipi_txphy_hw_init(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: hw txphy init error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_run_extra_init_seq(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: run extra init seq error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_module_hw_postinit(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: hw post init error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_module_hw_init);
|
||||
|
||||
static int maxim4c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
|
|
@ -529,32 +572,30 @@ static int maxim4c_probe(struct i2c_client *client,
|
|||
struct device *dev = &client->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
maxim4c_t *maxim4c = NULL;
|
||||
const u32 *chip_id = NULL;
|
||||
u32 chip_id;
|
||||
int ret = 0;
|
||||
|
||||
dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16,
|
||||
(DRIVER_VERSION & 0xff00) >> 8, DRIVER_VERSION & 0x00ff);
|
||||
|
||||
chip_id = of_device_get_match_data(dev);
|
||||
if (chip_id == NULL) {
|
||||
dev_err(dev, "maxim4c driver get match data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*chip_id == MAX96712_CHIP_ID) {
|
||||
dev_info(dev, "maxim4c driver for max96712");
|
||||
} else if (*chip_id == MAX96722_CHIP_ID) {
|
||||
dev_info(dev, "maxim4c driver for max96722");
|
||||
chip_id = (uintptr_t)of_device_get_match_data(dev);
|
||||
if (chip_id == MAX96712_CHIP_ID) {
|
||||
dev_info(dev, "maxim4c driver for max96712\n");
|
||||
} else if (chip_id == MAX96722_CHIP_ID) {
|
||||
dev_info(dev, "maxim4c driver for max96722\n");
|
||||
} else {
|
||||
dev_err(dev, "maxim4c driver unknown chip");
|
||||
dev_err(dev, "maxim4c driver unknown chip\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
maxim4c = devm_kzalloc(dev, sizeof(*maxim4c), GFP_KERNEL);
|
||||
if (!maxim4c)
|
||||
if (!maxim4c) {
|
||||
dev_err(dev, "maxim4c probe no memory error\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
maxim4c->client = client;
|
||||
maxim4c->chipid = *chip_id;
|
||||
maxim4c->chipid = chip_id;
|
||||
|
||||
ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
|
||||
&maxim4c->module_index);
|
||||
|
|
@ -569,9 +610,9 @@ static int maxim4c_probe(struct i2c_client *client,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
maxim4c->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(maxim4c->power_gpio))
|
||||
dev_warn(dev, "Failed to get power-gpios, maybe no use\n");
|
||||
maxim4c->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(maxim4c->pwdn_gpio))
|
||||
dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n");
|
||||
|
||||
maxim4c->pocen_gpio = devm_gpiod_get(dev, "pocen", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(maxim4c->pocen_gpio))
|
||||
|
|
@ -594,13 +635,21 @@ static int maxim4c_probe(struct i2c_client *client,
|
|||
// client->dev->driver_data = subdev
|
||||
// subdev->dev->driver_data = maxim4c
|
||||
ret = maxim4c_v4l2_subdev_init(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "maxim4c probe v4l2 subdev init error\n");
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
#if MAXIM4C_TEST_PATTERN
|
||||
ret = maxim4c_pattern_data_init(maxim4c);
|
||||
if (ret)
|
||||
goto err_power_off;
|
||||
|
||||
#if MAXIM4C_TEST_PATTERN
|
||||
ret = maxim4c_pattern_init(maxim4c);
|
||||
#if (MAXIM4C_LOCAL_DES_ON_OFF_EN == 0)
|
||||
ret = maxim4c_pattern_hw_init(maxim4c);
|
||||
if (ret)
|
||||
goto err_power_off;
|
||||
#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
|
@ -612,9 +661,11 @@ static int maxim4c_probe(struct i2c_client *client,
|
|||
maxim4c_module_data_init(maxim4c);
|
||||
maxim4c_module_parse_dt(maxim4c);
|
||||
|
||||
#if (MAXIM4C_LOCAL_DES_ON_OFF_EN == 0)
|
||||
ret = maxim4c_module_hw_init(maxim4c);
|
||||
if (ret)
|
||||
goto err_subdev_deinit;
|
||||
#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
|
||||
|
||||
ret = maxim4c_remote_mfd_add_devices(maxim4c);
|
||||
if (ret)
|
||||
|
|
@ -657,28 +708,17 @@ static int maxim4c_remove(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
static const u32 max96712_chip_id = MAX96712_CHIP_ID;
|
||||
static const u32 max96722_chip_id = MAX96722_CHIP_ID;
|
||||
|
||||
static const struct of_device_id maxim4c_of_match[] = {
|
||||
{
|
||||
.compatible = MAXIM4C_MAX96712_COMPAT,
|
||||
.data = &max96712_chip_id,
|
||||
.compatible = "maxim4c,max96712",
|
||||
.data = (const void *)MAX96712_CHIP_ID
|
||||
}, {
|
||||
.compatible = MAXIM4C_MAX96722_COMPAT,
|
||||
.data = &max96722_chip_id,
|
||||
.compatible = "maxim4c,max96722",
|
||||
.data = (const void *)MAX96722_CHIP_ID
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, maxim4c_of_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id maxim4c_match_id[] = {
|
||||
{ MAXIM4C_MAX96712_COMPAT, 0 },
|
||||
{ MAXIM4C_MAX96722_COMPAT, 0 },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct i2c_driver maxim4c_i2c_driver = {
|
||||
.driver = {
|
||||
|
|
@ -688,11 +728,10 @@ static struct i2c_driver maxim4c_i2c_driver = {
|
|||
},
|
||||
.probe = &maxim4c_probe,
|
||||
.remove = &maxim4c_remove,
|
||||
.id_table = maxim4c_match_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(maxim4c_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Cai wenzhong <cwz@rock-chips.com>");
|
||||
MODULE_DESCRIPTION("Maxim qual gmsl deserializer driver");
|
||||
MODULE_AUTHOR("Cai Wenzhong <cwz@rock-chips.com>");
|
||||
MODULE_DESCRIPTION("Maxim quad gmsl deserializer driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/rk-camera-module.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <media/media-entity.h>
|
||||
#include <media/v4l2-async.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
|
@ -55,7 +56,7 @@ struct maxim4c_mode {
|
|||
typedef struct maxim4c {
|
||||
struct i2c_client *client;
|
||||
struct clk *xvclk;
|
||||
struct gpio_desc *power_gpio;
|
||||
struct gpio_desc *pwdn_gpio;
|
||||
struct gpio_desc *pocen_gpio;
|
||||
struct gpio_desc *lock_gpio;
|
||||
|
||||
|
|
@ -101,6 +102,7 @@ typedef struct maxim4c {
|
|||
|
||||
struct maxim4c_i2c_init_seq extra_init_seq;
|
||||
|
||||
struct mfd_cell remote_mfd_devs[MAXIM4C_LINK_ID_MAX];
|
||||
maxim4c_remote_t *remote_device[MAXIM4C_LINK_ID_MAX];
|
||||
} maxim4c_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ int maxim4c_i2c_read_reg(struct i2c_client *client,
|
|||
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
dev_err(&client->dev,
|
||||
"%s: reading register 0x%x from 0x%x failed\n",
|
||||
"%s: reading register 0x%04x from 0x%02x failed\n",
|
||||
__func__, reg_addr, client->addr);
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,16 +107,16 @@ static int maxim4c_link_run_init_seq(maxim4c_t *maxim4c)
|
|||
maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link;
|
||||
struct maxim4c_link_cfg *link_cfg = NULL;
|
||||
struct maxim4c_i2c_init_seq *init_seq = NULL;
|
||||
int i = 0;
|
||||
int link_idx = 0;
|
||||
int ret = 0;
|
||||
|
||||
// link init sequence
|
||||
for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) {
|
||||
link_cfg = &gmsl_link->link_cfg[i];
|
||||
for (link_idx = 0; link_idx < MAXIM4C_LINK_ID_MAX; link_idx++) {
|
||||
link_cfg = &gmsl_link->link_cfg[link_idx];
|
||||
init_seq = &link_cfg->link_init_seq;
|
||||
ret = maxim4c_i2c_run_init_seq(client, init_seq);
|
||||
if (ret) {
|
||||
dev_err(dev, "link id = %d init sequence error\n", i);
|
||||
dev_err(dev, "link id = %d init sequence error\n", link_idx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -386,6 +386,11 @@ int maxim4c_link_wait_linklock(struct maxim4c *maxim4c, u8 link_mask)
|
|||
msleep(time_ms);
|
||||
|
||||
for (loop_idx = 0; loop_idx < 20; loop_idx++) {
|
||||
if (loop_idx != 0) {
|
||||
msleep(10);
|
||||
time_ms += 10;
|
||||
}
|
||||
|
||||
for (link_idx = 0; link_idx < MAXIM4C_LINK_ID_MAX; link_idx++) {
|
||||
link_bit_mask = BIT(link_idx);
|
||||
|
||||
|
|
@ -405,9 +410,6 @@ int maxim4c_link_wait_linklock(struct maxim4c *maxim4c, u8 link_mask)
|
|||
maxim4c->link_lock_state = lock_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
time_ms += 10;
|
||||
}
|
||||
|
||||
if ((lock_state & link_mask) != 0) {
|
||||
|
|
@ -554,9 +556,7 @@ static int maxim4c_gmsl_link_config_parse_dt(struct device *dev,
|
|||
struct device_node *init_seq_node = NULL;
|
||||
struct maxim4c_i2c_init_seq *init_seq = NULL;
|
||||
struct maxim4c_link_cfg *link_cfg = NULL;
|
||||
struct maxim4c_remote_info *remote_info;
|
||||
const char *link_cfg_name = "gmsl-link-config";
|
||||
const char *prop_str = NULL;
|
||||
u32 value = 0;
|
||||
u32 sub_idx = 0, link_id = 0;
|
||||
int ret = 0;
|
||||
|
|
@ -568,7 +568,8 @@ static int maxim4c_gmsl_link_config_parse_dt(struct device *dev,
|
|||
link_cfg_name,
|
||||
strlen(link_cfg_name))) {
|
||||
if (sub_idx >= MAXIM4C_LINK_ID_MAX) {
|
||||
dev_err(dev, "Too many matching %s node\n", link_cfg_name);
|
||||
dev_err(dev, "%pOF: Too many matching %s node\n",
|
||||
parent_node, link_cfg_name);
|
||||
|
||||
of_node_put(node);
|
||||
break;
|
||||
|
|
@ -622,20 +623,6 @@ static int maxim4c_gmsl_link_config_parse_dt(struct device *dev,
|
|||
link_cfg->link_rx_rate = value;
|
||||
}
|
||||
|
||||
/* remote info */
|
||||
remote_info = &link_cfg->remote_info;
|
||||
ret = of_property_read_string(node, "remote-name", &prop_str);
|
||||
if (ret == 0) {
|
||||
dev_info(dev, "remote-name property: %s", prop_str);
|
||||
remote_info->remote_name = prop_str;
|
||||
}
|
||||
|
||||
ret = of_property_read_string(node, "remote-compatible", &prop_str);
|
||||
if (ret == 0) {
|
||||
dev_info(dev, "remote-compatible property: %s", prop_str);
|
||||
remote_info->remote_compatible = prop_str;
|
||||
}
|
||||
|
||||
/* link init sequence */
|
||||
init_seq_node = of_get_child_by_name(node, "link-init-sequence");
|
||||
if (!IS_ERR_OR_NULL(init_seq_node)) {
|
||||
|
|
@ -666,8 +653,11 @@ int maxim4c_link_parse_dt(maxim4c_t *maxim4c, struct device_node *of_node)
|
|||
dev_info(dev, "=== maxim4c link parse dt ===\n");
|
||||
|
||||
node = of_get_child_by_name(of_node, "gmsl-links");
|
||||
if (IS_ERR_OR_NULL(node))
|
||||
if (IS_ERR_OR_NULL(node)) {
|
||||
dev_err(dev, "%pOF has no child node: gmsl-links\n",
|
||||
of_node);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", node);
|
||||
|
|
@ -699,29 +689,42 @@ EXPORT_SYMBOL(maxim4c_link_parse_dt);
|
|||
|
||||
int maxim4c_link_hw_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link;
|
||||
int ret = 0;
|
||||
|
||||
// All links disable at beginning.
|
||||
ret = maxim4c_link_status_init(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: link status error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (gmsl_link->link_vdd_ldo1_en)
|
||||
ret |= maxim4c_link_enable_vdd_ldo1(maxim4c);
|
||||
|
||||
if (gmsl_link->link_vdd_ldo2_en)
|
||||
ret |= maxim4c_link_enable_vdd_ldo2(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: link vdd ldo enable error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Link Rate Setting
|
||||
ret |= maxim4c_link_set_rate(maxim4c);
|
||||
if (ret)
|
||||
ret = maxim4c_link_set_rate(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: link set rate error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// link init sequence
|
||||
ret = maxim4c_link_run_init_seq(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: link run init seq error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_link_hw_init);
|
||||
|
||||
|
|
@ -745,8 +748,6 @@ void maxim4c_link_data_init(maxim4c_t *maxim4c)
|
|||
else
|
||||
link_cfg->link_rx_rate = MAXIM4C_LINK_RX_RATE_6GBPS;
|
||||
link_cfg->link_tx_rate = MAXIM4C_LINK_TX_RATE_187_5MPS;
|
||||
link_cfg->remote_info.remote_name = NULL;
|
||||
link_cfg->remote_info.remote_compatible = NULL;
|
||||
link_cfg->link_init_seq.reg_init_seq = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,18 +63,12 @@ enum maxim4c_link_tx_rate {
|
|||
MAXIM4C_LINK_TX_RATE_187_5MPS = 0,
|
||||
};
|
||||
|
||||
struct maxim4c_remote_info {
|
||||
const char *remote_name;
|
||||
const char *remote_compatible;
|
||||
};
|
||||
|
||||
struct maxim4c_link_cfg {
|
||||
u8 link_enable;
|
||||
u8 link_type;
|
||||
u8 link_rx_rate;
|
||||
u8 link_tx_rate;
|
||||
|
||||
struct maxim4c_remote_info remote_info;
|
||||
struct maxim4c_i2c_init_seq link_init_seq;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -220,11 +220,22 @@ int maxim4c_mipi_csi_output(maxim4c_t *maxim4c, bool enable)
|
|||
{
|
||||
struct i2c_client *client = maxim4c->client;
|
||||
struct device *dev = &client->dev;
|
||||
maxim4c_mipi_txphy_t *mipi_txphy = &maxim4c->mipi_txphy;
|
||||
u8 reg_mask = 0, reg_value = 0;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(dev, "%s: enable = %d\n", __func__, enable);
|
||||
|
||||
if (mipi_txphy->force_clock_out_en != 0) {
|
||||
reg_mask = BIT(7);
|
||||
reg_value = enable ? BIT(7) : 0;
|
||||
|
||||
// Force all MIPI clocks running Config
|
||||
ret |= maxim4c_i2c_update_byte(client,
|
||||
0x08A0, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
reg_mask, reg_value);
|
||||
}
|
||||
|
||||
/* Bit1 of the register 0x040B: CSI_OUT_EN
|
||||
* 1 = CSI output enabled
|
||||
* 0 = CSI output disabled
|
||||
|
|
@ -259,7 +270,8 @@ static int maxim4c_mipi_txphy_config_parse_dt(struct device *dev,
|
|||
txphy_cfg_name,
|
||||
strlen(txphy_cfg_name))) {
|
||||
if (sub_idx >= MAXIM4C_TXPHY_ID_MAX) {
|
||||
dev_err(dev, "Too many matching %s node\n", txphy_cfg_name);
|
||||
dev_err(dev, "%pOF: Too many matching %s node\n",
|
||||
parent_node, txphy_cfg_name);
|
||||
|
||||
of_node_put(node);
|
||||
break;
|
||||
|
|
@ -355,8 +367,11 @@ int maxim4c_mipi_txphy_parse_dt(maxim4c_t *maxim4c, struct device_node *of_node)
|
|||
dev_info(dev, "=== maxim4c mipi txphy parse dt ===\n");
|
||||
|
||||
node = of_get_child_by_name(of_node, "mipi-txphys");
|
||||
if (IS_ERR_OR_NULL(node))
|
||||
if (IS_ERR_OR_NULL(node)) {
|
||||
dev_err(dev, "%pOF has no child node: mipi-txphys\n",
|
||||
of_node);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", node);
|
||||
|
|
@ -404,6 +419,7 @@ EXPORT_SYMBOL(maxim4c_mipi_txphy_parse_dt);
|
|||
int maxim4c_mipi_txphy_hw_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct i2c_client *client = maxim4c->client;
|
||||
struct device *dev = &client->dev;
|
||||
maxim4c_mipi_txphy_t *mipi_txphy = &maxim4c->mipi_txphy;
|
||||
struct maxim4c_txphy_cfg *phy_cfg = NULL;
|
||||
u8 mode = 0;
|
||||
|
|
@ -479,9 +495,6 @@ int maxim4c_mipi_txphy_hw_init(maxim4c_t *maxim4c)
|
|||
phy_cfg->clock_master = 1;
|
||||
break;
|
||||
}
|
||||
// MIPI clocks running mode
|
||||
if (mipi_txphy->force_clock_out_en != 0)
|
||||
mode |= BIT(7);
|
||||
|
||||
// MIPI TXPHY Mode setting
|
||||
ret |= maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -497,7 +510,12 @@ int maxim4c_mipi_txphy_hw_init(maxim4c_t *maxim4c)
|
|||
// mipi txphy auto init deskew
|
||||
ret |= maxim4c_txphy_auto_init_deskew(maxim4c);
|
||||
|
||||
return ret;
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: txphy hw init error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_mipi_txphy_hw_init);
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,13 @@ static int maxim4c_pattern_previnit(maxim4c_t *maxim4c)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
// video pipe disable.
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
0x00F4, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
// MIPI CSI output disable.
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
0x040B, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
|
|
@ -108,7 +115,7 @@ static int maxim4c_pattern_previnit(maxim4c_t *maxim4c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int maxim4c_pattern_hw_init(maxim4c_t *maxim4c)
|
||||
static int maxim4c_pattern_config(maxim4c_t *maxim4c)
|
||||
{
|
||||
const u32 h_active = PATTERN_WIDTH;
|
||||
const u32 h_fp = 88;
|
||||
|
|
@ -249,18 +256,40 @@ static int maxim4c_pattern_hw_init(maxim4c_t *maxim4c)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int maxim4c_pattern_init(maxim4c_t *maxim4c)
|
||||
int maxim4c_pattern_support_mode_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
struct maxim4c_mode *supported_mode = NULL;
|
||||
|
||||
dev_info(dev, "=== maxim4c pattern support mode init ===\n");
|
||||
|
||||
maxim4c->cfg_modes_num = 1;
|
||||
maxim4c->cur_mode = &maxim4c->supported_mode;
|
||||
supported_mode = &maxim4c->supported_mode;
|
||||
|
||||
// init using def mode
|
||||
memcpy(supported_mode, &maxim4c_pattern_mode, sizeof(struct maxim4c_mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_pattern_support_mode_init);
|
||||
|
||||
int maxim4c_pattern_data_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
struct device_node *node = NULL;
|
||||
struct maxim4c_mode *supported_mode = NULL;
|
||||
struct maxim4c_pattern *pattern = NULL;
|
||||
maxim4c_mipi_txphy_t *mipi_txphy = &maxim4c->mipi_txphy;
|
||||
int ret = 0;
|
||||
|
||||
// maxim serdes local
|
||||
node = of_get_child_by_name(dev->of_node, "serdes-local-device");
|
||||
if (IS_ERR_OR_NULL(node))
|
||||
if (IS_ERR_OR_NULL(node)) {
|
||||
dev_err(dev, "%pOF has no child node: serdes-local-device\n",
|
||||
dev->of_node);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", node);
|
||||
|
|
@ -273,23 +302,14 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c)
|
|||
|
||||
/* mipi txphy parse dt */
|
||||
ret = maxim4c_mipi_txphy_parse_dt(maxim4c, node);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: txphy parse dt error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_pattern_previnit(maxim4c);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = maxim4c_mipi_txphy_hw_init(maxim4c);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
maxim4c->cfg_modes_num = 1;
|
||||
maxim4c->cur_mode = &maxim4c->supported_mode;
|
||||
supported_mode = &maxim4c->supported_mode;
|
||||
|
||||
// init using def mode
|
||||
memcpy(supported_mode, &maxim4c_pattern_mode, sizeof(struct maxim4c_mode));
|
||||
// pattern need enable force_clock_out_en
|
||||
dev_info(dev, "Pattern mode force_clock_out_en default enable\n");
|
||||
mipi_txphy->force_clock_out_en = 1;
|
||||
|
||||
// pattern generator and mode init
|
||||
pattern = &maxim4c->pattern;
|
||||
|
|
@ -297,6 +317,7 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c)
|
|||
pattern->pattern_mode = PATTERN_CHECKERBOARD;
|
||||
pattern->pattern_pclk = PATTERN_PCLK_75M;
|
||||
|
||||
supported_mode = &maxim4c->supported_mode;
|
||||
switch (pattern->pattern_pclk) {
|
||||
case PATTERN_PCLK_25M:
|
||||
supported_mode->max_fps.denominator = 100000;
|
||||
|
|
@ -307,13 +328,13 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c)
|
|||
case PATTERN_PCLK_150M:
|
||||
supported_mode->max_fps.denominator = 600000;
|
||||
if (supported_mode->link_freq_idx < 12)
|
||||
dev_info(dev, "link_freq_idx = %d is too low\n",
|
||||
dev_warn(dev, "link_freq_idx = %d is too low\n",
|
||||
supported_mode->link_freq_idx);
|
||||
break;
|
||||
case PATTERN_PCLK_375M:
|
||||
supported_mode->max_fps.denominator = 1500000;
|
||||
if (supported_mode->link_freq_idx < 22)
|
||||
dev_info(dev, "link_freq_idx = %d is too low\n",
|
||||
dev_warn(dev, "link_freq_idx = %d is too low\n",
|
||||
supported_mode->link_freq_idx);
|
||||
break;
|
||||
}
|
||||
|
|
@ -321,8 +342,33 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c)
|
|||
dev_info(dev, "video pattern: generator = %d, mode = %d, pclk = %d\n",
|
||||
pattern->pattern_generator, pattern->pattern_mode, pattern->pattern_pclk);
|
||||
|
||||
ret = maxim4c_pattern_hw_init(maxim4c);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_pattern_init);
|
||||
EXPORT_SYMBOL(maxim4c_pattern_data_init);
|
||||
|
||||
int maxim4c_pattern_hw_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
int ret = 0;
|
||||
|
||||
ret = maxim4c_pattern_previnit(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: pattern previnit error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_mipi_txphy_hw_init(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: txphy hw init error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_pattern_config(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: pattern config error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_pattern_hw_init);
|
||||
|
|
|
|||
|
|
@ -8,48 +8,129 @@
|
|||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include "maxim4c_api.h"
|
||||
|
||||
static struct mfd_cell maxim4c_remote_devs[MAXIM4C_LINK_ID_MAX];
|
||||
static const char *maxim4c_remote_devs_name[MAXIM4C_LINK_ID_MAX] = {
|
||||
"remote0", "remote1", "remote2", "remote3"
|
||||
};
|
||||
|
||||
static const char *maxim4c_remote_link_compat[MAXIM4C_LINK_ID_MAX] = {
|
||||
"maxim4c,link0", "maxim4c,link1", "maxim4c,link2", "maxim4c,link3"
|
||||
};
|
||||
|
||||
static int maxim4c_remote_dev_info_parse(struct device *dev,
|
||||
struct mfd_cell *remote_mfd_dev, u8 link_id)
|
||||
{
|
||||
struct device_node *node = NULL;
|
||||
const char *remote_device_name = "serdes-remote-device";
|
||||
const char *prop_str = NULL, *link_compat = NULL;
|
||||
u32 sub_idx = 0, remote_id = 0;
|
||||
int ret = 0;
|
||||
|
||||
node = NULL;
|
||||
sub_idx = 0;
|
||||
while ((node = of_get_next_child(dev->of_node, node))) {
|
||||
if (!strncasecmp(node->name,
|
||||
remote_device_name,
|
||||
strlen(remote_device_name))) {
|
||||
if (sub_idx >= MAXIM4C_LINK_ID_MAX) {
|
||||
dev_err(dev, "%pOF: Too many matching %s node\n",
|
||||
dev->of_node, remote_device_name);
|
||||
|
||||
of_node_put(node);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", node);
|
||||
|
||||
sub_idx++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* remote id */
|
||||
ret = of_property_read_u32(node, "remote-id", &remote_id);
|
||||
if (ret) {
|
||||
sub_idx++;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (remote_id >= MAXIM4C_LINK_ID_MAX) {
|
||||
sub_idx++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (remote_id != link_id) {
|
||||
sub_idx++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
dev_info(dev, "remote device id = %d\n", remote_id);
|
||||
|
||||
ret = of_property_read_string(node, "compatible", &prop_str);
|
||||
if (ret) {
|
||||
dev_err(dev, "%pOF no compatible error\n", node);
|
||||
|
||||
of_node_put(node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
link_compat = maxim4c_remote_link_compat[remote_id];
|
||||
if (!strncasecmp(prop_str,
|
||||
link_compat, strlen(link_compat))) {
|
||||
dev_info(dev, "compatible property: %s\n", prop_str);
|
||||
|
||||
remote_mfd_dev->name = maxim4c_remote_devs_name[remote_id];
|
||||
remote_mfd_dev->of_compatible = prop_str;
|
||||
|
||||
of_node_put(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_err(dev, "%pOF compatible and remote_id mismatch\n", node);
|
||||
|
||||
of_node_put(node);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int maxim4c_remote_mfd_devs_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link;
|
||||
struct maxim4c_link_cfg *link_cfg = NULL;
|
||||
struct mfd_cell *remote_mfd_dev = NULL;
|
||||
const char *remote_name = NULL, *remote_compatible = NULL;
|
||||
int link_idx = 0, nr_mfd_cell = 0;
|
||||
int ret = 0;
|
||||
|
||||
remote_mfd_dev = maxim4c_remote_devs;
|
||||
remote_mfd_dev = maxim4c->remote_mfd_devs;
|
||||
nr_mfd_cell = 0;
|
||||
for (link_idx = 0; link_idx < MAXIM4C_LINK_ID_MAX; link_idx++) {
|
||||
link_cfg = &gmsl_link->link_cfg[link_idx];
|
||||
if (link_cfg->link_enable == 0)
|
||||
continue;
|
||||
remote_mfd_dev->name = NULL;
|
||||
remote_mfd_dev->of_compatible = NULL;
|
||||
|
||||
remote_name = link_cfg->remote_info.remote_name;
|
||||
remote_compatible = link_cfg->remote_info.remote_compatible;
|
||||
if (remote_compatible == NULL) {
|
||||
dev_err(dev, "%s: link id = %d, remote compatible = NULL",
|
||||
__func__, link_idx);
|
||||
if (gmsl_link->link_cfg[link_idx].link_enable == 0) {
|
||||
dev_dbg(dev, "%s: link id = %d is disabled\n",
|
||||
__func__, link_idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (remote_name == NULL) {
|
||||
dev_err(dev, "%s: link id = %d, remote name = NULL",
|
||||
__func__, link_idx);
|
||||
continue;
|
||||
ret = maxim4c_remote_dev_info_parse(dev, remote_mfd_dev, link_idx);
|
||||
if (ret == 0) {
|
||||
remote_mfd_dev++;
|
||||
nr_mfd_cell++;
|
||||
}
|
||||
|
||||
remote_mfd_dev->name = remote_name;
|
||||
remote_mfd_dev->of_compatible = remote_compatible;
|
||||
|
||||
remote_mfd_dev++;
|
||||
nr_mfd_cell++;
|
||||
}
|
||||
|
||||
dev_info(dev, "Total number of remote devices is %d", nr_mfd_cell);
|
||||
|
||||
return nr_mfd_cell;
|
||||
}
|
||||
|
||||
|
|
@ -58,19 +139,21 @@ int maxim4c_remote_mfd_add_devices(maxim4c_t *maxim4c)
|
|||
struct device *dev = &maxim4c->client->dev;
|
||||
int nr_mfd_cell = 0, ret = 0;
|
||||
|
||||
dev_info(dev, "=== maxim4c add remote devices ===");
|
||||
|
||||
nr_mfd_cell = maxim4c_remote_mfd_devs_init(maxim4c);
|
||||
if (nr_mfd_cell == 0) {
|
||||
dev_err(dev, "%s: remote mfd devices init error\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO,
|
||||
maxim4c_remote_devs, nr_mfd_cell,
|
||||
maxim4c->remote_mfd_devs, nr_mfd_cell,
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
dev_err(dev, "%s: add remote mfd devices error: %d\n",
|
||||
__func__, ret);
|
||||
__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -87,14 +170,14 @@ int maxim4c_remote_devices_init(maxim4c_t *maxim4c, u8 link_init_mask)
|
|||
dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask);
|
||||
|
||||
for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) {
|
||||
link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable;
|
||||
if (link_enable == 0) {
|
||||
dev_info(dev, "link id = %d is disabled\n", i);
|
||||
if ((link_init_mask & BIT(i)) == 0) {
|
||||
dev_dbg(dev, "link id = %d init mask is disabled\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((link_init_mask & BIT(i)) == 0) {
|
||||
dev_info(dev, "link id = %d init mask is disabled\n", i);
|
||||
link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable;
|
||||
if (link_enable == 0) {
|
||||
dev_info(dev, "link id = %d is disabled\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -143,14 +226,14 @@ int maxim4c_remote_devices_deinit(maxim4c_t *maxim4c, u8 link_init_mask)
|
|||
dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask);
|
||||
|
||||
for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) {
|
||||
link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable;
|
||||
if (link_enable == 0) {
|
||||
dev_info(dev, "link id = %d is disabled\n", i);
|
||||
if ((link_init_mask & BIT(i)) == 0) {
|
||||
dev_dbg(dev, "link id = %d init mask is disabled\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((link_init_mask & BIT(i)) == 0) {
|
||||
dev_info(dev, "link id = %d init mask is disabled\n", i);
|
||||
link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable;
|
||||
if (link_enable == 0) {
|
||||
dev_info(dev, "link id = %d is disabled\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -196,54 +279,156 @@ int maxim4c_remote_load_init_seq(maxim4c_remote_t *remote_device)
|
|||
|
||||
node = of_get_child_by_name(dev->of_node, "remote-init-sequence");
|
||||
if (!IS_ERR_OR_NULL(node)) {
|
||||
dev_info(dev, "load remote-init-sequence\n");
|
||||
|
||||
ret = maxim4c_i2c_load_init_seq(dev, node,
|
||||
&remote_device->remote_init_seq);
|
||||
|
||||
of_node_put(node);
|
||||
|
||||
} else {
|
||||
ret = 0;
|
||||
dev_info(dev, "no node remote-init-sequence\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_remote_load_init_seq);
|
||||
|
||||
int maxim4c_remote_i2c_addr_select(maxim4c_remote_t *remote_device, u32 i2c_id)
|
||||
{
|
||||
struct device *dev = remote_device->dev;
|
||||
struct i2c_client *client = remote_device->client;
|
||||
|
||||
if (i2c_id == MAXIM4C_I2C_SER_DEF) {
|
||||
client->addr = remote_device->ser_i2c_addr_def;
|
||||
dev_info(dev, "ser select default i2c addr = 0x%02x\n", client->addr);
|
||||
} else if (i2c_id == MAXIM4C_I2C_SER_MAP) {
|
||||
client->addr = remote_device->ser_i2c_addr_map;
|
||||
dev_info(dev, "ser select mapping i2c addr = 0x%02x\n", client->addr);
|
||||
} else {
|
||||
dev_err(dev, "i2c select id = %d error\n", i2c_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_remote_i2c_addr_select);
|
||||
|
||||
int maxim4c_remote_i2c_client_init(maxim4c_remote_t *remote_device,
|
||||
struct i2c_client *des_client)
|
||||
{
|
||||
struct device *dev = remote_device->dev;
|
||||
struct i2c_client *ser_client = NULL;
|
||||
u16 ser_client_addr = 0;
|
||||
|
||||
if (remote_device->ser_i2c_addr_map)
|
||||
ser_client_addr = remote_device->ser_i2c_addr_map;
|
||||
else
|
||||
ser_client_addr = remote_device->ser_i2c_addr_def;
|
||||
ser_client = devm_i2c_new_dummy_device(&des_client->dev,
|
||||
des_client->adapter, ser_client_addr);
|
||||
if (IS_ERR(ser_client)) {
|
||||
dev_err(dev, "failed to alloc i2c client.\n");
|
||||
return -PTR_ERR(ser_client);
|
||||
}
|
||||
ser_client->addr = remote_device->ser_i2c_addr_def;
|
||||
|
||||
remote_device->client = ser_client;
|
||||
i2c_set_clientdata(ser_client, remote_device);
|
||||
|
||||
dev_info(dev, "remote i2c client init, i2c_addr = 0x%02x\n",
|
||||
ser_client_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_remote_i2c_client_init);
|
||||
|
||||
static int maxim4c_remote_device_chain_check(maxim4c_remote_t *remote_device)
|
||||
{
|
||||
struct device *dev = NULL;
|
||||
struct device_node *endpoint = NULL;
|
||||
struct device_node *link_node = NULL;
|
||||
u8 remote_id, link_id;
|
||||
u32 value;
|
||||
int ret = 0;
|
||||
|
||||
if (remote_device == NULL) {
|
||||
dev_err(dev, "%s: input parameter is error\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = remote_device->dev;
|
||||
remote_id = remote_device->remote_id;
|
||||
|
||||
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
|
||||
if (!endpoint) {
|
||||
dev_err(dev, "%s: no endpoint error\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
link_node = of_graph_get_remote_port_parent(endpoint);
|
||||
if (!link_node) {
|
||||
dev_err(dev, "%pOF: endpoint has no remote port parent error\n",
|
||||
endpoint);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(link_node, "link-id", &value);
|
||||
if (ret) {
|
||||
dev_err(dev, "%pOF: no property link_id error\n", link_node);
|
||||
|
||||
of_node_put(link_node);
|
||||
return -EINVAL;
|
||||
}
|
||||
of_node_put(link_node);
|
||||
link_id = value;
|
||||
|
||||
if (remote_id != link_id) {
|
||||
dev_err(dev, "remote_id (%d) != link_id (%d) of %pOF\n",
|
||||
remote_id, link_id, link_node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maxim4c_remote_device_register(maxim4c_t *maxim4c,
|
||||
maxim4c_remote_t *remote_device)
|
||||
{
|
||||
struct device *dev = NULL;
|
||||
u8 remote_id;
|
||||
int ret = 0;
|
||||
|
||||
if ((maxim4c == NULL) || (remote_device == NULL)) {
|
||||
dev_err(dev, "%s: input parameter is error!\n",
|
||||
__func__);
|
||||
dev_err(dev, "%s: input parameter is error!\n", __func__);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = remote_device->dev;
|
||||
remote_id = remote_device->remote_id;
|
||||
if (remote_id < MAXIM4C_LINK_ID_MAX) {
|
||||
if (maxim4c->remote_device[remote_id] == NULL) {
|
||||
remote_device->remote_enable = 1;
|
||||
maxim4c->remote_device[remote_id] = remote_device;
|
||||
dev_dbg(dev, "%s: remote_id = %d is success\n",
|
||||
__func__, remote_id);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
dev_err(dev, "%s: remote_id = %d is conflict\n",
|
||||
__func__, remote_id);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (remote_id >= MAXIM4C_LINK_ID_MAX) {
|
||||
dev_err(dev, "%s: remote_id = %d is error\n",
|
||||
__func__, remote_id);
|
||||
__func__, remote_id);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (maxim4c->remote_device[remote_id] != NULL) {
|
||||
dev_err(dev, "%s: remote_id = %d is conflict\n",
|
||||
__func__, remote_id);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_device_chain_check(remote_device);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: remote device id = %d chain error\n",
|
||||
__func__, remote_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
remote_device->remote_enable = 1;
|
||||
maxim4c->remote_device[remote_id] = remote_device;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(maxim4c_remote_device_register);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ static int maxim4c_support_mode_init(maxim4c_t *maxim4c)
|
|||
|
||||
dev_info(dev, "=== maxim4c support mode init ===\n");
|
||||
|
||||
#if MAXIM4C_TEST_PATTERN
|
||||
ret = maxim4c_pattern_support_mode_init(maxim4c);
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
maxim4c->cfg_modes_num = 1;
|
||||
maxim4c->cur_mode = &maxim4c->supported_mode;
|
||||
mode = &maxim4c->supported_mode;
|
||||
|
|
@ -311,14 +316,12 @@ static long maxim4c_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
|||
break;
|
||||
case RKMODULE_SET_CSI_DPHY_PARAM:
|
||||
dphy_param = (struct rkmodule_csi_dphy_param *)arg;
|
||||
if (dphy_param->vendor == rk3588_dcphy_param.vendor)
|
||||
rk3588_dcphy_param = *dphy_param;
|
||||
rk3588_dcphy_param = *dphy_param;
|
||||
dev_dbg(&maxim4c->client->dev, "set dcphy param\n");
|
||||
break;
|
||||
case RKMODULE_GET_CSI_DPHY_PARAM:
|
||||
dphy_param = (struct rkmodule_csi_dphy_param *)arg;
|
||||
if (dphy_param->vendor == rk3588_dcphy_param.vendor)
|
||||
*dphy_param = rk3588_dcphy_param;
|
||||
*dphy_param = rk3588_dcphy_param;
|
||||
dev_dbg(&maxim4c->client->dev, "get dcphy param\n");
|
||||
break;
|
||||
default:
|
||||
|
|
@ -430,6 +433,22 @@ static int __maxim4c_start_stream(struct maxim4c *maxim4c)
|
|||
u8 link_mask = 0, link_freq_idx = 0;
|
||||
u8 video_pipe_mask = 0;
|
||||
|
||||
#if MAXIM4C_LOCAL_DES_ON_OFF_EN
|
||||
#if MAXIM4C_TEST_PATTERN
|
||||
ret = maxim4c_pattern_hw_init(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "test pattern hw init error\n");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
ret = maxim4c_module_hw_init(maxim4c);
|
||||
if (ret) {
|
||||
dev_err(dev, "maxim4c module hw init error\n");
|
||||
return ret;
|
||||
}
|
||||
#endif /* MAXIM4C_TEST_PATTERN */
|
||||
#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
|
||||
|
||||
link_mask = maxim4c->gmsl_link.link_enable_mask;
|
||||
video_pipe_mask = maxim4c->video_pipe.pipe_enable_mask;
|
||||
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ static int maxim4c_video_pipe_config_parse_dt(struct device *dev,
|
|||
pipe_cfg_name,
|
||||
strlen(pipe_cfg_name))) {
|
||||
if (sub_idx >= MAXIM4C_PIPE_O_ID_MAX) {
|
||||
dev_err(dev, "Too many matching %s node\n",
|
||||
pipe_cfg_name);
|
||||
dev_err(dev, "%pOF: Too many matching %s node\n",
|
||||
parent_node, pipe_cfg_name);
|
||||
|
||||
of_node_put(node);
|
||||
break;
|
||||
|
|
@ -205,8 +205,11 @@ int maxim4c_video_pipe_parse_dt(maxim4c_t *maxim4c, struct device_node *of_node)
|
|||
dev_info(dev, "=== maxim4c video pipe parse dt ===\n");
|
||||
|
||||
node = of_get_child_by_name(of_node, "video-pipes");
|
||||
if (IS_ERR_OR_NULL(node))
|
||||
if (IS_ERR_OR_NULL(node)) {
|
||||
dev_err(dev, "%pOF has no child node: video-pipes\n",
|
||||
of_node);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_info(dev, "%pOF is disabled\n", node);
|
||||
|
|
@ -325,21 +328,28 @@ EXPORT_SYMBOL(maxim4c_video_pipe_data_init);
|
|||
|
||||
int maxim4c_video_pipe_hw_init(maxim4c_t *maxim4c)
|
||||
{
|
||||
struct device *dev = &maxim4c->client->dev;
|
||||
u8 pipe_enable_mask = 0;
|
||||
int ret = 0;
|
||||
|
||||
ret = maxim4c_video_pipe_select(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: video pipe select error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pipe_enable_mask = maxim4c->video_pipe.pipe_enable_mask;
|
||||
ret = maxim4c_video_pipe_mask_enable(maxim4c, pipe_enable_mask, true);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: video pipe mask enable error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_video_pipe_run_init_seq(maxim4c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: video pipe run init seq error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,25 +20,6 @@
|
|||
#define MAX9295_CHIP_ID 0x91
|
||||
#define MAX9295_REG_CHIP_ID 0x0D
|
||||
|
||||
static int max9295_i2c_addr_select(maxim4c_remote_t *max9295, u32 i2c_id)
|
||||
{
|
||||
struct device *dev = max9295->dev;
|
||||
struct i2c_client *client = max9295->client;
|
||||
|
||||
if (i2c_id == MAXIM4C_I2C_SER_DEF) {
|
||||
client->addr = max9295->ser_i2c_addr_def;
|
||||
dev_info(dev, "select default i2c addr = 0x%x\n", client->addr);
|
||||
} else if (i2c_id == MAXIM4C_I2C_SER_MAP) {
|
||||
client->addr = max9295->ser_i2c_addr_map;
|
||||
dev_info(dev, "select mapping i2c addr = 0x%x\n", client->addr);
|
||||
} else {
|
||||
dev_err(dev, "i2c select id = %d error\n", i2c_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9295_i2c_addr_remap(maxim4c_remote_t *max9295)
|
||||
{
|
||||
struct device *dev = max9295->dev;
|
||||
|
|
@ -49,7 +30,7 @@ static int max9295_i2c_addr_remap(maxim4c_remote_t *max9295)
|
|||
if (max9295->ser_i2c_addr_map) {
|
||||
dev_info(dev, "Serializer i2c address remap\n");
|
||||
|
||||
max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
|
||||
i2c_8bit_addr = (max9295->ser_i2c_addr_map << 1);
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -60,7 +41,7 @@ static int max9295_i2c_addr_remap(maxim4c_remote_t *max9295)
|
|||
return ret;
|
||||
}
|
||||
|
||||
max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP);
|
||||
}
|
||||
|
||||
if (max9295->cam_i2c_addr_map) {
|
||||
|
|
@ -98,7 +79,7 @@ static int max9295_i2c_addr_def(maxim4c_remote_t *max9295)
|
|||
if (max9295->ser_i2c_addr_map) {
|
||||
dev_info(dev, "Serializer i2c address def\n");
|
||||
|
||||
max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP);
|
||||
|
||||
i2c_8bit_addr = (max9295->ser_i2c_addr_def << 1);
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -109,7 +90,7 @@ static int max9295_i2c_addr_def(maxim4c_remote_t *max9295)
|
|||
return ret;
|
||||
}
|
||||
|
||||
max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -128,13 +109,13 @@ static int max9295_check_chipid(maxim4c_remote_t *max9295)
|
|||
&chip_id);
|
||||
if (ret != 0) {
|
||||
dev_info(dev, "Retry check chipid using map address\n");
|
||||
max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP);
|
||||
ret = maxim4c_i2c_read_byte(client,
|
||||
MAX9295_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
&chip_id);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "MAX9295 detect error, ret(%d)\n", ret);
|
||||
max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
@ -143,13 +124,13 @@ static int max9295_check_chipid(maxim4c_remote_t *max9295)
|
|||
}
|
||||
|
||||
if (chip_id != MAX9295_CHIP_ID) {
|
||||
dev_err(dev, "Unexpected MAX9295 chip id(%02x)\n", chip_id);
|
||||
dev_err(dev, "Unexpected chip id = %02x\n", chip_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(dev, "Detected MAX9295 chipid: 0x%02x\n", chip_id);
|
||||
dev_info(dev, "Detected MAX9295 chip id: 0x%02x\n", chip_id);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9295_soft_power_down(maxim4c_remote_t *max9295)
|
||||
|
|
@ -175,7 +156,7 @@ static int max9295_module_init(maxim4c_remote_t *max9295)
|
|||
struct i2c_client *client = max9295->client;
|
||||
int ret = 0;
|
||||
|
||||
ret = max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
ret = maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -263,47 +244,30 @@ static int max9295_parse_dt(maxim4c_remote_t *max9295)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int max9295_i2c_client_init(maxim4c_remote_t *max9295,
|
||||
struct i2c_client *local_client)
|
||||
{
|
||||
struct device *dev = max9295->dev;
|
||||
struct i2c_client *remote_client = NULL;
|
||||
u16 remote_client_addr = 0;
|
||||
|
||||
if (max9295->ser_i2c_addr_map)
|
||||
remote_client_addr = max9295->ser_i2c_addr_map;
|
||||
else
|
||||
remote_client_addr = max9295->ser_i2c_addr_def;
|
||||
remote_client = devm_i2c_new_dummy_device(&local_client->dev,
|
||||
local_client->adapter, remote_client_addr);
|
||||
if (IS_ERR(remote_client)) {
|
||||
dev_err(dev, "failed to alloc i2c client.\n");
|
||||
return -PTR_ERR(remote_client);
|
||||
}
|
||||
remote_client->addr = max9295->ser_i2c_addr_def;
|
||||
|
||||
max9295->client = remote_client;
|
||||
i2c_set_clientdata(remote_client, max9295);
|
||||
|
||||
dev_info(dev, "remote i2c client init, i2c_addr = 0x%x\n",
|
||||
remote_client_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9295_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(pdev->dev.parent);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct maxim4c *maxim4c = v4l2_get_subdevdata(sd);
|
||||
struct maxim4c_remote *max9295 = NULL;
|
||||
u32 link_id = MAXIM4C_LINK_ID_MAX;
|
||||
int ret = 0;
|
||||
|
||||
dev_info(&pdev->dev, "max9295 serializer probe\n");
|
||||
|
||||
link_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
|
||||
link_id = link_id - MAXIM4C_LINK_ID_MAX;
|
||||
if (link_id >= MAXIM4C_LINK_ID_MAX) {
|
||||
dev_err(&pdev->dev, "max9295 probe match data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(&pdev->dev, "max9295 probe link id = %d\n", link_id);
|
||||
|
||||
max9295 = devm_kzalloc(&pdev->dev, sizeof(*max9295), GFP_KERNEL);
|
||||
if (!max9295)
|
||||
if (!max9295) {
|
||||
dev_err(&pdev->dev, "max9295 probe no memory error\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
max9295->dev = &pdev->dev;
|
||||
max9295->remote_ops = &max9295_ops;
|
||||
|
|
@ -312,11 +276,22 @@ static int max9295_probe(struct platform_device *pdev)
|
|||
|
||||
max9295_parse_dt(max9295);
|
||||
|
||||
max9295_i2c_client_init(max9295, client);
|
||||
if (max9295->remote_id != link_id) {
|
||||
dev_err(&pdev->dev, "max9295 probe remote_id error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_i2c_client_init(max9295, client);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "remote i2c client init error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_device_register(maxim4c, max9295);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "remote serializer register error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
maxim4c_remote_load_init_seq(max9295);
|
||||
|
||||
|
|
@ -329,10 +304,21 @@ static int max9295_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id max9295_of_table[] = {
|
||||
{ .compatible = "maxim4c,max9295", },
|
||||
{
|
||||
.compatible = "maxim4c,link0,max9295",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_A)
|
||||
}, {
|
||||
.compatible = "maxim4c,link1,max9295",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_B)
|
||||
}, {
|
||||
.compatible = "maxim4c,link2,max9295",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_C)
|
||||
}, {
|
||||
.compatible = "maxim4c,link3,max9295",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_D)
|
||||
},
|
||||
{ /* Sentinel */ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, max9295_of_table);
|
||||
|
||||
static struct platform_driver max9295_driver = {
|
||||
|
|
|
|||
|
|
@ -34,43 +34,28 @@ static int __maybe_unused max96715_link_mode_select(maxim4c_remote_t *max96715,
|
|||
struct device *dev = max96715->dev;
|
||||
struct i2c_client *client = max96715->client;
|
||||
u8 reg_mask = 0, reg_value = 0;
|
||||
u32 delay_ms = 0;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(dev, "%s: mode = %d\n", __func__, mode);
|
||||
|
||||
reg_mask = BIT(7) | BIT(6);
|
||||
if (mode == LINK_MODE_CONFIG)
|
||||
if (mode == LINK_MODE_CONFIG) {
|
||||
reg_value = BIT(6);
|
||||
else
|
||||
delay_ms = 5;
|
||||
} else {
|
||||
reg_value = BIT(7);
|
||||
delay_ms = 50;
|
||||
}
|
||||
ret |= maxim4c_i2c_update_byte(client,
|
||||
0x04, MAXIM4C_I2C_REG_ADDR_08BITS,
|
||||
reg_mask, reg_value);
|
||||
|
||||
mdelay(5);
|
||||
msleep(delay_ms);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max96715_i2c_addr_select(maxim4c_remote_t *max96715, u32 i2c_id)
|
||||
{
|
||||
struct device *dev = max96715->dev;
|
||||
struct i2c_client *client = max96715->client;
|
||||
|
||||
if (i2c_id == MAXIM4C_I2C_SER_DEF) {
|
||||
client->addr = max96715->ser_i2c_addr_def;
|
||||
dev_info(dev, "select default i2c addr = 0x%x\n", client->addr);
|
||||
} else if (i2c_id == MAXIM4C_I2C_SER_MAP) {
|
||||
client->addr = max96715->ser_i2c_addr_map;
|
||||
dev_info(dev, "select mapping i2c addr = 0x%x\n", client->addr);
|
||||
} else {
|
||||
dev_err(dev, "i2c select id = %d error\n", i2c_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96715_i2c_addr_remap(maxim4c_remote_t *max96715)
|
||||
{
|
||||
struct device *dev = max96715->dev;
|
||||
|
|
@ -81,7 +66,7 @@ static int max96715_i2c_addr_remap(maxim4c_remote_t *max96715)
|
|||
if (max96715->ser_i2c_addr_map) {
|
||||
dev_info(dev, "Serializer i2c address remap\n");
|
||||
|
||||
max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
|
||||
i2c_8bit_addr = (max96715->ser_i2c_addr_map << 1);
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -92,7 +77,7 @@ static int max96715_i2c_addr_remap(maxim4c_remote_t *max96715)
|
|||
return ret;
|
||||
}
|
||||
|
||||
max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP);
|
||||
}
|
||||
|
||||
if (max96715->cam_i2c_addr_map) {
|
||||
|
|
@ -130,7 +115,7 @@ static int max96715_i2c_addr_def(maxim4c_remote_t *max96715)
|
|||
if (max96715->ser_i2c_addr_map) {
|
||||
dev_info(dev, "Serializer i2c address def\n");
|
||||
|
||||
max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP);
|
||||
|
||||
i2c_8bit_addr = (max96715->ser_i2c_addr_def << 1);
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -141,7 +126,7 @@ static int max96715_i2c_addr_def(maxim4c_remote_t *max96715)
|
|||
return ret;
|
||||
}
|
||||
|
||||
max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -160,13 +145,13 @@ static int max96715_check_chipid(maxim4c_remote_t *max96715)
|
|||
&chip_id);
|
||||
if (ret != 0) {
|
||||
dev_info(dev, "Retry check chipid using map address\n");
|
||||
max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP);
|
||||
ret = maxim4c_i2c_read_byte(client,
|
||||
MAX96715_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_08BITS,
|
||||
&chip_id);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "MAX96715 detect error, ret(%d)\n", ret);
|
||||
max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
@ -175,13 +160,13 @@ static int max96715_check_chipid(maxim4c_remote_t *max96715)
|
|||
}
|
||||
|
||||
if (chip_id != MAX96715_CHIP_ID) {
|
||||
dev_err(dev, "Unexpected MAX96715 chip id(%02x)\n", chip_id);
|
||||
dev_err(dev, "Unexpected chip id = %02x\n", chip_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(dev, "Detected MAX96715 chipid: 0x%02x\n", chip_id);
|
||||
dev_info(dev, "Detected MAX96715 chip id: 0x%02x\n", chip_id);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96715_soft_power_down(maxim4c_remote_t *max96715)
|
||||
|
|
@ -208,7 +193,7 @@ static int max96715_module_init(maxim4c_remote_t *max96715)
|
|||
struct maxim4c *maxim4c = max96715->local;
|
||||
int ret = 0;
|
||||
|
||||
ret = max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
ret = maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -322,47 +307,30 @@ static int max96715_parse_dt(maxim4c_remote_t *max96715)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int max96715_i2c_client_init(maxim4c_remote_t *max96715,
|
||||
struct i2c_client *local_client)
|
||||
{
|
||||
struct device *dev = max96715->dev;
|
||||
struct i2c_client *remote_client = NULL;
|
||||
u16 remote_client_addr = 0;
|
||||
|
||||
if (max96715->ser_i2c_addr_map)
|
||||
remote_client_addr = max96715->ser_i2c_addr_map;
|
||||
else
|
||||
remote_client_addr = max96715->ser_i2c_addr_def;
|
||||
remote_client = devm_i2c_new_dummy_device(&local_client->dev,
|
||||
local_client->adapter, remote_client_addr);
|
||||
if (IS_ERR(remote_client)) {
|
||||
dev_err(dev, "failed to alloc i2c client.\n");
|
||||
return -PTR_ERR(remote_client);
|
||||
}
|
||||
remote_client->addr = max96715->ser_i2c_addr_def;
|
||||
|
||||
max96715->client = remote_client;
|
||||
i2c_set_clientdata(remote_client, max96715);
|
||||
|
||||
dev_info(dev, "remote i2c client init, i2c_addr = 0x%x\n",
|
||||
remote_client_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96715_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(pdev->dev.parent);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct maxim4c *maxim4c = v4l2_get_subdevdata(sd);
|
||||
struct maxim4c_remote *max96715 = NULL;
|
||||
u32 link_id = MAXIM4C_LINK_ID_MAX;
|
||||
int ret = 0;
|
||||
|
||||
dev_info(&pdev->dev, "max96715 serializer probe\n");
|
||||
|
||||
link_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
|
||||
link_id = link_id - MAXIM4C_LINK_ID_MAX;
|
||||
if (link_id >= MAXIM4C_LINK_ID_MAX) {
|
||||
dev_err(&pdev->dev, "max96715 probe match data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(&pdev->dev, "max96715 probe link id = %d\n", link_id);
|
||||
|
||||
max96715 = devm_kzalloc(&pdev->dev, sizeof(*max96715), GFP_KERNEL);
|
||||
if (!max96715)
|
||||
if (!max96715) {
|
||||
dev_err(&pdev->dev, "max96715 probe no memory error\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
max96715->dev = &pdev->dev;
|
||||
max96715->remote_ops = &max96715_ops;
|
||||
|
|
@ -371,11 +339,22 @@ static int max96715_probe(struct platform_device *pdev)
|
|||
|
||||
max96715_parse_dt(max96715);
|
||||
|
||||
max96715_i2c_client_init(max96715, client);
|
||||
if (max96715->remote_id != link_id) {
|
||||
dev_err(&pdev->dev, "max96715 probe remote_id error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_i2c_client_init(max96715, client);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "remote i2c client init error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_device_register(maxim4c, max96715);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "remote serializer register error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
maxim4c_remote_load_init_seq(max96715);
|
||||
|
||||
|
|
@ -388,10 +367,21 @@ static int max96715_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id max96715_of_table[] = {
|
||||
{ .compatible = "maxim4c,max96715", },
|
||||
{
|
||||
.compatible = "maxim4c,link0,max96715",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_A)
|
||||
}, {
|
||||
.compatible = "maxim4c,link1,max96715",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_B)
|
||||
}, {
|
||||
.compatible = "maxim4c,link2,max96715",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_C)
|
||||
}, {
|
||||
.compatible = "maxim4c,link3,max96715",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_D)
|
||||
},
|
||||
{ /* Sentinel */ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, max96715_of_table);
|
||||
|
||||
static struct platform_driver max96715_driver = {
|
||||
|
|
|
|||
|
|
@ -20,25 +20,6 @@
|
|||
#define MAX96717_CHIP_ID 0xBF
|
||||
#define MAX96717_REG_CHIP_ID 0x0D
|
||||
|
||||
static int max96717_i2c_addr_select(maxim4c_remote_t *max96717, u32 i2c_id)
|
||||
{
|
||||
struct device *dev = max96717->dev;
|
||||
struct i2c_client *client = max96717->client;
|
||||
|
||||
if (i2c_id == MAXIM4C_I2C_SER_DEF) {
|
||||
client->addr = max96717->ser_i2c_addr_def;
|
||||
dev_info(dev, "select default i2c addr = 0x%x\n", client->addr);
|
||||
} else if (i2c_id == MAXIM4C_I2C_SER_MAP) {
|
||||
client->addr = max96717->ser_i2c_addr_map;
|
||||
dev_info(dev, "select mapping i2c addr = 0x%x\n", client->addr);
|
||||
} else {
|
||||
dev_err(dev, "i2c select id = %d error\n", i2c_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96717_i2c_addr_remap(maxim4c_remote_t *max96717)
|
||||
{
|
||||
struct device *dev = max96717->dev;
|
||||
|
|
@ -49,7 +30,7 @@ static int max96717_i2c_addr_remap(maxim4c_remote_t *max96717)
|
|||
if (max96717->ser_i2c_addr_map) {
|
||||
dev_info(dev, "Serializer i2c address remap\n");
|
||||
|
||||
max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
|
||||
i2c_8bit_addr = (max96717->ser_i2c_addr_map << 1);
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -60,7 +41,7 @@ static int max96717_i2c_addr_remap(maxim4c_remote_t *max96717)
|
|||
return ret;
|
||||
}
|
||||
|
||||
max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP);
|
||||
}
|
||||
|
||||
if (max96717->cam_i2c_addr_map) {
|
||||
|
|
@ -98,7 +79,7 @@ static int max96717_i2c_addr_def(maxim4c_remote_t *max96717)
|
|||
if (max96717->ser_i2c_addr_map) {
|
||||
dev_info(dev, "Serializer i2c address def\n");
|
||||
|
||||
max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP);
|
||||
|
||||
i2c_8bit_addr = (max96717->ser_i2c_addr_def << 1);
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
|
|
@ -109,7 +90,7 @@ static int max96717_i2c_addr_def(maxim4c_remote_t *max96717)
|
|||
return ret;
|
||||
}
|
||||
|
||||
max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -128,13 +109,13 @@ static int max96717_check_chipid(maxim4c_remote_t *max96717)
|
|||
&chip_id);
|
||||
if (ret != 0) {
|
||||
dev_info(dev, "Retry check chipid using map address\n");
|
||||
max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP);
|
||||
maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP);
|
||||
ret = maxim4c_i2c_read_byte(client,
|
||||
MAX96717_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
&chip_id);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "MAX96717 detect error, ret(%d)\n", ret);
|
||||
max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
@ -143,27 +124,10 @@ static int max96717_check_chipid(maxim4c_remote_t *max96717)
|
|||
}
|
||||
|
||||
if (chip_id != MAX96717_CHIP_ID) {
|
||||
dev_err(dev, "Unexpected MAX96717 chip id(%02x)\n", chip_id);
|
||||
dev_err(dev, "Unexpected chip id = %02x\n", chip_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
dev_info(dev, "Detected MAX96717 chipid: 0x%02x\n", chip_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max96717_soft_power_down(maxim4c_remote_t *max96717)
|
||||
{
|
||||
struct device *dev = max96717->dev;
|
||||
struct i2c_client *client = max96717->client;
|
||||
int ret = 0;
|
||||
|
||||
ret = maxim4c_i2c_write_byte(client,
|
||||
0x10, MAXIM4C_I2C_REG_ADDR_16BITS,
|
||||
BIT(7));
|
||||
if (ret) {
|
||||
dev_err(dev, "soft power down setting error!\n");
|
||||
return ret;
|
||||
}
|
||||
dev_info(dev, "Detected MAX96717 chip id: 0x%02x\n", chip_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -174,7 +138,7 @@ static int max96717_module_init(maxim4c_remote_t *max96717)
|
|||
struct i2c_client *client = max96717->client;
|
||||
int ret = 0;
|
||||
|
||||
ret = max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
ret = maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -201,10 +165,7 @@ static int max96717_module_deinit(maxim4c_remote_t *max96717)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
#if 0
|
||||
ret |= max96717_i2c_addr_def(max96717);
|
||||
#endif
|
||||
ret |= max96717_soft_power_down(max96717);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -262,47 +223,30 @@ static int max96717_parse_dt(maxim4c_remote_t *max96717)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int max96717_i2c_client_init(maxim4c_remote_t *max96717,
|
||||
struct i2c_client *local_client)
|
||||
{
|
||||
struct device *dev = max96717->dev;
|
||||
struct i2c_client *remote_client = NULL;
|
||||
u16 remote_client_addr = 0;
|
||||
|
||||
if (max96717->ser_i2c_addr_map)
|
||||
remote_client_addr = max96717->ser_i2c_addr_map;
|
||||
else
|
||||
remote_client_addr = max96717->ser_i2c_addr_def;
|
||||
remote_client = devm_i2c_new_dummy_device(&local_client->dev,
|
||||
local_client->adapter, remote_client_addr);
|
||||
if (IS_ERR(remote_client)) {
|
||||
dev_err(dev, "failed to alloc i2c client.\n");
|
||||
return -PTR_ERR(remote_client);
|
||||
}
|
||||
remote_client->addr = max96717->ser_i2c_addr_def;
|
||||
|
||||
max96717->client = remote_client;
|
||||
i2c_set_clientdata(remote_client, max96717);
|
||||
|
||||
dev_info(dev, "remote i2c client init, i2c_addr = 0x%x\n",
|
||||
remote_client_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96717_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(pdev->dev.parent);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct maxim4c *maxim4c = v4l2_get_subdevdata(sd);
|
||||
struct maxim4c_remote *max96717 = NULL;
|
||||
u32 link_id = MAXIM4C_LINK_ID_MAX;
|
||||
int ret = 0;
|
||||
|
||||
dev_info(&pdev->dev, "max96717 serializer probe\n");
|
||||
|
||||
link_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
|
||||
link_id = link_id - MAXIM4C_LINK_ID_MAX;
|
||||
if (link_id >= MAXIM4C_LINK_ID_MAX) {
|
||||
dev_err(&pdev->dev, "max96717 probe match data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(&pdev->dev, "max96717 probe link id = %d\n", link_id);
|
||||
|
||||
max96717 = devm_kzalloc(&pdev->dev, sizeof(*max96717), GFP_KERNEL);
|
||||
if (!max96717)
|
||||
if (!max96717) {
|
||||
dev_err(&pdev->dev, "max96717 probe no memory error\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
max96717->dev = &pdev->dev;
|
||||
max96717->remote_ops = &max96717_ops;
|
||||
|
|
@ -311,11 +255,22 @@ static int max96717_probe(struct platform_device *pdev)
|
|||
|
||||
max96717_parse_dt(max96717);
|
||||
|
||||
max96717_i2c_client_init(max96717, client);
|
||||
if (max96717->remote_id != link_id) {
|
||||
dev_err(&pdev->dev, "max96717 probe remote_id error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_i2c_client_init(max96717, client);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "remote i2c client init error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = maxim4c_remote_device_register(maxim4c, max96717);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "remote serializer register error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
maxim4c_remote_load_init_seq(max96717);
|
||||
|
||||
|
|
@ -328,10 +283,21 @@ static int max96717_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id max96717_of_table[] = {
|
||||
{ .compatible = "maxim4c,max96717", },
|
||||
{
|
||||
.compatible = "maxim4c,link0,max96717",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_A)
|
||||
}, {
|
||||
.compatible = "maxim4c,link1,max96717",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_B)
|
||||
}, {
|
||||
.compatible = "maxim4c,link2,max96717",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_C)
|
||||
}, {
|
||||
.compatible = "maxim4c,link3,max96717",
|
||||
.data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_D)
|
||||
},
|
||||
{ /* Sentinel */ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, max96717_of_table);
|
||||
|
||||
static struct platform_driver max96717_driver = {
|
||||
|
|
|
|||
|
|
@ -530,6 +530,16 @@ static int hdmirx_g_dv_timings(struct file *file, void *_fh,
|
|||
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
|
||||
u32 dma_cfg1;
|
||||
|
||||
if (port_no_link(hdmirx_dev)) {
|
||||
v4l2_err(v4l2_dev, "%s port has no link!\n", __func__);
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
if (signal_not_lock(hdmirx_dev)) {
|
||||
v4l2_err(v4l2_dev, "%s signal is not locked!\n", __func__);
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
*timings = hdmirx_dev->timings;
|
||||
dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1);
|
||||
v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n",
|
||||
|
|
@ -1558,7 +1568,7 @@ static int hdmirx_wait_lock_and_get_timing(struct rk_hdmirx_dev *hdmirx_dev)
|
|||
}
|
||||
|
||||
hdmirx_reset_dma(hdmirx_dev);
|
||||
usleep_range(200*1000, 200*1010);
|
||||
usleep_range(500*1000, 500*1010);
|
||||
hdmirx_format_change(hdmirx_dev);
|
||||
|
||||
return 0;
|
||||
|
|
@ -2473,13 +2483,28 @@ static void mainunit_2_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
|||
hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_FORCE, 0x0);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the normal preview, some scenarios will trigger the change interrupt
|
||||
* by mistake, and the trigger source of the interrupt needs to be detected
|
||||
* to avoid the problem.
|
||||
*/
|
||||
static void pkt_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
|
||||
int status, bool *handled)
|
||||
{
|
||||
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
|
||||
u32 pre_fmt_fourcc = hdmirx_dev->cur_fmt_fourcc;
|
||||
u32 pre_color_range = hdmirx_dev->cur_color_range;
|
||||
u32 pre_color_space = hdmirx_dev->cur_color_space;
|
||||
|
||||
if ((status & PKTDEC_AVIIF_CHG_IRQ)) {
|
||||
process_signal_change(hdmirx_dev);
|
||||
hdmirx_get_color_range(hdmirx_dev);
|
||||
hdmirx_get_color_space(hdmirx_dev);
|
||||
hdmirx_get_pix_fmt(hdmirx_dev);
|
||||
if (hdmirx_dev->cur_fmt_fourcc != pre_fmt_fourcc ||
|
||||
hdmirx_dev->cur_color_range != pre_color_range ||
|
||||
hdmirx_dev->cur_color_space != pre_color_space) {
|
||||
process_signal_change(hdmirx_dev);
|
||||
}
|
||||
v4l2_dbg(2, debug, v4l2_dev, "%s: ptk0_st:%#x\n",
|
||||
__func__, status);
|
||||
*handled = true;
|
||||
|
|
|
|||
|
|
@ -1537,7 +1537,7 @@ static struct irq_chip rk_pcie_legacy_irq_chip = {
|
|||
static int rk_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_level_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -26,11 +26,6 @@
|
|||
|
||||
#include "rpmsg_internal.h"
|
||||
|
||||
enum rk_rpmsg_chip {
|
||||
RK3562,
|
||||
RK3568,
|
||||
};
|
||||
|
||||
struct rk_virtio_dev {
|
||||
struct virtio_device vdev;
|
||||
unsigned int vring[2];
|
||||
|
|
@ -44,7 +39,6 @@ struct rk_virtio_dev {
|
|||
|
||||
struct rk_rpmsg_dev {
|
||||
struct platform_device *pdev;
|
||||
enum rk_rpmsg_chip chip;
|
||||
int vdev_nums;
|
||||
unsigned int link_id;
|
||||
int first_notify;
|
||||
|
|
@ -307,7 +301,6 @@ static int rockchip_rpmsg_probe(struct platform_device *pdev)
|
|||
|
||||
dev_info(dev, "rockchip rpmsg platform probe.\n");
|
||||
rpdev->pdev = pdev;
|
||||
rpdev->chip = (enum rk_rpmsg_chip)device_get_match_data(dev);
|
||||
rpdev->first_notify = 0;
|
||||
|
||||
cl = &rpdev->mbox_cl;
|
||||
|
|
@ -399,8 +392,7 @@ static int rockchip_rpmsg_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id rockchip_rpmsg_match[] = {
|
||||
{ .compatible = "rockchip,rk3562-rpmsg", .data = (void *)RK3562, },
|
||||
{ .compatible = "rockchip,rk3568-rpmsg", .data = (void *)RK3568, },
|
||||
{ .compatible = "rockchip,rpmsg", },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2104,7 +2104,7 @@ task_done_ret:
|
|||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} while (ret > 0);
|
||||
} while (!ret);
|
||||
|
||||
rkvenc2_task_timeout_process(session, task);
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,9 @@ struct rv1106_codec_priv {
|
|||
unsigned int mic_mute_l;
|
||||
unsigned int mic_mute_r;
|
||||
|
||||
/* DAC Control Manually */
|
||||
unsigned int dac_ctrl_manual;
|
||||
|
||||
/* For the high pass filter */
|
||||
unsigned int hpf_cutoff;
|
||||
|
||||
|
|
@ -182,12 +185,22 @@ static int rv1106_codec_main_micbias_get(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int rv1106_codec_main_micbias_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int rv1106_codec_dac_ctrl_manual_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int rv1106_codec_dac_ctrl_manual_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
static const char *offon_text[2] = {
|
||||
[0] = "Off",
|
||||
[1] = "On",
|
||||
};
|
||||
|
||||
static const char *noneoffon_text[3] = {
|
||||
[0] = "None",
|
||||
[1] = "Off",
|
||||
[2] = "On",
|
||||
};
|
||||
|
||||
static const char *mute_text[2] = {
|
||||
[0] = "Work",
|
||||
[1] = "Mute",
|
||||
|
|
@ -254,6 +267,11 @@ static const struct soc_enum rv1106_mic_mute_enum_array[] = {
|
|||
SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(mute_text), mute_text),
|
||||
};
|
||||
|
||||
/* DAC Control Manually */
|
||||
static const struct soc_enum rv1106_dac_pa_ctrl_maunal_enum_array[] = {
|
||||
SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(noneoffon_text), noneoffon_text),
|
||||
};
|
||||
|
||||
/* ALC AGC Approximate Sample Rate */
|
||||
#define AGC_ASR_NUM 8
|
||||
|
||||
|
|
@ -422,6 +440,10 @@ static const struct snd_kcontrol_new rv1106_codec_dapm_controls[] = {
|
|||
rv1106_codec_hpmix_gain_get,
|
||||
rv1106_codec_hpmix_gain_put,
|
||||
rv1106_codec_dac_hpmix_gain_tlv),
|
||||
|
||||
/* DAC Control Manually */
|
||||
SOC_ENUM_EXT("DAC Control Manually", rv1106_dac_pa_ctrl_maunal_enum_array[0],
|
||||
rv1106_codec_dac_ctrl_manual_get, rv1106_codec_dac_ctrl_manual_put),
|
||||
};
|
||||
|
||||
static unsigned int using_adc_lr(enum adc_mode_e adc_mode)
|
||||
|
|
@ -1015,35 +1037,47 @@ static int rv1106_codec_adc_dig_config(struct rv1106_codec_priv *rv1106,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rv1106_codec_dac_mute(struct rv1106_codec_priv *rv1106, int mute)
|
||||
{
|
||||
if (mute) {
|
||||
/* Mute DAC HPMIX/LINEOUT */
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_ANA_CTL1,
|
||||
ACODEC_DAC_L_LINEOUT_MUTE_MSK,
|
||||
ACODEC_DAC_L_LINEOUT_MUTE);
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_HPMIX_CTL,
|
||||
ACODEC_DAC_HPMIX_MUTE_MSK,
|
||||
ACODEC_DAC_HPMIX_MUTE);
|
||||
rv1106_codec_pa_ctrl(rv1106, false);
|
||||
} else {
|
||||
/* Unmute DAC HPMIX/LINEOUT */
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_HPMIX_CTL,
|
||||
ACODEC_DAC_HPMIX_MUTE_MSK,
|
||||
ACODEC_DAC_HPMIX_WORK);
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_ANA_CTL1,
|
||||
ACODEC_DAC_L_LINEOUT_MUTE_MSK,
|
||||
ACODEC_DAC_L_LINEOUT_WORK);
|
||||
rv1106_codec_pa_ctrl(rv1106, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv1106_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (mute) {
|
||||
/* Mute DAC HPMIX/LINEOUT */
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_ANA_CTL1,
|
||||
ACODEC_DAC_L_LINEOUT_MUTE_MSK,
|
||||
ACODEC_DAC_L_LINEOUT_MUTE);
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_HPMIX_CTL,
|
||||
ACODEC_DAC_HPMIX_MUTE_MSK,
|
||||
ACODEC_DAC_HPMIX_MUTE);
|
||||
rv1106_codec_pa_ctrl(rv1106, false);
|
||||
} else {
|
||||
/* Unmute DAC HPMIX/LINEOUT */
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_HPMIX_CTL,
|
||||
ACODEC_DAC_HPMIX_MUTE_MSK,
|
||||
ACODEC_DAC_HPMIX_WORK);
|
||||
regmap_update_bits(rv1106->regmap,
|
||||
ACODEC_DAC_L_LINEOUT_MUTE_MSK,
|
||||
ACODEC_DAC_MUTE_MSK,
|
||||
ACODEC_DAC_L_LINEOUT_WORK);
|
||||
rv1106_codec_pa_ctrl(rv1106, true);
|
||||
}
|
||||
if (rv1106->dac_ctrl_manual == 1)
|
||||
mute = 1; /* Force DAC control off manually */
|
||||
else if (rv1106->dac_ctrl_manual == 2)
|
||||
mute = 0; /* Force DAC control on manually */
|
||||
|
||||
rv1106_codec_dac_mute(rv1106, mute);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -1343,6 +1377,36 @@ static int rv1106_codec_hpmix_gain_put(struct snd_kcontrol *kcontrol,
|
|||
return snd_soc_put_volsw_range(kcontrol, ucontrol);
|
||||
}
|
||||
|
||||
static int rv1106_codec_dac_ctrl_manual_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = rv1106->dac_ctrl_manual;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv1106_codec_dac_ctrl_manual_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
rv1106->dac_ctrl_manual = ucontrol->value.integer.value[0];
|
||||
|
||||
if (rv1106->dac_ctrl_manual == 0)
|
||||
return 0;
|
||||
|
||||
if (rv1106->dac_ctrl_manual == 1)
|
||||
rv1106_codec_dac_mute(rv1106, 1); /* Force DAC control off manually */
|
||||
else if (rv1106->dac_ctrl_manual == 2)
|
||||
rv1106_codec_dac_mute(rv1106, 0); /* Force DAC control on manually */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv1106_codec_adc_enable(struct rv1106_codec_priv *rv1106)
|
||||
{
|
||||
unsigned int lr = using_adc_lr(rv1106->adc_mode);
|
||||
|
|
@ -1774,6 +1838,7 @@ static int rv1106_codec_check_micbias(struct rv1106_codec_priv *rv1106,
|
|||
static int rv1106_codec_dapm_controls_prepare(struct rv1106_codec_priv *rv1106)
|
||||
{
|
||||
rv1106->adc_mode = DIFF_ADCL;
|
||||
rv1106->dac_ctrl_manual = 0;
|
||||
rv1106->hpf_cutoff = 0;
|
||||
rv1106->agc_l = 0;
|
||||
rv1106->agc_r = 0;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,12 @@ config SND_SOC_ROCKCHIP_SAI
|
|||
Rockchip SAI Controller. The Controller supports up to maximum of
|
||||
128 channels each for play and record.
|
||||
|
||||
config SND_SOC_ROCKCHIP_SAI_VERBOSE
|
||||
bool "Rockchip SAI Verbose Controls"
|
||||
depends on SND_SOC_ROCKCHIP_SAI
|
||||
help
|
||||
Say Y if you want to export much more controls and info for SAI.
|
||||
|
||||
config SND_SOC_ROCKCHIP_SPDIF
|
||||
tristate "Rockchip SPDIF Device Driver"
|
||||
depends on HAVE_CLK && SND_SOC_ROCKCHIP
|
||||
|
|
|
|||
|
|
@ -653,7 +653,9 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
|
|||
i2s->has_capture ? &i2s->capture_dma_data : NULL);
|
||||
|
||||
if (i2s->mclk_calibrate)
|
||||
snd_soc_add_dai_controls(dai, &rockchip_i2s_compensation_control, 1);
|
||||
snd_soc_add_component_controls(dai->component,
|
||||
&rockchip_i2s_compensation_control,
|
||||
1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
#define CLK_PPM_MIN (-1000)
|
||||
#define CLK_PPM_MAX (1000)
|
||||
#define MAXBURST_PER_FIFO 8
|
||||
#define WAIT_TIME_MS_MAX 10000
|
||||
|
||||
#define TRCM_TXRX 0
|
||||
#define TRCM_TX 1
|
||||
|
|
@ -114,6 +115,7 @@ struct rk_i2s_tdm_dev {
|
|||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data playback_dma_data;
|
||||
struct snd_pcm_substream *substreams[SNDRV_PCM_STREAM_LAST + 1];
|
||||
unsigned int wait_time[SNDRV_PCM_STREAM_LAST + 1];
|
||||
struct reset_control *tx_reset;
|
||||
struct reset_control *rx_reset;
|
||||
struct pinctrl *pinctrl;
|
||||
|
|
@ -2030,7 +2032,101 @@ static int rockchip_i2s_tdm_loopback_put(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char * const rpaths_text[] = {
|
||||
"From SDI0", "From SDI1", "From SDI2", "From SDI3" };
|
||||
|
||||
static const char * const tpaths_text[] = {
|
||||
"From PATH0", "From PATH1", "From PATH2", "From PATH3" };
|
||||
|
||||
/* TXCR */
|
||||
static SOC_ENUM_SINGLE_DECL(tpath3_enum, I2S_TXCR, 29, tpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(tpath2_enum, I2S_TXCR, 27, tpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(tpath1_enum, I2S_TXCR, 25, tpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(tpath0_enum, I2S_TXCR, 23, tpaths_text);
|
||||
|
||||
/* RXCR */
|
||||
static SOC_ENUM_SINGLE_DECL(rpath3_enum, I2S_RXCR, 23, rpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(rpath2_enum, I2S_RXCR, 21, rpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(rpath1_enum, I2S_RXCR, 19, rpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(rpath0_enum, I2S_RXCR, 17, rpaths_text);
|
||||
|
||||
static int rockchip_i2s_tdm_wait_time_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = WAIT_TIME_MS_MAX;
|
||||
uinfo->value.integer.step = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_i2s_tdm_rd_wait_time_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = i2s_tdm->wait_time[SNDRV_PCM_STREAM_CAPTURE];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_i2s_tdm_rd_wait_time_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
i2s_tdm->wait_time[SNDRV_PCM_STREAM_CAPTURE] = ucontrol->value.integer.value[0];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rockchip_i2s_tdm_wr_wait_time_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.integer.value[0] = i2s_tdm->wait_time[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_i2s_tdm_wr_wait_time_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
i2s_tdm->wait_time[SNDRV_PCM_STREAM_PLAYBACK] = ucontrol->value.integer.value[0];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SAI_PCM_WAIT_TIME(xname, xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, \
|
||||
.info = rockchip_i2s_tdm_wait_time_info, \
|
||||
.get = xhandler_get, .put = xhandler_put }
|
||||
|
||||
static const struct snd_kcontrol_new rockchip_i2s_tdm_snd_controls[] = {
|
||||
SOC_ENUM("Receive PATH3 Source Select", rpath3_enum),
|
||||
SOC_ENUM("Receive PATH2 Source Select", rpath2_enum),
|
||||
SOC_ENUM("Receive PATH1 Source Select", rpath1_enum),
|
||||
SOC_ENUM("Receive PATH0 Source Select", rpath0_enum),
|
||||
SOC_ENUM("Transmit SDO3 Source Select", tpath3_enum),
|
||||
SOC_ENUM("Transmit SDO2 Source Select", tpath2_enum),
|
||||
SOC_ENUM("Transmit SDO1 Source Select", tpath1_enum),
|
||||
SOC_ENUM("Transmit SDO0 Source Select", tpath0_enum),
|
||||
|
||||
SOC_ENUM_EXT("I2STDM Digital Loopback Mode", loopback_mode,
|
||||
rockchip_i2s_tdm_loopback_get,
|
||||
rockchip_i2s_tdm_loopback_put),
|
||||
|
|
@ -2040,6 +2136,12 @@ static const struct snd_kcontrol_new rockchip_i2s_tdm_snd_controls[] = {
|
|||
SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum,
|
||||
rockchip_i2s_tdm_rx_lanes_get, rockchip_i2s_tdm_rx_lanes_put),
|
||||
#endif
|
||||
SAI_PCM_WAIT_TIME("PCM Read Wait Time MS",
|
||||
rockchip_i2s_tdm_rd_wait_time_get,
|
||||
rockchip_i2s_tdm_rd_wait_time_put),
|
||||
SAI_PCM_WAIT_TIME("PCM Write Wait Time MS",
|
||||
rockchip_i2s_tdm_wr_wait_time_get,
|
||||
rockchip_i2s_tdm_wr_wait_time_put),
|
||||
};
|
||||
|
||||
static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
|
||||
|
|
@ -2052,7 +2154,9 @@ static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
|
|||
dai->playback_dma_data = &i2s_tdm->playback_dma_data;
|
||||
|
||||
if (i2s_tdm->mclk_calibrate)
|
||||
snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
|
||||
snd_soc_add_component_controls(dai->component,
|
||||
&rockchip_i2s_tdm_compensation_control,
|
||||
1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2101,11 +2205,15 @@ static int rockchip_i2s_tdm_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
||||
int stream = substream->stream;
|
||||
|
||||
if (i2s_tdm->substreams[substream->stream])
|
||||
if (i2s_tdm->substreams[stream])
|
||||
return -EBUSY;
|
||||
|
||||
i2s_tdm->substreams[substream->stream] = substream;
|
||||
if (i2s_tdm->wait_time[stream])
|
||||
substream->wait_time = msecs_to_jiffies(i2s_tdm->wait_time[stream]);
|
||||
|
||||
i2s_tdm->substreams[stream] = substream;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#define DAIS_DRV_NAME "rockchip-mdais"
|
||||
#define RK3308_GRF_SOC_CON2 0x308
|
||||
|
||||
#define SOUND_NAME_PREFIX "sound-name-prefix"
|
||||
|
||||
static inline struct rk_mdais_dev *to_info(struct snd_soc_dai *dai)
|
||||
{
|
||||
return snd_soc_dai_get_drvdata(dai);
|
||||
|
|
@ -220,13 +222,23 @@ static int rockchip_mdais_tdm_slot(struct snd_soc_dai *dai,
|
|||
static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct rk_mdais_dev *mdais = to_info(dai);
|
||||
struct snd_soc_component *comp;
|
||||
struct snd_soc_dai *child;
|
||||
const char *str;
|
||||
int ret, i = 0;
|
||||
|
||||
for (i = 0; i < mdais->num_dais; i++) {
|
||||
child = mdais->dais[i].dai;
|
||||
comp = child->component;
|
||||
if (!child->probed && child->driver->probe) {
|
||||
child->component->card = dai->component->card;
|
||||
if (!comp->name_prefix) {
|
||||
ret = device_property_read_string(child->dev,
|
||||
SOUND_NAME_PREFIX, &str);
|
||||
if (!ret)
|
||||
comp->name_prefix = str;
|
||||
}
|
||||
|
||||
comp->card = dai->component->card;
|
||||
ret = child->driver->probe(child);
|
||||
if (ret < 0) {
|
||||
dev_err(child->dev,
|
||||
|
|
@ -234,6 +246,14 @@ static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai)
|
|||
child->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_add_component_controls(comp,
|
||||
comp->driver->controls,
|
||||
comp->driver->num_controls);
|
||||
if (ret)
|
||||
dev_err(dai->dev, "%s: Failed to add controls, should add '%s' in DT\n",
|
||||
dev_name(child->dev), SOUND_NAME_PREFIX);
|
||||
|
||||
dai->probed = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -383,9 +403,9 @@ static int rockchip_mdais_dai_prepare(struct platform_device *pdev,
|
|||
.probe = rockchip_mdais_dai_probe,
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 32,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.channels_min = 1,
|
||||
.channels_max = 512,
|
||||
.rates = SNDRV_PCM_RATE_8000_384000,
|
||||
.formats = (SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S20_3LE |
|
||||
|
|
@ -394,9 +414,9 @@ static int rockchip_mdais_dai_prepare(struct platform_device *pdev,
|
|||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 2,
|
||||
.channels_max = 32,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.channels_min = 1,
|
||||
.channels_max = 512,
|
||||
.rates = SNDRV_PCM_RATE_8000_384000,
|
||||
.formats = (SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S20_3LE |
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
#define MAX_FIFO_SIZE 32 /* max fifo size in frames */
|
||||
#define SND_DMAENGINE_MPCM_DRV_NAME "snd_dmaengine_mpcm"
|
||||
|
||||
static unsigned int prealloc_buffer_size_kbytes = 512;
|
||||
module_param(prealloc_buffer_size_kbytes, uint, 0444);
|
||||
MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB).");
|
||||
|
||||
struct dmaengine_mpcm {
|
||||
struct rk_mdais_dev *mdais;
|
||||
struct dma_chan *tx_chans[MAX_DAIS];
|
||||
|
|
@ -561,7 +565,7 @@ static int dmaengine_mpcm_new(struct snd_soc_component *component, struct snd_so
|
|||
size_t max_buffer_size;
|
||||
unsigned int i;
|
||||
|
||||
prealloc_buffer_size = 512 * 1024;
|
||||
prealloc_buffer_size = prealloc_buffer_size_kbytes * 1024;
|
||||
max_buffer_size = SIZE_MAX;
|
||||
|
||||
for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
|
||||
|
|
@ -683,6 +687,9 @@ int snd_dmaengine_mpcm_register(struct rk_mdais_dev *mdais)
|
|||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
pcm->component.debugfs_prefix = "dma";
|
||||
#endif
|
||||
pcm->mdais = mdais;
|
||||
for (i = 0; i < num; i++) {
|
||||
child = mdais->dais[i].dev;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#define DRV_NAME "rockchip-sai"
|
||||
|
||||
#define CLK_SHIFT_RATE_HZ_MAX 1 /* 1 Hz */
|
||||
#define FW_RATIO_MAX 8
|
||||
#define FW_RATIO_MIN 1
|
||||
#define MAXBURST_PER_FIFO 8
|
||||
|
|
@ -496,9 +497,10 @@ static int rockchip_sai_hw_params(struct snd_pcm_substream *substream,
|
|||
if (sai->is_clk_auto)
|
||||
clk_set_rate(sai->mclk, bclk_rate);
|
||||
mclk_rate = clk_get_rate(sai->mclk);
|
||||
if (mclk_rate < bclk_rate) {
|
||||
dev_err(sai->dev, "Mismatch mclk: %u, expected %u at least\n",
|
||||
mclk_rate, bclk_rate);
|
||||
if (mclk_rate < bclk_rate - CLK_SHIFT_RATE_HZ_MAX ||
|
||||
mclk_rate > bclk_rate + CLK_SHIFT_RATE_HZ_MAX) {
|
||||
dev_err(sai->dev, "Mismatch mclk: %u, expected %u (+/- %dHz)\n",
|
||||
mclk_rate, bclk_rate, CLK_SHIFT_RATE_HZ_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -795,8 +797,8 @@ static int rockchip_sai_init_dai(struct rk_sai_dev *sai, struct resource *res,
|
|||
if (sai->has_playback) {
|
||||
dai->playback.stream_name = "Playback";
|
||||
dai->playback.channels_min = 1;
|
||||
dai->playback.channels_max = 128;
|
||||
dai->playback.rates = SNDRV_PCM_RATE_8000_192000;
|
||||
dai->playback.channels_max = 512;
|
||||
dai->playback.rates = SNDRV_PCM_RATE_8000_384000;
|
||||
dai->playback.formats = SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
|
|
@ -811,8 +813,8 @@ static int rockchip_sai_init_dai(struct rk_sai_dev *sai, struct resource *res,
|
|||
if (sai->has_capture) {
|
||||
dai->capture.stream_name = "Capture";
|
||||
dai->capture.channels_min = 1;
|
||||
dai->capture.channels_max = 128;
|
||||
dai->capture.rates = SNDRV_PCM_RATE_8000_192000;
|
||||
dai->capture.channels_max = 512;
|
||||
dai->capture.rates = SNDRV_PCM_RATE_8000_384000;
|
||||
dai->capture.formats = SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
|
|
@ -867,14 +869,14 @@ static const char * const lpx_text[] = {
|
|||
"From SDO0", "From SDO1", "From SDO2", "From SDO3" };
|
||||
|
||||
static const char * const lps_text[] = { "Disable", "Enable" };
|
||||
static const char * const sync_out_text[] = { "External", "Internal" };
|
||||
static const char * const sync_in_text[] = { "External", "Internal" };
|
||||
static const char * const sync_out_text[] = { "From CRU", "From IO" };
|
||||
static const char * const sync_in_text[] = { "From IO", "From Sync Port" };
|
||||
|
||||
static const char * const rpaths_text[] = {
|
||||
"From SDI0", "From SDI1", "From SDI2", "From SDI3" };
|
||||
|
||||
static const char * const tpaths_text[] = {
|
||||
"To SDO0", "To SDO1", "To SDO2", "To SDO3" };
|
||||
"From PATH0", "From PATH1", "From PATH2", "From PATH3" };
|
||||
|
||||
/* TXCR */
|
||||
static SOC_ENUM_SINGLE_DECL(tsft_enum, SAI_TXCR, 22, edge_shift_text);
|
||||
|
|
@ -931,8 +933,8 @@ static SOC_ENUM_SINGLE_DECL(tpath2_enum, SAI_PATH_SEL, 4, tpaths_text);
|
|||
static SOC_ENUM_SINGLE_DECL(tpath1_enum, SAI_PATH_SEL, 2, tpaths_text);
|
||||
static SOC_ENUM_SINGLE_DECL(tpath0_enum, SAI_PATH_SEL, 0, tpaths_text);
|
||||
|
||||
static int rockchip_sai_fpw_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static int __maybe_unused rockchip_sai_fpw_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
|
||||
|
|
@ -942,8 +944,8 @@ static int rockchip_sai_fpw_get(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_sai_fpw_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static int __maybe_unused rockchip_sai_fpw_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
|
||||
|
|
@ -958,8 +960,8 @@ static int rockchip_sai_fpw_put(struct snd_kcontrol *kcontrol,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int rockchip_sai_fw_ratio_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static int __maybe_unused rockchip_sai_fw_ratio_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
|
||||
|
|
@ -969,8 +971,8 @@ static int rockchip_sai_fw_ratio_get(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_sai_fw_ratio_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static int __maybe_unused rockchip_sai_fw_ratio_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
|
||||
|
|
@ -1038,8 +1040,8 @@ static int rockchip_sai_rx_lanes_put(struct snd_kcontrol *kcontrol,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int rockchip_sai_mss_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static int __maybe_unused rockchip_sai_mss_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
|
||||
|
|
@ -1049,8 +1051,8 @@ static int rockchip_sai_mss_get(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_sai_mss_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static int __maybe_unused rockchip_sai_mss_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
|
||||
|
|
@ -1186,21 +1188,17 @@ static int rockchip_sai_wr_wait_time_put(struct snd_kcontrol *kcontrol,
|
|||
.info = rockchip_sai_wait_time_info, \
|
||||
.get = xhandler_get, .put = xhandler_put }
|
||||
|
||||
static DECLARE_TLV_DB_SCALE(fs_shift_tlv, 0, 8192, 0);
|
||||
static __maybe_unused DECLARE_TLV_DB_SCALE(fs_shift_tlv, 0, 8192, 0);
|
||||
|
||||
static const struct snd_kcontrol_new rockchip_sai_controls[] = {
|
||||
|
||||
#ifdef CONFIG_SND_SOC_ROCKCHIP_SAI_VERBOSE
|
||||
SOC_ENUM("Transmit Edge Shift", tsft_enum),
|
||||
SOC_ENUM_EXT("Transmit SDOx Select", tx_lanes_enum,
|
||||
rockchip_sai_tx_lanes_get, rockchip_sai_tx_lanes_put),
|
||||
SOC_ENUM("Transmit Store Justified Mode", tsjm_enum),
|
||||
SOC_ENUM("Transmit First Bit Mode", tfbm_enum),
|
||||
SOC_ENUM("Transmit Valid Data Justified", tvdj_enum),
|
||||
SOC_ENUM("Transmit Slot Bit Width", tsbw_enum),
|
||||
|
||||
SOC_ENUM("Receive Edge Shift", rsft_enum),
|
||||
SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum,
|
||||
rockchip_sai_rx_lanes_get, rockchip_sai_rx_lanes_put),
|
||||
SOC_ENUM("Receive Store Justified Mode", rsjm_enum),
|
||||
SOC_ENUM("Receive First Bit Mode", rfbm_enum),
|
||||
SOC_ENUM("Receive Valid Data Justified", rvdj_enum),
|
||||
|
|
@ -1212,16 +1210,25 @@ static const struct snd_kcontrol_new rockchip_sai_controls[] = {
|
|||
SOC_ENUM_EXT("Frame Width Ratio", fw_ratio_enum,
|
||||
rockchip_sai_fw_ratio_get, rockchip_sai_fw_ratio_put),
|
||||
|
||||
SOC_ENUM_EXT("Master Slave Mode Select", mss_switch,
|
||||
rockchip_sai_mss_get, rockchip_sai_mss_put),
|
||||
SOC_ENUM("Sclk Polarity", sp_switch),
|
||||
SOC_ENUM("Frame Sync Polarity", fp_switch),
|
||||
|
||||
SOC_SINGLE_TLV("Transmit Frame Shift Select", SAI_TX_SHIFT,
|
||||
0, 8192, 0, fs_shift_tlv),
|
||||
SOC_SINGLE_TLV("Receive Frame Shift Select", SAI_RX_SHIFT,
|
||||
0, 8192, 0, fs_shift_tlv),
|
||||
#endif
|
||||
SOC_ENUM_EXT("Transmit SDOx Select", tx_lanes_enum,
|
||||
rockchip_sai_tx_lanes_get, rockchip_sai_tx_lanes_put),
|
||||
SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum,
|
||||
rockchip_sai_rx_lanes_get, rockchip_sai_rx_lanes_put),
|
||||
SOC_SINGLE_TLV("Receive Mono Slot Select", SAI_MONO_CR,
|
||||
2, 128, 0, rmss_tlv),
|
||||
SOC_ENUM("Receive Mono Switch", rmono_switch),
|
||||
SOC_ENUM("Transmit Mono Switch", tmono_switch),
|
||||
|
||||
SOC_ENUM_EXT("Master / Slave Mode Select", mss_switch,
|
||||
rockchip_sai_mss_get, rockchip_sai_mss_put),
|
||||
SOC_ENUM("Sclk Polarity", sp_switch),
|
||||
SOC_ENUM("Frame Sync Polarity", fp_switch),
|
||||
|
||||
SOC_ENUM("SDI3 Loopback Src Select", lp3_enum),
|
||||
SOC_ENUM("SDI2 Loopback Src Select", lp2_enum),
|
||||
SOC_ENUM("SDI1 Loopback Src Select", lp1_enum),
|
||||
|
|
@ -1236,15 +1243,10 @@ static const struct snd_kcontrol_new rockchip_sai_controls[] = {
|
|||
SOC_ENUM("Receive PATH2 Source Select", rpath2_enum),
|
||||
SOC_ENUM("Receive PATH1 Source Select", rpath1_enum),
|
||||
SOC_ENUM("Receive PATH0 Source Select", rpath0_enum),
|
||||
SOC_ENUM("Transmit PATH3 Sink Select", tpath3_enum),
|
||||
SOC_ENUM("Transmit PATH2 Sink Select", tpath2_enum),
|
||||
SOC_ENUM("Transmit PATH1 Sink Select", tpath1_enum),
|
||||
SOC_ENUM("Transmit PATH0 Sink Select", tpath0_enum),
|
||||
|
||||
SOC_SINGLE_TLV("Transmit Frame Shift Select", SAI_TX_SHIFT,
|
||||
0, 8192, 0, fs_shift_tlv),
|
||||
SOC_SINGLE_TLV("Receive Frame Shift Select", SAI_RX_SHIFT,
|
||||
0, 8192, 0, fs_shift_tlv),
|
||||
SOC_ENUM("Transmit SDO3 Source Select", tpath3_enum),
|
||||
SOC_ENUM("Transmit SDO2 Source Select", tpath2_enum),
|
||||
SOC_ENUM("Transmit SDO1 Source Select", tpath1_enum),
|
||||
SOC_ENUM("Transmit SDO0 Source Select", tpath0_enum),
|
||||
|
||||
SOC_SINGLE_BOOL_EXT("Clk Auto Switch", 0,
|
||||
rockchip_sai_clk_auto_get,
|
||||
|
|
@ -1276,6 +1278,9 @@ static irqreturn_t rockchip_sai_isr(int irq, void *devid)
|
|||
dev_warn_ratelimited(sai->dev, "TX FIFO Underrun\n");
|
||||
regmap_update_bits(sai->regmap, SAI_INTCR,
|
||||
SAI_INTCR_TXUIC, SAI_INTCR_TXUIC);
|
||||
regmap_update_bits(sai->regmap, SAI_INTCR,
|
||||
SAI_INTCR_TXUIE_MASK,
|
||||
SAI_INTCR_TXUIE(0));
|
||||
substream = sai->substreams[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
if (substream)
|
||||
snd_pcm_stop_xrun(substream);
|
||||
|
|
@ -1285,6 +1290,9 @@ static irqreturn_t rockchip_sai_isr(int irq, void *devid)
|
|||
dev_warn_ratelimited(sai->dev, "RX FIFO Overrun\n");
|
||||
regmap_update_bits(sai->regmap, SAI_INTCR,
|
||||
SAI_INTCR_RXOIC, SAI_INTCR_RXOIC);
|
||||
regmap_update_bits(sai->regmap, SAI_INTCR,
|
||||
SAI_INTCR_RXOIE_MASK,
|
||||
SAI_INTCR_RXOIE(0));
|
||||
substream = sai->substreams[SNDRV_PCM_STREAM_CAPTURE];
|
||||
if (substream)
|
||||
snd_pcm_stop_xrun(substream);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue