diff options
2 files changed, 184 insertions, 3 deletions
diff --git a/target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch b/target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch new file mode 100644 index 0000000000..6931500c44 --- /dev/null +++ b/target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch @@ -0,0 +1,181 @@ +From 429a0edeefd88cbfca5c417dfb8561047bb50769 Mon Sep 17 00:00:00 2001 +From: DENG Qingfang <dqfext@gmail.com> +Date: Mon, 25 Jan 2021 12:43:22 +0800 +Subject: [PATCH] net: dsa: mt7530: MT7530 optional GPIO support + +MT7530's LED controller can drive up to 15 LED/GPIOs. + +Add support for GPIO control and allow users to use its GPIOs by +setting gpio-controller property in device tree. + +Signed-off-by: DENG Qingfang <dqfext@gmail.com> +Reviewed-by: Linus Walleij <linus.walleij@linaro.org> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + drivers/net/dsa/mt7530.c | 110 +++++++++++++++++++++++++++++++++++++++ + drivers/net/dsa/mt7530.h | 20 +++++++ + 2 files changed, 130 insertions(+) + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -18,6 +18,7 @@ + #include <linux/regulator/consumer.h> + #include <linux/reset.h> + #include <linux/gpio/consumer.h> ++#include <linux/gpio/driver.h> + #include <net/dsa.h> + + #include "mt7530.h" +@@ -1540,6 +1541,109 @@ mtk_get_tag_protocol(struct dsa_switch * + } + } + ++static inline u32 ++mt7530_gpio_to_bit(unsigned int offset) ++{ ++ /* Map GPIO offset to register bit ++ * [ 2: 0] port 0 LED 0..2 as GPIO 0..2 ++ * [ 6: 4] port 1 LED 0..2 as GPIO 3..5 ++ * [10: 8] port 2 LED 0..2 as GPIO 6..8 ++ * [14:12] port 3 LED 0..2 as GPIO 9..11 ++ * [18:16] port 4 LED 0..2 as GPIO 12..14 ++ */ ++ return BIT(offset + offset / 3); ++} ++ ++static int ++mt7530_gpio_get(struct gpio_chip *gc, unsigned int offset) ++{ ++ struct mt7530_priv *priv = gpiochip_get_data(gc); ++ u32 bit = mt7530_gpio_to_bit(offset); ++ ++ return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit); ++} ++ ++static void ++mt7530_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) ++{ ++ struct mt7530_priv *priv = gpiochip_get_data(gc); ++ u32 bit = mt7530_gpio_to_bit(offset); ++ ++ if (value) ++ mt7530_set(priv, MT7530_LED_GPIO_DATA, bit); ++ else ++ mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit); ++} ++ ++static int ++mt7530_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) ++{ ++ struct mt7530_priv *priv = gpiochip_get_data(gc); ++ u32 bit = mt7530_gpio_to_bit(offset); ++ ++ return (mt7530_read(priv, MT7530_LED_GPIO_DIR) & bit) ? ++ GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; ++} ++ ++static int ++mt7530_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) ++{ ++ struct mt7530_priv *priv = gpiochip_get_data(gc); ++ u32 bit = mt7530_gpio_to_bit(offset); ++ ++ mt7530_clear(priv, MT7530_LED_GPIO_OE, bit); ++ mt7530_clear(priv, MT7530_LED_GPIO_DIR, bit); ++ ++ return 0; ++} ++ ++static int ++mt7530_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value) ++{ ++ struct mt7530_priv *priv = gpiochip_get_data(gc); ++ u32 bit = mt7530_gpio_to_bit(offset); ++ ++ mt7530_set(priv, MT7530_LED_GPIO_DIR, bit); ++ ++ if (value) ++ mt7530_set(priv, MT7530_LED_GPIO_DATA, bit); ++ else ++ mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit); ++ ++ mt7530_set(priv, MT7530_LED_GPIO_OE, bit); ++ ++ return 0; ++} ++ ++static int ++mt7530_setup_gpio(struct mt7530_priv *priv) ++{ ++ struct device *dev = priv->dev; ++ struct gpio_chip *gc; ++ ++ gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); ++ if (!gc) ++ return -ENOMEM; ++ ++ mt7530_write(priv, MT7530_LED_GPIO_OE, 0); ++ mt7530_write(priv, MT7530_LED_GPIO_DIR, 0); ++ mt7530_write(priv, MT7530_LED_IO_MODE, 0); ++ ++ gc->label = "mt7530"; ++ gc->parent = dev; ++ gc->owner = THIS_MODULE; ++ gc->get_direction = mt7530_gpio_get_direction; ++ gc->direction_input = mt7530_gpio_direction_input; ++ gc->direction_output = mt7530_gpio_direction_output; ++ gc->get = mt7530_gpio_get; ++ gc->set = mt7530_gpio_set; ++ gc->base = -1; ++ gc->ngpio = 15; ++ gc->can_sleep = true; ++ ++ return devm_gpiochip_add_data(dev, gc, priv); ++} ++ + static int + mt7530_setup(struct dsa_switch *ds) + { +@@ -1681,6 +1785,12 @@ mt7530_setup(struct dsa_switch *ds) + } + } + ++ if (of_property_read_bool(priv->dev->of_node, "gpio-controller")) { ++ ret = mt7530_setup_gpio(priv); ++ if (ret) ++ return ret; ++ } ++ + mt7530_setup_port5(ds, interface); + + /* Flush the FDB table */ +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -529,6 +529,26 @@ enum mt7531_clk_skew { + #define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16) + #define MT7531_EXT_P_MDIO_12 (2 << 16) + ++/* Registers for LED GPIO control (MT7530 only) ++ * All registers follow this pattern: ++ * [ 2: 0] port 0 ++ * [ 6: 4] port 1 ++ * [10: 8] port 2 ++ * [14:12] port 3 ++ * [18:16] port 4 ++ */ ++ ++/* LED enable, 0: Disable, 1: Enable (Default) */ ++#define MT7530_LED_EN 0x7d00 ++/* LED mode, 0: GPIO mode, 1: PHY mode (Default) */ ++#define MT7530_LED_IO_MODE 0x7d04 ++/* GPIO direction, 0: Input, 1: Output */ ++#define MT7530_LED_GPIO_DIR 0x7d10 ++/* GPIO output enable, 0: Disable, 1: Enable */ ++#define MT7530_LED_GPIO_OE 0x7d14 ++/* GPIO value, 0: Low, 1: High */ ++#define MT7530_LED_GPIO_DATA 0x7d18 ++ + #define MT7530_CREV 0x7ffc + #define CHIP_NAME_SHIFT 16 + #define MT7530_ID 0x7530 diff --git a/target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch b/target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch index ae4270391d..4952abdb1e 100644 --- a/target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch +++ b/target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2267,6 +2267,17 @@ static void mt753x_phylink_mac_link_up(s +@@ -2377,6 +2377,17 @@ static void mt753x_phylink_mac_link_up(s mcr |= PMCR_RX_FC_EN; } @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> mt7530_set(priv, MT7530_PMCR_P(port), mcr); } -@@ -2497,6 +2508,36 @@ mt753x_phy_write(struct dsa_switch *ds, +@@ -2607,6 +2618,36 @@ mt753x_phy_write(struct dsa_switch *ds, return priv->info->phy_write(ds, port, regnum, val); } @@ -72,7 +72,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> static const struct dsa_switch_ops mt7530_switch_ops = { .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, -@@ -2525,6 +2566,8 @@ static const struct dsa_switch_ops mt753 +@@ -2635,6 +2676,8 @@ static const struct dsa_switch_ops mt753 .phylink_mac_an_restart = mt753x_phylink_mac_an_restart, .phylink_mac_link_down = mt753x_phylink_mac_link_down, .phylink_mac_link_up = mt753x_phylink_mac_link_up, |