drivers/usb/typec/mux/nb7vpq904m.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/typec/mux/nb7vpq904m.c
Extension
.c
Size
13070 bytes
Lines
528
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 nb7vpq904m {
	struct i2c_client *client;
	struct gpio_desc *enable_gpio;
	struct regulator *vcc_supply;
	struct regmap *regmap;
	struct typec_switch_dev *sw;
	struct typec_retimer *retimer;

	bool swap_data_lanes;
	struct typec_switch *typec_switch;
	struct typec_mux *typec_mux;

	struct mutex lock; /* protect non-concurrent retimer & switch */

	enum typec_orientation orientation;
	unsigned long mode;
	unsigned int svid;
};

static void nb7vpq904m_set_channel(struct nb7vpq904m *nb7, unsigned int channel, bool dp)
{
	u8 eq, out_comp, flat_gain, loss_match;

	if (dp) {
		eq = NB7_IS_CHAN_AD(channel) ? 0x6 : 0x4;
		out_comp = 0x3;
		flat_gain = NB7_IS_CHAN_AD(channel) ? 0x2 : 0x1;
		loss_match = 0x3;
	} else {
		eq = 0x4;
		out_comp = 0x3;
		flat_gain = NB7_IS_CHAN_AD(channel) ? 0x3 : 0x1;
		loss_match = NB7_IS_CHAN_AD(channel) ? 0x1 : 0x3;
	}

	regmap_update_bits(nb7->regmap, EQ_SETTING_REG(channel),
			   EQ_SETTING_MASK, FIELD_PREP(EQ_SETTING_MASK, eq));
	regmap_update_bits(nb7->regmap, OUTPUT_COMPRESSION_AND_POL_REG(channel),
			   OUTPUT_COMPRESSION_MASK, FIELD_PREP(OUTPUT_COMPRESSION_MASK, out_comp));
	regmap_update_bits(nb7->regmap, FLAT_GAIN_REG(channel),
			   FLAT_GAIN_MASK, FIELD_PREP(FLAT_GAIN_MASK, flat_gain));
	regmap_update_bits(nb7->regmap, LOSS_MATCH_REG(channel),
			   LOSS_MATCH_MASK, FIELD_PREP(LOSS_MATCH_MASK, loss_match));
}

static int nb7vpq904m_set(struct nb7vpq904m *nb7)
{
	bool reverse = (nb7->orientation == TYPEC_ORIENTATION_REVERSE);

	switch (nb7->mode) {
	case TYPEC_STATE_SAFE:
		regmap_write(nb7->regmap, GEN_DEV_SET_REG,
			     GEN_DEV_SET_CHIP_EN |
			     GEN_DEV_SET_CHNA_EN |
			     GEN_DEV_SET_CHNB_EN |
			     GEN_DEV_SET_CHNC_EN |
			     GEN_DEV_SET_CHND_EN |
			     FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK,
					GEN_DEV_SET_OP_MODE_USB));
		nb7vpq904m_set_channel(nb7, NB7_CHNA, false);
		nb7vpq904m_set_channel(nb7, NB7_CHNB, false);
		nb7vpq904m_set_channel(nb7, NB7_CHNC, false);
		nb7vpq904m_set_channel(nb7, NB7_CHND, false);
		regmap_write(nb7->regmap, AUX_CC_REG, 0x2);

		return 0;

	case TYPEC_STATE_USB:
		/*
		 * Normal Orientation (CC1)
		 * A -> USB RX
		 * B -> USB TX
		 * C -> X
		 * D -> X
		 * Flipped Orientation (CC2)
		 * A -> X
		 * B -> X
		 * C -> USB TX
		 * D -> USB RX
		 *
		 * Reversed if data lanes are swapped
		 */
		if (reverse ^ nb7->swap_data_lanes) {
			regmap_write(nb7->regmap, GEN_DEV_SET_REG,
				     GEN_DEV_SET_CHIP_EN |
				     GEN_DEV_SET_CHNA_EN |
				     GEN_DEV_SET_CHNB_EN |
				     FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK,
						GEN_DEV_SET_OP_MODE_USB));
			nb7vpq904m_set_channel(nb7, NB7_CHNA, false);

Annotation

Implementation Notes