Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

DENG Qingfang and committed by
Jakub Kicinski
429a0ede 974d5ba6

+130
+110
drivers/net/dsa/mt7530.c
··· 18 18 #include <linux/regulator/consumer.h> 19 19 #include <linux/reset.h> 20 20 #include <linux/gpio/consumer.h> 21 + #include <linux/gpio/driver.h> 21 22 #include <net/dsa.h> 22 23 23 24 #include "mt7530.h" ··· 1623 1622 } 1624 1623 } 1625 1624 1625 + static inline u32 1626 + mt7530_gpio_to_bit(unsigned int offset) 1627 + { 1628 + /* Map GPIO offset to register bit 1629 + * [ 2: 0] port 0 LED 0..2 as GPIO 0..2 1630 + * [ 6: 4] port 1 LED 0..2 as GPIO 3..5 1631 + * [10: 8] port 2 LED 0..2 as GPIO 6..8 1632 + * [14:12] port 3 LED 0..2 as GPIO 9..11 1633 + * [18:16] port 4 LED 0..2 as GPIO 12..14 1634 + */ 1635 + return BIT(offset + offset / 3); 1636 + } 1637 + 1638 + static int 1639 + mt7530_gpio_get(struct gpio_chip *gc, unsigned int offset) 1640 + { 1641 + struct mt7530_priv *priv = gpiochip_get_data(gc); 1642 + u32 bit = mt7530_gpio_to_bit(offset); 1643 + 1644 + return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit); 1645 + } 1646 + 1647 + static void 1648 + mt7530_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) 1649 + { 1650 + struct mt7530_priv *priv = gpiochip_get_data(gc); 1651 + u32 bit = mt7530_gpio_to_bit(offset); 1652 + 1653 + if (value) 1654 + mt7530_set(priv, MT7530_LED_GPIO_DATA, bit); 1655 + else 1656 + mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit); 1657 + } 1658 + 1659 + static int 1660 + mt7530_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) 1661 + { 1662 + struct mt7530_priv *priv = gpiochip_get_data(gc); 1663 + u32 bit = mt7530_gpio_to_bit(offset); 1664 + 1665 + return (mt7530_read(priv, MT7530_LED_GPIO_DIR) & bit) ? 1666 + GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; 1667 + } 1668 + 1669 + static int 1670 + mt7530_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) 1671 + { 1672 + struct mt7530_priv *priv = gpiochip_get_data(gc); 1673 + u32 bit = mt7530_gpio_to_bit(offset); 1674 + 1675 + mt7530_clear(priv, MT7530_LED_GPIO_OE, bit); 1676 + mt7530_clear(priv, MT7530_LED_GPIO_DIR, bit); 1677 + 1678 + return 0; 1679 + } 1680 + 1681 + static int 1682 + mt7530_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value) 1683 + { 1684 + struct mt7530_priv *priv = gpiochip_get_data(gc); 1685 + u32 bit = mt7530_gpio_to_bit(offset); 1686 + 1687 + mt7530_set(priv, MT7530_LED_GPIO_DIR, bit); 1688 + 1689 + if (value) 1690 + mt7530_set(priv, MT7530_LED_GPIO_DATA, bit); 1691 + else 1692 + mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit); 1693 + 1694 + mt7530_set(priv, MT7530_LED_GPIO_OE, bit); 1695 + 1696 + return 0; 1697 + } 1698 + 1699 + static int 1700 + mt7530_setup_gpio(struct mt7530_priv *priv) 1701 + { 1702 + struct device *dev = priv->dev; 1703 + struct gpio_chip *gc; 1704 + 1705 + gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); 1706 + if (!gc) 1707 + return -ENOMEM; 1708 + 1709 + mt7530_write(priv, MT7530_LED_GPIO_OE, 0); 1710 + mt7530_write(priv, MT7530_LED_GPIO_DIR, 0); 1711 + mt7530_write(priv, MT7530_LED_IO_MODE, 0); 1712 + 1713 + gc->label = "mt7530"; 1714 + gc->parent = dev; 1715 + gc->owner = THIS_MODULE; 1716 + gc->get_direction = mt7530_gpio_get_direction; 1717 + gc->direction_input = mt7530_gpio_direction_input; 1718 + gc->direction_output = mt7530_gpio_direction_output; 1719 + gc->get = mt7530_gpio_get; 1720 + gc->set = mt7530_gpio_set; 1721 + gc->base = -1; 1722 + gc->ngpio = 15; 1723 + gc->can_sleep = true; 1724 + 1725 + return devm_gpiochip_add_data(dev, gc, priv); 1726 + } 1727 + 1626 1728 static int 1627 1729 mt7530_setup(struct dsa_switch *ds) 1628 1730 { ··· 1865 1761 of_node_put(phy_node); 1866 1762 break; 1867 1763 } 1764 + } 1765 + 1766 + if (of_property_read_bool(priv->dev->of_node, "gpio-controller")) { 1767 + ret = mt7530_setup_gpio(priv); 1768 + if (ret) 1769 + return ret; 1868 1770 } 1869 1771 1870 1772 mt7530_setup_port5(ds, interface);
+20
drivers/net/dsa/mt7530.h
··· 554 554 #define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16) 555 555 #define MT7531_EXT_P_MDIO_12 (2 << 16) 556 556 557 + /* Registers for LED GPIO control (MT7530 only) 558 + * All registers follow this pattern: 559 + * [ 2: 0] port 0 560 + * [ 6: 4] port 1 561 + * [10: 8] port 2 562 + * [14:12] port 3 563 + * [18:16] port 4 564 + */ 565 + 566 + /* LED enable, 0: Disable, 1: Enable (Default) */ 567 + #define MT7530_LED_EN 0x7d00 568 + /* LED mode, 0: GPIO mode, 1: PHY mode (Default) */ 569 + #define MT7530_LED_IO_MODE 0x7d04 570 + /* GPIO direction, 0: Input, 1: Output */ 571 + #define MT7530_LED_GPIO_DIR 0x7d10 572 + /* GPIO output enable, 0: Disable, 1: Enable */ 573 + #define MT7530_LED_GPIO_OE 0x7d14 574 + /* GPIO value, 0: Low, 1: High */ 575 + #define MT7530_LED_GPIO_DATA 0x7d18 576 + 557 577 #define MT7530_CREV 0x7ffc 558 578 #define CHIP_NAME_SHIFT 16 559 579 #define MT7530_ID 0x7530