/*
* ALSA SoC TWL6040 codec driver
*
* Author: Misael Lopez Cruz <x0052729@ti.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.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/mfd/twl6040.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 "twl6040.h"
#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
#define TWL6040_OUTHS_0dB 0x00
#define TWL6040_OUTHS_M30dB 0x0F
#define TWL6040_OUTHF_0dB 0x03
#define TWL6040_OUTHF_M52dB 0x1D
/* Shadow register used by the driver */
#define TWL6040_REG_SW_SHADOW 0x2F
#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1)
/* TWL6040_REG_SW_SHADOW (0x2F) fields */
#define TWL6040_EAR_PATH_ENABLE 0x01
struct twl6040_jack_data {
struct snd_soc_jack *jack;
struct delayed_work work;
int report;
};
/* codec private data */
struct twl6040_data {
int plug_irq;
int codec_powered;
int pll;
int pll_power_mode;
int hs_power_mode;
int hs_power_mode_locked;
unsigned int clk_in;
unsigned int sysclk;
u16 hs_left_step;
u16 hs_right_step;
u16 hf_left_step;
u16 hf_right_step;
struct twl6040_jack_data hs_jack;
struct snd_soc_codec *codec;
struct workqueue_struct *workqueue;
struct mutex mutex;
};
/*
* twl6040 register cache & default register settings
*/
static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
0x00, /* not used 0x00 */
0x4B, /* REG_ASICID 0x01 (ro) */
0x00, /* REG_ASICREV 0x02 (ro) */
0x00, /* REG_INTID 0x03 */
0x00, /* REG_INTMR 0x04 */
0x00, /* REG_NCPCTRL 0x05 */
0x00, /* REG_LDOCTL 0x06 */
0x60, /* REG_HPPLLCTL 0x07 */
0x00, /* REG_LPPLLCTL 0x08 */
0x4A, /* REG_LPPLLDIV 0x09 */
0x00, /* REG_AMICBCTL 0x0A */
0x00, /* REG_DMICBCTL 0x0B */
0x00, /* REG_MICLCTL 0x0C */
0x00, /* REG_MICRCTL 0x0D */
0x00, /* REG_MICGAIN 0x0E */
0x1B, /* REG_LINEGAIN 0x0F */
0x00, /* REG_HSLCTL 0x10 */
0x00, /* REG_HSRCTL 0x11 */
0x00, /* REG_HSGAIN 0x12 */
0x00, /* REG_EARCTL 0x13 */
0x00, /* REG_HFLCTL 0x14 */
0x00, /* REG_HFLGAIN 0x15 */
0x00, /* REG_HFRCTL 0x16 */
0x00, /* REG_HFRGAIN 0x17 */
0x00, /* REG_VIBCTLL 0x18 */
0x00, /* REG_VIBDATL 0x19 */
0x00, /* REG_VIBCTLR 0x1A */
0x00, /* REG_VIBDATR 0x1B */
0x00, /* REG_HKCTL1 0x1C */
0x00, /* REG_HKCTL2 0x1D */
0x00, /* REG_GPOCTL 0x1E */
0x00, /* REG_ALB 0x1F */
0x00, /* REG_DLB 0x20 */
0x00, /* not used 0x21 */
0x00, /* not used 0x22 */
0x00, /* not used 0x23 */
0x00, /* not used 0x24 */
0x00, /* not used 0x25 */
0x00, /* not used 0x26 */
0x00, /* not used 0x27 */
0x00, /* REG_TRIM1 0x28 */