sound/soc/renesas/hac.c

Source file repositories/reference/linux-study-clean/sound/soc/renesas/hac.c

File Facts

System
Linux kernel
Corpus path
sound/soc/renesas/hac.c
Extension
.c
Size
8072 bytes
Lines
345
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

struct hac_priv {
	unsigned long mmio;	/* HAC base address */
} hac_cpu_data[] = {
#if defined(CONFIG_CPU_SUBTYPE_SH7760)
	{
		.mmio	= 0xFE240000,
	},
	{
		.mmio	= 0xFE250000,
	},
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
	{
		.mmio	= 0xFFE40000,
	},
#else
#error "Unsupported SuperH SoC"
#endif
};

#define HACREG(reg)	(*(unsigned long *)(hac->mmio + (reg)))

/*
 * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906)
 */
static int hac_get_codec_data(struct hac_priv *hac, unsigned short r,
			      unsigned short *v)
{
	unsigned int to1, to2, i;
	unsigned short adr;

	for (i = AC97_READ_RETRY; i; i--) {
		*v = 0;
		/* wait for HAC to receive something from the codec */
		for (to1 = TMO_E4;
		     to1 && !(HACREG(HACRSR) & RSR_STARY);
		     --to1)
			udelay(1);
		for (to2 = TMO_E4; 
		     to2 && !(HACREG(HACRSR) & RSR_STDRY);
		     --to2)
			udelay(1);

		if (!to1 && !to2)
			return 0;	/* codec comm is down */

		adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT);
		*v  = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT);

		HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);

		if (r == adr)
			break;

		/* manual says: wait at least 21 usec before retrying */
		udelay(21);
	}
	HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
	return i;
}

static unsigned short hac_read_codec_aux(struct hac_priv *hac,
					 unsigned short reg)
{
	unsigned short val;
	unsigned int i, to;

	for (i = AC97_READ_RETRY; i; i--) {
		/* send_read_request */
		local_irq_disable();
		HACREG(HACTSR) &= ~(TSR_CMDAMT);
		HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD;
		local_irq_enable();

		for (to = TMO_E3;
		     to && !(HACREG(HACTSR) & TSR_CMDAMT);
		     --to)
			udelay(1);

		HACREG(HACTSR) &= ~TSR_CMDAMT;
		val = 0;
		if (hac_get_codec_data(hac, reg, &val) != 0)
			break;
	}

	return i ? val : ~0;
}

static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
			   unsigned short val)
{

Annotation

Implementation Notes