Lines Matching +full:iio +full:- +full:aux
1 // SPDX-License-Identifier: GPL-2.0-only
3 // ALSA SoC glue to use IIO devices as audio components
10 #include <linux/iio/consumer.h>
37 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value; in audio_iio_aux_info_volsw()
39 uinfo->count = 1; in audio_iio_aux_info_volsw()
40 uinfo->value.integer.min = 0; in audio_iio_aux_info_volsw()
41 uinfo->value.integer.max = chan->max - chan->min; in audio_iio_aux_info_volsw()
42 uinfo->type = (uinfo->value.integer.max == 1) ? in audio_iio_aux_info_volsw()
50 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value; in audio_iio_aux_get_volsw()
51 int max = chan->max; in audio_iio_aux_get_volsw()
52 int min = chan->min; in audio_iio_aux_get_volsw()
53 bool invert_range = chan->is_invert_range; in audio_iio_aux_get_volsw()
57 ret = iio_read_channel_raw(chan->iio_chan, &val); in audio_iio_aux_get_volsw()
61 ucontrol->value.integer.value[0] = val - min; in audio_iio_aux_get_volsw()
63 ucontrol->value.integer.value[0] = max - ucontrol->value.integer.value[0]; in audio_iio_aux_get_volsw()
71 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value; in audio_iio_aux_put_volsw()
72 int max = chan->max; in audio_iio_aux_put_volsw()
73 int min = chan->min; in audio_iio_aux_put_volsw()
74 bool invert_range = chan->is_invert_range; in audio_iio_aux_put_volsw()
79 val = ucontrol->value.integer.value[0]; in audio_iio_aux_put_volsw()
81 return -EINVAL; in audio_iio_aux_put_volsw()
82 if (val > max - min) in audio_iio_aux_put_volsw()
83 return -EINVAL; in audio_iio_aux_put_volsw()
87 val = max - val; in audio_iio_aux_put_volsw()
89 ret = iio_read_channel_raw(chan->iio_chan, &tmp); in audio_iio_aux_put_volsw()
96 ret = iio_write_channel_raw(chan->iio_chan, val); in audio_iio_aux_put_volsw()
108 .name = chan->name, in audio_iio_aux_add_controls()
138 char *input_name __free(kfree) = kasprintf(GFP_KERNEL, "%s IN", chan->name); in audio_iio_aux_add_dapms()
140 return -ENOMEM; in audio_iio_aux_add_dapms()
142 char *output_name __free(kfree) = kasprintf(GFP_KERNEL, "%s OUT", chan->name); in audio_iio_aux_add_dapms()
144 return -ENOMEM; in audio_iio_aux_add_dapms()
146 char *pga_name __free(kfree) = kasprintf(GFP_KERNEL, "%s PGA", chan->name); in audio_iio_aux_add_dapms()
148 return -ENOMEM; in audio_iio_aux_add_dapms()
174 for (i = 0; i < iio_aux->num_chans; i++) { in audio_iio_aux_component_probe()
175 chan = iio_aux->chans + i; in audio_iio_aux_component_probe()
177 ret = iio_read_max_channel_raw(chan->iio_chan, &chan->max); in audio_iio_aux_component_probe()
179 return dev_err_probe(component->dev, ret, in audio_iio_aux_component_probe()
181 i, chan->name); in audio_iio_aux_component_probe()
183 ret = iio_read_min_channel_raw(chan->iio_chan, &chan->min); in audio_iio_aux_component_probe()
185 return dev_err_probe(component->dev, ret, in audio_iio_aux_component_probe()
187 i, chan->name); in audio_iio_aux_component_probe()
189 if (chan->min > chan->max) { in audio_iio_aux_component_probe()
195 dev_dbg(component->dev, "chan[%d] %s: Swap min and max\n", in audio_iio_aux_component_probe()
196 i, chan->name); in audio_iio_aux_component_probe()
197 swap(chan->min, chan->max); in audio_iio_aux_component_probe()
201 ret = iio_write_channel_raw(chan->iio_chan, in audio_iio_aux_component_probe()
202 chan->is_invert_range ? chan->max : chan->min); in audio_iio_aux_component_probe()
204 return dev_err_probe(component->dev, ret, in audio_iio_aux_component_probe()
206 i, chan->name); in audio_iio_aux_component_probe()
216 dev_dbg(component->dev, "chan[%d]: Added %s (min=%d, max=%d, invert=%s)\n", in audio_iio_aux_component_probe()
217 i, chan->name, chan->min, chan->max, in audio_iio_aux_component_probe()
218 str_on_off(chan->is_invert_range)); in audio_iio_aux_component_probe()
231 struct device *dev = &pdev->dev; in audio_iio_aux_probe()
237 count = device_property_string_array_count(dev, "io-channel-names"); in audio_iio_aux_probe()
239 return dev_err_probe(dev, count, "failed to count io-channel-names\n"); in audio_iio_aux_probe()
243 return -ENOMEM; in audio_iio_aux_probe()
245 iio_aux->dev = dev; in audio_iio_aux_probe()
247 iio_aux->num_chans = count; in audio_iio_aux_probe()
249 const char **names __free(kfree) = kcalloc(iio_aux->num_chans, in audio_iio_aux_probe()
253 return -ENOMEM; in audio_iio_aux_probe()
255 u32 *invert_ranges __free(kfree) = kcalloc(iio_aux->num_chans, in audio_iio_aux_probe()
259 return -ENOMEM; in audio_iio_aux_probe()
261 ret = device_property_read_string_array(dev, "io-channel-names", in audio_iio_aux_probe()
262 names, iio_aux->num_chans); in audio_iio_aux_probe()
264 return dev_err_probe(dev, ret, "failed to read io-channel-names\n"); in audio_iio_aux_probe()
267 * snd-control-invert-range is optional and can contain fewer items in audio_iio_aux_probe()
270 count = device_property_count_u32(dev, "snd-control-invert-range"); in audio_iio_aux_probe()
272 count = min_t(unsigned int, count, iio_aux->num_chans); in audio_iio_aux_probe()
273 ret = device_property_read_u32_array(dev, "snd-control-invert-range", in audio_iio_aux_probe()
276 return dev_err_probe(dev, ret, "failed to read snd-control-invert-range\n"); in audio_iio_aux_probe()
279 for (i = 0; i < iio_aux->num_chans; i++) { in audio_iio_aux_probe()
280 iio_aux_chan = iio_aux->chans + i; in audio_iio_aux_probe()
281 iio_aux_chan->name = names[i]; in audio_iio_aux_probe()
282 iio_aux_chan->is_invert_range = invert_ranges[i]; in audio_iio_aux_probe()
284 iio_aux_chan->iio_chan = devm_iio_channel_get(dev, iio_aux_chan->name); in audio_iio_aux_probe()
285 if (IS_ERR(iio_aux_chan->iio_chan)) in audio_iio_aux_probe()
286 return dev_err_probe(dev, PTR_ERR(iio_aux_chan->iio_chan), in audio_iio_aux_probe()
287 "get IIO channel '%s' failed\n", in audio_iio_aux_probe()
288 iio_aux_chan->name); in audio_iio_aux_probe()
298 { .compatible = "audio-iio-aux" },
305 .name = "audio-iio-aux",
313 MODULE_DESCRIPTION("IIO ALSA SoC aux driver");