/*
* wm8900.c -- WM8900 ALSA Soc Audio driver
*
* Copyright 2007, 2008 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* 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.
*
* TODO:
* - Tristating.
* - TDM.
* - Jack detect.
* - FLL source configuration, currently only MCLK is supported.
*/
#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/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include "wm8900.h"
/* WM8900 register space */
#define WM8900_REG_RESET 0x0
#define WM8900_REG_ID 0x0
#define WM8900_REG_POWER1 0x1
#define WM8900_REG_POWER2 0x2
#define WM8900_REG_POWER3 0x3
#define WM8900_REG_AUDIO1 0x4
#define WM8900_REG_AUDIO2 0x5
#define WM8900_REG_CLOCKING1 0x6
#define WM8900_REG_CLOCKING2 0x7
#define WM8900_REG_AUDIO3 0x8
#define WM8900_REG_AUDIO4 0x9
#define WM8900_REG_DACCTRL 0xa
#define WM8900_REG_LDAC_DV 0xb
#define WM8900_REG_RDAC_DV 0xc
#define WM8900_REG_SIDETONE 0xd
#define WM8900_REG_ADCCTRL 0xe
#define WM8900_REG_LADC_DV 0xf
#define WM8900_REG_RADC_DV 0x10
#define WM8900_REG_GPIO 0x12
#define WM8900_REG_INCTL 0x15
#define WM8900_REG_LINVOL 0x16
#define WM8900_REG_RINVOL 0x17
#define WM8900_REG_INBOOSTMIX1 0x18
#define WM8900_REG_INBOOSTMIX2 0x19
#define WM8900_REG_ADCPATH 0x1a
#define WM8900_REG_AUXBOOST 0x1b
#define WM8900_REG_ADDCTL 0x1e
#define WM8900_REG_FLLCTL1 0x24
#define WM8900_REG_FLLCTL2 0x25
#define WM8900_REG_FLLCTL3 0x26
#define WM8900_REG_FLLCTL4 0x27
#define WM8900_REG_FLLCTL5 0x28
#define WM8900_REG_FLLCTL6 0x29
#define WM8900_REG_LOUTMIXCTL1 0x2c
#define WM8900_REG_ROUTMIXCTL1 0x2d
#define WM8900_REG_BYPASS1 0x2e
#define WM8900_REG_BYPASS2 0x2f
#define WM8900_REG_AUXOUT_CTL 0x30
#define WM8900_REG_LOUT1CTL 0x33
#define WM8900_REG_ROUT1CTL 0x34
#define WM8900_REG_LOUT2CTL 0x35
#define WM8900_REG_ROUT2CTL 0x36
#define WM8900_REG_HPCTL1 0x3a
#define WM8900_REG_OUTBIASCTL 0x73
#define WM8900_MAXREG 0x80
#define WM8900_REG_ADDCTL_OUT1_DIS 0x80
#define WM8900_REG_ADDCTL_OUT2_DIS 0x40
#define WM8900_REG_ADDCTL_VMID_DIS 0x20
#define WM8900_REG_ADDCTL_BIAS_SRC 0x10
#define WM8900_REG_ADDCTL_VMID_SOFTST 0x04
#define WM8900_REG_ADDCTL_TEMP_SD 0x02
#define WM8900_REG_GPIO_TEMP_ENA 0x2
#define WM8900_REG_POWER1_STARTUP_BIAS_ENA 0x0100
#define WM8900_REG_POWER1_BIAS_ENA 0x0008
#define WM8900_REG_POWER1_VMID_BUF_ENA 0x0004
#define WM8900_REG_POWER1_FLL_ENA 0x0040
#define WM8900_REG_POWER2_SYSCLK_ENA 0x8000
#define WM8900_REG_POWER2_ADCL_ENA 0x0002
#define WM8900_REG_POWER2_ADCR_ENA 0x0001
#define WM8900_REG_POWER3_DACL_ENA 0x0002
#define WM8900_REG_POWER3_DACR_ENA 0x0001
#define WM8900_REG_AUDIO1_AIF_FMT_MASK 0x0018
#define WM8900_REG_AUDIO1_LRCLK_INV 0x0080
#define WM8900_REG_AUDIO1_BCLK_INV 0x0100
#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
#define WM8900_REG_CLOCKING1_BCLK_MASK 0x01e
#define WM8900_REG_CLOCKING1_OPCLK_MASK 0x7000
#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
#define WM8900_REG_DACCTRL_MUTE 0x004
#define WM8900_REG_DACCTRL_DAC_SB_FILT 0x100
#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
#define WM8900_REG_AUDIO4_DACLRC_DIR 0x0800
#define WM8900_REG_FLLCTL1_OSC_ENA 0x100
#define WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF 0x100
#define WM8900_REG_HPCTL1_HP_IPSTAGE_ENA 0x80
#define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40
#define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20
#define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10
#define WM8900_REG_HPCTL1_HP_SHORT 0x08
#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
#define WM8900_LRC_MASK 0x03ff
struct wm8900_priv {
enum snd_soc_control_type control_type;
u32 fll_in; /* FLL input frequency */
u32 fll_out; /* FLL output frequency */
};
/*
* wm8900 register cache. We can't read the entire register space and we
* have slow control buses so we cache the registers.
*/
static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
0x8900, 0x0000,
0xc000, 0x0000,
0x4050, 0x4000,
0x0008, 0x0000,
0x0040, 0x0040,
0x1004, 0x00c0,
0x00c0, 0x0000,
0x0100, 0x00c0,
0x00c0, 0x0000,
0xb001, 0x0000,
0x0000, 0x0044,
0x004c, 0x004c,