mirror of
https://github.com/armbian/build.git
synced 2026-01-06 09:58:46 -08:00
Rework ac200 patches and config for current and edge kernel.
Changes are based on https://github.com/jernejsk/linux-1/tree/ac200-v3
This commit is contained in:
@@ -3941,7 +3941,7 @@ CONFIG_MFD_SUN4I_GPADC=y
|
||||
# CONFIG_MFD_BCM590XX is not set
|
||||
CONFIG_MFD_BD9571MWV=m
|
||||
CONFIG_MFD_AC100=y
|
||||
# CONFIG_MFD_AC200 is not set
|
||||
CONFIG_MFD_AC200=m
|
||||
CONFIG_MFD_AXP20X=y
|
||||
CONFIG_MFD_AXP20X_I2C=y
|
||||
CONFIG_MFD_AXP20X_RSB=y
|
||||
@@ -5310,6 +5310,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
|
||||
# CODEC drivers
|
||||
#
|
||||
CONFIG_SND_SOC_WM_ADSP=m
|
||||
CONFIG_SND_SOC_AC200_CODEC=m
|
||||
# CONFIG_SND_SOC_AC97_CODEC is not set
|
||||
CONFIG_SND_SOC_ADAU_UTILS=m
|
||||
CONFIG_SND_SOC_ADAU1372=m
|
||||
@@ -5500,7 +5501,6 @@ CONFIG_SND_SOC_LPASS_WSA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_VA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_RX_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_TX_MACRO=m
|
||||
CONFIG_SND_SOC_ACX00=m
|
||||
# end of CODEC drivers
|
||||
|
||||
CONFIG_SND_SIMPLE_CARD_UTILS=m
|
||||
@@ -7326,6 +7326,7 @@ CONFIG_PHY_SUN4I_USB=y
|
||||
CONFIG_PHY_SUN6I_MIPI_DPHY=y
|
||||
CONFIG_PHY_SUN9I_USB=y
|
||||
CONFIG_PHY_SUN50I_USB3=y
|
||||
CONFIG_AC200_PHY_CTL=m
|
||||
|
||||
#
|
||||
# PHY drivers for Broadcom platforms
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm64 6.5.1 Kernel Configuration
|
||||
# Linux/arm64 6.5.3 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
@@ -2885,6 +2885,7 @@ CONFIG_RTL8189FS=m
|
||||
CONFIG_RTL8189ES=m
|
||||
# CONFIG_WLAN_VENDOR_ZYDAS is not set
|
||||
CONFIG_WLAN_VENDOR_QUANTENNA=y
|
||||
# CONFIG_SPARD_WLAN_SUPPORT is not set
|
||||
CONFIG_USB_NET_RNDIS_WLAN=m
|
||||
# CONFIG_MAC80211_HWSIM is not set
|
||||
CONFIG_VIRT_WIFI=m
|
||||
@@ -4000,7 +4001,7 @@ CONFIG_MFD_SUN4I_GPADC=y
|
||||
# CONFIG_MFD_BCM590XX is not set
|
||||
CONFIG_MFD_BD9571MWV=m
|
||||
CONFIG_MFD_AC100=y
|
||||
# CONFIG_MFD_AC200 is not set
|
||||
CONFIG_MFD_AC200=m
|
||||
CONFIG_MFD_AXP20X=y
|
||||
CONFIG_MFD_AXP20X_I2C=y
|
||||
CONFIG_MFD_AXP20X_RSB=y
|
||||
@@ -4630,10 +4631,7 @@ CONFIG_MEDIA_ATTACH=y
|
||||
# IR I2C driver auto-selected by 'Autoselect ancillary drivers'
|
||||
#
|
||||
CONFIG_VIDEO_IR_I2C=m
|
||||
|
||||
#
|
||||
# Camera sensor devices
|
||||
#
|
||||
CONFIG_VIDEO_CAMERA_SENSOR=y
|
||||
CONFIG_VIDEO_APTINA_PLL=m
|
||||
CONFIG_VIDEO_CCS_PLL=m
|
||||
CONFIG_VIDEO_AR0521=m
|
||||
@@ -4702,9 +4700,6 @@ CONFIG_VIDEO_S5K6A3=m
|
||||
# CONFIG_VIDEO_ST_VGXY61 is not set
|
||||
CONFIG_VIDEO_CCS=m
|
||||
CONFIG_VIDEO_ET8EK8=m
|
||||
CONFIG_VIDEO_HM5065=m
|
||||
CONFIG_VIDEO_GC2145=m
|
||||
# end of Camera sensor devices
|
||||
|
||||
#
|
||||
# Lens drivers
|
||||
@@ -4714,6 +4709,8 @@ CONFIG_VIDEO_GC2145=m
|
||||
# CONFIG_VIDEO_DW9714 is not set
|
||||
# CONFIG_VIDEO_DW9768 is not set
|
||||
# CONFIG_VIDEO_DW9807_VCM is not set
|
||||
CONFIG_VIDEO_HM5065=m
|
||||
CONFIG_VIDEO_GC2145=m
|
||||
# end of Lens drivers
|
||||
|
||||
#
|
||||
@@ -5397,6 +5394,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
|
||||
# CODEC drivers
|
||||
#
|
||||
CONFIG_SND_SOC_WM_ADSP=m
|
||||
CONFIG_SND_SOC_AC200_CODEC=m
|
||||
# CONFIG_SND_SOC_AC97_CODEC is not set
|
||||
CONFIG_SND_SOC_ADAU_UTILS=m
|
||||
CONFIG_SND_SOC_ADAU1372=m
|
||||
@@ -5598,7 +5596,6 @@ CONFIG_SND_SOC_LPASS_WSA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_VA_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_RX_MACRO=m
|
||||
CONFIG_SND_SOC_LPASS_TX_MACRO=m
|
||||
CONFIG_SND_SOC_ACX00=m
|
||||
# end of CODEC drivers
|
||||
|
||||
CONFIG_SND_SIMPLE_CARD_UTILS=m
|
||||
@@ -7445,6 +7442,7 @@ CONFIG_PHY_SUN4I_USB=y
|
||||
CONFIG_PHY_SUN6I_MIPI_DPHY=y
|
||||
CONFIG_PHY_SUN9I_USB=y
|
||||
CONFIG_PHY_SUN50I_USB3=y
|
||||
CONFIG_AC200_PHY_CTL=m
|
||||
|
||||
#
|
||||
# PHY drivers for Broadcom platforms
|
||||
@@ -7997,10 +7995,7 @@ CONFIG_IMA_APPRAISE=y
|
||||
# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set
|
||||
CONFIG_IMA_APPRAISE_BOOTPARAM=y
|
||||
# CONFIG_IMA_APPRAISE_MODSIG is not set
|
||||
CONFIG_IMA_TRUSTED_KEYRING=y
|
||||
# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set
|
||||
# CONFIG_IMA_BLACKLIST_KEYRING is not set
|
||||
# CONFIG_IMA_LOAD_X509 is not set
|
||||
CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
|
||||
CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
|
||||
# CONFIG_IMA_DISABLE_HTABLE is not set
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
From fad789644794fc525a38d27927996ae089477e3f Mon Sep 17 00:00:00 2001
|
||||
From: Ukhellfire <afaulkner420@gmail.com>
|
||||
Date: Fri, 1 Apr 2022 09:44:19 +0100
|
||||
Subject: [PATCH 169/170] Rollback r_rsb to r_i2c
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts
|
||||
index cc5a73026..0b07f8ca2 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts
|
||||
@@ -208,12 +208,12 @@ &pio {
|
||||
vcc-pg-supply = <®_vcc_wifi_io>;
|
||||
};
|
||||
|
||||
-&r_rsb {
|
||||
+&r_i2c {
|
||||
status = "okay";
|
||||
|
||||
- axp805: pmic@745 {
|
||||
+ axp805: pmic@36 {
|
||||
compatible = "x-powers,axp805", "x-powers,axp806";
|
||||
- reg = <0x745>;
|
||||
+ reg = <0x36>;
|
||||
interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
--
|
||||
2.35.3
|
||||
|
||||
@@ -5,9 +5,8 @@ Subject: [PATCH 151/158] add initial support for orangepi3-lts
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/Makefile | 1 +
|
||||
.../allwinner/sun50i-h6-orangepi-3-lts.dts | 398 ++++++++++++++++++
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 101 ++++-
|
||||
3 files changed, 487 insertions(+), 13 deletions(-)
|
||||
.../allwinner/sun50i-h6-orangepi-3-lts.dts | 399 ++++++++++++++++++
|
||||
2 files changed, 400 insertions(+), 0 deletions(-)
|
||||
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
|
||||
@@ -27,8 +26,9 @@ new file mode 100644
|
||||
index 000000000..cc5a73026
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dts
|
||||
@@ -0,0 +1,398 @@
|
||||
@@ -0,0 +1,399 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
+// Copyright (C) 2023 Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
+// Copyright (C) 2019 Ondřej Jirman <megous@megous.com>
|
||||
+
|
||||
+/dts-v1/;
|
||||
@@ -43,10 +43,8 @@ index 000000000..cc5a73026
|
||||
+ compatible = "xunlong,orangepi-3-lts", "allwinner,sun50i-h6";
|
||||
+
|
||||
+ aliases {
|
||||
+ serial0 = &uart0;
|
||||
+ serial1 = &uart1;
|
||||
+ serial9 = &r_uart;
|
||||
+ ethernet0 = &emac;
|
||||
+ serial0 = &uart0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
@@ -135,6 +133,19 @@ index 000000000..cc5a73026
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&ac200_codec {
|
||||
+ avcc-supply = <®_aldo2>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ac200_pwm_clk {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&analog {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&cpu0 {
|
||||
+ cpu-supply = <®_dcdca>;
|
||||
+};
|
||||
@@ -155,12 +166,24 @@ index 000000000..cc5a73026
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&emac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ext_rgmii_pins>;
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ phy-handle = <&ext_rgmii_phy>;
|
||||
+ phy-supply = <®_gmac_3v3>;
|
||||
+ allwinner,rx-delay-ps = <200>;
|
||||
+ allwinner,tx-delay-ps = <300>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&gpu {
|
||||
+ mali-supply = <®_dcdcc>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi {
|
||||
+ hvcc-supply = <®_bldo2>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
@@ -170,14 +193,15 @@ index 000000000..cc5a73026
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&emac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ext_rgmii_pins>;
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ phy-handle = <&ext_rgmii_phy>;
|
||||
+ phy-supply = <®_gmac_3v3>;
|
||||
+ allwinner,rx-delay-ps = <200>;
|
||||
+ allwinner,tx-delay-ps = <300>;
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
@@ -192,10 +216,6 @@ index 000000000..cc5a73026
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2s1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ vmmc-supply = <®_cldo1>;
|
||||
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
|
||||
@@ -213,8 +233,6 @@ index 000000000..cc5a73026
|
||||
+};
|
||||
+
|
||||
+&mmc2 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc2_pins>;
|
||||
+ vmmc-supply = <®_cldo1>;
|
||||
+ vqmmc-supply = <®_bldo2>;
|
||||
+ bus-width = <8>;
|
||||
@@ -238,12 +256,20 @@ index 000000000..cc5a73026
|
||||
+ vcc-pg-supply = <®_vcc_wifi_io>;
|
||||
+};
|
||||
+
|
||||
+&r_rsb {
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&r_ir {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&r_i2c {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ axp805: pmic@745 {
|
||||
+ axp805: pmic@36 {
|
||||
+ compatible = "x-powers,axp805", "x-powers,axp806";
|
||||
+ reg = <0x745>;
|
||||
+ reg = <0x36>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-controller;
|
||||
@@ -296,11 +322,11 @@ index 000000000..cc5a73026
|
||||
+ regulator-name = "vcc-efuse-pcie-hdmi-pc";
|
||||
+ };
|
||||
+
|
||||
+ reg_blod3: bldo3 {
|
||||
+ reg_bldo3: bldo3 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-name = "vcc-wifi-io-pm-pg";
|
||||
+ regulator-name = "vcc-pm-pg-dcxoio-wifi";
|
||||
+ };
|
||||
+
|
||||
+ bldo4 {
|
||||
@@ -359,26 +385,6 @@ index 000000000..cc5a73026
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ac200_pwm_clk {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&r_ir {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&rtc {
|
||||
+ clocks = <&ext_osc32k>;
|
||||
+};
|
||||
@@ -387,12 +393,6 @@ index 000000000..cc5a73026
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&sound_ac200 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/delete-node/ &spi0;
|
||||
+
|
||||
+&uart0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart0_ph_pins>;
|
||||
@@ -426,185 +426,6 @@ index 000000000..cc5a73026
|
||||
+&usb3phy {
|
||||
+ status = "okay";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index 11e905afa..791c124f4 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -92,6 +92,13 @@ osc24M: osc24M_clk {
|
||||
clock-output-names = "osc24M";
|
||||
};
|
||||
|
||||
+ ext_osc32k: ext_osc32k_clk {
|
||||
+ #clock-cells = <0>;
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-frequency = <32768>;
|
||||
+ clock-output-names = "ext_osc32k";
|
||||
+ };
|
||||
+
|
||||
pmu {
|
||||
compatible = "arm,cortex-a53-pmu";
|
||||
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -127,6 +134,28 @@ cpu {
|
||||
};
|
||||
};
|
||||
|
||||
+ sound_ac200: sound_ac200 {
|
||||
+ status = "disabled";
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,frame-master = <&i2s3_master>;
|
||||
+ simple-audio-card,bitclock-master = <&i2s3_master>;
|
||||
+ simple-audio-card,name = "allwinner,ac200-codec";
|
||||
+ simple-audio-card,mclk-fs = <512>;
|
||||
+ i2s3_master: simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s3>;
|
||||
+ system-clock-frequency = <22579200>;
|
||||
+ dai-tdm-slot-num = <2>;
|
||||
+ dai-tdm-slot-width = <32>;
|
||||
+ };
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&ac200_codec>;
|
||||
+ system-clock-frequency = <22579200>;
|
||||
+ dai-tdm-slot-num = <2>;
|
||||
+ dai-tdm-slot-width = <32>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
arm,no-tick-in-suspend;
|
||||
@@ -382,7 +411,6 @@ pwm: pwm@300a000 {
|
||||
pio: pinctrl@300b000 {
|
||||
compatible = "allwinner,sun50i-h6-pinctrl";
|
||||
reg = <0x0300b000 0x400>;
|
||||
- interrupt-parent = <&r_intc>;
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -532,6 +560,11 @@ uart3_rts_cts_pins: uart3-rts-cts-pins {
|
||||
pins = "PD25", "PD26";
|
||||
function = "uart3";
|
||||
};
|
||||
+
|
||||
+ i2s3_pins: i2s3-pins {
|
||||
+ pins = "PB12", "PB13", "PB14", "PB15", "PB16";
|
||||
+ function = "i2s3";
|
||||
+ };
|
||||
};
|
||||
|
||||
iommu: iommu@30f0000 {
|
||||
@@ -730,6 +763,7 @@ i2c3: i2c@5002c00 {
|
||||
ac200: mfd@10 {
|
||||
compatible = "x-powers,ac200";
|
||||
reg = <0x10>;
|
||||
+ clocks = <&ac200_pwm_clk>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <1 20 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
@@ -737,11 +771,16 @@ ac200: mfd@10 {
|
||||
|
||||
ac200_ephy: phy {
|
||||
compatible = "x-powers,ac200-ephy";
|
||||
- clocks = <&ac200_pwm_clk>;
|
||||
nvmem-cells = <&ephy_calibration>;
|
||||
nvmem-cell-names = "calibration";
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+ ac200_codec: codec {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "x-powers,ac200-codec";
|
||||
+ status = "okay";
|
||||
+ };
|
||||
};
|
||||
};
|
||||
|
||||
@@ -778,6 +817,21 @@ i2s1: i2s@5091000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ i2s3: i2s@508f000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun50i-h6-i2s";
|
||||
+ reg = <0x0508f000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2S3>, <&ccu CLK_I2S3>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ dmas = <&dma 6>, <&dma 6>;
|
||||
+ resets = <&ccu RST_BUS_I2S3>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2s3_pins>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
spdif: spdif@5093000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-h6-spdif";
|
||||
@@ -1073,6 +1127,7 @@ rtc: rtc@7000000 {
|
||||
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-output-names = "osc32k", "osc32k-out", "iosc";
|
||||
+ clocks = <&ext_osc32k>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
@@ -1139,17 +1194,18 @@ r_uart_pins: r-uart-pins {
|
||||
};
|
||||
|
||||
r_ir: ir@7040000 {
|
||||
- compatible = "allwinner,sun50i-h6-ir",
|
||||
- "allwinner,sun6i-a31-ir";
|
||||
- reg = <0x07040000 0x400>;
|
||||
- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
- clocks = <&r_ccu CLK_R_APB1_IR>,
|
||||
- <&r_ccu CLK_IR>;
|
||||
- clock-names = "apb", "ir";
|
||||
- resets = <&r_ccu RST_R_APB1_IR>;
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&r_ir_rx_pin>;
|
||||
- status = "disabled";
|
||||
+ compatible = "allwinner,sun50i-h6-ir",
|
||||
+ "allwinner,sun6i-a31-ir";
|
||||
+ reg = <0x07040000 0x400>;
|
||||
+ interrupt-parent = <&r_intc>;
|
||||
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&r_ccu CLK_R_APB1_IR>,
|
||||
+ <&r_ccu CLK_IR>;
|
||||
+ clock-names = "apb", "ir";
|
||||
+ resets = <&r_ccu RST_R_APB1_IR>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&r_ir_rx_pin>;
|
||||
+ status = "disabled";
|
||||
};
|
||||
|
||||
r_i2c: i2c@7081400 {
|
||||
@@ -1191,6 +1247,25 @@ ths: thermal-sensor@5070400 {
|
||||
nvmem-cell-names = "calibration";
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
+
|
||||
+ sunxi-info {
|
||||
+ compatible = "allwinner,sun50i-h6-sys-info";
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ addr_mgt: addr-mgt {
|
||||
+ compatible = "allwinner,sunxi-addr_mgt";
|
||||
+ type_addr_wifi = <0x2>;
|
||||
+ type_addr_bt = <0x2>;
|
||||
+ type_addr_eth = <0x2>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ dump_reg: dump_reg@20000 {
|
||||
+ compatible = "allwinner,sunxi-dump-reg";
|
||||
+ reg = <0x0 0x03001000 0x0 0x0f20>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
--
|
||||
2.35.3
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
From c21550d5fbd11743bee19e142d3eb04d9ea68177 Mon Sep 17 00:00:00 2001
|
||||
From: The-going <48602507+The-going@users.noreply.github.com>
|
||||
Date: Sat, 16 Apr 2022 11:51:35 +0300
|
||||
Subject: [PATCH 151/158] add nodes for sunxi-info, sunxi-addr and sunxi-dump-reg
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 101 ++++-
|
||||
1 files changed, 487 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index 11e905afa..791c124f4 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -1191,6 +1247,25 @@ ths: thermal-sensor@5070400 {
|
||||
nvmem-cell-names = "calibration";
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
+
|
||||
+ sunxi-info {
|
||||
+ compatible = "allwinner,sun50i-h6-sys-info";
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ addr_mgt: addr-mgt {
|
||||
+ compatible = "allwinner,sunxi-addr_mgt";
|
||||
+ type_addr_wifi = <0x2>;
|
||||
+ type_addr_bt = <0x2>;
|
||||
+ type_addr_eth = <0x2>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ dump_reg: dump_reg@20000 {
|
||||
+ compatible = "allwinner,sunxi-dump-reg";
|
||||
+ reg = <0x0 0x03001000 0x0 0x0f20>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
--
|
||||
2.35.3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,30 @@
|
||||
From fbb61f5656e716e63aba5b04f42966656790cd4b Mon Sep 17 00:00:00 2001
|
||||
From d1c807041c254b02e944bf12b8d0ea39953ffdd6 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sun, 12 Jan 2020 12:09:12 +0100
|
||||
Subject: [PATCH 072/153] arm64:dts: sun50i-h6: Add AC200 EPHY related nodes
|
||||
Date: Fri, 16 Aug 2019 16:40:20 +0200
|
||||
Subject: [PATCH] arm64: dts: allwinner: h6: Add AC200 EPHY nodes
|
||||
|
||||
All Allwinner H6 SoCs feature a co-packaged AC200 die, which replaces
|
||||
the integrated PHY and audio circuitry of its H3/H5 predecessors. It is
|
||||
using an internal I2C connection, but otherwise pretty much behaves as
|
||||
it would be externally connected.
|
||||
|
||||
Since every H6 SoC contains this chip, add the required DT nodes to the
|
||||
SoC .dtsi, but keep them disabled. This is for now just covering the
|
||||
AC200 MFD parent and its EPHY child.
|
||||
Any board making use of one of the integrated PHY needs to enable it and
|
||||
connect the MAC and PHY accordingly.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 63 ++++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 73 ++++++++++++++++++++
|
||||
1 file changed, 73 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index fcabca590..8118a3465 100644
|
||||
index 9eee1a1e189d..b1f3724b42ca 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -23,6 +23,16 @@ aliases {
|
||||
@@ -24,6 +24,16 @@ aliases {
|
||||
mmc2 = &mmc2;
|
||||
};
|
||||
|
||||
@@ -29,22 +41,25 @@ index fcabca590..8118a3465 100644
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -320,6 +330,10 @@ ths_calibration: thermal-sensor-calibration@14 {
|
||||
reg = <0x14 0x8>;
|
||||
};
|
||||
|
||||
+ ephy_calibration: ephy-calibration@2c {
|
||||
+ reg = <0x2c 0x2>;
|
||||
+ };
|
||||
+
|
||||
@@ -334,6 +344,14 @@ ths_calibration: thermal-sensor-calibration@14 {
|
||||
cpu_speed_grade: cpu-speed-grade@1c {
|
||||
reg = <0x1c 0x4>;
|
||||
};
|
||||
@@ -377,6 +391,14 @@ ext_rgmii_pins: rgmii-pins {
|
||||
+
|
||||
+ ephy_calib: ephy_calib@2c {
|
||||
+ reg = <0x2c 0x2>;
|
||||
+ };
|
||||
+
|
||||
+ ac200_bg: ac200_bg@30 {
|
||||
+ reg = <0x30 0x2>;
|
||||
+ };
|
||||
};
|
||||
|
||||
timer@3009000 {
|
||||
@@ -389,6 +407,13 @@ ext_rgmii_pins: rgmii-pins {
|
||||
drive-strength = <40>;
|
||||
};
|
||||
|
||||
+ /omit-if-no-ref/
|
||||
+ ext_rmii_pins: rmii_pins {
|
||||
+ pins = "PA0", "PA1", "PA2", "PA3", "PA4",
|
||||
+ "PA5", "PA6", "PA7", "PA8", "PA9";
|
||||
@@ -55,19 +70,20 @@ index fcabca590..8118a3465 100644
|
||||
hdmi_pins: hdmi-pins {
|
||||
pins = "PH8", "PH9", "PH10";
|
||||
function = "hdmi";
|
||||
@@ -397,6 +419,11 @@ i2c2_pins: i2c2-pins {
|
||||
@@ -409,6 +434,12 @@ i2c2_pins: i2c2-pins {
|
||||
function = "i2c2";
|
||||
};
|
||||
|
||||
+ i2c3_pins: i2c3-pins {
|
||||
+ pins = "PB17", "PB18";
|
||||
+ function = "i2c3";
|
||||
+ bias-pull-up;
|
||||
+ };
|
||||
+
|
||||
mmc0_pins: mmc0-pins {
|
||||
pins = "PF0", "PF1", "PF2", "PF3",
|
||||
"PF4", "PF5";
|
||||
@@ -414,6 +441,11 @@ mmc1_pins: mmc1-pins {
|
||||
@@ -436,6 +467,11 @@ mmc2_pins: mmc2-pins {
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
@@ -76,10 +92,10 @@ index fcabca590..8118a3465 100644
|
||||
+ function = "pwm1";
|
||||
+ };
|
||||
+
|
||||
mmc2_pins: mmc2-pins {
|
||||
pins = "PC1", "PC4", "PC5", "PC6",
|
||||
"PC7", "PC8", "PC9", "PC10",
|
||||
@@ -656,6 +688,37 @@ spi1: spi@5011000 {
|
||||
/omit-if-no-ref/
|
||||
spi0_pins: spi0-pins {
|
||||
pins = "PC0", "PC2", "PC3";
|
||||
@@ -647,6 +683,43 @@ i2c2: i2c@5002800 {
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
@@ -92,6 +108,7 @@ index fcabca590..8118a3465 100644
|
||||
+ resets = <&ccu RST_BUS_I2C3>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c3_pins>;
|
||||
+ clock-frequency = <100000>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
@@ -99,24 +116,29 @@ index fcabca590..8118a3465 100644
|
||||
+ ac200: mfd@10 {
|
||||
+ compatible = "x-powers,ac200";
|
||||
+ reg = <0x10>;
|
||||
+ clocks = <&ac200_pwm_clk>;
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <1 20 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ nvmem-cells = <&ac200_bg>;
|
||||
+ nvmem-cell-names = "bandgap";
|
||||
+
|
||||
+ ac200_ephy: phy {
|
||||
+ compatible = "x-powers,ac200-ephy";
|
||||
+ clocks = <&ac200_pwm_clk>;
|
||||
+ nvmem-cells = <&ephy_calibration>;
|
||||
+ ac200_ephy_ctl: syscon {
|
||||
+ compatible = "x-powers,ac200-ephy-ctl";
|
||||
+ nvmem-cells = <&ephy_calib>;
|
||||
+ nvmem-cell-names = "calibration";
|
||||
+ #clock-cells = <0>;
|
||||
+ #reset-cells = <0>;
|
||||
+ phy-mode = "rmii";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
emac: ethernet@5020000 {
|
||||
compatible = "allwinner,sun50i-h6-emac",
|
||||
"allwinner,sun50i-a64-emac";
|
||||
spi0: spi@5010000 {
|
||||
compatible = "allwinner,sun50i-h6-spi",
|
||||
"allwinner,sun8i-h3-spi";
|
||||
--
|
||||
2.35.3
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
From a809376f8af7cab04996585f9f68e1f6cf1afd73 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Date: Thu, 1 Sep 2022 17:45:03 +0200
|
||||
Subject: [PATCH] arm64: dts: allwinner: h6: add AC200 codec nodes
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 42 ++++++++++++++++++++
|
||||
1 file changed, 42 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index b1f3724b42ca..e1c6673da881 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -24,6 +24,22 @@ aliases {
|
||||
mmc2 = &mmc2;
|
||||
};
|
||||
|
||||
+ analog: analog-codec {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,name = "ac200-audio";
|
||||
+ simple-audio-card,mclk-fs = <512>;
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s3>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&ac200_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
ac200_pwm_clk: ac200_clk {
|
||||
compatible = "pwm-clock";
|
||||
#clock-cells = <0>;
|
||||
@@ -440,6 +456,11 @@ i2c3_pins: i2c3-pins {
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
+ i2s3_pins: i2s3-pins {
|
||||
+ pins = "PB12", "PB13", "PB14", "PB15", "PB16";
|
||||
+ function = "i2s3";
|
||||
+ };
|
||||
+
|
||||
mmc0_pins: mmc0-pins {
|
||||
pins = "PF0", "PF1", "PF2", "PF3",
|
||||
"PF4", "PF5";
|
||||
@@ -717,6 +738,12 @@ ac200_ephy_ctl: syscon {
|
||||
phy-mode = "rmii";
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+ ac200_codec: codec {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "x-powers,ac200-codec";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
};
|
||||
};
|
||||
|
||||
@@ -774,6 +801,21 @@ mdio: mdio {
|
||||
};
|
||||
};
|
||||
|
||||
+ i2s3: i2s@508f000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun50i-h6-i2s";
|
||||
+ reg = <0x0508f000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2S3>, <&ccu CLK_I2S3>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ dmas = <&dma 6>, <&dma 6>;
|
||||
+ resets = <&ccu RST_BUS_I2S3>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2s3_pins>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
i2s1: i2s@5091000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-h6-i2s";
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
From 37a4b303a1f6094f9f26bf1e82a7b1a679540651 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Date: Thu, 1 Sep 2022 17:49:28 +0200
|
||||
Subject: [PATCH] arm64: dts: allwinner: h6: enable AC200 codec
|
||||
|
||||
Enable AC200 analog codec on H6 based boards where present.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
---
|
||||
.../dts/allwinner/sun50i-h6-orangepi-3.dts | 25 +++++++++++++++++++
|
||||
.../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 25 +++++++++++++++++++
|
||||
.../allwinner/sun50i-h6-tanix-tx6-mini.dts | 14 +++++++++++
|
||||
3 files changed, 64 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
index 59e9095d7a15..f1fcd37d0fcc 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
@@ -104,6 +104,19 @@ wifi_pwrseq: wifi-pwrseq {
|
||||
};
|
||||
};
|
||||
|
||||
+&ac200_codec {
|
||||
+ avcc-supply = <®_aldo2>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ac200_pwm_clk {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&analog {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cpu0 {
|
||||
cpu-supply = <®_dcdca>;
|
||||
};
|
||||
@@ -172,6 +185,14 @@ &i2s1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_cldo1>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
|
||||
@@ -219,6 +240,10 @@ &pio {
|
||||
vcc-pg-supply = <®_vcc_wifi_io>;
|
||||
};
|
||||
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&r_ir {
|
||||
status = "okay";
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
|
||||
index 454d2a2974c9..5bb973ea3fb4 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
|
||||
@@ -93,6 +93,19 @@ &dwc3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&ac200_codec {
|
||||
+ avcc-supply = <®_aldo2>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ac200_pwm_clk {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&analog {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cpu0 {
|
||||
cpu-supply = <®_dcdca>;
|
||||
};
|
||||
@@ -139,6 +152,14 @@ &i2s1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mdio {
|
||||
ext_rgmii_phy: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
@@ -195,6 +216,10 @@ &pio {
|
||||
vcc-pg-supply = <®_aldo1>;
|
||||
};
|
||||
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&r_i2c {
|
||||
status = "okay";
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6-mini.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6-mini.dts
|
||||
index 08d84160d88f..931e8b99fd93 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6-mini.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6-mini.dts
|
||||
@@ -10,6 +10,20 @@ / {
|
||||
compatible = "oranth,tanix-tx6-mini", "allwinner,sun50i-h6";
|
||||
};
|
||||
|
||||
+
|
||||
+&ac200_codec {
|
||||
+ avcc-supply = <®_vcc3v3>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&analog {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&r_ir {
|
||||
linux,rc-map-name = "rc-tanix-tx3mini";
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
From 93df3a3c4c7afccbceceab0a8318dcd94cff3259 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 24 Aug 2019 01:03:05 +0200
|
||||
Subject: [PATCH] arm64: dts: allwinner: h6: tanix: enable Ethernet
|
||||
|
||||
Tanix-TX6 and TX6 mini boards provide an 100MBit/s Ethernet port, which
|
||||
uses the EPHY integrated into the Allwinner H6 SoC.
|
||||
|
||||
Enable the MAC node, plus the required AC200 nodes to allow configuring
|
||||
and enabling the integrated PHY.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
.../boot/dts/allwinner/sun50i-h6-tanix.dtsi | 38 +++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
|
||||
index 4903d6358112..51a75debab44 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
+ ethernet0 = &emac;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -84,6 +85,16 @@ wifi_pwrseq: wifi-pwrseq {
|
||||
};
|
||||
};
|
||||
|
||||
+&ac200_ephy_ctl {
|
||||
+ x-powers,led-polarity = <GPIO_ACTIVE_HIGH>;
|
||||
+ phy-address = <1>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ac200_pwm_clk {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cpu0 {
|
||||
cpu-supply = <®_vdd_cpu_gpu>;
|
||||
};
|
||||
@@ -104,6 +115,14 @@ &ehci3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&emac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ext_rmii_pins>;
|
||||
+ phy-mode = "rmii";
|
||||
+ phy-handle = <&ext_rmii_phy>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&gpu {
|
||||
mali-supply = <®_vdd_cpu_gpu>;
|
||||
status = "okay";
|
||||
@@ -119,6 +138,21 @@ hdmi_out_con: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mdio {
|
||||
+ ext_rmii_phy: ethernet-phy@1 {
|
||||
+ compatible = "ethernet-phy-id0044.1400",
|
||||
+ "ethernet-phy-ieee802.3-c22";
|
||||
+ reg = <1>;
|
||||
+ resets = <&ac200_ephy_ctl>;
|
||||
+ reset-names = "phy";
|
||||
+ clocks = <&ac200_ephy_ctl>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
@@ -161,6 +195,10 @@ &pio {
|
||||
vcc-pg-supply = <®_vcc1v8>;
|
||||
};
|
||||
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&r_ir {
|
||||
status = "okay";
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
From 948a378f8aef5bd7240a38e3a864c94276d6aa56 Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Fri, 10 Jun 2022 18:20:29 +0100
|
||||
Subject: [PATCH] clk: gate: add support for regmap based gates
|
||||
|
||||
While we have nice wrappers for simple bit-flip MMIO based clock gates,
|
||||
a single bit to toggle in a regmap still requires to write a lot of clock
|
||||
framework boilerplate.
|
||||
|
||||
Support generic wrappers for regmap based clock gates, by adding them to
|
||||
the existing clock-gates.c file. Since a read-modify-write operation in a
|
||||
regmap can be much more complex than a readl/writel pair, we cannot use
|
||||
the .enable/.disable ops members, but do the actual flipping already in
|
||||
.prepare/.unprepare, where we can sleep. Also we cannot provide an
|
||||
.is_enabled function, since this must not sleep as well.
|
||||
On the upside all the locking for the r/m/w operation is provided by
|
||||
regmap already, so we can skip that.
|
||||
The rest of the CCF boilerplate code can be shared.
|
||||
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
drivers/clk/clk-gate.c | 60 ++++++++++++++++++++++++++++++++++--
|
||||
include/linux/clk-provider.h | 36 +++++++++++++++++++---
|
||||
2 files changed, 89 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
|
||||
index 64283807600b..f83aef5e6e79 100644
|
||||
--- a/drivers/clk/clk-gate.c
|
||||
+++ b/drivers/clk/clk-gate.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
@@ -124,11 +125,42 @@ const struct clk_ops clk_gate_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_gate_ops);
|
||||
|
||||
+static int clk_gate_regmap_setclrbit(struct clk_hw *hw, bool enable)
|
||||
+{
|
||||
+ struct clk_gate *gate = to_clk_gate(hw);
|
||||
+ bool set = gate->flags & CLK_GATE_SET_TO_DISABLE;
|
||||
+
|
||||
+ set ^= enable;
|
||||
+
|
||||
+ if (set)
|
||||
+ return regmap_set_bits(gate->regmap, gate->regmap_offs,
|
||||
+ BIT(gate->bit_idx));
|
||||
+ else
|
||||
+ return regmap_clear_bits(gate->regmap, gate->regmap_offs,
|
||||
+ BIT(gate->bit_idx));
|
||||
+}
|
||||
+
|
||||
+static int clk_gate_regmap_prepare(struct clk_hw *hw)
|
||||
+{
|
||||
+ return clk_gate_regmap_setclrbit(hw, true);
|
||||
+}
|
||||
+
|
||||
+static void clk_gate_regmap_unprepare(struct clk_hw *hw)
|
||||
+{
|
||||
+ clk_gate_regmap_setclrbit(hw, false);
|
||||
+}
|
||||
+
|
||||
+const struct clk_ops clk_gate_regmap_ops = {
|
||||
+ .prepare = clk_gate_regmap_prepare,
|
||||
+ .unprepare = clk_gate_regmap_unprepare,
|
||||
+};
|
||||
+
|
||||
struct clk_hw *__clk_hw_register_gate(struct device *dev,
|
||||
struct device_node *np, const char *name,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags,
|
||||
+ struct regmap *regmap, unsigned int regmap_offs,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock)
|
||||
{
|
||||
@@ -150,7 +182,10 @@ struct clk_hw *__clk_hw_register_gate(struct device *dev,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
- init.ops = &clk_gate_ops;
|
||||
+ if (regmap)
|
||||
+ init.ops = &clk_gate_regmap_ops;
|
||||
+ else
|
||||
+ init.ops = &clk_gate_ops;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_name ? &parent_name : NULL;
|
||||
init.parent_hws = parent_hw ? &parent_hw : NULL;
|
||||
@@ -162,6 +197,8 @@ struct clk_hw *__clk_hw_register_gate(struct device *dev,
|
||||
|
||||
/* struct clk_gate assignments */
|
||||
gate->reg = reg;
|
||||
+ gate->regmap = regmap;
|
||||
+ gate->regmap_offs = regmap_offs;
|
||||
gate->bit_idx = bit_idx;
|
||||
gate->flags = clk_gate_flags;
|
||||
gate->lock = lock;
|
||||
@@ -197,6 +234,22 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_gate);
|
||||
|
||||
+struct clk *clk_register_regmap_gate(struct device *dev, const char *name,
|
||||
+ const char *parent_name, unsigned long flags,
|
||||
+ struct regmap *regmap, unsigned int regmap_offs,
|
||||
+ u8 bit_idx, u8 clk_gate_flags)
|
||||
+{
|
||||
+ struct clk_hw *hw;
|
||||
+
|
||||
+ hw = clk_hw_register_regmap_gate(dev, name, parent_name, flags, regmap,
|
||||
+ regmap_offs, bit_idx, clk_gate_flags);
|
||||
+
|
||||
+ if (IS_ERR(hw))
|
||||
+ return ERR_CAST(hw);
|
||||
+ return hw->clk;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(clk_register_regmap_gate);
|
||||
+
|
||||
void clk_unregister_gate(struct clk *clk)
|
||||
{
|
||||
struct clk_gate *gate;
|
||||
@@ -234,6 +287,7 @@ struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags,
|
||||
+ struct regmap *regmap, unsigned int regmap_offs,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock)
|
||||
{
|
||||
@@ -244,8 +298,8 @@ struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
hw = __clk_hw_register_gate(dev, np, name, parent_name, parent_hw,
|
||||
- parent_data, flags, reg, bit_idx,
|
||||
- clk_gate_flags, lock);
|
||||
+ parent_data, flags, regmap, regmap_offs,
|
||||
+ reg, bit_idx, clk_gate_flags, lock);
|
||||
|
||||
if (!IS_ERR(hw)) {
|
||||
*ptr = hw;
|
||||
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
|
||||
index 267cd06b54a0..5de2c071fcf8 100644
|
||||
--- a/include/linux/clk-provider.h
|
||||
+++ b/include/linux/clk-provider.h
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_clk.h>
|
||||
+#include <linux/regmap.h>
|
||||
|
||||
/*
|
||||
* flags used across common struct clk. these flags should only affect the
|
||||
@@ -510,6 +511,8 @@ void of_fixed_clk_setup(struct device_node *np);
|
||||
struct clk_gate {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
+ struct regmap *regmap;
|
||||
+ unsigned int regmap_offs;
|
||||
u8 bit_idx;
|
||||
u8 flags;
|
||||
spinlock_t *lock;
|
||||
@@ -527,6 +530,7 @@ struct clk_hw *__clk_hw_register_gate(struct device *dev,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags,
|
||||
+ struct regmap *regmap, unsigned int regmap_offs,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock);
|
||||
struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
|
||||
@@ -534,12 +538,17 @@ struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags,
|
||||
+ struct regmap *regmap, unsigned int regmap_offs,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock);
|
||||
struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock);
|
||||
+struct clk *clk_register_regmap_gate(struct device *dev, const char *name,
|
||||
+ const char *parent_name, unsigned long flags,
|
||||
+ struct regmap *regmap, unsigned int regmap_offs,
|
||||
+ u8 bit_idx, u8 clk_gate_flags);
|
||||
/**
|
||||
* clk_hw_register_gate - register a gate clock with the clock framework
|
||||
* @dev: device that is registering this clock
|
||||
@@ -554,8 +563,14 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
#define clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx, \
|
||||
clk_gate_flags, lock) \
|
||||
__clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
|
||||
- NULL, (flags), (reg), (bit_idx), \
|
||||
+ NULL, (flags), NULL, 0, (reg), (bit_idx), \
|
||||
(clk_gate_flags), (lock))
|
||||
+
|
||||
+#define clk_hw_register_regmap_gate(dev, name, parent_name, flags, regmap, \
|
||||
+ regmap_offs, bit_idx, clk_gate_flags) \
|
||||
+ __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
|
||||
+ NULL, (flags), regmap, regmap_offs, NULL, \
|
||||
+ (bit_idx), (clk_gate_flags), NULL)
|
||||
/**
|
||||
* clk_hw_register_gate_parent_hw - register a gate clock with the clock
|
||||
* framework
|
||||
@@ -571,8 +586,15 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
#define clk_hw_register_gate_parent_hw(dev, name, parent_hw, flags, reg, \
|
||||
bit_idx, clk_gate_flags, lock) \
|
||||
__clk_hw_register_gate((dev), NULL, (name), NULL, (parent_hw), \
|
||||
- NULL, (flags), (reg), (bit_idx), \
|
||||
+ NULL, (flags), NULL, 0, (reg), (bit_idx), \
|
||||
(clk_gate_flags), (lock))
|
||||
+
|
||||
+#define clk_hw_register_regmap_gate_parent_hw(dev, name, parent_hw, flags, \
|
||||
+ regmap, regmap_offs, bit_idx, \
|
||||
+ clk_gate_flags) \
|
||||
+ __clk_hw_register_gate((dev), NULL, (name), NULL, (parent_hw), \
|
||||
+ NULL, (flags), regmap, regmap_offs, NULL, \
|
||||
+ (bit_idx), (clk_gate_flags), NULL)
|
||||
/**
|
||||
* clk_hw_register_gate_parent_data - register a gate clock with the clock
|
||||
* framework
|
||||
@@ -588,7 +610,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
#define clk_hw_register_gate_parent_data(dev, name, parent_data, flags, reg, \
|
||||
bit_idx, clk_gate_flags, lock) \
|
||||
__clk_hw_register_gate((dev), NULL, (name), NULL, NULL, (parent_data), \
|
||||
- (flags), (reg), (bit_idx), \
|
||||
+ (flags), NULL, 0, (reg), (bit_idx), \
|
||||
(clk_gate_flags), (lock))
|
||||
/**
|
||||
* devm_clk_hw_register_gate - register a gate clock with the clock framework
|
||||
@@ -604,8 +626,14 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
#define devm_clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx,\
|
||||
clk_gate_flags, lock) \
|
||||
__devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
|
||||
- NULL, (flags), (reg), (bit_idx), \
|
||||
+ NULL, (flags), NULL, 0, (reg), (bit_idx), \
|
||||
(clk_gate_flags), (lock))
|
||||
+#define devm_clk_hw_register_regmap_gate(dev, name, parent_name, flags, \
|
||||
+ regmap, regmap_offs, bit_idx, \
|
||||
+ clk_gate_flags) \
|
||||
+ __devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
|
||||
+ NULL, (flags), (regmap), (regmap_offs), NULL, \
|
||||
+ (bit_idx), (clk_gate_flags), NULL)
|
||||
void clk_unregister_gate(struct clk *clk);
|
||||
void clk_hw_unregister_gate(struct clk_hw *hw);
|
||||
int clk_gate_is_enabled(struct clk_hw *hw);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,440 +0,0 @@
|
||||
From 6fc4380edfa07505416a18c91e81fe4e7ddb23cb Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 16 Aug 2019 16:38:21 +0200
|
||||
Subject: [PATCH 004/158] drv:mfd: Add support for AC200
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/mfd/Kconfig | 9 ++
|
||||
drivers/mfd/Makefile | 1 +
|
||||
drivers/mfd/ac200.c | 170 +++++++++++++++++++++++++++++++
|
||||
include/linux/mfd/ac200.h | 208 ++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 388 insertions(+)
|
||||
create mode 100644 drivers/mfd/ac200.c
|
||||
create mode 100644 include/linux/mfd/ac200.h
|
||||
|
||||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
|
||||
index 9940e2724..27285ddaa 100644
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -178,6 +178,15 @@ config MFD_AC100
|
||||
This driver include only the core APIs. You have to select individual
|
||||
components like codecs or RTC under the corresponding menus.
|
||||
|
||||
+config MFD_AC200
|
||||
+ bool "X-Powers AC200"
|
||||
+ select MFD_CORE
|
||||
+ depends on I2C
|
||||
+ help
|
||||
+ If you say Y here you get support for the X-Powers AC200 IC.
|
||||
+ This driver include only the core APIs. You have to select individual
|
||||
+ components like Ethernet PHY or RTC under the corresponding menus.
|
||||
+
|
||||
config MFD_AXP20X
|
||||
tristate
|
||||
select MFD_CORE
|
||||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
|
||||
index 7ed3ef4a6..91dc530d0 100644
|
||||
--- a/drivers/mfd/Makefile
|
||||
+++ b/drivers/mfd/Makefile
|
||||
@@ -144,6 +144,7 @@ obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
|
||||
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
|
||||
|
||||
obj-$(CONFIG_MFD_AC100) += ac100.o
|
||||
+obj-$(CONFIG_MFD_AC200) += ac200.o
|
||||
obj-$(CONFIG_MFD_AXP20X) += axp20x.o
|
||||
obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
|
||||
obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
|
||||
diff --git a/drivers/mfd/ac200.c b/drivers/mfd/ac200.c
|
||||
new file mode 100644
|
||||
index 000000000..570573790
|
||||
--- /dev/null
|
||||
+++ b/drivers/mfd/ac200.c
|
||||
@@ -0,0 +1,170 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * MFD core driver for X-Powers' AC200 IC
|
||||
+ *
|
||||
+ * The AC200 is a chip which is co-packaged with Allwinner H6 SoC and
|
||||
+ * includes analog audio codec, analog TV encoder, ethernet PHY, eFuse
|
||||
+ * and RTC.
|
||||
+ *
|
||||
+ * Copyright (c) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/core.h>
|
||||
+#include <linux/mfd/ac200.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+
|
||||
+/* Interrupts */
|
||||
+#define AC200_IRQ_RTC 0
|
||||
+#define AC200_IRQ_EPHY 1
|
||||
+#define AC200_IRQ_TVE 2
|
||||
+
|
||||
+/* IRQ enable register */
|
||||
+#define AC200_SYS_IRQ_ENABLE_OUT_EN BIT(15)
|
||||
+#define AC200_SYS_IRQ_ENABLE_RTC BIT(12)
|
||||
+#define AC200_SYS_IRQ_ENABLE_EPHY BIT(8)
|
||||
+#define AC200_SYS_IRQ_ENABLE_TVE BIT(4)
|
||||
+
|
||||
+static const struct regmap_range_cfg ac200_range_cfg[] = {
|
||||
+ {
|
||||
+ .range_min = AC200_SYS_VERSION,
|
||||
+ .range_max = AC200_IC_CHARA1,
|
||||
+ .selector_reg = AC200_TWI_REG_ADDR_H,
|
||||
+ .selector_mask = 0xff,
|
||||
+ .selector_shift = 0,
|
||||
+ .window_start = 0,
|
||||
+ .window_len = 256,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config ac200_regmap_config = {
|
||||
+ .reg_bits = 8,
|
||||
+ .val_bits = 16,
|
||||
+ .ranges = ac200_range_cfg,
|
||||
+ .num_ranges = ARRAY_SIZE(ac200_range_cfg),
|
||||
+ .max_register = AC200_IC_CHARA1,
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_irq ac200_regmap_irqs[] = {
|
||||
+ REGMAP_IRQ_REG(AC200_IRQ_RTC, 0, AC200_SYS_IRQ_ENABLE_RTC),
|
||||
+ REGMAP_IRQ_REG(AC200_IRQ_EPHY, 0, AC200_SYS_IRQ_ENABLE_EPHY),
|
||||
+ REGMAP_IRQ_REG(AC200_IRQ_TVE, 0, AC200_SYS_IRQ_ENABLE_TVE),
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_irq_chip ac200_regmap_irq_chip = {
|
||||
+ .name = "ac200_irq_chip",
|
||||
+ .status_base = AC200_SYS_IRQ_STATUS,
|
||||
+ .mask_base = AC200_SYS_IRQ_ENABLE,
|
||||
+ .mask_invert = true,
|
||||
+ .irqs = ac200_regmap_irqs,
|
||||
+ .num_irqs = ARRAY_SIZE(ac200_regmap_irqs),
|
||||
+ .num_regs = 1,
|
||||
+};
|
||||
+
|
||||
+static const struct resource ephy_resource[] = {
|
||||
+ DEFINE_RES_IRQ(AC200_IRQ_EPHY),
|
||||
+};
|
||||
+
|
||||
+static const struct mfd_cell ac200_cells[] = {
|
||||
+ {
|
||||
+ .name = "ac200-ephy",
|
||||
+ .num_resources = ARRAY_SIZE(ephy_resource),
|
||||
+ .resources = ephy_resource,
|
||||
+ .of_compatible = "x-powers,ac200-ephy",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int ac200_i2c_probe(struct i2c_client *i2c,
|
||||
+ const struct i2c_device_id *id)
|
||||
+{
|
||||
+ struct device *dev = &i2c->dev;
|
||||
+ struct ac200_dev *ac200;
|
||||
+ int ret;
|
||||
+
|
||||
+ ac200 = devm_kzalloc(dev, sizeof(*ac200), GFP_KERNEL);
|
||||
+ if (!ac200)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i2c_set_clientdata(i2c, ac200);
|
||||
+
|
||||
+ ac200->regmap = devm_regmap_init_i2c(i2c, &ac200_regmap_config);
|
||||
+ if (IS_ERR(ac200->regmap)) {
|
||||
+ ret = PTR_ERR(ac200->regmap);
|
||||
+ dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* do a reset to put chip in a known state */
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* enable interrupt pin */
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_IRQ_ENABLE,
|
||||
+ AC200_SYS_IRQ_ENABLE_OUT_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_add_irq_chip(ac200->regmap, i2c->irq, IRQF_ONESHOT, 0,
|
||||
+ &ac200_regmap_irq_chip, &ac200->regmap_irqc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, ac200_cells,
|
||||
+ ARRAY_SIZE(ac200_cells), NULL, 0, NULL);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to add MFD devices: %d\n", ret);
|
||||
+ regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_i2c_remove(struct i2c_client *i2c)
|
||||
+{
|
||||
+ struct ac200_dev *ac200 = i2c_get_clientdata(i2c);
|
||||
+
|
||||
+ regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0);
|
||||
+
|
||||
+ mfd_remove_devices(&i2c->dev);
|
||||
+ regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_device_id ac200_ids[] = {
|
||||
+ { "ac200", },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, ac200_ids);
|
||||
+
|
||||
+static const struct of_device_id ac200_of_match[] = {
|
||||
+ { .compatible = "x-powers,ac200" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ac200_of_match);
|
||||
+
|
||||
+static struct i2c_driver ac200_i2c_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "ac200",
|
||||
+ .of_match_table = of_match_ptr(ac200_of_match),
|
||||
+ },
|
||||
+ .probe = ac200_i2c_probe,
|
||||
+ .remove = ac200_i2c_remove,
|
||||
+ .id_table = ac200_ids,
|
||||
+};
|
||||
+module_i2c_driver(ac200_i2c_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("MFD core driver for AC200");
|
||||
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
diff --git a/include/linux/mfd/ac200.h b/include/linux/mfd/ac200.h
|
||||
new file mode 100644
|
||||
index 000000000..0c677094a
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mfd/ac200.h
|
||||
@@ -0,0 +1,208 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+/*
|
||||
+ * AC200 register list
|
||||
+ *
|
||||
+ * Copyright (C) 2019 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __LINUX_MFD_AC200_H
|
||||
+#define __LINUX_MFD_AC200_H
|
||||
+
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+/* interface registers (can be accessed from any page) */
|
||||
+#define AC200_TWI_CHANGE_TO_RSB 0x3E
|
||||
+#define AC200_TWI_PAD_DELAY 0xC4
|
||||
+#define AC200_TWI_REG_ADDR_H 0xFE
|
||||
+
|
||||
+/* General registers */
|
||||
+#define AC200_SYS_VERSION 0x0000
|
||||
+#define AC200_SYS_CONTROL 0x0002
|
||||
+#define AC200_SYS_IRQ_ENABLE 0x0004
|
||||
+#define AC200_SYS_IRQ_STATUS 0x0006
|
||||
+#define AC200_SYS_CLK_CTL 0x0008
|
||||
+#define AC200_SYS_DLDO_OSC_CTL 0x000A
|
||||
+#define AC200_SYS_PLL_CTL0 0x000C
|
||||
+#define AC200_SYS_PLL_CTL1 0x000E
|
||||
+#define AC200_SYS_AUDIO_CTL0 0x0010
|
||||
+#define AC200_SYS_AUDIO_CTL1 0x0012
|
||||
+#define AC200_SYS_EPHY_CTL0 0x0014
|
||||
+#define AC200_SYS_EPHY_CTL1 0x0016
|
||||
+#define AC200_SYS_TVE_CTL0 0x0018
|
||||
+#define AC200_SYS_TVE_CTL1 0x001A
|
||||
+
|
||||
+/* Audio Codec registers */
|
||||
+#define AC200_AC_SYS_CLK_CTL 0x2000
|
||||
+#define AC200_SYS_MOD_RST 0x2002
|
||||
+#define AC200_SYS_SAMP_CTL 0x2004
|
||||
+#define AC200_I2S_CTL 0x2100
|
||||
+#define AC200_I2S_CLK 0x2102
|
||||
+#define AC200_I2S_FMT0 0x2104
|
||||
+#define AC200_I2S_FMT1 0x2108
|
||||
+#define AC200_I2S_MIX_SRC 0x2114
|
||||
+#define AC200_I2S_MIX_GAIN 0x2116
|
||||
+#define AC200_I2S_DACDAT_DVC 0x2118
|
||||
+#define AC200_I2S_ADCDAT_DVC 0x211A
|
||||
+#define AC200_AC_DAC_DPC 0x2200
|
||||
+#define AC200_AC_DAC_MIX_SRC 0x2202
|
||||
+#define AC200_AC_DAC_MIX_GAIN 0x2204
|
||||
+#define AC200_DACA_OMIXER_CTRL 0x2220
|
||||
+#define AC200_OMIXER_SR 0x2222
|
||||
+#define AC200_LINEOUT_CTRL 0x2224
|
||||
+#define AC200_AC_ADC_DPC 0x2300
|
||||
+#define AC200_MBIAS_CTRL 0x2310
|
||||
+#define AC200_ADC_MIC_CTRL 0x2320
|
||||
+#define AC200_ADCMIXER_SR 0x2322
|
||||
+#define AC200_ANALOG_TUNING0 0x232A
|
||||
+#define AC200_ANALOG_TUNING1 0x232C
|
||||
+#define AC200_AC_AGC_SEL 0x2480
|
||||
+#define AC200_ADC_DAPLCTRL 0x2500
|
||||
+#define AC200_ADC_DAPRCTRL 0x2502
|
||||
+#define AC200_ADC_DAPLSTA 0x2504
|
||||
+#define AC200_ADC_DAPRSTA 0x2506
|
||||
+#define AC200_ADC_DAPLTL 0x2508
|
||||
+#define AC200_ADC_DAPRTL 0x250A
|
||||
+#define AC200_ADC_DAPLHAC 0x250C
|
||||
+#define AC200_ADC_DAPLLAC 0x250E
|
||||
+#define AC200_ADC_DAPRHAC 0x2510
|
||||
+#define AC200_ADC_DAPRLAC 0x2512
|
||||
+#define AC200_ADC_DAPLDT 0x2514
|
||||
+#define AC200_ADC_DAPLAT 0x2516
|
||||
+#define AC200_ADC_DAPRDT 0x2518
|
||||
+#define AC200_ADC_DAPRAT 0x251A
|
||||
+#define AC200_ADC_DAPNTH 0x251C
|
||||
+#define AC200_ADC_DAPLHNAC 0x251E
|
||||
+#define AC200_ADC_DAPLLNAC 0x2520
|
||||
+#define AC200_ADC_DAPRHNAC 0x2522
|
||||
+#define AC200_ADC_DAPRLNAC 0x2524
|
||||
+#define AC200_AC_DAPHHPFC 0x2526
|
||||
+#define AC200_AC_DAPLHPFC 0x2528
|
||||
+#define AC200_AC_DAPOPT 0x252A
|
||||
+#define AC200_AC_DAC_DAPCTRL 0x3000
|
||||
+#define AC200_AC_DRC_HHPFC 0x3002
|
||||
+#define AC200_AC_DRC_LHPFC 0x3004
|
||||
+#define AC200_AC_DRC_CTRL 0x3006
|
||||
+#define AC200_AC_DRC_LPFHAT 0x3008
|
||||
+#define AC200_AC_DRC_LPFLAT 0x300A
|
||||
+#define AC200_AC_DRC_RPFHAT 0x300C
|
||||
+#define AC200_AC_DRC_RPFLAT 0x300E
|
||||
+#define AC200_AC_DRC_LPFHRT 0x3010
|
||||
+#define AC200_AC_DRC_LPFLRT 0x3012
|
||||
+#define AC200_AC_DRC_RPFHRT 0x3014
|
||||
+#define AC200_AC_DRC_RPFLRT 0x3016
|
||||
+#define AC200_AC_DRC_LRMSHAT 0x3018
|
||||
+#define AC200_AC_DRC_LRMSLAT 0x301A
|
||||
+#define AC200_AC_DRC_RRMSHAT 0x301C
|
||||
+#define AC200_AC_DRC_RRMSLAT 0x301E
|
||||
+#define AC200_AC_DRC_HCT 0x3020
|
||||
+#define AC200_AC_DRC_LCT 0x3022
|
||||
+#define AC200_AC_DRC_HKC 0x3024
|
||||
+#define AC200_AC_DRC_LKC 0x3026
|
||||
+#define AC200_AC_DRC_HOPC 0x3028
|
||||
+#define AC200_AC_DRC_LOPC 0x302A
|
||||
+#define AC200_AC_DRC_HLT 0x302C
|
||||
+#define AC200_AC_DRC_LLT 0x302E
|
||||
+#define AC200_AC_DRC_HKI 0x3030
|
||||
+#define AC200_AC_DRC_LKI 0x3032
|
||||
+#define AC200_AC_DRC_HOPL 0x3034
|
||||
+#define AC200_AC_DRC_LOPL 0x3036
|
||||
+#define AC200_AC_DRC_HET 0x3038
|
||||
+#define AC200_AC_DRC_LET 0x303A
|
||||
+#define AC200_AC_DRC_HKE 0x303C
|
||||
+#define AC200_AC_DRC_LKE 0x303E
|
||||
+#define AC200_AC_DRC_HOPE 0x3040
|
||||
+#define AC200_AC_DRC_LOPE 0x3042
|
||||
+#define AC200_AC_DRC_HKN 0x3044
|
||||
+#define AC200_AC_DRC_LKN 0x3046
|
||||
+#define AC200_AC_DRC_SFHAT 0x3048
|
||||
+#define AC200_AC_DRC_SFLAT 0x304A
|
||||
+#define AC200_AC_DRC_SFHRT 0x304C
|
||||
+#define AC200_AC_DRC_SFLRT 0x304E
|
||||
+#define AC200_AC_DRC_MXGHS 0x3050
|
||||
+#define AC200_AC_DRC_MXGLS 0x3052
|
||||
+#define AC200_AC_DRC_MNGHS 0x3054
|
||||
+#define AC200_AC_DRC_MNGLS 0x3056
|
||||
+#define AC200_AC_DRC_EPSHC 0x3058
|
||||
+#define AC200_AC_DRC_EPSLC 0x305A
|
||||
+#define AC200_AC_DRC_HPFHGAIN 0x305E
|
||||
+#define AC200_AC_DRC_HPFLGAIN 0x3060
|
||||
+#define AC200_AC_DRC_BISTCR 0x3100
|
||||
+#define AC200_AC_DRC_BISTST 0x3102
|
||||
+
|
||||
+/* TVE registers */
|
||||
+#define AC200_TVE_CTL0 0x4000
|
||||
+#define AC200_TVE_CTL1 0x4002
|
||||
+#define AC200_TVE_MOD0 0x4004
|
||||
+#define AC200_TVE_MOD1 0x4006
|
||||
+#define AC200_TVE_DAC_CFG0 0x4008
|
||||
+#define AC200_TVE_DAC_CFG1 0x400A
|
||||
+#define AC200_TVE_YC_DELAY 0x400C
|
||||
+#define AC200_TVE_YC_FILTER 0x400E
|
||||
+#define AC200_TVE_BURST_FRQ0 0x4010
|
||||
+#define AC200_TVE_BURST_FRQ1 0x4012
|
||||
+#define AC200_TVE_FRONT_PORCH 0x4014
|
||||
+#define AC200_TVE_BACK_PORCH 0x4016
|
||||
+#define AC200_TVE_TOTAL_LINE 0x401C
|
||||
+#define AC200_TVE_FIRST_ACTIVE 0x401E
|
||||
+#define AC200_TVE_BLACK_LEVEL 0x4020
|
||||
+#define AC200_TVE_BLANK_LEVEL 0x4022
|
||||
+#define AC200_TVE_PLUG_EN 0x4030
|
||||
+#define AC200_TVE_PLUG_IRQ_EN 0x4032
|
||||
+#define AC200_TVE_PLUG_IRQ_STA 0x4034
|
||||
+#define AC200_TVE_PLUG_STA 0x4038
|
||||
+#define AC200_TVE_PLUG_DEBOUNCE 0x4040
|
||||
+#define AC200_TVE_DAC_TEST 0x4042
|
||||
+#define AC200_TVE_PLUG_PULSE_LEVEL 0x40F4
|
||||
+#define AC200_TVE_PLUG_PULSE_START 0x40F8
|
||||
+#define AC200_TVE_PLUG_PULSE_PERIOD 0x40FA
|
||||
+#define AC200_TVE_IF_CTL 0x5000
|
||||
+#define AC200_TVE_IF_TIM0 0x5008
|
||||
+#define AC200_TVE_IF_TIM1 0x500A
|
||||
+#define AC200_TVE_IF_TIM2 0x500C
|
||||
+#define AC200_TVE_IF_TIM3 0x500E
|
||||
+#define AC200_TVE_IF_SYNC0 0x5010
|
||||
+#define AC200_TVE_IF_SYNC1 0x5012
|
||||
+#define AC200_TVE_IF_SYNC2 0x5014
|
||||
+#define AC200_TVE_IF_TIM4 0x5016
|
||||
+#define AC200_TVE_IF_STATUS 0x5018
|
||||
+
|
||||
+/* EPHY registers */
|
||||
+#define AC200_EPHY_CTL 0x6000
|
||||
+#define AC200_EPHY_BIST 0x6002
|
||||
+
|
||||
+/* eFuse registers (0x8000 - 0x9FFF, layout unknown) */
|
||||
+
|
||||
+/* RTC registers */
|
||||
+#define AC200_LOSC_CTRL0 0xA000
|
||||
+#define AC200_LOSC_CTRL1 0xA002
|
||||
+#define AC200_LOSC_AUTO_SWT_STA 0xA004
|
||||
+#define AC200_INTOSC_CLK_PRESCAL 0xA008
|
||||
+#define AC200_RTC_YY_MM_DD0 0xA010
|
||||
+#define AC200_RTC_YY_MM_DD1 0xA012
|
||||
+#define AC200_RTC_HH_MM_SS0 0xA014
|
||||
+#define AC200_RTC_HH_MM_SS1 0xA016
|
||||
+#define AC200_ALARM0_CUR_VLU0 0xA024
|
||||
+#define AC200_ALARM0_CUR_VLU1 0xA026
|
||||
+#define AC200_ALARM0_ENABLE 0xA028
|
||||
+#define AC200_ALARM0_IRQ_EN 0xA02C
|
||||
+#define AC200_ALARM0_IRQ_STA 0xA030
|
||||
+#define AC200_ALARM1_WK_HH_MM_SS0 0xA040
|
||||
+#define AC200_ALARM1_WK_HH_MM_SS1 0xA042
|
||||
+#define AC200_ALARM1_ENABLE 0xA044
|
||||
+#define AC200_ALARM1_IRQ_EN 0xA048
|
||||
+#define AC200_ALARM1_IRQ_STA 0xA04C
|
||||
+#define AC200_ALARM_CONFIG 0xA050
|
||||
+#define AC200_LOSC_OUT_GATING 0xA060
|
||||
+#define AC200_GP_DATA(x) (0xA100 + (x) * 2)
|
||||
+#define AC200_RTC_DEB 0xA170
|
||||
+#define AC200_GPL_HOLD_OUTPUT 0xA180
|
||||
+#define AC200_VDD_RTC 0xA190
|
||||
+#define AC200_IC_CHARA0 0xA1F0
|
||||
+#define AC200_IC_CHARA1 0xA1F2
|
||||
+
|
||||
+struct ac200_dev {
|
||||
+ struct regmap *regmap;
|
||||
+ struct regmap_irq_chip_data *regmap_irqc;
|
||||
+};
|
||||
+
|
||||
+#endif /* __LINUX_MFD_AC200_H */
|
||||
--
|
||||
2.35.3
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
From b22ce8f1db276a0bc23c20a800e3f438df60737c Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 16 Aug 2019 16:38:57 +0200
|
||||
Subject: [PATCH 010/170] drv:net:phy: Add support for AC200 EPHY
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 7 ++
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/ac200.c | 220 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 228 insertions(+)
|
||||
create mode 100644 drivers/net/phy/ac200.c
|
||||
|
||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
|
||||
index 9fee639ee..cb9ad6790 100644
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -63,6 +63,13 @@ config SFP
|
||||
|
||||
comment "MII PHY device drivers"
|
||||
|
||||
+config AC200_PHY
|
||||
+ tristate "AC200 EPHY"
|
||||
+ depends on NVMEM
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Fast ethernet PHY as found in X-Powers AC200 multi-function device.
|
||||
+
|
||||
config AMD_PHY
|
||||
tristate "AMD PHYs"
|
||||
help
|
||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
|
||||
index b12b1d86f..e3469be6f 100644
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -30,6 +30,7 @@ obj-$(CONFIG_SFP) += sfp.o
|
||||
sfp-obj-$(CONFIG_SFP) += sfp-bus.o
|
||||
obj-y += $(sfp-obj-y) $(sfp-obj-m)
|
||||
|
||||
+obj-$(CONFIG_AC200_PHY) += ac200.o
|
||||
obj-$(CONFIG_ADIN_PHY) += adin.o
|
||||
obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
|
||||
obj-$(CONFIG_AMD_PHY) += amd.o
|
||||
diff --git a/drivers/net/phy/ac200.c b/drivers/net/phy/ac200.c
|
||||
new file mode 100644
|
||||
index 000000000..cb713188f
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/ac200.c
|
||||
@@ -0,0 +1,220 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/**
|
||||
+ * Driver for AC200 Ethernet PHY
|
||||
+ *
|
||||
+ * Copyright (c) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mfd/ac200.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#define AC200_EPHY_ID 0x00441400
|
||||
+#define AC200_EPHY_ID_MASK 0x0ffffff0
|
||||
+
|
||||
+/* macros for system ephy control 0 register */
|
||||
+#define AC200_EPHY_RESET_INVALID BIT(0)
|
||||
+#define AC200_EPHY_SYSCLK_GATING BIT(1)
|
||||
+
|
||||
+/* macros for system ephy control 1 register */
|
||||
+#define AC200_EPHY_E_EPHY_MII_IO_EN BIT(0)
|
||||
+#define AC200_EPHY_E_LNK_LED_IO_EN BIT(1)
|
||||
+#define AC200_EPHY_E_SPD_LED_IO_EN BIT(2)
|
||||
+#define AC200_EPHY_E_DPX_LED_IO_EN BIT(3)
|
||||
+
|
||||
+/* macros for ephy control register */
|
||||
+#define AC200_EPHY_SHUTDOWN BIT(0)
|
||||
+#define AC200_EPHY_LED_POL BIT(1)
|
||||
+#define AC200_EPHY_CLK_SEL BIT(2)
|
||||
+#define AC200_EPHY_ADDR(x) (((x) & 0x1F) << 4)
|
||||
+#define AC200_EPHY_XMII_SEL BIT(11)
|
||||
+#define AC200_EPHY_CALIB(x) (((x) & 0xF) << 12)
|
||||
+
|
||||
+struct ac200_ephy_dev {
|
||||
+ struct clk *clk;
|
||||
+ struct phy_driver *ephy;
|
||||
+ struct regmap *regmap;
|
||||
+};
|
||||
+
|
||||
+static char *ac200_phy_name = "AC200 EPHY";
|
||||
+
|
||||
+static int ac200_ephy_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ const struct ac200_ephy_dev *priv = phydev->drv->driver_data;
|
||||
+ unsigned int value;
|
||||
+ int ret;
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0100); /* Switch to Page 1 */
|
||||
+ phy_write(phydev, 0x12, 0x4824); /* Disable APS */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0200); /* Switch to Page 2 */
|
||||
+ phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0600); /* Switch to Page 6 */
|
||||
+ phy_write(phydev, 0x14, 0x708f); /* PHYAFE TX optimization */
|
||||
+ phy_write(phydev, 0x13, 0xF000); /* PHYAFE RX optimization */
|
||||
+ phy_write(phydev, 0x15, 0x1530);
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0800); /* Switch to Page 6 */
|
||||
+ phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0100); /* switch to page 1 */
|
||||
+ phy_clear_bits(phydev, 0x17, BIT(3)); /* disable intelligent IEEE */
|
||||
+
|
||||
+ /* next two blocks disable 802.3az IEEE */
|
||||
+ phy_write(phydev, 0x1f, 0x0200); /* switch to page 2 */
|
||||
+ phy_write(phydev, 0x18, 0x0000);
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0000); /* switch to page 0 */
|
||||
+ phy_clear_bits_mmd(phydev, 0x7, 0x3c, BIT(1));
|
||||
+
|
||||
+ if (phydev->interface == PHY_INTERFACE_MODE_RMII)
|
||||
+ value = AC200_EPHY_XMII_SEL;
|
||||
+ else
|
||||
+ value = 0;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->regmap, AC200_EPHY_CTL,
|
||||
+ AC200_EPHY_XMII_SEL, value);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* FIXME: This is H6 specific */
|
||||
+ phy_set_bits(phydev, 0x13, BIT(12));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ac200_dev *ac200 = dev_get_drvdata(pdev->dev.parent);
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ac200_ephy_dev *priv;
|
||||
+ struct nvmem_cell *calcell;
|
||||
+ struct phy_driver *ephy;
|
||||
+ u16 *caldata, calib;
|
||||
+ size_t callen;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ephy = devm_kzalloc(dev, sizeof(*ephy), GFP_KERNEL);
|
||||
+ if (!ephy)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->clk = devm_clk_get(dev, NULL);
|
||||
+ if (IS_ERR(priv->clk)) {
|
||||
+ dev_err(dev, "Can't obtain the clock!\n");
|
||||
+ return PTR_ERR(priv->clk);
|
||||
+ }
|
||||
+
|
||||
+ calcell = devm_nvmem_cell_get(dev, "calibration");
|
||||
+ if (IS_ERR(calcell)) {
|
||||
+ dev_err(dev, "Unable to find calibration data!\n");
|
||||
+ return PTR_ERR(calcell);
|
||||
+ }
|
||||
+
|
||||
+ caldata = nvmem_cell_read(calcell, &callen);
|
||||
+ if (IS_ERR(caldata)) {
|
||||
+ dev_err(dev, "Unable to read calibration data!\n");
|
||||
+ return PTR_ERR(caldata);
|
||||
+ }
|
||||
+
|
||||
+ if (callen != 2) {
|
||||
+ dev_err(dev, "Calibration data has wrong length: 2 != %zu\n",
|
||||
+ callen);
|
||||
+ kfree(caldata);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ calib = *caldata + 3;
|
||||
+ kfree(caldata);
|
||||
+
|
||||
+ ret = clk_prepare_enable(priv->clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ephy->phy_id = AC200_EPHY_ID;
|
||||
+ ephy->phy_id_mask = AC200_EPHY_ID_MASK;
|
||||
+ ephy->name = ac200_phy_name;
|
||||
+ ephy->driver_data = priv;
|
||||
+ ephy->soft_reset = genphy_soft_reset;
|
||||
+ ephy->config_init = ac200_ephy_config_init;
|
||||
+ ephy->suspend = genphy_suspend;
|
||||
+ ephy->resume = genphy_resume;
|
||||
+
|
||||
+ priv->ephy = ephy;
|
||||
+ priv->regmap = ac200->regmap;
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID |
|
||||
+ AC200_EPHY_SYSCLK_GATING);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_EPHY_CTL1,
|
||||
+ AC200_EPHY_E_EPHY_MII_IO_EN |
|
||||
+ AC200_EPHY_E_LNK_LED_IO_EN |
|
||||
+ AC200_EPHY_E_SPD_LED_IO_EN |
|
||||
+ AC200_EPHY_E_DPX_LED_IO_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_EPHY_CTL,
|
||||
+ AC200_EPHY_LED_POL |
|
||||
+ AC200_EPHY_CLK_SEL |
|
||||
+ AC200_EPHY_ADDR(1) |
|
||||
+ AC200_EPHY_CALIB(calib));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = phy_driver_register(priv->ephy, THIS_MODULE);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to register phy\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ac200_ephy_dev *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ phy_driver_unregister(priv->ephy);
|
||||
+
|
||||
+ regmap_write(priv->regmap, AC200_EPHY_CTL, AC200_EPHY_SHUTDOWN);
|
||||
+ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL1, 0);
|
||||
+ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL0, 0);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ac200_ephy_match[] = {
|
||||
+ { .compatible = "x-powers,ac200-ephy" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ac200_ephy_match);
|
||||
+
|
||||
+static struct platform_driver ac200_ephy_driver = {
|
||||
+ .probe = ac200_ephy_probe,
|
||||
+ .remove = ac200_ephy_remove,
|
||||
+ .driver = {
|
||||
+ .name = "ac200-ephy",
|
||||
+ .of_match_table = ac200_ephy_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(ac200_ephy_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
|
||||
+MODULE_DESCRIPTION("AC200 Ethernet PHY driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.35.3
|
||||
|
||||
@@ -0,0 +1,375 @@
|
||||
From 3f2e8f9da20ce69785be3135e2a2db74955d239b Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Mon, 13 Jun 2022 17:37:19 +0100
|
||||
Subject: [PATCH] mfd: Add support for X-Powers AC200 EPHY syscon
|
||||
|
||||
The X-Powers AC200 mixed signal chip contains a 100Mbit/s Ethernet PHY.
|
||||
While the PHY is using the standard MDIO and MII/RMII interfaces to
|
||||
the MAC, there are some registers in the AC200 that need to be setup to
|
||||
make the PHY functional:
|
||||
- The MDIO PHY address needs to set.
|
||||
- The LED polarity needs to be configured.
|
||||
- The MII interface mode needs to be set (MII or RMII).
|
||||
- There is a reset line that controls the PHY operation.
|
||||
- There is a clock gate that blocks or forwards the AC200's internal clock
|
||||
to the PHY.
|
||||
|
||||
This driver here takes care of those setup needs, but does not cover the
|
||||
actual PHY operation. Once the PHY is set up and enabled, it behaves like
|
||||
a standard MDIO/MII controlled PHY, and can be driven by the IEEE802.3-C22
|
||||
driver.
|
||||
|
||||
To some degree those parameters mimic the typical wired setup of a
|
||||
physical PHY chip: the LED polarity, MII interface mode and PHY address
|
||||
are typically configued via connecting certain pins. We use the
|
||||
devicetree to learn those parameters, which depend on the board setup.
|
||||
|
||||
This driver is a child of the AC200 MFD parent device, and uses its
|
||||
regmap and input clock. It also provides a reset and clock controller,
|
||||
which the actual PHY device (node) needs to refer to. This ensures that
|
||||
this PHY control device is initialised before the PHY is expected to work.
|
||||
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
drivers/phy/allwinner/Kconfig | 9 +
|
||||
drivers/phy/allwinner/Makefile | 1 +
|
||||
drivers/phy/allwinner/ac200-ephy-ctl.c | 301 +++++++++++++++++++++++++
|
||||
3 files changed, 311 insertions(+)
|
||||
create mode 100644 drivers/phy/allwinner/ac200-ephy-ctl.c
|
||||
|
||||
diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig
|
||||
index e93a53139460..d3614169de5c 100644
|
||||
--- a/drivers/phy/allwinner/Kconfig
|
||||
+++ b/drivers/phy/allwinner/Kconfig
|
||||
@@ -58,3 +58,12 @@ config PHY_SUN50I_USB3
|
||||
part of Allwinner H6 SoC.
|
||||
|
||||
This driver controls each individual USB 2+3 host PHY combo.
|
||||
+
|
||||
+config AC200_PHY_CTL
|
||||
+ tristate "X-Power AC200 PHY control driver"
|
||||
+ depends on MFD_AC200
|
||||
+ depends on RESET_CONTROLLER
|
||||
+ help
|
||||
+ Enable this to support the Ethernet PHY operation of the AC200
|
||||
+ mixed signal chip. This driver just enables and configures the
|
||||
+ PHY, the PHY itself is supported by a standard driver.
|
||||
diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile
|
||||
index bd74901a1255..0eecec7a908a 100644
|
||||
--- a/drivers/phy/allwinner/Makefile
|
||||
+++ b/drivers/phy/allwinner/Makefile
|
||||
@@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
|
||||
obj-$(CONFIG_PHY_SUN6I_MIPI_DPHY) += phy-sun6i-mipi-dphy.o
|
||||
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
|
||||
obj-$(CONFIG_PHY_SUN50I_USB3) += phy-sun50i-usb3.o
|
||||
+obj-$(CONFIG_AC200_PHY_CTL) += ac200-ephy-ctl.o
|
||||
diff --git a/drivers/phy/allwinner/ac200-ephy-ctl.c b/drivers/phy/allwinner/ac200-ephy-ctl.c
|
||||
new file mode 100644
|
||||
index 000000000000..8efeaf18e42c
|
||||
--- /dev/null
|
||||
+++ b/drivers/phy/allwinner/ac200-ephy-ctl.c
|
||||
@@ -0,0 +1,301 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/**
|
||||
+ * syscon driver to control and configure AC200 Ethernet PHY
|
||||
+ * Copyright (c) 2022 Arm Ltd.
|
||||
+ *
|
||||
+ * TODO's and questions:
|
||||
+ * =========================
|
||||
+ * - This driver is something like a syscon driver, as it controls various
|
||||
+ * bits and registers that effect other devices (the actual PHY). It's
|
||||
+ * unclear where it should live, though:
|
||||
+ * - it could be integrated into the MFD driver, but this looks messy
|
||||
+ * - it could live at the current location (drivers/phy/allwinner), but that
|
||||
+ * sounds wrong
|
||||
+ * - it could be a separate file, but in drivers/mfd
|
||||
+ * - anything else
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset-controller.h>
|
||||
+
|
||||
+/* macros for system ephy control 0 register */
|
||||
+#define AC200_SYS_EPHY_CTL0 0x0014
|
||||
+#define AC200_EPHY_RESET_INVALID BIT(0)
|
||||
+#define AC200_EPHY_SYSCLK_GATING 1
|
||||
+
|
||||
+/* macros for system ephy control 1 register */
|
||||
+#define AC200_SYS_EPHY_CTL1 0x0016
|
||||
+#define AC200_EPHY_E_EPHY_MII_IO_EN BIT(0)
|
||||
+#define AC200_EPHY_E_LNK_LED_IO_EN BIT(1)
|
||||
+#define AC200_EPHY_E_SPD_LED_IO_EN BIT(2)
|
||||
+#define AC200_EPHY_E_DPX_LED_IO_EN BIT(3)
|
||||
+
|
||||
+/* macros for ephy control register */
|
||||
+#define AC200_EPHY_CTL 0x6000
|
||||
+#define AC200_EPHY_SHUTDOWN BIT(0)
|
||||
+#define AC200_EPHY_LED_POL BIT(1)
|
||||
+#define AC200_EPHY_CLK_SEL BIT(2)
|
||||
+#define AC200_EPHY_ADDR(x) (((x) & 0x1F) << 4)
|
||||
+#define AC200_EPHY_XMII_SEL BIT(11)
|
||||
+#define AC200_EPHY_CALIB(x) (((x) & 0xF) << 12)
|
||||
+
|
||||
+struct ac200_ephy_ctl_dev {
|
||||
+ struct reset_controller_dev rcdev;
|
||||
+ struct clk_hw *gate_clk;
|
||||
+ struct regmap *regmap;
|
||||
+};
|
||||
+
|
||||
+static struct ac200_ephy_ctl_dev *to_phy_dev(struct reset_controller_dev *rcdev)
|
||||
+{
|
||||
+ return container_of(rcdev, struct ac200_ephy_ctl_dev, rcdev);
|
||||
+}
|
||||
+
|
||||
+static int ephy_ctl_reset(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
+{
|
||||
+ struct ac200_ephy_ctl_dev *ac200 = to_phy_dev(rcdev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_clear_bits(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* This is going via I2C, so there is plenty of built-in delay. */
|
||||
+ return regmap_set_bits(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID);
|
||||
+}
|
||||
+
|
||||
+static int ephy_ctl_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
+{
|
||||
+ struct ac200_ephy_ctl_dev *ac200 = to_phy_dev(rcdev);
|
||||
+
|
||||
+ return regmap_clear_bits(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID);
|
||||
+}
|
||||
+
|
||||
+static int ephy_ctl_deassert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct ac200_ephy_ctl_dev *ac200 = to_phy_dev(rcdev);
|
||||
+
|
||||
+ return regmap_set_bits(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID);
|
||||
+}
|
||||
+
|
||||
+static int ephy_ctl_status(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
+{
|
||||
+ struct ac200_ephy_ctl_dev *ac200 = to_phy_dev(rcdev);
|
||||
+
|
||||
+ return regmap_test_bits(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID);
|
||||
+}
|
||||
+
|
||||
+static int ephy_ctl_reset_of_xlate(struct reset_controller_dev *rcdev,
|
||||
+ const struct of_phandle_args *reset_spec)
|
||||
+{
|
||||
+ if (WARN_ON(reset_spec->args_count != 0))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+const struct reset_control_ops ephy_ctl_reset_ops = {
|
||||
+ .assert = ephy_ctl_assert,
|
||||
+ .deassert = ephy_ctl_deassert,
|
||||
+ .reset = ephy_ctl_reset,
|
||||
+ .status = ephy_ctl_status,
|
||||
+};
|
||||
+
|
||||
+static void ac200_ephy_ctl_disable(struct ac200_ephy_ctl_dev *priv)
|
||||
+{
|
||||
+ regmap_write(priv->regmap, AC200_EPHY_CTL, AC200_EPHY_SHUTDOWN);
|
||||
+ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL1, 0);
|
||||
+ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL0, 0);
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_ctl_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct reset_controller_dev *rcdev;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ac200_ephy_ctl_dev *priv;
|
||||
+ struct nvmem_cell *calcell;
|
||||
+ const char *parent_name;
|
||||
+ phy_interface_t phy_if;
|
||||
+ u16 *caldata, ephy_ctl;
|
||||
+ struct clk *clk;
|
||||
+ size_t callen;
|
||||
+ u32 value;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+
|
||||
+ priv->regmap = dev_get_regmap(dev->parent, NULL);
|
||||
+ if (!priv->regmap)
|
||||
+ return -EPROBE_DEFER;
|
||||
+
|
||||
+ calcell = devm_nvmem_cell_get(dev, "calibration");
|
||||
+ if (IS_ERR(calcell))
|
||||
+ return dev_err_probe(dev, PTR_ERR(calcell),
|
||||
+ "Unable to find calibration data!\n");
|
||||
+
|
||||
+ caldata = nvmem_cell_read(calcell, &callen);
|
||||
+ if (IS_ERR(caldata)) {
|
||||
+ dev_err(dev, "Unable to read calibration data!\n");
|
||||
+ return PTR_ERR(caldata);
|
||||
+ }
|
||||
+
|
||||
+ if (callen != 2) {
|
||||
+ dev_err(dev, "Calibration data length must be 2 bytes!\n");
|
||||
+ kfree(caldata);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ephy_ctl = AC200_EPHY_CALIB(*caldata + 3);
|
||||
+ kfree(caldata);
|
||||
+
|
||||
+ ret = of_get_phy_mode(dev->of_node, &phy_if);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to read PHY connection mode\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ switch (phy_if) {
|
||||
+ case PHY_INTERFACE_MODE_MII:
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_RMII:
|
||||
+ ephy_ctl |= AC200_EPHY_XMII_SEL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(dev, "Illegal PHY connection mode (%d), only RMII or MII supported\n",
|
||||
+ phy_if);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_property_read_u32(dev->of_node, "x-powers,led-polarity",
|
||||
+ &value);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to read LED polarity setting\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (value == GPIO_ACTIVE_LOW)
|
||||
+ ephy_ctl |= AC200_EPHY_LED_POL;
|
||||
+
|
||||
+ ret = of_property_read_u32(dev->of_node, "phy-address", &value);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to read PHY address value\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ephy_ctl |= AC200_EPHY_ADDR(value);
|
||||
+
|
||||
+ clk = clk_get(dev->parent, NULL);
|
||||
+ if (IS_ERR(clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(clk),
|
||||
+ "Unable to obtain the clock\n");
|
||||
+
|
||||
+ if (clk_get_rate(clk) == 24000000)
|
||||
+ ephy_ctl |= AC200_EPHY_CLK_SEL;
|
||||
+
|
||||
+ clk_put(clk);
|
||||
+
|
||||
+ /* Assert reset and gate clock, to disable PHY for now */
|
||||
+ ret = regmap_write(priv->regmap, AC200_SYS_EPHY_CTL0, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(priv->regmap, AC200_SYS_EPHY_CTL1,
|
||||
+ AC200_EPHY_E_EPHY_MII_IO_EN |
|
||||
+ AC200_EPHY_E_LNK_LED_IO_EN |
|
||||
+ AC200_EPHY_E_SPD_LED_IO_EN |
|
||||
+ AC200_EPHY_E_DPX_LED_IO_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(priv->regmap, AC200_EPHY_CTL, ephy_ctl);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ rcdev = &priv->rcdev;
|
||||
+ rcdev->owner = dev->driver->owner;
|
||||
+ rcdev->nr_resets = 1;
|
||||
+ rcdev->ops = &ephy_ctl_reset_ops;
|
||||
+ rcdev->of_node = dev->of_node;
|
||||
+ rcdev->of_reset_n_cells = 0;
|
||||
+ rcdev->of_xlate = ephy_ctl_reset_of_xlate;
|
||||
+
|
||||
+ ret = devm_reset_controller_register(dev, rcdev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to register reset controller: %d\n", ret);
|
||||
+ goto err_disable_ephy;
|
||||
+ }
|
||||
+
|
||||
+ parent_name = of_clk_get_parent_name(dev->parent->of_node, 0);
|
||||
+ priv->gate_clk = devm_clk_hw_register_regmap_gate(dev,
|
||||
+ "ac200-ephy-ctl-gate", parent_name, 0,
|
||||
+ priv->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_SYSCLK_GATING, 0);
|
||||
+ if (IS_ERR(priv->gate_clk)) {
|
||||
+ ret = PTR_ERR(priv->gate_clk);
|
||||
+ dev_err(dev, "Unable to register gate clock: %d\n", ret);
|
||||
+ goto err_disable_ephy;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
+ priv->gate_clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to register clock provider: %d\n", ret);
|
||||
+ goto err_disable_ephy;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_disable_ephy:
|
||||
+ ac200_ephy_ctl_disable(priv);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_ctl_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ac200_ephy_ctl_dev *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ ac200_ephy_ctl_disable(priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ac200_ephy_ctl_match[] = {
|
||||
+ { .compatible = "x-powers,ac200-ephy-ctl" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ac200_ephy_ctl_match);
|
||||
+
|
||||
+static struct platform_driver ac200_ephy_ctl_driver = {
|
||||
+ .probe = ac200_ephy_ctl_probe,
|
||||
+ .remove = ac200_ephy_ctl_remove,
|
||||
+ .driver = {
|
||||
+ .name = "ac200-ephy-ctl",
|
||||
+ .of_match_table = ac200_ephy_ctl_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(ac200_ephy_ctl_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Andre Przywara <andre.przywara@arm.com>");
|
||||
+MODULE_DESCRIPTION("AC200 Ethernet PHY control driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
From b9cfea3958c89d9a29b46fec023035a9964304bd Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 16 Aug 2019 16:38:21 +0200
|
||||
Subject: [PATCH] mfd: Add support for X-Powers AC200
|
||||
|
||||
The X-Powers AC200 is a mixed signal multi-purpose chip, which provides
|
||||
audio DAC/ADCs, a CVBS video encoder, a 100Mbit/s Ethernet PHY and a
|
||||
real-time clock. Its control registers can be accessed via I2C or
|
||||
Allwinner's RSB bus.
|
||||
Beside this chip being used on some older boards (for instance the Remix
|
||||
Mini PC), it is quite wide spread due to its die being co-packaged on the
|
||||
Allwinner H6 and H616 SoCs, which use its audio, video and PHY
|
||||
functionality.
|
||||
|
||||
Aside from the RTC, the other functions do not need constant
|
||||
hand-holding via the I2C registers, but rather need to be configured and
|
||||
enabled only once.
|
||||
|
||||
We model the control side of this chip using the MFD subsystem. This
|
||||
driver here just provides the parent device for the various subfunctions,
|
||||
and takes care of enabling clocks and reset, but also provides the regmap,
|
||||
which the respective child drivers will use.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
drivers/mfd/Kconfig | 12 +++
|
||||
drivers/mfd/Makefile | 1 +
|
||||
drivers/mfd/ac200.c | 191 +++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 204 insertions(+)
|
||||
create mode 100644 drivers/mfd/ac200.c
|
||||
|
||||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
|
||||
index 9da8235cb690..6fbf88940f26 100644
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -179,6 +179,18 @@ config MFD_AC100
|
||||
This driver include only the core APIs. You have to select individual
|
||||
components like codecs or RTC under the corresponding menus.
|
||||
|
||||
+config MFD_AC200
|
||||
+ tristate "X-Powers AC200"
|
||||
+ select MFD_CORE
|
||||
+ select REGMAP_I2C
|
||||
+ depends on COMMON_CLK
|
||||
+ depends on I2C
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ If you say Y here you get support for the X-Powers AC200 IC.
|
||||
+ This driver include only the core APIs. You have to select individual
|
||||
+ components like Ethernet PHY or codec under the corresponding menus.
|
||||
+
|
||||
config MFD_AXP20X
|
||||
tristate
|
||||
select MFD_CORE
|
||||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
|
||||
index 7ed3ef4a698c..91dc530d0bde 100644
|
||||
--- a/drivers/mfd/Makefile
|
||||
+++ b/drivers/mfd/Makefile
|
||||
@@ -144,6 +144,7 @@ obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
|
||||
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
|
||||
|
||||
obj-$(CONFIG_MFD_AC100) += ac100.o
|
||||
+obj-$(CONFIG_MFD_AC200) += ac200.o
|
||||
obj-$(CONFIG_MFD_AXP20X) += axp20x.o
|
||||
obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
|
||||
obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
|
||||
diff --git a/drivers/mfd/ac200.c b/drivers/mfd/ac200.c
|
||||
new file mode 100644
|
||||
index 000000000000..625b119f53cf
|
||||
--- /dev/null
|
||||
+++ b/drivers/mfd/ac200.c
|
||||
@@ -0,0 +1,191 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * MFD core driver for X-Powers' AC200 IC
|
||||
+ *
|
||||
+ * The AC200 is a chip which is co-packaged with Allwinner H6 SoC and
|
||||
+ * includes analog audio codec, analog TV encoder, ethernet PHY, eFuse
|
||||
+ * and RTC.
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
+ *
|
||||
+ * Based on AC100 driver with following copyrights:
|
||||
+ * Copyright (2016) Chen-Yu Tsai
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/core.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+struct ac200_dev {
|
||||
+ struct clk *clk;
|
||||
+ struct regmap *regmap;
|
||||
+};
|
||||
+
|
||||
+#define AC200_SYS_CONTROL 0x0002
|
||||
+#define AC200_SYS_BG_CTL 0x0050
|
||||
+
|
||||
+/* interface register (can be accessed from any page) */
|
||||
+#define AC200_TWI_REG_ADDR_H 0xFE
|
||||
+
|
||||
+#define AC200_MAX_REG 0xA1F2
|
||||
+
|
||||
+static const struct regmap_range_cfg ac200_range_cfg[] = {
|
||||
+ {
|
||||
+ .range_max = AC200_MAX_REG,
|
||||
+ .selector_reg = AC200_TWI_REG_ADDR_H,
|
||||
+ .selector_mask = 0xff,
|
||||
+ .selector_shift = 0,
|
||||
+ .window_start = 0,
|
||||
+ .window_len = 256,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config ac200_regmap_config = {
|
||||
+ .name = "AC200",
|
||||
+ .reg_bits = 8,
|
||||
+ .reg_stride = 2,
|
||||
+ .val_bits = 16,
|
||||
+ .ranges = ac200_range_cfg,
|
||||
+ .num_ranges = ARRAY_SIZE(ac200_range_cfg),
|
||||
+ .max_register = AC200_MAX_REG,
|
||||
+};
|
||||
+
|
||||
+static struct mfd_cell ac200_cells[] = {
|
||||
+ {
|
||||
+ .name = "ac200-codec",
|
||||
+ .of_compatible = "x-powers,ac200-codec",
|
||||
+ }, {
|
||||
+ .name = "ac200-ephy-ctl",
|
||||
+ .of_compatible = "x-powers,ac200-ephy-ctl",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int ac200_i2c_probe(struct i2c_client *i2c,
|
||||
+ const struct i2c_device_id *id)
|
||||
+{
|
||||
+ struct device *dev = &i2c->dev;
|
||||
+ struct nvmem_cell *bgcell;
|
||||
+ struct ac200_dev *ac200;
|
||||
+ u16 *bgdata, bgval;
|
||||
+ size_t bglen;
|
||||
+ int ret;
|
||||
+
|
||||
+ ac200 = devm_kzalloc(dev, sizeof(*ac200), GFP_KERNEL);
|
||||
+ if (!ac200)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i2c_set_clientdata(i2c, ac200);
|
||||
+
|
||||
+ ac200->clk = devm_clk_get(dev, NULL);
|
||||
+ if (IS_ERR(ac200->clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(ac200->clk),
|
||||
+ "Can't obtain the clock\n");
|
||||
+
|
||||
+ ac200->regmap = devm_regmap_init_i2c(i2c, &ac200_regmap_config);
|
||||
+ if (IS_ERR(ac200->regmap)) {
|
||||
+ ret = PTR_ERR(ac200->regmap);
|
||||
+ dev_err(dev, "Regmap init failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ bgcell = devm_nvmem_cell_get(dev, "bandgap");
|
||||
+ if (IS_ERR(bgcell))
|
||||
+ return dev_err_probe(dev, PTR_ERR(bgcell),
|
||||
+ "Unable to find bandgap data!\n");
|
||||
+
|
||||
+ bgdata = nvmem_cell_read(bgcell, &bglen);
|
||||
+ if (IS_ERR(bgdata)) {
|
||||
+ dev_err(dev, "Unable to read bandgap data!\n");
|
||||
+ return PTR_ERR(bgdata);
|
||||
+ }
|
||||
+
|
||||
+ if (bglen != 2) {
|
||||
+ dev_err(dev, "Invalid nvmem bandgap length!\n");
|
||||
+ kfree(bgdata);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ bgval = *bgdata;
|
||||
+ kfree(bgdata);
|
||||
+
|
||||
+ ret = clk_prepare_enable(ac200->clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * There is no documentation on how long we have to wait before
|
||||
+ * executing first operation. Vendor driver sleeps for 40 ms.
|
||||
+ */
|
||||
+ msleep(40);
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 1);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ if (bgval) {
|
||||
+ /* bandgap register is not documented */
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_BG_CTL,
|
||||
+ 0x8280 | bgval);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, ac200_cells,
|
||||
+ ARRAY_SIZE(ac200_cells), NULL, 0, NULL);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to add MFD devices: %d\n", ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err:
|
||||
+ clk_disable_unprepare(ac200->clk);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void ac200_i2c_remove(struct i2c_client *i2c)
|
||||
+{
|
||||
+ struct ac200_dev *ac200 = i2c_get_clientdata(i2c);
|
||||
+
|
||||
+ regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0);
|
||||
+
|
||||
+ clk_disable_unprepare(ac200->clk);
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_device_id ac200_ids[] = {
|
||||
+ { "ac200", },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, ac200_ids);
|
||||
+
|
||||
+static const struct of_device_id ac200_of_match[] = {
|
||||
+ { .compatible = "x-powers,ac200" },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ac200_of_match);
|
||||
+
|
||||
+static struct i2c_driver ac200_i2c_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "ac200",
|
||||
+ .of_match_table = of_match_ptr(ac200_of_match),
|
||||
+ },
|
||||
+ .probe = ac200_i2c_probe,
|
||||
+ .remove = ac200_i2c_remove,
|
||||
+ .id_table = ac200_ids,
|
||||
+};
|
||||
+module_i2c_driver(ac200_i2c_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("MFD core driver for AC200");
|
||||
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@gmail.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
From eab277e9ca1f5558dbbf9820dbf6cf4edf4d4c39 Mon Sep 17 00:00:00 2001
|
||||
From: The-going <48602507+The-going@users.noreply.github.com>
|
||||
Date: Tue, 28 Feb 2023 13:39:51 +0300
|
||||
Subject: [PATCH] mfd: sunxi-ac200: fix error initialization
|
||||
|
||||
---
|
||||
drivers/mfd/sunxi-ac200.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/sunxi-ac200.c b/drivers/mfd/sunxi-ac200.c
|
||||
index 368a54587..b784a82f3 100644
|
||||
--- a/drivers/mfd/sunxi-ac200.c
|
||||
+++ b/drivers/mfd/sunxi-ac200.c
|
||||
@@ -144,7 +144,7 @@ static int ac200_i2c_probe(struct i2c_client *i2c,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ac200_i2c_remove(struct i2c_client *i2c)
|
||||
+static void ac200_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct ac200_dev *ac200 = i2c_get_clientdata(i2c);
|
||||
|
||||
@@ -152,8 +152,6 @@ static int ac200_i2c_remove(struct i2c_client *i2c)
|
||||
|
||||
mfd_remove_devices(&i2c->dev);
|
||||
regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ac200_ids[] = {
|
||||
--
|
||||
2.35.3
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
From af665542835fd39edf63c8c9ad1f7267e64a2320 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 16 Aug 2019 16:38:57 +0200
|
||||
Subject: [PATCH] net: phy: Add support for AC200 EPHY
|
||||
|
||||
The X-Powers AC200 mixed signal chip contains a 100Mbit/s Ethernet PHY.
|
||||
While its sporting a usable default setup, and can be controlled by the
|
||||
generic IEEE802.3-C22 PHY driver, the BSP sets up some extra registers,
|
||||
which this driver here covers.
|
||||
|
||||
Add a PHY driver matching the AC200 EPHY ID registers, and which
|
||||
programs some PHY registers according to the BSP code.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 7 ++++
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/ac200-phy.c | 82 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 90 insertions(+)
|
||||
create mode 100644 drivers/net/phy/ac200.c
|
||||
|
||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
|
||||
index c57a0262fb64..a1f8fdfc5762 100644
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -63,6 +63,13 @@ config SFP
|
||||
|
||||
comment "MII PHY device drivers"
|
||||
|
||||
+config AC200_PHY
|
||||
+ tristate "AC200 EPHY"
|
||||
+ depends on NVMEM
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Fast ethernet PHY as found in X-Powers AC200 multi-function device.
|
||||
+
|
||||
config AMD_PHY
|
||||
tristate "AMD PHYs"
|
||||
help
|
||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
|
||||
index f7138d3c896b..9ad2b8cc01b1 100644
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -30,6 +30,7 @@ obj-$(CONFIG_SFP) += sfp.o
|
||||
sfp-obj-$(CONFIG_SFP) += sfp-bus.o
|
||||
obj-y += $(sfp-obj-y) $(sfp-obj-m)
|
||||
|
||||
+obj-$(CONFIG_AC200_PHY) += ac200-phy.o
|
||||
obj-$(CONFIG_ADIN_PHY) += adin.o
|
||||
obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
|
||||
obj-$(CONFIG_AMD_PHY) += amd.o
|
||||
diff --git a/drivers/net/phy/ac200-phy.c b/drivers/net/phy/ac200-phy.c
|
||||
new file mode 100644
|
||||
index 000000000000..8499914f49b8
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/ac200-phy.c
|
||||
@@ -0,0 +1,82 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/**
|
||||
+ * Driver for AC200 Ethernet PHY
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/phy.h>
|
||||
+
|
||||
+#define AC200_EPHY_ID 0x00441400
|
||||
+#define AC200_EPHY_ID_MASK 0x0ffffff0
|
||||
+
|
||||
+static int ac200_ephy_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ phy_write(phydev, 0x1f, 0x0100); /* Switch to Page 1 */
|
||||
+ phy_write(phydev, 0x12, 0x4824); /* Disable APS */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0200); /* Switch to Page 2 */
|
||||
+ phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0600); /* Switch to Page 6 */
|
||||
+ phy_write(phydev, 0x14, 0x708f); /* PHYAFE TX optimization */
|
||||
+ phy_write(phydev, 0x13, 0xF000); /* PHYAFE RX optimization */
|
||||
+ phy_write(phydev, 0x15, 0x1530);
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0800); /* Switch to Page 8 */
|
||||
+ phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0100); /* switch to page 1 */
|
||||
+ phy_clear_bits(phydev, 0x17, BIT(3)); /* disable intelligent EEE */
|
||||
+
|
||||
+ /* disable 802.3az EEE */
|
||||
+ phy_write(phydev, 0x1f, 0x0200); /* switch to page 2 */
|
||||
+ phy_write(phydev, 0x18, 0x0000);
|
||||
+ phy_write(phydev, 0x1f, 0x0000); /* switch to page 0 */
|
||||
+ phy_clear_bits_mmd(phydev, 0x7, 0x3c, BIT(1));
|
||||
+
|
||||
+ /* FIXME: This is probably H6 specific */
|
||||
+ phy_set_bits(phydev, 0x13, BIT(12));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ clk = devm_clk_get_optional_enabled(dev, NULL);
|
||||
+ if (IS_ERR(clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(clk),
|
||||
+ "Failed to request clock\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct phy_driver ac200_ephy_driver[] = {
|
||||
+ {
|
||||
+ .phy_id = AC200_EPHY_ID,
|
||||
+ .phy_id_mask = AC200_EPHY_ID_MASK,
|
||||
+ .name = "Allwinner AC200 EPHY",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
+ .config_init = ac200_ephy_config_init,
|
||||
+ .probe = ac200_ephy_probe,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ }
|
||||
+};
|
||||
+module_phy_driver(ac200_ephy_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@gmail.com>");
|
||||
+MODULE_DESCRIPTION("AC200 Ethernet PHY driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+static const struct mdio_device_id __maybe_unused ac200_ephy_phy_tbl[] = {
|
||||
+ { AC200_EPHY_ID, AC200_EPHY_ID_MASK },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(mdio, ac200_ephy_phy_tbl);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
# git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
|
||||
#
|
||||
patches.armbian/Doc-dt-bindings-usb-add-binding-for-DWC3-controller-on-Allwinne.patch
|
||||
patches.armbian/drv-mfd-Add-support-for-AC200.patch
|
||||
patches.armbian/drv-pinctrl-pinctrl-sun50i-a64-disable_strict_mode.patch
|
||||
patches.armbian/drv-net-phy-Add-support-for-AC200-EPHY.patch
|
||||
patches.armbian/drv-rtc-sun6i-support-RTCs-without-external-LOSCs.patch
|
||||
patches.armbian/drv-gpu-drm-gem-dma-Export-with-handle-allocator.patch
|
||||
patches.armbian/drv-gpu-drm-sun4i-Add-GEM-allocator.patch
|
||||
@@ -72,7 +70,6 @@
|
||||
patches.armbian/Bananapro-add-AXP209-regulators.patch
|
||||
patches.armbian/arm-dts-sunxi-h3-h5.dtsi-force-mmc0-bus-width.patch
|
||||
patches.armbian/arm64-dts-sun50i-a64-pine64-enable-wifi-mmc1.patch
|
||||
patches.armbian/arm64-dts-sun50i-h6-Add-AC200-EPHY-related-nodes.patch
|
||||
patches.armbian/arm64-dts-sun50i-a64-sopine-baseboard-Add-i2s2-mmc1.patch
|
||||
patches.armbian/arm64-dts-sun50i-h6-Add-r_uart-uart2-3-pins.patch
|
||||
####### sun50i-h616 #######
|
||||
@@ -163,16 +160,12 @@
|
||||
patches.armbian/Add-dump_reg-and-sunxi-sysinfo-drivers.patch
|
||||
patches.armbian/Add-sunxi-addr-driver-Used-to-fix-uwe5622-bluetooth-MAC-address.patch
|
||||
patches.armbian/net-phy-Support-yt8531c.patch
|
||||
patches.armbian/allwinner-h6-Support-ac200-audio-codec.patch
|
||||
patches.armbian/nvmem-sunxi_sid-add-sunxi_get_soc_chipid-sunxi_get_serial.patch
|
||||
patches.armbian/add-initial-support-for-orangepi3-lts.patch
|
||||
patches.armbian/mmc-host-sunxi-mmc-Fix-H6-emmc.patch
|
||||
patches.armbian/arm64-dts-allwinner-sun50i-h6-Fix-H6-emmc.patch
|
||||
patches.armbian/Rollback-r_rsb-to-r_i2c.patch
|
||||
patches.armbian/arm64-dts-sun50i-h5-nanopi-r1s-h5-add-rtl8153-support.patch
|
||||
patches.armbian/net-usb-r8152-add-LED-configuration-from-OF.patch
|
||||
patches.armbian/arm64-dts-sun50i-h6-orangepi.dtsi-Rollback-r_rsb-to-r_i2c.patch
|
||||
patches.armbian/mfd-sunxi-ac200-fix-error-initialization.patch
|
||||
patches.armbian/arm-dts-sunxi-h3-h5-add_tve.patch
|
||||
patches.armbian/arm-dts-sun8i-h3-fix-thermal-read.patch
|
||||
patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1.patch
|
||||
@@ -181,3 +174,14 @@
|
||||
patches.armbian/arm64-dts-sun50i-h5-enable-power-button-for-orangepi-prime.patch
|
||||
patches.armbian/arm64-dts-sun50i-h5-Add-missing-GPU-trip-point.patch
|
||||
patches.armbian/drivers-devfreq-sun8i-a33-mbus-disable-autorefresh.patch
|
||||
patches.armbian/clk-gate-add-support-for-regmap-based-gates.patch
|
||||
patches.armbian/mfd-Add-support-for-X-Powers-AC200.patch
|
||||
patches.armbian/mfd-Add-support-for-X-Powers-AC200-EPHY-syscon.patch
|
||||
patches.armbian/net-phy-Add-support-for-AC200-EPHY.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-Add-AC200-EPHY-nodes.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-tanix-enable-Ethernet.patch
|
||||
patches.armbian/ASoC-AC200-Initial-driver.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-add-AC200-codec-nodes.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-enable-AC200-codec.patch
|
||||
patches.armbian/add-nodes-for-sunxi-info-addr-dump-reg.patch
|
||||
patches.armbian/add-initial-support-for-orangepi3-lts.patch
|
||||
|
||||
@@ -408,9 +408,7 @@
|
||||
#
|
||||
################################################################################
|
||||
patches.armbian/Doc-dt-bindings-usb-add-binding-for-DWC3-controller-on-Allwinne.patch
|
||||
patches.armbian/drv-mfd-Add-support-for-AC200.patch
|
||||
patches.armbian/drv-pinctrl-pinctrl-sun50i-a64-disable_strict_mode.patch
|
||||
patches.armbian/drv-net-phy-Add-support-for-AC200-EPHY.patch
|
||||
patches.armbian/drv-rtc-sun6i-support-RTCs-without-external-LOSCs.patch
|
||||
patches.armbian/drv-gpu-drm-gem-dma-Export-with-handle-allocator.patch
|
||||
patches.armbian/drv-gpu-drm-sun4i-Add-GEM-allocator.patch
|
||||
@@ -476,7 +474,6 @@
|
||||
patches.armbian/Bananapro-add-AXP209-regulators.patch
|
||||
patches.armbian/arm-dts-sunxi-h3-h5.dtsi-force-mmc0-bus-width.patch
|
||||
patches.armbian/arm64-dts-sun50i-a64-pine64-enable-wifi-mmc1.patch
|
||||
patches.armbian/arm64-dts-sun50i-h6-Add-AC200-EPHY-related-nodes.patch
|
||||
patches.armbian/arm64-dts-sun50i-a64-sopine-baseboard-Add-i2s2-mmc1.patch
|
||||
patches.armbian/arm64-dts-sun50i-h6-Add-r_uart-uart2-3-pins.patch
|
||||
####### sun50i-h616 #######
|
||||
@@ -567,16 +564,12 @@
|
||||
patches.armbian/Add-dump_reg-and-sunxi-sysinfo-drivers.patch
|
||||
patches.armbian/Add-sunxi-addr-driver-Used-to-fix-uwe5622-bluetooth-MAC-address.patch
|
||||
patches.armbian/net-phy-Support-yt8531c.patch
|
||||
patches.armbian/allwinner-h6-Support-ac200-audio-codec.patch
|
||||
patches.armbian/nvmem-sunxi_sid-add-sunxi_get_soc_chipid-sunxi_get_serial.patch
|
||||
patches.armbian/add-initial-support-for-orangepi3-lts.patch
|
||||
patches.armbian/mmc-host-sunxi-mmc-Fix-H6-emmc.patch
|
||||
patches.armbian/arm64-dts-allwinner-sun50i-h6-Fix-H6-emmc.patch
|
||||
patches.armbian/Rollback-r_rsb-to-r_i2c.patch
|
||||
patches.armbian/arm64-dts-sun50i-h5-nanopi-r1s-h5-add-rtl8153-support.patch
|
||||
patches.armbian/net-usb-r8152-add-LED-configuration-from-OF.patch
|
||||
patches.armbian/arm64-dts-sun50i-h6-orangepi.dtsi-Rollback-r_rsb-to-r_i2c.patch
|
||||
patches.armbian/mfd-sunxi-ac200-fix-error-initialization.patch
|
||||
patches.armbian/arm-dts-sunxi-h3-h5-add_tve.patch
|
||||
patches.armbian/arm-dts-sun8i-h3-fix-thermal-read.patch
|
||||
patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1.patch
|
||||
@@ -585,3 +578,14 @@
|
||||
patches.armbian/arm64-dts-sun50i-h5-enable-power-button-for-orangepi-prime.patch
|
||||
patches.armbian/arm64-dts-sun50i-h5-Add-missing-GPU-trip-point.patch
|
||||
patches.armbian/drivers-devfreq-sun8i-a33-mbus-disable-autorefresh.patch
|
||||
patches.armbian/clk-gate-add-support-for-regmap-based-gates.patch
|
||||
patches.armbian/mfd-Add-support-for-X-Powers-AC200.patch
|
||||
patches.armbian/mfd-Add-support-for-X-Powers-AC200-EPHY-syscon.patch
|
||||
patches.armbian/net-phy-Add-support-for-AC200-EPHY.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-Add-AC200-EPHY-nodes.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-tanix-enable-Ethernet.patch
|
||||
patches.armbian/ASoC-AC200-Initial-driver.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-add-AC200-codec-nodes.patch
|
||||
patches.armbian/arm64-dts-allwinner-h6-enable-AC200-codec.patch
|
||||
patches.armbian/add-nodes-for-sunxi-info-addr-dump-reg.patch
|
||||
patches.armbian/add-initial-support-for-orangepi3-lts.patch
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user