linux/sound/soc/codecs/jz4770.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Ingenic JZ4770 CODEC driver
   4//
   5// Copyright (C) 2012, Maarten ter Huurne <maarten@treewalker.org>
   6// Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
   7
   8#include <linux/clk.h>
   9#include <linux/delay.h>
  10#include <linux/iopoll.h>
  11#include <linux/module.h>
  12#include <linux/regmap.h>
  13#include <linux/time64.h>
  14
  15#include <sound/pcm_params.h>
  16#include <sound/soc.h>
  17#include <sound/soc-dai.h>
  18#include <sound/soc-dapm.h>
  19#include <sound/tlv.h>
  20
  21#define ICDC_RGADW_OFFSET               0x00
  22#define ICDC_RGDATA_OFFSET              0x04
  23
  24/* ICDC internal register access control register(RGADW) */
  25#define ICDC_RGADW_RGWR                 BIT(16)
  26
  27#define ICDC_RGADW_RGADDR_OFFSET        8
  28#define ICDC_RGADW_RGADDR_MASK          GENMASK(14, ICDC_RGADW_RGADDR_OFFSET)
  29
  30#define ICDC_RGADW_RGDIN_OFFSET         0
  31#define ICDC_RGADW_RGDIN_MASK           GENMASK(7, ICDC_RGADW_RGDIN_OFFSET)
  32
  33/* ICDC internal register data output register (RGDATA)*/
  34#define ICDC_RGDATA_IRQ                 BIT(8)
  35
  36#define ICDC_RGDATA_RGDOUT_OFFSET       0
  37#define ICDC_RGDATA_RGDOUT_MASK         GENMASK(7, ICDC_RGDATA_RGDOUT_OFFSET)
  38
  39/* Internal register space, accessed through regmap */
  40enum {
  41        JZ4770_CODEC_REG_SR,
  42        JZ4770_CODEC_REG_AICR_DAC,
  43        JZ4770_CODEC_REG_AICR_ADC,
  44        JZ4770_CODEC_REG_CR_LO,
  45        JZ4770_CODEC_REG_CR_HP,
  46
  47        JZ4770_CODEC_REG_MISSING_REG1,
  48
  49        JZ4770_CODEC_REG_CR_DAC,
  50        JZ4770_CODEC_REG_CR_MIC,
  51        JZ4770_CODEC_REG_CR_LI,
  52        JZ4770_CODEC_REG_CR_ADC,
  53        JZ4770_CODEC_REG_CR_MIX,
  54        JZ4770_CODEC_REG_CR_VIC,
  55        JZ4770_CODEC_REG_CCR,
  56        JZ4770_CODEC_REG_FCR_DAC,
  57        JZ4770_CODEC_REG_FCR_ADC,
  58        JZ4770_CODEC_REG_ICR,
  59        JZ4770_CODEC_REG_IMR,
  60        JZ4770_CODEC_REG_IFR,
  61        JZ4770_CODEC_REG_GCR_HPL,
  62        JZ4770_CODEC_REG_GCR_HPR,
  63        JZ4770_CODEC_REG_GCR_LIBYL,
  64        JZ4770_CODEC_REG_GCR_LIBYR,
  65        JZ4770_CODEC_REG_GCR_DACL,
  66        JZ4770_CODEC_REG_GCR_DACR,
  67        JZ4770_CODEC_REG_GCR_MIC1,
  68        JZ4770_CODEC_REG_GCR_MIC2,
  69        JZ4770_CODEC_REG_GCR_ADCL,
  70        JZ4770_CODEC_REG_GCR_ADCR,
  71
  72        JZ4770_CODEC_REG_MISSING_REG2,
  73
  74        JZ4770_CODEC_REG_GCR_MIXADC,
  75        JZ4770_CODEC_REG_GCR_MIXDAC,
  76        JZ4770_CODEC_REG_AGC1,
  77        JZ4770_CODEC_REG_AGC2,
  78        JZ4770_CODEC_REG_AGC3,
  79        JZ4770_CODEC_REG_AGC4,
  80        JZ4770_CODEC_REG_AGC5,
  81};
  82
  83#define REG_AICR_DAC_ADWL_OFFSET        6
  84#define REG_AICR_DAC_ADWL_MASK          (0x3 << REG_AICR_DAC_ADWL_OFFSET)
  85#define REG_AICR_DAC_SERIAL             BIT(1)
  86#define REG_AICR_DAC_I2S                BIT(0)
  87
  88#define REG_AICR_ADC_ADWL_OFFSET        6
  89#define REG_AICR_ADC_ADWL_MASK          (0x3 << REG_AICR_ADC_ADWL_OFFSET)
  90#define REG_AICR_ADC_SERIAL             BIT(1)
  91#define REG_AICR_ADC_I2S                BIT(0)
  92
  93#define REG_CR_LO_MUTE_OFFSET           7
  94#define REG_CR_LO_SB_OFFSET             4
  95#define REG_CR_LO_SEL_OFFSET            0
  96#define REG_CR_LO_SEL_MASK              (0x3 << REG_CR_LO_SEL_OFFSET)
  97
  98#define REG_CR_HP_MUTE                  BIT(7)
  99#define REG_CR_HP_LOAD                  BIT(6)
 100#define REG_CR_HP_SB_OFFSET             4
 101#define REG_CR_HP_SB_HPCM_OFFSET        3
 102#define REG_CR_HP_SEL_OFFSET            0
 103#define REG_CR_HP_SEL_MASK              (0x3 << REG_CR_HP_SEL_OFFSET)
 104
 105#define REG_CR_DAC_MUTE                 BIT(7)
 106#define REG_CR_DAC_MONO                 BIT(6)
 107#define REG_CR_DAC_LEFT_ONLY            BIT(5)
 108#define REG_CR_DAC_SB_OFFSET            4
 109#define REG_CR_DAC_LRSWAP               BIT(3)
 110
 111#define REG_CR_MIC_STEREO_OFFSET        7
 112#define REG_CR_MIC_IDIFF_OFFSET         6
 113#define REG_CR_MIC_SB_MIC2_OFFSET       5
 114#define REG_CR_MIC_SB_MIC1_OFFSET       4
 115#define REG_CR_MIC_BIAS_V0_OFFSET       1
 116#define REG_CR_MIC_BIAS_SB_OFFSET       0
 117
 118#define REG_CR_LI_LIBY_OFFSET           4
 119#define REG_CR_LI_SB_OFFSET             0
 120
 121#define REG_CR_ADC_DMIC_SEL             BIT(7)
 122#define REG_CR_ADC_MONO                 BIT(6)
 123#define REG_CR_ADC_LEFT_ONLY            BIT(5)
 124#define REG_CR_ADC_SB_OFFSET            4
 125#define REG_CR_ADC_LRSWAP               BIT(3)
 126#define REG_CR_ADC_IN_SEL_OFFSET        0
 127#define REG_CR_ADC_IN_SEL_MASK          (0x3 << REG_CR_ADC_IN_SEL_OFFSET)
 128
 129#define REG_CR_VIC_SB_SLEEP             BIT(1)
 130#define REG_CR_VIC_SB                   BIT(0)
 131
 132#define REG_CCR_CRYSTAL_OFFSET          0
 133#define REG_CCR_CRYSTAL_MASK            (0xf << REG_CCR_CRYSTAL_OFFSET)
 134
 135#define REG_FCR_DAC_FREQ_OFFSET         0
 136#define REG_FCR_DAC_FREQ_MASK           (0xf << REG_FCR_DAC_FREQ_OFFSET)
 137
 138#define REG_FCR_ADC_FREQ_OFFSET         0
 139#define REG_FCR_ADC_FREQ_MASK           (0xf << REG_FCR_ADC_FREQ_OFFSET)
 140
 141#define REG_ICR_INT_FORM_OFFSET         6
 142#define REG_ICR_INT_FORM_MASK           (0x3 << REG_ICR_INT_FORM_OFFSET)
 143
 144#define REG_IMR_ALL_MASK                (0x7f)
 145#define REG_IMR_SCLR_MASK               BIT(6)
 146#define REG_IMR_JACK_MASK               BIT(5)
 147#define REG_IMR_SCMC_MASK               BIT(4)
 148#define REG_IMR_RUP_MASK                BIT(3)
 149#define REG_IMR_RDO_MASK                BIT(2)
 150#define REG_IMR_GUP_MASK                BIT(1)
 151#define REG_IMR_GDO_MASK                BIT(0)
 152
 153#define REG_IFR_ALL_MASK                (0x7f)
 154#define REG_IFR_SCLR                    BIT(6)
 155#define REG_IFR_JACK                    BIT(5)
 156#define REG_IFR_SCMC                    BIT(4)
 157#define REG_IFR_RUP                     BIT(3)
 158#define REG_IFR_RDO                     BIT(2)
 159#define REG_IFR_GUP                     BIT(1)
 160#define REG_IFR_GDO                     BIT(0)
 161
 162#define REG_GCR_HPL_LRGO                BIT(7)
 163
 164#define REG_GCR_DACL_RLGOD              BIT(7)
 165
 166#define REG_GCR_GAIN_OFFSET             0
 167#define REG_GCR_GAIN_MAX                0x1f
 168
 169#define REG_GCR_MIC_GAIN_OFFSET         0
 170#define REG_GCR_MIC_GAIN_MAX            5
 171
 172#define REG_GCR_ADC_GAIN_OFFSET         0
 173#define REG_GCR_ADC_GAIN_MAX            23
 174
 175#define REG_AGC1_EN                     BIT(7)
 176
 177/* codec private data */
 178struct jz_codec {
 179        struct device *dev;
 180        struct regmap *regmap;
 181        void __iomem *base;
 182        struct clk *clk;
 183};
 184
 185static int jz4770_codec_set_bias_level(struct snd_soc_component *codec,
 186                                       enum snd_soc_bias_level level)
 187{
 188        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 189        struct regmap *regmap = jz_codec->regmap;
 190
 191        switch (level) {
 192        case SND_SOC_BIAS_PREPARE:
 193                /* Reset all interrupt flags. */
 194                regmap_write(regmap, JZ4770_CODEC_REG_IFR, REG_IFR_ALL_MASK);
 195
 196                regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
 197                                  REG_CR_VIC_SB);
 198                msleep(250);
 199                regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
 200                                  REG_CR_VIC_SB_SLEEP);
 201                msleep(400);
 202                break;
 203        case SND_SOC_BIAS_STANDBY:
 204                regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
 205                                REG_CR_VIC_SB_SLEEP);
 206                regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_VIC,
 207                                REG_CR_VIC_SB);
 208                fallthrough;
 209        default:
 210                break;
 211        }
 212
 213        return 0;
 214}
 215
 216static int jz4770_codec_startup(struct snd_pcm_substream *substream,
 217                                struct snd_soc_dai *dai)
 218{
 219        struct snd_soc_component *codec = dai->component;
 220        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
 221
 222        /*
 223         * SYSCLK output from the codec to the AIC is required to keep the
 224         * DMA transfer going during playback when all audible outputs have
 225         * been disabled.
 226         */
 227        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 228                snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
 229
 230        return 0;
 231}
 232
 233static void jz4770_codec_shutdown(struct snd_pcm_substream *substream,
 234                                  struct snd_soc_dai *dai)
 235{
 236        struct snd_soc_component *codec = dai->component;
 237        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
 238
 239        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 240                snd_soc_dapm_disable_pin(dapm, "SYSCLK");
 241}
 242
 243
 244static int jz4770_codec_pcm_trigger(struct snd_pcm_substream *substream,
 245                                    int cmd, struct snd_soc_dai *dai)
 246{
 247        struct snd_soc_component *codec = dai->component;
 248        int ret = 0;
 249
 250        switch (cmd) {
 251        case SNDRV_PCM_TRIGGER_START:
 252        case SNDRV_PCM_TRIGGER_RESUME:
 253        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 254                if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
 255                        snd_soc_component_force_bias_level(codec,
 256                                                           SND_SOC_BIAS_ON);
 257                break;
 258        case SNDRV_PCM_TRIGGER_STOP:
 259        case SNDRV_PCM_TRIGGER_SUSPEND:
 260        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 261                /* do nothing */
 262                break;
 263        default:
 264                ret = -EINVAL;
 265        }
 266
 267        return ret;
 268}
 269
 270static int jz4770_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
 271{
 272        struct snd_soc_component *codec = dai->component;
 273        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 274        unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
 275        unsigned int val;
 276        int change, err;
 277
 278        change = snd_soc_component_update_bits(codec, JZ4770_CODEC_REG_CR_DAC,
 279                                               REG_CR_DAC_MUTE,
 280                                               mute ? REG_CR_DAC_MUTE : 0);
 281        if (change == 1) {
 282                regmap_read(jz_codec->regmap, JZ4770_CODEC_REG_CR_DAC, &val);
 283
 284                if (val & BIT(REG_CR_DAC_SB_OFFSET))
 285                        return 1;
 286
 287                err = regmap_read_poll_timeout(jz_codec->regmap,
 288                                               JZ4770_CODEC_REG_IFR,
 289                                               val, val & gain_bit,
 290                                               1000, 1 * USEC_PER_SEC);
 291                if (err) {
 292                        dev_err(jz_codec->dev,
 293                                "Timeout while setting digital mute: %d", err);
 294                        return err;
 295                }
 296
 297                /* clear GUP/GDO flag */
 298                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
 299                                gain_bit);
 300        }
 301
 302        return 0;
 303}
 304
 305/* unit: 0.01dB */
 306static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 0);
 307static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
 308static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 600);
 309static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
 310
 311/* Unconditional controls. */
 312static const struct snd_kcontrol_new jz4770_codec_snd_controls[] = {
 313        /* record gain control */
 314        SOC_DOUBLE_R_TLV("PCM Capture Volume",
 315                         JZ4770_CODEC_REG_GCR_ADCL, JZ4770_CODEC_REG_GCR_ADCR,
 316                         REG_GCR_ADC_GAIN_OFFSET, REG_GCR_ADC_GAIN_MAX,
 317                         0, adc_tlv),
 318
 319        SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
 320                         JZ4770_CODEC_REG_GCR_LIBYL, JZ4770_CODEC_REG_GCR_LIBYR,
 321                         REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
 322};
 323
 324static const struct snd_kcontrol_new jz4770_codec_pcm_playback_controls[] = {
 325        {
 326                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 327                .name = "Volume",
 328                .info = snd_soc_info_volsw,
 329                .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
 330                        | SNDRV_CTL_ELEM_ACCESS_READWRITE,
 331                .tlv.p = dac_tlv,
 332                .get = snd_soc_dapm_get_volsw,
 333                .put = snd_soc_dapm_put_volsw,
 334                /*
 335                 * NOTE: DACR/DACL are inversed; the gain value written to DACR
 336                 * seems to affect the left channel, and the gain value written
 337                 * to DACL seems to affect the right channel.
 338                 */
 339                .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_DACR,
 340                                                    JZ4770_CODEC_REG_GCR_DACL,
 341                                                    REG_GCR_GAIN_OFFSET,
 342                                                    REG_GCR_GAIN_MAX, 1),
 343        },
 344};
 345
 346static const struct snd_kcontrol_new jz4770_codec_hp_playback_controls[] = {
 347        {
 348                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 349                .name = "Volume",
 350                .info = snd_soc_info_volsw,
 351                .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
 352                        | SNDRV_CTL_ELEM_ACCESS_READWRITE,
 353                .tlv.p = out_tlv,
 354                .get = snd_soc_dapm_get_volsw,
 355                .put = snd_soc_dapm_put_volsw,
 356                /* HPR/HPL inversed for the same reason as above */
 357                .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_HPR,
 358                                                    JZ4770_CODEC_REG_GCR_HPL,
 359                                                    REG_GCR_GAIN_OFFSET,
 360                                                    REG_GCR_GAIN_MAX, 1),
 361        },
 362};
 363
 364static int hpout_event(struct snd_soc_dapm_widget *w,
 365                       struct snd_kcontrol *kcontrol, int event)
 366{
 367        struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
 368        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 369        unsigned int val;
 370        int err;
 371
 372        switch (event) {
 373        case SND_SOC_DAPM_PRE_PMU:
 374                /* unmute HP */
 375                regmap_clear_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
 376                                  REG_CR_HP_MUTE);
 377                break;
 378
 379        case SND_SOC_DAPM_POST_PMU:
 380                /* wait for ramp-up complete (RUP) */
 381                err = regmap_read_poll_timeout(jz_codec->regmap,
 382                                               JZ4770_CODEC_REG_IFR,
 383                                               val, val & REG_IFR_RUP,
 384                                               1000, 1 * USEC_PER_SEC);
 385                if (err) {
 386                        dev_err(jz_codec->dev, "RUP timeout: %d", err);
 387                        return err;
 388                }
 389
 390                /* clear RUP flag */
 391                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
 392                                REG_IFR_RUP);
 393
 394                break;
 395
 396        case SND_SOC_DAPM_POST_PMD:
 397                /* mute HP */
 398                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
 399                                REG_CR_HP_MUTE);
 400
 401                err = regmap_read_poll_timeout(jz_codec->regmap,
 402                                               JZ4770_CODEC_REG_IFR,
 403                                               val, val & REG_IFR_RDO,
 404                                               1000, 1 * USEC_PER_SEC);
 405                if (err) {
 406                        dev_err(jz_codec->dev, "RDO timeout: %d", err);
 407                        return err;
 408                }
 409
 410                /* clear RDO flag */
 411                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
 412                                REG_IFR_RDO);
 413
 414                break;
 415        }
 416
 417        return 0;
 418}
 419
 420static int adc_poweron_event(struct snd_soc_dapm_widget *w,
 421                             struct snd_kcontrol *kcontrol, int event)
 422{
 423        if (event == SND_SOC_DAPM_POST_PMU)
 424                msleep(1000);
 425
 426        return 0;
 427}
 428
 429static const char * const jz4770_codec_hp_texts[] = {
 430        "PCM", "Line In", "Mic 1", "Mic 2"
 431};
 432static const unsigned int jz4770_codec_hp_values[] = { 3, 2, 0, 1 };
 433static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_hp_enum,
 434                                  JZ4770_CODEC_REG_CR_HP,
 435                                  REG_CR_HP_SEL_OFFSET,
 436                                  REG_CR_HP_SEL_MASK,
 437                                  jz4770_codec_hp_texts,
 438                                  jz4770_codec_hp_values);
 439static const struct snd_kcontrol_new jz4770_codec_hp_source =
 440                        SOC_DAPM_ENUM("Route", jz4770_codec_hp_enum);
 441
 442static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_lo_enum,
 443                                  JZ4770_CODEC_REG_CR_LO,
 444                                  REG_CR_LO_SEL_OFFSET,
 445                                  REG_CR_LO_SEL_MASK,
 446                                  jz4770_codec_hp_texts,
 447                                  jz4770_codec_hp_values);
 448static const struct snd_kcontrol_new jz4770_codec_lo_source =
 449                        SOC_DAPM_ENUM("Route", jz4770_codec_lo_enum);
 450
 451static const char * const jz4770_codec_cap_texts[] = {
 452        "Line In", "Mic 1", "Mic 2"
 453};
 454static const unsigned int jz4770_codec_cap_values[] = { 2, 0, 1 };
 455static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_cap_enum,
 456                                  JZ4770_CODEC_REG_CR_ADC,
 457                                  REG_CR_ADC_IN_SEL_OFFSET,
 458                                  REG_CR_ADC_IN_SEL_MASK,
 459                                  jz4770_codec_cap_texts,
 460                                  jz4770_codec_cap_values);
 461static const struct snd_kcontrol_new jz4770_codec_cap_source =
 462                        SOC_DAPM_ENUM("Route", jz4770_codec_cap_enum);
 463
 464static const struct snd_kcontrol_new jz4770_codec_mic_controls[] = {
 465        SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4770_CODEC_REG_CR_MIC,
 466                        REG_CR_MIC_STEREO_OFFSET, 1, 0),
 467};
 468
 469static const struct snd_soc_dapm_widget jz4770_codec_dapm_widgets[] = {
 470        SND_SOC_DAPM_PGA_E("HP Out", JZ4770_CODEC_REG_CR_HP,
 471                           REG_CR_HP_SB_OFFSET, 1, NULL, 0, hpout_event,
 472                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 473                           SND_SOC_DAPM_POST_PMD),
 474
 475        SND_SOC_DAPM_PGA("Line Out", JZ4770_CODEC_REG_CR_LO,
 476                         REG_CR_LO_SB_OFFSET, 1, NULL, 0),
 477
 478        SND_SOC_DAPM_PGA("Line Out Switch 2", JZ4770_CODEC_REG_CR_LO,
 479                         REG_CR_LO_MUTE_OFFSET, 1, NULL, 0),
 480
 481        SND_SOC_DAPM_PGA("Line In", JZ4770_CODEC_REG_CR_LI,
 482                         REG_CR_LI_SB_OFFSET, 1, NULL, 0),
 483
 484        SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
 485                         &jz4770_codec_hp_source),
 486        SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
 487                         &jz4770_codec_cap_source),
 488        SND_SOC_DAPM_MUX("Line Out Source", SND_SOC_NOPM, 0, 0,
 489                         &jz4770_codec_lo_source),
 490
 491        SND_SOC_DAPM_PGA("Mic 1", JZ4770_CODEC_REG_CR_MIC,
 492                         REG_CR_MIC_SB_MIC1_OFFSET, 1, NULL, 0),
 493        SND_SOC_DAPM_PGA("Mic 2", JZ4770_CODEC_REG_CR_MIC,
 494                         REG_CR_MIC_SB_MIC2_OFFSET, 1, NULL, 0),
 495
 496        SND_SOC_DAPM_PGA("Mic Diff", JZ4770_CODEC_REG_CR_MIC,
 497                         REG_CR_MIC_IDIFF_OFFSET, 0, NULL, 0),
 498
 499        SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
 500                           jz4770_codec_mic_controls,
 501                           ARRAY_SIZE(jz4770_codec_mic_controls)),
 502
 503        SND_SOC_DAPM_PGA("Line In Bypass", JZ4770_CODEC_REG_CR_LI,
 504                         REG_CR_LI_LIBY_OFFSET, 1, NULL, 0),
 505
 506        SND_SOC_DAPM_ADC_E("ADC", "HiFi Capture", JZ4770_CODEC_REG_CR_ADC,
 507                           REG_CR_ADC_SB_OFFSET, 1, adc_poweron_event,
 508                           SND_SOC_DAPM_POST_PMU),
 509        SND_SOC_DAPM_DAC("DAC", "HiFi Playback", JZ4770_CODEC_REG_CR_DAC,
 510                         REG_CR_DAC_SB_OFFSET, 1),
 511
 512        SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
 513                           jz4770_codec_pcm_playback_controls,
 514                           ARRAY_SIZE(jz4770_codec_pcm_playback_controls)),
 515        SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
 516                           jz4770_codec_hp_playback_controls,
 517                           ARRAY_SIZE(jz4770_codec_hp_playback_controls)),
 518
 519        SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4770_CODEC_REG_CR_MIC,
 520                            REG_CR_MIC_BIAS_SB_OFFSET, 1, NULL, 0),
 521
 522        SND_SOC_DAPM_SUPPLY("Cap-less", JZ4770_CODEC_REG_CR_HP,
 523                            REG_CR_HP_SB_HPCM_OFFSET, 1, NULL, 0),
 524
 525        SND_SOC_DAPM_INPUT("MIC1P"),
 526        SND_SOC_DAPM_INPUT("MIC1N"),
 527        SND_SOC_DAPM_INPUT("MIC2P"),
 528        SND_SOC_DAPM_INPUT("MIC2N"),
 529
 530        SND_SOC_DAPM_OUTPUT("LOUT"),
 531        SND_SOC_DAPM_OUTPUT("ROUT"),
 532
 533        SND_SOC_DAPM_OUTPUT("LHPOUT"),
 534        SND_SOC_DAPM_OUTPUT("RHPOUT"),
 535
 536        SND_SOC_DAPM_INPUT("LLINEIN"),
 537        SND_SOC_DAPM_INPUT("RLINEIN"),
 538
 539        SND_SOC_DAPM_OUTPUT("SYSCLK"),
 540};
 541
 542/* Unconditional routes. */
 543static const struct snd_soc_dapm_route jz4770_codec_dapm_routes[] = {
 544        { "Mic 1", NULL, "MIC1P" },
 545        { "Mic Diff", NULL, "MIC1N" },
 546        { "Mic 1", NULL, "Mic Diff" },
 547        { "Mic 2", NULL, "MIC2P" },
 548        { "Mic Diff", NULL, "MIC2N" },
 549        { "Mic 2", NULL, "Mic Diff" },
 550
 551        { "Line In", NULL, "LLINEIN" },
 552        { "Line In", NULL, "RLINEIN" },
 553
 554        { "Mic", "Stereo Capture Switch", "Mic 1" },
 555        { "Mic", "Stereo Capture Switch", "Mic 2" },
 556        { "Headphones Source", "Mic 1", "Mic" },
 557        { "Headphones Source", "Mic 2", "Mic" },
 558        { "Capture Source", "Mic 1", "Mic" },
 559        { "Capture Source", "Mic 2", "Mic" },
 560
 561        { "Headphones Source", "Mic 1", "Mic 1" },
 562        { "Headphones Source", "Mic 2", "Mic 2" },
 563        { "Headphones Source", "Line In", "Line In Bypass" },
 564        { "Headphones Source", "PCM", "Headphones Playback" },
 565        { "HP Out", NULL, "Headphones Source" },
 566
 567        { "Capture Source", "Line In", "Line In" },
 568        { "Capture Source", "Mic 1", "Mic 1" },
 569        { "Capture Source", "Mic 2", "Mic 2" },
 570        { "ADC", NULL, "Capture Source" },
 571
 572        { "Line In Bypass", NULL, "Line In" },
 573        { "Line Out Source", "Line In", "Line In Bypass" },
 574        { "Line Out Source", "PCM", "PCM Playback" },
 575
 576        { "LHPOUT", NULL, "HP Out"},
 577        { "RHPOUT", NULL, "HP Out"},
 578
 579        { "Line Out", NULL, "Line Out Source" },
 580        { "Line Out Switch 2", NULL, "Line Out" },
 581
 582        { "LOUT", NULL, "Line Out Switch 2"},
 583        { "ROUT", NULL, "Line Out Switch 2"},
 584
 585        { "PCM Playback", "Volume", "DAC" },
 586        { "Headphones Playback", "Volume", "PCM Playback" },
 587
 588        { "SYSCLK", NULL, "DAC" },
 589};
 590
 591static void jz4770_codec_codec_init_regs(struct snd_soc_component *codec)
 592{
 593        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 594        struct regmap *regmap = jz_codec->regmap;
 595
 596        /* Collect updates for later sending. */
 597        regcache_cache_only(regmap, true);
 598
 599        /* default HP output to PCM */
 600        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_HP, REG_CR_HP_SEL_MASK);
 601
 602        /* default line output to PCM */
 603        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_LO, REG_CR_LO_SEL_MASK);
 604
 605        /* Disable stereo mic */
 606        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_MIC,
 607                          BIT(REG_CR_MIC_STEREO_OFFSET));
 608
 609        /* Set mic 1 as default source for ADC */
 610        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_ADC,
 611                          REG_CR_ADC_IN_SEL_MASK);
 612
 613        /* ADC/DAC: serial + i2s */
 614        regmap_set_bits(regmap, JZ4770_CODEC_REG_AICR_ADC,
 615                        REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S);
 616        regmap_set_bits(regmap, JZ4770_CODEC_REG_AICR_DAC,
 617                        REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
 618
 619        /* The generated IRQ is a high level */
 620        regmap_clear_bits(regmap, JZ4770_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
 621        regmap_update_bits(regmap, JZ4770_CODEC_REG_IMR, REG_IMR_ALL_MASK,
 622                           REG_IMR_JACK_MASK | REG_IMR_RUP_MASK |
 623                           REG_IMR_RDO_MASK | REG_IMR_GUP_MASK |
 624                           REG_IMR_GDO_MASK);
 625
 626        /* 12M oscillator */
 627        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CCR, REG_CCR_CRYSTAL_MASK);
 628
 629        /* 0: 16ohm/220uF, 1: 10kohm/1uF */
 630        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_HP, REG_CR_HP_LOAD);
 631
 632        /* disable automatic gain */
 633        regmap_clear_bits(regmap, JZ4770_CODEC_REG_AGC1, REG_AGC1_EN);
 634
 635        /* Disable DAC lrswap */
 636        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_DAC, REG_CR_DAC_LRSWAP);
 637
 638        /* Independent L/R DAC gain control */
 639        regmap_clear_bits(regmap, JZ4770_CODEC_REG_GCR_DACL,
 640                          REG_GCR_DACL_RLGOD);
 641
 642        /* Disable ADC lrswap */
 643        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_ADC, REG_CR_ADC_LRSWAP);
 644
 645        /* default to cap-less mode(0) */
 646        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_HP,
 647                          BIT(REG_CR_HP_SB_HPCM_OFFSET));
 648
 649        /* Send collected updates. */
 650        regcache_cache_only(regmap, false);
 651        regcache_sync(regmap);
 652}
 653
 654static int jz4770_codec_codec_probe(struct snd_soc_component *codec)
 655{
 656        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 657
 658        clk_prepare_enable(jz_codec->clk);
 659
 660        jz4770_codec_codec_init_regs(codec);
 661
 662        return 0;
 663}
 664
 665static void jz4770_codec_codec_remove(struct snd_soc_component *codec)
 666{
 667        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 668
 669        clk_disable_unprepare(jz_codec->clk);
 670}
 671
 672static const struct snd_soc_component_driver jz4770_codec_soc_codec_dev = {
 673        .probe                  = jz4770_codec_codec_probe,
 674        .remove                 = jz4770_codec_codec_remove,
 675        .set_bias_level         = jz4770_codec_set_bias_level,
 676        .controls               = jz4770_codec_snd_controls,
 677        .num_controls           = ARRAY_SIZE(jz4770_codec_snd_controls),
 678        .dapm_widgets           = jz4770_codec_dapm_widgets,
 679        .num_dapm_widgets       = ARRAY_SIZE(jz4770_codec_dapm_widgets),
 680        .dapm_routes            = jz4770_codec_dapm_routes,
 681        .num_dapm_routes        = ARRAY_SIZE(jz4770_codec_dapm_routes),
 682        .suspend_bias_off       = 1,
 683        .use_pmdown_time        = 1,
 684};
 685
 686static const unsigned int jz4770_codec_sample_rates[] = {
 687        96000, 48000, 44100, 32000,
 688        24000, 22050, 16000, 12000,
 689        11025, 9600, 8000,
 690};
 691
 692static int jz4770_codec_hw_params(struct snd_pcm_substream *substream,
 693                                  struct snd_pcm_hw_params *params,
 694                                  struct snd_soc_dai *dai)
 695{
 696        struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
 697        unsigned int rate, bit_width;
 698
 699        switch (params_format(params)) {
 700        case SNDRV_PCM_FORMAT_S16_LE:
 701                bit_width = 0;
 702                break;
 703        case SNDRV_PCM_FORMAT_S18_3LE:
 704                bit_width = 1;
 705                break;
 706        case SNDRV_PCM_FORMAT_S20_3LE:
 707                bit_width = 2;
 708                break;
 709        case SNDRV_PCM_FORMAT_S24_3LE:
 710                bit_width = 3;
 711                break;
 712        default:
 713                return -EINVAL;
 714        }
 715
 716        for (rate = 0; rate < ARRAY_SIZE(jz4770_codec_sample_rates); rate++) {
 717                if (jz4770_codec_sample_rates[rate] == params_rate(params))
 718                        break;
 719        }
 720
 721        if (rate == ARRAY_SIZE(jz4770_codec_sample_rates))
 722                return -EINVAL;
 723
 724        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 725                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_DAC,
 726                                   REG_AICR_DAC_ADWL_MASK,
 727                                   bit_width << REG_AICR_DAC_ADWL_OFFSET);
 728                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_DAC,
 729                                   REG_FCR_DAC_FREQ_MASK,
 730                                   rate << REG_FCR_DAC_FREQ_OFFSET);
 731        } else {
 732                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_ADC,
 733                                   REG_AICR_ADC_ADWL_MASK,
 734                                   bit_width << REG_AICR_ADC_ADWL_OFFSET);
 735                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_ADC,
 736                                   REG_FCR_ADC_FREQ_MASK,
 737                                   rate << REG_FCR_ADC_FREQ_OFFSET);
 738        }
 739
 740        return 0;
 741}
 742
 743static const struct snd_soc_dai_ops jz4770_codec_dai_ops = {
 744        .startup        = jz4770_codec_startup,
 745        .shutdown       = jz4770_codec_shutdown,
 746        .hw_params      = jz4770_codec_hw_params,
 747        .trigger        = jz4770_codec_pcm_trigger,
 748        .mute_stream    = jz4770_codec_mute_stream,
 749        .no_capture_mute = 1,
 750};
 751
 752#define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | \
 753                          SNDRV_PCM_FMTBIT_S18_3LE | \
 754                          SNDRV_PCM_FMTBIT_S20_3LE | \
 755                          SNDRV_PCM_FMTBIT_S24_3LE)
 756
 757static struct snd_soc_dai_driver jz4770_codec_dai = {
 758        .name = "jz4770-hifi",
 759        .playback = {
 760                .stream_name = "Playback",
 761                .channels_min = 2,
 762                .channels_max = 2,
 763                .rates = SNDRV_PCM_RATE_8000_96000,
 764                .formats = JZ_CODEC_FORMATS,
 765        },
 766        .capture = {
 767                .stream_name = "Capture",
 768                .channels_min = 2,
 769                .channels_max = 2,
 770                .rates = SNDRV_PCM_RATE_8000_96000,
 771                .formats = JZ_CODEC_FORMATS,
 772        },
 773        .ops = &jz4770_codec_dai_ops,
 774};
 775
 776static bool jz4770_codec_volatile(struct device *dev, unsigned int reg)
 777{
 778        return reg == JZ4770_CODEC_REG_SR || reg == JZ4770_CODEC_REG_IFR;
 779}
 780
 781static bool jz4770_codec_readable(struct device *dev, unsigned int reg)
 782{
 783        switch (reg) {
 784        case JZ4770_CODEC_REG_MISSING_REG1:
 785        case JZ4770_CODEC_REG_MISSING_REG2:
 786                return false;
 787        default:
 788                return true;
 789        }
 790}
 791
 792static bool jz4770_codec_writeable(struct device *dev, unsigned int reg)
 793{
 794        switch (reg) {
 795        case JZ4770_CODEC_REG_SR:
 796        case JZ4770_CODEC_REG_MISSING_REG1:
 797        case JZ4770_CODEC_REG_MISSING_REG2:
 798                return false;
 799        default:
 800                return true;
 801        }
 802}
 803
 804static int jz4770_codec_io_wait(struct jz_codec *codec)
 805{
 806        u32 reg;
 807
 808        return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
 809                                  !(reg & ICDC_RGADW_RGWR),
 810                                  1000, 1 * USEC_PER_SEC);
 811}
 812
 813static int jz4770_codec_reg_read(void *context, unsigned int reg,
 814                                 unsigned int *val)
 815{
 816        struct jz_codec *codec = context;
 817        unsigned int i;
 818        u32 tmp;
 819        int ret;
 820
 821        ret = jz4770_codec_io_wait(codec);
 822        if (ret)
 823                return ret;
 824
 825        tmp = readl(codec->base + ICDC_RGADW_OFFSET);
 826        tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
 827            | (reg << ICDC_RGADW_RGADDR_OFFSET);
 828        writel(tmp, codec->base + ICDC_RGADW_OFFSET);
 829
 830        /* wait 6+ cycles */
 831        for (i = 0; i < 6; i++)
 832                *val = readl(codec->base + ICDC_RGDATA_OFFSET) &
 833                        ICDC_RGDATA_RGDOUT_MASK;
 834
 835        return 0;
 836}
 837
 838static int jz4770_codec_reg_write(void *context, unsigned int reg,
 839                                  unsigned int val)
 840{
 841        struct jz_codec *codec = context;
 842        int ret;
 843
 844        ret = jz4770_codec_io_wait(codec);
 845        if (ret)
 846                return ret;
 847
 848        writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
 849               codec->base + ICDC_RGADW_OFFSET);
 850
 851        ret = jz4770_codec_io_wait(codec);
 852        if (ret)
 853                return ret;
 854
 855        return 0;
 856}
 857
 858static const u8 jz4770_codec_reg_defaults[] = {
 859        0x00, 0xC3, 0xC3, 0x90, 0x98, 0xFF, 0x90, 0xB1,
 860        0x11, 0x10, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00,
 861        0xFF, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
 862        0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x34,
 863        0x07, 0x44, 0x1F, 0x00
 864};
 865
 866static struct regmap_config jz4770_codec_regmap_config = {
 867        .reg_bits = 7,
 868        .val_bits = 8,
 869
 870        .max_register = JZ4770_CODEC_REG_AGC5,
 871        .volatile_reg = jz4770_codec_volatile,
 872        .readable_reg = jz4770_codec_readable,
 873        .writeable_reg = jz4770_codec_writeable,
 874
 875        .reg_read = jz4770_codec_reg_read,
 876        .reg_write = jz4770_codec_reg_write,
 877
 878        .reg_defaults_raw = jz4770_codec_reg_defaults,
 879        .num_reg_defaults_raw = ARRAY_SIZE(jz4770_codec_reg_defaults),
 880        .cache_type = REGCACHE_FLAT,
 881};
 882
 883static int jz4770_codec_probe(struct platform_device *pdev)
 884{
 885        struct device *dev = &pdev->dev;
 886        struct jz_codec *codec;
 887        int ret;
 888
 889        codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
 890        if (!codec)
 891                return -ENOMEM;
 892
 893        codec->dev = dev;
 894
 895        codec->base = devm_platform_ioremap_resource(pdev, 0);
 896        if (IS_ERR(codec->base))
 897                return PTR_ERR(codec->base);
 898
 899        codec->regmap = devm_regmap_init(dev, NULL, codec,
 900                                        &jz4770_codec_regmap_config);
 901        if (IS_ERR(codec->regmap))
 902                return PTR_ERR(codec->regmap);
 903
 904        codec->clk = devm_clk_get(dev, "aic");
 905        if (IS_ERR(codec->clk))
 906                return PTR_ERR(codec->clk);
 907
 908        platform_set_drvdata(pdev, codec);
 909
 910        ret = devm_snd_soc_register_component(dev, &jz4770_codec_soc_codec_dev,
 911                                              &jz4770_codec_dai, 1);
 912        if (ret) {
 913                dev_err(dev, "Failed to register codec: %d\n", ret);
 914                return ret;
 915        }
 916
 917        return 0;
 918}
 919
 920static const struct of_device_id jz4770_codec_of_matches[] = {
 921        { .compatible = "ingenic,jz4770-codec", },
 922        { /* sentinel */ }
 923};
 924MODULE_DEVICE_TABLE(of, jz4770_codec_of_matches);
 925
 926static struct platform_driver jz4770_codec_driver = {
 927        .probe                  = jz4770_codec_probe,
 928        .driver                 = {
 929                .name           = "jz4770-codec",
 930                .of_match_table = jz4770_codec_of_matches,
 931        },
 932};
 933module_platform_driver(jz4770_codec_driver);
 934
 935MODULE_DESCRIPTION("JZ4770 SoC internal codec driver");
 936MODULE_AUTHOR("Maarten ter Huurne <maarten@treewalker.org>");
 937MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
 938MODULE_LICENSE("GPL v2");
 939