Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
466b1516 | 2 | /* |
1c14905e HK |
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> | |
1c14905e HK |
8 | */ |
9 | #include <linux/module.h> | |
eb445a15 | 10 | #include <linux/bitfield.h> |
df37c998 | 11 | #include <linux/delay.h> |
1c14905e | 12 | #include <linux/ulpi/driver.h> |
54fe3088 | 13 | #include <linux/ulpi/regs.h> |
1c14905e | 14 | #include <linux/gpio/consumer.h> |
858edde0 | 15 | #include <linux/phy/ulpi_phy.h> |
48969a56 | 16 | #include <linux/power_supply.h> |
7559e757 | 17 | #include <linux/property.h> |
48969a56 SG |
18 | #include <linux/workqueue.h> |
19 | ||
20 | #define TUSB1211_POWER_CONTROL 0x3d | |
21 | #define TUSB1211_POWER_CONTROL_SET 0x3e | |
22 | #define TUSB1211_POWER_CONTROL_CLEAR 0x3f | |
23 | #define TUSB1211_POWER_CONTROL_SW_CONTROL BIT(0) | |
24 | #define TUSB1211_POWER_CONTROL_DET_COMP BIT(1) | |
25 | #define TUSB1211_POWER_CONTROL_DP_VSRC_EN BIT(6) | |
26 | ||
27 | #define TUSB1210_VENDOR_SPECIFIC2 0x80 | |
28 | #define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0) | |
29 | #define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4) | |
30 | #define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6) | |
31 | ||
32 | #define TUSB1211_VENDOR_SPECIFIC3 0x85 | |
33 | #define TUSB1211_VENDOR_SPECIFIC3_SET 0x86 | |
34 | #define TUSB1211_VENDOR_SPECIFIC3_CLEAR 0x87 | |
35 | #define TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET BIT(4) | |
36 | #define TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN BIT(6) | |
37 | ||
38 | #define TUSB1210_RESET_TIME_MS 50 | |
39 | ||
40 | #define TUSB1210_CHG_DET_MAX_RETRIES 5 | |
41 | ||
42 | /* TUSB1210 charger detection work states */ | |
43 | enum tusb1210_chg_det_state { | |
44 | TUSB1210_CHG_DET_CONNECTING, | |
45 | TUSB1210_CHG_DET_START_DET, | |
46 | TUSB1210_CHG_DET_READ_DET, | |
47 | TUSB1210_CHG_DET_FINISH_DET, | |
48 | TUSB1210_CHG_DET_CONNECTED, | |
49 | TUSB1210_CHG_DET_DISCONNECTING, | |
50 | TUSB1210_CHG_DET_DISCONNECTING_DONE, | |
51 | TUSB1210_CHG_DET_DISCONNECTED, | |
52 | }; | |
df37c998 | 53 | |
1c14905e HK |
54 | struct tusb1210 { |
55 | struct ulpi *ulpi; | |
56 | struct phy *phy; | |
57 | struct gpio_desc *gpio_reset; | |
58 | struct gpio_desc *gpio_cs; | |
48969a56 | 59 | u8 otg_ctrl; |
1c14905e | 60 | u8 vendor_specific2; |
48969a56 SG |
61 | #ifdef CONFIG_POWER_SUPPLY |
62 | enum power_supply_usb_type chg_type; | |
63 | enum tusb1210_chg_det_state chg_det_state; | |
64 | int chg_det_retries; | |
65 | struct delayed_work chg_det_work; | |
66 | struct notifier_block psy_nb; | |
67 | struct power_supply *psy; | |
68 | struct power_supply *charger; | |
69 | #endif | |
1c14905e HK |
70 | }; |
71 | ||
09a35126 HG |
72 | static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val) |
73 | { | |
74 | int ret; | |
75 | ||
76 | ret = ulpi_write(tusb->ulpi, reg, val); | |
77 | if (ret) | |
78 | dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n", | |
79 | ret, val, reg); | |
80 | ||
81 | return ret; | |
82 | } | |
83 | ||
84 | static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val) | |
85 | { | |
86 | int ret; | |
87 | ||
88 | ret = ulpi_read(tusb->ulpi, reg); | |
89 | if (ret >= 0) { | |
90 | *val = ret; | |
91 | ret = 0; | |
92 | } else { | |
93 | dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg); | |
94 | } | |
95 | ||
96 | return ret; | |
97 | } | |
98 | ||
1c14905e HK |
99 | static int tusb1210_power_on(struct phy *phy) |
100 | { | |
101 | struct tusb1210 *tusb = phy_get_drvdata(phy); | |
102 | ||
103 | gpiod_set_value_cansleep(tusb->gpio_reset, 1); | |
104 | gpiod_set_value_cansleep(tusb->gpio_cs, 1); | |
105 | ||
df37c998 HG |
106 | msleep(TUSB1210_RESET_TIME_MS); |
107 | ||
1c14905e | 108 | /* Restore the optional eye diagram optimization value */ |
d4a0a189 AS |
109 | tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, tusb->vendor_specific2); |
110 | ||
111 | return 0; | |
1c14905e HK |
112 | } |
113 | ||
114 | static int tusb1210_power_off(struct phy *phy) | |
115 | { | |
116 | struct tusb1210 *tusb = phy_get_drvdata(phy); | |
117 | ||
118 | gpiod_set_value_cansleep(tusb->gpio_reset, 0); | |
119 | gpiod_set_value_cansleep(tusb->gpio_cs, 0); | |
120 | ||
121 | return 0; | |
122 | } | |
123 | ||
79a5a18a | 124 | static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode) |
54fe3088 FB |
125 | { |
126 | struct tusb1210 *tusb = phy_get_drvdata(phy); | |
127 | int ret; | |
09a35126 | 128 | u8 reg; |
54fe3088 | 129 | |
09a35126 | 130 | ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, ®); |
54fe3088 FB |
131 | if (ret < 0) |
132 | return ret; | |
133 | ||
134 | switch (mode) { | |
135 | case PHY_MODE_USB_HOST: | |
09a35126 | 136 | reg |= (ULPI_OTG_CTRL_DRVVBUS_EXT |
54fe3088 FB |
137 | | ULPI_OTG_CTRL_ID_PULLUP |
138 | | ULPI_OTG_CTRL_DP_PULLDOWN | |
139 | | ULPI_OTG_CTRL_DM_PULLDOWN); | |
09a35126 HG |
140 | tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); |
141 | reg |= ULPI_OTG_CTRL_DRVVBUS; | |
54fe3088 FB |
142 | break; |
143 | case PHY_MODE_USB_DEVICE: | |
09a35126 | 144 | reg &= ~(ULPI_OTG_CTRL_DRVVBUS |
54fe3088 FB |
145 | | ULPI_OTG_CTRL_DP_PULLDOWN |
146 | | ULPI_OTG_CTRL_DM_PULLDOWN); | |
09a35126 HG |
147 | tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); |
148 | reg &= ~ULPI_OTG_CTRL_DRVVBUS_EXT; | |
54fe3088 FB |
149 | break; |
150 | default: | |
151 | /* nothing */ | |
152 | return 0; | |
153 | } | |
154 | ||
48969a56 | 155 | tusb->otg_ctrl = reg; |
09a35126 | 156 | return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); |
54fe3088 FB |
157 | } |
158 | ||
48969a56 | 159 | #ifdef CONFIG_POWER_SUPPLY |
b541f9e5 | 160 | static const char * const tusb1210_chg_det_states[] = { |
48969a56 SG |
161 | "CHG_DET_CONNECTING", |
162 | "CHG_DET_START_DET", | |
163 | "CHG_DET_READ_DET", | |
164 | "CHG_DET_FINISH_DET", | |
165 | "CHG_DET_CONNECTED", | |
166 | "CHG_DET_DISCONNECTING", | |
167 | "CHG_DET_DISCONNECTING_DONE", | |
168 | "CHG_DET_DISCONNECTED", | |
169 | }; | |
170 | ||
171 | static void tusb1210_reset(struct tusb1210 *tusb) | |
172 | { | |
173 | gpiod_set_value_cansleep(tusb->gpio_reset, 0); | |
174 | usleep_range(200, 500); | |
175 | gpiod_set_value_cansleep(tusb->gpio_reset, 1); | |
176 | } | |
177 | ||
178 | static void tusb1210_chg_det_set_type(struct tusb1210 *tusb, | |
179 | enum power_supply_usb_type type) | |
180 | { | |
181 | dev_dbg(&tusb->ulpi->dev, "charger type: %d\n", type); | |
182 | tusb->chg_type = type; | |
183 | tusb->chg_det_retries = 0; | |
184 | power_supply_changed(tusb->psy); | |
185 | } | |
186 | ||
187 | static void tusb1210_chg_det_set_state(struct tusb1210 *tusb, | |
188 | enum tusb1210_chg_det_state new_state, | |
189 | int delay_ms) | |
190 | { | |
191 | if (delay_ms) | |
192 | dev_dbg(&tusb->ulpi->dev, "chg_det new state %s in %d ms\n", | |
193 | tusb1210_chg_det_states[new_state], delay_ms); | |
194 | ||
195 | tusb->chg_det_state = new_state; | |
196 | mod_delayed_work(system_long_wq, &tusb->chg_det_work, | |
197 | msecs_to_jiffies(delay_ms)); | |
198 | } | |
199 | ||
200 | static void tusb1210_chg_det_handle_ulpi_error(struct tusb1210 *tusb) | |
201 | { | |
202 | tusb1210_reset(tusb); | |
203 | if (tusb->chg_det_retries < TUSB1210_CHG_DET_MAX_RETRIES) { | |
204 | tusb->chg_det_retries++; | |
205 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, | |
206 | TUSB1210_RESET_TIME_MS); | |
207 | } else { | |
208 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, | |
209 | TUSB1210_RESET_TIME_MS); | |
210 | } | |
211 | } | |
212 | ||
213 | /* | |
214 | * Boards using a TUSB121x for charger-detection have 3 power_supply class devs: | |
215 | * | |
216 | * tusb1211-charger-detect(1) -> charger -> fuel-gauge | |
217 | * | |
218 | * To determine if an USB charger is connected to the board, the online prop of | |
219 | * the charger psy needs to be read. Since the tusb1211-charger-detect psy is | |
220 | * the start of the supplier -> supplied-to chain, power_supply_am_i_supplied() | |
221 | * cannot be used here. | |
222 | * | |
223 | * Instead, below is a list of the power_supply names of known chargers for | |
224 | * these boards and the charger psy is looked up by name from this list. | |
225 | * | |
226 | * (1) modelling the external USB charger | |
227 | */ | |
228 | static const char * const tusb1210_chargers[] = { | |
229 | "bq24190-charger", | |
230 | }; | |
231 | ||
232 | static bool tusb1210_get_online(struct tusb1210 *tusb) | |
233 | { | |
234 | union power_supply_propval val; | |
235 | int i; | |
236 | ||
237 | for (i = 0; i < ARRAY_SIZE(tusb1210_chargers) && !tusb->charger; i++) | |
238 | tusb->charger = power_supply_get_by_name(tusb1210_chargers[i]); | |
239 | ||
240 | if (!tusb->charger) | |
241 | return false; | |
242 | ||
243 | if (power_supply_get_property(tusb->charger, POWER_SUPPLY_PROP_ONLINE, &val)) | |
244 | return false; | |
245 | ||
246 | return val.intval; | |
247 | } | |
248 | ||
249 | static void tusb1210_chg_det_work(struct work_struct *work) | |
250 | { | |
251 | struct tusb1210 *tusb = container_of(work, struct tusb1210, chg_det_work.work); | |
252 | bool vbus_present = tusb1210_get_online(tusb); | |
253 | int ret; | |
254 | u8 val; | |
255 | ||
256 | dev_dbg(&tusb->ulpi->dev, "chg_det state %s vbus_present %d\n", | |
257 | tusb1210_chg_det_states[tusb->chg_det_state], vbus_present); | |
258 | ||
259 | switch (tusb->chg_det_state) { | |
260 | case TUSB1210_CHG_DET_CONNECTING: | |
261 | tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN; | |
262 | tusb->chg_det_retries = 0; | |
263 | /* Power on USB controller for ulpi_read()/_write() */ | |
264 | ret = pm_runtime_resume_and_get(tusb->ulpi->dev.parent); | |
265 | if (ret < 0) { | |
266 | dev_err(&tusb->ulpi->dev, "error %d runtime-resuming\n", ret); | |
267 | /* Should never happen, skip charger detection */ | |
268 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0); | |
269 | return; | |
270 | } | |
271 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, 0); | |
272 | break; | |
273 | case TUSB1210_CHG_DET_START_DET: | |
274 | /* | |
275 | * Use the builtin charger detection FSM to keep things simple. | |
276 | * This only detects DCP / SDP. This is good enough for the few | |
277 | * boards which actually rely on the phy for charger detection. | |
278 | */ | |
279 | mutex_lock(&tusb->phy->mutex); | |
280 | ret = tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_SET, | |
281 | TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET); | |
282 | mutex_unlock(&tusb->phy->mutex); | |
283 | if (ret) { | |
284 | tusb1210_chg_det_handle_ulpi_error(tusb); | |
285 | break; | |
286 | } | |
287 | ||
288 | /* Wait 400 ms for the charger detection FSM to finish */ | |
289 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_READ_DET, 400); | |
290 | break; | |
291 | case TUSB1210_CHG_DET_READ_DET: | |
292 | mutex_lock(&tusb->phy->mutex); | |
293 | ret = tusb1210_ulpi_read(tusb, TUSB1211_POWER_CONTROL, &val); | |
294 | mutex_unlock(&tusb->phy->mutex); | |
295 | if (ret) { | |
296 | tusb1210_chg_det_handle_ulpi_error(tusb); | |
297 | break; | |
298 | } | |
299 | ||
300 | if (val & TUSB1211_POWER_CONTROL_DET_COMP) | |
301 | tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_DCP); | |
302 | else | |
303 | tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_SDP); | |
304 | ||
305 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, 0); | |
306 | break; | |
307 | case TUSB1210_CHG_DET_FINISH_DET: | |
308 | mutex_lock(&tusb->phy->mutex); | |
309 | ||
310 | /* Set SW_CONTROL to stop the charger-det FSM */ | |
311 | ret = tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_SET, | |
312 | TUSB1211_POWER_CONTROL_SW_CONTROL); | |
313 | ||
314 | /* Clear DP_VSRC_EN which may have been enabled by the charger-det FSM */ | |
315 | ret |= tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_CLEAR, | |
316 | TUSB1211_POWER_CONTROL_DP_VSRC_EN); | |
317 | ||
318 | /* Clear CHGD_IDP_SRC_EN (may have been enabled by the charger-det FSM) */ | |
319 | ret |= tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_CLEAR, | |
320 | TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN); | |
321 | ||
322 | /* If any of the above fails reset the phy */ | |
323 | if (ret) { | |
324 | tusb1210_reset(tusb); | |
325 | msleep(TUSB1210_RESET_TIME_MS); | |
326 | } | |
327 | ||
328 | /* Restore phy-parameters and OTG_CTRL register */ | |
329 | tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, tusb->otg_ctrl); | |
330 | tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, | |
331 | tusb->vendor_specific2); | |
332 | ||
333 | mutex_unlock(&tusb->phy->mutex); | |
334 | ||
335 | pm_runtime_put(tusb->ulpi->dev.parent); | |
336 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0); | |
337 | break; | |
338 | case TUSB1210_CHG_DET_CONNECTED: | |
339 | if (!vbus_present) | |
340 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING, 0); | |
341 | break; | |
342 | case TUSB1210_CHG_DET_DISCONNECTING: | |
343 | /* | |
344 | * The phy seems to take approx. 600ms longer then the charger | |
345 | * chip (which is used to get vbus_present) to determine Vbus | |
346 | * session end. Wait 800ms to ensure the phy has detected and | |
347 | * signalled Vbus session end. | |
348 | */ | |
349 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING_DONE, 800); | |
350 | break; | |
351 | case TUSB1210_CHG_DET_DISCONNECTING_DONE: | |
352 | /* | |
353 | * The phy often stops reacting to ulpi_read()/_write requests | |
354 | * after a Vbus-session end. Reset it to work around this. | |
355 | */ | |
356 | tusb1210_reset(tusb); | |
357 | tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_UNKNOWN); | |
358 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTED, 0); | |
359 | break; | |
360 | case TUSB1210_CHG_DET_DISCONNECTED: | |
361 | if (vbus_present) | |
362 | tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTING, 0); | |
363 | break; | |
364 | } | |
365 | } | |
366 | ||
367 | static int tusb1210_psy_notifier(struct notifier_block *nb, | |
368 | unsigned long event, void *ptr) | |
369 | { | |
370 | struct tusb1210 *tusb = container_of(nb, struct tusb1210, psy_nb); | |
371 | struct power_supply *psy = ptr; | |
372 | ||
373 | if (psy != tusb->psy && psy->desc->type == POWER_SUPPLY_TYPE_USB) | |
374 | queue_delayed_work(system_long_wq, &tusb->chg_det_work, 0); | |
375 | ||
376 | return NOTIFY_OK; | |
377 | } | |
378 | ||
379 | static int tusb1210_psy_get_prop(struct power_supply *psy, | |
380 | enum power_supply_property psp, | |
381 | union power_supply_propval *val) | |
382 | { | |
383 | struct tusb1210 *tusb = power_supply_get_drvdata(psy); | |
384 | ||
385 | switch (psp) { | |
386 | case POWER_SUPPLY_PROP_ONLINE: | |
387 | val->intval = tusb1210_get_online(tusb); | |
388 | break; | |
389 | case POWER_SUPPLY_PROP_USB_TYPE: | |
390 | val->intval = tusb->chg_type; | |
391 | break; | |
392 | case POWER_SUPPLY_PROP_CURRENT_MAX: | |
393 | if (tusb->chg_type == POWER_SUPPLY_USB_TYPE_DCP) | |
394 | val->intval = 2000000; | |
395 | else | |
396 | val->intval = 500000; | |
397 | break; | |
398 | default: | |
399 | return -EINVAL; | |
400 | } | |
401 | ||
402 | return 0; | |
403 | } | |
404 | ||
405 | static const enum power_supply_usb_type tusb1210_psy_usb_types[] = { | |
406 | POWER_SUPPLY_USB_TYPE_SDP, | |
407 | POWER_SUPPLY_USB_TYPE_DCP, | |
408 | POWER_SUPPLY_USB_TYPE_UNKNOWN, | |
409 | }; | |
410 | ||
411 | static const enum power_supply_property tusb1210_psy_props[] = { | |
412 | POWER_SUPPLY_PROP_ONLINE, | |
413 | POWER_SUPPLY_PROP_USB_TYPE, | |
414 | POWER_SUPPLY_PROP_CURRENT_MAX, | |
415 | }; | |
416 | ||
417 | static const struct power_supply_desc tusb1210_psy_desc = { | |
418 | .name = "tusb1211-charger-detect", | |
419 | .type = POWER_SUPPLY_TYPE_USB, | |
420 | .usb_types = tusb1210_psy_usb_types, | |
421 | .num_usb_types = ARRAY_SIZE(tusb1210_psy_usb_types), | |
422 | .properties = tusb1210_psy_props, | |
423 | .num_properties = ARRAY_SIZE(tusb1210_psy_props), | |
424 | .get_property = tusb1210_psy_get_prop, | |
425 | }; | |
426 | ||
427 | /* Setup charger detection if requested, on errors continue without chg-det */ | |
428 | static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) | |
429 | { | |
430 | struct power_supply_config psy_cfg = { .drv_data = tusb }; | |
431 | struct device *dev = &tusb->ulpi->dev; | |
432 | int ret; | |
433 | ||
434 | if (!device_property_read_bool(dev->parent, "linux,phy_charger_detect")) | |
435 | return; | |
436 | ||
437 | if (tusb->ulpi->id.product != 0x1508) { | |
438 | dev_err(dev, "error charger detection is only supported on the TUSB1211\n"); | |
439 | return; | |
440 | } | |
441 | ||
442 | ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &tusb->otg_ctrl); | |
443 | if (ret) | |
444 | return; | |
445 | ||
446 | tusb->psy = power_supply_register(dev, &tusb1210_psy_desc, &psy_cfg); | |
447 | if (IS_ERR(tusb->psy)) | |
448 | return; | |
449 | ||
450 | /* | |
451 | * Delay initial run by 2 seconds to allow the charger driver, | |
452 | * which is used to determine vbus_present, to load. | |
453 | */ | |
454 | tusb->chg_det_state = TUSB1210_CHG_DET_DISCONNECTED; | |
455 | INIT_DELAYED_WORK(&tusb->chg_det_work, tusb1210_chg_det_work); | |
456 | queue_delayed_work(system_long_wq, &tusb->chg_det_work, 2 * HZ); | |
457 | ||
458 | tusb->psy_nb.notifier_call = tusb1210_psy_notifier; | |
459 | power_supply_reg_notifier(&tusb->psy_nb); | |
460 | } | |
461 | ||
462 | static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) | |
463 | { | |
464 | ||
465 | if (!IS_ERR_OR_NULL(tusb->psy)) { | |
466 | power_supply_unreg_notifier(&tusb->psy_nb); | |
467 | cancel_delayed_work_sync(&tusb->chg_det_work); | |
468 | power_supply_unregister(tusb->psy); | |
469 | } | |
470 | ||
471 | if (tusb->charger) | |
472 | power_supply_put(tusb->charger); | |
473 | } | |
474 | #else | |
475 | static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) { } | |
476 | static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) { } | |
477 | #endif | |
478 | ||
4a9e5ca1 | 479 | static const struct phy_ops phy_ops = { |
1c14905e HK |
480 | .power_on = tusb1210_power_on, |
481 | .power_off = tusb1210_power_off, | |
54fe3088 | 482 | .set_mode = tusb1210_set_mode, |
1c14905e HK |
483 | .owner = THIS_MODULE, |
484 | }; | |
485 | ||
486 | static int tusb1210_probe(struct ulpi *ulpi) | |
487 | { | |
1c14905e HK |
488 | struct tusb1210 *tusb; |
489 | u8 val, reg; | |
09a35126 | 490 | int ret; |
1c14905e HK |
491 | |
492 | tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL); | |
493 | if (!tusb) | |
494 | return -ENOMEM; | |
495 | ||
09a35126 HG |
496 | tusb->ulpi = ulpi; |
497 | ||
8e71c680 UKK |
498 | tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset", |
499 | GPIOD_OUT_LOW); | |
500 | if (IS_ERR(tusb->gpio_reset)) | |
501 | return PTR_ERR(tusb->gpio_reset); | |
502 | ||
503 | gpiod_set_value_cansleep(tusb->gpio_reset, 1); | |
504 | ||
505 | tusb->gpio_cs = devm_gpiod_get_optional(&ulpi->dev, "cs", | |
506 | GPIOD_OUT_LOW); | |
507 | if (IS_ERR(tusb->gpio_cs)) | |
508 | return PTR_ERR(tusb->gpio_cs); | |
509 | ||
510 | gpiod_set_value_cansleep(tusb->gpio_cs, 1); | |
1c14905e HK |
511 | |
512 | /* | |
513 | * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye | |
514 | * diagram optimization and DP/DM swap. | |
515 | */ | |
516 | ||
09a35126 HG |
517 | ret = tusb1210_ulpi_read(tusb, TUSB1210_VENDOR_SPECIFIC2, ®); |
518 | if (ret) | |
519 | return ret; | |
eb445a15 | 520 | |
1c14905e | 521 | /* High speed output drive strength configuration */ |
eb445a15 LB |
522 | if (!device_property_read_u8(&ulpi->dev, "ihstx", &val)) |
523 | u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK); | |
1c14905e HK |
524 | |
525 | /* High speed output impedance configuration */ | |
eb445a15 LB |
526 | if (!device_property_read_u8(&ulpi->dev, "zhsdrv", &val)) |
527 | u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK); | |
1c14905e HK |
528 | |
529 | /* DP/DM swap control */ | |
eb445a15 LB |
530 | if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val)) |
531 | u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK); | |
1c14905e | 532 | |
09a35126 HG |
533 | ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg); |
534 | if (ret) | |
535 | return ret; | |
536 | ||
eb445a15 | 537 | tusb->vendor_specific2 = reg; |
1c14905e | 538 | |
48969a56 SG |
539 | tusb1210_probe_charger_detect(tusb); |
540 | ||
1c14905e | 541 | tusb->phy = ulpi_phy_create(ulpi, &phy_ops); |
a9f17d0c CJ |
542 | if (IS_ERR(tusb->phy)) { |
543 | ret = PTR_ERR(tusb->phy); | |
544 | goto err_remove_charger; | |
545 | } | |
1c14905e | 546 | |
1c14905e HK |
547 | phy_set_drvdata(tusb->phy, tusb); |
548 | ulpi_set_drvdata(ulpi, tusb); | |
549 | return 0; | |
a9f17d0c CJ |
550 | |
551 | err_remove_charger: | |
552 | tusb1210_remove_charger_detect(tusb); | |
553 | return ret; | |
1c14905e HK |
554 | } |
555 | ||
556 | static void tusb1210_remove(struct ulpi *ulpi) | |
557 | { | |
558 | struct tusb1210 *tusb = ulpi_get_drvdata(ulpi); | |
559 | ||
560 | ulpi_phy_destroy(ulpi, tusb->phy); | |
48969a56 | 561 | tusb1210_remove_charger_detect(tusb); |
1c14905e HK |
562 | } |
563 | ||
564 | #define TI_VENDOR_ID 0x0451 | |
565 | ||
566 | static const struct ulpi_device_id tusb1210_ulpi_id[] = { | |
82d9d5e0 FB |
567 | { TI_VENDOR_ID, 0x1507, }, /* TUSB1210 */ |
568 | { TI_VENDOR_ID, 0x1508, }, /* TUSB1211 */ | |
1c14905e HK |
569 | { }, |
570 | }; | |
571 | MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id); | |
572 | ||
573 | static struct ulpi_driver tusb1210_driver = { | |
574 | .id_table = tusb1210_ulpi_id, | |
575 | .probe = tusb1210_probe, | |
576 | .remove = tusb1210_remove, | |
577 | .driver = { | |
578 | .name = "tusb1210", | |
579 | .owner = THIS_MODULE, | |
580 | }, | |
581 | }; | |
582 | ||
583 | module_ulpi_driver(tusb1210_driver); | |
584 | ||
585 | MODULE_AUTHOR("Intel Corporation"); | |
586 | MODULE_LICENSE("GPL v2"); | |
587 | MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver"); |