Merge remote-tracking branch 'asoc/topic/arizona' into asoc-next
This commit is contained in:
commit
daa5ab9e0d
|
@ -72,6 +72,16 @@ config INPUT_AD714X_SPI
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ad714x-spi.
|
||||
|
||||
config INPUT_ARIZONA_HAPTICS
|
||||
tristate "Arizona haptics support"
|
||||
depends on MFD_ARIZONA && SND_SOC
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
Say Y to enable support for the haptics module in Arizona CODECs.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called arizona-haptics.
|
||||
|
||||
config INPUT_BMA150
|
||||
tristate "BMA150/SMB380 acceleration sensor support"
|
||||
depends on I2C
|
||||
|
|
|
@ -14,6 +14,7 @@ obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o
|
|||
obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o
|
||||
obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o
|
||||
obj-$(CONFIG_INPUT_APANEL) += apanel.o
|
||||
obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o
|
||||
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
|
||||
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
|
||||
obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Arizona haptics driver
|
||||
*
|
||||
* Copyright 2012 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.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
#include <linux/mfd/arizona/pdata.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
struct arizona_haptics {
|
||||
struct arizona *arizona;
|
||||
struct input_dev *input_dev;
|
||||
struct work_struct work;
|
||||
|
||||
struct mutex mutex;
|
||||
u8 intensity;
|
||||
};
|
||||
|
||||
static void arizona_haptics_work(struct work_struct *work)
|
||||
{
|
||||
struct arizona_haptics *haptics = container_of(work,
|
||||
struct arizona_haptics,
|
||||
work);
|
||||
struct arizona *arizona = haptics->arizona;
|
||||
struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex;
|
||||
int ret;
|
||||
|
||||
if (!haptics->arizona->dapm) {
|
||||
dev_err(arizona->dev, "No DAPM context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (haptics->intensity) {
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_HAPTICS_PHASE_2_INTENSITY,
|
||||
ARIZONA_PHASE2_INTENSITY_MASK,
|
||||
haptics->intensity);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to set intensity: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This enable sequence will be a noop if already enabled */
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_HAPTICS_CONTROL_1,
|
||||
ARIZONA_HAP_CTRL_MASK,
|
||||
1 << ARIZONA_HAP_CTRL_SHIFT);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to start haptics: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
||||
|
||||
ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS");
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to start HAPTICS: %d\n",
|
||||
ret);
|
||||
mutex_unlock(dapm_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = snd_soc_dapm_sync(arizona->dapm);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
|
||||
ret);
|
||||
mutex_unlock(dapm_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_unlock(dapm_mutex);
|
||||
|
||||
} else {
|
||||
/* This disable sequence will be a noop if already enabled */
|
||||
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
||||
|
||||
ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS");
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n",
|
||||
ret);
|
||||
mutex_unlock(dapm_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = snd_soc_dapm_sync(arizona->dapm);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
|
||||
ret);
|
||||
mutex_unlock(dapm_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_unlock(dapm_mutex);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_HAPTICS_CONTROL_1,
|
||||
ARIZONA_HAP_CTRL_MASK,
|
||||
1 << ARIZONA_HAP_CTRL_SHIFT);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to stop haptics: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int arizona_haptics_play(struct input_dev *input, void *data,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
struct arizona_haptics *haptics = input_get_drvdata(input);
|
||||
struct arizona *arizona = haptics->arizona;
|
||||
|
||||
if (!arizona->dapm) {
|
||||
dev_err(arizona->dev, "No DAPM context\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (effect->u.rumble.strong_magnitude) {
|
||||
/* Scale the magnitude into the range the device supports */
|
||||
if (arizona->pdata.hap_act) {
|
||||
haptics->intensity =
|
||||
effect->u.rumble.strong_magnitude >> 9;
|
||||
if (effect->direction < 0x8000)
|
||||
haptics->intensity += 0x7f;
|
||||
} else {
|
||||
haptics->intensity =
|
||||
effect->u.rumble.strong_magnitude >> 8;
|
||||
}
|
||||
} else {
|
||||
haptics->intensity = 0;
|
||||
}
|
||||
|
||||
schedule_work(&haptics->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arizona_haptics_close(struct input_dev *input)
|
||||
{
|
||||
struct arizona_haptics *haptics = input_get_drvdata(input);
|
||||
struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex;
|
||||
|
||||
cancel_work_sync(&haptics->work);
|
||||
|
||||
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
||||
|
||||
if (haptics->arizona->dapm)
|
||||
snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS");
|
||||
|
||||
mutex_unlock(dapm_mutex);
|
||||
}
|
||||
|
||||
static int arizona_haptics_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
struct arizona_haptics *haptics;
|
||||
int ret;
|
||||
|
||||
haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL);
|
||||
if (!haptics)
|
||||
return -ENOMEM;
|
||||
|
||||
haptics->arizona = arizona;
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1,
|
||||
ARIZONA_HAP_ACT, arizona->pdata.hap_act);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to set haptics actuator: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
INIT_WORK(&haptics->work, arizona_haptics_work);
|
||||
|
||||
haptics->input_dev = input_allocate_device();
|
||||
if (haptics->input_dev == NULL) {
|
||||
dev_err(arizona->dev, "Failed to allocate input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
input_set_drvdata(haptics->input_dev, haptics);
|
||||
|
||||
haptics->input_dev->name = "arizona:haptics";
|
||||
haptics->input_dev->dev.parent = pdev->dev.parent;
|
||||
haptics->input_dev->close = arizona_haptics_close;
|
||||
__set_bit(FF_RUMBLE, haptics->input_dev->ffbit);
|
||||
|
||||
ret = input_ff_create_memless(haptics->input_dev, NULL,
|
||||
arizona_haptics_play);
|
||||
if (ret < 0) {
|
||||
dev_err(arizona->dev, "input_ff_create_memless() failed: %d\n",
|
||||
ret);
|
||||
goto err_ialloc;
|
||||
}
|
||||
|
||||
ret = input_register_device(haptics->input_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(arizona->dev, "couldn't register input device: %d\n",
|
||||
ret);
|
||||
goto err_iff;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, haptics);
|
||||
|
||||
return 0;
|
||||
|
||||
err_iff:
|
||||
if (haptics->input_dev)
|
||||
input_ff_destroy(haptics->input_dev);
|
||||
err_ialloc:
|
||||
input_free_device(haptics->input_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arizona_haptics_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona_haptics *haptics = platform_get_drvdata(pdev);
|
||||
|
||||
input_unregister_device(haptics->input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver arizona_haptics_driver = {
|
||||
.probe = arizona_haptics_probe,
|
||||
.remove = arizona_haptics_remove,
|
||||
.driver = {
|
||||
.name = "arizona-haptics",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
module_platform_driver(arizona_haptics_driver);
|
||||
|
||||
MODULE_ALIAS("platform:arizona-haptics");
|
||||
MODULE_DESCRIPTION("Arizona haptics driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
|
@ -272,6 +272,7 @@ static struct mfd_cell early_devs[] = {
|
|||
static struct mfd_cell wm5102_devs[] = {
|
||||
{ .name = "arizona-extcon" },
|
||||
{ .name = "arizona-gpio" },
|
||||
{ .name = "arizona-haptics" },
|
||||
{ .name = "arizona-micsupp" },
|
||||
{ .name = "arizona-pwm" },
|
||||
{ .name = "wm5102-codec" },
|
||||
|
@ -280,6 +281,7 @@ static struct mfd_cell wm5102_devs[] = {
|
|||
static struct mfd_cell wm5110_devs[] = {
|
||||
{ .name = "arizona-extcon" },
|
||||
{ .name = "arizona-gpio" },
|
||||
{ .name = "arizona-haptics" },
|
||||
{ .name = "arizona-micsupp" },
|
||||
{ .name = "arizona-pwm" },
|
||||
{ .name = "wm5110-codec" },
|
||||
|
|
|
@ -78,6 +78,8 @@ enum arizona_type {
|
|||
|
||||
#define ARIZONA_NUM_IRQ 50
|
||||
|
||||
struct snd_soc_dapm_context;
|
||||
|
||||
struct arizona {
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
|
@ -98,6 +100,8 @@ struct arizona {
|
|||
|
||||
struct mutex clk_lock;
|
||||
int clk32k_ref;
|
||||
|
||||
struct snd_soc_dapm_context *dapm;
|
||||
};
|
||||
|
||||
int arizona_clk32k_enable(struct arizona *arizona);
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
|
||||
#define ARIZONA_MAX_OUTPUT 6
|
||||
|
||||
#define ARIZONA_HAP_ACT_ERM 0
|
||||
#define ARIZONA_HAP_ACT_LRA 2
|
||||
|
||||
#define ARIZONA_MAX_PDM_SPK 2
|
||||
|
||||
struct regulator_init_data;
|
||||
|
@ -114,6 +117,9 @@ struct arizona_pdata {
|
|||
|
||||
/** PDM speaker format */
|
||||
unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK];
|
||||
|
||||
/** Haptic actuator type */
|
||||
unsigned int hap_act;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -148,7 +148,9 @@ config SND_SOC_WM_HUBS
|
|||
|
||||
config SND_SOC_WM_ADSP
|
||||
tristate
|
||||
default y if SND_SOC_WM5102=y
|
||||
default y if SND_SOC_WM2200=y
|
||||
default m if SND_SOC_WM5102=m
|
||||
default m if SND_SOC_WM2200=m
|
||||
|
||||
config SND_SOC_AB8500_CODEC
|
||||
|
|
|
@ -226,6 +226,31 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
|
|||
const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
|
||||
EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
|
||||
|
||||
static const char *arizona_vol_ramp_text[] = {
|
||||
"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
|
||||
"15ms/6dB", "30ms/6dB",
|
||||
};
|
||||
|
||||
const struct soc_enum arizona_in_vd_ramp =
|
||||
SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
|
||||
ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
|
||||
EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
|
||||
|
||||
const struct soc_enum arizona_in_vi_ramp =
|
||||
SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
|
||||
ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
|
||||
EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
|
||||
|
||||
const struct soc_enum arizona_out_vd_ramp =
|
||||
SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
|
||||
ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
|
||||
EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
|
||||
|
||||
const struct soc_enum arizona_out_vi_ramp =
|
||||
SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
|
||||
ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
|
||||
EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
|
||||
|
||||
static const char *arizona_lhpf_mode_text[] = {
|
||||
"Low-pass", "High-pass"
|
||||
};
|
||||
|
@ -380,6 +405,18 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
|
|||
case 49152000:
|
||||
val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 67737600:
|
||||
case 73728000:
|
||||
val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 90316800:
|
||||
case 98304000:
|
||||
val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 135475200:
|
||||
case 147456000:
|
||||
val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -737,6 +774,9 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
|
||||
arizona_dai_clk_str(clk_id));
|
||||
|
||||
memset(&routes, 0, sizeof(routes));
|
||||
routes[0].sink = dai->driver->capture.stream_name;
|
||||
routes[1].sink = dai->driver->playback.stream_name;
|
||||
|
@ -749,6 +789,8 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
|
|||
routes[1].source = arizona_dai_clk_str(clk_id);
|
||||
snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
|
||||
|
||||
dai_priv->clk = clk_id;
|
||||
|
||||
return snd_soc_dapm_sync(&codec->dapm);
|
||||
}
|
||||
|
||||
|
@ -925,6 +967,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
|
|||
bool ena;
|
||||
int ret;
|
||||
|
||||
if (fll->fref == Fref && fll->fout == Fout)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(arizona->regmap, fll->base + 1, ®);
|
||||
if (ret != 0) {
|
||||
arizona_fll_err(fll, "Failed to read current state: %d\n",
|
||||
|
@ -970,6 +1015,9 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
|
|||
if (ena)
|
||||
pm_runtime_put_autosuspend(arizona->dev);
|
||||
|
||||
fll->fref = Fref;
|
||||
fll->fout = Fout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -998,10 +1046,13 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
|
|||
ARIZONA_FLL1_SYNC_ENA);
|
||||
|
||||
ret = wait_for_completion_timeout(&fll->ok,
|
||||
msecs_to_jiffies(25));
|
||||
msecs_to_jiffies(250));
|
||||
if (ret == 0)
|
||||
arizona_fll_warn(fll, "Timed out waiting for lock\n");
|
||||
|
||||
fll->fref = Fref;
|
||||
fll->fout = Fout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_set_fll);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "wm_adsp.h"
|
||||
|
||||
#define ARIZONA_CLK_SYSCLK 1
|
||||
#define ARIZONA_CLK_ASYNCCLK 2
|
||||
#define ARIZONA_CLK_OPCLK 3
|
||||
|
@ -46,15 +48,18 @@
|
|||
#define ARIZONA_MIXER_VOL_SHIFT 1
|
||||
#define ARIZONA_MIXER_VOL_WIDTH 7
|
||||
|
||||
#define ARIZONA_MAX_DAI 3
|
||||
#define ARIZONA_MAX_DAI 4
|
||||
#define ARIZONA_MAX_ADSP 4
|
||||
|
||||
struct arizona;
|
||||
struct wm_adsp;
|
||||
|
||||
struct arizona_dai_priv {
|
||||
int clk;
|
||||
};
|
||||
|
||||
struct arizona_priv {
|
||||
struct wm_adsp adsp[ARIZONA_MAX_ADSP];
|
||||
struct arizona *arizona;
|
||||
int sysclk;
|
||||
int asyncclk;
|
||||
|
@ -89,19 +94,30 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
|
|||
const struct snd_kcontrol_new name##_mux = \
|
||||
SOC_DAPM_VALUE_ENUM("Route", name##_enum)
|
||||
|
||||
#define ARIZONA_MUX_ENUMS(name, base_reg) \
|
||||
static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \
|
||||
static ARIZONA_MUX_CTL_DECL(name)
|
||||
|
||||
#define ARIZONA_MIXER_ENUMS(name, base_reg) \
|
||||
static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
|
||||
static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
|
||||
static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
|
||||
static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
|
||||
static ARIZONA_MUX_CTL_DECL(name##_in1); \
|
||||
static ARIZONA_MUX_CTL_DECL(name##_in2); \
|
||||
static ARIZONA_MUX_CTL_DECL(name##_in3); \
|
||||
static ARIZONA_MUX_CTL_DECL(name##_in4)
|
||||
ARIZONA_MUX_ENUMS(name##_in1, base_reg); \
|
||||
ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \
|
||||
ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \
|
||||
ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6)
|
||||
|
||||
#define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \
|
||||
ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \
|
||||
ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \
|
||||
ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \
|
||||
ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \
|
||||
ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \
|
||||
ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40)
|
||||
|
||||
#define ARIZONA_MUX(name, ctrl) \
|
||||
SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
|
||||
|
||||
#define ARIZONA_MUX_WIDGETS(name, name_str) \
|
||||
ARIZONA_MUX(name_str " Input", &name##_mux)
|
||||
|
||||
#define ARIZONA_MIXER_WIDGETS(name, name_str) \
|
||||
ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \
|
||||
ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \
|
||||
|
@ -109,6 +125,19 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
|
|||
ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \
|
||||
SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
|
||||
|
||||
#define ARIZONA_DSP_WIDGETS(name, name_str) \
|
||||
ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \
|
||||
ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \
|
||||
ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \
|
||||
ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \
|
||||
ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \
|
||||
ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \
|
||||
ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \
|
||||
ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux)
|
||||
|
||||
#define ARIZONA_MUX_ROUTES(name) \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Input")
|
||||
|
||||
#define ARIZONA_MIXER_ROUTES(widget, name) \
|
||||
{ widget, NULL, name " Mixer" }, \
|
||||
{ name " Mixer", NULL, name " Input 1" }, \
|
||||
|
@ -120,6 +149,28 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
|
|||
ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
|
||||
|
||||
#define ARIZONA_DSP_ROUTES(name) \
|
||||
{ name, NULL, name " Aux 1" }, \
|
||||
{ name, NULL, name " Aux 2" }, \
|
||||
{ name, NULL, name " Aux 3" }, \
|
||||
{ name, NULL, name " Aux 4" }, \
|
||||
{ name, NULL, name " Aux 5" }, \
|
||||
{ name, NULL, name " Aux 6" }, \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
|
||||
ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
|
||||
ARIZONA_MIXER_ROUTES(name, name "L"), \
|
||||
ARIZONA_MIXER_ROUTES(name, name "R")
|
||||
|
||||
extern const struct soc_enum arizona_in_vi_ramp;
|
||||
extern const struct soc_enum arizona_in_vd_ramp;
|
||||
|
||||
extern const struct soc_enum arizona_out_vi_ramp;
|
||||
extern const struct soc_enum arizona_out_vd_ramp;
|
||||
|
||||
extern const struct soc_enum arizona_lhpf1_mode;
|
||||
extern const struct soc_enum arizona_lhpf2_mode;
|
||||
extern const struct soc_enum arizona_lhpf3_mode;
|
||||
|
@ -146,6 +197,8 @@ struct arizona_fll {
|
|||
unsigned int vco_mult;
|
||||
struct completion lock;
|
||||
struct completion ok;
|
||||
unsigned int fref;
|
||||
unsigned int fout;
|
||||
|
||||
char lock_name[ARIZONA_FLL_NAME_LEN];
|
||||
char clock_ok_name[ARIZONA_FLL_NAME_LEN];
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "arizona.h"
|
||||
#include "wm5102.h"
|
||||
#include "wm_adsp.h"
|
||||
|
||||
struct wm5102_priv {
|
||||
struct arizona_priv core;
|
||||
|
@ -42,6 +43,13 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
|
|||
static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
|
||||
static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
|
||||
|
||||
static const struct wm_adsp_region wm5102_dsp1_regions[] = {
|
||||
{ .type = WMFW_ADSP2_PM, .base = 0x100000 },
|
||||
{ .type = WMFW_ADSP2_ZM, .base = 0x180000 },
|
||||
{ .type = WMFW_ADSP2_XM, .base = 0x190000 },
|
||||
{ .type = WMFW_ADSP2_YM, .base = 0x1a8000 },
|
||||
};
|
||||
|
||||
static const struct reg_default wm5102_sysclk_reva_patch[] = {
|
||||
{ 0x3000, 0x2225 },
|
||||
{ 0x3001, 0x3a03 },
|
||||
|
@ -627,11 +635,23 @@ SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
|
|||
ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT,
|
||||
0xbf, 0, digital_tlv),
|
||||
|
||||
SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
|
||||
SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
|
||||
|
||||
ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
|
||||
|
||||
SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21,
|
||||
ARIZONA_EQ1_ENA_MASK),
|
||||
SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21,
|
||||
ARIZONA_EQ2_ENA_MASK),
|
||||
SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21,
|
||||
ARIZONA_EQ3_ENA_MASK),
|
||||
SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21,
|
||||
ARIZONA_EQ4_ENA_MASK),
|
||||
|
||||
SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
|
||||
24, 0, eq_tlv),
|
||||
SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
|
||||
|
@ -687,6 +707,14 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
|
|||
ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
|
||||
|
||||
SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
|
||||
SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
|
||||
SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
|
||||
SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
|
||||
|
||||
ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
|
||||
|
||||
SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
|
||||
SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
|
||||
SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
|
||||
|
@ -708,14 +736,6 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
|
|||
ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
|
||||
|
||||
SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
|
||||
ARIZONA_OUT1_OSR_SHIFT, 1, 0),
|
||||
SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
|
||||
ARIZONA_OUT2_OSR_SHIFT, 1, 0),
|
||||
SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
|
||||
ARIZONA_OUT3_OSR_SHIFT, 1, 0),
|
||||
SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
|
||||
ARIZONA_OUT4_OSR_SHIFT, 1, 0),
|
||||
SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
|
||||
ARIZONA_OUT5_OSR_SHIFT, 1, 0),
|
||||
|
||||
|
@ -745,16 +765,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
|
|||
ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
|
||||
0xbf, 0, digital_tlv),
|
||||
|
||||
SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
|
||||
ARIZONA_OUTPUT_PATH_CONFIG_1R,
|
||||
ARIZONA_OUT1L_PGA_VOL_SHIFT,
|
||||
0x34, 0x40, 0, ana_tlv),
|
||||
SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
|
||||
ARIZONA_OUTPUT_PATH_CONFIG_2R,
|
||||
ARIZONA_OUT2L_PGA_VOL_SHIFT,
|
||||
0x34, 0x40, 0, ana_tlv),
|
||||
SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
|
||||
ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
|
||||
SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
|
||||
SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
|
||||
|
||||
SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
|
||||
ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
|
||||
|
@ -819,11 +831,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
|
|||
ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
|
||||
|
||||
ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
|
||||
|
||||
ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE);
|
||||
|
||||
ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE);
|
||||
|
||||
static const char *wm5102_aec_loopback_texts[] = {
|
||||
"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
|
||||
|
@ -864,6 +880,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
|
|||
|
||||
SND_SOC_DAPM_SIGGEN("TONE"),
|
||||
SND_SOC_DAPM_SIGGEN("NOISE"),
|
||||
SND_SOC_DAPM_SIGGEN("HAPTICS"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("IN1L"),
|
||||
SND_SOC_DAPM_INPUT("IN1R"),
|
||||
|
@ -894,9 +911,9 @@ SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
|
|||
SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
|
||||
ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
|
||||
ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
|
||||
ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
|
||||
ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
|
||||
ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
|
||||
ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
|
||||
|
@ -996,6 +1013,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
|
|||
SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
|
||||
ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
|
||||
|
||||
ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
|
||||
|
||||
SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
|
||||
ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
|
||||
|
||||
|
@ -1071,10 +1090,12 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
|
|||
ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
|
||||
ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
|
||||
|
||||
ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
|
||||
ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
|
||||
ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
|
||||
ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
|
||||
|
||||
WM_ADSP2("DSP1", 0),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("HPOUT1L"),
|
||||
SND_SOC_DAPM_OUTPUT("HPOUT1R"),
|
||||
|
@ -1094,6 +1115,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
|
|||
{ name, "Noise Generator", "Noise Generator" }, \
|
||||
{ name, "Tone Generator 1", "Tone Generator 1" }, \
|
||||
{ name, "Tone Generator 2", "Tone Generator 2" }, \
|
||||
{ name, "Haptics", "HAPTICS" }, \
|
||||
{ name, "AEC", "AEC Loopback" }, \
|
||||
{ name, "IN1L", "IN1L PGA" }, \
|
||||
{ name, "IN1R", "IN1R PGA" }, \
|
||||
|
@ -1127,7 +1149,13 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
|
|||
{ name, "ASRC1L", "ASRC1L" }, \
|
||||
{ name, "ASRC1R", "ASRC1R" }, \
|
||||
{ name, "ASRC2L", "ASRC2L" }, \
|
||||
{ name, "ASRC2R", "ASRC2R" }
|
||||
{ name, "ASRC2R", "ASRC2R" }, \
|
||||
{ name, "DSP1.1", "DSP1" }, \
|
||||
{ name, "DSP1.2", "DSP1" }, \
|
||||
{ name, "DSP1.3", "DSP1" }, \
|
||||
{ name, "DSP1.4", "DSP1" }, \
|
||||
{ name, "DSP1.5", "DSP1" }, \
|
||||
{ name, "DSP1.6", "DSP1" }
|
||||
|
||||
static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
|
||||
{ "AIF2 Capture", NULL, "DBVDD2" },
|
||||
|
@ -1213,6 +1241,11 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
|
|||
{ "IN3L PGA", NULL, "IN3L" },
|
||||
{ "IN3R PGA", NULL, "IN3R" },
|
||||
|
||||
{ "ASRC1L", NULL, "ASRC1L Input" },
|
||||
{ "ASRC1R", NULL, "ASRC1R Input" },
|
||||
{ "ASRC2L", NULL, "ASRC2L Input" },
|
||||
{ "ASRC2R", NULL, "ASRC2R Input" },
|
||||
|
||||
ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
|
||||
ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
|
||||
ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
|
||||
|
@ -1255,10 +1288,12 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
|
|||
ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
|
||||
ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
|
||||
|
||||
ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
|
||||
ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
|
||||
ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
|
||||
ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
|
||||
ARIZONA_MUX_ROUTES("ASRC1L"),
|
||||
ARIZONA_MUX_ROUTES("ASRC1R"),
|
||||
ARIZONA_MUX_ROUTES("ASRC2L"),
|
||||
ARIZONA_MUX_ROUTES("ASRC2R"),
|
||||
|
||||
ARIZONA_DSP_ROUTES("DSP1"),
|
||||
|
||||
{ "AEC Loopback", "HPOUT1L", "OUT1L" },
|
||||
{ "AEC Loopback", "HPOUT1R", "OUT1R" },
|
||||
|
@ -1377,9 +1412,28 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
|
|||
static int wm5102_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
codec->control_data = priv->core.arizona->regmap;
|
||||
return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
|
||||
|
||||
priv->core.arizona->dapm = &codec->dapm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm5102_codec_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
priv->core.arizona->dapm = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WM5102_DIG_VU 0x0200
|
||||
|
@ -1406,6 +1460,7 @@ static unsigned int wm5102_digital_vu[] = {
|
|||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
|
||||
.probe = wm5102_codec_probe,
|
||||
.remove = wm5102_codec_remove,
|
||||
|
||||
.idle_bias_off = true,
|
||||
|
||||
|
@ -1424,7 +1479,7 @@ static int __devinit wm5102_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
struct wm5102_priv *wm5102;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv),
|
||||
GFP_KERNEL);
|
||||
|
@ -1434,6 +1489,19 @@ static int __devinit wm5102_probe(struct platform_device *pdev)
|
|||
|
||||
wm5102->core.arizona = arizona;
|
||||
|
||||
wm5102->core.adsp[0].part = "wm5102";
|
||||
wm5102->core.adsp[0].num = 1;
|
||||
wm5102->core.adsp[0].type = WMFW_ADSP2;
|
||||
wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1;
|
||||
wm5102->core.adsp[0].dev = arizona->dev;
|
||||
wm5102->core.adsp[0].regmap = arizona->regmap;
|
||||
wm5102->core.adsp[0].mem = wm5102_dsp1_regions;
|
||||
wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions);
|
||||
|
||||
ret = wm_adsp2_init(&wm5102->core.adsp[0], true);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++)
|
||||
wm5102->fll[i].vco_mult = 1;
|
||||
|
||||
|
|
|
@ -84,11 +84,23 @@ SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L,
|
|||
ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT,
|
||||
0xbf, 0, digital_tlv),
|
||||
|
||||
SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
|
||||
SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
|
||||
|
||||
ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
|
||||
|
||||
SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21,
|
||||
ARIZONA_EQ1_ENA_MASK),
|
||||
SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21,
|
||||
ARIZONA_EQ2_ENA_MASK),
|
||||
SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21,
|
||||
ARIZONA_EQ3_ENA_MASK),
|
||||
SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21,
|
||||
ARIZONA_EQ4_ENA_MASK),
|
||||
|
||||
SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
|
||||
24, 0, eq_tlv),
|
||||
SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
|
||||
|
@ -148,6 +160,11 @@ ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
|
|||
ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
|
||||
|
||||
SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
|
||||
SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
|
||||
SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
|
||||
SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
|
||||
|
||||
SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
|
||||
SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
|
||||
SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
|
||||
|
@ -243,6 +260,9 @@ SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
|
|||
SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
|
||||
ARIZONA_SPK2R_MUTE_SHIFT, 1, 1),
|
||||
|
||||
SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
|
||||
SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
|
||||
|
||||
ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
|
||||
|
@ -308,10 +328,10 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
|
|||
ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
|
||||
|
||||
ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
|
||||
|
||||
static const char *wm5110_aec_loopback_texts[] = {
|
||||
"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
|
||||
|
@ -352,6 +372,7 @@ SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
|
|||
|
||||
SND_SOC_DAPM_SIGGEN("TONE"),
|
||||
SND_SOC_DAPM_SIGGEN("NOISE"),
|
||||
SND_SOC_DAPM_SIGGEN("HAPTICS"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("IN1L"),
|
||||
SND_SOC_DAPM_INPUT("IN1R"),
|
||||
|
@ -585,10 +606,10 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
|
|||
ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
|
||||
ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
|
||||
|
||||
ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
|
||||
ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
|
||||
ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
|
||||
ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
|
||||
ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("HPOUT1L"),
|
||||
SND_SOC_DAPM_OUTPUT("HPOUT1R"),
|
||||
|
@ -610,6 +631,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
|
|||
{ name, "Noise Generator", "Noise Generator" }, \
|
||||
{ name, "Tone Generator 1", "Tone Generator 1" }, \
|
||||
{ name, "Tone Generator 2", "Tone Generator 2" }, \
|
||||
{ name, "Haptics", "HAPTICS" }, \
|
||||
{ name, "AEC", "AEC Loopback" }, \
|
||||
{ name, "IN1L", "IN1L PGA" }, \
|
||||
{ name, "IN1R", "IN1R PGA" }, \
|
||||
|
@ -786,10 +808,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
|
|||
ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
|
||||
ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
|
||||
|
||||
ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
|
||||
ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
|
||||
ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
|
||||
ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
|
||||
ARIZONA_MUX_ROUTES("ASRC1L"),
|
||||
ARIZONA_MUX_ROUTES("ASRC1R"),
|
||||
ARIZONA_MUX_ROUTES("ASRC2L"),
|
||||
ARIZONA_MUX_ROUTES("ASRC2R"),
|
||||
|
||||
{ "HPOUT1L", NULL, "OUT1L" },
|
||||
{ "HPOUT1R", NULL, "OUT1R" },
|
||||
|
@ -902,9 +924,29 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
|
|||
static int wm5110_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
codec->control_data = priv->core.arizona->regmap;
|
||||
return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
|
||||
priv->core.arizona->dapm = &codec->dapm;
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
|
||||
|
||||
priv->core.arizona->dapm = &codec->dapm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm5110_codec_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
priv->core.arizona->dapm = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WM5110_DIG_VU 0x0200
|
||||
|
@ -935,6 +977,7 @@ static unsigned int wm5110_digital_vu[] = {
|
|||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
|
||||
.probe = wm5110_codec_probe,
|
||||
.remove = wm5110_codec_remove,
|
||||
|
||||
.idle_bias_off = true,
|
||||
|
||||
|
|
|
@ -544,6 +544,28 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/*
|
||||
* For simplicity set the DSP clock rate to be the
|
||||
* SYSCLK rate rather than making it configurable.
|
||||
*/
|
||||
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
|
||||
>> ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
|
||||
ret = regmap_update_bits(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING,
|
||||
ADSP2_CLK_SEL_MASK, val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to set clock rate: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dsp->dvfs) {
|
||||
ret = regmap_read(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING, &val);
|
||||
|
@ -631,6 +653,17 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Disable the DSP memory by default when in reset for a small
|
||||
* power saving.
|
||||
*/
|
||||
ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL,
|
||||
ADSP2_MEM_ENA, 0);
|
||||
if (ret != 0) {
|
||||
adsp_err(adsp, "Failed to clear memory retention: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dvfs) {
|
||||
adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
|
||||
if (IS_ERR(adsp->dvfs)) {
|
||||
|
|
Loading…
Reference in New Issue