drivers/usb/typec/mux/it5205.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/typec/mux/it5205.c
Extension
.c
Size
7644 bytes
Lines
295
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 it5205 {
	struct i2c_client *client;
	struct regmap *regmap;
	struct typec_switch_dev *sw;
	struct typec_mux_dev *mux;
};

static int it5205_switch_set(struct typec_switch_dev *sw, enum typec_orientation orientation)
{
	struct it5205 *it = typec_switch_get_drvdata(sw);

	switch (orientation) {
	case TYPEC_ORIENTATION_NORMAL:
		regmap_update_bits(it->regmap, IT5205_REG_MUXCR,
				   IT5205_POLARITY_INVERTED, 0);
		break;
	case TYPEC_ORIENTATION_REVERSE:
		regmap_update_bits(it->regmap, IT5205_REG_MUXCR,
				   IT5205_POLARITY_INVERTED, IT5205_POLARITY_INVERTED);
		break;
	case TYPEC_ORIENTATION_NONE:
		fallthrough;
	default:
		regmap_write(it->regmap, IT5205_REG_MUXCR, 0);
		break;
	}

	return 0;
}

static int it5205_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
{
	struct it5205 *it = typec_mux_get_drvdata(mux);
	u8 val;

	if (state->mode >= TYPEC_STATE_MODAL &&
	    state->alt->svid != USB_TYPEC_DP_SID)
		return -EINVAL;

	switch (state->mode) {
	case TYPEC_STATE_USB:
		val = IT5205_USB;
		break;
	case TYPEC_DP_STATE_C:
		fallthrough;
	case TYPEC_DP_STATE_E:
		val = IT5205_DP;
		break;
	case TYPEC_DP_STATE_D:
		val = IT5205_DP_USB;
		break;
	case TYPEC_STATE_SAFE:
		fallthrough;
	default:
		val = 0;
		break;
	}

	return regmap_update_bits(it->regmap, IT5205_REG_MUXCR,
				  IT5205_DP_USB_CTRL_MASK, val);
}

static irqreturn_t it5205_irq_handler(int irq, void *data)
{
	struct it5205 *it = data;
	int ret;
	u32 val;

	ret = regmap_read(it->regmap, IT5205_REG_ISR, &val);
	if (ret)
		return IRQ_NONE;

	if (val & IT5205_ISR_CSBU_OVP) {
		dev_warn(&it->client->dev, "Overvoltage detected!\n");

		/* Reset CSBU */
		regmap_update_bits(it->regmap, IT5205_REG_CSBUSR,
				   IT5205_CSBUSR_SWITCH, 0);
		regmap_update_bits(it->regmap, IT5205_REG_CSBUSR,
				   IT5205_CSBUSR_SWITCH, IT5205_CSBUSR_SWITCH);
	}

	return IRQ_HANDLED;
}

static void it5205_enable_ovp(struct it5205 *it)
{
	/* Select Vref 3.3v */
	regmap_update_bits(it->regmap, IT5205_REG_VSR,
			   IT5205_VREF_SELECT_MASK, IT5205_VREF_SELECT_3_3V);

Annotation

Implementation Notes