1*a2d8e0a7SRajeshwari Shinde /* 2*a2d8e0a7SRajeshwari Shinde * Copyright (C) 2012 Samsung Electronics 3*a2d8e0a7SRajeshwari Shinde * R. Chandrasekar <rcsekar@samsung.com> 4*a2d8e0a7SRajeshwari Shinde * 5*a2d8e0a7SRajeshwari Shinde * See file CREDITS for list of people who contributed to this 6*a2d8e0a7SRajeshwari Shinde * project. 7*a2d8e0a7SRajeshwari Shinde * 8*a2d8e0a7SRajeshwari Shinde * This program is free software; you can redistribute it and/or 9*a2d8e0a7SRajeshwari Shinde * modify it under the terms of the GNU General Public License as 10*a2d8e0a7SRajeshwari Shinde * published by the Free Software Foundation; either version 2 of 11*a2d8e0a7SRajeshwari Shinde * the License, or (at your option) any later version. 12*a2d8e0a7SRajeshwari Shinde * 13*a2d8e0a7SRajeshwari Shinde * This program is distributed in the hope that it will be useful, 14*a2d8e0a7SRajeshwari Shinde * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*a2d8e0a7SRajeshwari Shinde * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*a2d8e0a7SRajeshwari Shinde * GNU General Public License for more details. 17*a2d8e0a7SRajeshwari Shinde * 18*a2d8e0a7SRajeshwari Shinde * You should have received a copy of the GNU General Public License 19*a2d8e0a7SRajeshwari Shinde * along with this program; if not, write to the Free Software 20*a2d8e0a7SRajeshwari Shinde * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*a2d8e0a7SRajeshwari Shinde * MA 02111-1307 USA 22*a2d8e0a7SRajeshwari Shinde */ 23*a2d8e0a7SRajeshwari Shinde #include <asm/arch/clk.h> 24*a2d8e0a7SRajeshwari Shinde #include <asm/arch/cpu.h> 25*a2d8e0a7SRajeshwari Shinde #include <asm/gpio.h> 26*a2d8e0a7SRajeshwari Shinde #include <asm/io.h> 27*a2d8e0a7SRajeshwari Shinde #include <common.h> 28*a2d8e0a7SRajeshwari Shinde #include <div64.h> 29*a2d8e0a7SRajeshwari Shinde #include <i2c.h> 30*a2d8e0a7SRajeshwari Shinde #include <i2s.h> 31*a2d8e0a7SRajeshwari Shinde #include <sound.h> 32*a2d8e0a7SRajeshwari Shinde #include "wm8994.h" 33*a2d8e0a7SRajeshwari Shinde #include "wm8994_registers.h" 34*a2d8e0a7SRajeshwari Shinde 35*a2d8e0a7SRajeshwari Shinde /* defines for wm8994 system clock selection */ 36*a2d8e0a7SRajeshwari Shinde #define SEL_MCLK1 0x00 37*a2d8e0a7SRajeshwari Shinde #define SEL_MCLK2 0x08 38*a2d8e0a7SRajeshwari Shinde #define SEL_FLL1 0x10 39*a2d8e0a7SRajeshwari Shinde #define SEL_FLL2 0x18 40*a2d8e0a7SRajeshwari Shinde 41*a2d8e0a7SRajeshwari Shinde /* fll config to configure fll */ 42*a2d8e0a7SRajeshwari Shinde struct wm8994_fll_config { 43*a2d8e0a7SRajeshwari Shinde int src; /* Source */ 44*a2d8e0a7SRajeshwari Shinde int in; /* Input frequency in Hz */ 45*a2d8e0a7SRajeshwari Shinde int out; /* output frequency in Hz */ 46*a2d8e0a7SRajeshwari Shinde }; 47*a2d8e0a7SRajeshwari Shinde 48*a2d8e0a7SRajeshwari Shinde /* codec private data */ 49*a2d8e0a7SRajeshwari Shinde struct wm8994_priv { 50*a2d8e0a7SRajeshwari Shinde enum wm8994_type type; /* codec type of wolfson */ 51*a2d8e0a7SRajeshwari Shinde int revision; /* Revision */ 52*a2d8e0a7SRajeshwari Shinde int sysclk[WM8994_MAX_AIF]; /* System clock frequency in Hz */ 53*a2d8e0a7SRajeshwari Shinde int mclk[WM8994_MAX_AIF]; /* master clock frequency in Hz */ 54*a2d8e0a7SRajeshwari Shinde int aifclk[WM8994_MAX_AIF]; /* audio interface clock in Hz */ 55*a2d8e0a7SRajeshwari Shinde struct wm8994_fll_config fll[2]; /* fll config to configure fll */ 56*a2d8e0a7SRajeshwari Shinde }; 57*a2d8e0a7SRajeshwari Shinde 58*a2d8e0a7SRajeshwari Shinde /* wm 8994 supported sampling rate values */ 59*a2d8e0a7SRajeshwari Shinde static unsigned int src_rate[] = { 60*a2d8e0a7SRajeshwari Shinde 8000, 11025, 12000, 16000, 22050, 24000, 61*a2d8e0a7SRajeshwari Shinde 32000, 44100, 48000, 88200, 96000 62*a2d8e0a7SRajeshwari Shinde }; 63*a2d8e0a7SRajeshwari Shinde 64*a2d8e0a7SRajeshwari Shinde /* op clock divisions */ 65*a2d8e0a7SRajeshwari Shinde static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; 66*a2d8e0a7SRajeshwari Shinde 67*a2d8e0a7SRajeshwari Shinde /* lr clock frame size ratio */ 68*a2d8e0a7SRajeshwari Shinde static int fs_ratios[] = { 69*a2d8e0a7SRajeshwari Shinde 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536 70*a2d8e0a7SRajeshwari Shinde }; 71*a2d8e0a7SRajeshwari Shinde 72*a2d8e0a7SRajeshwari Shinde /* bit clock divisors */ 73*a2d8e0a7SRajeshwari Shinde static int bclk_divs[] = { 74*a2d8e0a7SRajeshwari Shinde 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480, 75*a2d8e0a7SRajeshwari Shinde 640, 880, 960, 1280, 1760, 1920 76*a2d8e0a7SRajeshwari Shinde }; 77*a2d8e0a7SRajeshwari Shinde 78*a2d8e0a7SRajeshwari Shinde static struct wm8994_priv g_wm8994_info; 79*a2d8e0a7SRajeshwari Shinde static unsigned char g_wm8994_i2c_dev_addr; 80*a2d8e0a7SRajeshwari Shinde 81*a2d8e0a7SRajeshwari Shinde /* 82*a2d8e0a7SRajeshwari Shinde * Initialise I2C for wm 8994 83*a2d8e0a7SRajeshwari Shinde * 84*a2d8e0a7SRajeshwari Shinde * @param bus no i2c bus number in which wm8994 is connected 85*a2d8e0a7SRajeshwari Shinde */ 86*a2d8e0a7SRajeshwari Shinde static void wm8994_i2c_init(int bus_no) 87*a2d8e0a7SRajeshwari Shinde { 88*a2d8e0a7SRajeshwari Shinde i2c_set_bus_num(bus_no); 89*a2d8e0a7SRajeshwari Shinde } 90*a2d8e0a7SRajeshwari Shinde 91*a2d8e0a7SRajeshwari Shinde /* 92*a2d8e0a7SRajeshwari Shinde * Writes value to a device register through i2c 93*a2d8e0a7SRajeshwari Shinde * 94*a2d8e0a7SRajeshwari Shinde * @param reg reg number to be write 95*a2d8e0a7SRajeshwari Shinde * @param data data to be writen to the above registor 96*a2d8e0a7SRajeshwari Shinde * 97*a2d8e0a7SRajeshwari Shinde * @return int value 1 for change, 0 for no change or negative error code. 98*a2d8e0a7SRajeshwari Shinde */ 99*a2d8e0a7SRajeshwari Shinde static int wm8994_i2c_write(unsigned int reg, unsigned short data) 100*a2d8e0a7SRajeshwari Shinde { 101*a2d8e0a7SRajeshwari Shinde unsigned char val[2]; 102*a2d8e0a7SRajeshwari Shinde 103*a2d8e0a7SRajeshwari Shinde val[0] = (unsigned char)((data >> 8) & 0xff); 104*a2d8e0a7SRajeshwari Shinde val[1] = (unsigned char)(data & 0xff); 105*a2d8e0a7SRajeshwari Shinde debug("Write Addr : 0x%04X, Data : 0x%04X\n", reg, data); 106*a2d8e0a7SRajeshwari Shinde 107*a2d8e0a7SRajeshwari Shinde return i2c_write(g_wm8994_i2c_dev_addr, reg, 2, val, 2); 108*a2d8e0a7SRajeshwari Shinde } 109*a2d8e0a7SRajeshwari Shinde 110*a2d8e0a7SRajeshwari Shinde /* 111*a2d8e0a7SRajeshwari Shinde * Read a value from a device register through i2c 112*a2d8e0a7SRajeshwari Shinde * 113*a2d8e0a7SRajeshwari Shinde * @param reg reg number to be read 114*a2d8e0a7SRajeshwari Shinde * @param data address of read data to be stored 115*a2d8e0a7SRajeshwari Shinde * 116*a2d8e0a7SRajeshwari Shinde * @return int value 0 for success, -1 in case of error. 117*a2d8e0a7SRajeshwari Shinde */ 118*a2d8e0a7SRajeshwari Shinde static unsigned int wm8994_i2c_read(unsigned int reg , unsigned short *data) 119*a2d8e0a7SRajeshwari Shinde { 120*a2d8e0a7SRajeshwari Shinde unsigned char val[2]; 121*a2d8e0a7SRajeshwari Shinde int ret; 122*a2d8e0a7SRajeshwari Shinde 123*a2d8e0a7SRajeshwari Shinde ret = i2c_read(g_wm8994_i2c_dev_addr, reg, 2, val, 2); 124*a2d8e0a7SRajeshwari Shinde if (ret != 0) { 125*a2d8e0a7SRajeshwari Shinde debug("%s: Error while reading register %#04x\n", 126*a2d8e0a7SRajeshwari Shinde __func__, reg); 127*a2d8e0a7SRajeshwari Shinde return -1; 128*a2d8e0a7SRajeshwari Shinde } 129*a2d8e0a7SRajeshwari Shinde 130*a2d8e0a7SRajeshwari Shinde *data = val[0]; 131*a2d8e0a7SRajeshwari Shinde *data <<= 8; 132*a2d8e0a7SRajeshwari Shinde *data |= val[1]; 133*a2d8e0a7SRajeshwari Shinde 134*a2d8e0a7SRajeshwari Shinde return 0; 135*a2d8e0a7SRajeshwari Shinde } 136*a2d8e0a7SRajeshwari Shinde 137*a2d8e0a7SRajeshwari Shinde /* 138*a2d8e0a7SRajeshwari Shinde * update device register bits through i2c 139*a2d8e0a7SRajeshwari Shinde * 140*a2d8e0a7SRajeshwari Shinde * @param reg codec register 141*a2d8e0a7SRajeshwari Shinde * @param mask register mask 142*a2d8e0a7SRajeshwari Shinde * @param value new value 143*a2d8e0a7SRajeshwari Shinde * 144*a2d8e0a7SRajeshwari Shinde * @return int value 1 if change in the register value, 145*a2d8e0a7SRajeshwari Shinde * 0 for no change or negative error code. 146*a2d8e0a7SRajeshwari Shinde */ 147*a2d8e0a7SRajeshwari Shinde static int wm8994_update_bits(unsigned int reg, unsigned short mask, 148*a2d8e0a7SRajeshwari Shinde unsigned short value) 149*a2d8e0a7SRajeshwari Shinde { 150*a2d8e0a7SRajeshwari Shinde int change , ret = 0; 151*a2d8e0a7SRajeshwari Shinde unsigned short old, new; 152*a2d8e0a7SRajeshwari Shinde 153*a2d8e0a7SRajeshwari Shinde if (wm8994_i2c_read(reg, &old) != 0) 154*a2d8e0a7SRajeshwari Shinde return -1; 155*a2d8e0a7SRajeshwari Shinde new = (old & ~mask) | (value & mask); 156*a2d8e0a7SRajeshwari Shinde change = (old != new) ? 1 : 0; 157*a2d8e0a7SRajeshwari Shinde if (change) 158*a2d8e0a7SRajeshwari Shinde ret = wm8994_i2c_write(reg, new); 159*a2d8e0a7SRajeshwari Shinde if (ret < 0) 160*a2d8e0a7SRajeshwari Shinde return ret; 161*a2d8e0a7SRajeshwari Shinde 162*a2d8e0a7SRajeshwari Shinde return change; 163*a2d8e0a7SRajeshwari Shinde } 164*a2d8e0a7SRajeshwari Shinde 165*a2d8e0a7SRajeshwari Shinde /* 166*a2d8e0a7SRajeshwari Shinde * Sets i2s set format 167*a2d8e0a7SRajeshwari Shinde * 168*a2d8e0a7SRajeshwari Shinde * @param aif_id Interface ID 169*a2d8e0a7SRajeshwari Shinde * @param fmt i2S format 170*a2d8e0a7SRajeshwari Shinde * 171*a2d8e0a7SRajeshwari Shinde * @return -1 for error and 0 Success. 172*a2d8e0a7SRajeshwari Shinde */ 173*a2d8e0a7SRajeshwari Shinde int wm8994_set_fmt(int aif_id, unsigned int fmt) 174*a2d8e0a7SRajeshwari Shinde { 175*a2d8e0a7SRajeshwari Shinde int ms_reg; 176*a2d8e0a7SRajeshwari Shinde int aif_reg; 177*a2d8e0a7SRajeshwari Shinde int ms = 0; 178*a2d8e0a7SRajeshwari Shinde int aif = 0; 179*a2d8e0a7SRajeshwari Shinde int aif_clk = 0; 180*a2d8e0a7SRajeshwari Shinde int error = 0; 181*a2d8e0a7SRajeshwari Shinde 182*a2d8e0a7SRajeshwari Shinde switch (aif_id) { 183*a2d8e0a7SRajeshwari Shinde case 1: 184*a2d8e0a7SRajeshwari Shinde ms_reg = WM8994_AIF1_MASTER_SLAVE; 185*a2d8e0a7SRajeshwari Shinde aif_reg = WM8994_AIF1_CONTROL_1; 186*a2d8e0a7SRajeshwari Shinde aif_clk = WM8994_AIF1_CLOCKING_1; 187*a2d8e0a7SRajeshwari Shinde break; 188*a2d8e0a7SRajeshwari Shinde case 2: 189*a2d8e0a7SRajeshwari Shinde ms_reg = WM8994_AIF2_MASTER_SLAVE; 190*a2d8e0a7SRajeshwari Shinde aif_reg = WM8994_AIF2_CONTROL_1; 191*a2d8e0a7SRajeshwari Shinde aif_clk = WM8994_AIF2_CLOCKING_1; 192*a2d8e0a7SRajeshwari Shinde break; 193*a2d8e0a7SRajeshwari Shinde default: 194*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid audio interface selection\n", __func__); 195*a2d8e0a7SRajeshwari Shinde return -1; 196*a2d8e0a7SRajeshwari Shinde } 197*a2d8e0a7SRajeshwari Shinde 198*a2d8e0a7SRajeshwari Shinde switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 199*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_CBS_CFS: 200*a2d8e0a7SRajeshwari Shinde break; 201*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_CBM_CFM: 202*a2d8e0a7SRajeshwari Shinde ms = WM8994_AIF1_MSTR; 203*a2d8e0a7SRajeshwari Shinde break; 204*a2d8e0a7SRajeshwari Shinde default: 205*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid i2s master selection\n", __func__); 206*a2d8e0a7SRajeshwari Shinde return -1; 207*a2d8e0a7SRajeshwari Shinde } 208*a2d8e0a7SRajeshwari Shinde 209*a2d8e0a7SRajeshwari Shinde switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 210*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_DSP_B: 211*a2d8e0a7SRajeshwari Shinde aif |= WM8994_AIF1_LRCLK_INV; 212*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_DSP_A: 213*a2d8e0a7SRajeshwari Shinde aif |= 0x18; 214*a2d8e0a7SRajeshwari Shinde break; 215*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_I2S: 216*a2d8e0a7SRajeshwari Shinde aif |= 0x10; 217*a2d8e0a7SRajeshwari Shinde break; 218*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_RIGHT_J: 219*a2d8e0a7SRajeshwari Shinde break; 220*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_LEFT_J: 221*a2d8e0a7SRajeshwari Shinde aif |= 0x8; 222*a2d8e0a7SRajeshwari Shinde break; 223*a2d8e0a7SRajeshwari Shinde default: 224*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid i2s format selection\n", __func__); 225*a2d8e0a7SRajeshwari Shinde return -1; 226*a2d8e0a7SRajeshwari Shinde } 227*a2d8e0a7SRajeshwari Shinde 228*a2d8e0a7SRajeshwari Shinde switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 229*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_DSP_A: 230*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_DSP_B: 231*a2d8e0a7SRajeshwari Shinde /* frame inversion not valid for DSP modes */ 232*a2d8e0a7SRajeshwari Shinde switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 233*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_NB_NF: 234*a2d8e0a7SRajeshwari Shinde break; 235*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_IB_NF: 236*a2d8e0a7SRajeshwari Shinde aif |= WM8994_AIF1_BCLK_INV; 237*a2d8e0a7SRajeshwari Shinde break; 238*a2d8e0a7SRajeshwari Shinde default: 239*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid i2s frame inverse selection\n", 240*a2d8e0a7SRajeshwari Shinde __func__); 241*a2d8e0a7SRajeshwari Shinde return -1; 242*a2d8e0a7SRajeshwari Shinde } 243*a2d8e0a7SRajeshwari Shinde break; 244*a2d8e0a7SRajeshwari Shinde 245*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_I2S: 246*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_RIGHT_J: 247*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_LEFT_J: 248*a2d8e0a7SRajeshwari Shinde switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 249*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_NB_NF: 250*a2d8e0a7SRajeshwari Shinde break; 251*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_IB_IF: 252*a2d8e0a7SRajeshwari Shinde aif |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV; 253*a2d8e0a7SRajeshwari Shinde break; 254*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_IB_NF: 255*a2d8e0a7SRajeshwari Shinde aif |= WM8994_AIF1_BCLK_INV; 256*a2d8e0a7SRajeshwari Shinde break; 257*a2d8e0a7SRajeshwari Shinde case SND_SOC_DAIFMT_NB_IF: 258*a2d8e0a7SRajeshwari Shinde aif |= WM8994_AIF1_LRCLK_INV; 259*a2d8e0a7SRajeshwari Shinde break; 260*a2d8e0a7SRajeshwari Shinde default: 261*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid i2s clock polarity selection\n", 262*a2d8e0a7SRajeshwari Shinde __func__); 263*a2d8e0a7SRajeshwari Shinde return -1; 264*a2d8e0a7SRajeshwari Shinde } 265*a2d8e0a7SRajeshwari Shinde break; 266*a2d8e0a7SRajeshwari Shinde default: 267*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid i2s format selection\n", __func__); 268*a2d8e0a7SRajeshwari Shinde return -1; 269*a2d8e0a7SRajeshwari Shinde } 270*a2d8e0a7SRajeshwari Shinde 271*a2d8e0a7SRajeshwari Shinde error = wm8994_update_bits(aif_reg, WM8994_AIF1_BCLK_INV | 272*a2d8e0a7SRajeshwari Shinde WM8994_AIF1_LRCLK_INV_MASK | WM8994_AIF1_FMT_MASK, aif); 273*a2d8e0a7SRajeshwari Shinde 274*a2d8e0a7SRajeshwari Shinde error |= wm8994_update_bits(ms_reg, WM8994_AIF1_MSTR_MASK, ms); 275*a2d8e0a7SRajeshwari Shinde error |= wm8994_update_bits(aif_clk, WM8994_AIF1CLK_ENA_MASK, 276*a2d8e0a7SRajeshwari Shinde WM8994_AIF1CLK_ENA); 277*a2d8e0a7SRajeshwari Shinde if (error < 0) { 278*a2d8e0a7SRajeshwari Shinde debug("%s: codec register access error\n", __func__); 279*a2d8e0a7SRajeshwari Shinde return -1; 280*a2d8e0a7SRajeshwari Shinde } 281*a2d8e0a7SRajeshwari Shinde 282*a2d8e0a7SRajeshwari Shinde return 0; 283*a2d8e0a7SRajeshwari Shinde } 284*a2d8e0a7SRajeshwari Shinde 285*a2d8e0a7SRajeshwari Shinde /* 286*a2d8e0a7SRajeshwari Shinde * Sets hw params FOR WM8994 287*a2d8e0a7SRajeshwari Shinde * 288*a2d8e0a7SRajeshwari Shinde * @param wm8994 wm8994 information pointer 289*a2d8e0a7SRajeshwari Shinde * @param aif_id Audio interface ID 290*a2d8e0a7SRajeshwari Shinde * @param sampling_rate Sampling rate 291*a2d8e0a7SRajeshwari Shinde * @param bits_per_sample Bits per sample 292*a2d8e0a7SRajeshwari Shinde * @param Channels Channels in the given audio input 293*a2d8e0a7SRajeshwari Shinde * 294*a2d8e0a7SRajeshwari Shinde * @return -1 for error and 0 Success. 295*a2d8e0a7SRajeshwari Shinde */ 296*a2d8e0a7SRajeshwari Shinde static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, 297*a2d8e0a7SRajeshwari Shinde unsigned int sampling_rate, unsigned int bits_per_sample, 298*a2d8e0a7SRajeshwari Shinde unsigned int channels) 299*a2d8e0a7SRajeshwari Shinde { 300*a2d8e0a7SRajeshwari Shinde int aif1_reg; 301*a2d8e0a7SRajeshwari Shinde int aif2_reg; 302*a2d8e0a7SRajeshwari Shinde int bclk_reg; 303*a2d8e0a7SRajeshwari Shinde int bclk = 0; 304*a2d8e0a7SRajeshwari Shinde int rate_reg; 305*a2d8e0a7SRajeshwari Shinde int aif1 = 0; 306*a2d8e0a7SRajeshwari Shinde int aif2 = 0; 307*a2d8e0a7SRajeshwari Shinde int rate_val = 0; 308*a2d8e0a7SRajeshwari Shinde int id = aif_id - 1; 309*a2d8e0a7SRajeshwari Shinde int i, cur_val, best_val, bclk_rate, best; 310*a2d8e0a7SRajeshwari Shinde unsigned short reg_data; 311*a2d8e0a7SRajeshwari Shinde int ret = 0; 312*a2d8e0a7SRajeshwari Shinde 313*a2d8e0a7SRajeshwari Shinde switch (aif_id) { 314*a2d8e0a7SRajeshwari Shinde case 1: 315*a2d8e0a7SRajeshwari Shinde aif1_reg = WM8994_AIF1_CONTROL_1; 316*a2d8e0a7SRajeshwari Shinde aif2_reg = WM8994_AIF1_CONTROL_2; 317*a2d8e0a7SRajeshwari Shinde bclk_reg = WM8994_AIF1_BCLK; 318*a2d8e0a7SRajeshwari Shinde rate_reg = WM8994_AIF1_RATE; 319*a2d8e0a7SRajeshwari Shinde break; 320*a2d8e0a7SRajeshwari Shinde case 2: 321*a2d8e0a7SRajeshwari Shinde aif1_reg = WM8994_AIF2_CONTROL_1; 322*a2d8e0a7SRajeshwari Shinde aif2_reg = WM8994_AIF2_CONTROL_2; 323*a2d8e0a7SRajeshwari Shinde bclk_reg = WM8994_AIF2_BCLK; 324*a2d8e0a7SRajeshwari Shinde rate_reg = WM8994_AIF2_RATE; 325*a2d8e0a7SRajeshwari Shinde break; 326*a2d8e0a7SRajeshwari Shinde default: 327*a2d8e0a7SRajeshwari Shinde return -1; 328*a2d8e0a7SRajeshwari Shinde } 329*a2d8e0a7SRajeshwari Shinde 330*a2d8e0a7SRajeshwari Shinde bclk_rate = sampling_rate * 32; 331*a2d8e0a7SRajeshwari Shinde switch (bits_per_sample) { 332*a2d8e0a7SRajeshwari Shinde case 16: 333*a2d8e0a7SRajeshwari Shinde bclk_rate *= 16; 334*a2d8e0a7SRajeshwari Shinde break; 335*a2d8e0a7SRajeshwari Shinde case 20: 336*a2d8e0a7SRajeshwari Shinde bclk_rate *= 20; 337*a2d8e0a7SRajeshwari Shinde aif1 |= 0x20; 338*a2d8e0a7SRajeshwari Shinde break; 339*a2d8e0a7SRajeshwari Shinde case 24: 340*a2d8e0a7SRajeshwari Shinde bclk_rate *= 24; 341*a2d8e0a7SRajeshwari Shinde aif1 |= 0x40; 342*a2d8e0a7SRajeshwari Shinde break; 343*a2d8e0a7SRajeshwari Shinde case 32: 344*a2d8e0a7SRajeshwari Shinde bclk_rate *= 32; 345*a2d8e0a7SRajeshwari Shinde aif1 |= 0x60; 346*a2d8e0a7SRajeshwari Shinde break; 347*a2d8e0a7SRajeshwari Shinde default: 348*a2d8e0a7SRajeshwari Shinde return -1; 349*a2d8e0a7SRajeshwari Shinde } 350*a2d8e0a7SRajeshwari Shinde 351*a2d8e0a7SRajeshwari Shinde /* Try to find an appropriate sample rate; look for an exact match. */ 352*a2d8e0a7SRajeshwari Shinde for (i = 0; i < ARRAY_SIZE(src_rate); i++) 353*a2d8e0a7SRajeshwari Shinde if (src_rate[i] == sampling_rate) 354*a2d8e0a7SRajeshwari Shinde break; 355*a2d8e0a7SRajeshwari Shinde 356*a2d8e0a7SRajeshwari Shinde if (i == ARRAY_SIZE(src_rate)) { 357*a2d8e0a7SRajeshwari Shinde debug("%s: Could not get the best matching samplingrate\n", 358*a2d8e0a7SRajeshwari Shinde __func__); 359*a2d8e0a7SRajeshwari Shinde return -1; 360*a2d8e0a7SRajeshwari Shinde } 361*a2d8e0a7SRajeshwari Shinde 362*a2d8e0a7SRajeshwari Shinde rate_val |= i << WM8994_AIF1_SR_SHIFT; 363*a2d8e0a7SRajeshwari Shinde 364*a2d8e0a7SRajeshwari Shinde /* AIFCLK/fs ratio; look for a close match in either direction */ 365*a2d8e0a7SRajeshwari Shinde best = 0; 366*a2d8e0a7SRajeshwari Shinde best_val = abs((fs_ratios[0] * sampling_rate) 367*a2d8e0a7SRajeshwari Shinde - wm8994->aifclk[id]); 368*a2d8e0a7SRajeshwari Shinde 369*a2d8e0a7SRajeshwari Shinde for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) { 370*a2d8e0a7SRajeshwari Shinde cur_val = abs((fs_ratios[i] * sampling_rate) 371*a2d8e0a7SRajeshwari Shinde - wm8994->aifclk[id]); 372*a2d8e0a7SRajeshwari Shinde if (cur_val >= best_val) 373*a2d8e0a7SRajeshwari Shinde continue; 374*a2d8e0a7SRajeshwari Shinde best = i; 375*a2d8e0a7SRajeshwari Shinde best_val = cur_val; 376*a2d8e0a7SRajeshwari Shinde } 377*a2d8e0a7SRajeshwari Shinde 378*a2d8e0a7SRajeshwari Shinde rate_val |= best; 379*a2d8e0a7SRajeshwari Shinde 380*a2d8e0a7SRajeshwari Shinde /* 381*a2d8e0a7SRajeshwari Shinde * We may not get quite the right frequency if using 382*a2d8e0a7SRajeshwari Shinde * approximate clocks so look for the closest match that is 383*a2d8e0a7SRajeshwari Shinde * higher than the target (we need to ensure that there enough 384*a2d8e0a7SRajeshwari Shinde * BCLKs to clock out the samples). 385*a2d8e0a7SRajeshwari Shinde */ 386*a2d8e0a7SRajeshwari Shinde best = 0; 387*a2d8e0a7SRajeshwari Shinde for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { 388*a2d8e0a7SRajeshwari Shinde cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate; 389*a2d8e0a7SRajeshwari Shinde if (cur_val < 0) /* BCLK table is sorted */ 390*a2d8e0a7SRajeshwari Shinde break; 391*a2d8e0a7SRajeshwari Shinde best = i; 392*a2d8e0a7SRajeshwari Shinde } 393*a2d8e0a7SRajeshwari Shinde 394*a2d8e0a7SRajeshwari Shinde if (i == ARRAY_SIZE(bclk_divs)) { 395*a2d8e0a7SRajeshwari Shinde debug("%s: Could not get the best matching bclk division\n", 396*a2d8e0a7SRajeshwari Shinde __func__); 397*a2d8e0a7SRajeshwari Shinde return -1; 398*a2d8e0a7SRajeshwari Shinde } 399*a2d8e0a7SRajeshwari Shinde 400*a2d8e0a7SRajeshwari Shinde bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best]; 401*a2d8e0a7SRajeshwari Shinde bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; 402*a2d8e0a7SRajeshwari Shinde 403*a2d8e0a7SRajeshwari Shinde if (wm8994_i2c_read(aif1_reg, ®_data) != 0) { 404*a2d8e0a7SRajeshwari Shinde debug("%s: AIF1 register read Failed\n", __func__); 405*a2d8e0a7SRajeshwari Shinde return -1; 406*a2d8e0a7SRajeshwari Shinde } 407*a2d8e0a7SRajeshwari Shinde 408*a2d8e0a7SRajeshwari Shinde if ((channels == 1) && ((reg_data & 0x18) == 0x18)) 409*a2d8e0a7SRajeshwari Shinde aif2 |= WM8994_AIF1_MONO; 410*a2d8e0a7SRajeshwari Shinde 411*a2d8e0a7SRajeshwari Shinde if (wm8994->aifclk[id] == 0) { 412*a2d8e0a7SRajeshwari Shinde debug("%s:Audio interface clock not set\n", __func__); 413*a2d8e0a7SRajeshwari Shinde return -1; 414*a2d8e0a7SRajeshwari Shinde } 415*a2d8e0a7SRajeshwari Shinde 416*a2d8e0a7SRajeshwari Shinde ret = wm8994_update_bits(aif1_reg, WM8994_AIF1_WL_MASK, aif1); 417*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(aif2_reg, WM8994_AIF1_MONO, aif2); 418*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk); 419*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(rate_reg, WM8994_AIF1_SR_MASK | 420*a2d8e0a7SRajeshwari Shinde WM8994_AIF1CLK_RATE_MASK, rate_val); 421*a2d8e0a7SRajeshwari Shinde 422*a2d8e0a7SRajeshwari Shinde debug("rate vale = %x , bclk val= %x\n", rate_val, bclk); 423*a2d8e0a7SRajeshwari Shinde 424*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 425*a2d8e0a7SRajeshwari Shinde debug("%s: codec register access error\n", __func__); 426*a2d8e0a7SRajeshwari Shinde return -1; 427*a2d8e0a7SRajeshwari Shinde } 428*a2d8e0a7SRajeshwari Shinde 429*a2d8e0a7SRajeshwari Shinde return 0; 430*a2d8e0a7SRajeshwari Shinde } 431*a2d8e0a7SRajeshwari Shinde 432*a2d8e0a7SRajeshwari Shinde /* 433*a2d8e0a7SRajeshwari Shinde * Configures Audio interface Clock 434*a2d8e0a7SRajeshwari Shinde * 435*a2d8e0a7SRajeshwari Shinde * @param wm8994 wm8994 information pointer 436*a2d8e0a7SRajeshwari Shinde * @param aif Audio Interface ID 437*a2d8e0a7SRajeshwari Shinde * 438*a2d8e0a7SRajeshwari Shinde * @return -1 for error and 0 Success. 439*a2d8e0a7SRajeshwari Shinde */ 440*a2d8e0a7SRajeshwari Shinde static int configure_aif_clock(struct wm8994_priv *wm8994, int aif) 441*a2d8e0a7SRajeshwari Shinde { 442*a2d8e0a7SRajeshwari Shinde int rate; 443*a2d8e0a7SRajeshwari Shinde int reg1 = 0; 444*a2d8e0a7SRajeshwari Shinde int offset; 445*a2d8e0a7SRajeshwari Shinde int ret; 446*a2d8e0a7SRajeshwari Shinde 447*a2d8e0a7SRajeshwari Shinde /* AIF(1/0) register adress offset calculated */ 448*a2d8e0a7SRajeshwari Shinde if (aif) 449*a2d8e0a7SRajeshwari Shinde offset = 4; 450*a2d8e0a7SRajeshwari Shinde else 451*a2d8e0a7SRajeshwari Shinde offset = 0; 452*a2d8e0a7SRajeshwari Shinde 453*a2d8e0a7SRajeshwari Shinde switch (wm8994->sysclk[aif]) { 454*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_MCLK1: 455*a2d8e0a7SRajeshwari Shinde reg1 |= SEL_MCLK1; 456*a2d8e0a7SRajeshwari Shinde rate = wm8994->mclk[0]; 457*a2d8e0a7SRajeshwari Shinde break; 458*a2d8e0a7SRajeshwari Shinde 459*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_MCLK2: 460*a2d8e0a7SRajeshwari Shinde reg1 |= SEL_MCLK2; 461*a2d8e0a7SRajeshwari Shinde rate = wm8994->mclk[1]; 462*a2d8e0a7SRajeshwari Shinde break; 463*a2d8e0a7SRajeshwari Shinde 464*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_FLL1: 465*a2d8e0a7SRajeshwari Shinde reg1 |= SEL_FLL1; 466*a2d8e0a7SRajeshwari Shinde rate = wm8994->fll[0].out; 467*a2d8e0a7SRajeshwari Shinde break; 468*a2d8e0a7SRajeshwari Shinde 469*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_FLL2: 470*a2d8e0a7SRajeshwari Shinde reg1 |= SEL_FLL2; 471*a2d8e0a7SRajeshwari Shinde rate = wm8994->fll[1].out; 472*a2d8e0a7SRajeshwari Shinde break; 473*a2d8e0a7SRajeshwari Shinde 474*a2d8e0a7SRajeshwari Shinde default: 475*a2d8e0a7SRajeshwari Shinde debug("%s: Invalid input clock selection [%d]\n", 476*a2d8e0a7SRajeshwari Shinde __func__, wm8994->sysclk[aif]); 477*a2d8e0a7SRajeshwari Shinde return -1; 478*a2d8e0a7SRajeshwari Shinde } 479*a2d8e0a7SRajeshwari Shinde 480*a2d8e0a7SRajeshwari Shinde /* if input clock frequenct is more than 135Mhz then divide */ 481*a2d8e0a7SRajeshwari Shinde if (rate >= WM8994_MAX_INPUT_CLK_FREQ) { 482*a2d8e0a7SRajeshwari Shinde rate /= 2; 483*a2d8e0a7SRajeshwari Shinde reg1 |= WM8994_AIF1CLK_DIV; 484*a2d8e0a7SRajeshwari Shinde } 485*a2d8e0a7SRajeshwari Shinde 486*a2d8e0a7SRajeshwari Shinde wm8994->aifclk[aif] = rate; 487*a2d8e0a7SRajeshwari Shinde 488*a2d8e0a7SRajeshwari Shinde ret = wm8994_update_bits(WM8994_AIF1_CLOCKING_1 + offset, 489*a2d8e0a7SRajeshwari Shinde WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV, 490*a2d8e0a7SRajeshwari Shinde reg1); 491*a2d8e0a7SRajeshwari Shinde 492*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_CLOCKING_1, 493*a2d8e0a7SRajeshwari Shinde WM8994_SYSCLK_SRC | WM8994_AIF2DSPCLK_ENA_MASK | 494*a2d8e0a7SRajeshwari Shinde WM8994_SYSDSPCLK_ENA_MASK, WM8994_SYSCLK_SRC | 495*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DSPCLK_ENA | WM8994_SYSDSPCLK_ENA); 496*a2d8e0a7SRajeshwari Shinde 497*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 498*a2d8e0a7SRajeshwari Shinde debug("%s: codec register access error\n", __func__); 499*a2d8e0a7SRajeshwari Shinde return -1; 500*a2d8e0a7SRajeshwari Shinde } 501*a2d8e0a7SRajeshwari Shinde 502*a2d8e0a7SRajeshwari Shinde return 0; 503*a2d8e0a7SRajeshwari Shinde } 504*a2d8e0a7SRajeshwari Shinde 505*a2d8e0a7SRajeshwari Shinde /* 506*a2d8e0a7SRajeshwari Shinde * Configures Audio interface for the given frequency 507*a2d8e0a7SRajeshwari Shinde * 508*a2d8e0a7SRajeshwari Shinde * @param wm8994 wm8994 information 509*a2d8e0a7SRajeshwari Shinde * @param aif_id Audio Interface 510*a2d8e0a7SRajeshwari Shinde * @param clk_id Input Clock ID 511*a2d8e0a7SRajeshwari Shinde * @param freq Sampling frequency in Hz 512*a2d8e0a7SRajeshwari Shinde * 513*a2d8e0a7SRajeshwari Shinde * @return -1 for error and 0 success. 514*a2d8e0a7SRajeshwari Shinde */ 515*a2d8e0a7SRajeshwari Shinde static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id, 516*a2d8e0a7SRajeshwari Shinde int clk_id, unsigned int freq) 517*a2d8e0a7SRajeshwari Shinde { 518*a2d8e0a7SRajeshwari Shinde int i; 519*a2d8e0a7SRajeshwari Shinde int ret = 0; 520*a2d8e0a7SRajeshwari Shinde 521*a2d8e0a7SRajeshwari Shinde wm8994->sysclk[aif_id - 1] = clk_id; 522*a2d8e0a7SRajeshwari Shinde 523*a2d8e0a7SRajeshwari Shinde switch (clk_id) { 524*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_MCLK1: 525*a2d8e0a7SRajeshwari Shinde wm8994->mclk[0] = freq; 526*a2d8e0a7SRajeshwari Shinde if (aif_id == 2) { 527*a2d8e0a7SRajeshwari Shinde ret = wm8994_update_bits(WM8994_AIF1_CLOCKING_2 , 528*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DAC_DIV_MASK , 0); 529*a2d8e0a7SRajeshwari Shinde } 530*a2d8e0a7SRajeshwari Shinde break; 531*a2d8e0a7SRajeshwari Shinde 532*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_MCLK2: 533*a2d8e0a7SRajeshwari Shinde /* TODO: Set GPIO AF */ 534*a2d8e0a7SRajeshwari Shinde wm8994->mclk[1] = freq; 535*a2d8e0a7SRajeshwari Shinde break; 536*a2d8e0a7SRajeshwari Shinde 537*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_FLL1: 538*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_FLL2: 539*a2d8e0a7SRajeshwari Shinde break; 540*a2d8e0a7SRajeshwari Shinde 541*a2d8e0a7SRajeshwari Shinde case WM8994_SYSCLK_OPCLK: 542*a2d8e0a7SRajeshwari Shinde /* 543*a2d8e0a7SRajeshwari Shinde * Special case - a division (times 10) is given and 544*a2d8e0a7SRajeshwari Shinde * no effect on main clocking. 545*a2d8e0a7SRajeshwari Shinde */ 546*a2d8e0a7SRajeshwari Shinde if (freq) { 547*a2d8e0a7SRajeshwari Shinde for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) 548*a2d8e0a7SRajeshwari Shinde if (opclk_divs[i] == freq) 549*a2d8e0a7SRajeshwari Shinde break; 550*a2d8e0a7SRajeshwari Shinde if (i == ARRAY_SIZE(opclk_divs)) { 551*a2d8e0a7SRajeshwari Shinde debug("%s frequency divisor not found\n", 552*a2d8e0a7SRajeshwari Shinde __func__); 553*a2d8e0a7SRajeshwari Shinde return -1; 554*a2d8e0a7SRajeshwari Shinde } 555*a2d8e0a7SRajeshwari Shinde ret = wm8994_update_bits(WM8994_CLOCKING_2, 556*a2d8e0a7SRajeshwari Shinde WM8994_OPCLK_DIV_MASK, i); 557*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_2, 558*a2d8e0a7SRajeshwari Shinde WM8994_OPCLK_ENA, WM8994_OPCLK_ENA); 559*a2d8e0a7SRajeshwari Shinde } else { 560*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_2, 561*a2d8e0a7SRajeshwari Shinde WM8994_OPCLK_ENA, 0); 562*a2d8e0a7SRajeshwari Shinde } 563*a2d8e0a7SRajeshwari Shinde 564*a2d8e0a7SRajeshwari Shinde default: 565*a2d8e0a7SRajeshwari Shinde debug("%s Invalid input clock selection [%d]\n", 566*a2d8e0a7SRajeshwari Shinde __func__, clk_id); 567*a2d8e0a7SRajeshwari Shinde return -1; 568*a2d8e0a7SRajeshwari Shinde } 569*a2d8e0a7SRajeshwari Shinde 570*a2d8e0a7SRajeshwari Shinde ret |= configure_aif_clock(wm8994, aif_id - 1); 571*a2d8e0a7SRajeshwari Shinde 572*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 573*a2d8e0a7SRajeshwari Shinde debug("%s: codec register access error\n", __func__); 574*a2d8e0a7SRajeshwari Shinde return -1; 575*a2d8e0a7SRajeshwari Shinde } 576*a2d8e0a7SRajeshwari Shinde 577*a2d8e0a7SRajeshwari Shinde return 0; 578*a2d8e0a7SRajeshwari Shinde } 579*a2d8e0a7SRajeshwari Shinde 580*a2d8e0a7SRajeshwari Shinde /* 581*a2d8e0a7SRajeshwari Shinde * Initializes Volume for AIF2 to HP path 582*a2d8e0a7SRajeshwari Shinde * 583*a2d8e0a7SRajeshwari Shinde * @returns -1 for error and 0 Success. 584*a2d8e0a7SRajeshwari Shinde * 585*a2d8e0a7SRajeshwari Shinde */ 586*a2d8e0a7SRajeshwari Shinde static int wm8994_init_volume_aif2_dac1(void) 587*a2d8e0a7SRajeshwari Shinde { 588*a2d8e0a7SRajeshwari Shinde int ret; 589*a2d8e0a7SRajeshwari Shinde 590*a2d8e0a7SRajeshwari Shinde /* Unmute AIF2DAC */ 591*a2d8e0a7SRajeshwari Shinde ret = wm8994_update_bits(WM8994_AIF2_DAC_FILTERS_1, 592*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DAC_MUTE_MASK, 0); 593*a2d8e0a7SRajeshwari Shinde 594*a2d8e0a7SRajeshwari Shinde 595*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_AIF2_DAC_LEFT_VOLUME, 596*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACL_VOL_MASK, 597*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DAC_VU | 0xff); 598*a2d8e0a7SRajeshwari Shinde 599*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_AIF2_DAC_RIGHT_VOLUME, 600*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACR_VOL_MASK, 601*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DAC_VU | 0xff); 602*a2d8e0a7SRajeshwari Shinde 603*a2d8e0a7SRajeshwari Shinde 604*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_DAC1_LEFT_VOLUME, 605*a2d8e0a7SRajeshwari Shinde WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK | 606*a2d8e0a7SRajeshwari Shinde WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0); 607*a2d8e0a7SRajeshwari Shinde 608*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_VOLUME, 609*a2d8e0a7SRajeshwari Shinde WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK | 610*a2d8e0a7SRajeshwari Shinde WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0); 611*a2d8e0a7SRajeshwari Shinde /* Head Phone Volume */ 612*a2d8e0a7SRajeshwari Shinde ret |= wm8994_i2c_write(WM8994_LEFT_OUTPUT_VOLUME, 0x12D); 613*a2d8e0a7SRajeshwari Shinde ret |= wm8994_i2c_write(WM8994_RIGHT_OUTPUT_VOLUME, 0x12D); 614*a2d8e0a7SRajeshwari Shinde 615*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 616*a2d8e0a7SRajeshwari Shinde debug("%s: codec register access error\n", __func__); 617*a2d8e0a7SRajeshwari Shinde return -1; 618*a2d8e0a7SRajeshwari Shinde } 619*a2d8e0a7SRajeshwari Shinde 620*a2d8e0a7SRajeshwari Shinde return 0; 621*a2d8e0a7SRajeshwari Shinde } 622*a2d8e0a7SRajeshwari Shinde 623*a2d8e0a7SRajeshwari Shinde /* 624*a2d8e0a7SRajeshwari Shinde * Intialise wm8994 codec device 625*a2d8e0a7SRajeshwari Shinde * 626*a2d8e0a7SRajeshwari Shinde * @param wm8994 wm8994 information 627*a2d8e0a7SRajeshwari Shinde * 628*a2d8e0a7SRajeshwari Shinde * @returns -1 for error and 0 Success. 629*a2d8e0a7SRajeshwari Shinde */ 630*a2d8e0a7SRajeshwari Shinde static int wm8994_device_init(struct wm8994_priv *wm8994) 631*a2d8e0a7SRajeshwari Shinde { 632*a2d8e0a7SRajeshwari Shinde const char *devname; 633*a2d8e0a7SRajeshwari Shinde unsigned short reg_data; 634*a2d8e0a7SRajeshwari Shinde int ret; 635*a2d8e0a7SRajeshwari Shinde 636*a2d8e0a7SRajeshwari Shinde wm8994_i2c_write(WM8994_SOFTWARE_RESET, WM8994_SW_RESET);/* Reset */ 637*a2d8e0a7SRajeshwari Shinde 638*a2d8e0a7SRajeshwari Shinde ret = wm8994_i2c_read(WM8994_SOFTWARE_RESET, ®_data); 639*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 640*a2d8e0a7SRajeshwari Shinde debug("Failed to read ID register\n"); 641*a2d8e0a7SRajeshwari Shinde goto err; 642*a2d8e0a7SRajeshwari Shinde } 643*a2d8e0a7SRajeshwari Shinde 644*a2d8e0a7SRajeshwari Shinde if (reg_data == WM8994_ID) { 645*a2d8e0a7SRajeshwari Shinde devname = "WM8994"; 646*a2d8e0a7SRajeshwari Shinde debug("Device registered as type %d\n", wm8994->type); 647*a2d8e0a7SRajeshwari Shinde wm8994->type = WM8994; 648*a2d8e0a7SRajeshwari Shinde } else { 649*a2d8e0a7SRajeshwari Shinde debug("Device is not a WM8994, ID is %x\n", ret); 650*a2d8e0a7SRajeshwari Shinde ret = -1; 651*a2d8e0a7SRajeshwari Shinde goto err; 652*a2d8e0a7SRajeshwari Shinde } 653*a2d8e0a7SRajeshwari Shinde 654*a2d8e0a7SRajeshwari Shinde ret = wm8994_i2c_read(WM8994_CHIP_REVISION, ®_data); 655*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 656*a2d8e0a7SRajeshwari Shinde debug("Failed to read revision register: %d\n", ret); 657*a2d8e0a7SRajeshwari Shinde goto err; 658*a2d8e0a7SRajeshwari Shinde } 659*a2d8e0a7SRajeshwari Shinde wm8994->revision = reg_data; 660*a2d8e0a7SRajeshwari Shinde debug("%s revision %c\n", devname, 'A' + wm8994->revision); 661*a2d8e0a7SRajeshwari Shinde 662*a2d8e0a7SRajeshwari Shinde /* VMID Selection */ 663*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1, 664*a2d8e0a7SRajeshwari Shinde WM8994_VMID_SEL_MASK | WM8994_BIAS_ENA_MASK, 0x3); 665*a2d8e0a7SRajeshwari Shinde 666*a2d8e0a7SRajeshwari Shinde /* Charge Pump Enable */ 667*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_CHARGE_PUMP_1, WM8994_CP_ENA_MASK, 668*a2d8e0a7SRajeshwari Shinde WM8994_CP_ENA); 669*a2d8e0a7SRajeshwari Shinde 670*a2d8e0a7SRajeshwari Shinde /* Head Phone Power Enable */ 671*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1, 672*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1L_ENA_MASK, WM8994_HPOUT1L_ENA); 673*a2d8e0a7SRajeshwari Shinde 674*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1, 675*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_ENA_MASK, WM8994_HPOUT1R_ENA); 676*a2d8e0a7SRajeshwari Shinde 677*a2d8e0a7SRajeshwari Shinde /* Power enable for AIF2 and DAC1 */ 678*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_5, 679*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK | 680*a2d8e0a7SRajeshwari Shinde WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK, 681*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | WM8994_DAC1L_ENA | 682*a2d8e0a7SRajeshwari Shinde WM8994_DAC1R_ENA); 683*a2d8e0a7SRajeshwari Shinde 684*a2d8e0a7SRajeshwari Shinde /* Head Phone Initialisation */ 685*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_ANALOGUE_HP_1, 686*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1L_DLY_MASK | WM8994_HPOUT1R_DLY_MASK, 687*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_DLY); 688*a2d8e0a7SRajeshwari Shinde 689*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_DC_SERVO_1, 690*a2d8e0a7SRajeshwari Shinde WM8994_DCS_ENA_CHAN_0_MASK | 691*a2d8e0a7SRajeshwari Shinde WM8994_DCS_ENA_CHAN_1_MASK , WM8994_DCS_ENA_CHAN_0 | 692*a2d8e0a7SRajeshwari Shinde WM8994_DCS_ENA_CHAN_1); 693*a2d8e0a7SRajeshwari Shinde 694*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_ANALOGUE_HP_1, 695*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1L_DLY_MASK | 696*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1L_OUTP_MASK | 697*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_OUTP_MASK | 698*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1L_RMV_SHORT_MASK | 699*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_RMV_SHORT_MASK, WM8994_HPOUT1L_DLY | 700*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_DLY | WM8994_HPOUT1L_OUTP | 701*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_OUTP | WM8994_HPOUT1L_RMV_SHORT | 702*a2d8e0a7SRajeshwari Shinde WM8994_HPOUT1R_RMV_SHORT); 703*a2d8e0a7SRajeshwari Shinde 704*a2d8e0a7SRajeshwari Shinde /* MIXER Config DAC1 to HP */ 705*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_OUTPUT_MIXER_1, 706*a2d8e0a7SRajeshwari Shinde WM8994_DAC1L_TO_HPOUT1L_MASK, WM8994_DAC1L_TO_HPOUT1L); 707*a2d8e0a7SRajeshwari Shinde 708*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_OUTPUT_MIXER_2, 709*a2d8e0a7SRajeshwari Shinde WM8994_DAC1R_TO_HPOUT1R_MASK, WM8994_DAC1R_TO_HPOUT1R); 710*a2d8e0a7SRajeshwari Shinde 711*a2d8e0a7SRajeshwari Shinde /* Routing AIF2 to DAC1 */ 712*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_DAC1_LEFT_MIXER_ROUTING, 713*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DACL_TO_DAC1L_MASK, 714*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DACL_TO_DAC1L); 715*a2d8e0a7SRajeshwari Shinde 716*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING, 717*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DACR_TO_DAC1R_MASK, 718*a2d8e0a7SRajeshwari Shinde WM8994_AIF2DACR_TO_DAC1R); 719*a2d8e0a7SRajeshwari Shinde 720*a2d8e0a7SRajeshwari Shinde /* GPIO Settings for AIF2 */ 721*a2d8e0a7SRajeshwari Shinde /* B CLK */ 722*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_GPIO_3, WM8994_GPIO_DIR_MASK | 723*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_FUNCTION_MASK , 724*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_DIR_OUTPUT | 725*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_FUNCTION_I2S_CLK); 726*a2d8e0a7SRajeshwari Shinde 727*a2d8e0a7SRajeshwari Shinde /* LR CLK */ 728*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_GPIO_4, WM8994_GPIO_DIR_MASK | 729*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_FUNCTION_MASK, 730*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_DIR_OUTPUT | 731*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_FUNCTION_I2S_CLK); 732*a2d8e0a7SRajeshwari Shinde 733*a2d8e0a7SRajeshwari Shinde /* DATA */ 734*a2d8e0a7SRajeshwari Shinde ret |= wm8994_update_bits(WM8994_GPIO_5, WM8994_GPIO_DIR_MASK | 735*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_FUNCTION_MASK, 736*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_DIR_OUTPUT | 737*a2d8e0a7SRajeshwari Shinde WM8994_GPIO_FUNCTION_I2S_CLK); 738*a2d8e0a7SRajeshwari Shinde 739*a2d8e0a7SRajeshwari Shinde ret |= wm8994_init_volume_aif2_dac1(); 740*a2d8e0a7SRajeshwari Shinde if (ret < 0) 741*a2d8e0a7SRajeshwari Shinde goto err; 742*a2d8e0a7SRajeshwari Shinde 743*a2d8e0a7SRajeshwari Shinde debug("%s: Codec chip init ok\n", __func__); 744*a2d8e0a7SRajeshwari Shinde return 0; 745*a2d8e0a7SRajeshwari Shinde err: 746*a2d8e0a7SRajeshwari Shinde debug("%s: Codec chip init error\n", __func__); 747*a2d8e0a7SRajeshwari Shinde return -1; 748*a2d8e0a7SRajeshwari Shinde } 749*a2d8e0a7SRajeshwari Shinde 750*a2d8e0a7SRajeshwari Shinde /*wm8994 Device Initialisation */ 751*a2d8e0a7SRajeshwari Shinde int wm8994_init(struct sound_codec_info *pcodec_info, 752*a2d8e0a7SRajeshwari Shinde enum en_audio_interface aif_id, 753*a2d8e0a7SRajeshwari Shinde int sampling_rate, int mclk_freq, 754*a2d8e0a7SRajeshwari Shinde int bits_per_sample, unsigned int channels) 755*a2d8e0a7SRajeshwari Shinde { 756*a2d8e0a7SRajeshwari Shinde int ret = 0; 757*a2d8e0a7SRajeshwari Shinde 758*a2d8e0a7SRajeshwari Shinde /* shift the device address by 1 for 7 bit addressing */ 759*a2d8e0a7SRajeshwari Shinde g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr; 760*a2d8e0a7SRajeshwari Shinde wm8994_i2c_init(pcodec_info->i2c_bus); 761*a2d8e0a7SRajeshwari Shinde 762*a2d8e0a7SRajeshwari Shinde if (pcodec_info->codec_type == CODEC_WM_8994) 763*a2d8e0a7SRajeshwari Shinde g_wm8994_info.type = WM8994; 764*a2d8e0a7SRajeshwari Shinde else { 765*a2d8e0a7SRajeshwari Shinde debug("%s: Codec id [%d] not defined\n", __func__, 766*a2d8e0a7SRajeshwari Shinde pcodec_info->codec_type); 767*a2d8e0a7SRajeshwari Shinde return -1; 768*a2d8e0a7SRajeshwari Shinde } 769*a2d8e0a7SRajeshwari Shinde 770*a2d8e0a7SRajeshwari Shinde ret = wm8994_device_init(&g_wm8994_info); 771*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 772*a2d8e0a7SRajeshwari Shinde debug("%s: wm8994 codec chip init failed\n", __func__); 773*a2d8e0a7SRajeshwari Shinde return ret; 774*a2d8e0a7SRajeshwari Shinde } 775*a2d8e0a7SRajeshwari Shinde 776*a2d8e0a7SRajeshwari Shinde ret = wm8994_set_sysclk(&g_wm8994_info, aif_id, WM8994_SYSCLK_MCLK1, 777*a2d8e0a7SRajeshwari Shinde mclk_freq); 778*a2d8e0a7SRajeshwari Shinde if (ret < 0) { 779*a2d8e0a7SRajeshwari Shinde debug("%s: wm8994 codec set sys clock failed\n", __func__); 780*a2d8e0a7SRajeshwari Shinde return ret; 781*a2d8e0a7SRajeshwari Shinde } 782*a2d8e0a7SRajeshwari Shinde 783*a2d8e0a7SRajeshwari Shinde ret = wm8994_hw_params(&g_wm8994_info, aif_id, sampling_rate, 784*a2d8e0a7SRajeshwari Shinde bits_per_sample, channels); 785*a2d8e0a7SRajeshwari Shinde 786*a2d8e0a7SRajeshwari Shinde if (ret == 0) { 787*a2d8e0a7SRajeshwari Shinde ret = wm8994_set_fmt(aif_id, SND_SOC_DAIFMT_I2S | 788*a2d8e0a7SRajeshwari Shinde SND_SOC_DAIFMT_NB_NF | 789*a2d8e0a7SRajeshwari Shinde SND_SOC_DAIFMT_CBS_CFS); 790*a2d8e0a7SRajeshwari Shinde } 791*a2d8e0a7SRajeshwari Shinde return ret; 792*a2d8e0a7SRajeshwari Shinde } 793