Lines Matching +full:accessory +full:- +full:mode +full:- +full:debug

1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/extcon/extcon-tusb320.c - TUSB320 extcon driver
10 #include <linux/extcon-provider.h>
70 int (*set_mode)(struct tusb320_priv *priv, enum tusb320_mode mode);
92 [TUSB320_ATTACHED_STATE_ACC] = "accessory",
108 ret = regmap_read(priv->regmap, sizeof(sig) - 1 - i, &val); in tusb320_check_signature()
112 dev_err(priv->dev, "signature mismatch!\n"); in tusb320_check_signature()
113 return -ENODEV; in tusb320_check_signature()
120 static int tusb320_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode) in tusb320_set_mode() argument
124 /* Mode cannot be changed while cable is attached */ in tusb320_set_mode()
125 if (priv->state != TUSB320_ATTACHED_STATE_NONE) in tusb320_set_mode()
126 return -EBUSY; in tusb320_set_mode()
128 /* Write mode */ in tusb320_set_mode()
129 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320_set_mode()
131 mode << TUSB320_REGA_MODE_SELECT_SHIFT); in tusb320_set_mode()
133 dev_err(priv->dev, "failed to write mode: %d\n", ret); in tusb320_set_mode()
140 static int tusb320l_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode) in tusb320l_set_mode() argument
145 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320l_set_mode()
148 dev_err(priv->dev, in tusb320l_set_mode()
153 /* Write mode */ in tusb320l_set_mode()
154 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320l_set_mode()
156 mode << TUSB320_REGA_MODE_SELECT_SHIFT); in tusb320l_set_mode()
158 dev_err(priv->dev, "failed to write mode: %d\n", ret); in tusb320l_set_mode()
164 /* Re-enable CC state machine */ in tusb320l_set_mode()
165 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320l_set_mode()
168 dev_err(priv->dev, in tusb320l_set_mode()
169 "failed to re-enable CC state machine: %d\n", ret); in tusb320l_set_mode()
178 /* Set mode to default (follow PORT pin) */ in tusb320_reset()
179 ret = priv->ops->set_mode(priv, TUSB320_MODE_PORT); in tusb320_reset()
180 if (ret && ret != -EBUSY) { in tusb320_reset()
181 dev_err(priv->dev, in tusb320_reset()
182 "failed to set mode to PORT: %d\n", ret); in tusb320_reset()
187 ret = regmap_write_bits(priv->regmap, TUSB320_REGA, in tusb320_reset()
190 dev_err(priv->dev, in tusb320_reset()
203 return regmap_read(priv->regmap, TUSB320L_REGA0_REVISION, revision); in tusb320l_get_revision()
217 u8 mode; in tusb320_set_adv_pwr_mode() local
219 if (priv->pwr_opmode == TYPEC_PWR_MODE_USB) in tusb320_set_adv_pwr_mode()
220 mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB; in tusb320_set_adv_pwr_mode()
221 else if (priv->pwr_opmode == TYPEC_PWR_MODE_1_5A) in tusb320_set_adv_pwr_mode()
222 mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A; in tusb320_set_adv_pwr_mode()
223 else if (priv->pwr_opmode == TYPEC_PWR_MODE_3_0A) in tusb320_set_adv_pwr_mode()
224 mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A; in tusb320_set_adv_pwr_mode()
225 else /* No other mode is supported. */ in tusb320_set_adv_pwr_mode()
226 return -EINVAL; in tusb320_set_adv_pwr_mode()
228 return regmap_write_bits(priv->regmap, TUSB320_REG8, in tusb320_set_adv_pwr_mode()
231 mode)); in tusb320_set_adv_pwr_mode()
240 return priv->ops->set_mode(priv, TUSB320_MODE_DFP); in tusb320_port_type_set()
242 return priv->ops->set_mode(priv, TUSB320_MODE_UFP); in tusb320_port_type_set()
244 return priv->ops->set_mode(priv, TUSB320_MODE_DRP); in tusb320_port_type_set()
246 return priv->ops->set_mode(priv, TUSB320_MODE_PORT); in tusb320_port_type_set()
260 dev_dbg(priv->dev, "attached state: %s, polarity: %d\n", in tusb320_extcon_irq_handler()
263 extcon_set_state(priv->edev, EXTCON_USB, in tusb320_extcon_irq_handler()
265 extcon_set_state(priv->edev, EXTCON_USB_HOST, in tusb320_extcon_irq_handler()
267 extcon_set_property(priv->edev, EXTCON_USB, in tusb320_extcon_irq_handler()
270 extcon_set_property(priv->edev, EXTCON_USB_HOST, in tusb320_extcon_irq_handler()
273 extcon_sync(priv->edev, EXTCON_USB); in tusb320_extcon_irq_handler()
274 extcon_sync(priv->edev, EXTCON_USB_HOST); in tusb320_extcon_irq_handler()
276 priv->state = state; in tusb320_extcon_irq_handler()
281 struct typec_port *port = priv->port; in tusb320_typec_irq_handler()
282 struct device *dev = priv->dev; in tusb320_typec_irq_handler()
287 u8 state, mode, accessory; in tusb320_typec_irq_handler() local
291 ret = regmap_read(priv->regmap, TUSB320_REG8, &reg8); in tusb320_typec_irq_handler()
302 accessory = FIELD_GET(TUSB320_REG8_ACCESSORY_CONNECTED, reg8); in tusb320_typec_irq_handler()
319 * Accessory detected. For debug accessories, just make some in tusb320_typec_irq_handler()
322 if (accessory == TUSB320_REG8_ACCESSORY_CONNECTED_AUDIO || in tusb320_typec_irq_handler()
323 accessory == TUSB320_REG8_ACCESSORY_CONNECTED_ACHRG) { in tusb320_typec_irq_handler()
329 } else if (accessory == in tusb320_typec_irq_handler()
336 } else if (accessory == in tusb320_typec_irq_handler()
345 dev_warn(priv->dev, "unexpected ACCESSORY_CONNECTED state %d\n", in tusb320_typec_irq_handler()
346 accessory); in tusb320_typec_irq_handler()
361 usb_role_switch_set_role(priv->role_sw, usb_role); in tusb320_typec_irq_handler()
363 mode = FIELD_GET(TUSB320_REG8_CURRENT_MODE_DETECT, reg8); in tusb320_typec_irq_handler()
364 if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_DEF) in tusb320_typec_irq_handler()
366 else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_MED) in tusb320_typec_irq_handler()
368 else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_HI) in tusb320_typec_irq_handler()
370 else /* Charge through accessory */ in tusb320_typec_irq_handler()
379 if (regmap_read(priv->regmap, TUSB320_REG9, &reg)) { in tusb320_state_update_handler()
380 dev_err(priv->dev, "error during i2c read!\n"); in tusb320_state_update_handler()
390 * Type-C support is optional. Only call the Type-C handler if a in tusb320_state_update_handler()
393 if (priv->port) in tusb320_state_update_handler()
396 regmap_write(priv->regmap, TUSB320_REG9, reg); in tusb320_state_update_handler()
417 priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); in tusb320_extcon_probe()
418 if (IS_ERR(priv->edev)) { in tusb320_extcon_probe()
419 dev_err(priv->dev, "failed to allocate extcon device\n"); in tusb320_extcon_probe()
420 return PTR_ERR(priv->edev); in tusb320_extcon_probe()
423 ret = devm_extcon_dev_register(priv->dev, priv->edev); in tusb320_extcon_probe()
425 dev_err(priv->dev, "failed to register extcon device\n"); in tusb320_extcon_probe()
429 extcon_set_property_capability(priv->edev, EXTCON_USB, in tusb320_extcon_probe()
431 extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, in tusb320_extcon_probe()
444 /* The Type-C connector is optional, for backward compatibility. */ in tusb320_typec_probe()
445 connector = device_get_named_child_node(&client->dev, "connector"); in tusb320_typec_probe()
449 /* Type-C connector found. */ in tusb320_typec_probe()
450 ret = typec_get_fw_cap(&priv->cap, connector); in tusb320_typec_probe()
454 priv->port_type = priv->cap.type; in tusb320_typec_probe()
457 ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str); in tusb320_typec_probe()
465 priv->pwr_opmode = ret; in tusb320_typec_probe()
472 priv->cap.revision = USB_TYPEC_REV_1_1; in tusb320_typec_probe()
473 priv->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO; in tusb320_typec_probe()
474 priv->cap.accessory[1] = TYPEC_ACCESSORY_DEBUG; in tusb320_typec_probe()
475 priv->cap.orientation_aware = true; in tusb320_typec_probe()
476 priv->cap.driver_data = priv; in tusb320_typec_probe()
477 priv->cap.ops = &tusb320_typec_ops; in tusb320_typec_probe()
478 priv->cap.fwnode = connector; in tusb320_typec_probe()
480 priv->port = typec_register_port(&client->dev, &priv->cap); in tusb320_typec_probe()
481 if (IS_ERR(priv->port)) { in tusb320_typec_probe()
482 ret = PTR_ERR(priv->port); in tusb320_typec_probe()
487 priv->role_sw = fwnode_usb_role_switch_get(connector); in tusb320_typec_probe()
488 if (IS_ERR(priv->role_sw)) { in tusb320_typec_probe()
489 ret = PTR_ERR(priv->role_sw); in tusb320_typec_probe()
493 priv->connector_fwnode = connector; in tusb320_typec_probe()
498 typec_unregister_port(priv->port); in tusb320_typec_probe()
508 usb_role_switch_put(priv->role_sw); in tusb320_typec_remove()
509 typec_unregister_port(priv->port); in tusb320_typec_remove()
510 fwnode_handle_put(priv->connector_fwnode); in tusb320_typec_remove()
522 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in tusb320_probe()
524 return -ENOMEM; in tusb320_probe()
526 priv->dev = &client->dev; in tusb320_probe()
529 priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config); in tusb320_probe()
530 if (IS_ERR(priv->regmap)) in tusb320_probe()
531 return PTR_ERR(priv->regmap); in tusb320_probe()
537 match_data = device_get_match_data(&client->dev); in tusb320_probe()
539 return -EINVAL; in tusb320_probe()
541 priv->ops = (struct tusb320_ops*)match_data; in tusb320_probe()
543 if (priv->ops->get_revision) { in tusb320_probe()
544 ret = priv->ops->get_revision(priv, &revision); in tusb320_probe()
546 dev_warn(priv->dev, in tusb320_probe()
549 dev_info(priv->dev, "chip revision %d\n", revision); in tusb320_probe()
566 dev_warn(priv->dev, "failed to reset chip: %d\n", ret); in tusb320_probe()
574 irq_d = irq_get_irq_data(client->irq); in tusb320_probe()
578 ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, in tusb320_probe()
581 client->name, priv); in tusb320_probe()
606 .name = "extcon-tusb320",