sound/isa/cs423x/cs4236_lib.c

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

File Facts

System
Linux kernel
Corpus path
sound/isa/cs423x/cs4236_lib.c
Extension
.c
Size
36354 bytes
Lines
1040
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

if (divisor < 21 || divisor > 192) {
			snd_BUG();
			return 192;
		}
		return divisor;
	}
}

static void snd_cs4236_playback_format(struct snd_wss *chip,
				       struct snd_pcm_hw_params *params,
				       unsigned char pdfr)
{
	unsigned char rate = divisor_to_rate_register(params->rate_den);
	
	guard(spinlock_irqsave)(&chip->reg_lock);
	/* set fast playback format change and clean playback FIFO */
	snd_wss_out(chip, CS4231_ALT_FEATURE_1,
		    chip->image[CS4231_ALT_FEATURE_1] | 0x10);
	snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0);
	snd_wss_out(chip, CS4231_ALT_FEATURE_1,
		    chip->image[CS4231_ALT_FEATURE_1] & ~0x10);
	snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate);
}

static void snd_cs4236_capture_format(struct snd_wss *chip,
				      struct snd_pcm_hw_params *params,
				      unsigned char cdfr)
{
	unsigned char rate = divisor_to_rate_register(params->rate_den);
	
	guard(spinlock_irqsave)(&chip->reg_lock);
	/* set fast capture format change and clean capture FIFO */
	snd_wss_out(chip, CS4231_ALT_FEATURE_1,
		    chip->image[CS4231_ALT_FEATURE_1] | 0x20);
	snd_wss_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0);
	snd_wss_out(chip, CS4231_ALT_FEATURE_1,
		    chip->image[CS4231_ALT_FEATURE_1] & ~0x20);
	snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate);
}

#ifdef CONFIG_PM

static void snd_cs4236_suspend(struct snd_wss *chip)
{
	int reg;
	
	guard(spinlock_irqsave)(&chip->reg_lock);
	for (reg = 0; reg < 32; reg++)
		chip->image[reg] = snd_wss_in(chip, reg);
	for (reg = 0; reg < 18; reg++)
		chip->eimage[reg] = snd_cs4236_ext_in(chip, CS4236_I23VAL(reg));
	for (reg = 2; reg < 9; reg++)
		chip->cimage[reg] = snd_cs4236_ctrl_in(chip, reg);
}

static void snd_cs4236_resume(struct snd_wss *chip)
{
	int reg;
	
	snd_wss_mce_up(chip);
	scoped_guard(spinlock_irqsave, &chip->reg_lock) {
		for (reg = 0; reg < 32; reg++) {
			switch (reg) {
			case CS4236_EXT_REG:
			case CS4231_VERSION:
			case 27:	/* why? CS4235 - master left */
			case 29:	/* why? CS4235 - master right */
				break;
			default:
				snd_wss_out(chip, reg, chip->image[reg]);
				break;
			}
		}
		for (reg = 0; reg < 18; reg++)
			snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), chip->eimage[reg]);
		for (reg = 2; reg < 9; reg++) {
			switch (reg) {
			case 7:
				break;
			default:
				snd_cs4236_ctrl_out(chip, reg, chip->cimage[reg]);
			}
		}
	}
	snd_wss_mce_down(chip);
}

#endif /* CONFIG_PM */
/*
 * This function does no fail if the chip is not CS4236B or compatible.

Annotation

Implementation Notes