From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- components/codec-ak4641/ak4641.c | 225 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 components/codec-ak4641/ak4641.c (limited to 'components/codec-ak4641/ak4641.c') diff --git a/components/codec-ak4641/ak4641.c b/components/codec-ak4641/ak4641.c new file mode 100644 index 0000000..f53a08d --- /dev/null +++ b/components/codec-ak4641/ak4641.c @@ -0,0 +1,225 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include +#include +#include +#include "ak4641.h" + +//------------------------------------------------------------------------------ +// Internal definitions +//------------------------------------------------------------------------------ + +// 5-bit address of an AK4641 component on the TWI interface +#define AK4641_SLAVEADDRESS 0x12 + +// Register addresses +// Power management 1 register address +#define AK4641_POWMGT1 0x00 +// Power management 2 register address +#define AK4641_POWMGT2 0x01 +// Signal select 2 register address +#define AK4641_SIGSEL2 0x03 +// DAC control register address +#define AK4641_DACCTRL 0x06 +// MIC control register address +#define AK4641_MICCTRL 0x07 + +// Register field values +// Power management 1 register +// Powers up the ADC block of the stereo CODEC +#define AK4641_POWMGT1_PMADC (1 << 0) +// Powers up the MIC in block of the stereo CODEC +#define AK4641_POWMGT1_PMMIC (1 << 1) +// Powers up the AUX in block of the stereo CODEC +#define AK4641_POWMGT1_PMAUX (1 << 2) +// Powers up the Mont out block of the stereo CODEC +#define AK4641_POWMGT1_PMMO (1 << 3) +// Powers up the Line out block of the stereo CODEC +#define AK4641_POWMGT1_PMLO (1 << 4) +// Powers up the VCOM block of the stereo DEOC +#define AK4641_POWMGT1_PMVCM (1 << 7) + +// Power management 2 register +// Powers up the DAC block of the stereo CODEC +#define AK4641_POWMGT2_PMDAC (1 << 0) +// Powers up the Mono out 2 block of the stereo CODEC +#define AK4641_POWMGT2_PMMO2 (1 << 3) +// Sets the master clock input mode to AC-coupling +#define AK4641_POWMGT2_MCKAC (1 << 4) +// Disables the master clock input buffer control +#define AK4641_POWMGT2_MCKPD (1 << 7) + +// Signal select 2 register +// Selects the right channel line output +#define AK4641_SIGSEL2_PSLOR (1 << 0) +// Selects the left channel line output +#define AK4641_SIGSEL2_PSLOL (1 << 1) +// Selects AUX single-ended output +#define AK4641_SIGSEL2_AUXSI (1 << 2) +// Sets MIC in as the line out mixer output +#define AK4641_SIGSEL2_MICL (1 << 4) +// Sets AUX in as the line out mixer output +#define AK4641_SIGSEL2_AUXL (1 << 5) +// Sets the DAC as the line out mixer output +#define AK4641_SIGSEL2_DACL (1 << 7) + +// DAC control register +// De-emphasis filter for a 44.1kHz sample rate +#define AK4641_DACCTRL_DEM44_1 0 +// Disables the de-emphasis filter +#define AK4641_DACCTRL_DEMDIS 1 +// De-emphasis filter for a 48kHz sample rate +#define AK4641_DACCTRL_DEM48 2 +// De-emphasis filter for a 32kHz sample rate +#define AK4641_DACCTRL_DEM32 3 +// Attenuator level for left & right channels controlled by the ATTL6-0 bits +#define AK4641_DACCTRL_DATTC (1 << 4) +// Soft-mutes the DAC +#define AK4641_DACCTRL_SMUTE (1 << 5) +// Sets the soft mute time setting to 256/Fs +#define AK4641_DACCTRL_TM (1 << 6) + +// MIC control register +// Enables the 20dB gain on the microphone input +#define AK4641_MICCTRL_MGAIN (1 << 0) +// Select the microphone as the ADC input +#define AK4641_MICCTRL_MICAD (1 << 2) +// Enables the power supply input for the internal microphone +#define AK4641_MICCTRL_MPWRI (1 << 3) + +//------------------------------------------------------------------------------ +// Internal functions +//------------------------------------------------------------------------------ +/*! + Reads data (using the given \a twi peripheral) from an AK4146 starting with + a particular \a registerAddress and stores it in the provided \a buffer. + Data is read until the buffer is filled to its \a bufferSize. + + This function returns true if the read operation was successful; otherwise + it returns false. + */ +inline unsigned char AK4641_Read(AT91S_TWI *twi, + void *buffer, + unsigned int bufferSize, + unsigned char registerAddress) +{ + return TWI_Read(twi, + buffer, + bufferSize, + AK4641_SLAVEADDRESS, + registerAddress, + 1); +} + +/*! + Writes (through a \a twi interface) the content of the provided \a buffer + in the registers of an AK4641 component, starting at the specified + \a registerAddress. + + This function returns true if the write operation was successful; otherwise + it returns false. + */ +inline unsigned char AK4641_Write(AT91S_TWI *twi, + void *buffer, + unsigned int bufferSize, + unsigned char registerAddress) +{ + return TWI_Write(twi, + buffer, + bufferSize, + AK4641_SLAVEADDRESS, + registerAddress, + 1); +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +/*! + Configures an external AK4641 component, through the specified \a twi + interface. + + The TWI interface and the AK4641 master clock must both be already + configured properly before calling this method. + */ +inline void AK4641_Configure(AT91S_TWI *twi) +{ + unsigned char value; + unsigned char values[20]; + + // Power up the ADC and VCOM blocks + value = AK4641_POWMGT1_PMADC | AK4641_POWMGT1_PMVCM; + AK4641_Write(twi, &value, 1, AK4641_POWMGT1); + + // Power up the DAC + value = AK4641_POWMGT2_PMDAC; + AK4641_Write(twi, &value, 1, AK4641_POWMGT2); + + // Select the right and left channel outputs, enable the DAC output + value = AK4641_SIGSEL2_PSLOR | AK4641_SIGSEL2_PSLOL | AK4641_SIGSEL2_DACL; + AK4641_Write(twi, &value, 1, AK4641_SIGSEL2); + + // Disable the de-emphasis filter + value = AK4641_DACCTRL_DEMDIS;// | AK4641_DACCTRL_SMUTE; + AK4641_Write(twi, &value, 1, AK4641_DACCTRL); + + // Enable the MIC 20dB gain and the internal MIC power supply + value = AK4641_MICCTRL_MGAIN | AK4641_MICCTRL_MICAD | AK4641_MICCTRL_MPWRI; + AK4641_Write(twi, &value, 1, AK4641_MICCTRL); + + // Power up the Line out and Mic blocks + value = AK4641_POWMGT1_PMMIC | AK4641_POWMGT1_PMADC + | AK4641_POWMGT1_PMVCM | AK4641_POWMGT1_PMLO; + AK4641_Write(twi, &value, 1, AK4641_POWMGT1); +} + +/*! + Mutes or unmutes an external AK4641 component connected to the given \a twi + peripheral, depending on the value of the \a muted parameter. + */ +inline void AK4641_SetMuted(AT91S_TWI *twi, unsigned char muted) +{ + if (muted) { + + unsigned char value = AK4641_DACCTRL_DEMDIS | AK4641_DACCTRL_SMUTE; + AK4641_Write(twi, &value, 1, AK4641_DACCTRL); + } + else { + + unsigned char value = AK4641_DACCTRL_DEMDIS; + AK4641_Write(twi, &value, 1, AK4641_DACCTRL); + } +} + -- cgit v1.2.3