1 #include <linux/module.h> 2 #include <linux/platform_device.h> 3 #include <linux/err.h> 4 #include <linux/of.h> 5 #include <linux/io.h> 6 7 struct phy_control { 8 void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on); 9 void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on); 10 }; 11 12 struct am335x_control_usb { 13 struct device *dev; 14 void __iomem *phy_reg; 15 void __iomem *wkup; 16 spinlock_t lock; 17 struct phy_control phy_ctrl; 18 }; 19 20 #define AM335X_USB0_CTRL 0x0 21 #define AM335X_USB1_CTRL 0x8 22 #define AM335x_USB_WKUP 0x0 23 24 #define USBPHY_CM_PWRDN (1 << 0) 25 #define USBPHY_OTG_PWRDN (1 << 1) 26 #define USBPHY_OTGVDET_EN (1 << 19) 27 #define USBPHY_OTGSESSEND_EN (1 << 20) 28 29 #define AM335X_PHY0_WK_EN (1 << 0) 30 #define AM335X_PHY1_WK_EN (1 << 8) 31 32 static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on) 33 { 34 struct am335x_control_usb *usb_ctrl; 35 u32 val; 36 u32 reg; 37 38 usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl); 39 40 switch (id) { 41 case 0: 42 reg = AM335X_PHY0_WK_EN; 43 break; 44 case 1: 45 reg = AM335X_PHY1_WK_EN; 46 break; 47 default: 48 WARN_ON(1); 49 return; 50 } 51 52 spin_lock(&usb_ctrl->lock); 53 val = readl(usb_ctrl->wkup); 54 55 if (on) 56 val |= reg; 57 else 58 val &= ~reg; 59 60 writel(val, usb_ctrl->wkup); 61 spin_unlock(&usb_ctrl->lock); 62 } 63 64 static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) 65 { 66 struct am335x_control_usb *usb_ctrl; 67 u32 val; 68 u32 reg; 69 70 usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl); 71 72 switch (id) { 73 case 0: 74 reg = AM335X_USB0_CTRL; 75 break; 76 case 1: 77 reg = AM335X_USB1_CTRL; 78 break; 79 default: 80 WARN_ON(1); 81 return; 82 } 83 84 val = readl(usb_ctrl->phy_reg + reg); 85 if (on) { 86 val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); 87 val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; 88 } else { 89 val |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; 90 } 91 92 writel(val, usb_ctrl->phy_reg + reg); 93 } 94 95 static const struct phy_control ctrl_am335x = { 96 .phy_power = am335x_phy_power, 97 .phy_wkup = am335x_phy_wkup, 98 }; 99 100 static const struct of_device_id omap_control_usb_id_table[] = { 101 { .compatible = "ti,am335x-usb-ctrl-module", .data = &ctrl_am335x }, 102 {} 103 }; 104 MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); 105 106 static struct platform_driver am335x_control_driver; 107 static int match(struct device *dev, void *data) 108 { 109 struct device_node *node = (struct device_node *)data; 110 return dev->of_node == node && 111 dev->driver == &am335x_control_driver.driver; 112 } 113 114 struct phy_control *am335x_get_phy_control(struct device *dev) 115 { 116 struct device_node *node; 117 struct am335x_control_usb *ctrl_usb; 118 119 node = of_parse_phandle(dev->of_node, "ti,ctrl_mod", 0); 120 if (!node) 121 return NULL; 122 123 dev = bus_find_device(&platform_bus_type, NULL, node, match); 124 ctrl_usb = dev_get_drvdata(dev); 125 if (!ctrl_usb) 126 return NULL; 127 return &ctrl_usb->phy_ctrl; 128 } 129 EXPORT_SYMBOL_GPL(am335x_get_phy_control); 130 131 static int am335x_control_usb_probe(struct platform_device *pdev) 132 { 133 struct resource *res; 134 struct am335x_control_usb *ctrl_usb; 135 const struct of_device_id *of_id; 136 const struct phy_control *phy_ctrl; 137 138 of_id = of_match_node(omap_control_usb_id_table, pdev->dev.of_node); 139 if (!of_id) 140 return -EINVAL; 141 142 phy_ctrl = of_id->data; 143 144 ctrl_usb = devm_kzalloc(&pdev->dev, sizeof(*ctrl_usb), GFP_KERNEL); 145 if (!ctrl_usb) { 146 dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); 147 return -ENOMEM; 148 } 149 150 ctrl_usb->dev = &pdev->dev; 151 152 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); 153 ctrl_usb->phy_reg = devm_ioremap_resource(&pdev->dev, res); 154 if (IS_ERR(ctrl_usb->phy_reg)) 155 return PTR_ERR(ctrl_usb->phy_reg); 156 157 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wakeup"); 158 ctrl_usb->wkup = devm_ioremap_resource(&pdev->dev, res); 159 if (IS_ERR(ctrl_usb->wkup)) 160 return PTR_ERR(ctrl_usb->wkup); 161 162 spin_lock_init(&ctrl_usb->lock); 163 ctrl_usb->phy_ctrl = *phy_ctrl; 164 165 dev_set_drvdata(ctrl_usb->dev, ctrl_usb); 166 return 0; 167 } 168 169 static struct platform_driver am335x_control_driver = { 170 .probe = am335x_control_usb_probe, 171 .driver = { 172 .name = "am335x-control-usb", 173 .owner = THIS_MODULE, 174 .of_match_table = omap_control_usb_id_table, 175 }, 176 }; 177 178 module_platform_driver(am335x_control_driver); 179 MODULE_LICENSE("GPL v2"); 180