/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * wm8523.h * * Tue Jun 4 20:47:15 CEST 2013 * Copyright 2013 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Pedal2Metal. * * Pedal2Metal is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Pedal2Metal is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pedal2Metal; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifndef __PEDAL2METAL_WM8523_H__ #define __PEDAL2METAL_WM8523_H__ #include typedef enum { WM8523_FS_8K, WM8523_FS_32K, WM8523_FS_44K1, WM8523_FS_48K, WM8523_FS_88K2, WM8523_FS_96K, WM8523_FS_176K4, WM8523_FS_192K, } wm8523_samplerate_t; /** * Prepare I2S, SSP and GPIO. */ void wm8523_init(uint8_t portnum, wm8523_samplerate_t fs); /** * Read chip ID. * Is always 0x8523 * Register: R0 [0:15] (read) * Default: 1000 0101 0010 0011 */ #define WM8532_CHIP_ID 0b1000010100100011 unsigned short wm8523_get_chip_id(uint8_t portnum); /** * Reset all register values to their defaults. * Register: R0 [0:15] (write) */ void wm8523_reset_registers(uint8_t portnum); /** * Read hardware revision counter. * Register: R1 [0:2] (read) */ uint8_t wm8523_get_hardware_revision(uint8_t portnum); typedef enum __attribute__ ((packed)) { WM8523_PWR_OFF = 0b00, WM8523_PWR_POWER_DOWN = 0b01, WM8523_PWR_POWER_UP_TO_MUTE = 0b10, WM8523_PWR_POWER_UP_TO_UNMUTE = 0b11, } wm8523_power_mode_t; /** * Get current power mode. * Register: R2 [0:1] (read) */ wm8523_power_mode_t wm8523_get_power_mode(uint8_t portnum); /** * Set power mode. * Register: R2 [0:1] (write) */ void wm8523_set_power_mode(uint8_t portnum, wm8523_power_mode_t mode); /* R3 [0:1] Audio Data Interface Format 00 = Right justified 01 = Left justified 10 = I2S format 11 = DSP mode */ typedef enum __attribute__ ((packed)) { WM8523_FMT_RIGHT = 0b00, // Right justified WM8523_FMT_LEFT = 0b01, // Left justified WM8523_FMT_I2S = 0b10, // I2S format WM8523_FMT_DSP = 0b11, // DSP mode } wm8523_audio_data_interface_format_t; /* R3 [3:4] Audio Data Word Length 00 = 16 bits 01 = 20 bits 10 = 24 bits 11 = 32 bits */ typedef enum __attribute__ ((packed)) { WM8523_WLEN_16 = 0b00, // 16 bit word length WM8523_WLEN_20 = 0b01, // 20 bit word length WM8523_WLEN_24 = 0b10, // 24 bit word length WM8523_WLEN_32 = 0b11, // 32 bit word length } wm8523_audio_data_word_length_t; /* R3 [5] BCLK Inversion Control Slave mode: 0 = Use rising edge 1 = Use falling edge Master mode: 0 = BCLK normal 1 = BCLK inverted */ typedef enum __attribute__ ((packed)) { // Slave mode: WM8523_INVCTL_SLAVE_RISING = 0b0, // Use rising edge WM8523_INVCTL_SLAVE_FALLING = 0b1, // Use falling edge // Master mode: WM8523_INVCTL_MASTER_NORMAL = 0b0, // BCLK normal WM8523_INVCTL_MASTER_INVERTED = 0b1, // BCLK inverted } wm8523_bclk_inversion_control_t; /* R3 [6] LRCLK Inversion Control 0 = Normal polarity 1 = Inverted polarity When AIF_FMT[2:0]=011 (DSP Mode): 0 = Mode A (2nd clock) 1 = Mode B (1st clock) */ typedef enum __attribute__ ((packed)) { // Slave mode: WM8523_LRCLKINVCTL_SLAVE_NORMAL = 0b0, // Normal polarity WM8523_LRCLKINVCTL_SLAVE_INVERTED = 0b1, // Inverted polarity // Master mode: WM8523_LRCLKINVCTL_MASTER_MODE_A = 0b0, // Mode A (2nd clock) WM8523_LRCLKINVCTL_MASTER_MODE_B = 0b1, // Mode B (1st clock) } wm8523_lrclk_inversion_control_t; /* R3 [7] Master/Slave Select 0 = Slave mode 1 = Master mode */ typedef enum __attribute__ ((packed)) { WM8523_MODESEL_SLAVE = 0b0, // Slave mode WM8523_MODESEL_MASTER = 0b1, // Master mode } wm8523_slave_master_mode_sel_t; /* R3 [8] DAC De-emphasis Control 0 = No de-emphasis 1 = De-emphasis enabled */ typedef enum __attribute__ ((packed)) { WM8523_DEEMPH_DISABLED = 0b0, // No de-emphasis WM8523_DEEMPH_ENABLED = 0b1, // De-emphasis enabled } wm8523_dac_deemphasis_control_t; typedef struct __attribute__ ((packed)) { wm8523_audio_data_interface_format_t fmt:2; int reserved:1; wm8523_audio_data_word_length_t wlen:2; wm8523_bclk_inversion_control_t invctl:1; wm8523_lrclk_inversion_control_t lrclkinvctl:1; wm8523_slave_master_mode_sel_t modesel:1; wm8523_dac_deemphasis_control_t deemp:1; uint16_t blank:7; } wm8523_aif_ctrl1_t; void wm8523_set_aif_ctrl1(uint8_t portnum, wm8523_aif_ctrl1_t aif_ctrl1); wm8523_aif_ctrl1_t wm8523_get_aif_ctrl1(uint8_t portnum); /* R4 [0:2] MCLK:LRCLK Ratio 000 = Auto detect 001 = 128fs 010 = 192fs 011 = 256fs 100 = 384fs 101 = 512fs 110 = 768fs 111 = 1152fs */ typedef enum __attribute__ ((packed)) { WM8523_CLKRATIO_AUTO = 0b000, // Auto detect WM8523_CLKRATIO_128_FS = 0b001, // 128fs WM8523_CLKRATIO_192_FS = 0b010, // 192fs WM8523_CLKRATIO_256_FS = 0b011, // 256fs WM8523_CLKRATIO_384_FS = 0b100, // 384fs WM8523_CLKRATIO_512_FS = 0b101, // 512fs WM8523_CLKRATIO_768_FS = 0b110, // 768fs WM8523_CLKRATIO_1152_FS = 0b111, // 1152fs } wm8523_mclk_lrclk_ratio_t; /* R4 [3:5] BCLK Divider Control (Master Mode) 000 = MCLK/4 001 = MCLK/8 010 = 32fs 011 = 64fs 100 = 128fs 101 - 111 reserved */ typedef enum __attribute__ ((packed)) { WM8523_CLKDIV_MCLK_4 = 0b000, // MCLK/4 WM8523_CLKDIV_MCLK_8 = 0b001, // MCLK/8 WM8523_CLKDIV_32_FS = 0b010, // 32fs WM8523_CLKDIV_64_FS = 0b011, // 64fs WM8523_CLKDIV_128_FS = 0b100, // 128fs } wm8523_bclk_divider_control_t; /* R4 [6:7] Digital Monomix Control 00 = Stereo (normal operation) 01 = Mono (Left data to DACR) 10 = Mono (Right data to DACL) 11 = Digital monomix, (L+R)/2 */ typedef enum __attribute__ ((packed)) { WM8523_MIX_STEREO = 0b00, // Stereo (normal operation) WM8523_MIX_MONO_LEFT = 0b01, // Mono (Left data to DACR) WM8523_MIX_MONO_RIGHT = 0b10, // Mono (Right data to DACL) WM8523_MIX_MONO_MIXED = 0b11, // Digital monomix, (L+R)/2 } wm8523_digital_monomix_control_t; typedef struct __attribute__ ((packed)) { wm8523_mclk_lrclk_ratio_t clkratio:3; wm8523_bclk_divider_control_t clkdiv:3; wm8523_digital_monomix_control_t mix:2; } wm8523_aif_ctrl2_t; void wm8523_set_aif_ctrl2(uint8_t portnum, wm8523_aif_ctrl2_t aif_ctrl2); wm8523_aif_ctrl2_t wm8523_get_aif_ctrl2(uint8_t portnum); /* R5 [0] DAC Digital Volume Decrease Control 0 = Apply volume decreases instantly (step) 1 = Ramp volume decreases */ typedef enum __attribute__ ((packed)) { WM8523_VOL_DOWN_RAMP = 0b00, // Apply volume decreases instantly (step) WM8523_VOL_DOWN_INSTANT = 0b01, // Ramp volume decreases } wm8523_dac_vol_down_ramp_t; /* R5 [1] DAC Digital Volume Increase Control 0 = Apply volume increases instantly (step) 1 = Ramp volume increases */ typedef enum __attribute__ ((packed)) { WM8523_VOL_UP_RAMP = 0b00, // Apply volume increases instantly (step) WM8523_VOL_UP_INSTANT = 0b01, // Ramp volume increases } wm8523_dac_vol_up_ramp_t; /* R5 [2] Left DAC Mute 0 = Normal operation 1 = Mute */ typedef enum __attribute__ ((packed)) { WM8523_DACL_UNMUTE = 0b00, // Normal operation WM8523_DACL_MUTE = 0b01, // Mute } wm8523_dacl_mute_t; /* R5 [3] Right DAC Mute 0 = Normal operation 1 = Mute */ typedef enum __attribute__ ((packed)) { WM8523_DACR_UNMUTE = 0b00, // Normal operation WM8523_DACR_MUTE = 0b01, // Mute } wm8523_dacr_mute_t; /* R5 [4] Zero Cross Enable 0 = Do not use zero cross 1 = Use zero cross */ typedef enum __attribute__ ((packed)) { WM8523_ZERO_CROSSING_DISABLED = 0b00, // Do not use zero cross WM8523_ZERO_CROSSING_ENABLED = 0b01, // Use zero cross } wm8523_dac_zc_t; typedef struct __attribute__ ((packed)) { wm8523_dac_vol_down_ramp_t downramp:1; wm8523_dac_vol_up_ramp_t upramp:1; wm8523_dacl_mute_t lmute:1; wm8523_dacr_mute_t rmute:1; wm8523_dac_zc_t dac_zc:1; } wm8523_dac_ctrl3_t; void wm8523_set_dac_ctrl3(uint8_t portnum, wm8523_dac_ctrl3_t dac_ctrl3); wm8523_dac_ctrl3_t wm8523_get_dac_ctrl3(uint8_t portnum); /* R6 [0:8] Left DAC Digital Volume Control 0 0000 0000 = -100dB 0 0000 0001 = -99.75dB 0 0000 0010 = -99.5dB ...0.25dB steps 1 1001 0000 = 0dB ...0.25dB steps 1 1011 1110 = +11.75dB 1 11XX XXXX = +12dB */ /* R6 [9] Left DAC Digital Volume Update 0 = Latch Left DAC volume setting into register map but do not update volume 1 = Latch Left DAC volume setting into register map and update left and right channels simultaneously */ /* R7 [0:8] Right DAC Digital Volume Control 0 0000 0000 = -100dB 0 0000 0001 = -99.75dB 0 0000 0010 = -99.5dB ...0.25dB steps 1 1001 0000 = 0dB ...0.25dB steps 1 1011 1110 = +11.75dB 1 11XX XXXX = +12dB */ /* R7 [9] Right DAC Digital Volume Update 0 = Latch Right DAC volume setting into register map but do not update volume 1 = Latch Right DAC volume setting into register map and update left and right channels simultaneously */ /* R8 [0] Zero Detect Count Control 0 = 1024 1 = 2048 */ void wm8523_tone(); //void wm8523_configure(); //uint16_t wm8523_read(uint8_t reg); //void wm8523_write(uint8_t reg, uint16_t data); #endif/*__PEDAL2METAL_WM8523_H__*/