sound/soc/intel/atom/sst-atom-controls.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/atom/sst-atom-controls.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/atom/sst-atom-controls.c
Extension
.c
Size
50078 bytes
Lines
1578
Domain
Driver Families
Bucket
sound/soc
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (nb_inputs == SST_CMD_SWM_MAX_INPUTS) {
			dev_warn(cmpnt->dev, "SET_SWM cmd max inputs reached");
			break;
		}
	}
	return nb_inputs;
}


/*
 * called with lock held
 */
static int sst_set_pipe_gain(struct sst_ids *ids,
			struct sst_data *drv, int mute)
{
	int ret = 0;
	struct sst_gain_mixer_control *mc;
	struct sst_gain_value *gv;
	struct sst_module *gain;

	list_for_each_entry(gain, &ids->gain_list, node) {
		struct snd_kcontrol *kctl = gain->kctl;

		dev_dbg(&drv->pdev->dev, "control name=%s\n", kctl->id.name);
		mc = (void *)kctl->private_value;
		gv = mc->gain_val;

		ret = sst_send_gain_cmd(drv, gv, mc->task_id,
			mc->pipe_id | mc->instance_id, mc->module_id, mute);
		if (ret)
			return ret;
	}
	return ret;
}

static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
			struct snd_kcontrol *k, int event)
{
	struct sst_cmd_set_swm cmd;
	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
	struct sst_data *drv = snd_soc_component_get_drvdata(cmpnt);
	struct sst_ids *ids = w->priv;
	bool set_mixer = false;
	struct soc_mixer_control *mc;
	int val = 0;
	int i = 0;

	dev_dbg(cmpnt->dev, "widget = %s\n", w->name);
	/*
	 * Identify which mixer input is on and send the bitmap of the
	 * inputs as an IPC to the DSP.
	 */
	for (i = 0; i < w->num_kcontrols; i++) {
		if (snd_soc_dapm_kcontrol_get_value(w->kcontrols[i])) {
			mc = (struct soc_mixer_control *)(w->kcontrols[i])->private_value;
			val |= 1 << mc->shift;
		}
	}
	dev_dbg(cmpnt->dev, "val = %#x\n", val);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
	case SND_SOC_DAPM_POST_PMD:
		set_mixer = true;
		break;
	case SND_SOC_DAPM_POST_REG:
		if (w->power)
			set_mixer = true;
		break;
	default:
		set_mixer = false;
	}

	if (!set_mixer)
		return 0;

	if (SND_SOC_DAPM_EVENT_ON(event) ||
	    event == SND_SOC_DAPM_POST_REG)
		cmd.switch_state = SST_SWM_ON;
	else
		cmd.switch_state = SST_SWM_OFF;

	SST_FILL_DEFAULT_DESTINATION(cmd.header.dst);
	/* MMX_SET_SWM == SBA_SET_SWM */
	cmd.header.command_id = SBA_SET_SWM;

	SST_FILL_DESTINATION(2, cmd.output_id,
			     ids->location_id, SST_DEFAULT_MODULE_ID);
	cmd.nb_inputs =	fill_swm_input(cmpnt, &cmd.input[0], val);
	cmd.header.length = offsetof(struct sst_cmd_set_swm, input)

Annotation

Implementation Notes