linux/sound/soc/codecs/mc13783.c
<<
>>
Prefs
   1/*
   2 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
   3 * Copyright 2009 Sascha Hauer, s.hauer@pengutronix.de
   4 * Copyright 2012 Philippe Retornaz, philippe.retornaz@epfl.ch
   5 *
   6 * Initial development of this code was funded by
   7 * Phytec Messtechnik GmbH, http://www.phytec.de
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License
  11 * as published by the Free Software Foundation; either version 2
  12 * of the License, or (at your option) any later version.
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  21 * MA  02110-1301, USA.
  22 */
  23#include <linux/module.h>
  24#include <linux/device.h>
  25#include <linux/mfd/mc13xxx.h>
  26#include <linux/slab.h>
  27#include <sound/core.h>
  28#include <sound/control.h>
  29#include <sound/pcm.h>
  30#include <sound/soc.h>
  31#include <sound/initval.h>
  32#include <sound/soc-dapm.h>
  33
  34#include "mc13783.h"
  35
  36#define MC13783_AUDIO_RX0       36
  37#define MC13783_AUDIO_RX1       37
  38#define MC13783_AUDIO_TX        38
  39#define MC13783_SSI_NETWORK     39
  40#define MC13783_AUDIO_CODEC     40
  41#define MC13783_AUDIO_DAC       41
  42
  43#define AUDIO_RX0_ALSPEN                (1 << 5)
  44#define AUDIO_RX0_ALSPSEL               (1 << 7)
  45#define AUDIO_RX0_ADDCDC                (1 << 21)
  46#define AUDIO_RX0_ADDSTDC               (1 << 22)
  47#define AUDIO_RX0_ADDRXIN               (1 << 23)
  48
  49#define AUDIO_RX1_PGARXEN               (1 << 0);
  50#define AUDIO_RX1_PGASTEN               (1 << 5)
  51#define AUDIO_RX1_ARXINEN               (1 << 10)
  52
  53#define AUDIO_TX_AMC1REN                (1 << 5)
  54#define AUDIO_TX_AMC1LEN                (1 << 7)
  55#define AUDIO_TX_AMC2EN                 (1 << 9)
  56#define AUDIO_TX_ATXINEN                (1 << 11)
  57#define AUDIO_TX_RXINREC                (1 << 13)
  58
  59#define SSI_NETWORK_CDCTXRXSLOT(x)      (((x) & 0x3) << 2)
  60#define SSI_NETWORK_CDCTXSECSLOT(x)     (((x) & 0x3) << 4)
  61#define SSI_NETWORK_CDCRXSECSLOT(x)     (((x) & 0x3) << 6)
  62#define SSI_NETWORK_CDCRXSECGAIN(x)     (((x) & 0x3) << 8)
  63#define SSI_NETWORK_CDCSUMGAIN(x)       (1 << 10)
  64#define SSI_NETWORK_CDCFSDLY(x)         (1 << 11)
  65#define SSI_NETWORK_DAC_SLOTS_8         (1 << 12)
  66#define SSI_NETWORK_DAC_SLOTS_4         (2 << 12)
  67#define SSI_NETWORK_DAC_SLOTS_2         (3 << 12)
  68#define SSI_NETWORK_DAC_SLOT_MASK       (3 << 12)
  69#define SSI_NETWORK_DAC_RXSLOT_0_1      (0 << 14)
  70#define SSI_NETWORK_DAC_RXSLOT_2_3      (1 << 14)
  71#define SSI_NETWORK_DAC_RXSLOT_4_5      (2 << 14)
  72#define SSI_NETWORK_DAC_RXSLOT_6_7      (3 << 14)
  73#define SSI_NETWORK_DAC_RXSLOT_MASK     (3 << 14)
  74#define SSI_NETWORK_STDCRXSECSLOT(x)    (((x) & 0x3) << 16)
  75#define SSI_NETWORK_STDCRXSECGAIN(x)    (((x) & 0x3) << 18)
  76#define SSI_NETWORK_STDCSUMGAIN         (1 << 20)
  77
  78/*
  79 * MC13783_AUDIO_CODEC and MC13783_AUDIO_DAC mostly share the same
  80 * register layout
  81 */
  82#define AUDIO_SSI_SEL                   (1 << 0)
  83#define AUDIO_CLK_SEL                   (1 << 1)
  84#define AUDIO_CSM                       (1 << 2)
  85#define AUDIO_BCL_INV                   (1 << 3)
  86#define AUDIO_CFS_INV                   (1 << 4)
  87#define AUDIO_CFS(x)                    (((x) & 0x3) << 5)
  88#define AUDIO_CLK(x)                    (((x) & 0x7) << 7)
  89#define AUDIO_C_EN                      (1 << 11)
  90#define AUDIO_C_CLK_EN                  (1 << 12)
  91#define AUDIO_C_RESET                   (1 << 15)
  92
  93#define AUDIO_CODEC_CDCFS8K16K          (1 << 10)
  94#define AUDIO_DAC_CFS_DLY_B             (1 << 10)
  95
  96struct mc13783_priv {
  97        struct snd_soc_codec codec;
  98        struct mc13xxx *mc13xxx;
  99
 100        enum mc13783_ssi_port adc_ssi_port;
 101        enum mc13783_ssi_port dac_ssi_port;
 102};
 103
 104static unsigned int mc13783_read(struct snd_soc_codec *codec,
 105        unsigned int reg)
 106{
 107        struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
 108        unsigned int value = 0;
 109
 110        mc13xxx_lock(priv->mc13xxx);
 111
 112        mc13xxx_reg_read(priv->mc13xxx, reg, &value);
 113
 114        mc13xxx_unlock(priv->mc13xxx);
 115
 116        return value;
 117}
 118
 119static int mc13783_write(struct snd_soc_codec *codec,
 120        unsigned int reg, unsigned int value)
 121{
 122        struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
 123        int ret;
 124
 125        mc13xxx_lock(priv->mc13xxx);
 126
 127        ret = mc13xxx_reg_write(priv->mc13xxx, reg, value);
 128
 129        mc13xxx_unlock(priv->mc13xxx);
 130
 131        return ret;
 132}
 133
 134/* Mapping between sample rates and register value */
 135static unsigned int mc13783_rates[] = {
 136        8000, 11025, 12000, 16000,
 137        22050, 24000, 32000, 44100,
 138        48000, 64000, 96000
 139};
 140
 141static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream,
 142                                struct snd_pcm_hw_params *params,
 143                                struct snd_soc_dai *dai)
 144{
 145        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 146        struct snd_soc_codec *codec = rtd->codec;
 147        unsigned int rate = params_rate(params);
 148        int i;
 149
 150        for (i = 0; i < ARRAY_SIZE(mc13783_rates); i++) {
 151                if (rate == mc13783_rates[i]) {
 152                        snd_soc_update_bits(codec, MC13783_AUDIO_DAC,
 153                                        0xf << 17, i << 17);
 154                        return 0;
 155                }
 156        }
 157
 158        return -EINVAL;
 159}
 160
 161static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
 162                                struct snd_pcm_hw_params *params,
 163                                struct snd_soc_dai *dai)
 164{
 165        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 166        struct snd_soc_codec *codec = rtd->codec;
 167        unsigned int rate = params_rate(params);
 168        unsigned int val;
 169
 170        switch (rate) {
 171        case 8000:
 172                val = 0;
 173                break;
 174        case 16000:
 175                val = AUDIO_CODEC_CDCFS8K16K;
 176                break;
 177        default:
 178                return -EINVAL;
 179        }
 180
 181        snd_soc_update_bits(codec, MC13783_AUDIO_CODEC, AUDIO_CODEC_CDCFS8K16K,
 182                        val);
 183
 184        return 0;
 185}
 186
 187static int mc13783_pcm_hw_params_sync(struct snd_pcm_substream *substream,
 188                                struct snd_pcm_hw_params *params,
 189                                struct snd_soc_dai *dai)
 190{
 191        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 192                return mc13783_pcm_hw_params_dac(substream, params, dai);
 193        else
 194                return mc13783_pcm_hw_params_codec(substream, params, dai);
 195}
 196
 197static int mc13783_set_fmt(struct snd_soc_dai *dai, unsigned int fmt,
 198                        unsigned int reg)
 199{
 200        struct snd_soc_codec *codec = dai->codec;
 201        unsigned int val = 0;
 202        unsigned int mask = AUDIO_CFS(3) | AUDIO_BCL_INV | AUDIO_CFS_INV |
 203                                AUDIO_CSM | AUDIO_C_CLK_EN | AUDIO_C_RESET;
 204
 205
 206        /* DAI mode */
 207        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 208        case SND_SOC_DAIFMT_I2S:
 209                val |= AUDIO_CFS(2);
 210                break;
 211        case SND_SOC_DAIFMT_DSP_A:
 212                val |= AUDIO_CFS(1);
 213                break;
 214        default:
 215                return -EINVAL;
 216        }
 217
 218        /* DAI clock inversion */
 219        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 220        case SND_SOC_DAIFMT_NB_NF:
 221                val |= AUDIO_BCL_INV;
 222                break;
 223        case SND_SOC_DAIFMT_NB_IF:
 224                val |= AUDIO_BCL_INV | AUDIO_CFS_INV;
 225                break;
 226        case SND_SOC_DAIFMT_IB_NF:
 227                break;
 228        case SND_SOC_DAIFMT_IB_IF:
 229                val |= AUDIO_CFS_INV;
 230                break;
 231        }
 232
 233        /* DAI clock master masks */
 234        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 235        case SND_SOC_DAIFMT_CBM_CFM:
 236                val |= AUDIO_C_CLK_EN;
 237                break;
 238        case SND_SOC_DAIFMT_CBS_CFS:
 239                val |= AUDIO_CSM;
 240                break;
 241        case SND_SOC_DAIFMT_CBM_CFS:
 242        case SND_SOC_DAIFMT_CBS_CFM:
 243                return -EINVAL;
 244        }
 245
 246        val |= AUDIO_C_RESET;
 247
 248        snd_soc_update_bits(codec, reg, mask, val);
 249
 250        return 0;
 251}
 252
 253static int mc13783_set_fmt_async(struct snd_soc_dai *dai, unsigned int fmt)
 254{
 255        if (dai->id == MC13783_ID_STEREO_DAC)
 256                return mc13783_set_fmt(dai, fmt, MC13783_AUDIO_DAC);
 257        else
 258                return mc13783_set_fmt(dai, fmt, MC13783_AUDIO_CODEC);
 259}
 260
 261static int mc13783_set_fmt_sync(struct snd_soc_dai *dai, unsigned int fmt)
 262{
 263        int ret;
 264
 265        ret = mc13783_set_fmt(dai, fmt, MC13783_AUDIO_DAC);
 266        if (ret)
 267                return ret;
 268
 269        /*
 270         * In synchronous mode force the voice codec into slave mode
 271         * so that the clock / framesync from the stereo DAC is used
 272         */
 273        fmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
 274        fmt |= SND_SOC_DAIFMT_CBS_CFS;
 275        ret = mc13783_set_fmt(dai, fmt, MC13783_AUDIO_CODEC);
 276
 277        return ret;
 278}
 279
 280static int mc13783_sysclk[] = {
 281        13000000,
 282        15360000,
 283        16800000,
 284        -1,
 285        26000000,
 286        -1, /* 12000000, invalid for voice codec */
 287        -1, /* 3686400, invalid for voice codec */
 288        33600000,
 289};
 290
 291static int mc13783_set_sysclk(struct snd_soc_dai *dai,
 292                                  int clk_id, unsigned int freq, int dir,
 293                                  unsigned int reg)
 294{
 295        struct snd_soc_codec *codec = dai->codec;
 296        int clk;
 297        unsigned int val = 0;
 298        unsigned int mask = AUDIO_CLK(0x7) | AUDIO_CLK_SEL;
 299
 300        for (clk = 0; clk < ARRAY_SIZE(mc13783_sysclk); clk++) {
 301                if (mc13783_sysclk[clk] < 0)
 302                        continue;
 303                if (mc13783_sysclk[clk] == freq)
 304                        break;
 305        }
 306
 307        if (clk == ARRAY_SIZE(mc13783_sysclk))
 308                return -EINVAL;
 309
 310        if (clk_id == MC13783_CLK_CLIB)
 311                val |= AUDIO_CLK_SEL;
 312
 313        val |= AUDIO_CLK(clk);
 314
 315        snd_soc_update_bits(codec, reg, mask, val);
 316
 317        return 0;
 318}
 319
 320static int mc13783_set_sysclk_dac(struct snd_soc_dai *dai,
 321                                  int clk_id, unsigned int freq, int dir)
 322{
 323        return mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_DAC);
 324}
 325
 326static int mc13783_set_sysclk_codec(struct snd_soc_dai *dai,
 327                                  int clk_id, unsigned int freq, int dir)
 328{
 329        return mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_CODEC);
 330}
 331
 332static int mc13783_set_sysclk_sync(struct snd_soc_dai *dai,
 333                                  int clk_id, unsigned int freq, int dir)
 334{
 335        int ret;
 336
 337        ret = mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_DAC);
 338        if (ret)
 339                return ret;
 340
 341        return mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_CODEC);
 342}
 343
 344static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
 345        unsigned int tx_mask, unsigned int rx_mask, int slots,
 346        int slot_width)
 347{
 348        struct snd_soc_codec *codec = dai->codec;
 349        unsigned int val = 0;
 350        unsigned int mask = SSI_NETWORK_DAC_SLOT_MASK |
 351                                SSI_NETWORK_DAC_RXSLOT_MASK;
 352
 353        switch (slots) {
 354        case 2:
 355                val |= SSI_NETWORK_DAC_SLOTS_2;
 356                break;
 357        case 4:
 358                val |= SSI_NETWORK_DAC_SLOTS_4;
 359                break;
 360        case 8:
 361                val |= SSI_NETWORK_DAC_SLOTS_8;
 362                break;
 363        default:
 364                return -EINVAL;
 365        }
 366
 367        switch (rx_mask) {
 368        case 0xfffffffc:
 369                val |= SSI_NETWORK_DAC_RXSLOT_0_1;
 370                break;
 371        case 0xfffffff3:
 372                val |= SSI_NETWORK_DAC_RXSLOT_2_3;
 373                break;
 374        case 0xffffffcf:
 375                val |= SSI_NETWORK_DAC_RXSLOT_4_5;
 376                break;
 377        case 0xffffff3f:
 378                val |= SSI_NETWORK_DAC_RXSLOT_6_7;
 379                break;
 380        default:
 381                return -EINVAL;
 382        };
 383
 384        snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
 385
 386        return 0;
 387}
 388
 389static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
 390        unsigned int tx_mask, unsigned int rx_mask, int slots,
 391        int slot_width)
 392{
 393        struct snd_soc_codec *codec = dai->codec;
 394        unsigned int val = 0;
 395        unsigned int mask = 0x3f;
 396
 397        if (slots != 4)
 398                return -EINVAL;
 399
 400        if (tx_mask != 0xfffffffc)
 401                return -EINVAL;
 402
 403        val |= (0x00 << 2);     /* primary timeslot RX/TX(?) is 0 */
 404        val |= (0x01 << 4);     /* secondary timeslot TX is 1 */
 405
 406        snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
 407
 408        return 0;
 409}
 410
 411static int mc13783_set_tdm_slot_sync(struct snd_soc_dai *dai,
 412        unsigned int tx_mask, unsigned int rx_mask, int slots,
 413        int slot_width)
 414{
 415        int ret;
 416
 417        ret = mc13783_set_tdm_slot_dac(dai, tx_mask, rx_mask, slots,
 418                        slot_width);
 419        if (ret)
 420                return ret;
 421
 422        ret = mc13783_set_tdm_slot_codec(dai, tx_mask, rx_mask, slots,
 423                        slot_width);
 424
 425        return ret;
 426}
 427
 428static const struct snd_kcontrol_new mc1l_amp_ctl =
 429        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 7, 1, 0);
 430
 431static const struct snd_kcontrol_new mc1r_amp_ctl =
 432        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 5, 1, 0);
 433
 434static const struct snd_kcontrol_new mc2_amp_ctl =
 435        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 9, 1, 0);
 436
 437static const struct snd_kcontrol_new atx_amp_ctl =
 438        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 11, 1, 0);
 439
 440
 441/* Virtual mux. The chip does the input selection automatically
 442 * as soon as we enable one input. */
 443static const char * const adcl_enum_text[] = {
 444        "MC1L", "RXINL",
 445};
 446
 447static const struct soc_enum adcl_enum =
 448        SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcl_enum_text), adcl_enum_text);
 449
 450static const struct snd_kcontrol_new left_input_mux =
 451        SOC_DAPM_ENUM_VIRT("Route", adcl_enum);
 452
 453static const char * const adcr_enum_text[] = {
 454        "MC1R", "MC2", "RXINR", "TXIN",
 455};
 456
 457static const struct soc_enum adcr_enum =
 458        SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcr_enum_text), adcr_enum_text);
 459
 460static const struct snd_kcontrol_new right_input_mux =
 461        SOC_DAPM_ENUM_VIRT("Route", adcr_enum);
 462
 463static const struct snd_kcontrol_new samp_ctl =
 464        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0);
 465
 466static const struct snd_kcontrol_new lamp_ctl =
 467        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 5, 1, 0);
 468
 469static const struct snd_kcontrol_new hlamp_ctl =
 470        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 10, 1, 0);
 471
 472static const struct snd_kcontrol_new hramp_ctl =
 473        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 9, 1, 0);
 474
 475static const struct snd_kcontrol_new llamp_ctl =
 476        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 16, 1, 0);
 477
 478static const struct snd_kcontrol_new lramp_ctl =
 479        SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 15, 1, 0);
 480
 481static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
 482/* Input */
 483        SND_SOC_DAPM_INPUT("MC1LIN"),
 484        SND_SOC_DAPM_INPUT("MC1RIN"),
 485        SND_SOC_DAPM_INPUT("MC2IN"),
 486        SND_SOC_DAPM_INPUT("RXINR"),
 487        SND_SOC_DAPM_INPUT("RXINL"),
 488        SND_SOC_DAPM_INPUT("TXIN"),
 489
 490        SND_SOC_DAPM_SUPPLY("MC1 Bias", MC13783_AUDIO_TX, 0, 0, NULL, 0),
 491        SND_SOC_DAPM_SUPPLY("MC2 Bias", MC13783_AUDIO_TX, 1, 0, NULL, 0),
 492
 493        SND_SOC_DAPM_SWITCH("MC1L Amp", MC13783_AUDIO_TX, 7, 0, &mc1l_amp_ctl),
 494        SND_SOC_DAPM_SWITCH("MC1R Amp", MC13783_AUDIO_TX, 5, 0, &mc1r_amp_ctl),
 495        SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl),
 496        SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl),
 497
 498        SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0,
 499                              &left_input_mux),
 500        SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0,
 501                              &right_input_mux),
 502
 503        SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0),
 504        SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0),
 505
 506        SND_SOC_DAPM_ADC("ADC", "Capture", MC13783_AUDIO_CODEC, 11, 0),
 507        SND_SOC_DAPM_SUPPLY("ADC_Reset", MC13783_AUDIO_CODEC, 15, 0, NULL, 0),
 508
 509/* Output */
 510        SND_SOC_DAPM_SUPPLY("DAC_E", MC13783_AUDIO_DAC, 11, 0, NULL, 0),
 511        SND_SOC_DAPM_SUPPLY("DAC_Reset", MC13783_AUDIO_DAC, 15, 0, NULL, 0),
 512        SND_SOC_DAPM_OUTPUT("RXOUTL"),
 513        SND_SOC_DAPM_OUTPUT("RXOUTR"),
 514        SND_SOC_DAPM_OUTPUT("HSL"),
 515        SND_SOC_DAPM_OUTPUT("HSR"),
 516        SND_SOC_DAPM_OUTPUT("LSP"),
 517        SND_SOC_DAPM_OUTPUT("SP"),
 518
 519        SND_SOC_DAPM_SWITCH("Speaker Amp", MC13783_AUDIO_RX0, 3, 0, &samp_ctl),
 520        SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl),
 521        SND_SOC_DAPM_SWITCH("Headset Amp Left", MC13783_AUDIO_RX0, 10, 0,
 522                        &hlamp_ctl),
 523        SND_SOC_DAPM_SWITCH("Headset Amp Right", MC13783_AUDIO_RX0, 9, 0,
 524                        &hramp_ctl),
 525        SND_SOC_DAPM_SWITCH("Line out Amp Left", MC13783_AUDIO_RX0, 16, 0,
 526                        &llamp_ctl),
 527        SND_SOC_DAPM_SWITCH("Line out Amp Right", MC13783_AUDIO_RX0, 15, 0,
 528                        &lramp_ctl),
 529        SND_SOC_DAPM_DAC("DAC", "Playback", MC13783_AUDIO_RX0, 22, 0),
 530        SND_SOC_DAPM_PGA("DAC PGA", MC13783_AUDIO_RX1, 5, 0, NULL, 0),
 531};
 532
 533static struct snd_soc_dapm_route mc13783_routes[] = {
 534/* Input */
 535        { "MC1L Amp", NULL, "MC1LIN"},
 536        { "MC1R Amp", NULL, "MC1RIN" },
 537        { "MC2 Amp", NULL, "MC2IN" },
 538        { "TXIN Amp", NULL, "TXIN"},
 539
 540        { "PGA Left Input Mux", "MC1L", "MC1L Amp" },
 541        { "PGA Left Input Mux", "RXINL", "RXINL"},
 542        { "PGA Right Input Mux", "MC1R", "MC1R Amp" },
 543        { "PGA Right Input Mux", "MC2",  "MC2 Amp"},
 544        { "PGA Right Input Mux", "TXIN", "TXIN Amp"},
 545        { "PGA Right Input Mux", "RXINR", "RXINR"},
 546
 547        { "PGA Left Input", NULL, "PGA Left Input Mux"},
 548        { "PGA Right Input", NULL, "PGA Right Input Mux"},
 549
 550        { "ADC", NULL, "PGA Left Input"},
 551        { "ADC", NULL, "PGA Right Input"},
 552        { "ADC", NULL, "ADC_Reset"},
 553
 554/* Output */
 555        { "HSL", NULL, "Headset Amp Left" },
 556        { "HSR", NULL, "Headset Amp Right"},
 557        { "RXOUTL", NULL, "Line out Amp Left"},
 558        { "RXOUTR", NULL, "Line out Amp Right"},
 559        { "SP", NULL, "Speaker Amp"},
 560        { "Speaker Amp", NULL, "DAC PGA"},
 561        { "LSP", NULL, "DAC PGA"},
 562        { "Headset Amp Left", NULL, "DAC PGA"},
 563        { "Headset Amp Right", NULL, "DAC PGA"},
 564        { "Line out Amp Left", NULL, "DAC PGA"},
 565        { "Line out Amp Right", NULL, "DAC PGA"},
 566        { "DAC PGA", NULL, "DAC"},
 567        { "DAC", NULL, "DAC_E"},
 568};
 569
 570static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix",
 571                                                "Mono", "Mono Mix"};
 572
 573static const struct soc_enum mc13783_enum_3d_mixer =
 574        SOC_ENUM_SINGLE(MC13783_AUDIO_RX1, 16, ARRAY_SIZE(mc13783_3d_mixer),
 575                        mc13783_3d_mixer);
 576
 577static struct snd_kcontrol_new mc13783_control_list[] = {
 578        SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0),
 579        SOC_SINGLE("PCM Playback Volume", MC13783_AUDIO_RX1, 6, 15, 0),
 580        SOC_DOUBLE("PCM Capture Volume", MC13783_AUDIO_TX, 19, 14, 31, 0),
 581        SOC_ENUM("3D Control", mc13783_enum_3d_mixer),
 582};
 583
 584static int mc13783_probe(struct snd_soc_codec *codec)
 585{
 586        struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
 587
 588        mc13xxx_lock(priv->mc13xxx);
 589
 590        /* these are the reset values */
 591        mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
 592        mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A);
 593        mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_TX, 0x420000);
 594        mc13xxx_reg_write(priv->mc13xxx, MC13783_SSI_NETWORK, 0x013060);
 595        mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_CODEC, 0x180027);
 596        mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_DAC, 0x0e0004);
 597
 598        if (priv->adc_ssi_port == MC13783_SSI1_PORT)
 599                mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC,
 600                                AUDIO_SSI_SEL, 0);
 601        else
 602                mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC,
 603                                0, AUDIO_SSI_SEL);
 604
 605        if (priv->dac_ssi_port == MC13783_SSI1_PORT)
 606                mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
 607                                AUDIO_SSI_SEL, 0);
 608        else
 609                mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
 610                                0, AUDIO_SSI_SEL);
 611
 612        mc13xxx_unlock(priv->mc13xxx);
 613
 614        return 0;
 615}
 616
 617static int mc13783_remove(struct snd_soc_codec *codec)
 618{
 619        struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
 620
 621        mc13xxx_lock(priv->mc13xxx);
 622
 623        /* Make sure VAUDIOON is off */
 624        mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
 625
 626        mc13xxx_unlock(priv->mc13xxx);
 627
 628        return 0;
 629}
 630
 631#define MC13783_RATES_RECORD (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
 632
 633#define MC13783_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 634        SNDRV_PCM_FMTBIT_S24_LE)
 635
 636static struct snd_soc_dai_ops mc13783_ops_dac = {
 637        .hw_params      = mc13783_pcm_hw_params_dac,
 638        .set_fmt        = mc13783_set_fmt_async,
 639        .set_sysclk     = mc13783_set_sysclk_dac,
 640        .set_tdm_slot   = mc13783_set_tdm_slot_dac,
 641};
 642
 643static struct snd_soc_dai_ops mc13783_ops_codec = {
 644        .hw_params      = mc13783_pcm_hw_params_codec,
 645        .set_fmt        = mc13783_set_fmt_async,
 646        .set_sysclk     = mc13783_set_sysclk_codec,
 647        .set_tdm_slot   = mc13783_set_tdm_slot_codec,
 648};
 649
 650/*
 651 * The mc13783 has two SSI ports, both of them can be routed either
 652 * to the voice codec or the stereo DAC. When two different SSI ports
 653 * are used for the voice codec and the stereo DAC we can do different
 654 * formats and sysclock settings for playback and capture
 655 * (mc13783-hifi-playback and mc13783-hifi-capture). Using the same port
 656 * forces us to use symmetric rates (mc13783-hifi).
 657 */
 658static struct snd_soc_dai_driver mc13783_dai_async[] = {
 659        {
 660                .name = "mc13783-hifi-playback",
 661                .id = MC13783_ID_STEREO_DAC,
 662                .playback = {
 663                        .stream_name = "Playback",
 664                        .channels_min = 2,
 665                        .channels_max = 2,
 666                        .rates = SNDRV_PCM_RATE_8000_96000,
 667                        .formats = MC13783_FORMATS,
 668                },
 669                .ops = &mc13783_ops_dac,
 670        }, {
 671                .name = "mc13783-hifi-capture",
 672                .id = MC13783_ID_STEREO_CODEC,
 673                .capture = {
 674                        .stream_name = "Capture",
 675                        .channels_min = 2,
 676                        .channels_max = 2,
 677                        .rates = MC13783_RATES_RECORD,
 678                        .formats = MC13783_FORMATS,
 679                },
 680                .ops = &mc13783_ops_codec,
 681        },
 682};
 683
 684static struct snd_soc_dai_ops mc13783_ops_sync = {
 685        .hw_params      = mc13783_pcm_hw_params_sync,
 686        .set_fmt        = mc13783_set_fmt_sync,
 687        .set_sysclk     = mc13783_set_sysclk_sync,
 688        .set_tdm_slot   = mc13783_set_tdm_slot_sync,
 689};
 690
 691static struct snd_soc_dai_driver mc13783_dai_sync[] = {
 692        {
 693                .name = "mc13783-hifi",
 694                .id = MC13783_ID_SYNC,
 695                .playback = {
 696                        .stream_name = "Playback",
 697                        .channels_min = 2,
 698                        .channels_max = 2,
 699                        .rates = SNDRV_PCM_RATE_8000_96000,
 700                        .formats = MC13783_FORMATS,
 701                },
 702                .capture = {
 703                        .stream_name = "Capture",
 704                        .channels_min = 2,
 705                        .channels_max = 2,
 706                        .rates = MC13783_RATES_RECORD,
 707                        .formats = MC13783_FORMATS,
 708                },
 709                .ops = &mc13783_ops_sync,
 710                .symmetric_rates = 1,
 711        }
 712};
 713
 714static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
 715        .probe          = mc13783_probe,
 716        .remove         = mc13783_remove,
 717        .read           = mc13783_read,
 718        .write          = mc13783_write,
 719        .controls       = mc13783_control_list,
 720        .num_controls   = ARRAY_SIZE(mc13783_control_list),
 721        .dapm_widgets   = mc13783_dapm_widgets,
 722        .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets),
 723        .dapm_routes    = mc13783_routes,
 724        .num_dapm_routes = ARRAY_SIZE(mc13783_routes),
 725};
 726
 727static int mc13783_codec_probe(struct platform_device *pdev)
 728{
 729        struct mc13xxx *mc13xxx;
 730        struct mc13783_priv *priv;
 731        struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data;
 732        int ret;
 733
 734        mc13xxx = dev_get_drvdata(pdev->dev.parent);
 735
 736
 737        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 738        if (priv == NULL)
 739                return -ENOMEM;
 740
 741        dev_set_drvdata(&pdev->dev, priv);
 742        priv->mc13xxx = mc13xxx;
 743        if (pdata) {
 744                priv->adc_ssi_port = pdata->adc_ssi_port;
 745                priv->dac_ssi_port = pdata->dac_ssi_port;
 746        } else {
 747                priv->adc_ssi_port = MC13783_SSI1_PORT;
 748                priv->dac_ssi_port = MC13783_SSI2_PORT;
 749        }
 750
 751        if (priv->adc_ssi_port == priv->dac_ssi_port)
 752                ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
 753                        mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
 754        else
 755                ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
 756                        mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
 757
 758        if (ret)
 759                goto err_register_codec;
 760
 761        return 0;
 762
 763err_register_codec:
 764        dev_err(&pdev->dev, "register codec failed with %d\n", ret);
 765
 766        return ret;
 767}
 768
 769static int mc13783_codec_remove(struct platform_device *pdev)
 770{
 771        snd_soc_unregister_codec(&pdev->dev);
 772
 773        return 0;
 774}
 775
 776static struct platform_driver mc13783_codec_driver = {
 777        .driver = {
 778                   .name = "mc13783-codec",
 779                   .owner = THIS_MODULE,
 780                   },
 781        .probe = mc13783_codec_probe,
 782        .remove = mc13783_codec_remove,
 783};
 784
 785module_platform_driver(mc13783_codec_driver);
 786
 787MODULE_DESCRIPTION("ASoC MC13783 driver");
 788MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
 789MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
 790MODULE_LICENSE("GPL");
 791