1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * tusb1210.c - TUSB1210 USB ULPI PHY driver 4 * 5 * Copyright (C) 2015 Intel Corporation 6 * 7 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> 8 */ 9 #include <linux/module.h> 10 #include <linux/bitfield.h> 11 #include <linux/ulpi/driver.h> 12 #include <linux/ulpi/regs.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/phy/ulpi_phy.h> 15 16 #define TUSB1210_VENDOR_SPECIFIC2 0x80 17 #define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0) 18 #define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4) 19 #define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6) 20 21 struct tusb1210 { 22 struct ulpi *ulpi; 23 struct phy *phy; 24 struct gpio_desc *gpio_reset; 25 struct gpio_desc *gpio_cs; 26 u8 vendor_specific2; 27 }; 28 29 static int tusb1210_power_on(struct phy *phy) 30 { 31 struct tusb1210 *tusb = phy_get_drvdata(phy); 32 33 gpiod_set_value_cansleep(tusb->gpio_reset, 1); 34 gpiod_set_value_cansleep(tusb->gpio_cs, 1); 35 36 /* Restore the optional eye diagram optimization value */ 37 if (tusb->vendor_specific2) 38 ulpi_write(tusb->ulpi, TUSB1210_VENDOR_SPECIFIC2, 39 tusb->vendor_specific2); 40 41 return 0; 42 } 43 44 static int tusb1210_power_off(struct phy *phy) 45 { 46 struct tusb1210 *tusb = phy_get_drvdata(phy); 47 48 gpiod_set_value_cansleep(tusb->gpio_reset, 0); 49 gpiod_set_value_cansleep(tusb->gpio_cs, 0); 50 51 return 0; 52 } 53 54 static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode) 55 { 56 struct tusb1210 *tusb = phy_get_drvdata(phy); 57 int ret; 58 59 ret = ulpi_read(tusb->ulpi, ULPI_OTG_CTRL); 60 if (ret < 0) 61 return ret; 62 63 switch (mode) { 64 case PHY_MODE_USB_HOST: 65 ret |= (ULPI_OTG_CTRL_DRVVBUS_EXT 66 | ULPI_OTG_CTRL_ID_PULLUP 67 | ULPI_OTG_CTRL_DP_PULLDOWN 68 | ULPI_OTG_CTRL_DM_PULLDOWN); 69 ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret); 70 ret |= ULPI_OTG_CTRL_DRVVBUS; 71 break; 72 case PHY_MODE_USB_DEVICE: 73 ret &= ~(ULPI_OTG_CTRL_DRVVBUS 74 | ULPI_OTG_CTRL_DP_PULLDOWN 75 | ULPI_OTG_CTRL_DM_PULLDOWN); 76 ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret); 77 ret &= ~ULPI_OTG_CTRL_DRVVBUS_EXT; 78 break; 79 default: 80 /* nothing */ 81 return 0; 82 } 83 84 return ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret); 85 } 86 87 static const struct phy_ops phy_ops = { 88 .power_on = tusb1210_power_on, 89 .power_off = tusb1210_power_off, 90 .set_mode = tusb1210_set_mode, 91 .owner = THIS_MODULE, 92 }; 93 94 static int tusb1210_probe(struct ulpi *ulpi) 95 { 96 struct tusb1210 *tusb; 97 u8 val, reg; 98 99 tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL); 100 if (!tusb) 101 return -ENOMEM; 102 103 tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset", 104 GPIOD_OUT_LOW); 105 if (IS_ERR(tusb->gpio_reset)) 106 return PTR_ERR(tusb->gpio_reset); 107 108 gpiod_set_value_cansleep(tusb->gpio_reset, 1); 109 110 tusb->gpio_cs = devm_gpiod_get_optional(&ulpi->dev, "cs", 111 GPIOD_OUT_LOW); 112 if (IS_ERR(tusb->gpio_cs)) 113 return PTR_ERR(tusb->gpio_cs); 114 115 gpiod_set_value_cansleep(tusb->gpio_cs, 1); 116 117 /* 118 * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye 119 * diagram optimization and DP/DM swap. 120 */ 121 122 reg = ulpi_read(ulpi, TUSB1210_VENDOR_SPECIFIC2); 123 124 /* High speed output drive strength configuration */ 125 if (!device_property_read_u8(&ulpi->dev, "ihstx", &val)) 126 u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK); 127 128 /* High speed output impedance configuration */ 129 if (!device_property_read_u8(&ulpi->dev, "zhsdrv", &val)) 130 u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK); 131 132 /* DP/DM swap control */ 133 if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val)) 134 u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK); 135 136 ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg); 137 tusb->vendor_specific2 = reg; 138 139 tusb->phy = ulpi_phy_create(ulpi, &phy_ops); 140 if (IS_ERR(tusb->phy)) 141 return PTR_ERR(tusb->phy); 142 143 tusb->ulpi = ulpi; 144 145 phy_set_drvdata(tusb->phy, tusb); 146 ulpi_set_drvdata(ulpi, tusb); 147 return 0; 148 } 149 150 static void tusb1210_remove(struct ulpi *ulpi) 151 { 152 struct tusb1210 *tusb = ulpi_get_drvdata(ulpi); 153 154 ulpi_phy_destroy(ulpi, tusb->phy); 155 } 156 157 #define TI_VENDOR_ID 0x0451 158 159 static const struct ulpi_device_id tusb1210_ulpi_id[] = { 160 { TI_VENDOR_ID, 0x1507, }, /* TUSB1210 */ 161 { TI_VENDOR_ID, 0x1508, }, /* TUSB1211 */ 162 { }, 163 }; 164 MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id); 165 166 static struct ulpi_driver tusb1210_driver = { 167 .id_table = tusb1210_ulpi_id, 168 .probe = tusb1210_probe, 169 .remove = tusb1210_remove, 170 .driver = { 171 .name = "tusb1210", 172 .owner = THIS_MODULE, 173 }, 174 }; 175 176 module_ulpi_driver(tusb1210_driver); 177 178 MODULE_AUTHOR("Intel Corporation"); 179 MODULE_LICENSE("GPL v2"); 180 MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver"); 181