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);
 310static const DECLARE_TLV_DB_MINMAX(mixer_tlv, -3100, 0);
 311
 312/* Unconditional controls. */
 313static const struct snd_kcontrol_new jz4770_codec_snd_controls[] = {
 314        /* record gain control */
 315        SOC_DOUBLE_R_TLV("PCM Capture Volume",
 316                         JZ4770_CODEC_REG_GCR_ADCL, JZ4770_CODEC_REG_GCR_ADCR,
 317                         REG_GCR_ADC_GAIN_OFFSET, REG_GCR_ADC_GAIN_MAX,
 318                         0, adc_tlv),
 319
 320        SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
 321                         JZ4770_CODEC_REG_GCR_LIBYL, JZ4770_CODEC_REG_GCR_LIBYR,
 322                         REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
 323
 324        SOC_SINGLE_TLV("Mixer Capture Volume",
 325                       JZ4770_CODEC_REG_GCR_MIXADC,
 326                       REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
 327
 328        SOC_SINGLE_TLV("Mixer Playback Volume",
 329                       JZ4770_CODEC_REG_GCR_MIXDAC,
 330                       REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
 331};
 332
 333static const struct snd_kcontrol_new jz4770_codec_pcm_playback_controls[] = {
 334        {
 335                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 336                .name = "Volume",
 337                .info = snd_soc_info_volsw,
 338                .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
 339                        | SNDRV_CTL_ELEM_ACCESS_READWRITE,
 340                .tlv.p = dac_tlv,
 341                .get = snd_soc_dapm_get_volsw,
 342                .put = snd_soc_dapm_put_volsw,
 343                /*
 344                 * NOTE: DACR/DACL are inversed; the gain value written to DACR
 345                 * seems to affect the left channel, and the gain value written
 346                 * to DACL seems to affect the right channel.
 347                 */
 348                .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_DACR,
 349                                                    JZ4770_CODEC_REG_GCR_DACL,
 350                                                    REG_GCR_GAIN_OFFSET,
 351                                                    REG_GCR_GAIN_MAX, 1),
 352        },
 353};
 354
 355static const struct snd_kcontrol_new jz4770_codec_hp_playback_controls[] = {
 356        {
 357                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 358                .name = "Volume",
 359                .info = snd_soc_info_volsw,
 360                .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
 361                        | SNDRV_CTL_ELEM_ACCESS_READWRITE,
 362                .tlv.p = out_tlv,
 363                .get = snd_soc_dapm_get_volsw,
 364                .put = snd_soc_dapm_put_volsw,
 365                /* HPR/HPL inversed for the same reason as above */
 366                .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_HPR,
 367                                                    JZ4770_CODEC_REG_GCR_HPL,
 368                                                    REG_GCR_GAIN_OFFSET,
 369                                                    REG_GCR_GAIN_MAX, 1),
 370        },
 371};
 372
 373static int hpout_event(struct snd_soc_dapm_widget *w,
 374                       struct snd_kcontrol *kcontrol, int event)
 375{
 376        struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
 377        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 378        unsigned int val;
 379        int err;
 380
 381        switch (event) {
 382        case SND_SOC_DAPM_PRE_PMU:
 383                /* unmute HP */
 384                regmap_clear_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
 385                                  REG_CR_HP_MUTE);
 386                break;
 387
 388        case SND_SOC_DAPM_POST_PMU:
 389                /* wait for ramp-up complete (RUP) */
 390                err = regmap_read_poll_timeout(jz_codec->regmap,
 391                                               JZ4770_CODEC_REG_IFR,
 392                                               val, val & REG_IFR_RUP,
 393                                               1000, 1 * USEC_PER_SEC);
 394                if (err) {
 395                        dev_err(jz_codec->dev, "RUP timeout: %d", err);
 396                        return err;
 397                }
 398
 399                /* clear RUP flag */
 400                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
 401                                REG_IFR_RUP);
 402
 403                break;
 404
 405        case SND_SOC_DAPM_POST_PMD:
 406                /* mute HP */
 407                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP,
 408                                REG_CR_HP_MUTE);
 409
 410                err = regmap_read_poll_timeout(jz_codec->regmap,
 411                                               JZ4770_CODEC_REG_IFR,
 412                                               val, val & REG_IFR_RDO,
 413                                               1000, 1 * USEC_PER_SEC);
 414                if (err) {
 415                        dev_err(jz_codec->dev, "RDO timeout: %d", err);
 416                        return err;
 417                }
 418
 419                /* clear RDO flag */
 420                regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR,
 421                                REG_IFR_RDO);
 422
 423                break;
 424        }
 425
 426        return 0;
 427}
 428
 429static int adc_poweron_event(struct snd_soc_dapm_widget *w,
 430                             struct snd_kcontrol *kcontrol, int event)
 431{
 432        if (event == SND_SOC_DAPM_POST_PMU)
 433                msleep(1000);
 434
 435        return 0;
 436}
 437
 438static const char * const jz4770_codec_hp_texts[] = {
 439        "PCM", "Line In", "Mic 1", "Mic 2"
 440};
 441static const unsigned int jz4770_codec_hp_values[] = { 3, 2, 0, 1 };
 442static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_hp_enum,
 443                                  JZ4770_CODEC_REG_CR_HP,
 444                                  REG_CR_HP_SEL_OFFSET,
 445                                  REG_CR_HP_SEL_MASK,
 446                                  jz4770_codec_hp_texts,
 447                                  jz4770_codec_hp_values);
 448static const struct snd_kcontrol_new jz4770_codec_hp_source =
 449                        SOC_DAPM_ENUM("Route", jz4770_codec_hp_enum);
 450
 451static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_lo_enum,
 452                                  JZ4770_CODEC_REG_CR_LO,
 453                                  REG_CR_LO_SEL_OFFSET,
 454                                  REG_CR_LO_SEL_MASK,
 455                                  jz4770_codec_hp_texts,
 456                                  jz4770_codec_hp_values);
 457static const struct snd_kcontrol_new jz4770_codec_lo_source =
 458                        SOC_DAPM_ENUM("Route", jz4770_codec_lo_enum);
 459
 460static const char * const jz4770_codec_cap_texts[] = {
 461        "Line In", "Mic 1", "Mic 2"
 462};
 463static const unsigned int jz4770_codec_cap_values[] = { 2, 0, 1 };
 464static SOC_VALUE_ENUM_SINGLE_DECL(jz4770_codec_cap_enum,
 465                                  JZ4770_CODEC_REG_CR_ADC,
 466                                  REG_CR_ADC_IN_SEL_OFFSET,
 467                                  REG_CR_ADC_IN_SEL_MASK,
 468                                  jz4770_codec_cap_texts,
 469                                  jz4770_codec_cap_values);
 470static const struct snd_kcontrol_new jz4770_codec_cap_source =
 471                        SOC_DAPM_ENUM("Route", jz4770_codec_cap_enum);
 472
 473static const struct snd_kcontrol_new jz4770_codec_mic_controls[] = {
 474        SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4770_CODEC_REG_CR_MIC,
 475                        REG_CR_MIC_STEREO_OFFSET, 1, 0),
 476};
 477
 478static const struct snd_soc_dapm_widget jz4770_codec_dapm_widgets[] = {
 479        SND_SOC_DAPM_PGA_E("HP Out", JZ4770_CODEC_REG_CR_HP,
 480                           REG_CR_HP_SB_OFFSET, 1, NULL, 0, hpout_event,
 481                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 482                           SND_SOC_DAPM_POST_PMD),
 483
 484        SND_SOC_DAPM_PGA("Line Out", JZ4770_CODEC_REG_CR_LO,
 485                         REG_CR_LO_SB_OFFSET, 1, NULL, 0),
 486
 487        SND_SOC_DAPM_PGA("Line Out Switch 2", JZ4770_CODEC_REG_CR_LO,
 488                         REG_CR_LO_MUTE_OFFSET, 1, NULL, 0),
 489
 490        SND_SOC_DAPM_PGA("Line In", JZ4770_CODEC_REG_CR_LI,
 491                         REG_CR_LI_SB_OFFSET, 1, NULL, 0),
 492
 493        SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
 494                         &jz4770_codec_hp_source),
 495        SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
 496                         &jz4770_codec_cap_source),
 497        SND_SOC_DAPM_MUX("Line Out Source", SND_SOC_NOPM, 0, 0,
 498                         &jz4770_codec_lo_source),
 499
 500        SND_SOC_DAPM_PGA("Mic 1", JZ4770_CODEC_REG_CR_MIC,
 501                         REG_CR_MIC_SB_MIC1_OFFSET, 1, NULL, 0),
 502        SND_SOC_DAPM_PGA("Mic 2", JZ4770_CODEC_REG_CR_MIC,
 503                         REG_CR_MIC_SB_MIC2_OFFSET, 1, NULL, 0),
 504
 505        SND_SOC_DAPM_PGA("Mic Diff", JZ4770_CODEC_REG_CR_MIC,
 506                         REG_CR_MIC_IDIFF_OFFSET, 0, NULL, 0),
 507
 508        SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
 509                           jz4770_codec_mic_controls,
 510                           ARRAY_SIZE(jz4770_codec_mic_controls)),
 511
 512        SND_SOC_DAPM_PGA("Line In Bypass", JZ4770_CODEC_REG_CR_LI,
 513                         REG_CR_LI_LIBY_OFFSET, 1, NULL, 0),
 514
 515        SND_SOC_DAPM_ADC_E("ADC", "HiFi Capture", JZ4770_CODEC_REG_CR_ADC,
 516                           REG_CR_ADC_SB_OFFSET, 1, adc_poweron_event,
 517                           SND_SOC_DAPM_POST_PMU),
 518        SND_SOC_DAPM_DAC("DAC", "HiFi Playback", JZ4770_CODEC_REG_CR_DAC,
 519                         REG_CR_DAC_SB_OFFSET, 1),
 520
 521        SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
 522                           jz4770_codec_pcm_playback_controls,
 523                           ARRAY_SIZE(jz4770_codec_pcm_playback_controls)),
 524        SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
 525                           jz4770_codec_hp_playback_controls,
 526                           ARRAY_SIZE(jz4770_codec_hp_playback_controls)),
 527
 528        SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4770_CODEC_REG_CR_MIC,
 529                            REG_CR_MIC_BIAS_SB_OFFSET, 1, NULL, 0),
 530
 531        SND_SOC_DAPM_SUPPLY("Cap-less", JZ4770_CODEC_REG_CR_HP,
 532                            REG_CR_HP_SB_HPCM_OFFSET, 1, NULL, 0),
 533
 534        SND_SOC_DAPM_INPUT("MIC1P"),
 535        SND_SOC_DAPM_INPUT("MIC1N"),
 536        SND_SOC_DAPM_INPUT("MIC2P"),
 537        SND_SOC_DAPM_INPUT("MIC2N"),
 538
 539        SND_SOC_DAPM_OUTPUT("LOUT"),
 540        SND_SOC_DAPM_OUTPUT("ROUT"),
 541
 542        SND_SOC_DAPM_OUTPUT("LHPOUT"),
 543        SND_SOC_DAPM_OUTPUT("RHPOUT"),
 544
 545        SND_SOC_DAPM_INPUT("LLINEIN"),
 546        SND_SOC_DAPM_INPUT("RLINEIN"),
 547
 548        SND_SOC_DAPM_OUTPUT("SYSCLK"),
 549};
 550
 551/* Unconditional routes. */
 552static const struct snd_soc_dapm_route jz4770_codec_dapm_routes[] = {
 553        { "Mic 1", NULL, "MIC1P" },
 554        { "Mic Diff", NULL, "MIC1N" },
 555        { "Mic 1", NULL, "Mic Diff" },
 556        { "Mic 2", NULL, "MIC2P" },
 557        { "Mic Diff", NULL, "MIC2N" },
 558        { "Mic 2", NULL, "Mic Diff" },
 559
 560        { "Line In", NULL, "LLINEIN" },
 561        { "Line In", NULL, "RLINEIN" },
 562
 563        { "Mic", "Stereo Capture Switch", "Mic 1" },
 564        { "Mic", "Stereo Capture Switch", "Mic 2" },
 565        { "Headphones Source", "Mic 1", "Mic" },
 566        { "Headphones Source", "Mic 2", "Mic" },
 567        { "Capture Source", "Mic 1", "Mic" },
 568        { "Capture Source", "Mic 2", "Mic" },
 569
 570        { "Headphones Source", "Mic 1", "Mic 1" },
 571        { "Headphones Source", "Mic 2", "Mic 2" },
 572        { "Headphones Source", "Line In", "Line In Bypass" },
 573        { "Headphones Source", "PCM", "Headphones Playback" },
 574        { "HP Out", NULL, "Headphones Source" },
 575
 576        { "Capture Source", "Line In", "Line In" },
 577        { "Capture Source", "Mic 1", "Mic 1" },
 578        { "Capture Source", "Mic 2", "Mic 2" },
 579        { "ADC", NULL, "Capture Source" },
 580
 581        { "Line In Bypass", NULL, "Line In" },
 582        { "Line Out Source", "Line In", "Line In Bypass" },
 583        { "Line Out Source", "PCM", "PCM Playback" },
 584
 585        { "LHPOUT", NULL, "HP Out"},
 586        { "RHPOUT", NULL, "HP Out"},
 587
 588        { "Line Out", NULL, "Line Out Source" },
 589        { "Line Out Switch 2", NULL, "Line Out" },
 590
 591        { "LOUT", NULL, "Line Out Switch 2"},
 592        { "ROUT", NULL, "Line Out Switch 2"},
 593
 594        { "PCM Playback", "Volume", "DAC" },
 595        { "Headphones Playback", "Volume", "PCM Playback" },
 596
 597        { "SYSCLK", NULL, "DAC" },
 598};
 599
 600static void jz4770_codec_codec_init_regs(struct snd_soc_component *codec)
 601{
 602        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 603        struct regmap *regmap = jz_codec->regmap;
 604
 605        /* Collect updates for later sending. */
 606        regcache_cache_only(regmap, true);
 607
 608        /* default HP output to PCM */
 609        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_HP, REG_CR_HP_SEL_MASK);
 610
 611        /* default line output to PCM */
 612        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_LO, REG_CR_LO_SEL_MASK);
 613
 614        /* Disable stereo mic */
 615        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_MIC,
 616                          BIT(REG_CR_MIC_STEREO_OFFSET));
 617
 618        /* Set mic 1 as default source for ADC */
 619        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_ADC,
 620                          REG_CR_ADC_IN_SEL_MASK);
 621
 622        /* ADC/DAC: serial + i2s */
 623        regmap_set_bits(regmap, JZ4770_CODEC_REG_AICR_ADC,
 624                        REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S);
 625        regmap_set_bits(regmap, JZ4770_CODEC_REG_AICR_DAC,
 626                        REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
 627
 628        /* The generated IRQ is a high level */
 629        regmap_clear_bits(regmap, JZ4770_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
 630        regmap_update_bits(regmap, JZ4770_CODEC_REG_IMR, REG_IMR_ALL_MASK,
 631                           REG_IMR_JACK_MASK | REG_IMR_RUP_MASK |
 632                           REG_IMR_RDO_MASK | REG_IMR_GUP_MASK |
 633                           REG_IMR_GDO_MASK);
 634
 635        /* 12M oscillator */
 636        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CCR, REG_CCR_CRYSTAL_MASK);
 637
 638        /* 0: 16ohm/220uF, 1: 10kohm/1uF */
 639        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_HP, REG_CR_HP_LOAD);
 640
 641        /* disable automatic gain */
 642        regmap_clear_bits(regmap, JZ4770_CODEC_REG_AGC1, REG_AGC1_EN);
 643
 644        /* Disable DAC lrswap */
 645        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_DAC, REG_CR_DAC_LRSWAP);
 646
 647        /* Independent L/R DAC gain control */
 648        regmap_clear_bits(regmap, JZ4770_CODEC_REG_GCR_DACL,
 649                          REG_GCR_DACL_RLGOD);
 650
 651        /* Disable ADC lrswap */
 652        regmap_set_bits(regmap, JZ4770_CODEC_REG_CR_ADC, REG_CR_ADC_LRSWAP);
 653
 654        /* default to cap-less mode(0) */
 655        regmap_clear_bits(regmap, JZ4770_CODEC_REG_CR_HP,
 656                          BIT(REG_CR_HP_SB_HPCM_OFFSET));
 657
 658        /* Send collected updates. */
 659        regcache_cache_only(regmap, false);
 660        regcache_sync(regmap);
 661}
 662
 663static int jz4770_codec_codec_probe(struct snd_soc_component *codec)
 664{
 665        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 666
 667        clk_prepare_enable(jz_codec->clk);
 668
 669        jz4770_codec_codec_init_regs(codec);
 670
 671        return 0;
 672}
 673
 674static void jz4770_codec_codec_remove(struct snd_soc_component *codec)
 675{
 676        struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
 677
 678        clk_disable_unprepare(jz_codec->clk);
 679}
 680
 681static const struct snd_soc_component_driver jz4770_codec_soc_codec_dev = {
 682        .probe                  = jz4770_codec_codec_probe,
 683        .remove                 = jz4770_codec_codec_remove,
 684        .set_bias_level         = jz4770_codec_set_bias_level,
 685        .controls               = jz4770_codec_snd_controls,
 686        .num_controls           = ARRAY_SIZE(jz4770_codec_snd_controls),
 687        .dapm_widgets           = jz4770_codec_dapm_widgets,
 688        .num_dapm_widgets       = ARRAY_SIZE(jz4770_codec_dapm_widgets),
 689        .dapm_routes            = jz4770_codec_dapm_routes,
 690        .num_dapm_routes        = ARRAY_SIZE(jz4770_codec_dapm_routes),
 691        .suspend_bias_off       = 1,
 692        .use_pmdown_time        = 1,
 693};
 694
 695static const unsigned int jz4770_codec_sample_rates[] = {
 696        96000, 48000, 44100, 32000,
 697        24000, 22050, 16000, 12000,
 698        11025, 9600, 8000,
 699};
 700
 701static int jz4770_codec_hw_params(struct snd_pcm_substream *substream,
 702                                  struct snd_pcm_hw_params *params,
 703                                  struct snd_soc_dai *dai)
 704{
 705        struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
 706        unsigned int rate, bit_width;
 707
 708        switch (params_format(params)) {
 709        case SNDRV_PCM_FORMAT_S16_LE:
 710                bit_width = 0;
 711                break;
 712        case SNDRV_PCM_FORMAT_S18_3LE:
 713                bit_width = 1;
 714                break;
 715        case SNDRV_PCM_FORMAT_S20_3LE:
 716                bit_width = 2;
 717                break;
 718        case SNDRV_PCM_FORMAT_S24_3LE:
 719                bit_width = 3;
 720                break;
 721        default:
 722                return -EINVAL;
 723        }
 724
 725        for (rate = 0; rate < ARRAY_SIZE(jz4770_codec_sample_rates); rate++) {
 726                if (jz4770_codec_sample_rates[rate] == params_rate(params))
 727                        break;
 728        }
 729
 730        if (rate == ARRAY_SIZE(jz4770_codec_sample_rates))
 731                return -EINVAL;
 732
 733        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 734                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_DAC,
 735                                   REG_AICR_DAC_ADWL_MASK,
 736                                   bit_width << REG_AICR_DAC_ADWL_OFFSET);
 737                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_DAC,
 738                                   REG_FCR_DAC_FREQ_MASK,
 739                                   rate << REG_FCR_DAC_FREQ_OFFSET);
 740        } else {
 741                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_ADC,
 742                                   REG_AICR_ADC_ADWL_MASK,
 743                                   bit_width << REG_AICR_ADC_ADWL_OFFSET);
 744                regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_ADC,
 745                                   REG_FCR_ADC_FREQ_MASK,
 746                                   rate << REG_FCR_ADC_FREQ_OFFSET);
 747        }
 748
 749        return 0;
 750}
 751
 752static const struct snd_soc_dai_ops jz4770_codec_dai_ops = {
 753        .startup        = jz4770_codec_startup,
 754        .shutdown       = jz4770_codec_shutdown,
 755        .hw_params      = jz4770_codec_hw_params,
 756        .trigger        = jz4770_codec_pcm_trigger,
 757        .mute_stream    = jz4770_codec_mute_stream,
 758        .no_capture_mute = 1,
 759};
 760
 761#define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | \
 762                          SNDRV_PCM_FMTBIT_S18_3LE | \
 763                          SNDRV_PCM_FMTBIT_S20_3LE | \
 764                          SNDRV_PCM_FMTBIT_S24_3LE)
 765
 766static struct snd_soc_dai_driver jz4770_codec_dai = {
 767        .name = "jz4770-hifi",
 768        .playback = {
 769                .stream_name = "Playback",
 770                .channels_min = 2,
 771                .channels_max = 2,
 772                .rates = SNDRV_PCM_RATE_8000_96000,
 773                .formats = JZ_CODEC_FORMATS,
 774        },
 775        .capture = {
 776                .stream_name = "Capture",
 777                .channels_min = 2,
 778                .channels_max = 2,
 779                .rates = SNDRV_PCM_RATE_8000_96000,
 780                .formats = JZ_CODEC_FORMATS,
 781        },
 782        .ops = &jz4770_codec_dai_ops,
 783};
 784
 785static bool jz4770_codec_volatile(struct device *dev, unsigned int reg)
 786{
 787        return reg == JZ4770_CODEC_REG_SR || reg == JZ4770_CODEC_REG_IFR;
 788}
 789
 790static bool jz4770_codec_readable(struct device *dev, unsigned int reg)
 791{
 792        switch (reg) {
 793        case JZ4770_CODEC_REG_MISSING_REG1:
 794        case JZ4770_CODEC_REG_MISSING_REG2:
 795                return false;
 796        default:
 797                return true;
 798        }
 799}
 800
 801static bool jz4770_codec_writeable(struct device *dev, unsigned int reg)
 802{
 803        switch (reg) {
 804        case JZ4770_CODEC_REG_SR:
 805        case JZ4770_CODEC_REG_MISSING_REG1:
 806        case JZ4770_CODEC_REG_MISSING_REG2:
 807                return false;
 808        default:
 809                return true;
 810        }
 811}
 812
 813static int jz4770_codec_io_wait(struct jz_codec *codec)
 814{
 815        u32 reg;
 816
 817        return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
 818                                  !(reg & ICDC_RGADW_RGWR),
 819                                  1000, 1 * USEC_PER_SEC);
 820}
 821
 822static int jz4770_codec_reg_read(void *context, unsigned int reg,
 823                                 unsigned int *val)
 824{
 825        struct jz_codec *codec = context;
 826        unsigned int i;
 827        u32 tmp;
 828        int ret;
 829
 830        ret = jz4770_codec_io_wait(codec);
 831        if (ret)
 832                return ret;
 833
 834        tmp = readl(codec->base + ICDC_RGADW_OFFSET);
 835        tmp = (tmp & ~ICDC_RGADW_RGADDR_MASK)
 836            | (reg << ICDC_RGADW_RGADDR_OFFSET);
 837        writel(tmp, codec->base + ICDC_RGADW_OFFSET);
 838
 839        /* wait 6+ cycles */
 840        for (i = 0; i < 6; i++)
 841                *val = readl(codec->base + ICDC_RGDATA_OFFSET) &
 842                        ICDC_RGDATA_RGDOUT_MASK;
 843
 844        return 0;
 845}
 846
 847static int jz4770_codec_reg_write(void *context, unsigned int reg,
 848                                  unsigned int val)
 849{
 850        struct jz_codec *codec = context;
 851        int ret;
 852
 853        ret = jz4770_codec_io_wait(codec);
 854        if (ret)
 855                return ret;
 856
 857        writel(ICDC_RGADW_RGWR | (reg << ICDC_RGADW_RGADDR_OFFSET) | val,
 858               codec->base + ICDC_RGADW_OFFSET);
 859
 860        ret = jz4770_codec_io_wait(codec);
 861        if (ret)
 862                return ret;
 863
 864        return 0;
 865}
 866
 867static const u8 jz4770_codec_reg_defaults[] = {
 868        0x00, 0xC3, 0xC3, 0x90, 0x98, 0xFF, 0x90, 0xB1,
 869        0x11, 0x10, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00,
 870        0xFF, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
 871        0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x34,
 872        0x07, 0x44, 0x1F, 0x00
 873};
 874
 875static struct regmap_config jz4770_codec_regmap_config = {
 876        .reg_bits = 7,
 877        .val_bits = 8,
 878
 879        .max_register = JZ4770_CODEC_REG_AGC5,
 880        .volatile_reg = jz4770_codec_volatile,
 881        .readable_reg = jz4770_codec_readable,
 882        .writeable_reg = jz4770_codec_writeable,
 883
 884        .reg_read = jz4770_codec_reg_read,
 885        .reg_write = jz4770_codec_reg_write,
 886
 887        .reg_defaults_raw = jz4770_codec_reg_defaults,
 888        .num_reg_defaults_raw = ARRAY_SIZE(jz4770_codec_reg_defaults),
 889        .cache_type = REGCACHE_FLAT,
 890};
 891
 892static int jz4770_codec_probe(struct platform_device *pdev)
 893{
 894        struct device *dev = &pdev->dev;
 895        struct jz_codec *codec;
 896        int ret;
 897
 898        codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
 899        if (!codec)
 900                return -ENOMEM;
 901
 902        codec->dev = dev;
 903
 904        codec->base = devm_platform_ioremap_resource(pdev, 0);
 905        if (IS_ERR(codec->base))
 906                return PTR_ERR(codec->base);
 907
 908        codec->regmap = devm_regmap_init(dev, NULL, codec,
 909                                        &jz4770_codec_regmap_config);
 910        if (IS_ERR(codec->regmap))
 911                return PTR_ERR(codec->regmap);
 912
 913        codec->clk = devm_clk_get(dev, "aic");
 914        if (IS_ERR(codec->clk))
 915                return PTR_ERR(codec->clk);
 916
 917        platform_set_drvdata(pdev, codec);
 918
 919        ret = devm_snd_soc_register_component(dev, &jz4770_codec_soc_codec_dev,
 920                                              &jz4770_codec_dai, 1);
 921        if (ret) {
 922                dev_err(dev, "Failed to register codec: %d\n", ret);
 923                return ret;
 924        }
 925
 926        return 0;
 927}
 928
 929static const struct of_device_id jz4770_codec_of_matches[] = {
 930        { .compatible = "ingenic,jz4770-codec", },
 931        { /* sentinel */ }
 932};
 933MODULE_DEVICE_TABLE(of, jz4770_codec_of_matches);
 934
 935static struct platform_driver jz4770_codec_driver = {
 936        .probe                  = jz4770_codec_probe,
 937        .driver                 = {
 938                .name           = "jz4770-codec",
 939                .of_match_table = jz4770_codec_of_matches,
 940        },
 941};
 942module_platform_driver(jz4770_codec_driver);
 943
 944MODULE_DESCRIPTION("JZ4770 SoC internal codec driver");
 945MODULE_AUTHOR("Maarten ter Huurne <maarten@treewalker.org>");
 946MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
 947MODULE_LICENSE("GPL v2");
 948