drivers/usb/typec/mux/wcd939x-usbss.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/typec/mux/wcd939x-usbss.c
Extension
.c
Size
23394 bytes
Lines
780
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 wcd939x_usbss {
	struct i2c_client *client;
	struct gpio_desc *reset_gpio;
	struct regulator *vdd_supply;

	/* used to serialize concurrent change requests */
	struct mutex lock;

	struct typec_switch_dev *sw;
	struct typec_mux_dev *mux;

	struct regmap *regmap;

	struct typec_mux *codec;
	struct typec_switch *codec_switch;

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

static const struct regmap_range_cfg wcd939x_usbss_ranges[] = {
	{
		.range_min = 0,
		.range_max = WCD_USBSS_MAX_REGISTER,
		.selector_reg = 0x0,
		.selector_mask = 0xff,
		.selector_shift = 0,
		.window_start = 0,
		.window_len = 0x100,
	},
};

static const struct regmap_config wcd939x_usbss_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = WCD_USBSS_MAX_REGISTER,
	.ranges = wcd939x_usbss_ranges,
	.num_ranges = ARRAY_SIZE(wcd939x_usbss_ranges),
};

/* Linearlizer coefficients for 32ohm load */
static const struct {
	unsigned int offset;
	unsigned int mask;
	unsigned int value;
} wcd939x_usbss_coeff_init[] = {
	{ WCD_USBSS_AUD_COEF_L_K5_0, GENMASK(7, 0), 0x39 },
	{ WCD_USBSS_AUD_COEF_R_K5_0, GENMASK(7, 0), 0x39 },
	{ WCD_USBSS_GND_COEF_L_K2_0, GENMASK(7, 0), 0xe8 },
	{ WCD_USBSS_GND_COEF_L_K4_0, GENMASK(7, 0), 0x73 },
	{ WCD_USBSS_GND_COEF_R_K2_0, GENMASK(7, 0), 0xe8 },
	{ WCD_USBSS_GND_COEF_R_K4_0, GENMASK(7, 0), 0x73 },
	{ WCD_USBSS_RATIO_SPKR_REXT_L_LSB, GENMASK(7, 0), 0x00 },
	{ WCD_USBSS_RATIO_SPKR_REXT_L_MSB, GENMASK(6, 0), 0x04 },
	{ WCD_USBSS_RATIO_SPKR_REXT_R_LSB, GENMASK(7, 0), 0x00 },
	{ WCD_USBSS_RATIO_SPKR_REXT_R_MSB, GENMASK(6, 0), 0x04 },
};

static int wcd939x_usbss_set(struct wcd939x_usbss *usbss)
{
	bool reverse = (usbss->orientation == TYPEC_ORIENTATION_REVERSE);
	bool enable_audio = false;
	bool enable_usb = false;
	bool enable_dp = false;
	int ret;

	/* USB Mode */
	if (usbss->mode < TYPEC_STATE_MODAL ||
	    (!usbss->svid && (usbss->mode == TYPEC_MODE_USB2 ||
			      usbss->mode == TYPEC_MODE_USB3))) {
		enable_usb = true;
	} else if (usbss->svid) {
		switch (usbss->mode) {
		/* DP Only */
		case TYPEC_DP_STATE_C:
		case TYPEC_DP_STATE_E:
			enable_dp = true;
			break;

		/* DP + USB */
		case TYPEC_DP_STATE_D:
		case TYPEC_DP_STATE_F:
			enable_usb = true;
			enable_dp = true;
			break;

		default:
			return -EOPNOTSUPP;
		}

Annotation

Implementation Notes