1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * SiRF audio codec driver
5 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/pm_runtime.h>
12 #include <linux/of_device.h>
13 #include <linux/clk.h>
14 #include <linux/delay.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>
25 #include "sirf-audio-codec.h"
27 struct sirf_audio_codec
{
29 struct regmap
*regmap
;
30 u32 reg_ctrl0
, reg_ctrl1
;
33 static const char * const input_mode_mux
[] = {"Single-ended",
36 static const struct soc_enum input_mode_mux_enum
=
37 SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1
, 4, 2, input_mode_mux
);
39 static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control
=
40 SOC_DAPM_ENUM("Route", input_mode_mux_enum
);
42 static const DECLARE_TLV_DB_SCALE(playback_vol_tlv
, -12400, 100, 0);
43 static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2
, 500, 100, 0);
44 static 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),
49 static 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
),
56 static 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
),
63 static 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),
68 static 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),
73 static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control
=
74 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 9, 1, 0);
76 static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control
=
77 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 8, 1, 0);
79 static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control
=
80 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 7, 1, 0);
82 static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control
=
83 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 6, 1, 0);
85 static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control
=
86 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 11, 1, 0);
88 static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control
=
89 SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0
, 10, 1, 0);
91 /* After enable adc, Delay 200ms to avoid pop noise */
92 static int adc_enable_delay_event(struct snd_soc_dapm_widget
*w
,
93 struct snd_kcontrol
*kcontrol
, int event
)
96 case SND_SOC_DAPM_POST_PMU
:
106 static void enable_and_reset_codec(struct regmap
*regmap
,
107 u32 codec_enable_bits
, u32 codec_reset_bits
)
109 regmap_update_bits(regmap
, AUDIO_IC_CODEC_CTRL1
,
110 codec_enable_bits
| codec_reset_bits
,
113 regmap_update_bits(regmap
, AUDIO_IC_CODEC_CTRL1
,
114 codec_reset_bits
, codec_reset_bits
);
117 static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget
*w
,
118 struct snd_kcontrol
*kcontrol
, int event
)
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
);
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 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
);
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
);
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);
163 static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets
[] = {
164 SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1
,
166 SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1
,
168 SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1
,
172 static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets
[] = {
173 SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1
,
175 SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1
,
177 SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1
,
181 static 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
);
186 static 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
);
191 static 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,
204 SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0
, 3, 0,
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,
214 SND_SOC_DAPM_OUTPUT("HPOUTL"),
215 SND_SOC_DAPM_OUTPUT("HPOUTR"),
216 SND_SOC_DAPM_OUTPUT("SPKOUT"),
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
)),
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"),
237 SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0
,
241 static 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"},
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"},
281 static void sirf_audio_codec_tx_enable(struct sirf_audio_codec
*sirf_audio_codec
)
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
);
295 static void sirf_audio_codec_tx_disable(struct sirf_audio_codec
*sirf_audio_codec
)
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
);
302 static void sirf_audio_codec_rx_enable(struct sirf_audio_codec
*sirf_audio_codec
,
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
);
315 regmap_update_bits(sirf_audio_codec
->regmap
,
316 AUDIO_PORT_IC_CODEC_RX_CTRL
,
317 IC_RX_ENABLE_MONO
, IC_RX_ENABLE_MONO
);
319 regmap_update_bits(sirf_audio_codec
->regmap
,
320 AUDIO_PORT_IC_CODEC_RX_CTRL
,
321 IC_RX_ENABLE_STEREO
, IC_RX_ENABLE_STEREO
);
324 static void sirf_audio_codec_rx_disable(struct sirf_audio_codec
*sirf_audio_codec
)
326 regmap_update_bits(sirf_audio_codec
->regmap
,
327 AUDIO_PORT_IC_CODEC_RX_CTRL
,
328 IC_RX_ENABLE_STEREO
, ~IC_RX_ENABLE_STEREO
);
331 static int sirf_audio_codec_trigger(struct snd_pcm_substream
*substream
,
333 struct snd_soc_dai
*dai
)
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
;
340 * This is a workaround, When stop playback,
341 * need disable HP amp, avoid the current noise.
344 case SNDRV_PCM_TRIGGER_STOP
:
345 case SNDRV_PCM_TRIGGER_SUSPEND
:
346 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
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
);
352 sirf_audio_codec_rx_disable(sirf_audio_codec
);
354 case SNDRV_PCM_TRIGGER_START
:
355 case SNDRV_PCM_TRIGGER_RESUME
:
356 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
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
);
362 sirf_audio_codec_rx_enable(sirf_audio_codec
,
363 substream
->runtime
->channels
);
372 static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops
= {
373 .trigger
= sirf_audio_codec_trigger
,
376 static struct snd_soc_dai_driver sirf_audio_codec_dai
= {
377 .name
= "sirf-audio-codec",
379 .stream_name
= "Playback",
382 .rates
= SNDRV_PCM_RATE_48000
,
383 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
386 .stream_name
= "Capture",
389 .rates
= SNDRV_PCM_RATE_48000
,
390 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
392 .ops
= &sirf_audio_codec_dai_ops
,
395 static int sirf_audio_codec_probe(struct snd_soc_component
*component
)
397 struct snd_soc_dapm_context
*dapm
= snd_soc_component_get_dapm(component
);
399 pm_runtime_enable(component
->dev
);
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
));
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
));
425 static void sirf_audio_codec_remove(struct snd_soc_component
*component
)
427 pm_runtime_disable(component
->dev
);
430 static 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,
439 .non_legacy_dai_naming
= 1,
442 static const struct of_device_id sirf_audio_codec_of_match
[] = {
443 { .compatible
= "sirf,prima2-audio-codec" },
444 { .compatible
= "sirf,atlas6-audio-codec" },
447 MODULE_DEVICE_TABLE(of
, sirf_audio_codec_of_match
);
449 static const struct regmap_config sirf_audio_codec_regmap_config
= {
453 .max_register
= AUDIO_PORT_IC_RXFIFO_INT_MSK
,
454 .cache_type
= REGCACHE_NONE
,
457 static int sirf_audio_codec_driver_probe(struct platform_device
*pdev
)
460 struct sirf_audio_codec
*sirf_audio_codec
;
463 sirf_audio_codec
= devm_kzalloc(&pdev
->dev
,
464 sizeof(struct sirf_audio_codec
), GFP_KERNEL
);
465 if (!sirf_audio_codec
)
468 platform_set_drvdata(pdev
, sirf_audio_codec
);
470 base
= devm_platform_ioremap_resource(pdev
, 0);
472 return PTR_ERR(base
);
474 sirf_audio_codec
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, base
,
475 &sirf_audio_codec_regmap_config
);
476 if (IS_ERR(sirf_audio_codec
->regmap
))
477 return PTR_ERR(sirf_audio_codec
->regmap
);
479 sirf_audio_codec
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
480 if (IS_ERR(sirf_audio_codec
->clk
)) {
481 dev_err(&pdev
->dev
, "Get clock failed.\n");
482 return PTR_ERR(sirf_audio_codec
->clk
);
485 ret
= clk_prepare_enable(sirf_audio_codec
->clk
);
487 dev_err(&pdev
->dev
, "Enable clock failed.\n");
491 ret
= devm_snd_soc_register_component(&(pdev
->dev
),
492 &soc_codec_device_sirf_audio_codec
,
493 &sirf_audio_codec_dai
, 1);
495 dev_err(&pdev
->dev
, "Register Audio Codec dai failed.\n");
500 * Always open charge pump, if not, when the charge pump closed the
501 * adc will not stable
503 regmap_update_bits(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
504 IC_CPFREQ
, IC_CPFREQ
);
506 if (of_device_is_compatible(pdev
->dev
.of_node
, "sirf,atlas6-audio-codec"))
507 regmap_update_bits(sirf_audio_codec
->regmap
,
508 AUDIO_IC_CODEC_CTRL0
, IC_CPEN
, IC_CPEN
);
512 clk_disable_unprepare(sirf_audio_codec
->clk
);
516 static int sirf_audio_codec_driver_remove(struct platform_device
*pdev
)
518 struct sirf_audio_codec
*sirf_audio_codec
= platform_get_drvdata(pdev
);
520 clk_disable_unprepare(sirf_audio_codec
->clk
);
525 #ifdef CONFIG_PM_SLEEP
526 static int sirf_audio_codec_suspend(struct device
*dev
)
528 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(dev
);
530 regmap_read(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
531 &sirf_audio_codec
->reg_ctrl0
);
532 regmap_read(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL1
,
533 &sirf_audio_codec
->reg_ctrl1
);
534 clk_disable_unprepare(sirf_audio_codec
->clk
);
539 static int sirf_audio_codec_resume(struct device
*dev
)
541 struct sirf_audio_codec
*sirf_audio_codec
= dev_get_drvdata(dev
);
544 ret
= clk_prepare_enable(sirf_audio_codec
->clk
);
548 regmap_write(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL0
,
549 sirf_audio_codec
->reg_ctrl0
);
550 regmap_write(sirf_audio_codec
->regmap
, AUDIO_IC_CODEC_CTRL1
,
551 sirf_audio_codec
->reg_ctrl1
);
557 static const struct dev_pm_ops sirf_audio_codec_pm_ops
= {
558 SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend
, sirf_audio_codec_resume
)
561 static struct platform_driver sirf_audio_codec_driver
= {
563 .name
= "sirf-audio-codec",
564 .of_match_table
= sirf_audio_codec_of_match
,
565 .pm
= &sirf_audio_codec_pm_ops
,
567 .probe
= sirf_audio_codec_driver_probe
,
568 .remove
= sirf_audio_codec_driver_remove
,
571 module_platform_driver(sirf_audio_codec_driver
);
573 MODULE_DESCRIPTION("SiRF audio codec driver");
574 MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
575 MODULE_LICENSE("GPL v2");