2 * rk2928_codec.c ALSA SoC RK2928 codec driver
4 * Copyright 2012 Rockchip
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 #include <linux/module.h>
23 #include <linux/moduleparam.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
27 #include <linux/gpio.h>
28 #include <linux/platform_device.h>
29 #include <linux/slab.h>
30 #include <linux/workqueue.h>
32 #include <asm/delay.h>
33 #include <linux/wakelock.h>
34 #include <sound/core.h>
35 #include <sound/pcm.h>
36 #include <sound/pcm_params.h>
37 #include <sound/soc.h>
38 #include <sound/initval.h>
39 #include <sound/tlv.h>
41 #include <mach/iomux.h>
43 #include <linux/clk.h>
44 #include "rk2928_codec.h"
48 static struct rk2928_codec_data {
50 struct snd_soc_codec *codec;
61 struct rk2928_codec_pdata *pdata;
62 bool stop_phone_depop;
63 struct delayed_work h_delayed_work;
64 struct mutex mutex_lock;
67 static int DAC_event(struct snd_soc_dapm_widget *w,
68 struct snd_kcontrol *kcontrol, int event)
70 struct snd_soc_codec *codec = w->codec;
71 struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec);
73 DBG("%s::%d event = %d\n",__FUNCTION__,__LINE__,event);
76 case SND_SOC_DAPM_PRE_PMD:
77 #ifdef CONFIG_MODEM_SOUND
78 if(rk2928_data.call_enable)
81 //before widget power down
82 if(rk2928_data.spkctl != INVALID_GPIO) {
83 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
85 if(rk2928_data.hp_ctl != 0 && rk2928_data.headset_status == HP_IN) {
86 // gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW);
89 case SND_SOC_DAPM_POST_PMU:
90 //after widget power up
91 if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT) {
92 gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
95 if(rk2928_data.hp_ctl != 0 ) {//&& rk2928_data.headset_status == HP_IN
96 gpio_direction_output(rk2928_data.hp_ctl, GPIO_HIGH);
104 static const struct snd_soc_dapm_widget rk2928_dapm_widgets[] = {
105 SND_SOC_DAPM_DAC_E("DACL", "HIFI Playback", CODEC_REG_POWER, 5, 1,DAC_event, SND_SOC_DAPM_PRE_PMD|SND_SOC_DAPM_POST_PMU),
106 SND_SOC_DAPM_DAC_E("DACR", "HIFI Playback", CODEC_REG_POWER, 4, 1,DAC_event, SND_SOC_DAPM_PRE_PMD|SND_SOC_DAPM_POST_PMU),
107 SND_SOC_DAPM_PGA("DACL Amp", CODEC_REG_DAC_GAIN, 2, 0, NULL, 0),
108 SND_SOC_DAPM_PGA("DACR Amp", CODEC_REG_DAC_GAIN, 0, 0, NULL, 0),
109 SND_SOC_DAPM_OUTPUT("SPKL"),
110 SND_SOC_DAPM_OUTPUT("SPKR"),
111 SND_SOC_DAPM_ADC("ADCL", "HIFI Capture", CODEC_REG_POWER, 3, 1),
112 SND_SOC_DAPM_INPUT("MICL"),
113 SND_SOC_DAPM_ADC("ADCR", "HIFI Capture", CODEC_REG_POWER, 2, 1),
114 SND_SOC_DAPM_INPUT("MICR"),
117 static const struct snd_soc_dapm_route rk2928_audio_map[] = {
118 {"SPKL", "DACL Amp", "DACL"},
119 {"SPKR", "DACR Amp", "DACR"},
120 {"ADCL", NULL, "MICL"},
121 {"ADCR", NULL, "MICR"},
124 static const struct snd_soc_dapm_widget rk2926_dapm_widgets[] = {
125 SND_SOC_DAPM_DAC("DACL", "HIFI Playback", CODEC_REG_POWER, 5, 1),
126 SND_SOC_DAPM_DAC("DACR", "HIFI Playback", CODEC_REG_POWER, 4, 1),
127 SND_SOC_DAPM_PGA("DACL Amp", CODEC_REG_DAC_GAIN, 2, 0, NULL, 0),
128 SND_SOC_DAPM_PGA("DACR Amp", CODEC_REG_DAC_GAIN, 0, 0, NULL, 0),
129 SND_SOC_DAPM_OUTPUT("SPKL"),
130 SND_SOC_DAPM_OUTPUT("SPKR"),
131 SND_SOC_DAPM_ADC("ADCR", "HIFI Capture", CODEC_REG_POWER, 2, 1),
132 SND_SOC_DAPM_INPUT("MICR"),
135 static const struct snd_soc_dapm_route rk2926_audio_map[] = {
136 {"SPKL", "DACL Amp", "DACL"},
137 {"SPKR", "DACR Amp", "DACR"},
138 {"ADCR", NULL, "MICR"},
141 static unsigned int rk2928_read(struct snd_soc_codec *codec, unsigned int reg)
143 return readl(rk2928_data.regbase + reg*4);
146 static int rk2928_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
148 #ifdef CONFIG_MODEM_SOUND
149 if(rk2928_data.call_enable)
152 DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, reg, value);
155 writel(value, rk2928_data.regbase + reg*4);
156 if( (reg == CODEC_REG_POWER) && ( (value & m_PD_DAC) == 0)) {
161 static int rk2928_write_incall(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
163 DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, reg, value);
166 writel(value, rk2928_data.regbase + reg*4);
167 if( (reg == CODEC_REG_POWER) && ( (value & m_PD_DAC) == 0)) {
173 static int rk2928_write_mask(struct snd_soc_codec *codec, unsigned int reg,
174 unsigned int mask, unsigned int value)
176 unsigned int regvalue = rk2928_read(codec, reg);
178 DBG("%s reg 0x%02x mask 0x%02x value 0x%02x", __FUNCTION__, reg, mask, value);
181 regvalue |= mask & value;
182 return rk2928_write(codec, reg, regvalue);
185 void codec_set_spk(bool on)
188 DBG("%s speaker is disabled\n", __FUNCTION__);
189 rk2928_data.hdmi_enable = 1;
190 if(rk2928_data.mute == 0) {
191 rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
192 if(rk2928_data.spkctl != INVALID_GPIO) {
193 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
198 DBG("%s speaker is enabled\n", __FUNCTION__);
199 rk2928_data.hdmi_enable = 0;
200 if(rk2928_data.mute == 0) {
201 rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
202 if((rk2928_data.spkctl != INVALID_GPIO) && (rk2928_data.headset_status == HP_OUT)) {
203 gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
209 static void call_delay_work(struct work_struct *work)
211 struct snd_soc_codec *codec = rk2928_data.codec;
214 printk("%s speaker is disabled\n", __FUNCTION__);
215 rk2928_write_incall(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
216 rk2928_write_incall(codec, CODEC_REG_POWER, 0x0c);
217 rk2928_write_incall(codec, CODEC_REG_ADC_SOURCE, 0x03);
218 rk2928_write_incall(codec, CODEC_REG_ADC_PGA_GAIN, 0x33);//spk 0x33
219 rk2928_data.call_enable = 1;
220 mutex_unlock(&rk2928_data.mutex_lock);
223 #ifdef CONFIG_MODEM_SOUND
224 void call_set_spk(int on)
226 struct snd_soc_codec *codec = rk2928_data.codec;
229 mutex_lock(&rk2928_data.mutex_lock);
233 printk("%s speaker is enabled\n", __FUNCTION__);
234 rk2928_data.call_enable = 0;
235 // rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
236 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
237 printk("rk2928 codec stop phone need depop\n");
238 rk2928_data.stop_phone_depop = true;
241 rk2928_write_incall(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
242 schedule_delayed_work(&rk2928_data.h_delayed_work, msecs_to_jiffies(1000));
245 printk("%s speaker is disabled\n", __FUNCTION__);
246 rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
247 rk2928_write(codec, CODEC_REG_POWER, 0x0c);
248 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
249 rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0x11);//headset
250 rk2928_data.call_enable = 1;
253 printk("%s speaker is disabled\n", __FUNCTION__);
254 rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
255 rk2928_write(codec, CODEC_REG_POWER, 0x0c);
256 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
257 rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0x33);//spk 0x33
258 rk2928_data.call_enable = 1;
261 mutex_unlock(&rk2928_data.mutex_lock);
265 #ifdef CONFIG_RK_HEADSET_DET
267 void rk2928_codec_set_spk(bool on)
269 struct snd_soc_codec *codec = rk2928_data.codec;
273 rk2928_data.headset_status = HP_IN;
275 rk2928_data.headset_status = HP_OUT;
276 if(rk2928_data.call_enable)
278 printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level);
280 if(rk2928_data.spkctl != INVALID_GPIO)
282 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
286 if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY
287 || codec->dapm.bias_level == SND_SOC_BIAS_OFF){
290 if(rk2928_data.spkctl != INVALID_GPIO)
292 gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
298 static int rk2928_audio_hw_params(struct snd_pcm_substream *substream,
299 struct snd_pcm_hw_params *params,
300 struct snd_soc_dai *dai)
302 // struct snd_soc_pcm_runtime *rtd = substream->private_data;
303 // struct snd_soc_codec *codec = rtd->codec;
304 // struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec);
306 DBG("%s", __FUNCTION__);
311 static int rk2928_audio_trigger(struct snd_pcm_substream *substream, int cmd,
312 struct snd_soc_dai *dai)
314 struct snd_soc_pcm_runtime *rtd = substream->private_data;
315 struct snd_soc_codec *codec = rtd->codec;
316 struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec);
319 DBG("%s cmd 0x%x", __FUNCTION__, cmd);
322 case SNDRV_PCM_TRIGGER_START:
323 case SNDRV_PCM_TRIGGER_RESUME:
324 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
325 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
326 // rk2928_write(codec, CODEC_REG_DAC_GAIN, v_GAIN_DAC(DAC_GAIN_3DB_P));
327 if(!rk2928_data.hdmi_enable) {
328 data = rk2928_read(codec, CODEC_REG_POWER);
329 if(soc_is_rk2928g()){
330 if( (data & m_PD_ADC) == 0) {
339 if( (data & m_PD_ADC_R) == 0) {
341 data |= v_PD_ADC_R(1);
348 DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, CODEC_REG_POWER, data);
349 writel(data, rk2928_data.regbase + CODEC_REG_POWER*4);
353 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
355 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
358 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
360 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
363 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
365 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
369 data = rk2928_read(codec, CODEC_REG_POWER);
370 if( soc_is_rk2928g() ) {
376 data |= v_PD_ADC_R(0);
378 DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, CODEC_REG_POWER, data);
379 writel(data, rk2928_data.regbase + CODEC_REG_POWER*4);
382 rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
383 if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT && rk2928_data.stop_phone_depop ) {
385 gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
386 rk2928_data.stop_phone_depop = false;
389 rk2928_data.mute = 0;
390 // if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT) {
391 // gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
395 rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0xFF);
396 rk2928_write(codec, 0x08, 0xff);
397 rk2928_write(codec, 0x09, 0x07);
400 case SNDRV_PCM_TRIGGER_STOP:
401 case SNDRV_PCM_TRIGGER_SUSPEND:
402 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
403 #ifdef CONFIG_MODEM_SOUND
404 if(rk2928_data.call_enable)
407 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
408 //if(rk2928_data.spkctl != INVALID_GPIO) {
409 //gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
411 rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
412 rk2928_data.mute = 1;
421 static int rk2928_audio_startup(struct snd_pcm_substream *substream,
422 struct snd_soc_dai *dai)
424 // struct snd_soc_pcm_runtime *rtd = substream->private_data;
425 // struct snd_soc_codec *codec = rtd->codec;
426 DBG("%s", __FUNCTION__);
430 static int rk2928_set_bias_level(struct snd_soc_codec *codec,
431 enum snd_soc_bias_level level)
433 DBG("%s level %d\n", __FUNCTION__, level);
440 case SND_SOC_BIAS_ON:
442 case SND_SOC_BIAS_PREPARE:
443 rk2928_write_mask(codec, CODEC_REG_POWER, m_PD_MIC_BIAS | m_PD_CODEC, v_PD_MIC_BIAS(0) | v_PD_CODEC(0));
445 case SND_SOC_BIAS_STANDBY:
446 case SND_SOC_BIAS_OFF:
447 printk("rk2928 codec standby\n");
448 #ifdef CONFIG_MODEM_SOUND
449 if(rk2928_data.call_enable)
452 // if(rk2928_data.spkctl != INVALID_GPIO) {
453 // gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
455 rk2928_write(codec, CODEC_REG_POWER, v_PWR_OFF);
460 codec->dapm.bias_level = level;
464 static void rk2929_codec_reset(void)
467 cru_set_soft_reset(SOFT_RST_ACODEC, true);
469 cru_set_soft_reset(SOFT_RST_ACODEC, false);
472 static int rk2928_probe(struct snd_soc_codec *codec)
474 struct platform_device *pdev = to_platform_device(codec->dev);
475 struct snd_soc_dapm_context *dapm = &codec->dapm;
476 struct resource *res, *mem;
477 struct rk2928_codec_pdata *pdata;
480 DBG("%s", __FUNCTION__);
482 snd_soc_codec_set_drvdata(codec, &rk2928_data);
484 rk2928_data.dev = &pdev->dev;
485 rk2928_data.pdata = pdev->dev.platform_data;
486 pdata = rk2928_data.pdata;
487 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
489 dev_err(&pdev->dev, "Unable to get register resource\n");
493 rk2928_data.regbase_phy = res->start;
494 rk2928_data.regsize_phy = (res->end - res->start) + 1;
495 mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name);
498 dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n");
503 rk2928_data.regbase = (int)ioremap(res->start, (res->end - res->start) + 1);
504 if (!rk2928_data.regbase) {
505 dev_err(&pdev->dev, "cannot ioremap acodec registers\n");
510 rk2928_data.pclk = clk_get(NULL,"pclk_acodec");
511 if(IS_ERR(rk2928_data.pclk))
513 dev_err(rk2928_data.dev, "Unable to get acodec hclk\n");
517 clk_enable(rk2928_data.pclk);
519 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
521 rk2928_data.spkctl = INVALID_GPIO;
524 rk2928_data.spkctl = res->start;
527 if(rk2928_data.spkctl != INVALID_GPIO) {
528 ret = gpio_request(rk2928_data.spkctl, NULL);
530 gpio_free(rk2928_data.spkctl);
533 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
535 //------------------------------------------------------------------
537 ret = pdata->hpctl_io_init();
540 rk2928_data.hp_ctl = pdata->hpctl;
541 gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW);
544 rk2929_codec_reset();
546 // Select SDI input from internal audio codec
547 writel(0x04000400, RK2928_GRF_BASE + GRF_SOC_CON0);
549 // Mute and Power off codec
550 rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
551 rk2928_set_bias_level(codec, SND_SOC_BIAS_OFF);
552 if(soc_is_rk2928g()){
553 snd_soc_dapm_new_controls(dapm, rk2928_dapm_widgets,
554 ARRAY_SIZE(rk2928_dapm_widgets));
555 snd_soc_dapm_add_routes(dapm, rk2928_audio_map, ARRAY_SIZE(rk2928_audio_map));
557 snd_soc_dapm_new_controls(dapm, rk2926_dapm_widgets,
558 ARRAY_SIZE(rk2926_dapm_widgets));
559 snd_soc_dapm_add_routes(dapm, rk2926_audio_map, ARRAY_SIZE(rk2926_audio_map));
562 INIT_DELAYED_WORK(&rk2928_data.h_delayed_work, call_delay_work);
563 mutex_init(&rk2928_data.mutex_lock);
564 rk2928_data.call_enable = 0;
565 rk2928_data.headset_status = HP_OUT;
566 rk2928_data.codec=codec;
567 rk2928_data.stop_phone_depop=false;
571 release_mem_region(res->start,(res->end - res->start) + 1);
572 // clk_disable(rk2928_data.hclk);
574 DBG("%s failed", __FUNCTION__);
578 static int rk2928_remove(struct snd_soc_codec *codec)
583 static int rk2928_suspend(struct snd_soc_codec *codec, pm_message_t state)
585 DBG("%s", __FUNCTION__);
586 rk2928_set_bias_level(codec, SND_SOC_BIAS_OFF);
587 clk_disable(rk2928_data.pclk);
591 static int rk2928_resume(struct snd_soc_codec *codec)
593 DBG("%s", __FUNCTION__);
594 clk_enable(rk2928_data.pclk);
595 rk2928_write(codec, CODEC_REG_POWER, v_PD_ADC(1) | v_PD_DAC(1) | v_PD_MIC_BIAS(0));
599 static struct snd_soc_codec_driver rk2928_audio_codec_drv = {
600 .probe = rk2928_probe,
601 .remove = rk2928_remove,
602 .suspend = rk2928_suspend,
603 .resume = rk2928_resume,
605 .write = rk2928_write,
606 .set_bias_level = rk2928_set_bias_level,
609 static struct snd_soc_dai_ops rk2928_audio_codec_ops = {
610 .hw_params = rk2928_audio_hw_params,
611 .trigger = rk2928_audio_trigger,
612 .startup = rk2928_audio_startup,
615 static struct snd_soc_dai_driver rk2928_codec_dai = {
616 .name = "rk2928-codec",
618 .stream_name = "HIFI Playback",
621 .rates = SNDRV_PCM_RATE_8000_48000,
622 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |
623 SNDRV_PCM_FMTBIT_S24_LE,
626 .stream_name = "HIFI Capture",
629 .rates = SNDRV_PCM_RATE_8000_48000,
630 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE,
632 .ops = &rk2928_audio_codec_ops,
635 static __devinit int rk2928_codec_probe(struct platform_device *pdev)
639 DBG("%s", __FUNCTION__);
641 /* Register ASoC codec DAI */
642 r = snd_soc_register_codec(&pdev->dev, &rk2928_audio_codec_drv,
643 &rk2928_codec_dai, 1);
645 dev_err(&pdev->dev, "can't register ASoC rk2928 audio codec\n");
649 DBG("%s success", __FUNCTION__);
654 static int __devexit rk2928_codec_remove(struct platform_device *pdev)
656 snd_soc_unregister_codec(&pdev->dev);
660 static void rk2928_codec_shutdown(struct platform_device *pdev)
662 printk("%s .....\n", __FUNCTION__);
663 if(rk2928_data.spkctl != INVALID_GPIO)
664 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
665 if(rk2928_data.hp_ctl != 0 )
666 gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW);
668 static struct platform_driver rk2928_codec_driver = {
669 .probe = rk2928_codec_probe,
670 .remove = __devexit_p(rk2928_codec_remove),
672 .name = "rk2928-codec",
673 .owner = THIS_MODULE,
675 .shutdown = rk2928_codec_shutdown,
678 static int __init rk2928_codec_init(void)
680 return platform_driver_register(&rk2928_codec_driver);
682 module_init(rk2928_codec_init);
684 static void __exit rk2928_codec_exit(void)
686 #ifdef CODEC_I2C_MODE
687 i2c_del_driver(&rk2928_codec_driver);
689 platform_driver_unregister(&rk2928_codec_driver);
692 module_exit(rk2928_codec_exit);
694 MODULE_DESCRIPTION("ASoC RK2928 codec driver");
695 MODULE_LICENSE("GPL");