2 * SiRF audio codec driver
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
6 * Licensed under GPLv2 or later.
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/pm_runtime.h>
13 #include <linux/of_device.h>
14 #include <linux/clk.h>
15 #include <linux/delay.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>
26 #include "sirf-audio-codec.h"
28 struct sirf_audio_codec
{
30 struct regmap
*regmap
;
31 u32 reg_ctrl0
, reg_ctrl1
;
34 static const char * const input_mode_mux
[] = {"Single-ended",
37 static const struct soc_enum input_mode_mux_enum
=
38 SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1
, 4, 2, input_mode_mux
);
40 static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control
=
41 SOC_DAPM_ENUM("Route", input_mode_mux_enum
);
43 static const DECLARE_TLV_DB_SCALE(playback_vol_tlv
, -12400, 100, 0);
44 static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2
, 500, 100, 0);
45 static 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),
50 static 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
),
57 static 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
),
64 static 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),
69 static 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),
74 static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control
=
75 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 9, 1, 0);
77 static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control
=
78 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 8, 1, 0);
80 static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control
=
81 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 7, 1, 0);
83 static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control
=
84 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 6, 1, 0);
86 static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control
=
87 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 11, 1, 0);
89 static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control
=
90 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 10, 1, 0);
92 /* After enable adc, Delay 200ms to avoid pop noise */
93 static int adc_enable_delay_event(struct snd_soc_dapm_widget
*w
,
94 struct snd_kcontrol
*kcontrol
, int event
)
97 case SND_SOC_DAPM_POST_PMU
:
107 static void enable_and_reset_codec(struct regmap
*regmap
,
108 u32 codec_enable_bits
, u32 codec_reset_bits
)
110 regmap_update_bits(regmap
, AUDIO_IC_CODEC_CTRL1
,
111 codec_enable_bits
| codec_reset_bits
,
114 regmap_update_bits(regmap
, AUDIO_IC_CODEC_CTRL1
,
115 codec_reset_bits
, codec_reset_bits
);
118 static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget
*w
,
119 struct snd_kcontrol
*kcontrol
, int event
)
121 #define ATLAS6_CODEC_ENABLE_BITS (1 << 29)
122 #define ATLAS6_CODEC_RESET_BITS (1 << 28)
123 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(w
->codec
->dev
);
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
);
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);
140 static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget
*w
,
141 struct snd_kcontrol
*kcontrol
, int event
)
143 #define PRIMA2_CODEC_ENABLE_BITS (1 << 27)
144 #define PRIMA2_CODEC_RESET_BITS (1 << 26)
145 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(w
->codec
->dev
);
147 case SND_SOC_DAPM_POST_PMU
:
148 enable_and_reset_codec(sirf_audio_codec
->regmap
,
149 PRIMA2_CODEC_ENABLE_BITS
, PRIMA2_CODEC_RESET_BITS
);
151 case SND_SOC_DAPM_POST_PMD
:
152 regmap_update_bits(sirf_audio_codec
->regmap
,
153 AUDIO_IC_CODEC_CTRL1
, PRIMA2_CODEC_ENABLE_BITS
, 0);
162 static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets
[] = {
163 SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1
,
165 SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1
,
167 SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1
,
171 static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets
[] = {
172 SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1
,
174 SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1
,
176 SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1
,
180 static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget
=
181 SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM
, 0, 0,
182 atlas6_codec_enable_and_reset_event
,
183 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
);
185 static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget
=
186 SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM
, 0, 0,
187 prima2_codec_enable_and_reset_event
,
188 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
);
190 static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets
[] = {
191 SND_SOC_DAPM_DAC("DAC left", NULL
, AUDIO_IC_CODEC_CTRL0
, 1, 0),
192 SND_SOC_DAPM_DAC("DAC right", NULL
, AUDIO_IC_CODEC_CTRL0
, 0, 0),
193 SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM
, 0, 0,
194 &left_dac_to_hp_left_amp_switch_control
),
195 SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM
, 0, 0,
196 &left_dac_to_hp_right_amp_switch_control
),
197 SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM
, 0, 0,
198 &right_dac_to_hp_left_amp_switch_control
),
199 SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM
, 0, 0,
200 &right_dac_to_hp_right_amp_switch_control
),
201 SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0
, 3, 0,
203 SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0
, 3, 0,
206 SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM
, 0, 0,
207 &left_dac_to_speaker_lineout_switch_control
),
208 SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM
, 0, 0,
209 &right_dac_to_speaker_lineout_switch_control
),
210 SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0
, 4, 0,
213 SND_SOC_DAPM_OUTPUT("HPOUTL"),
214 SND_SOC_DAPM_OUTPUT("HPOUTR"),
215 SND_SOC_DAPM_OUTPUT("SPKOUT"),
217 SND_SOC_DAPM_ADC_E("ADC left", NULL
, AUDIO_IC_CODEC_CTRL1
, 8, 0,
218 adc_enable_delay_event
, SND_SOC_DAPM_POST_PMU
),
219 SND_SOC_DAPM_ADC_E("ADC right", NULL
, AUDIO_IC_CODEC_CTRL1
, 7, 0,
220 adc_enable_delay_event
, SND_SOC_DAPM_POST_PMU
),
221 SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1
, 1, 0,
222 &left_input_path_controls
[0],
223 ARRAY_SIZE(left_input_path_controls
)),
224 SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1
, 0, 0,
225 &right_input_path_controls
[0],
226 ARRAY_SIZE(right_input_path_controls
)),
228 SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM
, 0, 0,
229 &sirf_audio_codec_input_mode_control
),
230 SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR
, 3, 0),
231 SND_SOC_DAPM_INPUT("MICIN1"),
232 SND_SOC_DAPM_INPUT("MICIN2"),
233 SND_SOC_DAPM_INPUT("LINEIN1"),
234 SND_SOC_DAPM_INPUT("LINEIN2"),
236 SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0
,
240 static const struct snd_soc_dapm_route sirf_audio_codec_map
[] = {
241 {"SPKOUT", NULL
, "Speaker Driver"},
242 {"Speaker Driver", NULL
, "Speaker amp driver"},
243 {"Speaker amp driver", NULL
, "Left dac to speaker lineout"},
244 {"Speaker amp driver", NULL
, "Right dac to speaker lineout"},
245 {"Left dac to speaker lineout", "Switch", "DAC left"},
246 {"Right dac to speaker lineout", "Switch", "DAC right"},
247 {"HPOUTL", NULL
, "HP Left Driver"},
248 {"HPOUTR", NULL
, "HP Right Driver"},
249 {"HP Left Driver", NULL
, "HP amp left driver"},
250 {"HP Right Driver", NULL
, "HP amp right driver"},
251 {"HP amp left driver", NULL
, "Right dac to hp left amp"},
252 {"HP amp right driver", NULL
, "Right dac to hp right amp"},
253 {"HP amp left driver", NULL
, "Left dac to hp left amp"},
254 {"HP amp right driver", NULL
, "Right dac to hp right amp"},
255 {"Right dac to hp left amp", "Switch", "DAC left"},
256 {"Right dac to hp right amp", "Switch", "DAC right"},
257 {"Left dac to hp left amp", "Switch", "DAC left"},
258 {"Left dac to hp right amp", "Switch", "DAC right"},
259 {"DAC left", NULL
, "codecclk"},
260 {"DAC right", NULL
, "codecclk"},
261 {"DAC left", NULL
, "Playback"},
262 {"DAC right", NULL
, "Playback"},
263 {"DAC left", NULL
, "HSL Phase Opposite"},
264 {"DAC right", NULL
, "HSL Phase Opposite"},
266 {"Capture", NULL
, "ADC left"},
267 {"Capture", NULL
, "ADC right"},
268 {"ADC left", NULL
, "codecclk"},
269 {"ADC right", NULL
, "codecclk"},
270 {"ADC left", NULL
, "Left PGA mixer"},
271 {"ADC right", NULL
, "Right PGA mixer"},
272 {"Left PGA mixer", "Line Left Switch", "LINEIN2"},
273 {"Right PGA mixer", "Line Right Switch", "LINEIN1"},
274 {"Left PGA mixer", "Mic Left Switch", "MICIN2"},
275 {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"},
276 {"Mic input mode mux", "Single-ended", "MICIN1"},
277 {"Mic input mode mux", "Differential", "MICIN1"},
280 static void sirf_audio_codec_tx_enable(struct sirf_audio_codec
*sirf_audio_codec
)
282 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
,
283 AUDIO_FIFO_RESET
, AUDIO_FIFO_RESET
);
284 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
,
285 AUDIO_FIFO_RESET
, ~AUDIO_FIFO_RESET
);
286 regmap_write(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_TXFIFO_INT_MSK
, 0);
287 regmap_write(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
, 0);
288 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
,
289 AUDIO_FIFO_START
, AUDIO_FIFO_START
);
290 regmap_update_bits(sirf_audio_codec
->regmap
,
291 AUDIO_PORT_IC_CODEC_TX_CTRL
, IC_TX_ENABLE
, IC_TX_ENABLE
);
294 static void sirf_audio_codec_tx_disable(struct sirf_audio_codec
*sirf_audio_codec
)
296 regmap_write(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
, 0);
297 regmap_update_bits(sirf_audio_codec
->regmap
,
298 AUDIO_PORT_IC_CODEC_TX_CTRL
, IC_TX_ENABLE
, ~IC_TX_ENABLE
);
301 static void sirf_audio_codec_rx_enable(struct sirf_audio_codec
*sirf_audio_codec
,
304 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
,
305 AUDIO_FIFO_RESET
, AUDIO_FIFO_RESET
);
306 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
,
307 AUDIO_FIFO_RESET
, ~AUDIO_FIFO_RESET
);
308 regmap_write(sirf_audio_codec
->regmap
,
309 AUDIO_PORT_IC_RXFIFO_INT_MSK
, 0);
310 regmap_write(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
, 0);
311 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
,
312 AUDIO_FIFO_START
, AUDIO_FIFO_START
);
314 regmap_update_bits(sirf_audio_codec
->regmap
,
315 AUDIO_PORT_IC_CODEC_RX_CTRL
,
316 IC_RX_ENABLE_MONO
, IC_RX_ENABLE_MONO
);
318 regmap_update_bits(sirf_audio_codec
->regmap
,
319 AUDIO_PORT_IC_CODEC_RX_CTRL
,
320 IC_RX_ENABLE_STEREO
, IC_RX_ENABLE_STEREO
);
323 static void sirf_audio_codec_rx_disable(struct sirf_audio_codec
*sirf_audio_codec
)
325 regmap_update_bits(sirf_audio_codec
->regmap
,
326 AUDIO_PORT_IC_CODEC_RX_CTRL
,
327 IC_RX_ENABLE_STEREO
, ~IC_RX_ENABLE_STEREO
);
330 static int sirf_audio_codec_trigger(struct snd_pcm_substream
*substream
,
332 struct snd_soc_dai
*dai
)
334 struct snd_soc_codec
*codec
= dai
->codec
;
335 struct sirf_audio_codec
*sirf_audio_codec
= snd_soc_codec_get_drvdata(codec
);
336 int playback
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
;
339 * This is a workaround, When stop playback,
340 * need disable HP amp, avoid the current noise.
343 case SNDRV_PCM_TRIGGER_STOP
:
344 case SNDRV_PCM_TRIGGER_SUSPEND
:
345 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
347 snd_soc_update_bits(codec
, AUDIO_IC_CODEC_CTRL0
,
348 IC_HSLEN
| IC_HSREN
, 0);
349 sirf_audio_codec_tx_disable(sirf_audio_codec
);
351 sirf_audio_codec_rx_disable(sirf_audio_codec
);
353 case SNDRV_PCM_TRIGGER_START
:
354 case SNDRV_PCM_TRIGGER_RESUME
:
355 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
357 sirf_audio_codec_tx_enable(sirf_audio_codec
);
358 snd_soc_update_bits(codec
, AUDIO_IC_CODEC_CTRL0
,
359 IC_HSLEN
| IC_HSREN
, IC_HSLEN
| IC_HSREN
);
361 sirf_audio_codec_rx_enable(sirf_audio_codec
,
362 substream
->runtime
->channels
);
371 struct snd_soc_dai_ops sirf_audio_codec_dai_ops
= {
372 .trigger
= sirf_audio_codec_trigger
,
375 struct snd_soc_dai_driver sirf_audio_codec_dai
= {
376 .name
= "sirf-audio-codec",
378 .stream_name
= "Playback",
381 .rates
= SNDRV_PCM_RATE_48000
,
382 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
385 .stream_name
= "Capture",
388 .rates
= SNDRV_PCM_RATE_48000
,
389 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
391 .ops
= &sirf_audio_codec_dai_ops
,
394 static int sirf_audio_codec_probe(struct snd_soc_codec
*codec
)
396 struct snd_soc_dapm_context
*dapm
= &codec
->dapm
;
398 pm_runtime_enable(codec
->dev
);
400 if (of_device_is_compatible(codec
->dev
->of_node
, "sirf,prima2-audio-codec")) {
401 snd_soc_dapm_new_controls(dapm
,
402 prima2_output_driver_dapm_widgets
,
403 ARRAY_SIZE(prima2_output_driver_dapm_widgets
));
404 snd_soc_dapm_new_controls(dapm
,
405 &prima2_codec_clock_dapm_widget
, 1);
406 return snd_soc_add_codec_controls(codec
,
407 volume_controls_prima2
,
408 ARRAY_SIZE(volume_controls_prima2
));
410 if (of_device_is_compatible(codec
->dev
->of_node
, "sirf,atlas6-audio-codec")) {
411 snd_soc_dapm_new_controls(dapm
,
412 atlas6_output_driver_dapm_widgets
,
413 ARRAY_SIZE(atlas6_output_driver_dapm_widgets
));
414 snd_soc_dapm_new_controls(dapm
,
415 &atlas6_codec_clock_dapm_widget
, 1);
416 return snd_soc_add_codec_controls(codec
,
417 volume_controls_atlas6
,
418 ARRAY_SIZE(volume_controls_atlas6
));
424 static int sirf_audio_codec_remove(struct snd_soc_codec
*codec
)
426 pm_runtime_disable(codec
->dev
);
430 static struct snd_soc_codec_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 .idle_bias_off
= true,
440 static const struct of_device_id sirf_audio_codec_of_match
[] = {
441 { .compatible
= "sirf,prima2-audio-codec" },
442 { .compatible
= "sirf,atlas6-audio-codec" },
445 MODULE_DEVICE_TABLE(of
, sirf_audio_codec_of_match
);
447 static const struct regmap_config sirf_audio_codec_regmap_config
= {
451 .max_register
= AUDIO_PORT_IC_RXFIFO_INT_MSK
,
452 .cache_type
= REGCACHE_NONE
,
455 static int sirf_audio_codec_driver_probe(struct platform_device
*pdev
)
458 struct sirf_audio_codec
*sirf_audio_codec
;
460 struct resource
*mem_res
;
461 const struct of_device_id
*match
;
463 match
= of_match_node(sirf_audio_codec_of_match
, pdev
->dev
.of_node
);
465 sirf_audio_codec
= devm_kzalloc(&pdev
->dev
,
466 sizeof(struct sirf_audio_codec
), GFP_KERNEL
);
467 if (!sirf_audio_codec
)
470 platform_set_drvdata(pdev
, sirf_audio_codec
);
472 mem_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
473 base
= devm_ioremap_resource(&pdev
->dev
, mem_res
);
477 sirf_audio_codec
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, base
,
478 &sirf_audio_codec_regmap_config
);
479 if (IS_ERR(sirf_audio_codec
->regmap
))
480 return PTR_ERR(sirf_audio_codec
->regmap
);
482 sirf_audio_codec
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
483 if (IS_ERR(sirf_audio_codec
->clk
)) {
484 dev_err(&pdev
->dev
, "Get clock failed.\n");
485 return PTR_ERR(sirf_audio_codec
->clk
);
488 ret
= clk_prepare_enable(sirf_audio_codec
->clk
);
490 dev_err(&pdev
->dev
, "Enable clock failed.\n");
494 ret
= snd_soc_register_codec(&(pdev
->dev
),
495 &soc_codec_device_sirf_audio_codec
,
496 &sirf_audio_codec_dai
, 1);
498 dev_err(&pdev
->dev
, "Register Audio Codec dai failed.\n");
503 * Always open charge pump, if not, when the charge pump closed the
504 * adc will not stable
506 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
507 IC_CPFREQ
, IC_CPFREQ
);
509 if (of_device_is_compatible(pdev
->dev
.of_node
, "sirf,atlas6-audio-codec"))
510 regmap_update_bits(sirf_audio_codec
->regmap
,
511 AUDIO_IC_CODEC_CTRL0
, IC_CPEN
, IC_CPEN
);
515 clk_disable_unprepare(sirf_audio_codec
->clk
);
519 static int sirf_audio_codec_driver_remove(struct platform_device
*pdev
)
521 struct sirf_audio_codec
*sirf_audio_codec
= platform_get_drvdata(pdev
);
523 clk_disable_unprepare(sirf_audio_codec
->clk
);
524 snd_soc_unregister_codec(&(pdev
->dev
));
529 #ifdef CONFIG_PM_SLEEP
530 static int sirf_audio_codec_suspend(struct device
*dev
)
532 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(dev
);
534 regmap_read(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
535 &sirf_audio_codec
->reg_ctrl0
);
536 regmap_read(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL1
,
537 &sirf_audio_codec
->reg_ctrl1
);
538 clk_disable_unprepare(sirf_audio_codec
->clk
);
543 static int sirf_audio_codec_resume(struct device
*dev
)
545 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(dev
);
548 ret
= clk_prepare_enable(sirf_audio_codec
->clk
);
552 regmap_write(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
553 sirf_audio_codec
->reg_ctrl0
);
554 regmap_write(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL1
,
555 sirf_audio_codec
->reg_ctrl1
);
561 static const struct dev_pm_ops sirf_audio_codec_pm_ops
= {
562 SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend
, sirf_audio_codec_resume
)
565 static struct platform_driver sirf_audio_codec_driver
= {
567 .name
= "sirf-audio-codec",
568 .owner
= THIS_MODULE
,
569 .of_match_table
= sirf_audio_codec_of_match
,
570 .pm
= &sirf_audio_codec_pm_ops
,
572 .probe
= sirf_audio_codec_driver_probe
,
573 .remove
= sirf_audio_codec_driver_remove
,
576 module_platform_driver(sirf_audio_codec_driver
);
578 MODULE_DESCRIPTION("SiRF audio codec driver");
579 MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
580 MODULE_LICENSE("GPL v2");