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