mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
Merge branch 'net-phy-marvell-usb-to-mdio-controller'
Tobias Waldekranz says: ==================== net: phy: marvell usb to mdio controller Support for an MDIO controller present on development boards for Marvell switches from the Link Street (88E6xxx) family. v3->v4: - Remove unnecessary dependency on OF_MDIO. v2->v3: - Rename driver smi2usb -> mvusb. - Clean up unused USB references. v1->v2: - Reverse christmas tree ordering of local variables. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
6a864730ae
65
Documentation/devicetree/bindings/net/marvell,mvusb.yaml
Normal file
65
Documentation/devicetree/bindings/net/marvell,mvusb.yaml
Normal file
@ -0,0 +1,65 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/marvell,mvusb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell USB to MDIO Controller
|
||||
|
||||
maintainers:
|
||||
- Tobias Waldekranz <tobias@waldekranz.com>
|
||||
|
||||
description: |+
|
||||
This controller is mounted on development boards for Marvell's Link Street
|
||||
family of Ethernet switches. It allows you to configure the switch's registers
|
||||
using the standard MDIO interface.
|
||||
|
||||
Since the device is connected over USB, there is no strict requirement of
|
||||
having a device tree representation of the device. But in order to use it with
|
||||
the mv88e6xxx driver, you need a device tree node in which to place the switch
|
||||
definition.
|
||||
|
||||
allOf:
|
||||
- $ref: "mdio.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: usb1286,1fa4
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: The USB port number on the host controller
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
examples:
|
||||
- |
|
||||
/* USB host controller */
|
||||
&usb1 {
|
||||
mvusb: mdio@1 {
|
||||
compatible = "usb1286,1fa4";
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
/* MV88E6390X devboard */
|
||||
&mvusb {
|
||||
switch@0 {
|
||||
compatible = "marvell,mv88e6190";
|
||||
status = "ok";
|
||||
reg = <0x0>;
|
||||
|
||||
ports {
|
||||
/* Port definitions */
|
||||
};
|
||||
|
||||
mdio {
|
||||
/* PHY definitions */
|
||||
};
|
||||
};
|
||||
};
|
@ -10106,6 +10106,13 @@ M: Nicolas Pitre <nico@fluxnic.net>
|
||||
S: Odd Fixes
|
||||
F: drivers/mmc/host/mvsdio.*
|
||||
|
||||
MARVELL USB MDIO CONTROLLER DRIVER
|
||||
M: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/phy/mdio-mvusb.c
|
||||
F: Documentation/devicetree/bindings/net/marvell,mvusb.yaml
|
||||
|
||||
MARVELL XENON MMC/SD/SDIO HOST CONTROLLER DRIVER
|
||||
M: Hu Ziji <huziji@marvell.com>
|
||||
L: linux-mmc@vger.kernel.org
|
||||
|
@ -179,6 +179,13 @@ config MDIO_MSCC_MIIM
|
||||
This driver supports the MIIM (MDIO) interface found in the network
|
||||
switches of the Microsemi SoCs
|
||||
|
||||
config MDIO_MVUSB
|
||||
tristate "Marvell USB to MDIO Adapter"
|
||||
depends on USB
|
||||
help
|
||||
A USB to MDIO converter present on development boards for
|
||||
Marvell's Link Street family of Ethernet switches.
|
||||
|
||||
config MDIO_OCTEON
|
||||
tristate "Octeon and some ThunderX SOCs MDIO buses"
|
||||
depends on (64BIT && OF_MDIO) || COMPILE_TEST
|
||||
|
@ -40,6 +40,7 @@ obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o
|
||||
obj-$(CONFIG_MDIO_IPQ8064) += mdio-ipq8064.o
|
||||
obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
|
||||
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
|
||||
obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
|
||||
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
|
||||
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
|
||||
obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
|
||||
|
120
drivers/net/phy/mdio-mvusb.c
Normal file
120
drivers/net/phy/mdio-mvusb.c
Normal file
@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#define USB_MARVELL_VID 0x1286
|
||||
|
||||
static const struct usb_device_id mvusb_mdio_table[] = {
|
||||
{ USB_DEVICE(USB_MARVELL_VID, 0x1fa4) },
|
||||
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, mvusb_mdio_table);
|
||||
|
||||
enum {
|
||||
MVUSB_CMD_PREAMBLE0,
|
||||
MVUSB_CMD_PREAMBLE1,
|
||||
MVUSB_CMD_ADDR,
|
||||
MVUSB_CMD_VAL,
|
||||
};
|
||||
|
||||
struct mvusb_mdio {
|
||||
struct usb_device *udev;
|
||||
struct mii_bus *mdio;
|
||||
|
||||
__le16 buf[4];
|
||||
};
|
||||
|
||||
static int mvusb_mdio_read(struct mii_bus *mdio, int dev, int reg)
|
||||
{
|
||||
struct mvusb_mdio *mvusb = mdio->priv;
|
||||
int err, alen;
|
||||
|
||||
if (dev & MII_ADDR_C45)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mvusb->buf[MVUSB_CMD_ADDR] = cpu_to_le16(0xa400 | (dev << 5) | reg);
|
||||
|
||||
err = usb_bulk_msg(mvusb->udev, usb_sndbulkpipe(mvusb->udev, 2),
|
||||
mvusb->buf, 6, &alen, 100);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = usb_bulk_msg(mvusb->udev, usb_rcvbulkpipe(mvusb->udev, 6),
|
||||
&mvusb->buf[MVUSB_CMD_VAL], 2, &alen, 100);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return le16_to_cpu(mvusb->buf[MVUSB_CMD_VAL]);
|
||||
}
|
||||
|
||||
static int mvusb_mdio_write(struct mii_bus *mdio, int dev, int reg, u16 val)
|
||||
{
|
||||
struct mvusb_mdio *mvusb = mdio->priv;
|
||||
int alen;
|
||||
|
||||
if (dev & MII_ADDR_C45)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mvusb->buf[MVUSB_CMD_ADDR] = cpu_to_le16(0x8000 | (dev << 5) | reg);
|
||||
mvusb->buf[MVUSB_CMD_VAL] = cpu_to_le16(val);
|
||||
|
||||
return usb_bulk_msg(mvusb->udev, usb_sndbulkpipe(mvusb->udev, 2),
|
||||
mvusb->buf, 8, &alen, 100);
|
||||
}
|
||||
|
||||
static int mvusb_mdio_probe(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct device *dev = &interface->dev;
|
||||
struct mvusb_mdio *mvusb;
|
||||
struct mii_bus *mdio;
|
||||
|
||||
mdio = devm_mdiobus_alloc_size(dev, sizeof(*mvusb));
|
||||
if (!mdio)
|
||||
return -ENOMEM;
|
||||
|
||||
mvusb = mdio->priv;
|
||||
mvusb->mdio = mdio;
|
||||
mvusb->udev = usb_get_dev(interface_to_usbdev(interface));
|
||||
|
||||
/* Reversed from USB PCAPs, no idea what these mean. */
|
||||
mvusb->buf[MVUSB_CMD_PREAMBLE0] = cpu_to_le16(0xe800);
|
||||
mvusb->buf[MVUSB_CMD_PREAMBLE1] = cpu_to_le16(0x0001);
|
||||
|
||||
snprintf(mdio->id, MII_BUS_ID_SIZE, "mvusb-%s", dev_name(dev));
|
||||
mdio->name = mdio->id;
|
||||
mdio->parent = dev;
|
||||
mdio->read = mvusb_mdio_read;
|
||||
mdio->write = mvusb_mdio_write;
|
||||
|
||||
usb_set_intfdata(interface, mvusb);
|
||||
return of_mdiobus_register(mdio, dev->of_node);
|
||||
}
|
||||
|
||||
static void mvusb_mdio_disconnect(struct usb_interface *interface)
|
||||
{
|
||||
struct mvusb_mdio *mvusb = usb_get_intfdata(interface);
|
||||
struct usb_device *udev = mvusb->udev;
|
||||
|
||||
mdiobus_unregister(mvusb->mdio);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
usb_put_dev(udev);
|
||||
}
|
||||
|
||||
static struct usb_driver mvusb_mdio_driver = {
|
||||
.name = "mvusb_mdio",
|
||||
.id_table = mvusb_mdio_table,
|
||||
.probe = mvusb_mdio_probe,
|
||||
.disconnect = mvusb_mdio_disconnect,
|
||||
};
|
||||
|
||||
module_usb_driver(mvusb_mdio_driver);
|
||||
|
||||
MODULE_AUTHOR("Tobias Waldekranz <tobias@waldekranz.com>");
|
||||
MODULE_DESCRIPTION("Marvell USB MDIO Adapter");
|
||||
MODULE_LICENSE("GPL");
|
Loading…
Reference in New Issue
Block a user