diff --git a/arch/arm/src/cxd56xx/cxd56_nxaudio.c b/arch/arm/src/cxd56xx/cxd56_nxaudio.c index 6551111157b98..99c8d04cdc98d 100644 --- a/arch/arm/src/cxd56xx/cxd56_nxaudio.c +++ b/arch/arm/src/cxd56xx/cxd56_nxaudio.c @@ -381,7 +381,7 @@ static int cxd56_release(struct audio_lowerhalf_s *lower); static int cxd56_getcaps(struct audio_lowerhalf_s *lower, int type, struct audio_caps_s *caps); -static int cxd56_shutdown(struct audio_lowerhalf_s *lower); +static int cxd56_shutdown(struct audio_lowerhalf_s *lower, int opencnt); static int cxd56_enqueuebuffer(struct audio_lowerhalf_s *lower, struct ap_buffer_s *apb); static int cxd56_cancelbuffer(struct audio_lowerhalf_s *lower, @@ -438,6 +438,7 @@ static uint16_t g_codec_start_count = 0; static const struct audio_ops_s g_audioops = { + NULL, /* setup */ cxd56_getcaps, /* getcaps */ cxd56_configure, /* configure */ cxd56_shutdown, /* shutdown */ @@ -2698,7 +2699,7 @@ static int cxd56_getcaps(struct audio_lowerhalf_s *lower, int type, * ****************************************************************************/ -static int cxd56_shutdown(struct audio_lowerhalf_s *lower) +static int cxd56_shutdown(struct audio_lowerhalf_s *lower, int opencnt) { int ret; struct cxd56_dev_s *priv = (struct cxd56_dev_s *)lower; diff --git a/arch/arm/src/sama5/sam_classd.c b/arch/arm/src/sama5/sam_classd.c index 74adb4fa313a2..450df55e9c18a 100644 --- a/arch/arm/src/sama5/sam_classd.c +++ b/arch/arm/src/sama5/sam_classd.c @@ -554,6 +554,7 @@ static struct sam_classd_config_s sam_classd_const = static const struct audio_ops_s g_audioops = { + NULL, /* setup */ classd_getcaps, /* getcaps */ classd_configure, /* configure */ classd_shutdown, /* shutdown */ @@ -1747,7 +1748,7 @@ static int classd_configure(struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int classd_shutdown(struct audio_lowerhalf_s *dev) +static int classd_shutdown(struct audio_lowerhalf_s *dev, int cnt) { struct classd_dev_s *priv = (struct classd_dev_s *)dev; diff --git a/arch/sim/src/sim/posix/sim_alsa.c b/arch/sim/src/sim/posix/sim_alsa.c index bf6fc06e7529c..0eb5c44535e80 100644 --- a/arch/sim/src/sim/posix/sim_alsa.c +++ b/arch/sim/src/sim/posix/sim_alsa.c @@ -104,7 +104,7 @@ static int sim_audio_resume(struct audio_lowerhalf_s *dev); static int sim_audio_reserve(struct audio_lowerhalf_s *dev); static int sim_audio_release(struct audio_lowerhalf_s *dev); #endif -static int sim_audio_shutdown(struct audio_lowerhalf_s *dev); +static int sim_audio_shutdown(struct audio_lowerhalf_s *dev, int cnt); static int sim_audio_enqueuebuffer(struct audio_lowerhalf_s *dev, struct ap_buffer_s *apb); static int sim_audio_ioctl(struct audio_lowerhalf_s *dev, int cmd, @@ -115,6 +115,7 @@ static int sim_audio_ioctl(struct audio_lowerhalf_s *dev, int cmd, static const struct audio_ops_s g_sim_audio_ops = { + .setup = NULL, .getcaps = sim_audio_getcaps, .configure = sim_audio_configure, .shutdown = sim_audio_shutdown, @@ -484,7 +485,7 @@ static int sim_audio_configure(struct audio_lowerhalf_s *dev, return ret; } -static int sim_audio_shutdown(struct audio_lowerhalf_s *dev) +static int sim_audio_shutdown(struct audio_lowerhalf_s *dev, int cnt) { return 0; } diff --git a/audio/audio.c b/audio/audio.c index 3bc906e9836cc..aeec0dbe00acd 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -139,6 +139,7 @@ static int audio_open(FAR struct file *filep) { FAR struct inode *inode = filep->f_inode; FAR struct audio_upperhalf_s *upper = inode->i_private; + FAR struct audio_lowerhalf_s *lower = upper->dev; uint8_t tmp; int ret; @@ -166,6 +167,17 @@ static int audio_open(FAR struct file *filep) goto errout_with_lock; } + /* Call open method of lowerhalf if exist */ + + if (lower && lower->ops && lower->ops->setup) + { + ret = lower->ops->setup(lower, tmp); + if (ret < 0) + { + goto errout_with_lock; + } + } + /* Save the new open count on success */ upper->crefs = tmp; @@ -223,7 +235,7 @@ static int audio_close(FAR struct file *filep) DEBUGASSERT(lower->ops->shutdown != NULL); audinfo("calling shutdown\n"); - lower->ops->shutdown(lower); + lower->ops->shutdown(lower, upper->crefs); upper->usermq = NULL; } @@ -415,7 +427,8 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* Call the lower-half driver initialize handler */ - ret = lower->ops->shutdown(lower); + ret = lower->ops->shutdown(lower, upper->crefs); + upper->started = false; } break; @@ -479,6 +492,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg) audinfo("AUDIOIOC_PAUSE\n"); DEBUGASSERT(lower->ops->pause != NULL); + ret = -EAGAIN; if (upper->started) { #ifdef CONFIG_AUDIO_MULTI_SESSION @@ -501,6 +515,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg) audinfo("AUDIOIOC_RESUME\n"); DEBUGASSERT(lower->ops->resume != NULL); + ret = -EAGAIN; if (upper->started) { #ifdef CONFIG_AUDIO_MULTI_SESSION @@ -723,6 +738,45 @@ static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper, } } +/**************************************************************************** + * Name: audio_ioerror + * + * Description: + * Send an AUDIO_MSG_IOERROR message to the client to indicate that a + * something error was happend in lower-half driver. The lower-half + * driver initiates this call via its callback pointer to our upper-half + * driver. + * + ****************************************************************************/ + +#ifdef CONFIG_AUDIO_MULTI_SESSION +static inline void audio_ioerror(FAR struct audio_upperhalf_s *upper, + FAR struct ap_buffer_s *apb, uint16_t status, + FAR void *session) +#else +static inline void audio_ioerror(FAR struct audio_upperhalf_s *upper, + FAR struct ap_buffer_s *apb, uint16_t status) +#endif +{ + struct audio_msg_s msg; + + audinfo("Entry\n"); + + /* Send a dequeue message to the user if a message queue is registered */ + + upper->started = false; + if (upper->usermq != NULL) + { + msg.msg_id = AUDIO_MSG_IOERROR; + msg.u.data = (uint32_t)status; +#ifdef CONFIG_AUDIO_MULTI_SESSION + msg.session = session; +#endif + file_mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg), + CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO); + } +} + /**************************************************************************** * Name: audio_complete * @@ -849,6 +903,11 @@ static void audio_callback(FAR void *handle, uint16_t reason, case AUDIO_CALLBACK_IOERR: { +#ifdef CONFIG_AUDIO_MULTI_SESSION + audio_ioerror(upper, apb, status, session); +#else + audio_ioerror(upper, apb, status); +#endif } break; diff --git a/audio/audio_comp.c b/audio/audio_comp.c index d9957da3131c4..87e91502465e2 100644 --- a/audio/audio_comp.c +++ b/audio/audio_comp.c @@ -57,6 +57,7 @@ struct audio_comp_priv_s * Private Function Prototypes ****************************************************************************/ +static int audio_comp_setup(FAR struct audio_lowerhalf_s *dev, int opencnt); static int audio_comp_getcaps(FAR struct audio_lowerhalf_s *dev, int type, FAR struct audio_caps_s *caps); #ifdef CONFIG_AUDIO_MULTI_SESSION @@ -67,7 +68,7 @@ static int audio_comp_configure(FAR struct audio_lowerhalf_s *dev, static int audio_comp_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int audio_comp_shutdown(FAR struct audio_lowerhalf_s *dev); +static int audio_comp_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); #ifdef CONFIG_AUDIO_MULTI_SESSION static int audio_comp_start(FAR struct audio_lowerhalf_s *dev, FAR void *session); @@ -137,6 +138,7 @@ static void audio_comp_callback(FAR void *arg, uint16_t reason, static const struct audio_ops_s g_audio_comp_ops = { + audio_comp_setup, /* setup */ audio_comp_getcaps, /* getcaps */ audio_comp_configure, /* configure */ audio_comp_shutdown, /* shutdown */ @@ -163,6 +165,50 @@ static const struct audio_ops_s g_audio_comp_ops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: audio_comp_setup + * + * Description: Call lower device driver's setup + * + ****************************************************************************/ + +static int audio_comp_setup(FAR struct audio_lowerhalf_s *dev, int cnt) +{ + FAR struct audio_comp_priv_s *priv = (FAR struct audio_comp_priv_s *)dev; + FAR struct audio_lowerhalf_s **lower = priv->lower; + int i; + int ret; + + for (i = 0; i < priv->count; i++) + { + if (lower[i]->ops->setup) + { + ret = lower[i]->ops->setup(lower[i], cnt); + if (ret < 0) + { + break; + } + } + } + + /* If an error is occured on a lower device, + * shutdown of lower device which is already opened is called. + */ + + if (i != priv->count) + { + for (; i >= 0; i--) + { + if (lower[i]->ops->open && lower[i]->ops->shutdown) + { + lower[i]->ops->shutdown(lower[i], cnt - 1); + } + } + } + + return ret; +} + /**************************************************************************** * Name: audio_comp_getcaps * @@ -280,7 +326,7 @@ static int audio_comp_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int audio_comp_shutdown(FAR struct audio_lowerhalf_s *dev) +static int audio_comp_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct audio_comp_priv_s *priv = (FAR struct audio_comp_priv_s *)dev; FAR struct audio_lowerhalf_s **lower = priv->lower; @@ -291,7 +337,7 @@ static int audio_comp_shutdown(FAR struct audio_lowerhalf_s *dev) { if (lower[i]->ops->shutdown) { - int tmp = lower[i]->ops->shutdown(lower[i]); + int tmp = lower[i]->ops->shutdown(lower[i], cnt); if (tmp == -ENOTTY) { continue; diff --git a/audio/pcm_decode.c b/audio/pcm_decode.c index 60c8b9af4d9fe..3cab75113652e 100644 --- a/audio/pcm_decode.c +++ b/audio/pcm_decode.c @@ -122,6 +122,8 @@ static void pcm_subsample(FAR struct pcm_decode_s *priv, /* struct audio_lowerhalf_s methods *****************************************/ +static int pcm_setup(FAR struct audio_lowerhalf_s *dev, int opencnt); + static int pcm_getcaps(FAR struct audio_lowerhalf_s *dev, int type, FAR struct audio_caps_s *caps); @@ -133,7 +135,7 @@ static int pcm_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int pcm_shutdown(FAR struct audio_lowerhalf_s *dev); +static int pcm_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); #ifdef CONFIG_AUDIO_MULTI_SESSION static int pcm_start(FAR struct audio_lowerhalf_s *dev, FAR void *session); @@ -665,6 +667,34 @@ static void pcm_subsample(FAR struct pcm_decode_s *priv, } #endif +/**************************************************************************** + * Name: pcm_setup + * + * Description: + * This method is called when the related device file is opened. + * And then next lower's setup is called in this method. + * + ****************************************************************************/ + +static int pcm_setup(FAR struct audio_lowerhalf_s *dev, int opencnt) +{ + FAR struct pcm_decode_s *priv = (FAR struct pcm_decode_s *)dev; + FAR struct audio_lowerhalf_s *lower; + + DEBUGASSERT(priv); + + lower = priv->lower; + + DEBUGASSERT(lower); + + if (lower->ops && lower->ops->setup) + { + return lower->ops->setup(lower, opencnt); + } + + return OK; +} + /**************************************************************************** * Name: pcm_getcaps * @@ -788,7 +818,7 @@ static int pcm_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int pcm_shutdown(FAR struct audio_lowerhalf_s *dev) +static int pcm_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct pcm_decode_s *priv = (FAR struct pcm_decode_s *)dev; FAR struct audio_lowerhalf_s *lower; @@ -805,7 +835,7 @@ static int pcm_shutdown(FAR struct audio_lowerhalf_s *dev) DEBUGASSERT(lower && lower->ops->start); audinfo("Defer to lower shutdown\n"); - return lower->ops->shutdown(lower); + return lower->ops->shutdown(lower, cnt); } /**************************************************************************** @@ -1403,6 +1433,7 @@ FAR struct audio_lowerhalf_s * /* Setup our operations */ ops = &priv->ops; + ops->setup = pcm_setup; ops->getcaps = pcm_getcaps; ops->configure = pcm_configure; ops->shutdown = pcm_shutdown; diff --git a/drivers/audio/audio_dma.c b/drivers/audio/audio_dma.c index 10b5c753ec7e5..1e7f228389789 100644 --- a/drivers/audio/audio_dma.c +++ b/drivers/audio/audio_dma.c @@ -55,7 +55,7 @@ struct audio_dma_s static int audio_dma_getcaps(struct audio_lowerhalf_s *dev, int type, struct audio_caps_s *caps); -static int audio_dma_shutdown(struct audio_lowerhalf_s *dev); +static int audio_dma_shutdown(struct audio_lowerhalf_s *dev, int cnt); #ifdef CONFIG_AUDIO_MULTI_SESSION static int audio_dma_configure(struct audio_lowerhalf_s *dev, void *session, @@ -106,6 +106,7 @@ static void audio_dma_callback(struct dma_chan_s *chan, void *arg, static const struct audio_ops_s g_audio_dma_ops = { + .setup = NULL, .getcaps = audio_dma_getcaps, .configure = audio_dma_configure, .shutdown = audio_dma_shutdown, @@ -255,7 +256,7 @@ static int audio_dma_configure(struct audio_lowerhalf_s *dev, return ret; } -static int audio_dma_shutdown(struct audio_lowerhalf_s *dev) +static int audio_dma_shutdown(struct audio_lowerhalf_s *dev, int cnt) { /* apps enqueued buffers, but doesn't start. stop here to * clear audio_dma->pendq. diff --git a/drivers/audio/audio_i2s.c b/drivers/audio/audio_i2s.c index c427b6e5ed1fe..65628c414b819 100644 --- a/drivers/audio/audio_i2s.c +++ b/drivers/audio/audio_i2s.c @@ -48,7 +48,7 @@ struct audio_i2s_s static int audio_i2s_getcaps(FAR struct audio_lowerhalf_s *dev, int type, FAR struct audio_caps_s *caps); -static int audio_i2s_shutdown(FAR struct audio_lowerhalf_s *dev); +static int audio_i2s_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); #ifdef CONFIG_AUDIO_MULTI_SESSION static int audio_i2s_configure(FAR struct audio_lowerhalf_s *dev, FAR void *session, @@ -101,6 +101,7 @@ static void audio_i2s_callback(struct i2s_dev_s *dev, static const struct audio_ops_s g_audio_i2s_ops = { + NULL, /* setup */ audio_i2s_getcaps, /* getcaps */ audio_i2s_configure, /* configure */ audio_i2s_shutdown, /* shutdown */ @@ -185,9 +186,7 @@ static int audio_i2s_getcaps(FAR struct audio_lowerhalf_s *dev, int type, /* Report the Sample rates we support */ caps->ac_controls.hw[0] = AUDIO_SAMP_RATE_DEF_ALL; - caps->ac_channels = 2; - break; } @@ -255,7 +254,7 @@ static int audio_i2s_configure(FAR struct audio_lowerhalf_s *dev, return ret; } -static int audio_i2s_shutdown(FAR struct audio_lowerhalf_s *dev) +static int audio_i2s_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev; FAR struct i2s_dev_s *i2s = audio_i2s->i2s; diff --git a/drivers/audio/audio_null.c b/drivers/audio/audio_null.c index 427f32bf23108..b015bde8b4b63 100644 --- a/drivers/audio/audio_null.c +++ b/drivers/audio/audio_null.c @@ -132,6 +132,7 @@ static int null_sleep(FAR struct audio_lowerhalf_s *dev, static const struct audio_ops_s g_audioops = { + NULL, /* setup */ null_getcaps, /* getcaps */ null_configure, /* configure */ null_shutdown, /* shutdown */ @@ -451,7 +452,7 @@ static int null_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int null_shutdown(FAR struct audio_lowerhalf_s *dev) +static int null_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { audinfo("Return OK\n"); return OK; diff --git a/drivers/audio/cs4344.c b/drivers/audio/cs4344.c index cfdc37c3700c8..b54b6e087e036 100644 --- a/drivers/audio/cs4344.c +++ b/drivers/audio/cs4344.c @@ -71,7 +71,7 @@ static int cs4344_configure(FAR struct audio_lowerhalf_s *dev, static int cs4344_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int cs4344_shutdown(FAR struct audio_lowerhalf_s *dev); +static int cs4344_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void cs4344_senddone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, int result); @@ -134,6 +134,7 @@ static int cs4344_reset(FAR struct cs4344_dev_s *priv); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ cs4344_getcaps, /* getcaps */ cs4344_configure, /* configure */ cs4344_shutdown, /* shutdown */ @@ -627,7 +628,7 @@ cs4344_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int cs4344_shutdown(FAR struct audio_lowerhalf_s *dev) +static int cs4344_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct cs4344_dev_s *priv = (FAR struct cs4344_dev_s *)dev; diff --git a/drivers/audio/cs43l22.c b/drivers/audio/cs43l22.c index 299518f028317..8523b5335767b 100644 --- a/drivers/audio/cs43l22.c +++ b/drivers/audio/cs43l22.c @@ -88,7 +88,7 @@ static int cs43l22_configure(FAR struct audio_lowerhalf_s *dev, static int cs43l22_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int cs43l22_shutdown(FAR struct audio_lowerhalf_s *dev); +static int cs43l22_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void cs43l22_senddone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, int result); @@ -168,6 +168,7 @@ static void cs43l22_reset(FAR struct cs43l22_dev_s *priv); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ cs43l22_getcaps, /* getcaps */ cs43l22_configure, /* configure */ cs43l22_shutdown, /* shutdown */ @@ -858,7 +859,7 @@ cs43l22_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int cs43l22_shutdown(FAR struct audio_lowerhalf_s *dev) +static int cs43l22_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct cs43l22_dev_s *priv = (FAR struct cs43l22_dev_s *)dev; diff --git a/drivers/audio/es8311.c b/drivers/audio/es8311.c index 296c75cb58e0c..9eb90049d7a11 100644 --- a/drivers/audio/es8311.c +++ b/drivers/audio/es8311.c @@ -91,7 +91,7 @@ static int es8311_configure(FAR struct audio_lowerhalf_s *dev, static int es8311_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif /* !CONFIG_AUDIO_MULTI_SESSION */ -static int es8311_shutdown(FAR struct audio_lowerhalf_s *dev); +static int es8311_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void es8311_processdone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, @@ -154,6 +154,7 @@ static int es8311_get_mclk_src(void); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ es8311_getcaps, /* getcaps */ es8311_configure, /* configure */ es8311_shutdown, /* shutdown */ @@ -1107,7 +1108,7 @@ static int es8311_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int es8311_shutdown(FAR struct audio_lowerhalf_s *dev) +static int es8311_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct es8311_dev_s *priv = (FAR struct es8311_dev_s *)dev; diff --git a/drivers/audio/es8388.c b/drivers/audio/es8388.c index 4708fb0d9ef52..57aa0bdf5e733 100644 --- a/drivers/audio/es8388.c +++ b/drivers/audio/es8388.c @@ -91,7 +91,7 @@ static int es8388_configure(FAR struct audio_lowerhalf_s *dev, static int es8388_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int es8388_shutdown(FAR struct audio_lowerhalf_s *dev); +static int es8388_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void es8388_processdone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, @@ -153,6 +153,7 @@ static void es8388_reset(FAR struct es8388_dev_s *priv); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ es8388_getcaps, /* getcaps */ es8388_configure, /* configure */ es8388_shutdown, /* shutdown */ @@ -1123,7 +1124,7 @@ static int es8388_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int es8388_shutdown(FAR struct audio_lowerhalf_s *dev) +static int es8388_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct es8388_dev_s *priv = (FAR struct es8388_dev_s *)dev; diff --git a/drivers/audio/vs1053.c b/drivers/audio/vs1053.c index 1b8d0aa1b062c..8901729d1c865 100644 --- a/drivers/audio/vs1053.c +++ b/drivers/audio/vs1053.c @@ -181,6 +181,7 @@ static int vs1053_ioctl(FAR struct audio_lowerhalf_s *lower, int cmd, static const struct audio_ops_s g_audioops = { + NULL, /* setup */ vs1053_getcaps, /* getcaps */ vs1053_configure, /* configure */ vs1053_shutdown, /* shutdown */ @@ -932,7 +933,7 @@ static int vs1053_hardreset(FAR struct vs1053_struct_s *dev) * ****************************************************************************/ -static int vs1053_shutdown(FAR struct audio_lowerhalf_s *lower) +static int vs1053_shutdown(FAR struct audio_lowerhalf_s *lower, int cnt) { FAR struct vs1053_struct_s *dev = (struct vs1053_struct_s *) lower; FAR struct spi_dev_s *spi = dev->spi; diff --git a/drivers/audio/wm8776.c b/drivers/audio/wm8776.c index b2088a2180fb1..79632c413dcd9 100644 --- a/drivers/audio/wm8776.c +++ b/drivers/audio/wm8776.c @@ -67,7 +67,7 @@ static int wm8776_configure(FAR struct audio_lowerhalf_s *dev, static int wm8776_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int wm8776_shutdown(FAR struct audio_lowerhalf_s *dev); +static int wm8776_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void wm8776_senddone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, int result); static void wm8776_returnbuffers(FAR struct wm8776_dev_s *priv); @@ -133,6 +133,7 @@ static void wm8776_hw_reset(FAR struct wm8776_dev_s *priv); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ wm8776_getcaps, /* getcaps */ wm8776_configure, /* configure */ wm8776_shutdown, /* shutdown */ @@ -450,7 +451,7 @@ static int wm8776_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int wm8776_shutdown(FAR struct audio_lowerhalf_s *dev) +static int wm8776_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct wm8776_dev_s *priv = (FAR struct wm8776_dev_s *)dev; diff --git a/drivers/audio/wm8904.c b/drivers/audio/wm8904.c index 1f25a7aae0b71..f45ab04f7eb8c 100644 --- a/drivers/audio/wm8904.c +++ b/drivers/audio/wm8904.c @@ -103,7 +103,7 @@ static int wm8904_configure(FAR struct audio_lowerhalf_s *dev, static int wm8904_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int wm8904_shutdown(FAR struct audio_lowerhalf_s *dev); +static int wm8904_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void wm8904_senddone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, int result); static void wm8904_returnbuffers(FAR struct wm8904_dev_s *priv); @@ -182,6 +182,7 @@ static void wm8904_hw_reset(FAR struct wm8904_dev_s *priv); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ wm8904_getcaps, /* getcaps */ wm8904_configure, /* configure */ wm8904_shutdown, /* shutdown */ @@ -1298,7 +1299,7 @@ static int wm8904_configure(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int wm8904_shutdown(FAR struct audio_lowerhalf_s *dev) +static int wm8904_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct wm8904_dev_s *priv = (FAR struct wm8904_dev_s *)dev; diff --git a/drivers/audio/wm8994.c b/drivers/audio/wm8994.c index 418fc1011fe9a..07ba935893897 100644 --- a/drivers/audio/wm8994.c +++ b/drivers/audio/wm8994.c @@ -113,7 +113,7 @@ static int wm8994_configure(FAR struct audio_lowerhalf_s *dev, static int wm8994_configure(FAR struct audio_lowerhalf_s *dev, FAR const struct audio_caps_s *caps); #endif -static int wm8994_shutdown(FAR struct audio_lowerhalf_s *dev); +static int wm8994_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static void wm8994_senddone(FAR struct i2s_dev_s *i2s, FAR struct ap_buffer_s *apb, FAR void *arg, int result); static void wm8994_returnbuffers(FAR struct wm8994_dev_s *priv); @@ -190,6 +190,7 @@ static void wm8994_hw_reset(FAR struct wm8994_dev_s *priv); static const struct audio_ops_s g_audioops = { + NULL, /* setup */ wm8994_getcaps, /* getcaps */ wm8994_configure, /* configure */ wm8994_shutdown, /* shutdown */ @@ -993,7 +994,7 @@ static int wm8994_configure(FAR struct audio_lowerhalf_s *dev, * */ -static int wm8994_shutdown(FAR struct audio_lowerhalf_s *dev) +static int wm8994_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { FAR struct wm8994_dev_s *priv = (FAR struct wm8994_dev_s *)dev; diff --git a/drivers/virtio/virtio-snd.c b/drivers/virtio/virtio-snd.c index 210c9a49794b2..691919aa1a2bc 100644 --- a/drivers/virtio/virtio-snd.c +++ b/drivers/virtio/virtio-snd.c @@ -168,7 +168,7 @@ static int virtio_snd_enqueuebuffer(FAR struct audio_lowerhalf_s *dev, static int virtio_snd_ioctl(FAR struct audio_lowerhalf_s *dev, int cmd, unsigned long arg); -static int virtio_snd_shutdown(FAR struct audio_lowerhalf_s *dev); +static int virtio_snd_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt); static int virtio_snd_probe(FAR struct virtio_device *vdev); static void virtio_snd_remove(FAR struct virtio_device *vdev); @@ -243,6 +243,7 @@ static struct virtio_driver g_virtio_snd_driver = static const struct audio_ops_s g_virtio_snd_ops = { + NULL, /* setup */ virtio_snd_getcaps, /* getcaps */ virtio_snd_configure, /* configure */ virtio_snd_shutdown, /* shutdown */ @@ -1004,7 +1005,7 @@ static int virtio_snd_ioctl(FAR struct audio_lowerhalf_s *dev, * ****************************************************************************/ -static int virtio_snd_shutdown(FAR struct audio_lowerhalf_s *dev) +static int virtio_snd_shutdown(FAR struct audio_lowerhalf_s *dev, int cnt) { vrtinfo("Return OK\n"); return OK; diff --git a/include/nuttx/audio/audio.h b/include/nuttx/audio/audio.h index 1053d8b9ffa00..d26e780e5a9d4 100644 --- a/include/nuttx/audio/audio.h +++ b/include/nuttx/audio/audio.h @@ -114,6 +114,7 @@ #define AUDIOIOC_SETPARAMTER _AUDIOIOC(18) #define AUDIOIOC_GETLATENCY _AUDIOIOC(19) #define AUDIOIOC_FLUSH _AUDIOIOC(20) +#define AUDIOIOC_VENDORSPECIFIC _AUDIOIOC(255) /* Audio Device Types *******************************************************/ @@ -353,6 +354,7 @@ #define AUDIO_MSG_COMMAND 10 #define AUDIO_MSG_SLIENCE 11 #define AUDIO_MSG_UNDERRUN 12 +#define AUDIO_MSG_IOERROR 13 #define AUDIO_MSG_USER 64 /* Audio Pipeline Buffer flags */ @@ -534,6 +536,10 @@ typedef CODE void (*audio_callback_t)(FAR void *priv, uint16_t reason, struct audio_lowerhalf_s; struct audio_ops_s { + /* This method is called when the related device file is opened. */ + + CODE int (*setup)(FAR struct audio_lowerhalf_s *dev, int opencnt); + /* This method is called to retrieve the lower-half device capabilities. * It will be called with device type AUDIO_TYPE_QUERY to request the * overall capabilities, such as to determine the types of devices @@ -571,7 +577,7 @@ struct audio_ops_s * processed / dequeued should be dequeued by this function. */ - CODE int (*shutdown)(FAR struct audio_lowerhalf_s *dev); + CODE int (*shutdown)(FAR struct audio_lowerhalf_s *dev, int opencnt); /* Start audio streaming in the configured mode. For input and synthesis * devices, this means it should begin sending streaming audio data.