mirror of https://gitee.com/openkylin/linux.git
usb: phy: ab8500-usb: add flag bits to control driver features
Introduce a "flags" field in "struct ab8500_usb" to allow controlling driver features and quirks depending on ab8500 chip variant and revision. Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Maxime Coquelin <maxime.coquelin@st.com> Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
16604a3c27
commit
bd4c9f0278
|
@ -121,6 +121,17 @@ enum ab8500_usb_mode {
|
||||||
USB_DEDICATED_CHG
|
USB_DEDICATED_CHG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Register USB_LINK_STATUS interrupt */
|
||||||
|
#define AB8500_USB_FLAG_USE_LINK_STATUS_IRQ (1 << 0)
|
||||||
|
/* Register ID_WAKEUP_F interrupt */
|
||||||
|
#define AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ (1 << 1)
|
||||||
|
/* Register VBUS_DET_F interrupt */
|
||||||
|
#define AB8500_USB_FLAG_USE_VBUS_DET_IRQ (1 << 2)
|
||||||
|
/* Driver is using the ab-iddet driver*/
|
||||||
|
#define AB8500_USB_FLAG_USE_AB_IDDET (1 << 3)
|
||||||
|
/* Enable setting regulators voltage */
|
||||||
|
#define AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE (1 << 4)
|
||||||
|
|
||||||
struct ab8500_usb {
|
struct ab8500_usb {
|
||||||
struct usb_phy phy;
|
struct usb_phy phy;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
@ -136,6 +147,7 @@ struct ab8500_usb {
|
||||||
int previous_link_status_state;
|
int previous_link_status_state;
|
||||||
struct pinctrl *pinctrl;
|
struct pinctrl *pinctrl;
|
||||||
struct pinctrl_state *pins_sleep;
|
struct pinctrl_state *pins_sleep;
|
||||||
|
unsigned int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x)
|
static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x)
|
||||||
|
@ -174,7 +186,7 @@ static void ab8500_usb_regulator_enable(struct ab8500_usb *ab)
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(ab->dev, "Failed to enable v-ape\n");
|
dev_err(ab->dev, "Failed to enable v-ape\n");
|
||||||
|
|
||||||
if (!is_ab8500_2p0_or_earlier(ab->ab8500)) {
|
if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) {
|
||||||
ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi);
|
ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi);
|
||||||
if (ab->saved_v_ulpi < 0)
|
if (ab->saved_v_ulpi < 0)
|
||||||
dev_err(ab->dev, "Failed to get v_ulpi voltage\n");
|
dev_err(ab->dev, "Failed to get v_ulpi voltage\n");
|
||||||
|
@ -194,7 +206,7 @@ static void ab8500_usb_regulator_enable(struct ab8500_usb *ab)
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(ab->dev, "Failed to enable vddulpivio18\n");
|
dev_err(ab->dev, "Failed to enable vddulpivio18\n");
|
||||||
|
|
||||||
if (!is_ab8500_2p0_or_earlier(ab->ab8500)) {
|
if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) {
|
||||||
volt = regulator_get_voltage(ab->v_ulpi);
|
volt = regulator_get_voltage(ab->v_ulpi);
|
||||||
if ((volt != 1300000) && (volt != 1350000))
|
if ((volt != 1300000) && (volt != 1350000))
|
||||||
dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n",
|
dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n",
|
||||||
|
@ -215,7 +227,7 @@ static void ab8500_usb_regulator_disable(struct ab8500_usb *ab)
|
||||||
regulator_disable(ab->v_ulpi);
|
regulator_disable(ab->v_ulpi);
|
||||||
|
|
||||||
/* USB is not the only consumer of Vintcore, restore old settings */
|
/* USB is not the only consumer of Vintcore, restore old settings */
|
||||||
if (!is_ab8500_2p0_or_earlier(ab->ab8500)) {
|
if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) {
|
||||||
if (ab->saved_v_ulpi > 0) {
|
if (ab->saved_v_ulpi > 0) {
|
||||||
ret = regulator_set_voltage(ab->v_ulpi,
|
ret = regulator_set_voltage(ab->v_ulpi,
|
||||||
ab->saved_v_ulpi, ab->saved_v_ulpi);
|
ab->saved_v_ulpi, ab->saved_v_ulpi);
|
||||||
|
@ -729,43 +741,52 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev,
|
||||||
int err;
|
int err;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS");
|
if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) {
|
||||||
if (irq < 0) {
|
irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS");
|
||||||
dev_err(&pdev->dev, "Link status irq not found\n");
|
if (irq < 0) {
|
||||||
return irq;
|
dev_err(&pdev->dev, "Link status irq not found\n");
|
||||||
}
|
return irq;
|
||||||
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
}
|
||||||
ab8500_usb_link_status_irq,
|
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||||
IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab);
|
ab8500_usb_link_status_irq,
|
||||||
if (err < 0) {
|
IRQF_NO_SUSPEND | IRQF_SHARED,
|
||||||
dev_err(ab->dev, "request_irq failed for link status irq\n");
|
"usb-link-status", ab);
|
||||||
return err;
|
if (err < 0) {
|
||||||
|
dev_err(ab->dev, "request_irq failed for link status irq\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F");
|
if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) {
|
||||||
if (irq < 0) {
|
irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F");
|
||||||
dev_err(&pdev->dev, "ID fall irq not found\n");
|
if (irq < 0) {
|
||||||
return irq;
|
dev_err(&pdev->dev, "ID fall irq not found\n");
|
||||||
}
|
return irq;
|
||||||
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
}
|
||||||
ab8500_usb_disconnect_irq,
|
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||||
IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab);
|
ab8500_usb_disconnect_irq,
|
||||||
if (err < 0) {
|
IRQF_NO_SUSPEND | IRQF_SHARED,
|
||||||
dev_err(ab->dev, "request_irq failed for ID fall irq\n");
|
"usb-id-fall", ab);
|
||||||
return err;
|
if (err < 0) {
|
||||||
|
dev_err(ab->dev, "request_irq failed for ID fall irq\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
irq = platform_get_irq_byname(pdev, "VBUS_DET_F");
|
if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) {
|
||||||
if (irq < 0) {
|
irq = platform_get_irq_byname(pdev, "VBUS_DET_F");
|
||||||
dev_err(&pdev->dev, "VBUS fall irq not found\n");
|
if (irq < 0) {
|
||||||
return irq;
|
dev_err(&pdev->dev, "VBUS fall irq not found\n");
|
||||||
}
|
return irq;
|
||||||
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
}
|
||||||
ab8500_usb_disconnect_irq,
|
err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||||
IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab);
|
ab8500_usb_disconnect_irq,
|
||||||
if (err < 0) {
|
IRQF_NO_SUSPEND | IRQF_SHARED,
|
||||||
dev_err(ab->dev, "request_irq failed for Vbus fall irq\n");
|
"usb-vbus-fall", ab);
|
||||||
return err;
|
if (err < 0) {
|
||||||
|
dev_err(ab->dev, "request_irq failed for Vbus fall irq\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -888,6 +909,22 @@ static int ab8500_usb_probe(struct platform_device *pdev)
|
||||||
otg->set_host = ab8500_usb_set_host;
|
otg->set_host = ab8500_usb_set_host;
|
||||||
otg->set_peripheral = ab8500_usb_set_peripheral;
|
otg->set_peripheral = ab8500_usb_set_peripheral;
|
||||||
|
|
||||||
|
if (is_ab8500(ab->ab8500)) {
|
||||||
|
ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ |
|
||||||
|
AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ |
|
||||||
|
AB8500_USB_FLAG_USE_VBUS_DET_IRQ |
|
||||||
|
AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE;
|
||||||
|
} else if (is_ab8505(ab->ab8500)) {
|
||||||
|
ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ |
|
||||||
|
AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ |
|
||||||
|
AB8500_USB_FLAG_USE_VBUS_DET_IRQ |
|
||||||
|
AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable regulator voltage setting for AB8500 <= v2.0 */
|
||||||
|
if (is_ab8500_2p0_or_earlier(ab->ab8500))
|
||||||
|
ab->flags &= ~AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ab);
|
platform_set_drvdata(pdev, ab);
|
||||||
|
|
||||||
ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier);
|
ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier);
|
||||||
|
|
Loading…
Reference in New Issue