linux/sound/soc/codecs/sirf-audio-codec.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * SiRF audio codec driver
   4 *
   5 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/platform_device.h>
  10#include <linux/pm_runtime.h>
  11#include <linux/of.h>
  12#include <linux/of_device.h>
  13#include <linux/clk.h>
  14#include <linux/delay.h>
  15#include <linux/io.h>
  16#include <linux/regmap.h>
  17#include <sound/core.h>
  18#include <sound/pcm.h>
  19#include <sound/pcm_params.h>
  20#include <sound/initval.h>
  21#include <sound/tlv.h>
  22#include <sound/soc.h>
  23#include <sound/dmaengine_pcm.h>
  24
  25#include "sirf-audio-codec.h"
  26
  27struct sirf_audio_codec {
  28        struct clk *clk;
  29        struct regmap *regmap;
  30        u32 reg_ctrl0, reg_ctrl1;
  31};
  32
  33static const char * const input_mode_mux[] = {"Single-ended",
  34        "Differential"};
  35
  36static const struct soc_enum input_mode_mux_enum =
  37        SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux);
  38
  39static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control =
  40        SOC_DAPM_ENUM("Route", input_mode_mux_enum);
  41
  42static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0);
  43static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0);
  44static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6,
  45        0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0),
  46        0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0),
  47);
  48
  49static struct snd_kcontrol_new volume_controls_atlas6[] = {
  50        SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14,
  51                        0x7F, 0, playback_vol_tlv),
  52        SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10,
  53                        0x3F, 0, capture_vol_tlv_atlas6),
  54};
  55
  56static struct snd_kcontrol_new volume_controls_prima2[] = {
  57        SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14,
  58                        0x7F, 0, playback_vol_tlv),
  59        SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10,
  60                        0x1F, 0, capture_vol_tlv_prima2),
  61};
  62
  63static struct snd_kcontrol_new left_input_path_controls[] = {
  64        SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0),
  65        SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0),
  66};
  67
  68static struct snd_kcontrol_new right_input_path_controls[] = {
  69        SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0),
  70        SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0),
  71};
  72
  73static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control =
  74        SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0);
  75
  76static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control =
  77        SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0);
  78
  79static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control =
  80        SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0);
  81
  82static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control =
  83        SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0);
  84
  85static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control =
  86        SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0);
  87
  88static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control =
  89        SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0);
  90
  91/* After enable adc, Delay 200ms to avoid pop noise */
  92static int adc_enable_delay_event(struct snd_soc_dapm_widget *w,
  93                struct snd_kcontrol *kcontrol, int event)
  94{
  95        switch (event) {
  96        case SND_SOC_DAPM_POST_PMU:
  97                msleep(200);
  98                break;
  99        default:
 100                break;
 101        }
 102
 103        return 0;
 104}
 105
 106static void enable_and_reset_codec(struct regmap *regmap,
 107                u32 codec_enable_bits, u32 codec_reset_bits)
 108{
 109        regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1,
 110                        codec_enable_bits | codec_reset_bits,
 111                        codec_enable_bits);
 112        msleep(20);
 113        regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1,
 114                        codec_reset_bits, codec_reset_bits);
 115}
 116
 117static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
 118                struct snd_kcontrol *kcontrol, int event)
 119{
 120#define ATLAS6_CODEC_ENABLE_BITS (1 << 29)
 121#define ATLAS6_CODEC_RESET_BITS (1 << 28)
 122        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 123        struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
 124        switch (event) {
 125        case SND_SOC_DAPM_PRE_PMU:
 126                enable_and_reset_codec(sirf_audio_codec->regmap,
 127                        ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS);
 128                break;
 129        case SND_SOC_DAPM_POST_PMD:
 130                regmap_update_bits(sirf_audio_codec->regmap,
 131                        AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 0);
 132                break;
 133        default:
 134                break;
 135        }
 136
 137        return 0;
 138}
 139
 140static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
 141                struct snd_kcontrol *kcontrol, int event)
 142{
 143#define PRIMA2_CODEC_ENABLE_BITS (1 << 27)
 144#define PRIMA2_CODEC_RESET_BITS (1 << 26)
 145        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 146        struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
 147        switch (event) {
 148        case SND_SOC_DAPM_POST_PMU:
 149                enable_and_reset_codec(sirf_audio_codec->regmap,
 150                        PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS);
 151                break;
 152        case SND_SOC_DAPM_POST_PMD:
 153                regmap_update_bits(sirf_audio_codec->regmap,
 154                        AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 0);
 155                break;
 156        default:
 157                break;
 158        }
 159
 160        return 0;
 161}
 162
 163static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = {
 164        SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1,
 165                        25, 0, NULL, 0),
 166        SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1,
 167                        26, 0, NULL, 0),
 168        SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1,
 169                        27, 0, NULL, 0),
 170};
 171
 172static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = {
 173        SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1,
 174                        23, 0, NULL, 0),
 175        SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1,
 176                        24, 0, NULL, 0),
 177        SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1,
 178                        25, 0, NULL, 0),
 179};
 180
 181static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget =
 182        SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0,
 183                        atlas6_codec_enable_and_reset_event,
 184                        SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD);
 185
 186static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget =
 187        SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0,
 188                        prima2_codec_enable_and_reset_event,
 189                        SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD);
 190
 191static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = {
 192        SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0),
 193        SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0),
 194        SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0,
 195                        &left_dac_to_hp_left_amp_switch_control),
 196        SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0,
 197                        &left_dac_to_hp_right_amp_switch_control),
 198        SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0,
 199                        &right_dac_to_hp_left_amp_switch_control),
 200        SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0,
 201                        &right_dac_to_hp_right_amp_switch_control),
 202        SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0,
 203                        NULL, 0),
 204        SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0,
 205                        NULL, 0),
 206
 207        SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0,
 208                        &left_dac_to_speaker_lineout_switch_control),
 209        SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0,
 210                        &right_dac_to_speaker_lineout_switch_control),
 211        SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0,
 212                        NULL, 0),
 213
 214        SND_SOC_DAPM_OUTPUT("HPOUTL"),
 215        SND_SOC_DAPM_OUTPUT("HPOUTR"),
 216        SND_SOC_DAPM_OUTPUT("SPKOUT"),
 217
 218        SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0,
 219                        adc_enable_delay_event, SND_SOC_DAPM_POST_PMU),
 220        SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0,
 221                        adc_enable_delay_event, SND_SOC_DAPM_POST_PMU),
 222        SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0,
 223                &left_input_path_controls[0],
 224                ARRAY_SIZE(left_input_path_controls)),
 225        SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0,
 226                &right_input_path_controls[0],
 227                ARRAY_SIZE(right_input_path_controls)),
 228
 229        SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0,
 230                        &sirf_audio_codec_input_mode_control),
 231        SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0),
 232        SND_SOC_DAPM_INPUT("MICIN1"),
 233        SND_SOC_DAPM_INPUT("MICIN2"),
 234        SND_SOC_DAPM_INPUT("LINEIN1"),
 235        SND_SOC_DAPM_INPUT("LINEIN2"),
 236
 237        SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0,
 238                        30, 0, NULL, 0),
 239};
 240
 241static const struct snd_soc_dapm_route sirf_audio_codec_map[] = {
 242        {"SPKOUT", NULL, "Speaker Driver"},
 243        {"Speaker Driver", NULL, "Speaker amp driver"},
 244        {"Speaker amp driver", NULL, "Left dac to speaker lineout"},
 245        {"Speaker amp driver", NULL, "Right dac to speaker lineout"},
 246        {"Left dac to speaker lineout", "Switch", "DAC left"},
 247        {"Right dac to speaker lineout", "Switch", "DAC right"},
 248        {"HPOUTL", NULL, "HP Left Driver"},
 249        {"HPOUTR", NULL, "HP Right Driver"},
 250        {"HP Left Driver", NULL, "HP amp left driver"},
 251        {"HP Right Driver", NULL, "HP amp right driver"},
 252        {"HP amp left driver", NULL, "Right dac to hp left amp"},
 253        {"HP amp right driver", NULL , "Right dac to hp right amp"},
 254        {"HP amp left driver", NULL, "Left dac to hp left amp"},
 255        {"HP amp right driver", NULL , "Right dac to hp right amp"},
 256        {"Right dac to hp left amp", "Switch", "DAC left"},
 257        {"Right dac to hp right amp", "Switch", "DAC right"},
 258        {"Left dac to hp left amp", "Switch", "DAC left"},
 259        {"Left dac to hp right amp", "Switch", "DAC right"},
 260        {"DAC left", NULL, "codecclk"},
 261        {"DAC right", NULL, "codecclk"},
 262        {"DAC left", NULL, "Playback"},
 263        {"DAC right", NULL, "Playback"},
 264        {"DAC left", NULL, "HSL Phase Opposite"},
 265        {"DAC right", NULL, "HSL Phase Opposite"},
 266
 267        {"Capture", NULL, "ADC left"},
 268        {"Capture", NULL, "ADC right"},
 269        {"ADC left", NULL, "codecclk"},
 270        {"ADC right", NULL, "codecclk"},
 271        {"ADC left", NULL, "Left PGA mixer"},
 272        {"ADC right", NULL, "Right PGA mixer"},
 273        {"Left PGA mixer", "Line Left Switch", "LINEIN2"},
 274        {"Right PGA mixer", "Line Right Switch", "LINEIN1"},
 275        {"Left PGA mixer", "Mic Left Switch", "MICIN2"},
 276        {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"},
 277        {"Mic input mode mux", "Single-ended", "MICIN1"},
 278        {"Mic input mode mux", "Differential", "MICIN1"},
 279};
 280
 281static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec)
 282{
 283        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
 284                AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
 285        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
 286                AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
 287        regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
 288        regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
 289        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
 290                AUDIO_FIFO_START, AUDIO_FIFO_START);
 291        regmap_update_bits(sirf_audio_codec->regmap,
 292                AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE);
 293}
 294
 295static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec)
 296{
 297        regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
 298        regmap_update_bits(sirf_audio_codec->regmap,
 299                AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE);
 300}
 301
 302static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec,
 303        int channels)
 304{
 305        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
 306                AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
 307        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
 308                AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
 309        regmap_write(sirf_audio_codec->regmap,
 310                AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
 311        regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
 312        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
 313                AUDIO_FIFO_START, AUDIO_FIFO_START);
 314        if (channels == 1)
 315                regmap_update_bits(sirf_audio_codec->regmap,
 316                        AUDIO_PORT_IC_CODEC_RX_CTRL,
 317                        IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
 318        else
 319                regmap_update_bits(sirf_audio_codec->regmap,
 320                        AUDIO_PORT_IC_CODEC_RX_CTRL,
 321                        IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
 322}
 323
 324static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec)
 325{
 326        regmap_update_bits(sirf_audio_codec->regmap,
 327                        AUDIO_PORT_IC_CODEC_RX_CTRL,
 328                        IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
 329}
 330
 331static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
 332                int cmd,
 333                struct snd_soc_dai *dai)
 334{
 335        struct snd_soc_component *component = dai->component;
 336        struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
 337        int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 338
 339        /*
 340         * This is a workaround, When stop playback,
 341         * need disable HP amp, avoid the current noise.
 342         */
 343        switch (cmd) {
 344        case SNDRV_PCM_TRIGGER_STOP:
 345        case SNDRV_PCM_TRIGGER_SUSPEND:
 346        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 347                if (playback) {
 348                        snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0,
 349                                IC_HSLEN | IC_HSREN, 0);
 350                        sirf_audio_codec_tx_disable(sirf_audio_codec);
 351                } else
 352                        sirf_audio_codec_rx_disable(sirf_audio_codec);
 353                break;
 354        case SNDRV_PCM_TRIGGER_START:
 355        case SNDRV_PCM_TRIGGER_RESUME:
 356        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 357                if (playback) {
 358                        sirf_audio_codec_tx_enable(sirf_audio_codec);
 359                        snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0,
 360                                IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
 361                } else
 362                        sirf_audio_codec_rx_enable(sirf_audio_codec,
 363                                substream->runtime->channels);
 364                break;
 365        default:
 366                return -EINVAL;
 367        }
 368
 369        return 0;
 370}
 371
 372static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops = {
 373        .trigger = sirf_audio_codec_trigger,
 374};
 375
 376static struct snd_soc_dai_driver sirf_audio_codec_dai = {
 377        .name = "sirf-audio-codec",
 378        .playback = {
 379                .stream_name = "Playback",
 380                .channels_min = 2,
 381                .channels_max = 2,
 382                .rates = SNDRV_PCM_RATE_48000,
 383                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 384        },
 385        .capture = {
 386                .stream_name = "Capture",
 387                .channels_min = 1,
 388                .channels_max = 2,
 389                .rates = SNDRV_PCM_RATE_48000,
 390                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 391        },
 392        .ops = &sirf_audio_codec_dai_ops,
 393};
 394
 395static int sirf_audio_codec_probe(struct snd_soc_component *component)
 396{
 397        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 398
 399        pm_runtime_enable(component->dev);
 400
 401        if (of_device_is_compatible(component->dev->of_node, "sirf,prima2-audio-codec")) {
 402                snd_soc_dapm_new_controls(dapm,
 403                        prima2_output_driver_dapm_widgets,
 404                        ARRAY_SIZE(prima2_output_driver_dapm_widgets));
 405                snd_soc_dapm_new_controls(dapm,
 406                        &prima2_codec_clock_dapm_widget, 1);
 407                return snd_soc_add_component_controls(component,
 408                        volume_controls_prima2,
 409                        ARRAY_SIZE(volume_controls_prima2));
 410        }
 411        if (of_device_is_compatible(component->dev->of_node, "sirf,atlas6-audio-codec")) {
 412                snd_soc_dapm_new_controls(dapm,
 413                        atlas6_output_driver_dapm_widgets,
 414                        ARRAY_SIZE(atlas6_output_driver_dapm_widgets));
 415                snd_soc_dapm_new_controls(dapm,
 416                        &atlas6_codec_clock_dapm_widget, 1);
 417                return snd_soc_add_component_controls(component,
 418                        volume_controls_atlas6,
 419                        ARRAY_SIZE(volume_controls_atlas6));
 420        }
 421
 422        return -EINVAL;
 423}
 424
 425static void sirf_audio_codec_remove(struct snd_soc_component *component)
 426{
 427        pm_runtime_disable(component->dev);
 428}
 429
 430static const struct snd_soc_component_driver soc_codec_device_sirf_audio_codec = {
 431        .probe                  = sirf_audio_codec_probe,
 432        .remove                 = sirf_audio_codec_remove,
 433        .dapm_widgets           = sirf_audio_codec_dapm_widgets,
 434        .num_dapm_widgets       = ARRAY_SIZE(sirf_audio_codec_dapm_widgets),
 435        .dapm_routes            = sirf_audio_codec_map,
 436        .num_dapm_routes        = ARRAY_SIZE(sirf_audio_codec_map),
 437        .use_pmdown_time        = 1,
 438        .endianness             = 1,
 439        .non_legacy_dai_naming  = 1,
 440};
 441
 442static const struct of_device_id sirf_audio_codec_of_match[] = {
 443        { .compatible = "sirf,prima2-audio-codec" },
 444        { .compatible = "sirf,atlas6-audio-codec" },
 445        {}
 446};
 447MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match);
 448
 449static const struct regmap_config sirf_audio_codec_regmap_config = {
 450        .reg_bits = 32,
 451        .reg_stride = 4,
 452        .val_bits = 32,
 453        .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
 454        .cache_type = REGCACHE_NONE,
 455};
 456
 457static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
 458{
 459        int ret;
 460        struct sirf_audio_codec *sirf_audio_codec;
 461        void __iomem *base;
 462        struct resource *mem_res;
 463
 464        sirf_audio_codec = devm_kzalloc(&pdev->dev,
 465                sizeof(struct sirf_audio_codec), GFP_KERNEL);
 466        if (!sirf_audio_codec)
 467                return -ENOMEM;
 468
 469        platform_set_drvdata(pdev, sirf_audio_codec);
 470
 471        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 472        base = devm_ioremap_resource(&pdev->dev, mem_res);
 473        if (IS_ERR(base))
 474                return PTR_ERR(base);
 475
 476        sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
 477                                            &sirf_audio_codec_regmap_config);
 478        if (IS_ERR(sirf_audio_codec->regmap))
 479                return PTR_ERR(sirf_audio_codec->regmap);
 480
 481        sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL);
 482        if (IS_ERR(sirf_audio_codec->clk)) {
 483                dev_err(&pdev->dev, "Get clock failed.\n");
 484                return PTR_ERR(sirf_audio_codec->clk);
 485        }
 486
 487        ret = clk_prepare_enable(sirf_audio_codec->clk);
 488        if (ret) {
 489                dev_err(&pdev->dev, "Enable clock failed.\n");
 490                return ret;
 491        }
 492
 493        ret = devm_snd_soc_register_component(&(pdev->dev),
 494                        &soc_codec_device_sirf_audio_codec,
 495                        &sirf_audio_codec_dai, 1);
 496        if (ret) {
 497                dev_err(&pdev->dev, "Register Audio Codec dai failed.\n");
 498                goto err_clk_put;
 499        }
 500
 501        /*
 502         * Always open charge pump, if not, when the charge pump closed the
 503         * adc will not stable
 504         */
 505        regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0,
 506                IC_CPFREQ, IC_CPFREQ);
 507
 508        if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec"))
 509                regmap_update_bits(sirf_audio_codec->regmap,
 510                                AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN);
 511        return 0;
 512
 513err_clk_put:
 514        clk_disable_unprepare(sirf_audio_codec->clk);
 515        return ret;
 516}
 517
 518static int sirf_audio_codec_driver_remove(struct platform_device *pdev)
 519{
 520        struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev);
 521
 522        clk_disable_unprepare(sirf_audio_codec->clk);
 523
 524        return 0;
 525}
 526
 527#ifdef CONFIG_PM_SLEEP
 528static int sirf_audio_codec_suspend(struct device *dev)
 529{
 530        struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev);
 531
 532        regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0,
 533                &sirf_audio_codec->reg_ctrl0);
 534        regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1,
 535                &sirf_audio_codec->reg_ctrl1);
 536        clk_disable_unprepare(sirf_audio_codec->clk);
 537
 538        return 0;
 539}
 540
 541static int sirf_audio_codec_resume(struct device *dev)
 542{
 543        struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev);
 544        int ret;
 545
 546        ret = clk_prepare_enable(sirf_audio_codec->clk);
 547        if (ret)
 548                return ret;
 549
 550        regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0,
 551                sirf_audio_codec->reg_ctrl0);
 552        regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1,
 553                sirf_audio_codec->reg_ctrl1);
 554
 555        return 0;
 556}
 557#endif
 558
 559static const struct dev_pm_ops sirf_audio_codec_pm_ops = {
 560        SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume)
 561};
 562
 563static struct platform_driver sirf_audio_codec_driver = {
 564        .driver = {
 565                .name = "sirf-audio-codec",
 566                .of_match_table = sirf_audio_codec_of_match,
 567                .pm = &sirf_audio_codec_pm_ops,
 568        },
 569        .probe = sirf_audio_codec_driver_probe,
 570        .remove = sirf_audio_codec_driver_remove,
 571};
 572
 573module_platform_driver(sirf_audio_codec_driver);
 574
 575MODULE_DESCRIPTION("SiRF audio codec driver");
 576MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
 577MODULE_LICENSE("GPL v2");
 578