Linux Audio

Check our new training course

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