STM32F4: add cs43l22 audio driver and i2s driver
This commit is contained in:
parent
679a08e371
commit
4ab2a3661e
arch/arm/src/stm32
configs/stm32f4discovery
drivers/audio
include/nuttx/audio
@ -1530,6 +1530,7 @@ config STM32_STM32F40XX
|
||||
select STM32_HAVE_TIM4
|
||||
select STM32_HAVE_SPI2
|
||||
select STM32_HAVE_SPI3
|
||||
select STM32_HAVE_I2S3
|
||||
select STM32_HAVE_I2C2
|
||||
select STM32_HAVE_I2C3
|
||||
|
||||
@ -1542,6 +1543,9 @@ config STM32_STM32F401
|
||||
select STM32_HAVE_TIM9
|
||||
select STM32_HAVE_TIM10
|
||||
select STM32_HAVE_TIM11
|
||||
select STM32_HAVE_SPI2
|
||||
select STM32_HAVE_SPI3
|
||||
select STM32_HAVE_I2S3
|
||||
|
||||
config STM32_STM32F410
|
||||
bool
|
||||
@ -1563,6 +1567,9 @@ config STM32_STM32F411
|
||||
select STM32_HAVE_TIM9
|
||||
select STM32_HAVE_TIM10
|
||||
select STM32_HAVE_TIM11
|
||||
select STM32_HAVE_SPI2
|
||||
select STM32_HAVE_SPI3
|
||||
select STM32_HAVE_I2S3
|
||||
select STM32_HAVE_SPI4
|
||||
select STM32_HAVE_SPI5
|
||||
|
||||
@ -1655,6 +1662,9 @@ config STM32_STM32F427
|
||||
select STM32_HAVE_DAC2
|
||||
select STM32_HAVE_RNG
|
||||
select STM32_HAVE_ETHMAC
|
||||
select STM32_HAVE_SPI2
|
||||
select STM32_HAVE_SPI3
|
||||
select STM32_HAVE_I2S3
|
||||
select STM32_HAVE_SPI4
|
||||
select STM32_HAVE_SPI5
|
||||
select STM32_HAVE_SPI6
|
||||
@ -1691,6 +1701,9 @@ config STM32_STM32F429
|
||||
select STM32_HAVE_DAC2
|
||||
select STM32_HAVE_RNG
|
||||
select STM32_HAVE_ETHMAC
|
||||
select STM32_HAVE_SPI2
|
||||
select STM32_HAVE_SPI3
|
||||
select STM32_HAVE_I2S3
|
||||
select STM32_HAVE_SPI4
|
||||
select STM32_HAVE_SPI5
|
||||
select STM32_HAVE_SPI6
|
||||
@ -2016,6 +2029,10 @@ config STM32_HAVE_SPI3
|
||||
bool
|
||||
default n
|
||||
|
||||
config STM32_HAVE_I2S3
|
||||
bool
|
||||
default n
|
||||
|
||||
config STM32_HAVE_SPI4
|
||||
bool
|
||||
default n
|
||||
@ -2353,6 +2370,13 @@ config STM32_SPI3
|
||||
select SPI
|
||||
select STM32_SPI
|
||||
|
||||
config STM32_I2S3
|
||||
bool "I2S3"
|
||||
default n
|
||||
depends on STM32_HAVE_I2S3
|
||||
select I2S
|
||||
select STM32_I2S
|
||||
|
||||
config STM32_SPI4
|
||||
bool "SPI4"
|
||||
default n
|
||||
@ -2610,6 +2634,11 @@ config STM32_SPI3_REMAP
|
||||
default n
|
||||
depends on STM32_STM32F10XX && STM32_SPI3 && !STM32_VALUELINE
|
||||
|
||||
config STM32_I2S3_REMAP
|
||||
bool "I2S3 Alternate Pin Mapping"
|
||||
default n
|
||||
depends on STM32_STM32F10XX && STM32_I2S3 && !STM32_VALUELINE
|
||||
|
||||
choice
|
||||
prompt "TIM1 Alternate Pin Mappings"
|
||||
depends on STM32_STM32F10XX && STM32_TIM1
|
||||
@ -6270,6 +6299,66 @@ config STM32_SPI_DMA
|
||||
|
||||
endmenu
|
||||
|
||||
menu "I2S Configuration"
|
||||
depends on STM32_I2S3
|
||||
|
||||
config STM32_I2S_MCK
|
||||
bool "I2S_MCK"
|
||||
default n
|
||||
---help---
|
||||
TBD.
|
||||
|
||||
config STM32_I2S_MAXINFLIGHT
|
||||
int "I2S queue size"
|
||||
default 16
|
||||
---help---
|
||||
This is the total number of transfers, both RX and TX, that can be
|
||||
enqueue before the caller is required to wait. This setting
|
||||
determines the number certain queue data structures that will be
|
||||
pre-allocated.
|
||||
|
||||
comment "I2S3 Configuration"
|
||||
|
||||
config STM32_I2S3_DATALEN
|
||||
int "Data width (bits)"
|
||||
default 16
|
||||
---help---
|
||||
Data width in bits. This is a default value and may be change
|
||||
via the I2S interface
|
||||
|
||||
#if STM32_I2S
|
||||
config STM32_I2S3_RX
|
||||
bool "Enable I2C receiver"
|
||||
default n
|
||||
---help---
|
||||
Enable I2S receipt logic
|
||||
|
||||
config STM32_I2S3_TX
|
||||
bool "Enable I2C transmitter"
|
||||
default n
|
||||
---help---
|
||||
Enable I2S transmission logic
|
||||
|
||||
config STM32_I2S_DMADEBUG
|
||||
bool "I2S DMA transfer debug"
|
||||
depends on DEBUG_DMA
|
||||
default n
|
||||
---help---
|
||||
Enable special debug instrumentation analyze I2S DMA data transfers.
|
||||
This logic is as non-invasive as possible: It samples DMA
|
||||
registers at key points in the data transfer and then dumps all of
|
||||
the registers at the end of the transfer.
|
||||
|
||||
config STM32_I2S_REGDEBUG
|
||||
bool "SSC Register level debug"
|
||||
depends on DEBUG
|
||||
default n
|
||||
---help---
|
||||
Output detailed register-level SSC device debug information.
|
||||
Very invasive! Requires also DEBUG.
|
||||
|
||||
endmenu # I2S Configuration
|
||||
|
||||
menu "I2C Configuration"
|
||||
depends on STM32_I2C
|
||||
|
||||
|
@ -101,7 +101,7 @@ CHIP_ASRCS =
|
||||
CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c
|
||||
CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c
|
||||
CHIP_CSRCS += stm32_irq.c stm32_dma.c stm32_lowputc.c
|
||||
CHIP_CSRCS += stm32_serial.c stm32_spi.c stm32_sdio.c stm32_tim.c
|
||||
CHIP_CSRCS += stm32_serial.c stm32_spi.c stm32_i2s.c stm32_sdio.c stm32_tim.c
|
||||
CHIP_CSRCS += stm32_waste.c stm32_ccm.c stm32_uid.c stm32_capture.c
|
||||
|
||||
ifeq ($(CONFIG_TIMER),y)
|
||||
|
@ -615,7 +615,7 @@
|
||||
#endif
|
||||
|
||||
#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4)
|
||||
#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11)
|
||||
#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7)
|
||||
#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5)
|
||||
#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12)
|
||||
#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15)
|
||||
|
2658
arch/arm/src/stm32/stm32_i2s.c
Normal file
2658
arch/arm/src/stm32/stm32_i2s.c
Normal file
File diff suppressed because it is too large
Load Diff
90
arch/arm/src/stm32/stm32_i2s.h
Normal file
90
arch/arm/src/stm32/stm32_i2s.h
Normal file
@ -0,0 +1,90 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/stm32/stm32_i2s.h
|
||||
*
|
||||
* Copyright (C) 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 __ARCH_ARM_SRC_STM32_I2S_H
|
||||
#define __ARCH_ARM_SRC_STM32_I2S_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/audio/i2s.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "chip/stm32_i2s.h"
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Function Prototypes
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_i2sdev_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the selected I2S port
|
||||
*
|
||||
* Input Parameter:
|
||||
* Port number (for hardware that has mutiple I2S interfaces)
|
||||
*
|
||||
* Returned Value:
|
||||
* Valid I2S device structure reference on succcess; a NULL on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
FAR struct i2s_dev_s *stm32_i2sdev_initialize(int port);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_ARM_SRC_STM32_I2S_H */
|
@ -300,9 +300,9 @@
|
||||
|
||||
/* SPI - There is a MEMS device on SPI1 using these pins: */
|
||||
|
||||
#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1
|
||||
#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1
|
||||
#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1
|
||||
#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1
|
||||
#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1
|
||||
#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1
|
||||
|
||||
/* SPI2 - Test MAX31855 on SPI2 PB10 = SCK, PB14 = MISO */
|
||||
|
||||
@ -310,10 +310,38 @@
|
||||
#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1
|
||||
#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1
|
||||
|
||||
/* SPI3 - Onboard devices use SPI3 */
|
||||
|
||||
#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2
|
||||
#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_2
|
||||
#define GPIO_SPI3_SCK GPIO_SPI3_SCK_2
|
||||
#define GPIO_SPI3_NSS GPIO_SPI3_NSS_2
|
||||
|
||||
/* I2S3 - Onboard devices use I2S3 */
|
||||
|
||||
#define GPIO_I2S3_SD GPIO_I2S3_SD_2
|
||||
#define GPIO_I2S3_CK GPIO_I2S3_CK_2
|
||||
#define GPIO_I2S3_WS GPIO_I2S3_WS_1
|
||||
|
||||
#define DMACHAN_SPI3_RX DMAMAP_SPI3_RX_2
|
||||
#define DMACHAN_SPI3_TX DMAMAP_SPI3_TX_2
|
||||
|
||||
/* I2C config to use with Nunchuk PB7 (SDA) and PB8 (SCL) */
|
||||
|
||||
#if 0
|
||||
#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2
|
||||
#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1
|
||||
#endif
|
||||
|
||||
/* I2C. Only I2C1 is available on the stm32f4discovery. I2C1_SCL and I2C1_SDA are
|
||||
* available on the following pins:
|
||||
*
|
||||
* - PB6 is I2C1_SCL
|
||||
* - PB9 is I2C1_SDA
|
||||
*/
|
||||
|
||||
#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1
|
||||
#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2
|
||||
|
||||
/* Timer Inputs/Outputs (see the README.txt file for options) */
|
||||
|
||||
|
@ -44,6 +44,10 @@ else
|
||||
CSRCS += stm32_userleds.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_CS43L22),y)
|
||||
CSRCS += stm32_cs43l22.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_BUTTONS),y)
|
||||
CSRCS += stm32_buttons.c
|
||||
endif
|
||||
|
@ -216,6 +216,16 @@ int stm32_bringup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CS43L22
|
||||
/* Configure CS43L22 audio */
|
||||
|
||||
ret = stm32_cs43l22_initialize(1);
|
||||
if (ret != OK)
|
||||
{
|
||||
serr("Failed to initialize CS43L22 audio: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ELF
|
||||
/* Initialize the ELF binary loader */
|
||||
|
||||
|
389
configs/stm32f4discovery/src/stm32_cs43l22.c
Normal file
389
configs/stm32f4discovery/src/stm32_cs43l22.c
Normal file
@ -0,0 +1,389 @@
|
||||
/************************************************************************************
|
||||
* configs/stm32f4discovery/src/stm32_cs43l22.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Taras Drozdovskiy <t.drozdovskiy@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 <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/audio/i2s.h>
|
||||
#include <nuttx/audio/pcm.h>
|
||||
#include <nuttx/audio/cs43l22.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "stm32.h"
|
||||
#include "stm32f4discovery.h"
|
||||
|
||||
#ifdef HAVE_CS43L22
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32_mwinfo_s
|
||||
{
|
||||
/* Standard CS43L22 interface */
|
||||
|
||||
struct cs43l22_lower_s lower;
|
||||
|
||||
/* Extensions for the stm32f4discovery board */
|
||||
|
||||
cs43l22_handler_t handler;
|
||||
FAR void *arg;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* IRQ/PIO access callbacks. These operations all hidden behind
|
||||
* callbacks to isolate the CS43L22 driver from differences in PIO
|
||||
* interrupt handling by varying boards and MCUs. If possible,
|
||||
* interrupts should be configured on both rising and falling edges
|
||||
* so that contact and loss-of-contact events can be detected.
|
||||
*
|
||||
* attach - Attach the CS43L22 interrupt handler to the PIO interrupt
|
||||
* enable - Enable or disable the PIO interrupt
|
||||
*/
|
||||
|
||||
static int cs43l22_attach(FAR const struct cs43l22_lower_s *lower,
|
||||
cs43l22_handler_t isr, FAR void *arg);
|
||||
static bool cs43l22_enable(FAR const struct cs43l22_lower_s *lower,
|
||||
bool enable);
|
||||
static void cs43l22_hw_reset(FAR const struct cs43l22_lower_s *lower);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* A reference to a structure of this type must be passed to the CS43L22
|
||||
* driver. This structure provides information about the configuration
|
||||
* of the CS43L22 and provides some board-specific hooks.
|
||||
*
|
||||
* Memory for this structure is provided by the caller. It is not copied
|
||||
* by the driver and is presumed to persist while the driver is active.
|
||||
*/
|
||||
|
||||
#define CONFIG_STM32_CS43L22_I2CFREQUENCY 100000
|
||||
#define BOARD_MAINCK_FREQUENCY 8000000
|
||||
|
||||
static struct stm32_mwinfo_s g_cs43l22info =
|
||||
{
|
||||
.lower =
|
||||
{
|
||||
.address = CS43L22_I2C_ADDRESS,
|
||||
.frequency = CONFIG_STM32_CS43L22_I2CFREQUENCY,
|
||||
#ifdef CONFIG_STM32_CS43L22_SRCSCK
|
||||
.mclk = BOARD_SLOWCLK_FREQUENCY,
|
||||
#else
|
||||
.mclk = BOARD_MAINCK_FREQUENCY,
|
||||
#endif
|
||||
.attach = cs43l22_attach,
|
||||
.enable = cs43l22_enable,
|
||||
.reset = cs43l22_hw_reset,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* IRQ/PIO access callbacks. These operations all hidden behind
|
||||
* callbacks to isolate the CS43L22 driver from differences in PIO
|
||||
* interrupt handling by varying boards and MCUs. If possible,
|
||||
* interrupts should be configured on both rising and falling edges
|
||||
* so that contact and loss-of-contact events can be detected.
|
||||
*
|
||||
* attach - Attach the CS43L22 interrupt handler to the PIO interrupt
|
||||
* enable - Enable or disable the PIO interrupt
|
||||
* clear - Acknowledge/clear any pending PIO interrupt
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int cs43l22_attach(FAR const struct cs43l22_lower_s *lower,
|
||||
cs43l22_handler_t isr, FAR void *arg)
|
||||
{
|
||||
if (isr)
|
||||
{
|
||||
/* Just save the address of the handler and its argument for now. The
|
||||
* new handler will called via cs43l22_interrupt() when the interrupt occurs.
|
||||
*/
|
||||
|
||||
audinfo("Attaching %p\n", isr);
|
||||
g_cs43l22info.handler = isr;
|
||||
g_cs43l22info.arg = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
audinfo("Detaching %p\n", g_cs43l22info.handler);
|
||||
(void)cs43l22_enable(lower, false);
|
||||
g_cs43l22info.handler = NULL;
|
||||
g_cs43l22info.arg = NULL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static bool cs43l22_enable(FAR const struct cs43l22_lower_s *lower, bool enable)
|
||||
{
|
||||
static bool enabled;
|
||||
irqstate_t flags;
|
||||
bool ret;
|
||||
|
||||
/* Has the interrupt state changed */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (enable != enabled)
|
||||
{
|
||||
/* Enable or disable interrupts */
|
||||
|
||||
if (enable && g_cs43l22info.handler)
|
||||
{
|
||||
audinfo("Enabling\n");
|
||||
/* TODO: stm32_pioirqenable(IRQ_INT_CS43L22); */
|
||||
enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
audinfo("Disabling\n");
|
||||
/* TODO: stm32_pioirqdisable(IRQ_INT_CS43L22); */
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
ret = enabled;
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int cs43l22_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
Just forward the interrupt to the CS43L22 driver
|
||||
|
||||
audinfo("handler %p\n", g_cs43l22info.handler);
|
||||
if (g_cs43l22info.handler)
|
||||
{
|
||||
return g_cs43l22info.handler(&g_cs43l22info.lower, g_cs43l22info.arg);
|
||||
}
|
||||
|
||||
We got an interrupt with no handler. This should not
|
||||
happen.
|
||||
|
||||
TODO: stm32_pioirqdisable(IRQ_INT_CS43L22);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cs43l22_hw_reset(FAR const struct cs43l22_lower_s *lower)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reset the codec */
|
||||
|
||||
stm32_gpiowrite(GPIO_CS43L22_RESET, false);
|
||||
for (i = 0; i < 0x4fff; i++)
|
||||
{
|
||||
__asm__ volatile("nop");
|
||||
}
|
||||
|
||||
stm32_gpiowrite(GPIO_CS43L22_RESET, true);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_cs43l22_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function is called by platform-specific, setup logic to configure
|
||||
* and register the CS43L22 device. This function will register the driver
|
||||
* as /dev/audio/pcm[x] where x is determined by the minor device number.
|
||||
*
|
||||
* Input Parameters:
|
||||
* minor - The input device minor number
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stm32_cs43l22_initialize(int minor)
|
||||
{
|
||||
FAR struct audio_lowerhalf_s *cs43l22;
|
||||
FAR struct audio_lowerhalf_s *pcm;
|
||||
FAR struct i2c_master_s *i2c;
|
||||
FAR struct i2s_dev_s *i2s;
|
||||
static bool initialized = false;
|
||||
char devname[12];
|
||||
int ret;
|
||||
|
||||
audinfo("minor %d\n", minor);
|
||||
DEBUGASSERT(minor >= 0 && minor <= 25);
|
||||
|
||||
/* Have we already initialized? Since we never uninitialize we must prevent
|
||||
* multiple initializations. This is necessary, for example, when the
|
||||
* touchscreen example is used as a built-in application in NSH and can be
|
||||
* called numerous time. It will attempt to initialize each time.
|
||||
*/
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
stm32_configgpio(GPIO_CS43L22_RESET);
|
||||
|
||||
/* Configure the CS43L22 interrupt pin */
|
||||
|
||||
/* TODO: (void)stm32_configgpio(PIO_INT_CS43L22); */
|
||||
|
||||
/* Get an instance of the I2C interface for the CS43L22 chip select */
|
||||
|
||||
i2c = stm32_i2cbus_initialize(CS43L22_I2C_BUS);
|
||||
if (!i2c)
|
||||
{
|
||||
auderr("ERROR: Failed to initialize TWI%d\n", CS43L22_I2C_BUS);
|
||||
ret = -ENODEV;
|
||||
goto errout;
|
||||
}
|
||||
/* Get an instance of the I2S interface for the CS43L22 data channel */
|
||||
|
||||
i2s = stm32_i2sdev_initialize(CS43L22_I2S_BUS);
|
||||
if (!i2s)
|
||||
{
|
||||
auderr("ERROR: Failed to initialize I2S%d\n", CS43L22_I2S_BUS);
|
||||
ret = -ENODEV;
|
||||
goto errout_with_i2c;
|
||||
}
|
||||
|
||||
/* Configure the DAC master clock. This clock is provided by PCK2 (PB10)
|
||||
* that is connected to the CS43L22 MCLK.
|
||||
*/
|
||||
|
||||
/* Configure CS43L22 interrupts */
|
||||
|
||||
#if 0 /* TODO: */
|
||||
stm32_pioirq(PIO_INT_CS43L22);
|
||||
ret = irq_attach(IRQ_INT_CS43L22, cs43l22_interrupt);
|
||||
if (ret < 0)
|
||||
{
|
||||
auderr("ERROR: Failed to attach CS43L22 interrupt: %d\n", ret);
|
||||
goto errout_with_i2s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now we can use these I2C and I2S interfaces to initialize the
|
||||
* CS43L22 which will return an audio interface.
|
||||
*/
|
||||
|
||||
cs43l22 = cs43l22_initialize(i2c, i2s, &g_cs43l22info.lower);
|
||||
if (!cs43l22)
|
||||
{
|
||||
auderr("ERROR: Failed to initialize the CS43L22\n");
|
||||
ret = -ENODEV;
|
||||
goto errout_with_irq;
|
||||
}
|
||||
/* No we can embed the CS43L22/I2C/I2S conglomerate into a PCM decoder
|
||||
* instance so that we will have a PCM front end for the the CS43L22
|
||||
* driver.
|
||||
*/
|
||||
|
||||
pcm = pcm_decode_initialize(cs43l22);
|
||||
if (!pcm)
|
||||
{
|
||||
auderr("ERROR: Failed create the PCM decoder\n");
|
||||
ret = -ENODEV;
|
||||
goto errout_with_cs43l22;
|
||||
}
|
||||
/* Create a device name */
|
||||
|
||||
snprintf(devname, 12, "pcm%d", minor);
|
||||
|
||||
/* Finally, we can register the PCM/CS43L22/I2C/I2S audio device.
|
||||
*
|
||||
* Is anyone young enough to remember Rube Goldberg?
|
||||
*/
|
||||
|
||||
ret = audio_register(devname, pcm);
|
||||
if (ret < 0)
|
||||
{
|
||||
auderr("ERROR: Failed to register /dev/%s device: %d\n",
|
||||
devname, ret);
|
||||
goto errout_with_pcm;
|
||||
}
|
||||
|
||||
/* Now we are initialized */
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
/* Error exits. Unfortunately there is no mechanism in place now to
|
||||
* recover resources from most errors on initialization failures.
|
||||
*/
|
||||
|
||||
errout_with_pcm:
|
||||
errout_with_cs43l22:
|
||||
errout_with_irq:
|
||||
|
||||
#if 0
|
||||
irq_detach(IRQ_INT_CS43L22);
|
||||
errout_with_i2s:
|
||||
#endif
|
||||
|
||||
errout_with_i2c:
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CS43L22 */
|
@ -77,6 +77,7 @@
|
||||
#define HAVE_USBHOST 1
|
||||
#define HAVE_USBMONITOR 1
|
||||
#define HAVE_SDIO 1
|
||||
#define HAVE_CS43L22 1
|
||||
#define HAVE_RTC_DRIVER 1
|
||||
#define HAVE_ELF 1
|
||||
#define HAVE_NETMONITOR 1
|
||||
@ -148,6 +149,26 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The CS43L22 depends on the CS43L22 driver, I2C1, and I2S3 support */
|
||||
|
||||
#if !defiend(CONFIG_AUDIO_CS43L22) || !defined(CONFIG_STM32_I2C1) || \
|
||||
!defined(CONFIG_STM32_I2S3)
|
||||
# undef HAVE_CS43L22
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CS43L22
|
||||
/* The CS43L22 communicates on I2C1, I2C address 0x1a for control
|
||||
* operations
|
||||
*/
|
||||
|
||||
# define CS43L22_I2C_BUS 1
|
||||
# define CS43L22_I2C_ADDRESS (0x94 >> 1)
|
||||
|
||||
/* The CS43L22 transfers data on I2S3 */
|
||||
|
||||
# define CS43L22_I2S_BUS 3
|
||||
#endif
|
||||
|
||||
/* Check if we can support the RTC driver */
|
||||
|
||||
#if !defined(CONFIG_RTC) || !defined(CONFIG_RTC_DRIVER)
|
||||
@ -216,6 +237,8 @@
|
||||
|
||||
#define GPIO_ZEROCROSS (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTD|GPIO_PIN0)
|
||||
|
||||
#define GPIO_CS43L22_RESET (GPIO_OUTPUT|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN4)
|
||||
|
||||
/* PWM
|
||||
*
|
||||
* The STM32F4 Discovery has no real on-board PWM devices, but the board can be
|
||||
@ -369,6 +392,17 @@
|
||||
|
||||
void weak_function stm32_spidev_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_i2sdev_initialize
|
||||
*
|
||||
* Description:
|
||||
* Called to configure I2S chip select GPIO pins for the stm32f4discovery
|
||||
* board.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct i2s_dev_s *stm32_i2sdev_initialize(int port);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_bh1750initialize
|
||||
*
|
||||
@ -608,6 +642,27 @@ int stm32_zerocross_initialize(void);
|
||||
int stm32_max6675initialize(FAR const char *devpath);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_cs43l22_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function is called by platform-specific, setup logic to configure
|
||||
* and register the CS43L22 device. This function will register the driver
|
||||
* as /dev/cs43l22[x] where x is determined by the minor device number.
|
||||
*
|
||||
* Input Parameters:
|
||||
* minor - The input device minor number
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CS43L22
|
||||
int stm32_cs43l22_initialize(int minor);
|
||||
#endif /* HAVE_CS43L22 */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_pca9635_initialize
|
||||
*
|
||||
|
@ -95,6 +95,67 @@ endif # AUDIO_DRIVER_SPECIFIC_BUFFERS
|
||||
|
||||
endif # VS1053
|
||||
|
||||
config AUDIO_CS43L22
|
||||
bool "CS43L22 audio chip"
|
||||
default n
|
||||
depends on AUDIO
|
||||
---help---
|
||||
Select to enable support for the CS43L22 Audio codec by Cirrus Logic.
|
||||
This chip is a lower level audio chip.. basically
|
||||
an exotic D-to-A. It includes no built-in support for audio CODECS
|
||||
The CS43L22 provides:
|
||||
|
||||
- Low power consumption
|
||||
- High SNR
|
||||
- Stereo digital microphone input
|
||||
- Digital Dynamic Range Controller (compressor / limiter)
|
||||
- Digital sidetone mixing
|
||||
- Ground-referenced headphone driver
|
||||
- Ground-referenced line outputs
|
||||
|
||||
NOTE: This driver also depends on both I2C and I2S support although
|
||||
that dependency is not explicit here.
|
||||
|
||||
if AUDIO_CS43L22
|
||||
|
||||
config CS43L22_INITVOLUME
|
||||
int "CS43L22 initial volume setting"
|
||||
default 250
|
||||
|
||||
config CS43L22_INFLIGHT
|
||||
int "CS43L22 maximum in-flight audio buffers"
|
||||
default 2
|
||||
|
||||
config CS43L22_MSG_PRIO
|
||||
int "CS43L22 message priority"
|
||||
default 1
|
||||
|
||||
config CS43L22_BUFFER_SIZE
|
||||
int "CS43L22 preferred buffer size"
|
||||
default 8192
|
||||
|
||||
config CS43L22_NUM_BUFFERS
|
||||
int "CS43L22 preferred number of buffers"
|
||||
default 4
|
||||
|
||||
config CS43L22_WORKER_STACKSIZE
|
||||
int "CS43L22 worker thread stack size"
|
||||
default 768
|
||||
|
||||
config CS43L22_REGDUMP
|
||||
bool "CS43L22 register dump"
|
||||
default n
|
||||
---help---
|
||||
Enable logic to dump the contents of all CS43L22 registers.
|
||||
|
||||
config CS43L22_CLKDEBUG
|
||||
bool "CS43L22 clock analysis"
|
||||
default n
|
||||
---help---
|
||||
Enable logic to analyze CS43L22 clock configuation.
|
||||
|
||||
endif # AUDIO_CS43L22
|
||||
|
||||
config AUDIO_WM8904
|
||||
bool "WM8904 audio chip"
|
||||
default n
|
||||
|
@ -43,6 +43,17 @@ ifeq ($(CONFIG_VS1053),y)
|
||||
CSRCS += vs1053.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_CS43L22),y)
|
||||
CSRCS += cs43l22.c
|
||||
ifeq ($(CONFIG_CS43L22_REGDUMP),y)
|
||||
CSRCS += cs43l22_debug.c
|
||||
else
|
||||
ifeq ($(CONFIG_CS43L22_CLKDEBUG),y)
|
||||
CSRCS += cs43l22_debug.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_WM8904),y)
|
||||
CSRCS += wm8904.c
|
||||
ifeq ($(CONFIG_WM8904_REGDUMP),y)
|
||||
|
1959
drivers/audio/cs43l22.c
Normal file
1959
drivers/audio/cs43l22.c
Normal file
File diff suppressed because it is too large
Load Diff
388
drivers/audio/cs43l22.h
Normal file
388
drivers/audio/cs43l22.h
Normal file
@ -0,0 +1,388 @@
|
||||
/****************************************************************************
|
||||
* drivers/audio/cs43l22.h
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Reference:
|
||||
* "CS43L22 Ultra Low Power CODEC for Portable Audio Applications, Pre-
|
||||
* Production", September 2012, Rev 3.3, Wolfson Microelectronics
|
||||
*
|
||||
* 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_CS43L22_H
|
||||
#define __DRIVERS_AUDIO_CS43L22_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <mqueue.h>
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
#define getreg32(a) (*(volatile uint32_t *)(a))
|
||||
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
|
||||
#define getreg16(a) (*(volatile uint16_t *)(a))
|
||||
#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v))
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
/* So far, I have not been able to get FLL lock interrupts. Worse, I have
|
||||
* been able to get the FLL to claim that it is locked at all even when
|
||||
* polling. What am I doing wrong?
|
||||
*
|
||||
* Hmmm.. seems unnecessary anyway
|
||||
*/
|
||||
|
||||
#undef CS43L22_USE_FFLOCK_INT
|
||||
#undef CS43L22_USE_FFLOCK_POLL
|
||||
|
||||
/* Registers Addresses ******************************************************/
|
||||
|
||||
#define CS43L22_ID_REV 0x01 /* Chip I.D. and Revision */
|
||||
#define CS43L22_POWER_CTRL1 0x02 /* Power Control 1 */
|
||||
#define CS43L22_POWER_CTRL2 0x04 /* Power Control 2 */
|
||||
#define CS43L22_CLOCK_CTRL 0x05 /* Clocking Control */
|
||||
#define CS43L22_INTERFACE_CTRL1 0x06 /* Interface Control 1 */
|
||||
#define CS43L22_INTERFACE_CTRL2 0x07 /* Interface Control 2 */
|
||||
#define CS43L22_PASS_SEL_A 0x08 /* Passthrough x Select: PassA */
|
||||
#define CS43L22_PASS_SEL_B 0x09 /* Passthrough x Select: PassB */
|
||||
#define CS43L22_ANLG_ZC_SR_SEL 0x0A /* Analog ZC and SR Settings */
|
||||
#define CS43L22_PASS_GANG_CTRL 0x0C /* Passthrough Gang Control */
|
||||
#define CS43L22_PLAYBACK_CTRL1 0x0D /* Playback Control 1 */
|
||||
#define CS43L22_MISCLLNS_CTRL 0x0E /* Miscellaneous Controls */
|
||||
#define CS43L22_PLAYBACK_CTRL2 0x0F /* Playback Control 2 */
|
||||
#define CS43L22_PASS_VOL_A 0x14 /* Passthrough x Volume: PASSAVOL */
|
||||
#define CS43L22_PASS_VOL_B 0x15 /* Passthrough x Volume: PASSBVOL */
|
||||
#define CS43L22_PCM_VOL_A 0x1A /* PCMx Volume: PCMA */
|
||||
#define CS43L22_PCM_VOL_B 0x1B /* PCMx Volume: PCMB */
|
||||
#define CS43L22_BP_FREQ_ON_TIME 0x1C /* Beep Frequency & On Time */
|
||||
#define CS43L22_BP_VOL_OFF_TIME 0x1D /* Beep Volume & Off Time */
|
||||
#define CS43L22_BP_TONE_CFG 0x1E /* Beep & Tone Configuration */
|
||||
#define CS43L22_TONE_CTRL 0x1F /* Tone Control */
|
||||
#define CS43L22_MS_VOL_CTRL_A 0x20 /* Master Volume Control: MSTA */
|
||||
#define CS43L22_MS_VOL_CTRL_B 0x21 /* Master Volume Control: MSTB */
|
||||
#define CS43L22_HP_VOL_CTRL_A 0x22 /* Headphone Volume Control: HPA */
|
||||
#define CS43L22_HP_VOL_CTRL_B 0x23 /* Headphone Volume Control: HPB */
|
||||
#define CS43L22_SPK_VOL_CTRL_A 0x24 /* Speaker Volume Control: SPKA */
|
||||
#define CS43L22_SPK_VOL_CTRL_B 0x25 /* Speaker Volume Control: SPKB */
|
||||
#define CS43L22_PCM_CH_SWAP 0x26 /* PCM Channel Swap */
|
||||
#define CS43L22_LIM_CTRL1 0x27 /* Limiter Control 1, Min/Max Thresholds */
|
||||
#define CS43L22_LIM_CTRL2 0x28 /* Limiter Control 2, Release Rate */
|
||||
#define CS43L22_LIM_ATTACK_RATE 0x29 /* Limiter Attack Rate */
|
||||
#define CS43L22_STATUS 0x2E /* Status */
|
||||
#define CS43L22_BAT_COMP 0x2F /* Battery Compensation */
|
||||
#define CS43L22_VP_BAT_LEVEL 0x30 /* VP Battery Level */
|
||||
#define CS43L22_SPK_STATUS 0x31 /* Speaker Status */
|
||||
#define CS43L22_TEMP_MON_CTRL 0x32 /* Temperature Monitor Control */
|
||||
#define CS43L22_THERMAL_FOLDBACK 0x33 /* Thermal Foldback */
|
||||
#define CS43L22_CHRG_PUMP_FREQ 0x34 /* Charge Pump Frequency */
|
||||
|
||||
#define CS43L22_HPBMUTE (1 << 7)
|
||||
#define CS43L22_HPAMUTE (1 << 6)
|
||||
#define CS43L22_SPKBMUTE (1 << 5)
|
||||
#define CS43L22_SPKAMUTE (1 << 4)
|
||||
|
||||
/* Register Default Values **************************************************/
|
||||
/* Registers have some undocumented bits set on power up. These probably
|
||||
* should be retained on writes (?).
|
||||
*/
|
||||
|
||||
#define CS43L22_ID_REV_DEFAULT 0xe3 /* Chip I.D. and Revision */
|
||||
#define CS43L22_POWER_CTRL1_DEFAULT 0x01 /* Power Control 1 */
|
||||
#define CS43L22_POWER_CTRL2_DEFAULT 0x05 /* Power Control 2 */
|
||||
#define CS43L22_CLOCK_CTRL_DEFAULT 0xa0 /* Clocking Control */
|
||||
#define CS43L22_INTERFACE_CTRL1_DEFAULT 0x00 /* Interface Control 1 */
|
||||
#define CS43L22_INTERFACE_CTRL2_DEFAULT 0x00 /* Interface Control 2 */
|
||||
#define CS43L22_PASS_SEL_A_DEFAULT 0x81 /* Passthrough x Select: PassA */
|
||||
#define CS43L22_PASS_SEL_B_DEFAULT 0x81 /* Passthrough x Select: PassB */
|
||||
#define CS43L22_ANLG_ZC_SR_SEL_DEFAULT 0xa5 /* Analog ZC and SR Settings */
|
||||
#define CS43L22_PASS_GANG_CTRL_DEFAULT 0x00 /* Passthrough Gang Control */
|
||||
#define CS43L22_PLAYBACK_CTRL1_DEFAULT 0x60 /* Playback Control 1 */
|
||||
#define CS43L22_MISCLLNS_CTRL_DEFAULT 0x02 /* Miscellaneous Controls */
|
||||
#define CS43L22_PLAYBACK_CTRL2_DEFAULT 0x00 /* Playback Control 2 */
|
||||
#define CS43L22_PASS_VOL_A_DEFAULT 0x00 /* Passthrough x Volume: PASSAVOL */
|
||||
#define CS43L22_PASS_VOL_B_DEFAULT 0x00 /* Passthrough x Volume: PASSBVOL */
|
||||
#define CS43L22_PCM_VOL_A_DEFAULT 0x00 /* PCMx Volume: PCMA */
|
||||
#define CS43L22_PCM_VOL_B_DEFAULT 0x00 /* PCMx Volume: PCMB */
|
||||
#define CS43L22_BP_FREQ_ON_TIME_DEFAULT 0x00 /* Beep Frequency & On Time */
|
||||
#define CS43L22_BP_VOL_OFF_TIME_DEFAULT 0x00 /* Beep Volume & Off Time */
|
||||
#define CS43L22_BP_TONE_CFG_DEFAULT 0x00 /* Beep & Tone Configuration */
|
||||
#define CS43L22_TONE_CTRL_DEFAULT 0x88 /* Tone Control */
|
||||
#define CS43L22_MS_VOL_CTRL_A_DEFAULT 0x00 /* Master Volume Control: MSTA */
|
||||
#define CS43L22_MS_VOL_CTRL_B_DEFAULT 0x00 /* Master Volume Control: MSTB */
|
||||
#define CS43L22_HP_VOL_CTRL_A_DEFAULT 0x00 /* Headphone Volume Control: HPA */
|
||||
#define CS43L22_HP_VOL_CTRL_B_DEFAULT 0x00 /* Headphone Volume Control: HPB */
|
||||
#define CS43L22_SPK_VOL_CTRL_A_DEFAULT 0x00 /* Speaker Volume Control: SPKA */
|
||||
#define CS43L22_SPK_VOL_CTRL_B_DEFAULT 0x00 /* Speaker Volume Control: SPKB */
|
||||
#define CS43L22_PCM_CH_SWAP_DEFAULT 0x00 /* PCM Channel Swap */
|
||||
#define CS43L22_LIM_CTRL1_DEFAULT 0x00 /* Limiter Control 1, Min/Max Thresholds */
|
||||
#define CS43L22_LIM_CTRL2_DEFAULT 0x7f /* Limiter Control 2, Release Rate */
|
||||
#define CS43L22_LIM_ATTACK_RATE_DEFAULT 0xc0 /* Limiter Attack Rate */
|
||||
#define CS43L22_STATUS_DEFAULT 0x00 /* Status */
|
||||
#define CS43L22_BAT_COMP_DEFAULT 0x00 /* Battery Compensation */
|
||||
#define CS43L22_VP_BAT_LEVEL_DEFAULT 0x00 /* VP Battery Level */
|
||||
#define CS43L22_SPK_STATUS_DEFAULT 0x00 /* Speaker Status */
|
||||
#define CS43L22_TEMP_MON_CTRL_DEFAULT 0x3b /* Temperature Monitor Control */
|
||||
#define CS43L22_THERMAL_FOLDBACK_DEFAULT 0x00 /* Thermal Foldback */
|
||||
#define CS43L22_CHRG_PUMP_FREQ_DEFAULT 0x5f /* Charge Pump Frequency */
|
||||
|
||||
/* Register Bit Definitions *************************************************/
|
||||
|
||||
/* 0x01 Chip I.D. and Revision (Read Only) */
|
||||
#define CS43L22_DEV_ID_REV (0xe3)
|
||||
#define CS43L22_ID_SHIFT (3)
|
||||
#define CS43L22_ID_MASK (0x1f << CS43L22_ID_SHIFT)
|
||||
#define CS43L22_REV_SHIFT (0)
|
||||
#define CS43L22_REV_MASK (0x07 << CS43L22_REV_SHIFT)
|
||||
|
||||
/* 0x02 Power Control 1 */
|
||||
#define CS43L22_POWER_DOWN (0x01) /* Powered Down */
|
||||
#define CS43L22_POWER_UP (0x9e) /* Powered Up */
|
||||
|
||||
/* 0x04 Power Control 2 */
|
||||
#define CS43L22_PDN_HPB_SHIFT (6) /* Bits 6-7: Headphone channel B Control */
|
||||
#define CS43L22_PDN_HPB_ON_HW_PIN_LO (0 << CS43L22_PDN_HPB_SHIFT) /* PDN_HPx[1:0] 00 Headphone channel is ON when the SPK/HP_SW pin, 6, is LO
|
||||
Headphone channel is OFF when the SPK/HP_SW pin, 6, is HI */
|
||||
#define CS43L22_PDN_HPB_ON_HW_PIN_HI (1 << CS43L22_PDN_HPB_SHIFT) /* PDN_HPx[1:0] 01 Headphone channel is ON when the SPK/HP_SW pin, 6, is HI
|
||||
Headphone channel is OFF when the SPK/HP_SW pin, 6, is LO */
|
||||
#define CS43L22_PDN_HPB_ON (2 << CS43L22_PDN_HPB_SHIFT) /* PDN_HPx[1:0] 10 Headphone channel is always ON */
|
||||
#define CS43L22_PDN_HPB_OFF (3 << CS43L22_PDN_HPB_SHIFT) /* PDN_HPx[1:0] 11 Headphone channel is always OFF */
|
||||
|
||||
#define CS43L22_PDN_HPA_SHIFT (4) /* Bits 4-5: Headphone channel A Control */
|
||||
#define CS43L22_PDN_HPA_ON_HW_PIN_LO (0 << CS43L22_PDN_HPA_SHIFT) /* PDN_HPx[1:0] 00 Headphone channel is ON when the SPK/HP_SW pin, 6, is LO
|
||||
Headphone channel is OFF when the SPK/HP_SW pin, 6, is HI */
|
||||
#define CS43L22_PDN_HPA_ON_HW_PIN_HI (1 << CS43L22_PDN_HPA_SHIFT) /* PDN_HPx[1:0] 01 Headphone channel is ON when the SPK/HP_SW pin, 6, is HI
|
||||
Headphone channel is OFF when the SPK/HP_SW pin, 6, is LO */
|
||||
#define CS43L22_PDN_HPA_ON (2 << CS43L22_PDN_HPA_SHIFT) /* PDN_HPx[1:0] 10 Headphone channel is always ON */
|
||||
#define CS43L22_PDN_HPA_OFF (3 << CS43L22_PDN_HPA_SHIFT) /* PDN_HPx[1:0] 11 Headphone channel is always OFF */
|
||||
|
||||
#define CS43L22_PDN_SPKB_SHIFT (2) /* Bits 2-3: Speaker channel B Control */
|
||||
#define CS43L22_PDN_SPKB_ON_HW_PIN_LO (0 << CS43L22_PDN_SPKB_SHIFT) /* PDN_HPx[1:0] 00 Speaker channel is ON when the SPK/HP_SW pin, 6, is LO
|
||||
Speaker channel is OFF when the SPK/HP_SW pin, 6, is HI */
|
||||
#define CS43L22_PDN_SPKB_ON_HW_PIN_HI (1 << CS43L22_PDN_SPKB_SHIFT) /* PDN_HPx[1:0] 01 Speaker channel is ON when the SPK/HP_SW pin, 6, is HI
|
||||
Speaker channel is OFF when the SPK/HP_SW pin, 6, is LO */
|
||||
#define CS43L22_PDN_SPKB_ON (2 << CS43L22_PDN_SPKB_SHIFT) /* PDN_HPx[1:0] 10 Speaker channel is always ON */
|
||||
#define CS43L22_PDN_SPKB_OFF (3 << CS43L22_PDN_SPKB_SHIFT) /* PDN_HPx[1:0] 11 Speaker channel is always OFF */
|
||||
|
||||
#define CS43L22_PDN_SPKA_SHIFT (0) /* Bits 0-1: Speaker channel A Control */
|
||||
#define CS43L22_PDN_SPKA_ON_HW_PIN_LO (0 << CS43L22_PDN_SPKA_SHIFT) /* PDN_HPx[1:0] 00 Speaker channel is ON when the SPK/HP_SW pin, 6, is LO
|
||||
Speaker channel is OFF when the SPK/HP_SW pin, 6, is HI */
|
||||
#define CS43L22_PDN_SPKA_ON_HW_PIN_HI (1 << CS43L22_PDN_SPKA_SHIFT) /* PDN_HPx[1:0] 01 Speaker channel is ON when the SPK/HP_SW pin, 6, is HI
|
||||
Speaker channel is OFF when the SPK/HP_SW pin, 6, is LO */
|
||||
#define CS43L22_PDN_SPKA_ON (2 << CS43L22_PDN_SPKA_SHIFT) /* PDN_HPx[1:0] 10 Speaker channel is always ON */
|
||||
#define CS43L22_PDN_SPKA_OFF (3 << CS43L22_PDN_SPKA_SHIFT) /* PDN_HPx[1:0] 11 Speaker channel is always OFF */
|
||||
|
||||
/* 0x05 Clocking Control */
|
||||
#define CS43L22_AUTO_DETECT_ENABLE (1 << 7) /* Auto-detection of speed mode enable */
|
||||
|
||||
#define CS43L22_SPEED_SHIFT (5) /* Bits 5-6: Speed mode */
|
||||
#define CS43L22_SPEED_DOUBLE (0 << CS43L22_SPEED_SHIFT) /* Slave: Double-Speed Mode (DSM - 50 kHz -100 kHz Fs) Master: MCLK=512 SCLK=64*/
|
||||
#define CS43L22_SPEED_SINGLE (1 << CS43L22_SPEED_SHIFT) /* Slave: Single-Speed Mode (SSM - 4 kHz -50 kHz Fs) Master: MCLK=256 SCLK=64*/
|
||||
#define CS43L22_SPEED_HALF (2 << CS43L22_SPEED_SHIFT) /* Slave: Half-Speed Mode (HSM - 12.5kHz -25 kHz Fs) Master: MCLK=128 SCLK=64*/
|
||||
#define CS43L22_SPEED_QUARTER (3 << CS43L22_SPEED_SHIFT) /* Slave: Quarter-Speed Mode (QSM - 4 kHz -12.5 kHz Fs)Master: MCLK=128 SCLK=64*/
|
||||
|
||||
#define CS43L22_32k_GROUP_ENABLE (1 << 4) /* Bit 4: Specifies whether or not the input/output sample rate is 8 kHz, 16 kHz or 32 kHz */
|
||||
|
||||
#define CS43L22_VIDEOCLK_ENABLE (1 << 3) /* Bit 3: Specifies whether or not the external MCLK frequency is 27 MHz */
|
||||
|
||||
#define CS43L22_MCLK_LRCK_RATIO_SHIFT (1) /* Bits 1-2: Internal MCLK/LRCK Ratio */
|
||||
#define CS43L22_RATIO_128_64 (0 << CS43L22_MCLK_LRCK_RATIO_SHIFT) /* RATIO[1:0] Internal MCLK Cycles per LRCK=128, SCLK/LRCK=64 Ratio in Master Mode */
|
||||
#define CS43L22_RATIO_125_62 (1 << CS43L22_MCLK_LRCK_RATIO_SHIFT) /* RATIO[1:0] Internal MCLK Cycles per LRCK=125, SCLK/LRCK=62 Ratio in Master Mode */
|
||||
#define CS43L22_RATIO_132_66 (2 << CS43L22_MCLK_LRCK_RATIO_SHIFT) /* RATIO[1:0] Internal MCLK Cycles per LRCK=132, SCLK/LRCK=66 Ratio in Master Mode */
|
||||
#define CS43L22_RATIO_136_68 (3 << CS43L22_MCLK_LRCK_RATIO_SHIFT) /* RATIO[1:0] Internal MCLK Cycles per LRCK=136, SCLK/LRCK=68 Ratio in Master Mode */
|
||||
|
||||
#define CS43L22_CLKDIV2_ENABLE (1 << 0) /* Bit 0: Divided by 2 */
|
||||
|
||||
/* 0x06 Interface Control 1 */
|
||||
#define CS43L22_MODE_MASTER (1 << 7) /* Configures the serial port I/O clocking */
|
||||
|
||||
#define CS43L22_SCLK_POLARITY_INVERT (1 << 6) /* Configures the polarity of the SCLK signal */
|
||||
|
||||
#define CS43L22_DSP_MODE_ENABLE (1 << 4) /* Configures a data-packed interface format for the DAC */
|
||||
|
||||
#define CS43L22_DAC_IF_FORMAT_SHIFT (2) /* Bits 2-3: Configures the digital interface format for data on SDIN */
|
||||
#define CS43L22_DAC_IF_LEFT_JUSTIFIED (0 << CS43L22_DAC_IF_FORMAT_SHIFT) /* DACDIF[1:0] Left Justified, up to 24-bit data */
|
||||
#define CS43L22_DAC_IF_I2S (1 << CS43L22_DAC_IF_FORMAT_SHIFT) /* DACDIF[1:0] I2S, up to 24-bit data */
|
||||
#define CS43L22_DAC_IF_RIGHT_JUSTIFIED (2 << CS43L22_DAC_IF_FORMAT_SHIFT) /* DACDIF[1:0] Right Justified */
|
||||
#define CS43L22_DAC_IF_RESERVED (3 << CS43L22_DAC_IF_FORMAT_SHIFT) /* DACDIF[1:0] Reserved */
|
||||
|
||||
#define CS43L22_AUDIO_WORD_LENGHT_SHIFT (0) /* Bits 0-1: Configures the audio sample word length used for the data into SDIN */
|
||||
#define CS43L22_AWL_DSP_32_RJ_24 (0 << CS43L22_AUDIO_WORD_LENGHT_SHIFT)/* AWL[1:0] DSP Mode: 32-bit data, Right Justified: 24-bit data */
|
||||
#define CS43L22_AWL_DSP_24_RJ_20 (1 << CS43L22_AUDIO_WORD_LENGHT_SHIFT)/* AWL[1:0] DSP Mode: 24-bit data, Right Justified: 20-bit data */
|
||||
#define CS43L22_AWL_DSP_20_RJ_18 (2 << CS43L22_AUDIO_WORD_LENGHT_SHIFT)/* AWL[1:0] DSP Mode: 20-bit data, Right Justified: 18-bit data */
|
||||
#define CS43L22_AWL_DSP_16_RJ_16 (3 << CS43L22_AUDIO_WORD_LENGHT_SHIFT)/* AWL[1:0] DSP Mode: 16 bit data, Right Justified: 16-bit data */
|
||||
|
||||
/* 0x0E Miscellaneous Controls */
|
||||
#define CS43L22_FREEZE (1 << 3) /* Configures a hold on all register settings */
|
||||
#define CS43L22_DEEMPHASIS_ENABLE (1 << 2) /* Configures a 15μs/50μs digital de-emphasis filter response on the headphone/line and speaker outputs */
|
||||
|
||||
/* 0x1F Tone Control */
|
||||
#define CS43L22_TREB_GAIN_SHIFT (4) /* Sets the gain of the treble shelving filter */
|
||||
#define CS43L22_TREB_GAIN(a) ((a) << CS43L22_TREB_GAIN_SHIFT)
|
||||
/* TREB[3:0] Gain Setting:*/
|
||||
/* 0000 +12.0 dB */
|
||||
/* ··· ··· */
|
||||
/* 0111 +1.5 dB */
|
||||
/* 1000 0 dB */
|
||||
/* 1001 -1.5 dB */
|
||||
/* 1111 -10.5 dB */
|
||||
/* Step Size: 1.5 dB */
|
||||
|
||||
#define CS43L22_BASS_GAIN_SHIFT (0) /* Sets the gain of the bass shelving filter */
|
||||
#define CS43L22_BASS_GAIN(a) ((a) << CS43L22_BASS_GAIN_SHIFT)
|
||||
/* BASS[3:0] Gain Setting:*/
|
||||
/* 0000 +12.0 dB */
|
||||
/* ··· ··· */
|
||||
/* 0111 +1.5 dB */
|
||||
/* 1000 0 dB */
|
||||
/* 1001 -1.5 dB */
|
||||
/* 1111 -10.5 dB */
|
||||
/* Step Size: 1.5 dB */
|
||||
|
||||
/* FLL Configuration *********************************************************/
|
||||
/* Default FLL configuration */
|
||||
|
||||
#define CS43L22_DEFAULT_SAMPRATE 11025 /* Initial sample rate */
|
||||
#define CS43L22_DEFAULT_NCHANNELS 1 /* Initial number of channels */
|
||||
#define CS43L22_DEFAULT_BPSAMP 16 /* Initial bits per sample */
|
||||
|
||||
#define CS43L22_NFLLRATIO 5 /* Number of FLL_RATIO values */
|
||||
|
||||
#define CS43L22_MINOUTDIV 4 /* Minimum FLL_OUTDIV divider */
|
||||
#define CS43L22_MAXOUTDIV 64 /* Maximum FLL_OUTDIV divider */
|
||||
|
||||
#define CS43L22_BCLK_MAXDIV 20 /* Maximum BCLK divider */
|
||||
|
||||
#define CS43L22_FRAMELEN8 14 /* Bits per frame for 8-bit data */
|
||||
#define CS43L22_FRAMELEN16 32 /* Bits per frame for 16-bit data */
|
||||
|
||||
/* 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
|
||||
****************************************************************************/
|
||||
|
||||
struct cs43l22_dev_s
|
||||
{
|
||||
/* We are an audio lower half driver (We are also the upper "half" of
|
||||
* the CS43L22 driver with respect to the board lower half driver).
|
||||
*
|
||||
* Terminology: Our "lower" half audio instances will be called dev for the
|
||||
* publicly visible version and "priv" for the version that only this driver
|
||||
* knows. From the point of view of this driver, it is the board lower
|
||||
* "half" that is referred to as "lower".
|
||||
*/
|
||||
|
||||
struct audio_lowerhalf_s dev; /* CS43L22 audio lower half (this device) */
|
||||
|
||||
/* Our specific driver data goes here */
|
||||
|
||||
const FAR struct cs43l22_lower_s *lower; /* Pointer to the board lower functions */
|
||||
FAR struct i2c_master_s *i2c; /* I2C driver to use */
|
||||
FAR struct i2s_dev_s *i2s; /* I2S driver to use */
|
||||
struct dq_queue_s pendq; /* Queue of pending buffers to be sent */
|
||||
struct dq_queue_s doneq; /* Queue of sent buffers to be returned */
|
||||
mqd_t mq; /* Message queue for receiving messages */
|
||||
char mqname[16]; /* Our message queue name */
|
||||
pthread_t threadid; /* ID of our thread */
|
||||
uint32_t bitrate; /* Actual programmed bit rate */
|
||||
sem_t pendsem; /* Protect pendq */
|
||||
#ifdef CS43L22_USE_FFLOCK_INT
|
||||
struct work_s work; /* Interrupt work */
|
||||
#endif
|
||||
uint16_t samprate; /* Configured samprate (samples/sec) */
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
|
||||
uint16_t balance; /* Current balance level (b16) */
|
||||
#endif /* CONFIG_AUDIO_EXCLUDE_BALANCE */
|
||||
uint8_t volume; /* Current volume level {0..63} */
|
||||
#endif /* CONFIG_AUDIO_EXCLUDE_VOLUME */
|
||||
uint8_t nchannels; /* Number of channels (1 or 2) */
|
||||
uint8_t bpsamp; /* Bits per sample (8 or 16) */
|
||||
volatile uint8_t inflight; /* Number of audio buffers in-flight */
|
||||
#ifdef CS43L22_USE_FFLOCK_INT
|
||||
volatile bool locked; /* FLL is locked */
|
||||
#endif
|
||||
bool running; /* True: Worker thread is running */
|
||||
bool paused; /* True: Playing is paused */
|
||||
bool mute; /* True: Output is muted */
|
||||
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
|
||||
bool terminating; /* True: Stop requested */
|
||||
#endif
|
||||
bool reserved; /* True: Device is reserved */
|
||||
volatile int result; /* The result of the last transfer */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_CLKDEBUG
|
||||
extern const uint8_t g_sysclk_scaleb1[CS43L22_BCLK_MAXDIV+1];
|
||||
extern const uint8_t g_fllratio[CS43L22_NFLLRATIO];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cs43l22_readreg
|
||||
*
|
||||
* Description
|
||||
* Read the specified 8-bit register from the CS43L22 device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_CS43L22_REGDUMP) || defined(CONFIG_CS43L22_CLKDEBUG)
|
||||
struct cs43l22_dev_s;
|
||||
uint8_t cs43l22_readreg(FAR struct cs43l22_dev_s *priv, uint8_t regaddr);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_AUDIO */
|
||||
#endif /* __DRIVERS_AUDIO_CS43L22_H */
|
184
drivers/audio/cs43l22_debug.c
Normal file
184
drivers/audio/cs43l22_debug.c
Normal file
@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
* drivers/audio/cs43l22_debug.c
|
||||
* Audio device driver for Cirrus Logic CS43L22 Audio codec.
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Taras Drozdovsky <t.drozdovskiy@gmail.comnuttx.org>
|
||||
*
|
||||
* References:
|
||||
* - "CS43L22 Ultra Low Power CODEC for Portable Audio Applications, Pre-
|
||||
* Production", September 2012, Rev b1, Cirrus Logic
|
||||
* - The framework for this driver is based on Ken Pettit's VS1053 driver.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <fixedmath.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <nuttx/audio/audio.h>
|
||||
#include <nuttx/audio/cs43l22.h>
|
||||
|
||||
#include "cs43l22.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_REGDUMP
|
||||
struct cs43l22_regdump_s
|
||||
{
|
||||
FAR const char *regname;
|
||||
uint8_t regaddr;
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_REGDUMP
|
||||
static const struct cs43l22_regdump_s g_cs43l22_debug[] =
|
||||
{
|
||||
{"CHIP_ID_REV", CS43L22_ID_REV },
|
||||
{"POWER_CTRL1", CS43L22_POWER_CTRL1 },
|
||||
{"POWER_CTRL2", CS43L22_POWER_CTRL2 },
|
||||
{"CLOCK_CTRL", CS43L22_CLOCK_CTRL },
|
||||
{"INTERFACE_CTRL1", CS43L22_INTERFACE_CTRL1 },
|
||||
{"INTERFACE_CTRL2", CS43L22_INTERFACE_CTRL2 },
|
||||
{"PASS_SEL_A", CS43L22_PASS_SEL_A },
|
||||
{"PASS_SEL_B", CS43L22_PASS_SEL_B },
|
||||
{"ANLG_ZC_SR_SEL", CS43L22_ANLG_ZC_SR_SEL },
|
||||
{"PASS_GANG_CTRL", CS43L22_PASS_GANG_CTRL },
|
||||
{"PLAYBACK_CTRL1", CS43L22_PLAYBACK_CTRL1 },
|
||||
{"MISCLLNS_CTRL", CS43L22_MISCLLNS_CTRL },
|
||||
{"PLAYBACK_CTRL2", CS43L22_PLAYBACK_CTRL2 },
|
||||
{"PASS_VOL_A", CS43L22_PASS_VOL_A },
|
||||
{"PASS_VOL_B", CS43L22_PASS_VOL_B },
|
||||
{"PCM_VOL_A", CS43L22_PCM_VOL_A },
|
||||
{"PCM_VOL_B", CS43L22_PCM_VOL_B },
|
||||
{"BP_FREQ_ON_T", CS43L22_BP_FREQ_ON_TIME },
|
||||
{"BP_VOL_OFF_T", CS43L22_BP_VOL_OFF_TIME },
|
||||
{"BP_TONE_CFG", CS43L22_BP_TONE_CFG },
|
||||
{"TONE_CTRL", CS43L22_TONE_CTRL },
|
||||
{"MS_VOL_CTRL_A", CS43L22_MS_VOL_CTRL_A },
|
||||
{"MS_VOL_CTRL_B", CS43L22_MS_VOL_CTRL_B },
|
||||
{"HP_VOL_CTRL_A", CS43L22_HP_VOL_CTRL_A },
|
||||
{"HP_VOL_CTRL_B", CS43L22_HP_VOL_CTRL_B },
|
||||
{"SPK_VOL_CTRL_A", CS43L22_SPK_VOL_CTRL_A },
|
||||
{"SPK_VOL_CTRL_B", CS43L22_SPK_VOL_CTRL_B },
|
||||
{"PCM_CH_SWAP", CS43L22_PCM_CH_SWAP },
|
||||
{"LIM_CTRL1", CS43L22_LIM_CTRL1 },
|
||||
{"LIM_CTRL2", CS43L22_LIM_CTRL2 },
|
||||
{"LIM_ATTACK_RATE", CS43L22_LIM_ATTACK_RATE },
|
||||
{"STATUS", CS43L22_STATUS },
|
||||
{"BAT_COMP", CS43L22_BAT_COMP },
|
||||
{"VP_BAT_LEVEL", CS43L22_VP_BAT_LEVEL },
|
||||
{"SPK_STATUS", CS43L22_SPK_STATUS },
|
||||
{"TEMP_MON_CTRL", CS43L22_TEMP_MON_CTRL },
|
||||
{"THERMAL_FOLDBACK",CS43L22_THERMAL_FOLDBACK},
|
||||
{"CHRG_PUMP_FREQ", CS43L22_CHRG_PUMP_FREQ }
|
||||
};
|
||||
|
||||
# define CS43L22_NREGISTERS (sizeof(g_cs43l22_debug)/sizeof(struct cs43l22_regdump_s))
|
||||
#endif /* CONFIG_CS43L22_REGDUMP */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cs43l22_dump_registers
|
||||
*
|
||||
* Description:
|
||||
* Dump the contents of all CS43L22 registers to the syslog device
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by cs43l22_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_REGDUMP
|
||||
void cs43l22_dump_registers(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg)
|
||||
{
|
||||
int i;
|
||||
|
||||
syslog(LOG_INFO, "CS43L22 Registers: %s\n", msg);
|
||||
for (i = 0; i < CS43L22_NREGISTERS; i++)
|
||||
{
|
||||
syslog(LOG_INFO, "%16s[%02x]: %02x\n",
|
||||
g_cs43l22_debug[i].regname, g_cs43l22_debug[i].regaddr,
|
||||
cs43l22_readreg((FAR struct cs43l22_dev_s *)dev,
|
||||
g_cs43l22_debug[i].regaddr));
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_CS43L22_REGDUMP */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cs43l22_clock_analysis
|
||||
*
|
||||
* Description:
|
||||
* Analyze the settings in the clock chain and dump to syslog.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by cs43l22_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_CLKDEBUG
|
||||
void cs43l22_clock_analysis(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg)
|
||||
{
|
||||
#warning Missing logic
|
||||
/* TODO */
|
||||
}
|
||||
#endif /* CONFIG_CS43L22_CLKDEBUG */
|
280
include/nuttx/audio/cs43l22.h
Normal file
280
include/nuttx/audio/cs43l22.h
Normal file
@ -0,0 +1,280 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/audio/cs43l22.h
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Reference:
|
||||
* "CS43L22 Ultra Low Power CODEC for Portable Audio Applications, Pre-
|
||||
* Production", September 2012, Rev 3.3, Wolfson Microelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_AUDIO_CS43L22_H
|
||||
#define __INCLUDE_NUTTX_AUDIO_CS43L22_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#ifdef CONFIG_AUDIO_CS43L22
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************
|
||||
*
|
||||
* CONFIG_AUDIO_CS43L22 - Enables CS43L22 support
|
||||
* CONFIG_CS43L22_INITVOLUME - The initial volume level in the range {0..1000}
|
||||
* CONFIG_CS43L22_INFLIGHT - Maximum number of buffers that the CS43L22 driver
|
||||
* will send to the I2S driver before any have completed.
|
||||
* CONFIG_CS43L22_MSG_PRIO - Priority of messages sent to the CS43L22 worker
|
||||
* thread.
|
||||
* CONFIG_CS43L22_BUFFER_SIZE - Preferred buffer size
|
||||
* CONFIG_CS43L22_NUM_BUFFERS - Preferred number of buffers
|
||||
* CONFIG_CS43L22_WORKER_STACKSIZE - Stack size to use when creating the the
|
||||
* CS43L22 worker thread.
|
||||
* CONFIG_CS43L22_REGDUMP - Enable logic to dump all CS43L22 registers to
|
||||
* the SYSLOG device.
|
||||
*/
|
||||
|
||||
/* Pre-requisites */
|
||||
|
||||
#ifndef CONFIG_AUDIO
|
||||
# error CONFIG_AUDIO is required for audio subsystem support
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_I2S
|
||||
# error CONFIG_I2S is required by the CS43L22 driver
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_I2C
|
||||
# error CONFIG_I2C is required by the CS43L22 driver
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SCHED_WORKQUEUE
|
||||
# error CONFIG_SCHED_WORKQUEUE is required by the CS43L22 driver
|
||||
#endif
|
||||
|
||||
/* Default configuration values */
|
||||
|
||||
#ifndef CONFIG_CS43L22_INITVOLUME
|
||||
# define CONFIG_CS43L22_INITVOLUME 400
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CS43L22_INFLIGHT
|
||||
# define CONFIG_CS43L22_INFLIGHT 2
|
||||
#endif
|
||||
|
||||
#if CONFIG_CS43L22_INFLIGHT > 255
|
||||
# error CONFIG_CS43L22_INFLIGHT must fit in a uint8_t
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CS43L22_MSG_PRIO
|
||||
# define CONFIG_CS43L22_MSG_PRIO 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CS43L22_BUFFER_SIZE
|
||||
# define CONFIG_CS43L22_BUFFER_SIZE 8192
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CS43L22_NUM_BUFFERS
|
||||
# define CONFIG_CS43L22_NUM_BUFFERS 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CS43L22_WORKER_STACKSIZE
|
||||
# define CONFIG_CS43L22_WORKER_STACKSIZE 768
|
||||
#endif
|
||||
|
||||
/* Helper macros ************************************************************/
|
||||
|
||||
#define CS43L22_ATTACH(s,isr,arg) ((s)->attach(s,isr,arg))
|
||||
#define CS43L22_DETACH(s) ((s)->attach(s,NULL,NULL))
|
||||
#define CS43L22_ENABLE(s) ((s)->enable(s,true))
|
||||
#define CS43L22_DISABLE(s) ((s)->enable(s,false))
|
||||
#define CS43L22_RESTORE(s,e) ((s)->enable(s,e))
|
||||
#define CS43L22_HW_RESET(s) ((s)->reset(s))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
/* This is the type of the CS43L22 interrupt handler. The lower level code
|
||||
* will intercept the interrupt and provide the upper level with the private
|
||||
* data that was provided when the interrupt was attached.
|
||||
*/
|
||||
|
||||
struct cs43l22_lower_s; /* Forward reference. Defined below */
|
||||
|
||||
typedef CODE int (*cs43l22_handler_t)(FAR const struct cs43l22_lower_s *lower,
|
||||
FAR void *arg);
|
||||
|
||||
/* A reference to a structure of this type must be passed to the CS43L22
|
||||
* driver. This structure provides information about the configuration
|
||||
* of the CS43L22 and provides some board-specific hooks.
|
||||
*
|
||||
* Memory for this structure is provided by the caller. It is not copied
|
||||
* by the driver and is presumed to persist while the driver is active.
|
||||
*/
|
||||
|
||||
struct cs43l22_lower_s
|
||||
{
|
||||
/* I2C characterization */
|
||||
|
||||
uint32_t frequency; /* Initial I2C frequency */
|
||||
uint8_t address; /* 7-bit I2C address (only bits 0-6 used) */
|
||||
|
||||
/* Clocking is provided via MCLK. The CS43L22 driver will need to know
|
||||
* the frequency of MCLK in order to generate the correct bitrates.
|
||||
*/
|
||||
|
||||
uint32_t mclk; /* CS43L22 Master clock frequency */
|
||||
|
||||
/* IRQ/GPIO access callbacks. These operations all hidden behind
|
||||
* callbacks to isolate the CS43L22 driver from differences in GPIO
|
||||
* interrupt handling by varying boards and MCUs. If possible,
|
||||
* interrupts should be configured on both rising and falling edges
|
||||
* so that contact and loss-of-contact events can be detected.
|
||||
*
|
||||
* attach - Attach or detach the CS43L22 interrupt handler to the GPIO
|
||||
* interrupt
|
||||
* enable - Enable or disable the GPIO interrupt. Returns the
|
||||
* previous interrupt state.
|
||||
* reset - HW reset of the CS43L22 chip
|
||||
*/
|
||||
|
||||
CODE int (*attach)(FAR const struct cs43l22_lower_s *lower,
|
||||
cs43l22_handler_t isr, FAR void *arg);
|
||||
CODE bool (*enable)(FAR const struct cs43l22_lower_s *lower, bool enable);
|
||||
CODE void (*reset)(FAR const struct cs43l22_lower_s *lower);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cs43l22_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the CS43L22 device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* i2c - An I2C driver instance
|
||||
* i2s - An I2S driver instance
|
||||
* lower - Persistent board configuration data
|
||||
*
|
||||
* Returned Value:
|
||||
* A new lower half audio interface for the CS43L22 device is returned on
|
||||
* success; NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct i2c_master_s; /* Forward reference. Defined in include/nuttx/i2c/i2c_master.h */
|
||||
struct i2s_dev_s; /* Forward reference. Defined in include/nuttx/audio/i2s.h */
|
||||
struct audio_lowerhalf_s; /* Forward reference. Defined in nuttx/audio/audio.h */
|
||||
|
||||
FAR struct audio_lowerhalf_s *
|
||||
cs43l22_initialize(FAR struct i2c_master_s *i2c, FAR struct i2s_dev_s *i2s,
|
||||
FAR const struct cs43l22_lower_s *lower);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cs43l22_dump_registers
|
||||
*
|
||||
* Description:
|
||||
* Dump the contents of all CS43L22 registers to the syslog device
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by cs43l22_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_REGDUMP
|
||||
void cs43l22_dump_registers(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg);
|
||||
#else
|
||||
/* This eliminates the need for any conditional compilation in the
|
||||
* including file.
|
||||
*/
|
||||
|
||||
# define cs43l22_dump_registers(d,m)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cs43l22_clock_analysis
|
||||
*
|
||||
* Description:
|
||||
* Analyze the settings in the clock chain and dump to syslog.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The device instance returned by cs43l22_initialize
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CS43L22_CLKDEBUG
|
||||
void cs43l22_clock_analysis(FAR struct audio_lowerhalf_s *dev,
|
||||
FAR const char *msg);
|
||||
#else
|
||||
/* This eliminates the need for any conditional compilation in the
|
||||
* including file.
|
||||
*/
|
||||
|
||||
# define cs43l22_clock_analysis(d,m)
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_AUDIO_CS43L22 */
|
||||
#endif /* __INCLUDE_NUTTX_AUDIO_CS43L22_H */
|
Loading…
x
Reference in New Issue
Block a user