sound/isa/sb/sb16_csp.c

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

File Facts

System
Linux kernel
Corpus path
sound/isa/sb/sb16_csp.c
Extension
.c
Size
31964 bytes
Lines
1158
Domain
Driver Families
Bucket
sound/isa
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 riff_header {
	__le32 name;
	__le32 len;
};

struct desc_header {
	struct riff_header info;
	__le16 func_nr;
	__le16 VOC_type;
	__le16 flags_play_rec;
	__le16 flags_16bit_8bit;
	__le16 flags_stereo_mono;
	__le16 flags_rates;
};

/*
 * prototypes
 */
static void snd_sb_csp_free(struct snd_hwdep *hw);
static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file);
static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg);
static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file);

static int csp_detect(struct snd_sb *chip, int *version);
static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val);
static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val);
static int read_register(struct snd_sb *chip, unsigned char reg);
static int set_mode_register(struct snd_sb *chip, unsigned char mode);
static int get_version(struct snd_sb *chip);

static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
				struct snd_sb_csp_microcode __user * code);
static int snd_sb_csp_unload(struct snd_sb_csp * p);
static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags);
static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode);
static int snd_sb_csp_check_version(struct snd_sb_csp * p);

static int snd_sb_csp_use(struct snd_sb_csp * p);
static int snd_sb_csp_unuse(struct snd_sb_csp * p);
static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels);
static int snd_sb_csp_stop(struct snd_sb_csp * p);
static int snd_sb_csp_pause(struct snd_sb_csp * p);
static int snd_sb_csp_restart(struct snd_sb_csp * p);

static int snd_sb_qsound_build(struct snd_sb_csp * p);
static void snd_sb_qsound_destroy(struct snd_sb_csp * p);
static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p);

static int init_proc_entry(struct snd_sb_csp * p, int device);
static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);

/*
 * Detect CSP chip and create a new instance
 */
int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
{
	struct snd_sb_csp *p;
	int version;
	int err;
	struct snd_hwdep *hw;

	if (rhwdep)
		*rhwdep = NULL;

	if (csp_detect(chip, &version))
		return -ENODEV;

	err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw);
	if (err < 0)
		return err;

	p = kzalloc_obj(*p);
	if (!p) {
		snd_device_free(chip->card, hw);
		return -ENOMEM;
	}
	p->chip = chip;
	p->version = version;

	/* CSP operators */
	p->ops.csp_use = snd_sb_csp_use;
	p->ops.csp_unuse = snd_sb_csp_unuse;
	p->ops.csp_autoload = snd_sb_csp_autoload;
	p->ops.csp_start = snd_sb_csp_start;
	p->ops.csp_stop = snd_sb_csp_stop;
	p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer;

	mutex_init(&p->access_mutex);
	sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f));
	hw->iface = SNDRV_HWDEP_IFACE_SB16CSP;

Annotation

Implementation Notes