/*
* 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/i2c/twl.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
#define TWL6040_RAMP_NONE 0
#define TWL6040_RAMP_UP 1
#define TWL6040_RAMP_DOWN 2
#define TWL6040_HSL_VOL_MASK 0x0F
#define TWL6040_HSL_VOL_SHIFT 0
#define TWL6040_HSR_VOL_MASK 0xF0
#define TWL6040_HSR_VOL_SHIFT 4
#define TWL6040_HF_VOL_MASK 0x1F
#define TWL6040_HF_VOL_SHIFT 0
/* 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_output {
u16 active;
u16 left_vol;
u16 right_vol;
u16 left_step;
u16 right_step;
unsigned int step_delay;
u16 ramp;
struct delayed_work work;
struct completion ramp_done;
};
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;
struct twl6040_output headset;
struct twl6040_output handsfree;
};
/*
* 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 */
0
|