1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Gigabeat S specific code for the WM8978 codec
12 * Copyright (C) 2008 Michael Sevakis
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
28 #include "i2c-imx31.h"
30 /* NOTE: Some port-specific bits will have to be moved away (node and GPIO
31 * writes) for cleanest implementation. */
33 static struct i2c_node wm8978_i2c_node
=
36 .ifdr
= I2C_IFDR_DIV192
, /* 66MHz/.4MHz = 165, closest = 192 = 343750Hz */
37 /* Just hard-code for now - scaling may require
42 void audiohw_init(void)
44 /* How SYSCLK for codec is derived (USBPLL=338.688MHz).
46 * SSI post dividers (SSI2 PODF=4, SSI2 PRE PODF=0):
47 * 338688000Hz / 5 = 67737600Hz = ssi1_clk
49 * SSI bit clock dividers (DIV2=1, PSR=0, PM=0):
50 * ssi1_clk / 4 = 16934400Hz = INT_BIT_CLK (MCLK)
52 * WM Codec post divider (MCLKDIV=1.5):
53 * INT_BIT_CLK (MCLK) / 1.5 = 11289600Hz = 256*fs = SYSCLK
55 imx31_regmod32(&CLKCTL_PDR1
,
56 PDR1_SSI1_PODFw(5-1) | PDR1_SSI2_PODFw(64-1) |
57 PDR1_SSI1_PRE_PODFw(1-1) | PDR1_SSI2_PRE_PODFw(8-1),
58 PDR1_SSI1_PODF
| PDR1_SSI2_PODF
|
59 PDR1_SSI1_PRE_PODF
| PDR1_SSI2_PRE_PODF
);
61 i2c_enable_node(&wm8978_i2c_node
, true);
65 imx31_regset32(&GPIO3_DR
, (1 << 21)); /* Turn on analogue LDO */
68 void audiohw_enable_headphone_jack(bool enable
)
70 /* Turn headphone jack output on or off. */
71 imx31_regmod32(&GPIO3_DR
, enable
? (1 << 22) : 0, (1 << 22));
74 void wmcodec_write(int reg
, int data
)
77 /* |aaaaaaad|dddddddd| */
78 d
[0] = (reg
<< 1) | ((data
& 0x100) >> 8);
80 i2c_write(&wm8978_i2c_node
, d
, 2);