sound/pci/mixart/mixart_mixer.c
Source file repositories/reference/linux-study-clean/sound/pci/mixart/mixart_mixer.c
File Facts
- System
- Linux kernel
- Corpus path
sound/pci/mixart/mixart_mixer.c- Extension
.c- Size
- 46732 bytes
- Lines
- 1191
- Domain
- Driver Families
- Bucket
- sound/pci
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/time.hlinux/interrupt.hlinux/init.hlinux/mutex.hsound/core.hmixart.hmixart_core.hmixart_hwdep.hsound/control.hsound/tlv.hmixart_mixer.h
Detected Declarations
function mixart_update_analog_audio_levelfunction mixart_analog_vol_infofunction mixart_analog_vol_getfunction mixart_analog_vol_putfunction mixart_audio_sw_getfunction mixart_audio_sw_putfunction mixart_update_playback_stream_levelfunction mixart_update_capture_stream_levelfunction mixart_digital_vol_infofunction mixart_pcm_vol_getfunction mixart_pcm_vol_putfunction mixart_pcm_sw_getfunction mixart_pcm_sw_putfunction mixart_update_monitoringfunction mixart_monitor_vol_getfunction mixart_monitor_vol_putfunction mixart_monitor_sw_getfunction mixart_monitor_sw_putfunction mixart_reset_audio_levelsfunction snd_mixart_create_mixer
Annotated Snippet
if(is_capture) {
io_level.level[i].analog_level = mixart_analog_level[chip->analog_capture_volume[i]];
} else {
if(chip->analog_playback_active[i])
io_level.level[i].analog_level = mixart_analog_level[chip->analog_playback_volume[i]];
else
io_level.level[i].analog_level = mixart_analog_level[MIXART_ANALOG_PLAYBACK_LEVEL_MIN];
}
}
if(is_capture) request.uid = chip->uid_in_analog_physio;
else request.uid = chip->uid_out_analog_physio;
request.message_id = MSG_PHYSICALIO_SET_LEVEL;
request.data = &io_level;
request.size = sizeof(io_level);
err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
if((err<0) || (resp.error_code)) {
dev_dbg(chip->card->dev,
"error MSG_PHYSICALIO_SET_LEVEL card(%d) is_capture(%d) error_code(%x)\n",
chip->chip_idx, is_capture, resp.error_code);
return -EINVAL;
}
return 0;
}
/*
* analog level control
*/
static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
if(kcontrol->private_value == 0) { /* playback */
uinfo->value.integer.min = MIXART_ANALOG_PLAYBACK_LEVEL_MIN; /* -96 dB */
uinfo->value.integer.max = MIXART_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */
} else { /* capture */
uinfo->value.integer.min = MIXART_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */
uinfo->value.integer.max = MIXART_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */
}
return 0;
}
static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
guard(mutex)(&chip->mgr->mixer_mutex);
if(kcontrol->private_value == 0) { /* playback */
ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
} else { /* capture */
ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
}
return 0;
}
static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
int changed = 0;
int is_capture, i;
guard(mutex)(&chip->mgr->mixer_mutex);
is_capture = (kcontrol->private_value != 0);
for (i = 0; i < 2; i++) {
int new_volume = ucontrol->value.integer.value[i];
int *stored_volume = is_capture ?
&chip->analog_capture_volume[i] :
&chip->analog_playback_volume[i];
if (is_capture) {
if (new_volume < MIXART_ANALOG_CAPTURE_LEVEL_MIN ||
new_volume > MIXART_ANALOG_CAPTURE_LEVEL_MAX)
continue;
} else {
if (new_volume < MIXART_ANALOG_PLAYBACK_LEVEL_MIN ||
new_volume > MIXART_ANALOG_PLAYBACK_LEVEL_MAX)
continue;
}
if (*stored_volume != new_volume) {
*stored_volume = new_volume;
changed = 1;
}
}
if (changed)
mixart_update_analog_audio_level(chip, is_capture);
return changed;
}
Annotation
- Immediate include surface: `linux/time.h`, `linux/interrupt.h`, `linux/init.h`, `linux/mutex.h`, `sound/core.h`, `mixart.h`, `mixart_core.h`, `mixart_hwdep.h`.
- Detected declarations: `function mixart_update_analog_audio_level`, `function mixart_analog_vol_info`, `function mixart_analog_vol_get`, `function mixart_analog_vol_put`, `function mixart_audio_sw_get`, `function mixart_audio_sw_put`, `function mixart_update_playback_stream_level`, `function mixart_update_capture_stream_level`, `function mixart_digital_vol_info`, `function mixart_pcm_vol_get`.
- Atlas domain: Driver Families / sound/pci.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.