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 static void call_delay_work(struct work_struct *work)
187 struct snd_soc_codec *codec = rk2928_data.codec;
190 printk("%s speaker is disabled\n", __FUNCTION__);
191 rk2928_write_incall(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
192 rk2928_write_incall(codec, CODEC_REG_POWER, 0x0c);
193 rk2928_write_incall(codec, CODEC_REG_ADC_SOURCE, 0x03);
194 rk2928_write_incall(codec, CODEC_REG_ADC_PGA_GAIN, 0x33);//spk 0x33
195 rk2928_data.call_enable = 1;
196 mutex_unlock(&rk2928_data.mutex_lock);
199 #ifdef CONFIG_MODEM_SOUND
200 void call_set_spk(int on)
202 struct snd_soc_codec *codec = rk2928_data.codec;
205 mutex_lock(&rk2928_data.mutex_lock);
209 printk("%s speaker is enabled\n", __FUNCTION__);
210 rk2928_data.call_enable = 0;
211 // rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
212 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
213 printk("rk2928 codec stop phone need depop\n");
214 rk2928_data.stop_phone_depop = true;
217 rk2928_write_incall(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
218 schedule_delayed_work(&rk2928_data.h_delayed_work, msecs_to_jiffies(1000));
221 printk("%s speaker is disabled\n", __FUNCTION__);
222 rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
223 rk2928_write(codec, CODEC_REG_POWER, 0x0c);
224 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
225 rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0x11);//headset
226 rk2928_data.call_enable = 1;
229 printk("%s speaker is disabled\n", __FUNCTION__);
230 rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
231 rk2928_write(codec, CODEC_REG_POWER, 0x0c);
232 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
233 rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0x33);//spk 0x33
234 rk2928_data.call_enable = 1;
237 mutex_unlock(&rk2928_data.mutex_lock);
241 #ifdef CONFIG_RK_HEADSET_DET
243 void rk2928_codec_set_spk(bool on)
245 struct snd_soc_codec *codec = rk2928_data.codec;
249 rk2928_data.headset_status = HP_IN;
251 rk2928_data.headset_status = HP_OUT;
252 if(rk2928_data.call_enable)
254 printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level);
256 if(rk2928_data.spkctl != INVALID_GPIO)
258 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
262 if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY
263 || codec->dapm.bias_level == SND_SOC_BIAS_OFF){
266 if(rk2928_data.spkctl != INVALID_GPIO)
268 gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
274 static int rk2928_audio_hw_params(struct snd_pcm_substream *substream,
275 struct snd_pcm_hw_params *params,
276 struct snd_soc_dai *dai)
278 // struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 // struct snd_soc_codec *codec = rtd->codec;
280 // struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec);
282 DBG("%s", __FUNCTION__);
287 static int rk2928_audio_trigger(struct snd_pcm_substream *substream, int cmd,
288 struct snd_soc_dai *dai)
290 struct snd_soc_pcm_runtime *rtd = substream->private_data;
291 struct snd_soc_codec *codec = rtd->codec;
292 struct rk2928_codec_data *priv = snd_soc_codec_get_drvdata(codec);
295 DBG("%s cmd 0x%x", __FUNCTION__, cmd);
298 case SNDRV_PCM_TRIGGER_START:
299 case SNDRV_PCM_TRIGGER_RESUME:
300 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
301 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
302 // rk2928_write(codec, CODEC_REG_DAC_GAIN, v_GAIN_DAC(DAC_GAIN_3DB_P));
303 if(!rk2928_data.hdmi_enable) {
304 data = rk2928_read(codec, CODEC_REG_POWER);
305 if(soc_is_rk2928g()){
306 if( (data & m_PD_ADC) == 0) {
315 if( (data & m_PD_ADC_R) == 0) {
317 data |= v_PD_ADC_R(1);
324 DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, CODEC_REG_POWER, data);
325 writel(data, rk2928_data.regbase + CODEC_REG_POWER*4);
329 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
331 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
334 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
336 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
339 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x03);
341 rk2928_write(codec, CODEC_REG_ADC_SOURCE, 0x00);
345 data = rk2928_read(codec, CODEC_REG_POWER);
346 if( soc_is_rk2928g() ) {
352 data |= v_PD_ADC_R(0);
354 DBG("%s reg 0x%02x value 0x%02x", __FUNCTION__, CODEC_REG_POWER, data);
355 writel(data, rk2928_data.regbase + CODEC_REG_POWER*4);
358 rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
359 if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT && rk2928_data.stop_phone_depop ) {
361 gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
362 rk2928_data.stop_phone_depop = false;
365 rk2928_data.mute = 0;
366 // if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT) {
367 // gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
371 rk2928_write(codec, CODEC_REG_ADC_PGA_GAIN, 0xFF);
372 rk2928_write(codec, 0x08, 0xff);
373 rk2928_write(codec, 0x09, 0x07);
376 case SNDRV_PCM_TRIGGER_STOP:
377 case SNDRV_PCM_TRIGGER_SUSPEND:
378 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
379 #ifdef CONFIG_MODEM_SOUND
380 if(rk2928_data.call_enable)
383 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
384 //if(rk2928_data.spkctl != INVALID_GPIO) {
385 //gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
387 rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
388 rk2928_data.mute = 1;
397 static int rk2928_audio_startup(struct snd_pcm_substream *substream,
398 struct snd_soc_dai *dai)
400 // struct snd_soc_pcm_runtime *rtd = substream->private_data;
401 // struct snd_soc_codec *codec = rtd->codec;
402 DBG("%s", __FUNCTION__);
406 static int rk2928_set_bias_level(struct snd_soc_codec *codec,
407 enum snd_soc_bias_level level)
409 DBG("%s level %d\n", __FUNCTION__, level);
416 case SND_SOC_BIAS_ON:
418 case SND_SOC_BIAS_PREPARE:
419 rk2928_write_mask(codec, CODEC_REG_POWER, m_PD_MIC_BIAS | m_PD_CODEC, v_PD_MIC_BIAS(0) | v_PD_CODEC(0));
421 case SND_SOC_BIAS_STANDBY:
422 case SND_SOC_BIAS_OFF:
423 printk("rk2928 codec standby\n");
424 #ifdef CONFIG_MODEM_SOUND
425 if(rk2928_data.call_enable)
428 // if(rk2928_data.spkctl != INVALID_GPIO) {
429 // gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
431 rk2928_write(codec, CODEC_REG_POWER, v_PWR_OFF);
436 codec->dapm.bias_level = level;
440 static void rk2929_codec_reset(void)
443 cru_set_soft_reset(SOFT_RST_ACODEC, true);
445 cru_set_soft_reset(SOFT_RST_ACODEC, false);
448 static int rk2928_probe(struct snd_soc_codec *codec)
450 struct platform_device *pdev = to_platform_device(codec->dev);
451 struct snd_soc_dapm_context *dapm = &codec->dapm;
452 struct resource *res, *mem;
453 struct rk2928_codec_pdata *pdata;
456 DBG("%s", __FUNCTION__);
458 snd_soc_codec_set_drvdata(codec, &rk2928_data);
460 rk2928_data.dev = &pdev->dev;
461 rk2928_data.pdata = pdev->dev.platform_data;
462 pdata = rk2928_data.pdata;
463 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
465 dev_err(&pdev->dev, "Unable to get register resource\n");
469 rk2928_data.regbase_phy = res->start;
470 rk2928_data.regsize_phy = (res->end - res->start) + 1;
471 mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name);
474 dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n");
479 rk2928_data.regbase = (int)ioremap(res->start, (res->end - res->start) + 1);
480 if (!rk2928_data.regbase) {
481 dev_err(&pdev->dev, "cannot ioremap acodec registers\n");
486 rk2928_data.pclk = clk_get(NULL,"pclk_acodec");
487 if(IS_ERR(rk2928_data.pclk))
489 dev_err(rk2928_data.dev, "Unable to get acodec hclk\n");
493 clk_enable(rk2928_data.pclk);
495 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
497 rk2928_data.spkctl = INVALID_GPIO;
500 rk2928_data.spkctl = res->start;
503 if(rk2928_data.spkctl != INVALID_GPIO) {
504 ret = gpio_request(rk2928_data.spkctl, NULL);
506 gpio_free(rk2928_data.spkctl);
509 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
511 //------------------------------------------------------------------
513 ret = pdata->hpctl_io_init();
516 rk2928_data.hp_ctl = pdata->hpctl;
517 gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW);
520 rk2929_codec_reset();
522 // Select SDI input from internal audio codec
523 writel(0x04000400, RK2928_GRF_BASE + GRF_SOC_CON0);
525 // Mute and Power off codec
526 rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
527 rk2928_set_bias_level(codec, SND_SOC_BIAS_OFF);
528 if(soc_is_rk2928g()){
529 snd_soc_dapm_new_controls(dapm, rk2928_dapm_widgets,
530 ARRAY_SIZE(rk2928_dapm_widgets));
531 snd_soc_dapm_add_routes(dapm, rk2928_audio_map, ARRAY_SIZE(rk2928_audio_map));
533 snd_soc_dapm_new_controls(dapm, rk2926_dapm_widgets,
534 ARRAY_SIZE(rk2926_dapm_widgets));
535 snd_soc_dapm_add_routes(dapm, rk2926_audio_map, ARRAY_SIZE(rk2926_audio_map));
538 INIT_DELAYED_WORK(&rk2928_data.h_delayed_work, call_delay_work);
539 mutex_init(&rk2928_data.mutex_lock);
540 rk2928_data.call_enable = 0;
541 rk2928_data.headset_status = HP_OUT;
542 rk2928_data.codec=codec;
543 rk2928_data.stop_phone_depop=false;
547 release_mem_region(res->start,(res->end - res->start) + 1);
548 // clk_disable(rk2928_data.hclk);
550 DBG("%s failed", __FUNCTION__);
554 static int rk2928_remove(struct snd_soc_codec *codec)
559 static int rk2928_suspend(struct snd_soc_codec *codec)
561 DBG("%s", __FUNCTION__);
562 rk2928_set_bias_level(codec, SND_SOC_BIAS_OFF);
563 clk_disable(rk2928_data.pclk);
567 static int rk2928_resume(struct snd_soc_codec *codec)
569 DBG("%s", __FUNCTION__);
570 clk_enable(rk2928_data.pclk);
571 rk2928_write(codec, CODEC_REG_POWER, v_PD_ADC(1) | v_PD_DAC(1) | v_PD_MIC_BIAS(0));
575 static struct snd_soc_codec_driver rk2928_audio_codec_drv = {
576 .probe = rk2928_probe,
577 .remove = rk2928_remove,
578 .suspend = rk2928_suspend,
579 .resume = rk2928_resume,
581 .write = rk2928_write,
582 .set_bias_level = rk2928_set_bias_level,
585 static struct snd_soc_dai_ops rk2928_audio_codec_ops = {
586 .hw_params = rk2928_audio_hw_params,
587 .trigger = rk2928_audio_trigger,
588 .startup = rk2928_audio_startup,
591 static struct snd_soc_dai_driver rk2928_codec_dai = {
592 .name = "rk2928-codec",
594 .stream_name = "HIFI Playback",
597 .rates = SNDRV_PCM_RATE_8000_48000,
598 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |
599 SNDRV_PCM_FMTBIT_S24_LE,
602 .stream_name = "HIFI Capture",
605 .rates = SNDRV_PCM_RATE_8000_48000,
606 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE,
608 .ops = &rk2928_audio_codec_ops,
611 static int rk2928_codec_probe(struct platform_device *pdev)
615 DBG("%s", __FUNCTION__);
617 /* Register ASoC codec DAI */
618 r = snd_soc_register_codec(&pdev->dev, &rk2928_audio_codec_drv,
619 &rk2928_codec_dai, 1);
621 dev_err(&pdev->dev, "can't register ASoC rk2928 audio codec\n");
625 DBG("%s success", __FUNCTION__);
630 static int __devexit rk2928_codec_remove(struct platform_device *pdev)
632 snd_soc_unregister_codec(&pdev->dev);
636 static void rk2928_codec_shutdown(struct platform_device *pdev)
638 printk("%s .....\n", __FUNCTION__);
639 if(rk2928_data.spkctl != INVALID_GPIO)
640 gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
641 if(rk2928_data.hp_ctl != 0 )
642 gpio_direction_output(rk2928_data.hp_ctl, GPIO_LOW);
644 static struct platform_driver rk2928_codec_driver = {
645 .probe = rk2928_codec_probe,
646 .remove = __devexit_p(rk2928_codec_remove),
648 .name = "rk2928-codec",
649 .owner = THIS_MODULE,
651 .shutdown = rk2928_codec_shutdown,
654 static int __init rk2928_codec_init(void)
656 return platform_driver_register(&rk2928_codec_driver);
658 module_init(rk2928_codec_init);
660 static void __exit rk2928_codec_exit(void)
662 #ifdef CODEC_I2C_MODE
663 i2c_del_driver(&rk2928_codec_driver);
665 platform_driver_unregister(&rk2928_codec_driver);
668 module_exit(rk2928_codec_exit);
670 MODULE_DESCRIPTION("ASoC RK2928 codec driver");
671 MODULE_LICENSE("GPL");