2 * rk610.c -- RK610 ALSA SoC audio driver
4 * Copyright (C) 2009 rockchip lhh
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
19 #include <linux/i2c.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
22 #include <sound/core.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
26 #include <sound/soc-dapm.h>
27 #include <sound/initval.h>
28 #include <linux/workqueue.h>
30 #include <linux/of_gpio.h>
31 #include <linux/clk.h>
32 #include <linux/gpio.h>
33 #include "rk610_codec.h"
40 //if you find resume rk610 cannot work,you can try RESUME_PROBLEM 1.
41 //if rk610 Normal working on RESUME_PROBLEM 1, you must detect Machine other driver queue.
42 //you can look soc-core.c the resume source.s
43 #define RESUME_PROBLEM 0
45 //1:set pll from rk610
46 #define RK610_CTL_PLL 0
52 #define DBG(x...) printk(KERN_INFO x)
57 //rk610 output volume,DAC Digital Gain
59 #define Volume_Output 0xF42
60 //0x0 ~ 0x3f(bit0-bit5) max=0x0(+6DB) min=0x3f(-60DB) //Analog Gain
61 #define Volume_Codec_PA 0x0
63 //rk610 input volume,rk610 can not adjust the recording volume
64 #define Volume_Input 0x07
68 #define OUT_CAPLESS (1) //ÊÇ·ñΪÎÞµçÈÝÊä³ö£¬1:ÎÞµçÈÝÊä³ö£¬0:ÓеçÈÝÊä³ö
70 static u8 gR0AReg = 0; //ÓÃÓڼǼR0A¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0AÍ£Ö¹clk
71 static u8 gR0BReg = 0; //ÓÃÓڼǼR0B¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0BÍ£Ö¹interplateºÍdecimation
75 * rk610 register cache
76 * We can't read the RK610 register space when we
77 * are using 2 wire for device control, so we cache them instead.
79 static const u16 rk610_codec_reg[] = {
80 0x0005, 0x0004, 0x00fd, 0x00f3, /* 0 */
81 0x0003, 0x0000, 0x0000, 0x0000, /* 4 */
82 0x0000, 0x0005, 0x0000, 0x0000, /* 8 */
83 0x0097, 0x0097, 0x0097, 0x0097, /* 12 */
84 0x0097, 0x0097, 0x00cc, 0x0000, /* 16 */
85 0x0000, 0x00f1, 0x0090, 0x00ff, /* 20 */
86 0x00ff, 0x00ff, 0x009c, 0x0000, /* 24 */
87 0x0000, 0x00ff, 0x00ff, 0x00ff, /* 28 */
90 static struct snd_soc_codec *rk610_codec_codec=NULL;
91 /* codec private data */
92 struct rk610_codec_priv {
93 enum snd_soc_control_type control_type;
95 struct snd_soc_codec codec;
96 struct snd_pcm_hw_constraint_list *sysclk_constraints;
97 u16 reg_cache[RK610_CODEC_NUM_REG];
99 struct delayed_work rk610_delayed_work;
100 unsigned int spk_ctrl_io;
102 Some amplifiers enable a longer time.
103 config after pa_enable_io delay pa_enable_time(ms)
104 default = 0,preferably not more than 1000ms
105 so value range is 0 - 1000.
107 unsigned int pa_enable_time;
109 int boot_depop;//if found boot pop,set boot_depop 1 test
111 int rk610_workstatus;
117 static void spk_ctrl_fun(int status)
119 struct rk610_codec_priv *rk610_codec = NULL;
120 if(rk610_codec_codec == NULL)
122 rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec);
123 if(rk610_codec == NULL)
125 #ifdef CONFIG_MODEM_SOUND
126 if(rk610_codec->call_enable){
127 DBG("%s:: is calling cannot set spk\n",__FUNCTION__);
131 if(rk610_codec->spk_ctrl_io)
133 DBG("%s:: spk status = %d\n",__FUNCTION__,status);
134 gpio_set_value(rk610_codec->spk_ctrl_io, status);
138 void codec_set_spk(bool on)
140 struct rk610_codec_priv *rk610_codec;
141 if(!rk610_codec_codec)
144 rk610_codec=snd_soc_codec_get_drvdata(rk610_codec_codec);
148 rk610_codec->hdmi_ndet = on;
150 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_HIGH);
152 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW);
154 EXPORT_SYMBOL(codec_set_spk);
157 * read rk610 register cache
159 static inline unsigned int rk610_codec_read_reg_cache(struct snd_soc_codec *codec,
162 u16 *cache = codec->reg_cache;
163 if (reg > RK610_CACHE_REGNUM)
168 static unsigned int rk610_codec_read(struct snd_soc_codec *codec, unsigned int r)
170 struct i2c_msg xfer[1];
173 struct i2c_client *i2c = to_i2c_client(codec->dev);
176 xfer[0].addr = (i2c->addr& 0x60)|(reg);
177 xfer[0].flags = I2C_M_RD;
180 xfer[0].scl_rate = 100000;
181 ret = i2c_transfer(i2c->adapter, xfer, 1);
183 dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
191 * write rk610 register cache
193 static inline void rk610_codec_write_reg_cache(struct snd_soc_codec *codec,
194 unsigned int reg, unsigned int value)
196 u16 *cache = codec->reg_cache;
197 if (reg > RK610_CACHE_REGNUM)
202 static int rk610_codec_write(struct snd_soc_codec *codec, unsigned int reg,
206 struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec);
208 struct i2c_client *i2c = to_i2c_client(codec->dev);
209 #ifdef CONFIG_MODEM_SOUND
210 if(rk610_codec->call_enable)
213 if(value == rk610_codec_read_reg_cache(codec,reg))
215 DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value);
216 data[0] = value & 0x00ff;
218 i2c->addr = (i2c->addr & 0x60)|reg;
220 if (codec->hw_write(i2c, data, 1) == 1){
221 // DBG("================%s %d Run OK================\n",__FUNCTION__,__LINE__);
222 rk610_codec_write_reg_cache (codec, reg, value);
225 DBG("================%s %d Run EIO================\n",__FUNCTION__,__LINE__);
230 #ifdef CONFIG_MODEM_SOUND
231 static int rk610_codec_write_incall(struct snd_soc_codec *codec, unsigned int reg,
235 struct i2c_client *i2c = to_i2c_client(codec->dev);
236 DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value);
237 data[0] = value & 0x00ff;
238 rk610_codec_write_reg_cache (codec, reg, value);
239 i2c = (struct i2c_client *)codec->control_data;
240 i2c->addr = (i2c->addr & 0x60)|reg;
242 if (codec->hw_write(i2c, data, 1) == 1)
248 void call_set_spk(int on)
250 struct rk610_codec_priv *rk610_codec;
251 if(!rk610_codec_codec)
253 rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec);
260 //modem exit call,codec disable loopback
261 printk("%s modem exit call \n", __FUNCTION__);
262 rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x80);
263 rk610_codec->call_enable = 0;
266 //modem calling,codec enable loopback,spk hp different volume
267 printk("%s spk incalling\n", __FUNCTION__);
268 rk610_codec->call_enable = 1;
269 rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x00);
272 printk("%s hp incalling\n", __FUNCTION__);
273 rk610_codec->call_enable = 1;
274 rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x00);
277 printk("%s bt incalling\n", __FUNCTION__);
278 rk610_codec->call_enable = 1;
279 rk610_codec_write_incall(rk610_codec_codec,ACCELCODEC_R0E, 0x00);
286 #ifdef CONFIG_RK_HEADSET_DET
288 void rk2928_codec_set_spk(bool on)
290 struct rk610_codec_priv *rk610_codec;
291 if(!rk610_codec_codec)
293 rk610_codec=snd_soc_codec_get_drvdata(rk610_codec_codec);
298 rk610_codec->headset_status = HP_IN;
300 rk610_codec->headset_status = HP_OUT;
302 if(rk610_codec->call_enable)
305 printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level);
307 if(rk610_codec->spk_ctrl_io)
308 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW);
311 if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY
312 || codec->dapm.bias_level == SND_SOC_BIAS_OFF){
315 if(rk610_codec->spk_ctrl_io)
316 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_HIGH);
321 void rk610_codec_reg_read(void)
323 struct snd_soc_codec *codec = rk610_codec_codec;
327 for (i=0; i<=0x1f; i++){
328 data = rk610_codec_read(codec, i);
329 printk("reg[0x%x]=0x%x\n",i,data);
342 /* codec hifi mclk clock divider coefficients */
343 static const struct _coeff_div coeff_div[] = {
345 {12288000, 8000, 1536, 0x6, 0x0,ASC_BCLKDIV_16},
346 {11289600, 8000, 1408, 0x16, 0x0,ASC_BCLKDIV_16},
347 {18432000, 8000, 2304, 0x7, 0x0,ASC_BCLKDIV_16},
348 {16934400, 8000, 2112, 0x17, 0x0,ASC_BCLKDIV_16},
349 {8192000, 8000, 1024, 0x0, 0x0,ASC_BCLKDIV_16},
350 {12000000, 8000, 1500, 0x6, 0x1,ASC_BCLKDIV_16},
353 {11289600, 11025, 1024, 0x18, 0x0,ASC_BCLKDIV_16},
354 {16934400, 11025, 1536, 0x19, 0x0,ASC_BCLKDIV_16},
355 {12000000, 11025, 1088, 0x19, 0x1,ASC_BCLKDIV_16},
358 {12288000, 12000, 1024, 0x8, 0x0,ASC_BCLKDIV_16},
359 {18432000, 12000, 1536, 0x9, 0x0,ASC_BCLKDIV_16},
360 {12000000, 12000, 1000, 0x8, 0x1,ASC_BCLKDIV_16},
363 {12288000, 16000, 768, 0xa, 0x0,ASC_BCLKDIV_8},
364 {18432000, 16000, 1152, 0xb, 0x0,ASC_BCLKDIV_8},
365 {12000000, 16000, 750, 0xa, 0x1,ASC_BCLKDIV_8},
368 {11289600, 22050, 512, 0x1a, 0x0,ASC_BCLKDIV_8},
369 {16934400, 22050, 768, 0x1b, 0x0,ASC_BCLKDIV_8},
370 {12000000, 22050, 544, 0x1b, 0x1,ASC_BCLKDIV_8},
373 {12288000, 24000, 512, 0x1c, 0x0,ASC_BCLKDIV_8},
374 {18432000, 24000, 768, 0x1d, 0x0,ASC_BCLKDIV_8},
375 {12000000, 24000, 500, 0x1c, 0x1,ASC_BCLKDIV_8},
378 {12288000, 32000, 384, 0xc, 0x0,ASC_BCLKDIV_8},
379 {18432000, 32000, 576, 0xd, 0x0,ASC_BCLKDIV_8},
380 {12000000, 32000, 375, 0xa, 0x1,ASC_BCLKDIV_8},
383 {11289600, 44100, 256, 0x10, 0x0,ASC_BCLKDIV_4},
384 {16934400, 44100, 384, 0x11, 0x0,ASC_BCLKDIV_8},
385 {12000000, 44100, 272, 0x11, 0x1,ASC_BCLKDIV_8},
388 {12288000, 48000, 256, 0x0, 0x0,ASC_BCLKDIV_4},
389 {18432000, 48000, 384, 0x1, 0x0,ASC_BCLKDIV_4},
390 {12000000, 48000, 250, 0x0, 0x1,ASC_BCLKDIV_4},
393 {11289600, 88200, 128, 0x1e, 0x0,ASC_BCLKDIV_4},
394 {16934400, 88200, 192, 0x1f, 0x0,ASC_BCLKDIV_4},
395 {12000000, 88200, 136, 0x1f, 0x1,ASC_BCLKDIV_4},
398 {12288000, 96000, 128, 0xe, 0x0,ASC_BCLKDIV_4},
399 {18432000, 96000, 192, 0xf, 0x0,ASC_BCLKDIV_4},
400 {12000000, 96000, 125, 0xe, 0x1,ASC_BCLKDIV_4},
403 static inline int get_coeff(int mclk, int rate)
407 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
408 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
415 /* The set of rates we can generate from the above for each SYSCLK */
417 static unsigned int rates_12288[] = {
418 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
421 static struct snd_pcm_hw_constraint_list constraints_12288 = {
422 .count = ARRAY_SIZE(rates_12288),
426 static unsigned int rates_112896[] = {
427 8000, 11025, 22050, 44100,
430 static struct snd_pcm_hw_constraint_list constraints_112896 = {
431 .count = ARRAY_SIZE(rates_112896),
432 .list = rates_112896,
435 static unsigned int rates_12[] = {
436 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
440 static struct snd_pcm_hw_constraint_list constraints_12 = {
441 .count = ARRAY_SIZE(rates_12),
445 static int rk610_codec_set_bias_level(struct snd_soc_codec *codec,
446 enum snd_soc_bias_level level)
448 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
449 DBG("Enter::%s----%d now_level =%d old_level = %d\n",__FUNCTION__,__LINE__,level,codec->dapm.bias_level);
451 case SND_SOC_BIAS_ON:
453 case SND_SOC_BIAS_PREPARE:
454 /* VREF, VMID=2x50k, digital enabled */
455 // rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
458 case SND_SOC_BIAS_STANDBY:
460 if(rk610_codec->rk610_workstatus == SND_SOC_DAPM_STREAM_RESUME)
462 DBG("rk610 is resume,have not into standby\n");
463 rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
467 printk("rk610 standby\n");
468 spk_ctrl_fun(GPIO_LOW);
469 rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE);
470 rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
471 rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
472 rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
475 case SND_SOC_BIAS_OFF:
476 printk("rk610 power off\n");
477 spk_ctrl_fun(GPIO_LOW);
478 rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE);
479 rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF);
480 rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
481 rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
485 codec->dapm.bias_level = level;
491 * Note that this should be called from init rather than from hw_params.
493 static int rk610_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
494 int clk_id, unsigned int freq, int dir)
496 struct snd_soc_codec *codec = codec_dai->codec;
498 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
500 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
503 if(rk610_codec_pll_set(freq))
511 rk610_codec->sysclk_constraints = &constraints_112896;
512 rk610_codec->sysclk = freq;
519 rk610_codec->sysclk_constraints = &constraints_12288;
520 rk610_codec->sysclk = freq;
525 rk610_codec->sysclk_constraints = &constraints_12;
526 rk610_codec->sysclk = freq;
534 static int rk610_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
537 struct snd_soc_codec *codec = codec_dai->codec;
538 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
542 if(rk610_codec->pa_enable_time<300)
543 spk_ctrl_fun(GPIO_LOW);
545 spk_ctrl_fun(GPIO_HIGH);
546 rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down
547 rk610_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE);
549 /* set master/slave audio interface */
550 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
551 case SND_SOC_DAIFMT_CBM_CFM:
554 case SND_SOC_DAIFMT_CBS_CFS:
561 /* interface format */
562 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
563 case SND_SOC_DAIFMT_I2S:
566 case SND_SOC_DAIFMT_RIGHT_J:
568 case SND_SOC_DAIFMT_LEFT_J:
571 case SND_SOC_DAIFMT_DSP_A:
574 case SND_SOC_DAIFMT_DSP_B:
581 /* clock inversion */
582 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
583 case SND_SOC_DAIFMT_NB_NF:
585 case SND_SOC_DAIFMT_IB_IF:
588 case SND_SOC_DAIFMT_IB_NF:
591 case SND_SOC_DAIFMT_NB_IF:
598 DBG("Enter::%s----%d iface=%x\n",__FUNCTION__,__LINE__,iface);
599 rk610_codec_write(codec, ACCELCODEC_R09, iface);
603 static int rk610_codec_pcm_hw_params(struct snd_pcm_substream *substream,
604 struct snd_pcm_hw_params *params,
605 struct snd_soc_dai *dai)
607 struct snd_soc_pcm_runtime *rtd = substream->private_data;
608 struct snd_soc_codec *codec = rtd->codec;
609 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
610 unsigned int dai_fmt = rtd->card->dai_link[0].dai_fmt;
612 u16 iface = rk610_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3;
613 u16 srate = rk610_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180;
616 coeff = get_coeff(rk610_codec->sysclk, params_rate(params));
617 DBG("Enter::%s----%d rk610_codec->sysclk=%d coeff = %d\n",__FUNCTION__,__LINE__,rk610_codec->sysclk, coeff);
619 switch (params_format(params)) {
620 case SNDRV_PCM_FORMAT_S16_LE:
622 case SNDRV_PCM_FORMAT_S20_3LE:
625 case SNDRV_PCM_FORMAT_S24_LE:
628 case SNDRV_PCM_FORMAT_S32_LE:
632 DBG("Enter::%s----%d iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));
634 // rk610_codec_write(codec,ACCELCODEC_R0C, 0x17);
635 rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
636 //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬
637 //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô
638 rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE); //0x00
640 /* set iface & srate */
641 if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
642 iface |= ASC_INVERT_BCLK;//·×ªBCLK master״̬ËͳöµÄÉÙÁË°ë¸öʱÖÓ£¬µ¼ÖÂδµ½×î´óÒôÁ¿µÄʱºòÆÆÒô¡¢
644 rk610_codec_write(codec, ACCELCODEC_R09, iface);
646 // rk610_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk);
647 rk610_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE);
649 rk610_codec_write(codec,ACCELCODEC_R0B, gR0BReg);
654 static int rk610_codec_mute(struct snd_soc_dai *dai, int mute)
656 struct snd_soc_codec *codec = dai->codec;
657 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
658 printk("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
662 rk610_codec_write(codec,ACCELCODEC_R17, 0xFF); //AOL
663 rk610_codec_write(codec,ACCELCODEC_R18, 0xFF); //AOR
664 rk610_codec_write(codec,ACCELCODEC_R19, 0xFF); //AOM
665 rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
667 // if(!dai->capture_active)
669 // rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
670 // rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
671 // rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
676 // rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down
677 // rk610_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE);
678 rk610_codec_write(codec,ACCELCODEC_R17, Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL
679 rk610_codec_write(codec,ACCELCODEC_R18, Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR
680 rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);
681 rk610_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM
683 if(rk610_codec->pa_enable_time == 0)
686 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
688 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
690 // schedule_delayed_work(&rk610_codec->rk610_delayed_work, 0);
691 // rk610_codec_reg_read();
692 if(rk610_codec->hdmi_ndet){
693 if(rk610_codec->pa_enable_time == 0 )
694 spk_ctrl_fun(GPIO_HIGH);
695 else if(rk610_codec->pa_enable_time > 0 && rk610_codec->pa_enable_time < 300){
696 spk_ctrl_fun(GPIO_HIGH);
697 msleep(rk610_codec->pa_enable_time) ;
699 else if(rk610_codec->pa_enable_time >=300 && rk610_codec->pa_enable_time < 1000)
700 msleep(rk610_codec->pa_enable_time);
707 static void rk610_delayedwork_fun(struct work_struct *work)
709 struct snd_soc_codec *codec = rk610_codec_codec;
710 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
712 DBG("--------%s----------\n",__FUNCTION__);
713 if(!rk610_codec->boot_depop){
715 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
717 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
720 spk_ctrl_fun(GPIO_HIGH);
723 static struct snd_soc_dai_ops rk610_codec_ops = {
724 .hw_params = rk610_codec_pcm_hw_params,
725 .set_fmt = rk610_codec_set_dai_fmt,
726 .set_sysclk = rk610_codec_set_dai_sysclk,
727 .digital_mute = rk610_codec_mute,
730 #define RK610_CODEC_RATES SNDRV_PCM_RATE_8000_96000
731 #define RK610_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
732 SNDRV_PCM_FMTBIT_S24_LE)
734 static struct snd_soc_dai_driver rk610_codec_dai = {
735 .name = "rk610_codec",
737 .stream_name = "Playback",
740 .rates = RK610_CODEC_RATES,
741 .formats = RK610_CODEC_FORMATS,
744 .stream_name = "Capture",
747 .rates = RK610_CODEC_RATES,
748 .formats = RK610_CODEC_FORMATS,
750 .ops = &rk610_codec_ops,
751 .symmetric_rates = 1,
754 static int rk610_codec_suspend(struct snd_soc_codec *codec)
756 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
757 rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
758 // rk610_codec_reg_read();
762 static int rk610_codec_resume(struct snd_soc_codec *codec)
764 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
766 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
767 /* Sync reg_cache with the hardware */
769 // rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
771 rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_RESUME;
778 void rk610_codec_reg_set(void)
780 struct snd_soc_codec *codec = rk610_codec_codec;
781 struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
783 unsigned int digital_gain;
784 unsigned int mic_vol = Volume_Input;
785 rk610_codec_write(codec,ACCELCODEC_R1D, 0x30);
786 rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);
789 // Route R-LPF->R-Mixer, L-LPF->L-Mixer
790 rk610_codec_write(codec,ACCELCODEC_R15, 0xC1);
792 // Route RDAC->R-Mixer, LDAC->L->Mixer
793 rk610_codec_write(codec,ACCELCODEC_R15, 0x0C);
795 // With Cap Output, VMID ramp up slow
796 rk610_codec_write(codec,ACCELCODEC_R1A, 0x14);
799 rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB); //LIL
800 rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB); //LIR
805 rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB); //Select MIC input
809 rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT); //Select MIC input
810 rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); //0x00); //use default value
812 rk610_codec_write(codec,ACCELCODEC_R12, 0x4c); //Select Line input
815 rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|mic_vol); //MIC
817 // Diable route PGA->R/L Mixer, PGA gain 0db.
818 rk610_codec_write(codec,ACCELCODEC_R13, 0x05 | 0 << 3);
819 rk610_codec_write(codec,ACCELCODEC_R14, 0x05 | 0 << 3);
822 rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
824 //2set default SR and clk
825 rk610_codec_write(codec,ACCELCODEC_R0A, ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE);
826 gR0AReg = ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE;
827 //2Config audio interface
828 rk610_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_NORMAL_BCLK);
829 rk610_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_ENABLE|ASC_SCRAMBLE_ENABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_4);
830 //2volume,input,output
831 digital_gain = Volume_Output;
833 if(rk610_codec_read(codec,ACCELCODEC_R05)!=0x0f) {
834 rk610_codec_write(codec,ACCELCODEC_R05, (digital_gain >> 8) & 0xFF);
835 rk610_codec_write(codec,ACCELCODEC_R06, digital_gain & 0xFF);
837 if(rk610_codec_read(codec,ACCELCODEC_R07)!=0x0f){
838 rk610_codec_write(codec,ACCELCODEC_R07, (digital_gain >> 8) & 0xFF);
839 rk610_codec_write(codec,ACCELCODEC_R08, digital_gain & 0xFF);
841 rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_ENABLE|ASC_INT_ENABLE);
842 gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE; //ASC_DEC_DISABLE|ASC_INT_ENABLE;
844 if(rk610_codec->boot_depop){
846 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
848 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
853 static int rk610_codec_probe(struct snd_soc_codec *codec)
855 struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(codec);
858 rk610_codec_codec = codec;
859 DBG("[%s] start\n", __FUNCTION__);
860 ret = snd_soc_codec_set_cache_io(codec, 8, 16, rk610_codec->control_type);
862 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
866 //For RK610, i2c write&read method is special, do not use system default method.
867 codec->write = rk610_codec_write;
868 codec->read = rk610_codec_read;
869 codec->hw_write = (hw_write_t)i2c_master_send;
871 if (rk610_codec_codec == NULL) {
872 dev_err(codec->dev, "Codec device not registered\n");
876 INIT_DELAYED_WORK(&rk610_codec->rk610_delayed_work, rk610_delayedwork_fun);
878 if(rk610_codec->spk_ctrl_io)
880 ret = gpio_request(rk610_codec->spk_ctrl_io, "rk610 spk_ctrl");
882 printk("rk610_control request gpio fail!\n");
885 gpio_direction_output(rk610_codec->spk_ctrl_io, GPIO_LOW);
886 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW);
889 rk610_codec->hdmi_ndet = true;
890 rk610_codec->call_enable = 0;
891 rk610_codec->headset_status = HP_OUT;
893 rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
896 rk610_control_init_codec();
897 rk610_codec_reg_set();
898 // rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
899 schedule_delayed_work(&rk610_codec->rk610_delayed_work, msecs_to_jiffies(1000));
901 codec->dapm.bias_level = SND_SOC_BIAS_PREPARE;
905 /* power down chip */
906 static int rk610_codec_remove(struct snd_soc_codec *codec)
908 rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
912 static struct snd_soc_codec_driver soc_codec_dev_rk610_codec = {
913 .probe = rk610_codec_probe,
914 .remove = rk610_codec_remove,
915 .suspend = rk610_codec_suspend,
916 .resume = rk610_codec_resume,
917 .set_bias_level = rk610_codec_set_bias_level,
918 // .volatile_register = wm8900_volatile_register,
919 .reg_cache_size = ARRAY_SIZE(rk610_codec_reg),
920 .reg_word_size = sizeof(u16),
921 .reg_cache_default = rk610_codec_reg,
922 // .dapm_widgets = rk610_codec_dapm_widgets,
923 // .num_dapm_widgets = ARRAY_SIZE(rk610_codec_dapm_widgets),
924 // .dapm_routes = audio_map,
925 // .num_dapm_routes = ARRAY_SIZE(audio_map),
928 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
929 static int rk610_codec_i2c_probe(struct i2c_client *i2c,
930 const struct i2c_device_id *id)
932 struct rk610_codec_priv *rk610_codec;
933 struct device_node *rk610_np = i2c->dev.of_node;
936 DBG("%s start\n", __FUNCTION__);
937 rk610_codec = kzalloc(sizeof(struct rk610_codec_priv), GFP_KERNEL);
938 if (rk610_codec == NULL)
941 if(!of_property_read_u32(rk610_np, "boot_depop", &val))
942 rk610_codec->boot_depop = val;
943 if(!of_property_read_u32(rk610_np, "pa_enable_time", &val))
944 rk610_codec->pa_enable_time = val;
945 if(rk610_codec->pa_enable_time > 1000)
946 rk610_codec->pa_enable_time = 1000;
948 rk610_codec->spk_ctrl_io = of_get_named_gpio(rk610_np,"spk_ctl_io", 0);
949 if (!gpio_is_valid(rk610_codec->spk_ctrl_io)){
950 printk("invalid core_info->reset_gpio: %d\n",rk610_codec->spk_ctrl_io);
954 i2c_set_clientdata(i2c, rk610_codec);
955 rk610_codec->control_type = SND_SOC_I2C;
957 ret = snd_soc_register_codec(&i2c->dev,
958 &soc_codec_dev_rk610_codec, &rk610_codec_dai, 1);
960 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
966 static int rk610_codec_i2c_remove(struct i2c_client *client)
968 snd_soc_unregister_codec(&client->dev);
969 kfree(i2c_get_clientdata(client));
973 static const struct i2c_device_id rk610_codec_i2c_id[] = {
974 { "rk610_codec", 0 },
977 MODULE_DEVICE_TABLE(i2c, rk610_codec_i2c_id);
979 /* corgi i2c codec control layer */
980 static struct i2c_driver rk610_codec_i2c_driver = {
982 .name = "rk610_codec",
983 .owner = THIS_MODULE,
985 .probe = rk610_codec_i2c_probe,
986 .remove = rk610_codec_i2c_remove,
987 .id_table = rk610_codec_i2c_id,
991 static int __init rk610_codec_modinit(void)
994 DBG("[%s] start\n", __FUNCTION__);
995 ret = i2c_add_driver(&rk610_codec_i2c_driver);
997 pr_err("rk610 codec: Unable to register I2C driver: %d\n", ret);
1000 module_init(rk610_codec_modinit);
1002 static void __exit rk610_codec_exit(void)
1004 i2c_del_driver(&rk610_codec_i2c_driver);
1006 module_exit(rk610_codec_exit);
1008 MODULE_DESCRIPTION("ASoC RK610 CODEC driver");
1009 MODULE_AUTHOR("rk@rock-chips.com");
1010 MODULE_LICENSE("GPL");
1012 //=====================================================================
1015 #include <linux/proc_fs.h>
1016 #include <linux/seq_file.h>
1017 #include <linux/vmalloc.h>
1018 static ssize_t rk610_reg_write(struct file *file,
1019 const char __user *buffer, size_t len, loff_t *ppos)
1025 struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec);
1027 cookie_pot = (char *)vmalloc( len );
1034 if (copy_from_user( cookie_pot, buffer, len ))
1038 switch(cookie_pot[0])
1041 spk_ctrl_fun(GPIO_HIGH);
1044 spk_ctrl_fun(GPIO_LOW);
1048 printk("Read reg debug\n");
1049 if(cookie_pot[1] ==':')
1051 strsep(&cookie_pot,":");
1052 while((p=strsep(&cookie_pot,",")))
1054 reg = simple_strtol(p,NULL,16);
1055 value = rk610_codec_read(rk610_codec_codec,reg);
1056 printk("wm8994_read:0x%04x = 0x%04x\n",reg,value);
1062 printk("Error Read reg debug.\n");
1063 printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n");
1068 printk("Write reg debug\n");
1069 if(cookie_pot[1] ==':')
1071 strsep(&cookie_pot,":");
1072 while((p=strsep(&cookie_pot,"=")))
1074 reg = simple_strtol(p,NULL,16);
1075 p=strsep(&cookie_pot,",");
1076 value = simple_strtol(p,NULL,16);
1077 rk610_codec_write(rk610_codec_codec,reg,value);
1078 printk("wm8994_write:0x%04x = 0x%04x\n",reg,value);
1084 printk("Error Write reg debug.\n");
1085 printk("For example: w:22=0,23=0,24=0,25=0\n");
1089 printk("Dump reg\n");
1090 rk610_codec_reg_read();
1093 printk("old pa_enable_time = %d\n",rk610_codec->pa_enable_time);
1094 if(cookie_pot[1] ==':')
1096 strsep(&cookie_pot,":");
1097 p=strsep(&cookie_pot," ");
1098 rk610_codec->pa_enable_time = simple_strtol(p,NULL,10);
1099 printk("new pa_enable_time = %d\n",rk610_codec->pa_enable_time);
1106 static int proc_reg_show(struct seq_file *s, void *v)
1111 static int proc_open(struct inode *inode, struct file *file)
1113 return single_open(file, proc_reg_show, NULL);
1116 static const struct file_operations proc_i2s_fops = {
1119 .write = rk610_reg_write,
1120 .llseek = seq_lseek,
1121 .release = single_release,
1123 static int __init rk610_proc_init(void)
1125 proc_create("driver/rk610_ts", 0, NULL, &proc_i2s_fops);
1128 late_initcall(rk610_proc_init);