sound/soc/codecs/aw88395/aw88395_device.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/aw88395/aw88395_device.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/aw88395/aw88395_device.c- Extension
.c- Size
- 43397 bytes
- Lines
- 1722
- Domain
- Driver Families
- Bucket
- sound/soc
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/crc32.hlinux/i2c.hlinux/minmax.hlinux/regmap.haw88395_device.haw88395_reg.h
Detected Declarations
function aw_dev_dsp_write_16bitfunction aw_dev_dsp_write_32bitfunction aw_dev_dsp_writefunction aw_dev_dsp_read_16bitfunction aw_dev_dsp_read_32bitfunction aw_dev_dsp_readfunction aw_dev_read_chipidfunction reg_val_to_dbfunction db_to_reg_valfunction aw_dev_dsp_fw_checkfunction aw_dev_set_volumefunction aw88395_dev_set_volumefunction aw_dev_fade_infunction aw_dev_fade_outfunction aw_dev_modify_dsp_cfgfunction aw_dev_dsp_set_cali_refunction aw_dev_i2s_tx_enablefunction aw_dev_dsp_set_crc32function aw_dev_dsp_check_crc_enablefunction aw_dev_dsp_check_stfunction aw_dev_dsp_enablefunction aw_dev_dsp_check_crc32function aw_dev_pwdfunction aw_dev_amppdfunction aw88395_dev_mutefunction aw_dev_get_icalkfunction aw_dev_get_vcalkfunction aw_dev_get_vcalk_dacfunction aw_dev_vsense_selectfunction aw_dev_set_vcalbfunction aw_dev_get_cali_f0_delayfunction aw_dev_get_int_statusfunction aw_dev_clear_int_statusfunction aw_dev_get_iis_statusfunction aw_dev_check_mode1_pllfunction aw_dev_check_mode2_pllfunction aw_dev_check_syspllfunction aw_dev_check_sysstfunction aw_dev_check_sysintfunction aw_dev_get_cur_mode_stfunction aw_dev_get_dsp_configfunction aw_dev_select_memclkfunction aw_dev_get_dsp_statusfunction aw_dev_get_vmaxfunction aw_dev_update_reg_containerfunction aw_dev_reg_updatefunction aw_dev_get_rafunction aw_dev_dsp_update_container
Annotated Snippet
if (ret) {
dev_err(aw_dev->dev, "dsp read failed");
return ret;
}
bin_val = be16_to_cpup((void *)&dsp_fw_desc->data[2 * (addr - base_addr)]);
if (dsp_val != bin_val) {
dev_err(aw_dev->dev, "fw check failed, addr[0x%x], read[0x%x] != bindata[0x%x]",
addr, dsp_val, bin_val);
return -EINVAL;
}
addr += (dsp_fw_desc->len / 2) / AW88395_FW_CHECK_PART;
if ((addr - base_addr) > dsp_fw_desc->len) {
dev_err(aw_dev->dev, "fw check failed, addr[0x%x] too large", addr);
return -EINVAL;
}
}
return 0;
}
static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value)
{
struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
unsigned int reg_value;
u16 real_value, volume;
int ret;
volume = min((value + vol_desc->init_volume), (unsigned int)AW88395_MUTE_VOL);
real_value = db_to_reg_val(volume);
/* cal real value */
ret = regmap_read(aw_dev->regmap, AW88395_SYSCTRL2_REG, ®_value);
if (ret)
return ret;
dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value);
/* [15 : 6] volume */
real_value = (real_value << AW88395_VOL_START_BIT) | (reg_value & AW88395_VOL_MASK);
/* write value */
ret = regmap_write(aw_dev->regmap, AW88395_SYSCTRL2_REG, real_value);
return ret;
}
void aw88395_dev_set_volume(struct aw_device *aw_dev, unsigned short set_vol)
{
int ret;
ret = aw_dev_set_volume(aw_dev, set_vol);
if (ret)
dev_dbg(aw_dev->dev, "set volume failed");
}
EXPORT_SYMBOL_GPL(aw88395_dev_set_volume);
static void aw_dev_fade_in(struct aw_device *aw_dev)
{
struct aw_volume_desc *desc = &aw_dev->volume_desc;
u16 fade_in_vol = desc->ctl_volume;
int fade_step = aw_dev->fade_step;
int i;
if (fade_step == 0 || aw_dev->fade_in_time == 0) {
aw_dev_set_volume(aw_dev, fade_in_vol);
return;
}
for (i = AW88395_MUTE_VOL; i >= fade_in_vol; i -= fade_step) {
aw_dev_set_volume(aw_dev, i);
usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10);
}
if (i != fade_in_vol)
aw_dev_set_volume(aw_dev, fade_in_vol);
}
static void aw_dev_fade_out(struct aw_device *aw_dev)
{
struct aw_volume_desc *desc = &aw_dev->volume_desc;
int fade_step = aw_dev->fade_step;
int i;
if (fade_step == 0 || aw_dev->fade_out_time == 0) {
aw_dev_set_volume(aw_dev, AW88395_MUTE_VOL);
return;
}
Annotation
- Immediate include surface: `linux/crc32.h`, `linux/i2c.h`, `linux/minmax.h`, `linux/regmap.h`, `aw88395_device.h`, `aw88395_reg.h`.
- Detected declarations: `function aw_dev_dsp_write_16bit`, `function aw_dev_dsp_write_32bit`, `function aw_dev_dsp_write`, `function aw_dev_dsp_read_16bit`, `function aw_dev_dsp_read_32bit`, `function aw_dev_dsp_read`, `function aw_dev_read_chipid`, `function reg_val_to_db`, `function db_to_reg_val`, `function aw_dev_dsp_fw_check`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.