File Index
Files and directories
Sign in
FILE

arizona.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/arizona.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * arizona.c - Wolfson Arizona class device shared support
   4 *
   5 * Copyright 2012 Wolfson Microelectronics plc
   6 *
   7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   8 */
   9
  10#include <linux/delay.h>
  11#include <linux/gcd.h>
  12#include <linux/module.h>
  13#include <linux/of.h>
  14#include <linux/pm_runtime.h>
  15#include <sound/pcm.h>
  16#include <sound/pcm_params.h>
  17#include <sound/tlv.h>
  18
  19#include <linux/mfd/arizona/core.h>
  20#include <linux/mfd/arizona/registers.h>
  21
  22#include "arizona.h"
  23
  24#define ARIZONA_AIF_BCLK_CTRL                   0x00
  25#define ARIZONA_AIF_TX_PIN_CTRL                 0x01
  26#define ARIZONA_AIF_RX_PIN_CTRL                 0x02
  27#define ARIZONA_AIF_RATE_CTRL                   0x03
  28#define ARIZONA_AIF_FORMAT                      0x04
  29#define ARIZONA_AIF_TX_BCLK_RATE                0x05
  30#define ARIZONA_AIF_RX_BCLK_RATE                0x06
  31#define ARIZONA_AIF_FRAME_CTRL_1                0x07
  32#define ARIZONA_AIF_FRAME_CTRL_2                0x08
  33#define ARIZONA_AIF_FRAME_CTRL_3                0x09
  34#define ARIZONA_AIF_FRAME_CTRL_4                0x0A
  35#define ARIZONA_AIF_FRAME_CTRL_5                0x0B
  36#define ARIZONA_AIF_FRAME_CTRL_6                0x0C
  37#define ARIZONA_AIF_FRAME_CTRL_7                0x0D
  38#define ARIZONA_AIF_FRAME_CTRL_8                0x0E
  39#define ARIZONA_AIF_FRAME_CTRL_9                0x0F
  40#define ARIZONA_AIF_FRAME_CTRL_10               0x10
  41#define ARIZONA_AIF_FRAME_CTRL_11               0x11
  42#define ARIZONA_AIF_FRAME_CTRL_12               0x12
  43#define ARIZONA_AIF_FRAME_CTRL_13               0x13
  44#define ARIZONA_AIF_FRAME_CTRL_14               0x14
  45#define ARIZONA_AIF_FRAME_CTRL_15               0x15
  46#define ARIZONA_AIF_FRAME_CTRL_16               0x16
  47#define ARIZONA_AIF_FRAME_CTRL_17               0x17
  48#define ARIZONA_AIF_FRAME_CTRL_18               0x18
  49#define ARIZONA_AIF_TX_ENABLES                  0x19
  50#define ARIZONA_AIF_RX_ENABLES                  0x1A
  51#define ARIZONA_AIF_FORCE_WRITE                 0x1B
  52
  53#define ARIZONA_FLL_VCO_CORNER 141900000
  54#define ARIZONA_FLL_MAX_FREF   13500000
  55#define ARIZONA_FLL_MIN_FVCO   90000000
  56#define ARIZONA_FLL_MAX_FRATIO 16
  57#define ARIZONA_FLL_MAX_REFDIV 8
  58#define ARIZONA_FLL_MIN_OUTDIV 2
  59#define ARIZONA_FLL_MAX_OUTDIV 7
  60
  61#define ARIZONA_FMT_DSP_MODE_A          0
  62#define ARIZONA_FMT_DSP_MODE_B          1
  63#define ARIZONA_FMT_I2S_MODE            2
  64#define ARIZONA_FMT_LEFT_JUSTIFIED_MODE 3
  65
  66#define arizona_fll_err(_fll, fmt, ...) \
  67	dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  68#define arizona_fll_warn(_fll, fmt, ...) \
  69	dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  70#define arizona_fll_dbg(_fll, fmt, ...) \
  71	dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  72
  73#define arizona_aif_err(_dai, fmt, ...) \
  74	dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  75#define arizona_aif_warn(_dai, fmt, ...) \
  76	dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  77#define arizona_aif_dbg(_dai, fmt, ...) \
  78	dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  79
  80static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
  81			  struct snd_kcontrol *kcontrol,
  82			  int event)
  83{
  84	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  85	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
  86	int val;
  87
  88	switch (event) {
  89	case SND_SOC_DAPM_POST_PMU:
  90		val = snd_soc_component_read(component,
  91					       ARIZONA_INTERRUPT_RAW_STATUS_3);
  92		if (val & ARIZONA_SPK_OVERHEAT_STS) {
  93			dev_crit(arizona->dev,
  94				 "Speaker not enabled due to temperature\n");
  95			return -EBUSY;
  96		}
  97
  98		regmap_update_bits_async(arizona->regmap,
  99					 ARIZONA_OUTPUT_ENABLES_1,
 100					 1 << w->shift, 1 << w->shift);
 101		break;
 102	case SND_SOC_DAPM_PRE_PMD:
 103		regmap_update_bits_async(arizona->regmap,
 104					 ARIZONA_OUTPUT_ENABLES_1,
 105					 1 << w->shift, 0);
 106		break;
 107	default:
 108		break;
 109	}
 110
 111	return arizona_out_ev(w, kcontrol, event);
 112}
 113
 114static irqreturn_t arizona_thermal_warn(int irq, void *data)
 115{
 116	struct arizona *arizona = data;
 117	unsigned int val;
 118	int ret;
 119
 120	ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
 121			  &val);
 122	if (ret != 0) {
 123		dev_err(arizona->dev, "Failed to read thermal status: %d\n",
 124			ret);
 125	} else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
 126		dev_crit(arizona->dev, "Thermal warning\n");
 127	}
 128
 129	return IRQ_HANDLED;
 130}
 131
 132static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
 133{
 134	struct arizona *arizona = data;
 135	unsigned int val;
 136	int ret;
 137
 138	ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
 139			  &val);
 140	if (ret != 0) {
 141		dev_err(arizona->dev, "Failed to read thermal status: %d\n",
 142			ret);
 143	} else if (val & ARIZONA_SPK_OVERHEAT_STS) {
 144		dev_crit(arizona->dev, "Thermal shutdown\n");
 145		ret = regmap_update_bits(arizona->regmap,
 146					 ARIZONA_OUTPUT_ENABLES_1,
 147					 ARIZONA_OUT4L_ENA |
 148					 ARIZONA_OUT4R_ENA, 0);
 149		if (ret != 0)
 150			dev_crit(arizona->dev,
 151				 "Failed to disable speaker outputs: %d\n",
 152				 ret);
 153	}
 154
 155	return IRQ_HANDLED;
 156}
 157
 158static const struct snd_soc_dapm_widget arizona_spkl =
 159	SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
 160			   ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
 161			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 162			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
 163
 164static const struct snd_soc_dapm_widget arizona_spkr =
 165	SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
 166			   ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
 167			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 168			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
 169
 170int arizona_init_spk(struct snd_soc_component *component)
 171{
 172	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 173	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 174	struct arizona *arizona = priv->arizona;
 175	int ret;
 176
 177	ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
 178	if (ret != 0)
 179		return ret;
 180
 181	switch (arizona->type) {
 182	case WM8997:
 183	case CS47L24:
 184	case WM1831:
 185		break;
 186	default:
 187		ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
 188		if (ret != 0)
 189			return ret;
 190		break;
 191	}
 192
 193	return 0;
 194}
 195EXPORT_SYMBOL_GPL(arizona_init_spk);
 196
 197int arizona_init_spk_irqs(struct arizona *arizona)
 198{
 199	int ret;
 200
 201	ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
 202				  "Thermal warning", arizona_thermal_warn,
 203				  arizona);
 204	if (ret != 0)
 205		dev_err(arizona->dev,
 206			"Failed to get thermal warning IRQ: %d\n",
 207			ret);
 208
 209	ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
 210				  "Thermal shutdown", arizona_thermal_shutdown,
 211				  arizona);
 212	if (ret != 0)
 213		dev_err(arizona->dev,
 214			"Failed to get thermal shutdown IRQ: %d\n",
 215			ret);
 216
 217	return 0;
 218}
 219EXPORT_SYMBOL_GPL(arizona_init_spk_irqs);
 220
 221int arizona_free_spk_irqs(struct arizona *arizona)
 222{
 223	arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona);
 224	arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona);
 225
 226	return 0;
 227}
 228EXPORT_SYMBOL_GPL(arizona_free_spk_irqs);
 229
 230static const struct snd_soc_dapm_route arizona_mono_routes[] = {
 231	{ "OUT1R", NULL, "OUT1L" },
 232	{ "OUT2R", NULL, "OUT2L" },
 233	{ "OUT3R", NULL, "OUT3L" },
 234	{ "OUT4R", NULL, "OUT4L" },
 235	{ "OUT5R", NULL, "OUT5L" },
 236	{ "OUT6R", NULL, "OUT6L" },
 237};
 238
 239int arizona_init_mono(struct snd_soc_component *component)
 240{
 241	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 242	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 243	struct arizona *arizona = priv->arizona;
 244	int i;
 245
 246	for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
 247		if (arizona->pdata.out_mono[i])
 248			snd_soc_dapm_add_routes(dapm,
 249						&arizona_mono_routes[i], 1);
 250	}
 251
 252	return 0;
 253}
 254EXPORT_SYMBOL_GPL(arizona_init_mono);
 255
 256int arizona_init_gpio(struct snd_soc_component *component)
 257{
 258	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 259	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 260	struct arizona *arizona = priv->arizona;
 261	int i;
 262
 263	switch (arizona->type) {
 264	case WM5110:
 265	case WM8280:
 266		snd_soc_dapm_disable_pin(dapm, "DRC2 Signal Activity");
 267		break;
 268	default:
 269		break;
 270	}
 271
 272	snd_soc_dapm_disable_pin(dapm, "DRC1 Signal Activity");
 273
 274	for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
 275		switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
 276		case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
 277			snd_soc_dapm_enable_pin(dapm, "DRC1 Signal Activity");
 278			break;
 279		case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
 280			snd_soc_dapm_enable_pin(dapm, "DRC2 Signal Activity");
 281			break;
 282		default:
 283			break;
 284		}
 285	}
 286
 287	return 0;
 288}
 289EXPORT_SYMBOL_GPL(arizona_init_gpio);
 290
 291int arizona_init_common(struct arizona *arizona)
 292{
 293	struct arizona_pdata *pdata = &arizona->pdata;
 294	unsigned int val, mask;
 295	int i;
 296
 297	BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
 298
 299	for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
 300		/* Default is 0 so noop with defaults */
 301		if (pdata->out_mono[i])
 302			val = ARIZONA_OUT1_MONO;
 303		else
 304			val = 0;
 305
 306		regmap_update_bits(arizona->regmap,
 307				   ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
 308				   ARIZONA_OUT1_MONO, val);
 309	}
 310
 311	for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
 312		if (pdata->spk_mute[i])
 313			regmap_update_bits(arizona->regmap,
 314					   ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
 315					   ARIZONA_SPK1_MUTE_ENDIAN_MASK |
 316					   ARIZONA_SPK1_MUTE_SEQ1_MASK,
 317					   pdata->spk_mute[i]);
 318
 319		if (pdata->spk_fmt[i])
 320			regmap_update_bits(arizona->regmap,
 321					   ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
 322					   ARIZONA_SPK1_FMT_MASK,
 323					   pdata->spk_fmt[i]);
 324	}
 325
 326	for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
 327		/* Default for both is 0 so noop with defaults */
 328		val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
 329		if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
 330			val |= 1 << ARIZONA_IN1_MODE_SHIFT;
 331
 332		switch (arizona->type) {
 333		case WM8998:
 334		case WM1814:
 335			regmap_update_bits(arizona->regmap,
 336				ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
 337				ARIZONA_IN1L_SRC_SE_MASK,
 338				(pdata->inmode[i] & ARIZONA_INMODE_SE)
 339					<< ARIZONA_IN1L_SRC_SE_SHIFT);
 340
 341			regmap_update_bits(arizona->regmap,
 342				ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
 343				ARIZONA_IN1R_SRC_SE_MASK,
 344				(pdata->inmode[i] & ARIZONA_INMODE_SE)
 345					<< ARIZONA_IN1R_SRC_SE_SHIFT);
 346
 347			mask = ARIZONA_IN1_DMIC_SUP_MASK |
 348			       ARIZONA_IN1_MODE_MASK;
 349			break;
 350		default:
 351			if (pdata->inmode[i] & ARIZONA_INMODE_SE)
 352				val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
 353
 354			mask = ARIZONA_IN1_DMIC_SUP_MASK |
 355			       ARIZONA_IN1_MODE_MASK |
 356			       ARIZONA_IN1_SINGLE_ENDED_MASK;
 357			break;
 358		}
 359
 360		regmap_update_bits(arizona->regmap,
 361				   ARIZONA_IN1L_CONTROL + (i * 8),
 362				   mask, val);
 363	}
 364
 365	return 0;
 366}
 367EXPORT_SYMBOL_GPL(arizona_init_common);
 368
 369int arizona_init_vol_limit(struct arizona *arizona)
 370{
 371	int i;
 372
 373	for (i = 0; i < ARRAY_SIZE(arizona->pdata.out_vol_limit); ++i) {
 374		if (arizona->pdata.out_vol_limit[i])
 375			regmap_update_bits(arizona->regmap,
 376					   ARIZONA_DAC_VOLUME_LIMIT_1L + i * 4,
 377					   ARIZONA_OUT1L_VOL_LIM_MASK,
 378					   arizona->pdata.out_vol_limit[i]);
 379	}
 380
 381	return 0;
 382}
 383EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
 384
 385const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
 386	"None",
 387	"Tone Generator 1",
 388	"Tone Generator 2",
 389	"Haptics",
 390	"AEC",
 391	"AEC2",
 392	"Mic Mute Mixer",
 393	"Noise Generator",
 394	"IN1L",
 395	"IN1R",
 396	"IN2L",
 397	"IN2R",
 398	"IN3L",
 399	"IN3R",
 400	"IN4L",
 401	"IN4R",
 402	"AIF1RX1",
 403	"AIF1RX2",
 404	"AIF1RX3",
 405	"AIF1RX4",
 406	"AIF1RX5",
 407	"AIF1RX6",
 408	"AIF1RX7",
 409	"AIF1RX8",
 410	"AIF2RX1",
 411	"AIF2RX2",
 412	"AIF2RX3",
 413	"AIF2RX4",
 414	"AIF2RX5",
 415	"AIF2RX6",
 416	"AIF3RX1",
 417	"AIF3RX2",
 418	"SLIMRX1",
 419	"SLIMRX2",
 420	"SLIMRX3",
 421	"SLIMRX4",
 422	"SLIMRX5",
 423	"SLIMRX6",
 424	"SLIMRX7",
 425	"SLIMRX8",
 426	"EQ1",
 427	"EQ2",
 428	"EQ3",
 429	"EQ4",
 430	"DRC1L",
 431	"DRC1R",
 432	"DRC2L",
 433	"DRC2R",
 434	"LHPF1",
 435	"LHPF2",
 436	"LHPF3",
 437	"LHPF4",
 438	"DSP1.1",
 439	"DSP1.2",
 440	"DSP1.3",
 441	"DSP1.4",
 442	"DSP1.5",
 443	"DSP1.6",
 444	"DSP2.1",
 445	"DSP2.2",
 446	"DSP2.3",
 447	"DSP2.4",
 448	"DSP2.5",
 449	"DSP2.6",
 450	"DSP3.1",
 451	"DSP3.2",
 452	"DSP3.3",
 453	"DSP3.4",
 454	"DSP3.5",
 455	"DSP3.6",
 456	"DSP4.1",
 457	"DSP4.2",
 458	"DSP4.3",
 459	"DSP4.4",
 460	"DSP4.5",
 461	"DSP4.6",
 462	"ASRC1L",
 463	"ASRC1R",
 464	"ASRC2L",
 465	"ASRC2R",
 466	"ISRC1INT1",
 467	"ISRC1INT2",
 468	"ISRC1INT3",
 469	"ISRC1INT4",
 470	"ISRC1DEC1",
 471	"ISRC1DEC2",
 472	"ISRC1DEC3",
 473	"ISRC1DEC4",
 474	"ISRC2INT1",
 475	"ISRC2INT2",
 476	"ISRC2INT3",
 477	"ISRC2INT4",
 478	"ISRC2DEC1",
 479	"ISRC2DEC2",
 480	"ISRC2DEC3",
 481	"ISRC2DEC4",
 482	"ISRC3INT1",
 483	"ISRC3INT2",
 484	"ISRC3INT3",
 485	"ISRC3INT4",
 486	"ISRC3DEC1",
 487	"ISRC3DEC2",
 488	"ISRC3DEC3",
 489	"ISRC3DEC4",
 490};
 491EXPORT_SYMBOL_GPL(arizona_mixer_texts);
 492
 493unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
 494	0x00,  /* None */
 495	0x04,  /* Tone */
 496	0x05,
 497	0x06,  /* Haptics */
 498	0x08,  /* AEC */
 499	0x09,  /* AEC2 */
 500	0x0c,  /* Noise mixer */
 501	0x0d,  /* Comfort noise */
 502	0x10,  /* IN1L */
 503	0x11,
 504	0x12,
 505	0x13,
 506	0x14,
 507	0x15,
 508	0x16,
 509	0x17,
 510	0x20,  /* AIF1RX1 */
 511	0x21,
 512	0x22,
 513	0x23,
 514	0x24,
 515	0x25,
 516	0x26,
 517	0x27,
 518	0x28,  /* AIF2RX1 */
 519	0x29,
 520	0x2a,
 521	0x2b,
 522	0x2c,
 523	0x2d,
 524	0x30,  /* AIF3RX1 */
 525	0x31,
 526	0x38,  /* SLIMRX1 */
 527	0x39,
 528	0x3a,
 529	0x3b,
 530	0x3c,
 531	0x3d,
 532	0x3e,
 533	0x3f,
 534	0x50,  /* EQ1 */
 535	0x51,
 536	0x52,
 537	0x53,
 538	0x58,  /* DRC1L */
 539	0x59,
 540	0x5a,
 541	0x5b,
 542	0x60,  /* LHPF1 */
 543	0x61,
 544	0x62,
 545	0x63,
 546	0x68,  /* DSP1.1 */
 547	0x69,
 548	0x6a,
 549	0x6b,
 550	0x6c,
 551	0x6d,
 552	0x70,  /* DSP2.1 */
 553	0x71,
 554	0x72,
 555	0x73,
 556	0x74,
 557	0x75,
 558	0x78,  /* DSP3.1 */
 559	0x79,
 560	0x7a,
 561	0x7b,
 562	0x7c,
 563	0x7d,
 564	0x80,  /* DSP4.1 */
 565	0x81,
 566	0x82,
 567	0x83,
 568	0x84,
 569	0x85,
 570	0x90,  /* ASRC1L */
 571	0x91,
 572	0x92,
 573	0x93,
 574	0xa0,  /* ISRC1INT1 */
 575	0xa1,
 576	0xa2,
 577	0xa3,
 578	0xa4,  /* ISRC1DEC1 */
 579	0xa5,
 580	0xa6,
 581	0xa7,
 582	0xa8,  /* ISRC2DEC1 */
 583	0xa9,
 584	0xaa,
 585	0xab,
 586	0xac,  /* ISRC2INT1 */
 587	0xad,
 588	0xae,
 589	0xaf,
 590	0xb0,  /* ISRC3DEC1 */
 591	0xb1,
 592	0xb2,
 593	0xb3,
 594	0xb4,  /* ISRC3INT1 */
 595	0xb5,
 596	0xb6,
 597	0xb7,
 598};
 599EXPORT_SYMBOL_GPL(arizona_mixer_values);
 600
 601const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
 602EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
 603
 604const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
 605	"12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
 606	"11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
 607	"4kHz", "8kHz", "16kHz", "32kHz",
 608};
 609EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
 610
 611const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
 612	0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
 613	0x10, 0x11, 0x12, 0x13,
 614};
 615EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
 616
 617const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
 618{
 619	int i;
 620
 621	for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
 622		if (arizona_sample_rate_val[i] == rate_val)
 623			return arizona_sample_rate_text[i];
 624	}
 625
 626	return "Illegal";
 627}
 628EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
 629
 630const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
 631	"SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
 632};
 633EXPORT_SYMBOL_GPL(arizona_rate_text);
 634
 635const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
 636	0, 1, 2, 8,
 637};
 638EXPORT_SYMBOL_GPL(arizona_rate_val);
 639
 640const struct soc_enum arizona_isrc_fsh[] = {
 641	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
 642			      ARIZONA_ISRC1_FSH_SHIFT, 0xf,
 643			      ARIZONA_RATE_ENUM_SIZE,
 644			      arizona_rate_text, arizona_rate_val),
 645	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
 646			      ARIZONA_ISRC2_FSH_SHIFT, 0xf,
 647			      ARIZONA_RATE_ENUM_SIZE,
 648			      arizona_rate_text, arizona_rate_val),
 649	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
 650			      ARIZONA_ISRC3_FSH_SHIFT, 0xf,
 651			      ARIZONA_RATE_ENUM_SIZE,
 652			      arizona_rate_text, arizona_rate_val),
 653};
 654EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
 655
 656const struct soc_enum arizona_isrc_fsl[] = {
 657	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
 658			      ARIZONA_ISRC1_FSL_SHIFT, 0xf,
 659			      ARIZONA_RATE_ENUM_SIZE,
 660			      arizona_rate_text, arizona_rate_val),
 661	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
 662			      ARIZONA_ISRC2_FSL_SHIFT, 0xf,
 663			      ARIZONA_RATE_ENUM_SIZE,
 664			      arizona_rate_text, arizona_rate_val),
 665	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
 666			      ARIZONA_ISRC3_FSL_SHIFT, 0xf,
 667			      ARIZONA_RATE_ENUM_SIZE,
 668			      arizona_rate_text, arizona_rate_val),
 669};
 670EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
 671
 672const struct soc_enum arizona_asrc_rate1 =
 673	SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
 674			      ARIZONA_ASRC_RATE1_SHIFT, 0xf,
 675			      ARIZONA_RATE_ENUM_SIZE - 1,
 676			      arizona_rate_text, arizona_rate_val);
 677EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
 678
 679static const char * const arizona_vol_ramp_text[] = {
 680	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
 681	"15ms/6dB", "30ms/6dB",
 682};
 683
 684SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
 685		     ARIZONA_INPUT_VOLUME_RAMP,
 686		     ARIZONA_IN_VD_RAMP_SHIFT,
 687		     arizona_vol_ramp_text);
 688EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
 689
 690SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
 691		     ARIZONA_INPUT_VOLUME_RAMP,
 692		     ARIZONA_IN_VI_RAMP_SHIFT,
 693		     arizona_vol_ramp_text);
 694EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
 695
 696SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
 697		     ARIZONA_OUTPUT_VOLUME_RAMP,
 698		     ARIZONA_OUT_VD_RAMP_SHIFT,
 699		     arizona_vol_ramp_text);
 700EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
 701
 702SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
 703		     ARIZONA_OUTPUT_VOLUME_RAMP,
 704		     ARIZONA_OUT_VI_RAMP_SHIFT,
 705		     arizona_vol_ramp_text);
 706EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
 707
 708static const char * const arizona_lhpf_mode_text[] = {
 709	"Low-pass", "High-pass"
 710};
 711
 712SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
 713		     ARIZONA_HPLPF1_1,
 714		     ARIZONA_LHPF1_MODE_SHIFT,
 715		     arizona_lhpf_mode_text);
 716EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
 717
 718SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
 719		     ARIZONA_HPLPF2_1,
 720		     ARIZONA_LHPF2_MODE_SHIFT,
 721		     arizona_lhpf_mode_text);
 722EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
 723
 724SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
 725		     ARIZONA_HPLPF3_1,
 726		     ARIZONA_LHPF3_MODE_SHIFT,
 727		     arizona_lhpf_mode_text);
 728EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
 729
 730SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
 731		     ARIZONA_HPLPF4_1,
 732		     ARIZONA_LHPF4_MODE_SHIFT,
 733		     arizona_lhpf_mode_text);
 734EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
 735
 736static const char * const arizona_ng_hold_text[] = {
 737	"30ms", "120ms", "250ms", "500ms",
 738};
 739
 740SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
 741		     ARIZONA_NOISE_GATE_CONTROL,
 742		     ARIZONA_NGATE_HOLD_SHIFT,
 743		     arizona_ng_hold_text);
 744EXPORT_SYMBOL_GPL(arizona_ng_hold);
 745
 746static const char * const arizona_in_hpf_cut_text[] = {
 747	"2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
 748};
 749
 750SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
 751		     ARIZONA_HPF_CONTROL,
 752		     ARIZONA_IN_HPF_CUT_SHIFT,
 753		     arizona_in_hpf_cut_text);
 754EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
 755
 756static const char * const arizona_in_dmic_osr_text[] = {
 757	"1.536MHz", "3.072MHz", "6.144MHz", "768kHz",
 758};
 759
 760const struct soc_enum arizona_in_dmic_osr[] = {
 761	SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
 762			ARRAY_SIZE(arizona_in_dmic_osr_text),
 763			arizona_in_dmic_osr_text),
 764	SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
 765			ARRAY_SIZE(arizona_in_dmic_osr_text),
 766			arizona_in_dmic_osr_text),
 767	SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
 768			ARRAY_SIZE(arizona_in_dmic_osr_text),
 769			arizona_in_dmic_osr_text),
 770	SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
 771			ARRAY_SIZE(arizona_in_dmic_osr_text),
 772			arizona_in_dmic_osr_text),
 773};
 774EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
 775
 776static const char * const arizona_anc_input_src_text[] = {
 777	"None", "IN1", "IN2", "IN3", "IN4",
 778};
 779
 780static const char * const arizona_anc_channel_src_text[] = {
 781	"None", "Left", "Right", "Combine",
 782};
 783
 784const struct soc_enum arizona_anc_input_src[] = {
 785	SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
 786			ARIZONA_IN_RXANCL_SEL_SHIFT,
 787			ARRAY_SIZE(arizona_anc_input_src_text),
 788			arizona_anc_input_src_text),
 789	SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
 790			ARIZONA_FCL_MIC_MODE_SEL_SHIFT,
 791			ARRAY_SIZE(arizona_anc_channel_src_text),
 792			arizona_anc_channel_src_text),
 793	SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
 794			ARIZONA_IN_RXANCR_SEL_SHIFT,
 795			ARRAY_SIZE(arizona_anc_input_src_text),
 796			arizona_anc_input_src_text),
 797	SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
 798			ARIZONA_FCR_MIC_MODE_SEL_SHIFT,
 799			ARRAY_SIZE(arizona_anc_channel_src_text),
 800			arizona_anc_channel_src_text),
 801};
 802EXPORT_SYMBOL_GPL(arizona_anc_input_src);
 803
 804static const char * const arizona_anc_ng_texts[] = {
 805	"None",
 806	"Internal",
 807	"External",
 808};
 809
 810SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
 811		     arizona_anc_ng_texts);
 812EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
 813
 814static const char * const arizona_output_anc_src_text[] = {
 815	"None", "RXANCL", "RXANCR",
 816};
 817
 818const struct soc_enum arizona_output_anc_src[] = {
 819	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
 820			ARIZONA_OUT1L_ANC_SRC_SHIFT,
 821			ARRAY_SIZE(arizona_output_anc_src_text),
 822			arizona_output_anc_src_text),
 823	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
 824			ARIZONA_OUT1R_ANC_SRC_SHIFT,
 825			ARRAY_SIZE(arizona_output_anc_src_text),
 826			arizona_output_anc_src_text),
 827	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
 828			ARIZONA_OUT2L_ANC_SRC_SHIFT,
 829			ARRAY_SIZE(arizona_output_anc_src_text),
 830			arizona_output_anc_src_text),
 831	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
 832			ARIZONA_OUT2R_ANC_SRC_SHIFT,
 833			ARRAY_SIZE(arizona_output_anc_src_text),
 834			arizona_output_anc_src_text),
 835	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
 836			ARIZONA_OUT3L_ANC_SRC_SHIFT,
 837			ARRAY_SIZE(arizona_output_anc_src_text),
 838			arizona_output_anc_src_text),
 839	SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
 840			ARIZONA_OUT3R_ANC_SRC_SHIFT,
 841			ARRAY_SIZE(arizona_output_anc_src_text),
 842			arizona_output_anc_src_text),
 843	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
 844			ARIZONA_OUT4L_ANC_SRC_SHIFT,
 845			ARRAY_SIZE(arizona_output_anc_src_text),
 846			arizona_output_anc_src_text),
 847	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
 848			ARIZONA_OUT4R_ANC_SRC_SHIFT,
 849			ARRAY_SIZE(arizona_output_anc_src_text),
 850			arizona_output_anc_src_text),
 851	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
 852			ARIZONA_OUT5L_ANC_SRC_SHIFT,
 853			ARRAY_SIZE(arizona_output_anc_src_text),
 854			arizona_output_anc_src_text),
 855	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
 856			ARIZONA_OUT5R_ANC_SRC_SHIFT,
 857			ARRAY_SIZE(arizona_output_anc_src_text),
 858			arizona_output_anc_src_text),
 859	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
 860			ARIZONA_OUT6L_ANC_SRC_SHIFT,
 861			ARRAY_SIZE(arizona_output_anc_src_text),
 862			arizona_output_anc_src_text),
 863	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
 864			ARIZONA_OUT6R_ANC_SRC_SHIFT,
 865			ARRAY_SIZE(arizona_output_anc_src_text),
 866			arizona_output_anc_src_text),
 867};
 868EXPORT_SYMBOL_GPL(arizona_output_anc_src);
 869
 870const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
 871	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
 872	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0),
 873	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0),
 874	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0),
 875};
 876EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
 877
 878static void arizona_in_set_vu(struct snd_soc_component *component, int ena)
 879{
 880	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 881	unsigned int val;
 882	int i;
 883
 884	if (ena)
 885		val = ARIZONA_IN_VU;
 886	else
 887		val = 0;
 888
 889	for (i = 0; i < priv->num_inputs; i++)
 890		snd_soc_component_update_bits(component,
 891				    ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
 892				    ARIZONA_IN_VU, val);
 893}
 894
 895bool arizona_input_analog(struct snd_soc_component *component, int shift)
 896{
 897	unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
 898	unsigned int val = snd_soc_component_read(component, reg);
 899
 900	return !(val & ARIZONA_IN1_MODE_MASK);
 901}
 902EXPORT_SYMBOL_GPL(arizona_input_analog);
 903
 904int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
 905		  int event)
 906{
 907	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 908	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 909	unsigned int reg;
 910
 911	if (w->shift % 2)
 912		reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
 913	else
 914		reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
 915
 916	switch (event) {
 917	case SND_SOC_DAPM_PRE_PMU:
 918		priv->in_pending++;
 919		break;
 920	case SND_SOC_DAPM_POST_PMU:
 921		snd_soc_component_update_bits(component, reg,
 922					      ARIZONA_IN1L_MUTE, 0);
 923
 924		/* If this is the last input pending then allow VU */
 925		priv->in_pending--;
 926		if (priv->in_pending == 0) {
 927			msleep(1);
 928			arizona_in_set_vu(component, 1);
 929		}
 930		break;
 931	case SND_SOC_DAPM_PRE_PMD:
 932		snd_soc_component_update_bits(component, reg,
 933				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
 934				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
 935		break;
 936	case SND_SOC_DAPM_POST_PMD:
 937		/* Disable volume updates if no inputs are enabled */
 938		reg = snd_soc_component_read(component, ARIZONA_INPUT_ENABLES);
 939		if (reg == 0)
 940			arizona_in_set_vu(component, 0);
 941		break;
 942	default:
 943		break;
 944	}
 945
 946	return 0;
 947}
 948EXPORT_SYMBOL_GPL(arizona_in_ev);
 949
 950int arizona_out_ev(struct snd_soc_dapm_widget *w,
 951		   struct snd_kcontrol *kcontrol,
 952		   int event)
 953{
 954	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 955	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 956	struct arizona *arizona = priv->arizona;
 957
 958	switch (event) {
 959	case SND_SOC_DAPM_PRE_PMU:
 960		switch (w->shift) {
 961		case ARIZONA_OUT1L_ENA_SHIFT:
 962		case ARIZONA_OUT1R_ENA_SHIFT:
 963		case ARIZONA_OUT2L_ENA_SHIFT:
 964		case ARIZONA_OUT2R_ENA_SHIFT:
 965		case ARIZONA_OUT3L_ENA_SHIFT:
 966		case ARIZONA_OUT3R_ENA_SHIFT:
 967			priv->out_up_pending++;
 968			priv->out_up_delay += 17000;
 969			break;
 970		case ARIZONA_OUT4L_ENA_SHIFT:
 971		case ARIZONA_OUT4R_ENA_SHIFT:
 972			priv->out_up_pending++;
 973			switch (arizona->type) {
 974			case WM5102:
 975			case WM8997:
 976				break;
 977			default:
 978				priv->out_up_delay += 10000;
 979				break;
 980			}
 981			break;
 982		default:
 983			break;
 984		}
 985		break;
 986	case SND_SOC_DAPM_POST_PMU:
 987		switch (w->shift) {
 988		case ARIZONA_OUT1L_ENA_SHIFT:
 989		case ARIZONA_OUT1R_ENA_SHIFT:
 990		case ARIZONA_OUT2L_ENA_SHIFT:
 991		case ARIZONA_OUT2R_ENA_SHIFT:
 992		case ARIZONA_OUT3L_ENA_SHIFT:
 993		case ARIZONA_OUT3R_ENA_SHIFT:
 994		case ARIZONA_OUT4L_ENA_SHIFT:
 995		case ARIZONA_OUT4R_ENA_SHIFT:
 996			priv->out_up_pending--;
 997			if (!priv->out_up_pending && priv->out_up_delay) {
 998				dev_dbg(component->dev, "Power up delay: %d\n",
 999					priv->out_up_delay);
1000				fsleep(priv->out_up_delay);
1001				priv->out_up_delay = 0;
1002			}
1003			break;
1004
1005		default:
1006			break;
1007		}
1008		break;
1009	case SND_SOC_DAPM_PRE_PMD:
1010		switch (w->shift) {
1011		case ARIZONA_OUT1L_ENA_SHIFT:
1012		case ARIZONA_OUT1R_ENA_SHIFT:
1013		case ARIZONA_OUT2L_ENA_SHIFT:
1014		case ARIZONA_OUT2R_ENA_SHIFT:
1015		case ARIZONA_OUT3L_ENA_SHIFT:
1016		case ARIZONA_OUT3R_ENA_SHIFT:
1017			priv->out_down_pending++;
1018			priv->out_down_delay += 1000;
1019			break;
1020		case ARIZONA_OUT4L_ENA_SHIFT:
1021		case ARIZONA_OUT4R_ENA_SHIFT:
1022			priv->out_down_pending++;
1023			switch (arizona->type) {
1024			case WM5102:
1025			case WM8997:
1026				break;
1027			case WM8998:
1028			case WM1814:
1029				priv->out_down_delay += 5000;
1030				break;
1031			default:
1032				priv->out_down_delay += 1000;
1033				break;
1034			}
1035			break;
1036		default:
1037			break;
1038		}
1039		break;
1040	case SND_SOC_DAPM_POST_PMD:
1041		switch (w->shift) {
1042		case ARIZONA_OUT1L_ENA_SHIFT:
1043		case ARIZONA_OUT1R_ENA_SHIFT:
1044		case ARIZONA_OUT2L_ENA_SHIFT:
1045		case ARIZONA_OUT2R_ENA_SHIFT:
1046		case ARIZONA_OUT3L_ENA_SHIFT:
1047		case ARIZONA_OUT3R_ENA_SHIFT:
1048		case ARIZONA_OUT4L_ENA_SHIFT:
1049		case ARIZONA_OUT4R_ENA_SHIFT:
1050			priv->out_down_pending--;
1051			if (!priv->out_down_pending && priv->out_down_delay) {
1052				dev_dbg(component->dev, "Power down delay: %d\n",
1053					priv->out_down_delay);
1054				fsleep(priv->out_down_delay);
1055				priv->out_down_delay = 0;
1056			}
1057			break;
1058		default:
1059			break;
1060		}
1061		break;
1062	default:
1063		break;
1064	}
1065
1066	return 0;
1067}
1068EXPORT_SYMBOL_GPL(arizona_out_ev);
1069
1070int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
1071		  int event)
1072{
1073	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1074	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1075	struct arizona *arizona = priv->arizona;
1076	unsigned int mask = 1 << w->shift;
1077	unsigned int val;
1078
1079	switch (event) {
1080	case SND_SOC_DAPM_POST_PMU:
1081		val = mask;
1082		break;
1083	case SND_SOC_DAPM_PRE_PMD:
1084		val = 0;
1085		break;
1086	case SND_SOC_DAPM_PRE_PMU:
1087	case SND_SOC_DAPM_POST_PMD:
1088		return arizona_out_ev(w, kcontrol, event);
1089	default:
1090		return -EINVAL;
1091	}
1092
1093	/* Store the desired state for the HP outputs */
1094	priv->arizona->hp_ena &= ~mask;
1095	priv->arizona->hp_ena |= val;
1096
1097	/* Force off if HPDET clamp is active */
1098	if (priv->arizona->hpdet_clamp)
1099		val = 0;
1100
1101	regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1102				 mask, val);
1103
1104	return arizona_out_ev(w, kcontrol, event);
1105}
1106EXPORT_SYMBOL_GPL(arizona_hp_ev);
1107
1108static int arizona_dvfs_enable(struct snd_soc_component *component)
1109{
1110	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1111	struct arizona *arizona = priv->arizona;
1112	int ret;
1113
1114	ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1115	if (ret) {
1116		dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
1117		return ret;
1118	}
1119
1120	ret = regmap_update_bits(arizona->regmap,
1121				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1122				 ARIZONA_SUBSYS_MAX_FREQ,
1123				 ARIZONA_SUBSYS_MAX_FREQ);
1124	if (ret) {
1125		dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
1126		regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1127		return ret;
1128	}
1129
1130	return 0;
1131}
1132
1133static int arizona_dvfs_disable(struct snd_soc_component *component)
1134{
1135	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1136	struct arizona *arizona = priv->arizona;
1137	int ret;
1138
1139	ret = regmap_update_bits(arizona->regmap,
1140				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1141				 ARIZONA_SUBSYS_MAX_FREQ, 0);
1142	if (ret) {
1143		dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
1144		return ret;
1145	}
1146
1147	ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1148	if (ret) {
1149		dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
1150		return ret;
1151	}
1152
1153	return 0;
1154}
1155
1156int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
1157{
1158	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1159	int ret = 0;
1160
1161	mutex_lock(&priv->dvfs_lock);
1162
1163	if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1164		ret = arizona_dvfs_enable(component);
1165		if (ret)
1166			goto err;
1167	}
1168
1169	priv->dvfs_reqs |= flags;
1170err:
1171	mutex_unlock(&priv->dvfs_lock);
1172	return ret;
1173}
1174EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1175
1176int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
1177{
1178	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1179	unsigned int old_reqs;
1180	int ret = 0;
1181
1182	mutex_lock(&priv->dvfs_lock);
1183
1184	old_reqs = priv->dvfs_reqs;
1185	priv->dvfs_reqs &= ~flags;
1186
1187	if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1188		ret = arizona_dvfs_disable(component);
1189
1190	mutex_unlock(&priv->dvfs_lock);
1191	return ret;
1192}
1193EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1194
1195int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1196			   struct snd_kcontrol *kcontrol, int event)
1197{
1198	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1199	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1200	int ret = 0;
1201
1202	mutex_lock(&priv->dvfs_lock);
1203
1204	switch (event) {
1205	case SND_SOC_DAPM_POST_PMU:
1206		if (priv->dvfs_reqs)
1207			ret = arizona_dvfs_enable(component);
1208
1209		priv->dvfs_cached = false;
1210		break;
1211	case SND_SOC_DAPM_PRE_PMD:
1212		/* We must ensure DVFS is disabled before the codec goes into
1213		 * suspend so that we are never in an illegal state of DVFS
1214		 * enabled without enough DCVDD
1215		 */
1216		priv->dvfs_cached = true;
1217
1218		if (priv->dvfs_reqs)
1219			ret = arizona_dvfs_disable(component);
1220		break;
1221	default:
1222		break;
1223	}
1224
1225	mutex_unlock(&priv->dvfs_lock);
1226	return ret;
1227}
1228EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1229
1230void arizona_init_dvfs(struct arizona_priv *priv)
1231{
1232	mutex_init(&priv->dvfs_lock);
1233}
1234EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1235
1236int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1237		   struct snd_kcontrol *kcontrol,
1238		   int event)
1239{
1240	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1241	unsigned int val;
1242
1243	switch (event) {
1244	case SND_SOC_DAPM_POST_PMU:
1245		val = 1 << w->shift;
1246		break;
1247	case SND_SOC_DAPM_PRE_PMD:
1248		val = 1 << (w->shift + 1);
1249		break;
1250	default:
1251		return 0;
1252	}
1253
1254	snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
1255
1256	return 0;
1257}
1258EXPORT_SYMBOL_GPL(arizona_anc_ev);
1259
1260static unsigned int arizona_opclk_ref_48k_rates[] = {
1261	6144000,
1262	12288000,
1263	24576000,
1264	49152000,
1265};
1266
1267static unsigned int arizona_opclk_ref_44k1_rates[] = {
1268	5644800,
1269	11289600,
1270	22579200,
1271	45158400,
1272};
1273
1274static int arizona_set_opclk(struct snd_soc_component *component,
1275			     unsigned int clk, unsigned int freq)
1276{
1277	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1278	unsigned int reg;
1279	unsigned int *rates;
1280	int ref, div, refclk;
1281
1282	switch (clk) {
1283	case ARIZONA_CLK_OPCLK:
1284		reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1285		refclk = priv->sysclk;
1286		break;
1287	case ARIZONA_CLK_ASYNC_OPCLK:
1288		reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1289		refclk = priv->asyncclk;
1290		break;
1291	default:
1292		return -EINVAL;
1293	}
1294
1295	if (refclk % 8000)
1296		rates = arizona_opclk_ref_44k1_rates;
1297	else
1298		rates = arizona_opclk_ref_48k_rates;
1299
1300	for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1301	     rates[ref] <= refclk; ref++) {
1302		div = 1;
1303		while (rates[ref] / div >= freq && div < 32) {
1304			if (rates[ref] / div == freq) {
1305				dev_dbg(component->dev, "Configured %dHz OPCLK\n",
1306					freq);
1307				snd_soc_component_update_bits(component, reg,
1308						    ARIZONA_OPCLK_DIV_MASK |
1309						    ARIZONA_OPCLK_SEL_MASK,
1310						    (div <<
1311						     ARIZONA_OPCLK_DIV_SHIFT) |
1312						    ref);
1313				return 0;
1314			}
1315			div++;
1316		}
1317	}
1318
1319	dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
1320	return -EINVAL;
1321}
1322
1323int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1324		   struct snd_kcontrol *kcontrol, int event)
1325{
1326	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1327	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
1328	unsigned int val;
1329	int clk_idx;
1330	int ret;
1331
1332	ret = regmap_read(arizona->regmap, w->reg, &val);
1333	if (ret) {
1334		dev_err(component->dev, "Failed to check clock source: %d\n", ret);
1335		return ret;
1336	}
1337
1338	val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1339
1340	switch (val) {
1341	case ARIZONA_CLK_SRC_MCLK1:
1342		clk_idx = ARIZONA_MCLK1;
1343		break;
1344	case ARIZONA_CLK_SRC_MCLK2:
1345		clk_idx = ARIZONA_MCLK2;
1346		break;
1347	default:
1348		return 0;
1349	}
1350
1351	switch (event) {
1352	case SND_SOC_DAPM_PRE_PMU:
1353		return clk_prepare_enable(arizona->mclk[clk_idx]);
1354	case SND_SOC_DAPM_POST_PMD:
1355		clk_disable_unprepare(arizona->mclk[clk_idx]);
1356		return 0;
1357	default:
1358		return 0;
1359	}
1360}
1361EXPORT_SYMBOL_GPL(arizona_clk_ev);
1362
1363int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
1364		       int source, unsigned int freq, int dir)
1365{
1366	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1367	struct arizona *arizona = priv->arizona;
1368	char *name;
1369	unsigned int reg;
1370	unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1371	unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1372	int *clk;
1373
1374	switch (clk_id) {
1375	case ARIZONA_CLK_SYSCLK:
1376		name = "SYSCLK";
1377		reg = ARIZONA_SYSTEM_CLOCK_1;
1378		clk = &priv->sysclk;
1379		mask |= ARIZONA_SYSCLK_FRAC;
1380		break;
1381	case ARIZONA_CLK_ASYNCCLK:
1382		name = "ASYNCCLK";
1383		reg = ARIZONA_ASYNC_CLOCK_1;
1384		clk = &priv->asyncclk;
1385		break;
1386	case ARIZONA_CLK_OPCLK:
1387	case ARIZONA_CLK_ASYNC_OPCLK:
1388		return arizona_set_opclk(component, clk_id, freq);
1389	default:
1390		return -EINVAL;
1391	}
1392
1393	switch (freq) {
1394	case  5644800:
1395	case  6144000:
1396		break;
1397	case 11289600:
1398	case 12288000:
1399		val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1400		break;
1401	case 22579200:
1402	case 24576000:
1403		val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1404		break;
1405	case 45158400:
1406	case 49152000:
1407		val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1408		break;
1409	case 67737600:
1410	case 73728000:
1411		val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1412		break;
1413	case 90316800:
1414	case 98304000:
1415		val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1416		break;
1417	case 135475200:
1418	case 147456000:
1419		val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1420		break;
1421	case 0:
1422		dev_dbg(arizona->dev, "%s cleared\n", name);
1423		*clk = freq;
1424		return 0;
1425	default:
1426		return -EINVAL;
1427	}
1428
1429	*clk = freq;
1430
1431	if (freq % 6144000)
1432		val |= ARIZONA_SYSCLK_FRAC;
1433
1434	dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1435
1436	return regmap_update_bits(arizona->regmap, reg, mask, val);
1437}
1438EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1439
1440static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1441{
1442	struct snd_soc_component *component = dai->component;
1443	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1444	struct arizona *arizona = priv->arizona;
1445	int lrclk, bclk, mode, base;
1446
1447	base = dai->driver->base;
1448
1449	lrclk = 0;
1450	bclk = 0;
1451
1452	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1453	case SND_SOC_DAIFMT_DSP_A:
1454		mode = ARIZONA_FMT_DSP_MODE_A;
1455		break;
1456	case SND_SOC_DAIFMT_DSP_B:
1457		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1458				!= SND_SOC_DAIFMT_CBP_CFP) {
1459			arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1460			return -EINVAL;
1461		}
1462		mode = ARIZONA_FMT_DSP_MODE_B;
1463		break;
1464	case SND_SOC_DAIFMT_I2S:
1465		mode = ARIZONA_FMT_I2S_MODE;
1466		break;
1467	case SND_SOC_DAIFMT_LEFT_J:
1468		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1469				!= SND_SOC_DAIFMT_CBP_CFP) {
1470			arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1471			return -EINVAL;
1472		}
1473		mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1474		break;
1475	default:
1476		arizona_aif_err(dai, "Unsupported DAI format %d\n",
1477				fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1478		return -EINVAL;
1479	}
1480
1481	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1482	case SND_SOC_DAIFMT_CBC_CFC:
1483		break;
1484	case SND_SOC_DAIFMT_CBC_CFP:
1485		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1486		break;
1487	case SND_SOC_DAIFMT_CBP_CFC:
1488		bclk |= ARIZONA_AIF1_BCLK_MSTR;
1489		break;
1490	case SND_SOC_DAIFMT_CBP_CFP:
1491		bclk |= ARIZONA_AIF1_BCLK_MSTR;
1492		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1493		break;
1494	default:
1495		arizona_aif_err(dai, "Unsupported master mode %d\n",
1496				fmt & SND_SOC_DAIFMT_MASTER_MASK);
1497		return -EINVAL;
1498	}
1499
1500	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1501	case SND_SOC_DAIFMT_NB_NF:
1502		break;
1503	case SND_SOC_DAIFMT_IB_IF:
1504		bclk |= ARIZONA_AIF1_BCLK_INV;
1505		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1506		break;
1507	case SND_SOC_DAIFMT_IB_NF:
1508		bclk |= ARIZONA_AIF1_BCLK_INV;
1509		break;
1510	case SND_SOC_DAIFMT_NB_IF:
1511		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1512		break;
1513	default:
1514		return -EINVAL;
1515	}
1516
1517	regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1518				 ARIZONA_AIF1_BCLK_INV |
1519				 ARIZONA_AIF1_BCLK_MSTR,
1520				 bclk);
1521	regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1522				 ARIZONA_AIF1TX_LRCLK_INV |
1523				 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1524	regmap_update_bits_async(arizona->regmap,
1525				 base + ARIZONA_AIF_RX_PIN_CTRL,
1526				 ARIZONA_AIF1RX_LRCLK_INV |
1527				 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1528	regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1529			   ARIZONA_AIF1_FMT_MASK, mode);
1530
1531	return 0;
1532}
1533
1534static const int arizona_48k_bclk_rates[] = {
1535	-1,
1536	48000,
1537	64000,
1538	96000,
1539	128000,
1540	192000,
1541	256000,
1542	384000,
1543	512000,
1544	768000,
1545	1024000,
1546	1536000,
1547	2048000,
1548	3072000,
1549	4096000,
1550	6144000,
1551	8192000,
1552	12288000,
1553	24576000,
1554};
1555
1556static const int arizona_44k1_bclk_rates[] = {
1557	-1,
1558	44100,
1559	58800,
1560	88200,
1561	117600,
1562	177640,
1563	235200,
1564	352800,
1565	470400,
1566	705600,
1567	940800,
1568	1411200,
1569	1881600,
1570	2822400,
1571	3763200,
1572	5644800,
1573	7526400,
1574	11289600,
1575	22579200,
1576};
1577
1578static const unsigned int arizona_sr_vals[] = {
1579	0,
1580	12000,
1581	24000,
1582	48000,
1583	96000,
1584	192000,
1585	384000,
1586	768000,
1587	0,
1588	11025,
1589	22050,
1590	44100,
1591	88200,
1592	176400,
1593	352800,
1594	705600,
1595	4000,
1596	8000,
1597	16000,
1598	32000,
1599	64000,
1600	128000,
1601	256000,
1602	512000,
1603};
1604
1605#define ARIZONA_48K_RATE_MASK	0x0F003E
1606#define ARIZONA_44K1_RATE_MASK	0x003E00
1607#define ARIZONA_RATE_MASK	(ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1608
1609static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1610	.count	= ARRAY_SIZE(arizona_sr_vals),
1611	.list	= arizona_sr_vals,
1612};
1613
1614static int arizona_startup(struct snd_pcm_substream *substream,
1615			   struct snd_soc_dai *dai)
1616{
1617	struct snd_soc_component *component = dai->component;
1618	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1619	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1620	unsigned int base_rate;
1621
1622	if (!substream->runtime)
1623		return 0;
1624
1625	switch (dai_priv->clk) {
1626	case ARIZONA_CLK_SYSCLK:
1627		base_rate = priv->sysclk;
1628		break;
1629	case ARIZONA_CLK_ASYNCCLK:
1630		base_rate = priv->asyncclk;
1631		break;
1632	default:
1633		return 0;
1634	}
1635
1636	if (base_rate == 0)
1637		dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1638	else if (base_rate % 8000)
1639		dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1640	else
1641		dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1642
1643	return snd_pcm_hw_constraint_list(substream->runtime, 0,
1644					  SNDRV_PCM_HW_PARAM_RATE,
1645					  &dai_priv->constraint);
1646}
1647
1648static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
1649					unsigned int rate)
1650{
1651	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1652	struct arizona *arizona = priv->arizona;
1653	struct reg_sequence dac_comp[] = {
1654		{ 0x80, 0x3 },
1655		{ ARIZONA_DAC_COMP_1, 0 },
1656		{ ARIZONA_DAC_COMP_2, 0 },
1657		{ 0x80, 0x0 },
1658	};
1659
1660	mutex_lock(&arizona->dac_comp_lock);
1661
1662	dac_comp[1].def = arizona->dac_comp_coeff;
1663	if (rate >= 176400)
1664		dac_comp[2].def = arizona->dac_comp_enabled;
1665
1666	mutex_unlock(&arizona->dac_comp_lock);
1667
1668	regmap_multi_reg_write(arizona->regmap,
1669			       dac_comp,
1670			       ARRAY_SIZE(dac_comp));
1671}
1672
1673static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1674				  struct snd_pcm_hw_params *params,
1675				  struct snd_soc_dai *dai)
1676{
1677	struct snd_soc_component *component = dai->component;
1678	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1679	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1680	int base = dai->driver->base;
1681	int i, sr_val, ret;
1682
1683	/*
1684	 * We will need to be more flexible than this in future,
1685	 * currently we use a single sample rate for SYSCLK.
1686	 */
1687	for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1688		if (arizona_sr_vals[i] == params_rate(params))
1689			break;
1690	if (i == ARRAY_SIZE(arizona_sr_vals)) {
1691		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1692				params_rate(params));
1693		return -EINVAL;
1694	}
1695	sr_val = i;
1696
1697	switch (priv->arizona->type) {
1698	case WM5102:
1699	case WM8997:
1700		if (arizona_sr_vals[sr_val] >= 88200)
1701			ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
1702		else
1703			ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
1704
1705		if (ret) {
1706			arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1707			return ret;
1708		}
1709		break;
1710	default:
1711		break;
1712	}
1713
1714	switch (dai_priv->clk) {
1715	case ARIZONA_CLK_SYSCLK:
1716		switch (priv->arizona->type) {
1717		case WM5102:
1718			arizona_wm5102_set_dac_comp(component,
1719						    params_rate(params));
1720			break;
1721		default:
1722			break;
1723		}
1724
1725		snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
1726					      ARIZONA_SAMPLE_RATE_1_MASK,
1727					      sr_val);
1728		if (base)
1729			snd_soc_component_update_bits(component,
1730					base + ARIZONA_AIF_RATE_CTRL,
1731					ARIZONA_AIF1_RATE_MASK, 0);
1732		break;
1733	case ARIZONA_CLK_ASYNCCLK:
1734		snd_soc_component_update_bits(component,
1735					      ARIZONA_ASYNC_SAMPLE_RATE_1,
1736					      ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
1737					      sr_val);
1738		if (base)
1739			snd_soc_component_update_bits(component,
1740					base + ARIZONA_AIF_RATE_CTRL,
1741					ARIZONA_AIF1_RATE_MASK,
1742					8 << ARIZONA_AIF1_RATE_SHIFT);
1743		break;
1744	default:
1745		arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1746		return -EINVAL;
1747	}
1748
1749	return 0;
1750}
1751
1752static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
1753				    int base, int bclk, int lrclk, int frame)
1754{
1755	int val;
1756
1757	val = snd_soc_component_read(component, base + ARIZONA_AIF_BCLK_CTRL);
1758	if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1759		return true;
1760
1761	val = snd_soc_component_read(component, base + ARIZONA_AIF_RX_BCLK_RATE);
1762	if (lrclk != (val & ARIZONA_AIF1RX_BCPF_MASK))
1763		return true;
1764
1765	val = snd_soc_component_read(component, base + ARIZONA_AIF_FRAME_CTRL_1);
1766	if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1767			     ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1768		return true;
1769
1770	return false;
1771}
1772
1773static int arizona_hw_params(struct snd_pcm_substream *substream,
1774			     struct snd_pcm_hw_params *params,
1775			     struct snd_soc_dai *dai)
1776{
1777	struct snd_soc_component *component = dai->component;
1778	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1779	struct arizona *arizona = priv->arizona;
1780	int base = dai->driver->base;
1781	const int *rates;
1782	int i, ret, val;
1783	int channels = params_channels(params);
1784	int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1785	int tdm_width = arizona->tdm_width[dai->id - 1];
1786	int tdm_slots = arizona->tdm_slots[dai->id - 1];
1787	int bclk, lrclk, wl, frame, bclk_target;
1788	bool reconfig;
1789	unsigned int aif_tx_state, aif_rx_state;
1790
1791	if (params_rate(params) % 4000)
1792		rates = &arizona_44k1_bclk_rates[0];
1793	else
1794		rates = &arizona_48k_bclk_rates[0];
1795
1796	wl = params_width(params);
1797
1798	if (tdm_slots) {
1799		arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1800				tdm_slots, tdm_width);
1801		bclk_target = tdm_slots * tdm_width * params_rate(params);
1802		channels = tdm_slots;
1803	} else {
1804		bclk_target = snd_soc_params_to_bclk(params);
1805		tdm_width = wl;
1806	}
1807
1808	if (chan_limit && chan_limit < channels) {
1809		arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1810		bclk_target /= channels;
1811		bclk_target *= chan_limit;
1812	}
1813
1814	/* Force multiple of 2 channels for I2S mode */
1815	val = snd_soc_component_read(component, base + ARIZONA_AIF_FORMAT);
1816	val &= ARIZONA_AIF1_FMT_MASK;
1817	if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1818		arizona_aif_dbg(dai, "Forcing stereo mode\n");
1819		bclk_target /= channels;
1820		bclk_target *= channels + 1;
1821	}
1822
1823	for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1824		if (rates[i] >= bclk_target &&
1825		    rates[i] % params_rate(params) == 0) {
1826			bclk = i;
1827			break;
1828		}
1829	}
1830	if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1831		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1832				params_rate(params));
1833		return -EINVAL;
1834	}
1835
1836	lrclk = rates[bclk] / params_rate(params);
1837
1838	arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1839			rates[bclk], rates[bclk] / lrclk);
1840
1841	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1842
1843	reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
1844
1845	if (reconfig) {
1846		/* Save AIF TX/RX state */
1847		aif_tx_state = snd_soc_component_read(component,
1848					    base + ARIZONA_AIF_TX_ENABLES);
1849		aif_rx_state = snd_soc_component_read(component,
1850					    base + ARIZONA_AIF_RX_ENABLES);
1851		/* Disable AIF TX/RX before reconfiguring it */
1852		regmap_update_bits_async(arizona->regmap,
1853					 base + ARIZONA_AIF_TX_ENABLES,
1854					 0xff, 0x0);
1855		regmap_update_bits(arizona->regmap,
1856				   base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1857	}
1858
1859	ret = arizona_hw_params_rate(substream, params, dai);
1860	if (ret != 0)
1861		goto restore_aif;
1862
1863	if (reconfig) {
1864		regmap_update_bits_async(arizona->regmap,
1865					 base + ARIZONA_AIF_BCLK_CTRL,
1866					 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1867		regmap_update_bits_async(arizona->regmap,
1868					 base + ARIZONA_AIF_TX_BCLK_RATE,
1869					 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1870		regmap_update_bits_async(arizona->regmap,
1871					 base + ARIZONA_AIF_RX_BCLK_RATE,
1872					 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1873		regmap_update_bits_async(arizona->regmap,
1874					 base + ARIZONA_AIF_FRAME_CTRL_1,
1875					 ARIZONA_AIF1TX_WL_MASK |
1876					 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1877		regmap_update_bits(arizona->regmap,
1878				   base + ARIZONA_AIF_FRAME_CTRL_2,
1879				   ARIZONA_AIF1RX_WL_MASK |
1880				   ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1881	}
1882
1883restore_aif:
1884	if (reconfig) {
1885		/* Restore AIF TX/RX state */
1886		regmap_update_bits_async(arizona->regmap,
1887					 base + ARIZONA_AIF_TX_ENABLES,
1888					 0xff, aif_tx_state);
1889		regmap_update_bits(arizona->regmap,
1890				   base + ARIZONA_AIF_RX_ENABLES,
1891				   0xff, aif_rx_state);
1892	}
1893	return ret;
1894}
1895
1896static const char *arizona_dai_clk_str(int clk_id)
1897{
1898	switch (clk_id) {
1899	case ARIZONA_CLK_SYSCLK:
1900		return "SYSCLK";
1901	case ARIZONA_CLK_ASYNCCLK:
1902		return "ASYNCCLK";
1903	default:
1904		return "Unknown clock";
1905	}
1906}
1907
1908static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1909				  int clk_id, unsigned int freq, int dir)
1910{
1911	struct snd_soc_component *component = dai->component;
1912	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
1913	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1914	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1915	struct snd_soc_dapm_route routes[2];
1916
1917	switch (clk_id) {
1918	case ARIZONA_CLK_SYSCLK:
1919	case ARIZONA_CLK_ASYNCCLK:
1920		break;
1921	default:
1922		return -EINVAL;
1923	}
1924
1925	if (clk_id == dai_priv->clk)
1926		return 0;
1927
1928	if (snd_soc_dai_active(dai)) {
1929		dev_err(component->dev, "Can't change clock on active DAI %d\n",
1930			dai->id);
1931		return -EBUSY;
1932	}
1933
1934	dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
1935		arizona_dai_clk_str(clk_id));
1936
1937	memset(&routes, 0, sizeof(routes));
1938	routes[0].sink = dai->driver->capture.stream_name;
1939	routes[1].sink = dai->driver->playback.stream_name;
1940
1941	routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1942	routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1943	snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1944
1945	routes[0].source = arizona_dai_clk_str(clk_id);
1946	routes[1].source = arizona_dai_clk_str(clk_id);
1947	snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1948
1949	dai_priv->clk = clk_id;
1950
1951	return snd_soc_dapm_sync(dapm);
1952}
1953
1954static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1955{
1956	struct snd_soc_component *component = dai->component;
1957	int base = dai->driver->base;
1958	unsigned int reg;
1959
1960	if (tristate)
1961		reg = ARIZONA_AIF1_TRI;
1962	else
1963		reg = 0;
1964
1965	return snd_soc_component_update_bits(component,
1966					     base + ARIZONA_AIF_RATE_CTRL,
1967					     ARIZONA_AIF1_TRI, reg);
1968}
1969
1970static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1971					 unsigned int base,
1972					 int channels, unsigned int mask)
1973{
1974	struct snd_soc_component *component = dai->component;
1975	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1976	struct arizona *arizona = priv->arizona;
1977	int slot, i;
1978
1979	for (i = 0; i < channels; ++i) {
1980		slot = ffs(mask) - 1;
1981		if (slot < 0)
1982			return;
1983
1984		regmap_write(arizona->regmap, base + i, slot);
1985
1986		mask &= ~(1 << slot);
1987	}
1988
1989	if (mask)
1990		arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1991}
1992
1993static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1994				unsigned int rx_mask, int slots, int slot_width)
1995{
1996	struct snd_soc_component *component = dai->component;
1997	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1998	struct arizona *arizona = priv->arizona;
1999	int base = dai->driver->base;
2000	int rx_max_chan = dai->driver->playback.channels_max;
2001	int tx_max_chan = dai->driver->capture.channels_max;
2002
2003	/* Only support TDM for the physical AIFs */
2004	if (dai->id > ARIZONA_MAX_AIF)
2005		return -ENOTSUPP;
2006
2007	if (slots == 0) {
2008		tx_mask = (1 << tx_max_chan) - 1;
2009		rx_mask = (1 << rx_max_chan) - 1;
2010	}
2011
2012	arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2013				     tx_max_chan, tx_mask);
2014	arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2015				     rx_max_chan, rx_mask);
2016
2017	arizona->tdm_width[dai->id - 1] = slot_width;
2018	arizona->tdm_slots[dai->id - 1] = slots;
2019
2020	return 0;
2021}
2022
2023const struct snd_soc_dai_ops arizona_dai_ops = {
2024	.startup = arizona_startup,
2025	.set_fmt = arizona_set_fmt,
2026	.set_tdm_slot = arizona_set_tdm_slot,
2027	.hw_params = arizona_hw_params,
2028	.set_sysclk = arizona_dai_set_sysclk,
2029	.set_tristate = arizona_set_tristate,
2030};
2031EXPORT_SYMBOL_GPL(arizona_dai_ops);
2032
2033const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2034	.startup = arizona_startup,
2035	.hw_params = arizona_hw_params_rate,
2036	.set_sysclk = arizona_dai_set_sysclk,
2037};
2038EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2039
2040int arizona_init_dai(struct arizona_priv *priv, int id)
2041{
2042	struct arizona_dai_priv *dai_priv = &priv->dai[id];
2043
2044	dai_priv->clk = ARIZONA_CLK_SYSCLK;
2045	dai_priv->constraint = arizona_constraint;
2046
2047	return 0;
2048}
2049EXPORT_SYMBOL_GPL(arizona_init_dai);
2050
2051static struct {
2052	unsigned int min;
2053	unsigned int max;
2054	u16 fratio;
2055	int ratio;
2056} fll_fratios[] = {
2057	{       0,    64000, 4, 16 },
2058	{   64000,   128000, 3,  8 },
2059	{  128000,   256000, 2,  4 },
2060	{  256000,  1000000, 1,  2 },
2061	{ 1000000, 13500000, 0,  1 },
2062};
2063
2064static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2065	13500000,
2066	 6144000,
2067	 6144000,
2068	 3072000,
2069	 3072000,
2070	 2822400,
2071	 2822400,
2072	 1536000,
2073	 1536000,
2074	 1536000,
2075	 1536000,
2076	 1536000,
2077	 1536000,
2078	 1536000,
2079	 1536000,
2080	  768000,
2081};
2082
2083static struct {
2084	unsigned int min;
2085	unsigned int max;
2086	u16 gain;
2087} fll_gains[] = {
2088	{       0,   256000, 0 },
2089	{  256000,  1000000, 2 },
2090	{ 1000000, 13500000, 4 },
2091};
2092
2093struct arizona_fll_cfg {
2094	int n;
2095	unsigned int theta;
2096	unsigned int lambda;
2097	int refdiv;
2098	int outdiv;
2099	int fratio;
2100	int gain;
2101};
2102
2103static int arizona_validate_fll(struct arizona_fll *fll,
2104				unsigned int Fref,
2105				unsigned int Fout)
2106{
2107	unsigned int Fvco_min;
2108
2109	if (fll->fout && Fout != fll->fout) {
2110		arizona_fll_err(fll,
2111				"Can't change output on active FLL\n");
2112		return -EINVAL;
2113	}
2114
2115	if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2116		arizona_fll_err(fll,
2117				"Can't scale %dMHz in to <=13.5MHz\n",
2118				Fref);
2119		return -EINVAL;
2120	}
2121
2122	Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2123	if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2124		arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2125				Fout);
2126		return -EINVAL;
2127	}
2128
2129	return 0;
2130}
2131
2132static int arizona_find_fratio(unsigned int Fref, int *fratio)
2133{
2134	int i;
2135
2136	/* Find an appropriate FLL_FRATIO */
2137	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2138		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2139			if (fratio)
2140				*fratio = fll_fratios[i].fratio;
2141			return fll_fratios[i].ratio;
2142		}
2143	}
2144
2145	return -EINVAL;
2146}
2147
2148static int arizona_calc_fratio(struct arizona_fll *fll,
2149			       struct arizona_fll_cfg *cfg,
2150			       unsigned int target,
2151			       unsigned int Fref, bool sync)
2152{
2153	int init_ratio, ratio;
2154	int refdiv, div;
2155
2156	/* Fref must be <=13.5MHz, find initial refdiv */
2157	div = 1;
2158	cfg->refdiv = 0;
2159	while (Fref > ARIZONA_FLL_MAX_FREF) {
2160		div *= 2;
2161		Fref /= 2;
2162		cfg->refdiv++;
2163
2164		if (div > ARIZONA_FLL_MAX_REFDIV)
2165			return -EINVAL;
2166	}
2167
2168	/* Find an appropriate FLL_FRATIO */
2169	init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2170	if (init_ratio < 0) {
2171		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2172				Fref);
2173		return init_ratio;
2174	}
2175
2176	switch (fll->arizona->type) {
2177	case WM5102:
2178	case WM8997:
2179		return init_ratio;
2180	case WM5110:
2181	case WM8280:
2182		if (fll->arizona->rev < 3 || sync)
2183			return init_ratio;
2184		break;
2185	default:
2186		if (sync)
2187			return init_ratio;
2188		break;
2189	}
2190
2191	cfg->fratio = init_ratio - 1;
2192
2193	/* Adjust FRATIO/refdiv to avoid integer mode if possible */
2194	refdiv = cfg->refdiv;
2195
2196	arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2197			init_ratio, Fref, refdiv);
2198
2199	while (div <= ARIZONA_FLL_MAX_REFDIV) {
2200		/* start from init_ratio because this may already give a
2201		 * fractional N.K
2202		 */
2203		for (ratio = init_ratio; ratio > 0; ratio--) {
2204			if (target % (ratio * Fref)) {
2205				cfg->refdiv = refdiv;
2206				cfg->fratio = ratio - 1;
2207				arizona_fll_dbg(fll,
2208					"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2209					Fref, refdiv, div, ratio);
2210				return ratio;
2211			}
2212		}
2213
2214		for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2215		     ratio++) {
2216			if ((ARIZONA_FLL_VCO_CORNER / 2) /
2217			    (fll->vco_mult * ratio) < Fref) {
2218				arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2219				break;
2220			}
2221
2222			if (Fref > pseudo_fref_max[ratio - 1]) {
2223				arizona_fll_dbg(fll,
2224					"pseudo: exceeded max fref(%u) for ratio=%u\n",
2225					pseudo_fref_max[ratio - 1],
2226					ratio);
2227				break;
2228			}
2229
2230			if (target % (ratio * Fref)) {
2231				cfg->refdiv = refdiv;
2232				cfg->fratio = ratio - 1;
2233				arizona_fll_dbg(fll,
2234					"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2235					Fref, refdiv, div, ratio);
2236				return ratio;
2237			}
2238		}
2239
2240		div *= 2;
2241		Fref /= 2;
2242		refdiv++;
2243		init_ratio = arizona_find_fratio(Fref, NULL);
2244		arizona_fll_dbg(fll,
2245				"pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2246				Fref, refdiv, div, init_ratio);
2247	}
2248
2249	arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2250	return cfg->fratio + 1;
2251}
2252
2253static int arizona_calc_fll(struct arizona_fll *fll,
2254			    struct arizona_fll_cfg *cfg,
2255			    unsigned int Fref, bool sync)
2256{
2257	unsigned int target, div, gcd_fll;
2258	int i, ratio;
2259
2260	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2261
2262	/* Fvco should be over the targt; don't check the upper bound */
2263	div = ARIZONA_FLL_MIN_OUTDIV;
2264	while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2265		div++;
2266		if (div > ARIZONA_FLL_MAX_OUTDIV)
2267			return -EINVAL;
2268	}
2269	target = fll->fout * div / fll->vco_mult;
2270	cfg->outdiv = div;
2271
2272	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2273
2274	/* Find an appropriate FLL_FRATIO and refdiv */
2275	ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2276	if (ratio < 0)
2277		return ratio;
2278
2279	/* Apply the division for our remaining calculations */
2280	Fref = Fref / (1 << cfg->refdiv);
2281
2282	cfg->n = target / (ratio * Fref);
2283
2284	if (target % (ratio * Fref)) {
2285		gcd_fll = gcd(target, ratio * Fref);
2286		arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2287
2288		cfg->theta = (target - (cfg->n * ratio * Fref))
2289			/ gcd_fll;
2290		cfg->lambda = (ratio * Fref) / gcd_fll;
2291	} else {
2292		cfg->theta = 0;
2293		cfg->lambda = 0;
2294	}
2295
2296	/* Round down to 16bit range with cost of accuracy lost.
2297	 * Denominator must be bigger than numerator so we only
2298	 * take care of it.
2299	 */
2300	while (cfg->lambda >= (1 << 16)) {
2301		cfg->theta >>= 1;
2302		cfg->lambda >>= 1;
2303	}
2304
2305	for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2306		if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2307			cfg->gain = fll_gains[i].gain;
2308			break;
2309		}
2310	}
2311	if (i == ARRAY_SIZE(fll_gains)) {
2312		arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2313				Fref);
2314		return -EINVAL;
2315	}
2316
2317	arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2318			cfg->n, cfg->theta, cfg->lambda);
2319	arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2320			cfg->fratio, ratio, cfg->outdiv,
2321			cfg->refdiv, 1 << cfg->refdiv);
2322	arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2323
2324	return 0;
2325}
2326
2327static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2328			      struct arizona_fll_cfg *cfg, int source,
2329			      bool sync)
2330{
2331	regmap_update_bits_async(arizona->regmap, base + 3,
2332				 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2333	regmap_update_bits_async(arizona->regmap, base + 4,
2334				 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2335	regmap_update_bits_async(arizona->regmap, base + 5,
2336				 ARIZONA_FLL1_FRATIO_MASK,
2337				 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2338	regmap_update_bits_async(arizona->regmap, base + 6,
2339				 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2340				 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2341				 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2342				 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2343
2344	if (sync) {
2345		regmap_update_bits(arizona->regmap, base + 0x7,
2346				   ARIZONA_FLL1_GAIN_MASK,
2347				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2348	} else {
2349		regmap_update_bits(arizona->regmap, base + 0x5,
2350				   ARIZONA_FLL1_OUTDIV_MASK,
2351				   cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2352		regmap_update_bits(arizona->regmap, base + 0x9,
2353				   ARIZONA_FLL1_GAIN_MASK,
2354				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2355	}
2356
2357	regmap_update_bits_async(arizona->regmap, base + 2,
2358				 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2359				 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2360}
2361
2362static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2363{
2364	struct arizona *arizona = fll->arizona;
2365	unsigned int reg;
2366	int ret;
2367
2368	ret = regmap_read(arizona->regmap, base + 1, &reg);
2369	if (ret != 0) {
2370		arizona_fll_err(fll, "Failed to read current state: %d\n",
2371				ret);
2372		return ret;
2373	}
2374
2375	return reg & ARIZONA_FLL1_ENA;
2376}
2377
2378static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2379{
2380	struct arizona *arizona = fll->arizona;
2381	unsigned int val;
2382	struct clk *clk;
2383	int ret;
2384
2385	ret = regmap_read(arizona->regmap, base + 6, &val);
2386	if (ret != 0) {
2387		arizona_fll_err(fll, "Failed to read current source: %d\n",
2388				ret);
2389		return ret;
2390	}
2391
2392	val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2393	val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2394
2395	switch (val) {
2396	case ARIZONA_FLL_SRC_MCLK1:
2397		clk = arizona->mclk[ARIZONA_MCLK1];
2398		break;
2399	case ARIZONA_FLL_SRC_MCLK2:
2400		clk = arizona->mclk[ARIZONA_MCLK2];
2401		break;
2402	default:
2403		return 0;
2404	}
2405
2406	if (ena) {
2407		return clk_prepare_enable(clk);
2408	} else {
2409		clk_disable_unprepare(clk);
2410		return 0;
2411	}
2412}
2413
2414static int arizona_enable_fll(struct arizona_fll *fll)
2415{
2416	struct arizona *arizona = fll->arizona;
2417	bool use_sync = false;
2418	int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2419	int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2420	struct arizona_fll_cfg cfg;
2421	int i;
2422	unsigned int val;
2423
2424	if (already_enabled < 0)
2425		return already_enabled;
2426	if (sync_enabled < 0)
2427		return sync_enabled;
2428
2429	if (already_enabled) {
2430		/* Facilitate smooth refclk across the transition */
2431		regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2432				   ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2433		udelay(32);
2434		regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2435					 ARIZONA_FLL1_GAIN_MASK, 0);
2436
2437		if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2438			arizona_set_fll_clks(fll, fll->base + 0x10, false);
2439		arizona_set_fll_clks(fll, fll->base, false);
2440	}
2441
2442	/*
2443	 * If we have both REFCLK and SYNCCLK then enable both,
2444	 * otherwise apply the SYNCCLK settings to REFCLK.
2445	 */
2446	if (fll->ref_src >= 0 && fll->ref_freq &&
2447	    fll->ref_src != fll->sync_src) {
2448		arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2449
2450		/* Ref path hardcodes lambda to 65536 when sync is on */
2451		if (fll->sync_src >= 0 && cfg.lambda)
2452			cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2453
2454		arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2455				  false);
2456		if (fll->sync_src >= 0) {
2457			arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2458
2459			arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2460					  fll->sync_src, true);
2461			use_sync = true;
2462		}
2463	} else if (fll->sync_src >= 0) {
2464		arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2465
2466		arizona_apply_fll(arizona, fll->base, &cfg,
2467				  fll->sync_src, false);
2468
2469		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2470					 ARIZONA_FLL1_SYNC_ENA, 0);
2471	} else {
2472		arizona_fll_err(fll, "No clocks provided\n");
2473		return -EINVAL;
2474	}
2475
2476	if (already_enabled && !!sync_enabled != use_sync)
2477		arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2478
2479	/*
2480	 * Increase the bandwidth if we're not using a low frequency
2481	 * sync source.
2482	 */
2483	if (use_sync && fll->sync_freq > 100000)
2484		regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2485					 ARIZONA_FLL1_SYNC_BW, 0);
2486	else
2487		regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2488					 ARIZONA_FLL1_SYNC_BW,
2489					 ARIZONA_FLL1_SYNC_BW);
2490
2491	if (!already_enabled)
2492		pm_runtime_get_sync(arizona->dev);
2493
2494	if (use_sync) {
2495		arizona_set_fll_clks(fll, fll->base + 0x10, true);
2496		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2497					 ARIZONA_FLL1_SYNC_ENA,
2498					 ARIZONA_FLL1_SYNC_ENA);
2499	}
2500	arizona_set_fll_clks(fll, fll->base, true);
2501	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2502				 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2503
2504	if (already_enabled)
2505		regmap_update_bits_async(arizona->regmap, fll->base + 1,
2506					 ARIZONA_FLL1_FREERUN, 0);
2507
2508	arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2509	val = 0;
2510	for (i = 0; i < 15; i++) {
2511		if (i < 5)
2512			usleep_range(200, 400);
2513		else
2514			msleep(20);
2515
2516		regmap_read(arizona->regmap,
2517			    ARIZONA_INTERRUPT_RAW_STATUS_5,
2518			    &val);
2519		if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2520			break;
2521	}
2522	if (i == 15)
2523		arizona_fll_warn(fll, "Timed out waiting for lock\n");
2524	else
2525		arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2526
2527	return 0;
2528}
2529
2530static void arizona_disable_fll(struct arizona_fll *fll)
2531{
2532	struct arizona *arizona = fll->arizona;
2533	bool ref_change, sync_change;
2534
2535	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2536				 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2537	regmap_update_bits_check(arizona->regmap, fll->base + 1,
2538				 ARIZONA_FLL1_ENA, 0, &ref_change);
2539	regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2540				 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2541	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2542				 ARIZONA_FLL1_FREERUN, 0);
2543
2544	if (sync_change)
2545		arizona_set_fll_clks(fll, fll->base + 0x10, false);
2546
2547	if (ref_change) {
2548		arizona_set_fll_clks(fll, fll->base, false);
2549		pm_runtime_put_autosuspend(arizona->dev);
2550	}
2551}
2552
2553int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2554			   unsigned int Fref, unsigned int Fout)
2555{
2556	int ret = 0;
2557
2558	if (fll->ref_src == source && fll->ref_freq == Fref)
2559		return 0;
2560
2561	if (fll->fout && Fref > 0) {
2562		ret = arizona_validate_fll(fll, Fref, fll->fout);
2563		if (ret != 0)
2564			return ret;
2565	}
2566
2567	fll->ref_src = source;
2568	fll->ref_freq = Fref;
2569
2570	if (fll->fout && Fref > 0)
2571		ret = arizona_enable_fll(fll);
2572
2573	return ret;
2574}
2575EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2576
2577int arizona_set_fll(struct arizona_fll *fll, int source,
2578		    unsigned int Fref, unsigned int Fout)
2579{
2580	int ret = 0;
2581
2582	if (fll->sync_src == source &&
2583	    fll->sync_freq == Fref && fll->fout == Fout)
2584		return 0;
2585
2586	if (Fout) {
2587		if (fll->ref_src >= 0) {
2588			ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2589			if (ret != 0)
2590				return ret;
2591		}
2592
2593		ret = arizona_validate_fll(fll, Fref, Fout);
2594		if (ret != 0)
2595			return ret;
2596	}
2597
2598	fll->sync_src = source;
2599	fll->sync_freq = Fref;
2600	fll->fout = Fout;
2601
2602	if (Fout)
2603		ret = arizona_enable_fll(fll);
2604	else
2605		arizona_disable_fll(fll);
2606
2607	return ret;
2608}
2609EXPORT_SYMBOL_GPL(arizona_set_fll);
2610
2611int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2612		     int ok_irq, struct arizona_fll *fll)
2613{
2614	unsigned int val;
2615
2616	fll->id = id;
2617	fll->base = base;
2618	fll->arizona = arizona;
2619	fll->sync_src = ARIZONA_FLL_SRC_NONE;
2620
2621	/* Configure default refclk to 32kHz if we have one */
2622	regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2623	switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2624	case ARIZONA_CLK_SRC_MCLK1:
2625	case ARIZONA_CLK_SRC_MCLK2:
2626		fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2627		break;
2628	default:
2629		fll->ref_src = ARIZONA_FLL_SRC_NONE;
2630	}
2631	fll->ref_freq = 32768;
2632
2633	snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2634	snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2635		 "FLL%d clock OK", id);
2636
2637	regmap_update_bits(arizona->regmap, fll->base + 1,
2638			   ARIZONA_FLL1_FREERUN, 0);
2639
2640	return 0;
2641}
2642EXPORT_SYMBOL_GPL(arizona_init_fll);
2643
2644/**
2645 * arizona_set_output_mode - Set the mode of the specified output
2646 *
2647 * @component: Device to configure
2648 * @output: Output number
2649 * @diff: True to set the output to differential mode
2650 *
2651 * Some systems use external analogue switches to connect more
2652 * analogue devices to the CODEC than are supported by the device.  In
2653 * some systems this requires changing the switched output from single
2654 * ended to differential mode dynamically at runtime, an operation
2655 * supported using this function.
2656 *
2657 * Most systems have a single static configuration and should use
2658 * platform data instead.
2659 */
2660int arizona_set_output_mode(struct snd_soc_component *component, int output,
2661			    bool diff)
2662{
2663	unsigned int reg, val;
2664
2665	if (output < 1 || output > 6)
2666		return -EINVAL;
2667
2668	reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2669
2670	if (diff)
2671		val = ARIZONA_OUT1_MONO;
2672	else
2673		val = 0;
2674
2675	return snd_soc_component_update_bits(component, reg,
2676					     ARIZONA_OUT1_MONO, val);
2677}
2678EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2679
2680static const struct soc_enum arizona_adsp2_rate_enum[] = {
2681	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2682			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2683			      ARIZONA_RATE_ENUM_SIZE,
2684			      arizona_rate_text, arizona_rate_val),
2685	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2686			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2687			      ARIZONA_RATE_ENUM_SIZE,
2688			      arizona_rate_text, arizona_rate_val),
2689	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2690			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2691			      ARIZONA_RATE_ENUM_SIZE,
2692			      arizona_rate_text, arizona_rate_val),
2693	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2694			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2695			      ARIZONA_RATE_ENUM_SIZE,
2696			      arizona_rate_text, arizona_rate_val),
2697};
2698
2699const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2700	SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2701	SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2702	SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2703	SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2704};
2705EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2706
2707static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2708{
2709	s16 a = be16_to_cpu(_a);
2710	s16 b = be16_to_cpu(_b);
2711
2712	if (!mode) {
2713		return abs(a) >= 4096;
2714	} else {
2715		if (abs(b) >= 4096)
2716			return true;
2717
2718		return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2719	}
2720}
2721
2722int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2723			 struct snd_ctl_elem_value *ucontrol)
2724{
2725	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
2726	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2727	struct soc_bytes *params = (void *)kcontrol->private_value;
2728	unsigned int val;
2729	__be16 *data;
2730	int len;
2731	int ret;
2732
2733	len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2734
2735	data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2736	if (!data)
2737		return -ENOMEM;
2738
2739	data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2740
2741	if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2742	    arizona_eq_filter_unstable(true, data[4], data[5]) ||
2743	    arizona_eq_filter_unstable(true, data[8], data[9]) ||
2744	    arizona_eq_filter_unstable(true, data[12], data[13]) ||
2745	    arizona_eq_filter_unstable(false, data[16], data[17])) {
2746		dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2747		ret = -EINVAL;
2748		goto out;
2749	}
2750
2751	ret = regmap_read(arizona->regmap, params->base, &val);
2752	if (ret != 0)
2753		goto out;
2754
2755	val &= ~ARIZONA_EQ1_B1_MODE;
2756	data[0] |= cpu_to_be16(val);
2757
2758	ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2759
2760out:
2761	kfree(data);
2762	return ret;
2763}
2764EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2765
2766int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2767			   struct snd_ctl_elem_value *ucontrol)
2768{
2769	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
2770	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2771	__be16 *data = (__be16 *)ucontrol->value.bytes.data;
2772	s16 val = be16_to_cpu(*data);
2773
2774	if (abs(val) >= 4096) {
2775		dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2776		return -EINVAL;
2777	}
2778
2779	return snd_soc_bytes_put(kcontrol, ucontrol);
2780}
2781EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2782
2783int arizona_of_get_audio_pdata(struct arizona *arizona)
2784{
2785	struct arizona_pdata *pdata = &arizona->pdata;
2786	struct device_node *np = arizona->dev->of_node;
2787	u32 val;
2788	u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2789	int ret;
2790	int count = 0;
2791
2792	count = 0;
2793	of_property_for_each_u32(np, "wlf,inmode", val) {
2794		if (count == ARRAY_SIZE(pdata->inmode))
2795			break;
2796
2797		pdata->inmode[count] = val;
2798		count++;
2799	}
2800
2801	count = 0;
2802	of_property_for_each_u32(np, "wlf,dmic-ref", val) {
2803		if (count == ARRAY_SIZE(pdata->dmic_ref))
2804			break;
2805
2806		pdata->dmic_ref[count] = val;
2807		count++;
2808	}
2809
2810	count = 0;
2811	of_property_for_each_u32(np, "wlf,out-mono", val) {
2812		if (count == ARRAY_SIZE(pdata->out_mono))
2813			break;
2814
2815		pdata->out_mono[count] = !!val;
2816		count++;
2817	}
2818
2819	count = 0;
2820	of_property_for_each_u32(np, "wlf,max-channels-clocked", val) {
2821		if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2822			break;
2823
2824		pdata->max_channels_clocked[count] = val;
2825		count++;
2826	}
2827
2828	count = 0;
2829	of_property_for_each_u32(np, "wlf,out-volume-limit", val) {
2830		if (count == ARRAY_SIZE(pdata->out_vol_limit))
2831			break;
2832
2833		pdata->out_vol_limit[count] = val;
2834		count++;
2835	}
2836
2837	ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2838					 pdm_val, ARRAY_SIZE(pdm_val));
2839
2840	if (ret >= 0)
2841		for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2842			pdata->spk_fmt[count] = pdm_val[count];
2843
2844	ret = of_property_read_u32_array(np, "wlf,spk-mute",
2845					 pdm_val, ARRAY_SIZE(pdm_val));
2846
2847	if (ret >= 0)
2848		for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2849			pdata->spk_mute[count] = pdm_val[count];
2850
2851	return 0;
2852}
2853EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2854
2855MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2856MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2857MODULE_LICENSE("GPL");
~/ Read-only file preview.