drivers/usb/typec/mux/gpio-sbu-mux.c

Source file repositories/reference/linux-study-clean/drivers/usb/typec/mux/gpio-sbu-mux.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/typec/mux/gpio-sbu-mux.c
Extension
.c
Size
4050 bytes
Lines
172
Domain
Driver Families
Bucket
drivers/usb
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

struct gpio_sbu_mux {
	struct gpio_desc *enable_gpio;
	struct gpio_desc *select_gpio;

	struct typec_switch_dev *sw;
	struct typec_mux_dev *mux;

	struct mutex lock; /* protect enabled and swapped */
	bool enabled;
	bool swapped;
};

static int gpio_sbu_switch_set(struct typec_switch_dev *sw,
			       enum typec_orientation orientation)
{
	struct gpio_sbu_mux *sbu_mux = typec_switch_get_drvdata(sw);
	bool enabled;
	bool swapped;

	mutex_lock(&sbu_mux->lock);

	enabled = sbu_mux->enabled;
	swapped = sbu_mux->swapped;

	switch (orientation) {
	case TYPEC_ORIENTATION_NONE:
		enabled = false;
		break;
	case TYPEC_ORIENTATION_NORMAL:
		swapped = false;
		break;
	case TYPEC_ORIENTATION_REVERSE:
		swapped = true;
		break;
	}

	if (enabled != sbu_mux->enabled)
		gpiod_set_value_cansleep(sbu_mux->enable_gpio, enabled);

	if (swapped != sbu_mux->swapped)
		gpiod_set_value_cansleep(sbu_mux->select_gpio, swapped);

	sbu_mux->enabled = enabled;
	sbu_mux->swapped = swapped;

	mutex_unlock(&sbu_mux->lock);

	return 0;
}

static int gpio_sbu_mux_set(struct typec_mux_dev *mux,
			    struct typec_mux_state *state)
{
	struct gpio_sbu_mux *sbu_mux = typec_mux_get_drvdata(mux);

	if (!sbu_mux->enable_gpio)
		return -EOPNOTSUPP;

	mutex_lock(&sbu_mux->lock);

	switch (state->mode) {
	case TYPEC_STATE_SAFE:
	case TYPEC_STATE_USB:
		sbu_mux->enabled = false;
		break;
	case TYPEC_DP_STATE_C:
	case TYPEC_DP_STATE_D:
	case TYPEC_DP_STATE_E:
		sbu_mux->enabled = true;
		break;
	default:
		break;
	}

	gpiod_set_value_cansleep(sbu_mux->enable_gpio, sbu_mux->enabled);

	mutex_unlock(&sbu_mux->lock);

	return 0;
}

static int gpio_sbu_mux_probe(struct platform_device *pdev)
{
	struct typec_switch_desc sw_desc = { };
	struct typec_mux_desc mux_desc = { };
	struct device *dev = &pdev->dev;
	struct gpio_sbu_mux *sbu_mux;

	sbu_mux = devm_kzalloc(dev, sizeof(*sbu_mux), GFP_KERNEL);
	if (!sbu_mux)

Annotation

Implementation Notes