mirror of https://gitee.com/openkylin/linux.git
Merge remote-tracking branch 'asoc/topic/arizona' into asoc-next
This commit is contained in:
commit
a18d5151aa
|
@ -100,6 +100,55 @@ static const char *arizona_cable[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static void arizona_extcon_do_magic(struct arizona_extcon_info *info,
|
||||
unsigned int magic)
|
||||
{
|
||||
struct arizona *arizona = info->arizona;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&arizona->dapm->card->dapm_mutex);
|
||||
|
||||
arizona->hpdet_magic = magic;
|
||||
|
||||
/* Keep the HP output stages disabled while doing the magic */
|
||||
if (magic) {
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT1L_ENA |
|
||||
ARIZONA_OUT1R_ENA, 0);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev,
|
||||
"Failed to disable headphone outputs: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
|
||||
magic);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to do magic: %d\n",
|
||||
ret);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
|
||||
magic);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to do magic: %d\n",
|
||||
ret);
|
||||
|
||||
/* Restore the desired state while not doing the magic */
|
||||
if (!magic) {
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT1L_ENA |
|
||||
ARIZONA_OUT1R_ENA, arizona->hp_ena);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev,
|
||||
"Failed to restore headphone outputs: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&arizona->dapm->card->dapm_mutex);
|
||||
}
|
||||
|
||||
static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
|
||||
{
|
||||
struct arizona *arizona = info->arizona;
|
||||
|
@ -484,7 +533,6 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
|
|||
struct arizona *arizona = info->arizona;
|
||||
int id_gpio = arizona->pdata.hpdet_id_gpio;
|
||||
int report = ARIZONA_CABLE_HEADPHONE;
|
||||
unsigned int val;
|
||||
int ret, reading;
|
||||
|
||||
mutex_lock(&info->lock);
|
||||
|
@ -539,28 +587,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
|
|||
dev_err(arizona->dev, "Failed to report HP/line: %d\n",
|
||||
ret);
|
||||
|
||||
mutex_lock(&arizona->dapm->card->dapm_mutex);
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to read output enables: %d\n",
|
||||
ret);
|
||||
val = 0;
|
||||
}
|
||||
|
||||
if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) {
|
||||
ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to undo magic: %d\n",
|
||||
ret);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to undo magic: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&arizona->dapm->card->dapm_mutex);
|
||||
arizona_extcon_do_magic(info, 0);
|
||||
|
||||
done:
|
||||
if (id_gpio)
|
||||
|
@ -606,13 +633,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)
|
|||
if (info->mic)
|
||||
arizona_stop_mic(info);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
|
||||
arizona_extcon_do_magic(info, 0x4000);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_ACCESSORY_DETECT_MODE_1,
|
||||
|
@ -653,7 +674,6 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)
|
|||
static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
|
||||
{
|
||||
struct arizona *arizona = info->arizona;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
dev_dbg(arizona->dev, "Starting identification via HPDET\n");
|
||||
|
@ -665,30 +685,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
|
|||
|
||||
arizona_extcon_pulse_micbias(info);
|
||||
|
||||
mutex_lock(&arizona->dapm->card->dapm_mutex);
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to read output enables: %d\n",
|
||||
ret);
|
||||
val = 0;
|
||||
}
|
||||
|
||||
if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) {
|
||||
ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
|
||||
0x4000);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to do magic: %d\n",
|
||||
ret);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
|
||||
0x4000);
|
||||
if (ret != 0)
|
||||
dev_warn(arizona->dev, "Failed to do magic: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&arizona->dapm->card->dapm_mutex);
|
||||
arizona_extcon_do_magic(info, 0x4000);
|
||||
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_ACCESSORY_DETECT_MODE_1,
|
||||
|
|
|
@ -290,12 +290,14 @@ static const struct reg_default wm5102_reg_default[] = {
|
|||
{ 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */
|
||||
{ 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */
|
||||
{ 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */
|
||||
{ 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */
|
||||
{ 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */
|
||||
{ 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */
|
||||
{ 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */
|
||||
{ 0x00000184, 0x0000 }, /* R388 - FLL1 Synchroniser 4 */
|
||||
{ 0x00000185, 0x0000 }, /* R389 - FLL1 Synchroniser 5 */
|
||||
{ 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */
|
||||
{ 0x00000187, 0x0001 }, /* R391 - FLL1 Synchroniser 7 */
|
||||
{ 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */
|
||||
{ 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */
|
||||
{ 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */
|
||||
|
@ -306,12 +308,14 @@ static const struct reg_default wm5102_reg_default[] = {
|
|||
{ 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */
|
||||
{ 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */
|
||||
{ 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */
|
||||
{ 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */
|
||||
{ 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */
|
||||
{ 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */
|
||||
{ 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */
|
||||
{ 0x000001A4, 0x0000 }, /* R420 - FLL2 Synchroniser 4 */
|
||||
{ 0x000001A5, 0x0000 }, /* R421 - FLL2 Synchroniser 5 */
|
||||
{ 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */
|
||||
{ 0x000001A7, 0x0001 }, /* R423 - FLL2 Synchroniser 7 */
|
||||
{ 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */
|
||||
{ 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */
|
||||
{ 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */
|
||||
|
@ -1051,12 +1055,14 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
|
|||
case ARIZONA_FLL1_CONTROL_6:
|
||||
case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL1_NCO_TEST_0:
|
||||
case ARIZONA_FLL1_CONTROL_7:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_3:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_4:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_5:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_6:
|
||||
case ARIZONA_FLL1_SYNCHRONISER_7:
|
||||
case ARIZONA_FLL1_SPREAD_SPECTRUM:
|
||||
case ARIZONA_FLL1_GPIO_CLOCK:
|
||||
case ARIZONA_FLL2_CONTROL_1:
|
||||
|
@ -1067,12 +1073,14 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
|
|||
case ARIZONA_FLL2_CONTROL_6:
|
||||
case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
|
||||
case ARIZONA_FLL2_NCO_TEST_0:
|
||||
case ARIZONA_FLL2_CONTROL_7:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_1:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_2:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_3:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_4:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_5:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_6:
|
||||
case ARIZONA_FLL2_SYNCHRONISER_7:
|
||||
case ARIZONA_FLL2_SPREAD_SPECTRUM:
|
||||
case ARIZONA_FLL2_GPIO_CLOCK:
|
||||
case ARIZONA_MIC_CHARGE_PUMP_1:
|
||||
|
@ -1161,6 +1169,8 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
|
|||
case ARIZONA_NOISE_GATE_CONTROL:
|
||||
case ARIZONA_PDM_SPK1_CTRL_1:
|
||||
case ARIZONA_PDM_SPK1_CTRL_2:
|
||||
case ARIZONA_SPK_CTRL_2:
|
||||
case ARIZONA_SPK_CTRL_3:
|
||||
case ARIZONA_DAC_COMP_1:
|
||||
case ARIZONA_DAC_COMP_2:
|
||||
case ARIZONA_DAC_COMP_3:
|
||||
|
|
|
@ -100,6 +100,9 @@ struct arizona {
|
|||
struct regmap_irq_chip_data *aod_irq_chip;
|
||||
struct regmap_irq_chip_data *irq_chip;
|
||||
|
||||
bool hpdet_magic;
|
||||
unsigned int hp_ena;
|
||||
|
||||
struct mutex clk_lock;
|
||||
int clk32k_ref;
|
||||
|
||||
|
|
|
@ -85,12 +85,14 @@
|
|||
#define ARIZONA_FLL1_CONTROL_6 0x176
|
||||
#define ARIZONA_FLL1_LOOP_FILTER_TEST_1 0x177
|
||||
#define ARIZONA_FLL1_NCO_TEST_0 0x178
|
||||
#define ARIZONA_FLL1_CONTROL_7 0x179
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_1 0x181
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_2 0x182
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_3 0x183
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_4 0x184
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_5 0x185
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_6 0x186
|
||||
#define ARIZONA_FLL1_SYNCHRONISER_7 0x187
|
||||
#define ARIZONA_FLL1_SPREAD_SPECTRUM 0x189
|
||||
#define ARIZONA_FLL1_GPIO_CLOCK 0x18A
|
||||
#define ARIZONA_FLL2_CONTROL_1 0x191
|
||||
|
@ -101,12 +103,14 @@
|
|||
#define ARIZONA_FLL2_CONTROL_6 0x196
|
||||
#define ARIZONA_FLL2_LOOP_FILTER_TEST_1 0x197
|
||||
#define ARIZONA_FLL2_NCO_TEST_0 0x198
|
||||
#define ARIZONA_FLL2_CONTROL_7 0x199
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_1 0x1A1
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_2 0x1A2
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_3 0x1A3
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_4 0x1A4
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_5 0x1A5
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_6 0x1A6
|
||||
#define ARIZONA_FLL2_SYNCHRONISER_7 0x1A7
|
||||
#define ARIZONA_FLL2_SPREAD_SPECTRUM 0x1A9
|
||||
#define ARIZONA_FLL2_GPIO_CLOCK 0x1AA
|
||||
#define ARIZONA_MIC_CHARGE_PUMP_1 0x200
|
||||
|
@ -213,6 +217,8 @@
|
|||
#define ARIZONA_PDM_SPK1_CTRL_2 0x491
|
||||
#define ARIZONA_PDM_SPK2_CTRL_1 0x492
|
||||
#define ARIZONA_PDM_SPK2_CTRL_2 0x493
|
||||
#define ARIZONA_SPK_CTRL_2 0x4B5
|
||||
#define ARIZONA_SPK_CTRL_3 0x4B6
|
||||
#define ARIZONA_DAC_COMP_1 0x4DC
|
||||
#define ARIZONA_DAC_COMP_2 0x4DD
|
||||
#define ARIZONA_DAC_COMP_3 0x4DE
|
||||
|
@ -1677,6 +1683,13 @@
|
|||
#define ARIZONA_FLL1_FRC_INTEG_VAL_SHIFT 0 /* FLL1_FRC_INTEG_VAL - [11:0] */
|
||||
#define ARIZONA_FLL1_FRC_INTEG_VAL_WIDTH 12 /* FLL1_FRC_INTEG_VAL - [11:0] */
|
||||
|
||||
/*
|
||||
* R377 (0x179) - FLL1 Control 7
|
||||
*/
|
||||
#define ARIZONA_FLL1_GAIN_MASK 0x003c /* FLL1_GAIN */
|
||||
#define ARIZONA_FLL1_GAIN_SHIFT 2 /* FLL1_GAIN */
|
||||
#define ARIZONA_FLL1_GAIN_WIDTH 4 /* FLL1_GAIN */
|
||||
|
||||
/*
|
||||
* R385 (0x181) - FLL1 Synchroniser 1
|
||||
*/
|
||||
|
@ -1723,6 +1736,17 @@
|
|||
#define ARIZONA_FLL1_CLK_SYNC_SRC_SHIFT 0 /* FLL1_CLK_SYNC_SRC - [3:0] */
|
||||
#define ARIZONA_FLL1_CLK_SYNC_SRC_WIDTH 4 /* FLL1_CLK_SYNC_SRC - [3:0] */
|
||||
|
||||
/*
|
||||
* R391 (0x187) - FLL1 Synchroniser 7
|
||||
*/
|
||||
#define ARIZONA_FLL1_SYNC_GAIN_MASK 0x003c /* FLL1_SYNC_GAIN */
|
||||
#define ARIZONA_FLL1_SYNC_GAIN_SHIFT 2 /* FLL1_SYNC_GAIN */
|
||||
#define ARIZONA_FLL1_SYNC_GAIN_WIDTH 4 /* FLL1_SYNC_GAIN */
|
||||
#define ARIZONA_FLL1_SYNC_BW 0x0001 /* FLL1_SYNC_BW */
|
||||
#define ARIZONA_FLL1_SYNC_BW_MASK 0x0001 /* FLL1_SYNC_BW */
|
||||
#define ARIZONA_FLL1_SYNC_BW_SHIFT 0 /* FLL1_SYNC_BW */
|
||||
#define ARIZONA_FLL1_SYNC_BW_WIDTH 1 /* FLL1_SYNC_BW */
|
||||
|
||||
/*
|
||||
* R393 (0x189) - FLL1 Spread Spectrum
|
||||
*/
|
||||
|
@ -1815,6 +1839,13 @@
|
|||
#define ARIZONA_FLL2_FRC_INTEG_VAL_SHIFT 0 /* FLL2_FRC_INTEG_VAL - [11:0] */
|
||||
#define ARIZONA_FLL2_FRC_INTEG_VAL_WIDTH 12 /* FLL2_FRC_INTEG_VAL - [11:0] */
|
||||
|
||||
/*
|
||||
* R409 (0x199) - FLL2 Control 7
|
||||
*/
|
||||
#define ARIZONA_FLL2_GAIN_MASK 0x003c /* FLL2_GAIN */
|
||||
#define ARIZONA_FLL2_GAIN_SHIFT 2 /* FLL2_GAIN */
|
||||
#define ARIZONA_FLL2_GAIN_WIDTH 4 /* FLL2_GAIN */
|
||||
|
||||
/*
|
||||
* R417 (0x1A1) - FLL2 Synchroniser 1
|
||||
*/
|
||||
|
@ -1861,6 +1892,17 @@
|
|||
#define ARIZONA_FLL2_CLK_SYNC_SRC_SHIFT 0 /* FLL2_CLK_SYNC_SRC - [3:0] */
|
||||
#define ARIZONA_FLL2_CLK_SYNC_SRC_WIDTH 4 /* FLL2_CLK_SYNC_SRC - [3:0] */
|
||||
|
||||
/*
|
||||
* R423 (0x1A7) - FLL2 Synchroniser 7
|
||||
*/
|
||||
#define ARIZONA_FLL2_SYNC_GAIN_MASK 0x003c /* FLL2_SYNC_GAIN */
|
||||
#define ARIZONA_FLL2_SYNC_GAIN_SHIFT 2 /* FLL2_SYNC_GAIN */
|
||||
#define ARIZONA_FLL2_SYNC_GAIN_WIDTH 4 /* FLL2_SYNC_GAIN */
|
||||
#define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */
|
||||
#define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */
|
||||
#define ARIZONA_FLL2_SYNC_BW_SHIFT 0 /* FLL2_SYNC_BW */
|
||||
#define ARIZONA_FLL2_SYNC_BW_WIDTH 1 /* FLL2_SYNC_BW */
|
||||
|
||||
/*
|
||||
* R425 (0x1A9) - FLL2 Spread Spectrum
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gcd.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
@ -65,6 +66,163 @@
|
|||
#define arizona_aif_dbg(_dai, fmt, ...) \
|
||||
dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
|
||||
|
||||
static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
bool manual_ena = false;
|
||||
int val;
|
||||
|
||||
switch (arizona->type) {
|
||||
case WM5102:
|
||||
switch (arizona->rev) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
manual_ena = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
if (!priv->spk_ena && manual_ena) {
|
||||
snd_soc_write(codec, 0x4f5, 0x25a);
|
||||
priv->spk_ena_pending = true;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
|
||||
if (val & ARIZONA_SPK_SHUTDOWN_STS) {
|
||||
dev_crit(arizona->dev,
|
||||
"Speaker not enabled due to temperature\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
|
||||
1 << w->shift, 1 << w->shift);
|
||||
|
||||
if (priv->spk_ena_pending) {
|
||||
msleep(75);
|
||||
snd_soc_write(codec, 0x4f5, 0xda);
|
||||
priv->spk_ena_pending = false;
|
||||
priv->spk_ena++;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
if (manual_ena) {
|
||||
priv->spk_ena--;
|
||||
if (!priv->spk_ena)
|
||||
snd_soc_write(codec, 0x4f5, 0x25a);
|
||||
}
|
||||
|
||||
snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
|
||||
1 << w->shift, 0);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (manual_ena) {
|
||||
if (!priv->spk_ena)
|
||||
snd_soc_write(codec, 0x4f5, 0x0da);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t arizona_thermal_warn(int irq, void *data)
|
||||
{
|
||||
struct arizona *arizona = data;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
|
||||
&val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to read thermal status: %d\n",
|
||||
ret);
|
||||
} else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
|
||||
dev_crit(arizona->dev, "Thermal warning\n");
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
|
||||
{
|
||||
struct arizona *arizona = data;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
|
||||
&val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to read thermal status: %d\n",
|
||||
ret);
|
||||
} else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
|
||||
dev_crit(arizona->dev, "Thermal shutdown\n");
|
||||
ret = regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT4L_ENA |
|
||||
ARIZONA_OUT4R_ENA, 0);
|
||||
if (ret != 0)
|
||||
dev_crit(arizona->dev,
|
||||
"Failed to disable speaker outputs: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget arizona_spkl =
|
||||
SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
|
||||
ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
|
||||
|
||||
static const struct snd_soc_dapm_widget arizona_spkr =
|
||||
SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
|
||||
ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
|
||||
|
||||
int arizona_init_spk(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
struct arizona *arizona = priv->arizona;
|
||||
int ret;
|
||||
|
||||
ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
|
||||
"Thermal warning", arizona_thermal_warn,
|
||||
arizona);
|
||||
if (ret != 0)
|
||||
dev_err(arizona->dev,
|
||||
"Failed to get thermal warning IRQ: %d\n",
|
||||
ret);
|
||||
|
||||
ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
|
||||
"Thermal shutdown", arizona_thermal_shutdown,
|
||||
arizona);
|
||||
if (ret != 0)
|
||||
dev_err(arizona->dev,
|
||||
"Failed to get thermal shutdown IRQ: %d\n",
|
||||
ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_init_spk);
|
||||
|
||||
const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
|
||||
"None",
|
||||
"Tone Generator 1",
|
||||
|
@ -274,6 +432,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
|
|||
const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
|
||||
EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
|
||||
|
||||
const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
|
||||
"SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(arizona_rate_text);
|
||||
|
||||
const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
|
||||
0, 1, 2, 8,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(arizona_rate_val);
|
||||
|
||||
|
||||
const struct soc_enum arizona_isrc_fsl[] = {
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
|
||||
ARIZONA_ISRC1_FSL_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
|
||||
ARIZONA_ISRC2_FSL_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
|
||||
ARIZONA_ISRC3_FSL_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
|
||||
|
||||
static const char *arizona_vol_ramp_text[] = {
|
||||
"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
|
||||
"15ms/6dB", "30ms/6dB",
|
||||
|
@ -332,9 +517,27 @@ const struct soc_enum arizona_ng_hold =
|
|||
4, arizona_ng_hold_text);
|
||||
EXPORT_SYMBOL_GPL(arizona_ng_hold);
|
||||
|
||||
static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
|
||||
{
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int val;
|
||||
int i;
|
||||
|
||||
if (ena)
|
||||
val = ARIZONA_IN_VU;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
for (i = 0; i < priv->num_inputs; i++)
|
||||
snd_soc_update_bits(codec,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
|
||||
ARIZONA_IN_VU, val);
|
||||
}
|
||||
|
||||
int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
|
||||
unsigned int reg;
|
||||
|
||||
if (w->shift % 2)
|
||||
|
@ -343,13 +546,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
|
|||
reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
priv->in_pending++;
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
|
||||
|
||||
/* If this is the last input pending then allow VU */
|
||||
priv->in_pending--;
|
||||
if (priv->in_pending == 0) {
|
||||
msleep(1);
|
||||
arizona_in_set_vu(w->codec, 1);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE,
|
||||
ARIZONA_IN1L_MUTE);
|
||||
snd_soc_update_bits(w->codec, reg,
|
||||
ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
|
||||
ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Disable volume updates if no inputs are enabled */
|
||||
reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
|
||||
if (reg == 0)
|
||||
arizona_in_set_vu(w->codec, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -360,10 +579,61 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
switch (w->shift) {
|
||||
case ARIZONA_OUT1L_ENA_SHIFT:
|
||||
case ARIZONA_OUT1R_ENA_SHIFT:
|
||||
case ARIZONA_OUT2L_ENA_SHIFT:
|
||||
case ARIZONA_OUT2R_ENA_SHIFT:
|
||||
case ARIZONA_OUT3L_ENA_SHIFT:
|
||||
case ARIZONA_OUT3R_ENA_SHIFT:
|
||||
msleep(17);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_out_ev);
|
||||
|
||||
int arizona_hp_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
|
||||
unsigned int mask = 1 << w->shift;
|
||||
unsigned int val;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
val = mask;
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Store the desired state for the HP outputs */
|
||||
priv->arizona->hp_ena &= ~mask;
|
||||
priv->arizona->hp_ena |= val;
|
||||
|
||||
/* Force off if HPDET magic is active */
|
||||
if (priv->arizona->hpdet_magic)
|
||||
val = 0;
|
||||
|
||||
snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
|
||||
|
||||
return arizona_out_ev(w, kcontrol, event);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_hp_ev);
|
||||
|
||||
static unsigned int arizona_sysclk_48k_rates[] = {
|
||||
6144000,
|
||||
12288000,
|
||||
|
@ -469,27 +739,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
|
|||
break;
|
||||
case 11289600:
|
||||
case 12288000:
|
||||
val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 22579200:
|
||||
case 24576000:
|
||||
val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 45158400:
|
||||
case 49152000:
|
||||
val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 67737600:
|
||||
case 73728000:
|
||||
val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 90316800:
|
||||
case 98304000:
|
||||
val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 135475200:
|
||||
case 147456000:
|
||||
val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
break;
|
||||
case 0:
|
||||
dev_dbg(arizona->dev, "%s cleared\n", name);
|
||||
|
@ -783,7 +1053,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
|
|||
struct arizona *arizona = priv->arizona;
|
||||
int base = dai->driver->base;
|
||||
const int *rates;
|
||||
int i, ret;
|
||||
int i, ret, val;
|
||||
int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
|
||||
int bclk, lrclk, wl, frame, bclk_target;
|
||||
|
||||
|
@ -799,6 +1069,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
|
|||
bclk_target *= chan_limit;
|
||||
}
|
||||
|
||||
/* Force stereo for I2S mode */
|
||||
val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
|
||||
if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
|
||||
arizona_aif_dbg(dai, "Forcing stereo mode\n");
|
||||
bclk_target *= 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
|
||||
if (rates[i] >= bclk_target &&
|
||||
rates[i] % params_rate(params) == 0) {
|
||||
|
@ -955,6 +1232,16 @@ static struct {
|
|||
{ 1000000, 13500000, 0, 1 },
|
||||
};
|
||||
|
||||
static struct {
|
||||
unsigned int min;
|
||||
unsigned int max;
|
||||
u16 gain;
|
||||
} fll_gains[] = {
|
||||
{ 0, 256000, 0 },
|
||||
{ 256000, 1000000, 2 },
|
||||
{ 1000000, 13500000, 4 },
|
||||
};
|
||||
|
||||
struct arizona_fll_cfg {
|
||||
int n;
|
||||
int theta;
|
||||
|
@ -962,6 +1249,7 @@ struct arizona_fll_cfg {
|
|||
int refdiv;
|
||||
int outdiv;
|
||||
int fratio;
|
||||
int gain;
|
||||
};
|
||||
|
||||
static int arizona_calc_fll(struct arizona_fll *fll,
|
||||
|
@ -1021,6 +1309,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
|
||||
if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
|
||||
cfg->gain = fll_gains[i].gain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == ARRAY_SIZE(fll_gains)) {
|
||||
arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
|
||||
Fref);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cfg->n = target / (ratio * Fref);
|
||||
|
||||
if (target % (ratio * Fref)) {
|
||||
|
@ -1048,13 +1348,15 @@ static int arizona_calc_fll(struct arizona_fll *fll,
|
|||
cfg->n, cfg->theta, cfg->lambda);
|
||||
arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
|
||||
cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
|
||||
arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
|
||||
struct arizona_fll_cfg *cfg, int source)
|
||||
struct arizona_fll_cfg *cfg, int source,
|
||||
bool sync)
|
||||
{
|
||||
regmap_update_bits(arizona->regmap, base + 3,
|
||||
ARIZONA_FLL1_THETA_MASK, cfg->theta);
|
||||
|
@ -1069,87 +1371,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
|
|||
cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
|
||||
source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
|
||||
|
||||
if (sync)
|
||||
regmap_update_bits(arizona->regmap, base + 0x7,
|
||||
ARIZONA_FLL1_GAIN_MASK,
|
||||
cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
|
||||
else
|
||||
regmap_update_bits(arizona->regmap, base + 0x9,
|
||||
ARIZONA_FLL1_GAIN_MASK,
|
||||
cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
|
||||
|
||||
regmap_update_bits(arizona->regmap, base + 2,
|
||||
ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
|
||||
ARIZONA_FLL1_CTRL_UPD | cfg->n);
|
||||
}
|
||||
|
||||
int arizona_set_fll(struct arizona_fll *fll, int source,
|
||||
unsigned int Fref, unsigned int Fout)
|
||||
static bool arizona_is_enabled_fll(struct arizona_fll *fll)
|
||||
{
|
||||
struct arizona *arizona = fll->arizona;
|
||||
struct arizona_fll_cfg cfg, sync;
|
||||
unsigned int reg, val;
|
||||
int syncsrc;
|
||||
bool ena;
|
||||
unsigned int reg;
|
||||
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",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
ena = reg & ARIZONA_FLL1_ENA;
|
||||
|
||||
if (Fout) {
|
||||
/* Do we have a 32kHz reference? */
|
||||
regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
|
||||
switch (val & ARIZONA_CLK_32K_SRC_MASK) {
|
||||
case ARIZONA_CLK_SRC_MCLK1:
|
||||
case ARIZONA_CLK_SRC_MCLK2:
|
||||
syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
|
||||
break;
|
||||
default:
|
||||
syncsrc = -1;
|
||||
}
|
||||
return reg & ARIZONA_FLL1_ENA;
|
||||
}
|
||||
|
||||
if (source == syncsrc)
|
||||
syncsrc = -1;
|
||||
|
||||
if (syncsrc >= 0) {
|
||||
ret = arizona_calc_fll(fll, &sync, Fref, Fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
} else {
|
||||
ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
regmap_update_bits(arizona->regmap, fll->base + 1,
|
||||
ARIZONA_FLL1_ENA, 0);
|
||||
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
||||
ARIZONA_FLL1_SYNC_ENA, 0);
|
||||
|
||||
if (ena)
|
||||
pm_runtime_put_autosuspend(arizona->dev);
|
||||
|
||||
fll->fref = Fref;
|
||||
fll->fout = Fout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void arizona_enable_fll(struct arizona_fll *fll,
|
||||
struct arizona_fll_cfg *ref,
|
||||
struct arizona_fll_cfg *sync)
|
||||
{
|
||||
struct arizona *arizona = fll->arizona;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If we have both REFCLK and SYNCCLK then enable both,
|
||||
* otherwise apply the SYNCCLK settings to REFCLK.
|
||||
*/
|
||||
if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
|
||||
regmap_update_bits(arizona->regmap, fll->base + 5,
|
||||
ARIZONA_FLL1_OUTDIV_MASK,
|
||||
cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
||||
ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
||||
|
||||
if (syncsrc >= 0) {
|
||||
arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
|
||||
arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
|
||||
arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
|
||||
false);
|
||||
if (fll->sync_src >= 0)
|
||||
arizona_apply_fll(arizona, fll->base + 0x10, sync,
|
||||
fll->sync_src, true);
|
||||
} else if (fll->sync_src >= 0) {
|
||||
regmap_update_bits(arizona->regmap, fll->base + 5,
|
||||
ARIZONA_FLL1_OUTDIV_MASK,
|
||||
sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
|
||||
|
||||
arizona_apply_fll(arizona, fll->base, sync,
|
||||
fll->sync_src, false);
|
||||
|
||||
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
||||
ARIZONA_FLL1_SYNC_ENA, 0);
|
||||
} else {
|
||||
arizona_apply_fll(arizona, fll->base, &cfg, source);
|
||||
arizona_fll_err(fll, "No clocks provided\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ena)
|
||||
/*
|
||||
* Increase the bandwidth if we're not using a low frequency
|
||||
* sync source.
|
||||
*/
|
||||
if (fll->sync_src >= 0 && fll->sync_freq > 100000)
|
||||
regmap_update_bits(arizona->regmap, fll->base + 0x17,
|
||||
ARIZONA_FLL1_SYNC_BW, 0);
|
||||
else
|
||||
regmap_update_bits(arizona->regmap, fll->base + 0x17,
|
||||
ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
|
||||
|
||||
if (!arizona_is_enabled_fll(fll))
|
||||
pm_runtime_get(arizona->dev);
|
||||
|
||||
/* Clear any pending completions */
|
||||
|
@ -1157,7 +1456,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
|
|||
|
||||
regmap_update_bits(arizona->regmap, fll->base + 1,
|
||||
ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
|
||||
if (syncsrc >= 0)
|
||||
if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
|
||||
fll->ref_src != fll->sync_src)
|
||||
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
||||
ARIZONA_FLL1_SYNC_ENA,
|
||||
ARIZONA_FLL1_SYNC_ENA);
|
||||
|
@ -1166,10 +1466,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
|
|||
msecs_to_jiffies(250));
|
||||
if (ret == 0)
|
||||
arizona_fll_warn(fll, "Timed out waiting for lock\n");
|
||||
}
|
||||
|
||||
fll->fref = Fref;
|
||||
static void arizona_disable_fll(struct arizona_fll *fll)
|
||||
{
|
||||
struct arizona *arizona = fll->arizona;
|
||||
bool change;
|
||||
|
||||
regmap_update_bits_check(arizona->regmap, fll->base + 1,
|
||||
ARIZONA_FLL1_ENA, 0, &change);
|
||||
regmap_update_bits(arizona->regmap, fll->base + 0x11,
|
||||
ARIZONA_FLL1_SYNC_ENA, 0);
|
||||
|
||||
if (change)
|
||||
pm_runtime_put_autosuspend(arizona->dev);
|
||||
}
|
||||
|
||||
int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
|
||||
unsigned int Fref, unsigned int Fout)
|
||||
{
|
||||
struct arizona_fll_cfg ref, sync;
|
||||
int ret;
|
||||
|
||||
if (fll->ref_src == source && fll->ref_freq == Fref)
|
||||
return 0;
|
||||
|
||||
if (fll->fout && Fref > 0) {
|
||||
ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (fll->sync_src >= 0) {
|
||||
ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
|
||||
fll->fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
fll->ref_src = source;
|
||||
fll->ref_freq = Fref;
|
||||
|
||||
if (fll->fout && Fref > 0) {
|
||||
arizona_enable_fll(fll, &ref, &sync);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
|
||||
|
||||
int arizona_set_fll(struct arizona_fll *fll, int source,
|
||||
unsigned int Fref, unsigned int Fout)
|
||||
{
|
||||
struct arizona_fll_cfg ref, sync;
|
||||
int ret;
|
||||
|
||||
if (fll->sync_src == source &&
|
||||
fll->sync_freq == Fref && fll->fout == Fout)
|
||||
return 0;
|
||||
|
||||
if (Fout) {
|
||||
if (fll->ref_src >= 0) {
|
||||
ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
|
||||
Fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = arizona_calc_fll(fll, &sync, Fref, Fout);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
fll->sync_src = source;
|
||||
fll->sync_freq = Fref;
|
||||
fll->fout = Fout;
|
||||
|
||||
if (Fout) {
|
||||
arizona_enable_fll(fll, &ref, &sync);
|
||||
} else {
|
||||
arizona_disable_fll(fll);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_set_fll);
|
||||
|
@ -1178,12 +1556,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
|
|||
int ok_irq, struct arizona_fll *fll)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
init_completion(&fll->ok);
|
||||
|
||||
fll->id = id;
|
||||
fll->base = base;
|
||||
fll->arizona = arizona;
|
||||
fll->sync_src = ARIZONA_FLL_SRC_NONE;
|
||||
|
||||
/* Configure default refclk to 32kHz if we have one */
|
||||
regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
|
||||
switch (val & ARIZONA_CLK_32K_SRC_MASK) {
|
||||
case ARIZONA_CLK_SRC_MCLK1:
|
||||
case ARIZONA_CLK_SRC_MCLK2:
|
||||
fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
|
||||
break;
|
||||
default:
|
||||
fll->ref_src = ARIZONA_FLL_SRC_NONE;
|
||||
}
|
||||
fll->ref_freq = 32768;
|
||||
|
||||
snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
|
||||
snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define ARIZONA_CLK_SRC_AIF2BCLK 0x9
|
||||
#define ARIZONA_CLK_SRC_AIF3BCLK 0xa
|
||||
|
||||
#define ARIZONA_FLL_SRC_NONE -1
|
||||
#define ARIZONA_FLL_SRC_MCLK1 0
|
||||
#define ARIZONA_FLL_SRC_MCLK2 1
|
||||
#define ARIZONA_FLL_SRC_SLIMCLK 3
|
||||
|
@ -48,6 +49,14 @@
|
|||
#define ARIZONA_MIXER_VOL_SHIFT 1
|
||||
#define ARIZONA_MIXER_VOL_WIDTH 7
|
||||
|
||||
#define ARIZONA_CLK_6MHZ 0
|
||||
#define ARIZONA_CLK_12MHZ 1
|
||||
#define ARIZONA_CLK_24MHZ 2
|
||||
#define ARIZONA_CLK_49MHZ 3
|
||||
#define ARIZONA_CLK_73MHZ 4
|
||||
#define ARIZONA_CLK_98MHZ 5
|
||||
#define ARIZONA_CLK_147MHZ 6
|
||||
|
||||
#define ARIZONA_MAX_DAI 4
|
||||
#define ARIZONA_MAX_ADSP 4
|
||||
|
||||
|
@ -64,6 +73,12 @@ struct arizona_priv {
|
|||
int sysclk;
|
||||
int asyncclk;
|
||||
struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
|
||||
|
||||
int num_inputs;
|
||||
unsigned int in_pending;
|
||||
|
||||
unsigned int spk_ena:2;
|
||||
unsigned int spk_ena_pending:1;
|
||||
};
|
||||
|
||||
#define ARIZONA_NUM_MIXER_INPUTS 99
|
||||
|
@ -165,6 +180,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
|
|||
ARIZONA_MIXER_ROUTES(name, name "L"), \
|
||||
ARIZONA_MIXER_ROUTES(name, name "R")
|
||||
|
||||
#define ARIZONA_RATE_ENUM_SIZE 4
|
||||
extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
|
||||
extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
|
||||
|
||||
extern const struct soc_enum arizona_isrc_fsl[];
|
||||
|
||||
extern const struct soc_enum arizona_in_vi_ramp;
|
||||
extern const struct soc_enum arizona_in_vd_ramp;
|
||||
|
||||
|
@ -184,6 +205,9 @@ extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
|
|||
extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event);
|
||||
extern int arizona_hp_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event);
|
||||
|
||||
extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
|
||||
int source, unsigned int freq, int dir);
|
||||
|
@ -198,8 +222,12 @@ struct arizona_fll {
|
|||
unsigned int base;
|
||||
unsigned int vco_mult;
|
||||
struct completion ok;
|
||||
unsigned int fref;
|
||||
|
||||
unsigned int fout;
|
||||
int sync_src;
|
||||
unsigned int sync_freq;
|
||||
int ref_src;
|
||||
unsigned int ref_freq;
|
||||
|
||||
char lock_name[ARIZONA_FLL_NAME_LEN];
|
||||
char clock_ok_name[ARIZONA_FLL_NAME_LEN];
|
||||
|
@ -207,9 +235,13 @@ struct arizona_fll {
|
|||
|
||||
extern int arizona_init_fll(struct arizona *arizona, int id, int base,
|
||||
int lock_irq, int ok_irq, struct arizona_fll *fll);
|
||||
extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
|
||||
unsigned int Fref, unsigned int Fout);
|
||||
extern int arizona_set_fll(struct arizona_fll *fll, int source,
|
||||
unsigned int Fref, unsigned int Fout);
|
||||
|
||||
extern int arizona_init_spk(struct snd_soc_codec *codec);
|
||||
|
||||
extern int arizona_init_dai(struct arizona_priv *priv, int dai);
|
||||
|
||||
int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
|
||||
|
|
|
@ -1565,7 +1565,7 @@ static int wm2200_probe(struct snd_soc_codec *codec)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2);
|
||||
ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -36,9 +36,6 @@
|
|||
struct wm5102_priv {
|
||||
struct arizona_priv core;
|
||||
struct arizona_fll fll[2];
|
||||
|
||||
unsigned int spk_ena:2;
|
||||
unsigned int spk_ena_pending:1;
|
||||
};
|
||||
|
||||
static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
|
||||
|
@ -615,6 +612,26 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char *wm5102_osr_text[] = {
|
||||
"Low power", "Normal", "High performance",
|
||||
};
|
||||
|
||||
static const unsigned int wm5102_osr_val[] = {
|
||||
0x0, 0x3, 0x5,
|
||||
};
|
||||
|
||||
static const struct soc_enum wm5102_hpout_osr[] = {
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
|
||||
ARIZONA_OUT1_OSR_SHIFT, 0x7, 3,
|
||||
wm5102_osr_text, wm5102_osr_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
|
||||
ARIZONA_OUT2_OSR_SHIFT, 0x7, 3,
|
||||
wm5102_osr_text, wm5102_osr_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
|
||||
ARIZONA_OUT3_OSR_SHIFT, 0x7, 3,
|
||||
wm5102_osr_text, wm5102_osr_val),
|
||||
};
|
||||
|
||||
#define WM5102_NG_SRC(name, base) \
|
||||
SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
|
||||
SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
|
||||
|
@ -745,6 +762,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
|
|||
SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
|
||||
SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
|
||||
|
||||
SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
|
||||
SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
|
||||
|
||||
ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
|
||||
ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
|
||||
|
||||
|
@ -761,6 +781,8 @@ 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("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),
|
||||
|
||||
|
@ -790,6 +812,10 @@ 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_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]),
|
||||
SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]),
|
||||
SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]),
|
||||
|
||||
SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
|
||||
SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
|
||||
|
||||
|
@ -828,47 +854,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
|
|||
ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
|
||||
};
|
||||
|
||||
static int wm5102_spk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (arizona->rev < 1)
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
if (!wm5102->spk_ena) {
|
||||
snd_soc_write(codec, 0x4f5, 0x25a);
|
||||
wm5102->spk_ena_pending = true;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
if (wm5102->spk_ena_pending) {
|
||||
msleep(75);
|
||||
snd_soc_write(codec, 0x4f5, 0xda);
|
||||
wm5102->spk_ena_pending = false;
|
||||
wm5102->spk_ena++;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
wm5102->spk_ena--;
|
||||
if (!wm5102->spk_ena)
|
||||
snd_soc_write(codec, 0x4f5, 0x25a);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (!wm5102->spk_ena)
|
||||
snd_soc_write(codec, 0x4f5, 0x0da);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
|
||||
ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
|
||||
|
@ -984,22 +969,28 @@ SND_SOC_DAPM_INPUT("IN3R"),
|
|||
|
||||
SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
|
||||
ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
|
||||
|
@ -1131,11 +1122,11 @@ 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),
|
||||
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
|
@ -1146,12 +1137,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
|
|||
SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
|
@ -1494,6 +1479,12 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
|||
return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
|
||||
case WM5102_FLL2:
|
||||
return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
|
||||
case WM5102_FLL1_REFCLK:
|
||||
return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref,
|
||||
Fout);
|
||||
case WM5102_FLL2_REFCLK:
|
||||
return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref,
|
||||
Fout);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1581,10 +1572,12 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
|
|||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1);
|
||||
ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
arizona_init_spk(codec);
|
||||
|
||||
snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
|
||||
|
||||
priv->core.arizona->dapm = &codec->dapm;
|
||||
|
@ -1604,13 +1597,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec)
|
|||
#define WM5102_DIG_VU 0x0200
|
||||
|
||||
static unsigned int wm5102_digital_vu[] = {
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1R,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_2L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_2R,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_3L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_3R,
|
||||
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_1L,
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_1R,
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_2L,
|
||||
|
@ -1653,6 +1639,7 @@ static int wm5102_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, wm5102);
|
||||
|
||||
wm5102->core.arizona = arizona;
|
||||
wm5102->core.num_inputs = 6;
|
||||
|
||||
wm5102->core.adsp[0].part = "wm5102";
|
||||
wm5102->core.adsp[0].num = 1;
|
||||
|
@ -1677,6 +1664,12 @@ static int wm5102_probe(struct platform_device *pdev)
|
|||
ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
|
||||
&wm5102->fll[1]);
|
||||
|
||||
/* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
|
||||
regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
|
||||
ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
|
||||
regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
|
||||
ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
|
||||
arizona_init_dai(&wm5102->core, i);
|
||||
|
||||
|
|
|
@ -17,5 +17,7 @@
|
|||
|
||||
#define WM5102_FLL1 1
|
||||
#define WM5102_FLL2 2
|
||||
#define WM5102_FLL1_REFCLK 3
|
||||
#define WM5102_FLL2_REFCLK 4
|
||||
|
||||
#endif
|
||||
|
|
|
@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"),
|
|||
|
||||
SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT,
|
||||
0, NULL, 0, arizona_in_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
|
||||
ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
|
||||
|
@ -551,11 +559,11 @@ 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),
|
||||
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
|
@ -569,12 +577,6 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
|
|||
SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
|
@ -880,6 +882,12 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
|||
return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout);
|
||||
case WM5110_FLL2:
|
||||
return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout);
|
||||
case WM5110_FLL1_REFCLK:
|
||||
return arizona_set_fll_refclk(&wm5110->fll[0], source, Fref,
|
||||
Fout);
|
||||
case WM5110_FLL2_REFCLK:
|
||||
return arizona_set_fll_refclk(&wm5110->fll[1], source, Fref,
|
||||
Fout);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -987,15 +995,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec)
|
|||
#define WM5110_DIG_VU 0x0200
|
||||
|
||||
static unsigned int wm5110_digital_vu[] = {
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1R,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_2L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_2R,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_3L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_3R,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_4L,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_4R,
|
||||
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_1L,
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_1R,
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_2L,
|
||||
|
@ -1040,6 +1039,7 @@ static int wm5110_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, wm5110);
|
||||
|
||||
wm5110->core.arizona = arizona;
|
||||
wm5110->core.num_inputs = 8;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
|
||||
wm5110->fll[i].vco_mult = 3;
|
||||
|
|
|
@ -17,5 +17,7 @@
|
|||
|
||||
#define WM5110_FLL1 1
|
||||
#define WM5110_FLL2 2
|
||||
#define WM5110_FLL1_REFCLK 3
|
||||
#define WM5110_FLL2_REFCLK 4
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
|
||||
#include "arizona.h"
|
||||
#include "wm_adsp.h"
|
||||
|
||||
#define adsp_crit(_dsp, fmt, ...) \
|
||||
|
@ -254,17 +255,52 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
|
|||
SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
|
||||
};
|
||||
|
||||
const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
|
||||
const struct snd_kcontrol_new wm_adsp1_fw_controls[] = {
|
||||
SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_ARIZONA)
|
||||
static const struct soc_enum wm_adsp2_rate_enum[] = {
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
|
||||
ARIZONA_DSP1_RATE_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
|
||||
ARIZONA_DSP1_RATE_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
|
||||
ARIZONA_DSP1_RATE_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
|
||||
ARIZONA_DSP1_RATE_SHIFT, 0xf,
|
||||
ARIZONA_RATE_ENUM_SIZE,
|
||||
arizona_rate_text, arizona_rate_val),
|
||||
};
|
||||
|
||||
const struct snd_kcontrol_new wm_adsp2_fw_controls[] = {
|
||||
SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]),
|
||||
SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]),
|
||||
SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]),
|
||||
SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
|
||||
wm_adsp_fw_get, wm_adsp_fw_put),
|
||||
SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
|
||||
EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls);
|
||||
#endif
|
||||
|
||||
static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
|
||||
int type)
|
||||
|
|
|
@ -67,7 +67,8 @@ struct wm_adsp {
|
|||
.shift = num, .event = wm_adsp2_event, \
|
||||
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
|
||||
|
||||
extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
|
||||
extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
|
||||
extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
|
||||
|
||||
int wm_adsp1_init(struct wm_adsp *adsp);
|
||||
int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
|
||||
|
|
Loading…
Reference in New Issue