From 360c181dd747f033cb61f83915ce277c6497720f Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Wed, 22 Sep 2021 19:16:32 -0700 Subject: [PATCH] kernel: backport GPIO LED patch for MT7530 This allows to specify and control switch LEDs on devices using mt7530 (typically mediatek and ramips targets). Normally these LED GPIOs are 0, 3, 6, 9, and 12. wan/lan assignment is per device. GPIO 9 is normally inverted. so GPIO_ACTIVE_HIGH instead of GPIO_ACTIVE_LOW. Tested on Linksys E7350. Refreshed all patches. Signed-off-by: Rosen Penev --- ...-mt7530-MT7530-optional-GPIO-support.patch | 181 ++++++++++++++++++ ...-mt7530-Add-support-for-EEE-features.patch | 6 +- 2 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch 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 00000000000..6931500c447 --- /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 +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 +Reviewed-by: Linus Walleij +Reviewed-by: Andrew Lunn +Signed-off-by: Jakub Kicinski +--- + 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 + #include + #include ++#include + #include + + #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 ae4270391d5..4952abdb1ed 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 --- 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 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 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, -- 2.30.2