|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/of.h>
|
|
|
+#include <linux/of_device.h>
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/clk.h>
|
|
@@ -46,61 +47,70 @@ struct device *omap_get_control_dev(void)
|
|
|
EXPORT_SYMBOL_GPL(omap_get_control_dev);
|
|
|
|
|
|
/**
|
|
|
- * omap_control_usb3_phy_power - power on/off the serializer using control
|
|
|
- * module
|
|
|
+ * omap_control_usb_phy_power - power on/off the phy using control module reg
|
|
|
* @dev: the control module device
|
|
|
- * @on: 0 to off and 1 to on based on powering on or off the PHY
|
|
|
- *
|
|
|
- * usb3 PHY driver should call this API to power on or off the PHY.
|
|
|
+ * @on: 0 or 1, based on powering on or off the PHY
|
|
|
*/
|
|
|
-void omap_control_usb3_phy_power(struct device *dev, bool on)
|
|
|
+void omap_control_usb_phy_power(struct device *dev, int on)
|
|
|
{
|
|
|
u32 val;
|
|
|
unsigned long rate;
|
|
|
- struct omap_control_usb *control_usb = dev_get_drvdata(dev);
|
|
|
+ struct omap_control_usb *control_usb;
|
|
|
|
|
|
- if (control_usb->type != OMAP_CTRL_DEV_TYPE2)
|
|
|
+ if (IS_ERR(dev) || !dev) {
|
|
|
+ pr_err("%s: invalid device\n", __func__);
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
- rate = clk_get_rate(control_usb->sys_clk);
|
|
|
- rate = rate/1000000;
|
|
|
-
|
|
|
- val = readl(control_usb->phy_power);
|
|
|
-
|
|
|
- if (on) {
|
|
|
- val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
|
|
|
- OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
|
|
|
- val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
|
|
|
- OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
|
|
- val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
|
|
|
- } else {
|
|
|
- val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
|
|
|
- val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
|
|
|
- OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
|
|
+ control_usb = dev_get_drvdata(dev);
|
|
|
+ if (!control_usb) {
|
|
|
+ dev_err(dev, "%s: invalid control usb device\n", __func__);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- writel(val, control_usb->phy_power);
|
|
|
-}
|
|
|
-EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power);
|
|
|
+ if (control_usb->type == OMAP_CTRL_TYPE_OTGHS)
|
|
|
+ return;
|
|
|
|
|
|
-/**
|
|
|
- * omap_control_usb_phy_power - power on/off the phy using control module reg
|
|
|
- * @dev: the control module device
|
|
|
- * @on: 0 or 1, based on powering on or off the PHY
|
|
|
- */
|
|
|
-void omap_control_usb_phy_power(struct device *dev, int on)
|
|
|
-{
|
|
|
- u32 val;
|
|
|
- struct omap_control_usb *control_usb = dev_get_drvdata(dev);
|
|
|
+ val = readl(control_usb->power);
|
|
|
+
|
|
|
+ switch (control_usb->type) {
|
|
|
+ case OMAP_CTRL_TYPE_USB2:
|
|
|
+ if (on)
|
|
|
+ val &= ~OMAP_CTRL_DEV_PHY_PD;
|
|
|
+ else
|
|
|
+ val |= OMAP_CTRL_DEV_PHY_PD;
|
|
|
+ break;
|
|
|
|
|
|
- val = readl(control_usb->dev_conf);
|
|
|
+ case OMAP_CTRL_TYPE_PIPE3:
|
|
|
+ rate = clk_get_rate(control_usb->sys_clk);
|
|
|
+ rate = rate/1000000;
|
|
|
+
|
|
|
+ if (on) {
|
|
|
+ val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
|
|
|
+ OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
|
|
|
+ val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
|
|
|
+ OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
|
|
+ val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
|
|
|
+ } else {
|
|
|
+ val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
|
|
|
+ val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
|
|
|
+ OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
|
|
|
- if (on)
|
|
|
- val &= ~OMAP_CTRL_DEV_PHY_PD;
|
|
|
- else
|
|
|
- val |= OMAP_CTRL_DEV_PHY_PD;
|
|
|
+ case OMAP_CTRL_TYPE_DRA7USB2:
|
|
|
+ if (on)
|
|
|
+ val &= ~OMAP_CTRL_USB2_PHY_PD;
|
|
|
+ else
|
|
|
+ val |= OMAP_CTRL_USB2_PHY_PD;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ dev_err(dev, "%s: type %d not recognized\n",
|
|
|
+ __func__, control_usb->type);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- writel(val, control_usb->dev_conf);
|
|
|
+ writel(val, control_usb->power);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(omap_control_usb_phy_power);
|
|
|
|
|
@@ -172,7 +182,7 @@ void omap_control_usb_set_mode(struct device *dev,
|
|
|
{
|
|
|
struct omap_control_usb *ctrl_usb;
|
|
|
|
|
|
- if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1)
|
|
|
+ if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_TYPE_OTGHS)
|
|
|
return;
|
|
|
|
|
|
ctrl_usb = dev_get_drvdata(dev);
|
|
@@ -193,10 +203,45 @@ void omap_control_usb_set_mode(struct device *dev,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
|
|
|
|
|
|
+#ifdef CONFIG_OF
|
|
|
+
|
|
|
+static const enum omap_control_usb_type otghs_data = OMAP_CTRL_TYPE_OTGHS;
|
|
|
+static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2;
|
|
|
+static const enum omap_control_usb_type pipe3_data = OMAP_CTRL_TYPE_PIPE3;
|
|
|
+static const enum omap_control_usb_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2;
|
|
|
+
|
|
|
+static const struct of_device_id omap_control_usb_id_table[] = {
|
|
|
+ {
|
|
|
+ .compatible = "ti,control-phy-otghs",
|
|
|
+ .data = &otghs_data,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .compatible = "ti,control-phy-usb2",
|
|
|
+ .data = &usb2_data,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .compatible = "ti,control-phy-pipe3",
|
|
|
+ .data = &pipe3_data,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .compatible = "ti,control-phy-dra7usb2",
|
|
|
+ .data = &dra7usb2_data,
|
|
|
+ },
|
|
|
+ {},
|
|
|
+};
|
|
|
+MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
static int omap_control_usb_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct resource *res;
|
|
|
- struct device_node *np = pdev->dev.of_node;
|
|
|
+ const struct of_device_id *of_id;
|
|
|
+
|
|
|
+ of_id = of_match_device(of_match_ptr(omap_control_usb_id_table),
|
|
|
+ &pdev->dev);
|
|
|
+ if (!of_id)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),
|
|
|
GFP_KERNEL);
|
|
@@ -205,36 +250,27 @@ static int omap_control_usb_probe(struct platform_device *pdev)
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- if (np)
|
|
|
- of_property_read_u32(np, "ti,type", &control_usb->type);
|
|
|
- else
|
|
|
- return -EINVAL; /* We only support DT boot */
|
|
|
-
|
|
|
- control_usb->dev = &pdev->dev;
|
|
|
+ control_usb->dev = &pdev->dev;
|
|
|
+ control_usb->type = *(enum omap_control_usb_type *)of_id->data;
|
|
|
|
|
|
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
|
|
- "control_dev_conf");
|
|
|
- control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res);
|
|
|
- if (IS_ERR(control_usb->dev_conf))
|
|
|
- return PTR_ERR(control_usb->dev_conf);
|
|
|
-
|
|
|
- if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
|
|
|
+ if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) {
|
|
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
|
|
"otghs_control");
|
|
|
control_usb->otghs_control = devm_ioremap_resource(
|
|
|
&pdev->dev, res);
|
|
|
if (IS_ERR(control_usb->otghs_control))
|
|
|
return PTR_ERR(control_usb->otghs_control);
|
|
|
- }
|
|
|
-
|
|
|
- if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
|
|
|
+ } else {
|
|
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
|
|
- "phy_power_usb");
|
|
|
- control_usb->phy_power = devm_ioremap_resource(
|
|
|
- &pdev->dev, res);
|
|
|
- if (IS_ERR(control_usb->phy_power))
|
|
|
- return PTR_ERR(control_usb->phy_power);
|
|
|
+ "power");
|
|
|
+ control_usb->power = devm_ioremap_resource(&pdev->dev, res);
|
|
|
+ if (IS_ERR(control_usb->power)) {
|
|
|
+ dev_err(&pdev->dev, "Couldn't get power register\n");
|
|
|
+ return PTR_ERR(control_usb->power);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ if (control_usb->type == OMAP_CTRL_TYPE_PIPE3) {
|
|
|
control_usb->sys_clk = devm_clk_get(control_usb->dev,
|
|
|
"sys_clkin");
|
|
|
if (IS_ERR(control_usb->sys_clk)) {
|
|
@@ -243,20 +279,11 @@ static int omap_control_usb_probe(struct platform_device *pdev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
dev_set_drvdata(control_usb->dev, control_usb);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_OF
|
|
|
-static const struct of_device_id omap_control_usb_id_table[] = {
|
|
|
- { .compatible = "ti,omap-control-usb" },
|
|
|
- {}
|
|
|
-};
|
|
|
-MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
|
|
|
-#endif
|
|
|
-
|
|
|
static struct platform_driver omap_control_usb_driver = {
|
|
|
.probe = omap_control_usb_probe,
|
|
|
.driver = {
|