Merge remote-tracking branch 'asoc/topic/wm8994' into asoc-next
This commit is contained in:
commit
faa9c2a798
|
@ -401,13 +401,19 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = {
|
|||
*/
|
||||
static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
||||
{
|
||||
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
|
||||
struct wm8994_pdata *pdata;
|
||||
struct regmap_config *regmap_config;
|
||||
const struct reg_default *regmap_patch = NULL;
|
||||
const char *devname;
|
||||
int ret, i, patch_regs;
|
||||
int pulls = 0;
|
||||
|
||||
if (dev_get_platdata(wm8994->dev)) {
|
||||
pdata = dev_get_platdata(wm8994->dev);
|
||||
wm8994->pdata = *pdata;
|
||||
}
|
||||
pdata = &wm8994->pdata;
|
||||
|
||||
dev_set_drvdata(wm8994->dev, wm8994);
|
||||
|
||||
/* Add the on-chip regulators first for bootstrapping */
|
||||
|
@ -604,25 +610,22 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
|||
}
|
||||
}
|
||||
|
||||
if (pdata) {
|
||||
wm8994->irq_base = pdata->irq_base;
|
||||
wm8994->gpio_base = pdata->gpio_base;
|
||||
wm8994->irq_base = pdata->irq_base;
|
||||
wm8994->gpio_base = pdata->gpio_base;
|
||||
|
||||
/* GPIO configuration is only applied if it's non-zero */
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
|
||||
if (pdata->gpio_defaults[i]) {
|
||||
wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
|
||||
0xffff,
|
||||
pdata->gpio_defaults[i]);
|
||||
}
|
||||
/* GPIO configuration is only applied if it's non-zero */
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
|
||||
if (pdata->gpio_defaults[i]) {
|
||||
wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
|
||||
0xffff, pdata->gpio_defaults[i]);
|
||||
}
|
||||
|
||||
wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
|
||||
|
||||
if (pdata->spkmode_pu)
|
||||
pulls |= WM8994_SPKMODE_PU;
|
||||
}
|
||||
|
||||
wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
|
||||
|
||||
if (pdata->spkmode_pu)
|
||||
pulls |= WM8994_SPKMODE_PU;
|
||||
|
||||
/* Disable unneeded pulls */
|
||||
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
|
||||
WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD |
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <linux/mfd/wm8994/pdata.h>
|
||||
|
||||
enum wm8994_type {
|
||||
WM8994 = 0,
|
||||
WM8958 = 1,
|
||||
|
@ -55,6 +57,8 @@ struct regulator_bulk_data;
|
|||
struct wm8994 {
|
||||
struct mutex irq_lock;
|
||||
|
||||
struct wm8994_pdata pdata;
|
||||
|
||||
enum wm8994_type type;
|
||||
int revision;
|
||||
int cust_id;
|
||||
|
|
|
@ -176,6 +176,11 @@ struct wm8994_pdata {
|
|||
unsigned int lineout1fb:1;
|
||||
unsigned int lineout2fb:1;
|
||||
|
||||
/* Delay between detecting a jack and starting microphone
|
||||
* detect (specified in ms)
|
||||
*/
|
||||
int micdet_delay;
|
||||
|
||||
/* IRQ for microphone detection if brought out directly as a
|
||||
* signal.
|
||||
*/
|
||||
|
|
|
@ -195,7 +195,7 @@ ok:
|
|||
static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int i;
|
||||
|
||||
/* If the DSP is already running then noop */
|
||||
|
@ -210,9 +210,9 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
|
|||
WM8958_DSP2_ENA, WM8958_DSP2_ENA);
|
||||
|
||||
/* If we've got user supplied MBC settings use them */
|
||||
if (pdata && pdata->num_mbc_cfgs) {
|
||||
if (control->pdata.num_mbc_cfgs) {
|
||||
struct wm8958_mbc_cfg *cfg
|
||||
= &pdata->mbc_cfgs[wm8994->mbc_cfg];
|
||||
= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
|
||||
snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
|
||||
|
@ -239,7 +239,7 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
|
|||
static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int i, ena;
|
||||
|
||||
if (wm8994->mbc_vss)
|
||||
|
@ -249,26 +249,26 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
|
|||
WM8958_DSP2_ENA, WM8958_DSP2_ENA);
|
||||
|
||||
/* If we've got user supplied settings use them */
|
||||
if (pdata && pdata->num_mbc_cfgs) {
|
||||
if (control->pdata.num_mbc_cfgs) {
|
||||
struct wm8958_mbc_cfg *cfg
|
||||
= &pdata->mbc_cfgs[wm8994->mbc_cfg];
|
||||
= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
|
||||
snd_soc_write(codec, i + 0x2800,
|
||||
cfg->combined_regs[i]);
|
||||
}
|
||||
|
||||
if (pdata && pdata->num_vss_cfgs) {
|
||||
if (control->pdata.num_vss_cfgs) {
|
||||
struct wm8958_vss_cfg *cfg
|
||||
= &pdata->vss_cfgs[wm8994->vss_cfg];
|
||||
= &control->pdata.vss_cfgs[wm8994->vss_cfg];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
|
||||
snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
|
||||
}
|
||||
|
||||
if (pdata && pdata->num_vss_hpf_cfgs) {
|
||||
if (control->pdata.num_vss_hpf_cfgs) {
|
||||
struct wm8958_vss_hpf_cfg *cfg
|
||||
= &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
|
||||
= &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
|
||||
snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
|
||||
|
@ -300,7 +300,7 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
|
|||
static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int i;
|
||||
|
||||
wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
|
||||
|
@ -309,9 +309,9 @@ static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
|
|||
WM8958_DSP2_ENA, WM8958_DSP2_ENA);
|
||||
|
||||
/* If we've got user supplied settings use them */
|
||||
if (pdata && pdata->num_enh_eq_cfgs) {
|
||||
if (control->pdata.num_enh_eq_cfgs) {
|
||||
struct wm8958_enh_eq_cfg *cfg
|
||||
= &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
|
||||
= &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
|
||||
snd_soc_write(codec, i + 0x2200,
|
||||
|
@ -458,7 +458,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
int reg;
|
||||
|
||||
|
@ -467,7 +467,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
|
|||
if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
|
||||
return -EBUSY;
|
||||
|
||||
if (value >= pdata->num_mbc_cfgs)
|
||||
if (value >= control->pdata.num_mbc_cfgs)
|
||||
return -EINVAL;
|
||||
|
||||
wm8994->mbc_cfg = value;
|
||||
|
@ -548,7 +548,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
int reg;
|
||||
|
||||
|
@ -557,7 +557,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
|
|||
if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
|
||||
return -EBUSY;
|
||||
|
||||
if (value >= pdata->num_vss_cfgs)
|
||||
if (value >= control->pdata.num_vss_cfgs)
|
||||
return -EINVAL;
|
||||
|
||||
wm8994->vss_cfg = value;
|
||||
|
@ -581,7 +581,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
int reg;
|
||||
|
||||
|
@ -590,7 +590,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
|
|||
if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
|
||||
return -EBUSY;
|
||||
|
||||
if (value >= pdata->num_vss_hpf_cfgs)
|
||||
if (value >= control->pdata.num_vss_hpf_cfgs)
|
||||
return -EINVAL;
|
||||
|
||||
wm8994->vss_hpf_cfg = value;
|
||||
|
@ -748,7 +748,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
int reg;
|
||||
|
||||
|
@ -757,7 +757,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
|
|||
if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
|
||||
return -EBUSY;
|
||||
|
||||
if (value >= pdata->num_enh_eq_cfgs)
|
||||
if (value >= control->pdata.num_enh_eq_cfgs)
|
||||
return -EINVAL;
|
||||
|
||||
wm8994->enh_eq_cfg = value;
|
||||
|
@ -883,13 +883,6 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
|
|||
wm8994->mbc_vss = fw;
|
||||
mutex_unlock(&codec->mutex);
|
||||
}
|
||||
|
||||
/* We can't have more than one request outstanding at once so
|
||||
* we daisy chain.
|
||||
*/
|
||||
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
"wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
|
||||
codec, wm8958_enh_eq_loaded);
|
||||
}
|
||||
|
||||
static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
|
||||
|
@ -897,25 +890,18 @@ static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
|
|||
struct snd_soc_codec *codec = context;
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
|
||||
return;
|
||||
|
||||
mutex_lock(&codec->mutex);
|
||||
wm8994->mbc = fw;
|
||||
mutex_unlock(&codec->mutex);
|
||||
|
||||
/* We can't have more than one request outstanding at once so
|
||||
* we daisy chain.
|
||||
*/
|
||||
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
"wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
|
||||
codec, wm8958_mbc_vss_loaded);
|
||||
if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) {
|
||||
mutex_lock(&codec->mutex);
|
||||
wm8994->mbc = fw;
|
||||
mutex_unlock(&codec->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void wm8958_dsp2_init(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
int ret, i;
|
||||
|
||||
wm8994->dsp_active = -1;
|
||||
|
@ -932,9 +918,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
|
|||
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
"wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
|
||||
codec, wm8958_mbc_loaded);
|
||||
|
||||
if (!pdata)
|
||||
return;
|
||||
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
"wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
|
||||
codec, wm8958_mbc_vss_loaded);
|
||||
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
"wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
|
||||
codec, wm8958_enh_eq_loaded);
|
||||
|
||||
if (pdata->num_mbc_cfgs) {
|
||||
struct snd_kcontrol_new control[] = {
|
||||
|
|
|
@ -110,13 +110,13 @@ static const struct wm8958_micd_rate jackdet_rates[] = {
|
|||
static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int best, i, sysclk, val;
|
||||
bool idle;
|
||||
const struct wm8958_micd_rate *rates;
|
||||
int num_rates;
|
||||
|
||||
if (!(wm8994->pdata && wm8994->pdata->micd_rates) &&
|
||||
wm8994->jack_cb != wm8958_default_micdet)
|
||||
if (wm8994->jack_cb != wm8958_default_micdet)
|
||||
return;
|
||||
|
||||
idle = !wm8994->jack_mic;
|
||||
|
@ -127,9 +127,9 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
|
|||
else
|
||||
sysclk = wm8994->aifclk[0];
|
||||
|
||||
if (wm8994->pdata && wm8994->pdata->micd_rates) {
|
||||
rates = wm8994->pdata->micd_rates;
|
||||
num_rates = wm8994->pdata->num_micd_rates;
|
||||
if (control->pdata.micd_rates) {
|
||||
rates = control->pdata.micd_rates;
|
||||
num_rates = control->pdata.num_micd_rates;
|
||||
} else if (wm8994->jackdet) {
|
||||
rates = jackdet_rates;
|
||||
num_rates = ARRAY_SIZE(jackdet_rates);
|
||||
|
@ -326,7 +326,8 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
|
|||
static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
int base = wm8994_drc_base[drc];
|
||||
int cfg = wm8994->drc_cfg[drc];
|
||||
int save, i;
|
||||
|
@ -362,7 +363,8 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
int drc = wm8994_get_drc(kcontrol->id.name);
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
|
||||
|
@ -394,7 +396,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
|
|||
static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
int base = wm8994_retune_mobile_base[block];
|
||||
int iface, best, best_val, save, i, cfg;
|
||||
|
||||
|
@ -465,7 +468,8 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
|
||||
|
@ -862,7 +866,7 @@ static void vmid_reference(struct snd_soc_codec *codec)
|
|||
WM8994_BIAS_SRC |
|
||||
WM8994_STARTUP_BIAS_ENA |
|
||||
WM8994_VMID_BUF_ENA |
|
||||
(0x3 << WM8994_VMID_RAMP_SHIFT));
|
||||
(0x2 << WM8994_VMID_RAMP_SHIFT));
|
||||
|
||||
/* Main bias enable, VMID=2x40k */
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
|
||||
|
@ -870,7 +874,7 @@ static void vmid_reference(struct snd_soc_codec *codec)
|
|||
WM8994_VMID_SEL_MASK,
|
||||
WM8994_BIAS_ENA | 0x2);
|
||||
|
||||
msleep(50);
|
||||
msleep(300);
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
||||
WM8994_VMID_RAMP_MASK |
|
||||
|
@ -939,16 +943,10 @@ static void vmid_dereference(struct snd_soc_codec *codec)
|
|||
WM8994_BIAS_SRC |
|
||||
WM8994_VMID_DISCH);
|
||||
|
||||
switch (wm8994->vmid_mode) {
|
||||
case WM8994_VMID_FORCE:
|
||||
msleep(350);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
|
||||
WM8994_VMID_SEL_MASK, 0);
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
|
||||
WM8994_VROI, WM8994_VROI);
|
||||
msleep(400);
|
||||
|
||||
/* Active discharge */
|
||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
|
||||
|
@ -957,17 +955,12 @@ static void vmid_dereference(struct snd_soc_codec *codec)
|
|||
WM8994_LINEOUT1_DISCH |
|
||||
WM8994_LINEOUT2_DISCH);
|
||||
|
||||
msleep(150);
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
|
||||
WM8994_LINEOUT1N_ENA |
|
||||
WM8994_LINEOUT1P_ENA |
|
||||
WM8994_LINEOUT2N_ENA |
|
||||
WM8994_LINEOUT2P_ENA, 0);
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
|
||||
WM8994_VROI, 0);
|
||||
|
||||
/* Switch off startup biases */
|
||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
||||
WM8994_BIAS_SRC |
|
||||
|
@ -976,10 +969,7 @@ static void vmid_dereference(struct snd_soc_codec *codec)
|
|||
WM8994_VMID_RAMP_MASK, 0);
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
|
||||
WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
||||
WM8994_VMID_RAMP_MASK, 0);
|
||||
WM8994_VMID_SEL_MASK, 0);
|
||||
}
|
||||
|
||||
pm_runtime_put(codec->dev);
|
||||
|
@ -2277,6 +2267,18 @@ out:
|
|||
|
||||
configure_clock(codec);
|
||||
|
||||
/*
|
||||
* If SYSCLK will be less than 50kHz adjust AIFnCLK dividers
|
||||
* for detection.
|
||||
*/
|
||||
if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
|
||||
dev_dbg(codec->dev, "Configuring AIFs for 128fs\n");
|
||||
snd_soc_update_bits(codec, WM8994_AIF1_RATE,
|
||||
WM8994_AIF1CLK_RATE_MASK, 0x1);
|
||||
snd_soc_update_bits(codec, WM8994_AIF2_RATE,
|
||||
WM8994_AIF2CLK_RATE_MASK, 0x1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2365,6 +2367,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
|||
|
||||
configure_clock(codec);
|
||||
|
||||
/*
|
||||
* If SYSCLK will be less than 50kHz adjust AIFnCLK dividers
|
||||
* for detection.
|
||||
*/
|
||||
if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
|
||||
dev_dbg(codec->dev, "Configuring AIFs for 128fs\n");
|
||||
snd_soc_update_bits(codec, WM8994_AIF1_RATE,
|
||||
WM8994_AIF1CLK_RATE_MASK, 0x1);
|
||||
snd_soc_update_bits(codec, WM8994_AIF2_RATE,
|
||||
WM8994_AIF2CLK_RATE_MASK, 0x1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3082,7 +3096,8 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec)
|
|||
static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
|
||||
{
|
||||
struct snd_soc_codec *codec = wm8994->hubs.codec;
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
struct snd_kcontrol_new controls[] = {
|
||||
SOC_ENUM_EXT("AIF1.1 EQ Mode",
|
||||
wm8994->retune_mobile_enum,
|
||||
|
@ -3149,7 +3164,8 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
|
|||
static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
|
||||
{
|
||||
struct snd_soc_codec *codec = wm8994->hubs.codec;
|
||||
struct wm8994_pdata *pdata = wm8994->pdata;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct wm8994_pdata *pdata = &control->pdata;
|
||||
int ret, i;
|
||||
|
||||
if (!pdata)
|
||||
|
@ -3451,7 +3467,7 @@ static void wm8958_default_micdet(u16 status, void *data)
|
|||
|
||||
mutex_unlock(&wm8994->accdet_lock);
|
||||
|
||||
if (wm8994->pdata->jd_ext_cap)
|
||||
if (wm8994->wm8994->pdata.jd_ext_cap)
|
||||
snd_soc_dapm_disable_pin(&codec->dapm,
|
||||
"MICBIAS2");
|
||||
}
|
||||
|
@ -3486,11 +3502,48 @@ static void wm8958_default_micdet(u16 status, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Deferred mic detection to allow for extra settling time */
|
||||
static void wm1811_mic_work(struct work_struct *work)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv,
|
||||
mic_work.work);
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct snd_soc_codec *codec = wm8994->hubs.codec;
|
||||
|
||||
pm_runtime_get_sync(codec->dev);
|
||||
|
||||
/* If required for an external cap force MICBIAS on */
|
||||
if (control->pdata.jd_ext_cap) {
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm,
|
||||
"MICBIAS2");
|
||||
snd_soc_dapm_sync(&codec->dapm);
|
||||
}
|
||||
|
||||
mutex_lock(&wm8994->accdet_lock);
|
||||
|
||||
dev_dbg(codec->dev, "Starting mic detection\n");
|
||||
|
||||
/*
|
||||
* Start off measument of microphone impedence to find out
|
||||
* what's actually there.
|
||||
*/
|
||||
wm8994->mic_detecting = true;
|
||||
wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
|
||||
|
||||
snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
|
||||
WM8958_MICD_ENA, WM8958_MICD_ENA);
|
||||
|
||||
mutex_unlock(&wm8994->accdet_lock);
|
||||
|
||||
pm_runtime_put(codec->dev);
|
||||
}
|
||||
|
||||
static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = data;
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
struct snd_soc_codec *codec = wm8994->hubs.codec;
|
||||
int reg;
|
||||
int reg, delay;
|
||||
bool present;
|
||||
|
||||
pm_runtime_get_sync(codec->dev);
|
||||
|
@ -3521,18 +3574,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
|
|||
snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
|
||||
WM1811_JACKDET_DB, 0);
|
||||
|
||||
/*
|
||||
* Start off measument of microphone impedence to find
|
||||
* out what's actually there.
|
||||
*/
|
||||
wm8994->mic_detecting = true;
|
||||
wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
|
||||
|
||||
snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
|
||||
WM8958_MICD_ENA, WM8958_MICD_ENA);
|
||||
delay = control->pdata.micdet_delay;
|
||||
schedule_delayed_work(&wm8994->mic_work,
|
||||
msecs_to_jiffies(delay));
|
||||
} else {
|
||||
dev_dbg(codec->dev, "Jack not detected\n");
|
||||
|
||||
cancel_delayed_work_sync(&wm8994->mic_work);
|
||||
|
||||
snd_soc_update_bits(codec, WM8958_MICBIAS2,
|
||||
WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
|
||||
|
||||
|
@ -3549,14 +3598,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
|
|||
|
||||
mutex_unlock(&wm8994->accdet_lock);
|
||||
|
||||
/* If required for an external cap force MICBIAS on */
|
||||
if (wm8994->pdata->jd_ext_cap) {
|
||||
if (present)
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm,
|
||||
"MICBIAS2");
|
||||
else
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
|
||||
}
|
||||
/* Turn off MICBIAS if it was on for an external cap */
|
||||
if (control->pdata.jd_ext_cap && !present)
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
|
||||
|
||||
if (present)
|
||||
snd_soc_jack_report(wm8994->micdet[0].jack,
|
||||
|
@ -3633,8 +3677,8 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
|
|||
wm8958_micd_set_rate(codec);
|
||||
|
||||
/* Detect microphones and short circuits by default */
|
||||
if (wm8994->pdata->micd_lvl_sel)
|
||||
micd_lvl_sel = wm8994->pdata->micd_lvl_sel;
|
||||
if (control->pdata.micd_lvl_sel)
|
||||
micd_lvl_sel = control->pdata.micd_lvl_sel;
|
||||
else
|
||||
micd_lvl_sel = 0x41;
|
||||
|
||||
|
@ -3779,15 +3823,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
|
|||
snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
|
||||
|
||||
mutex_init(&wm8994->accdet_lock);
|
||||
INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
|
||||
INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
|
||||
wm1811_jackdet_bootstrap);
|
||||
|
||||
switch (control->type) {
|
||||
case WM8994:
|
||||
INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
|
||||
break;
|
||||
case WM1811:
|
||||
INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
|
||||
init_completion(&wm8994->fll_locked[i]);
|
||||
|
||||
if (wm8994->pdata && wm8994->pdata->micdet_irq)
|
||||
wm8994->micdet_irq = wm8994->pdata->micdet_irq;
|
||||
wm8994->micdet_irq = control->pdata.micdet_irq;
|
||||
|
||||
pm_runtime_enable(codec->dev);
|
||||
pm_runtime_idle(codec->dev);
|
||||
|
@ -3800,8 +3853,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
|
|||
switch (control->type) {
|
||||
case WM8994:
|
||||
/* Single ended line outputs should have VMID on. */
|
||||
if (!wm8994->pdata->lineout1_diff ||
|
||||
!wm8994->pdata->lineout2_diff)
|
||||
if (!control->pdata.lineout1_diff ||
|
||||
!control->pdata.lineout2_diff)
|
||||
codec->dapm.idle_bias_off = 0;
|
||||
|
||||
switch (wm8994->revision) {
|
||||
|
@ -3839,20 +3892,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
|
|||
wm8994->hubs.no_cache_dac_hp_direct = true;
|
||||
wm8994->fll_byp = true;
|
||||
|
||||
switch (control->cust_id) {
|
||||
case 0:
|
||||
case 2:
|
||||
wm8994->hubs.dcs_codes_l = -9;
|
||||
wm8994->hubs.dcs_codes_r = -7;
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
wm8994->hubs.dcs_codes_l = -8;
|
||||
wm8994->hubs.dcs_codes_r = -7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
wm8994->hubs.dcs_codes_l = -9;
|
||||
wm8994->hubs.dcs_codes_r = -7;
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
|
||||
WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
|
||||
|
@ -4236,7 +4277,6 @@ static int __devinit wm8994_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, wm8994);
|
||||
|
||||
wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
|
||||
wm8994->pdata = dev_get_platdata(pdev->dev.parent);
|
||||
|
||||
return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
|
||||
wm8994_dai, ARRAY_SIZE(wm8994_dai));
|
||||
|
|
|
@ -143,7 +143,6 @@ struct wm8994_priv {
|
|||
int micdet_irq;
|
||||
|
||||
int revision;
|
||||
struct wm8994_pdata *pdata;
|
||||
|
||||
unsigned int aif1clk_enable:1;
|
||||
unsigned int aif2clk_enable:1;
|
||||
|
|
Loading…
Reference in New Issue