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 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
);
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
);
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);
141 static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget
*w
,
142 struct snd_kcontrol
*kcontrol
, int event
)
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
);
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
);
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);
164 static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets
[] = {
165 SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1
,
167 SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1
,
169 SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1
,
173 static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets
[] = {
174 SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1
,
176 SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1
,
178 SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1
,
182 static 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
);
187 static 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
);
192 static 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,
205 SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0
, 3, 0,
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,
215 SND_SOC_DAPM_OUTPUT("HPOUTL"),
216 SND_SOC_DAPM_OUTPUT("HPOUTR"),
217 SND_SOC_DAPM_OUTPUT("SPKOUT"),
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
)),
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"),
238 SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0
,
242 static 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"},
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"},
282 static void sirf_audio_codec_tx_enable(struct sirf_audio_codec
*sirf_audio_codec
)
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
);
296 static void sirf_audio_codec_tx_disable(struct sirf_audio_codec
*sirf_audio_codec
)
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
);
303 static void sirf_audio_codec_rx_enable(struct sirf_audio_codec
*sirf_audio_codec
,
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
);
316 regmap_update_bits(sirf_audio_codec
->regmap
,
317 AUDIO_PORT_IC_CODEC_RX_CTRL
,
318 IC_RX_ENABLE_MONO
, IC_RX_ENABLE_MONO
);
320 regmap_update_bits(sirf_audio_codec
->regmap
,
321 AUDIO_PORT_IC_CODEC_RX_CTRL
,
322 IC_RX_ENABLE_STEREO
, IC_RX_ENABLE_STEREO
);
325 static void sirf_audio_codec_rx_disable(struct sirf_audio_codec
*sirf_audio_codec
)
327 regmap_update_bits(sirf_audio_codec
->regmap
,
328 AUDIO_PORT_IC_CODEC_RX_CTRL
,
329 IC_RX_ENABLE_STEREO
, ~IC_RX_ENABLE_STEREO
);
332 static int sirf_audio_codec_trigger(struct snd_pcm_substream
*substream
,
334 struct snd_soc_dai
*dai
)
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
;
341 * This is a workaround, When stop playback,
342 * need disable HP amp, avoid the current noise.
345 case SNDRV_PCM_TRIGGER_STOP
:
346 case SNDRV_PCM_TRIGGER_SUSPEND
:
347 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
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
);
353 sirf_audio_codec_rx_disable(sirf_audio_codec
);
355 case SNDRV_PCM_TRIGGER_START
:
356 case SNDRV_PCM_TRIGGER_RESUME
:
357 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
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
);
363 sirf_audio_codec_rx_enable(sirf_audio_codec
,
364 substream
->runtime
->channels
);
373 static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops
= {
374 .trigger
= sirf_audio_codec_trigger
,
377 static struct snd_soc_dai_driver sirf_audio_codec_dai
= {
378 .name
= "sirf-audio-codec",
380 .stream_name
= "Playback",
383 .rates
= SNDRV_PCM_RATE_48000
,
384 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
387 .stream_name
= "Capture",
390 .rates
= SNDRV_PCM_RATE_48000
,
391 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
393 .ops
= &sirf_audio_codec_dai_ops
,
396 static int sirf_audio_codec_probe(struct snd_soc_codec
*codec
)
398 struct snd_soc_dapm_context
*dapm
= snd_soc_codec_get_dapm(codec
);
400 pm_runtime_enable(codec
->dev
);
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
));
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
));
426 static int sirf_audio_codec_remove(struct snd_soc_codec
*codec
)
428 pm_runtime_disable(codec
->dev
);
432 static const struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec
= {
433 .probe
= sirf_audio_codec_probe
,
434 .remove
= sirf_audio_codec_remove
,
435 .component_driver
= {
436 .dapm_widgets
= sirf_audio_codec_dapm_widgets
,
437 .num_dapm_widgets
= ARRAY_SIZE(sirf_audio_codec_dapm_widgets
),
438 .dapm_routes
= sirf_audio_codec_map
,
439 .num_dapm_routes
= ARRAY_SIZE(sirf_audio_codec_map
),
441 .idle_bias_off
= true,
444 static const struct of_device_id sirf_audio_codec_of_match
[] = {
445 { .compatible
= "sirf,prima2-audio-codec" },
446 { .compatible
= "sirf,atlas6-audio-codec" },
449 MODULE_DEVICE_TABLE(of
, sirf_audio_codec_of_match
);
451 static const struct regmap_config sirf_audio_codec_regmap_config
= {
455 .max_register
= AUDIO_PORT_IC_RXFIFO_INT_MSK
,
456 .cache_type
= REGCACHE_NONE
,
459 static int sirf_audio_codec_driver_probe(struct platform_device
*pdev
)
462 struct sirf_audio_codec
*sirf_audio_codec
;
464 struct resource
*mem_res
;
465 const struct of_device_id
*match
;
467 match
= of_match_node(sirf_audio_codec_of_match
, pdev
->dev
.of_node
);
469 sirf_audio_codec
= devm_kzalloc(&pdev
->dev
,
470 sizeof(struct sirf_audio_codec
), GFP_KERNEL
);
471 if (!sirf_audio_codec
)
474 platform_set_drvdata(pdev
, sirf_audio_codec
);
476 mem_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
477 base
= devm_ioremap_resource(&pdev
->dev
, mem_res
);
479 return PTR_ERR(base
);
481 sirf_audio_codec
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, base
,
482 &sirf_audio_codec_regmap_config
);
483 if (IS_ERR(sirf_audio_codec
->regmap
))
484 return PTR_ERR(sirf_audio_codec
->regmap
);
486 sirf_audio_codec
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
487 if (IS_ERR(sirf_audio_codec
->clk
)) {
488 dev_err(&pdev
->dev
, "Get clock failed.\n");
489 return PTR_ERR(sirf_audio_codec
->clk
);
492 ret
= clk_prepare_enable(sirf_audio_codec
->clk
);
494 dev_err(&pdev
->dev
, "Enable clock failed.\n");
498 ret
= snd_soc_register_codec(&(pdev
->dev
),
499 &soc_codec_device_sirf_audio_codec
,
500 &sirf_audio_codec_dai
, 1);
502 dev_err(&pdev
->dev
, "Register Audio Codec dai failed.\n");
507 * Always open charge pump, if not, when the charge pump closed the
508 * adc will not stable
510 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
511 IC_CPFREQ
, IC_CPFREQ
);
513 if (of_device_is_compatible(pdev
->dev
.of_node
, "sirf,atlas6-audio-codec"))
514 regmap_update_bits(sirf_audio_codec
->regmap
,
515 AUDIO_IC_CODEC_CTRL0
, IC_CPEN
, IC_CPEN
);
519 clk_disable_unprepare(sirf_audio_codec
->clk
);
523 static int sirf_audio_codec_driver_remove(struct platform_device
*pdev
)
525 struct sirf_audio_codec
*sirf_audio_codec
= platform_get_drvdata(pdev
);
527 clk_disable_unprepare(sirf_audio_codec
->clk
);
528 snd_soc_unregister_codec(&(pdev
->dev
));
533 #ifdef CONFIG_PM_SLEEP
534 static int sirf_audio_codec_suspend(struct device
*dev
)
536 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(dev
);
538 regmap_read(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
539 &sirf_audio_codec
->reg_ctrl0
);
540 regmap_read(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL1
,
541 &sirf_audio_codec
->reg_ctrl1
);
542 clk_disable_unprepare(sirf_audio_codec
->clk
);
547 static int sirf_audio_codec_resume(struct device
*dev
)
549 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(dev
);
552 ret
= clk_prepare_enable(sirf_audio_codec
->clk
);
556 regmap_write(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
557 sirf_audio_codec
->reg_ctrl0
);
558 regmap_write(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL1
,
559 sirf_audio_codec
->reg_ctrl1
);
565 static const struct dev_pm_ops sirf_audio_codec_pm_ops
= {
566 SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend
, sirf_audio_codec_resume
)
569 static struct platform_driver sirf_audio_codec_driver
= {
571 .name
= "sirf-audio-codec",
572 .of_match_table
= sirf_audio_codec_of_match
,
573 .pm
= &sirf_audio_codec_pm_ops
,
575 .probe
= sirf_audio_codec_driver_probe
,
576 .remove
= sirf_audio_codec_driver_remove
,
579 module_platform_driver(sirf_audio_codec_driver
);
581 MODULE_DESCRIPTION("SiRF audio codec driver");
582 MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
583 MODULE_LICENSE("GPL v2");