rk610 codec : disable rk610 pll and 0AH clkgate,reduce power consumption
[firefly-linux-kernel-4.4.55.git] / sound / soc / codecs / rk610_codec.c
1 /*
2  * rk610.c -- RK610 ALSA SoC audio driver
3  *
4  * Copyright (C) 2009 rockchip lhh
5  *
6  *
7  * Based on RK610.c
8  *
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.
12  */
13
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/pm.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 <mach/gpio.h>
29 #include <mach/iomux.h>
30 #include <linux/workqueue.h>
31 #include "rk610_codec.h"
32 #include <mach/board.h>
33
34 #define RK610_PROC
35 #ifdef RK610_PROC
36 #include <linux/proc_fs.h>
37 #include <linux/seq_file.h>
38 #include <linux/vmalloc.h>
39 #endif
40
41 //if you find resume rk610 cannot work,you can try RESUME_PROBLEM 1.
42 //if rk610 Normal working on RESUME_PROBLEM 1, you must detect Machine other driver queue.
43 //you can look soc-core.c the resume source.s
44 #define RESUME_PROBLEM 0
45
46 //old control method,please filling rk610_codec_platform_data into Board-xx-xx.c
47 //qjb 2013-01-14
48 #if 0
49 #if defined(CONFIG_MACH_RK3168_DS1006H)|| defined(CONFIG_MACH_RK3168_LR097)
50 #define RK610_SPK_CTRL_PIN  RK30_PIN2_PD7
51 #elif defined(CONFIG_ARCH_RK3066B)
52 #define RK610_SPK_CTRL_PIN  RK30_PIN2_PA0
53 #elif defined(CONFIG_ARCH_RK30)
54 #define RK610_SPK_CTRL_PIN  RK30_PIN4_PC6
55 #else
56 #define RK610_SPK_CTRL_PIN  RK29_PIN6_PB6
57 #endif
58 #endif
59
60 //1:set pll from rk610
61 #define RK610_CTL_PLL 0
62
63 /*
64  * Debug
65  */
66 #if 0
67 #define DBG(x...)       printk(KERN_INFO x)
68 #else
69 #define DBG(x...)
70 #endif
71
72 //it can change rk610 output volume 
73 //0x0000 ~ 0xFFFF
74 #define Volume_Output 0xF42
75 //it can change rk610 input volume
76 //0x00 ~ 0x0E
77 #define Volume_Input 0x07
78
79 #define OUT_CAPLESS  (1)   //ÊÇ·ñΪÎÞµçÈÝÊä³ö£¬1:ÎÞµçÈÝÊä³ö£¬0:ÓеçÈÝÊä³ö
80
81 static u32 gVolReg = 0x00;  ///0x0f; //ÓÃÓڼǼÒôÁ¿¼Ä´æÆ÷
82 //static u32 gCodecVol = 0x0f;
83 static u8 gR0AReg = 0;  //ÓÃÓڼǼR0A¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0AÍ£Ö¹clk
84 static u8 gR0BReg = 0;  //ÓÃÓڼǼR0B¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0BÍ£Ö¹interplateºÍdecimation
85 //static u8 gR1314Reg = 0;  //ÓÃÓڼǼR13,R14¼Ä´æÆ÷µÄÖµ£¬ÓÃÓÚFMÒôÁ¿Îª0ʱ
86
87 /*
88  * rk610 register cache
89  * We can't read the RK610 register space when we
90  * are using 2 wire for device control, so we cache them instead.
91  */
92 static const u16 rk610_codec_reg[] = {
93         0x0005, 0x0004, 0x00fd, 0x00f3,  /*  0 */
94         0x0003, 0x0000, 0x0000, 0x0000,  /*  4 */
95         0x0000, 0x0005, 0x0000, 0x0000,  /*  8 */
96         0x0097, 0x0097, 0x0097, 0x0097,  /* 12 */
97         0x0097, 0x0097, 0x00cc, 0x0000,  /* 16 */
98         0x0000, 0x00f1, 0x0090, 0x00ff,  /* 20 */
99         0x00ff, 0x00ff, 0x009c, 0x0000,  /* 24 */
100         0x0000, 0x00ff, 0x00ff, 0x00ff,  /* 28 */
101 };
102
103 static struct snd_soc_codec *rk610_codec_codec=NULL;
104 /* codec private data */
105 struct rk610_codec_priv {
106         enum snd_soc_control_type control_type;
107         unsigned int sysclk;
108         struct snd_soc_codec codec;
109         struct snd_pcm_hw_constraint_list *sysclk_constraints;
110         u16 reg_cache[RK610_CODEC_NUM_REG];
111
112         struct delayed_work rk610_delayed_work;
113         unsigned int spk_ctrl_io;
114         bool hdmi_ndet;
115 #if RESUME_PROBLEM
116         int rk610_workstatus;
117 #endif
118         struct rk610_codec_platform_data *pdata;
119 };
120
121 void codec_set_spk(bool on)
122 {
123         struct rk610_codec_priv *rk610_codec;
124         if(!rk610_codec_codec)
125                 return;
126                 
127         rk610_codec=snd_soc_codec_get_drvdata(rk610_codec_codec);
128         if(!rk610_codec)
129                 return;
130         
131         rk610_codec->hdmi_ndet = on;
132         if(on)
133                 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_HIGH);
134         else
135                 gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW);                     
136 }
137 EXPORT_SYMBOL(codec_set_spk);
138
139 /*
140  * read rk610 register cache
141  */
142 static inline unsigned int rk610_codec_read_reg_cache(struct snd_soc_codec *codec,
143         unsigned int reg)
144 {
145         u16 *cache = codec->reg_cache;
146         if (reg > RK610_CACHE_REGNUM)
147                 return -1;
148         return cache[reg];
149 }
150
151 static unsigned int rk610_codec_read(struct snd_soc_codec *codec, unsigned int r)
152 {
153         struct i2c_msg xfer[1];
154         u8 reg = r;
155         int ret;
156         struct i2c_client *client = codec->control_data;
157
158         /* Read register */
159         xfer[0].addr = (client->addr& 0x60)|(reg);
160         xfer[0].flags = I2C_M_RD;
161         xfer[0].len = 1;
162         xfer[0].buf = &reg;
163         xfer[0].scl_rate = 100000;
164         ret = i2c_transfer(client->adapter, xfer, 1);
165         if (ret != 1) {
166                 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
167                 return 0;
168         }
169
170         return reg;
171 }
172
173 /*
174  * write rk610 register cache
175  */
176 static inline void rk610_codec_write_reg_cache(struct snd_soc_codec *codec,
177         unsigned int reg, unsigned int value)
178 {
179         u16 *cache = codec->reg_cache;
180         if (reg > RK610_CACHE_REGNUM)
181                 return;
182         cache[reg] = value;
183 }
184
185 static int rk610_codec_write(struct snd_soc_codec *codec, unsigned int reg,
186         unsigned int value)
187 {
188         u8 data[2];
189         struct i2c_client *i2c;
190         DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value);
191         data[0] = value & 0x00ff;
192         rk610_codec_write_reg_cache (codec, reg, value);
193         i2c = (struct i2c_client *)codec->control_data;
194         i2c->addr = (i2c->addr & 0x60)|reg;
195
196         if (codec->hw_write(codec->control_data, data, 1) == 1){
197 //              DBG("================%s %d Run OK================\n",__FUNCTION__,__LINE__);
198                 return 0;
199         }else{
200                 DBG("================%s %d Run EIO================\n",__FUNCTION__,__LINE__);
201                 return -EIO;
202         }
203 }
204
205 void rk610_codec_reg_read(void)
206 {
207     struct snd_soc_codec *codec = rk610_codec_codec;
208     int i;
209     unsigned int data;
210
211     for (i=0; i<=0x1f; i++){
212         data = rk610_codec_read(codec, i);
213         printk("reg[0x%x]=0x%x\n",i,data);
214     }
215 }
216
217 static void spk_ctrl_fun(int status)
218 {
219         struct rk610_codec_priv *rk610_codec = NULL;
220         if(rk610_codec_codec == NULL)
221                 return;
222         rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec);
223         if(rk610_codec == NULL)
224                 return;
225                 
226         if(rk610_codec->spk_ctrl_io)
227         {
228                 DBG("--------%s----------status = %d\n",__FUNCTION__,status);
229                 gpio_set_value(rk610_codec->spk_ctrl_io, status);
230         }
231 }
232
233 struct _coeff_div {
234         u32 mclk;
235         u32 rate;
236         u16 fs;
237         u8 sr:5;
238         u8 usb:1;
239         u8 bclk;
240 };
241
242 /* codec hifi mclk clock divider coefficients */
243 static const struct _coeff_div coeff_div[] = {
244         /* 8k */
245         {12288000, 8000, 1536, 0x6, 0x0,ASC_BCLKDIV_16},
246         {11289600, 8000, 1408, 0x16, 0x0,ASC_BCLKDIV_16},
247         {18432000, 8000, 2304, 0x7, 0x0,ASC_BCLKDIV_16},
248         {16934400, 8000, 2112, 0x17, 0x0,ASC_BCLKDIV_16},
249         {8192000, 8000, 1024, 0x0, 0x0,ASC_BCLKDIV_16},
250         {12000000, 8000, 1500, 0x6, 0x1,ASC_BCLKDIV_16},
251
252         /* 11.025k */
253         {11289600, 11025, 1024, 0x18, 0x0,ASC_BCLKDIV_16},
254         {16934400, 11025, 1536, 0x19, 0x0,ASC_BCLKDIV_16},
255         {12000000, 11025, 1088, 0x19, 0x1,ASC_BCLKDIV_16},
256
257     /* 12k */
258         {12288000, 12000, 1024, 0x8, 0x0,ASC_BCLKDIV_16},
259         {18432000, 12000, 1536, 0x9, 0x0,ASC_BCLKDIV_16},
260         {12000000, 12000, 1000, 0x8, 0x1,ASC_BCLKDIV_16},
261
262         /* 16k */
263         {12288000, 16000, 768, 0xa, 0x0,ASC_BCLKDIV_8},
264         {18432000, 16000, 1152, 0xb, 0x0,ASC_BCLKDIV_8},
265         {12000000, 16000, 750, 0xa, 0x1,ASC_BCLKDIV_8},
266
267         /* 22.05k */
268         {11289600, 22050, 512, 0x1a, 0x0,ASC_BCLKDIV_8},
269         {16934400, 22050, 768, 0x1b, 0x0,ASC_BCLKDIV_8},
270         {12000000, 22050, 544, 0x1b, 0x1,ASC_BCLKDIV_8},
271
272     /* 24k */
273         {12288000, 24000, 512, 0x1c, 0x0,ASC_BCLKDIV_8},
274         {18432000, 24000, 768, 0x1d, 0x0,ASC_BCLKDIV_8},
275         {12000000, 24000, 500, 0x1c, 0x1,ASC_BCLKDIV_8},
276
277         /* 32k */
278         {12288000, 32000, 384, 0xc, 0x0,ASC_BCLKDIV_8},
279         {18432000, 32000, 576, 0xd, 0x0,ASC_BCLKDIV_8},
280         {12000000, 32000, 375, 0xa, 0x1,ASC_BCLKDIV_8},
281
282         /* 44.1k */
283         {11289600, 44100, 256, 0x10, 0x0,ASC_BCLKDIV_4},
284         {16934400, 44100, 384, 0x11, 0x0,ASC_BCLKDIV_8},
285         {12000000, 44100, 272, 0x11, 0x1,ASC_BCLKDIV_8},
286
287         /* 48k */
288         {12288000, 48000, 256, 0x0, 0x0,ASC_BCLKDIV_4},
289         {18432000, 48000, 384, 0x1, 0x0,ASC_BCLKDIV_4},
290         {12000000, 48000, 250, 0x0, 0x1,ASC_BCLKDIV_4},
291
292         /* 88.2k */
293         {11289600, 88200, 128, 0x1e, 0x0,ASC_BCLKDIV_4},
294         {16934400, 88200, 192, 0x1f, 0x0,ASC_BCLKDIV_4},
295         {12000000, 88200, 136, 0x1f, 0x1,ASC_BCLKDIV_4},
296
297         /* 96k */
298         {12288000, 96000, 128, 0xe, 0x0,ASC_BCLKDIV_4},
299         {18432000, 96000, 192, 0xf, 0x0,ASC_BCLKDIV_4},
300         {12000000, 96000, 125, 0xe, 0x1,ASC_BCLKDIV_4},
301 };
302
303 static inline int get_coeff(int mclk, int rate)
304 {
305         int i;
306
307         for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
308                 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
309                         return i;
310         }
311
312         return -EINVAL;
313 }
314
315 /* The set of rates we can generate from the above for each SYSCLK */
316
317 static unsigned int rates_12288[] = {
318         8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
319 };
320
321 static struct snd_pcm_hw_constraint_list constraints_12288 = {
322         .count  = ARRAY_SIZE(rates_12288),
323         .list   = rates_12288,
324 };
325
326 static unsigned int rates_112896[] = {
327         8000, 11025, 22050, 44100,
328 };
329
330 static struct snd_pcm_hw_constraint_list constraints_112896 = {
331         .count  = ARRAY_SIZE(rates_112896),
332         .list   = rates_112896,
333 };
334
335 static unsigned int rates_12[] = {
336         8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
337         48000, 88235, 96000,
338 };
339
340 static struct snd_pcm_hw_constraint_list constraints_12 = {
341         .count  = ARRAY_SIZE(rates_12),
342         .list   = rates_12,
343 };
344
345 static int rk610_codec_set_bias_level(struct snd_soc_codec *codec,
346                                  enum snd_soc_bias_level level)
347 {
348         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
349         DBG("Enter::%s----%d now_level =%d  old_level = %d\n",__FUNCTION__,__LINE__,level,codec->dapm.bias_level);
350         switch (level) {
351         case SND_SOC_BIAS_ON:
352                 break;
353         case SND_SOC_BIAS_PREPARE:
354                 /* VREF, VMID=2x50k, digital enabled */
355         //      rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
356                 break;
357
358         case SND_SOC_BIAS_STANDBY:
359 #if RESUME_PROBLEM      
360                 if(rk610_codec->rk610_workstatus == SND_SOC_DAPM_STREAM_RESUME)
361                 {
362                         DBG("rk610 is resume,have not into standby\n");
363                         rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
364                         break;
365                 }
366 #endif
367                 printk("rk610 standby\n");
368                 spk_ctrl_fun(GPIO_LOW);
369                  rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE);
370                 rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
371                 rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
372                 rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
373                 break;
374
375         case SND_SOC_BIAS_OFF:
376                 printk("rk610 power off\n");
377                 spk_ctrl_fun(GPIO_LOW);
378                 rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF);
379                 rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
380                 rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
381                 break;
382         }
383
384         codec->dapm.bias_level = level;
385
386         return 0;
387 }
388
389 /*
390  * Note that this should be called from init rather than from hw_params.
391  */
392 static int rk610_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
393                 int clk_id, unsigned int freq, int dir)
394 {
395         struct snd_soc_codec *codec = codec_dai->codec;
396
397         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
398
399         DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
400
401 #if RK610_CTL_PLL
402         if(rk610_codec_pll_set(freq))
403                 return -EINVAL;
404 #endif
405         switch (freq) {
406         case 11289600:
407         case 18432000:
408         case 22579200:
409         case 36864000:
410                 rk610_codec->sysclk_constraints = &constraints_112896;
411                 rk610_codec->sysclk = freq;
412                 break;
413
414         case 12288000:
415         case 16934400:
416         case 24576000:
417         case 33868800:
418                 rk610_codec->sysclk_constraints = &constraints_12288;
419                 rk610_codec->sysclk = freq;
420                 break;
421
422         case 12000000:
423         case 24000000:
424                 rk610_codec->sysclk_constraints = &constraints_12;
425                 rk610_codec->sysclk = freq;
426                 break;
427         default:
428                 return -EINVAL;
429         }
430         return 0;
431 }
432
433 static int rk610_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
434                 unsigned int fmt)
435 {
436         struct snd_soc_codec *codec = codec_dai->codec;
437         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
438         u16 iface = 0;
439
440         spk_ctrl_fun(GPIO_LOW);
441         rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a);  //setup Vmid and Vref, other module power down
442         rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);  ///|ASC_PDASDML_ENABLE);
443
444         /* set master/slave audio interface */
445         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
446         case SND_SOC_DAIFMT_CBM_CFM:
447                 iface = 0x0040;
448                 break;
449         case SND_SOC_DAIFMT_CBS_CFS:
450                 iface = 0x0000;
451                 break;
452         default:
453                 return -EINVAL;
454         }
455
456         /* interface format */
457         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
458         case SND_SOC_DAIFMT_I2S:
459                 iface |= 0x0002;
460                 break;
461         case SND_SOC_DAIFMT_RIGHT_J:
462                 break;
463         case SND_SOC_DAIFMT_LEFT_J:
464                 iface |= 0x0001;
465                 break;
466         case SND_SOC_DAIFMT_DSP_A:
467                 iface |= 0x0003;
468                 break;
469         case SND_SOC_DAIFMT_DSP_B:
470                 iface |= 0x0013;
471                 break;
472         default:
473                 return -EINVAL;
474         }
475
476         /* clock inversion */
477         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
478         case SND_SOC_DAIFMT_NB_NF:
479                 break;
480         case SND_SOC_DAIFMT_IB_IF:
481                 iface |= 0x0090;
482                 break;
483         case SND_SOC_DAIFMT_IB_NF:
484                 iface |= 0x0080;
485                 break;
486         case SND_SOC_DAIFMT_NB_IF:
487                 iface |= 0x0010;
488                 break;
489         default:
490                 return -EINVAL;
491         }
492
493         DBG("Enter::%s----%d  iface=%x\n",__FUNCTION__,__LINE__,iface);
494         rk610_codec_write(codec, ACCELCODEC_R09, iface);
495         return 0;
496 }
497
498 static int rk610_codec_pcm_hw_params(struct snd_pcm_substream *substream,
499                                 struct snd_pcm_hw_params *params,
500                                 struct snd_soc_dai *dai)
501 {
502         struct snd_soc_pcm_runtime *rtd = substream->private_data;
503         struct snd_soc_codec *codec = rtd->codec;
504         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
505
506         u16 iface = rk610_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3;
507         u16 srate = rk610_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180;
508         int coeff;
509
510         coeff = get_coeff(rk610_codec->sysclk, params_rate(params));
511         DBG("Enter::%s----%d  rk610_codec->sysclk=%d coeff = %d\n",__FUNCTION__,__LINE__,rk610_codec->sysclk, coeff);
512         /* bit size */
513         switch (params_format(params)) {
514         case SNDRV_PCM_FORMAT_S16_LE:
515                 break;
516         case SNDRV_PCM_FORMAT_S20_3LE:
517                 iface |= 0x0004;
518                 break;
519         case SNDRV_PCM_FORMAT_S24_LE:
520                 iface |= 0x0008;
521                 break;
522         case SNDRV_PCM_FORMAT_S32_LE:
523                 iface |= 0x000c;
524                 break;
525         }
526         DBG("Enter::%s----%d  iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));
527
528 //      rk610_codec_write(codec,ACCELCODEC_R0C, 0x17);
529         rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);   //soft mute
530         //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬
531         //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô
532         rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE);  //0x00
533
534         /* set iface & srate */
535         #ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER
536         iface |= ASC_INVERT_BCLK;//·­×ªBCLK  master״̬ËͳöµÄÉÙÁË°ë¸öʱÖÓ£¬µ¼ÖÂδµ½×î´óÒôÁ¿µÄʱºòÆÆÒô¡¢
537         #endif
538         rk610_codec_write(codec, ACCELCODEC_R09, iface);
539         if (coeff >= 0){
540         //    rk610_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk);
541                 rk610_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE);
542         }
543         rk610_codec_write(codec,ACCELCODEC_R0B, gR0BReg);
544
545         return 0;
546 }
547
548 static int rk610_codec_mute(struct snd_soc_dai *dai, int mute)
549 {
550     struct snd_soc_codec *codec = dai->codec;
551         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
552     DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
553
554     if (mute)
555         {
556                 rk610_codec_write(codec,ACCELCODEC_R17, 0xFF);  //AOL
557                 rk610_codec_write(codec,ACCELCODEC_R18, 0xFF);  //AOR
558         rk610_codec_write(codec,ACCELCODEC_R19, 0xFF);  //AOM
559         rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);  //soft mute
560         //add for standby
561         //      if(!dai->capture_active)
562         //      {
563         //              rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
564         //              rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
565         //              rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
566         //      }
567     }
568         else
569         {
570         //      rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a);  //setup Vmid and Vref, other module power down
571         //      rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);  ///|ASC_PDASDML_ENABLE);
572                 rk610_codec_write(codec,ACCELCODEC_R17, gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL
573                 rk610_codec_write(codec,ACCELCODEC_R18, gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOR
574         rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);
575                 rk610_codec_write(codec,ACCELCODEC_R19, 0x7F);  //AOM
576                 msleep(300);
577                 #if OUT_CAPLESS
578         rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
579         #else
580         rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
581                 #endif
582         //      schedule_delayed_work(&rk610_codec->rk610_delayed_work, 0);
583         //      rk610_codec_reg_read();
584                 if(rk610_codec->hdmi_ndet)
585                         spk_ctrl_fun(GPIO_HIGH);
586     }
587
588     return 0;
589 }
590
591 static void rk610_delayedwork_fun(struct work_struct *work)
592 {
593     struct snd_soc_codec *codec = rk610_codec_codec;
594         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); 
595         struct rk610_codec_platform_data *pdata= rk610_codec->pdata;    
596         DBG("--------%s----------\n",__FUNCTION__);
597         if(!pdata->boot_depop){
598                 #if OUT_CAPLESS
599                 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
600                 #else
601                 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
602                 #endif
603         }
604         spk_ctrl_fun(GPIO_HIGH);
605 }
606
607 static struct snd_soc_dai_ops rk610_codec_ops = {
608         .hw_params = rk610_codec_pcm_hw_params,
609         .set_fmt = rk610_codec_set_dai_fmt,
610         .set_sysclk = rk610_codec_set_dai_sysclk,
611         .digital_mute = rk610_codec_mute,
612 };
613
614 #define RK610_CODEC_RATES SNDRV_PCM_RATE_8000_96000
615 #define RK610_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
616                                                         SNDRV_PCM_FMTBIT_S24_LE)
617
618 static struct snd_soc_dai_driver rk610_codec_dai = {
619         .name = "rk610_codec",
620         .playback = {
621                 .stream_name = "Playback",
622                 .channels_min = 1,
623                 .channels_max = 2,
624                 .rates = RK610_CODEC_RATES,
625                 .formats = RK610_CODEC_FORMATS,
626         },
627         .capture = {
628                 .stream_name = "Capture",
629                 .channels_min = 1,
630                 .channels_max = 2,
631                 .rates = RK610_CODEC_RATES,
632                 .formats = RK610_CODEC_FORMATS,
633          },
634         .ops = &rk610_codec_ops,
635         .symmetric_rates = 1,
636 };
637
638 static int rk610_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
639 {
640         DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
641         rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
642 //      rk610_codec_reg_read();
643         return 0;
644 }
645
646 static int rk610_codec_resume(struct snd_soc_codec *codec)
647 {
648         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
649
650         DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
651         /* Sync reg_cache with the hardware */
652         
653 //      rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
654 #if RESUME_PROBLEM
655         rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_RESUME;
656 #endif
657         return 0;
658 }
659
660 #define USE_MIC_IN
661 #define USE_LPF
662 void rk610_codec_reg_set(void)
663 {
664     struct snd_soc_codec *codec = rk610_codec_codec;
665         struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec); 
666         struct rk610_codec_platform_data *pdata= rk610_codec->pdata;
667     unsigned int digital_gain;
668         unsigned int mic_vol = Volume_Input;
669         rk610_codec_write(codec,ACCELCODEC_R1D, 0x30);
670         rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);
671
672 #ifdef USE_LPF
673         // Route R-LPF->R-Mixer, L-LPF->L-Mixer
674         rk610_codec_write(codec,ACCELCODEC_R15, 0xC1);
675 #else
676         // Route RDAC->R-Mixer, LDAC->L->Mixer
677         rk610_codec_write(codec,ACCELCODEC_R15, 0x0C);
678 #endif
679         // With Cap Output, VMID ramp up slow
680         rk610_codec_write(codec,ACCELCODEC_R1A, 0x14);
681     mdelay(10);
682
683         rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB);   //LIL
684     rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB);   //LIR
685
686 #ifdef USE_MIC_IN
687         if(mic_vol > 0x07)
688         {
689                 rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB);   //Select MIC input
690                 mic_vol -= 0x07;
691         }       
692         else
693                 rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT);   //Select MIC input
694     rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE);  //0x00);  //use default value
695 #else
696     rk610_codec_write(codec,ACCELCODEC_R12, 0x4c);   //Select Line input
697 #endif
698
699     rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|mic_vol);   //MIC
700         
701         // Diable route PGA->R/L Mixer, PGA gain 0db.
702     rk610_codec_write(codec,ACCELCODEC_R13, 0x05 | 0 << 3);
703     rk610_codec_write(codec,ACCELCODEC_R14, 0x05 | 0 << 3);
704
705     //2soft mute
706     rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);   //soft mute
707
708     //2set default SR and clk
709     rk610_codec_write(codec,ACCELCODEC_R0A, ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE);
710     gR0AReg = ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE;
711     //2Config audio  interface
712     rk610_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_MASTER_MODE|ASC_NORMAL_BCLK);
713     rk610_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_ENABLE|ASC_SCRAMBLE_ENABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_4);
714     //2volume,input,output
715     digital_gain = Volume_Output;
716         
717         if(rk610_codec_read(codec,ACCELCODEC_R05)!=0x0f) {
718                 rk610_codec_write(codec,ACCELCODEC_R05, (digital_gain >> 8) & 0xFF);
719                 rk610_codec_write(codec,ACCELCODEC_R06, digital_gain & 0xFF);
720         }
721         if(rk610_codec_read(codec,ACCELCODEC_R07)!=0x0f){
722                 rk610_codec_write(codec,ACCELCODEC_R07, (digital_gain >> 8) & 0xFF);
723                 rk610_codec_write(codec,ACCELCODEC_R08, digital_gain & 0xFF);
724         }
725     rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_ENABLE|ASC_INT_ENABLE);
726     gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE;  //ASC_DEC_DISABLE|ASC_INT_ENABLE;
727
728         if(pdata->boot_depop){
729                 #if OUT_CAPLESS
730                 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
731                 #else
732                 rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
733                 #endif
734         }       
735 }
736
737 #ifdef RK610_PROC       
738 static int RK610_PROC_init(void);
739 #endif
740
741 static int rk610_codec_probe(struct snd_soc_codec *codec)
742 {
743         struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(codec);
744         int ret;
745
746 #ifdef RK610_PROC       
747         RK610_PROC_init();
748 #endif  
749         rk610_codec_codec = codec;
750         DBG("[%s] start\n", __FUNCTION__);
751         ret = snd_soc_codec_set_cache_io(codec, 8, 16, rk610_codec->control_type);
752         if (ret != 0) {
753                 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
754                 return ret;
755         }
756         //For RK610, i2c write&read method is special, do not use system default method.
757         codec->write = rk610_codec_write;
758         codec->read = rk610_codec_read;
759         codec->hw_write = (hw_write_t)i2c_master_send;
760
761         if (rk610_codec_codec == NULL) {
762                 dev_err(codec->dev, "Codec device not registered\n");
763                 return -ENODEV;
764         }
765
766         INIT_DELAYED_WORK(&rk610_codec->rk610_delayed_work, rk610_delayedwork_fun);
767         
768 //old control method,please filling rk610_codec_platform_data into Board-xx-xx.c
769 //qjb 2013-01-14
770 #if 0
771 #ifdef RK610_SPK_CTRL_PIN
772         rk610_codec->spk_ctrl_io = RK610_SPK_CTRL_PIN;
773         ret = gpio_request(rk610_codec->spk_ctrl_io, "rk610 spk_ctrl");
774     if (ret){
775         printk("rk610_control request gpio fail!\n");
776                 return ret;
777     }
778     gpio_direction_output(rk610_codec->spk_ctrl_io, GPIO_LOW);
779     gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW);
780 #else
781         rk610_codec->spk_ctrl_io = 0;
782 #endif
783 #endif
784         if(rk610_codec->spk_ctrl_io)
785         {
786                 ret = gpio_request(rk610_codec->spk_ctrl_io, "rk610 spk_ctrl");
787             if (ret){
788                 printk("rk610_control request gpio fail!\n");
789                         return ret;
790             }
791             gpio_direction_output(rk610_codec->spk_ctrl_io, GPIO_LOW);
792             gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW); 
793         }
794         
795         rk610_codec->hdmi_ndet = true;
796 #if RESUME_PROBLEM      
797         rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
798 #endif
799         
800     rk610_control_init_codec();
801     rk610_codec_reg_set();
802 //      rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
803         schedule_delayed_work(&rk610_codec->rk610_delayed_work, msecs_to_jiffies(1000));
804
805         codec->dapm.bias_level = SND_SOC_BIAS_PREPARE;
806         return ret;
807 }
808
809 /* power down chip */
810 static int rk610_codec_remove(struct snd_soc_codec *codec)
811 {
812         rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
813         return 0;
814 }
815
816 static struct snd_soc_codec_driver soc_codec_dev_rk610_codec = {
817         .probe =        rk610_codec_probe,
818         .remove =       rk610_codec_remove,
819         .suspend =      rk610_codec_suspend,
820         .resume =       rk610_codec_resume,
821         .set_bias_level = rk610_codec_set_bias_level,
822 //      .volatile_register = wm8900_volatile_register,
823         .reg_cache_size = ARRAY_SIZE(rk610_codec_reg),
824         .reg_word_size = sizeof(u16),
825         .reg_cache_default = rk610_codec_reg,
826 //      .dapm_widgets = rk610_codec_dapm_widgets,
827 //      .num_dapm_widgets = ARRAY_SIZE(rk610_codec_dapm_widgets),
828 //      .dapm_routes = audio_map,
829 //      .num_dapm_routes = ARRAY_SIZE(audio_map),
830 };
831
832 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
833 static int rk610_codec_i2c_probe(struct i2c_client *i2c,
834                             const struct i2c_device_id *id)
835 {
836         struct rk610_codec_priv *rk610_codec;
837         struct rk610_codec_platform_data *pdata = i2c->dev.platform_data;
838         int ret;
839         DBG("%s start\n", __FUNCTION__);
840         rk610_codec = kzalloc(sizeof(struct rk610_codec_priv), GFP_KERNEL);
841         if (rk610_codec == NULL)
842                 return -ENOMEM;
843 //qjb 2013-01-14
844         rk610_codec->pdata = pdata;
845         rk610_codec->spk_ctrl_io = pdata->spk_ctl_io;
846         if(pdata->io_init){
847                 ret =  pdata->io_init();
848                 if (ret < 0) {
849                         dev_err(&i2c->dev, "Failed to register codec pdata io_init error: %d\n", ret);
850                         kfree(rk610_codec);
851                         return ret;
852                 }
853         }
854         
855         i2c_set_clientdata(i2c, rk610_codec);
856         rk610_codec->control_type = SND_SOC_I2C;
857
858         ret =  snd_soc_register_codec(&i2c->dev,
859                         &soc_codec_dev_rk610_codec, &rk610_codec_dai, 1);
860         if (ret < 0) {
861                 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
862                 kfree(rk610_codec);
863         }
864         return ret;
865 }
866
867 static int rk610_codec_i2c_remove(struct i2c_client *client)
868 {
869         snd_soc_unregister_codec(&client->dev);
870         kfree(i2c_get_clientdata(client));
871         return 0;
872 }
873
874 static const struct i2c_device_id rk610_codec_i2c_id[] = {
875         { "rk610_i2c_codec", 0 },
876         { }
877 };
878 MODULE_DEVICE_TABLE(i2c, rk610_codec_i2c_id);
879
880 /* corgi i2c codec control layer */
881 static struct i2c_driver rk610_codec_i2c_driver = {
882         .driver = {
883                 .name = "RK610_CODEC",
884                 .owner = THIS_MODULE,
885         },
886         .probe = rk610_codec_i2c_probe,
887         .remove = rk610_codec_i2c_remove,
888         .id_table = rk610_codec_i2c_id,
889 };
890 #endif
891
892 static int __init rk610_codec_modinit(void)
893 {
894         int ret;
895         DBG("[%s] start\n", __FUNCTION__);
896         ret = i2c_add_driver(&rk610_codec_i2c_driver);
897         if (ret != 0)
898                 pr_err("rk610 codec: Unable to register I2C driver: %d\n", ret);
899         return ret;
900 }
901 module_init(rk610_codec_modinit);
902
903 static void __exit rk610_codec_exit(void)
904 {
905         i2c_del_driver(&rk610_codec_i2c_driver);
906 }
907 module_exit(rk610_codec_exit);
908
909 MODULE_DESCRIPTION("ASoC RK610 CODEC driver");
910 MODULE_AUTHOR("rk@rock-chips.com");
911 MODULE_LICENSE("GPL");
912
913 //=====================================================================
914 //Proc
915 #ifdef RK610_PROC
916 static ssize_t RK610_PROC_write(struct file *file, const char __user *buffer,
917                            unsigned long len, void *data)
918 {
919         char *cookie_pot; 
920         char *p;
921         int reg;
922         int value;
923         
924         cookie_pot = (char *)vmalloc( len );
925         if (!cookie_pot) 
926         {
927                 return -ENOMEM;
928         } 
929         else 
930         {
931                 if (copy_from_user( cookie_pot, buffer, len )) 
932                         return -EFAULT;
933         }
934
935         switch(cookie_pot[0])
936         {
937         case 'p':
938                 spk_ctrl_fun(GPIO_HIGH);
939                 break;
940         case 'o':
941                 spk_ctrl_fun(GPIO_LOW);
942                 break;  
943         case 'r':
944         case 'R':
945                 printk("Read reg debug\n");             
946                 if(cookie_pot[1] ==':')
947                 {
948                         strsep(&cookie_pot,":");
949                         while((p=strsep(&cookie_pot,",")))
950                         {
951                                 reg = simple_strtol(p,NULL,16);
952                                 value = rk610_codec_read(rk610_codec_codec,reg);
953                                 printk("wm8994_read:0x%04x = 0x%04x\n",reg,value);
954                         }
955                         printk("\n");
956                 }
957                 else
958                 {
959                         printk("Error Read reg debug.\n");
960                         printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n");
961                 }
962                 break;
963         case 'w':
964         case 'W':
965                 printk("Write reg debug\n");            
966                 if(cookie_pot[1] ==':')
967                 {
968                         strsep(&cookie_pot,":");
969                         while((p=strsep(&cookie_pot,"=")))
970                         {
971                                 reg = simple_strtol(p,NULL,16);
972                                 p=strsep(&cookie_pot,",");
973                                 value = simple_strtol(p,NULL,16);
974                                 rk610_codec_write(rk610_codec_codec,reg,value);
975                                 printk("wm8994_write:0x%04x = 0x%04x\n",reg,value);
976                         }
977                         printk("\n");
978                 }
979                 else
980                 {
981                         printk("Error Write reg debug.\n");
982                         printk("For example: w:22=0,23=0,24=0,25=0\n");
983                 }
984                 break;  
985         case 'D' :
986                 printk("Dump reg\n");
987                 rk610_codec_reg_read();
988                 break;
989         }
990
991         return len;
992 }
993
994 static int RK610_PROC_init(void)
995 {
996         struct proc_dir_entry *RK610_PROC_entry;
997         RK610_PROC_entry = create_proc_entry("driver/rk610_ts", 0777, NULL);
998         if(RK610_PROC_entry != NULL)
999         {
1000                 RK610_PROC_entry->write_proc = RK610_PROC_write;
1001                 return -1;
1002         }
1003         else
1004         {
1005                 printk("create proc error !\n");
1006         }
1007         return 0;
1008 }
1009
1010 #endif