231 lines
6.0 KiB
C
231 lines
6.0 KiB
C
|
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License version 2 and
|
||
|
* only 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.
|
||
|
*/
|
||
|
#ifndef MSM8X10_WCD_H
|
||
|
#define MSM8X10_WCD_H
|
||
|
|
||
|
#include <sound/soc.h>
|
||
|
#include <sound/jack.h>
|
||
|
#include "wcd9xxx-mbhc.h"
|
||
|
#include "wcd9xxx-resmgr.h"
|
||
|
|
||
|
#define MSM8X10_WCD_NUM_REGISTERS 0x600
|
||
|
#define MSM8X10_WCD_MAX_REGISTER (MSM8X10_WCD_NUM_REGISTERS-1)
|
||
|
#define MSM8X10_WCD_CACHE_SIZE MSM8X10_WCD_NUM_REGISTERS
|
||
|
#define MSM8X10_WCD_NUM_IRQ_REGS 3
|
||
|
#define MAX_REGULATOR 7
|
||
|
#define MSM8X10_WCD_REG_VAL(reg, val) {reg, 0, val}
|
||
|
|
||
|
#define MSM8X10_WCD_IS_DINO_REG(reg) \
|
||
|
(((reg >= 0x400) && (reg <= 0x5FF)) ? 1 : 0)
|
||
|
#define MSM8X10_WCD_IS_HELICON_REG(reg) \
|
||
|
(((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0)
|
||
|
extern const u8 msm8x10_wcd_reg_readable[MSM8X10_WCD_CACHE_SIZE];
|
||
|
extern const u8 msm8x10_wcd_reset_reg_defaults[MSM8X10_WCD_CACHE_SIZE];
|
||
|
struct msm8x10_wcd_codec_dai_data {
|
||
|
u32 rate;
|
||
|
u32 *ch_num;
|
||
|
u32 ch_act;
|
||
|
u32 ch_tot;
|
||
|
};
|
||
|
|
||
|
enum msm8x10_wcd_pid_current {
|
||
|
MSM8X10_WCD_PID_MIC_2P5_UA,
|
||
|
MSM8X10_WCD_PID_MIC_5_UA,
|
||
|
MSM8X10_WCD_PID_MIC_10_UA,
|
||
|
MSM8X10_WCD_PID_MIC_20_UA,
|
||
|
};
|
||
|
|
||
|
struct msm8x10_wcd_reg_mask_val {
|
||
|
u16 reg;
|
||
|
u8 mask;
|
||
|
u8 val;
|
||
|
};
|
||
|
|
||
|
enum msm8x10_wcd_mbhc_analog_pwr_cfg {
|
||
|
MSM8X10_WCD_ANALOG_PWR_COLLAPSED = 0,
|
||
|
MSM8X10_WCD_ANALOG_PWR_ON,
|
||
|
MSM8X10_WCD_NUM_ANALOG_PWR_CONFIGS,
|
||
|
};
|
||
|
|
||
|
/* Number of input and output Slimbus port */
|
||
|
enum {
|
||
|
MSM8X10_WCD_RX1 = 0,
|
||
|
MSM8X10_WCD_RX2,
|
||
|
MSM8X10_WCD_RX3,
|
||
|
MSM8X10_WCD_RX_MAX,
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
MSM8X10_WCD_TX1 = 0,
|
||
|
MSM8X10_WCD_TX2,
|
||
|
MSM8X10_WCD_TX3,
|
||
|
MSM8X10_WCD_TX4,
|
||
|
MSM8X10_WCD_TX_MAX,
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
/* INTR_REG 0 */
|
||
|
MSM8X10_WCD_IRQ_RESERVED_0 = 0,
|
||
|
MSM8X10_WCD_IRQ_MBHC_REMOVAL,
|
||
|
MSM8X10_WCD_IRQ_MBHC_SHORT_TERM,
|
||
|
MSM8X10_WCD_IRQ_MBHC_PRESS,
|
||
|
MSM8X10_WCD_IRQ_MBHC_RELEASE,
|
||
|
MSM8X10_WCD_IRQ_MBHC_POTENTIAL,
|
||
|
MSM8X10_WCD_IRQ_MBHC_INSERTION,
|
||
|
MSM8X10_WCD_IRQ_MBHC_HS_DET,
|
||
|
/* INTR_REG 1 */
|
||
|
MSM8X10_WCD_IRQ_PA_STARTUP,
|
||
|
MSM8X10_WCD_IRQ_BG_PRECHARGE,
|
||
|
MSM8X10_WCD_IRQ_RESERVED_1,
|
||
|
MSM8X10_WCD_IRQ_EAR_PA_OCPL_FAULT,
|
||
|
MSM8X10_WCD_IRQ_EAR_PA_STARTUP,
|
||
|
MSM8X10_WCD_IRQ_SPKR_PA_OCPL_FAULT,
|
||
|
MSM8X10_WCD_IRQ_SPKR_CLIP_FAULT,
|
||
|
MSM8X10_WCD_IRQ_RESERVED_2,
|
||
|
/* INTR_REG 2 */
|
||
|
MSM8X10_WCD_IRQ_HPH_L_PA_STARTUP,
|
||
|
MSM8X10_WCD_IRQ_HPH_R_PA_STARTUP,
|
||
|
MSM8X10_WCD_IRQ_HPH_PA_OCPL_FAULT,
|
||
|
MSM8X10_WCD_IRQ_HPH_PA_OCPR_FAULT,
|
||
|
MSM8X10_WCD_IRQ_RESERVED_3,
|
||
|
MSM8X10_WCD_IRQ_RESERVED_4,
|
||
|
MSM8X10_WCD_IRQ_RESERVED_5,
|
||
|
MSM8X10_WCD_IRQ_RESERVED_6,
|
||
|
MSM8X10_WCD_NUM_IRQS,
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Each micbias can be assigned to one of three cfilters
|
||
|
* Vbatt_min >= .15V + ldoh_v
|
||
|
* ldoh_v >= .15v + cfiltx_mv
|
||
|
* If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv
|
||
|
* If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv
|
||
|
* If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv
|
||
|
* If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv
|
||
|
*/
|
||
|
struct msm8x10_wcd_micbias_setting {
|
||
|
u8 ldoh_v;
|
||
|
u32 cfilt1_mv; /* in mv */
|
||
|
/*
|
||
|
* Different WCD9xxx series codecs may not
|
||
|
* have 4 mic biases. If a codec has fewer
|
||
|
* mic biases, some of these properties will
|
||
|
* not be used.
|
||
|
*/
|
||
|
u8 bias1_cfilt_sel;
|
||
|
u8 bias1_cap_mode;
|
||
|
};
|
||
|
|
||
|
struct msm8x10_wcd_ocp_setting {
|
||
|
unsigned int use_pdata:1; /* 0 - use sys default as recommended */
|
||
|
unsigned int num_attempts:4; /* up to 15 attempts */
|
||
|
unsigned int run_time:4; /* in duty cycle */
|
||
|
unsigned int wait_time:4; /* in duty cycle */
|
||
|
unsigned int hph_ocp_limit:3; /* Headphone OCP current limit */
|
||
|
};
|
||
|
|
||
|
struct msm8x10_wcd_regulator {
|
||
|
const char *name;
|
||
|
int min_uV;
|
||
|
int max_uV;
|
||
|
int optimum_uA;
|
||
|
struct regulator *regulator;
|
||
|
};
|
||
|
|
||
|
struct msm8x10_wcd_pdata {
|
||
|
int irq;
|
||
|
int irq_base;
|
||
|
int num_irqs;
|
||
|
int reset_gpio;
|
||
|
void *msm8x10_wcd_ahb_base_vaddr;
|
||
|
struct msm8x10_wcd_micbias_setting micbias;
|
||
|
struct msm8x10_wcd_ocp_setting ocp;
|
||
|
struct msm8x10_wcd_regulator regulator[MAX_REGULATOR];
|
||
|
u32 mclk_rate;
|
||
|
};
|
||
|
|
||
|
enum msm8x10_wcd_micbias_num {
|
||
|
MSM8X10_WCD_MICBIAS1 = 0,
|
||
|
};
|
||
|
|
||
|
struct msm8x10_wcd_mbhc_config {
|
||
|
struct snd_soc_jack *headset_jack;
|
||
|
struct snd_soc_jack *button_jack;
|
||
|
bool read_fw_bin;
|
||
|
/*
|
||
|
* void* calibration contains:
|
||
|
* struct msm8x10_wcd_mbhc_general_cfg generic;
|
||
|
* struct msm8x10_wcd_mbhc_plug_detect_cfg plug_det;
|
||
|
* struct msm8x10_wcd_mbhc_plug_type_cfg plug_type;
|
||
|
* struct msm8x10_wcd_mbhc_btn_detect_cfg btn_det;
|
||
|
* struct msm8x10_wcd_mbhc_imped_detect_cfg imped_det;
|
||
|
* Note: various size depends on btn_det->num_btn
|
||
|
*/
|
||
|
void *calibration;
|
||
|
enum msm8x10_wcd_micbias_num micbias;
|
||
|
int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
|
||
|
unsigned int mclk_rate;
|
||
|
unsigned int gpio;
|
||
|
unsigned int gpio_irq;
|
||
|
int gpio_level_insert;
|
||
|
bool detect_extn_cable;
|
||
|
/* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
|
||
|
bool (*swap_gnd_mic) (struct snd_soc_codec *);
|
||
|
};
|
||
|
|
||
|
enum msm8x10_wcd_pm_state {
|
||
|
MSM8X10_WCD_PM_SLEEPABLE,
|
||
|
MSM8X10_WCD_PM_AWAKE,
|
||
|
MSM8X10_WCD_PM_ASLEEP,
|
||
|
};
|
||
|
|
||
|
struct msm8x10_wcd {
|
||
|
struct device *dev;
|
||
|
struct mutex io_lock;
|
||
|
struct mutex xfer_lock;
|
||
|
struct mutex irq_lock;
|
||
|
u8 version;
|
||
|
|
||
|
int reset_gpio;
|
||
|
int (*read_dev)(struct msm8x10_wcd *msm8x10,
|
||
|
unsigned short reg, unsigned int *val);
|
||
|
int (*write_dev)(struct msm8x10_wcd *msm8x10,
|
||
|
unsigned short reg, u8 val);
|
||
|
|
||
|
u32 num_of_supplies;
|
||
|
struct regulator_bulk_data *supplies;
|
||
|
|
||
|
enum msm8x10_wcd_pm_state pm_state;
|
||
|
struct mutex pm_lock;
|
||
|
/* pm_wq notifies change of pm_state */
|
||
|
wait_queue_head_t pm_wq;
|
||
|
struct pm_qos_request pm_qos_req;
|
||
|
int wlock_holders;
|
||
|
|
||
|
u8 idbyte[4];
|
||
|
|
||
|
unsigned int irq_base;
|
||
|
unsigned int irq;
|
||
|
u8 irq_masks_cur[MSM8X10_WCD_NUM_IRQ_REGS];
|
||
|
u8 irq_masks_cache[MSM8X10_WCD_NUM_IRQ_REGS];
|
||
|
bool irq_level_high[MSM8X10_WCD_NUM_IRQS];
|
||
|
int num_irqs;
|
||
|
u32 mclk_rate;
|
||
|
};
|
||
|
|
||
|
extern int msm8x10_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
|
||
|
bool dapm);
|
||
|
extern int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
|
||
|
struct msm8x10_wcd_mbhc_config *mbhc_cfg);
|
||
|
|
||
|
#endif
|