nuttx/audio: add AUDIOIOC_GETSTATE ioctl

support get lower driver state

Signed-off-by: yangyalei <yangyalei@xiaomi.com>
This commit is contained in:
yangyalei
2025-05-30 11:12:21 +08:00
committed by Alan C. Assis
parent 0af7c985b4
commit 2cc624a4c4
2 changed files with 43 additions and 7 deletions
+33 -7
View File
@@ -74,7 +74,7 @@
struct audio_upperhalf_s struct audio_upperhalf_s
{ {
uint8_t crefs; /* The number of times the device has been opened */ uint8_t crefs; /* The number of times the device has been opened */
volatile bool started; /* True: playback is active */ volatile enum audio_state_e state; /* lowerhalf state */
struct audio_info_s info; /* Record the last playing audio format */ struct audio_info_s info; /* Record the last playing audio format */
mutex_t lock; /* Supports mutual exclusion */ mutex_t lock; /* Supports mutual exclusion */
FAR struct audio_lowerhalf_s *dev; /* lower-half state */ FAR struct audio_lowerhalf_s *dev; /* lower-half state */
@@ -228,6 +228,7 @@ static int audio_close(FAR struct file *filep)
lower->ops->shutdown(lower); lower->ops->shutdown(lower);
upper->usermq = NULL; upper->usermq = NULL;
upper->state = AUDIO_STATE_OPEN;
} }
ret = OK; ret = OK;
@@ -319,6 +320,7 @@ static int audio_configure(FAR struct audio_upperhalf_s *upper,
if (ret == OK && (caps->ac_type == AUDIO_TYPE_INPUT || if (ret == OK && (caps->ac_type == AUDIO_TYPE_INPUT ||
caps->ac_type == AUDIO_TYPE_OUTPUT)) caps->ac_type == AUDIO_TYPE_OUTPUT))
{ {
upper->state = AUDIO_STATE_PREPARED;
upper->info.format = caps->ac_subtype; upper->info.format = caps->ac_subtype;
upper->info.channels = caps->ac_channels; upper->info.channels = caps->ac_channels;
upper->info.subformat = caps->ac_controls.b[2]; upper->info.subformat = caps->ac_controls.b[2];
@@ -351,7 +353,7 @@ static int audio_start(FAR struct audio_upperhalf_s *upper)
/* Verify that the Audio is not already running */ /* Verify that the Audio is not already running */
if (!upper->started) if (upper->state == AUDIO_STATE_PREPARED)
{ {
/* Invoke the bottom half method to start the audio stream */ /* Invoke the bottom half method to start the audio stream */
@@ -369,7 +371,7 @@ static int audio_start(FAR struct audio_upperhalf_s *upper)
{ {
/* Indicate that the audio stream has started */ /* Indicate that the audio stream has started */
upper->started = true; upper->state = AUDIO_STATE_RUNNING;
} }
} }
@@ -487,7 +489,8 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
audinfo("AUDIOIOC_STOP\n"); audinfo("AUDIOIOC_STOP\n");
DEBUGASSERT(lower->ops->stop != NULL); DEBUGASSERT(lower->ops->stop != NULL);
if (upper->started) if (upper->state == AUDIO_STATE_RUNNING ||
upper->state == AUDIO_STATE_PAUSED)
{ {
#ifdef CONFIG_AUDIO_MULTI_SESSION #ifdef CONFIG_AUDIO_MULTI_SESSION
session = (FAR void *) arg; session = (FAR void *) arg;
@@ -495,7 +498,10 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
#else #else
ret = lower->ops->stop(lower); ret = lower->ops->stop(lower);
#endif #endif
upper->started = false; if (ret == OK)
{
upper->state = AUDIO_STATE_DRAINING;
}
} }
} }
break; break;
@@ -513,7 +519,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
audinfo("AUDIOIOC_PAUSE\n"); audinfo("AUDIOIOC_PAUSE\n");
DEBUGASSERT(lower->ops->pause != NULL); DEBUGASSERT(lower->ops->pause != NULL);
if (upper->started) if (upper->state == AUDIO_STATE_RUNNING)
{ {
#ifdef CONFIG_AUDIO_MULTI_SESSION #ifdef CONFIG_AUDIO_MULTI_SESSION
session = (FAR void *) arg; session = (FAR void *) arg;
@@ -521,6 +527,10 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
#else #else
ret = lower->ops->pause(lower); ret = lower->ops->pause(lower);
#endif #endif
if (ret == OK)
{
upper->state = AUDIO_STATE_PAUSED;
}
} }
} }
break; break;
@@ -535,7 +545,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
audinfo("AUDIOIOC_RESUME\n"); audinfo("AUDIOIOC_RESUME\n");
DEBUGASSERT(lower->ops->resume != NULL); DEBUGASSERT(lower->ops->resume != NULL);
if (upper->started) if (upper->state == AUDIO_STATE_PAUSED)
{ {
#ifdef CONFIG_AUDIO_MULTI_SESSION #ifdef CONFIG_AUDIO_MULTI_SESSION
session = (FAR void *) arg; session = (FAR void *) arg;
@@ -543,6 +553,10 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
#else #else
ret = lower->ops->resume(lower); ret = lower->ops->resume(lower);
#endif #endif
if (ret == OK)
{
upper->state = AUDIO_STATE_RUNNING;
}
} }
} }
break; break;
@@ -693,6 +707,18 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
} }
break; break;
/* AUDIOIOC_GETSTATE - Get lower driver state
*
* ioctl argument - pointer to receive the state
*/
case AUDIOIOC_GETSTATE:
{
*(FAR enum audio_state_e *)arg = upper->state;
ret = OK;
}
break;
/* Any unrecognized IOCTL commands might be /* Any unrecognized IOCTL commands might be
* platform-specific ioctl commands * platform-specific ioctl commands
*/ */
+10
View File
@@ -118,6 +118,7 @@
#define AUDIOIOC_FLUSH _AUDIOIOC(20) #define AUDIOIOC_FLUSH _AUDIOIOC(20)
#define AUDIOIOC_GETPOSITION _AUDIOIOC(21) #define AUDIOIOC_GETPOSITION _AUDIOIOC(21)
#define AUDIOIOC_GETAUDIOINFO _AUDIOIOC(22) #define AUDIOIOC_GETAUDIOINFO _AUDIOIOC(22)
#define AUDIOIOC_GETSTATE _AUDIOIOC(23)
/* Audio Device Types *******************************************************/ /* Audio Device Types *******************************************************/
@@ -376,6 +377,15 @@
#define AUDIO_CHANNELS_RANGE(min, max) ((uint8_t)(((min) << 4) | ((max) & 0xf))) #define AUDIO_CHANNELS_RANGE(min, max) ((uint8_t)(((min) << 4) | ((max) & 0xf)))
/* State of appl and lower driver, higher value = higher priority */
#define AUDIO_STATE_OPEN 0
#define AUDIO_STATE_PREPARED 1
#define AUDIO_STATE_PAUSED 2
#define AUDIO_STATE_XRUN 3
#define AUDIO_STATE_DRAINING 4
#define AUDIO_STATE_RUNNING 5
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/