Linux Audio

Check our new training course

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