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_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val) 30 { 31 int ret; 32 33 ret = ulpi_write(tusb->ulpi, reg, val); 34 if (ret) 35 dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n", 36 ret, val, reg); 37 38 return ret; 39 } 40 41 static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val) 42 { 43 int ret; 44 45 ret = ulpi_read(tusb->ulpi, reg); 46 if (ret >= 0) { 47 *val = ret; 48 ret = 0; 49 } else { 50 dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg); 51 } 52 53 return ret; 54 } 55 56 static int tusb1210_power_on(struct phy *phy) 57 { 58 struct tusb1210 *tusb = phy_get_drvdata(phy); 59 60 gpiod_set_value_cansleep(tusb->gpio_reset, 1); 61 gpiod_set_value_cansleep(tusb->gpio_cs, 1); 62 63 /* Restore the optional eye diagram optimization value */ 64 if (tusb->vendor_specific2) 65 return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, 66 tusb->vendor_specific2); 67 68 return 0; 69 } 70 71 static int tusb1210_power_off(struct phy *phy) 72 { 73 struct tusb1210 *tusb = phy_get_drvdata(phy); 74 75 gpiod_set_value_cansleep(tusb->gpio_reset, 0); 76 gpiod_set_value_cansleep(tusb->gpio_cs, 0); 77 78 return 0; 79 } 80 81 static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode) 82 { 83 struct tusb1210 *tusb = phy_get_drvdata(phy); 84 int ret; 85 u8 reg; 86 87 ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, ®); 88 if (ret < 0) 89 return ret; 90 91 switch (mode) { 92 case PHY_MODE_USB_HOST: 93 reg |= (ULPI_OTG_CTRL_DRVVBUS_EXT 94 | ULPI_OTG_CTRL_ID_PULLUP 95 | ULPI_OTG_CTRL_DP_PULLDOWN 96 | ULPI_OTG_CTRL_DM_PULLDOWN); 97 tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); 98 reg |= ULPI_OTG_CTRL_DRVVBUS; 99 break; 100 case PHY_MODE_USB_DEVICE: 101 reg &= ~(ULPI_OTG_CTRL_DRVVBUS 102 | ULPI_OTG_CTRL_DP_PULLDOWN 103 | ULPI_OTG_CTRL_DM_PULLDOWN); 104 tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); 105 reg &= ~ULPI_OTG_CTRL_DRVVBUS_EXT; 106 break; 107 default: 108 /* nothing */ 109 return 0; 110 } 111 112 return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); 113 } 114 115 static const struct phy_ops phy_ops = { 116 .power_on = tusb1210_power_on, 117 .power_off = tusb1210_power_off, 118 .set_mode = tusb1210_set_mode, 119 .owner = THIS_MODULE, 120 }; 121 122 static int tusb1210_probe(struct ulpi *ulpi) 123 { 124 struct tusb1210 *tusb; 125 u8 val, reg; 126 int ret; 127 128 tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL); 129 if (!tusb) 130 return -ENOMEM; 131 132 tusb->ulpi = ulpi; 133 134 tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset", 135 GPIOD_OUT_LOW); 136 if (IS_ERR(tusb->gpio_reset)) 137 return PTR_ERR(tusb->gpio_reset); 138 139 gpiod_set_value_cansleep(tusb->gpio_reset, 1); 140 141 tusb->gpio_cs = devm_gpiod_get_optional(&ulpi->dev, "cs", 142 GPIOD_OUT_LOW); 143 if (IS_ERR(tusb->gpio_cs)) 144 return PTR_ERR(tusb->gpio_cs); 145 146 gpiod_set_value_cansleep(tusb->gpio_cs, 1); 147 148 /* 149 * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye 150 * diagram optimization and DP/DM swap. 151 */ 152 153 ret = tusb1210_ulpi_read(tusb, TUSB1210_VENDOR_SPECIFIC2, ®); 154 if (ret) 155 return ret; 156 157 /* High speed output drive strength configuration */ 158 if (!device_property_read_u8(&ulpi->dev, "ihstx", &val)) 159 u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK); 160 161 /* High speed output impedance configuration */ 162 if (!device_property_read_u8(&ulpi->dev, "zhsdrv", &val)) 163 u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK); 164 165 /* DP/DM swap control */ 166 if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val)) 167 u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK); 168 169 ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg); 170 if (ret) 171 return ret; 172 173 tusb->vendor_specific2 = reg; 174 175 tusb->phy = ulpi_phy_create(ulpi, &phy_ops); 176 if (IS_ERR(tusb->phy)) 177 return PTR_ERR(tusb->phy); 178 179 phy_set_drvdata(tusb->phy, tusb); 180 ulpi_set_drvdata(ulpi, tusb); 181 return 0; 182 } 183 184 static void tusb1210_remove(struct ulpi *ulpi) 185 { 186 struct tusb1210 *tusb = ulpi_get_drvdata(ulpi); 187 188 ulpi_phy_destroy(ulpi, tusb->phy); 189 } 190 191 #define TI_VENDOR_ID 0x0451 192 193 static const struct ulpi_device_id tusb1210_ulpi_id[] = { 194 { TI_VENDOR_ID, 0x1507, }, /* TUSB1210 */ 195 { TI_VENDOR_ID, 0x1508, }, /* TUSB1211 */ 196 { }, 197 }; 198 MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id); 199 200 static struct ulpi_driver tusb1210_driver = { 201 .id_table = tusb1210_ulpi_id, 202 .probe = tusb1210_probe, 203 .remove = tusb1210_remove, 204 .driver = { 205 .name = "tusb1210", 206 .owner = THIS_MODULE, 207 }, 208 }; 209 210 module_ulpi_driver(tusb1210_driver); 211 212 MODULE_AUTHOR("Intel Corporation"); 213 MODULE_LICENSE("GPL v2"); 214 MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver"); 215