Lines Matching +full:wait +full:- +full:pin +full:- +full:polarity
1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/extcon/extcon-tusb320.c - TUSB320 extcon driver
10 #include <linux/extcon-provider.h>
107 ret = regmap_read(priv->regmap, sizeof(sig) - 1 - i, &val); in tusb320_check_signature()
111 dev_err(priv->dev, "signature mismatch!\n"); in tusb320_check_signature()
112 return -ENODEV; in tusb320_check_signature()
124 if (priv->state != TUSB320_ATTACHED_STATE_NONE) in tusb320_set_mode()
125 return -EBUSY; in tusb320_set_mode()
128 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320_set_mode()
132 dev_err(priv->dev, "failed to write mode: %d\n", ret); in tusb320_set_mode()
144 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320l_set_mode()
147 dev_err(priv->dev, in tusb320l_set_mode()
153 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320l_set_mode()
157 dev_err(priv->dev, "failed to write mode: %d\n", ret); in tusb320l_set_mode()
163 /* Re-enable CC state machine */ in tusb320l_set_mode()
164 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320l_set_mode()
167 dev_err(priv->dev, in tusb320l_set_mode()
168 "failed to re-enable CC state machine: %d\n", ret); in tusb320l_set_mode()
177 /* Set mode to default (follow PORT pin) */ in tusb320_reset()
178 ret = priv->ops->set_mode(priv, TUSB320_MODE_PORT); in tusb320_reset()
179 if (ret && ret != -EBUSY) { in tusb320_reset()
180 dev_err(priv->dev, in tusb320_reset()
186 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320_reset()
189 dev_err(priv->dev, in tusb320_reset()
194 /* Wait for chip to go through reset */ in tusb320_reset()
202 return regmap_read(priv->regmap, TUSB320L_REGA0_REVISION, revision); in tusb320l_get_revision()
218 if (priv->pwr_opmode == TYPEC_PWR_MODE_USB) in tusb320_set_adv_pwr_mode()
220 else if (priv->pwr_opmode == TYPEC_PWR_MODE_1_5A) in tusb320_set_adv_pwr_mode()
222 else if (priv->pwr_opmode == TYPEC_PWR_MODE_3_0A) in tusb320_set_adv_pwr_mode()
225 return -EINVAL; in tusb320_set_adv_pwr_mode()
227 return regmap_write_bits(priv->regmap, TUSB320_REG8, in tusb320_set_adv_pwr_mode()
239 return priv->ops->set_mode(priv, TUSB320_MODE_DFP); in tusb320_port_type_set()
241 return priv->ops->set_mode(priv, TUSB320_MODE_UFP); in tusb320_port_type_set()
243 return priv->ops->set_mode(priv, TUSB320_MODE_DRP); in tusb320_port_type_set()
245 return priv->ops->set_mode(priv, TUSB320_MODE_PORT); in tusb320_port_type_set()
254 int state, polarity; in tusb320_extcon_irq_handler() local
257 polarity = !!(reg & TUSB320_REG9_CABLE_DIRECTION); in tusb320_extcon_irq_handler()
259 dev_dbg(priv->dev, "attached state: %s, polarity: %d\n", in tusb320_extcon_irq_handler()
260 tusb_attached_states[state], polarity); in tusb320_extcon_irq_handler()
262 extcon_set_state(priv->edev, EXTCON_USB, in tusb320_extcon_irq_handler()
264 extcon_set_state(priv->edev, EXTCON_USB_HOST, in tusb320_extcon_irq_handler()
266 extcon_set_property(priv->edev, EXTCON_USB, in tusb320_extcon_irq_handler()
268 (union extcon_property_value)polarity); in tusb320_extcon_irq_handler()
269 extcon_set_property(priv->edev, EXTCON_USB_HOST, in tusb320_extcon_irq_handler()
271 (union extcon_property_value)polarity); in tusb320_extcon_irq_handler()
272 extcon_sync(priv->edev, EXTCON_USB); in tusb320_extcon_irq_handler()
273 extcon_sync(priv->edev, EXTCON_USB_HOST); in tusb320_extcon_irq_handler()
275 priv->state = state; in tusb320_extcon_irq_handler()
280 struct typec_port *port = priv->port; in tusb320_typec_irq_handler()
281 struct device *dev = priv->dev; in tusb320_typec_irq_handler()
290 ret = regmap_read(priv->regmap, TUSB320_REG8, ®8); in tusb320_typec_irq_handler()
344 dev_warn(priv->dev, "unexpected ACCESSORY_CONNECTED state %d\n", in tusb320_typec_irq_handler()
360 usb_role_switch_set_role(priv->role_sw, usb_role); in tusb320_typec_irq_handler()
378 if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { in tusb320_state_update_handler()
379 dev_err(priv->dev, "error during i2c read!\n"); in tusb320_state_update_handler()
389 * Type-C support is optional. Only call the Type-C handler if a in tusb320_state_update_handler()
392 if (priv->port) in tusb320_state_update_handler()
395 regmap_write(priv->regmap, TUSB320_REG9, reg); in tusb320_state_update_handler()
416 priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); in tusb320_extcon_probe()
417 if (IS_ERR(priv->edev)) { in tusb320_extcon_probe()
418 dev_err(priv->dev, "failed to allocate extcon device\n"); in tusb320_extcon_probe()
419 return PTR_ERR(priv->edev); in tusb320_extcon_probe()
422 ret = devm_extcon_dev_register(priv->dev, priv->edev); in tusb320_extcon_probe()
424 dev_err(priv->dev, "failed to register extcon device\n"); in tusb320_extcon_probe()
428 extcon_set_property_capability(priv->edev, EXTCON_USB, in tusb320_extcon_probe()
430 extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, in tusb320_extcon_probe()
443 /* The Type-C connector is optional, for backward compatibility. */ in tusb320_typec_probe()
444 connector = device_get_named_child_node(&client->dev, "connector"); in tusb320_typec_probe()
448 /* Type-C connector found. */ in tusb320_typec_probe()
449 ret = typec_get_fw_cap(&priv->cap, connector); in tusb320_typec_probe()
453 priv->port_type = priv->cap.type; in tusb320_typec_probe()
456 ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str); in tusb320_typec_probe()
464 priv->pwr_opmode = ret; in tusb320_typec_probe()
471 priv->cap.revision = USB_TYPEC_REV_1_1; in tusb320_typec_probe()
472 priv->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO; in tusb320_typec_probe()
473 priv->cap.accessory[1] = TYPEC_ACCESSORY_DEBUG; in tusb320_typec_probe()
474 priv->cap.orientation_aware = true; in tusb320_typec_probe()
475 priv->cap.driver_data = priv; in tusb320_typec_probe()
476 priv->cap.ops = &tusb320_typec_ops; in tusb320_typec_probe()
477 priv->cap.fwnode = connector; in tusb320_typec_probe()
479 priv->port = typec_register_port(&client->dev, &priv->cap); in tusb320_typec_probe()
480 if (IS_ERR(priv->port)) { in tusb320_typec_probe()
481 ret = PTR_ERR(priv->port); in tusb320_typec_probe()
486 priv->role_sw = fwnode_usb_role_switch_get(connector); in tusb320_typec_probe()
487 if (IS_ERR(priv->role_sw)) { in tusb320_typec_probe()
488 ret = PTR_ERR(priv->role_sw); in tusb320_typec_probe()
492 priv->connector_fwnode = connector; in tusb320_typec_probe()
497 typec_unregister_port(priv->port); in tusb320_typec_probe()
507 usb_role_switch_put(priv->role_sw); in tusb320_typec_remove()
508 typec_unregister_port(priv->port); in tusb320_typec_remove()
509 fwnode_handle_put(priv->connector_fwnode); in tusb320_typec_remove()
519 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in tusb320_probe()
521 return -ENOMEM; in tusb320_probe()
523 priv->dev = &client->dev; in tusb320_probe()
526 priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config); in tusb320_probe()
527 if (IS_ERR(priv->regmap)) in tusb320_probe()
528 return PTR_ERR(priv->regmap); in tusb320_probe()
534 match_data = device_get_match_data(&client->dev); in tusb320_probe()
536 return -EINVAL; in tusb320_probe()
538 priv->ops = (struct tusb320_ops*)match_data; in tusb320_probe()
540 if (priv->ops->get_revision) { in tusb320_probe()
541 ret = priv->ops->get_revision(priv, &revision); in tusb320_probe()
543 dev_warn(priv->dev, in tusb320_probe()
546 dev_info(priv->dev, "chip revision %d\n", revision); in tusb320_probe()
563 dev_warn(priv->dev, "failed to reset chip: %d\n", ret); in tusb320_probe()
566 * State and polarity might change after a reset, so update in tusb320_probe()
571 ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, in tusb320_probe()
574 client->name, priv); in tusb320_probe()
599 .name = "extcon-tusb320",