int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
+ /* pcm creation and destruction */
+ int (*pcm_new)(struct snd_soc_pcm_runtime *);
+ void (*pcm_free)(struct snd_pcm *);
+
/* component wide operations */
int (*set_sysclk)(struct snd_soc_component *component,
int clk_id, int source, unsigned int freq, int dir);
void (*remove)(struct snd_soc_component *);
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
+ int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
+ void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
int (*set_sysclk)(struct snd_soc_component *component,
int clk_id, int source, unsigned int freq, int dir);
return component->driver->stream_event(component, event);
}
+static int snd_soc_component_drv_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ if (component->driver->pcm_new)
+ return component->driver->pcm_new(rtd);
+
+ return 0;
+}
+
+static void snd_soc_component_drv_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ if (component->driver->pcm_free)
+ component->driver->pcm_free(pcm);
+}
+
static int snd_soc_component_initialize(struct snd_soc_component *component,
const struct snd_soc_component_driver *driver, struct device *dev)
{
component->set_sysclk = component->driver->set_sysclk;
component->set_pll = component->driver->set_pll;
component->set_jack = component->driver->set_jack;
+ component->pcm_new = snd_soc_component_drv_pcm_new;
+ component->pcm_free = snd_soc_component_drv_pcm_free;
dapm = snd_soc_component_get_dapm(component);
dapm->dev = dev;
platform->driver->remove(platform);
}
+static int snd_soc_platform_drv_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ if (platform->driver->pcm_new)
+ return platform->driver->pcm_new(rtd);
+
+ return 0;
+}
+
+static void snd_soc_platform_drv_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ if (platform->driver->pcm_free)
+ platform->driver->pcm_free(pcm);
+}
+
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
platform->component.probe = snd_soc_platform_drv_probe;
if (platform_drv->remove)
platform->component.remove = snd_soc_platform_drv_remove;
+ if (platform_drv->pcm_new)
+ platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
+ if (platform_drv->pcm_free)
+ platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
#ifdef CONFIG_DEBUG_FS
platform->component.debugfs_prefix = "platform";
static void soc_pcm_private_free(struct snd_pcm *pcm)
{
struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ /* need to sync the delayed work before releasing resources */
+
+ flush_delayed_work(&rtd->delayed_work);
+ component = rtdcom->component;
- /* need to sync the delayed work before releasing resources */
- flush_delayed_work(&rtd->delayed_work);
- if (platform->driver->pcm_free)
- platform->driver->pcm_free(pcm);
+ if (component->pcm_free)
+ component->pcm_free(component, pcm);
+ }
}
/* create a new pcm */
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_pcm *pcm;
char new_name[64];
int ret = 0, playback = 0, capture = 0;
if (capture)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
- if (platform->driver->pcm_new) {
- ret = platform->driver->pcm_new(rtd);
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->pcm_new)
+ continue;
+
+ ret = component->pcm_new(component, rtd);
if (ret < 0) {
- dev_err(platform->dev,
+ dev_err(component->dev,
"ASoC: pcm constructor failed: %d\n",
ret);
return ret;