Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: scratch registers and external MDIO pins
Browse files Browse the repository at this point in the history
MV88E6352 and later switches support GPIO control through the "Scratch
& Misc" global2 register. Two of the pins controlled this way on the
mv88e6390 family are the external MDIO pins. They can either by used
as part of the MII interface for port 0, GPIOs, or MDIO. Add a
function to configure them for MDIO, if possible, and call it when
registering the external MDIO bus.

Suggested-by: Russell King <rmk@armlinux.org.uk>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed Feb 22, 2018
1 parent aa90294 commit 2510bab
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,15 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
struct mii_bus *bus;
int err;

if (external) {
mutex_lock(&chip->reg_lock);
err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
mutex_unlock(&chip->reg_lock);

if (err)
return err;
}

bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
if (!bus)
return -ENOMEM;
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/dsa/mv88e6xxx/global2.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@
#define MV88E6352_G2_SCRATCH_GPIO_PCTL5 0x6D
#define MV88E6352_G2_SCRATCH_GPIO_PCTL6 0x6E
#define MV88E6352_G2_SCRATCH_GPIO_PCTL7 0x6F
#define MV88E6352_G2_SCRATCH_CONFIG_DATA0 0x70
#define MV88E6352_G2_SCRATCH_CONFIG_DATA1 0x71
#define MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU BIT(2)
#define MV88E6352_G2_SCRATCH_CONFIG_DATA2 0x72
#define MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK 0x3

#define MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO 0
#define MV88E6352_G2_SCRATCH_GPIO_PCTL_TRIG 1
Expand Down Expand Up @@ -325,6 +330,9 @@ extern const struct mv88e6xxx_avb_ops mv88e6390_avb_ops;

extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops;

int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
bool external);

#else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */

static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
Expand Down Expand Up @@ -465,6 +473,12 @@ static const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {};

static const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {};

static inline int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
bool external)
{
return -EOPNOTSUPP;
}

#endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */

#endif /* _MV88E6XXX_GLOBAL2_H */
51 changes: 51 additions & 0 deletions drivers/net/dsa/mv88e6xxx/global2_scratch.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,54 @@ const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
.get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
.set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
};

/**
* mv88e6xxx_g2_gpio_set_smi - set gpio muxing for external smi
* @chip: chip private data
* @external: set mux for external smi, or free for gpio usage
*
* Some mv88e6xxx models have GPIO pins that may be configured as
* an external SMI interface, or they may be made free for other
* GPIO uses.
*/
int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
bool external)
{
int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
bool no_cpu;
u8 p0_mode;
int err;
u8 val;

err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
if (err)
return err;

p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;

if (p0_mode == 0x01 || p0_mode == 0x02)
return -EBUSY;

err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
if (err)
return err;

no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);

err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
if (err)
return err;

/* NO_CPU being 0 inverts the meaning of the bit */
if (!no_cpu)
external = !external;

if (external)
val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
else
val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;

return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
}

0 comments on commit 2510bab

Please sign in to comment.