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