summaryrefslogtreecommitdiff
path: root/sound/soc/soc-component.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-component.c')
-rw-r--r--sound/soc/soc-component.c164
1 files changed, 103 insertions, 61 deletions
diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c
index e12f8244242b..c815fd1b3fd1 100644
--- a/sound/soc/soc-component.c
+++ b/sound/soc/soc-component.c
@@ -13,32 +13,20 @@
#include <sound/soc.h>
#include <linux/bitops.h>
-#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret, -1)
-#define soc_component_ret_reg_rw(dai, ret, reg) _soc_component_ret(dai, __func__, ret, reg)
-static inline int _soc_component_ret(struct snd_soc_component *component,
- const char *func, int ret, int reg)
-{
- /* Positive/Zero values are not errors */
- if (ret >= 0)
- return ret;
-
- /* Negative values might be errors */
- switch (ret) {
- case -EPROBE_DEFER:
- case -ENOTSUPP:
- break;
- default:
- if (reg == -1)
- dev_err(component->dev,
- "ASoC: error at %s on %s: %d\n",
- func, component->name, ret);
- else
- dev_err(component->dev,
- "ASoC: error at %s on %s for register: [0x%08x] %d\n",
- func, component->name, reg, ret);
- }
+#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
+static inline int _soc_component_ret(struct snd_soc_component *component, const char *func, int ret)
+{
+ return snd_soc_ret(component->dev, ret,
+ "at %s() on %s\n", func, component->name);
+}
- return ret;
+#define soc_component_ret_reg_rw(dai, ret, reg) _soc_component_ret_reg_rw(dai, __func__, ret, reg)
+static inline int _soc_component_ret_reg_rw(struct snd_soc_component *component,
+ const char *func, int ret, int reg)
+{
+ return snd_soc_ret(component->dev, ret,
+ "at %s() on %s for register: [0x%08x]\n",
+ func, component->name, reg);
}
static inline int soc_component_field_shift(struct snd_soc_component *component,
@@ -58,7 +46,7 @@ static inline int soc_component_field_shift(struct snd_soc_component *component,
* In such case, we can update these macros.
*/
#define soc_component_mark_push(component, substream, tgt) ((component)->mark_##tgt = substream)
-#define soc_component_mark_pop(component, substream, tgt) ((component)->mark_##tgt = NULL)
+#define soc_component_mark_pop(component, tgt) ((component)->mark_##tgt = NULL)
#define soc_component_mark_match(component, substream, tgt) ((component)->mark_##tgt == substream)
void snd_soc_component_set_aux(struct snd_soc_component *component,
@@ -236,6 +224,43 @@ int snd_soc_component_force_enable_pin_unlocked(
}
EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
+static void soc_get_kcontrol_name(struct snd_soc_component *component,
+ char *buf, int size, const char * const ctl)
+{
+ /* When updating, change also snd_soc_dapm_widget_name_cmp() */
+ if (component->name_prefix)
+ snprintf(buf, size, "%s %s", component->name_prefix, ctl);
+ else
+ snprintf(buf, size, "%s", ctl);
+}
+
+struct snd_kcontrol *snd_soc_component_get_kcontrol(struct snd_soc_component *component,
+ const char * const ctl)
+{
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+
+ soc_get_kcontrol_name(component, name, ARRAY_SIZE(name), ctl);
+
+ return snd_soc_card_get_kcontrol(component->card, name);
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_get_kcontrol);
+
+int snd_soc_component_notify_control(struct snd_soc_component *component,
+ const char * const ctl)
+{
+ struct snd_kcontrol *kctl;
+
+ kctl = snd_soc_component_get_kcontrol(component, ctl);
+ if (!kctl)
+ return soc_component_ret(component, -EINVAL);
+
+ snd_ctl_notify(component->card->snd_card,
+ SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_notify_control);
+
/**
* snd_soc_component_set_jack - configure component jack.
* @component: COMPONENTs
@@ -256,6 +281,26 @@ int snd_soc_component_set_jack(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
+/**
+ * snd_soc_component_get_jack_type
+ * @component: COMPONENTs
+ *
+ * Returns the jack type of the component
+ * This can either be the supported type or one read from
+ * devicetree with the property: jack-type.
+ */
+int snd_soc_component_get_jack_type(
+ struct snd_soc_component *component)
+{
+ int ret = -ENOTSUPP;
+
+ if (component->driver->get_jack_type)
+ ret = component->driver->get_jack_type(component);
+
+ return soc_component_ret(component, ret);
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_get_jack_type);
+
int snd_soc_component_module_get(struct snd_soc_component *component,
void *mark, int upon_open)
{
@@ -282,7 +327,7 @@ void snd_soc_component_module_put(struct snd_soc_component *component,
module_put(component->dev->driver->owner);
/* remove the mark from module */
- soc_component_mark_pop(component, mark, module);
+ soc_component_mark_pop(component, module);
}
int snd_soc_component_open(struct snd_soc_component *component,
@@ -313,7 +358,7 @@ int snd_soc_component_close(struct snd_soc_component *component,
ret = component->driver->close(component, substream);
/* remove marked substream */
- soc_component_mark_pop(component, substream, open);
+ soc_component_mark_pop(component, open);
return soc_component_ret(component, ret);
}
@@ -458,7 +503,7 @@ void snd_soc_component_compr_free(struct snd_soc_component *component,
component->driver->compress_ops->free(component, cstream);
/* remove marked substream */
- soc_component_mark_pop(component, cstream, compr_open);
+ soc_component_mark_pop(component, compr_open);
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_free);
@@ -530,7 +575,7 @@ int snd_soc_component_compr_get_caps(struct snd_compr_stream *cstream,
struct snd_soc_component *component;
int i, ret = 0;
- mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+ snd_soc_dpcm_mutex_lock(rtd);
for_each_rtd_components(rtd, i, component) {
if (component->driver->compress_ops &&
@@ -541,7 +586,7 @@ int snd_soc_component_compr_get_caps(struct snd_compr_stream *cstream,
}
}
- mutex_unlock(&rtd->card->pcm_mutex);
+ snd_soc_dpcm_mutex_unlock(rtd);
return soc_component_ret(component, ret);
}
@@ -554,7 +599,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream,
struct snd_soc_component *component;
int i, ret = 0;
- mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+ snd_soc_dpcm_mutex_lock(rtd);
for_each_rtd_components(rtd, i, component) {
if (component->driver->compress_ops &&
@@ -565,7 +610,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream,
}
}
- mutex_unlock(&rtd->card->pcm_mutex);
+ snd_soc_dpcm_mutex_unlock(rtd);
return soc_component_ret(component, ret);
}
@@ -592,7 +637,7 @@ int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);
int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp)
+ struct snd_compr_tstamp64 *tstamp)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
@@ -618,7 +663,7 @@ int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,
struct snd_soc_component *component;
int i, ret = 0;
- mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+ snd_soc_dpcm_mutex_lock(rtd);
for_each_rtd_components(rtd, i, component) {
if (component->driver->compress_ops &&
@@ -629,7 +674,7 @@ int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,
}
}
- mutex_unlock(&rtd->card->pcm_mutex);
+ snd_soc_dpcm_mutex_unlock(rtd);
return soc_component_ret(component, ret);
}
@@ -920,7 +965,7 @@ EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;
@@ -950,7 +995,7 @@ void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream,
snd_pcm_sframes_t *cpu_delay,
snd_pcm_sframes_t *codec_delay)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
snd_pcm_sframes_t delay;
int i;
@@ -977,7 +1022,7 @@ void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream,
int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;
@@ -994,7 +1039,7 @@ int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i, ret;
@@ -1010,22 +1055,20 @@ int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
return 0;
}
-int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
- int channel, unsigned long pos,
- void __user *buf, unsigned long bytes)
+int snd_soc_pcm_component_copy(struct snd_pcm_substream *substream,
+ int channel, unsigned long pos,
+ struct iov_iter *iter, unsigned long bytes)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;
/* FIXME. it returns 1st copy now */
for_each_rtd_components(rtd, i, component)
- if (component->driver->copy_user)
- return soc_component_ret(
- component,
- component->driver->copy_user(
- component, substream, channel,
- pos, buf, bytes));
+ if (component->driver->copy)
+ return soc_component_ret(component,
+ component->driver->copy(component, substream,
+ channel, pos, iter, bytes));
return -EINVAL;
}
@@ -1033,7 +1076,7 @@ int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
unsigned long offset)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
struct page *page;
int i;
@@ -1054,7 +1097,7 @@ struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;
@@ -1101,7 +1144,7 @@ void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i, ret;
@@ -1119,7 +1162,7 @@ int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i, ret;
@@ -1140,7 +1183,7 @@ int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
int rollback)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i, ret;
@@ -1155,7 +1198,7 @@ void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
}
/* remove marked substream */
- soc_component_mark_pop(component, substream, hw_params);
+ soc_component_mark_pop(component, hw_params);
}
}
@@ -1174,7 +1217,7 @@ static int soc_component_trigger(struct snd_soc_component *component,
int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
int cmd, int rollback)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i, r, ret = 0;
@@ -1199,7 +1242,7 @@ int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
r = soc_component_trigger(component, substream, cmd);
if (r < 0)
ret = r; /* use last ret */
- soc_component_mark_pop(component, substream, trigger);
+ soc_component_mark_pop(component, trigger);
}
}
@@ -1235,17 +1278,16 @@ void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd,
if (rollback && !soc_component_mark_match(component, stream, pm))
continue;
- pm_runtime_mark_last_busy(component->dev);
pm_runtime_put_autosuspend(component->dev);
/* remove marked stream */
- soc_component_mark_pop(component, stream, pm);
+ soc_component_mark_pop(component, pm);
}
}
int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;