+++ /dev/null
-#
-# For a description of the syntax of this configuration file,
-# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
-#
-
-config EXAMPLES_ALC5658CHAR_TEST
- bool "ALC5658 Character Codec reference application"
- default n
- depends on AUDIO_ALC5658CHAR
- ---help---
-
-
-
+++ /dev/null
-/****************************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <tinyara/config.h>
-#include <tinyara/audio/audio.h>
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <fcntl.h>
-#include <debug.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-#define BPSMPL 2
-
-#define BUFFSIZE (1024 * 16)
-
-#ifndef CONFIG_EXAMPLES_ALC5658CHAR_RXSTACKSIZE
-#define CONFIG_EXAMPLES_ALC5658CHAR_RXSTACKSIZE 2048
-#endif
-
-#ifndef CONFIG_EXAMPLES_ALC5658CHAR_TXSTACKSIZE
-#define CONFIG_EXAMPLES_ALC5658CHAR_TXSTACKSIZE 2048
-#endif
-
-#define LOOPBACK_CNT 200
-#define RECORD_CNT 20
-
-#define DEVICE_PATH "/dev/alc5658char0"
-/****************************************************************************
- * Private Type Declarations
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-enum alctest_mode {
- MODE_LOOPBACK = 0,
- MODE_RECORD,
-};
-
-static struct ap_buffer_s *rx_apb;
-static sem_t tx_start_sem;
-static sem_t rx_done_sem;
-static void *buff;
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static pthread_addr_t alc5658char_receiver(void *arg)
-{
- int fd;
- int pcm_fd;
- int i = 0;
- int errcode;
- int pos = 0;
- int nwritten;
- int mode = *(int *)arg;
-
- FAR struct audio_buf_desc_s bufdesc;
- char sign[4] = {'|', '/', '-', '\\'};
-
- /* Open the alc character device */
- fd = open(DEVICE_PATH, O_RDWR);
- if (fd < 0) {
- errcode = errno;
- printf("failed to open file, %d\n", errcode);
- return NULL;
- }
-
- if (mode == MODE_LOOPBACK)
- i = LOOPBACK_CNT;
- else if (mode == MODE_RECORD)
- i = RECORD_CNT;
-
- while (i--) {
- printf("Now Recording.. ");
- printf("%c\r", sign[i%4]);
-
- /* Define buffer size, if not defined 16KB buffer will be used */
- bufdesc.numbytes = BUFFSIZE;
- bufdesc.u.ppBuffer = NULL;
-
- /* Initiate Audio IN, read audio data */
- ioctl(fd, AUDIOIOC_DEQUEUEBUFFER, (unsigned long)&bufdesc);
-
- rx_apb = bufdesc.u.pBuffer;
-
- if (mode == MODE_LOOPBACK) {
- sem_post(&rx_done_sem);
- sem_wait(&tx_start_sem);
- } else if (mode == MODE_RECORD) {
- memcpy((void *)buff + pos, rx_apb->samp, rx_apb->nbytes);
- pos += rx_apb->nbytes;
- }
-
- ioctl(fd, AUDIOIOC_FREEBUFFER, (unsigned long)&bufdesc);
- }
- printf("\n - END\n");
-
- if (mode == MODE_RECORD) {
- printf("Received Data Write Start..\n");
-
- pcm_fd = open("/mnt/test.pcm", O_RDWR | O_CREAT | O_TRUNC);
- if (pcm_fd < 0) {
- errcode = errno;
- printf("failed to open file, %d\n", errcode);
- return NULL;
- }
-
- nwritten = write(pcm_fd, buff, BUFFSIZE * RECORD_CNT);
-
- if (nwritten != (BUFFSIZE * RECORD_CNT))
- printf("File Write Fail\n");
-
- printf("File Write Done\n");
- }
-
- close(fd);
-
- return NULL;
-}
-
-static pthread_addr_t alc5658char_transmitter(void *arg)
-{
- int fd;
- int pcm_fd;
- int i = 0;
- int errcode;
- int pos = 0;
- int nwritten;
- int mode = *(int *)arg;
- FAR struct audio_buf_desc_s bufdesc;
- struct ap_buffer_s *apb;
-
- if (mode == MODE_RECORD) {
- printf("Read File Start..\n");
-
- pcm_fd = open("/mnt/test.pcm", O_RDONLY | O_NONBLOCK);
- if (pcm_fd < 0) {
- errcode = errno;
- printf("failed to open file, %d\n", errcode);
- return NULL;
- }
-
- nwritten = read(pcm_fd, buff, BUFFSIZE * RECORD_CNT);
-
- printf("File Read Done\n");
- }
-
- /* Open the alc character device */
-
- fd = open(DEVICE_PATH, O_RDWR);
- if (fd < 0) {
- errcode = errno;
- printf("failed to open file, %d\n", errcode);
- return NULL;
- }
-
- if (mode == MODE_LOOPBACK)
- i = LOOPBACK_CNT;
- else if (mode == MODE_RECORD)
- i = RECORD_CNT;
-
- while (i--) {
- if (mode == MODE_LOOPBACK)
- sem_wait(&rx_done_sem);
-
- /* Define APB size and allocate */
- bufdesc.numbytes = BUFFSIZE;
- bufdesc.u.ppBuffer = &apb;
- ioctl(fd, AUDIOIOC_ALLOCBUFFER, (unsigned long)&bufdesc);
-
- if (mode == MODE_LOOPBACK) {
- memcpy(apb->samp, rx_apb->samp, rx_apb->nbytes);
- sem_post(&tx_start_sem);
-
- bufdesc.u.pBuffer = apb;
- apb->nbytes = rx_apb->nbytes;
- } else if (mode == MODE_RECORD) {
- memcpy(apb->samp, (void *)buff + pos, rx_apb->nbytes);
- pos += rx_apb->nbytes;
-
- bufdesc.u.pBuffer = apb;
- apb->nbytes = apb->nmaxbytes;
- }
-
- /* Enqueue buffer to be sent */
- ioctl(fd, AUDIOIOC_ENQUEUEBUFFER, (unsigned long)&bufdesc);
- }
-
- close(fd);
-
- return NULL;
-}
-
-static void alc5658char_test_help(FAR const char *program)
-{
- printf("================== %s commands ==================\n", program);
- printf("%s loopback : Loopback test using headphone jack\n", program);
- printf("%s record : Record and Play test using headphone jack\n", program);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#ifdef CONFIG_BUILD_KERNEL
-int main(int argc, FAR char *argv[])
-#else
-int alc5658char_test_main(int argc, char *argv[])
-#endif
-{
- pthread_attr_t attr;
- pthread_addr_t result;
- pthread_t transmitter;
- pthread_t receiver;
- int ret;
- int fd;
- int errcode;
- int mode;
- struct audio_caps_s caps;
-
- if (argc > 2) {
- alc5658char_test_help(argv[0]);
- return -EINVAL;
- }
-
- if (!strcmp(argv[1], "loopback")) {
- mode = MODE_LOOPBACK;
- } else if (!strcmp(argv[1], "record")) {
- mode = MODE_RECORD;
- } else {
- alc5658char_test_help(argv[0]);
- return -EINVAL;
- }
-
- /* Open the alc character device */
- fd = open(DEVICE_PATH, O_RDWR);
- if (fd < 0) {
- errcode = errno;
- printf("failed to open file, %d\n", errcode);
- return -ENODEV;
- }
-
- if (mode == MODE_LOOPBACK) {
- sem_init(&tx_start_sem, 0, 0);
- sem_init(&rx_done_sem, 0, 0);
- }
-
- printf("HELLO!!! %s\n", argv[0]);
-
- /* Input will be the same since it is the same I2S channel */
- caps.ac_len = sizeof(struct audio_caps_s);
- caps.ac_type = AUDIO_TYPE_OUTPUT;
- caps.ac_channels = 2;
-
- caps.ac_controls.hw[0] = AUDIO_SAMP_RATE_48K;
- caps.ac_controls.b[2] = 8 * BPSMPL;
-
- ret = ioctl(fd, AUDIOIOC_CONFIGURE, &caps);
-
- if (mode == MODE_RECORD) {
- buff = malloc(BUFFSIZE * RECORD_CNT);
- if (!buff) {
- printf("Alloc failed!!! Please Decrease BUFFSIZE\n");
- return -ENOMEM;
- }
- }
-
- /* Start the receiver thread */
- sched_lock();
- pthread_attr_init(&attr);
-
- /* Set the receiver stack size */
- (void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_ALC5658CHAR_RXSTACKSIZE);
-
- /* Start the receiver */
-
- ret = pthread_create(&receiver, &attr, alc5658char_receiver, (void *)&mode);
- if (ret != OK) {
- sched_unlock();
- printf("%s: ERROR: failed to Start receiver thread: %d\n", __func__, ret);
- goto err;
- }
-
- pthread_setname_np(receiver, "receiver");
- sched_unlock();
-
- ioctl(fd, AUDIOIOC_START, 0);
-
- /* Set Volume */
- caps.ac_type = AUDIO_TYPE_FEATURE;
-
- caps.ac_format.hw = AUDIO_FU_VOLUME;
- caps.ac_controls.hw[0] = 800;
- ret = ioctl(fd, AUDIOIOC_CONFIGURE, &caps);
-
- caps.ac_format.hw = AUDIO_FU_MUTE;
- caps.ac_controls.b[0] = false;
- ret = ioctl(fd, AUDIOIOC_CONFIGURE, &caps);
-
- caps.ac_format.hw = AUDIO_FU_BALANCE;
- caps.ac_controls.hw[0] = -500;
- ret = ioctl(fd, AUDIOIOC_CONFIGURE, &caps);
-
- /* Values -16 ~ 0 ~ 53 equal to -12dB ~ 0dB ~ 39.75 */
- caps.ac_format.hw = AUDIO_FU_MICGAIN;
- caps.ac_controls.hw[0] = 0;
- ret = ioctl(fd, AUDIOIOC_CONFIGURE, &caps);
-
- if (mode == MODE_RECORD) {
- ret = pthread_join(receiver, &result);
- if (ret != OK) {
- printf("%s: ERROR: pthread_join failed: %d\n", __func__, ret);
- goto err;
- }
- }
-
- /* Start the transmitter thread */
- sched_lock();
- pthread_attr_init(&attr);
-
- /* Set the transmitter stack size */
- (void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_ALC5658CHAR_TXSTACKSIZE);
-
- ret = pthread_create(&transmitter, &attr, alc5658char_transmitter, (void *)&mode);
- if (ret != OK) {
- sched_unlock();
- printf("%s: ERROR: failed to Start transmitter thread: %d\n", __func__, ret);
- printf("%s: Waiting for the receiver thread\n", __func__);
- (void)pthread_join(receiver, &result);
- goto err;
- }
-
- pthread_setname_np(transmitter, "transmitter");
- sched_unlock();
-
- ret = pthread_join(transmitter, &result);
- if (ret != OK) {
- printf("%s: ERROR: pthread_join failed: %d\n", __func__, ret);
- goto err;
- }
-
- if (mode == MODE_LOOPBACK) {
- ret = pthread_join(receiver, &result);
- if (ret != OK) {
- printf("%s: ERROR: pthread_join failed: %d\n", __func__, ret);
- goto err;
- }
- }
-
- sem_destroy(&tx_start_sem);
- sem_destroy(&rx_done_sem);
-
- ioctl(fd, AUDIOIOC_STOP, 0);
- close(fd);
- if (buff != NULL)
- free(buff);
-
- return EXIT_SUCCESS;
-
-err:
- sem_destroy(&tx_start_sem);
- sem_destroy(&rx_done_sem);
-
- ioctl(fd, AUDIOIOC_STOP, 0);
- close(fd);
- if (buff != NULL)
- free(buff);
- return EXIT_FAILURE;
-}
/* Fill the audio buffer with crap */
j = 0;
- for (ptr = apb->samp; j < CONFIG_EXAMPLES_I2SCHAR_BUFSIZE / 2; ) {
+ for (ptr = apb->samp; j < CONFIG_EXAMPLES_I2SCHAR_BUFSIZE / 2;) {
((uint16_t *) ptr)[j] = j;
j++;
((uint16_t *) ptr)[j] = -j;
--- /dev/null
+#
+# For a description of the syntax of this configuration file,
+# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
+#
+
+config EXAMPLES_NXPLAYER
+ bool "NxPlayer Media Player"
+ default n
+ depends on AUDIO
+ ---help---
+ Enable support for the NxPlayer media player library and optional
+ command line interface.
+
+if EXAMPLES_NXPLAYER
+
+config NXPLAYER_PLAYTHREAD_STACKSIZE
+ int "NxPlayer thread stack size"
+ default 1500
+ ---help---
+ Stack size to use with the NxPlayer play thread.
+
+config NXPLAYER_COMMAND_LINE
+ bool "Include nxplayer command line application"
+ default y
+ ---help---
+ Compiles in code for the nxplayer command line control.
+ This is a text-based command line interface that uses
+ the nxplayer library to play media files, control the
+ volume, balance, bass, etc.
+
+if NXPLAYER_COMMAND_LINE
+
+config NXPLAYER_INCLUDE_HELP
+ bool "Include HELP command and text"
+ default y
+ ---help---
+ Compiles in the NxPlayer help text to provide online help
+ for available commands with syntax.
+
+endif
+
+config NXPLAYER_INCLUDE_DEVICE_SEARCH
+ bool "Include audio device search code"
+ default y
+ ---help---
+ Compiles in extra code to search the audio device directory
+ for a suitable audio device to play the specified file.
+ Disabling this feature saves some code space, but it will
+ mean the calling application must specify the path of the
+ audio device to use before performing any other operations.
+
+config NXPLAYER_INCLUDE_PREFERRED_DEVICE
+ bool "Include preferred audio device specification code"
+ default y
+ ---help---
+ Adds support for identifying a specific audio device to use
+ for audio operations. If this feature is not enabled, then
+ an audio device search will be performed.
+
+config NXPLAYER_FMT_FROM_EXT
+ bool "Include code to determine Audio format from extension"
+ default y
+ ---help---
+ Compiles in extra code to determine audio format based
+ on the filename extension for known file types.
+ This feature is used if the format is not manually
+ specified, and will take priority over the more lengthy
+ file content detection approach.
+
+config NXPLAYER_FMT_FROM_HEADER
+ bool "Include code to find Audio format from file content"
+ default n
+ ---help---
+ Compiles in extra code to determine audio format based
+ on the header content of a file for known file types.
+ This feature is used when the format type cannot be
+ determined from the filename extension.
+
+config NXPLAYER_INCLUDE_MEDIADIR
+ bool "Include support for specifying a media directory"
+ default y
+ ---help---
+ Compiles in extra code to set a media directory which
+ will be searched when a request is made to play a file
+ which is not fully qualified.
+
+if NXPLAYER_INCLUDE_MEDIADIR
+
+config NXPLAYER_DEFAULT_MEDIADIR
+ string "Default root directory to search for media files"
+ default "/music"
+ ---help---
+ Specifies a root directory to search for media files
+ when an absolute path is not provided. This can be
+ changed at the nxplayer command line, but will default
+ to this value each time nxplayer is launched.
+
+config NXPLAYER_RECURSIVE_MEDIA_SEARCH
+ bool "Perform recursive directory search for media files"
+ default n
+ ---help---
+ When enabled, this feature will add code to perform
+ a complete recursive directory search within the
+ MEDIADIR for any media files that do not have a
+ qualified path (i.e. contain no '/' characters).
+
+endif
+
+config NXPLAYER_INCLUDE_SYSTEM_RESET
+ bool "Include support for system / hardware reset"
+ default n
+ ---help---
+ When enabled, this feature will add code to enable issuing
+ a HW reset via program call. The system reset will perform
+ a reset on all registered audio devices.
+
+endif
#
###########################################################################
-ifeq ($(CONFIG_EXAMPLES_ALC5658CHAR_TEST),y)
-CONFIGURED_APPS += examples/alc5658char_test
+ifeq ($(CONFIG_SYSTEM_NXPLAYER),y)
+CONFIGURED_APPS += examples/nxplayer
endif
###########################################################################
#
-# Copyright 2016 Samsung Electronics All Rights Reserved.
+# Copyright 2017 Samsung Electronics All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
###########################################################################
############################################################################
-# apps/examples/alctest/Makefile
+# apps/examples/nxplayer/Makefile
#
# Copyright (C) 2013 Ken Pettit. All rights reserved.
-# Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
+# Copyright (C) 2012-2013, 2016 Gregory Nutt. All rights reserved.
# Author: Ken Pettit <pettitkd@gmail.com>
# Gregory Nutt <gnutt@nuttx.org>
#
# built-in application info
-APPNAME = alctest
-FUNCNAME = alc5658char_test_main
-THREADEXEC = TASH_EXECMD_ASYNC
-
+APPNAME = nxplayer
+THREADEXEC = TASH_EXECMD_SYNC
ASRCS =
-CSRCS =
-MAINSRC = alc5658char_test_main.c
+CSRCS = nxplayer.c
+MAINSRC = nxplayer_main.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
INSTALL_DIR = $(BIN_DIR)
endif
-CONFIG_EXAMPLES_ALC5658CHAR_TEST_PROGNAME ?= alc5658char_test$(EXEEXT)
-PROGNAME = $(CONFIG_EXAMPLES_ALC5658CHAR_TEST_PROGNAME)
+CONFIG_EXAMPLES_NXPLAYER_PROGNAME ?= nxplayer$(EXEEXT)
+PROGNAME = $(CONFIG_EXAMPLES_NXPLAYER_PROGNAME)
ROOTDEPPATH = --dep-path .
endif
-ifeq ($(CONFIG_BUILTIN_APPS)$(CONFIG_EXAMPLES_ALC5658CHAR_TEST),yy)
-$(BUILTIN_REGISTRY)$(DELIM)$(FUNCNAME).bdat: $(DEPCONFIG) Makefile
- $(call REGISTER,$(APPNAME),$(FUNCNAME),$(THREADEXEC))
+ifeq ($(CONFIG_BUILTIN_APPS)$(CONFIG_SYSTEM_NXPLAYER),yy)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
+ $(call REGISTER,$(APPNAME),$(APPNAME)_main,$(THREADEXEC))
-context: $(BUILTIN_REGISTRY)$(DELIM)$(FUNCNAME).bdat
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
--- /dev/null
+NXPlayer
+========
+
+ Source: NuttX
+ Author: Ken Pettit
+ Date: 11 Sept 2013
+
+This application implements a command-line media player
+which uses the NuttX Audio system to play files (mp3,
+wav, etc.) from the file system.
+
+Usage:
+ nxplayer
+
+The application presents an command line for specifying
+player commands, such as "play filename", "pause",
+"volume 50%", etc.
--- /dev/null
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * apps/examples/nxplayer/nxplayer.c
+ *
+ * Developed by:
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * With ongoing support:
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Greory Nutt <gnutt@nuttx.org>
+ *
+ * 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 <tinyara/config.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <debug.h>
+
+#include <tinyara/audio/audio.h>
+#include <apps/nxplayer.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NXPLAYER_STATE_IDLE 0
+#define NXPLAYER_STATE_PLAYING 1
+#define NXPLAYER_STATE_PAUSED 2
+
+#ifndef CONFIG_AUDIO_NUM_BUFFERS
+#define CONFIG_AUDIO_NUM_BUFFERS 2
+#endif
+
+#ifndef CONFIG_AUDIO_BUFFER_NUMBYTES
+#define CONFIG_AUDIO_BUFFER_NUMBYTES 8192
+#endif
+
+#ifndef CONFIG_NXPLAYER_MSG_PRIO
+#define CONFIG_NXPLAYER_MSG_PRIO 1
+#endif
+
+#ifndef CONFIG_NXPLAYER_PLAYTHREAD_STACKSIZE
+#define CONFIG_NXPLAYER_PLAYTHREAD_STACKSIZE 1500
+#endif
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
+struct nxplayer_ext_fmt_s {
+ const char *ext;
+ uint16_t format;
+ CODE int (*getsubformat)(FAR FILE *fd);
+};
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_AUDIO_FORMAT_MIDI
+int nxplayer_getmidisubformat(FAR FILE *fd);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
+static const struct nxplayer_ext_fmt_s g_known_ext[] = {
+#ifdef CONFIG_AUDIO_FORMAT_AC3
+ {"ac3", AUDIO_FMT_AC3, NULL},
+#endif
+#ifdef CONFIG_AUDIO_FORMAT_MP3
+ {"mp3", AUDIO_FMT_MP3, NULL},
+#endif
+#ifdef CONFIG_AUDIO_FORMAT_DTS
+ {"dts", AUDIO_FMT_DTS, NULL},
+#endif
+#ifdef CONFIG_AUDIO_FORMAT_WMA
+ {"wma", AUDIO_FMT_WMA, NULL},
+#endif
+#ifdef CONFIG_AUDIO_FORMAT_PCM
+ {"wav", AUDIO_FMT_PCM, NULL},
+#endif
+#ifdef CONFIG_AUDIO_FORMAT_MIDI
+ {"mid", AUDIO_FMT_MIDI, nxplayer_getmidisubformat},
+ {"midi", AUDIO_FMT_MIDI, nxplayer_getmidisubformat},
+#endif
+#ifdef CONFIG_AUDIO_FORMAT_OGG_VORBIS
+ {"ogg", AUDIO_FMT_OGG_VORBIS, NULL}
+#endif
+};
+
+static const int g_known_ext_count = sizeof(g_known_ext) / sizeof(struct nxplayer_ext_fmt_s);
+#endif /* CONFIG_NXPLAYER_FMT_FROM_EXT */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxplayer_opendevice
+ *
+ * nxplayer_opendevice() either searches the Audio system for a device
+ * that is compatible with the specified audio format and opens it, or
+ * tries to open the prefered device if specified and validates that
+ * it supports the requested format.
+ *
+ * Return:
+ * OK if compatible device opened (searched or preferred)
+ * -ENODEV if no compatible device opened.
+ * -ENOENT if preferred device couldn't be opened.
+ *
+ ****************************************************************************/
+
+static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format, int subfmt)
+{
+ /* If we have a preferred device, then open it */
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+ if (pPlayer->prefdevice[0] != '\0') {
+ /* Use the saved prefformat to test if the requested
+ * format is specified by the device
+ */
+
+ if ((pPlayer->prefformat & (1 << (format - 1))) == 0 || (pPlayer->preftype & AUDIO_TYPE_OUTPUT) == 0) {
+ /* Format not supported by the device */
+
+ auddbg("ERROR: Format not supported by device: %d\n", format);
+ return -ENODEV;
+ }
+
+ /* Device supports the format. Open the device file. */
+
+ pPlayer->devFd = open(pPlayer->prefdevice, O_RDWR);
+ if (pPlayer->devFd == -1) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ auddbg("ERROR: Failed to open %s: %d\n", -errcode);
+ UNUSED(errcode);
+ return -ENOENT;
+ }
+
+ return OK;
+ }
+#endif
+
+#if defined(CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE) && \
+ defined(CONFIG_NXPLAYER_INCLUDE_DEVICE_SEARCH)
+
+ else
+#endif
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_DEVICE_SEARCH
+ {
+ struct audio_caps_s caps;
+ FAR struct dirent *pDevice;
+ FAR DIR *dirp;
+ char path[64];
+ uint8_t supported = true;
+ uint8_t x;
+
+ /* Search for a device in the audio device directory */
+
+#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
+#ifdef CONFIG_AUDIO_DEV_ROOT
+ dirp = opendir("/dev");
+#else
+ dirp = opendir(CONFIG_AUDIO_DEV_PATH);
+#endif /* CONFIG_AUDIO_DEV_ROOT */
+#else
+ dirp = opendir("/dev/audio");
+#endif /* CONFIG_AUDIO_CUSTOM_DEV_PATH */
+ if (dirp == NULL) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ auddbg("ERROR: Failed to open /dev/audio: %d\n", -errcode);
+ UNUSED(errcode);
+ return -ENODEV;
+ }
+
+ while ((pDevice = readdir(dirp)) != NULL) {
+ /* We found the next device. Try to open it and
+ * get its audio capabilities.
+ */
+
+#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
+#ifdef CONFIG_AUDIO_DEV_ROOT
+ snprintf(path, sizeof(path), "/dev/%s", pDevice->d_name);
+#else
+ snprintf(path, sizeof(path), CONFIG_AUDIO_DEV_PATH "/%s", pDevice->d_name);
+#endif /* CONFIG_AUDIO_DEV_ROOT */
+#else
+ snprintf(path, sizeof(path), "/dev/audio/%s", pDevice->d_name);
+#endif /* CONFIG_AUDIO_CUSTOM_DEV_PATH */
+
+ if ((pPlayer->devFd = open(path, O_RDWR)) != -1) {
+ /* We have the device file open. Now issue an AUDIO ioctls to
+ * get the capabilities
+ */
+
+ caps.ac_len = sizeof(caps);
+ caps.ac_type = AUDIO_TYPE_QUERY;
+ caps.ac_subtype = AUDIO_TYPE_QUERY;
+
+ if (ioctl(pPlayer->devFd, AUDIOIOC_GETCAPS, (unsigned long)&caps)
+ == caps.ac_len) {
+ /* Test if this device supports the format we want */
+
+ if (((caps.ac_format.hw & (1 << (format - 1))) != 0) && (caps.ac_controls.b[0] & AUDIO_TYPE_OUTPUT)) {
+ /* Do subformat detection */
+
+ if (subfmt != AUDIO_FMT_UNDEF) {
+ /* Prepare to get sub-formats for this main format */
+
+ caps.ac_subtype = format;
+ caps.ac_format.b[0] = 0;
+
+ while (ioctl(pPlayer->devFd, AUDIOIOC_GETCAPS, (unsigned long)&caps) == caps.ac_len) {
+ /* Check the next set of 4 controls to find the subformat */
+
+ for (x = 0; x < sizeof(caps.ac_controls); x++) {
+ if (caps.ac_controls.b[x] == subfmt) {
+ /* Sub format supported! */
+
+ break;
+ } else if (caps.ac_controls.b[x] == AUDIO_SUBFMT_END) {
+ /* Sub format not supported */
+
+ supported = false;
+ break;
+ }
+ }
+
+ /* If we reached the end of the subformat list, then
+ * break out of the loop.
+ */
+
+ if (x != sizeof(caps.ac_controls)) {
+ break;
+ }
+
+ /* Increment ac_format.b[0] to get next set of subformats */
+
+ caps.ac_format.b[0]++;
+ }
+ }
+
+ /* Test if subformat needed and detected */
+
+ if (supported) {
+ /* Yes, it supports this format. Use this device */
+
+ closedir(dirp);
+ return OK;
+ }
+ }
+ }
+
+ /* Not this device! */
+
+ close(pPlayer->devFd);
+ }
+ }
+
+ /* Close the directory */
+
+ closedir(dirp);
+ }
+#endif /* CONFIG_NXPLAYER_INCLUDE_DEVICE_SEARCH */
+
+ /* Device not found */
+
+ auddbg("ERROR: Device not found\n");
+ pPlayer->devFd = -1;
+ return -ENODEV;
+}
+
+/****************************************************************************
+ * Name: nxplayer_getmidisubformat
+ *
+ * nxplayer_getmidisubformat() reads the MIDI header and determins the
+ * MIDI format of the file.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_AUDIO_FORMAT_MIDI
+int nxplayer_getmidisubformat(FAR FILE *fd)
+{
+ char type[2];
+ int ret;
+
+ /* Seek to location 8 in the file (the format type) */
+
+ fseek(fd, 8, SEEK_SET);
+ fread(type, 1, 2, fd);
+
+ /* Set return value based on type */
+
+ switch (type[1]) {
+ case 0:
+ ret = AUDIO_SUBFMT_MIDI_0;
+ break;
+
+ case 1:
+ ret = AUDIO_SUBFMT_MIDI_1;
+ break;
+
+ case 2:
+ ret = AUDIO_SUBFMT_MIDI_2;
+ break;
+
+ default:
+ ret = AUDIO_SUBFMT_END;
+ break;
+ }
+ fseek(fd, 0, SEEK_SET);
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_fmtfromextension
+ *
+ * nxplayer_fmtfromextension() tries to determine the file format based
+ * on the extension of the supplied filename.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
+static inline int nxplayer_fmtfromextension(FAR struct nxplayer_s *pPlayer, FAR const char *pFilename, FAR int *subfmt)
+{
+ const char *pExt;
+ uint8_t x;
+ uint8_t c;
+
+ /* Find the file extension, if any */
+
+ x = strlen(pFilename) - 1;
+ while (x > 0) {
+ /* Seach backward for the first '.' */
+
+ if (pFilename[x] == '.') {
+ /* First '.' found. Now compare with known extensions */
+
+ pExt = &pFilename[x + 1];
+ for (c = 0; c < g_known_ext_count; c++) {
+ /* Test for extension match */
+
+ if (strcasecmp(pExt, g_known_ext[c].ext) == 0) {
+ /* Test if we have a sub-format detection routine */
+
+ if (subfmt && g_known_ext[c].getsubformat) {
+ *subfmt = g_known_ext[c].getsubformat(pPlayer->fileFd);
+ }
+
+ /* Return the format for this extension */
+
+ return g_known_ext[c].format;
+ }
+ }
+ }
+
+ /* Stop if we find a '/' */
+
+ if (pFilename[x] == '/') {
+ break;
+ }
+
+ x--;
+ }
+
+ return AUDIO_FMT_UNDEF;
+}
+#endif /* CONFIG_NXPLAYER_FMT_FROM_EXT */
+
+/****************************************************************************
+ * Name: nxplayer_fmtfromheader
+ *
+ * nxplayer_fmtfromheader() tries to determine the file format by checking
+ * the file header for known file types.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_FMT_FROM_HEADER
+static int nxplayer_fmtfromheader(FAR struct nxplayer_s *pPlayer)
+{
+ return AUDIO_FMT_UNDEF;
+}
+#endif /* CONFIG_NXPLAYER_FMT_FROM_HEADER */
+
+/****************************************************************************
+ * Name: nxplayer_mediasearch
+ *
+ * nxplayer_mediasearch() searches the subdirectories in the mediadir
+ * for the specified media file. We borrow the caller's path stack
+ * variable (playfile) to conserve stack space.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NXPLAYER_MEDIA_SEARCH) && defined(CONFIG_NXPLAYER_INCLUDE_MEDIADIR)
+static int nxplayer_mediasearch(FAR struct nxplayer_s *pPlayer, FAR const char *pFilename, FAR const char *path, int pathmax)
+{
+ return -ENOENT;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_readbuffer
+ *
+ * Read the next block of data from the media file into the specified
+ * buffer.
+ *
+ ****************************************************************************/
+
+static int nxplayer_readbuffer(FAR struct nxplayer_s *pPlayer, FAR struct ap_buffer_s *apb)
+{
+ /* Validate the file is still open. It will be closed automatically when
+ * we encounter the end of file (or, perhaps, a read error that we cannot
+ * handle.
+ */
+
+ if (pPlayer->fileFd == NULL) {
+ /* Return -ENODATA to indicate that there is nothing more to read from
+ * the file.
+ */
+
+ return -ENODATA;
+ }
+
+ /* Read data into the buffer. */
+
+ apb->nbytes = fread(&apb->samp, 1, apb->nmaxbytes, pPlayer->fileFd);
+ apb->curbyte = 0;
+ apb->flags = 0;
+
+ if (apb->nbytes < apb->nmaxbytes) {
+#ifdef CONFIG_DEBUG
+ int errcode = errno;
+ int readerror = ferror(pPlayer->fileFd);
+
+ audvdbg("Closing audio file, nbytes=%d readerr=%d\n", apb->nbytes, readerror);
+#endif
+
+ /* End of file or read error.. We are finished with this file in any
+ * event.
+ */
+
+ fclose(pPlayer->fileFd);
+ pPlayer->fileFd = NULL;
+
+ /* Set a flag to indicate that this is the final buffer in the stream */
+
+ apb->flags |= AUDIO_APB_FINAL;
+
+#ifdef CONFIG_DEBUG
+ /* Was this a file read error */
+
+ if (apb->nbytes == 0 && readerror) {
+ DEBUGASSERT(errcode > 0);
+ auddbg("ERROR: fread failed: %d\n", errcode);
+ }
+#endif
+ }
+
+ /* Return OK to indicate that the buffer should be passed through to the
+ * audio device. This does not necessarily indicate that data was read
+ * correctly.
+ */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nxplayer_enqueuebuffer
+ *
+ * Description:
+ * Enqueue the audio buffer in the downstream device. Normally we are
+ * called with a buffer of data to be enqueued in the audio stream.
+ *
+ * Be we may also receive an empty length buffer (with only the
+ * AUDIO_APB_FINAL set) in the event of certin read error occurs or in the
+ * event that the file was an exact multiple of the nmaxbytes size of the
+ * audio buffer. In that latter case, we have an end of file with no bytes
+ * read.
+ *
+ * These infrequent zero length buffers have to be passed through because
+ * the include the AUDIO_APB_FINAL flag that is needed to terminate the
+ * audio stream.
+ *
+ ****************************************************************************/
+
+static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer, FAR struct ap_buffer_s *apb)
+{
+ struct audio_buf_desc_s bufdesc;
+ int ret;
+
+ /* Now enqueue the buffer with the audio device. If the number of
+ * bytes in the file happens to be an exact multiple of the audio
+ * buffer size, then we will receive the last buffer size = 0. We
+ * encode this buffer also so the audio system knows its the end of
+ * the file and can do proper clean-up.
+ */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ bufdesc.session = pPlayer->session;
+#endif
+ bufdesc.numbytes = apb->nbytes;
+ bufdesc.u.pBuffer = apb;
+
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_ENQUEUEBUFFER, (unsigned long)&bufdesc);
+ if (ret < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ auddbg("ERROR: AUDIOIOC_ENQUEUEBUFFER ioctl failed: %d\n", errcode);
+ return -errcode;
+ }
+
+ /* Return OK to indicate that we successfully read data from the file
+ * (and we are not yet at the end of file)
+ */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nxplayer_thread_playthread
+ *
+ * This is the thread that reads the audio file file and enqueues /
+ * dequeues buffers to the selected and opened audio device.
+ *
+ ****************************************************************************/
+
+static void *nxplayer_playthread(pthread_addr_t pvarg)
+{
+ struct nxplayer_s *pPlayer = (struct nxplayer_s *)pvarg;
+ struct audio_msg_s msg;
+ struct audio_buf_desc_s buf_desc;
+ ssize_t size;
+ bool running = true;
+ bool streaming = true;
+ bool failed = false;
+#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
+ struct ap_buffer_info_s buf_info;
+ FAR struct ap_buffer_s **pBuffers;
+#else
+ FAR struct ap_buffer_s *pBuffers[CONFIG_AUDIO_NUM_BUFFERS];
+#endif
+#ifdef CONFIG_DEBUG
+ int outstanding = 0;
+#endif
+ int prio;
+ int x;
+ int ret;
+
+ audvdbg("Entry\n");
+
+ /* Query the audio device for it's preferred buffer size / qty */
+
+#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
+ if ((ret = ioctl(pPlayer->devFd, AUDIOIOC_GETBUFFERINFO, (unsigned long)&buf_info)) != OK) {
+ /* Driver doesn't report it's buffer size. Use our default. */
+
+ buf_info.buffer_size = CONFIG_AUDIO_BUFFER_NUMBYTES;
+ buf_info.nbuffers = CONFIG_AUDIO_NUM_BUFFERS;
+ }
+
+ /* Create array of pointers to buffers */
+
+ pBuffers = (FAR struct ap_buffer_s **)malloc(buf_info.nbuffers * sizeof(FAR void *));
+ if (pBuffers == NULL) {
+ /* Error allocating memory for buffer storage! */
+
+ ret = -ENOMEM;
+ running = false;
+ goto err_out;
+ }
+
+ /* Create our audio pipeline buffers to use for queueing up data */
+
+ for (x = 0; x < buf_info.nbuffers; x++) {
+ pBuffers[x] = NULL;
+ }
+
+ for (x = 0; x < buf_info.nbuffers; x++)
+#else /* CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFER */
+
+ for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++) {
+ pBuffers[x] = NULL;
+ }
+
+ for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++)
+#endif /* CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFER */
+ {
+ /* Fill in the buffer descriptor struct to issue an alloc request */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ buf_desc.session = pPlayer->session;
+#endif
+#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
+ buf_desc.numbytes = buf_info.buffer_size;
+#else
+ buf_desc.numbytes = CONFIG_AUDIO_BUFFER_NUMBYTES;
+#endif
+ buf_desc.u.ppBuffer = &pBuffers[x];
+
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_ALLOCBUFFER, (unsigned long)&buf_desc);
+ if (ret != sizeof(buf_desc)) {
+ /* Buffer alloc Operation not supported or error allocating! */
+
+ auddbg("ERROR: Could not allocate buffer %d\n", x);
+ running = false;
+ goto err_out;
+ }
+ }
+
+ /* Fill up the pipeline with enqueued buffers */
+
+#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
+ for (x = 0; x < buf_info.nbuffers; x++)
+#else
+ for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++)
+#endif
+ {
+ /* Read the next buffer of data */
+
+ ret = nxplayer_readbuffer(pPlayer, pBuffers[x]);
+ if (ret != OK) {
+ /* nxplayer_readbuffer will return an error if there is no further
+ * data to be read from the file. This can happen normally if the
+ * file is very small (less than will fit in
+ * CONFIG_AUDIO_NUM_BUFFERS) or if an error occurs trying to read
+ * from the file.
+ */
+
+ /* We are no longer streaming data from the file */
+
+ streaming = false;
+
+ if (x == 0) {
+ /* No buffers read? Should never really happen. Even in the
+ * case of a read failure, one empty buffer containing the
+ * AUDIO_APB_FINAL indication will be returned.
+ */
+
+ running = false;
+ }
+ }
+
+ /* Enqueue buffer by sending it to the audio driver */
+
+ else {
+ ret = nxplayer_enqueuebuffer(pPlayer, pBuffers[x]);
+ if (ret != OK) {
+ /* Failed to enqueue the buffer. The driver is not happy with
+ * the buffer. Perhaps a decoder has detected something that it
+ * does not like in the stream and has stopped streaming. This
+ * would happen normally if we send a file in the incorrect format
+ * to an audio decoder.
+ *
+ * We must stop streaming as gracefully as possible. Close the
+ * file so that no further data is read.
+ */
+
+ fclose(pPlayer->fileFd);
+ pPlayer->fileFd = NULL;
+
+ /* We are no longer streaming data from the file. Be we will
+ * need to wait for any outstanding buffers to be recovered. We
+ * also still expect the audio driver to send a AUDIO_MSG_COMPLETE
+ * message after all queued buffers have been returned.
+ */
+
+ streaming = false;
+ failed = true;
+ break;
+ }
+#ifdef CONFIG_DEBUG
+ else {
+ /* The audio driver has one more buffer */
+
+ outstanding++;
+ }
+#endif
+ }
+ }
+
+ audvdbg("%d buffers queued, running=%d streaming=%d\n", x, running, streaming);
+
+ /* Start the audio device */
+
+ if (running && !failed) {
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_START, (unsigned long)pPlayer->session);
+#else
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_START, 0);
+#endif
+
+ if (ret < 0) {
+ /* Error starting the audio stream! We need to continue running
+ * in order to recover the audio buffers that have already been
+ * queued.
+ */
+
+ failed = true;
+ }
+ }
+
+ if (running && !failed) {
+ /* Indicate we are playing a file */
+
+ pPlayer->state = NXPLAYER_STATE_PLAYING;
+
+ /* Set initial parameters such as volume, bass, etc.
+ * REVISIT: Shouldn't this actually be done BEFORE we start playing?
+ */
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+ (void)nxplayer_setvolume(pPlayer, pPlayer->volume);
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+ nxplayer_setbalance(pPlayer, pPlayer->balance);
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+ nxplayer_setbass(pPlayer, pPlayer->bass);
+ nxplayer_settreble(pPlayer, pPlayer->treble);
+#endif
+ }
+
+ /* Loop until we specifically break. running == true means that we are
+ * still looping waiting for the playback to complete. All of the file
+ * data may have been sent (if streaming == false), but the playback is
+ * not complete until we get the AUDIO_MSG_COMPLETE (or AUDIO_MSG_STOP)
+ * message
+ *
+ * The normal protocol for streaming errors detected by the audio driver
+ * is as follows:
+ *
+ * (1) The audio driver will indicated the error by returning a negated
+ * error value when the next buffer is enqueued. The upper level
+ * then knows that this buffer was not queue.
+ * (2) The audio driver must return all queued buffers using the
+ * AUDIO_MSG_DEQUEUE message, and
+ * (3) Terminate playing by sending the AUDIO_MSG_COMPLETE message.
+ */
+
+ audvdbg("%s\n", running ? "Playing..." : "Not runnning");
+ while (running) {
+ /* Wait for a signal either from the Audio driver that it needs
+ * additional buffer data, or from a user-space signal to pause,
+ * stop, etc.
+ */
+
+ size = mq_receive(pPlayer->mq, (FAR char *)&msg, sizeof(msg), &prio);
+
+ /* Validate a message was received */
+
+ if (size != sizeof(msg)) {
+ /* Interrupted by a signal? What to do? */
+
+ continue;
+ }
+
+ /* Perform operation based on message id */
+
+ switch (msg.msgId) {
+ /* An audio buffer is being dequeued by the driver */
+
+ case AUDIO_MSG_DEQUEUE:
+#ifdef CONFIG_DEBUG
+ /* Make sure that we believe that the audio driver has at
+ * least one buffer.
+ */
+
+ DEBUGASSERT(msg.u.pPtr && outstanding > 0);
+ outstanding--;
+#endif
+
+ /* Read data from the file directly into this buffer and
+ * re-enqueue it. streaming == true means that we have
+ * not yet hit the end-of-file.
+ */
+
+ if (streaming) {
+ /* Read the next buffer of data */
+
+ ret = nxplayer_readbuffer(pPlayer, msg.u.pPtr);
+ if (ret != OK) {
+ /* Out of data. Stay in the loop until the device sends
+ * us a COMPLETE message, but stop trying to play more
+ * data.
+ */
+
+ streaming = false;
+ }
+
+ /* Enqueue buffer by sending it to the audio driver */
+
+ else {
+ ret = nxplayer_enqueuebuffer(pPlayer, msg.u.pPtr);
+ if (ret != OK) {
+ /* There is some issue from the audio driver.
+ * Perhaps a problem in the file format?
+ *
+ * We must stop streaming as gracefully as possible.
+ * Close the file so that no further data is read.
+ */
+
+ fclose(pPlayer->fileFd);
+ pPlayer->fileFd = NULL;
+
+ /* Stop streaming and wait for buffers to be
+ * returned and to receive the AUDIO_MSG_COMPLETE
+ * indication.
+ */
+
+ streaming = false;
+ failed = true;
+ }
+#ifdef CONFIG_DEBUG
+ else {
+ /* The audio driver has one more buffer */
+
+ outstanding++;
+ }
+#endif
+ }
+ }
+ break;
+
+ /* Someone wants to stop the playback. */
+
+ case AUDIO_MSG_STOP:
+ /* Send a stop message to the device */
+
+ audvdbg("Stopping! outstanding=%d\n", outstanding);
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ ioctl(pPlayer->devFd, AUDIOIOC_STOP, (unsigned long)pPlayer->session);
+#else
+ ioctl(pPlayer->devFd, AUDIOIOC_STOP, 0);
+#endif
+ /* Stay in the running loop (without sending more data).
+ * we will need to recover our audio buffers. We will
+ * loop until AUDIO_MSG_COMPLETE is received.
+ */
+
+ streaming = false;
+ break;
+
+ /* Message indicating the playback is complete */
+
+ case AUDIO_MSG_COMPLETE:
+ audvdbg("Play complete. outstanding=%d\n", outstanding);
+ DEBUGASSERT(outstanding == 0);
+ running = false;
+ break;
+
+ /* Unknown / unsupported message ID */
+
+ default:
+ break;
+ }
+ }
+
+ /* Release our audio buffers and unregister / release the device */
+
+err_out:
+ audvdbg("Clean-up and exit\n");
+
+ /* Unregister the message queue and release the session */
+
+ ioctl(pPlayer->devFd, AUDIOIOC_UNREGISTERMQ, (unsigned long)pPlayer->mq);
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ ioctl(pPlayer->devFd, AUDIOIOC_RELEASE, (unsigned long)pPlayer->session);
+#else
+ ioctl(pPlayer->devFd, AUDIOIOC_RELEASE, 0);
+#endif
+
+ /* Cleanup */
+
+ while (sem_wait(&pPlayer->sem) < 0) ;
+
+#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
+ if (pBuffers != NULL) {
+ audvdbg("Freeing buffers\n");
+ for (x = 0; x < buf_info.nbuffers; x++) {
+ /* Fill in the buffer descriptor struct to issue a free request */
+
+ if (pBuffers[x] != NULL) {
+ buf_desc.u.pBuffer = pBuffers[x];
+ ioctl(pPlayer->devFd, AUDIOIOC_FREEBUFFER, (unsigned long)&buf_desc);
+ }
+ }
+
+ /* Free the pointers to the buffers */
+
+ free(pBuffers);
+ }
+#else
+ audvdbg("Freeing buffers\n");
+ for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++) {
+ /* Fill in the buffer descriptor struct to issue a free request */
+
+ if (pBuffers[x] != NULL) {
+ buf_desc.u.pBuffer = pBuffers[x];
+ ioctl(pPlayer->devFd, AUDIOIOC_FREEBUFFER, (unsigned long)&buf_desc);
+ }
+ }
+#endif
+
+ /* Close the files */
+
+ if (pPlayer->fileFd != NULL) {
+ fclose(pPlayer->fileFd); /* Close the file */
+ pPlayer->fileFd = NULL; /* Clear out the FD */
+ }
+
+ close(pPlayer->devFd); /* Close the device */
+ pPlayer->devFd = -1; /* Mark device as closed */
+ mq_close(pPlayer->mq); /* Close the message queue */
+ mq_unlink(pPlayer->mqname); /* Unlink the message queue */
+ pPlayer->state = NXPLAYER_STATE_IDLE; /* Go to IDLE */
+
+ sem_post(&pPlayer->sem); /* Release the semaphore */
+
+ /* The playthread is done with the context. Release it, which may
+ * actually cause the context to be freed if the creator has already
+ * abandoned (released) the context too.
+ */
+
+ nxplayer_release(pPlayer);
+
+ audvdbg("Exit\n");
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxplayer_setvolume
+ *
+ * nxplayer_setvolume() sets the volume.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+int nxplayer_setvolume(FAR struct nxplayer_s *pPlayer, uint16_t volume)
+{
+ struct audio_caps_desc_s cap_desc;
+ int ret;
+
+ /* Thread sync using the semaphore */
+
+ while (sem_wait(&pPlayer->sem) < 0) ;
+
+ /* If we are currently playing, then we need to post a message to
+ * the playthread to perform the volume change operation. If we
+ * are not playing, then just store the volume setting and it will
+ * be applied before the next playback begins.
+ */
+
+ if (pPlayer->state == NXPLAYER_STATE_PLAYING) {
+ /* Send a CONFIGURE ioctl to the device to set the volume */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ cap_desc.session = pPlayer->session;
+#endif
+ cap_desc.caps.ac_len = sizeof(struct audio_caps_s);
+ cap_desc.caps.ac_type = AUDIO_TYPE_FEATURE;
+ cap_desc.caps.ac_format.hw = AUDIO_FU_VOLUME;
+ cap_desc.caps.ac_controls.hw[0] = volume;
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_CONFIGURE, (unsigned long)&cap_desc);
+ if (ret < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ auddbg("ERROR: AUDIOIOC_CONFIGURE ioctl failed: %d\n", errcode);
+ return -errcode;
+ }
+ }
+
+ /* Store the volume setting */
+
+ pPlayer->volume = volume;
+ sem_post(&pPlayer->sem);
+
+ return OK;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_VOLUME */
+
+/****************************************************************************
+ * Name: nxplayer_setequalization
+ *
+ * Sets the level on each band of an equalizer. Each band setting is
+ * represented in one percent increments, so the range is 0-100.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * equalization - Pointer to array of equalizer settings of size
+ * CONFIG_AUDIO_EQUALIZER_NBANDS bytes. Each byte
+ * represents the setting for one band in the range of
+ * 0-100.
+ *
+ * Returned Value:
+ * OK if equalization was set correctly.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_EQUALIZER
+int nxplayer_setequalization(FAR struct nxplayer_s *pPlayer, FAR uint8_t *equalization)
+{
+#warning Missing logic
+ return -ENOSYS;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_setbass
+ *
+ * nxplayer_setbass() sets the bass level and range.
+ *
+ * Input:
+ * pPlayer - Pointer to the nxplayer context
+ * level - Bass level in percentage (0-100)
+ * range - Bass range in percentage (0-100)
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+int nxplayer_setbass(FAR struct nxplayer_s *pPlayer, uint8_t level)
+{
+ struct audio_caps_desc_s cap_desc;
+
+ /* Thread sync using the semaphore */
+
+ while (sem_wait(&pPlayer->sem) < 0) ;
+
+ /* If we are currently playing, then we need to post a message to
+ * the playthread to perform the volume change operation. If we
+ * are not playing, then just store the bass setting and it will
+ * be applied before the next playback begins.
+ */
+
+ if (pPlayer->state == NXPLAYER_STATE_PLAYING) {
+ /* Send a CONFIGURE ioctl to the device to set the volume */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ cap_desc.session = pPlayer->session;
+#endif
+ cap_desc.caps.ac_len = sizeof(struct audio_caps_s);
+ cap_desc.caps.ac_type = AUDIO_TYPE_FEATURE;
+ cap_desc.caps.ac_format.hw = AUDIO_FU_BASS;
+ cap_desc.caps.ac_controls.b[0] = level;
+ ioctl(pPlayer->devFd, AUDIOIOC_CONFIGURE, (unsigned long)&cap_desc);
+ }
+
+ /* Store the volume setting */
+
+ pPlayer->bass = level;
+
+ sem_post(&pPlayer->sem);
+
+ return -ENOENT;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_TONE */
+
+/****************************************************************************
+ * Name: nxplayer_settreble
+ *
+ * nxplayer_settreble() sets the treble level and range.
+ *
+ * Input:
+ * pPlayer - Pointer to the nxplayer context
+ * level - Treble level in percentage (0-100)
+ * range - Treble range in percentage (0-100)
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+int nxplayer_settreble(FAR struct nxplayer_s *pPlayer, uint8_t level)
+{
+ struct audio_caps_desc_s cap_desc;
+
+ /* Thread sync using the semaphore */
+
+ while (sem_wait(&pPlayer->sem) < 0) ;
+
+ /* If we are currently playing, then we need to post a message to
+ * the playthread to perform the volume change operation. If we
+ * are not playing, then just store the treble setting and it will
+ * be applied before the next playback begins.
+ */
+
+ if (pPlayer->state == NXPLAYER_STATE_PLAYING) {
+ /* Send a CONFIGURE ioctl to the device to set the volume */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ cap_desc.session = pPlayer->session;
+#endif
+ cap_desc.caps.ac_len = sizeof(struct audio_caps_s);
+ cap_desc.caps.ac_type = AUDIO_TYPE_FEATURE;
+ cap_desc.caps.ac_format.hw = AUDIO_FU_TREBLE;
+ cap_desc.caps.ac_controls.b[0] = level;
+ ioctl(pPlayer->devFd, AUDIOIOC_CONFIGURE, (unsigned long)&cap_desc);
+ }
+
+ /* Store the volume setting */
+
+ pPlayer->treble = level;
+
+ sem_post(&pPlayer->sem);
+
+ return -ENOENT;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_TONE */
+
+/****************************************************************************
+ * Name: nxplayer_setbalance
+ *
+ * nxplayer_setbalance() sets the volume.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+int nxplayer_setbalance(FAR struct nxplayer_s *pPlayer, uint16_t balance)
+{
+ struct audio_caps_desc_s cap_desc;
+
+ /* Thread sync using the semaphore */
+
+ while (sem_wait(&pPlayer->sem) < 0) ;
+
+ /* If we are currently playing, then we need to post a message to
+ * the playthread to perform the volume change operation. If we
+ * are not playing, then just store the volume setting and it will
+ * be applied before the next playback begins.
+ */
+
+ if (pPlayer->state == NXPLAYER_STATE_PLAYING) {
+ /* Send a CONFIGURE ioctl to the device to set the volume */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ cap_desc.session = pPlayer->session;
+#endif
+ cap_desc.caps.ac_len = sizeof(struct audio_caps_s);
+ cap_desc.caps.ac_type = AUDIO_TYPE_FEATURE;
+ cap_desc.caps.ac_format.hw = AUDIO_FU_BALANCE;
+ cap_desc.caps.ac_controls.hw[0] = balance;
+ ioctl(pPlayer->devFd, AUDIOIOC_CONFIGURE, (unsigned long)&cap_desc);
+ }
+
+ /* Store the volume setting */
+
+ pPlayer->balance = balance;
+
+ sem_post(&pPlayer->sem);
+
+ return -ENOENT;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_pause
+ *
+ * nxplayer_pause() pauses playback without cancelling it.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+int nxplayer_pause(FAR struct nxplayer_s *pPlayer)
+{
+ int ret = OK;
+
+ if (pPlayer->state == NXPLAYER_STATE_PLAYING) {
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_PAUSE, (unsigned long)pPlayer->session);
+#else
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_PAUSE, 0);
+#endif
+ if (ret == OK) {
+ pPlayer->state = NXPLAYER_STATE_PAUSED;
+ }
+ }
+
+ return ret;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME */
+
+/****************************************************************************
+ * Name: nxplayer_resume
+ *
+ * nxplayer_resume() resumes playback after a pause operation.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+int nxplayer_resume(FAR struct nxplayer_s *pPlayer)
+{
+ int ret = OK;
+
+ if (pPlayer->state == NXPLAYER_STATE_PAUSED) {
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_RESUME, (unsigned long)pPlayer->session);
+#else
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_RESUME, 0);
+#endif
+ if (ret == OK) {
+ pPlayer->state = NXPLAYER_STATE_PLAYING;
+ }
+ }
+
+ return ret;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME */
+
+/****************************************************************************
+ * Name: nxplayer_fforward
+ *
+ * Selects to fast forward in the audio data stream. The fast forward
+ * operation can be cancelled by simply selected no sub-sampling with
+ * the AUDIO_SUBSAMPLE_NONE argument returning to normal 1x forward play.
+ * This function may be called multiple times to change fast forward rate.
+ *
+ * The preferred way to cancel a fast forward operation is via
+ * nxplayer_cancel_motion() that provides the option to also return to
+ * paused, non-playing state.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * subsample - Identifies the fast forward rate (in terms of sub-sampling,
+ * but does not explicitly require sub-sampling). See
+ * AUDIO_SUBSAMPLE_* definitions.
+ *
+ * Returned Value:
+ * OK if fast forward operation successful.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_FFORWARD
+int nxplayer_fforward(FAR struct nxplayer_s *pPlayer, uint8_t subsample)
+{
+ struct audio_caps_desc_s cap_desc;
+ int ret;
+
+ DEBUGASSERT(pPlayer && subsample >= AUDIO_SUBSAMPLE_NONE && subsample <= AUDIO_SUBSAMPLE_MAX);
+
+ /* Send a CONFIGURE ioctl to the device to set the forward rate */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ cap_desc.session = pPlayer->session;
+#endif
+ cap_desc.caps.ac_len = sizeof(struct audio_caps_s);
+ cap_desc.caps.ac_type = AUDIO_TYPE_PROCESSING;
+ cap_desc.caps.ac_format.hw = AUDIO_PU_SUBSAMPLE_FORWARD;
+ cap_desc.caps.ac_controls.b[0] = subsample;
+
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_CONFIGURE, (unsigned long)&cap_desc);
+ if (ret < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ auddbg("ERROR: ioctl AUDIOIOC_CONFIGURE failed: %d\n", errcode);
+ ret = -errcode;
+ }
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_rewind
+ *
+ * Selects to rewind in the audio data stream. The rewind operation must
+ * be cancelled with nxplayer_cancel_motion. This function may be called
+ * multiple times to change rewind rate.
+ *
+ * NOTE that cancellation of the rewind operation differs from
+ * cancellation of the fast forward operation because we must both restore
+ * the sub-sampling rate to 1x and also return to forward play.
+ * AUDIO_SUBSAMPLE_NONE is not a valid argument to this function.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * subsample - Identifies the rewind rate (in terms of sub-sampling, but
+ * does not explicitly require sub-sampling). See
+ * AUDIO_SUBSAMPLE_* definitions.
+ *
+ * Returned Value:
+ * OK if rewind operation successfully initiated.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_REWIND
+int nxplayer_rewind(FAR struct nxplayer_s *pPlayer, uint8_t subsample)
+{
+ struct audio_caps_desc_s cap_desc;
+ int ret;
+
+ DEBUGASSERT(pPlayer && subsample >= AUDIO_SUBSAMPLE_MIN && subsample <= AUDIO_SUBSAMPLE_MAX);
+
+ /* Send a CONFIGURE ioctl to the device to set the forward rate */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ cap_desc.session = pPlayer->session;
+#endif
+ cap_desc.caps.ac_len = sizeof(struct audio_caps_s);
+ cap_desc.caps.ac_type = AUDIO_TYPE_PROCESSING;
+ cap_desc.caps.ac_format.hw = AUDIO_PU_SUBSAMPLE_REWIND;
+ cap_desc.caps.ac_controls.b[0] = subsample;
+
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_CONFIGURE, (unsigned long)&cap_desc);
+ if (ret < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ auddbg("ERROR: ioctl AUDIOIOC_CONFIGURE failed: %d\n", errcode);
+ ret = -errcode;
+ }
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cancel_motion
+ *
+ * Cancel a rewind or fast forward operation and return to either the
+ * paused state or to the normal, forward play state.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * paused - True: return to the paused state, False: return to the 1X
+ * forward play state.
+ *
+ * Returned Value:
+ * OK if rewind operation successfully cancelled.
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_AUDIO_EXCLUDE_FFORWARD) || !defined(CONFIG_AUDIO_EXCLUDE_REWIND)
+int nxplayer_cancel_motion(FAR struct nxplayer_s *pPlayer, bool paused)
+{
+ int ret;
+
+ /* I think this is equivalent to calling nxplayer_fforward with the
+ * argument AUDIO_SUBSAMPLE_NONE: Forward motion with no sub-sampling.
+ *
+ * REVISIT: There is no way at present to cancel sub-sampling and return
+ * to pause atomically.
+ */
+
+ ret = nxplayer_fforward(pPlayer, AUDIO_SUBSAMPLE_NONE);
+ if (ret < 0) {
+ auddbg("ERROR: nxplayer_fforward failed: %d\n", ret);
+ return ret;
+ }
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+ if (paused) {
+ ret = nxplayer_pause(pPlayer);
+ if (ret < 0) {
+ auddbg("ERROR: nxplayer_pause failed: %d\n", ret);
+ return ret;
+ }
+ }
+#endif
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_setdevice
+ *
+ * nxplayer_setdevice() sets the perferred audio device to use with the
+ * provided nxplayer context.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+int nxplayer_setdevice(FAR struct nxplayer_s *pPlayer, FAR const char *pDevice)
+{
+ int tempFd;
+ struct audio_caps_s caps;
+
+ DEBUGASSERT(pPlayer != NULL);
+ DEBUGASSERT(pDevice != NULL);
+
+ /* Try to open the device */
+
+ tempFd = open(pDevice, O_RDWR);
+ if (tempFd == -1) {
+ /* Error opening the device */
+
+ return -ENOENT;
+ }
+
+ /* Validate it's an Audio device by issuing an AUDIOIOC_GETCAPS ioctl */
+
+ caps.ac_len = sizeof(caps);
+ caps.ac_type = AUDIO_TYPE_QUERY;
+ caps.ac_subtype = AUDIO_TYPE_QUERY;
+ if (ioctl(tempFd, AUDIOIOC_GETCAPS, (unsigned long)&caps) != caps.ac_len) {
+ /* Not an Audio device! */
+
+ close(tempFd);
+ return -ENODEV;
+ }
+
+ /* Close the file */
+
+ close(tempFd);
+
+ /* Save the path and format capabilities of the preferred device */
+
+ strncpy(pPlayer->prefdevice, pDevice, sizeof(pPlayer->prefdevice));
+ pPlayer->prefformat = caps.ac_format.b[0] | (caps.ac_format.b[1] << 8);
+ pPlayer->preftype = caps.ac_controls.b[0];
+
+ return OK;
+}
+#endif /* CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE */
+
+/****************************************************************************
+ * Name: nxplayer_stop
+ *
+ * nxplayer_stop() stops the current playback and closes the file and
+ * the associated device.
+ *
+ * Input:
+ * pPlayer Pointer to the initialized MPlayer context
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+int nxplayer_stop(FAR struct nxplayer_s *pPlayer)
+{
+ struct audio_msg_s term_msg;
+ FAR void *value;
+
+ DEBUGASSERT(pPlayer != NULL);
+
+ /* Validate we are not in IDLE state */
+
+ sem_wait(&pPlayer->sem); /* Get the semaphore */
+ if (pPlayer->state == NXPLAYER_STATE_IDLE) {
+ sem_post(&pPlayer->sem); /* Release the semaphore */
+ return OK;
+ }
+
+ sem_post(&pPlayer->sem);
+
+ /* Notify the playback thread that it needs to cancel the playback */
+
+ term_msg.msgId = AUDIO_MSG_STOP;
+ term_msg.u.data = 0;
+ mq_send(pPlayer->mq, (FAR const char *)&term_msg, sizeof(term_msg), CONFIG_NXPLAYER_MSG_PRIO);
+
+ /* Join the thread. The thread will do all the cleanup. */
+
+ pthread_join(pPlayer->playId, &value);
+ pPlayer->playId = 0;
+
+ return OK;
+}
+#endif /* CONFIG_AUDIO_EXCLUDE_STOP */
+
+/****************************************************************************
+ * Name: nxplayer_playfile
+ *
+ * nxplayer_playfile() tries to play the specified file using the Audio
+ * system. If a preferred device is specified, it will try to use that
+ * device otherwise it will perform a search of the Audio device files
+ * to find a suitable device.
+ *
+ * Input:
+ * pPlayer Pointer to the initialized MPlayer context
+ * pFilename Pointer to the filename to play
+ * filefmt Format of the file or AUD_FMT_UNDEF if unknown / to be
+ * determined by nxplayer_playfile()
+ *
+ * Returns:
+ * OK File is being played
+ * -EBUSY The media device is busy
+ * -ENOSYS The media file is an unsupported type
+ * -ENODEV No audio device suitable to play the media type
+ * -ENOENT The media file was not found
+ *
+ ****************************************************************************/
+
+int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, FAR const char *pFilename, int filefmt, int subfmt)
+{
+ struct mq_attr attr;
+ struct sched_param sparam;
+ pthread_attr_t tattr;
+ void *value;
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+ char path[128];
+#endif
+ int tmpsubfmt = AUDIO_FMT_UNDEF;
+ int ret;
+
+ DEBUGASSERT(pPlayer != NULL);
+ DEBUGASSERT(pFilename != NULL);
+
+ if (pPlayer->state != NXPLAYER_STATE_IDLE) {
+ return -EBUSY;
+ }
+
+ audvdbg("==============================\n");
+ audvdbg("Playing file %s\n", pFilename);
+ audvdbg("==============================\n");
+
+ /* Test that the specified file exists */
+
+ if ((pPlayer->fileFd = fopen(pFilename, "r")) == NULL) {
+ /* File not found. Test if its in the mediadir */
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+ snprintf(path, sizeof(path), "%s/%s", pPlayer->mediadir, pFilename);
+
+ if ((pPlayer->fileFd = fopen(path, "r")) == NULL) {
+#ifdef CONFIG_NXPLAYER_MEDIA_SEARCH
+ /* File not found in the media dir. Do a search */
+
+ if (nxplayer_mediasearch(pPlayer, pFilename, path, sizeof(path)) != OK) {
+ auddbg("ERROR: Could not find file\n");
+ return -ENOENT;
+ }
+#else
+ auddbg("ERROR: Could not open %s or %s\n", pFilename, path);
+ return -ENOENT;
+#endif /* CONFIG_NXPLAYER_MEDIA_SEARCH */
+ }
+#else /* CONFIG_NXPLAYER_INCLUDE_MEDIADIR */
+
+ auddbg("ERROR: Could not open %s\n", pFilename);
+ return -ENOENT;
+#endif /* CONFIG_NXPLAYER_INCLUDE_MEDIADIR */
+ }
+#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
+ /* Try to determine the format of audio file based on the extension */
+
+ if (filefmt == AUDIO_FMT_UNDEF) {
+ filefmt = nxplayer_fmtfromextension(pPlayer, pFilename, &tmpsubfmt);
+ }
+#endif
+
+#ifdef CONFIG_NXPLAYER_FMT_FROM_HEADER
+ /* If type not identified, then test for known header types */
+
+ if (filefmt == AUDIO_FMT_UNDEF) {
+ filefmt = nxplayer_fmtfromheader(pPlayer, &subfmt, &tmpsubfmt);
+ }
+#endif
+
+ /* Test if we determined the file format */
+
+ if (filefmt == AUDIO_FMT_UNDEF) {
+ /* Hmmm, it's some unknown / unsupported type */
+
+ auddbg("ERROR: Unsupported format: %d \n", filefmt);
+ ret = -ENOSYS;
+ goto err_out_nodev;
+ }
+
+ /* Test if we have a sub format assignment from above */
+
+ if (subfmt == AUDIO_FMT_UNDEF) {
+ subfmt = tmpsubfmt;
+ }
+
+ /* Try to open the device */
+
+ ret = nxplayer_opendevice(pPlayer, filefmt, subfmt);
+ if (ret < 0) {
+ /* Error opening the device */
+
+ auddbg("ERROR: nxplayer_opendevice failed: %d\n", ret);
+ goto err_out_nodev;
+ }
+
+ /* Try to reserve the device */
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_RESERVE, (unsigned long)&pPlayer->session);
+#else
+ ret = ioctl(pPlayer->devFd, AUDIOIOC_RESERVE, 0);
+#endif
+ if (ret < 0) {
+ /* Device is busy or error */
+
+ auddbg("ERROR: Failed to reserve device: %d\n", ret);
+ ret = -errno;
+ goto err_out;
+ }
+
+ /* Create a message queue for the playthread */
+
+ attr.mq_maxmsg = 16;
+ attr.mq_msgsize = sizeof(struct audio_msg_s);
+ attr.mq_curmsgs = 0;
+ attr.mq_flags = 0;
+
+ snprintf(pPlayer->mqname, sizeof(pPlayer->mqname), "/tmp/%0lx", (unsigned long)((uintptr_t) pPlayer));
+
+ pPlayer->mq = mq_open(pPlayer->mqname, O_RDWR | O_CREAT, 0644, &attr);
+ if (pPlayer->mq == NULL) {
+ /* Unable to open message queue! */
+
+ ret = -errno;
+ auddbg("ERROR: mq_open failed: %d\n", ret);
+ goto err_out;
+ }
+
+ /* Register our message queue with the audio device */
+
+ ioctl(pPlayer->devFd, AUDIOIOC_REGISTERMQ, (unsigned long)pPlayer->mq);
+
+ /* Check if there was a previous thread and join it if there was
+ * to perform clean-up.
+ */
+
+ if (pPlayer->playId != 0) {
+ pthread_join(pPlayer->playId, &value);
+ }
+
+ /* Start the playfile thread to stream the media file to the
+ * audio device.
+ */
+
+ pthread_attr_init(&tattr);
+ sparam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 9;
+ (void)pthread_attr_setschedparam(&tattr, &sparam);
+ (void)pthread_attr_setstacksize(&tattr, CONFIG_NXPLAYER_PLAYTHREAD_STACKSIZE);
+
+ /* Add a reference count to the player for the thread and start the
+ * thread. We increment for the thread to avoid thread start-up
+ * race conditions.
+ */
+
+ nxplayer_reference(pPlayer);
+ ret = pthread_create(&pPlayer->playId, &tattr, nxplayer_playthread, (pthread_addr_t) pPlayer);
+ if (ret != OK) {
+ auddbg("ERROR: Failed to create playthread: %d\n", ret);
+ goto err_out;
+ }
+
+ /* Name the thread */
+
+ pthread_setname_np(pPlayer->playId, "playthread");
+ return OK;
+
+err_out:
+ close(pPlayer->devFd);
+ pPlayer->devFd = -1;
+
+err_out_nodev:
+ if (pPlayer->fileFd != NULL) {
+ fclose(pPlayer->fileFd);
+ pPlayer->fileFd = NULL;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxplayer_setmediadir
+ *
+ * nxplayer_setmediadir() sets the root path for media searches.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+void nxplayer_setmediadir(FAR struct nxplayer_s *pPlayer, FAR const char *mediadir)
+{
+ strncpy(pPlayer->mediadir, mediadir, sizeof(pPlayer->mediadir));
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_create
+ *
+ * nxplayer_create() allocates and initializes a nxplayer context for
+ * use by further nxplayer operations. This routine must be called before
+ * to perform the create for proper reference counting.
+ *
+ * Input Parameters: None
+ *
+ * Returned values:
+ * Pointer to the created context or NULL if there was an error.
+ *
+ ****************************************************************************/
+
+FAR struct nxplayer_s *nxplayer_create(void)
+{
+ FAR struct nxplayer_s *pPlayer;
+
+ /* Allocate the memory */
+
+ pPlayer = (FAR struct nxplayer_s *)malloc(sizeof(struct nxplayer_s));
+ if (pPlayer == NULL) {
+ return NULL;
+ }
+
+ /* Initialize the context data */
+
+ pPlayer->state = NXPLAYER_STATE_IDLE;
+ pPlayer->devFd = -1;
+ pPlayer->fileFd = NULL;
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+ pPlayer->prefdevice[0] = '\0';
+ pPlayer->prefformat = 0;
+ pPlayer->preftype = 0;
+#endif
+ pPlayer->mq = NULL;
+ pPlayer->playId = 0;
+ pPlayer->crefs = 1;
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+ pPlayer->bass = 50;
+ pPlayer->treble = 50;
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+ pPlayer->balance = 500;
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+ pPlayer->volume = 400;
+#endif
+
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ pPlayer->session = NULL;
+#endif
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+ strncpy(pPlayer->mediadir, CONFIG_NXPLAYER_DEFAULT_MEDIADIR, sizeof(pPlayer->mediadir));
+#endif
+ sem_init(&pPlayer->sem, 0, 1);
+
+ return pPlayer;
+}
+
+/****************************************************************************
+ * Name: nxplayer_release
+ *
+ * nxplayer_release() reduces the reference count by one and if it
+ * reaches zero, frees the context.
+ *
+ * Input Parameters:
+ * pPlayer Pointer to the NxPlayer context
+ *
+ * Returned values: None
+ *
+ ****************************************************************************/
+
+void nxplayer_release(FAR struct nxplayer_s *pPlayer)
+{
+ int refcount;
+ FAR void *value;
+
+ /* Grab the semaphore */
+
+ while (sem_wait(&pPlayer->sem) < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ if (errcode != EINTR) {
+ auddbg("ERROR: sem_wait failed: %d\n", errcode);
+ return;
+ }
+ }
+
+ /* Check if there was a previous thread and join it if there was */
+
+ if (pPlayer->playId != 0) {
+ sem_post(&pPlayer->sem);
+ pthread_join(pPlayer->playId, &value);
+ pPlayer->playId = 0;
+
+ while (sem_wait(&pPlayer->sem) < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ if (errcode != -EINTR) {
+ auddbg("ERROR: sem_wait failed: %d\n", errcode);
+ return;
+ }
+ }
+ }
+
+ /* Reduce the reference count */
+
+ refcount = pPlayer->crefs--;
+ sem_post(&pPlayer->sem);
+
+ /* If the ref count *was* one, then free the context */
+
+ if (refcount == 1) {
+ free(pPlayer);
+ }
+}
+
+/****************************************************************************
+ * Name: nxplayer_reference
+ *
+ * nxplayer_reference() increments the reference count by one.
+ *
+ * Input Parameters:
+ * pPlayer Pointer to the NxPlayer context
+ *
+ * Returned values: None
+ *
+ ****************************************************************************/
+
+void nxplayer_reference(FAR struct nxplayer_s *pPlayer)
+{
+ /* Grab the semaphore */
+
+ while (sem_wait(&pPlayer->sem) < 0) {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ if (errcode != -EINTR) {
+ auddbg("ERROR: sem_wait failed: %d\n", errcode);
+ return;
+ }
+ }
+
+ /* Increment the reference count */
+
+ pPlayer->crefs++;
+ sem_post(&pPlayer->sem);
+}
+
+/****************************************************************************
+ * Name: nxplayer_systemreset
+ *
+ * nxplayer_systemreset() performs a HW reset on all registered
+ * audio devices.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_SYSTEM_RESET
+int nxplayer_systemreset(FAR struct nxplayer_s *pPlayer)
+{
+ struct dirent *pDevice;
+ DIR *dirp;
+ char path[64];
+
+ /* Search for a device in the audio device directory */
+
+#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
+#ifdef CONFIG_AUDIO_DEV_ROOT
+ dirp = opendir("/dev");
+#else
+ dirp = opendir(CONFIG_AUDIO_DEV_PATH);
+#endif
+#else
+ dirp = opendir("/dev/audio");
+#endif
+ if (dirp == NULL) {
+ return -ENODEV;
+ }
+
+ while ((pDevice = readdir(dirp)) != NULL) {
+ /* We found the next device. Try to open it and
+ * get its audio capabilities.
+ */
+
+#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
+#ifdef CONFIG_AUDIO_DEV_ROOT
+ snprintf(path, sizeof(path), "/dev/%s", pDevice->d_name);
+#else
+ snprintf(path, sizeof(path), CONFIG_AUDIO_DEV_PATH "/%s", pDevice->d_name);
+#endif
+#else
+ snprintf(path, sizeof(path), "/dev/audio/%s", pDevice->d_name);
+#endif
+ if ((pPlayer->devFd = open(path, O_RDWR)) != -1) {
+ /* We have the device file open. Now issue an
+ * AUDIO ioctls to perform a HW reset
+ */
+
+ ioctl(pPlayer->devFd, AUDIOIOC_HWRESET, 0);
+
+ /* Now close the device */
+
+ close(pPlayer->devFd);
+ }
+
+ }
+
+ pPlayer->devFd = -1;
+ return OK;
+}
+#endif /* CONFIG_NXPLAYER_INCLUDE_SYSTEM_RESET */
--- /dev/null
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * apps/examples/nxplayer/nxplayer_main.c
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * 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 <tinyara/config.h>
+#include <tinyara/audio/audio.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <apps/readline.h>
+#include <apps/nxplayer.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NXPLAYER_VER "1.04"
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_HELP
+#define NXPLAYER_HELP_TEXT(x) #x
+#else
+#define NXPLAYER_HELP_TEXT(x)
+#endif
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+struct mp_cmd_s {
+ const char *cmd; /* The command text */
+ const char *arghelp; /* Text describing the args */
+ nxplayer_func pFunc; /* Pointer to command handler */
+ const char *help; /* The help text */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int nxplayer_cmd_quit(FAR struct nxplayer_s *pPlayer, char *parg);
+static int nxplayer_cmd_play(FAR struct nxplayer_s *pPlayer, char *parg);
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_SYSTEM_RESET
+static int nxplayer_cmd_reset(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+static int nxplayer_cmd_device(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int nxplayer_cmd_pause(FAR struct nxplayer_s *pPlayer, char *parg);
+static int nxplayer_cmd_resume(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+static int nxplayer_cmd_mediadir(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+static int nxplayer_cmd_stop(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+static int nxplayer_cmd_volume(FAR struct nxplayer_s *pPlayer, char *parg);
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+static int nxplayer_cmd_balance(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+#endif
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+static int nxplayer_cmd_bass(FAR struct nxplayer_s *pPlayer, char *parg);
+static int nxplayer_cmd_treble(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_HELP
+static int nxplayer_cmd_help(FAR struct nxplayer_s *pPlayer, char *parg);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct mp_cmd_s g_nxplayer_cmds[] = {
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+ {"balance", "d%", nxplayer_cmd_balance, NXPLAYER_HELP_TEXT(Set balance percentage( < 50 % means more left))},
+#endif
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+ {"bass", "d%", nxplayer_cmd_bass, NXPLAYER_HELP_TEXT(Set bass level percentage)},
+#endif
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+ {"device", "devfile", nxplayer_cmd_device, NXPLAYER_HELP_TEXT(Specify a preferred audio device)},
+#endif
+#ifdef CONFIG_NXPLAYER_INCLUDE_HELP
+ {"h", "", nxplayer_cmd_help, NXPLAYER_HELP_TEXT(Display help for commands)}
+ ,
+ {"help", "", nxplayer_cmd_help, NXPLAYER_HELP_TEXT(Display help for commands)}
+ ,
+#endif
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+ {"mediadir", "path", nxplayer_cmd_mediadir, NXPLAYER_HELP_TEXT(Change the media directory)}
+ ,
+#endif
+ {"play", "filename", nxplayer_cmd_play, NXPLAYER_HELP_TEXT(Play a media file)}
+ ,
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+ {"pause", "", nxplayer_cmd_pause, NXPLAYER_HELP_TEXT(Pause playback)}
+ ,
+#endif
+#ifdef CONFIG_NXPLAYER_INCLUDE_SYSTEM_RESET
+ {"reset", "", nxplayer_cmd_reset, NXPLAYER_HELP_TEXT(Perform a HW reset)}
+ ,
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+ {"resume", "", nxplayer_cmd_resume, NXPLAYER_HELP_TEXT(Resume playback)}
+ ,
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+ {"stop", "", nxplayer_cmd_stop, NXPLAYER_HELP_TEXT(Stop playback)}
+ ,
+#endif
+ {"tone", "freq secs", NULL, NXPLAYER_HELP_TEXT(Produce a pure tone)}
+ ,
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+ {"treble", "d%", nxplayer_cmd_treble, NXPLAYER_HELP_TEXT(Set treble level percentage)}
+ ,
+#endif
+ {"q", "", nxplayer_cmd_quit, NXPLAYER_HELP_TEXT(Exit NxPlayer)}
+ ,
+ {"quit", "", nxplayer_cmd_quit, NXPLAYER_HELP_TEXT(Exit NxPlayer)}
+ ,
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+ {"volume", "d%", nxplayer_cmd_volume, NXPLAYER_HELP_TEXT(Set volume to level specified)}
+#endif
+};
+
+static const int g_nxplayer_cmd_count = sizeof
+ (g_nxplayer_cmds) / sizeof(struct mp_cmd_s);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxplayer_cmd_play
+ *
+ * nxplayer_cmd_play() plays the specified media file using the nxplayer
+ * context.
+ *
+ ****************************************************************************/
+
+static int nxplayer_cmd_play(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ int ret;
+
+ /* Try to play the file specified */
+
+ ret = nxplayer_playfile(pPlayer, parg, AUDIO_FMT_UNDEF, AUDIO_FMT_UNDEF);
+
+ /* nxplayer_playfile returned values:
+ *
+ * OK File is being played
+ * -EBUSY The media device is busy
+ * -ENOSYS The media file is an unsupported type
+ * -ENODEV No audio device suitable to play the media type
+ * -ENOENT The media file was not found
+ */
+
+ switch (-ret) {
+ case OK:
+ break;
+
+ case ENODEV:
+ printf("No suitable Audio Device found\n");
+ break;
+
+ case EBUSY:
+ printf("Audio device busy\n");
+ break;
+
+ case ENOENT:
+ printf("File %s not found\n", parg);
+ break;
+
+ case ENOSYS:
+ printf("Unknown audio format\n");
+ break;
+
+ default:
+ printf("Error playing file: %d\n", -ret);
+ break;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxplayer_cmd_volume
+ *
+ * nxplayer_cmd_volume() sets the volume level.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+static int nxplayer_cmd_volume(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ uint16_t percent;
+
+ /* If no arg given, then print current volume */
+
+ if (parg == NULL || *parg == '\0') {
+ printf("volume: %d\n", pPlayer->volume / 10);
+ } else {
+ /* Get the percentage value from the argument */
+
+ percent = (uint16_t)(atof(parg) * 10.0);
+ nxplayer_setvolume(pPlayer, percent);
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_bass
+ *
+ * nxplayer_cmd_bass() sets the bass level and range.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+static int nxplayer_cmd_bass(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ uint8_t level_percent;
+
+ /* If no arg given, then print current bass */
+
+ if (parg == NULL || *parg == '\0') {
+ printf("bass: %d\n", pPlayer->bass);
+ } else {
+ /* Get the level and range percentage value from the argument */
+
+ level_percent = (uint8_t) atoi(parg);
+ nxplayer_setbass(pPlayer, level_percent);
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_treble
+ *
+ * nxplayer_cmd_treble() sets the treble level and range.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+static int nxplayer_cmd_treble(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ uint8_t level_percent;
+
+ /* If no arg given, then print current bass */
+
+ if (parg == NULL || *parg == '\0') {
+ printf("treble: %d\n", pPlayer->treble);
+ } else {
+ /* Get the level and range percentage value from the argument */
+
+ level_percent = (uint8_t) atoi(parg);
+ nxplayer_settreble(pPlayer, level_percent);
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_balance
+ *
+ * nxplayer_cmd_balance() sets the balance level.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+static int nxplayer_cmd_balance(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ uint16_t percent;
+
+ /* If no arg given, then print current volume */
+
+ if (parg == NULL || *parg == '\0') {
+ printf("balance: %d\n", pPlayer->volume / 10);
+ } else {
+ /* Get the percentage value from the argument */
+
+ percent = (uint16_t)(atof(parg) * 10.0);
+ nxplayer_setbalance(pPlayer, percent);
+ }
+
+ return OK;
+}
+#endif
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_reset
+ *
+ * nxplayer_cmd_reset() performs a HW reset of all the audio devices.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_SYSTEM_RESET
+static int nxplayer_cmd_reset(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ nxplayer_systemreset(pPlayer);
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_mediadir
+ *
+ * nxplayer_cmd_mediadir() displays or changes the media directory
+ * context.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+static int nxplayer_cmd_mediadir(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ /* If no arg given, then print current media dir */
+
+ if (parg == NULL || *parg == '\0') {
+ printf("%s\n", pPlayer->mediadir);
+ } else {
+ nxplayer_setmediadir(pPlayer, parg);
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_stop
+ *
+ * nxplayer_cmd_stop() stops playback of currently playing file
+ * context.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+static int nxplayer_cmd_stop(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ /* Stop the playback */
+
+ nxplayer_stop(pPlayer);
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_pause
+ *
+ * nxplayer_cmd_pause() pauses playback of currently playing file
+ * context.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int nxplayer_cmd_pause(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ /* Pause the playback */
+
+ nxplayer_pause(pPlayer);
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_resume
+ *
+ * nxplayer_cmd_resume() resumes playback of currently playing file
+ * context.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+static int nxplayer_cmd_resume(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ /* Resume the playback */
+
+ nxplayer_resume(pPlayer);
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cmd_device
+ *
+ * nxplayer_cmd_device() sets the preferred audio device for playback
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+static int nxplayer_cmd_device(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ int ret;
+ char path[32];
+
+ /* First try to open the file directly */
+
+ ret = nxplayer_setdevice(pPlayer, parg);
+ if (ret == -ENOENT) {
+ /* Append the /dev/audio path and try again */
+
+#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
+#ifdef CONFIG_AUDIO_DEV_ROOT
+ snprintf(path, sizeof(path), "/dev/%s", parg);
+#else
+ snprintf(path, sizeof(path), CONFIG_AUDIO_DEV_PATH "/%s", parg);
+#endif
+#else
+ snprintf(path, sizeof(path), "/dev/audio/%s", parg);
+#endif
+ ret = nxplayer_setdevice(pPlayer, path);
+ }
+
+ /* Test if the device file exists */
+
+ if (ret == -ENOENT) {
+ /* Device doesn't exit. Report error */
+
+ printf("Device %s not found\n", parg);
+ return ret;
+ }
+
+ /* Test if is is an audio device */
+
+ if (ret == -ENODEV) {
+ printf("Device %s is not an audio device\n", parg);
+ return ret;
+ }
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Device set successfully */
+
+ return OK;
+}
+#endif /* CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE */
+
+/****************************************************************************
+ * Name: nxplayer_cmd_quit
+ *
+ * nxplayer_cmd_quit() terminates the application
+ ****************************************************************************/
+
+static int nxplayer_cmd_quit(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ /* Stop the playback if any */
+
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+ nxplayer_stop(pPlayer);
+#endif
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nxplayer_cmd_help
+ *
+ * nxplayer_cmd_help() displays the application's help information on
+ * supported commands and command syntax.
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_HELP
+static int nxplayer_cmd_help(FAR struct nxplayer_s *pPlayer, char *parg)
+{
+ int x, len, maxlen = 0;
+ int c;
+
+ /* Calculate length of longest cmd + arghelp */
+
+ for (x = 0; x < g_nxplayer_cmd_count; x++) {
+ len = strlen(g_nxplayer_cmds[x].cmd) + strlen(g_nxplayer_cmds[x].arghelp);
+ if (len > maxlen) {
+ maxlen = len;
+ }
+ }
+
+ printf("NxPlayer commands\n================\n");
+ for (x = 0; x < g_nxplayer_cmd_count; x++) {
+ /* Print the command and it's arguments */
+
+ printf(" %s %s", g_nxplayer_cmds[x].cmd, g_nxplayer_cmds[x].arghelp);
+
+ /* Calculate number of spaces to print before the help text */
+
+ len = maxlen - (strlen(g_nxplayer_cmds[x].cmd) + strlen(g_nxplayer_cmds[x].arghelp));
+ for (c = 0; c < len; c++) {
+ printf(" ");
+ }
+
+ printf(" : %s\n", g_nxplayer_cmds[x].help);
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxplayer
+ *
+ * nxplayer() reads in commands from the console using the readline
+ * system add-in and implemets a command-line based media player that
+ * uses the NuttX audio system to play media files read in from the
+ * file system. Commands are provided for setting volume, base and
+ * other audio features, as well as for pausing and stoping the
+ * playback.
+ *
+ * Input Parameters:
+ * buf - The user allocated buffer to be filled.
+ * buflen - the size of the buffer.
+ * instream - The stream to read characters from
+ * outstream - The stream to each characters to.
+ *
+ * Returned values:
+ * On success, the (positive) number of bytes transferred is returned.
+ * EOF is returned to indicate either an end of file condition or a
+ * failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BUILD_KERNEL
+int main(int argc, FAR char *argv[])
+#else
+int nxplayer_main(int argc, char *argv[])
+#endif
+{
+ char buffer[64];
+ int len, x, running;
+ char *cmd, *arg;
+ FAR struct nxplayer_s *pPlayer;
+
+ printf("NxPlayer version " NXPLAYER_VER "\n");
+ printf("h for commands, q to exit\n");
+ printf("\n");
+
+ /* Initialize our NxPlayer context */
+
+ pPlayer = nxplayer_create();
+ if (pPlayer == NULL) {
+ printf("Error: Out of RAM\n");
+ return -ENOMEM;
+ }
+
+ /* Loop until the user exits */
+
+ running = TRUE;
+ while (running) {
+ /* Print a prompt */
+
+ printf("nxplayer> ");
+ fflush(stdout);
+
+ /* Read a line from the terminal */
+
+ len = readline(buffer, sizeof(buffer), stdin, stdout);
+ buffer[len] = '\0';
+ if (len > 0) {
+ if (buffer[len - 1] == '\n') {
+ buffer[len - 1] = '\0';
+ }
+
+ /* Parse the command from the argument */
+
+ cmd = strtok_r(buffer, " \n", &arg);
+ if (cmd == NULL) {
+ continue;
+ }
+
+ /* Remove leading spaces from arg */
+
+ while (*arg == ' ') {
+ arg++;
+ }
+
+ /* Find the command in our cmd array */
+
+ for (x = 0; x < g_nxplayer_cmd_count; x++) {
+ if (strcmp(cmd, g_nxplayer_cmds[x].cmd) == 0) {
+ /* Command found. Call it's handler if not NULL */
+
+ if (g_nxplayer_cmds[x].pFunc != NULL) {
+ g_nxplayer_cmds[x].pFunc(pPlayer, arg);
+ }
+
+ /* Test if it is a quit command */
+
+ if (g_nxplayer_cmds[x].pFunc == nxplayer_cmd_quit) {
+ running = FALSE;
+ }
+ break;
+ }
+ }
+
+ /* Test for Unknown command */
+
+ if (x == g_nxplayer_cmd_count) {
+ printf("%s: unknown nxplayer command\n", buffer);
+ }
+ }
+ }
+
+ /* Release the NxPlayer context */
+
+ nxplayer_release(pPlayer);
+
+ return OK;
+}
unsigned short int lut_sin[1024];
-
/****************************************************************************
* Private Functions
****************************************************************************/
}
for (i = 0; i < nSAMPLES; i++) {
- sample[0] = (0x8000 - lut_sin[(i&0x3F)<<4])/2;
- sample[1] = -(0x8000 - lut_sin[(i&0x3F)<<4])/2;
+ sample[0] = (0x8000 - lut_sin[(i & 0x3F) << 4]) / 2;
+ sample[1] = -(0x8000 - lut_sin[(i & 0x3F) << 4]) / 2;
((unsigned int *)buff)[i & 0xFF] = *(unsigned int *)sample;
if ((i & 0xff) == 0xff) {
nwritten = write(fd, buff, (i & 0xFF) * 4);
}
unsigned short int lut_sin[1024] = {
- 0x0, 0x2, 0x5, 0x9, 0xe, 0x14, 0x1c, 0x25,
- 0x2f, 0x3b, 0x47, 0x55, 0x64, 0x75, 0x86, 0x99,
- 0xad, 0xc3, 0xd9, 0xf1, 0x10a, 0x124, 0x13f, 0x15c,
- 0x17a, 0x199, 0x1b9, 0x1db, 0x1fe, 0x221, 0x247, 0x26d,
- 0x295, 0x2bd, 0x2e8, 0x313, 0x33f, 0x36d, 0x39c, 0x3cc,
- 0x3fd, 0x42f, 0x463, 0x498, 0x4ce, 0x505, 0x53e, 0x577,
- 0x5b2, 0x5ee, 0x62b, 0x669, 0x6a9, 0x6e9, 0x72b, 0x76e,
- 0x7b2, 0x7f8, 0x83e, 0x886, 0x8cf, 0x919, 0x964, 0x9b0,
- 0x9fd, 0xa4c, 0xa9b, 0xaec, 0xb3e, 0xb91, 0xbe5, 0xc3b,
- 0xc91, 0xce9, 0xd41, 0xd9b, 0xdf6, 0xe52, 0xeaf, 0xf0d,
- 0xf6c, 0xfcc, 0x102e, 0x1090, 0x10f4, 0x1158, 0x11be, 0x1225,
- 0x128d, 0x12f6, 0x1360, 0x13cb, 0x1437, 0x14a4, 0x1512, 0x1581,
- 0x15f1, 0x1662, 0x16d4, 0x1748, 0x17bc, 0x1831, 0x18a7, 0x191f,
- 0x1997, 0x1a10, 0x1a8a, 0x1b05, 0x1b82, 0x1bff, 0x1c7d, 0x1cfc,
- 0x1d7c, 0x1dfd, 0x1e7f, 0x1f02, 0x1f85, 0x200a, 0x2090, 0x2116,
- 0x219e, 0x2226, 0x22b0, 0x233a, 0x23c5, 0x2451, 0x24de, 0x256c,
- 0x25fa, 0x268a, 0x271a, 0x27ab, 0x283d, 0x28d0, 0x2964, 0x29f9,
- 0x2a8e, 0x2b24, 0x2bbc, 0x2c53, 0x2cec, 0x2d86, 0x2e20, 0x2ebb,
- 0x2f57, 0x2ff4, 0x3091, 0x312f, 0x31ce, 0x326e, 0x330e, 0x33b0,
- 0x3451, 0x34f4, 0x3598, 0x363c, 0x36e0, 0x3786, 0x382c, 0x38d3,
- 0x397b, 0x3a23, 0x3acc, 0x3b76, 0x3c20, 0x3ccb, 0x3d77, 0x3e23,
- 0x3ed0, 0x3f7d, 0x402b, 0x40da, 0x4189, 0x4239, 0x42ea, 0x439b,
- 0x444d, 0x44ff, 0x45b2, 0x4666, 0x471a, 0x47ce, 0x4883, 0x4939,
- 0x49ef, 0x4aa6, 0x4b5d, 0x4c15, 0x4ccd, 0x4d85, 0x4e3f, 0x4ef8,
- 0x4fb2, 0x506d, 0x5128, 0x51e4, 0x52a0, 0x535c, 0x5419, 0x54d6,
- 0x5594, 0x5652, 0x5710, 0x57cf, 0x588f, 0x594e, 0x5a0e, 0x5acf,
- 0x5b8f, 0x5c50, 0x5d12, 0x5dd4, 0x5e96, 0x5f58, 0x601b, 0x60de,
- 0x61a1, 0x6265, 0x6329, 0x63ed, 0x64b2, 0x6576, 0x663b, 0x6701,
- 0x67c6, 0x688c, 0x6952, 0x6a18, 0x6ade, 0x6ba5, 0x6c6c, 0x6d33,
- 0x6dfa, 0x6ec1, 0x6f89, 0x7051, 0x7118, 0x71e0, 0x72a8, 0x7371,
- 0x7439, 0x7501, 0x75ca, 0x7693, 0x775b, 0x7824, 0x78ed, 0x79b6,
- 0x7a7f, 0x7b48, 0x7c11, 0x7cdb, 0x7da4, 0x7e6d, 0x7f36, 0x8000,
- 0x8000, 0x80c9, 0x8192, 0x825b, 0x8324, 0x83ee, 0x84b7, 0x8580,
- 0x8649, 0x8712, 0x87db, 0x88a4, 0x896c, 0x8a35, 0x8afe, 0x8bc6,
- 0x8c8e, 0x8d57, 0x8e1f, 0x8ee7, 0x8fae, 0x9076, 0x913e, 0x9205,
- 0x92cc, 0x9393, 0x945a, 0x9521, 0x95e7, 0x96ad, 0x9773, 0x9839,
- 0x98fe, 0x99c4, 0x9a89, 0x9b4d, 0x9c12, 0x9cd6, 0x9d9a, 0x9e5e,
- 0x9f21, 0x9fe4, 0xa0a7, 0xa169, 0xa22b, 0xa2ed, 0xa3af, 0xa470,
- 0xa530, 0xa5f1, 0xa6b1, 0xa770, 0xa830, 0xa8ef, 0xa9ad, 0xaa6b,
- 0xab29, 0xabe6, 0xaca3, 0xad5f, 0xae1b, 0xaed7, 0xaf92, 0xb04d,
- 0xb107, 0xb1c0, 0xb27a, 0xb332, 0xb3ea, 0xb4a2, 0xb559, 0xb610,
- 0xb6c6, 0xb77c, 0xb831, 0xb8e5, 0xb999, 0xba4d, 0xbb00, 0xbbb2,
- 0xbc64, 0xbd15, 0xbdc6, 0xbe76, 0xbf25, 0xbfd4, 0xc082, 0xc12f,
- 0xc1dc, 0xc288, 0xc334, 0xc3df, 0xc489, 0xc533, 0xc5dc, 0xc684,
- 0xc72c, 0xc7d3, 0xc879, 0xc91f, 0xc9c3, 0xca67, 0xcb0b, 0xcbae,
- 0xcc4f, 0xccf1, 0xcd91, 0xce31, 0xced0, 0xcf6e, 0xd00b, 0xd0a8,
- 0xd144, 0xd1df, 0xd279, 0xd313, 0xd3ac, 0xd443, 0xd4db, 0xd571,
- 0xd606, 0xd69b, 0xd72f, 0xd7c2, 0xd854, 0xd8e5, 0xd975, 0xda05,
- 0xda93, 0xdb21, 0xdbae, 0xdc3a, 0xdcc5, 0xdd4f, 0xddd9, 0xde61,
- 0xdee9, 0xdf6f, 0xdff5, 0xe07a, 0xe0fd, 0xe180, 0xe202, 0xe283,
- 0xe303, 0xe382, 0xe400, 0xe47d, 0xe4fa, 0xe575, 0xe5ef, 0xe668,
- 0xe6e0, 0xe758, 0xe7ce, 0xe843, 0xe8b7, 0xe92b, 0xe99d, 0xea0e,
- 0xea7e, 0xeaed, 0xeb5b, 0xebc8, 0xec34, 0xec9f, 0xed09, 0xed72,
- 0xedda, 0xee41, 0xeea7, 0xef0b, 0xef6f, 0xefd1, 0xf033, 0xf093,
- 0xf0f2, 0xf150, 0xf1ad, 0xf209, 0xf264, 0xf2be, 0xf316, 0xf36e,
- 0xf3c4, 0xf41a, 0xf46e, 0xf4c1, 0xf513, 0xf564, 0xf5b3, 0xf602,
- 0xf64f, 0xf69b, 0xf6e6, 0xf730, 0xf779, 0xf7c1, 0xf807, 0xf84d,
- 0xf891, 0xf8d4, 0xf916, 0xf956, 0xf996, 0xf9d4, 0xfa11, 0xfa4d,
- 0xfa88, 0xfac1, 0xfafa, 0xfb31, 0xfb67, 0xfb9c, 0xfbd0, 0xfc02,
- 0xfc33, 0xfc63, 0xfc92, 0xfcc0, 0xfcec, 0xfd17, 0xfd42, 0xfd6a,
- 0xfd92, 0xfdb8, 0xfdde, 0xfe01, 0xfe24, 0xfe46, 0xfe66, 0xfe85,
- 0xfea3, 0xfec0, 0xfedb, 0xfef5, 0xff0e, 0xff26, 0xff3c, 0xff52,
- 0xff66, 0xff79, 0xff8a, 0xff9b, 0xffaa, 0xffb8, 0xffc4, 0xffd0,
- 0xffda, 0xffe3, 0xffeb, 0xfff1, 0xfff6, 0xfffa, 0xfffd, 0xffff,
- 0xffff, 0xfffe, 0xfffc, 0xfff8, 0xfff4, 0xffee, 0xffe7, 0xffdf,
- 0xffd5, 0xffca, 0xffbe, 0xffb1, 0xffa2, 0xff93, 0xff82, 0xff6f,
- 0xff5c, 0xff47, 0xff31, 0xff1a, 0xff02, 0xfee8, 0xfece, 0xfeb1,
- 0xfe94, 0xfe76, 0xfe56, 0xfe35, 0xfe13, 0xfdf0, 0xfdcb, 0xfda5,
- 0xfd7e, 0xfd56, 0xfd2d, 0xfd02, 0xfcd6, 0xfca9, 0xfc7b, 0xfc4b,
- 0xfc1b, 0xfbe9, 0xfbb6, 0xfb82, 0xfb4c, 0xfb16, 0xfade, 0xfaa5,
- 0xfa6b, 0xfa2f, 0xf9f3, 0xf9b5, 0xf976, 0xf936, 0xf8f5, 0xf8b2,
- 0xf86f, 0xf82a, 0xf7e4, 0xf79d, 0xf755, 0xf70c, 0xf6c1, 0xf675,
- 0xf629, 0xf5db, 0xf58c, 0xf53b, 0xf4ea, 0xf498, 0xf444, 0xf3ef,
- 0xf399, 0xf342, 0xf2ea, 0xf291, 0xf237, 0xf1db, 0xf17f, 0xf121,
- 0xf0c3, 0xf063, 0xf002, 0xefa0, 0xef3d, 0xeed9, 0xee74, 0xee0e,
- 0xeda6, 0xed3e, 0xecd5, 0xec6a, 0xebff, 0xeb92, 0xeb24, 0xeab6,
- 0xea46, 0xe9d6, 0xe964, 0xe8f1, 0xe87d, 0xe809, 0xe793, 0xe71c,
- 0xe6a4, 0xe62c, 0xe5b2, 0xe537, 0xe4bc, 0xe43f, 0xe3c1, 0xe343,
- 0xe2c3, 0xe243, 0xe1c1, 0xe13f, 0xe0bc, 0xe037, 0xdfb2, 0xdf2c,
- 0xdea5, 0xde1d, 0xdd94, 0xdd0a, 0xdc80, 0xdbf4, 0xdb68, 0xdada,
- 0xda4c, 0xd9bd, 0xd92d, 0xd89c, 0xd80b, 0xd778, 0xd6e5, 0xd651,
- 0xd5bc, 0xd526, 0xd48f, 0xd3f8, 0xd35f, 0xd2c6, 0xd22c, 0xd192,
- 0xd0f6, 0xd05a, 0xcfbd, 0xcf1f, 0xce80, 0xcde1, 0xcd41, 0xcca0,
- 0xcbff, 0xcb5c, 0xcab9, 0xca16, 0xc971, 0xc8cc, 0xc826, 0xc77f,
- 0xc6d8, 0xc630, 0xc588, 0xc4de, 0xc434, 0xc38a, 0xc2de, 0xc232,
- 0xc186, 0xc0d9, 0xc02b, 0xbf7c, 0xbecd, 0xbe1e, 0xbd6d, 0xbcbd,
- 0xbc0b, 0xbb59, 0xbaa6, 0xb9f3, 0xb940, 0xb88b, 0xb7d6, 0xb721,
- 0xb66b, 0xb5b5, 0xb4fe, 0xb446, 0xb38e, 0xb2d6, 0xb21d, 0xb164,
- 0xb0aa, 0xafef, 0xaf34, 0xae79, 0xadbd, 0xad01, 0xac45, 0xab88,
- 0xaaca, 0xaa0c, 0xa94e, 0xa88f, 0xa7d0, 0xa711, 0xa651, 0xa591,
- 0xa4d0, 0xa40f, 0xa34e, 0xa28c, 0xa1ca, 0xa108, 0xa045, 0x9f83,
- 0x9ebf, 0x9dfc, 0x9d38, 0x9c74, 0x9bb0, 0x9aeb, 0x9a26, 0x9961,
- 0x989c, 0x97d6, 0x9710, 0x964a, 0x9584, 0x94bd, 0x93f7, 0x9330,
- 0x9269, 0x91a1, 0x90da, 0x9012, 0x8f4b, 0x8e83, 0x8dbb, 0x8cf3,
- 0x8c2a, 0x8b62, 0x8a99, 0x89d1, 0x8908, 0x883f, 0x8776, 0x86ad,
- 0x85e4, 0x851b, 0x8452, 0x8389, 0x82c0, 0x81f7, 0x812d, 0x8064,
- 0x7f9b, 0x7ed2, 0x7e08, 0x7d3f, 0x7c76, 0x7bad, 0x7ae4, 0x7a1b,
- 0x7952, 0x7889, 0x77c0, 0x76f7, 0x762e, 0x7566, 0x749d, 0x73d5,
- 0x730c, 0x7244, 0x717c, 0x70b4, 0x6fed, 0x6f25, 0x6e5e, 0x6d96,
- 0x6ccf, 0x6c08, 0x6b42, 0x6a7b, 0x69b5, 0x68ef, 0x6829, 0x6763,
- 0x669e, 0x65d9, 0x6514, 0x644f, 0x638b, 0x62c7, 0x6203, 0x6140,
- 0x607c, 0x5fba, 0x5ef7, 0x5e35, 0x5d73, 0x5cb1, 0x5bf0, 0x5b2f,
- 0x5a6e, 0x59ae, 0x58ee, 0x582f, 0x5770, 0x56b1, 0x55f3, 0x5535,
- 0x5477, 0x53ba, 0x52fe, 0x5242, 0x5186, 0x50cb, 0x5010, 0x4f55,
- 0x4e9b, 0x4de2, 0x4d29, 0x4c71, 0x4bb9, 0x4b01, 0x4a4a, 0x4994,
- 0x48de, 0x4829, 0x4774, 0x46bf, 0x460c, 0x4559, 0x44a6, 0x43f4,
- 0x4342, 0x4292, 0x41e1, 0x4132, 0x4083, 0x3fd4, 0x3f26, 0x3e79,
- 0x3dcd, 0x3d21, 0x3c75, 0x3bcb, 0x3b21, 0x3a77, 0x39cf, 0x3927,
- 0x3880, 0x37d9, 0x3733, 0x368e, 0x35e9, 0x3546, 0x34a3, 0x3400,
- 0x335f, 0x32be, 0x321e, 0x317f, 0x30e0, 0x3042, 0x2fa5, 0x2f09,
- 0x2e6d, 0x2dd3, 0x2d39, 0x2ca0, 0x2c07, 0x2b70, 0x2ad9, 0x2a43,
- 0x29ae, 0x291a, 0x2887, 0x27f4, 0x2763, 0x26d2, 0x2642, 0x25b3,
- 0x2525, 0x2497, 0x240b, 0x237f, 0x22f5, 0x226b, 0x21e2, 0x215a,
- 0x20d3, 0x204d, 0x1fc8, 0x1f43, 0x1ec0, 0x1e3e, 0x1dbc, 0x1d3c,
- 0x1cbc, 0x1c3e, 0x1bc0, 0x1b43, 0x1ac8, 0x1a4d, 0x19d3, 0x195b,
- 0x18e3, 0x186c, 0x17f6, 0x1782, 0x170e, 0x169b, 0x1629, 0x15b9,
- 0x1549, 0x14db, 0x146d, 0x1400, 0x1395, 0x132a, 0x12c1, 0x1259,
- 0x11f1, 0x118b, 0x1126, 0x10c2, 0x105f, 0xffd, 0xf9c, 0xf3c,
- 0xede, 0xe80, 0xe24, 0xdc8, 0xd6e, 0xd15, 0xcbd, 0xc66,
- 0xc10, 0xbbb, 0xb67, 0xb15, 0xac4, 0xa73, 0xa24, 0x9d6,
- 0x98a, 0x93e, 0x8f3, 0x8aa, 0x862, 0x81b, 0x7d5, 0x790,
- 0x74d, 0x70a, 0x6c9, 0x689, 0x64a, 0x60c, 0x5d0, 0x594,
- 0x55a, 0x521, 0x4e9, 0x4b3, 0x47d, 0x449, 0x416, 0x3e4,
- 0x3b4, 0x384, 0x356, 0x329, 0x2fd, 0x2d2, 0x2a9, 0x281,
- 0x25a, 0x234, 0x20f, 0x1ec, 0x1ca, 0x1a9, 0x189, 0x16b,
- 0x14e, 0x131, 0x117, 0xfd, 0xe5, 0xce, 0xb8, 0xa3,
- 0x90, 0x7d, 0x6c, 0x5d, 0x4e, 0x41, 0x35, 0x2a,
- 0x20, 0x18, 0x11, 0xb, 0x7, 0x3, 0x1, 0x0,
+ 0x0, 0x2, 0x5, 0x9, 0xe, 0x14, 0x1c, 0x25,
+ 0x2f, 0x3b, 0x47, 0x55, 0x64, 0x75, 0x86, 0x99,
+ 0xad, 0xc3, 0xd9, 0xf1, 0x10a, 0x124, 0x13f, 0x15c,
+ 0x17a, 0x199, 0x1b9, 0x1db, 0x1fe, 0x221, 0x247, 0x26d,
+ 0x295, 0x2bd, 0x2e8, 0x313, 0x33f, 0x36d, 0x39c, 0x3cc,
+ 0x3fd, 0x42f, 0x463, 0x498, 0x4ce, 0x505, 0x53e, 0x577,
+ 0x5b2, 0x5ee, 0x62b, 0x669, 0x6a9, 0x6e9, 0x72b, 0x76e,
+ 0x7b2, 0x7f8, 0x83e, 0x886, 0x8cf, 0x919, 0x964, 0x9b0,
+ 0x9fd, 0xa4c, 0xa9b, 0xaec, 0xb3e, 0xb91, 0xbe5, 0xc3b,
+ 0xc91, 0xce9, 0xd41, 0xd9b, 0xdf6, 0xe52, 0xeaf, 0xf0d,
+ 0xf6c, 0xfcc, 0x102e, 0x1090, 0x10f4, 0x1158, 0x11be, 0x1225,
+ 0x128d, 0x12f6, 0x1360, 0x13cb, 0x1437, 0x14a4, 0x1512, 0x1581,
+ 0x15f1, 0x1662, 0x16d4, 0x1748, 0x17bc, 0x1831, 0x18a7, 0x191f,
+ 0x1997, 0x1a10, 0x1a8a, 0x1b05, 0x1b82, 0x1bff, 0x1c7d, 0x1cfc,
+ 0x1d7c, 0x1dfd, 0x1e7f, 0x1f02, 0x1f85, 0x200a, 0x2090, 0x2116,
+ 0x219e, 0x2226, 0x22b0, 0x233a, 0x23c5, 0x2451, 0x24de, 0x256c,
+ 0x25fa, 0x268a, 0x271a, 0x27ab, 0x283d, 0x28d0, 0x2964, 0x29f9,
+ 0x2a8e, 0x2b24, 0x2bbc, 0x2c53, 0x2cec, 0x2d86, 0x2e20, 0x2ebb,
+ 0x2f57, 0x2ff4, 0x3091, 0x312f, 0x31ce, 0x326e, 0x330e, 0x33b0,
+ 0x3451, 0x34f4, 0x3598, 0x363c, 0x36e0, 0x3786, 0x382c, 0x38d3,
+ 0x397b, 0x3a23, 0x3acc, 0x3b76, 0x3c20, 0x3ccb, 0x3d77, 0x3e23,
+ 0x3ed0, 0x3f7d, 0x402b, 0x40da, 0x4189, 0x4239, 0x42ea, 0x439b,
+ 0x444d, 0x44ff, 0x45b2, 0x4666, 0x471a, 0x47ce, 0x4883, 0x4939,
+ 0x49ef, 0x4aa6, 0x4b5d, 0x4c15, 0x4ccd, 0x4d85, 0x4e3f, 0x4ef8,
+ 0x4fb2, 0x506d, 0x5128, 0x51e4, 0x52a0, 0x535c, 0x5419, 0x54d6,
+ 0x5594, 0x5652, 0x5710, 0x57cf, 0x588f, 0x594e, 0x5a0e, 0x5acf,
+ 0x5b8f, 0x5c50, 0x5d12, 0x5dd4, 0x5e96, 0x5f58, 0x601b, 0x60de,
+ 0x61a1, 0x6265, 0x6329, 0x63ed, 0x64b2, 0x6576, 0x663b, 0x6701,
+ 0x67c6, 0x688c, 0x6952, 0x6a18, 0x6ade, 0x6ba5, 0x6c6c, 0x6d33,
+ 0x6dfa, 0x6ec1, 0x6f89, 0x7051, 0x7118, 0x71e0, 0x72a8, 0x7371,
+ 0x7439, 0x7501, 0x75ca, 0x7693, 0x775b, 0x7824, 0x78ed, 0x79b6,
+ 0x7a7f, 0x7b48, 0x7c11, 0x7cdb, 0x7da4, 0x7e6d, 0x7f36, 0x8000,
+ 0x8000, 0x80c9, 0x8192, 0x825b, 0x8324, 0x83ee, 0x84b7, 0x8580,
+ 0x8649, 0x8712, 0x87db, 0x88a4, 0x896c, 0x8a35, 0x8afe, 0x8bc6,
+ 0x8c8e, 0x8d57, 0x8e1f, 0x8ee7, 0x8fae, 0x9076, 0x913e, 0x9205,
+ 0x92cc, 0x9393, 0x945a, 0x9521, 0x95e7, 0x96ad, 0x9773, 0x9839,
+ 0x98fe, 0x99c4, 0x9a89, 0x9b4d, 0x9c12, 0x9cd6, 0x9d9a, 0x9e5e,
+ 0x9f21, 0x9fe4, 0xa0a7, 0xa169, 0xa22b, 0xa2ed, 0xa3af, 0xa470,
+ 0xa530, 0xa5f1, 0xa6b1, 0xa770, 0xa830, 0xa8ef, 0xa9ad, 0xaa6b,
+ 0xab29, 0xabe6, 0xaca3, 0xad5f, 0xae1b, 0xaed7, 0xaf92, 0xb04d,
+ 0xb107, 0xb1c0, 0xb27a, 0xb332, 0xb3ea, 0xb4a2, 0xb559, 0xb610,
+ 0xb6c6, 0xb77c, 0xb831, 0xb8e5, 0xb999, 0xba4d, 0xbb00, 0xbbb2,
+ 0xbc64, 0xbd15, 0xbdc6, 0xbe76, 0xbf25, 0xbfd4, 0xc082, 0xc12f,
+ 0xc1dc, 0xc288, 0xc334, 0xc3df, 0xc489, 0xc533, 0xc5dc, 0xc684,
+ 0xc72c, 0xc7d3, 0xc879, 0xc91f, 0xc9c3, 0xca67, 0xcb0b, 0xcbae,
+ 0xcc4f, 0xccf1, 0xcd91, 0xce31, 0xced0, 0xcf6e, 0xd00b, 0xd0a8,
+ 0xd144, 0xd1df, 0xd279, 0xd313, 0xd3ac, 0xd443, 0xd4db, 0xd571,
+ 0xd606, 0xd69b, 0xd72f, 0xd7c2, 0xd854, 0xd8e5, 0xd975, 0xda05,
+ 0xda93, 0xdb21, 0xdbae, 0xdc3a, 0xdcc5, 0xdd4f, 0xddd9, 0xde61,
+ 0xdee9, 0xdf6f, 0xdff5, 0xe07a, 0xe0fd, 0xe180, 0xe202, 0xe283,
+ 0xe303, 0xe382, 0xe400, 0xe47d, 0xe4fa, 0xe575, 0xe5ef, 0xe668,
+ 0xe6e0, 0xe758, 0xe7ce, 0xe843, 0xe8b7, 0xe92b, 0xe99d, 0xea0e,
+ 0xea7e, 0xeaed, 0xeb5b, 0xebc8, 0xec34, 0xec9f, 0xed09, 0xed72,
+ 0xedda, 0xee41, 0xeea7, 0xef0b, 0xef6f, 0xefd1, 0xf033, 0xf093,
+ 0xf0f2, 0xf150, 0xf1ad, 0xf209, 0xf264, 0xf2be, 0xf316, 0xf36e,
+ 0xf3c4, 0xf41a, 0xf46e, 0xf4c1, 0xf513, 0xf564, 0xf5b3, 0xf602,
+ 0xf64f, 0xf69b, 0xf6e6, 0xf730, 0xf779, 0xf7c1, 0xf807, 0xf84d,
+ 0xf891, 0xf8d4, 0xf916, 0xf956, 0xf996, 0xf9d4, 0xfa11, 0xfa4d,
+ 0xfa88, 0xfac1, 0xfafa, 0xfb31, 0xfb67, 0xfb9c, 0xfbd0, 0xfc02,
+ 0xfc33, 0xfc63, 0xfc92, 0xfcc0, 0xfcec, 0xfd17, 0xfd42, 0xfd6a,
+ 0xfd92, 0xfdb8, 0xfdde, 0xfe01, 0xfe24, 0xfe46, 0xfe66, 0xfe85,
+ 0xfea3, 0xfec0, 0xfedb, 0xfef5, 0xff0e, 0xff26, 0xff3c, 0xff52,
+ 0xff66, 0xff79, 0xff8a, 0xff9b, 0xffaa, 0xffb8, 0xffc4, 0xffd0,
+ 0xffda, 0xffe3, 0xffeb, 0xfff1, 0xfff6, 0xfffa, 0xfffd, 0xffff,
+ 0xffff, 0xfffe, 0xfffc, 0xfff8, 0xfff4, 0xffee, 0xffe7, 0xffdf,
+ 0xffd5, 0xffca, 0xffbe, 0xffb1, 0xffa2, 0xff93, 0xff82, 0xff6f,
+ 0xff5c, 0xff47, 0xff31, 0xff1a, 0xff02, 0xfee8, 0xfece, 0xfeb1,
+ 0xfe94, 0xfe76, 0xfe56, 0xfe35, 0xfe13, 0xfdf0, 0xfdcb, 0xfda5,
+ 0xfd7e, 0xfd56, 0xfd2d, 0xfd02, 0xfcd6, 0xfca9, 0xfc7b, 0xfc4b,
+ 0xfc1b, 0xfbe9, 0xfbb6, 0xfb82, 0xfb4c, 0xfb16, 0xfade, 0xfaa5,
+ 0xfa6b, 0xfa2f, 0xf9f3, 0xf9b5, 0xf976, 0xf936, 0xf8f5, 0xf8b2,
+ 0xf86f, 0xf82a, 0xf7e4, 0xf79d, 0xf755, 0xf70c, 0xf6c1, 0xf675,
+ 0xf629, 0xf5db, 0xf58c, 0xf53b, 0xf4ea, 0xf498, 0xf444, 0xf3ef,
+ 0xf399, 0xf342, 0xf2ea, 0xf291, 0xf237, 0xf1db, 0xf17f, 0xf121,
+ 0xf0c3, 0xf063, 0xf002, 0xefa0, 0xef3d, 0xeed9, 0xee74, 0xee0e,
+ 0xeda6, 0xed3e, 0xecd5, 0xec6a, 0xebff, 0xeb92, 0xeb24, 0xeab6,
+ 0xea46, 0xe9d6, 0xe964, 0xe8f1, 0xe87d, 0xe809, 0xe793, 0xe71c,
+ 0xe6a4, 0xe62c, 0xe5b2, 0xe537, 0xe4bc, 0xe43f, 0xe3c1, 0xe343,
+ 0xe2c3, 0xe243, 0xe1c1, 0xe13f, 0xe0bc, 0xe037, 0xdfb2, 0xdf2c,
+ 0xdea5, 0xde1d, 0xdd94, 0xdd0a, 0xdc80, 0xdbf4, 0xdb68, 0xdada,
+ 0xda4c, 0xd9bd, 0xd92d, 0xd89c, 0xd80b, 0xd778, 0xd6e5, 0xd651,
+ 0xd5bc, 0xd526, 0xd48f, 0xd3f8, 0xd35f, 0xd2c6, 0xd22c, 0xd192,
+ 0xd0f6, 0xd05a, 0xcfbd, 0xcf1f, 0xce80, 0xcde1, 0xcd41, 0xcca0,
+ 0xcbff, 0xcb5c, 0xcab9, 0xca16, 0xc971, 0xc8cc, 0xc826, 0xc77f,
+ 0xc6d8, 0xc630, 0xc588, 0xc4de, 0xc434, 0xc38a, 0xc2de, 0xc232,
+ 0xc186, 0xc0d9, 0xc02b, 0xbf7c, 0xbecd, 0xbe1e, 0xbd6d, 0xbcbd,
+ 0xbc0b, 0xbb59, 0xbaa6, 0xb9f3, 0xb940, 0xb88b, 0xb7d6, 0xb721,
+ 0xb66b, 0xb5b5, 0xb4fe, 0xb446, 0xb38e, 0xb2d6, 0xb21d, 0xb164,
+ 0xb0aa, 0xafef, 0xaf34, 0xae79, 0xadbd, 0xad01, 0xac45, 0xab88,
+ 0xaaca, 0xaa0c, 0xa94e, 0xa88f, 0xa7d0, 0xa711, 0xa651, 0xa591,
+ 0xa4d0, 0xa40f, 0xa34e, 0xa28c, 0xa1ca, 0xa108, 0xa045, 0x9f83,
+ 0x9ebf, 0x9dfc, 0x9d38, 0x9c74, 0x9bb0, 0x9aeb, 0x9a26, 0x9961,
+ 0x989c, 0x97d6, 0x9710, 0x964a, 0x9584, 0x94bd, 0x93f7, 0x9330,
+ 0x9269, 0x91a1, 0x90da, 0x9012, 0x8f4b, 0x8e83, 0x8dbb, 0x8cf3,
+ 0x8c2a, 0x8b62, 0x8a99, 0x89d1, 0x8908, 0x883f, 0x8776, 0x86ad,
+ 0x85e4, 0x851b, 0x8452, 0x8389, 0x82c0, 0x81f7, 0x812d, 0x8064,
+ 0x7f9b, 0x7ed2, 0x7e08, 0x7d3f, 0x7c76, 0x7bad, 0x7ae4, 0x7a1b,
+ 0x7952, 0x7889, 0x77c0, 0x76f7, 0x762e, 0x7566, 0x749d, 0x73d5,
+ 0x730c, 0x7244, 0x717c, 0x70b4, 0x6fed, 0x6f25, 0x6e5e, 0x6d96,
+ 0x6ccf, 0x6c08, 0x6b42, 0x6a7b, 0x69b5, 0x68ef, 0x6829, 0x6763,
+ 0x669e, 0x65d9, 0x6514, 0x644f, 0x638b, 0x62c7, 0x6203, 0x6140,
+ 0x607c, 0x5fba, 0x5ef7, 0x5e35, 0x5d73, 0x5cb1, 0x5bf0, 0x5b2f,
+ 0x5a6e, 0x59ae, 0x58ee, 0x582f, 0x5770, 0x56b1, 0x55f3, 0x5535,
+ 0x5477, 0x53ba, 0x52fe, 0x5242, 0x5186, 0x50cb, 0x5010, 0x4f55,
+ 0x4e9b, 0x4de2, 0x4d29, 0x4c71, 0x4bb9, 0x4b01, 0x4a4a, 0x4994,
+ 0x48de, 0x4829, 0x4774, 0x46bf, 0x460c, 0x4559, 0x44a6, 0x43f4,
+ 0x4342, 0x4292, 0x41e1, 0x4132, 0x4083, 0x3fd4, 0x3f26, 0x3e79,
+ 0x3dcd, 0x3d21, 0x3c75, 0x3bcb, 0x3b21, 0x3a77, 0x39cf, 0x3927,
+ 0x3880, 0x37d9, 0x3733, 0x368e, 0x35e9, 0x3546, 0x34a3, 0x3400,
+ 0x335f, 0x32be, 0x321e, 0x317f, 0x30e0, 0x3042, 0x2fa5, 0x2f09,
+ 0x2e6d, 0x2dd3, 0x2d39, 0x2ca0, 0x2c07, 0x2b70, 0x2ad9, 0x2a43,
+ 0x29ae, 0x291a, 0x2887, 0x27f4, 0x2763, 0x26d2, 0x2642, 0x25b3,
+ 0x2525, 0x2497, 0x240b, 0x237f, 0x22f5, 0x226b, 0x21e2, 0x215a,
+ 0x20d3, 0x204d, 0x1fc8, 0x1f43, 0x1ec0, 0x1e3e, 0x1dbc, 0x1d3c,
+ 0x1cbc, 0x1c3e, 0x1bc0, 0x1b43, 0x1ac8, 0x1a4d, 0x19d3, 0x195b,
+ 0x18e3, 0x186c, 0x17f6, 0x1782, 0x170e, 0x169b, 0x1629, 0x15b9,
+ 0x1549, 0x14db, 0x146d, 0x1400, 0x1395, 0x132a, 0x12c1, 0x1259,
+ 0x11f1, 0x118b, 0x1126, 0x10c2, 0x105f, 0xffd, 0xf9c, 0xf3c,
+ 0xede, 0xe80, 0xe24, 0xdc8, 0xd6e, 0xd15, 0xcbd, 0xc66,
+ 0xc10, 0xbbb, 0xb67, 0xb15, 0xac4, 0xa73, 0xa24, 0x9d6,
+ 0x98a, 0x93e, 0x8f3, 0x8aa, 0x862, 0x81b, 0x7d5, 0x790,
+ 0x74d, 0x70a, 0x6c9, 0x689, 0x64a, 0x60c, 0x5d0, 0x594,
+ 0x55a, 0x521, 0x4e9, 0x4b3, 0x47d, 0x449, 0x416, 0x3e4,
+ 0x3b4, 0x384, 0x356, 0x329, 0x2fd, 0x2d2, 0x2a9, 0x281,
+ 0x25a, 0x234, 0x20f, 0x1ec, 0x1ca, 0x1a9, 0x189, 0x16b,
+ 0x14e, 0x131, 0x117, 0xfd, 0xe5, 0xce, 0xb8, 0xa3,
+ 0x90, 0x7d, 0x6c, 0x5d, 0x4e, 0x41, 0x35, 0x2a,
+ 0x20, 0x18, 0x11, 0xb, 0x7, 0x3, 0x1, 0x0,
};
--- /dev/null
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * apps/include/nxplayer/nxplayer.h
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * With updates, enhancements, and modifications by:
+ *
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 __APPS_SYSTEM_NXPLAYER_NXPLAYER_H
+#define __APPS_SYSTEM_NXPLAYER_NXPLAYER_H 1
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <tinyara/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+/* This structure describes the internal state of the NxPlayer */
+
+struct nxplayer_s {
+ int state; /* Current player state */
+ int devFd; /* File descriptor of active device */
+ mqd_t mq; /* Message queue for the playthread */
+ char mqname[16]; /* Name of our message queue */
+ pthread_t playId; /* Thread ID of the playthread */
+ int crefs; /* Number of references to the player */
+ sem_t sem; /* Thread sync semaphore */
+ FILE *fileFd; /* File descriptor of open file */
+#ifdef CONFIG_NXPLAYER_INCLUDE_PREFERRED_DEVICE
+ char prefdevice[CONFIG_NAME_MAX]; /* Preferred audio device */
+ int prefformat; /* Formats supported by preferred device */
+ int preftype; /* Types supported by preferred device */
+#endif
+#ifdef CONFIG_NXPLAYER_INCLUDE_MEDIADIR
+ char mediadir[CONFIG_NAME_MAX]; /* Root media directory where media is located */
+#endif
+#ifdef CONFIG_AUDIO_MULTI_SESSION
+ FAR void *session; /* Session assigment from device */
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+ uint16_t volume; /* Volume as a whole percentage (0-100) */
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+ uint16_t balance; /* Balance as a whole % (0=left off, 100=right off) */
+#endif
+#endif
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+ uint16_t treble; /* Treble as a whole % */
+ uint16_t bass; /* Bass as a whole % */
+#endif
+};
+
+typedef int (*nxplayer_func)(FAR struct nxplayer_s *pPlayer, char *pargs);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxplayer_create
+ *
+ * Allocates and Initializes a NxPlayer context that is passed to all
+ * nxplayer routines. The player MUST be destroyed using the
+ * nxplayer_destroy() routine since the context is reference counted.
+ * The context can be used in a mode where the caller creates the
+ * context, starts a file playing, and then forgets about the context
+ * and it will self free. This is because the nxplayer_playfile
+ * will also create a reference to the context, so the client calling
+ * nxplayer_destroy() won't actually de-allocate anything. The freeing
+ * will occur after the playthread has completed.
+ *
+ * Alternately, the caller can create the objec and hold on to it, then
+ * the context will persist until the original creator destroys it.
+ *
+ * Input Parameters: None
+ *
+ * Returned Value:
+ * Pointer to created NxPlayer context or NULL if error.
+ *
+ ****************************************************************************/
+
+FAR struct nxplayer_s *nxplayer_create(void);
+
+/****************************************************************************
+ * Name: nxplayer_release
+ *
+ * Reduces the reference count to the player and if it reaches zero,
+ * frees all memory used by the context.
+ *
+ * Input Parameters:
+ * pPlayer Pointer to the NxPlayer context
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void nxplayer_release(FAR struct nxplayer_s *pPlayer);
+
+/****************************************************************************
+ * Name: nxplayer_reference
+ *
+ * Increments the reference count to the player.
+ *
+ * Input Parameters:
+ * pPlayer Pointer to the NxPlayer context
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void nxplayer_reference(FAR struct nxplayer_s *pPlayer);
+
+/****************************************************************************
+ * Name: nxplayer_setdevice
+ *
+ * Sets the preferred Audio device to use with the instance of the
+ * nxplayer. Without a preferred device set, the nxplayer will search
+ * the audio subsystem to find a suitable device depending on the
+ * type of audio operation requested (i.e. an MP3 decoder device when
+ * playing an MP3 file, a WAV decoder device for a WAV file, etc.).
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * device - Pointer to pathname of the preferred device
+ *
+ * Returned Value:
+ * OK if context initialized successfully, error code otherwise.
+ *
+ ****************************************************************************/
+
+int nxplayer_setdevice(FAR struct nxplayer_s *pPlayer, FAR const char *device);
+
+/****************************************************************************
+ * Name: nxplayer_playfile
+ *
+ * Plays the specified media file (from the filesystem) using the
+ * Audio system. If a preferred device has been set, that device
+ * will be used for the playback, otherwise the first suitable device
+ * found in the /dev/audio directory will be used.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * filename - Pointer to pathname of the file to play
+ * filefmt - Format of audio in filename if known, AUDIO_FMT_UNDEF
+ * to let nxplayer_playfile() determine automatically.
+ * subfmt - Sub-Format of audio in filename if known, AUDIO_FMT_UNDEF
+ * to let nxplayer_playfile() determine automatically.
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, FAR const char *filename, int filefmt, int subfmt);
+
+/****************************************************************************
+ * Name: nxplayer_stop
+ *
+ * Stops current playback.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_STOP
+int nxplayer_stop(FAR struct nxplayer_s *pPlayer);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_pause
+ *
+ * Pauses current playback.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+int nxplayer_pause(FAR struct nxplayer_s *pPlayer);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_resume
+ *
+ * Resumes current playback.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
+int nxplayer_resume(FAR struct nxplayer_s *pPlayer);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_fforward
+ *
+ * Selects to fast forward in the audio data stream. The fast forward
+ * operation can be cancelled by simply selected no sub-sampling with
+ * the AUDIO_SUBSAMPLE_NONE argument returning to normal 1x forward play.
+ *
+ * The preferred way to cancel a fast forward operation is via
+ * nxplayer_cancel_motion() that provides the option to also return to
+ * paused, non-playing state.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * subsample - Identifies the fast forward rate (in terms of sub-sampling,
+ * but does not explicitly require sub-sampling). See
+ * AUDIO_SUBSAMPLE_* definitions.
+ *
+ * Returned Value:
+ * OK if fast forward operation successful.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_FFORWARD
+int nxplayer_fforward(FAR struct nxplayer_s *pPlayer, uint8_t subsample);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_rewind
+ *
+ * Selects to rewind in the audio data stream. The rewind operation must
+ * be cancelled with nxplayer_cancel_motion. This function may be called
+ * multiple times to change rewind rate.
+ *
+ * NOTE that cancellation of the rewind operation differs from
+ * cancellation of the fast forward operation because we must both restore
+ * the sub-sampling rate to 1x and also return to forward play.
+ * AUDIO_SUBSAMPLE_NONE is not a valid argument to this function.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * subsample - Identifies the rewind rate (in terms of sub-sampling, but
+ * does not explicitly require sub-sampling). See
+ * AUDIO_SUBSAMPLE_* definitions.
+ *
+ * Returned Value:
+ * OK if rewind operation successfully initiated.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_REWIND
+int nxplayer_rewind(FAR struct nxplayer_s *pPlayer, uint8_t subsample);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_cancel_motion
+ *
+ * Cancel a rewind or fast forward operation and return to either the
+ * paused state or to the normal, forward play state.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * paused - True: return to the paused state, False: return to the 1X
+ * forward play state.
+ *
+ * Returned Value:
+ * OK if rewind operation successfully cancelled.
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_AUDIO_EXCLUDE_FFORWARD) || !defined(CONFIG_AUDIO_EXCLUDE_REWIND)
+int nxplayer_cancel_motion(FAR struct nxplayer_s *pPlayer, bool paused);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_setvolume
+ *
+ * Sets the playback volume. The volume is represented in 1/10th of a
+ * percent increments, so the range is 0-1000. A value of 10 would mean
+ * 1%.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * volume - Volume level to set in 1/10th percent increments
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+int nxplayer_setvolume(FAR struct nxplayer_s *pPlayer, uint16_t volume);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_setbalance
+ *
+ * Sets the playback balance. The balance is represented in 1/10th of a
+ * percent increments, so the range is 0-1000. A value of 10 would mean
+ * 1%.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * balance - Balance level to set in 1/10th percent increments
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
+#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
+int nxplayer_setbalance(FAR struct nxplayer_s *pPlayer, uint16_t balance);
+#endif
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_setmediadir
+ *
+ * Sets the root media directory for non-path qualified file searches.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * mediadir - Pointer to pathname of the media directory
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void nxplayer_setmediadir(FAR struct nxplayer_s *pPlayer, FAR const char *mediadir);
+
+/****************************************************************************
+ * Name: nxplayer_setequalization
+ *
+ * Sets the level on each band of an equalizer. Each band setting is
+ * represented in one percent increments, so the range is 0-100.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * equalization - Pointer to array of equalizer settings of size
+ * CONFIG_AUDIO_EQUALIZER_NBANDS bytes. Each byte
+ * represents the setting for one band in the range of
+ * 0-100.
+ *
+ * Returned Value:
+ * OK if equalization was set correctly.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_EQUALIZER
+int nxplayer_setequalization(FAR struct nxplayer_s *pPlayer, FAR uint8_t *equalization);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_setbass
+ *
+ * Sets the playback bass level. The bass is represented in one percent
+ * increments, so the range is 0-100.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * bass - Bass level to set in one percent increments
+ *
+ * Returned Value:
+ * OK if the bass level was set successfully
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+int nxplayer_setbass(FAR struct nxplayer_s *pPlayer, uint8_t bass);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_settreble
+ *
+ * Sets the playback treble level. The bass is represented in one percent
+ * increments, so the range is 0-100.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ * treble - Treble level to set in one percent increments
+ *
+ * Returned Value:
+ * OK if the treble level was set successfully
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_AUDIO_EXCLUDE_TONE
+int nxplayer_settreble(FAR struct nxplayer_s *pPlayer, uint8_t treble);
+#endif
+
+/****************************************************************************
+ * Name: nxplayer_systemreset
+ *
+ * Performs an audio system reset, including a hardware reset on all
+ * registered audio devices.
+ *
+ * Input Parameters:
+ * pPlayer - Pointer to the context to initialize
+ *
+ * Returned Value:
+ * OK if file found, device found, and playback started.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXPLAYER_INCLUDE_SYSTEM_RESET
+int nxplayer_systemreset(FAR struct nxplayer_s *pPlayer);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPS_SYSTEM_NXPLAYER_NXPLAYER_H */
# CONFIG_ARCH_MATH_H is not set
# CONFIG_ARCH_FLOAT_H is not set
# CONFIG_ARCH_STDARG_H is not set
+
+#
+# Debug Options
+#
+CONFIG_DEBUG=y
+CONFIG_DEBUG_ERROR=y
+# CONFIG_DEBUG_WARN is not set
+CONFIG_DEBUG_VERBOSE=y
+
+#
+# Subsystem Debug Options
+#
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_LIB is not set
+# CONFIG_DEBUG_MM is not set
+CONFIG_DEBUG_NET=y
+# CONFIG_DEBUG_NET_ERROR is not set
+# CONFIG_DEBUG_NET_INFO is not set
+# CONFIG_DEBUG_SCHED is not set
+# CONFIG_DEBUG_WLAN is not set
+
+#
+# OS Function Debug Options
+#
+# CONFIG_DEBUG_DMA is not set
+# CONFIG_ARCH_HAVE_HEAPCHECK is not set
+CONFIG_DEBUG_MM_HEAPINFO=y
+# CONFIG_DEBUG_IRQ is not set
+# CONFIG_DEBUG_IRQ_INFO is not set
+
+#
+# Driver Debug Options
+#
+# CONFIG_DEBUG_PWM is not set
+# CONFIG_DEBUG_RTC is not set
+# CONFIG_DEBUG_SPI is not set
+# CONFIG_DEBUG_WATCHDOG is not set
+# CONFIG_DEBUG_TTRACE is not set
+
+#
+# Stack Debug Options
+#
+CONFIG_ARCH_HAVE_STACKCHECK=y
+CONFIG_STACK_COLORATION=y
+
+#
+# Build Debug Options
+#
+CONFIG_DEBUG_SYMBOLS=y
+# CONFIG_FRAME_POINTER is not set
CONFIG_ARCH_HAVE_CUSTOMOPT=y
# CONFIG_DEBUG_NOOPT is not set
# CONFIG_DEBUG_CUSTOMOPT is not set
CONFIG_DEBUG_FULLOPT=y
#
-# Hardware Configuration
-#
-
-#
# Chip Selection
#
CONFIG_ARCH_ARM=y
CONFIG_ARCH="arm"
-# CONFIG_ARCH_CHIP_LM is not set
-CONFIG_ARCH_CHIP_S5J=y
-CONFIG_ARCH_CHIP="s5j"
#
# ARM Options
#
+# CONFIG_ARCH_CHIP_LM is not set
+CONFIG_ARCH_CHIP_S5J=y
# CONFIG_ARCH_CORTEXM3 is not set
# CONFIG_ARCH_CORTEXM4 is not set
CONFIG_ARCH_CORTEXR4=y
CONFIG_ARCH_FAMILY="armv7-r"
+CONFIG_ARCH_CHIP="s5j"
# CONFIG_ARCH_HAVE_FPU is not set
CONFIG_ARMV7M_MPU=y
CONFIG_ARMV7M_MPU_NREGIONS=12
#
CONFIG_S5J_PWR_DSTOP=y
# CONFIG_S5J_PWR_SLEEP is not set
-# CONFIG_S5J_SENSOR_PPD42NS is not set
#
# Architecture Options
# Boot Memory Configuration
#
CONFIG_RAM_START=0x02023800
-CONFIG_RAM_SIZE=968704
+CONFIG_RAM_SIZE=804864
# CONFIG_ARCH_HAVE_SDRAM is not set
#
CONFIG_ARTIK053_AUTOMOUNT_USERFS_MOUNTPOINT="/mnt"
#
-# Kernel Features
#
CONFIG_DISABLE_OS_API=y
# CONFIG_DISABLE_POSIX_TIMERS is not set
CONFIG_PTHREAD_STACK_DEFAULT=2048
#
+# System Call
+#
+# CONFIG_LIB_SYSCALL is not set
+
+#
# Device Drivers
#
# CONFIG_DISABLE_POLL is not set
CONFIG_DEV_NULL=y
CONFIG_DEV_ZERO=y
+
+#
+# Buffering
+#
# CONFIG_DRVR_WRITEBUFFER is not set
# CONFIG_DRVR_READAHEAD is not set
# CONFIG_CAN is not set
CONFIG_AUDIO_I2SCHAR_TXTIMEOUT=0
# CONFIG_AUDIO_NULL is not set
# CONFIG_AUDIO_ALC5658 is not set
-# CONFIG_AUDIO_ALC5658CHAR is not set
# CONFIG_BCH is not set
CONFIG_RTC=y
CONFIG_RTC_DATETIME=y
CONFIG_SCSC_PLATFORM=y
# CONFIG_SCSC_WLANLITE is not set
# CONFIG_SCSC_DISABLE_WLAN_RESET is not set
-# CONFIG_SENSOR is not set
#
# Networking Support
# CONFIG_NET_LWIP_SLIP_INTERFACE is not set
# CONFIG_NET_LWIP_PPP_SUPPORT is not set
# CONFIG_NET_LWIP_SNMP is not set
+CONFIG_NET_SECURITY_TLS=y
+# CONFIG_TLS_WITH_SSS is not set
#
# Driver buffer configuration
# Network utilities
#
CONFIG_NETUTILS_NETLIB=y
+# CONFIG_NET_ROUTE is not set
#
# Audio Support
#
# File Systems
#
+
+#
+# File system configuration
+#
# CONFIG_DISABLE_MOUNTPOINT is not set
# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
CONFIG_FS_READABLE=y
# CONFIG_SYSLOG_TIMESTAMP is not set
#
-# Database
+# Arastorage
+#
+
+#
+# AraStorage database configuration
#
# CONFIG_ARASTORAGE is not set
CONFIG_PM_SLEEPENTER_COUNT=70
#
-# Debug Options
-#
-CONFIG_DEBUG=y
-CONFIG_DEBUG_ERROR=y
-# CONFIG_DEBUG_WARN is not set
-CONFIG_DEBUG_VERBOSE=y
-
-#
-# Subsystem Debug Options
-#
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_LIB is not set
-# CONFIG_DEBUG_MM is not set
-CONFIG_DEBUG_NET=y
-# CONFIG_DEBUG_NET_ERROR is not set
-# CONFIG_DEBUG_NET_INFO is not set
-# CONFIG_DEBUG_SCHED is not set
-# CONFIG_DEBUG_WLAN is not set
-
-#
-# OS Function Debug Options
-#
-# CONFIG_DEBUG_DMA is not set
-# CONFIG_ARCH_HAVE_HEAPCHECK is not set
-CONFIG_DEBUG_MM_HEAPINFO=y
-# CONFIG_DEBUG_IRQ is not set
-# CONFIG_DEBUG_IRQ_INFO is not set
-
-#
-# Driver Debug Options
-#
-# CONFIG_DEBUG_PWM is not set
-# CONFIG_DEBUG_RTC is not set
-# CONFIG_DEBUG_SPI is not set
-# CONFIG_DEBUG_WATCHDOG is not set
-# CONFIG_DEBUG_TTRACE is not set
-
-#
-# Stack Debug Options
-#
-CONFIG_ARCH_HAVE_STACKCHECK=y
-CONFIG_STACK_COLORATION=y
-
-#
-# Build Debug Options
-#
-CONFIG_DEBUG_SYMBOLS=y
-# CONFIG_FRAME_POINTER is not set
-
-#
# Logger Module
#
CONFIG_LOGM=y
# CONFIG_LOGM_TEST is not set
#
-# Built-in Libraries
+# Library Routines
#
#
CONFIG_LIBM=y
# CONFIG_NOPRINTF_FIELDWIDTH is not set
CONFIG_LIBC_FLOATINGPOINT=y
-# CONFIG_NOPRINTF_LONGLONG_TO_ASCII is not set
CONFIG_LIBC_IOCTL_VARIADIC=y
CONFIG_LIB_RAND_ORDER=1
# CONFIG_EOL_IS_CR is not set
# CONFIG_HAVE_CXX is not set
#
-# External Libraries
+# External Functions
#
# CONFIG_LWM2M_WAKAAMA is not set
# CONFIG_DM is not set
+
+#
+# IOTIVITY Config Parameters
+#
# CONFIG_ENABLE_IOTIVITY is not set
# CONFIG_LIBTUV is not set
# CONFIG_AWS_SDK is not set
-CONFIG_NETUTILS_JSON=y
-# CONFIG_NETUTILS_CODECS is not set
#
# Application Configuration
#
+CONFIG_ENTRY_MANUAL=y
#
# Application entry point list
#
-CONFIG_ENTRY_MANUAL=y
# CONFIG_ENTRY_HELLO is not set
CONFIG_USER_ENTRYPOINT="hello_main"
CONFIG_BUILTIN_APPS=y
# CONFIG_EXAMPLES_EASYSETUP is not set
# CONFIG_EXAMPLES_EEPROM_TEST is not set
# CONFIG_EXAMPLES_FOTA_SAMPLE is not set
-# CONFIG_FILESYSTEM_HELPER_ENABLE is not set
# CONFIG_EXAMPLES_FTPC is not set
CONFIG_EXAMPLES_HELLO=y
# CONFIG_EXAMPLES_HELLO_TASH is not set
# CONFIG_EXAMPLES_SMTPCLIENT is not set
# CONFIG_EXAMPLES_SYSIO_TEST is not set
# CONFIG_EXAMPLES_TESTCASE is not set
-# CONFIG_EXAMPLES_TLS_BENCHMARK is not set
# CONFIG_EXAMPLES_TLS_CLIENT is not set
# CONFIG_EXAMPLES_TLS_SELFTEST is not set
# CONFIG_EXAMPLES_TLS_SERVER is not set
# CONFIG_EXAMPLES_WORKQUEUE is not set
#
+# Network Utilities
+#
+# CONFIG_NETUTILS_CODECS is not set
+CONFIG_NETUTILS_DHCPC=y
+CONFIG_NETUTILS_DHCPD=y
+CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST=y
+CONFIG_NETUTILS_DHCPD_INTERFACE="wl1"
+CONFIG_NETUTILS_DHCPD_LEASETIME=864000
+CONFIG_NETUTILS_DHCPD_MINLEASETIME=86400
+CONFIG_NETUTILS_DHCPD_MAXLEASETIME=2592000
+CONFIG_NETUTILS_DHCPD_MAXLEASES=6
+CONFIG_NETUTILS_DHCPD_STARTIP=0xc0a82f02
+CONFIG_NETUTILS_DHCPD_ROUTERIP=0xc0a82f01
+CONFIG_NETUTILS_DHCPD_NETMASK=0xffffff00
+CONFIG_NETUTILS_DHCPD_DNSIP=0x08080808
+CONFIG_NETUTILS_DHCPD_OFFERTIME=3600
+CONFIG_NETUTILS_DHCPD_DECLINETIME=3600
+CONFIG_NETUTILS_FTPC=y
+# CONFIG_DEBUG_FTPC is not set
+# CONFIG_NETUTILS_FTPD is not set
+CONFIG_NETUTILS_JSON=y
+# CONFIG_NETUTILS_LIBCOAP is not set
+CONFIG_NETUTILS_MDNS=y
+# CONFIG_NETUTILS_MDNS_RESPONDER_SUPPORT is not set
+# CONFIG_NETUTILS_MDNS_XMDNS is not set
+CONFIG_NETUTILS_MQTT=y
+CONFIG_NETUTILS_MQTT_SECURITY=y
+CONFIG_NETUTILS_NETLIB=y
+CONFIG_NETUTILS_NTPCLIENT=y
+CONFIG_NETUTILS_NTPCLIENT_STACKSIZE=2048
+CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO=100
+CONFIG_NETUTILS_NTPCLIENT_SIGWAKEUP=18
+CONFIG_NETUTILS_SMTP=y
+# CONFIG_NETUTILS_TELNETD is not set
+# CONFIG_NETUTILS_TFTPC is not set
+CONFIG_NETUTILS_WEBCLIENT=y
+CONFIG_WGET_USERAGENT="TinyARA"
+CONFIG_NETUTILS_WEBSERVER=y
+# CONFIG_NETUTILS_WEBSERVER_LOGD is not set
+# CONFIG_NETUTILS_WEBSERVER_LOGE is not set
+CONFIG_NETUTILS_WEBSOCKET=y
+CONFIG_NETUTILS_WIFI=y
+CONFIG_SLSI_WIFI_DEFAULT_WLAN_COUNTRY_CODE="00"
+CONFIG_SLSI_WIFI_DEFAULT_WLAN_TX_POWER=30
+# CONFIG_SLSI_WIFI_FILESYSTEM_SUPPORT is not set
+# CONFIG_NETUTILS_XMLRPC is not set
+
+#
# Platform-specific Support
#
# CONFIG_PLATFORM_CONFIGDATA is not set
# CONFIG_SYSTEM_NETDB is not set
# CONFIG_SYSTEM_POWEROFF is not set
CONFIG_SYSTEM_RAMTEST=y
-CONFIG_SYSTEM_RAMTEST_PRIORITY=100
-CONFIG_SYSTEM_RAMTEST_STACKSIZE=1024
CONFIG_SYSTEM_READLINE=y
CONFIG_READLINE_ECHO=y
CONFIG_SYSTEM_INFORMATION=y
CONFIG_STACKMONITOR_INTERVAL=5
CONFIG_ENABLE_UPTIME=y
# CONFIG_SYSTEM_VI is not set
+
+#
+# wpa_supplicant
+#
+CONFIG_WPA_SUPPLICANT=y
+CONFIG_WPA_SUPPLICANT_PRIORITY=100
+CONFIG_WPA_SUPPLICANT_STACKSIZE=16384
+CONFIG_WPA_SUPPLICANT_ENTRYPOINT="wpa_supplicant_main"
+CONFIG_CTRL_IFACE=y
+CONFIG_CTRL_IFACE_FIFO=y
+CONFIG_WPA_CTRL_FIFO_DEV_REQ="/dev/wpa_ctrl_req"
+CONFIG_WPA_CTRL_FIFO_DEV_CFM="/dev/wpa_ctrl_cfm"
+CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_REQ="/dev/wpa_ctrl_global_req"
+CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_CFM="/dev/wpa_ctrl_global_cfm"
+CONFIG_WPA_MONITOR_FIFO_DEV="/dev/wpa_monitor"
+CONFIG_WPA_CTRL_FIFO_MK_MODE=666
+CONFIG_ELOOP_POLL=y
+# CONFIG_WPA_SUPPLICANT_CMD is not set
endif # LIB_USRWORK
endif # BUILD_PROTECTED || BUILD_KERNEL
-
-
-config AUDIO
- bool "Audio library"
- default n
- ---help---
- Audio library.
-############################################################################
+###########################################################################
#
# Copyright 2017 Samsung Electronics All Rights Reserved.
#
# either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
#
-############################################################################
+###########################################################################
############################################################################
# libc/audio/Make.defs
#
ifeq ($(CONFIG_AUDIO),y)
CSRCS += lib_buffer.c
+# Add the audio/ directory to the build
DEPPATH += --dep-path audio
VPATH += :audio
#include <debug.h>
#include <tinyara/audio/audio.h>
-#include "libc.h"
+
+#include "lib_internal.h"
+
+#if defined(CONFIG_AUDIO)
/****************************************************************************
* Pre-processor Definitions
int ret;
struct ap_buffer_s *apb;
- DEBUGASSERT(bufdesc != NULL);
DEBUGASSERT(bufdesc->u.ppBuffer != NULL);
/* Perform a user mode allocation */
apb_semgive(apb);
if (refcount <= 1) {
- audinfo("Freeing %p\n", apb);
+ audvdbg("Freeing %p\n", apb);
lib_ufree(apb);
}
}
apb_semgive(apb);
}
+#endif /* CONFIG_AUDIO */
+++ /dev/null
-
-/****************************************************************************
- *
- * Copyright 2017 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- *
- ****************************************************************************/
-/****************************************************************************
- * libc/libc.h
- *
- * Copyright (C) 2007-2014, 2016-2017 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 __LIB_LIBC_H
-#define __LIB_LIBC_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <tinyara/config.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <limits.h>
-#include <semaphore.h>
-
-#include <tinyara/streams.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* The Tinyara C library an be build in two modes: (1) as a standard, C-library
- * that can be used by normal, user-space applications, or (2) as a special,
- * kernel-mode C-library only used within the OS. If NuttX is not being
- * built as separated kernel- and user-space modules, then only the first
- * mode is supported.
- */
-
-#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
- defined(CONFIG_BUILD_KERNEL)
-#include <tinyara/kmalloc.h>
-
-/* Domain-specific allocations */
-
-#define lib_malloc(s) kmm_malloc(s)
-#define lib_zalloc(s) kmm_zalloc(s)
-#define lib_realloc(p,s) kmm_realloc(p,s)
-#define lib_memalign(p,s) kmm_memalign(p,s)
-#define lib_free(p) kmm_free(p)
-
-/* User-accessible allocations */
-
-#define lib_umalloc(s) kumm_malloc(s)
-#define lib_uzalloc(s) kumm_zalloc(s)
-#define lib_urealloc(p,s) kumm_realloc(p,s)
-#define lib_ufree(p) kumm_free(p)
-
-#else
-#include <stdlib.h>
-
-/* Domain-specific allocations */
-
-#define lib_malloc(s) malloc(s)
-#define lib_zalloc(s) zalloc(s)
-#define lib_realloc(p,s) realloc(p,s)
-#define lib_free(p) free(p)
-
-/* User-accessible allocations */
-
-#define lib_umalloc(s) malloc(s)
-#define lib_uzalloc(s) zalloc(s)
-#define lib_urealloc(p,s) realloc(p,s)
-#define lib_ufree(p) free(p)
-
-#endif
-
-#define LIB_BUFLEN_UNKNOWN INT_MAX
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __LIB_LIBC_H */
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
-#define s5j_dmasetup(a, b) \
-do { \
- if ((b)->setup) { \
- (b)->setup(a, b); \
- } \
-} while (0)
+#define s5j_dmasetup(a, b) if((b)->setup) (b)->setup(a, b);
/************************************************************************************
* Public Types
endif
endif
-ifeq ($(CONFIG_AUDIO_ALC5658),y)
-CSRCS += artik053_alc5658.c
-else ifeq ($(CONFIG_AUDIO_ALC5658CHAR),y)
+ifeq ($(CONFIG_AUDIO_ALC5658CHAR),y)
CSRCS += artik053_alc5658char.c
endif
}
/* Call s5j_i2s_initialize() to get an instance of the I2S interface */
- i2s = s5j_i2s_initialize(0);
+ i2s = s5j_i2s_initialize();
if (!i2s) {
auddbg("ERROR: Failed to get the S5J I2S driver\n");
return -ENODEV;
#include <tinyara/gpio.h>
+#include <arch/board/artik053_alc5658_i2c.h>
#include "up_arch.h"
#include "s5j_gpio.h"
struct gpio_lowerhalf_s *lower;
struct {
- uint8_t minor;
+ uint8_t minor;
uint16_t pincfg;
} pins[] = {
- { 30, GPIO_XGPIO1 }, /* ARTIK_A053_XGPIO1 */
- { 31, GPIO_XGPIO2 }, /* ARTIK_A053_XGPIO2 */
- { 32, GPIO_XGPIO3 }, /* ARTIK_A053_XGPIO3 */
- { 37, GPIO_XGPIO8 }, /* ARTIK_A053_XGPIO8 */
- { 38, GPIO_XGPIO9 }, /* ARTIK_A053_XGPIO9 */
- { 39, GPIO_XGPIO10 }, /* ARTIK_A053_XGPIO10 */
- { 40, GPIO_XGPIO11 }, /* ARTIK_A053_XGPIO11 */
- { 41, GPIO_XGPIO12 }, /* ARTIK_A053_XGPIO12 */
- { 42, GPIO_XGPIO13 }, /* ARTIK_A053_XGPIO13 */
- { 43, GPIO_XGPIO14 }, /* ARTIK_A053_XGPIO14 */
- { 44, GPIO_XGPIO15 }, /* ARTIK_A053_XGPIO15 */
- { 45, GPIO_XGPIO16 }, /* ARTIK_A053_XGPIO16 */
- { 46, GPIO_XGPIO17 }, /* ARTIK_A053_XGPIO17 */
- { 47, GPIO_XGPIO18 }, /* ARTIK_A053_XGPIO18 */
- { 48, GPIO_XGPIO19 }, /* ARTIK_A053_XGPIO19 */
- { 49, GPIO_XGPIO20 }, /* ARTIK_A053_XGPIO20 */
- { 50, GPIO_XGPIO21 }, /* ARTIK_A053_XGPIO21 */
- { 51, GPIO_XGPIO22 }, /* ARTIK_A053_XGPIO22 */
- { 52, GPIO_XGPIO23 }, /* ARTIK_A053_XGPIO23 */
- { 53, GPIO_XGPIO24 }, /* ARTIK_A053_XGPIO24 */
- { 54, GPIO_XGPIO25 }, /* ARTIK_A053_XGPIO25 */
- { 55, GPIO_XGPIO26 }, /* ARTIK_A053_XGPIO26 */
- { 57, GPIO_XEINT0 }, /* ARTIK_A053_XEINT0 */
- { 58, GPIO_XEINT1 }, /* ARTIK_A053_XEINT1 */
- { 59, GPIO_XEINT2 }, /* ARTIK_A053_XEINT2 */
+ {
+ 30, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG0 | GPIO_PIN1
+ }, /* ARTIK_A053_XGPIO1 */
+ {
+ 31, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG0 | GPIO_PIN2
+ }, /* ARTIK_A053_XGPIO2 */
+ {
+ 32, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG0 | GPIO_PIN3
+ }, /* ARTIK_A053_XGPIO3 */
+ {
+ 37, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN0
+ }, /* ARTIK_A053_XGPIO8 */
+ {
+ 38, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN1
+ }, /* ARTIK_A053_XGPIO9 */
+ {
+ 39, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN2
+ }, /* ARTIK_A053_XGPIO10 */
+ {
+ 40, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN3
+ }, /* ARTIK_A053_XGPIO11 */
+ {
+ 41, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN4
+ }, /* ARTIK_A053_XGPIO12 */
+ {
+ 42, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN5
+ }, /* ARTIK_A053_XGPIO13 */
+ {
+ 43, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN6
+ }, /* ARTIK_A053_XGPIO14 */
+ {
+ 44, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN7
+ }, /* ARTIK_A053_XGPIO15 */
+ {
+ 45, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN0
+ }, /* ARTIK_A053_XGPIO16 */
+ {
+ 46, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN1
+ }, /* ARTIK_A053_XGPIO17 */
+ {
+ 47, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN2
+ }, /* ARTIK_A053_XGPIO18 */
+ {
+ 48, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN3
+ }, /* ARTIK_A053_XGPIO19 */
+ {
+ 49, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN4
+ }, /* ARTIK_A053_XGPIO20 */
+ {
+ 50, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN5
+ }, /* ARTIK_A053_XGPIO21 */
+ {
+ 51, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN6
+ }, /* ARTIK_A053_XGPIO22 */
+ {
+ 52, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN7
+ }, /* ARTIK_A053_XGPIO23 */
+ {
+ 53, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN0
+ }, /* ARTIK_A053_XGPIO24 */
+ {
+ 54, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN1
+ }, /* ARTIK_A053_XGPIO25 */
+ {
+ 55, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN2
+ }, /* ARTIK_A053_XGPIO26 */
+ {
+ 57, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN0
+ }, /* ARTIK_A053_XEINT0 */
+ {
+ 58, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN1
+ }, /* ARTIK_A053_XEINT1 */
+ {
+ 59, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN2
+ }, /* ARTIK_A053_XEINT2 */
};
for (i = 0; i < sizeof(pins) / sizeof(*pins); i++) {
lower = s5j_gpio_lowerhalf(pins[i].pincfg);
gpio_register(pins[i].minor, lower);
}
-#endif /* CONFIG_GPIO */
+#endif /* CONFIG_GPIO */
}
/****************************************************************************
board_gpio_initialize();
board_i2c_initialize();
- board_audio_initialize();
- board_sensor_initialize();
+#if defined(CONFIG_AUDIO_ALC5658)
+ s5j_alc5658_initialize(0);
+#elif defined(CONFIG_AUDIO_ALC5658CHAR)
+ s5j_alc5658char_initialize(0);
+#elif defined(CONFIG_AUDIO_I2SCHAR)
+ alc5658_i2c_initialize();
+ i2schar_devinit();
+#endif
}
-#endif /* CONFIG_BOARD_INITIALIZE */
+#endif /* CONFIG_BOARD_INITIALIZE */
if (!initialized) {
/* Call s5j_i2s_initialize() to get an instance of the I2S interface */
- i2s = s5j_i2s_initialize(0);
+ i2s = s5j_i2s_initialize();
if (!i2s) {
auddbg("ERROR: Failed to get the S5J I2S driver\n");
return -ENODEV;
* Pre-processor Definitions
************************************************************************************/
-#define S5J_I2S_MAXPERCLK 26000000 /* Maximum peripheral clock frequency */
+#define S5J_I2S_MAXPERCLK 26000000 /* Maximum peripheral clock frequency */
/* I2S Register Offsets *************************************************************/
-#define S5J_I2S_CON 0x0000 /* I2S interface control */
-#define S5J_I2S_MOD 0x0004 /* I2S interface mode */
-#define S5J_I2S_FIC 0x0008 /* I2S interface TxFIFO and Rx FIFO control */
-#define S5J_I2S_PSR 0x000C /* I2S interface clock divider control */
-#define S5J_I2S_TXD 0x0010 /* I2S interface transmit sound data */
-#define S5J_I2S_RXD 0x0014 /* I2S interface receive data */
-#define S5J_I2S_FICS 0x0018 /* I2S interface secondary TxFIFO_S Control */
-#define S5J_I2S_TXDS 0x001C /* I2S interface transmit secondary data */
-#define S5J_I2S_VER 0x0044 /* I2S version */
+#define S5J_I2S_CON 0x0000 /* I2S interface control */
+#define S5J_I2S_MOD 0x0004 /* I2S interface mode */
+#define S5J_I2S_FIC 0x0008 /* I2S interface TxFIFO and Rx FIFO control */
+#define S5J_I2S_PSR 0x000C /* I2S interface clock divider control */
+#define S5J_I2S_TXD 0x0010 /* I2S interface transmit sound data */
+#define S5J_I2S_RXD 0x0014 /* I2S interface receive data */
+#define S5J_I2S_FICS 0x0018 /* I2S interface secondary TxFIFO_S Control */
+#define S5J_I2S_TXDS 0x001C /* I2S interface transmit secondary data */
+#define S5J_I2S_VER 0x0044 /* I2S version */
/* I2S Register Bit Definitions *****************************************************/
-#define I2S_CR_SW_RST_SHIFT (31)
-#define I2S_CR_SW_RST_MASK (1 << I2S_CR_SW_RST_SHIFT)
-#define I2S_CR_SW_RST_RELEASE (1 << I2S_CR_SW_RST_SHIFT)
-
-#define I2S_CR_FRXOFSTATUS (1 << 26)
-#define I2S_CR_FRXOFINTEN (1 << 25)
-#define I2S_CR_FTXSURSTATUS (1 << 24)
-#define I2S_CR_FTXSURINTEN (1 << 23)
-#define I2S_CR_FTXSEMPT (1 << 22)
-#define I2S_CR_FTXSFULL (1 << 21)
-#define I2S_CR_TXSDMAPAUSE (1 << 20)
-#define I2S_CR_TXSDMACTIVE (1 << 18)
-#define I2S_CR_FTXURSTATUS (1 << 17)
-#define I2S_CR_FTXURINTEN (1 << 16)
-#define I2S_CR_LRI (1 << 11)
-#define I2S_CR_FTX0EMPT (1 << 10)
-#define I2S_CR_FRXEMPT (1 << 9)
-#define I2S_CR_FTX0FULL (1 << 8)
-#define I2S_CR_FRXFULL (1 << 7)
-#define I2S_CR_TXDMAPAUSE (1 << 6)
-#define I2S_CR_RXDMAPAUSE (1 << 5)
-#define I2S_CR_TXCHPAUSE (1 << 4)
-#define I2S_CR_RXCHPAUSE (1 << 3)
-#define I2S_CR_TXDMACTIVE (1 << 2)
-#define I2S_CR_RXDMACTIVE (1 << 1)
-#define I2S_CR_I2SACTIVE (1 << 0)
+#define I2S_CR_SW_RST_SHIFT (31)
+#define I2S_CR_SW_RST_MASK (1 << I2S_CR_SW_RST_SHIFT)
+#define I2S_CR_SW_RST_RELEASE (1 << I2S_CR_SW_RST_SHIFT)
+
+#define I2S_CR_FRXOFSTATUS (1 << 26)
+#define I2S_CR_FRXOFINTEN (1 << 25)
+#define I2S_CR_FTXSURSTATUS (1 << 24)
+#define I2S_CR_FTXSURINTEN (1 << 23)
+#define I2S_CR_FTXSEMPT (1 << 22)
+#define I2S_CR_FTXSFULL (1 << 21)
+#define I2S_CR_TXSDMAPAUSE (1 << 20)
+#define I2S_CR_TXSDMACTIVE (1 << 18)
+#define I2S_CR_FTXURSTATUS (1 << 17)
+#define I2S_CR_FTXURINTEN (1 << 16)
+#define I2S_CR_LRI (1 << 11)
+#define I2S_CR_FTX0EMPT (1 << 10)
+#define I2S_CR_FRXEMPT (1 << 9)
+#define I2S_CR_FTX0FULL (1 << 8)
+#define I2S_CR_FRXFULL (1 << 7)
+#define I2S_CR_TXDMAPAUSE (1 << 6)
+#define I2S_CR_RXDMAPAUSE (1 << 5)
+#define I2S_CR_TXCHPAUSE (1 << 4)
+#define I2S_CR_RXCHPAUSE (1 << 3)
+#define I2S_CR_TXDMACTIVE (1 << 2)
+#define I2S_CR_RXDMACTIVE (1 << 1)
+#define I2S_CR_I2SACTIVE (1 << 0)
/* MOD register */
-#define I2S_MOD_OP_CLK_MASK (3 << 30)
-#define I2S_MOD_OP_CLK_PCLK (3 << 30)
-
-#define BLC_8BIT (1)
-#define BLC_16BIT (0)
-#define BLC_24BIT (2)
-
-#define I2S_MOD_BLC_S_MASK (3 << 26)
-#define I2S_MOD_BLC_S(x) ((x & 3) << 26)
-#define I2S_MOD_BLC_P_MASK (3 << 24)
-#define I2S_MOD_BLC_P(x) ((x & 3) << 24)
-#define I2S_MOD_LRP (1 << 15)
-#define I2S_MOD_BLC_MASK (3 << 13)
-#define I2S_MOD_BLC(x) ((x & 3) << 13)
-#define I2S_MOD_CDCLKCON_IN (1 << 12)
-#define I2S_MOD_MSS_SLAVE (1 << 11)
-#define I2S_MOD_RCLKSRC (1 << 10)
-
-#define TXR_TX 0
-#define TXR_RX 1
-#define TXR_TXRX 2
-#define I2S_MOD_TXR_MASK (3 << 8)
-#define I2S_MOD_TXR(x) ((x & 3) << 8)
-
-#define I2S_MOD_SDF_MASK (3 << 6)
-#define I2S_MOD_SDF_I2S (0 << 6)
-#define I2S_MOD_SDF_MSB_Jstf (1 << 6)
-#define I2S_MOD_SDF_LSB_Jstf (2 << 6)
-
-#define RFS_256 (0x0)
-#define RFS_192 (0x7)
-
-#define BFS_64 (0x4)
-
-#define I2S_MOD_RFS_MASK (7 << 3)
-#define I2S_MOD_RFS(x) ((x & 7) << 3)
-#define I2S_MOD_BFS_MASK (7 << 0)
-#define I2S_MOD_BFS(x) ((x & 7) << 0)
+#define I2S_MOD_OP_CLK_MASK (3 << 30)
+#define I2S_MOD_OP_CLK_PCLK (3 << 30)
+
+#define BLC_8BIT (1)
+#define BLC_16BIT (0)
+#define BLC_24BIT (2)
+
+#define I2S_MOD_BLC_S_MASK (3 << 26)
+#define I2S_MOD_BLC_S(x) ((x & 3) << 26)
+#define I2S_MOD_BLC_P_MASK (3 << 24)
+#define I2S_MOD_BLC_P(x) ((x & 3) << 24)
+#define I2S_MOD_LRP (1 << 15)
+#define I2S_MOD_BLC_MASK (3 << 13)
+#define I2S_MOD_BLC(x) ((x & 3) << 13)
+#define I2S_MOD_CDCLKCON_IN (1 << 12)
+#define I2S_MOD_MSS_SLAVE (1 << 11)
+#define I2S_MOD_RCLKSRC (1 << 10)
+
+#define TXR_TX 0
+#define TXR_RX 1
+#define TXR_TXRX 2
+#define I2S_MOD_TXR_MASK (3 << 8)
+#define I2S_MOD_TXR(x) ((x & 3) << 8)
+
+#define I2S_MOD_SDF_MASK (3 << 6)
+#define I2S_MOD_SDF_I2S (0 << 6)
+#define I2S_MOD_SDF_MSB_Jstf (1 << 6)
+#define I2S_MOD_SDF_LSB_Jstf (2 << 6)
+
+#define RFS_256 (0x0)
+#define RFS_192 (0x7)
+
+#define BFS_64 (0x4)
+
+#define I2S_MOD_RFS_MASK (7 << 3)
+#define I2S_MOD_RFS(x) ((x & 7) << 3)
+#define I2S_MOD_BFS_MASK (7 << 0)
+#define I2S_MOD_BFS(x) ((x & 7) << 0)
/* FIC register */
-#define I2S_FIC_TFLUSH (1 << 15)
-#define I2S_FIC_FTX0CNT (0x7F << 8)
-#define I2S_FIC_RFLUSH (1 << 7)
-#define I2S_FIC_FRXCNT (0x7F << 0)
-
-#define I2S_PSR_PSREN (1 << 15)
-#define I2S_PSR_PSVAL (0x3F << 8)
-
-#define I2S_FICS_TXDMA_TH_EN (1 << 31)
-#define I2S_FICS_TXDMA_TH (0x3F << 24)
-#define I2S_FICS_RXDMA_TH_EN (1 << 23)
-#define I2S_FICS_RXDMA_TH (0x3F << 16)
-#define I2S_FICS_TFLUSHS (1 << 15)
-#define I2S_FICS_FTXSCNT (0x7F << 8)
+#define I2S_FIC_TFLUSH (1 << 15)
+#define I2S_FIC_FTX0CNT (0x7F << 8)
+#define I2S_FIC_RFLUSH (1 << 7)
+#define I2S_FIC_FRXCNT (0x7F << 0)
+
+#define I2S_PSR_PSREN (1 << 15)
+#define I2S_PSR_PSVAL (0x3F << 8)
+
+#define I2S_FICS_TXDMA_TH_EN (1 << 31)
+#define I2S_FICS_TXDMA_TH (0x3F << 24)
+#define I2S_FICS_RXDMA_TH_EN (1 << 23)
+#define I2S_FICS_RXDMA_TH (0x3F << 16)
+#define I2S_FICS_TFLUSHS (1 << 15)
+#define I2S_FICS_FTXSCNT (0x7F << 8)
#endif /* __ARCH_ARM_SRC_S5JT200_CHIP_S5J_I2S_H */
#define GPIO_WEXT_INTA01 (GPIO_EINT | GPIO_PORTA0 | GPIO_PIN1)
#define GPIO_WEXT_INTA02 (GPIO_EINT | GPIO_PORTA0 | GPIO_PIN2)
-/* XGPIO */
-#define GPIO_XGPIO1 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG0 | GPIO_PIN1)
-#define GPIO_XGPIO2 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG0 | GPIO_PIN2)
-#define GPIO_XGPIO3 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG0 | GPIO_PIN3)
-#define GPIO_XGPIO8 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN0)
-#define GPIO_XGPIO9 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN1)
-#define GPIO_XGPIO10 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN2)
-#define GPIO_XGPIO11 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN3)
-#define GPIO_XGPIO12 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN4)
-#define GPIO_XGPIO13 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN5)
-#define GPIO_XGPIO14 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN6)
-#define GPIO_XGPIO15 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG1 | GPIO_PIN7)
-#define GPIO_XGPIO16 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN0)
-#define GPIO_XGPIO17 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN1)
-#define GPIO_XGPIO18 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN2)
-#define GPIO_XGPIO19 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN3)
-#define GPIO_XGPIO20 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN4)
-#define GPIO_XGPIO21 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN5)
-#define GPIO_XGPIO22 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN6)
-#define GPIO_XGPIO23 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG2 | GPIO_PIN7)
-#define GPIO_XGPIO24 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN0)
-#define GPIO_XGPIO25 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN1)
-#define GPIO_XGPIO26 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN2)
-#define GPIO_XGPIO27 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTG3 | GPIO_PIN3)
-#define GPIO_XEINT0 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN0)
-#define GPIO_XEINT1 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN1)
-#define GPIO_XEINT2 (GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN2)
-
-#endif /* __ARCH_ARM_SRC_S5J_CHIP_S5JT200_PINCONFIG_H__ */
+#endif /* __ARCH_ARM_SRC_S5J_CHIP_S5JT200_PINCONFIG_H__ */
return getreg32(dma->base + (u32)(DMAC_INTMIS));
}
-static void dma_enable_ch_interrupt(struct dma_drvdata *dma,
- DMA_CHANNEL_NUM ch_num)
+static void dma_enable_ch_interrupt(struct dma_drvdata *dma, DMA_CHANNEL_NUM ch_num)
{
volatile u32 inten_reg;
inten_reg = getreg32(dma->base + (u32)(DMAC_INTEN));
putreg32((inten_reg | (1 << ch_num)), (dma->base + (u32) DMAC_INTEN));
}
-static void dma_disable_ch_interrupt(struct dma_drvdata *dma,
- DMA_CHANNEL_NUM ch_num)
+static void dma_disable_ch_interrupt(struct dma_drvdata *dma, DMA_CHANNEL_NUM ch_num)
{
volatile u32 inten_reg;
inten_reg = getreg32(dma->base + (u32)(DMAC_INTEN));
putreg32((inten_reg & ~(1 << ch_num)), (dma->base + (u32) DMAC_INTEN));
}
-static u32 dma_clear_ch_interrupt(struct dma_drvdata *dma,
- DMA_CHANNEL_NUM ch_num)
+static u32 dma_clear_ch_interrupt(struct dma_drvdata *dma, DMA_CHANNEL_NUM ch_num)
{
volatile u32 reg = getreg32(dma->base + (u32)(DMAC_INTCLR));
int debug_inst0;
/* Debug status busy? */
- while ((getreg32(dma->base + DMAC_DBG_STATUS) & 0x1));
+ while ((getreg32(dma->base + DMAC_DBG_STATUS) & 0x1)) ;
- debug_inst0 = (0 << 24) | ((0x01) << 16) |
- (dma_ch->dma_chan_num << 8) | (1 << 0);
+ debug_inst0 = (0 << 24) | ((0x01) << 16) | (dma_ch->dma_chan_num << 8) | (1 << 0);
putreg32(debug_inst0, dma->base + (u32) DMAC_DBG_INTST0);
putreg32(0, dma->base + DMAC_DBG_CMD);
for (i = 0; i < dma->max_ch_num; i++) {
if ((intstatus & (1 << i)) && (dma->dma_ch[i].task->callback)) {
- dma->dma_ch[i].task->callback(&dma->dma_ch[i],
- dma->dma_ch[i].task->arg, 0);
+ dma->dma_ch[i].task->callback(&dma->dma_ch[i], dma->dma_ch[i].task->arg, 0);
dma_clear_ch_interrupt(dma, i);
dma_disable_ch_interrupt(dma, i);
}
if (reg) {
for (i = 0; i < dma->max_ch_num; i++) {
if (reg & (1 << i)) {
- dmalldbg("\nChannel %d failt FTRD = 0x%x CH_FTR = 0x%x \n",
- i, getreg32(dma->base + (u32)(DMAC_FTRD)),
- getreg32(dma->base + (u32)(DMAC_CH_FTR(i))));
+ dmalldbg("\nChannel %d failt FTRD = 0x%x CH_FTR = 0x%x \n", i, getreg32(dma->base + (u32)(DMAC_FTRD)), getreg32(dma->base + (u32)(DMAC_CH_FTR(i))));
dmalldbg("- CSR 0x%x, CPC 0x%x, SAR 0x%x, DAR 0x%x,\
- CCR 0x%x, LC0 0x%x, LC1 0x%x\n",
- getreg32(dma->base + (u32)(DMAC_CH_CSR(i))),
- getreg32(dma->base + (u32)(DMAC_CH_CPC(i))),
- getreg32(dma->base + (u32)(DMAC_CH_SAR(i))),
- getreg32(dma->base + (u32)(DMAC_CH_DAR(i))),
- getreg32(dma->base + (u32)(DMAC_CH_CCR(i))),
- getreg32(dma->base + (u32)(DMAC_CH_LC0(i))),
- getreg32(dma->base + (u32)(DMAC_CH_LC1(i))));
+ CCR 0x%x, LC0 0x%x, LC1 0x%x\n", getreg32(dma->base + (u32)(DMAC_CH_CSR(i))), getreg32(dma->base + (u32)(DMAC_CH_CPC(i))), getreg32(dma->base + (u32)(DMAC_CH_SAR(i))), getreg32(dma->base + (u32)(DMAC_CH_DAR(i))), getreg32(dma->base + (u32)(DMAC_CH_CCR(i))), getreg32(dma->base + (u32)(DMAC_CH_LC0(i))), getreg32(dma->base + (u32)(DMAC_CH_LC1(i))));
dmalldbg("- INTEN 0x%x, RIS 0x%x, INTMIS 0x%x,\
- FSRD 0x%x, FSRC 0x%x, FTRD 0x%x \n",
- getreg32(dma->base + (u32)(DMAC_INTEN)),
- getreg32(dma->base + (u32)(DMAC_INT_EVENT_RIS)),
- getreg32(dma->base + (u32)(DMAC_INTMIS)),
- getreg32(dma->base + (u32)(DMAC_FSRD)),
- getreg32(dma->base + (u32)(DMAC_FSRC)),
- getreg32(dma->base + (u32)(DMAC_FTRD)));
+ FSRD 0x%x, FSRC 0x%x, FTRD 0x%x \n", getreg32(dma->base + (u32)(DMAC_INTEN)), getreg32(dma->base + (u32)(DMAC_INT_EVENT_RIS)), getreg32(dma->base + (u32)(DMAC_INTMIS)), getreg32(dma->base + (u32)(DMAC_FSRD)), getreg32(dma->base + (u32)(DMAC_FSRC)), getreg32(dma->base + (u32)(DMAC_FTRD)));
dma_ch_kill(&dma->dma_ch[i]);
dma_disable_ch_interrupt(dma, i);
if (dma->dma_ch[i].task->callback) {
- dma->dma_ch[i].task->callback(&dma->dma_ch[i],
- dma->dma_ch[i].task->arg, -1);
+ dma->dma_ch[i].task->callback(&dma->dma_ch[i], dma->dma_ch[i].task->arg, -1);
}
}
while ((getreg32(dma->base + DMAC_DBG_STATUS) & 0x1)) ; /* Debug status busy? */
secure_status = ((getreg32(dma->base + DMAC_CR0) >> 2) & 0x1);
- debug_inst0 = (dma_ch->dma_chan_num << 24) |
- ((0xA0 | secure_status << 1) << 16) |
- (dma_ch->dma_chan_num << 8) |
- (0 << 0);
+ debug_inst0 = (dma_ch->dma_chan_num << 24) | ((0xA0 | secure_status << 1) << 16) | (dma_ch->dma_chan_num << 8) | (0 << 0);
putreg32(debug_inst0, dma->base + (u32) DMAC_DBG_INTST0);
putreg32((int)(dma_ch->task->microcode), dma->base + DMAC_DBG_INTST1);
#define DMAC_FSRC (0x034)
#define DMAC_FTRD (0x038)
-#define DMAC_CH_FTR(n) 0x040 + 0x04 * (n)
-#define DMAC_CH_CSR(n) (u32)(0x100 + 0x08 * (n))
-#define DMAC_CH_CPC(n) 0x104 + 0x08 * (n)
-#define DMAC_CH_SAR(n) 0x400 + 0x20 * (n)
-#define DMAC_CH_DAR(n) 0x404 + 0x20 * (n)
-#define DMAC_CH_CCR(n) 0x408 + 0x20 * (n)
-#define DMAC_CH_LC0(n) 0x40C + 0x20 * (n)
-#define DMAC_CH_LC1(n) 0x410 + 0x20 * (n)
+#define DMAC_CH_FTR(n) 0x040 + 0x04*(n)
+#define DMAC_CH_CSR(n) (u32)(0x100 + 0x08*(n))
+#define DMAC_CH_CPC(n) 0x104 + 0x08*(n)
+#define DMAC_CH_SAR(n) 0x400 + 0x20*(n)
+#define DMAC_CH_DAR(n) 0x404 + 0x20*(n)
+#define DMAC_CH_CCR(n) 0x408 + 0x20*(n)
+#define DMAC_CH_LC0(n) 0x40C + 0x20*(n)
+#define DMAC_CH_LC1(n) 0x410 + 0x20*(n)
#define DMAC_DBG_STATUS 0xD00
#define DMAC_DBG_CMD 0xD04
/* CCR BITFIELDS */
-#define NOSWAP (0)
-#define ENDIAN_SWAP_SIZE_MASK (7 << 28)
-#define ENDIAN_SWAP_SIZE(x) ((x & 7) << 28)
+#define NOSWAP (0)
+#define ENDIAN_SWAP_SIZE_MASK (7 << 28)
+#define ENDIAN_SWAP_SIZE(x) ((x & 7) << 28)
-#define AWCACHE0 (1)
-#define AWCACHE1 (2)
-#define AWCACHE2 (4)
-#define DST_CACHE_CTRL_MASK (7 << 25)
-#define DST_CACHE_CTRL(x) ((x & 7) << 25)
+#define AWCACHE0 (1)
+#define AWCACHE1 (2)
+#define AWCACHE2 (4)
+#define DST_CACHE_CTRL_MASK (7 << 25)
+#define DST_CACHE_CTRL(x) ((x & 7) << 25)
-#define AWPROT0 (1)
-#define AWPROT1 (2)
-#define AWPROT2 (4)
-#define DST_PROT_CTRL_MASK (7 << 22)
-#define DST_PROT_CTRL(x) ((x & 7) << 22)
+#define AWPROT0 (1)
+#define AWPROT1 (2)
+#define AWPROT2 (4)
+#define DST_PROT_CTRL_MASK (7 << 22)
+#define DST_PROT_CTRL(x) ((x & 7) << 22)
/* Burst Len absolute value */
-#define DST_BURST_LEN_MASK (0xf << 18)
-#define DST_BURST_LEN(x) (((x - 1) & 0xf) << 18)
-
-#define BS_1 0
-#define BS_2 1
-#define BS_4 2
-#define BS_8 3
-#define DST_BURST_SIZE_MASK (7 << 15)
-#define DST_BURST_SIZE(x) ((x & 7) << 15)
-
-#define DST_INC (1 << 14)
-
-#define ARCACHE0 (1)
-#define ARCACHE1 (2)
-#define ARCACHE2 (4)
-#define SRC_CACHE_CTRL_MASK (7 << 11)
-#define SRC_CACHE_CTRL(x) ((x & 7) << 11)
-
-#define ARPROT0 (1)
-#define ARPROT1 (2)
-#define ARPROT2 (4)
-#define SRC_PROT_CTRL_MASK (7 << 8)
-#define SRC_PROT_CTRL(x) ((x & 7) << 8)
+#define DST_BURST_LEN_MASK (0xf << 18)
+#define DST_BURST_LEN(x) (((x - 1) & 0xf) << 18)
+
+#define BS_1 0
+#define BS_2 1
+#define BS_4 2
+#define BS_8 3
+#define DST_BURST_SIZE_MASK (7 << 15)
+#define DST_BURST_SIZE(x) ((x & 7) << 15)
+
+#define DST_INC (1 << 14)
+
+#define ARCACHE0 (1)
+#define ARCACHE1 (2)
+#define ARCACHE2 (4)
+#define SRC_CACHE_CTRL_MASK (7 << 11)
+#define SRC_CACHE_CTRL(x) ((x & 7) << 11)
+
+#define ARPROT0 (1)
+#define ARPROT1 (2)
+#define ARPROT2 (4)
+#define SRC_PROT_CTRL_MASK (7 << 8)
+#define SRC_PROT_CTRL(x) ((x & 7) << 8)
/* Burst Len absolute value */
-#define SRC_BURST_LENGTH_MASK (0xf << 4)
-#define SRC_BURST_LENGTH(x) (((x - 1) & 0xf) << 4)
+#define SRC_BURST_LENGTH_MASK (0xf << 4)
+#define SRC_BURST_LENGTH(x) (((x - 1) & 0xf) << 4)
/* Burst Size absolute value */
-#define SRC_BURST_SIZE_MASK (7 << 1)
-#define SRC_BURST_SIZE(x) ((x & 7) << 1)
+#define SRC_BURST_SIZE_MASK (7 << 1)
+#define SRC_BURST_SIZE(x) ((x & 7) << 1)
-#define SRC_INC (1 << 0)
+#define SRC_INC (1 << 0)
-#define LC0 0x0
-#define LC0_END 0x10
-#define LC1 0x2
-#define LC1_END 0x14
+#define LC0 0x0
+#define LC0_END 0x10
+#define LC1 0x2
+#define LC1_END 0x14
#define CCR_M2M_DFLT (ENDIAN_SWAP_SIZE(NOSWAP) | \
DST_CACHE_CTRL(AWCACHE1) | \
SRC_PROT_CTRL(2) | \
DST_PROT_CTRL(2))
-#define DMA_MC_4B_SET(a, b) (*(unsigned int *)(a) = (unsigned int)(b))
-#define DMA_MC_1B_SET(a, b) (*(char *)(a) = (char)(b))
-#define DMA_MC_EV_SET(a, b) (*(char *)(a) = (char)(b << 3))
+#define DMA_MC_4B_SET(a, b) (*(unsigned int *)(a) = (unsigned int)(b))
+#define DMA_MC_1B_SET(a, b) (*(char *)(a) = (char)(b))
+#define DMA_MC_EV_SET(a, b) (*(char *)(a) = (char)(b << 3))
#define DMA_NOP (0x18)
************************************************************************************/
/* Microcode functions */
-static inline int DMA_Encode_DMAMOV(char *base, void **reg_addr, DMA_INST_REG rd)
+inline static int DMA_Encode_DMAMOV(char *base, void **reg_addr, DMA_INST_REG rd)
{
rd &= 0x07;
return 2;
}
-static inline int DMA_Encode_DMALPEND(char *base, u8 CTRL, char backwards_jump)
+inline static int DMA_Encode_DMALPEND(char *base, u8 CTRL, char backwards_jump)
{
base[0] = 0x28 | CTRL;
base[1] = backwards_jump;
return 2;
}
-static inline int DMA_Encode_DMALD(char *base, u8 CTRL)
+inline static int DMA_Encode_DMALD(char *base, u8 CTRL)
{
base[0] = 0x04 | CTRL;
return 1;
}
-static inline int DMA_Encode_DMALDP(char *base, u8 CTRL, DMA_REQ_MAP periph)
+inline static int DMA_Encode_DMALDP(char *base, u8 CTRL, DMA_REQ_MAP periph)
{
base[0] = 0x25 | CTRL;
base[1] = periph << 3;
return 2;
}
-static inline int DMA_Encode_DMAST(char *base, u8 CTRL)
+inline static int DMA_Encode_DMAST(char *base, u8 CTRL)
{
base[0] = 0x08 | CTRL;
return 1;
}
-static inline int DMA_Encode_DMASTP(char *base, u8 CTRL, DMA_REQ_MAP periph)
+inline static int DMA_Encode_DMASTP(char *base, u8 CTRL, DMA_REQ_MAP periph)
{
base[0] = 0x29 | CTRL;
base[1] = periph << 3;
return 2;
}
-static inline int DMA_Encode_DMAWFP(char *base, u8 CTRL, DMA_REQ_MAP periph)
+inline static int DMA_Encode_DMAWFP(char *base, u8 CTRL, DMA_REQ_MAP periph)
{
base[0] = 0x30 | CTRL;
base[1] = periph << 3;
return 2;
}
-static inline int DMA_Encode_DMASEV(char *base, void **event_num)
+inline static int DMA_Encode_DMASEV(char *base, void **event_num)
{
base[0] = 0x34;
base[1] = 0xe;
return 2;
}
-static inline int DMA_Encode_DMAEND(char *base)
+inline static int DMA_Encode_DMAEND(char *base)
{
base[0] = 0x00;
return 1;
}
-static inline int DMA_Encode_DMAFLUSHP(char *base, u8 periph)
+inline static int DMA_Encode_DMAFLUSHP(char *base, u8 periph)
{
base[0] = 0x35;
base[1] = periph << 3;
return 2;
}
-static inline int DMA_Encode_DMAWMB(char *base)
+inline static int DMA_Encode_DMAWMB(char *base)
{
base[0] = 0x13;
return 1;
DMA_CH_CONTEXT *ch;
ch = handle;
- priv_task->chflags = CCR_M2M_DFLT |
- SRC_BURST_SIZE(BS_4) |
- DST_BURST_SIZE(BS_4);
+ priv_task->chflags = CCR_M2M_DFLT | SRC_BURST_SIZE(BS_4) | DST_BURST_SIZE(BS_4);
DMA_MC_4B_SET(priv_task->SAR, task->src);
DMA_MC_4B_SET(priv_task->DAR, task->dst);
DMA_MC_EV_SET(priv_task->EVENT_CH, ch->dma_chan_num);
- arch_clean_dcache((uintptr_t)task->microcode,
- (uintptr_t)(task->microcode + priv_task->mc_size));
+ arch_clean_dcache((uintptr_t) task->microcode, (uintptr_t)(task->microcode + priv_task->mc_size));
return OK;
}
unsigned int tx_num = (task->size / 4) & (~0xFF);
unsigned int tx_num_residual = (task->size / 4) & 0xFF;
- priv_task->chflags = CCR_M2P_DFLT |
- SRC_BURST_SIZE(BS_1) |
- DST_BURST_SIZE(BS_4);
+ priv_task->chflags = CCR_M2P_DFLT | SRC_BURST_SIZE(BS_1) | DST_BURST_SIZE(BS_4);
DMA_MC_4B_SET(priv_task->SAR, task->src);
DMA_MC_4B_SET(priv_task->DAR, task->dst);
memset(priv_task->finish_1, DMA_NOP, priv_task->finish_size);
}
- arch_clean_dcache((uintptr_t)task->microcode,
- (uintptr_t)(task->microcode + priv_task->mc_size));
+ arch_clean_dcache((uintptr_t) task->microcode, (uintptr_t)(task->microcode + priv_task->mc_size));
return OK;
}
unsigned int rx_num = (task->size / 4) & (~0xFF);
unsigned int rx_num_residual = (task->size / 4) & 0xFF;
- priv_task->chflags = CCR_P2M_DFLT |
- SRC_BURST_SIZE(BS_4) |
- DST_BURST_SIZE(BS_1);
+ priv_task->chflags = CCR_P2M_DFLT | SRC_BURST_SIZE(BS_4) | DST_BURST_SIZE(BS_1);
DMA_MC_4B_SET(priv_task->SAR, task->src);
DMA_MC_4B_SET(priv_task->DAR, task->dst);
memset(priv_task->finish_1, DMA_NOP, priv_task->finish_size);
}
- arch_clean_dcache((uintptr_t)task->microcode,
- (uintptr_t)(task->microcode + priv_task->mc_size));
+ arch_clean_dcache((uintptr_t) task->microcode, (uintptr_t)(task->microcode + priv_task->mc_size));
return OK;
}
#error CONFIG_AUDIO required by this driver
#endif
-#define S5J_I2S_MAXPORTS 1
-
#ifndef CONFIG_S5J_I2S_MAXINFLIGHT
#define CONFIG_S5J_I2S_MAXINFLIGHT 16
#endif
#undef CONFIG_I2S_TXS_DMACH
#undef CONFIG_I2S_RX_DMACH
-#define CONFIG_I2S_TXP_DMACH 0
-#define CONFIG_I2S_TXS_DMACH 1
-#define CONFIG_I2S_RX_DMACH 2
+#define CONFIG_I2S_TXP_DMACH 0
+#define CONFIG_I2S_TXS_DMACH 1
+#define CONFIG_I2S_RX_DMACH 2
#endif
#if defined(I2S_HAVE_RX) || defined(I2S_HAVE_TX_P) || defined(I2S_HAVE_TX_S)
struct s5j_i2s_s {
struct i2s_dev_s dev; /* Externally visible I2S interface */
- uintptr_t base; /* I2S controller register base address */
- int isr_num; /* isr number */
- xcpt_t isr_handler; /* irs handler */
+ uintptr_t base; /* I2S controller register base address */
+ int isr_num; /* isr number */
+ xcpt_t isr_handler; /* irs handler */
sem_t exclsem; /* Assures mutually exclusive acess to I2S */
uint8_t datalen; /* Data width (8, 16, or 32) */
/* Register helpers */
#ifdef CONFIG_S5J_I2S_DUMPBUFFERS
-#define i2s_init_buffer(b, s) memset(b, 0x55, s);
+#define i2s_init_buffer(b, s) memset(b, 0x55, s);
#define i2s_dump_buffer(m, b, s) lib_dumpbuffer(m, b, s)
#else
#define i2s_init_buffer(b, s)
static int i2s_checkwidth(struct s5j_i2s_s *priv, int bits);
static uint32_t i2s_rxdatawidth(struct i2s_dev_s *dev, int bits);
-static int i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
- i2s_callback_t callback, void *arg, uint32_t timeout);
+static int i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_callback_t callback, void *arg, uint32_t timeout);
static uint32_t i2s_samplerate(struct i2s_dev_s *dev, uint32_t rate);
static uint32_t i2s_txdatawidth(struct i2s_dev_s *dev, int bits);
-static int i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
- i2s_callback_t callback, void *arg, uint32_t timeout);
+static int i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_callback_t callback, void *arg, uint32_t timeout);
/* Initialization */
.i2s_send = i2s_send,
};
-static struct s5j_i2s_s *g_i2sdevice[S5J_I2S_MAXPORTS];
-
/****************************************************************************
* Public Data
****************************************************************************/
/* Increment the DMA timeout */
if (bfcontainer->timeout > 0) {
- timeout += bfcontainer->timeout;
+ timeout += bfcontainer->timeout;
} else {
- notimeout = true;
+ notimeout = true;
}
/* Add the container to the list of active DMAs */
/* Increment the DMA timeout */
if (bfcontainer->timeout > 0) {
- timeout += bfcontainer->timeout;
+ timeout += bfcontainer->timeout;
} else {
- notimeout = true;
+ notimeout = true;
}
/* Add the container to the list of active DMAs */
/* Reset I2S */
putreg32(0, priv->base + S5J_I2S_CON);
- modifyreg32(priv->base + S5J_I2S_CON, I2S_CR_SW_RST_MASK,
- I2S_CR_SW_RST_RELEASE);
+ modifyreg32(priv->base + S5J_I2S_CON, I2S_CR_SW_RST_MASK, I2S_CR_SW_RST_RELEASE);
/* Set Mode */
- reg = I2S_MOD_OP_CLK_PCLK | I2S_MOD_CDCLKCON_IN | I2S_MOD_MSS_SLAVE |
- I2S_MOD_RCLKSRC | I2S_MOD_TXR(TXR_TXRX) | I2S_MOD_RFS(RFS_256) |
- I2S_MOD_BFS(BFS_64);
+ reg = I2S_MOD_OP_CLK_PCLK | I2S_MOD_CDCLKCON_IN | I2S_MOD_MSS_SLAVE | I2S_MOD_RCLKSRC | I2S_MOD_TXR(TXR_TXRX) | I2S_MOD_RFS(RFS_256) | I2S_MOD_BFS(BFS_64);
putreg32(reg, priv->base + S5J_I2S_MOD);
ret = s5j_configgpio(GPIO_I2S0_BCLK);
return 0;
}
-
/****************************************************************************
* Public Functions
****************************************************************************/
*
****************************************************************************/
-struct i2s_dev_s *s5j_i2s_initialize(uint16_t port)
+struct i2s_dev_s *s5j_i2s_initialize(void)
{
- if (port >= S5J_I2S_MAXPORTS) {
- lldbg("ERROR: Port number outside the allowed port number range\n");
- return NULL;
- }
- if (g_i2sdevice[port] != NULL) {
- return &g_i2sdevice[port]->dev;
- }
-
struct s5j_i2s_s *priv;
int ret;
irq_attach(priv->isr_num, priv->isr_handler, priv);
up_enable_irq(priv->isr_num);
- g_i2sdevice[port] = priv;
-
/* Success exit */
return &priv->dev;
*
****************************************************************************/
-FAR struct i2s_dev_s *s5j_i2s_initialize(uint16_t port);
+FAR struct i2s_dev_s *s5j_i2s_initialize(void);
#undef EXTERN
#if defined(__cplusplus)
endmenu # Audio Buffer Configuration
-config AUDIO_MULTI_CARD
- bool "Registering audio device as different devices for capture and playback"
- default n
-
-
config DEBUG_AUDIO_ERROR
bool "Output AUDIO Error Debug Messages"
default n
driver. See include/tinyara/gpio.h for further GPIO driver
information.
+menuconfig I2S
+ bool "I2S Driver Support"
+ default n
+ ---help---
+ This selection enables selection of common I2S options. This option
+ should be enabled by all platforms that support I2S interfaces.
+ See include/tinyara/audio/i2s.h for further I2S driver information.
+
+if I2S
+endif # I2S
+
+menuconfig AUDIO_DEVICES
+ bool "Audio Device Support"
+ default n
+ ---help---
+ Enable support for audio device drivers. This includes drivers for
+ MP3, WMA and Ogg Vorbis encoding, decoding, as well as drivers for
+ interfacing with external DSP chips to perform custom audio functions.
+
+ NOTE: All of these drivers depend on support from the audio subsystem
+ enabled with the AUDIO selection.
+
+if AUDIO_DEVICES
+source drivers/audio/Kconfig
+endif # AUDIO_DEVICES
+
menuconfig BCH
bool "Block-to-Character (BCH) Support"
default n
source drivers/wireless/Kconfig
-source drivers/audio/Kconfig
# the appropriate paths to the VPATH variable
include analog$(DELIM)Make.defs
-include audio$(DELIM)Make.defs
include bch$(DELIM)Make.defs
include i2c$(DELIM)Make.defs
include audio$(DELIM)Make.defs
#
# For a description of the syntax of this configuration file,
# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
-#
-
-menuconfig I2S
- bool "I2S Driver Support"
- default n
- ---help---
- This selection enables selection of common I2S options. This option
- should be enabled by all platforms that support I2S interfaces.
- See include/tinyara/audio/i2s.h for further I2S driver information.
-
-if I2S
config AUDIO_I2SCHAR
bool "I2S character driver (for testing only)"
The special value of zero disables RX timeouts. Default: 0
endif # AUDIO_I2SCHAR
-endif # I2S
-config AUDIO_DEVICES
- bool "Support for Audio Devices"
+config AUDIO_NULL
+ bool "NULL audio device"
default n
depends on AUDIO
---help---
- Enables support for Audio Devices.
-
-if AUDIO_DEVICES
+ A do-nothinig audio device driver to simplify testing of audio
+ decoders.
-config AUDIO_MULTI_SESSION
- bool "Support multiple sessions"
- default n
+config AUDIO_ALC5658
+ bool "ALC5658 audio chip"
+ depends on AUDIO
---help---
- Some audio devices, such as USB attached sound cards, may support more
- than one streaming session at a time (each with one or more audio channels).
- Selecting this feature adds support for tracking multiple concurrent
- sessions with the lower-level audio devices.
+ Select to enable support for the ALC5658 Audio codec by Realtek
+ NOTE: This driver also depends on both I2C and I2S support although
+ that dependency is not explicit here.
-menu "Audio Buffer Configuration"
+if AUDIO_ALC5658
-config AUDIO_LARGE_BUFFERS
- bool "Support Audio Buffers with greater than 65K samples"
- default n
- ---help---
- By default, the Audio Pipeline Buffers use a 16-bit max sample count, limiting
- the number of samples per buffer to 65K. Enable this option to specify a
- 32-bit max sample count for increased samples / buffer capability.
- channel capability.
+config ALC5658_INITVOLUME
+ int "ALC5658 initial volume setting"
+ default 250
-config AUDIO_NUM_BUFFERS
- int "Number of buffers for audio processing"
+config ALC5658_INFLIGHT
+ int "ALC5658 maximum in-flight audio buffers"
default 2
- ---help---
- Specifies the number of buffers to allocate for audio processing.
- If Driver Specified buffer sizes is enabled (below), then the
- low-level drivers will have the opportunity to override this
- value.
-
-config AUDIO_BUFFER_NUMBYTES
- int "Size of each audio buffer for audio processing"
- default 8192
- ---help---
- Specifies the allocation size for each audio buffer
- If Driver Specified buffer sizes is enabled (below), then the
- low-level drivers will have the opportunity to override this
- value.
-
-config AUDIO_DRIVER_SPECIFIC_BUFFERS
- bool "Support for Driver specified buffer sizes"
- default n
- ---help---
- By default, the Audio system uses the same size and number of buffers
- regardless of the specific audio device in use. Specifying 'y' here
- adds extra code which allows the lower-level audio device to specify
- a partucular size and number of buffers.
-endmenu # Audio Buffer Configuration
+config ALC5658_MSG_PRIO
+ int "ALC5658 message priority"
+ default 1
-menu "Supported Audio Formats"
-
-config AUDIO_FORMAT_PCM
- bool "PCM Audio"
- default y
- ---help---
- Build in support for PCM Audio format.
+config ALC5658_BUFFER_SIZE
+ int "ALC5658 preferred buffer size"
+ default 8192
-endmenu
+config ALC5658_NUM_BUFFERS
+ int "ALC5658 preferred number of buffers"
+ default 4
-menu "Exclude Specific Audio Features"
+config ALC5658_WORKER_STACKSIZE
+ int "ALC5658 worker thread stack size"
+ default 768
-config AUDIO_EXCLUDE_PAUSE_RESUME
- bool "Exclude pause and resume controls"
- default n
- ---help---
- Exclude building support for pausing and resuming audio files
- once they are submitted. If the sound system is being used to play
- short system notification or error type sounds that typicaly only
- last a second or two, then there is no need (or chance) to pause or
- resume sound playback once it has started.
-
-config AUDIO_EXCLUDE_STOP
- bool "Exclude stop playback controls"
+config ALC5658_REGDUMP
+ bool "ALC5658 register dump"
default n
---help---
- Exclude building support for stopping audio files once they are
- submitted. If the sound system is being used to play short sytem
- notification or error type sounds that typically only last a second
- or two, then there is no need (or chance) to stop the sound
- playback once it has started.
-
-config AUDIO_EXCLUDE_FFORWARD
- bool "Exclude fast forward controls"
- default n if !AUDIO_EXCLUDE_STOP
- default y if AUDIO_EXCLUDE_STOP
- ---help---
- Exclude building support for fast forwarding through audio files
- once they are submitted. Selecting this option would only make
- if the underlying audio decoding logic is capable of sub-sampling
- in the stream of audio data.
-
-config AUDIO_EXCLUDE_REWIND
- bool "Exclude rewind controls"
- default y
- ---help---
- Rewind may be supported by some audio devices, but not the typical
- device that receives a non-seekable, stream of audio buffers.
-
-endmenu
+ Enable logic to dump the contents of all ALC5658 registers.
-config AUDIO_CUSTOM_DEV_PATH
- bool "Use custom device path"
+config ALC5658_CLKDEBUG
+ bool "ALC5658 clock analysis"
default n
---help---
- By default, all audio devices on the target are are registered in the
- /dev/audio directory. Select this option to change the default location
- for the device registration.
+ Enable logic to analyze ALC5658 clock configuation.
-if AUDIO_CUSTOM_DEV_PATH
+endif # AUDIO_ALC5658
-config AUDIO_DEV_ROOT
- bool "Place audio devices in /dev"
- default n
- ---help---
- This option causes all device entries to appear in /dev with all the
- other device entries. This option generates the smallest code and
- RAM footprint.
+if AUDIO_NULL
-if !AUDIO_DEV_ROOT
+config AUDIO_NULL_MSG_PRIO
+ int "Null audio device message priority"
+ default 1
-config AUDIO_DEV_PATH
- string "Base path for Audio devices"
- default "/dev/audio"
- ---help---
- The path on the target where audio devices are registered. The default
- is to place all audio devices in the /dev/audio/ directory.
+config AUDIO_NULL_BUFFER_SIZE
+ int "Null audio device preferred buffer size"
+ default 8192
+
+config AUDIO_NULL_NUM_BUFFERS
+ int "Null audio device preferred number of buffers"
+ default 4
-endif # AUDIO_CUSTOM_DEV_PATH
-endif #AUDIO_DEV_ROOT
+config AUDIO_NULL_WORKER_STACKSIZE
+ int "Null audio device worker thread stack size"
+ default 768
-endif # AUDIO_DEVICES
+endif # AUDIO_NULL
-###########################################################################
+##########################################################################
#
# Copyright 2017 Samsung Electronics All Rights Reserved.
#
# either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
#
-###########################################################################
+############################################################################
############################################################################
# drivers/audio/Make.defs
# These drivers support various Audio devices using the NuttX Audio
# Include Audio drivers
ifeq ($(CONFIG_AUDIO_DEVICES),y)
-CSRCS += audio.c
+
+ifeq ($(CONFIG_AUDIO_NULL),y)
+CSRCS += audio_null.c
+endif
+
ifeq ($(CONFIG_AUDIO_I2SCHAR),y)
CSRCS += i2schar.c
endif
CSRCS += alc5658.c
endif
-ifeq ($(CONFIG_AUDIO_ALC5658CHAR),y)
-CSRCS += alc5658char.c
-endif
-
# Include Audio driver support
DEPPATH += --dep-path audio
* Pre-processor Definitions
****************************************************************************/
-#define ALC5658_DEFAULT_SAMPRATE 48000
-#define ALC5658_DEFAULT_NCHANNELS 2
-#define ALC5658_DEFAULT_BPSAMP 16
-#define FAIL 0xFFFF
+#define ALC5658_DEFAULT_SAMPRATE 48000
+#define ALC5658_DEFAULT_NCHANNELS 2
+#define ALC5658_DEFAULT_BPSAMP 16
+#define FAIL 0xFFFF
/****************************************************************************
* Private Function Prototypes
ALC5658_SIDETONE = 0x0018,
- /* DIGITAL Volume*/
+ /* DIGITAL Volume */
ALC5658_DAC_L1R1_VLM = 0x0019,
ALC5658_DAC_L2R2_VLM = 0x001A,
ALC5658_DAC_L2R2_MUTE = 0x001B,
- /* DIGITAL Mixers*/
+ /* DIGITAL Mixers */
ALC5658_ADC_2_DAC_MXR = 0x0029,
ALC5658_DAC_STR_MXR = 0x002A,
ALC5658_DAC_MN_MXR = 0x002B,
ALC5658_TDM_CTRL3 = 0x0079,
ALC5658_TDM_CTRL4 = 0x007A,
- /* Global Clock*/
+ /* Global Clock */
ALC5658_GLBL_CLK = 0x0080,
ALC5658_GLBL_PLL1 = 0x0081,
ALC5658_GLBL_PLL2 = 0x0082,
/* Commonly defined and redefined macros */
#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
/****************************************************************************
+++ /dev/null
-/****************************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- *
- ****************************************************************************/
-/****************************************************************************
- * drivers/audio/alc5658char.c
- *
- * This is a simple character driver for testing I2C. It is not an audio
- * driver but does conform to some of the buffer management heuristics of an
- * audio driver. It is not suitable for use in any real driver application
- * in its current form.
- *
- * Copyright (C) 2013 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <tinyara/config.h>
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <tinyara/kmalloc.h>
-#include <tinyara/fs/fs.h>
-#include <tinyara/audio/audio.h>
-#include <tinyara/audio/i2s.h>
-#include <tinyara/i2c.h>
-
-#include <tinyara/clock.h>
-
-#include "alc5658char.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_AUDIO_ALC5658CHAR_RXTIMEOUT
-#define CONFIG_AUDIO_ALC5658CHAR_RXTIMEOUT 0
-#endif
-
-#ifndef CONFIG_AUDIO_ALC5658CHAR_TXTIMEOUT
-#define CONFIG_AUDIO_ALC5658CHAR_TXTIMEOUT 0
-#endif
-
-#define ALC5658CHAR_RXBUF_CNT 8
-#define ALC5658CHAR_TXBUF_CNT 8
-
-#define FAIL 0xFFFF
-
-/* Device naming ************************************************************/
-#define DEVNAME_FMT "/dev/alc5658char%d"
-#define DEVNAME_FMTLEN (16 + 3 + 1)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct alc5658char_dev_s {
- FAR struct i2s_dev_s *i2s; /* The lower half i2s driver */
- FAR struct i2c_dev_s *i2c; /* i2c bus access ops */
- FAR struct i2c_config_s *i2c_config;
-
-#ifdef AUDIO_BUFFERS_REUSE
- /*If we decide to reuse bufferes use next queues*/
- struct dq_queue_s doneq; /* Queue of sent buffers to be reused */
- sem_t donesem; /* Protect dq */
-#endif
-
- struct dq_queue_s rxedq; /* Queue of received audio IN buffers */
- sem_t rxsem; /* Protect RX Q and rx_cnt */
- sem_t cnt_rxsem; /* Counting semaphore to block receiving thread if no data is received yet */
- int rx_cnt; /* Count allocated RX buffers */
-
- sem_t alloc; /* Counting semaphore for Alloc TX buffers, and block allocator if needed */
-
- sem_t exclsem; /* Assures mutually exclusive access */
-
- uint32_t samprate; /* 8000, 44100, ... */
- uint8_t bpsamp; /* Bits per sample: 8 bits = 8, 16 bits = 16 */
- uint8_t nchannels; /* Mono=1, Stereo=2 */
-
- uint8_t volume;
- int16_t balance; /* Current balance level */
- int16_t micgain; /* Current mic gain level */
-
- bool running; /* True: Worker thread is running */
- bool paused; /* True: Playing is paused */
- bool mute; /* True: Output is muted */
- bool terminating; /* True: Stop requested */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* I2S callback function */
-
-static void alc5658char_rxcallback(FAR struct i2s_dev_s *dev, FAR struct ap_buffer_s *apb, FAR void *arg, int result);
-static void alc5658char_txcallback(FAR struct i2s_dev_s *dev, FAR struct ap_buffer_s *apb, FAR void *arg, int result);
-
-/* Character driver methods */
-
-static ssize_t alc5658char_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
-static ssize_t alc5658char_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-
-static ssize_t alc5658char_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations alc5658char_fops = {
- NULL, /* open */
- NULL, /* close */
- alc5658char_read, /* read */
- alc5658char_write, /* write */
- NULL, /* seek */
- alc5658char_ioctl, /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- NULL, /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static void delay(unsigned int mS)
-{
- systime_t start = clock_systimer();
-
- mS = mS / MSEC_PER_TICK + 1;
-
- while (1) {
- if ((start + mS) < clock_systimer()) {
- return;
- }
- }
-}
-
-/****************************************************************************
- * Name: alc5658char_readreg
- *
- * Description
- * Read the specified 16-bit register from the ALC5658 device.
- *
- ****************************************************************************/
-static uint16_t alc5658char_readreg(FAR struct alc5658char_dev_s *priv, uint16_t regaddr)
-{
-
- int32_t ret;
- uint8_t reg[2];
- uint16_t regval;
- FAR struct i2c_dev_s *dev = priv->i2c;
- FAR struct i2c_config_s *alc5658char_i2c_config = priv->i2c_config;
-
- reg[0] = ((char *)®addr)[1];
- reg[1] = ((char *)®addr)[0];
-
- ret = i2c_write(dev, alc5658char_i2c_config, reg, 2);
- if (ret < 0) {
- auddbg("Error, cannot read reg %x\n", regaddr);
- return FAIL;
- }
-
- ret = i2c_read(dev, alc5658char_i2c_config, reg, 2);
- if (ret < 0) {
- auddbg("Error, cannot read reg %x\n", regaddr);
- return FAIL;
- }
-
- regval = ((uint16_t) reg[0] << 8) | (uint16_t) reg[1];
-
- return regval;
-}
-
-/************************************************************************************
- * Name: alc5658char_writereg
- *
- * Description:
- * Write the specified 16-bit register to the ALC5658 device.
- *
- ************************************************************************************/
-
-static void alc5658char_writereg(FAR struct alc5658char_dev_s *priv, uint16_t regaddr, uint16_t regval)
-{
- int32_t ret;
- uint8_t reg[4];
- FAR struct i2c_dev_s *dev = priv->i2c;
- FAR struct i2c_config_s *alc5658char_i2c_config = priv->i2c_config;
-
- reg[0] = ((char *)®addr)[1];
- reg[1] = ((char *)®addr)[0];
-
- reg[2] = ((char *)®val)[1];
- reg[3] = ((char *)®val)[0];
-
- ret = i2c_write(dev, alc5658char_i2c_config, (uint8_t *) reg, 4);
- if (ret < 0) {
- auddbg("Error, cannot write reg %x\n", regaddr);
- }
-}
-
-static uint16_t alc5658char_modifyreg(FAR struct alc5658char_dev_s *priv, uint16_t regaddr, uint16_t set, uint16_t clear)
-{
- uint16_t data;
-
- data = alc5658char_readreg(priv, regaddr);
- data &= ~clear;
- data |= set;
-
- alc5658char_writereg(priv, regaddr, data);
- return alc5658char_readreg(priv, regaddr);
-}
-
-static void alc5658char_i2c_script(FAR struct alc5658char_dev_s *priv, t_codec_init_script_entry *script, uint32_t size)
-{
- uint32_t i;
- uint16_t ret;
-
- for (i = 0; i < size; i++) {
- ret = alc5658char_modifyreg(priv, script[i].addr, script[i].val, 0xFFFF);
-
- delay(script[i].delay);
- }
-}
-
-/****************************************************************************
- * Name: alc5658char_setdatawidth
- *
- * Description:
- * Set the 8- 16- 24- bit data modes
- *
- ****************************************************************************/
-
-static void alc5658char_setdatawidth(FAR struct alc5658char_dev_s *priv)
-{
- I2S_TXDATAWIDTH(priv->i2s, priv->bpsamp);
-}
-
-/****************************************************************************
- * Name: alc5658char_setbitrate
- *
- * Description:
- *
- ****************************************************************************/
-
-static void alc5658char_setbitrate(FAR struct alc5658char_dev_s *priv)
-{
-}
-
-/************************************************************************************
- * Name: alc5658char_setvolume
- *
- * Description:
- * Set the right and left volume values in the ALC5658 device based on the current
- * volume and balance settings.
- *
- ************************************************************************************/
-
-static void alc5658char_setvolume(FAR struct alc5658char_dev_s *priv)
-{
- uint16_t vol_l, vol_r;
- int16_t bal = priv->balance;
-
- /* ADD VOLUME CODE HERE */
- vol_l = priv->volume;
- vol_r = priv->volume;
-
- if (bal > 0) {
- vol_l = vol_l - vol_l * abs(bal) / 1000;
- }
-
- if (bal < 0) {
- vol_r = vol_r - vol_l * abs(bal) / 1000;
- }
-
- if (priv->mute) {
- alc5658char_writereg(priv, ALC5658_HPOUT_MUTE, 0x8080);
- } else {
- alc5658char_writereg(priv, ALC5658_HPOUT_MUTE, 0x0000);
- }
-
- alc5658char_writereg(priv, ALC5658_HPOUT_VLML, vol_l << 8);
- alc5658char_writereg(priv, ALC5658_HPOUT_VLMR, vol_r << 8);
- audvdbg("MUTE %x, VOLL %x VOLR %x\n", (uint32_t) alc5658char_readreg(priv, ALC5658_HPOUT_MUTE), (uint32_t) alc5658char_readreg(priv, ALC5658_HPOUT_VLML), (uint32_t) alc5658char_readreg(priv, ALC5658_HPOUT_VLMR));
-
-}
-
-/************************************************************************************
- * Name: alc5658char_setmic
- *
- * Description:
- * Set Mic gain and some other related options if needed
- *
- ************************************************************************************/
-
-static void alc5658char_setmic(FAR struct alc5658char_dev_s *priv)
-{
- alc5658char_writereg(priv, ALC5658_IN1_CTRL, (priv->micgain + 16) << 8);
- audvdbg("MIC GAIN 0x%x\n", (uint32_t) alc5658char_readreg(priv, ALC5658_IN1_CTRL));
-}
-
-/****************************************************************************
- * Name: alc5658char_configure
- *
- * Description:
- * Configure the audio device for the specified mode of operation.
- *
- ****************************************************************************/
-
-static int alc5658char_configure(FAR struct alc5658char_dev_s *priv, FAR const struct audio_caps_s *caps)
-{
- int ret = OK;
-
- DEBUGASSERT(priv && caps);
- audvdbg("ac_type: %d\n", caps->ac_type);
-
- /* Process the configure operation */
-
- switch (caps->ac_type) {
- case AUDIO_TYPE_FEATURE:
- audvdbg(" AUDIO_TYPE_FEATURE\n");
-
- /* Process based on Feature Unit */
-
- switch (caps->ac_format.hw) {
- case AUDIO_FU_VOLUME: {
- /* Set the volume 0 ~ 1000 */
- if (caps->ac_controls.hw[0] <= 1000) {
- priv->volume = 63 - 63 * caps->ac_controls.hw[0] / 1000;
- }
- alc5658char_setvolume(priv);
- audvdbg(" Volume: %d\n", priv->volume);
- }
- break;
- case AUDIO_FU_MUTE: {
- /* Set the mute true/false */
- priv->mute = !!(caps->ac_controls.b[0]);
- audvdbg(" Mute: %d\n", priv->mute);
- alc5658char_setvolume(priv);
- }
- break;
- case AUDIO_FU_BALANCE: {
- /* Set the balamce -1000 ~ 0 ~ 1000 */
- int16_t bal = caps->ac_controls.hw[0];
-
- if (abs(bal) <= 1000) {
- priv->balance = bal;
- }
- audvdbg(" Balance: %d\n", priv->balance);
- alc5658char_setvolume(priv);
- }
- break;
- case AUDIO_FU_MICGAIN: {
- /* Set MIC gain */
- /* Values -16 ~ 0 ~ 53 equal to -12dB ~ 0dB ~ 39.75 */
- int16_t gain = caps->ac_controls.hw[0];
-
- if ((gain >= -16) && (gain <= 53)) {
- priv->micgain = gain;
- audvdbg(" Mic Gain: %d\n", priv->micgain);
- alc5658char_setmic(priv);
- } else {
- audvdbg(" Mic Gain request is out of range, unchanged: %d\n", priv->micgain);
- }
- }
- break;
-
- default:
- auddbg(" ERROR: Unrecognized feature unit\n");
- ret = -ENOTTY;
- break;
- }
- break;
-
- case AUDIO_TYPE_OUTPUT: {
- audvdbg(" AUDIO_TYPE_OUTPUT:\n");
- audvdbg(" Number of channels: %u\n", caps->ac_channels);
- audvdbg(" Sample rate: %u\n", caps->ac_controls.hw[0]);
- audvdbg(" Sample width: %u\n", caps->ac_controls.b[2]);
-
- /* Verify that all of the requested values are supported */
-
- ret = -ERANGE;
- if (caps->ac_channels != 1 && caps->ac_channels != 2) {
- auddbg("ERROR: Unsupported number of channels: %d\n", caps->ac_channels);
- break;
- }
-
- if (caps->ac_controls.b[2] != 8 && caps->ac_controls.b[2] != 16) {
- auddbg("ERROR: Unsupported bits per sample: %d\n", caps->ac_controls.b[2]);
- break;
- }
-
- /* Save the current stream configuration */
-
- priv->samprate = caps->ac_controls.hw[0];
- priv->nchannels = caps->ac_channels;
- priv->bpsamp = caps->ac_controls.b[2];
-
- /* alc5658char_setdatawidth(priv); */
- /* alc5658char_setbitrate(priv); */
-
- ret = OK;
- }
- break;
-
- case AUDIO_TYPE_PROCESSING:
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: alc5658char_start
- *
- * Description:
- * Configure the audio device for the specified mode of operation.
- *
- ****************************************************************************/
-
-static int alc5658char_start(FAR struct alc5658char_dev_s *priv, FAR const struct audio_caps_s *caps)
-{
- int ret = OK;
-
- alc5658char_setdatawidth(priv);
-
- /* Init codec here only for debugging purposes. Remove later. */
- alc5658char_i2c_script(priv, codec_init_inout_script1, sizeof(codec_init_inout_script1) / sizeof(t_codec_init_script_entry));
-
- switch (priv->samprate) {
- case AUDIO_SAMP_RATE_8K:
- alc5658char_i2c_script(priv, codec_init_pll_8K, sizeof(codec_init_pll_8K) / sizeof(t_codec_init_script_entry));
- break;
- case AUDIO_SAMP_RATE_11K:
- alc5658char_i2c_script(priv, codec_init_pll_11K, sizeof(codec_init_pll_11K) / sizeof(t_codec_init_script_entry));
- break;
- case AUDIO_SAMP_RATE_16K:
- alc5658char_i2c_script(priv, codec_init_pll_16K, sizeof(codec_init_pll_16K) / sizeof(t_codec_init_script_entry));
- break;
- case AUDIO_SAMP_RATE_22K:
- alc5658char_i2c_script(priv, codec_init_pll_22K, sizeof(codec_init_pll_22K) / sizeof(t_codec_init_script_entry));
- break;
- case AUDIO_SAMP_RATE_32K:
- alc5658char_i2c_script(priv, codec_init_pll_32K, sizeof(codec_init_pll_32K) / sizeof(t_codec_init_script_entry));
- break;
- case AUDIO_SAMP_RATE_44K:
- alc5658char_i2c_script(priv, codec_init_pll_44K, sizeof(codec_init_pll_44K) / sizeof(t_codec_init_script_entry));
- break;
- case AUDIO_SAMP_RATE_48K:
- default:
- alc5658char_i2c_script(priv, codec_init_pll_48K, sizeof(codec_init_pll_48K) / sizeof(t_codec_init_script_entry));
-
- };
-
- alc5658char_i2c_script(priv, codec_init_inout_script2, sizeof(codec_init_inout_script2) / sizeof(t_codec_init_script_entry));
-
- return ret;
-}
-
-static int alc5658char_stop(FAR struct alc5658char_dev_s *priv, FAR const struct audio_caps_s *caps)
-{
- int ret = OK;
- /* Init codec here only for debugging purposes. Remove later. */
-
- alc5658char_i2c_script(priv, codec_stop_script, sizeof(codec_stop_script) / sizeof(t_codec_init_script_entry));
- return ret;
-}
-
-/****************************************************************************
- * Name: alc5658char_rxcallback
- *
- * Description:
- * I2S RX transfer complete callback.
- *
- * NOTE: In this test driver, the RX is simply dumped in the bit bucket.
- * You would not do this in a real application. You would return the
- * received data to the caller via some IPC.
- *
- * Also, the test buffer is simply freed. This will work if this driver
- * has the sole reference to buffer; in that case the buffer will be freed.
- * Otherwise -- memory leak! A more efficient design would recycle the
- * audio buffers.
- *
- ****************************************************************************/
-
-static void alc5658char_rxcallback(FAR struct i2s_dev_s *dev, FAR struct ap_buffer_s *apb, FAR void *arg, int result)
-{
- FAR struct alc5658char_dev_s *priv = (FAR struct alc5658char_dev_s *)arg;
-
- DEBUGASSERT(priv && apb);
- audvdbg("apb=%p nbytes=%d result=%d crefs=%d\n", apb, apb->nbytes, result, apb->crefs);
-
- sem_wait(&priv->rxsem);
- /* we have some data, read ... */
- dq_addlast((FAR dq_entry_t *) apb, &priv->rxedq);
- sem_post(&priv->rxsem);
-
- /* Let the waiting thread to capture received data */
- sem_post(&priv->cnt_rxsem);
-}
-
-/****************************************************************************
- * Name: alc5658char_txcallback
- *
- * Description:
- * I2S TX transfer complete callback
- *
- * NOTE: The test buffer is simply freed. This will work if this driver
- * has the sole reference to buffer; in that case the buffer will be freed.
- * Otherwise -- memory leak! A more efficient design would recycle the
- * audio buffers.
- *
- ****************************************************************************/
-
-static void alc5658char_txcallback(FAR struct i2s_dev_s *dev, FAR struct ap_buffer_s *apb, FAR void *arg, int result)
-{
- FAR struct alc5658char_dev_s *priv = (FAR struct alc5658char_dev_s *)arg;
-
- DEBUGASSERT(priv && apb);
- audvdbg("apb=%p nbytes=%d result=%d crefs=%d\n", apb, apb->nbytes, result, apb->crefs);
-
- /* Free buffer here ... completety, if not reused */
- apb_free(apb);
-
- /* Let to alloc next buffer if pull was full */
- sem_post(&priv->alloc);
-}
-
-/****************************************************************************
- * Name: alc5658char_read
- *
- * Description:
- * Standard character driver read method
- *
- ****************************************************************************/
-
-static ssize_t alc5658char_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/****************************************************************************
- * Name: alc5658char_write
- *
- * Description:
- * Standard character driver write method
- *
- ****************************************************************************/
-
-static ssize_t alc5658char_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/************************************************************************************
- * Name: alc5658char_ioctl
- *
- * Description:
- * The standard ioctl method. This is where ALL of the Audio work is done.
- *
- ************************************************************************************/
-
-static ssize_t alc5658char_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct alc5658char_dev_s *priv;
- FAR struct audio_buf_desc_s *bufdesc;
- struct ap_buffer_s *apb;
- int ret;
-
- /* Get our private data structure */
- DEBUGASSERT(filep);
-
- inode = filep->f_inode;
- DEBUGASSERT(inode);
-
- priv = (FAR struct alc5658char_dev_s *)inode->i_private;
- DEBUGASSERT(priv);
-
- ret = 0;
-
- switch (cmd) {
-
- /* Alloc buffer for further TX operation. Will be filled by user APP. */
- case AUDIOIOC_ALLOCBUFFER: {
- audvdbg("AUDIOIOC_ALLOCBUFFER, arg - %ld\n", arg);
-
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
- /* We will be waiting here is if we reached max number of allocated TX buffers */
- sem_wait(&priv->alloc);
- ret = apb_alloc(bufdesc);
- }
- break;
-
- /* Free buffer we received at DEQUEUE with TXed data. */
- case AUDIOIOC_FREEBUFFER: {
- audvdbg("AUDIOIOC_FREEBUFFER, arg - %ld\n", arg);
-
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
- DEBUGASSERT(bufdesc->u.pBuffer != NULL);
-
- apb_free(bufdesc->u.pBuffer);
-
- /* decrement number of allocated rx buffers */
- DEBUGASSERT(priv->rx_cnt > 0);
-
- sem_wait(&priv->rxsem);
- priv->rx_cnt--;
- sem_post(&priv->rxsem);
-
- ret = sizeof(struct audio_buf_desc_s);
- }
- break;
-
- /* Put buffer into TX queue. callback will be called after buffer is transferred */
- case AUDIOIOC_ENQUEUEBUFFER: {
- audvdbg("AUDIOIOC_ENQUEUEBUFFER, arg - %ld\n", arg);
-
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
- ret = I2S_SEND(priv->i2s, bufdesc->u.pBuffer, alc5658char_txcallback, priv, CONFIG_AUDIO_ALC5658CHAR_TXTIMEOUT);
-
- }
- break;
-
- /* Request RXed data. Before receive anything we allocate and enqueue empty RX buffer for receiving */
- case AUDIOIOC_DEQUEUEBUFFER: {
- audvdbg("AUDIOIOC_DEQUEUEBUFFER, arg - %ld\n", arg);
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
-
- /* Try to allocate needed buffers and enqueue in receive queue */
- while (priv->rx_cnt < ALC5658CHAR_RXBUF_CNT) {
-
- if (bufdesc->numbytes == 0) {
- bufdesc->numbytes = 1024 * 16;
- }
-
- bufdesc->u.ppBuffer = &apb;
- ret = apb_alloc(bufdesc);
-
- if (ret < 0) {
- break;
- }
-
- ret = I2S_RECEIVE(priv->i2s, apb, alc5658char_rxcallback, priv, CONFIG_AUDIO_ALC5658CHAR_RXTIMEOUT);
-
- if (ret < 0) {
- apb_free(apb);
- break;
- }
- /* Increment counter of allocated RX buffers */
- sem_wait(&priv->rxsem);
- priv->rx_cnt++;
- sem_post(&priv->rxsem);
- }
-
- /* Clean buffer pointer to prevent wrong accesses */
- bufdesc->u.ppBuffer = NULL;
-
- /* We didn't hit any error before, so try to read any data from rx queue */
- if (ret >= 0) {
- /* Will be blocked here if no data is available to read yet */
- sem_wait(&priv->cnt_rxsem);
-
- /* we have some data, read ... */
- sem_wait(&priv->rxsem);
- apb = (FAR struct ap_buffer_s *)dq_remfirst(&priv->rxedq);
- sem_post(&priv->rxsem);
-
- bufdesc->u.pBuffer = apb;
- ret = 0;
- }
- break;
- }
- break;
-
- case AUDIOIOC_CONFIGURE: {
- audvdbg("AUDIOIOC_CONFIGURE, arg - %ld\n", arg);
- ret = alc5658char_configure(priv, (FAR const struct audio_caps_s *)arg);
- }
- break;
-
- case AUDIOIOC_START: {
- audvdbg("AUDIOIOC_START, arg - %ld\n", arg);
- ret = alc5658char_start(priv, (FAR const struct audio_caps_s *)arg);
- }
- break;
-
- case AUDIOIOC_STOP: {
- audvdbg("AUDIOIOC_STOP, arg - %ld\n", arg);
- ret = alc5658char_stop(priv, (FAR const struct audio_caps_s *)arg);
- }
- break;
-
- default:
- audvdbg("NOT SUPPORTED COMMAND %X, arg - %ld\n", cmd, arg);
- }
-
- return ret;
-
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: alc5658char_register
- *
- * Description:
- * Create and register the I2S character driver.
- *
- * The I2S character driver is a simple character driver that supports I2S
- * transfers via a read() and write(). The intent of this driver is to
- * support I2S testing. It is not an audio driver but does conform to some
- * of the buffer management heuristics of an audio driver. It is not
- * suitable for use in any real driver application in its current form.
- *
- * Input Parameters:
- * i2s - An instance of the lower half I2S driver
- * minor - The device minor number. The I2S character device will be
- * registers as /dev/alc5658charN where N is the minor number
- *
- * Returned Value:
- * OK if the driver was successfully register; A negated errno value is
- * returned on any failure.
- *
- ****************************************************************************/
-
-int alc5658char_register(FAR struct i2s_dev_s *i2s, FAR struct i2c_dev_s *i2c, FAR struct i2c_config_s *i2c_config, int minor)
-{
- FAR struct alc5658char_dev_s *priv;
- char devname[DEVNAME_FMTLEN];
- int ret;
- uint16_t regval;
-
- /* Sanity check */
-
- DEBUGASSERT(i2s != NULL && i2c != NULL && (unsigned)minor < 1000);
-
- /* Allocate a I2S character device structure */
-
- priv = (FAR struct alc5658char_dev_s *)kmm_zalloc(sizeof(struct alc5658char_dev_s));
- if (priv) {
- /* Initialize the I2S character device structure */
-
- priv->i2s = i2s;
- priv->i2c = i2c;
- priv->i2c_config = i2c_config;
-
- sem_init(&priv->exclsem, 0, 1);
-
- sem_init(&priv->alloc, 0, ALC5658CHAR_TXBUF_CNT);
-
- dq_init(&priv->rxedq); /* Queue of received audio IN buffers */
- sem_init(&priv->rxsem, 0, 1); /* Protect dq */
- sem_init(&priv->cnt_rxsem, 0, 0); /* Assume we did not receive anything yet!!! */
- priv->rx_cnt = 0; /* Count allocated RX buffers */
-
- regval = alc5658char_readreg(priv, ALC5658_RESET);
- if (regval != 0) {
- auddbg("ERROR: ALC5658 not found: ID=%04x\n", regval);
- return -ENODEV;
- }
-
- /* Create the character device name */
- snprintf(devname, DEVNAME_FMTLEN, DEVNAME_FMT, minor);
- ret = register_driver(devname, &alc5658char_fops, 0666, priv);
- if (ret < 0) {
- /* Free the device structure if we failed to create the character
- * device.
- */
-
- kmm_free(priv);
- }
-
- /* Init codec here only once */
- alc5658char_i2c_script(priv, codec_init_script, sizeof(codec_init_script) / sizeof(t_codec_init_script_entry));
-
- /* Return the result of the registration */
-
- return OK;
- }
-
- return -ENOMEM;
-}
+++ /dev/null
-/****************************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- *
- ****************************************************************************/
-/****************************************************************************
- * drivers/audio/alc5658char.h
- *
- * Copyright (C) 2014 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 __DRIVERS_AUDIO_ALC5658CHAR_H
-#define __DRIVERS_AUDIO_ALC5658CHAR_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <tinyara/config.h>
-#include <tinyara/compiler.h>
-
-#include <pthread.h>
-#include <mqueue.h>
-
-#include <tinyara/wqueue.h>
-#include <tinyara/fs/ioctl.h>
-
-#ifdef CONFIG_AUDIO
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Registers Addresses ******************************************************/
-
-typedef enum {
- ALC5658_RESET = 0x0000,
- ALC5658_SPO_VOL = 0x0001,
- ALC5658_HPOUT_MUTE = 0x0002,
- ALC5658_LOUT_CTRL1 = 0x0003,
- ALC5658_LOUT_CTRL2 = 0x0004,
- ALC5658_HPOUT_VLML = 0x0005,
- ALC5658_HPOUT_VLMR = 0x0006,
- ALC5658_SPDIF_CTRL1 = 0x0008,
- ALC5658_SPDIF_CTRL2 = 0x0009,
- ALC5658_SPDIF_CTRL3 = 0x0036,
- ALC5658_IN1_CTRL = 0x000C,
- ALC5658_INL_VLM = 0x000F,
- ALC5658_SIDETONE = 0x0018,
- /* DIGITAL Volume */
- ALC5658_DAC_L1R1_VLM = 0x0019,
- ALC5658_DAC_L2R2_VLM = 0x001A,
- ALC5658_DAC_L2R2_MUTE = 0x001B,
- /* DIGITAL Mixers */
- ALC5658_ADC_STR1_MXR = 0x0026,
- ALC5658_ADC_MONO_MXR = 0x0027,
- ALC5658_ADC_2_DAC_MXR = 0x0029,
- ALC5658_DAC_STR_MXR = 0x002A,
- ALC5658_DAC_MONO_MXR = 0x002B,
- ALC5658_DAC_LB_SDTONE = 0x002C,
- ALC5658_COPY_MODE = 0x002F,
- /* Analog DAC Source */
- ALC5658_DAC_SRC = 0x002D,
- ALC5658_RECMIX1L_CTRL_1 = 0x003B,
- ALC5658_RECMIX1L_CTRL_2 = 0x003C,
- ALC5658_RECMIX1R_CTRL_1 = 0x003D,
- ALC5658_RECMIX1R_CTRL_2 = 0x003E,
- /* ANALOG Mixers */
- ALC5658_SPKMIXL = 0x0046,
- ALC5658_SPKMIXR = 0x0047,
- ALC5658_SPOMIX = 0x0048,
- ALC5658_OUTMIXL1 = 0x004D,
- ALC5658_OUTMIXL2 = 0x004E,
- ALC5658_OUTMIXR1 = 0x004F,
- ALC5658_OUTMIXR2 = 0x0050,
- ALC5658_LOUTMIX = 0x0052,
- /* Power management */
- ALC5658_PWR_MNG1 = 0x0061,
- ALC5658_PWR_MNG2 = 0x0062,
- ALC5658_PWR_MNG3 = 0x0063,
- ALC5658_PWR_MNG4 = 0x0064,
- ALC5658_PWR_MNG5 = 0x0065,
- ALC5658_PWR_MNG6 = 0x0066,
- ALC5658_PWR_MNG7 = 0x0067,
- /* DIGITAL ports control */
- ALC5658_IF_DTCT = 0x006B,
- ALC5658_006E = 0x006E,
- ALC5658_006F = 0x006F,
- ALC5658_I2S1_CTRL = 0x0070,
- ALC5658_I2S2_CTRL = 0x0071,
- ALC5658_ADDA_CLK = 0x0073,
- ALC5658_ADDA_HPF = 0x0074,
- ALC5658_007B = 0x007B,
- /* TDM */
- ALC5658_TDM_CTRL1 = 0x0077,
- ALC5658_TDM_CTRL2 = 0x0078,
- ALC5658_TDM_CTRL3 = 0x0079,
- ALC5658_TDM_CTRL4 = 0x007A,
- /* Global Clock */
- ALC5658_GLBL_CLK = 0x0080,
- ALC5658_GLBL_PLL1 = 0x0081,
- ALC5658_GLBL_PLL2 = 0x0082,
- ALC5658_GLBL_ASRC1 = 0x0083,
- ALC5658_GLBL_ASRC2 = 0x0084,
- ALC5658_GLBL_ASRC3 = 0x0085,
- ALC5658_GLBL_ASRC4 = 0x008A,
- /* Amplifiers */
- ALC5658_HP_AMP = 0x008E,
- ALC5658_SPK_AMP = 0x00A0,
- ALC5658_0091 = 0x0091,
- ALC5658_INTCLK_CTRL = 0x0094,
- ALC5658_GNRL_CTRL = 0x00FA,
- ALC5658_GNRL_CTRL2 = 0x00FB,
- ALC5658_0111 = 0x0111,
- ALC5658_0125 = 0x0125,
- ALC5658_ADDA_RST1 = 0x013A,
- ALC5658_ADDA_RST2 = 0x013B,
- ALC5658_0x013C = 0x013C,
- ALC5658_NOISE_G_M1_CTRL1 = 0x0015,
- ALC5658_NOISE_G_M2_CTRL = 0x0160,
- ALC5658_0x01DE = 0x01DE,
- ALC5658_0x01DF = 0x01DF,
- ALC5658_0x01E4 = 0x01E4,
- ALC5658_0040 = 0x0040,
- ALC5658_0010 = 0x0010,
-} ALC5658_REG;
-
-typedef struct {
- ALC5658_REG addr;
- uint16_t val;
- unsigned int delay;
-} t_codec_init_script_entry;
-
-typedef struct {
- ALC5658_REG addr;
- char *name;
-} t_codec_dump_entry;
-
-t_codec_init_script_entry codec_reset_script[] = {
- {ALC5658_RESET, 0x0000, 0}, /* Reset */
-};
-
-t_codec_init_script_entry codec_stop_script[] = {
- {ALC5658_RESET, 0x0000, 0}, /* Reset */
- {ALC5658_I2S1_CTRL, 0x8000, 0}, /* Switch into slave to stop data transfer */
-};
-
-t_codec_init_script_entry codec_init_script[] = {
- {ALC5658_RESET, 0x0000, 0}, /* Reset */
- {ALC5658_006E, 0xFFFF, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_006F, 0xFFFF, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_GLBL_CLK, 0x8000, 0}, /* RC CLK, No dividers */
- {ALC5658_INTCLK_CTRL, 0x0280, 0}, /* ??? Enable ALL int CLK, even more than in documentation */
- {ALC5658_0111, 0xA502, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0125, 0x0430, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_ADDA_RST1, 0x3020, 0}, /* ??? DAC1, DAC2 + alpha clock enable */
- {ALC5658_ADDA_CLK, 0x1770, 0}, /* I2Sprediv1 = 2, bclk_ms2 = 16bits(32FS), I2Sprediv2 = 7, something reserved, dac/adc 128Fs */
- {ALC5658_I2S1_CTRL, 0x0000, 0}, /* Master, off/normal/I2S... 16bit */
- {ALC5658_007B, 0x0003, 0}, /* Select 64*FS for BCLK in master mode, No Info in documentation */
- {ALC5658_GNRL_CTRL, 0x0001, 0}, /* Enable Gate mode, Use(pass) Noise Gain Mode2 CTRL */
- {ALC5658_0091, 0x0C16, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_PWR_MNG3, 0xA23E, 60}, /* VREF1 on, fast VREF1, VREF2 on, fast VREF2, MBIAS on, LOUT off, MBIAS bandgap off, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG3, 0xF23E, 50}, /* VREF1 on, SLOW VREF1, VREF2 on, SLOW VREF2, MBIAS on, LOUT off, MBIAS bandgap off, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG2, 0x0400, 50}, /* pow_dac_stereo1_filter ON */
- {ALC5658_PWR_MNG1, 0x8080, 10}, /* en_i2s1, Pow_ldo_dacref ON */
- {ALC5658_ADC_2_DAC_MXR, 0x8080, 0}, /* Mu_stereo1_adc_mixer_l/r MUTE */
- {ALC5658_DAC_STR_MXR, 0xAAAA, 0}, /* Default, mute all */
- {ALC5658_DAC_SRC, 0x0000, 0}, /* Default, no mixers (direct) */
- {ALC5658_HP_AMP, 0x0009, 50}, /* en_out_hp - OFF, pow_pump_hp - ON, pow_capless - ON */
- {ALC5658_PWR_MNG1, 0x8C80, 50}, /* en_i2s1, pow_dac1_l/r, Pow_ldo_dacref - ON */
- {ALC5658_0091, 0x0E16, 50}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0040, 0x0505, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_PWR_MNG5, 0x0180, 0}, /* Does not match with documentation */
- {ALC5658_0x013C, 0x3C05, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DF, 0x02C1, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DF, 0x2CC1, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DE, 0x5100, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01E4, 0x0014, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DE, 0xD100, 30}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DF, 0x2CC1, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DE, 0x4900, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01E4, 0x0016, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DE, 0xC900, 250}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DF, 0x2CC1, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_HPOUT_MUTE, 0x0000, 0}, /* UNMUTE HP Output */
- {ALC5658_0x01DE, 0x4500, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01E4, 0x001F, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DE, 0xC500, 800}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0040, 0x0808, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_PWR_MNG5, 0x0000, 0}, /* Default, PLL, LDO2, Speaker VDD off */
- {ALC5658_0x013C, 0x2005, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01E4, 0x0000, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_0x01DF, 0x20C0, 0}, /* NO INFO IN DOCUMENTATION!!! */
- {ALC5658_ADDA_CLK, 0x0770, 0}, /* I2Sprediv1 = 2, bclk_ms2 = 16bits(32FS), I2Sprediv2 = 7, something reserved, dac/adc 128Fs */
- {ALC5658_GLBL_CLK, 0x0000, 0}, /* MCLK, No dividers */
- {ALC5658_NOISE_G_M2_CTRL, 0x8EC0, 0}, /* Stereo_noise_gate_mode2_en - ENABLE */
- {ALC5658_HP_AMP, 0x0019, 0}, /* en_out_hp - ON, pow_pump_hp - ON, pow_capless - ON */
- {ALC5658_NOISE_G_M1_CTRL1, 0xC0F0, 0}, /* Noise_gate_mode1_en, Noise_gate_mode1_auto_en - EN, Noise_gate_mode1_threshold -78dB, DOES NOT MATCH WITH DOCUMENTATION !!! */
- {ALC5658_NOISE_G_M1_CTRL1, 0x87F9, 0}, /* Blah blah blah, eventually enable Noise gate function >:( */
- {ALC5658_INTCLK_CTRL, 0x0180, 0}, /* Probably enable Pow_int_clk1/2, does not match with DOC !!! */
- {ALC5658_GNRL_CTRL2, 0x3000, 0}, /* Noise_gate_mode1/2_hp enable, DOES NOT MATCH WITH DOCUMENTATION */
-};
-
-t_codec_init_script_entry codec_initial_script[] = {
- {ALC5658_RESET, 0x0000, 0},
- {ALC5658_0111, 0xA502, 0},
- {ALC5658_ADDA_RST1, 0x3030, 0}, /* ??? DAC1, DAC2 + alpha clock enable */
- {ALC5658_006E, 0xEF00, 0},
- {ALC5658_006F, 0xEFFC, 0},
- {ALC5658_INTCLK_CTRL, 0x0280, 0}, /* ??? Enable ALL int CLK, even more than in documentation */
- {ALC5658_GLBL_CLK, 0x8000, 0}, /* RC CLK, No dividers */
- {ALC5658_I2S1_CTRL, 0x0000, 0}, /* Master, off/normal/I2S... 16bit */
- {ALC5658_ADDA_CLK, 0x1770, 0}, /* I2Sprediv1 = 2, bclk_ms2 = 16bits(32FS), I2Sprediv2 = 7, something reserved, dac/adc 128Fs */
- {ALC5658_0091, 0x0C16, 0},
- {ALC5658_PWR_MNG3, 0xAA7E, 60}, /* VREF1 on, fast VREF1, VREF2 on, fast VREF2, MBIAS on, LOUT off, MBIAS bandgap off, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG3, 0xFE7E, 50}, /* VREF1 on, SLOW VREF1, VREF2 on, SLOW VREF2, MBIAS on, LOUT off, MBIAS bandgap off, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG5, 0x0004, 0}, /* LDO2 ON */
- {ALC5658_PWR_MNG2, 0x0400, 50}, /* pow_dac_stereo1_filter ON */
- {ALC5658_PWR_MNG1, 0x0080, 10}, /* Pow_ldo_dacref ON */
- {ALC5658_ADC_2_DAC_MXR, 0x8080, 0}, /* Mu_stereo1_adc_mixer_l/r MUTE */
- {ALC5658_DAC_STR_MXR, 0xAAAA, 0}, /* Default, mute all */
- {ALC5658_DAC_SRC, 0x0000, 0}, /* Default, no mixers (direct) */
- {ALC5658_HP_AMP, 0x0009, 50}, /* en_out_hp - OFF, pow_pump_hp - ON, pow_capless - ON */
- {ALC5658_PWR_MNG1, 0x0F80, 50}, /* pow_dac1_l/r, pow_dac2_l/r, Pow_ldo_dacref - ON */
- {ALC5658_0091, 0x0E16, 50},
- {ALC5658_0040, 0x0505, 0},
- {ALC5658_PWR_MNG5, 0x0184, 0}, /* ???NonDescribed, LDO2 ON */
- {ALC5658_0x013C, 0x3C05, 0},
- {ALC5658_0x01DF, 0x2cc1, 6},
- {ALC5658_0x01DE, 0x5100, 6},
- {ALC5658_0x01E4, 0x0014, 6},
- {ALC5658_0x01DE, 0xd100, 30},
- {ALC5658_0x01DF, 0x20C1, 0},
- {ALC5658_0x01DF, 0x2CC1, 0},
- {ALC5658_0x01DE, 0x4900, 0},
- {ALC5658_0x01E4, 0x0016, 0},
- {ALC5658_0x01DE, 0xC900, 250},
- {ALC5658_0x01DF, 0x2CC1, 0},
- {ALC5658_HPOUT_MUTE, 0x0000, 0}, /* UNMUTE HP Output */
- {ALC5658_0x01DE, 0x4500, 0},
- {ALC5658_0x01E4, 0x001F, 0},
- {ALC5658_0x01DE, 0xC500, 600},
- {ALC5658_0x01E4, 0x0000, 0},
- {ALC5658_0x01DF, 0x20C0, 0},
- {ALC5658_0040, 0x0808, 0},
- {ALC5658_PWR_MNG5, 0x0000, 0}, /* LDO2 OFF */
- {ALC5658_0x013C, 0x2005, 0},
- {ALC5658_PWR_MNG6, 0x0000, 0}, /* MIXERs OFF */
- {ALC5658_PWR_MNG7, 0x0000, 0}, /* VOL Out/In ctrl, MIC in det OFF */
- {ALC5658_PWR_MNG1, 0x0000, 0}, /* I2S, DAC, ADC, SPDIFF, CLASS D OFF */
- {ALC5658_PWR_MNG2, 0x0000, 0}, /* Filters, PDM I/F OFF */
- {ALC5658_PWR_MNG3, 0x003C, 0}, /* HP L/R ON, HPamp x5, LDO1 out 0.9V */
- {ALC5658_GLBL_CLK, 0x0000, 0}, /* MCLK, No dividers */
- {ALC5658_ADDA_CLK, 0x0770, 0}, /* I2Sprediv1 = 2, bclk_ms2 = 16bits(32FS), I2Sprediv2 = 7, something reserved, dac/adc 128Fs */
- {ALC5658_INTCLK_CTRL, 0x0080, 0}, /* Probably enable Pow_int_clk1/2, does not match with DOC !!! */
-};
-
-t_codec_init_script_entry codec_init_out_script[] = {
- {ALC5658_RESET, 0x0000, 0},
- {ALC5658_006E, 0xFFFF, 0},
- {ALC5658_006F, 0xFFFF, 0},
- {ALC5658_GNRL_CTRL, 0x8001, 0}, /* Bypass_noise_gate_mode2 BYPASS, digital_gate_ctrl ENABLE */
- {ALC5658_ADDA_RST1, 0x3030, 0}, /* ??? DAC1, DAC2 + alpha clock enable */
- {ALC5658_GLBL_PLL1, 0x0302, 0}, /* k = 2, n = 8 */
- {ALC5658_GLBL_PLL2, 0x0800, 0}, /* m - bypass */
- {ALC5658_ADDA_CLK, 0x1110, 0}, /* I2Sprediv1 = 2, bclk_ms2 = 16bits(32FS), I2Sprediv2 = 2, something reserved, dac/adc 128Fs */
- {ALC5658_0091, 0x0C16, 0},
- {ALC5658_PWR_MNG3, 0xA23E, 20}, /* VREF1 on, fast VREF1, VREF2 on, fast VREF2, MBIAS on, LOUT off, MBIAS bandgap off, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG3, 0xF23E, 0}, /* VREF1 on, SLOW VREF1, VREF2 on, SLOW VREF2, MBIAS on, LOUT off, MBIAS bandgap off, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG5, 0x0040, 0}, /* LDO2 ON */
- {ALC5658_GLBL_CLK, 0x4000, 0}, /* PLL1, No dividers */
- {ALC5658_GLBL_ASRC4, 0x0100, 0}, /* sel_i2s2_asrc = ASRC2 */
- {ALC5658_GLBL_ASRC1, 0x1300, 0}, /* En_i2s2_asrc - EN, Sel_mono_dac_l/r_mode EN */
- {ALC5658_GLBL_ASRC2, 0x0220, 0}, /* sel_da_filter_monol_track = clk_i2s2_track, sel_da_filter_monor_track = clk_i2s2_track */
- {ALC5658_PWR_MNG1, 0xC080, 0}, /* en_i2s1/en_i2s2, Pow_ldo_dacref ON */
- {ALC5658_HP_AMP, 0x0009, 0}, /* en_out_hp - OFF, pow_pump_hp - ON, pow_capless - ON */
- {ALC5658_PWR_MNG1, 0xCC80, 0}, /* en_i2s1/en_i2s2, pow_dac1_l/r, Pow_ldo_dacref ON */
- {ALC5658_0091, 0x0E16, 0},
- {ALC5658_PWR_MNG2, 0x0700, 0}, /* pow_dac_stereo1_filter, pow_dac_monol/r_filter ON */
- {ALC5658_HPOUT_MUTE, 0x0000, 0}, /* OFF */
- {ALC5658_0091, 0x0E1E, 0},
- {ALC5658_006E, 0xFFFF, 0},
- {ALC5658_006F, 0xFFFF, 0},
- {ALC5658_I2S1_CTRL, 0x0000, 0}, //MASTER 32FS
- {ALC5658_DAC_STR_MXR, 0x2A8A, 0}, /* mu_stereo_dacl1_mixl, mu_stereo_dacr1_mixr unmute */
- {ALC5658_DAC_SRC, 0x000F, 0}, /* DAC1 stereo, DAC2 mono */
- {ALC5658_HP_AMP, 0x0019, 0}, /* en_out_hp - ON, pow_pump_hp - ON, pow_capless - ON */
- {ALC5658_TDM_CTRL2, 0x000C, 0}, //loopback
-};
-
-t_codec_init_script_entry codec_init_in_script[] = {
- {ALC5658_RESET, 0x0000, 0},
- {ALC5658_ADDA_RST1, 0x3030, 0}, /* ??? DAC1, DAC2 + alpha clock enable */
- {ALC5658_ADDA_RST2, 0x3030, 0}, /* ??? ADC1, ADC2 + alpha clock enable */
- {ALC5658_006E, 0xEF00, 0},
- {ALC5658_006F, 0xEFFC, 0},
- {ALC5658_I2S1_CTRL, 0x0000, 0}, /* Master, off/normal/I2S... 16bit */
- {ALC5658_GNRL_CTRL, 0x8001, 0}, /* Bypass_noise_gate_mode2 BYPASS, digital_gate_ctrl ENABLE */
- {ALC5658_ADDA_CLK, 0x0000, 0}, /* I2Sprediv1 = 1, bclk_ms2 = 16bits(32FS), I2Sprediv2 = 1, something reserved, dac/adc 128Fs */
- {ALC5658_PWR_MNG3, 0xA2BE, 50}, /* VREF1 on, fast VREF1, VREF2 on, fast VREF2, MBIAS on, LOUT off, MBIAS bandgap ON, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG3, 0xF2BE, 0}, /* VREF1 on, slow VREF1, VREF2 on, slow VREF2, MBIAS on, LOUT off, MBIAS bandgap ON, HP L/R ON, HPamp x5, LDO1 out 1.2V */
- {ALC5658_PWR_MNG1, 0x8098, 0}, /* en_i2s1, Pow_ldo_dacref, pow_adc1_l/r ON */
- {ALC5658_PWR_MNG1, 0x8C80, 0}, /* en_i2s1, pow_dac1_l/r Pow_ldo_dacref, pow_adc1_l/r ON */
- {ALC5658_0091, 0x0E16, 0},
- {ALC5658_PWR_MNG2, 0xB400, 0}, /* pow_adc_stereo1_filter, pow_adc_monol/r_filter, pow_dac_stereo1_filter ON */
- {ALC5658_0010, 0x3040, 0}, //CRT Mbias1 path
- {ALC5658_PWR_MNG4, 0xC860, 0}, //enable mbias1 /* pow_bst1, pow_bst2, pow_micbias1_digital, pow_bst1-2, pow_bst2-2 ON */
- {ALC5658_PWR_MNG1, 0x8C98, 0}, /* en_i2s1, pow_dac1_l/r, Pow_ldo_dacref, pow_adc1_l/r ON */
- {ALC5658_PWR_MNG6, 0x0C00, 0}, /* pow_recmix1l/r ON */
- {ALC5658_PWR_MNG7, 0x0300, 0}, /* ?extra bits set? pow_inl_vol ON */
- {ALC5658_IN1_CTRL, 0x3000, 0}, /* Gain -12dB + 0.75dB*0x30 */
- {ALC5658_RECMIX1L_CTRL_2, 0x005F, 0}, /* Default, all mute */
- {ALC5658_RECMIX1R_CTRL_2, 0x005F, 0}, /* Default, all mute */
- {ALC5658_ADC_STR1_MXR, 0x6020, 0}, /* mu_stereo1_adcl1 unmute, sel_stereo1_adc1 Sel, mu_stereo1_adcr1 unmute */
- {ALC5658_ADC_2_DAC_MXR, 0x0000, 100}, /* Mu_stereo1_adc_mixer_l/r unmute */
- {ALC5658_DAC_MONO_MXR, 0x2A8A, 0}, /* mu_mono_dacl1_mixl/r unmute */
- {ALC5658_ADC_MONO_MXR, 0x4040, 0}, /* mu_mono_adcl1 UM, sel_mono_adcl1/2 - Mono_DAC_Mixer_L, mu_mono_adcr1 UM, Sel_mono_adcr1/2 - Mono_DAC_Mixer_R, sel_mono_adcr - ADC1_L, Sel_mono_dmic_r - DMIC1_R */
- {ALC5658_DAC_SRC, 0x000F, 0}, /* DAC1 stereo, DAC2 mono */
- {ALC5658_TDM_CTRL1, 0x00F0, 0}, /* TDM IN/OUT 32bit LEN Applicable in master mode ??? */
- {ALC5658_TDM_CTRL2, 0x0000, 0}, /* rx_adc_data_sel - IF_ADC1 / IF_ADC2 / DAC_REF / Null */
-};
-
-t_codec_init_script_entry codec_init_inout_script1[] = {
- {ALC5658_RESET, 0x0000, 0},
- {ALC5658_006E, 0xEF00, 0},
- {ALC5658_006F, 0xEFFC, 0},
- {ALC5658_GNRL_CTRL, 0x8001, 0},
- {ALC5658_ADDA_RST1, 0x3030, 0},
- {ALC5658_ADDA_RST2, 0x3030, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_8K[] = {
- {ALC5658_GLBL_PLL1, 0x0302, 0},
- {ALC5658_GLBL_PLL2, 0x0800, 0},
- {ALC5658_ADDA_CLK, 0x6110, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_11K[] = {
- {ALC5658_GLBL_PLL1, 0x4883, 0},
- {ALC5658_GLBL_PLL2, 0xE000, 0},
- {ALC5658_ADDA_CLK, 0x5110, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_16K[] = {
- {ALC5658_GLBL_PLL1, 0x0302, 0},
- {ALC5658_GLBL_PLL2, 0x0800, 0},
- {ALC5658_ADDA_CLK, 0x4110, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_22K[] = {
- {ALC5658_GLBL_PLL1, 0x4883, 0},
- {ALC5658_GLBL_PLL2, 0xE000, 0},
- {ALC5658_ADDA_CLK, 0x3110, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_32K[] = {
- {ALC5658_GLBL_PLL1, 0x0302, 0},
- {ALC5658_GLBL_PLL2, 0x0800, 0},
- {ALC5658_ADDA_CLK, 0x2110, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_44K[] = {
- {ALC5658_GLBL_PLL1, 0x4883, 0},
- {ALC5658_GLBL_PLL2, 0xE000, 0},
- {ALC5658_ADDA_CLK, 0x1110, 0},
-};
-
-t_codec_init_script_entry codec_init_pll_48K[] = {
- {ALC5658_GLBL_PLL1, 0x0302, 0},
- {ALC5658_GLBL_PLL2, 0x0800, 0},
- {ALC5658_ADDA_CLK, 0x1110, 0},
-};
-
-t_codec_init_script_entry codec_init_inout_script2[] = {
- {ALC5658_0091, 0x0C16, 0},
- {ALC5658_PWR_MNG3, 0xA2BE, 20},
- {ALC5658_PWR_MNG3, 0xF2BE, 0},
- {ALC5658_PWR_MNG5, 0x0040, 0},
- {ALC5658_GLBL_CLK, 0x4000, 0},
- {ALC5658_GLBL_ASRC4, 0x0100, 0},
- {ALC5658_GLBL_ASRC1, 0x1300, 0},
- {ALC5658_GLBL_ASRC2, 0x0220, 0},
- {ALC5658_PWR_MNG1, 0xC080, 0},
- {ALC5658_HP_AMP, 0x0009, 0},
- {ALC5658_PWR_MNG1, 0xCC80, 0},
- {ALC5658_PWR_MNG1, 0xCC98, 0},
- {ALC5658_0091, 0x0E16, 0},
- {ALC5658_PWR_MNG2, 0xB700, 0},
- {ALC5658_PWR_MNG4, 0xC860, 0}, //enable mbias1
- {ALC5658_PWR_MNG6, 0x0C00, 0},
- {ALC5658_PWR_MNG7, 0x0300, 0},
- {ALC5658_HPOUT_MUTE, 0x8080, 0}, // MUTE OUTPUT
- {ALC5658_0091, 0x0E1E, 0},
- {ALC5658_I2S1_CTRL, 0x0000, 0},
- {ALC5658_DAC_STR_MXR, 0x2A8A, 0},
- {ALC5658_DAC_SRC, 0x000F, 0},
- {ALC5658_HP_AMP, 0x0019, 0},
- {ALC5658_0010, 0x3040, 0}, //CRT Mbias1 path
- {ALC5658_IN1_CTRL, 0x0000, 0}, //BST1 gain (minimal)
- {ALC5658_RECMIX1L_CTRL_2, 0x005F, 0}, //BST1
- {ALC5658_RECMIX1R_CTRL_2, 0x005F, 0}, //BST1
- {ALC5658_ADC_STR1_MXR, 0x6020, 0},
- {ALC5658_ADC_2_DAC_MXR, 0x8080, 100},
- {ALC5658_DAC_MONO_MXR, 0x2A8A, 0},
- {ALC5658_ADC_MONO_MXR, 0x4040, 0},
- {ALC5658_DAC_SRC, 0x000F, 0},
- {ALC5658_TDM_CTRL1, 0x00F0, 0},
- {ALC5658_TDM_CTRL2, 0x0000, 0},
-
-};
-
-t_codec_dump_entry codec_dump_script[] = {
- {ALC5658_RESET, "ALC5658_RESET"},
- {ALC5658_SPO_VOL, "ALC5658_SPO_VOL"},
- {ALC5658_HPOUT_MUTE, "ALC5658_HPOUT_MUTE"},
- {ALC5658_LOUT_CTRL1, "ALC5658_LOUT_CTRL1"},
- {ALC5658_LOUT_CTRL2, "ALC5658_LOUT_CTRL2"},
- {ALC5658_HPOUT_VLML, "ALC5658_HPOUT_VLML"},
- {ALC5658_HPOUT_VLMR, "ALC5658_HPOUT_VLMR"},
- {ALC5658_SPDIF_CTRL1, "ALC5658_SPDIF_CTRL1"},
- {ALC5658_SPDIF_CTRL2, "ALC5658_SPDIF_CTRL2"},
- {ALC5658_SPDIF_CTRL3, "ALC5658_SPDIF_CTRL3"},
- {ALC5658_IN1_CTRL, "ALC5658_IN1_CTRL"},
- {ALC5658_INL_VLM, "ALC5658_INL_VLM"},
- {ALC5658_SIDETONE, "ALC5658_SIDETONE"},
- {ALC5658_DAC_L1R1_VLM, "ALC5658_DAC_L1R1_VLM"},
- {ALC5658_DAC_L2R2_VLM, "ALC5658_DAC_L2R2_VLM"},
- {ALC5658_DAC_L2R2_MUTE, "ALC5658_DAC_L2R2_MUTE"},
- {ALC5658_ADC_STR1_MXR, "ALC5658_ADC_STR1_MXR"},
- {ALC5658_ADC_MONO_MXR, "ALC5658_ADC_MONO_MXR"},
- {ALC5658_ADC_2_DAC_MXR, "ALC5658_ADC_2_DAC_MXR"},
- {ALC5658_DAC_STR_MXR, "ALC5658_DAC_STR_MXR"},
- {ALC5658_DAC_MONO_MXR, "ALC5658_DAC_MONO_MXR"},
- {ALC5658_DAC_LB_SDTONE, "ALC5658_DAC_LB_SDTONE"},
- {ALC5658_COPY_MODE, "ALC5658_COPY_MODE"},
- {ALC5658_DAC_SRC, "ALC5658_DAC_SRC"},
- {ALC5658_RECMIX1L_CTRL_1, "ALC5658_RECMIX1L_CTRL_1"},
- {ALC5658_RECMIX1L_CTRL_2, "ALC5658_RECMIX1L_CTRL_2"},
- {ALC5658_RECMIX1R_CTRL_1, "ALC5658_RECMIX1R_CTRL_1"},
- {ALC5658_RECMIX1R_CTRL_2, "ALC5658_RECMIX1R_CTRL_2"},
- {ALC5658_SPKMIXL, "ALC5658_SPKMIXL"},
- {ALC5658_SPKMIXR, "ALC5658_SPKMIXR"},
- {ALC5658_SPOMIX, "ALC5658_SPOMIX"},
- {ALC5658_OUTMIXL1, "ALC5658_OUTMIXL1"},
- {ALC5658_OUTMIXL2, "ALC5658_OUTMIXL2"},
- {ALC5658_OUTMIXR1, "ALC5658_OUTMIXR1"},
- {ALC5658_OUTMIXR2, "ALC5658_OUTMIXR2"},
- {ALC5658_LOUTMIX, "ALC5658_LOUTMIX"},
- {ALC5658_PWR_MNG1, "ALC5658_PWR_MNG1"},
- {ALC5658_PWR_MNG2, "ALC5658_PWR_MNG2"},
- {ALC5658_PWR_MNG3, "ALC5658_PWR_MNG3"},
- {ALC5658_PWR_MNG4, "ALC5658_PWR_MNG4"},
- {ALC5658_PWR_MNG5, "ALC5658_PWR_MNG5"},
- {ALC5658_PWR_MNG6, "ALC5658_PWR_MNG6"},
- {ALC5658_PWR_MNG7, "ALC5658_PWR_MNG7"},
- {ALC5658_IF_DTCT, "ALC5658_IF_DTCT"},
- {ALC5658_006E, "ALC5658_006E"},
- {ALC5658_006F, "ALC5658_006F"},
- {ALC5658_I2S1_CTRL, "ALC5658_I2S1_CTRL"},
- {ALC5658_I2S2_CTRL, "ALC5658_I2S2_CTRL"},
- {ALC5658_ADDA_CLK, "ALC5658_ADDA_CLK"},
- {ALC5658_ADDA_HPF, "ALC5658_ADDA_HPF"},
- {ALC5658_007B, "ALC5658_007B"},
- {ALC5658_TDM_CTRL1, "ALC5658_TDM_CTRL1"},
- {ALC5658_TDM_CTRL2, "ALC5658_TDM_CTRL2"},
- {ALC5658_TDM_CTRL3, "ALC5658_TDM_CTRL3"},
- {ALC5658_TDM_CTRL4, "ALC5658_TDM_CTRL4"},
- {ALC5658_GLBL_CLK, "ALC5658_GLBL_CLK"},
- {ALC5658_GLBL_PLL1, "ALC5658_GLBL_PLL1"},
- {ALC5658_GLBL_PLL2, "ALC5658_GLBL_PLL2"},
- {ALC5658_GLBL_ASRC1, "ALC5658_GLBL_ASRC1"},
- {ALC5658_GLBL_ASRC2, "ALC5658_GLBL_ASRC2"},
- {ALC5658_GLBL_ASRC3, "ALC5658_GLBL_ASRC3"},
- {ALC5658_GLBL_ASRC4, "ALC5658_GLBL_ASRC4"},
- {ALC5658_HP_AMP, "ALC5658_HP_AMP"},
- {ALC5658_SPK_AMP, "ALC5658_SPK_AMP"},
- {ALC5658_0091, "ALC5658_0091"},
- {ALC5658_INTCLK_CTRL, "ALC5658_INTCLK_CTRL"},
- {ALC5658_GNRL_CTRL, "ALC5658_GNRL_CTRL"},
- {ALC5658_GNRL_CTRL2, "ALC5658_GNRL_CTRL2"},
- {ALC5658_0111, "ALC5658_0111"},
- {ALC5658_0125, "ALC5658_0125"},
- {ALC5658_ADDA_RST1, "ALC5658_ADDA_RST1"},
- {ALC5658_ADDA_RST2, "ALC5658_ADDA_RST2"},
- {ALC5658_0x013C, "ALC5658_0x013C"},
- {ALC5658_NOISE_G_M1_CTRL1, "ALC5658_NOISE_G_M1_CTRL1"},
- {ALC5658_NOISE_G_M2_CTRL, "ALC5658_NOISE_G_M2_CTRL"},
- {ALC5658_0x01DE, "ALC5658_0x01DE"},
- {ALC5658_0x01DF, "ALC5658_0x01DF"},
- {ALC5658_0x01E4, "ALC5658_0x01E4"},
- {ALC5658_0040, "ALC5658_0040"},
- {ALC5658_0010, "ALC5658_0010"},
-};
-
-/* Commonly defined and redefined macros */
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifdef CONFIG_ALC5658CHAR_CLKDEBUG
-extern const uint8_t g_sysclk_scaleb1[ALC5658CHAR_BCLK_MAXDIV + 1];
-extern const uint8_t g_fllratio[ALC5658CHAR_NFLLRATIO];
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: alc5658char_readreg
- *
- * Description
- * Read the specified 16-bit register from the ALC5658CHAR device.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_ALC5658CHAR_REGDUMP) || defined(CONFIG_ALC5658CHAR_CLKDEBUG)
-struct alc5658char_dev_s;
-uint16_t alc5658char_readreg(FAR struct alc5658char_dev_s *priv, uint16_t regaddr);
-#endif
-
-#endif /* CONFIG_AUDIO */
-#endif /* __DRIVERS_AUDIO_ALC5658CHAR_H */
+++ /dev/null
-
-/****************************************************************************
- *
- * Copyright 2017 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- *
- ****************************************************************************/
-/****************************************************************************
- * audio/audio.c
- *
- * Copyright (C) 2013 Ken Pettit. All rights reserved.
- * Author: Ken Pettit <pettitkd@gmail.com>
- *
- * 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 <tinyara/config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <tinyara/kmalloc.h>
-#include <tinyara/fs/fs.h>
-#include <tinyara/arch.h>
-#include <tinyara/audio/audio.h>
-#include <mqueue.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_AUDIO
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Debug ********************************************************************/
-/* Non-standard debug that may be enabled just for testing Audio */
-
-#ifndef AUDIO_MAX_DEVICE_PATH
-#define AUDIO_MAX_DEVICE_PATH 32
-#endif
-
-#ifndef CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO
-#define CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO 1
-#endif
-
-/****************************************************************************
- * Private Type Definitions
- ****************************************************************************/
-
-/* This structure describes the state of the upper half driver */
-
-struct audio_upperhalf_s {
- uint8_t crefs; /* The number of times the device has been opened */
- volatile bool started; /* True: playback is active */
- sem_t exclsem; /* Supports mutual exclusion */
- FAR struct audio_lowerhalf_s *dev; /* lower-half state */
- mqd_t usermq; /* User mode app's message queue */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int audio_open(FAR struct file *filep);
-static int audio_close(FAR struct file *filep);
-static ssize_t audio_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
-static ssize_t audio_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-#ifdef CONFIG_AUDIO_MULTI_SESSION
-static int audio_start(FAR struct audio_upperhalf_s *upper, FAR void *session);
-static void audio_callback(FAR void *priv, uint16_t reason, FAR struct ap_buffer_s *apb, uint16_t status, FAR void *session);
-#else
-static int audio_start(FAR struct audio_upperhalf_s *upper);
-static void audio_callback(FAR void *priv, uint16_t reason, FAR struct ap_buffer_s *apb, uint16_t status);
-#endif /* CONFIG_AUDIO_MULTI_SESSION */
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_audioops = {
- audio_open, /* open */
- audio_close, /* close */
- audio_read, /* read */
- audio_write, /* write */
- 0, /* seek */
- audio_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: audio_open
- *
- * Description:
- * This function is called whenever the Audio device is opened.
- *
- ************************************************************************************/
-
-static int audio_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct audio_upperhalf_s *upper = inode->i_private;
- uint8_t tmp;
- int ret;
-
- audinfo("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0) {
- ret = -errno;
- goto errout;
- }
-
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = upper->crefs + 1;
- if (tmp == 0) {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* Save the new open count on success */
-
- upper->crefs = tmp;
- upper->usermq = NULL;
- ret = OK;
-
-errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: audio_close
- *
- * Description:
- * This function is called when the Audio device is closed.
- *
- ************************************************************************************/
-
-static int audio_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct audio_upperhalf_s *upper = inode->i_private;
- int ret;
-
- audinfo("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0) {
- ret = -errno;
- goto errout;
- }
-
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (upper->crefs > 1) {
- upper->crefs--;
- } else {
- FAR struct audio_lowerhalf_s *lower = upper->dev;
-
- /* There are no more references to the port */
-
- upper->crefs = 0;
-
- /* Disable the Audio device */
-
- DEBUGASSERT(lower->ops->shutdown != NULL);
- audinfo("calling shutdown: %d\n");
-
- lower->ops->shutdown(lower);
- }
- ret = OK;
-
-//errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: audio_read
- *
- * Description:
- * A dummy read method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t audio_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct audio_upperhalf_s *upper = inode->i_private;
- FAR struct audio_lowerhalf_s *lower = upper->dev;
-
- /* TODO: Should we check permissions here? */
-
- /* Audio read operations get passed directly to the lower-level */
-
- if (lower->ops->read != NULL) {
- return lower->ops->read(lower, buffer, buflen);
- }
-
- return 0;
-}
-
-/************************************************************************************
- * Name: audio_write
- *
- * Description:
- * A dummy write method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t audio_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct audio_upperhalf_s *upper = inode->i_private;
- FAR struct audio_lowerhalf_s *lower = upper->dev;
-
- /* TODO: Should we check permissions here? */
-
- /* Audio write operations get passed directly to the lower-level */
-
- if (lower->ops->write != NULL) {
- return lower->ops->write(lower, buffer, buflen);
- }
-
- return 0;
-}
-
-/************************************************************************************
- * Name: audio_start
- *
- * Description:
- * Handle the AUDIOIOC_START ioctl command
- *
- ************************************************************************************/
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
-static int audio_start(FAR struct audio_upperhalf_s *upper, FAR void *session)
-#else
-static int audio_start(FAR struct audio_upperhalf_s *upper)
-#endif
-{
- FAR struct audio_lowerhalf_s *lower = upper->dev;
- int ret = OK;
-
- DEBUGASSERT(upper != NULL && lower->ops->start != NULL);
-
- /* Verify that the Audio is not already running */
-
- if (!upper->started) {
- /* Invoke the bottom half method to start the audio stream */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- ret = lower->ops->start(lower, session);
-#else
- ret = lower->ops->start(lower);
-#endif
-
- /* A return value of zero means that the audio stream was started
- * successfully.
- */
-
- if (ret == OK) {
- /* Indicate that the audio stream has started */
-
- upper->started = true;
- }
- }
-
- return ret;
-}
-
-/************************************************************************************
- * Name: audio_ioctl
- *
- * Description:
- * The standard ioctl method. This is where ALL of the Audio work is done.
- *
- ************************************************************************************/
-
-static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct audio_upperhalf_s *upper = inode->i_private;
- FAR struct audio_lowerhalf_s *lower = upper->dev;
- FAR struct audio_buf_desc_s *bufdesc;
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- FAR void *session;
-#endif
- int ret;
-
- audinfo("cmd: %d arg: %ld\n", cmd, arg);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0) {
- return ret;
- }
-
- /* Handle built-in ioctl commands */
-
- switch (cmd) {
- /* AUDIOIOC_GETCAPS - Get the audio device capabilities.
- *
- * ioctl argument: A pointer to the audio_caps_s structure.
- */
-
- case AUDIOIOC_GETCAPS: {
- FAR struct audio_caps_s *caps = (FAR struct audio_caps_s *)((uintptr_t) arg);
- DEBUGASSERT(lower->ops->getcaps != NULL);
-
- audinfo("AUDIOIOC_GETCAPS: Device=%d\n", caps->ac_type);
-
- /* Call the lower-half driver capabilities handler */
-
- ret = lower->ops->getcaps(lower, caps->ac_type, caps);
- }
- break;
-
- case AUDIOIOC_CONFIGURE: {
- FAR const struct audio_caps_desc_s *caps = (FAR const struct audio_caps_desc_s *)((uintptr_t) arg);
- DEBUGASSERT(lower->ops->configure != NULL);
-
- audinfo("AUDIOIOC_INITIALIZE: Device=%d\n", caps->caps.ac_type);
-
- /* Call the lower-half driver configure handler */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- ret = lower->ops->configure(lower, caps->session, &caps->caps);
-#else
- ret = lower->ops->configure(lower, &caps->caps);
-#endif
- }
- break;
-
- case AUDIOIOC_SHUTDOWN: {
- DEBUGASSERT(lower->ops->shutdown != NULL);
-
- audinfo("AUDIOIOC_SHUTDOWN\n");
-
- /* Call the lower-half driver initialize handler */
- ret = lower->ops->shutdown(lower);
- }
- break;
-
- /* AUDIOIOC_START - Start the audio stream. The AUDIOIOC_SETCHARACTERISTICS
- * command must have previously been sent.
- *
- * ioctl argument: Audio session
- */
-
- case AUDIOIOC_START: {
- audinfo("AUDIOIOC_START\n");
- DEBUGASSERT(lower->ops->start != NULL);
-
- /* Start the audio stream */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- session = (FAR void *)arg;
- ret = audio_start(upper, session);
-#else
- ret = audio_start(upper);
-#endif
- }
- break;
-
- /* AUDIOIOC_STOP - Stop the audio stream.
- *
- * ioctl argument: Audio session
- */
-
-#ifndef CONFIG_AUDIO_EXCLUDE_STOP
- case AUDIOIOC_STOP: {
- audinfo("AUDIOIOC_STOP\n");
- DEBUGASSERT(lower->ops->stop != NULL);
-
- if (upper->started) {
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- session = (FAR void *)arg;
- ret = lower->ops->stop(lower, session);
-#else
- ret = lower->ops->stop(lower);
-#endif
- upper->started = false;
- }
- }
- break;
-#endif /* CONFIG_AUDIO_EXCLUDE_STOP */
-
- /* AUDIOIOC_PAUSE - Pause the audio stream.
- *
- * ioctl argument: Audio session
- */
-
-#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
-
- case AUDIOIOC_PAUSE: {
- audinfo("AUDIOIOC_PAUSE\n");
- DEBUGASSERT(lower->ops->pause != NULL);
-
- if (upper->started) {
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- session = (FAR void *)arg;
- ret = lower->ops->pause(lower, session);
-#else
- ret = lower->ops->pause(lower);
-#endif
- }
- }
- break;
-
- /* AUDIOIOC_RESUME - Resume the audio stream.
- *
- * ioctl argument: Audio session
- */
-
- case AUDIOIOC_RESUME: {
- audinfo("AUDIOIOC_RESUME\n");
- DEBUGASSERT(lower->ops->resume != NULL);
-
- if (upper->started) {
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- session = (FAR void *)arg;
- ret = lower->ops->resume(lower, session);
-#else
- ret = lower->ops->resume(lower);
-#endif
- }
- }
- break;
-
-#endif /* CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME */
-
- /* AUDIOIOC_ALLOCBUFFER - Allocate an audio buffer
- *
- * ioctl argument: pointer to an audio_buf_desc_s structure
- */
-
- case AUDIOIOC_ALLOCBUFFER: {
- audinfo("AUDIOIOC_ALLOCBUFFER\n");
-
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
- if (lower->ops->allocbuffer) {
- ret = lower->ops->allocbuffer(lower, bufdesc);
- } else {
- /* Perform a simple kumm_malloc operation assuming 1 session */
-
- ret = apb_alloc(bufdesc);
- }
- }
- break;
-
- /* AUDIOIOC_FREEBUFFER - Free an audio buffer
- *
- * ioctl argument: pointer to an audio_buf_desc_s structure
- */
-
- case AUDIOIOC_FREEBUFFER: {
- audinfo("AUDIOIOC_FREEBUFFER\n");
-
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
- if (lower->ops->freebuffer) {
- ret = lower->ops->freebuffer(lower, bufdesc);
- } else {
- /* Perform a simple apb_free operation */
-
- DEBUGASSERT(bufdesc->u.pBuffer != NULL);
- apb_free(bufdesc->u.pBuffer);
- ret = sizeof(struct audio_buf_desc_s);
- }
- }
- break;
-
- /* AUDIOIOC_ENQUEUEBUFFER - Enqueue an audio buffer
- *
- * ioctl argument: pointer to an audio_buf_desc_s structure
- */
-
- case AUDIOIOC_ENQUEUEBUFFER: {
- audinfo("AUDIOIOC_ENQUEUEBUFFER\n");
-
- DEBUGASSERT(lower->ops->enqueuebuffer != NULL);
-
- bufdesc = (FAR struct audio_buf_desc_s *)arg;
- ret = lower->ops->enqueuebuffer(lower, bufdesc->u.pBuffer);
- }
- break;
-
- /* AUDIOIOC_REGISTERMQ - Register a client Message Queue
- *
- * TODO: This needs to have multi session support.
- */
-
- case AUDIOIOC_REGISTERMQ: {
- audinfo("AUDIOIOC_REGISTERMQ\n");
-
- upper->usermq = (mqd_t) arg;
- ret = OK;
- }
- break;
-
- /* AUDIOIOC_UNREGISTERMQ - Register a client Message Queue
- *
- * TODO: This needs to have multi session support.
- */
-
- case AUDIOIOC_UNREGISTERMQ: {
- audinfo("AUDIOIOC_UNREGISTERMQ\n");
-
- upper->usermq = NULL;
- ret = OK;
- }
- break;
-
- /* AUDIOIOC_RESERVE - Reserve a session with the driver
- *
- * ioctl argument - pointer to receive the session context
- */
-
- case AUDIOIOC_RESERVE: {
- audinfo("AUDIOIOC_RESERVE\n");
- DEBUGASSERT(lower->ops->reserve != NULL);
-
- /* Call lower-half to perform the reservation */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- ret = lower->ops->reserve(lower, (FAR void **)arg);
-#else
- ret = lower->ops->reserve(lower);
-#endif
- }
- break;
-
- /* AUDIOIOC_RESERVE - Reserve a session with the driver
- *
- * ioctl argument - pointer to receive the session context
- */
-
- case AUDIOIOC_RELEASE: {
- audinfo("AUDIOIOC_RELEASE\n");
- DEBUGASSERT(lower->ops->release != NULL);
-
- /* Call lower-half to perform the release */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- ret = lower->ops->release(lower, (FAR void *)arg);
-#else
- ret = lower->ops->release(lower);
-#endif
- }
- break;
-
- /* Any unrecognized IOCTL commands might be platform-specific ioctl commands */
-
- default: {
- audinfo("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(lower->ops->ioctl != NULL);
- ret = lower->ops->ioctl(lower, cmd, arg);
- }
- break;
- }
-
- sem_post(&upper->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: audio_dequeuebuffer
- *
- * Description:
- * Dequeues a previously enqueued Audio Pipeline Buffer.
- *
- * 1. The upper half driver calls the enqueuebuffer method, providing the
- * lower half driver with the ab_buffer to process.
- * 2. The lower half driver's enqueuebuffer will either processes the
- * buffer directly, or more likely add it to a queue for processing
- * by a background thread or worker task.
- * 3. When the lower half driver has completed processing of the enqueued
- * ab_buffer, it will call this routine to indicate processing of the
- * buffer is complete.
- * 4. When this routine is called, it will check if any threads are waiting
- * to enqueue additional buffers and "wake them up" for further
- * processing.
- *
- * Input parameters:
- * handle - This is the handle that was provided to the lower-half
- * start() method.
- * apb - A pointer to the previsously enqueued ap_buffer_s
- * status - Status of the dequeue operation
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * This function may be called from an interrupt handler.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
-static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper, FAR struct ap_buffer_s *apb, uint16_t status, FAR void *session)
-#else
-static inline void audio_dequeuebuffer(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 */
-
- if (upper->usermq != NULL) {
- msg.msgId = AUDIO_MSG_DEQUEUE;
- msg.u.pPtr = apb;
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- msg.session = session;
-#endif
- apb->flags |= AUDIO_APB_DEQUEUED;
- mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg), CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
- }
-}
-
-/****************************************************************************
- * Name: audio_complete
- *
- * Description:
- * Send an AUDIO_MSG_COMPLETE message to the client to indicate that the
- * active playback has completed. 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_complete(FAR struct audio_upperhalf_s *upper, FAR struct ap_buffer_s *apb, uint16_t status, FAR void *session)
-#else
-static inline void audio_complete(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.msgId = AUDIO_MSG_COMPLETE;
- msg.u.pPtr = NULL;
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- msg.session = session;
-#endif
- mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg), CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
- }
-}
-
-/****************************************************************************
- * Name: audio_callback
- *
- * Description:
- * Provides a callback interface for lower-half drivers to call to the
- * upper-half for buffer dequeueing, error reporting, etc.
- *
- * Input parameters:
- * priv - Private context data owned by the upper-half
- * reason - The reason code for the callback
- * apb - A pointer to the previsously enqueued ap_buffer_s
- * status - Status information associated with the callback
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * This function may be called from an interrupt handler.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
-static void audio_callback(FAR void *handle, uint16_t reason, FAR struct ap_buffer_s *apb, uint16_t status, FAR void *session)
-#else
-static void audio_callback(FAR void *handle, uint16_t reason, FAR struct ap_buffer_s *apb, uint16_t status)
-#endif
-{
- FAR struct audio_upperhalf_s *upper = (FAR struct audio_upperhalf_s *)handle;
-
- audinfo("Entry\n");
-
- /* Perform operation based on reason code */
-
- switch (reason) {
- case AUDIO_CALLBACK_DEQUEUE: {
- /* Call the dequeue routine */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- audio_dequeuebuffer(upper, apb, status, session);
-#else
- audio_dequeuebuffer(upper, apb, status);
-#endif
- break;
- }
-
- /* Lower-half I/O error occurred */
-
- case AUDIO_CALLBACK_IOERR: {
- }
- break;
-
- /* Lower-half driver has completed a playback */
-
- case AUDIO_CALLBACK_COMPLETE: {
- /* Send a complete message to the user if a message queue is registered */
-
-#ifdef CONFIG_AUDIO_MULTI_SESSION
- audio_complete(upper, apb, status, session);
-#else
- audio_complete(upper, apb, status);
-#endif
- }
- break;
-
- default: {
- auderr("ERROR: Unknown callback reason code %d\n", reason);
- break;
- }
- }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: audio_register
- *
- * Description:
- * This function binds an instance of a "lower half" audio driver with the
- * "upper half" Audio device and registers that device so that can be used
- * by application code.
- *
- * When this function is called, the "lower half" driver should be in the
- * reset state (as if the shutdown() method had already been called).
- *
- * Input parameters:
- * path - The full path to the driver to be registers in the tinyara pseudo-
- * filesystem. The recommended convention is to name Audio drivers
- * based on the function they provide, such as "/dev/pcm0", "/dev/mp31",
- * etc.
- * dev - A pointer to an instance of lower half audio driver. This instance
- * is bound to the Audio driver and must persists as long as the driver
- * persists.
- *
- * Returned Value:
- * Zero on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
-{
- FAR struct audio_upperhalf_s *upper;
- char path[AUDIO_MAX_DEVICE_PATH];
- static bool dev_audio_created = false;
-#ifndef CONFIG_AUDIO_CUSTOM_DEV_PATH
- FAR const char *devname = "/dev/audio";
-#elif !defined(CONFIG_AUDIO_DEV_ROOT)
- FAR const char *devname = CONFIG_AUDIO_DEV_PATH;
- FAR const char *ptr;
- FAR char *pathptr;
-#endif
-
- /* Allocate the upper-half data structure */
-
- upper = (FAR struct audio_upperhalf_s *)kmm_zalloc(sizeof(struct audio_upperhalf_s));
- if (!upper) {
- auderr("ERROR: Allocation failed\n");
- return -ENOMEM;
- }
-
- /* Initialize the Audio device structure (it was already zeroed by kmm_zalloc()) */
-
- sem_init(&upper->exclsem, 0, 1);
- upper->dev = dev;
-
-#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
-
-#ifdef CONFIG_AUDIO_DEV_ROOT
-
- /* This is the simple case ... No need to make a directory */
-
- strcpy(path, "/dev/");
- strcat(path, name);
-
-#else
- /* Ensure the path begins with "/dev" as we don't support placing device
- * anywhere but in the /dev directory
- */
-
- DEBUGASSERT(strncmp(devname, "/dev", 4) == 0);
-
- /* Create a /dev/audio directory. */
-
- if (!dev_audio_created) {
- /* Get path name after "/dev" */
-
- ptr = &devname[4];
- if (*ptr == '/') {
- ptr++;
- }
-
- strcpy(path, "/dev/");
- pathptr = &path[5];
-
- /* Do mkdir for each segment of the path */
-
- while (*ptr != '\0') {
- /* Build next path segment into path variable */
-
- while (*ptr != '/' && *ptr != '\0') {
- *pathptr++ = *ptr++;
- }
- *pathptr = '\0';
-
- /* Make this level of directory */
-
- mkdir(path, 0644);
-
- /* Check for another level */
-
- *pathptr++ = '/';
- if (*ptr == '/') {
- ptr++;
- }
- }
-
- /* Indicate we have created the audio dev path */
-
- dev_audio_created = true;
- }
-
- /* Now build the path for registration */
-
- strcpy(path, devname);
- if (devname[sizeof(devname) - 1] != '/') {
- strcat(path, "/");
- }
-
- strcat(path, name);
-
-#endif /* CONFIG_AUDIO_DEV_PATH=="/dev" */
-
-#else /* CONFIG_AUDIO_CUSTOM_DEV_PATH */
-
- /* Create a /dev/audio directory. */
-
- if (!dev_audio_created) {
- /* We don't check for error here because even if it fails, then
- * the register_driver call below will return an error condition
- * for us.
- */
-
- mkdir(devname, 0644);
- dev_audio_created = true;
- }
-
- /* Register the Audio device */
-
- memset(path, 0, AUDIO_MAX_DEVICE_PATH);
- strcpy(path, devname);
- strcat(path, "/");
- strncat(path, name, AUDIO_MAX_DEVICE_PATH - 11);
-#endif
-
- /* Give the lower-half a context to the upper half */
-
- dev->upper = audio_callback;
- dev->priv = upper;
-
- audinfo("Registering %s\n", path);
- return register_driver(path, &g_audioops, 0666, upper);
-}
-
-#endif /* CONFIG_AUDIO */
#define CONFIG_AUDIO_I2SCHAR_TXTIMEOUT 0
#endif
-#define i2serr printf
-#define i2sinfo printf
-
/* Device naming ************************************************************/
#define DEVNAME_FMT "/dev/i2schar%d"
#define DEVNAME_FMTLEN (12 + 3 + 1)
****************************************************************************/
static const struct file_operations i2schar_fops = {
- NULL, /* open */
- NULL, /* close */
+ NULL, /* open */
+ NULL, /* close */
i2schar_read, /* read */
i2schar_write, /* write */
- NULL, /* seek */
- NULL, /* ioctl */
+ NULL, /* seek */
+ NULL, /* ioctl */
#ifndef CONFIG_DISABLE_POLL
- NULL, /* poll */
+ NULL, /* poll */
#endif
};
#define i2cllvdbg(x...)
#endif
-
-
#ifdef CONFIG_NET_LWIP_DEBUG
#define lwipdbg(format, ...) dbg(format, ##__VA_ARGS__)
#define lwiplldbg(format, ...) lldbg(format, ##__VA_ARGS__)
#define audvdbg (void)
#define audllvdbg (void)
#endif
-
#endif /* CONFIG_CPP_HAVE_VARARGS */
+#ifdef CONFIG_DEBUG_AUDIO_ERROR
+#define auddbg dbg
+#define audlldbg lldbg
+#else
+#define auddbg (void)
+#define audlldbg (void)
+#endif
+
+#ifdef CONFIG_DEBUG_AUDIO_WARN
+#define audwdbg wdbg
+#define audllwdbg llwdbg
+#else
+#define audwdbg (void)
+#define audllwdbg (void)
+#endif
+
+#ifdef CONFIG_DEBUG_AUDIO_INFO
+#define audvdbg vdbg
+#define audllvdbg llvdbg
+#else
+#define audvdbg (void)
+#define audllvdbg (void)
+#endif
+
/* Buffer dumping macros do not depend on varargs */
#ifdef CONFIG_DEBUG
/* Helper macros ************************************************************/
-#define ALC5658_ATTACH(s, isr, arg) ((s)->attach(s, isr, arg))
-#define ALC5658_DETACH(s) ((s)->attach(s, NULL, NULL))
-#define ALC5658_ENABLE(s) ((s)->enable(s, true))
-#define ALC5658_DISABLE(s) ((s)->enable(s, false))
-#define ALC5658_RESTORE(s, e) ((s)->enable(s, e))
+#define ALC5658_ATTACH(s,isr,arg) ((s)->attach(s,isr,arg))
+#define ALC5658_DETACH(s) ((s)->attach(s,NULL,NULL))
+#define ALC5658_ENABLE(s) ((s)->enable(s,true))
+#define ALC5658_DISABLE(s) ((s)->enable(s,false))
+#define ALC5658_RESTORE(s,e) ((s)->enable(s,e))
/****************************************************************************
* Public Types
* including file.
*/
-#define alc5658_dump_registers(d, m)
+#define alc5658_dump_registers(d,m)
#endif
/****************************************************************************
* including file.
*/
-#define alc5658_clock_analysis(d, m)
+#define alc5658_clock_analysis(d,m)
#endif
#undef EXTERN
#ifdef CONFIG_AUDIO
-#define audinfo printf
-
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define AUDIO_ABP_CANDMA 0x0010 /* Set if the data is DMA'able */
#define AUDIO_ABP_STATIC 0x0020 /* Set if statically allocated */
#define AUDIO_ABP_ACTIVE 0x0040 /* Set if this buffer is still active.
- * A buffer could become inactive
- * if it is processed by an output
- * device or a processing device
- * that replaces it with an alternate
- * buffer as a result of some DSP
- * operation, etc.
- */
+ * A buffer could become inactive
+ * if it is processed by an output
+ * device or a processing device
+ * that replaces it with an alternate
+ * buffer as a result of some DSP
+ * operation, etc.
+ */
/* Standard Audio Message Queue message IDs */
/* This structure is used to describe the audio device capabilities */
struct audio_caps_s {
- uint8_t ac_len; /* Length of the structure */
- uint8_t ac_type; /* Capabilities (device) type */
- uint8_t ac_subtype; /* Capabilities sub-type, if needed */
- uint8_t ac_channels; /* Number of channels (1, 2, 5, 7) */
+ uint8_t ac_len; /* Length of the structure */
+ uint8_t ac_type; /* Capabilities (device) type */
+ uint8_t ac_subtype; /* Capabilities sub-type, if needed */
+ uint8_t ac_channels; /* Number of channels (1, 2, 5, 7) */
union { /* Audio data format(s) for this device */
uint8_t b[2];
} ac_format;
union {
- /* Device specific controls. For AUDIO_DEVICE_QUERY, */
- /* this field reports the device type supported */
- uint8_t b[4]; /* by this lower-half driver. */
+ /* Device specific controls. For AUDIO_DEVICE_QUERY, *//* this field reports the device type supported */
+ uint8_t b[4]; /* by this lower-half driver. */
uint16_t hw[2];
uint32_t w;
} ac_controls;
struct dq_entry_s dq_entry; /* Double linked queue entry */
struct audio_info_s i; /* The info for samples in this buffer */
#ifdef CONFIG_AUDIO_MULTI_SESSION
- FAR void *session; /* Associated session */
+ FAR void *session; /* Associated session */
#endif
apb_samp_t nmaxbytes; /* The maximum number of bytes */
- apb_samp_t nbytes; /* The number of bytes used */
- apb_samp_t curbyte; /* Next byte to be processed */
- sem_t sem; /* Reference locking semaphore */
- uint16_t flags; /* Buffer flags */
- uint16_t crefs; /* Number of reference counts */
- uint8_t samp[0]; /* Offset of the first sample */
-};
+ apb_samp_t nbytes; /* The number of bytes used */
+ apb_samp_t curbyte; /* Next byte to be processed */
+ sem_t sem; /* Reference locking semaphore */
+ uint16_t flags; /* Buffer flags */
+ uint16_t crefs; /* Number of reference counts */
+ uint8_t samp[0]; /* Offset of the first sample */
+} packed_struct;
/* Structure defining the messages passed to a listening audio thread
* for dequeuing buffers and other operations. Also used to allocate
*
****************************************************************************/
-#define I2S_RXSAMPLERATE(d, f) ((d)->ops->i2s_rxsamplerate(d, r))
+#define I2S_RXSAMPLERATE(d,f) ((d)->ops->i2s_rxsamplerate(d,r))
/****************************************************************************
* Name: I2S_RXDATAWIDTH
*
****************************************************************************/
-#define I2S_RXDATAWIDTH(d, b) ((d)->ops->i2s_rxdatawidth(d, b))
+#define I2S_RXDATAWIDTH(d,b) ((d)->ops->i2s_rxdatawidth(d,b))
/****************************************************************************
* Name: I2S_RECEIVE
*
****************************************************************************/
-#define I2S_RECEIVE(d, b, c, a, t) ((d)->ops->i2s_receive(d, b, c, a, t))
+#define I2S_RECEIVE(d,b,c,a,t) ((d)->ops->i2s_receive(d,b,c,a,t))
/****************************************************************************
* Name: I2S_TXSAMPLERATE
*
****************************************************************************/
-#define I2S_TXSAMPLERATE(d, f) ((d)->ops->i2s_txsamplerate(d, r))
+#define I2S_TXSAMPLERATE(d,f) ((d)->ops->i2s_txsamplerate(d,r))
/****************************************************************************
* Name: I2S_TXDATAWIDTH
*
****************************************************************************/
-#define I2S_TXDATAWIDTH(d, b) ((d)->ops->i2s_txdatawidth(d, b))
+#define I2S_TXDATAWIDTH(d,b) ((d)->ops->i2s_txdatawidth(d,b))
/****************************************************************************
* Name: I2S_SEND
*
****************************************************************************/
-#define I2S_SEND(d, b, c, a, t) ((d)->ops->i2s_send(d, b, c, a, t))
+#define I2S_SEND(d,b,c,a,t) ((d)->ops->i2s_send(d,b,c,a,t))
/****************************************************************************
* Public Types
#define _CAIOCBASE (0x0d00) /* CDC/ACM ioctl commands */
#define _BATIOCBASE (0x0e00) /* Battery driver ioctl commands */
#define _QEIOCBASE (0x0f00) /* Quadrature encoder ioctl commands */
-#define _AUDIOIOCBASE (0x1000) /* Audio ioctl commands */
#define _AUDIOIOCBASE (0x1000) /* Audio ioctl commands */
#define _SLCDIOCBASE (0x1100) /* Segment LCD ioctl commands */
#define _WLIOCBASE (0x1200) /* Wireless modules ioctl commands */
#define _QEIOCVALID(c) (_IOC_TYPE(c) == _QEIOCBASE)
#define _QEIOC(nr) _IOC(_QEIOCBASE, nr)
-/* Tinyara Audio driver ioctl definitions (see tinyara/audio/audio.h)*************************/
+/* Audio driver ioctl definitions *************************************/
+/* (see tinyara/audio/audio.h) */
#define _AUDIOIOCVALID(c) (_IOC_TYPE(c)==_AUDIOIOCBASE)
#define _AUDIOIOC(nr) _IOC(_AUDIOIOCBASE,nr)