drivers/audio/audio_i2s.c: Add audio_i2s device driver.
This commit is contained in:
parent
47db09633c
commit
85a993999e
@ -239,3 +239,9 @@ config AUDIO_NULL_WORKER_STACKSIZE
|
||||
default 768
|
||||
|
||||
endif # AUDIO_NULL
|
||||
|
||||
config AUDIO_I2S
|
||||
bool "Audio I2S"
|
||||
depends on AUDIO
|
||||
depends on I2S
|
||||
|
||||
|
@ -77,6 +77,10 @@ ifeq ($(CONFIG_AUDIO_TONE),y)
|
||||
CSRCS += tone.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_I2S),y)
|
||||
CSRCS += audio_i2s.c
|
||||
endif
|
||||
|
||||
# Include Audio driver support
|
||||
|
||||
DEPPATH += --dep-path audio
|
||||
|
463
drivers/audio/audio_i2s.c
Normal file
463
drivers/audio/audio_i2s.c
Normal file
@ -0,0 +1,463 @@
|
||||
/****************************************************************************
|
||||
* drivers/audio/audio_i2s.c
|
||||
*
|
||||
* Copyright (C) 2018 Pinecone Inc. All rights reserved.
|
||||
* Author: Zhong An <zhongan@pinecone.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/audio/audio.h>
|
||||
#include <nuttx/audio/i2s.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct audio_i2s_s
|
||||
{
|
||||
struct audio_lowerhalf_s dev;
|
||||
struct i2s_dev_s *i2s;
|
||||
bool playback;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
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);
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_configure(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session,
|
||||
FAR const struct audio_caps_s *caps);
|
||||
static int audio_i2s_start(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session);
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
|
||||
static int audio_i2s_stop(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session);
|
||||
#endif
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
|
||||
static int audio_i2s_pause(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session);
|
||||
static int audio_i2s_resume(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session);
|
||||
#endif
|
||||
static int audio_i2s_reserve(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void **session);
|
||||
static int audio_i2s_release(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session);
|
||||
#else
|
||||
static int audio_i2s_configure(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const struct audio_caps_s *caps);
|
||||
static int audio_i2s_start(FAR struct audio_lowerhalf_s *dev);
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
|
||||
static int audio_i2s_stop(FAR struct audio_lowerhalf_s *dev);
|
||||
#endif
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
|
||||
static int audio_i2s_pause(FAR struct audio_lowerhalf_s *dev);
|
||||
static int audio_i2s_resume(FAR struct audio_lowerhalf_s *dev);
|
||||
#endif
|
||||
static int audio_i2s_reserve(FAR struct audio_lowerhalf_s *dev);
|
||||
static int audio_i2s_release(FAR struct audio_lowerhalf_s *dev);
|
||||
#endif
|
||||
static int audio_i2s_allocbuffer(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR struct audio_buf_desc_s *bufdesc);
|
||||
static int audio_i2s_freebuffer(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR struct audio_buf_desc_s *bufdesc);
|
||||
static int audio_i2s_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR struct ap_buffer_s *apb);
|
||||
static int audio_i2s_ioctl(FAR struct audio_lowerhalf_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
static void audio_i2s_callback(struct i2s_dev_s *dev,
|
||||
FAR struct ap_buffer_s *apb, FAR void *arg,
|
||||
int result);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct audio_ops_s g_audio_i2s_ops =
|
||||
{
|
||||
.getcaps = audio_i2s_getcaps,
|
||||
.configure = audio_i2s_configure,
|
||||
.shutdown = audio_i2s_shutdown,
|
||||
.start = audio_i2s_start,
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
|
||||
.stop = audio_i2s_stop,
|
||||
#endif
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
|
||||
.pause = audio_i2s_pause,
|
||||
.resume = audio_i2s_resume,
|
||||
#endif
|
||||
.allocbuffer = audio_i2s_allocbuffer,
|
||||
.freebuffer = audio_i2s_freebuffer,
|
||||
.enqueuebuffer = audio_i2s_enqueuebuffer,
|
||||
.ioctl = audio_i2s_ioctl,
|
||||
.reserve = audio_i2s_reserve,
|
||||
.release = audio_i2s_release,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int audio_i2s_getcaps(FAR struct audio_lowerhalf_s *dev, int type,
|
||||
FAR struct audio_caps_s *caps)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
/* Validate the structure */
|
||||
|
||||
DEBUGASSERT(caps && caps->ac_len >= sizeof(struct audio_caps_s));
|
||||
audinfo("type=%d ac_type=%d\n", type, caps->ac_type);
|
||||
|
||||
caps->ac_format.hw = 0;
|
||||
caps->ac_controls.w = 0;
|
||||
|
||||
switch (caps->ac_type)
|
||||
{
|
||||
/* Caller is querying for the types of units we support */
|
||||
|
||||
case AUDIO_TYPE_QUERY:
|
||||
|
||||
/* Provide our overall capabilities. The interfacing software
|
||||
* must then call us back for specific info for each capability.
|
||||
*/
|
||||
|
||||
switch (caps->ac_subtype)
|
||||
{
|
||||
case AUDIO_TYPE_QUERY:
|
||||
|
||||
/* We don't decode any formats! Only something above us in
|
||||
* the audio stream can perform decoding on our behalf.
|
||||
*/
|
||||
|
||||
/* The types of audio units we implement */
|
||||
|
||||
if (audio_i2s->playback)
|
||||
{
|
||||
caps->ac_controls.b[0] = AUDIO_TYPE_OUTPUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
caps->ac_controls.b[0] = AUDIO_TYPE_INPUT;
|
||||
}
|
||||
|
||||
caps->ac_format.hw = 1 << (AUDIO_FMT_PCM - 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
caps->ac_controls.b[0] = AUDIO_SUBFMT_END;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Provide capabilities of our OUTPUT unit */
|
||||
|
||||
case AUDIO_TYPE_OUTPUT:
|
||||
case AUDIO_TYPE_INPUT:
|
||||
|
||||
switch (caps->ac_subtype)
|
||||
{
|
||||
case AUDIO_TYPE_QUERY:
|
||||
|
||||
/* Report the Sample rates we support */
|
||||
|
||||
caps->ac_controls.hw[0] =
|
||||
AUDIO_SAMP_RATE_8K | AUDIO_SAMP_RATE_11K |
|
||||
AUDIO_SAMP_RATE_16K | AUDIO_SAMP_RATE_22K |
|
||||
AUDIO_SAMP_RATE_32K | AUDIO_SAMP_RATE_44K |
|
||||
AUDIO_SAMP_RATE_48K | AUDIO_SAMP_RATE_96K |
|
||||
AUDIO_SAMP_RATE_128K | AUDIO_SAMP_RATE_160K |
|
||||
AUDIO_SAMP_RATE_172K | AUDIO_SAMP_RATE_192K;
|
||||
break;
|
||||
|
||||
default:
|
||||
I2S_IOCTL(i2s, AUDIOIOC_GETCAPS, (unsigned long)caps);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
I2S_IOCTL(i2s, AUDIOIOC_GETCAPS, (unsigned long)caps);
|
||||
break;
|
||||
}
|
||||
|
||||
return caps->ac_len;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_configure(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session,
|
||||
FAR const struct audio_caps_s *caps)
|
||||
#else
|
||||
static int audio_i2s_configure(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const struct audio_caps_s *caps)
|
||||
#endif
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
int samprate, nchannels, bpsamp;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(audio_i2s && caps);
|
||||
audinfo("ac_type: %d\n", caps->ac_type);
|
||||
|
||||
/* Process the configure operation */
|
||||
|
||||
switch (caps->ac_type)
|
||||
{
|
||||
case AUDIO_TYPE_OUTPUT:
|
||||
case AUDIO_TYPE_INPUT:
|
||||
|
||||
/* Save the current stream configuration */
|
||||
|
||||
samprate = caps->ac_controls.hw[0] |
|
||||
(caps->ac_controls.b[3] << 16);
|
||||
nchannels = caps->ac_channels;
|
||||
bpsamp = caps->ac_controls.b[2];
|
||||
|
||||
if (audio_i2s->playback)
|
||||
{
|
||||
I2S_TXCHANNELS(i2s, nchannels);
|
||||
I2S_TXDATAWIDTH(i2s, bpsamp);
|
||||
I2S_TXSAMPLERATE(i2s, samprate);
|
||||
}
|
||||
else
|
||||
{
|
||||
I2S_RXCHANNELS(i2s, nchannels);
|
||||
I2S_RXDATAWIDTH(i2s, bpsamp);
|
||||
I2S_RXSAMPLERATE(i2s, samprate);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = I2S_IOCTL(i2s, AUDIOIOC_CONFIGURE, (unsigned long)caps);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int audio_i2s_shutdown(FAR struct audio_lowerhalf_s *dev)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_SHUTDOWN, audio_i2s->playback);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_start(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session)
|
||||
#else
|
||||
static int audio_i2s_start(FAR struct audio_lowerhalf_s *dev)
|
||||
#endif
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_START, audio_i2s->playback);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_stop(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session)
|
||||
#else
|
||||
static int audio_i2s_stop(FAR struct audio_lowerhalf_s *dev)
|
||||
#endif
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_STOP, audio_i2s->playback);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_pause(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session)
|
||||
#else
|
||||
static int audio_i2s_pause(FAR struct audio_lowerhalf_s *dev)
|
||||
#endif
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_PAUSE, audio_i2s->playback);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_resume(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session)
|
||||
#else
|
||||
static int audio_i2s_resume(FAR struct audio_lowerhalf_s *dev)
|
||||
#endif
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_RESUME, audio_i2s->playback);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int audio_i2s_allocbuffer(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR struct audio_buf_desc_s *bufdesc)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_ALLOCBUFFER, (unsigned long)bufdesc);
|
||||
}
|
||||
|
||||
static int audio_i2s_freebuffer(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR struct audio_buf_desc_s *bufdesc)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, AUDIOIOC_FREEBUFFER, (unsigned long)bufdesc);
|
||||
}
|
||||
|
||||
static int audio_i2s_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR struct ap_buffer_s *apb)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
if (audio_i2s->playback)
|
||||
{
|
||||
return I2S_SEND(i2s, apb, audio_i2s_callback, audio_i2s, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return I2S_RECEIVE(i2s, apb, audio_i2s_callback, audio_i2s, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int audio_i2s_ioctl(FAR struct audio_lowerhalf_s *dev, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = (struct audio_i2s_s *)dev;
|
||||
FAR struct i2s_dev_s *i2s = audio_i2s->i2s;
|
||||
|
||||
return I2S_IOCTL(i2s, cmd, arg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_reserve(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void **session)
|
||||
#else
|
||||
static int audio_i2s_reserve(FAR struct audio_lowerhalf_s *dev)
|
||||
#endif
|
||||
{
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
*session = (void *)audio_i2s->playback;
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
static int audio_i2s_release(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR void *session)
|
||||
#else
|
||||
static int audio_i2s_release(FAR struct audio_lowerhalf_s *dev)
|
||||
#endif
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void audio_i2s_callback(struct i2s_dev_s *dev,
|
||||
FAR struct ap_buffer_s *apb,
|
||||
FAR void *arg, int result)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s = arg;
|
||||
bool final = false;
|
||||
|
||||
if ((apb->flags & AUDIO_APB_FINAL) != 0)
|
||||
{
|
||||
final = true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
audio_i2s->dev.upper(audio_i2s->dev.priv, AUDIO_CALLBACK_DEQUEUE, apb,
|
||||
OK, NULL);
|
||||
#else
|
||||
audio_i2s->dev.upper(audio_i2s->dev.priv, AUDIO_CALLBACK_DEQUEUE, apb,
|
||||
OK);
|
||||
#endif
|
||||
if (final)
|
||||
{
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
audio_i2s->dev.upper(audio_i2s->dev.priv, AUDIO_CALLBACK_COMPLETE,
|
||||
NULL, OK, NULL);
|
||||
#else
|
||||
audio_i2s->dev.upper(audio_i2s->dev.priv, AUDIO_CALLBACK_COMPLETE,
|
||||
NULL, OK);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct audio_lowerhalf_s *audio_i2s_initialize(FAR struct i2s_dev_s *i2s,
|
||||
bool playback)
|
||||
{
|
||||
FAR struct audio_i2s_s *audio_i2s;
|
||||
|
||||
if (i2s == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audio_i2s = kmm_zalloc(sizeof(struct audio_i2s_s));
|
||||
if (audio_i2s == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audio_i2s->playback = playback;
|
||||
audio_i2s->i2s = i2s;
|
||||
audio_i2s->dev.ops = &g_audio_i2s_ops;
|
||||
|
||||
return &audio_i2s->dev;
|
||||
}
|
54
include/nuttx/audio/audio_i2s.h
Normal file
54
include/nuttx/audio/audio_i2s.h
Normal file
@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/audio/audio_i2s.h
|
||||
*
|
||||
* Copyright (C) 2018 Pinecone Inc. All rights reserved.
|
||||
* Author: Zhong An <zhongan@pinecone.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_AUDIO_AUDIO_I2S_H
|
||||
#define __INCLUDE_NUTTX_AUDIO_AUDIO_I2S_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/audio/audio.h>
|
||||
#include <nuttx/audio/i2s.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct audio_lowerhalf_s *audio_i2s_initialize(FAR struct i2s_dev_s *i2s,
|
||||
bool playback);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user