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.

Dependency Surface

Detected Declarations

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, &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

Implementation Notes