Lines Matching +full:audio +full:- +full:widgets
1 // SPDX-License-Identifier: GPL-2.0-only
3 // ALSA SoC glue to use IIO devices as audio components
36 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value; in audio_iio_aux_info_volsw()
38 uinfo->count = 1; in audio_iio_aux_info_volsw()
39 uinfo->value.integer.min = 0; in audio_iio_aux_info_volsw()
40 uinfo->value.integer.max = chan->max - chan->min; in audio_iio_aux_info_volsw()
41 uinfo->type = (uinfo->value.integer.max == 1) ? in audio_iio_aux_info_volsw()
49 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value; in audio_iio_aux_get_volsw()
50 int max = chan->max; in audio_iio_aux_get_volsw()
51 int min = chan->min; in audio_iio_aux_get_volsw()
52 bool invert_range = chan->is_invert_range; in audio_iio_aux_get_volsw()
56 ret = iio_read_channel_raw(chan->iio_chan, &val); in audio_iio_aux_get_volsw()
60 ucontrol->value.integer.value[0] = val - min; in audio_iio_aux_get_volsw()
62 ucontrol->value.integer.value[0] = max - ucontrol->value.integer.value[0]; in audio_iio_aux_get_volsw()
70 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value; in audio_iio_aux_put_volsw()
71 int max = chan->max; in audio_iio_aux_put_volsw()
72 int min = chan->min; in audio_iio_aux_put_volsw()
73 bool invert_range = chan->is_invert_range; in audio_iio_aux_put_volsw()
78 val = ucontrol->value.integer.value[0]; in audio_iio_aux_put_volsw()
80 return -EINVAL; in audio_iio_aux_put_volsw()
81 if (val > max - min) in audio_iio_aux_put_volsw()
82 return -EINVAL; in audio_iio_aux_put_volsw()
86 val = max - val; in audio_iio_aux_put_volsw()
88 ret = iio_read_channel_raw(chan->iio_chan, &tmp); in audio_iio_aux_put_volsw()
95 ret = iio_write_channel_raw(chan->iio_chan, val); in audio_iio_aux_put_volsw()
107 .name = chan->name, in audio_iio_aux_add_controls()
123 static struct snd_soc_dapm_widget widgets[3]; variable
126 /* Be sure sizes are correct (need 3 widgets and 2 routes) */
127 static_assert(ARRAY_SIZE(widgets) >= 3, "3 widgets are needed");
139 input_name = kasprintf(GFP_KERNEL, "%s IN", chan->name); in audio_iio_aux_add_dapms()
141 return -ENOMEM; in audio_iio_aux_add_dapms()
143 output_name = kasprintf(GFP_KERNEL, "%s OUT", chan->name); in audio_iio_aux_add_dapms()
145 ret = -ENOMEM; in audio_iio_aux_add_dapms()
149 pga_name = kasprintf(GFP_KERNEL, "%s PGA", chan->name); in audio_iio_aux_add_dapms()
151 ret = -ENOMEM; in audio_iio_aux_add_dapms()
155 widgets[0] = SND_SOC_DAPM_INPUT(input_name); in audio_iio_aux_add_dapms()
156 widgets[1] = SND_SOC_DAPM_OUTPUT(output_name); in audio_iio_aux_add_dapms()
157 widgets[2] = SND_SOC_DAPM_PGA(pga_name, SND_SOC_NOPM, 0, 0, NULL, 0); in audio_iio_aux_add_dapms()
158 ret = snd_soc_dapm_new_controls(dapm, widgets, 3); in audio_iio_aux_add_dapms()
188 for (i = 0; i < iio_aux->num_chans; i++) { in audio_iio_aux_component_probe()
189 chan = iio_aux->chans + i; in audio_iio_aux_component_probe()
191 ret = iio_read_max_channel_raw(chan->iio_chan, &chan->max); in audio_iio_aux_component_probe()
193 return dev_err_probe(component->dev, ret, in audio_iio_aux_component_probe()
195 i, chan->name); in audio_iio_aux_component_probe()
197 ret = iio_read_min_channel_raw(chan->iio_chan, &chan->min); in audio_iio_aux_component_probe()
199 return dev_err_probe(component->dev, ret, in audio_iio_aux_component_probe()
201 i, chan->name); in audio_iio_aux_component_probe()
203 if (chan->min > chan->max) { in audio_iio_aux_component_probe()
209 dev_dbg(component->dev, "chan[%d] %s: Swap min and max\n", in audio_iio_aux_component_probe()
210 i, chan->name); in audio_iio_aux_component_probe()
211 swap(chan->min, chan->max); in audio_iio_aux_component_probe()
215 ret = iio_write_channel_raw(chan->iio_chan, in audio_iio_aux_component_probe()
216 chan->is_invert_range ? chan->max : chan->min); in audio_iio_aux_component_probe()
218 return dev_err_probe(component->dev, ret, in audio_iio_aux_component_probe()
220 i, chan->name); in audio_iio_aux_component_probe()
230 dev_dbg(component->dev, "chan[%d]: Added %s (min=%d, max=%d, invert=%s)\n", in audio_iio_aux_component_probe()
231 i, chan->name, chan->min, chan->max, in audio_iio_aux_component_probe()
232 str_on_off(chan->is_invert_range)); in audio_iio_aux_component_probe()
245 struct device *dev = &pdev->dev; in audio_iio_aux_probe()
255 return -ENOMEM; in audio_iio_aux_probe()
257 iio_aux->dev = dev; in audio_iio_aux_probe()
259 count = device_property_string_array_count(dev, "io-channel-names"); in audio_iio_aux_probe()
261 return dev_err_probe(dev, count, "failed to count io-channel-names\n"); in audio_iio_aux_probe()
263 iio_aux->num_chans = count; in audio_iio_aux_probe()
265 iio_aux->chans = devm_kmalloc_array(dev, iio_aux->num_chans, in audio_iio_aux_probe()
266 sizeof(*iio_aux->chans), GFP_KERNEL); in audio_iio_aux_probe()
267 if (!iio_aux->chans) in audio_iio_aux_probe()
268 return -ENOMEM; in audio_iio_aux_probe()
270 names = kcalloc(iio_aux->num_chans, sizeof(*names), GFP_KERNEL); in audio_iio_aux_probe()
272 return -ENOMEM; in audio_iio_aux_probe()
274 invert_ranges = kcalloc(iio_aux->num_chans, sizeof(*invert_ranges), GFP_KERNEL); in audio_iio_aux_probe()
276 ret = -ENOMEM; in audio_iio_aux_probe()
280 ret = device_property_read_string_array(dev, "io-channel-names", in audio_iio_aux_probe()
281 names, iio_aux->num_chans); in audio_iio_aux_probe()
283 dev_err_probe(dev, ret, "failed to read io-channel-names\n"); in audio_iio_aux_probe()
288 * snd-control-invert-range is optional and can contain fewer items in audio_iio_aux_probe()
291 count = device_property_count_u32(dev, "snd-control-invert-range"); in audio_iio_aux_probe()
293 count = min_t(unsigned int, count, iio_aux->num_chans); in audio_iio_aux_probe()
294 ret = device_property_read_u32_array(dev, "snd-control-invert-range", in audio_iio_aux_probe()
297 dev_err_probe(dev, ret, "failed to read snd-control-invert-range\n"); in audio_iio_aux_probe()
302 for (i = 0; i < iio_aux->num_chans; i++) { in audio_iio_aux_probe()
303 iio_aux_chan = iio_aux->chans + i; in audio_iio_aux_probe()
304 iio_aux_chan->name = names[i]; in audio_iio_aux_probe()
305 iio_aux_chan->is_invert_range = invert_ranges[i]; in audio_iio_aux_probe()
307 iio_aux_chan->iio_chan = devm_iio_channel_get(dev, iio_aux_chan->name); in audio_iio_aux_probe()
308 if (IS_ERR(iio_aux_chan->iio_chan)) { in audio_iio_aux_probe()
309 ret = PTR_ERR(iio_aux_chan->iio_chan); in audio_iio_aux_probe()
311 iio_aux_chan->name); in audio_iio_aux_probe()
328 { .compatible = "audio-iio-aux" },
335 .name = "audio-iio-aux",