sound/i2c/other/ak4xxx-adda.c
Source file repositories/reference/linux-study-clean/sound/i2c/other/ak4xxx-adda.c
File Facts
- System
- Linux kernel
- Corpus path
sound/i2c/other/ak4xxx-adda.c- Extension
.c- Size
- 26338 bytes
- Lines
- 923
- Domain
- Driver Families
- Bucket
- sound/i2c
- 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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/io.hlinux/delay.hlinux/interrupt.hlinux/init.hlinux/module.hsound/core.hsound/control.hsound/tlv.hsound/ak4xxx-adda.hsound/info.h
Detected Declarations
function snd_akm4xxx_writefunction ak4524_resetfunction ak4529_resetfunction ak435X_resetfunction ak4381_resetfunction snd_akm4xxx_resetfunction snd_akm4xxx_initfunction snd_akm4xxx_volume_infofunction snd_akm4xxx_volume_getfunction put_ak_regfunction snd_akm4xxx_volume_putfunction snd_akm4xxx_stereo_volume_infofunction snd_akm4xxx_stereo_volume_getfunction snd_akm4xxx_stereo_volume_putfunction snd_akm4xxx_deemphasis_infofunction snd_akm4xxx_deemphasis_getfunction snd_akm4xxx_deemphasis_putfunction ak4xxx_switch_getfunction ak4xxx_switch_putfunction ak4xxx_capture_num_inputsfunction ak4xxx_capture_source_infofunction ak4xxx_capture_source_getfunction ak4xxx_capture_source_putfunction build_dac_controlsfunction build_adc_controlsfunction build_deemphasisfunction proc_regs_readfunction proc_initfunction snd_akm4xxx_build_controlsexport snd_akm4xxx_writeexport snd_akm4xxx_resetexport snd_akm4xxx_initexport snd_akm4xxx_build_controls
Annotated Snippet
while (*ptr != 0xff) {
reg = *ptr++;
data = *ptr++;
snd_akm4xxx_write(ak, chip, reg, data);
udelay(10);
}
}
}
EXPORT_SYMBOL(snd_akm4xxx_init);
/*
* Mixer callbacks
*/
#define AK_IPGA (1<<20) /* including IPGA */
#define AK_VOL_CVT (1<<21) /* need dB conversion */
#define AK_NEEDSMSB (1<<22) /* need MSB update bit */
#define AK_INVERT (1<<23) /* data is inverted */
#define AK_GET_CHIP(val) (((val) >> 8) & 0xff)
#define AK_GET_ADDR(val) ((val) & 0xff)
#define AK_GET_SHIFT(val) (((val) >> 16) & 0x0f)
#define AK_GET_VOL_CVT(val) (((val) >> 21) & 1)
#define AK_GET_IPGA(val) (((val) >> 20) & 1)
#define AK_GET_NEEDSMSB(val) (((val) >> 22) & 1)
#define AK_GET_INVERT(val) (((val) >> 23) & 1)
#define AK_GET_MASK(val) (((val) >> 24) & 0xff)
#define AK_COMPOSE(chip,addr,shift,mask) \
(((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
unsigned int mask = AK_GET_MASK(kcontrol->private_value);
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = mask;
return 0;
}
static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
int chip = AK_GET_CHIP(kcontrol->private_value);
int addr = AK_GET_ADDR(kcontrol->private_value);
ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
return 0;
}
static int put_ak_reg(struct snd_kcontrol *kcontrol, int addr,
unsigned char nval)
{
struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
unsigned int mask = AK_GET_MASK(kcontrol->private_value);
int chip = AK_GET_CHIP(kcontrol->private_value);
if (snd_akm4xxx_get_vol(ak, chip, addr) == nval)
return 0;
snd_akm4xxx_set_vol(ak, chip, addr, nval);
if (AK_GET_VOL_CVT(kcontrol->private_value) && nval < 128)
nval = vol_cvt_datt[nval];
if (AK_GET_IPGA(kcontrol->private_value) && nval >= 128)
nval++; /* need to correct + 1 since both 127 and 128 are 0dB */
if (AK_GET_INVERT(kcontrol->private_value))
nval = mask - nval;
if (AK_GET_NEEDSMSB(kcontrol->private_value))
nval |= 0x80;
snd_akm4xxx_write(ak, chip, addr, nval);
return 1;
}
static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned int mask = AK_GET_MASK(kcontrol->private_value);
unsigned int val = ucontrol->value.integer.value[0];
if (val > mask)
return -EINVAL;
return put_ak_reg(kcontrol, AK_GET_ADDR(kcontrol->private_value), val);
}
static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
unsigned int mask = AK_GET_MASK(kcontrol->private_value);
Annotation
- Immediate include surface: `linux/io.h`, `linux/delay.h`, `linux/interrupt.h`, `linux/init.h`, `linux/module.h`, `sound/core.h`, `sound/control.h`, `sound/tlv.h`.
- Detected declarations: `function snd_akm4xxx_write`, `function ak4524_reset`, `function ak4529_reset`, `function ak435X_reset`, `function ak4381_reset`, `function snd_akm4xxx_reset`, `function snd_akm4xxx_init`, `function snd_akm4xxx_volume_info`, `function snd_akm4xxx_volume_get`, `function put_ak_reg`.
- Atlas domain: Driver Families / sound/i2c.
- Implementation status: integration 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.