drivers/platform/chrome/cros_ec_typec.c

Source file repositories/reference/linux-study-clean/drivers/platform/chrome/cros_ec_typec.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/chrome/cros_ec_typec.c
Extension
.c
Size
41587 bytes
Lines
1469
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (role != target_role) {
			dev_err(data->dev, "Data role swap failed despite EC returning success\n");
			return -EIO;
		}
		typec_set_data_role(tc_port, target_role);
		break;
	case USB_PD_CTRL_SWAP_POWER:
		role = resp.role & PD_CTRL_RESP_ROLE_POWER ? TYPEC_SOURCE : TYPEC_SINK;
		if (role != target_role) {
			dev_err(data->dev, "Power role swap failed despite EC returning success\n");
			return -EIO;
		}
		typec_set_pwr_role(tc_port, target_role);
		break;
	default:
		/* Should never execute */
		break;
	}

	return 0;
}

static int cros_typec_dr_swap(struct typec_port *port, enum typec_data_role role)
{
	return cros_typec_perform_role_swap(port, role, USB_PD_CTRL_SWAP_DATA);
}

static int cros_typec_pr_swap(struct typec_port *port, enum typec_role role)
{
	return cros_typec_perform_role_swap(port, role, USB_PD_CTRL_SWAP_POWER);
}

static const struct typec_operations cros_typec_usb_mode_ops = {
	.enter_usb_mode = cros_typec_enter_usb_mode,
	.dr_set = cros_typec_dr_swap,
	.pr_set = cros_typec_pr_swap,
};

static int cros_typec_parse_port_props(struct typec_capability *cap,
				       struct fwnode_handle *fwnode,
				       struct device *dev)
{
	const char *buf;
	int ret;

	memset(cap, 0, sizeof(*cap));
	ret = fwnode_property_read_string(fwnode, "power-role", &buf);
	if (ret) {
		dev_err(dev, "power-role not found: %d\n", ret);
		return ret;
	}

	ret = typec_find_port_power_role(buf);
	if (ret < 0)
		return ret;
	cap->type = ret;

	ret = fwnode_property_read_string(fwnode, "data-role", &buf);
	if (ret) {
		dev_err(dev, "data-role not found: %d\n", ret);
		return ret;
	}

	ret = typec_find_port_data_role(buf);
	if (ret < 0)
		return ret;
	cap->data = ret;

	/* Try-power-role is optional. */
	ret = fwnode_property_read_string(fwnode, "try-power-role", &buf);
	if (ret) {
		dev_warn(dev, "try-power-role not found: %d\n", ret);
		cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
	} else {
		ret = typec_find_power_role(buf);
		if (ret < 0)
			return ret;
		cap->prefer_role = ret;
	}

	if (fwnode_property_present(fwnode, "usb2-port"))
		cap->usb_capability |= USB_CAPABILITY_USB2;
	if (fwnode_property_present(fwnode, "usb3-port"))
		cap->usb_capability |= USB_CAPABILITY_USB3;
	if (fwnode_property_present(fwnode, "usb4-port"))
		cap->usb_capability |= USB_CAPABILITY_USB4;

	cros_typec_role_switch_quirk(fwnode);

	cap->fwnode = fwnode;

Annotation

Implementation Notes