4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2011 Develer S.r.l. (http://www.develer.com/)
33 * \author Daniele Basile <asterix@develer.com>
35 * \brief WM8731 Audio codec 2 wire driver.
39 #include "hw/hw_wm8731.h"
40 #include "cfg/cfg_wm8731.h"
47 #define WM8731_REG_RESET 0x0F
49 /* Left Line in register */
50 #define WM8731_REG_LEFT_LINEIN 0x0
51 #define WM8731_LINVOL_BITS_MASK 0xF // Left line input volume control
52 #define WM8731_LINMUTE_BIT 7 // Left line input mute to ADC
53 #define WM8731_LRINBOTH_BIT 8 // Left to right channel line input volume and mute data load control
55 /* Right Line in register */
56 #define WM8731_REG_RIGHT_LINEIN 0x1
57 #define WM8731_RINVOL_BITS_MASK 0xF // Right line input volume control
58 #define WM8731_RINMUTE_BIT 7 // Right line input mute to ADC
59 #define WM8731_RLINBOTH_BIT 8 // Right to right channel line input volume and mute data load control
61 /* Left Headphone out register*/
62 #define WM8731_REG_LEFT_HPOUT 0x2
63 #define WM8731_LHPVOL_BITS_MASK 0x7 // Left chnnel headphone output volume control
64 #define WM8731_LZCEN_BIT 7 // Left channel zero cross detect enable
65 #define WM8731_LRHPBOTH_BIT 8 // Left to right channel headphone volume, mute and zero cross data load control
67 /* Right Headphone out register*/
68 #define WM8731_REG_RIGHT_HPOUT 0x3
69 #define WM8731_RHPVOL_BITS_MASK 0x7 // Right chnnel headphone output volume control
70 #define WM8731_RZCEN_BIT 7 // Right channel zero cross detect enable
71 #define WM8731_RLHPBOTH_BIT 8 // Right to right channel headphone volume, mute and zero cross data load control
73 /* Analogue audio path control register*/
74 #define WM8731_REG_ANALOGUE_PATH_CTRL 0x4
75 #define WM8731_MICBOOST 0 // Microphone Input Level Boost
76 #define WM8731_MUTEMIC 1 // Line input Mute to ADC
77 #define WM8731_INSEL 2 // Microphone/Line Select to ADC
78 #define WM8731_BYPASS 3 // Bypass switch
79 #define WM8731_DACSEL 4 // DAC select
80 #define WM8731_SIDETONE 5 // Side tone switch
81 #define WM8731_SIDEATT_MASK 0xC0 // Side tone attenuation
82 #define WM8731_SIDEATT_15dB 0xC0 // -15dB
83 #define WM8731_SIDEATT_12dB 0x80 // -12dB
84 #define WM8731_SIDEATT_9dB 0x40 // -9dB
85 #define WM8731_SIDEATT_6dB 0x00 // -6dB
88 /* Digital audio path control register*/
89 #define WM8731_REG_DIGITAL_PATH_CTRL 0x5
90 #define WM8731_ADCHPD 0 // ADC high pass filter enable
91 #define WM8731_DEEMP_MASK 0x6 // De-emphasis controll
92 #define WM8731_DEEMP_48kHz 0x6 // 48kHz
93 #define WM8731_DEEMP_44k1Hz 0x4 // 44.1kHz
94 #define WM8731_DEEMP_32kHz 0x2 // 32kHz
95 #define WM8731_DEEMP_DISABLE 0x0 // Disable
96 #define WM8731_DACMU 3 // DAC Soft Mute control
98 /* Power down control register*/
99 #define WM8731_REG_PWDOWN_CTRL 0x6
100 #define WM8731_LINEINPD_BIT 0 // LineIn power down
101 #define WM8731_MICPD_BIT 1 // Mic power down
102 #define WM8731_ADCPD_BIT 2 // ADC power down
103 #define WM8731_DACPD_BIT 3 // DAC power down
104 #define WM8731_OUTPD_BIT 4 // OUT power down
105 #define WM8731_OSCBIT 5 // OSC power down
106 #define WM8731_CLKOUTPD_BIT 6 // CLKOUT powerdown
107 #define WM8731_POWEROFF_BIT 7 // Power off device
109 /* Interface format register*/
110 #define WM8731_REG_DA_INTERFACE_FORMAT 0x7
111 #define WM8731_FORMAT_BITS_MASK 0x3 // Format
112 #define WM8731_FORMAT_MSB_LEFT_JUSTIFIED 0x0 // MSB-First, left justified
113 #define WM8731_FORMAT_MSB_RIGHT_JUSTIFIED 0x1 // MSB-First, right justified
114 #define WM8731_FORMAT_I2S 0x2 //I2S Format, MSB-First left-1 justified
115 #define WM8731_FORMAT_DSP 0x3 //DSP Mode, frame sync + 2 data packed words
116 #define WM8731_IWL_BITS 0xC // Input audio data bit length select
117 #define WM8731_IWL_16_BIT 0x0 // 16 bit
118 #define WM8731_IWL_20_BIT 0x4 // 20 bit
119 #define WM8731_IWL_24_BIT 0x8 // 24 bit
120 #define WM8731_IWL_32_BIT 0xC // 32 bit
121 #define WM8731_IRP_BITS 4 // DACLRC phase control
122 #define WM8731_IRSWAP_BIT 5 // DAC Left right clock swap
123 #define WM8731_MS_BIT 6 // Master slave mode control
124 #define WM8731_BCLKINV_BIT 7 // Bit clock invert
126 /* Sampling control*/
127 #define WM8731_REG_SAMPLECTRL 0x8
128 #define WM8731_USBNORMAL_BIT 0 // Mode select, usb mode, normal mode
129 #define WM8731_BOSR_BIT 1 // Base over-sampling rate
130 #define WM8731_SR_BITS_MASK 0x3C // Sample rate control
131 #define WM8731_CLKIDIV2_BIT 6 // Core clock divider select
132 #define WM8731_CLKODIV2_BIT 7 // CLKOUT divider select
134 /* Active control register*/
135 #define WM8731_REG_ACTIVE_CTRL 0x9
136 #define WM8731_ACTIVE_BIT 0 // Activate interface
139 * Codec has 7-bit address, the eighth is the R/W bit, so we
140 * write the codec address with one bit shifted left
142 #define CODEC_ADDR 0x36
147 static void wm8731_write(uint8_t reg, uint16_t value)
150 uint16_t tmp = ((reg & 0x7f) << 9) | (value & 0x1ff);
151 uint8_t msb = (tmp & 0xFF00) >> 8;
152 uint8_t lsb = tmp & 0xFF;
154 kprintf("msb: %0x lsb: %0x\n", msb, lsb);
156 i2c_start_w(&i2c, CODEC_ADDR, 2, I2C_STOP);
166 void wm8731_init(void)