Lines Matching refs:tusb

71 static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)  in tusb1210_ulpi_write()  argument
75 ret = ulpi_write(tusb->ulpi, reg, val); in tusb1210_ulpi_write()
77 dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n", in tusb1210_ulpi_write()
83 static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val) in tusb1210_ulpi_read() argument
87 ret = ulpi_read(tusb->ulpi, reg); in tusb1210_ulpi_read()
92 dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg); in tusb1210_ulpi_read()
100 struct tusb1210 *tusb = phy_get_drvdata(phy); in tusb1210_power_on() local
102 gpiod_set_value_cansleep(tusb->gpio_reset, 1); in tusb1210_power_on()
103 gpiod_set_value_cansleep(tusb->gpio_cs, 1); in tusb1210_power_on()
108 tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, tusb->vendor_specific2); in tusb1210_power_on()
115 struct tusb1210 *tusb = phy_get_drvdata(phy); in tusb1210_power_off() local
117 gpiod_set_value_cansleep(tusb->gpio_reset, 0); in tusb1210_power_off()
118 gpiod_set_value_cansleep(tusb->gpio_cs, 0); in tusb1210_power_off()
125 struct tusb1210 *tusb = phy_get_drvdata(phy); in tusb1210_set_mode() local
129 ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &reg); in tusb1210_set_mode()
139 tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); in tusb1210_set_mode()
146 tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); in tusb1210_set_mode()
154 tusb->otg_ctrl = reg; in tusb1210_set_mode()
155 return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg); in tusb1210_set_mode()
170 static void tusb1210_reset(struct tusb1210 *tusb) in tusb1210_reset() argument
172 gpiod_set_value_cansleep(tusb->gpio_reset, 0); in tusb1210_reset()
174 gpiod_set_value_cansleep(tusb->gpio_reset, 1); in tusb1210_reset()
177 static void tusb1210_chg_det_set_type(struct tusb1210 *tusb, in tusb1210_chg_det_set_type() argument
180 dev_dbg(&tusb->ulpi->dev, "charger type: %d\n", type); in tusb1210_chg_det_set_type()
181 tusb->chg_type = type; in tusb1210_chg_det_set_type()
182 tusb->chg_det_retries = 0; in tusb1210_chg_det_set_type()
183 power_supply_changed(tusb->psy); in tusb1210_chg_det_set_type()
186 static void tusb1210_chg_det_set_state(struct tusb1210 *tusb, in tusb1210_chg_det_set_state() argument
191 dev_dbg(&tusb->ulpi->dev, "chg_det new state %s in %d ms\n", in tusb1210_chg_det_set_state()
194 tusb->chg_det_state = new_state; in tusb1210_chg_det_set_state()
195 mod_delayed_work(system_long_wq, &tusb->chg_det_work, in tusb1210_chg_det_set_state()
199 static void tusb1210_chg_det_handle_ulpi_error(struct tusb1210 *tusb) in tusb1210_chg_det_handle_ulpi_error() argument
201 tusb1210_reset(tusb); in tusb1210_chg_det_handle_ulpi_error()
202 if (tusb->chg_det_retries < TUSB1210_CHG_DET_MAX_RETRIES) { in tusb1210_chg_det_handle_ulpi_error()
203 tusb->chg_det_retries++; in tusb1210_chg_det_handle_ulpi_error()
204 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, in tusb1210_chg_det_handle_ulpi_error()
207 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, in tusb1210_chg_det_handle_ulpi_error()
231 static bool tusb1210_get_online(struct tusb1210 *tusb) in tusb1210_get_online() argument
255 struct tusb1210 *tusb = container_of(work, struct tusb1210, chg_det_work.work); in tusb1210_chg_det_work() local
256 bool vbus_present = tusb1210_get_online(tusb); in tusb1210_chg_det_work()
260 dev_dbg(&tusb->ulpi->dev, "chg_det state %s vbus_present %d\n", in tusb1210_chg_det_work()
261 tusb1210_chg_det_states[tusb->chg_det_state], vbus_present); in tusb1210_chg_det_work()
263 switch (tusb->chg_det_state) { in tusb1210_chg_det_work()
265 tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN; in tusb1210_chg_det_work()
266 tusb->chg_det_retries = 0; in tusb1210_chg_det_work()
268 ret = pm_runtime_resume_and_get(tusb->ulpi->dev.parent); in tusb1210_chg_det_work()
270 dev_err(&tusb->ulpi->dev, "error %d runtime-resuming\n", ret); in tusb1210_chg_det_work()
272 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0); in tusb1210_chg_det_work()
275 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, 0); in tusb1210_chg_det_work()
283 mutex_lock(&tusb->phy->mutex); in tusb1210_chg_det_work()
284 ret = tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_SET, in tusb1210_chg_det_work()
286 mutex_unlock(&tusb->phy->mutex); in tusb1210_chg_det_work()
288 tusb1210_chg_det_handle_ulpi_error(tusb); in tusb1210_chg_det_work()
293 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_READ_DET, 400); in tusb1210_chg_det_work()
296 mutex_lock(&tusb->phy->mutex); in tusb1210_chg_det_work()
297 ret = tusb1210_ulpi_read(tusb, TUSB1211_POWER_CONTROL, &val); in tusb1210_chg_det_work()
298 mutex_unlock(&tusb->phy->mutex); in tusb1210_chg_det_work()
300 tusb1210_chg_det_handle_ulpi_error(tusb); in tusb1210_chg_det_work()
305 tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_DCP); in tusb1210_chg_det_work()
307 tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_SDP); in tusb1210_chg_det_work()
309 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, 0); in tusb1210_chg_det_work()
312 mutex_lock(&tusb->phy->mutex); in tusb1210_chg_det_work()
315 ret = tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_SET, in tusb1210_chg_det_work()
319 ret |= tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_CLEAR, in tusb1210_chg_det_work()
323 ret |= tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_CLEAR, in tusb1210_chg_det_work()
328 tusb1210_reset(tusb); in tusb1210_chg_det_work()
333 tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, tusb->otg_ctrl); in tusb1210_chg_det_work()
334 tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, in tusb1210_chg_det_work()
335 tusb->vendor_specific2); in tusb1210_chg_det_work()
337 mutex_unlock(&tusb->phy->mutex); in tusb1210_chg_det_work()
339 pm_runtime_put(tusb->ulpi->dev.parent); in tusb1210_chg_det_work()
340 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0); in tusb1210_chg_det_work()
344 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING, 0); in tusb1210_chg_det_work()
353 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING_DONE, 800); in tusb1210_chg_det_work()
360 tusb1210_reset(tusb); in tusb1210_chg_det_work()
361 tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_UNKNOWN); in tusb1210_chg_det_work()
362 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTED, 0); in tusb1210_chg_det_work()
366 tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTING, 0); in tusb1210_chg_det_work()
374 struct tusb1210 *tusb = container_of(nb, struct tusb1210, psy_nb); in tusb1210_psy_notifier() local
377 if (psy != tusb->psy && psy->desc->type == POWER_SUPPLY_TYPE_USB) in tusb1210_psy_notifier()
378 queue_delayed_work(system_long_wq, &tusb->chg_det_work, 0); in tusb1210_psy_notifier()
387 struct tusb1210 *tusb = power_supply_get_drvdata(psy); in tusb1210_psy_get_prop() local
391 val->intval = tusb1210_get_online(tusb); in tusb1210_psy_get_prop()
394 val->intval = tusb->chg_type; in tusb1210_psy_get_prop()
397 if (tusb->chg_type == POWER_SUPPLY_USB_TYPE_DCP) in tusb1210_psy_get_prop()
432 static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) in tusb1210_probe_charger_detect() argument
434 struct power_supply_config psy_cfg = { .drv_data = tusb }; in tusb1210_probe_charger_detect()
435 struct device *dev = &tusb->ulpi->dev; in tusb1210_probe_charger_detect()
441 if (tusb->ulpi->id.product != 0x1508) { in tusb1210_probe_charger_detect()
446 ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &tusb->otg_ctrl); in tusb1210_probe_charger_detect()
450 tusb->psy = power_supply_register(dev, &tusb1210_psy_desc, &psy_cfg); in tusb1210_probe_charger_detect()
451 if (IS_ERR(tusb->psy)) in tusb1210_probe_charger_detect()
458 tusb->chg_det_state = TUSB1210_CHG_DET_DISCONNECTED; in tusb1210_probe_charger_detect()
459 INIT_DELAYED_WORK(&tusb->chg_det_work, tusb1210_chg_det_work); in tusb1210_probe_charger_detect()
460 queue_delayed_work(system_long_wq, &tusb->chg_det_work, 2 * HZ); in tusb1210_probe_charger_detect()
462 tusb->psy_nb.notifier_call = tusb1210_psy_notifier; in tusb1210_probe_charger_detect()
463 power_supply_reg_notifier(&tusb->psy_nb); in tusb1210_probe_charger_detect()
466 static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) in tusb1210_remove_charger_detect() argument
469 if (!IS_ERR_OR_NULL(tusb->psy)) { in tusb1210_remove_charger_detect()
470 power_supply_unreg_notifier(&tusb->psy_nb); in tusb1210_remove_charger_detect()
471 cancel_delayed_work_sync(&tusb->chg_det_work); in tusb1210_remove_charger_detect()
472 power_supply_unregister(tusb->psy); in tusb1210_remove_charger_detect()
476 static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) { } in tusb1210_probe_charger_detect() argument
477 static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) { } in tusb1210_remove_charger_detect() argument
489 struct tusb1210 *tusb; in tusb1210_probe() local
493 tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL); in tusb1210_probe()
494 if (!tusb) in tusb1210_probe()
497 tusb->ulpi = ulpi; in tusb1210_probe()
499 tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset", in tusb1210_probe()
501 if (IS_ERR(tusb->gpio_reset)) in tusb1210_probe()
502 return PTR_ERR(tusb->gpio_reset); in tusb1210_probe()
504 gpiod_set_value_cansleep(tusb->gpio_reset, 1); in tusb1210_probe()
506 tusb->gpio_cs = devm_gpiod_get_optional(&ulpi->dev, "cs", in tusb1210_probe()
508 if (IS_ERR(tusb->gpio_cs)) in tusb1210_probe()
509 return PTR_ERR(tusb->gpio_cs); in tusb1210_probe()
511 gpiod_set_value_cansleep(tusb->gpio_cs, 1); in tusb1210_probe()
518 ret = tusb1210_ulpi_read(tusb, TUSB1210_VENDOR_SPECIFIC2, &reg); in tusb1210_probe()
534 ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg); in tusb1210_probe()
538 tusb->vendor_specific2 = reg; in tusb1210_probe()
540 tusb1210_probe_charger_detect(tusb); in tusb1210_probe()
542 tusb->phy = ulpi_phy_create(ulpi, &phy_ops); in tusb1210_probe()
543 if (IS_ERR(tusb->phy)) { in tusb1210_probe()
544 ret = PTR_ERR(tusb->phy); in tusb1210_probe()
548 phy_set_drvdata(tusb->phy, tusb); in tusb1210_probe()
549 ulpi_set_drvdata(ulpi, tusb); in tusb1210_probe()
553 tusb1210_remove_charger_detect(tusb); in tusb1210_probe()
559 struct tusb1210 *tusb = ulpi_get_drvdata(ulpi); in tusb1210_remove() local
561 ulpi_phy_destroy(ulpi, tusb->phy); in tusb1210_remove()
562 tusb1210_remove_charger_detect(tusb); in tusb1210_remove()