Skip to content

Commit 2510bab

Browse files
lunndavem330
authored andcommitted
net: dsa: mv88e6xxx: scratch registers and external MDIO pins
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 <[email protected]> Signed-off-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent aa90294 commit 2510bab

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,15 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
21652165
struct mii_bus *bus;
21662166
int err;
21672167

2168+
if (external) {
2169+
mutex_lock(&chip->reg_lock);
2170+
err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
2171+
mutex_unlock(&chip->reg_lock);
2172+
2173+
if (err)
2174+
return err;
2175+
}
2176+
21682177
bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
21692178
if (!bus)
21702179
return -ENOMEM;

drivers/net/dsa/mv88e6xxx/global2.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@
266266
#define MV88E6352_G2_SCRATCH_GPIO_PCTL5 0x6D
267267
#define MV88E6352_G2_SCRATCH_GPIO_PCTL6 0x6E
268268
#define MV88E6352_G2_SCRATCH_GPIO_PCTL7 0x6F
269+
#define MV88E6352_G2_SCRATCH_CONFIG_DATA0 0x70
270+
#define MV88E6352_G2_SCRATCH_CONFIG_DATA1 0x71
271+
#define MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU BIT(2)
272+
#define MV88E6352_G2_SCRATCH_CONFIG_DATA2 0x72
273+
#define MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK 0x3
269274

270275
#define MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO 0
271276
#define MV88E6352_G2_SCRATCH_GPIO_PCTL_TRIG 1
@@ -325,6 +330,9 @@ extern const struct mv88e6xxx_avb_ops mv88e6390_avb_ops;
325330

326331
extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops;
327332

333+
int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
334+
bool external);
335+
328336
#else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
329337

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

466474
static const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {};
467475

476+
static inline int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
477+
bool external)
478+
{
479+
return -EOPNOTSUPP;
480+
}
481+
468482
#endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
469483

470484
#endif /* _MV88E6XXX_GLOBAL2_H */

drivers/net/dsa/mv88e6xxx/global2_scratch.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,54 @@ const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
238238
.get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
239239
.set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
240240
};
241+
242+
/**
243+
* mv88e6xxx_g2_gpio_set_smi - set gpio muxing for external smi
244+
* @chip: chip private data
245+
* @external: set mux for external smi, or free for gpio usage
246+
*
247+
* Some mv88e6xxx models have GPIO pins that may be configured as
248+
* an external SMI interface, or they may be made free for other
249+
* GPIO uses.
250+
*/
251+
int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
252+
bool external)
253+
{
254+
int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
255+
int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
256+
int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
257+
bool no_cpu;
258+
u8 p0_mode;
259+
int err;
260+
u8 val;
261+
262+
err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
263+
if (err)
264+
return err;
265+
266+
p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;
267+
268+
if (p0_mode == 0x01 || p0_mode == 0x02)
269+
return -EBUSY;
270+
271+
err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
272+
if (err)
273+
return err;
274+
275+
no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);
276+
277+
err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
278+
if (err)
279+
return err;
280+
281+
/* NO_CPU being 0 inverts the meaning of the bit */
282+
if (!no_cpu)
283+
external = !external;
284+
285+
if (external)
286+
val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
287+
else
288+
val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
289+
290+
return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
291+
}

0 commit comments

Comments
 (0)