2 * ALSA SoC CX2070X codec driver
4 * Copyright: (C) 2009/2010 Conexant Systems
6 * Based on sound/soc/codecs/tlv320aic2x.c by Vladimir Barinov
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 *************************************************************************
15 * Modified Date: 09/14/12
16 * File Version: 3.1.10.13
17 *************************************************************************
20 #include <linux/module.h>
21 #include <linux/moduleparam.h>
22 #include <linux/init.h>
23 #include <linux/delay.h>
25 #include <linux/platform_device.h>
26 #include <sound/core.h>
27 #include <sound/pcm.h>
28 #include <sound/pcm_params.h>
29 #include <sound/soc.h>
30 #include <sound/soc-dapm.h>
31 #include <sound/initval.h>
32 #include <sound/tlv.h>
33 #include <linux/gpio.h>
34 #include <sound/jack.h>
35 #include <linux/slab.h>
39 #define CX2070X_DRIVER_VERSION AUDDRV_VERSION( 3, 1 ,0x10 ,0x13)
42 #include <linux/i2c.h>
46 #include <linux/spi/spi.h>
49 #if defined(CONFIG_SND_CXLIFEGUARD)
53 #ifdef CONFIG_SND_CX2070X_LOAD_FW
54 #ifdef CONFIG_SND_CX2070X_USE_FW_H
55 #include "cx2070x_fw.h"
57 #include <linux/firmware.h>
63 #define CX2070X_TRISTATE_EEPROM 0
64 #define CX2070X_REG_NAMES 1
65 #define CX2070X_REG_WIDE 1
68 #define AUDIO_NAME "cx2070x"
71 #define CX2070X_RATES ( \
73 | SNDRV_PCM_RATE_11025 \
74 | SNDRV_PCM_RATE_16000 \
75 | SNDRV_PCM_RATE_22050 \
76 | SNDRV_PCM_RATE_32000 \
77 | SNDRV_PCM_RATE_44100 \
78 | SNDRV_PCM_RATE_48000 \
79 | SNDRV_PCM_RATE_88200 \
80 | SNDRV_PCM_RATE_96000 )
82 #if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F)
84 #define CX2070X_FORMATS ( SNDRV_PCM_FMTBIT_S16_LE \
85 | SNDRV_PCM_FMTBIT_S16_BE \
86 | SNDRV_PCM_FMTBIT_MU_LAW \
87 | SNDRV_PCM_FMTBIT_A_LAW )
89 #define CX2070X_FORMATS ( SNDRV_PCM_FMTBIT_S16_LE \
90 | SNDRV_PCM_FMTBIT_S16_BE )
95 #define noof(a) (sizeof(a)/sizeof(a[0]))
96 #define NOINLINE __attribute__((__noinline__))
99 # define INFO(fmt,...) printk(KERN_INFO fmt, ##__VA_ARGS__)
100 # define _INFO(fmt,...) printk(KERN_INFO fmt, ##__VA_ARGS__)
103 # define INFO(fmt,...)
104 # define _INFO(fmt,...)
107 #define MSG(fmt,...) printk(KERN_INFO fmt, ##__VA_ARGS__)
108 #define ERROR(fmt,...) printk(KERN_ERR fmt, ##__VA_ARGS__)
111 b_00000000,b_00000001,b_00000010,b_00000011, b_00000100,b_00000101,b_00000110,b_00000111,
112 b_00001000,b_00001001,b_00001010,b_00001011, b_00001100,b_00001101,b_00001110,b_00001111,
113 b_00010000,b_00010001,b_00010010,b_00010011, b_00010100,b_00010101,b_00010110,b_00010111,
114 b_00011000,b_00011001,b_00011010,b_00011011, b_00011100,b_00011101,b_00011110,b_00011111,
115 b_00100000,b_00100001,b_00100010,b_00100011, b_00100100,b_00100101,b_00100110,b_00100111,
116 b_00101000,b_00101001,b_00101010,b_00101011, b_00101100,b_00101101,b_00101110,b_00101111,
117 b_00110000,b_00110001,b_00110010,b_00110011, b_00110100,b_00110101,b_00110110,b_00110111,
118 b_00111000,b_00111001,b_00111010,b_00111011, b_00111100,b_00111101,b_00111110,b_00111111,
119 b_01000000,b_01000001,b_01000010,b_01000011, b_01000100,b_01000101,b_01000110,b_01000111,
120 b_01001000,b_01001001,b_01001010,b_01001011, b_01001100,b_01001101,b_01001110,b_01001111,
121 b_01010000,b_01010001,b_01010010,b_01010011, b_01010100,b_01010101,b_01010110,b_01010111,
122 b_01011000,b_01011001,b_01011010,b_01011011, b_01011100,b_01011101,b_01011110,b_01011111,
123 b_01100000,b_01100001,b_01100010,b_01100011, b_01100100,b_01100101,b_01100110,b_01100111,
124 b_01101000,b_01101001,b_01101010,b_01101011, b_01101100,b_01101101,b_01101110,b_01101111,
125 b_01110000,b_01110001,b_01110010,b_01110011, b_01110100,b_01110101,b_01110110,b_01110111,
126 b_01111000,b_01111001,b_01111010,b_01111011, b_01111100,b_01111101,b_01111110,b_01111111,
127 b_10000000,b_10000001,b_10000010,b_10000011, b_10000100,b_10000101,b_10000110,b_10000111,
128 b_10001000,b_10001001,b_10001010,b_10001011, b_10001100,b_10001101,b_10001110,b_10001111,
129 b_10010000,b_10010001,b_10010010,b_10010011, b_10010100,b_10010101,b_10010110,b_10010111,
130 b_10011000,b_10011001,b_10011010,b_10011011, b_10011100,b_10011101,b_10011110,b_10011111,
131 b_10100000,b_10100001,b_10100010,b_10100011, b_10100100,b_10100101,b_10100110,b_10100111,
132 b_10101000,b_10101001,b_10101010,b_10101011, b_10101100,b_10101101,b_10101110,b_10101111,
133 b_10110000,b_10110001,b_10110010,b_10110011, b_10110100,b_10110101,b_10110110,b_10110111,
134 b_10111000,b_10111001,b_10111010,b_10111011, b_10111100,b_10111101,b_10111110,b_10111111,
135 b_11000000,b_11000001,b_11000010,b_11000011, b_11000100,b_11000101,b_11000110,b_11000111,
136 b_11001000,b_11001001,b_11001010,b_11001011, b_11001100,b_11001101,b_11001110,b_11001111,
137 b_11010000,b_11010001,b_11010010,b_11010011, b_11010100,b_11010101,b_11010110,b_11010111,
138 b_11011000,b_11011001,b_11011010,b_11011011, b_11011100,b_11011101,b_11011110,b_11011111,
139 b_11100000,b_11100001,b_11100010,b_11100011, b_11100100,b_11100101,b_11100110,b_11100111,
140 b_11101000,b_11101001,b_11101010,b_11101011, b_11101100,b_11101101,b_11101110,b_11101111,
141 b_11110000,b_11110001,b_11110010,b_11110011, b_11110100,b_11110101,b_11110110,b_11110111,
142 b_11111000,b_11111001,b_11111010,b_11111011, b_11111100,b_11111101,b_11111110,b_11111111,
152 #define REG_TYPE_RO 0 // read only, read during initialization
153 #define REG_TYPE_RW 1 // read/write, read during initialization
154 #define REG_TYPE_WI 2 // write only, written during initialization
155 #define REG_TYPE_WC 3 // write/init, needs NEWC to be set when written
156 #define REG_TYPE_DM 4 // dummy register, read/write to cache only
158 # define REG_TYPE_MASK 0x0F
159 # define REG_WIDTH_B 0x00 // 8-bit data
160 # define REG_WIDTH_W 0x10 // 16-bit data
161 # define REG_WIDTH_MASK 0xF0
164 #define __REG(a,b2,b1,c,d,e,f) a,
165 #include "cx2070x-i2c.h"
170 typedef u16 cx2070x_reg_t;
172 typedef u8 cx2070x_reg_t;
174 static const cx2070x_reg_t cx2070x_data[]=
176 #define __REG(a,b2,b1,c,d,e,f) c,
177 #include "cx2070x-i2c.h"
183 #if CX2070X_REG_NAMES
191 static const struct cx2070x_reg cx2070x_regs[]=
193 #if defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_3_13E)
194 # if CX2070X_REG_NAMES
195 # define __REG(a,b2,b1,c,d,e,f) { #a,b1,d,REG_TYPE_##e|REG_WIDTH_##f },
197 # define __REG(a,b2,b1,c,d,e,f) { b1,d,REG_TYPE_##e|REG_WIDTH_##f },
199 #elif defined(CONFIG_SND_DIGICOLOR_SOC_CHANNEL_VER_4_30F)
200 # if CX2070X_REG_NAMES
201 # define __REG(a,b2,b1,c,d,e,f) { #a,b2,d,REG_TYPE_##e|REG_WIDTH_##f },
203 # define __REG(a,b2,b1,c,d,e,f) { b2,d,REG_TYPE_##e|REG_WIDTH_##f },
206 # if CX2070X_REG_NAMES
207 # define __REG(a,b2,b1,c,d,e,f) { #a,b2,d,REG_TYPE_##e|REG_WIDTH_##f },
209 # define __REG(a,b2,b1,c,d,e,f) { b2,d,REG_TYPE_##e|REG_WIDTH_##f },
212 #include "cx2070x-i2c.h"
216 // codec private data
219 enum snd_soc_control_type control_type;
223 enum Cx_INPUT_SEL input_sel;
224 enum Cx_OUTPUT_SEL output_sel;
226 long int playback_path;
227 long int capture_path;
230 #define get_cx2070x_priv(_codec_) ((struct cx2070x_priv *)snd_soc_codec_get_drvdata(codec))
232 #if defined(CONFIG_CXNT_SOFTWOARE_SIMULATION)
233 static int bNoHW = 1;
235 static int bNoHW = 0;
244 * min : 0xB6 : -74 dB
246 static const DECLARE_TLV_DB_SCALE(dac_tlv, -7400 , 100, 0);
254 * min : 0xB6 : -74 dB
256 static const DECLARE_TLV_DB_SCALE(adc_tlv, -7400 , 100, 0);
259 #if defined (CONFIG_SND_CX2070X_GPIO_JACKSENSE)
260 // TODO : the jack sensing code should be moved to machine layer.
261 static struct snd_soc_jack hs_jack ;
262 /* Headset jack detection DAPM pins */
263 static struct snd_soc_jack_pin hs_jack_pins[] = {
265 /*.list_head list*/{},
267 /*.mask*/SND_JACK_HEADPHONE,
271 /*.list_head list*/{},
273 /*.mask*/SND_JACK_HEADPHONE,
278 /* Headset jack detection gpios */
279 static struct snd_soc_jack_gpio hs_jack_gpios[] = {
281 /*.gpio*/ JACK_SENSE_GPIO_PIN,
282 /*.name*/ "hsdet-gpio",
283 /*.report*/ SND_JACK_HEADSET,
285 /*.debounce_time*/ 200,
291 #endif //CONFIG_SND_CX2070X_GPIO_JACKSENSE
293 #if defined(CONFIG_SND_CX2070X_LOAD_FW)
294 int I2cWrite( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf, unsigned char* pBuf);
295 int I2cWriteThenRead( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf,
296 unsigned char* pBuf, unsigned long cbReadBuf, unsigned char*pReadBuf);
299 #define GET_REG_CACHE(_codec_) (cx2070x_reg_t *) (_codec_)->reg_cache
300 static inline unsigned int cx2070x_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg)
302 cx2070x_reg_t *reg_cache;
303 if (reg >= noof(cx2070x_regs))
304 return (unsigned int)0;
305 reg_cache = GET_REG_CACHE(codec);
306 return reg_cache[reg];
309 static inline void cx2070x_write_reg_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
311 cx2070x_reg_t *reg_cache;
312 if (reg >= noof(cx2070x_regs))
314 reg_cache=GET_REG_CACHE(codec);
315 reg_cache[reg] = value;
319 static int NOINLINE cx2070x_real_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
323 struct spi_device * spi = (struct spi_device *) codec->control_data;
325 const struct cx2070x_reg *ri;
327 ri=&cx2070x_regs[reg];
330 switch(ri->type®_TYPE_MASK)
332 case REG_TYPE_RO: // read only, read during initialization
333 #if CX2070X_REG_NAMES
334 ERROR("%s(): write to Read-only register '%s'\n",__func__,ri->name);
338 case REG_TYPE_RW: // read/write, read during initialization
339 case REG_TYPE_WI: // write only, written during initialization
340 case REG_TYPE_WC: // write/init, needs NEWC to be set when written
341 // msg[0].addr = client->addr;
342 // msg[0].flags = client->flags & I2C_M_TEN;
343 data[0]=(u8)(ri->addr>>8);
344 data[1]=(u8)(ri->addr>>0);
345 switch(ri->type®_WIDTH_MASK)
348 data[2]=(u8)(value-ri->bias);
352 data[2]=(u8)((value-ri->bias)>>0)&0xFF;
353 data[3]=(u8)((value-ri->bias)>>8)&0xFF;
359 data[0] |= 0x80; //Write flag.
360 #ifdef DBG_MONITOR_REG
361 printk(KERN_ERR "Write REG %02x%02x %02x\n",data[0],data[1],data[2]);
363 spi_write(spi, data, len);
366 #if defined(REG_TYPE_DM)
367 case REG_TYPE_DM: // dummy register, no I2C transfers
372 cx2070x_write_reg_cache(codec,reg,value);
376 static int NOINLINE cx2070x_real_read(struct snd_soc_codec *codec, unsigned int reg)
378 struct spi_device * spi = (struct spi_device *) codec->control_data;
382 const struct cx2070x_reg *ri;
385 ri=&cx2070x_regs[reg];
387 if ((ri->type®_TYPE_MASK)==REG_TYPE_DM)
388 return cx2070x_read_reg_cache(codec,reg);
390 data[0]=(u8)(ri->addr>>8);
391 data[1]=(u8)(ri->addr>>0);
392 len = ((ri->type®_WIDTH_MASK)==REG_WIDTH_W)?2:1;
394 if (spi_write_then_read(spi, &data[0], 3, &data[2],len))
398 switch(ri->type®_WIDTH_MASK)
401 dat=ri->bias+data[2];
404 dat=ri->bias+(data[2]<<0)+(data[3]<<8);
409 cx2070x_write_reg_cache(codec,reg,dat);
413 static int NOINLINE cx2070x_real_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
415 struct i2c_client *client = (struct i2c_client *) codec->control_data;
416 struct i2c_adapter *adap = client->adapter;
417 struct i2c_msg msg[2];
419 const struct cx2070x_reg *ri;
420 if(reg == MIC_CONTROL)
421 printk(">>>>>>>>>>>>>%s value = %0x\n", __func__, value);
422 if(reg == MIC_CONTROL)
425 ri=&cx2070x_regs[reg];
427 switch(ri->type®_TYPE_MASK)
429 case REG_TYPE_RO: // read only, read during initialization
430 #if CX2070X_REG_NAMES
431 ERROR("%s(): write to Read-only register '%s'\n",__func__,ri->name);
435 case REG_TYPE_RW: // read/write, read during initialization
436 case REG_TYPE_WI: // write only, written during initialization
437 case REG_TYPE_WC: // write/init, needs NEWC to be set when written
438 msg[0].addr = client->addr;
439 msg[0].flags = client->flags & I2C_M_TEN;
440 msg[0].buf = &data[0];
441 msg[0].scl_rate = 200 * 1000;
442 data[0]=(u8)(ri->addr>>8);
443 data[1]=(u8)(ri->addr>>0);
444 switch(ri->type®_WIDTH_MASK)
447 data[2]=(u8)(value-ri->bias);
451 data[2]=(u8)((value-ri->bias)>>0)&0xFF;
452 data[3]=(u8)((value-ri->bias)>>8)&0xFF;
458 #ifdef DBG_MONITOR_REG
459 printk(KERN_ERR "Write REG %02x%02x %02x\n",data[0],data[1],data[2]);
462 if (i2c_transfer(adap,msg,1)!=1)
466 #if defined(REG_TYPE_DM)
467 case REG_TYPE_DM: // dummy register, no I2C transfers
472 cx2070x_write_reg_cache(codec,reg,value);
476 static int NOINLINE cx2070x_real_read(struct snd_soc_codec *codec, unsigned int reg)
478 struct i2c_client *client =(struct i2c_client *) codec->control_data;
479 struct i2c_adapter *adap = client->adapter;
480 struct i2c_msg msg[2];
482 const struct cx2070x_reg *ri;
485 ri=&cx2070x_regs[reg];
487 if ((ri->type®_TYPE_MASK)==REG_TYPE_DM)
488 return cx2070x_read_reg_cache(codec,reg);
490 data[0]=(u8)(ri->addr>>8);
491 data[1]=(u8)(ri->addr>>0);
493 msg[0].addr = client->addr;
494 msg[0].flags = client->flags & I2C_M_TEN;
496 msg[0].buf = &data[0];
497 msg[0].scl_rate = 200 * 1000;
499 msg[1].addr = client->addr;
500 msg[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
501 msg[1].len = ((ri->type®_WIDTH_MASK)==REG_WIDTH_W)?2:1;
502 msg[1].buf = &data[2];
503 msg[1].scl_rate = 200 * 1000;
505 if (i2c_transfer(adap,msg,2)!=2)
508 switch(ri->type®_WIDTH_MASK)
511 dat=ri->bias+data[2];
514 dat=ri->bias+(data[2]<<0)+(data[3]<<8);
519 cx2070x_write_reg_cache(codec,reg,dat);
522 #endif //#!ENABLE_SPI
524 // reset codec via gpio pin.
525 #if defined(CONFIG_SND_CX2070X_GPIO_RESET)
526 static int cx2070x_reset_device(void)
530 int reset_pin = CODEC_RESET_GPIO_PIN;
531 INFO("%lu: %s() called\n",jiffies,__func__);
532 if (gpio_is_valid(reset_pin)) {
533 if (gpio_request(reset_pin, "reset_pin")) {
534 printk( KERN_ERR "cx2070x: reset pin %d not available\n",reset_pin);
537 gpio_direction_output(reset_pin, 1);
539 gpio_set_value(reset_pin, 0);
540 //udelay(1);// simon :need to re-check the reset timing.
542 gpio_set_value(reset_pin, 1);
543 gpio_free(reset_pin);
544 mdelay(200); //simon :not sure how long the device become ready.
549 printk( KERN_ERR "cx2070x: reset pin %d is not valid\n",reset_pin);
554 #endif //#if defined(CONFIG_SND_CX2070X_GPIO_RESET)
557 static int cx2070x_dsp_init(struct snd_soc_codec *codec,unsigned mode)
560 cx2070x_real_write(codec,DSP_INIT,mode);
561 printk("******************%s mode = %0x\n",__func__, mode);
562 // maximum time for the NEWC to clear is about 2ms.
564 if (!(cx2070x_real_read(codec,DSP_INIT)&DSP_INIT_NEWC))
572 static int NOINLINE cx2070x_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
576 if ((err=cx2070x_real_write(codec,reg,value))<0)
579 switch(cx2070x_regs[reg].type®_TYPE_MASK)
582 printk("^^^^^^^^^%0x\n",cx2070x_read_reg_cache(codec,DSP_INIT));
583 printk("^^^^^^^^^%0x\n",cx2070x_read_reg_cache(codec,DSP_INIT)|DSP_INIT_NEWC);
584 return cx2070x_dsp_init(codec,cx2070x_read_reg_cache(codec,DSP_INIT)|DSP_INIT_NEWC);
591 static int output_select_event_set(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
596 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
597 struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
598 struct cx2070x_priv *channel = get_cx2070x_priv(codec);
600 // unsigned short sel;
602 /* Refuse any mode changes if we are not able to control the codec. */
603 if (!codec->control_data)
606 if (ucontrol->value.enumerated.item[0] >= control->max)
609 mutex_lock(&codec->mutex);
611 /* Translate selection to bitmap */
612 channel->output_sel = (enum Cx_OUTPUT_SEL) ucontrol->value.enumerated.item[0];
615 switch(ucontrol->value.enumerated.item[0])
617 case Cx_OUTPUT_SEL_BY_GPIO:
620 snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT");
621 //snd_soc_dapm_disable_pin(codec, "Headphone");
622 snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT");
624 #if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE)
625 #ifdef CONFIG_GPIOLIB
626 // snd_soc_jack_gpio_detect(&hs_jack_gpios[0]);
627 //snd_soc_dapm_enable_pin(codec, "INT SPK");
629 snd_soc_dapm_enable_pin(&codec->dapm, "INT SPK");
632 snd_soc_dapm_enable_pin(&codec->dapm, "INT SPK");
633 #endif //if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE)
636 case Cx_OUTPUT_SEL_SPK:
637 case Cx_OUTPUT_SEL_LINE:
639 snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT");
640 snd_soc_dapm_disable_pin(&codec->dapm, "Headphone");
642 snd_soc_dapm_enable_pin(&codec->dapm, "INT SPK");
645 case Cx_OUTPUT_SEL_HP:
647 snd_soc_dapm_disable_pin(&codec->dapm, "BT OUT");
648 snd_soc_dapm_disable_pin(&codec->dapm, "INT SPK");
649 snd_soc_dapm_enable_pin(&codec->dapm, "Headphone");
652 case Cx_OUTPUT_SEL_DPORT2:
654 snd_soc_dapm_disable_pin(&codec->dapm, "INT SPK");
655 snd_soc_dapm_disable_pin(&codec->dapm, "Headphone");
656 snd_soc_dapm_enable_pin(&codec->dapm, "BT OUT");
660 printk( KERN_ERR "output mode is not valid\n");
663 snd_soc_dapm_sync(&codec->dapm);
664 mutex_unlock(&codec->mutex);
668 static int output_select_event_get(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
671 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
672 struct cx2070x_priv *channel = get_cx2070x_priv(codec);
673 ucontrol->value.enumerated.item[0] = channel->output_sel;
678 static const char *output_select_mode[] =
679 {"AUTO", "SPK" ,"LINE", "HP" ,"PCM2"};
681 static const struct soc_enum output_select_enum[] = {
682 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(output_select_mode),
686 static const char *input_select_mode[] =
689 static const struct soc_enum input_select_enum[] = {
690 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_select_mode),
694 static const struct snd_kcontrol_new input_select_controls =
695 SOC_DAPM_ENUM("Route", input_select_enum);
697 static const struct snd_kcontrol_new cx2070x_snd_controls[]=
700 SOC_DOUBLE_R_TLV("Master Playback Volume", DAC1_GAIN_LEFT, DAC2_GAIN_RIGHT, 0, 74, 0,dac_tlv),
701 SOC_SINGLE( "EQ Switch", DSP_PROCESSING_ENABLE_2, 0, 0x01, 0),
702 SOC_SINGLE( "SWC Switch", DSP_PROCESSING_ENABLE_2, 1, 0x01, 0),
703 SOC_SINGLE( "DRC Switch", DSP_PROCESSING_ENABLE_2, 2, 0x01, 0),
704 SOC_SINGLE( "Stage Enhancer Switch", DSP_PROCESSING_ENABLE_2, 3, 0x01, 0),
705 SOC_SINGLE( "Loudness Switch", DSP_PROCESSING_ENABLE_2, 4, 0x01, 0),
706 SOC_SINGLE( "DSP Mono Out Switch", DSP_PROCESSING_ENABLE_2, 5, 0x01, 0),
710 SOC_DOUBLE_R_TLV("Mic Pga Volume", ADC2_GAIN_LEFT, ADC2_GAIN_RIGHT, 0, 74, 0,adc_tlv),
711 SOC_SINGLE( "Right Microphone Switch", DSP_PROCESSING_ENABLE_1, 6, 0x01, 0),
712 SOC_SINGLE( "Inbound Noice Reduction Switch", DSP_PROCESSING_ENABLE_1, 5, 0x01, 0),
713 SOC_SINGLE( "Mic AGC Switch", DSP_PROCESSING_ENABLE_1, 4, 0x01, 0),
714 SOC_SINGLE( "Beam Forming Switch", DSP_PROCESSING_ENABLE_1, 3, 0x01, 0),
715 SOC_SINGLE( "Noise Reduction Switch", DSP_PROCESSING_ENABLE_1, 2, 0x01, 0),
716 SOC_SINGLE( "LEC Switch", DSP_PROCESSING_ENABLE_1, 1, 0x01, 0),
717 SOC_SINGLE( "AEC Switch", DSP_PROCESSING_ENABLE_1, 0, 0x01, 0),
718 SOC_ENUM_EXT("Master Playback Switch", output_select_enum[0], output_select_event_get, output_select_event_set),
721 //For tiny alsa playback/capture/voice call path
722 static const char *cx2070x_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6
723 "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10
725 static const char *cx2070x_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"};
727 static const SOC_ENUM_SINGLE_DECL(cx2070x_playback_path_type, 0, 0, cx2070x_playback_path_mode);
729 static const SOC_ENUM_SINGLE_DECL(cx2070x_capture_path_type, 0, 0, cx2070x_capture_path_mode);
732 static int cx2070x_playback_path_get(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_value *ucontrol)
735 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
736 struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec);
739 printk("%s : cx2070x_priv is NULL\n", __func__);
743 printk("%s : playback_path %ld\n",__func__,ucontrol->value.integer.value[0]);
745 ucontrol->value.integer.value[0] = cx2070x->playback_path;
750 static int cx2070x_playback_path_put(struct snd_kcontrol *kcontrol,
751 struct snd_ctl_elem_value *ucontrol)
753 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
754 struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec);
758 printk("%s : cx2070x_priv is NULL\n", __func__);
762 if (cx2070x->playback_path == ucontrol->value.integer.value[0]){
763 printk("%s : playback_path is not changed!\n",__func__);
767 pre_path = cx2070x->playback_path;
768 cx2070x->playback_path = ucontrol->value.integer.value[0];
770 printk("%s : set playback_path %ld, pre_path %ld\n", __func__,
771 cx2070x->playback_path, pre_path);
773 switch (cx2070x->playback_path) {
775 if (pre_path != OFF) {
776 cx2070x_real_read(codec,DSP_INIT);
777 cx2070x_write(codec,DSP_INIT,(cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC) & ~(1 << 3));
784 printk("%s : >>>>>>>>>>>>>>>PUT SPK_PATH\n",__func__);
785 if (pre_path == OFF) {
786 cx2070x_real_read(codec,DSP_INIT);
787 cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3);
794 if (pre_path == OFF) {
795 cx2070x_real_read(codec,DSP_INIT);
796 cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3);
803 if (pre_path == OFF) {
804 cx2070x_real_read(codec,DSP_INIT);
805 cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3);
815 static int cx2070x_capture_path_get(struct snd_kcontrol *kcontrol,
816 struct snd_ctl_elem_value *ucontrol)
818 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
819 struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec);
822 printk("%s : cx2070x_priv is NULL\n", __func__);
826 printk("%s : capture_path %ld\n", __func__,
827 ucontrol->value.integer.value[0]);
829 ucontrol->value.integer.value[0] = cx2070x->capture_path;
834 static int cx2070x_capture_path_put(struct snd_kcontrol *kcontrol,
835 struct snd_ctl_elem_value *ucontrol)
837 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
838 struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec);
842 printk("%s : cx2070x_priv is NULL\n", __func__);
846 if (cx2070x->capture_path == ucontrol->value.integer.value[0]){
847 printk("%s : capture_path is not changed!\n", __func__);
851 pre_path = cx2070x->capture_path;
852 cx2070x->capture_path = ucontrol->value.integer.value[0];
854 printk("%s : set capture_path %ld, pre_path %ld\n", __func__,
855 cx2070x->capture_path, pre_path);
857 switch (cx2070x->capture_path) {
859 if (pre_path != MIC_OFF) {
860 cx2070x_real_read(codec,DSP_INIT);
861 cx2070x_write(codec,DSP_INIT,(cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC) & ~(DSP_INIT_STREAM_5));
865 printk("%s : >>>>>>>>>>>>>>>PUT MAIN_MIC_PATH\n",__func__);
866 if (pre_path == MIC_OFF) {
867 cx2070x_real_read(codec,DSP_INIT);
868 cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_5);
872 if (pre_path == MIC_OFF) {
873 cx2070x_real_read(codec,DSP_INIT);
874 cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_5);
886 static const struct snd_kcontrol_new cx2070x_snd_path_controls[] = {
887 SOC_ENUM_EXT("Playback Path", cx2070x_playback_path_type,
888 cx2070x_playback_path_get, cx2070x_playback_path_put),
890 SOC_ENUM_EXT("Capture MIC Path", cx2070x_capture_path_type,
891 cx2070x_capture_path_get, cx2070x_capture_path_put),
895 // add non dapm controls
896 static int cx2070x_add_controls(struct snd_soc_codec *codec)
898 INFO("%lu: %s() called\n",jiffies,__func__);
900 return (snd_soc_add_codec_controls(codec, cx2070x_snd_controls, ARRAY_SIZE(cx2070x_snd_controls)));
903 static int hpportpga_event(struct snd_soc_dapm_widget *w,
904 struct snd_kcontrol *kcontrol, int event)
907 struct snd_soc_codec * codec = w->codec;
908 unsigned int on = 0x1;
909 old = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL);
913 case SND_SOC_DAPM_POST_PMU:
914 cx2070x_write(codec,OUTPUT_CONTROL,old|on );
916 case SND_SOC_DAPM_POST_PMD:
917 cx2070x_write(codec,OUTPUT_CONTROL,old);
924 static int lineoutpga_event(struct snd_soc_dapm_widget *w,
925 struct snd_kcontrol *kcontrol, int event)
928 struct snd_soc_codec * codec = w->codec;
929 unsigned int on = (unsigned int)1<<1;
930 val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL);
934 case SND_SOC_DAPM_POST_PMU:
935 cx2070x_write(codec,OUTPUT_CONTROL,val|on);
937 case SND_SOC_DAPM_POST_PMD:
938 cx2070x_write(codec,OUTPUT_CONTROL,val);
943 static int clsdportpga_event(struct snd_soc_dapm_widget *w,
944 struct snd_kcontrol *kcontrol, int event)
947 struct snd_soc_codec * codec = w->codec;
948 unsigned int on = (unsigned int)1<<2;
949 val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL);
953 case SND_SOC_DAPM_POST_PMU:
954 cx2070x_write(codec,OUTPUT_CONTROL,val|on);
956 case SND_SOC_DAPM_POST_PMD:
957 cx2070x_write(codec,OUTPUT_CONTROL,val);
963 static int lineinpga_event(struct snd_soc_dapm_widget *w,
964 struct snd_kcontrol *kcontrol, int event)
967 //struct snd_soc_codec * codec = w->codec;
968 //unsigned int on = (unsigned int)1<<2;
969 //val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL);
973 //case SND_SOC_DAPM_POST_PMU:
974 // cx2070x_write(codec,OUTPUT_CONTROL,val|on);
976 //case SND_SOC_DAPM_POST_PMD:
977 // cx2070x_write(codec,OUTPUT_CONTROL,val);
983 static int micportpga_event(struct snd_soc_dapm_widget *w,
984 struct snd_kcontrol *kcontrol, int event)
987 //struct snd_soc_codec * codec = w->codec;
988 //unsigned int on = (unsigned int)1<<1;
989 //val = cx2070x_read_reg_cache(codec,OUTPUT_CONTROL);
993 //case SND_SOC_DAPM_POST_PMU:
994 // cx2070x_write(codec,OUTPUT_CONTROL,val|on);
996 //case SND_SOC_DAPM_POST_PMD:
997 // cx2070x_write(codec,OUTPUT_CONTROL,val);
1003 static int aout_pga_event(struct snd_soc_dapm_widget *w,
1004 struct snd_kcontrol *kcontrol, int event)
1007 struct snd_soc_codec * codec = w->codec;
1008 unsigned int on = (unsigned int)1<<7; //steam 7
1009 unsigned int reg = DSP_INIT;
1010 val = cx2070x_read_reg_cache(codec,reg);
1014 case SND_SOC_DAPM_POST_PMU:
1015 cx2070x_write(codec,STREAMOP_ROUTING,0x60 ); // scal_out
1016 cx2070x_write(codec,STREAM7_SOURCE,5 ); //Scale_out
1017 cx2070x_write(codec,reg,val|on );
1019 case SND_SOC_DAPM_POST_PMD:
1020 cx2070x_write(codec,STREAM7_SOURCE,0 ); //disconnect
1021 cx2070x_write(codec,reg,val);
1027 static int dout_pga_event(struct snd_soc_dapm_widget *w,
1028 struct snd_kcontrol *kcontrol, int event)
1031 struct snd_soc_codec * codec = w->codec;
1032 unsigned int on = (unsigned int)1<<4;
1033 unsigned int reg = DSP_INIT;
1034 val = cx2070x_read_reg_cache(codec,reg);
1038 case SND_SOC_DAPM_POST_PMU:
1039 cx2070x_write(codec,STREAMOP_ROUTING,0x60 ); // scal_out
1040 snd_soc_update_bits(codec, MIC_CONTROL, 3, 1);
1041 //cx2070x_write(codec,STREAM6_ROUTING,5 ); // scal_out
1042 cx2070x_write(codec,reg,val|on );
1044 case SND_SOC_DAPM_POST_PMD:
1045 cx2070x_write(codec,STREAMOP_ROUTING,0x62 ); // scal_out
1046 cx2070x_write(codec,STREAM6_ROUTING,0 ); //disconnect
1047 cx2070x_write(codec,reg,val);
1053 static int ain_pga_event(struct snd_soc_dapm_widget *w,
1054 struct snd_kcontrol *kcontrol, int event)
1057 struct snd_soc_codec * codec = w->codec;
1058 unsigned int on = (unsigned int)1<<2; //steam 2
1059 unsigned int reg = DSP_INIT;
1060 val = cx2070x_read_reg_cache(codec,reg);
1064 case SND_SOC_DAPM_POST_PMU:
1065 //cx2070x_write(codec,VOICE_IN_SOURCE, 0x2 ); //stream 2 -> Voice In
1066 cx2070x_write(codec,reg,val|on );
1068 case SND_SOC_DAPM_POST_PMD:
1069 cx2070x_write(codec,reg,val);
1075 static int din_pga_event(struct snd_soc_dapm_widget *w,
1076 struct snd_kcontrol *kcontrol, int event)
1079 struct snd_soc_codec * codec = w->codec;
1080 unsigned int on = (unsigned int)1<<4; //stream 4
1081 unsigned int reg = DSP_INIT;
1082 val = cx2070x_read_reg_cache(codec,reg);
1086 case SND_SOC_DAPM_POST_PMU:
1087 cx2070x_write(codec,VOICE_IN_SOURCE, 0x4 ); //stream 4 -> Voice In
1088 cx2070x_write(codec,reg,val|on );
1090 case SND_SOC_DAPM_POST_PMD:
1091 cx2070x_write(codec,reg,val);
1097 static int adc_pga_event(struct snd_soc_dapm_widget *w,
1098 struct snd_kcontrol *kcontrol, int event)
1101 struct snd_soc_codec * codec = w->codec;
1102 unsigned int on = (unsigned int)1<<5; //stream 5
1103 unsigned int reg = DSP_INIT;
1104 val = cx2070x_read_reg_cache(codec,reg);
1108 case SND_SOC_DAPM_POST_PMU:
1109 cx2070x_write(codec,reg,val|on );
1111 case SND_SOC_DAPM_POST_PMD:
1112 cx2070x_write(codec,reg,val);
1118 static const struct snd_soc_dapm_widget cx2070x_dapm_widgets[]=
1122 SND_SOC_DAPM_DAC( "DAC", "Playback", DSP_INIT,3,0), //stream 3
1124 SND_SOC_DAPM_PGA_E("AOUT PGA", SND_SOC_NOPM,
1125 0, 0, NULL, 0, aout_pga_event,
1126 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1128 SND_SOC_DAPM_PGA_E("DOUT PGA", SND_SOC_NOPM,
1129 0, 0, NULL, 0, dout_pga_event,
1130 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1132 SND_SOC_DAPM_PGA_E("HP Port", SND_SOC_NOPM,
1133 0, 0, NULL, 0, hpportpga_event,
1134 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1136 SND_SOC_DAPM_PGA_E("CLASSD Port", SND_SOC_NOPM,
1137 0, 0, NULL, 0, clsdportpga_event,
1138 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1140 SND_SOC_DAPM_PGA_E("LINEOUT Port", SND_SOC_NOPM,
1141 0, 0, NULL, 0, lineoutpga_event,
1142 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1145 SND_SOC_DAPM_OUTPUT("SPK OUT"),
1146 SND_SOC_DAPM_OUTPUT("LINE OUT"),
1147 SND_SOC_DAPM_OUTPUT("HP OUT"),
1148 SND_SOC_DAPM_OUTPUT("PCM OUT"),
1153 SND_SOC_DAPM_ADC_E("ADC", "Capture", SND_SOC_NOPM,
1154 0, 0, adc_pga_event,
1155 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1158 SND_SOC_DAPM_PGA_E("AIN PGA", SND_SOC_NOPM,
1159 0, 0, NULL, 0, ain_pga_event,
1160 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1162 SND_SOC_DAPM_PGA_E("DIN PGA", SND_SOC_NOPM,
1163 0, 0, NULL, 0, din_pga_event,
1164 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1166 SND_SOC_DAPM_PGA_E("MIC Port", SND_SOC_NOPM,
1167 0, 0, NULL, 0, micportpga_event,
1168 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1170 SND_SOC_DAPM_PGA_E("LINEIN Port", SND_SOC_NOPM,
1171 0, 0, NULL, 0, lineinpga_event,
1172 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1174 //DECLARE_TLV_DB_SCALE
1176 SND_SOC_DAPM_INPUT("MIC IN"),
1177 SND_SOC_DAPM_INPUT("PCM IN"),
1178 SND_SOC_DAPM_INPUT("LINE IN"),
1180 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
1181 &input_select_controls),
1183 SND_SOC_DAPM_MICBIAS("Mic Bias",MIC_CONTROL,3,0),
1186 SND_SOC_DAPM_MIC("INT MIC", NULL),
1187 SND_SOC_DAPM_MIC("BT IN", NULL),
1188 SND_SOC_DAPM_HP("BT OUT", NULL),
1189 SND_SOC_DAPM_SPK("INT SPK", NULL),
1190 SND_SOC_DAPM_HP("Headphone", NULL),
1194 static const struct snd_soc_dapm_route cx2070x_routes[] =
1197 { "AOUT PGA", NULL,"DAC" },
1198 { "DOUT PGA", NULL,"DAC" },
1200 { "HP Port", NULL,"AOUT PGA" },
1201 { "LINEOUT Port", NULL,"AOUT PGA" },
1202 { "CLASSD Port", NULL,"AOUT PGA" },
1204 { "HP OUT", NULL,"HP Port" },
1205 { "LINE OUT", NULL,"LINEOUT Port" },
1206 { "SPK OUT", NULL,"CLASSD Port" },
1207 { "PCM OUT", NULL,"DOUT PGA" },
1210 { "ADC", NULL,"Capture Source" },
1212 { "Capture Source", "MIC","AIN PGA" },
1213 { "Capture Source", "PCM","DIN PGA" },
1215 { "AIN PGA", NULL,"MIC Port" },
1216 // { "MIC Port", NULL,"Mic Bias" },
1217 { "MIC Port", NULL,"MIC IN" },
1219 // { "Mic Bias", NULL,"MIC IN" },
1220 { "DIN PGA", NULL,"PCM IN" },
1223 { "Headphone", NULL,"HP OUT" },
1224 { "INT SPK", NULL,"SPK OUT" },
1225 { "BT OUT", NULL,"PCM OUT" },
1226 { "MIC IN", NULL,"INT MIC" },
1227 { "PCM IN", NULL,"BT IN" },
1231 static int cx2070x_add_widgets(struct snd_soc_codec *codec)
1233 struct snd_soc_dapm_context *dapm = &codec->dapm;
1235 INFO("%lu: %s() called\n",jiffies,__func__);
1237 snd_soc_dapm_new_controls(dapm, cx2070x_dapm_widgets, ARRAY_SIZE(cx2070x_dapm_widgets));
1238 snd_soc_dapm_add_routes(dapm, cx2070x_routes, ARRAY_SIZE(cx2070x_routes));
1242 static int cx2070x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1245 struct snd_soc_codec *codec = dai->codec;
1246 unsigned int s5,s3,i2s,dsp;
1247 #define _3_3_f_f_5 1
1248 #define _1_1_7_7_0 0
1251 ERROR("%lu: %s() called\n",jiffies,__func__);
1252 ERROR("\tformat:%u speed:%u\n",params_format(params),params_rate(params));
1254 switch(params_format(params))
1256 case SNDRV_PCM_FORMAT_S16_LE: s5=STREAM5_SAMPLE_16_LIN; s3=STREAM5_SAMPLE_16_LIN; i2s=_3_3_f_f_5; break;
1257 case SNDRV_PCM_FORMAT_S16_BE: s5=STREAM5_SAMPLE_16_LIN; s3=STREAM5_SAMPLE_16_LIN; i2s=_3_3_f_f_5; break;
1258 case SNDRV_PCM_FORMAT_MU_LAW: s5=STREAM5_SAMPLE_U_LAW; s3=STREAM5_SAMPLE_U_LAW; i2s=_1_1_7_7_0; break;
1259 case SNDRV_PCM_FORMAT_A_LAW: s5=STREAM5_SAMPLE_A_LAW; s3=STREAM5_SAMPLE_A_LAW; i2s=_1_1_7_7_0; break;
1261 printk(KERN_ERR "cx2070x: unsupported PCM format 0x%u\n",params_format(params));
1265 switch(params_rate(params))
1267 case 8000: s5|= STREAM5_RATE_8000;
1268 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_8000; break;
1269 case 11025: s5|= STREAM5_RATE_11025;
1270 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_11025; break;
1271 case 16000: s5|= STREAM5_RATE_16000;
1272 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_16000; break;
1273 case 22050: s5|= STREAM5_RATE_22050;
1274 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_22050; break;
1275 case 24000: s5|= STREAM5_RATE_24000;
1276 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_24000; break;
1277 case 32000: s5|= STREAM5_RATE_32000;
1278 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_32000; break;
1279 case 44100: s5|= STREAM5_RATE_44100;
1280 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_44100; break;
1281 case 48000: s5|= STREAM5_RATE_48000;
1282 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_48000; break;
1283 case 88200: s5|= STREAM5_RATE_88200;
1284 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_88200; break;
1285 case 96000: s5|= STREAM5_RATE_96000;
1286 s3|=STREAM3_STREAM_STEREO|STREAM3_RATE_96000; break;
1288 printk(KERN_ERR "cx2070x: unsupported rate %d\n",params_rate(params));
1292 cx2070x_real_write(codec,PORT1_TX_CLOCKS_PER_FRAME_PHASE,i2s?0x07:0x01);
1293 cx2070x_real_write(codec,PORT1_RX_CLOCKS_PER_FRAME_PHASE,i2s?0x07:0x01);
1294 cx2070x_real_write(codec,PORT1_TX_SYNC_WIDTH, i2s?0x0f:0x07);
1295 cx2070x_real_write(codec,PORT1_RX_SYNC_WIDTH, i2s?0x0f:0x07);
1296 cx2070x_real_write(codec,PORT1_CONTROL_2, i2s?0x05:0x00);
1297 /*params for port2 by showy.zhang*/
1298 cx2070x_real_write(codec,STREAM5_RATE,s5);
1299 cx2070x_real_write(codec,STREAM3_RATE,s3);// cause by incorrect parameter
1301 cx2070x_real_read(codec,DSP_INIT);
1302 dsp=cx2070x_read_reg_cache(codec,DSP_INIT);
1303 printk(">>>>>>>>>>>> dsp = %0x", dsp);
1304 if ((err=cx2070x_dsp_init(codec,dsp|DSP_INIT_NEWC))<0)
1310 static int cx2070x_mute(struct snd_soc_dai *dai, int mute)
1312 struct snd_soc_codec *codec = dai->codec;
1314 ERROR("%lu: %s(%d) called\n",jiffies,__func__,mute);
1316 cx2070x_real_write(codec,VOLUME_MUTE,mute?VOLUME_MUTE_ALL:b_00000000);
1320 // cx2070x_real_write(codec,DSP_POWER,0xe0); // deep sleep mode
1321 // cx2070x_dsp_init(codec,DSP_INIT_STREAM_OFF);
1323 cx2070x_real_read(codec,DSP_INIT);
1324 cx2070x_write(codec,DSP_INIT,(cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC) & ~(1 << 3));
1328 /*unmute I2S output*/
1329 cx2070x_real_read(codec,DSP_INIT);
1330 cx2070x_write(codec,DSP_INIT,cx2070x_read_reg_cache(codec,DSP_INIT)| DSP_INIT_NEWC | DSP_INIT_STREAM_3);
1331 //cx2070x_dsp_init(codec,DSP_INIT_NEWC | 0xff);
1337 static int cx2070x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir)
1339 struct snd_soc_codec *codec = dai->codec;
1340 struct cx2070x_priv *channel = get_cx2070x_priv(codec);
1342 INFO("%lu: %s() called\n",jiffies,__func__);
1344 // sysclk is not used where, but store it anyway
1345 channel->sysclk = freq;
1349 static int cx2070x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1351 struct snd_soc_codec *codec = dai->codec;
1352 struct cx2070x_priv *channel = get_cx2070x_priv(codec);
1354 INFO("%lu: %s() called\n",jiffies,__func__);
1356 // set master/slave audio interface
1357 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK)
1359 case SND_SOC_DAIFMT_CBS_CFS: // This design only supports slave mode
1360 channel->master = 0;
1363 printk(KERN_ERR "unsupport DAI format, driver only supports slave mode\n");
1367 switch (fmt & SND_SOC_DAIFMT_INV_MASK)
1369 case SND_SOC_DAIFMT_NB_NF: // This design only supports normal bclk + frm
1372 printk(KERN_ERR "unsupport DAI format, driver only supports normal bclk+ frm\n");
1377 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK)
1379 case SND_SOC_DAIFMT_I2S: // This design only supports I2S
1382 printk( KERN_ERR "unspoort DAI format, driver only supports I2S interface.\n");
1389 struct snd_soc_dai_ops cx2070x_dai_ops =
1391 .set_sysclk=cx2070x_set_dai_sysclk,
1392 .set_fmt = cx2070x_set_dai_fmt,
1393 .digital_mute=cx2070x_mute,
1394 .hw_params = cx2070x_hw_params,
1397 struct snd_soc_dai_driver soc_codec_cx2070x_dai =
1399 .name = "cx2070x-hifi",
1400 .ops = &cx2070x_dai_ops,
1402 .stream_name="Capture",
1403 .formats = CX2070X_FORMATS,
1404 .rates = CX2070X_RATES,
1409 .stream_name="Playback",
1410 .formats = CX2070X_FORMATS,
1411 .rates = CX2070X_RATES,
1415 .symmetric_rates = 1,
1417 EXPORT_SYMBOL_GPL(soc_codec_cx2070x_dai);
1419 static int cx2070x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level)
1421 INFO("%lu: %s(,%d) called\n",jiffies,__func__,level);
1426 case SND_SOC_BIAS_ON:
1427 cx2070x_real_write(codec,DSP_POWER,0x20);
1428 // all power is driven by DAPM system
1432 case SND_SOC_BIAS_PREPARE:
1436 case SND_SOC_BIAS_STANDBY:
1437 //cx2070x_real_write(codec,VOLUME_MUTE,VOLUME_MUTE_ALL); // mute all
1438 //cx2070x_real_write(codec,DSP_POWER,0xe0); // deep sleep mode
1439 //cx2070x_dsp_init(codec,DSP_INIT_STREAM_OFF);
1441 // TODO: power down channel
1444 // Off, without power
1445 case SND_SOC_BIAS_OFF:
1446 cx2070x_real_write(codec,VOLUME_MUTE,VOLUME_MUTE_ALL); // mute all
1447 cx2070x_real_write(codec,DSP_POWER,0xe0); // deep sleep mode
1448 cx2070x_dsp_init(codec,DSP_INIT_STREAM_OFF);
1449 // TODO: put channel into deep-sleep
1456 int I2cWrite( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf, unsigned char* pBuf)
1459 struct spi_device * spi = (struct spi_device *) codec->control_data;
1460 pBuf[0] |= 0x80; //SPI_WRITE
1461 spi_write(spi,pBuf,cbBuf);
1463 #else //#ifdef ENABLE_SPI
1464 struct i2c_client *client = (struct i2c_client *)codec->control_data;
1465 struct i2c_adapter *adap = client->adapter;
1466 struct i2c_msg msg[1];
1469 msg[0].addr = client->addr;
1470 msg[0].flags = client->flags & I2C_M_TEN;
1473 if (i2c_transfer(adap,msg,1)!=1)
1475 printk(KERN_ERR "cx2070x: I2cWriteThenRead failed.\n");
1483 #endif //#!ENABLE_SPI
1486 int I2cWriteThenRead( struct snd_soc_codec *codec, unsigned char ChipAddr, unsigned long cbBuf,
1487 unsigned char* pBuf, unsigned long cbReadBuf, unsigned char*pReadBuf)
1492 struct spi_device * spi = (struct spi_device *) codec->control_data;
1496 spi_write_then_read(spi, reg, 3, pReadBuf,cbReadBuf);
1498 #else //#ifdef USING_SPI
1499 struct i2c_client *client = (struct i2c_client *)codec->control_data;
1500 struct i2c_adapter *adap = client->adapter;
1501 struct i2c_msg msg[2];
1503 msg[0].addr = client->addr;
1504 msg[0].flags = client->flags & I2C_M_TEN;
1508 msg[1].addr = client->addr;
1509 msg[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
1510 msg[1].len = cbReadBuf;
1511 msg[1].buf = pReadBuf;
1513 if (i2c_transfer(adap,msg,2)!=2)
1515 printk(KERN_ERR "cx2070x: I2cWriteThenRead failed.\n");
1522 #endif //#!ENABLE_SPI
1526 #if defined(CONFIG_SND_CX2070X_LOAD_FW)
1527 static int cx2070x_apply_firmware_patch(struct snd_soc_codec *codec)
1530 const struct firmware *fw = NULL;
1531 const unsigned char *dsp_code = NULL;
1532 struct device *dev = codec->dev;
1534 #if defined(CONFIG_SND_CX2070X_USE_FW_H)
1535 // load firmware from c head file.
1536 dsp_code = ChannelFW;
1538 // load firmware from file.
1539 ret = request_firmware(&fw, CX2070X_FIRMWARE_FILENAME, dev);
1541 printk( KERN_ERR "%s(): Firmware %s not available %d",
1542 __func__, CX2070X_FIRMWARE_FILENAME, ret);
1545 dsp_code = fw->data;
1548 ret = ApplyDSPChanges(dsp_code);
1550 printk(KERN_ERR "cx2070x: patch firmware failed, Error %d\n", ret);
1552 printk(KERN_INFO "cx2070x: patch firmware successfully.\n");
1558 static int cx2070x_download_firmware(struct snd_soc_codec *codec)
1562 const struct firmware *fw = NULL;
1563 const unsigned char *dsp_code = NULL;
1564 #if !defined(CONFIG_SND_CX2070X_USE_FW_H)
1565 struct device *dev = codec->dev;
1568 // load firmware to memory.
1569 #if defined(CONFIG_SND_CX2070X_USE_FW_H)
1570 // load firmware from c head file.
1571 dsp_code = ChannelFW;
1573 // load firmware from file.
1574 ret = request_firmware(&fw, CX2070X_FIRMWARE_FILENAME,dev);
1577 printk( KERN_ERR "%s(): Firmware %s not available %d",__func__,CX2070X_FIRMWARE_FILENAME,ret);
1580 dsp_code = fw->data;
1581 #endif // #if defined(CONFIG_SND_CX2070X_USE_FW_H)
1583 // Load rom data from a array.
1585 buf = (char*)kzalloc(0x200,GFP_KERNEL);
1588 printk(KERN_ERR "cx2070x: out of memory .\n");
1594 // Setup the i2c callback function.
1596 SetupI2cWriteCallback( (void *) codec, (fun_I2cWrite) I2cWrite,32);
1597 SetupI2cWriteThenReadCallback( (void *) codec, (fun_I2cWriteThenRead) I2cWriteThenRead);
1600 SetupMemoryBuffer(buf);
1602 ret = DownloadFW(dsp_code);
1605 printk(KERN_ERR "cx2070x: download firmware failed, Error %d\n",ret);
1609 printk(KERN_INFO "cx2070x: download firmware successfully.\n");
1617 #if defined(CONFIG_SND_CX2070X_LOAD_FW) && !defined(CONFIG_SND_CX2070X_USE_FW_H)
1620 release_firmware(fw);
1628 unsigned int cx2070x_hw_read( struct snd_soc_codec *codec, unsigned int regaddr)
1631 unsigned char chipaddr = 0;
1632 unsigned char reg[2];
1634 struct i2c_client *client = (struct i2c_client *) codec->control_data;
1635 chipaddr = client->addr;
1637 reg[0] = regaddr>>8;
1638 reg[1] = regaddr&0xff;
1639 I2cWriteThenRead(codec,chipaddr, 2, reg, 1,&data);
1640 return (unsigned int)data;
1643 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
1646 // Initialise the cx2070x driver
1647 // Register the mixer and dsp interfaces with the kernel
1649 static int NOINLINE cx2070x_init(struct snd_soc_codec* codec)
1651 struct cx2070x_priv *cx2070x = get_cx2070x_priv(codec);
1652 int n,vl,vh,vm,fh, fl,ret = 0;
1653 cx2070x_reg_t *reg_cache;
1655 printk(">>>>>>>%s",__func__);
1656 INFO("%lu: %s() called\n",jiffies,__func__);
1658 codec->control_data = cx2070x->control_data;
1661 #if defined(CONFIG_SND_CX2070X_GPIO_RESET)
1662 cx2070x_reset_device();
1665 #if CX2070X_TRISTATE_EEPROM
1666 // If CX2070X has to float the pins to the NVRAM, enable this code
1670 pad=cx2070x_real_read(codec,PAD);
1671 pbd=cx2070x_real_read(codec,PBD);
1672 printk("%s(): PAD/PBD=%02x/%02x\n",__func__,pad,pbd);
1674 _cx2070x_real_write(codec,PAD,pad&~(1<<4));
1675 _cx2070x_real_write(codec,PBD,pbd&~(1<<6));
1681 #if defined(CONFIG_SND_CX2070X_LOAD_FW)
1682 ret = cx2070x_download_firmware(codec);
1685 printk(KERN_ERR "%s: failed to download firmware\n",__func__);
1690 // Verify that Channel/Balboa is ready.
1691 // May have to wait for ~5sec becore Channel/Balboa comes out of reset
1694 int abcode=cx2070x_real_read(codec,ABORT_CODE);
1695 // int abcode=cx2070x_real_read(codec,CHIP_VERSION);
1696 printk(">>>>>>>>>>>>>>>%s abcode = %d",__func__, abcode);
1698 break; // initialization done!
1701 printk(KERN_ERR "Timeout waiting for cx2070x to come out of reset!\n");
1707 cx2070x_real_read(codec,FIRMWARE_VERSION);
1708 cx2070x_real_read(codec,PATCH_VERSION);
1709 cx2070x_real_read(codec,CHIP_VERSION);
1710 cx2070x_real_read(codec,RELEASE_TYPE);
1712 reg_cache = GET_REG_CACHE(codec);
1713 fl=(reg_cache[FIRMWARE_VERSION]>>0)&0xFF;
1714 fl=(fl>>4)*10+(fl&0xf);
1715 fh=(reg_cache[FIRMWARE_VERSION]>>8)&0xFF;
1717 // determine whether the codec is ROM version or not.
1720 //shows the firmware patch version.
1721 cx2070x_real_read(codec,ROM_PATCH_VER_HB);
1722 cx2070x_real_read(codec,ROM_PATCH_VER_MB);
1723 cx2070x_real_read(codec,ROM_PATCH_VER_LB);
1724 vh = reg_cache[ROM_PATCH_VER_HB];
1725 vm = reg_cache[ROM_PATCH_VER_MB];
1726 vl = reg_cache[ROM_PATCH_VER_LB];
1727 printk("cx2070x: firmware version %u.%u, patch %u.%u.%u, chip CX2070%u (ROM)\n",fh,fl,vh,vm,vl,reg_cache[CHIP_VERSION]);
1732 printk("cx2070x: firmware version %u.%u, chip CX2070%u (RAM), ",fh,fl,reg_cache[CHIP_VERSION]);
1733 // shows the firmware release type.
1734 switch(reg_cache[RELEASE_TYPE])
1736 case 12: printk("Custom Release\n"); break;
1737 case 14: printk("Engineering Release\n"); break;
1738 case 15: printk("Field Release\n"); break;
1739 default: printk("Release %u?\n",reg_cache[RELEASE_TYPE]); break;
1744 printk("cx2070x: Unsupported firmware version %u.%u!!!\n",fh,fl);
1750 if (reg_cache[PATCH_VERSION])
1752 vl=(reg_cache[PATCH_VERSION]>>0)&0xFF;
1753 vh=(reg_cache[PATCH_VERSION]>>8)&0xFF;
1754 printk("%s(): CX2070X patch version %u.%u\n",__func__,vh,vl);
1757 // Initialize the CX2070X regisers and/or read them as needed.
1758 for(n=0;n<noof(cx2070x_regs);n++)
1759 switch(cx2070x_regs[n].type®_TYPE_MASK)
1763 cx2070x_real_read(codec,n);
1767 cx2070x_real_write(codec,n,cx2070x_data[n]);
1769 #if defined(REG_TYPE_DM)
1777 #if defined(CONFIG_SND_CX2070X_LOAD_FW)
1778 cx2070x_apply_firmware_patch(codec);
1781 //cx2070x_add_controls(codec);
1782 //cx2070x_add_widgets(codec);
1783 snd_soc_add_codec_controls(codec, cx2070x_snd_path_controls,
1784 ARRAY_SIZE(cx2070x_snd_path_controls));
1786 //snd_soc_dapm_nc_pin(&codec->dapm, "LINE IN");
1787 //snd_soc_dapm_nc_pin( &codec->dapm, "LINE OUT");
1788 //snd_soc_dapm_enable_pin( &codec->dapm, "INT MIC");
1789 //snd_soc_dapm_enable_pin( &codec->dapm, "INT SPK");
1790 //snd_soc_dapm_disable_pin( &codec->dapm, "BT IN");
1791 //snd_soc_dapm_enable_pin( &codec->dapm, "Headphone");
1792 //snd_soc_dapm_disable_pin( &codec->dapm, "BT OUT");
1795 #if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE)
1796 /* Headset jack detection */
1797 ret = snd_soc_jack_new(codec, "Headset Jack",
1798 SND_JACK_HEADSET, &hs_jack);
1801 printk(KERN_ERR "CX2070X: failed to register Headset Jack\n");
1805 ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
1809 printk(KERN_ERR "CX2070X: failed to add jack gpios.\n");
1813 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
1817 printk(KERN_ERR "CX2070X: failed to add soc jack pin\n");
1821 snd_soc_dapm_sync( &codec->dapm);
1822 #endif //#if defined(CONFIG_SND_CX2070X_GPIO_JACKSENSE)
1824 #if defined(CONFIG_SND_CXLIFEGUARD)
1825 cxdbg_dev_init(codec);
1828 cx2070x_real_write(codec, USB_LOCAL_VOLUME, 0x42);
1832 printk(KERN_INFO "CX2070X: codec is ready.\n");
1840 static int cx2070x_hw_reset(void)
1844 err = gpio_request(CODEC_RESET_GPIO_PIN, "nCX2070X_Reset");
1845 printk(KERN_ERR "channel reset gpio=%d\n", CODEC_RESET_GPIO_PIN);
1847 printk(KERN_ERR "#### failed to request GPH3_2 for Audio Reset\n");
1849 gpio_direction_output(CODEC_RESET_GPIO_PIN, 0);
1851 gpio_direction_output(CODEC_RESET_GPIO_PIN, 1);
1852 gpio_free(CODEC_RESET_GPIO_PIN);
1858 #ifdef CONFIG_DEBUG_FS
1859 #include <linux/debugfs.h>
1860 #include <linux/seq_file.h>
1861 static struct snd_soc_codec *g_cx2070x_codec;
1863 static int cx2070x_dbg_show_regs(struct seq_file *s, void *unused)
1866 int reg_no = (int)s->private;
1868 int source_switch = 0;
1869 if(reg_no == 0x4321) {
1870 cx2070x_real_read(g_cx2070x_codec, DSP_INIT);
1871 source_switch = cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT) & DSP_ENABLE_STREAM_3_4;
1872 printk(">>>>>>>>>>>>source_switch = %0x",source_switch);
1873 switch (source_switch) {
1875 seq_printf(s, "NO_INPUT\t");
1877 case DSP_ENABLE_STREAM_3:
1878 seq_printf(s, "I2S_ONLY\t");
1880 case DSP_ENABLE_STREAM_4:
1881 seq_printf(s, "USB_ONLY\t");
1883 case DSP_ENABLE_STREAM_3_4:
1884 seq_printf(s, "I2S_USB_MIXING\t");
1887 seq_printf(s, "UNKNOWN\t");
1892 if (reg_no == noof(cx2070x_regs)) {
1893 seq_printf(s, "Offset\tType\tValue\tName\n");
1894 for (i = 0; i < reg_no; i++) {
1895 seq_printf(s, "0x%02X\t", cx2070x_regs[i].addr);
1896 switch (cx2070x_regs[i].type) {
1901 seq_printf(s, "RW");
1904 seq_printf(s, "WC");
1907 seq_printf(s, "WI");
1910 seq_printf(s, "UNKNOWN\t");
1912 seq_printf(s, "\t0x%02X\t%s\n", cx2070x_read_reg_cache(g_cx2070x_codec, i),
1913 cx2070x_regs[i].name);
1918 seq_printf(s, "Offset:\t0x%02X\n", cx2070x_regs[reg_no].addr);
1920 seq_printf(s, "Type:\t");
1921 switch (cx2070x_regs[reg_no].type) {
1926 seq_printf(s, "RW");
1929 seq_printf(s, "WC");
1932 seq_printf(s, "WI");
1935 seq_printf(s, "UNKNOWN");
1937 seq_printf(s, "\n");
1939 seq_printf(s, "Value:\t0x%02X\n", cx2070x_read_reg_cache(g_cx2070x_codec, reg_no));
1944 static int cx2070x_dbg_reg_open(struct inode *inode, struct file *file)
1946 return single_open(file, cx2070x_dbg_show_regs, inode->i_private);
1949 static ssize_t cx2070x_dbg_reg_write(struct file *file,
1950 const char __user *ubuf,
1951 size_t count, loff_t *off)
1953 struct seq_file *seq = file->private_data;
1956 int reg_no = (int)seq->private;
1959 if (count >= sizeof(buf)) {
1960 ERROR("%s, The buffer is not enough.\n", __func__);
1962 } if (copy_from_user(buf, ubuf, count)) {
1963 ERROR("%s, Faied to copy data from user space.\n", __func__);
1969 ret = strict_strtoul(buf, 16, &val);
1971 ERROR("%s, Failed to convert a string to an unsinged long integer.\n", __func__);
1975 if(reg_no == 0x4321) {
1976 printk(">>>>>>>>>>>>>>>>>>>>>>val = %d",val);
1977 cx2070x_real_read(g_cx2070x_codec, DSP_INIT);
1980 cx2070x_write(g_cx2070x_codec,DSP_INIT,(cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)|
1981 DSP_INIT_NEWC) & ~DSP_ENABLE_STREAM_3_4);
1984 cx2070x_write(g_cx2070x_codec,DSP_INIT,(cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)|
1985 DSP_INIT_NEWC | DSP_ENABLE_STREAM_3) & ~DSP_ENABLE_STREAM_4);
1988 cx2070x_write(g_cx2070x_codec,DSP_INIT,(cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)|
1989 DSP_INIT_NEWC | DSP_ENABLE_STREAM_4) & ~DSP_ENABLE_STREAM_3);
1991 case I2S_USB_MIXING:
1992 cx2070x_write(g_cx2070x_codec,DSP_INIT,cx2070x_read_reg_cache(g_cx2070x_codec,DSP_INIT)|
1993 DSP_INIT_NEWC | DSP_ENABLE_STREAM_3_4);
2000 switch (cx2070x_regs[reg_no].type) {
2002 ERROR("%s, A read-only register 0x%02x cannot be written.\n",
2003 __func__, cx2070x_regs[reg_no].addr);
2008 ret = cx2070x_write(g_cx2070x_codec, reg_no, (u8)val);
2010 ERROR("%s, Failed to write register 0x%02x.\n", __func__,
2011 cx2070x_regs[reg_no].addr);
2016 ERROR("%s, Unknown type register\n", __func__);
2023 static const struct file_operations cx2070x_debug_reg_fops = {
2024 .open = cx2070x_dbg_reg_open,
2026 .write = cx2070x_dbg_reg_write,
2027 .llseek = seq_lseek,
2028 .release = single_release,
2032 static int cx2070x_probe(struct snd_soc_codec *codec)
2034 #ifdef CONFIG_DEBUG_FS
2035 struct dentry *d, *regs;
2040 INFO("%lu: %s() called\n",jiffies,__func__);
2041 printk(KERN_INFO "cx2070x codec driver version: %02x,%02x,%02x,%02x\n",(u8)((CX2070X_DRIVER_VERSION)>>24),
2042 (u8)((CX2070X_DRIVER_VERSION)>>16),
2043 (u8)((CX2070X_DRIVER_VERSION)>>8),
2044 (u8)((CX2070X_DRIVER_VERSION)));
2046 #ifdef CONFIG_DEBUG_FS
2047 g_cx2070x_codec = codec;
2048 d = debugfs_create_dir("cx2070x", NULL);
2052 debugfs_create_file("SOURCE_SWITCH", 0644, d, (void *)m,
2053 &cx2070x_debug_reg_fops);
2055 regs = debugfs_create_dir("regs", d);
2057 return PTR_ERR(regs);
2059 for (n = 0; n < noof(cx2070x_regs); n++)
2060 debugfs_create_file(cx2070x_regs[n].name, 0644, regs, (void *)n,
2061 &cx2070x_debug_reg_fops);
2063 debugfs_create_file("ALL", 0644, regs, (void *)n,
2064 &cx2070x_debug_reg_fops);
2067 return cx2070x_init(codec);
2070 static int cx2070x_remove(struct snd_soc_codec *codec)
2072 INFO("%lu: %s() called\n",jiffies,__func__);
2074 cx2070x_set_bias_level(codec, SND_SOC_BIAS_OFF);
2076 #if defined (CONFIG_SND_CX2070X_GPIO_JACKSENSE)
2077 snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
2079 #endif//#if defined (CONFIG_SND_CX2070X_GPIO_JACKSENSE)
2083 static int cx2070x_suspend(struct snd_soc_codec *codec)
2085 INFO("%lu: %s() called\n",jiffies,__func__);
2086 cx2070x_set_bias_level(codec, SND_SOC_BIAS_OFF);
2090 static int cx2070x_resume(struct snd_soc_codec *codec)
2093 INFO("%lu: %s() called\n",jiffies,__func__);
2095 // Sync reg_cache with the hardware
2096 for(n=0;n<noof(cx2070x_regs);n++)
2097 switch(cx2070x_regs[n].type®_TYPE_MASK)
2104 cx2070x_real_write(codec,n,cx2070x_read_reg_cache(codec,n));
2106 #if defined(REG_TYPE_DM)
2113 cx2070x_dsp_init(codec,cx2070x_read_reg_cache(codec,DSP_INIT)|DSP_INIT_NEWC);
2114 cx2070x_set_bias_level(codec, SND_SOC_BIAS_ON);
2118 static inline unsigned int cx2070x_read(struct snd_soc_codec *codec,
2124 struct snd_soc_codec_driver soc_codec_dev_cx2070x=
2126 .probe =cx2070x_probe,
2127 .remove = cx2070x_remove,
2128 .suspend = cx2070x_suspend,
2129 .resume = cx2070x_resume,
2130 .read = cx2070x_read,
2131 .write = cx2070x_write,
2132 .reg_cache_size = sizeof(cx2070x_data),
2133 .reg_cache_step = 1,
2134 .reg_word_size = sizeof(u8),
2135 .reg_cache_default = cx2070x_data,
2136 .set_bias_level = cx2070x_set_bias_level,
2140 #if defined(USING_I2C)
2141 static int cx2070x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
2143 struct cx2070x_priv *cx2070x;
2146 INFO("%lu: %s() called\n", jiffies, __func__);
2148 cx2070x = (struct cx2070x_priv*)kzalloc(sizeof(struct cx2070x_priv), GFP_KERNEL);
2149 if (cx2070x == NULL)
2154 i2c_set_clientdata(i2c, cx2070x);
2156 cx2070x->control_data = (void*)i2c;
2157 cx2070x->control_type = SND_SOC_I2C;
2159 cx2070x->input_sel = Cx_INPUT_SEL_BY_GPIO;
2160 cx2070x->output_sel = Cx_OUTPUT_SEL_BY_GPIO;
2162 ret = snd_soc_register_codec(&i2c->dev,
2163 &soc_codec_dev_cx2070x, &soc_codec_cx2070x_dai, 1);
2164 printk(">>>>>>>%s ret = %d ",__func__,ret);
2167 INFO("%s() failed ret = %d\n", __func__, ret);
2171 static int cx2070x_i2c_remove(struct i2c_client *client)
2173 snd_soc_unregister_codec(&client->dev);
2174 #if defined(CONFIG_SND_CXLIFEGUARD)
2177 kfree(i2c_get_clientdata(client));
2181 static const struct i2c_device_id cx2070x_i2c_id[] =
2187 MODULE_DEVICE_TABLE(i2c, cx2070x_i2c_id);
2189 static struct i2c_driver cx2070x_i2c_driver = {
2192 .owner = THIS_MODULE,
2194 .probe=cx2070x_i2c_probe,
2195 .remove=__devexit_p(cx2070x_i2c_remove),
2196 .id_table=cx2070x_i2c_id,
2199 #elif defined(USING_SPI)
2200 static int cx2070x_spi_probe(struct spi_device *spi)
2202 INFO("%lu: %s() called\n", jiffies, __func__);
2204 struct cx2070x_priv *cx2070x;
2207 //printk(KERN_INFO "Channel Audio Codec %08x\n", CX2070X_DRIVER_VERSION);
2209 cx2070x = (struct cx2070x_priv *)kzalloc(sizeof(struct cx2070x_priv), GFP_KERNEL);
2210 if (cx2070x == NULL)
2215 spi_set_drvdata(spi, cx2070x);
2217 cx2070x->control_data = (void*)spi;
2218 cx2070x->control_type = SND_SOC_SPI;
2220 cx2070x->input_sel = Cx_INPUT_SEL_BY_GPIO;
2221 cx2070x->output_sel = Cx_OUTPUT_SEL_BY_GPIO;
2223 ret = snd_soc_register_codec(&spi->dev,
2224 &soc_codec_dev_cx2070x, &soc_codec_cx2070x_dai, 1);
2227 INFO("%s() failed ret = %d\n", __func__, ret);
2231 static int cx2070x_spi_remove(struct spi_device *client)
2233 struct snd_soc_codec *codec = (struct snd_soc_codec *)spi_get_drvdata(client);
2235 kfree(codec->reg_cache);
2239 static const struct spi_device_id cx2070x_spi_id[]={
2240 { CX2070X_SPI_DRIVER_NAME,NULL},
2243 static struct spi_driver cx2070x_spi_driver = {
2245 .name = "cx2070x-codec",
2246 .owner = THIS_MODULE,
2248 .probe = cx2070x_spi_probe,
2249 .remove = __devexit_p(cx2070x_spi_remove),
2253 static int __init cx2070x_modinit(void)
2256 INFO("%lu: %s() called\n",jiffies,__func__);
2257 #if defined(USING_I2C)
2258 ret = i2c_add_driver(&cx2070x_i2c_driver);
2260 printk(KERN_ERR "Failed to register CX2070X I2C driver: %d\n",
2263 #elif defined(USING_SPI)
2264 ret = spi_register_driver(&cx2070x_spi_driver);
2266 printk(KERN_ERR "Failed to register CX2070X SPI driver: %d\n",
2272 module_init(cx2070x_modinit);
2274 static void __exit cx2070x_exit(void)
2276 INFO("%lu: %s() called\n",jiffies,__func__);
2277 #if defined(USING_I2C)
2278 i2c_del_driver(&cx2070x_i2c_driver);
2279 #elif defined(USING_SPI)
2280 spi_unregister_driver(&cx2070x_spi_driver);
2283 module_exit(cx2070x_exit);
2285 int CX_AUDDRV_VERSION = CX2070X_DRIVER_VERSION;
2286 EXPORT_SYMBOL_GPL(CX_AUDDRV_VERSION);
2287 EXPORT_SYMBOL_GPL(soc_codec_dev_cx2070x);
2288 MODULE_DESCRIPTION("ASoC cx2070x Codec Driver");
2289 MODULE_LICENSE("GPL");