sound/isa/cmi8328.c

Source file repositories/reference/linux-study-clean/sound/isa/cmi8328.c

File Facts

System
Linux kernel
Corpus path
sound/isa/cmi8328.c
Extension
.c
Size
13432 bytes
Lines
461
Domain
Driver Families
Bucket
sound/isa
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 snd_cmi8328 {
	u16 port;
	u8 cfg[3];
	u8 wss_cfg;
	struct snd_card *card;
	struct snd_wss *wss;
#ifdef SUPPORT_JOYSTICK
	struct gameport *gameport;
#endif
};

/* CMI8328 configuration registers */
#define CFG1 0x61
#define CFG1_SB_DISABLE	(1 << 0)
#define CFG1_GAMEPORT	(1 << 1)
/*
 * bit 0:    SB: 0=enabled, 1=disabled
 * bit 1:    gameport: 0=disabled, 1=enabled
 * bits 2-4: SB IRQ: 001=3, 010=5, 011=7, 100=9, 101=10, 110=11
 * bits 5-6: SB DMA: 00=disabled (when SB disabled), 01=DMA0, 10=DMA1, 11=DMA3
 * bit 7:    SB port: 0=0x220, 1=0x240
 */
#define CFG2 0x62
#define CFG2_MPU_ENABLE (1 << 2)
/*
 * bits 0-1: CD-ROM mode: 00=disabled, 01=Panasonic, 10=Sony/Mitsumi/Wearnes,
			  11=IDE
 * bit 2:    MPU401: 0=disabled, 1=enabled
 * bits 3-4: MPU401 IRQ: 00=3, 01=5, 10=7, 11=9,
 * bits 5-7: MPU401 port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x332,
			  101=0x334, 110=0x336
 */
#define CFG3 0x63
/*
 * bits 0-2: CD-ROM IRQ: 000=disabled, 001=3, 010=5, 011=7, 100=9, 101=10,
			 110=11
 * bits 3-4: CD-ROM DMA: 00=disabled, 01=DMA0, 10=DMA1, 11=DMA3
 * bits 5-7: CD-ROM port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x340,
			  101=0x350, 110=0x360, 111=0x370
 */

static u8 snd_cmi8328_cfg_read(u16 port, u8 reg)
{
	outb(0x43, port + 3);
	outb(0x21, port + 3);
	outb(reg, port + 3);
	return inb(port);
}

static void snd_cmi8328_cfg_write(u16 port, u8 reg, u8 val)
{
	outb(0x43, port + 3);
	outb(0x21, port + 3);
	outb(reg, port + 3);
	outb(val, port + 3);	/* yes, value goes to the same port as index */
}

#ifdef CONFIG_PM
static void snd_cmi8328_cfg_save(u16 port, u8 cfg[])
{
	cfg[0] = snd_cmi8328_cfg_read(port, CFG1);
	cfg[1] = snd_cmi8328_cfg_read(port, CFG2);
	cfg[2] = snd_cmi8328_cfg_read(port, CFG3);
}

static void snd_cmi8328_cfg_restore(u16 port, u8 cfg[])
{
	snd_cmi8328_cfg_write(port, CFG1, cfg[0]);
	snd_cmi8328_cfg_write(port, CFG2, cfg[1]);
	snd_cmi8328_cfg_write(port, CFG3, cfg[2]);
}
#endif /* CONFIG_PM */

static int snd_cmi8328_mixer(struct snd_wss *chip)
{
	struct snd_card *card;
	struct snd_ctl_elem_id id1, id2;
	int err;

	card = chip->card;

	memset(&id1, 0, sizeof(id1));
	memset(&id2, 0, sizeof(id2));
	id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
	/* rename AUX0 switch to CD */
	strscpy(id1.name, "Aux Playback Switch");
	strscpy(id2.name, "CD Playback Switch");
	err = snd_ctl_rename_id(card, &id1, &id2);
	if (err < 0) {
		dev_err(card->dev, "error renaming control\n");

Annotation

Implementation Notes