sound/hda/codecs/si3054.c
Source file repositories/reference/linux-study-clean/sound/hda/codecs/si3054.c
File Facts
- System
- Linux kernel
- Corpus path
sound/hda/codecs/si3054.c- Extension
.c- Size
- 8355 bytes
- Lines
- 304
- Domain
- Driver Families
- Bucket
- sound/hda
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/delay.hlinux/slab.hlinux/module.hsound/core.hsound/hda_codec.hhda_local.h
Detected Declarations
struct si3054_specfunction si3054_switch_getfunction si3054_switch_putfunction si3054_build_controlsfunction si3054_pcm_preparefunction si3054_pcm_openfunction si3054_build_pcmsfunction si3054_initfunction si3054_removefunction si3054_probe
Annotated Snippet
struct si3054_spec {
unsigned international;
};
/*
* Modem mixer
*/
#define PRIVATE_VALUE(reg,mask) ((reg<<16)|(mask&0xffff))
#define PRIVATE_REG(val) ((val>>16)&0xffff)
#define PRIVATE_MASK(val) (val&0xffff)
#define si3054_switch_info snd_ctl_boolean_mono_info
static int si3054_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uvalue)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
u16 reg = PRIVATE_REG(kcontrol->private_value);
u16 mask = PRIVATE_MASK(kcontrol->private_value);
uvalue->value.integer.value[0] = (GET_REG(codec, reg)) & mask ? 1 : 0 ;
return 0;
}
static int si3054_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uvalue)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
u16 reg = PRIVATE_REG(kcontrol->private_value);
u16 mask = PRIVATE_MASK(kcontrol->private_value);
if (uvalue->value.integer.value[0])
SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) | mask);
else
SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) & ~mask);
return 0;
}
#define SI3054_KCONTROL(kname,reg,mask) { \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
.name = kname, \
.subdevice = HDA_SUBDEV_NID_FLAG | reg, \
.info = si3054_switch_info, \
.get = si3054_switch_get, \
.put = si3054_switch_put, \
.private_value = PRIVATE_VALUE(reg,mask), \
}
static const struct snd_kcontrol_new si3054_modem_mixer[] = {
SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH),
SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID),
{}
};
static int si3054_build_controls(struct hda_codec *codec)
{
return snd_hda_add_new_ctls(codec, si3054_modem_mixer);
}
/*
* PCM callbacks
*/
static int si3054_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
u16 val;
SET_REG(codec, SI3054_LINE_RATE, substream->runtime->rate);
val = GET_REG(codec, SI3054_LINE_LEVEL);
val &= 0xff << (8 * (substream->stream != SNDRV_PCM_STREAM_PLAYBACK));
val |= ((stream_tag & 0xf) << 4) << (8 * (substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
SET_REG(codec, SI3054_LINE_LEVEL, val);
snd_hda_codec_setup_stream(codec, hinfo->nid,
stream_tag, 0, format);
return 0;
}
static int si3054_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
static const unsigned int rates[] = { 8000, 9600, 16000 };
static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
Annotation
- Immediate include surface: `linux/init.h`, `linux/delay.h`, `linux/slab.h`, `linux/module.h`, `sound/core.h`, `sound/hda_codec.h`, `hda_local.h`.
- Detected declarations: `struct si3054_spec`, `function si3054_switch_get`, `function si3054_switch_put`, `function si3054_build_controls`, `function si3054_pcm_prepare`, `function si3054_pcm_open`, `function si3054_build_pcms`, `function si3054_init`, `function si3054_remove`, `function si3054_probe`.
- Atlas domain: Driver Families / sound/hda.
- 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.