0001
0002
0003 #include <linux/module.h>
0004 #include <linux/platform_device.h>
0005 #include <linux/regmap.h>
0006
0007 #include <linux/slab.h>
0008 #include <linux/of.h>
0009 #include <linux/io.h>
0010 #include <linux/usb/phy_companion.h>
0011 #include <linux/clk.h>
0012 #include <linux/err.h>
0013 #include <linux/pm_runtime.h>
0014 #include <linux/delay.h>
0015 #include <linux/phy/phy.h>
0016 #include <linux/of_platform.h>
0017
0018 #include <linux/mfd/syscon.h>
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #define DM816X_USB_CTRL_PHYCLKSRC BIT(8)
0036 #define DM816X_USB_CTRL_PHYSLEEP1 BIT(1)
0037 #define DM816X_USB_CTRL_PHYSLEEP0 BIT(0)
0038
0039 #define DM816X_USBPHY_CTRL_TXRISETUNE 1
0040 #define DM816X_USBPHY_CTRL_TXVREFTUNE 0xc
0041 #define DM816X_USBPHY_CTRL_TXPREEMTUNE 0x2
0042
0043 struct dm816x_usb_phy {
0044 struct regmap *syscon;
0045 struct device *dev;
0046 unsigned int instance;
0047 struct clk *refclk;
0048 struct usb_phy phy;
0049 unsigned int usb_ctrl;
0050 unsigned int usbphy_ctrl;
0051 };
0052
0053 static int dm816x_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host)
0054 {
0055 otg->host = host;
0056 if (!host)
0057 otg->state = OTG_STATE_UNDEFINED;
0058
0059 return 0;
0060 }
0061
0062 static int dm816x_usb_phy_set_peripheral(struct usb_otg *otg,
0063 struct usb_gadget *gadget)
0064 {
0065 otg->gadget = gadget;
0066 if (!gadget)
0067 otg->state = OTG_STATE_UNDEFINED;
0068
0069 return 0;
0070 }
0071
0072 static int dm816x_usb_phy_init(struct phy *x)
0073 {
0074 struct dm816x_usb_phy *phy = phy_get_drvdata(x);
0075 unsigned int val;
0076
0077 if (clk_get_rate(phy->refclk) != 24000000)
0078 dev_warn(phy->dev, "nonstandard phy refclk\n");
0079
0080
0081 regmap_update_bits(phy->syscon, phy->usb_ctrl,
0082 DM816X_USB_CTRL_PHYCLKSRC |
0083 DM816X_USB_CTRL_PHYSLEEP1 |
0084 DM816X_USB_CTRL_PHYSLEEP0,
0085 0);
0086 regmap_read(phy->syscon, phy->usb_ctrl, &val);
0087 if ((val & 3) != 0)
0088 dev_info(phy->dev,
0089 "Working dm816x USB_CTRL! (0x%08x)\n",
0090 val);
0091
0092
0093
0094
0095
0096
0097 regmap_read(phy->syscon, phy->usbphy_ctrl, &val);
0098 val |= DM816X_USBPHY_CTRL_TXRISETUNE |
0099 DM816X_USBPHY_CTRL_TXVREFTUNE |
0100 DM816X_USBPHY_CTRL_TXPREEMTUNE;
0101 regmap_write(phy->syscon, phy->usbphy_ctrl, val);
0102
0103 return 0;
0104 }
0105
0106 static const struct phy_ops ops = {
0107 .init = dm816x_usb_phy_init,
0108 .owner = THIS_MODULE,
0109 };
0110
0111 static int __maybe_unused dm816x_usb_phy_runtime_suspend(struct device *dev)
0112 {
0113 struct dm816x_usb_phy *phy = dev_get_drvdata(dev);
0114 unsigned int mask, val;
0115 int error = 0;
0116
0117 mask = BIT(phy->instance);
0118 val = ~BIT(phy->instance);
0119 error = regmap_update_bits(phy->syscon, phy->usb_ctrl,
0120 mask, val);
0121 if (error)
0122 dev_err(phy->dev, "phy%i failed to power off\n",
0123 phy->instance);
0124 clk_disable(phy->refclk);
0125
0126 return 0;
0127 }
0128
0129 static int __maybe_unused dm816x_usb_phy_runtime_resume(struct device *dev)
0130 {
0131 struct dm816x_usb_phy *phy = dev_get_drvdata(dev);
0132 unsigned int mask, val;
0133 int error;
0134
0135 error = clk_enable(phy->refclk);
0136 if (error)
0137 return error;
0138
0139
0140
0141
0142
0143
0144
0145 mask = BIT(phy->instance);
0146 val = BIT(phy->instance);
0147 error = regmap_update_bits(phy->syscon, phy->usb_ctrl,
0148 mask, val);
0149 if (error) {
0150 dev_err(phy->dev, "phy%i failed to power on\n",
0151 phy->instance);
0152 clk_disable(phy->refclk);
0153 return error;
0154 }
0155
0156 return 0;
0157 }
0158
0159 static UNIVERSAL_DEV_PM_OPS(dm816x_usb_phy_pm_ops,
0160 dm816x_usb_phy_runtime_suspend,
0161 dm816x_usb_phy_runtime_resume,
0162 NULL);
0163
0164 #ifdef CONFIG_OF
0165 static const struct of_device_id dm816x_usb_phy_id_table[] = {
0166 {
0167 .compatible = "ti,dm8168-usb-phy",
0168 },
0169 {},
0170 };
0171 MODULE_DEVICE_TABLE(of, dm816x_usb_phy_id_table);
0172 #endif
0173
0174 static int dm816x_usb_phy_probe(struct platform_device *pdev)
0175 {
0176 struct dm816x_usb_phy *phy;
0177 struct resource *res;
0178 struct phy *generic_phy;
0179 struct phy_provider *phy_provider;
0180 struct usb_otg *otg;
0181 const struct of_device_id *of_id;
0182 int error;
0183
0184 of_id = of_match_device(of_match_ptr(dm816x_usb_phy_id_table),
0185 &pdev->dev);
0186 if (!of_id)
0187 return -EINVAL;
0188
0189 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
0190 if (!phy)
0191 return -ENOMEM;
0192
0193 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0194 if (!res)
0195 return -ENOENT;
0196
0197 phy->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
0198 "syscon");
0199 if (IS_ERR(phy->syscon))
0200 return PTR_ERR(phy->syscon);
0201
0202
0203
0204
0205
0206
0207 phy->usb_ctrl = 0x20;
0208 phy->usbphy_ctrl = (res->start & 0xff) + 4;
0209 if (phy->usbphy_ctrl == 0x2c)
0210 phy->instance = 1;
0211
0212 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
0213 if (!otg)
0214 return -ENOMEM;
0215
0216 phy->dev = &pdev->dev;
0217 phy->phy.dev = phy->dev;
0218 phy->phy.label = "dm8168_usb_phy";
0219 phy->phy.otg = otg;
0220 phy->phy.type = USB_PHY_TYPE_USB2;
0221 otg->set_host = dm816x_usb_phy_set_host;
0222 otg->set_peripheral = dm816x_usb_phy_set_peripheral;
0223 otg->usb_phy = &phy->phy;
0224
0225 platform_set_drvdata(pdev, phy);
0226
0227 phy->refclk = devm_clk_get(phy->dev, "refclk");
0228 if (IS_ERR(phy->refclk))
0229 return PTR_ERR(phy->refclk);
0230 error = clk_prepare(phy->refclk);
0231 if (error)
0232 return error;
0233
0234 pm_runtime_enable(phy->dev);
0235 generic_phy = devm_phy_create(phy->dev, NULL, &ops);
0236 if (IS_ERR(generic_phy)) {
0237 error = PTR_ERR(generic_phy);
0238 goto clk_unprepare;
0239 }
0240
0241 phy_set_drvdata(generic_phy, phy);
0242
0243 phy_provider = devm_of_phy_provider_register(phy->dev,
0244 of_phy_simple_xlate);
0245 if (IS_ERR(phy_provider)) {
0246 error = PTR_ERR(phy_provider);
0247 goto clk_unprepare;
0248 }
0249
0250 usb_add_phy_dev(&phy->phy);
0251
0252 return 0;
0253
0254 clk_unprepare:
0255 pm_runtime_disable(phy->dev);
0256 clk_unprepare(phy->refclk);
0257 return error;
0258 }
0259
0260 static int dm816x_usb_phy_remove(struct platform_device *pdev)
0261 {
0262 struct dm816x_usb_phy *phy = platform_get_drvdata(pdev);
0263
0264 usb_remove_phy(&phy->phy);
0265 pm_runtime_disable(phy->dev);
0266 clk_unprepare(phy->refclk);
0267
0268 return 0;
0269 }
0270
0271 static struct platform_driver dm816x_usb_phy_driver = {
0272 .probe = dm816x_usb_phy_probe,
0273 .remove = dm816x_usb_phy_remove,
0274 .driver = {
0275 .name = "dm816x-usb-phy",
0276 .pm = &dm816x_usb_phy_pm_ops,
0277 .of_match_table = of_match_ptr(dm816x_usb_phy_id_table),
0278 },
0279 };
0280
0281 module_platform_driver(dm816x_usb_phy_driver);
0282
0283 MODULE_ALIAS("platform:dm816x_usb");
0284 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
0285 MODULE_DESCRIPTION("dm816x usb phy driver");
0286 MODULE_LICENSE("GPL v2");