mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
add wm8988 driver for kernel3.0
This commit is contained in:
@@ -1418,7 +1418,7 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_alc5631)
|
||||
#if defined (CONFIG_SND_SOC_RT5631)
|
||||
{
|
||||
.type = "rt5631",
|
||||
.addr = 0x1a,
|
||||
@@ -1432,6 +1432,13 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_WM8988)
|
||||
{
|
||||
.type = "wm8988",
|
||||
.addr = 0x1A,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_WM8900)
|
||||
{
|
||||
.type = "wm8900",
|
||||
|
||||
@@ -25,10 +25,23 @@
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <sound/initval.h>
|
||||
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#include "wm8988.h"
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* wm8988 register cache
|
||||
* We can't read the WM8988 register space when we
|
||||
@@ -53,6 +66,8 @@ struct wm8988_priv {
|
||||
unsigned int sysclk;
|
||||
enum snd_soc_control_type control_type;
|
||||
struct snd_pcm_hw_constraint_list *sysclk_constraints;
|
||||
int is_startup; // gModify.Add
|
||||
int is_biason;
|
||||
};
|
||||
|
||||
|
||||
@@ -190,6 +205,8 @@ static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
|
||||
else
|
||||
adctl2 |= 0x4;
|
||||
|
||||
DBG("Enter::%s----%d, adctl2 = %x\n",__FUNCTION__,__LINE__,adctl2);
|
||||
|
||||
return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
|
||||
}
|
||||
|
||||
@@ -290,8 +307,9 @@ static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0),
|
||||
SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0),
|
||||
|
||||
SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),
|
||||
SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),
|
||||
/* gModify.Cmmt Implement when suspend/startup */
|
||||
/*SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),*/
|
||||
/*SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),*/
|
||||
|
||||
SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&wm8988_left_mixer_controls[0],
|
||||
@@ -477,7 +495,7 @@ static struct snd_pcm_hw_constraint_list constraints_112896 = {
|
||||
};
|
||||
|
||||
static unsigned int rates_12[] = {
|
||||
8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
|
||||
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
|
||||
48000, 88235, 96000,
|
||||
};
|
||||
|
||||
@@ -495,6 +513,8 @@ static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
switch (freq) {
|
||||
case 11289600:
|
||||
case 18432000:
|
||||
@@ -575,6 +595,8 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DBG("Enter::%s----%d iface=%x\n",__FUNCTION__,__LINE__,iface);
|
||||
|
||||
snd_soc_write(codec, WM8988_IFACE, iface);
|
||||
return 0;
|
||||
}
|
||||
@@ -585,6 +607,17 @@ static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (!wm8988->is_startup) {
|
||||
wm8988->is_startup = 1;
|
||||
snd_soc_write(codec, WM8988_PWR1, 0xfc);
|
||||
gpio_direction_output(RK29_PIN6_PB5, GPIO_LOW);
|
||||
mdelay(100); // Discharge C310
|
||||
snd_soc_write(codec, WM8988_PWR2, 0x1e0);
|
||||
gpio_direction_output(RK29_PIN6_PB5, GPIO_HIGH);
|
||||
}
|
||||
|
||||
DBG("Enter::%s----%d wm8988->sysclk=%d\n",__FUNCTION__,__LINE__,wm8988->sysclk);
|
||||
|
||||
/* The set of sample rates that can be supported depends on the
|
||||
* MCLK supplied to the CODEC - enforce this.
|
||||
*/
|
||||
@@ -639,6 +672,8 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
break;
|
||||
}
|
||||
|
||||
DBG("Enter::%s----%d iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));
|
||||
|
||||
/* set iface & srate */
|
||||
snd_soc_write(codec, WM8988_IFACE, iface);
|
||||
if (coeff >= 0)
|
||||
@@ -653,6 +688,8 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7;
|
||||
|
||||
DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
|
||||
|
||||
if (mute)
|
||||
snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
|
||||
else
|
||||
@@ -663,13 +700,22 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
|
||||
static int wm8988_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
|
||||
u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
|
||||
|
||||
DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level);
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
wm8988->is_biason = 1;
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
if (wm8988->is_startup && wm8988->is_biason) {
|
||||
snd_soc_write(codec, WM8988_PWR2, 0x0);
|
||||
wm8988->is_startup = 0;
|
||||
wm8988->is_biason = 0;
|
||||
}
|
||||
/* VREF, VMID=2x50k, digital enabled */
|
||||
snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
|
||||
break;
|
||||
@@ -709,7 +755,7 @@ static struct snd_soc_dai_ops wm8988_ops = {
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver wm8988_dai = {
|
||||
.name = "wm8988-hifi",
|
||||
.name = "WM8988 HiFi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
@@ -730,6 +776,8 @@ static struct snd_soc_dai_driver wm8988_dai = {
|
||||
|
||||
static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
|
||||
{
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
@@ -740,6 +788,8 @@ static int wm8988_resume(struct snd_soc_codec *codec)
|
||||
u8 data[2];
|
||||
u16 *cache = codec->reg_cache;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
/* Sync reg_cache with the hardware */
|
||||
for (i = 0; i < WM8988_NUM_REG; i++) {
|
||||
if (i == WM8988_RESET)
|
||||
@@ -748,12 +798,30 @@ static int wm8988_resume(struct snd_soc_codec *codec)
|
||||
data[1] = cache[i] & 0x00ff;
|
||||
codec->hw_write(codec->control_data, data, 2);
|
||||
}
|
||||
|
||||
//snd_soc_write(codec, WM8988_PWR1, 0xfc);
|
||||
//snd_soc_write(codec, WM8988_PWR2, 0x1e0);
|
||||
|
||||
wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec *wm8988_codec;
|
||||
|
||||
static int entry_read(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len;
|
||||
|
||||
snd_soc_write(wm8988_codec, WM8988_PWR1, 0x0000);
|
||||
snd_soc_write(wm8988_codec, WM8988_PWR2, 0x0000);
|
||||
|
||||
len = sprintf(page, "wm8988 suspend...\n");
|
||||
|
||||
return len ;
|
||||
}
|
||||
|
||||
static int wm8988_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
|
||||
@@ -761,6 +829,13 @@ static int wm8988_probe(struct snd_soc_codec *codec)
|
||||
int ret = 0;
|
||||
u16 reg;
|
||||
|
||||
if (codec == NULL) {
|
||||
dev_err(codec->dev, "Codec device not registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
wm8988_codec = codec;
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
|
||||
@@ -773,6 +848,14 @@ static int wm8988_probe(struct snd_soc_codec *codec)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*disable speaker */
|
||||
gpio_request(RK2818_PIN_PF7, "WM8988");
|
||||
rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7);
|
||||
gpio_direction_output(RK2818_PIN_PF7,GPIO_HIGH);
|
||||
|
||||
#endif
|
||||
|
||||
/* set the update bits (we always update left then right) */
|
||||
reg = snd_soc_read(codec, WM8988_RADC);
|
||||
snd_soc_write(codec, WM8988_RADC, reg | 0x100);
|
||||
@@ -783,7 +866,40 @@ static int wm8988_probe(struct snd_soc_codec *codec)
|
||||
reg = snd_soc_read(codec, WM8988_ROUT2V);
|
||||
snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100);
|
||||
reg = snd_soc_read(codec, WM8988_RINVOL);
|
||||
snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
|
||||
snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
|
||||
|
||||
snd_soc_write(codec, WM8988_LOUTM1, 0x120);
|
||||
snd_soc_write(codec, WM8988_ROUTM2, 0x120);
|
||||
snd_soc_write(codec, WM8988_LOUTM2, 0x0070);
|
||||
snd_soc_write(codec, WM8988_ROUTM1, 0x0070);
|
||||
//tcl miaozh modify
|
||||
// snd_soc_write(codec, WM8988_LOUT1V, 0x017f);
|
||||
// snd_soc_write(codec, WM8988_ROUT1V, 0x017f);
|
||||
snd_soc_write(codec, WM8988_LOUT1V, 0x017a);
|
||||
snd_soc_write(codec, WM8988_ROUT1V, 0x017a);
|
||||
|
||||
snd_soc_write(codec, WM8988_LDAC, 0xfa/*0xff*/); // Change max by zhansb@110415
|
||||
snd_soc_write(codec, WM8988_RDAC, 0x1fa/*0x1ff*/);//vol set
|
||||
|
||||
//TCL lgw add 20110412
|
||||
snd_soc_write(codec, WM8988_LINVOL, 0x0117);
|
||||
snd_soc_write(codec, WM8988_RINVOL, 0x0117);
|
||||
|
||||
snd_soc_write(codec, WM8988_ADCTL2, 0x0184);
|
||||
|
||||
snd_soc_write(codec, WM8988_LADC, 0x01ec);
|
||||
snd_soc_write(codec, WM8988_RADC, 0x01ec);
|
||||
|
||||
snd_soc_write(codec, WM8988_ADCIN, 0x0140);
|
||||
snd_soc_write(codec, WM8988_LADCIN, 0x00f0);//0x00e0
|
||||
snd_soc_write(codec, WM8988_RADCIN, 0x0);//0x00e0
|
||||
//lgw end
|
||||
|
||||
snd_soc_write(codec, WM8988_SRATE,0x100); ///SET MCLK/8
|
||||
//snd_soc_write(codec, WM8988_PWR1, 0x1cc); ///(0x80|0x40|0x20|0x08|0x04|0x10|0x02));
|
||||
//TCL lgw modify 20110412
|
||||
//snd_soc_write(codec, WM8988_PWR1, 0xfc);
|
||||
//snd_soc_write(codec, WM8988_PWR2, 0x1e0); //power r l out1
|
||||
|
||||
wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
@@ -792,6 +908,7 @@ static int wm8988_probe(struct snd_soc_codec *codec)
|
||||
snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
|
||||
ARRAY_SIZE(wm8988_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
|
||||
create_proc_read_entry("wm8988_suspend", 0644, NULL, entry_read, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -842,7 +959,7 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
|
||||
|
||||
static struct spi_driver wm8988_spi_driver = {
|
||||
.driver = {
|
||||
.name = "wm8988-codec",
|
||||
.name = "WM8988",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = wm8988_spi_probe,
|
||||
@@ -886,7 +1003,7 @@ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
|
||||
|
||||
static struct i2c_driver wm8988_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "wm8988-codec",
|
||||
.name = "WM8988",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = wm8988_i2c_probe,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* rk2818_wm8988.c -- SoC audio for rockchip
|
||||
* rk29_wm8988.c -- SoC audio for rockchip
|
||||
*
|
||||
* Driver for rockchip wm8988 audio
|
||||
*
|
||||
@@ -24,18 +24,22 @@
|
||||
#include "rk29_pcm.h"
|
||||
#include "rk29_i2s.h"
|
||||
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
static int rk2818_hw_params(struct snd_pcm_substream *substream,
|
||||
//static void *rk29_speaker = NULL;
|
||||
|
||||
static int rk29_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
@@ -44,39 +48,39 @@ static int rk2818_hw_params(struct snd_pcm_substream *substream,
|
||||
#define HW_PARAMS_FLAG_EQVOL_OFF 0x22
|
||||
if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
|
||||
{
|
||||
ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent
|
||||
ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set codec DAI configuration */
|
||||
#if defined (CONFIG_SND_CODEC_SOC_SLAVE)
|
||||
ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_CODEC_SOC_MASTER)
|
||||
ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* set cpu DAI configuration */
|
||||
#if defined (CONFIG_SND_CODEC_SOC_SLAVE)
|
||||
ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_CODEC_SOC_MASTER)
|
||||
ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget rk2818_dapm_widgets[] = {
|
||||
static const struct snd_soc_dapm_widget rk29_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_LINE("Audio Out", NULL),
|
||||
SND_SOC_DAPM_LINE("Line in", NULL),
|
||||
SND_SOC_DAPM_MIC("Micn", NULL),
|
||||
@@ -96,84 +100,86 @@ static const struct snd_soc_dapm_route audio_map[]= {
|
||||
/*
|
||||
* Logic for a wm8988 as connected on a rockchip board.
|
||||
*/
|
||||
static int rk2818_wm8988_init(struct snd_soc_codec *codec)
|
||||
static int rk29_wm8988_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_dai *codec_dai = &codec->dai[0];
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
|
||||
12000000, SND_SOC_CLOCK_IN);
|
||||
/*12000000*/11289600, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "Failed to set WM8988 SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add specific widgets */
|
||||
snd_soc_dapm_new_controls(codec, rk2818_dapm_widgets,
|
||||
ARRAY_SIZE(rk2818_dapm_widgets));
|
||||
snd_soc_dapm_nc_pin(codec, "LOUT2");
|
||||
snd_soc_dapm_nc_pin(codec, "ROUT2");
|
||||
snd_soc_dapm_new_controls(dapm, rk29_dapm_widgets,
|
||||
ARRAY_SIZE(rk29_dapm_widgets));
|
||||
//snd_soc_dapm_nc_pin(codec, "LOUT2");
|
||||
//snd_soc_dapm_nc_pin(codec, "ROUT2");
|
||||
|
||||
/* Set up specific audio path audio_mapnects */
|
||||
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
|
||||
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
|
||||
|
||||
snd_soc_dapm_sync(codec);
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops rk2818_ops = {
|
||||
.hw_params = rk2818_hw_params,
|
||||
static struct snd_soc_ops rk29_ops = {
|
||||
.hw_params = rk29_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_link rk2818_dai = {
|
||||
.name = "WM8988",
|
||||
.stream_name = "WM8988 PCM",
|
||||
.cpu_dai = &rk2818_i2s_dai,
|
||||
.codec_dai = &wm8988_dai,
|
||||
.init = rk2818_wm8988_init,
|
||||
.ops = &rk2818_ops,
|
||||
static struct snd_soc_dai_link rk29_dai = {
|
||||
.name = "WM8988",
|
||||
.stream_name = "WM8988 PCM",
|
||||
.codec_name = "WM8988.0-001a",
|
||||
.platform_name = "rockchip-audio",
|
||||
.cpu_dai_name = "rk29_i2s.0",
|
||||
.codec_dai_name = "WM8988 HiFi",
|
||||
.init = rk29_wm8988_init,
|
||||
.ops = &rk29_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_card_rk2818 = {
|
||||
.name = "RK2818_WM8988",
|
||||
.platform = &rk2818_soc_platform,
|
||||
.dai_link = &rk2818_dai,
|
||||
.num_links = 1,
|
||||
static struct snd_soc_card snd_soc_card_rk29 = {
|
||||
.name = "RK29_WM8988",
|
||||
.dai_link = &rk29_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
|
||||
static struct snd_soc_device rk2818_snd_devdata = {
|
||||
.card = &snd_soc_card_rk2818,
|
||||
.codec_dev = &soc_codec_dev_wm8988,
|
||||
};
|
||||
|
||||
static struct platform_device *rk2818_snd_device;
|
||||
static struct platform_device *rk29_snd_device;
|
||||
|
||||
static int __init audio_card_init(void)
|
||||
{
|
||||
int ret =0;
|
||||
int ret =0;
|
||||
|
||||
//rk29_speaker = rk29_speaker_init(RK29_PIN6_PB6, GPIO_HIGH, 2, (200*1000*1000));
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
rk2818_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!rk2818_snd_device) {
|
||||
rk29_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!rk29_snd_device) {
|
||||
DBG("platform device allocation failed\n");
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(rk2818_snd_device, &rk2818_snd_devdata);
|
||||
rk2818_snd_devdata.dev = &rk2818_snd_device->dev;
|
||||
ret = platform_device_add(rk2818_snd_device);
|
||||
platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29);
|
||||
ret = platform_device_add(rk29_snd_device);
|
||||
if (ret) {
|
||||
DBG("platform device add failed\n");
|
||||
platform_device_put(rk2818_snd_device);
|
||||
platform_device_put(rk29_snd_device);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
static void __exit audio_card_exit(void)
|
||||
{
|
||||
platform_device_unregister(rk2818_snd_device);
|
||||
platform_device_unregister(rk29_snd_device);
|
||||
//rk29_speaker_deinit(rk29_speaker);
|
||||
}
|
||||
|
||||
module_init(audio_card_init);
|
||||
|
||||
Reference in New Issue
Block a user