aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/isp1760/isp1760-if.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/isp1760/isp1760-if.c')
-rw-r--r--drivers/usb/isp1760/isp1760-if.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/drivers/usb/isp1760/isp1760-if.c b/drivers/usb/isp1760/isp1760-if.c
new file mode 100644
index 0000000000..c96ab459f9
--- /dev/null
+++ b/drivers/usb/isp1760/isp1760-if.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 Linaro, Rui Miguel Silva <rui.silva@linaro.org>
+ *
+ * based on original code from:
+ * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <dm/lists.h>
+#include <linux/bug.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/usb/otg.h>
+#include <log.h>
+#include <usb.h>
+
+#include "isp1760-core.h"
+#include "isp1760-regs.h"
+#include "isp1760-uboot.h"
+
+static int isp1760_of_to_plat(struct udevice *dev)
+{
+ struct isp1760_device *isp = dev_get_plat(dev);
+ unsigned int devflags = 0;
+ u32 bus_width = 0;
+ ofnode dp;
+
+ if (!dev_has_ofnode(dev)) {
+ /* select isp1763 as the default device */
+ devflags = ISP1760_FLAG_ISP1763 | ISP1760_FLAG_BUS_WIDTH_16;
+ pr_err("isp1760: no platform data\n");
+ goto isp_setup;
+ }
+
+ dp = dev_ofnode(dev);
+
+ if (ofnode_device_is_compatible(dp, "nxp,usb-isp1761"))
+ devflags |= ISP1760_FLAG_ISP1761;
+
+ if (ofnode_device_is_compatible(dp, "nxp,usb-isp1763"))
+ devflags |= ISP1760_FLAG_ISP1763;
+
+ /*
+ * Some systems wire up only 8 of 16 data lines or
+ * 16 of the 32 data lines
+ */
+ bus_width = ofnode_read_u32_default(dp, "bus-width", 16);
+ if (bus_width == 16)
+ devflags |= ISP1760_FLAG_BUS_WIDTH_16;
+ else if (bus_width == 8)
+ devflags |= ISP1760_FLAG_BUS_WIDTH_8;
+
+ if (usb_get_dr_mode(dev_ofnode(dev)) == USB_DR_MODE_PERIPHERAL)
+ devflags |= ISP1760_FLAG_PERIPHERAL_EN;
+
+ if (ofnode_read_bool(dp, "analog-oc"))
+ devflags |= ISP1760_FLAG_ANALOG_OC;
+
+ if (ofnode_read_bool(dp, "dack-polarity"))
+ devflags |= ISP1760_FLAG_DACK_POL_HIGH;
+
+ if (ofnode_read_bool(dp, "dreq-polarity"))
+ devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
+
+isp_setup:
+ isp->devflags = devflags;
+ isp->dev = dev;
+
+ return 0;
+}
+
+static int isp1760_plat_probe(struct udevice *dev)
+{
+ struct isp1760_device *isp = dev_get_plat(dev);
+ struct resource mem_res;
+ struct resource irq_res;
+ int ret;
+
+ dev_read_resource(dev, 0, &mem_res);
+ dev_read_resource(dev, 1, &irq_res);
+
+ isp1760_init_kmem_once();
+
+ ret = isp1760_register(isp, &mem_res, irq_res.start, irq_res.flags);
+ if (ret < 0) {
+ isp1760_deinit_kmem_cache();
+ return ret;
+ }
+
+ return 0;
+}
+
+static int isp1760_plat_remove(struct udevice *dev)
+{
+ struct isp1760_device *isp = dev_get_plat(dev);
+
+ isp1760_deinit_kmem_cache();
+ isp1760_unregister(isp);
+
+ return 0;
+}
+
+static const struct udevice_id isp1760_ids[] = {
+ { .compatible = "nxp,usb-isp1760", },
+ { .compatible = "nxp,usb-isp1761", },
+ { .compatible = "nxp,usb-isp1763", },
+ { },
+};
+
+U_BOOT_DRIVER(isp1760) = {
+ .name = "isp1760",
+ .id = UCLASS_USB,
+ .of_match = isp1760_ids,
+ .of_to_plat = isp1760_of_to_plat,
+ .ops = &isp1760_usb_ops,
+ .probe = isp1760_plat_probe,
+ .remove = isp1760_plat_remove,
+ .plat_auto = sizeof(struct isp1760_device),
+ .priv_auto = sizeof(struct isp1760_host_data),
+};