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