File Index
Files and directories
Sign in
FILE

cs42l56.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/cs42l56.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * cs42l56.c -- CS42L56 ALSA SoC audio driver
   4 *
   5 * Copyright 2014 CirrusLogic, Inc.
   6 *
   7 * Author: Brian Austin <brian.austin@cirrus.com>
   8 */
   9
  10#include <linux/delay.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/i2c.h>
  13#include <linux/init.h>
  14#include <linux/input.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/moduleparam.h>
  18#include <linux/of.h>
  19#include <linux/platform_device.h>
  20#include <linux/pm.h>
  21#include <linux/regmap.h>
  22#include <linux/regulator/consumer.h>
  23#include <linux/slab.h>
  24#include <linux/workqueue.h>
  25#include <sound/core.h>
  26#include <sound/initval.h>
  27#include <sound/pcm.h>
  28#include <sound/pcm_params.h>
  29#include <sound/soc.h>
  30#include <sound/soc-dapm.h>
  31#include <sound/tlv.h>
  32#include "cs42l56.h"
  33
  34#define CS42L56_NUM_SUPPLIES 3
  35
  36struct cs42l56_platform_data {
  37	/* GPIO for Reset */
  38	struct gpio_desc *gpio_nreset;
  39
  40	/* MICBIAS Level. Check datasheet Pg48 */
  41	unsigned int micbias_lvl;
  42
  43	/* Analog Input 1A Reference 0=Single 1=Pseudo-Differential */
  44	unsigned int ain1a_ref_cfg;
  45
  46	/* Analog Input 2A Reference 0=Single 1=Pseudo-Differential */
  47	unsigned int ain2a_ref_cfg;
  48
  49	/* Analog Input 1B Reference 0=Single 1=Pseudo-Differential */
  50	unsigned int ain1b_ref_cfg;
  51
  52	/* Analog Input 2B Reference 0=Single 1=Pseudo-Differential */
  53	unsigned int ain2b_ref_cfg;
  54
  55	/* Charge Pump Freq. Check datasheet Pg62 */
  56	unsigned int chgfreq;
  57
  58	/* HighPass Filter Right Channel Corner Frequency */
  59	unsigned int hpfb_freq;
  60
  61	/* HighPass Filter Left Channel Corner Frequency */
  62	unsigned int hpfa_freq;
  63
  64	/* Adaptive Power Control for LO/HP */
  65	unsigned int adaptive_pwr;
  66};
  67
  68static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
  69	"VA",
  70	"VCP",
  71	"VLDO",
  72};
  73
  74struct  cs42l56_private {
  75	struct regmap *regmap;
  76	struct snd_soc_component *component;
  77	struct device *dev;
  78	struct cs42l56_platform_data pdata;
  79	struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES];
  80	u32 mclk;
  81	u8 mclk_prediv;
  82	u8 mclk_div2;
  83	u8 mclk_ratio;
  84	u8 iface;
  85	u8 iface_fmt;
  86	u8 iface_inv;
  87#if IS_ENABLED(CONFIG_INPUT)
  88	struct input_dev *beep;
  89	struct work_struct beep_work;
  90	int beep_rate;
  91#endif
  92};
  93
  94static const struct reg_default cs42l56_reg_defaults[] = {
  95	{ 3, 0x7f },	/* r03	- Power Ctl 1 */
  96	{ 4, 0xff },	/* r04	- Power Ctl 2 */
  97	{ 5, 0x00 },	/* ro5	- Clocking Ctl 1 */
  98	{ 6, 0x0b },	/* r06	- Clocking Ctl 2 */
  99	{ 7, 0x00 },	/* r07	- Serial Format */
 100	{ 8, 0x05 },	/* r08	- Class H Ctl */
 101	{ 9, 0x0c },	/* r09	- Misc Ctl */
 102	{ 10, 0x80 },	/* r0a	- INT Status */
 103	{ 11, 0x00 },	/* r0b	- Playback Ctl */
 104	{ 12, 0x0c },	/* r0c	- DSP Mute Ctl */
 105	{ 13, 0x00 },	/* r0d	- ADCA Mixer Volume */
 106	{ 14, 0x00 },	/* r0e	- ADCB Mixer Volume */
 107	{ 15, 0x00 },	/* r0f	- PCMA Mixer Volume */
 108	{ 16, 0x00 },	/* r10	- PCMB Mixer Volume */
 109	{ 17, 0x00 },	/* r11	- Analog Input Advisory Volume */
 110	{ 18, 0x00 },	/* r12	- Digital Input Advisory Volume */
 111	{ 19, 0x00 },	/* r13	- Master A Volume */
 112	{ 20, 0x00 },	/* r14	- Master B Volume */
 113	{ 21, 0x00 },	/* r15	- Beep Freq / On Time */
 114	{ 22, 0x00 },	/* r16	- Beep Volume / Off Time */
 115	{ 23, 0x00 },	/* r17	- Beep Tone Ctl */
 116	{ 24, 0x88 },	/* r18	- Tone Ctl */
 117	{ 25, 0x00 },	/* r19	- Channel Mixer & Swap */
 118	{ 26, 0x00 },	/* r1a	- AIN Ref Config / ADC Mux */
 119	{ 27, 0xa0 },	/* r1b	- High-Pass Filter Ctl */
 120	{ 28, 0x00 },	/* r1c	- Misc ADC Ctl */
 121	{ 29, 0x00 },	/* r1d	- Gain & Bias Ctl */
 122	{ 30, 0x00 },	/* r1e	- PGAA Mux & Volume */
 123	{ 31, 0x00 },	/* r1f	- PGAB Mux & Volume */
 124	{ 32, 0x00 },	/* r20	- ADCA Attenuator */
 125	{ 33, 0x00 },	/* r21	- ADCB Attenuator */
 126	{ 34, 0x00 },	/* r22	- ALC Enable & Attack Rate */
 127	{ 35, 0xbf },	/* r23	- ALC Release Rate */
 128	{ 36, 0x00 },	/* r24	- ALC Threshold */
 129	{ 37, 0x00 },	/* r25	- Noise Gate Ctl */
 130	{ 38, 0x00 },	/* r26	- ALC, Limiter, SFT, ZeroCross */
 131	{ 39, 0x00 },	/* r27	- Analog Mute, LO & HP Mux */
 132	{ 40, 0x00 },	/* r28	- HP A Volume */
 133	{ 41, 0x00 },	/* r29	- HP B Volume */
 134	{ 42, 0x00 },	/* r2a	- LINEOUT A Volume */
 135	{ 43, 0x00 },	/* r2b	- LINEOUT B Volume */
 136	{ 44, 0x00 },	/* r2c	- Limit Threshold Ctl */
 137	{ 45, 0x7f },	/* r2d	- Limiter Ctl & Release Rate */
 138	{ 46, 0x00 },	/* r2e	- Limiter Attack Rate */
 139};
 140
 141static bool cs42l56_readable_register(struct device *dev, unsigned int reg)
 142{
 143	switch (reg) {
 144	case CS42L56_CHIP_ID_1 ... CS42L56_LIM_ATTACK_RATE:
 145		return true;
 146	default:
 147		return false;
 148	}
 149}
 150
 151static bool cs42l56_volatile_register(struct device *dev, unsigned int reg)
 152{
 153	switch (reg) {
 154	case CS42L56_INT_STATUS:
 155		return true;
 156	default:
 157		return false;
 158	}
 159}
 160
 161static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0);
 162static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0);
 163static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0);
 164static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0);
 165static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
 166static DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0);
 167static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
 168
 169static const DECLARE_TLV_DB_RANGE(ngnb_tlv,
 170	0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0),
 171	2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0)
 172);
 173static const DECLARE_TLV_DB_RANGE(ngb_tlv,
 174	0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0),
 175	3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0)
 176);
 177static const DECLARE_TLV_DB_RANGE(alc_tlv,
 178	0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
 179	3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
 180);
 181
 182static const char * const beep_config_text[] = {
 183	"Off", "Single", "Multiple", "Continuous"
 184};
 185
 186static const struct soc_enum beep_config_enum =
 187	SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 6,
 188			ARRAY_SIZE(beep_config_text), beep_config_text);
 189
 190static const char * const beep_pitch_text[] = {
 191	"C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
 192	"C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
 193};
 194
 195static const struct soc_enum beep_pitch_enum =
 196	SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 4,
 197			ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
 198
 199static const char * const beep_ontime_text[] = {
 200	"86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
 201	"1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
 202	"3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
 203};
 204
 205static const struct soc_enum beep_ontime_enum =
 206	SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 0,
 207			ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
 208
 209static const char * const beep_offtime_text[] = {
 210	"1.23 s", "2.58 s", "3.90 s", "5.20 s",
 211	"6.60 s", "8.05 s", "9.35 s", "10.80 s"
 212};
 213
 214static const struct soc_enum beep_offtime_enum =
 215	SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_OFFTIME, 5,
 216			ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
 217
 218static const char * const beep_treble_text[] = {
 219	"5kHz", "7kHz", "10kHz", "15kHz"
 220};
 221
 222static const struct soc_enum beep_treble_enum =
 223	SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 3,
 224			ARRAY_SIZE(beep_treble_text), beep_treble_text);
 225
 226static const char * const beep_bass_text[] = {
 227	"50Hz", "100Hz", "200Hz", "250Hz"
 228};
 229
 230static const struct soc_enum beep_bass_enum =
 231	SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1,
 232			ARRAY_SIZE(beep_bass_text), beep_bass_text);
 233
 234static const char * const pgaa_mux_text[] = {
 235	"AIN1A", "AIN2A", "AIN3A"};
 236
 237static const struct soc_enum pgaa_mux_enum =
 238	SOC_ENUM_SINGLE(CS42L56_PGAA_MUX_VOLUME, 0,
 239			      ARRAY_SIZE(pgaa_mux_text),
 240			      pgaa_mux_text);
 241
 242static const struct snd_kcontrol_new pgaa_mux =
 243	SOC_DAPM_ENUM("Route", pgaa_mux_enum);
 244
 245static const char * const pgab_mux_text[] = {
 246	"AIN1B", "AIN2B", "AIN3B"};
 247
 248static const struct soc_enum pgab_mux_enum =
 249	SOC_ENUM_SINGLE(CS42L56_PGAB_MUX_VOLUME, 0,
 250			      ARRAY_SIZE(pgab_mux_text),
 251			      pgab_mux_text);
 252
 253static const struct snd_kcontrol_new pgab_mux =
 254	SOC_DAPM_ENUM("Route", pgab_mux_enum);
 255
 256static const char * const adca_mux_text[] = {
 257	"PGAA", "AIN1A", "AIN2A", "AIN3A"};
 258
 259static const struct soc_enum adca_mux_enum =
 260	SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 0,
 261			      ARRAY_SIZE(adca_mux_text),
 262			      adca_mux_text);
 263
 264static const struct snd_kcontrol_new adca_mux =
 265	SOC_DAPM_ENUM("Route", adca_mux_enum);
 266
 267static const char * const adcb_mux_text[] = {
 268	"PGAB", "AIN1B", "AIN2B", "AIN3B"};
 269
 270static const struct soc_enum adcb_mux_enum =
 271	SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 2,
 272			      ARRAY_SIZE(adcb_mux_text),
 273			      adcb_mux_text);
 274
 275static const struct snd_kcontrol_new adcb_mux =
 276	SOC_DAPM_ENUM("Route", adcb_mux_enum);
 277
 278static const char * const left_swap_text[] = {
 279	"Left", "LR 2", "Right"};
 280
 281static const char * const right_swap_text[] = {
 282	"Right", "LR 2", "Left"};
 283
 284static const unsigned int swap_values[] = { 0, 1, 3 };
 285
 286static const struct soc_enum adca_swap_enum =
 287	SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 0, 3,
 288			      ARRAY_SIZE(left_swap_text),
 289			      left_swap_text,
 290			      swap_values);
 291static const struct snd_kcontrol_new adca_swap_mux =
 292	SOC_DAPM_ENUM("Route", adca_swap_enum);
 293
 294static const struct soc_enum pcma_swap_enum =
 295	SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3,
 296			      ARRAY_SIZE(left_swap_text),
 297			      left_swap_text,
 298			      swap_values);
 299static const struct snd_kcontrol_new pcma_swap_mux =
 300	SOC_DAPM_ENUM("Route", pcma_swap_enum);
 301
 302static const struct soc_enum adcb_swap_enum =
 303	SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3,
 304			      ARRAY_SIZE(right_swap_text),
 305			      right_swap_text,
 306			      swap_values);
 307static const struct snd_kcontrol_new adcb_swap_mux =
 308	SOC_DAPM_ENUM("Route", adcb_swap_enum);
 309
 310static const struct soc_enum pcmb_swap_enum =
 311	SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3,
 312			      ARRAY_SIZE(right_swap_text),
 313			      right_swap_text,
 314			      swap_values);
 315static const struct snd_kcontrol_new pcmb_swap_mux =
 316	SOC_DAPM_ENUM("Route", pcmb_swap_enum);
 317
 318static const struct snd_kcontrol_new hpa_switch =
 319	SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1);
 320
 321static const struct snd_kcontrol_new hpb_switch =
 322	SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1);
 323
 324static const struct snd_kcontrol_new loa_switch =
 325	SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1);
 326
 327static const struct snd_kcontrol_new lob_switch =
 328	SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1);
 329
 330static const char * const hploa_input_text[] = {
 331	"DACA", "PGAA"};
 332
 333static const struct soc_enum lineouta_input_enum =
 334	SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 2,
 335			      ARRAY_SIZE(hploa_input_text),
 336			      hploa_input_text);
 337
 338static const struct snd_kcontrol_new lineouta_input =
 339	SOC_DAPM_ENUM("Route", lineouta_input_enum);
 340
 341static const struct soc_enum hpa_input_enum =
 342	SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 0,
 343			      ARRAY_SIZE(hploa_input_text),
 344			      hploa_input_text);
 345
 346static const struct snd_kcontrol_new hpa_input =
 347	SOC_DAPM_ENUM("Route", hpa_input_enum);
 348
 349static const char * const hplob_input_text[] = {
 350	"DACB", "PGAB"};
 351
 352static const struct soc_enum lineoutb_input_enum =
 353	SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 3,
 354			      ARRAY_SIZE(hplob_input_text),
 355			      hplob_input_text);
 356
 357static const struct snd_kcontrol_new lineoutb_input =
 358	SOC_DAPM_ENUM("Route", lineoutb_input_enum);
 359
 360static const struct soc_enum hpb_input_enum =
 361	SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 1,
 362			      ARRAY_SIZE(hplob_input_text),
 363			      hplob_input_text);
 364
 365static const struct snd_kcontrol_new hpb_input =
 366	SOC_DAPM_ENUM("Route", hpb_input_enum);
 367
 368static const char * const dig_mux_text[] = {
 369	"ADC", "DSP"};
 370
 371static const struct soc_enum dig_mux_enum =
 372	SOC_ENUM_SINGLE(CS42L56_MISC_CTL, 7,
 373			      ARRAY_SIZE(dig_mux_text),
 374			      dig_mux_text);
 375
 376static const struct snd_kcontrol_new dig_mux =
 377	SOC_DAPM_ENUM("Route", dig_mux_enum);
 378
 379static const char * const hpf_freq_text[] = {
 380	"1.8Hz", "119Hz", "236Hz", "464Hz"
 381};
 382
 383static const struct soc_enum hpfa_freq_enum =
 384	SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0,
 385			ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
 386
 387static const struct soc_enum hpfb_freq_enum =
 388	SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2,
 389			ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
 390
 391static const char * const ng_delay_text[] = {
 392	"50ms", "100ms", "150ms", "200ms"
 393};
 394
 395static const struct soc_enum ng_delay_enum =
 396	SOC_ENUM_SINGLE(CS42L56_NOISE_GATE_CTL, 0,
 397			ARRAY_SIZE(ng_delay_text), ng_delay_text);
 398
 399static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
 400
 401	SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME,
 402			      CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xE4, adv_tlv),
 403	SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1),
 404
 405	SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME,
 406			      CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
 407	SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1),
 408
 409	SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME,
 410			      CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
 411	SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1),
 412
 413	SOC_SINGLE_TLV("Analog Advisory Volume",
 414			  CS42L56_ANAINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
 415	SOC_SINGLE_TLV("Digital Advisory Volume",
 416			  CS42L56_DIGINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
 417
 418	SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME,
 419			      CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0x24, pga_tlv),
 420	SOC_DOUBLE_R_TLV("ADC Volume", CS42L56_ADCA_ATTENUATOR,
 421			      CS42L56_ADCB_ATTENUATOR, 0, 0x00, 1, adc_tlv),
 422	SOC_DOUBLE("ADC Mute Switch", CS42L56_MISC_ADC_CTL, 2, 3, 1, 1),
 423	SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
 424
 425	SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
 426			      CS42L56_HPB_VOLUME, 0, 0x44, 0x48, hl_tlv),
 427	SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
 428			      CS42L56_LOB_VOLUME, 0, 0x44, 0x48, hl_tlv),
 429
 430	SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
 431			0, 0x00, 1, tone_tlv),
 432	SOC_SINGLE_TLV("Treble Shelving Volume", CS42L56_TONE_CTL,
 433			4, 0x00, 1, tone_tlv),
 434
 435	SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL,
 436			4, 6, 0x02, 1, preamp_tlv),
 437
 438	SOC_SINGLE("DSP Switch", CS42L56_PLAYBACK_CTL, 7, 1, 1),
 439	SOC_SINGLE("Gang Playback Switch", CS42L56_PLAYBACK_CTL, 4, 1, 1),
 440	SOC_SINGLE("Gang ADC Switch", CS42L56_MISC_ADC_CTL, 7, 1, 1),
 441	SOC_SINGLE("Gang PGA Switch", CS42L56_MISC_ADC_CTL, 6, 1, 1),
 442
 443	SOC_SINGLE("PCMA Invert", CS42L56_PLAYBACK_CTL, 2, 1, 1),
 444	SOC_SINGLE("PCMB Invert", CS42L56_PLAYBACK_CTL, 3, 1, 1),
 445	SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1),
 446	SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1),
 447
 448	SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1),
 449	SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1),
 450	SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum),
 451	SOC_ENUM("HPFB Corner Freq", hpfb_freq_enum),
 452
 453	SOC_SINGLE("Analog Soft Ramp", CS42L56_MISC_CTL, 4, 1, 1),
 454	SOC_DOUBLE("Analog Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
 455		7, 5, 1, 1),
 456	SOC_SINGLE("Analog Zero Cross", CS42L56_MISC_CTL, 3, 1, 1),
 457	SOC_DOUBLE("Analog Zero Cross Disable", CS42L56_ALC_LIM_SFT_ZC,
 458		6, 4, 1, 1),
 459	SOC_SINGLE("Digital Soft Ramp", CS42L56_MISC_CTL, 2, 1, 1),
 460	SOC_SINGLE("Digital Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
 461		3, 1, 1),
 462
 463	SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1),
 464
 465	SOC_SINGLE("ALC Switch", CS42L56_ALC_EN_ATTACK_RATE, 6, 1, 1),
 466	SOC_SINGLE("ALC Limit All Switch", CS42L56_ALC_RELEASE_RATE, 7, 1, 1),
 467	SOC_SINGLE_RANGE("ALC Attack", CS42L56_ALC_EN_ATTACK_RATE,
 468			0, 0, 0x3f, 0),
 469	SOC_SINGLE_RANGE("ALC Release", CS42L56_ALC_RELEASE_RATE,
 470			0, 0x3f, 0, 0),
 471	SOC_SINGLE_TLV("ALC MAX", CS42L56_ALC_THRESHOLD,
 472			5, 0x07, 1, alc_tlv),
 473	SOC_SINGLE_TLV("ALC MIN", CS42L56_ALC_THRESHOLD,
 474			2, 0x07, 1, alc_tlv),
 475
 476	SOC_SINGLE("Limiter Switch", CS42L56_LIM_CTL_RELEASE_RATE, 7, 1, 1),
 477	SOC_SINGLE("Limit All Switch", CS42L56_LIM_CTL_RELEASE_RATE, 6, 1, 1),
 478	SOC_SINGLE_RANGE("Limiter Attack", CS42L56_LIM_ATTACK_RATE,
 479			0, 0, 0x3f, 0),
 480	SOC_SINGLE_RANGE("Limiter Release", CS42L56_LIM_CTL_RELEASE_RATE,
 481			0, 0x3f, 0, 0),
 482	SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL,
 483			5, 0x07, 1, alc_tlv),
 484	SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD,
 485			2, 0x07, 1, alc_tlv),
 486
 487	SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1),
 488	SOC_SINGLE("NG All Switch", CS42L56_NOISE_GATE_CTL, 7, 1, 1),
 489	SOC_SINGLE("NG Boost Switch", CS42L56_NOISE_GATE_CTL, 5, 1, 1),
 490	SOC_SINGLE_TLV("NG Unboost Threshold", CS42L56_NOISE_GATE_CTL,
 491			2, 0x07, 1, ngnb_tlv),
 492	SOC_SINGLE_TLV("NG Boost Threshold", CS42L56_NOISE_GATE_CTL,
 493			2, 0x07, 1, ngb_tlv),
 494	SOC_ENUM("NG Delay", ng_delay_enum),
 495
 496	SOC_ENUM("Beep Config", beep_config_enum),
 497	SOC_ENUM("Beep Pitch", beep_pitch_enum),
 498	SOC_ENUM("Beep on Time", beep_ontime_enum),
 499	SOC_ENUM("Beep off Time", beep_offtime_enum),
 500	SOC_SINGLE_SX_TLV("Beep Volume", CS42L56_BEEP_FREQ_OFFTIME,
 501			0, 0x07, 0x23, beep_tlv),
 502	SOC_SINGLE("Beep Tone Ctl Switch", CS42L56_BEEP_TONE_CFG, 0, 1, 1),
 503	SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
 504	SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
 505
 506};
 507
 508static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = {
 509
 510	SND_SOC_DAPM_SIGGEN("Beep"),
 511	SND_SOC_DAPM_SUPPLY("VBUF", CS42L56_PWRCTL_1, 5, 1, NULL, 0),
 512	SND_SOC_DAPM_MICBIAS("MIC1 Bias", CS42L56_PWRCTL_1, 4, 1),
 513	SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L56_PWRCTL_1, 3, 1, NULL, 0),
 514
 515	SND_SOC_DAPM_INPUT("AIN1A"),
 516	SND_SOC_DAPM_INPUT("AIN2A"),
 517	SND_SOC_DAPM_INPUT("AIN1B"),
 518	SND_SOC_DAPM_INPUT("AIN2B"),
 519	SND_SOC_DAPM_INPUT("AIN3A"),
 520	SND_SOC_DAPM_INPUT("AIN3B"),
 521
 522	SND_SOC_DAPM_AIF_OUT("SDOUT", NULL,  0,
 523			SND_SOC_NOPM, 0, 0),
 524
 525	SND_SOC_DAPM_AIF_IN("SDIN", NULL,  0,
 526			SND_SOC_NOPM, 0, 0),
 527
 528	SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM,
 529			 0, 0, &dig_mux),
 530
 531	SND_SOC_DAPM_PGA("PGAA", SND_SOC_NOPM, 0, 0, NULL, 0),
 532	SND_SOC_DAPM_PGA("PGAB", SND_SOC_NOPM, 0, 0, NULL, 0),
 533	SND_SOC_DAPM_MUX("PGAA Input Mux",
 534			SND_SOC_NOPM, 0, 0, &pgaa_mux),
 535	SND_SOC_DAPM_MUX("PGAB Input Mux",
 536			SND_SOC_NOPM, 0, 0, &pgab_mux),
 537
 538	SND_SOC_DAPM_MUX("ADCA Mux", SND_SOC_NOPM,
 539			 0, 0, &adca_mux),
 540	SND_SOC_DAPM_MUX("ADCB Mux", SND_SOC_NOPM,
 541			 0, 0, &adcb_mux),
 542
 543	SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1),
 544	SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1),
 545
 546	SND_SOC_DAPM_MUX("ADCA Swap Mux", SND_SOC_NOPM, 0, 0,
 547		&adca_swap_mux),
 548	SND_SOC_DAPM_MUX("ADCB Swap Mux", SND_SOC_NOPM, 0, 0,
 549		&adcb_swap_mux),
 550
 551	SND_SOC_DAPM_MUX("PCMA Swap Mux", SND_SOC_NOPM, 0, 0,
 552		&pcma_swap_mux),
 553	SND_SOC_DAPM_MUX("PCMB Swap Mux", SND_SOC_NOPM, 0, 0,
 554		&pcmb_swap_mux),
 555
 556	SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0),
 557	SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0),
 558
 559	SND_SOC_DAPM_OUTPUT("HPA"),
 560	SND_SOC_DAPM_OUTPUT("LOA"),
 561	SND_SOC_DAPM_OUTPUT("HPB"),
 562	SND_SOC_DAPM_OUTPUT("LOB"),
 563
 564	SND_SOC_DAPM_SWITCH("Headphone Right",
 565			    CS42L56_PWRCTL_2, 4, 1, &hpb_switch),
 566	SND_SOC_DAPM_SWITCH("Headphone Left",
 567			    CS42L56_PWRCTL_2, 6, 1, &hpa_switch),
 568
 569	SND_SOC_DAPM_SWITCH("Lineout Right",
 570			    CS42L56_PWRCTL_2, 0, 1, &lob_switch),
 571	SND_SOC_DAPM_SWITCH("Lineout Left",
 572			    CS42L56_PWRCTL_2, 2, 1, &loa_switch),
 573
 574	SND_SOC_DAPM_MUX("LINEOUTA Input Mux", SND_SOC_NOPM,
 575			 0, 0, &lineouta_input),
 576	SND_SOC_DAPM_MUX("LINEOUTB Input Mux", SND_SOC_NOPM,
 577			 0, 0, &lineoutb_input),
 578	SND_SOC_DAPM_MUX("HPA Input Mux", SND_SOC_NOPM,
 579			 0, 0, &hpa_input),
 580	SND_SOC_DAPM_MUX("HPB Input Mux", SND_SOC_NOPM,
 581			 0, 0, &hpb_input),
 582
 583};
 584
 585static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
 586
 587	{"HiFi Capture", "DSP", "Digital Output Mux"},
 588	{"HiFi Capture", "ADC", "Digital Output Mux"},
 589
 590	{"Digital Output Mux", NULL, "ADCA"},
 591	{"Digital Output Mux", NULL, "ADCB"},
 592
 593	{"ADCB", NULL, "ADCB Swap Mux"},
 594	{"ADCA", NULL, "ADCA Swap Mux"},
 595
 596	{"ADCA Swap Mux", NULL, "ADCA"},
 597	{"ADCB Swap Mux", NULL, "ADCB"},
 598
 599	{"DACA", "Left", "ADCA Swap Mux"},
 600	{"DACA", "LR 2", "ADCA Swap Mux"},
 601	{"DACA", "Right", "ADCA Swap Mux"},
 602
 603	{"DACB", "Left", "ADCB Swap Mux"},
 604	{"DACB", "LR 2", "ADCB Swap Mux"},
 605	{"DACB", "Right", "ADCB Swap Mux"},
 606
 607	{"ADCA Mux", NULL, "AIN3A"},
 608	{"ADCA Mux", NULL, "AIN2A"},
 609	{"ADCA Mux", NULL, "AIN1A"},
 610	{"ADCA Mux", NULL, "PGAA"},
 611	{"ADCB Mux", NULL, "AIN3B"},
 612	{"ADCB Mux", NULL, "AIN2B"},
 613	{"ADCB Mux", NULL, "AIN1B"},
 614	{"ADCB Mux", NULL, "PGAB"},
 615
 616	{"PGAA", "AIN1A", "PGAA Input Mux"},
 617	{"PGAA", "AIN2A", "PGAA Input Mux"},
 618	{"PGAA", "AIN3A", "PGAA Input Mux"},
 619	{"PGAB", "AIN1B", "PGAB Input Mux"},
 620	{"PGAB", "AIN2B", "PGAB Input Mux"},
 621	{"PGAB", "AIN3B", "PGAB Input Mux"},
 622
 623	{"PGAA Input Mux", NULL, "AIN1A"},
 624	{"PGAA Input Mux", NULL, "AIN2A"},
 625	{"PGAA Input Mux", NULL, "AIN3A"},
 626	{"PGAB Input Mux", NULL, "AIN1B"},
 627	{"PGAB Input Mux", NULL, "AIN2B"},
 628	{"PGAB Input Mux", NULL, "AIN3B"},
 629
 630	{"LOB", "Switch", "LINEOUTB Input Mux"},
 631	{"LOA", "Switch", "LINEOUTA Input Mux"},
 632
 633	{"LINEOUTA Input Mux", "PGAA", "PGAA"},
 634	{"LINEOUTB Input Mux", "PGAB", "PGAB"},
 635	{"LINEOUTA Input Mux", "DACA", "DACA"},
 636	{"LINEOUTB Input Mux", "DACB", "DACB"},
 637
 638	{"HPA", "Switch", "HPB Input Mux"},
 639	{"HPB", "Switch", "HPA Input Mux"},
 640
 641	{"HPA Input Mux", "PGAA", "PGAA"},
 642	{"HPB Input Mux", "PGAB", "PGAB"},
 643	{"HPA Input Mux", "DACA", "DACA"},
 644	{"HPB Input Mux", "DACB", "DACB"},
 645
 646	{"DACA", NULL, "PCMA Swap Mux"},
 647	{"DACB", NULL, "PCMB Swap Mux"},
 648
 649	{"PCMB Swap Mux", "Left", "HiFi Playback"},
 650	{"PCMB Swap Mux", "LR 2", "HiFi Playback"},
 651	{"PCMB Swap Mux", "Right", "HiFi Playback"},
 652
 653	{"PCMA Swap Mux", "Left", "HiFi Playback"},
 654	{"PCMA Swap Mux", "LR 2", "HiFi Playback"},
 655	{"PCMA Swap Mux", "Right", "HiFi Playback"},
 656
 657};
 658
 659struct cs42l56_clk_para {
 660	u32 mclk;
 661	u32 srate;
 662	u8 ratio;
 663};
 664
 665static const struct cs42l56_clk_para clk_ratio_table[] = {
 666	/* 8k */
 667	{ 6000000, 8000, CS42L56_MCLK_LRCLK_768 },
 668	{ 6144000, 8000, CS42L56_MCLK_LRCLK_750 },
 669	{ 12000000, 8000, CS42L56_MCLK_LRCLK_768 },
 670	{ 12288000, 8000, CS42L56_MCLK_LRCLK_750 },
 671	{ 24000000, 8000, CS42L56_MCLK_LRCLK_768 },
 672	{ 24576000, 8000, CS42L56_MCLK_LRCLK_750 },
 673	/* 11.025k */
 674	{ 5644800, 11025, CS42L56_MCLK_LRCLK_512},
 675	{ 11289600, 11025, CS42L56_MCLK_LRCLK_512},
 676	{ 22579200, 11025, CS42L56_MCLK_LRCLK_512 },
 677	/* 11.0294k */
 678	{ 6000000, 110294, CS42L56_MCLK_LRCLK_544 },
 679	{ 12000000, 110294, CS42L56_MCLK_LRCLK_544 },
 680	{ 24000000, 110294, CS42L56_MCLK_LRCLK_544 },
 681	/* 12k */
 682	{ 6000000, 12000, CS42L56_MCLK_LRCLK_500 },
 683	{ 6144000, 12000, CS42L56_MCLK_LRCLK_512 },
 684	{ 12000000, 12000, CS42L56_MCLK_LRCLK_500 },
 685	{ 12288000, 12000, CS42L56_MCLK_LRCLK_512 },
 686	{ 24000000, 12000, CS42L56_MCLK_LRCLK_500 },
 687	{ 24576000, 12000, CS42L56_MCLK_LRCLK_512 },
 688	/* 16k */
 689	{ 6000000, 16000, CS42L56_MCLK_LRCLK_375 },
 690	{ 6144000, 16000, CS42L56_MCLK_LRCLK_384 },
 691	{ 12000000, 16000, CS42L56_MCLK_LRCLK_375 },
 692	{ 12288000, 16000, CS42L56_MCLK_LRCLK_384 },
 693	{ 24000000, 16000, CS42L56_MCLK_LRCLK_375 },
 694	{ 24576000, 16000, CS42L56_MCLK_LRCLK_384 },
 695	/* 22.050k */
 696	{ 5644800, 22050, CS42L56_MCLK_LRCLK_256 },
 697	{ 11289600, 22050, CS42L56_MCLK_LRCLK_256 },
 698	{ 22579200, 22050, CS42L56_MCLK_LRCLK_256 },
 699	/* 22.0588k */
 700	{ 6000000, 220588, CS42L56_MCLK_LRCLK_272 },
 701	{ 12000000, 220588, CS42L56_MCLK_LRCLK_272 },
 702	{ 24000000, 220588, CS42L56_MCLK_LRCLK_272 },
 703	/* 24k */
 704	{ 6000000, 24000, CS42L56_MCLK_LRCLK_250 },
 705	{ 6144000, 24000, CS42L56_MCLK_LRCLK_256 },
 706	{ 12000000, 24000, CS42L56_MCLK_LRCLK_250 },
 707	{ 12288000, 24000, CS42L56_MCLK_LRCLK_256 },
 708	{ 24000000, 24000, CS42L56_MCLK_LRCLK_250 },
 709	{ 24576000, 24000, CS42L56_MCLK_LRCLK_256 },
 710	/* 32k */
 711	{ 6000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
 712	{ 6144000, 32000, CS42L56_MCLK_LRCLK_192 },
 713	{ 12000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
 714	{ 12288000, 32000, CS42L56_MCLK_LRCLK_192 },
 715	{ 24000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
 716	{ 24576000, 32000, CS42L56_MCLK_LRCLK_192 },
 717	/* 44.118k */
 718	{ 6000000, 44118, CS42L56_MCLK_LRCLK_136 },
 719	{ 12000000, 44118, CS42L56_MCLK_LRCLK_136 },
 720	{ 24000000, 44118, CS42L56_MCLK_LRCLK_136 },
 721	/* 44.1k */
 722	{ 5644800, 44100, CS42L56_MCLK_LRCLK_128 },
 723	{ 11289600, 44100, CS42L56_MCLK_LRCLK_128 },
 724	{ 22579200, 44100, CS42L56_MCLK_LRCLK_128 },
 725	/* 48k */
 726	{ 6000000, 48000, CS42L56_MCLK_LRCLK_125 },
 727	{ 6144000, 48000, CS42L56_MCLK_LRCLK_128 },
 728	{ 12000000, 48000, CS42L56_MCLK_LRCLK_125 },
 729	{ 12288000, 48000, CS42L56_MCLK_LRCLK_128 },
 730	{ 24000000, 48000, CS42L56_MCLK_LRCLK_125 },
 731	{ 24576000, 48000, CS42L56_MCLK_LRCLK_128 },
 732};
 733
 734static int cs42l56_get_mclk_ratio(int mclk, int rate)
 735{
 736	int i;
 737
 738	for (i = 0; i < ARRAY_SIZE(clk_ratio_table); i++) {
 739		if (clk_ratio_table[i].mclk == mclk &&
 740		    clk_ratio_table[i].srate == rate)
 741			return clk_ratio_table[i].ratio;
 742	}
 743	return -EINVAL;
 744}
 745
 746static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
 747			int clk_id, unsigned int freq, int dir)
 748{
 749	struct snd_soc_component *component = codec_dai->component;
 750	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 751
 752	switch (freq) {
 753	case CS42L56_MCLK_5P6448MHZ:
 754	case CS42L56_MCLK_6MHZ:
 755	case CS42L56_MCLK_6P144MHZ:
 756		cs42l56->mclk_div2 = 0;
 757		cs42l56->mclk_prediv = 0;
 758		break;
 759	case CS42L56_MCLK_11P2896MHZ:
 760	case CS42L56_MCLK_12MHZ:
 761	case CS42L56_MCLK_12P288MHZ:
 762		cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
 763		cs42l56->mclk_prediv = 0;
 764		break;
 765	case CS42L56_MCLK_22P5792MHZ:
 766	case CS42L56_MCLK_24MHZ:
 767	case CS42L56_MCLK_24P576MHZ:
 768		cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
 769		cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV;
 770		break;
 771	default:
 772		return -EINVAL;
 773	}
 774	cs42l56->mclk = freq;
 775
 776	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 777			    CS42L56_MCLK_PREDIV_MASK,
 778				cs42l56->mclk_prediv);
 779	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 780			    CS42L56_MCLK_DIV2_MASK,
 781				cs42l56->mclk_div2);
 782
 783	return 0;
 784}
 785
 786static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 787{
 788	struct snd_soc_component *component = codec_dai->component;
 789	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 790
 791	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 792	case SND_SOC_DAIFMT_CBP_CFP:
 793		cs42l56->iface = CS42L56_MASTER_MODE;
 794		break;
 795	case SND_SOC_DAIFMT_CBC_CFC:
 796		cs42l56->iface = CS42L56_SLAVE_MODE;
 797		break;
 798	default:
 799		return -EINVAL;
 800	}
 801
 802	 /* interface format */
 803	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 804	case SND_SOC_DAIFMT_I2S:
 805		cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S;
 806		break;
 807	case SND_SOC_DAIFMT_LEFT_J:
 808		cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J;
 809		break;
 810	default:
 811		return -EINVAL;
 812	}
 813
 814	/* sclk inversion */
 815	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 816	case SND_SOC_DAIFMT_NB_NF:
 817		cs42l56->iface_inv = 0;
 818		break;
 819	case SND_SOC_DAIFMT_IB_NF:
 820		cs42l56->iface_inv = CS42L56_SCLK_INV;
 821		break;
 822	default:
 823		return -EINVAL;
 824	}
 825
 826	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 827			    CS42L56_MS_MODE_MASK, cs42l56->iface);
 828	snd_soc_component_update_bits(component, CS42L56_SERIAL_FMT,
 829			    CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt);
 830	snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 831			    CS42L56_SCLK_INV_MASK, cs42l56->iface_inv);
 832	return 0;
 833}
 834
 835static int cs42l56_mute(struct snd_soc_dai *dai, int mute, int direction)
 836{
 837	struct snd_soc_component *component = dai->component;
 838
 839	if (mute) {
 840		/* Hit the DSP Mixer first */
 841		snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
 842				    CS42L56_ADCAMIX_MUTE_MASK |
 843				    CS42L56_ADCBMIX_MUTE_MASK |
 844				    CS42L56_PCMAMIX_MUTE_MASK |
 845				    CS42L56_PCMBMIX_MUTE_MASK |
 846				    CS42L56_MSTB_MUTE_MASK |
 847				    CS42L56_MSTA_MUTE_MASK,
 848				    CS42L56_MUTE_ALL);
 849		/* Mute ADC's */
 850		snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
 851				    CS42L56_ADCA_MUTE_MASK |
 852				    CS42L56_ADCB_MUTE_MASK,
 853				    CS42L56_MUTE_ALL);
 854		/* HP And LO */
 855		snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
 856				    CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
 857		snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
 858				    CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
 859		snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
 860				    CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
 861		snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
 862				    CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
 863	} else {
 864		snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
 865				    CS42L56_ADCAMIX_MUTE_MASK |
 866				    CS42L56_ADCBMIX_MUTE_MASK |
 867				    CS42L56_PCMAMIX_MUTE_MASK |
 868				    CS42L56_PCMBMIX_MUTE_MASK |
 869				    CS42L56_MSTB_MUTE_MASK |
 870				    CS42L56_MSTA_MUTE_MASK,
 871				    CS42L56_UNMUTE);
 872
 873		snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
 874				    CS42L56_ADCA_MUTE_MASK |
 875				    CS42L56_ADCB_MUTE_MASK,
 876				    CS42L56_UNMUTE);
 877
 878		snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
 879				    CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
 880		snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
 881				    CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
 882		snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
 883				    CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
 884		snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
 885				    CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
 886	}
 887	return 0;
 888}
 889
 890static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
 891				     struct snd_pcm_hw_params *params,
 892				     struct snd_soc_dai *dai)
 893{
 894	struct snd_soc_component *component = dai->component;
 895	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 896	int ratio;
 897
 898	ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params));
 899	if (ratio >= 0) {
 900		snd_soc_component_update_bits(component, CS42L56_CLKCTL_2,
 901				    CS42L56_CLK_RATIO_MASK, ratio);
 902	} else {
 903		dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n");
 904		return -EINVAL;
 905	}
 906
 907	return 0;
 908}
 909
 910static int cs42l56_set_bias_level(struct snd_soc_component *component,
 911					enum snd_soc_bias_level level)
 912{
 913	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 914	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 915	int ret;
 916
 917	switch (level) {
 918	case SND_SOC_BIAS_ON:
 919		break;
 920	case SND_SOC_BIAS_PREPARE:
 921		snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 922				    CS42L56_MCLK_DIS_MASK, 0);
 923		snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
 924				    CS42L56_PDN_ALL_MASK, 0);
 925		break;
 926	case SND_SOC_BIAS_STANDBY:
 927		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
 928			regcache_cache_only(cs42l56->regmap, false);
 929			regcache_sync(cs42l56->regmap);
 930			ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
 931						    cs42l56->supplies);
 932			if (ret != 0) {
 933				dev_err(cs42l56->dev,
 934					"Failed to enable regulators: %d\n",
 935					ret);
 936				return ret;
 937			}
 938		}
 939		snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
 940				    CS42L56_PDN_ALL_MASK, 1);
 941		break;
 942	case SND_SOC_BIAS_OFF:
 943		snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
 944				    CS42L56_PDN_ALL_MASK, 1);
 945		snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
 946				    CS42L56_MCLK_DIS_MASK, 1);
 947		regcache_cache_only(cs42l56->regmap, true);
 948		regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
 949						    cs42l56->supplies);
 950		break;
 951	}
 952
 953	return 0;
 954}
 955
 956#define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000)
 957
 958#define CS42L56_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
 959			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \
 960			SNDRV_PCM_FMTBIT_S32_LE)
 961
 962
 963static const struct snd_soc_dai_ops cs42l56_ops = {
 964	.hw_params	= cs42l56_pcm_hw_params,
 965	.mute_stream	= cs42l56_mute,
 966	.set_fmt	= cs42l56_set_dai_fmt,
 967	.set_sysclk	= cs42l56_set_sysclk,
 968	.no_capture_mute = 1,
 969};
 970
 971static struct snd_soc_dai_driver cs42l56_dai = {
 972		.name = "cs42l56",
 973		.playback = {
 974			.stream_name = "HiFi Playback",
 975			.channels_min = 1,
 976			.channels_max = 2,
 977			.rates = CS42L56_RATES,
 978			.formats = CS42L56_FORMATS,
 979		},
 980		.capture = {
 981			.stream_name = "HiFi Capture",
 982			.channels_min = 1,
 983			.channels_max = 2,
 984			.rates = CS42L56_RATES,
 985			.formats = CS42L56_FORMATS,
 986		},
 987		.ops = &cs42l56_ops,
 988};
 989
 990static int beep_freq[] = {
 991	261, 522, 585, 667, 706, 774, 889, 1000,
 992	1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
 993};
 994
 995static void cs42l56_beep_work(struct work_struct *work)
 996{
 997	struct cs42l56_private *cs42l56 =
 998		container_of(work, struct cs42l56_private, beep_work);
 999	struct snd_soc_component *component = cs42l56->component;
1000	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
1001	int i;
1002	int val = 0;
1003	int best = 0;
1004
1005	if (cs42l56->beep_rate) {
1006		for (i = 0; i < ARRAY_SIZE(beep_freq); i++) {
1007			if (abs(cs42l56->beep_rate - beep_freq[i]) <
1008			    abs(cs42l56->beep_rate - beep_freq[best]))
1009				best = i;
1010		}
1011
1012		dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
1013			beep_freq[best], cs42l56->beep_rate);
1014
1015		val = (best << CS42L56_BEEP_RATE_SHIFT);
1016
1017		snd_soc_dapm_enable_pin(dapm, "Beep");
1018	} else {
1019		dev_dbg(component->dev, "Disabling beep\n");
1020		snd_soc_dapm_disable_pin(dapm, "Beep");
1021	}
1022
1023	snd_soc_component_update_bits(component, CS42L56_BEEP_FREQ_ONTIME,
1024			    CS42L56_BEEP_FREQ_MASK, val);
1025
1026	snd_soc_dapm_sync(dapm);
1027}
1028
1029/* For usability define a way of injecting beep events for the device -
1030 * many systems will not have a keyboard.
1031 */
1032static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
1033			     unsigned int code, int hz)
1034{
1035	struct snd_soc_component *component = input_get_drvdata(dev);
1036	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1037
1038	dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
1039
1040	switch (code) {
1041	case SND_BELL:
1042		if (hz)
1043			hz = 261;
1044		break;
1045	case SND_TONE:
1046		break;
1047	default:
1048		return -1;
1049	}
1050
1051	/* Kick the beep from a workqueue */
1052	cs42l56->beep_rate = hz;
1053	schedule_work(&cs42l56->beep_work);
1054	return 0;
1055}
1056
1057static ssize_t beep_store(struct device *dev, struct device_attribute *attr,
1058			  const char *buf, size_t count)
1059{
1060	struct cs42l56_private *cs42l56 = dev_get_drvdata(dev);
1061	long int time;
1062	int ret;
1063
1064	ret = kstrtol(buf, 10, &time);
1065	if (ret != 0)
1066		return ret;
1067
1068	input_event(cs42l56->beep, EV_SND, SND_TONE, time);
1069
1070	return count;
1071}
1072
1073static DEVICE_ATTR_WO(beep);
1074
1075static void cs42l56_init_beep(struct snd_soc_component *component)
1076{
1077	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1078	int ret;
1079
1080	cs42l56->beep = devm_input_allocate_device(component->dev);
1081	if (!cs42l56->beep) {
1082		dev_err(component->dev, "Failed to allocate beep device\n");
1083		return;
1084	}
1085
1086	INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work);
1087	cs42l56->beep_rate = 0;
1088
1089	cs42l56->beep->name = "CS42L56 Beep Generator";
1090	cs42l56->beep->phys = dev_name(component->dev);
1091	cs42l56->beep->id.bustype = BUS_I2C;
1092
1093	cs42l56->beep->evbit[0] = BIT_MASK(EV_SND);
1094	cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1095	cs42l56->beep->event = cs42l56_beep_event;
1096	cs42l56->beep->dev.parent = component->dev;
1097	input_set_drvdata(cs42l56->beep, component);
1098
1099	ret = input_register_device(cs42l56->beep);
1100	if (ret != 0) {
1101		cs42l56->beep = NULL;
1102		dev_err(component->dev, "Failed to register beep device\n");
1103	}
1104
1105	ret = device_create_file(component->dev, &dev_attr_beep);
1106	if (ret != 0) {
1107		dev_err(component->dev, "Failed to create keyclick file: %d\n",
1108			ret);
1109	}
1110}
1111
1112static void cs42l56_free_beep(struct snd_soc_component *component)
1113{
1114	struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1115
1116	device_remove_file(component->dev, &dev_attr_beep);
1117	cancel_work_sync(&cs42l56->beep_work);
1118	cs42l56->beep = NULL;
1119
1120	snd_soc_component_update_bits(component, CS42L56_BEEP_TONE_CFG,
1121			    CS42L56_BEEP_EN_MASK, 0);
1122}
1123
1124static int cs42l56_probe(struct snd_soc_component *component)
1125{
1126	cs42l56_init_beep(component);
1127
1128	return 0;
1129}
1130
1131static void cs42l56_remove(struct snd_soc_component *component)
1132{
1133	cs42l56_free_beep(component);
1134}
1135
1136static const struct snd_soc_component_driver soc_component_dev_cs42l56 = {
1137	.probe			= cs42l56_probe,
1138	.remove			= cs42l56_remove,
1139	.set_bias_level		= cs42l56_set_bias_level,
1140	.controls		= cs42l56_snd_controls,
1141	.num_controls		= ARRAY_SIZE(cs42l56_snd_controls),
1142	.dapm_widgets		= cs42l56_dapm_widgets,
1143	.num_dapm_widgets	= ARRAY_SIZE(cs42l56_dapm_widgets),
1144	.dapm_routes		= cs42l56_audio_map,
1145	.num_dapm_routes	= ARRAY_SIZE(cs42l56_audio_map),
1146	.suspend_bias_off	= 1,
1147	.idle_bias_on		= 1,
1148	.use_pmdown_time	= 1,
1149	.endianness		= 1,
1150};
1151
1152static const struct regmap_config cs42l56_regmap = {
1153	.reg_bits = 8,
1154	.val_bits = 8,
1155
1156	.max_register = CS42L56_MAX_REGISTER,
1157	.reg_defaults = cs42l56_reg_defaults,
1158	.num_reg_defaults = ARRAY_SIZE(cs42l56_reg_defaults),
1159	.readable_reg = cs42l56_readable_register,
1160	.volatile_reg = cs42l56_volatile_register,
1161	.cache_type = REGCACHE_MAPLE,
1162};
1163
1164static int cs42l56_handle_of_data(struct i2c_client *i2c_client,
1165				    struct cs42l56_platform_data *pdata)
1166{
1167	struct device_node *np = i2c_client->dev.of_node;
1168	u32 val32;
1169
1170	if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg"))
1171		pdata->ain1a_ref_cfg = true;
1172
1173	if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg"))
1174		pdata->ain2a_ref_cfg = true;
1175
1176	if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg"))
1177		pdata->ain1b_ref_cfg = true;
1178
1179	if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg"))
1180		pdata->ain2b_ref_cfg = true;
1181
1182	if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0)
1183		pdata->micbias_lvl = val32;
1184
1185	if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0)
1186		pdata->chgfreq = val32;
1187
1188	if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0)
1189		pdata->adaptive_pwr = val32;
1190
1191	if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1192		pdata->hpfa_freq = val32;
1193
1194	if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1195		pdata->hpfb_freq = val32;
1196
1197	pdata->gpio_nreset = devm_gpiod_get_optional(&i2c_client->dev, "cirrus,gpio-nreset",
1198						     GPIOD_OUT_LOW);
1199
1200	if (IS_ERR(pdata->gpio_nreset))
1201		return PTR_ERR(pdata->gpio_nreset);
1202
1203	gpiod_set_consumer_name(pdata->gpio_nreset, "CS42L56 /RST");
1204
1205	return 0;
1206}
1207
1208static int cs42l56_i2c_probe(struct i2c_client *i2c_client)
1209{
1210	struct cs42l56_private *cs42l56;
1211	int ret, i;
1212	unsigned int devid;
1213	unsigned int alpha_rev, metal_rev;
1214	unsigned int reg;
1215
1216	cs42l56 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l56), GFP_KERNEL);
1217	if (cs42l56 == NULL)
1218		return -ENOMEM;
1219	cs42l56->dev = &i2c_client->dev;
1220
1221	cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap);
1222	if (IS_ERR(cs42l56->regmap)) {
1223		ret = PTR_ERR(cs42l56->regmap);
1224		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1225		return ret;
1226	}
1227
1228	if (i2c_client->dev.of_node) {
1229		ret = cs42l56_handle_of_data(i2c_client, &cs42l56->pdata);
1230		if (ret != 0)
1231			return ret;
1232	}
1233
1234	if (cs42l56->pdata.gpio_nreset) {
1235		gpiod_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1);
1236		gpiod_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0);
1237	}
1238
1239	i2c_set_clientdata(i2c_client, cs42l56);
1240
1241	for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++)
1242		cs42l56->supplies[i].supply = cs42l56_supply_names[i];
1243
1244	ret = devm_regulator_bulk_get(&i2c_client->dev,
1245				      ARRAY_SIZE(cs42l56->supplies),
1246				      cs42l56->supplies);
1247	if (ret != 0) {
1248		dev_err(&i2c_client->dev,
1249			"Failed to request supplies: %d\n", ret);
1250		return ret;
1251	}
1252
1253	ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
1254				    cs42l56->supplies);
1255	if (ret != 0) {
1256		dev_err(&i2c_client->dev,
1257			"Failed to enable supplies: %d\n", ret);
1258		return ret;
1259	}
1260
1261	ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, &reg);
1262	if (ret) {
1263		dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret);
1264		goto err_enable;
1265	}
1266
1267	devid = reg & CS42L56_CHIP_ID_MASK;
1268	if (devid != CS42L56_DEVID) {
1269		dev_err(&i2c_client->dev,
1270			"CS42L56 Device ID (%X). Expected %X\n",
1271			devid, CS42L56_DEVID);
1272		ret = -EINVAL;
1273		goto err_enable;
1274	}
1275	alpha_rev = reg & CS42L56_AREV_MASK;
1276	metal_rev = reg & CS42L56_MTLREV_MASK;
1277
1278	dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 ");
1279	dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n",
1280		 alpha_rev, metal_rev);
1281
1282	if (cs42l56->pdata.ain1a_ref_cfg)
1283		regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1284				   CS42L56_AIN1A_REF_MASK,
1285				   CS42L56_AIN1A_REF_MASK);
1286
1287	if (cs42l56->pdata.ain1b_ref_cfg)
1288		regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1289				   CS42L56_AIN1B_REF_MASK,
1290				   CS42L56_AIN1B_REF_MASK);
1291
1292	if (cs42l56->pdata.ain2a_ref_cfg)
1293		regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1294				   CS42L56_AIN2A_REF_MASK,
1295				   CS42L56_AIN2A_REF_MASK);
1296
1297	if (cs42l56->pdata.ain2b_ref_cfg)
1298		regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1299				   CS42L56_AIN2B_REF_MASK,
1300				   CS42L56_AIN2B_REF_MASK);
1301
1302	if (cs42l56->pdata.micbias_lvl)
1303		regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL,
1304				   CS42L56_MIC_BIAS_MASK,
1305				cs42l56->pdata.micbias_lvl);
1306
1307	if (cs42l56->pdata.chgfreq)
1308		regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1309				   CS42L56_CHRG_FREQ_MASK,
1310				cs42l56->pdata.chgfreq);
1311
1312	if (cs42l56->pdata.hpfb_freq)
1313		regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1314				   CS42L56_HPFB_FREQ_MASK,
1315				cs42l56->pdata.hpfb_freq);
1316
1317	if (cs42l56->pdata.hpfa_freq)
1318		regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1319				   CS42L56_HPFA_FREQ_MASK,
1320				cs42l56->pdata.hpfa_freq);
1321
1322	if (cs42l56->pdata.adaptive_pwr)
1323		regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1324				   CS42L56_ADAPT_PWR_MASK,
1325				cs42l56->pdata.adaptive_pwr);
1326
1327	ret =  devm_snd_soc_register_component(&i2c_client->dev,
1328			&soc_component_dev_cs42l56, &cs42l56_dai, 1);
1329	if (ret < 0)
1330		goto err_enable;
1331
1332	return 0;
1333
1334err_enable:
1335	regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1336			       cs42l56->supplies);
1337	return ret;
1338}
1339
1340static void cs42l56_i2c_remove(struct i2c_client *client)
1341{
1342	struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
1343
1344	regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1345			       cs42l56->supplies);
1346}
1347
1348static const struct of_device_id cs42l56_of_match[] = {
1349	{ .compatible = "cirrus,cs42l56", },
1350	{ }
1351};
1352MODULE_DEVICE_TABLE(of, cs42l56_of_match);
1353
1354
1355static const struct i2c_device_id cs42l56_id[] = {
1356	{ "cs42l56" },
1357	{ }
1358};
1359MODULE_DEVICE_TABLE(i2c, cs42l56_id);
1360
1361static struct i2c_driver cs42l56_i2c_driver = {
1362	.driver = {
1363		.name = "cs42l56",
1364		.of_match_table = cs42l56_of_match,
1365	},
1366	.id_table = cs42l56_id,
1367	.probe =    cs42l56_i2c_probe,
1368	.remove =   cs42l56_i2c_remove,
1369};
1370
1371module_i2c_driver(cs42l56_i2c_driver);
1372
1373MODULE_DESCRIPTION("ASoC CS42L56 driver");
1374MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1375MODULE_LICENSE("GPL");
~/ Read-only file preview.