/*
* wm8978.c -- WM8978 ALSA SoC Audio Codec driver
*
* Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
* Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
* Copyright 2006-2009 Wolfson Microelectronics PLC.
* Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <asm/div64.h>
#include "wm8978.h"
static struct snd_soc_codec *wm8978_codec;
/* wm8978 register cache. Note that register 0 is not included in the cache. */
static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */
0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */
0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */
0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */
0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */
0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */
0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */
0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */
0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */
0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */
0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */
0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */
0x0001, 0x0001, /* 0x38...0x3b */
};
/* codec private data */
struct wm8978_priv {
struct snd_soc_codec codec;
unsigned int f_pllout;
unsigned int f_mclk;
unsigned int f_256fs;
unsigned int f_opclk;
int mclk_idx;
enum wm8978_sysclk_src sysclk;
u16 reg_cache[WM8978_CACHEREGNUM];
};
static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
static const char *wm8978_eqmode[] = {"Capture", "Playback"};
static const char *wm8978_bw[] = {"Narrow", "Wide"};
static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
static const char *wm8978_alc3[] = {"ALC", "Limiter"};
static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
wm8978_companding);
static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL