^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Motorola CPCAP PMIC USB PHY driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Some parts based on earlier Motorola Linux kernel tree code in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * board-mapphone-usb.c and cpcap-usb-det.c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2007 - 2011 Motorola, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * modify it under the terms of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * published by the Free Software Foundation version 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * kind, whether express or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/iio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/mfd/motorola-cpcap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/phy/omap_usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/usb/musb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* CPCAP_REG_USBC1 register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CPCAP_BIT_IDPULSE BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define CPCAP_BIT_ID100KPU BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CPCAP_BIT_IDPUCNTRL BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define CPCAP_BIT_IDPU BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define CPCAP_BIT_IDPD BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define CPCAP_BIT_VBUSCHRGTMR3 BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define CPCAP_BIT_VBUSCHRGTMR2 BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CPCAP_BIT_VBUSCHRGTMR1 BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define CPCAP_BIT_VBUSCHRGTMR0 BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define CPCAP_BIT_VBUSPU BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define CPCAP_BIT_VBUSPD BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define CPCAP_BIT_DMPD BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define CPCAP_BIT_DPPD BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CPCAP_BIT_DM1K5PU BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define CPCAP_BIT_DP1K5PU BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define CPCAP_BIT_DP150KPU BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* CPCAP_REG_USBC2 register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define CPCAP_BIT_ZHSDRV1 BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define CPCAP_BIT_ZHSDRV0 BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define CPCAP_BIT_DPLLCLKREQ BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define CPCAP_BIT_SE0CONN BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define CPCAP_BIT_UARTTXTRI BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define CPCAP_BIT_UARTSWAP BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define CPCAP_BIT_UARTMUX1 BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define CPCAP_BIT_UARTMUX0 BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define CPCAP_BIT_ULPISTPLOW BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define CPCAP_BIT_TXENPOL BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define CPCAP_BIT_USBXCVREN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define CPCAP_BIT_USBCNTRL BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define CPCAP_BIT_USBSUSPEND BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define CPCAP_BIT_EMUMODE2 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define CPCAP_BIT_EMUMODE1 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define CPCAP_BIT_EMUMODE0 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* CPCAP_REG_USBC3 register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define CPCAP_BIT_SPARE_898_15 BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define CPCAP_BIT_IHSTX03 BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define CPCAP_BIT_IHSTX02 BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define CPCAP_BIT_IHSTX01 BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define CPCAP_BIT_IHSTX0 BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define CPCAP_BIT_IDPU_SPI BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define CPCAP_BIT_UNUSED_898_9 BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define CPCAP_BIT_VBUSSTBY_EN BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define CPCAP_BIT_VBUSEN_SPI BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define CPCAP_BIT_VBUSPU_SPI BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define CPCAP_BIT_VBUSPD_SPI BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define CPCAP_BIT_DMPD_SPI BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define CPCAP_BIT_DPPD_SPI BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define CPCAP_BIT_SUSPEND_SPI BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define CPCAP_BIT_PU_SPI BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define CPCAP_BIT_ULPI_SPI_SEL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct cpcap_usb_ints_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) bool id_ground;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bool id_float;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) bool chrg_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bool rvrs_chrg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bool vbusov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bool chrg_se1b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) bool se0conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bool rvrs_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) bool chrgcurr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) bool vbusvld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bool sessvld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) bool sessend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bool se1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bool battdetb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bool dm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) enum cpcap_gpio_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) CPCAP_DM_DP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) CPCAP_MDM_RX_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) CPCAP_OTG_DM_DP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct cpcap_phy_ddata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct regmap *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct usb_phy phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct delayed_work detect_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct pinctrl *pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct pinctrl_state *pins_ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct pinctrl_state *pins_utmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct pinctrl_state *pins_uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct gpio_desc *gpio[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct iio_channel *vbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct iio_channel *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct regulator *vusb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) atomic_t active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned int vbus_provider:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned int docked:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int error, value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) error = iio_read_channel_processed(ddata->vbus, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (error >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return value > 3900 ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_err(ddata->dev, "error reading VBUS: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int cpcap_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) otg->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) otg->state = OTG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int cpcap_usb_phy_set_peripheral(struct usb_otg *otg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct usb_gadget *gadget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) otg->gadget = gadget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!gadget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) otg->state = OTG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static const struct phy_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct cpcap_usb_ints_state *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int val, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) error = regmap_read(ddata->reg, CPCAP_REG_INTS1, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) s->id_ground = val & BIT(15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) s->id_float = val & BIT(14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) s->vbusov = val & BIT(11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) s->vbusvld = val & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) s->sessvld = val & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) s->sessend = val & BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) s->se1 = val & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) error = regmap_read(ddata->reg, CPCAP_REG_INTS4, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) s->dm = val & BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) s->dp = val & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) enum musb_vbus_id_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) error = musb_mailbox(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static void cpcap_usb_detect(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct cpcap_phy_ddata *ddata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct cpcap_usb_ints_state s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) bool vbus = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ddata = container_of(work, struct cpcap_phy_ddata, detect_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) error = cpcap_phy_get_ints_state(ddata, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) vbus = cpcap_usb_vbus_valid(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* We need to kick the VBUS as USB A-host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (s.id_ground && ddata->vbus_provider) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) CPCAP_BIT_VBUSSTBY_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) CPCAP_BIT_VBUSEN_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) CPCAP_BIT_VBUSEN_SPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (vbus && s.id_ground && ddata->docked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* No VBUS needed with docks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (vbus && s.id_ground && !ddata->vbus_provider) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dev_dbg(ddata->dev, "connected to a dock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ddata->docked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) error = cpcap_usb_set_usb_mode(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Force check state again after musb has reoriented,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * otherwise devices won't enumerate after loading PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) schedule_delayed_work(&ddata->detect_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (s.id_ground && !ddata->docked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_dbg(ddata->dev, "id ground, USB host mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ddata->vbus_provider = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) error = cpcap_usb_set_usb_mode(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) CPCAP_BIT_VBUSSTBY_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) CPCAP_BIT_VBUSEN_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) CPCAP_BIT_VBUSEN_SPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) CPCAP_BIT_VBUSSTBY_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) CPCAP_BIT_VBUSEN_SPI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) vbus = cpcap_usb_vbus_valid(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Otherwise assume we're connected to a USB host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (vbus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dev_dbg(ddata->dev, "connected to USB host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) error = cpcap_usb_set_usb_mode(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ddata->vbus_provider = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ddata->docked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Default to debug UART mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) error = cpcap_usb_set_uart_mode(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_dbg(ddata->dev, "set UART mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dev_err(ddata->dev, "error setting cable state: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static irqreturn_t cpcap_phy_irq_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct cpcap_phy_ddata *ddata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!atomic_read(&ddata->active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int cpcap_usb_init_irq(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct cpcap_phy_ddata *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int irq, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) irq = platform_get_irq_byname(pdev, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) error = devm_request_threaded_irq(ddata->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) cpcap_phy_irq_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) IRQF_SHARED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) name, ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dev_err(ddata->dev, "could not get irq %s: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) name, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static const char * const cpcap_phy_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* REG_INT_0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) "id_ground", "id_float",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* REG_INT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) "se0conn", "vbusvld", "sessvld", "sessend", "se1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* REG_INT_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) "dm", "dp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int cpcap_usb_init_interrupts(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int i, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) for (i = 0; i < ARRAY_SIZE(cpcap_phy_irqs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) error = cpcap_usb_init_irq(pdev, ddata, cpcap_phy_irqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * Optional pins and modes. At least Motorola mapphone devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * are using two GPIOs and dynamic pinctrl to multiplex PHY pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * to UART, ULPI or UTMI mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int cpcap_usb_gpio_set_mode(struct cpcap_phy_ddata *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) enum cpcap_gpio_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!ddata->gpio[0] || !ddata->gpio[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) gpiod_set_value(ddata->gpio[0], mode & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) gpiod_set_value(ddata->gpio[1], mode >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Disable lines to prevent glitches from waking up mdm6600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (ddata->pins_uart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) error = pinctrl_select_state(ddata->pins, ddata->pins_uart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) CPCAP_BIT_VBUSPD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) CPCAP_BIT_VBUSPD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 0xffff, CPCAP_BIT_UARTMUX0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) CPCAP_BIT_EMUMODE0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) CPCAP_BIT_IDPU_SPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* Enable UART mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Disable lines to prevent glitches from waking up mdm6600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (ddata->pins_utmi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) error = pinctrl_select_state(ddata->pins, ddata->pins_utmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dev_err(ddata->dev, "could not set usb mode: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) CPCAP_BIT_VBUSPD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) CPCAP_BIT_PU_SPI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) CPCAP_BIT_DMPD_SPI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) CPCAP_BIT_DPPD_SPI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) CPCAP_BIT_SUSPEND_SPI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) CPCAP_BIT_ULPI_SPI_SEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) CPCAP_BIT_USBXCVREN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) CPCAP_BIT_USBXCVREN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Enable USB mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int cpcap_usb_init_optional_pins(struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ddata->pins = devm_pinctrl_get(ddata->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (IS_ERR(ddata->pins)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_info(ddata->dev, "default pins not configured: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) PTR_ERR(ddata->pins));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ddata->pins = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ddata->pins_ulpi = pinctrl_lookup_state(ddata->pins, "ulpi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (IS_ERR(ddata->pins_ulpi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dev_info(ddata->dev, "ulpi pins not configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ddata->pins_ulpi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ddata->pins_utmi = pinctrl_lookup_state(ddata->pins, "utmi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (IS_ERR(ddata->pins_utmi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dev_info(ddata->dev, "utmi pins not configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ddata->pins_utmi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ddata->pins_uart = pinctrl_lookup_state(ddata->pins, "uart");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (IS_ERR(ddata->pins_uart)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dev_info(ddata->dev, "uart pins not configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ddata->pins_uart = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (ddata->pins_uart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return pinctrl_select_state(ddata->pins, ddata->pins_uart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static void cpcap_usb_init_optional_gpios(struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ddata->gpio[i] = devm_gpiod_get_index(ddata->dev, "mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) i, GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (IS_ERR(ddata->gpio[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dev_info(ddata->dev, "no mode change GPIO%i: %li\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) i, PTR_ERR(ddata->gpio[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ddata->gpio[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static int cpcap_usb_init_iio(struct cpcap_phy_ddata *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) enum iio_chan_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ddata->vbus = devm_iio_channel_get(ddata->dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (IS_ERR(ddata->vbus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) error = PTR_ERR(ddata->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!ddata->vbus->indio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) error = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) error = iio_get_channel_type(ddata->vbus, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (type != IIO_VOLTAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static const struct of_device_id cpcap_usb_phy_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .compatible = "motorola,cpcap-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .compatible = "motorola,mapphone-cpcap-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) MODULE_DEVICE_TABLE(of, cpcap_usb_phy_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int cpcap_usb_phy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct cpcap_phy_ddata *ddata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct phy *generic_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct phy_provider *phy_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct usb_otg *otg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) of_id = of_match_device(of_match_ptr(cpcap_usb_phy_id_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (!of_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (!ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!ddata->reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!otg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ddata->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ddata->phy.dev = ddata->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ddata->phy.label = "cpcap_usb_phy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ddata->phy.otg = otg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ddata->phy.type = USB_PHY_TYPE_USB2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) otg->set_host = cpcap_usb_phy_set_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) otg->set_peripheral = cpcap_usb_phy_set_peripheral;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) otg->usb_phy = &ddata->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) platform_set_drvdata(pdev, ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ddata->vusb = devm_regulator_get(&pdev->dev, "vusb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (IS_ERR(ddata->vusb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return PTR_ERR(ddata->vusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) error = regulator_enable(ddata->vusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) generic_phy = devm_phy_create(ddata->dev, NULL, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (IS_ERR(generic_phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) error = PTR_ERR(generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) goto out_reg_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) phy_set_drvdata(generic_phy, ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) phy_provider = devm_of_phy_provider_register(ddata->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) of_phy_simple_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (IS_ERR(phy_provider)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) error = PTR_ERR(phy_provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto out_reg_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) error = cpcap_usb_init_optional_pins(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto out_reg_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) cpcap_usb_init_optional_gpios(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) error = cpcap_usb_init_iio(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) goto out_reg_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) error = cpcap_usb_init_interrupts(pdev, ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) goto out_reg_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) usb_add_phy_dev(&ddata->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) atomic_set(&ddata->active, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) out_reg_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) regulator_disable(ddata->vusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static int cpcap_usb_phy_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) atomic_set(&ddata->active, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) error = cpcap_usb_set_uart_mode(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_err(ddata->dev, "could not set UART mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) usb_remove_phy(&ddata->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) cancel_delayed_work_sync(&ddata->detect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) regulator_disable(ddata->vusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static struct platform_driver cpcap_usb_phy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .probe = cpcap_usb_phy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .remove = cpcap_usb_phy_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) .name = "cpcap-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) .of_match_table = of_match_ptr(cpcap_usb_phy_id_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) module_platform_driver(cpcap_usb_phy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) MODULE_ALIAS("platform:cpcap_usb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) MODULE_DESCRIPTION("CPCAP usb phy driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) MODULE_LICENSE("GPL v2");