sound/soc/uniphier/aio-core.c

Source file repositories/reference/linux-study-clean/sound/soc/uniphier/aio-core.c

File Facts

System
Linux kernel
Corpus path
sound/soc/uniphier/aio-core.c
Extension
.c
Size
32054 bytes
Lines
1267
Domain
Driver Families
Bucket
sound/soc
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 (sub->swm->dir == PORT_DIR_INPUT) {
			regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
				     MAPCTR0_EN | sub->swm->iif.map);
			regmap_write(r, A2IPORTNMAPCTR0(sub->swm->iport.hw),
				     MAPCTR0_EN | sub->swm->iport.map);
		} else {
			regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
				     MAPCTR0_EN | sub->swm->oif.map);
			regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
				     MAPCTR0_EN | sub->swm->oport.map);
		}
		break;
	case PORT_TYPE_CONV:
		regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
			     MAPCTR0_EN | sub->swm->oif.map);
		regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
			     MAPCTR0_EN | sub->swm->oport.map);
		regmap_write(r, A2CHNMAPCTR0(sub->swm->och.hw),
			     MAPCTR0_EN | sub->swm->och.map);
		regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
			     MAPCTR0_EN | sub->swm->iif.map);
		break;
	default:
		dev_err(dev, "Unknown port type %d.\n", sub->swm->type);
		return -EINVAL;
	}

	return 0;
}

/**
 * aio_port_reset - reset AIO port block
 * @sub: the AIO substream pointer
 *
 * Resets the digital signal input/output port block of AIO.
 */
void aio_port_reset(struct uniphier_aio_sub *sub)
{
	struct regmap *r = sub->aio->chip->regmap;

	if (sub->swm->dir == PORT_DIR_OUTPUT) {
		regmap_write(r, AOUTRSTCTR0, BIT(sub->swm->oport.map));
		regmap_write(r, AOUTRSTCTR1, BIT(sub->swm->oport.map));
	} else {
		regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
				   IPORTMXRSTCTR_RSTPI_MASK,
				   IPORTMXRSTCTR_RSTPI_RESET);
		regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
				   IPORTMXRSTCTR_RSTPI_MASK,
				   IPORTMXRSTCTR_RSTPI_RELEASE);
	}
}

/**
 * aio_port_set_ch - set channels of LPCM
 * @sub: the AIO substream pointer, PCM substream only
 *
 * Set suitable slot selecting to input/output port block of AIO.
 *
 * This function may return error if non-PCM substream.
 *
 * Return: Zero if successful, otherwise a negative value on error.
 */
static int aio_port_set_ch(struct uniphier_aio_sub *sub)
{
	struct regmap *r = sub->aio->chip->regmap;
	static const u32 slotsel_2ch[] = {
		0, 0, 0, 0, 0,
	};
	static const u32 slotsel_multi[] = {
		OPORTMXTYSLOTCTR_SLOTSEL_SLOT0,
		OPORTMXTYSLOTCTR_SLOTSEL_SLOT1,
		OPORTMXTYSLOTCTR_SLOTSEL_SLOT2,
		OPORTMXTYSLOTCTR_SLOTSEL_SLOT3,
		OPORTMXTYSLOTCTR_SLOTSEL_SLOT4,
	};
	u32 mode;
	const u32 *slotsel;
	int i;

	switch (params_channels(&sub->params)) {
	case 8:
	case 6:
		mode = OPORTMXTYSLOTCTR_MODE;
		slotsel = slotsel_multi;
		break;
	case 2:
		mode = 0;
		slotsel = slotsel_2ch;
		break;

Annotation

Implementation Notes