blob: 622cf7e3c3fedf0ae87959eb7f20dee3d2a52edb [file] [log] [blame]
/****************************************************************************
* boards/arm/stm32/axoloti/src/stm32_adau1961.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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 <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/adau1961.h>
#include <arch/board/board.h>
#include "stm32.h"
#include "axoloti.h"
#ifdef HAVE_ADAU1961
/****************************************************************************
* Private Types
****************************************************************************/
struct stm32_mwinfo_s
{
/* Standard ADAU1961 interface */
struct adau1961_lower_s lower;
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int adau1961_attach(const struct adau1961_lower_s *lower,
adau1961_handler_t isr, void *arg)
{
audinfo("TODO\n");
return 0;
}
static bool adau1961_enable(const struct adau1961_lower_s *lower,
bool enable)
{
audinfo("TODO\n");
return 0;
}
static void adau1961_hw_reset(const struct adau1961_lower_s *lower)
{
audinfo("TODO\n");
}
/****************************************************************************
* Private Data
****************************************************************************/
/* A reference to a structure of this type must be passed to the ADAU1961
* driver. This structure provides information about the configuration
* of the ADAU1961 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.
*/
static struct stm32_mwinfo_s g_adau1961info =
{
.lower =
{
.address = ADAU1961_I2C_ADDRESS,
.frequency = I2C_SPEED_FAST, /* 400 kHz */
.mclk = STM32_HSE_FREQUENCY, /* see MCO1 configuration */
.attach = adau1961_attach,
.enable = adau1961_enable,
.reset = adau1961_hw_reset,
}
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_adau1961_initialize
*
* Description:
* This function is called by platform-specific, setup logic to configure
* and register the ADAU1961 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_adau1961_initialize(int minor)
{
struct audio_lowerhalf_s *adau1961;
struct i2c_master_s *i2c;
struct i2s_dev_s *i2s;
static bool initialized = false;
char devname[12];
int ret;
audinfo("minor %d\n", minor);
DEBUGASSERT(minor >= 0 && minor <= 25);
/* Initialize the CODEC if we have not already done so */
if (!initialized)
{
/* Configure MC01 to drive the master clock of the CODEC at 8MHz */
stm32_configgpio(GPIO_MCO1);
stm32_mco1config(RCC_CFGR_MCO1_HSE, RCC_CFGR_MCO1PRE_NONE);
/* Get an instance of the I2C interface for the CODEC */
i2c = stm32_i2cbus_initialize(ADAU1961_I2C_BUS);
if (!i2c)
{
auderr("stm32_i2cbus_initialize failed\n");
ret = -ENODEV;
goto error;
}
/* Get an instance of the I2S interface for the CODEC data streams */
i2s = stm32_sai_initialize(ADAU1961_SAI_BUS);
if (!i2s)
{
auderr("stm32_sai_initialize failed\n");
ret = -ENODEV;
goto error;
}
/* Now we can use these I2C and I2S interfaces to initialize the
* CODEC which will return an audio interface.
*/
adau1961 = adau1961_initialize(i2c, i2s, &g_adau1961info.lower);
if (!adau1961)
{
auderr("adau1961_initialize failed\n");
ret = -ENODEV;
goto error;
}
/* Create a device name */
snprintf(devname, sizeof(devname), "pcm%d", minor);
/* Finally, we can register the ADAU1961/I2C/I2S audio device. */
ret = audio_register(devname, adau1961);
if (ret < 0)
{
auderr("failed to register /dev/%s device: %d\n", devname, ret);
goto error;
}
/* 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.
*/
error:
return ret;
}
#endif /* HAVE_ADAU1961 */