blob: 54246b49d5fef2cdeb3d979773c938b973dca79d [file] [log] [blame]
Rui Miguel Silva08ee3772022-06-29 11:06:15 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2021 Linaro, Rui Miguel Silva <rui.silva@linaro.org>
4 *
5 * based on original code from:
6 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
7 */
8
Rui Miguel Silva08ee3772022-06-29 11:06:15 +01009#include <dm.h>
10#include <dm/device-internal.h>
11#include <dm/device_compat.h>
12#include <dm/devres.h>
13#include <dm/lists.h>
14#include <linux/bug.h>
15#include <linux/io.h>
16#include <linux/kernel.h>
17#include <linux/usb/otg.h>
18#include <log.h>
19#include <usb.h>
20
21#include "isp1760-core.h"
22#include "isp1760-regs.h"
23#include "isp1760-uboot.h"
24
25static int isp1760_of_to_plat(struct udevice *dev)
26{
27 struct isp1760_device *isp = dev_get_plat(dev);
28 unsigned int devflags = 0;
29 u32 bus_width = 0;
30 ofnode dp;
31
32 if (!dev_has_ofnode(dev)) {
33 /* select isp1763 as the default device */
34 devflags = ISP1760_FLAG_ISP1763 | ISP1760_FLAG_BUS_WIDTH_16;
35 pr_err("isp1760: no platform data\n");
36 goto isp_setup;
37 }
38
39 dp = dev_ofnode(dev);
40
41 if (ofnode_device_is_compatible(dp, "nxp,usb-isp1761"))
42 devflags |= ISP1760_FLAG_ISP1761;
43
44 if (ofnode_device_is_compatible(dp, "nxp,usb-isp1763"))
45 devflags |= ISP1760_FLAG_ISP1763;
46
47 /*
48 * Some systems wire up only 8 of 16 data lines or
49 * 16 of the 32 data lines
50 */
51 bus_width = ofnode_read_u32_default(dp, "bus-width", 16);
52 if (bus_width == 16)
53 devflags |= ISP1760_FLAG_BUS_WIDTH_16;
54 else if (bus_width == 8)
55 devflags |= ISP1760_FLAG_BUS_WIDTH_8;
56
57 if (usb_get_dr_mode(dev_ofnode(dev)) == USB_DR_MODE_PERIPHERAL)
58 devflags |= ISP1760_FLAG_PERIPHERAL_EN;
59
60 if (ofnode_read_bool(dp, "analog-oc"))
61 devflags |= ISP1760_FLAG_ANALOG_OC;
62
63 if (ofnode_read_bool(dp, "dack-polarity"))
64 devflags |= ISP1760_FLAG_DACK_POL_HIGH;
65
66 if (ofnode_read_bool(dp, "dreq-polarity"))
67 devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
68
69isp_setup:
70 isp->devflags = devflags;
71 isp->dev = dev;
72
73 return 0;
74}
75
76static int isp1760_plat_probe(struct udevice *dev)
77{
78 struct isp1760_device *isp = dev_get_plat(dev);
79 struct resource mem_res;
80 struct resource irq_res;
81 int ret;
82
83 dev_read_resource(dev, 0, &mem_res);
84 dev_read_resource(dev, 1, &irq_res);
85
86 isp1760_init_kmem_once();
87
88 ret = isp1760_register(isp, &mem_res, irq_res.start, irq_res.flags);
89 if (ret < 0) {
90 isp1760_deinit_kmem_cache();
91 return ret;
92 }
93
94 return 0;
95}
96
97static int isp1760_plat_remove(struct udevice *dev)
98{
99 struct isp1760_device *isp = dev_get_plat(dev);
100
101 isp1760_deinit_kmem_cache();
102 isp1760_unregister(isp);
103
104 return 0;
105}
106
107static const struct udevice_id isp1760_ids[] = {
108 { .compatible = "nxp,usb-isp1760", },
109 { .compatible = "nxp,usb-isp1761", },
110 { .compatible = "nxp,usb-isp1763", },
111 { },
112};
113
114U_BOOT_DRIVER(isp1760) = {
115 .name = "isp1760",
116 .id = UCLASS_USB,
117 .of_match = isp1760_ids,
118 .of_to_plat = isp1760_of_to_plat,
119 .ops = &isp1760_usb_ops,
120 .probe = isp1760_plat_probe,
121 .remove = isp1760_plat_remove,
122 .plat_auto = sizeof(struct isp1760_device),
123 .priv_auto = sizeof(struct isp1760_host_data),
124};