#define AUDIO_NAME "wm8731"
#define WM8731_VERSION "0.13"
-/*
- * Debug
- */
-
-#define WM8731_DEBUG 0
-
-#ifdef WM8731_DEBUG
-#define dbg(format, arg...) \
- printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
struct snd_soc_codec_device soc_codec_dev_wm8731;
/* codec private data */
data[0] = (reg << 1) | ((value >> 8) & 0x0001);
data[1] = value & 0x00ff;
- wm8731_write_reg_cache (codec, reg, value);
+ wm8731_write_reg_cache(codec, reg, value);
if (codec->hw_write(codec->control_data, data, 2) == 2)
return 0;
else
int err, i;
for (i = 0; i < ARRAY_SIZE(wm8731_snd_controls); i++) {
- if ((err = snd_ctl_add(codec->card,
- snd_soc_cnew(&wm8731_snd_controls[i],codec, NULL))) < 0)
+ err = snd_ctl_add(codec->card,
+ snd_soc_cnew(&wm8731_snd_controls[i],
+ codec, NULL));
+ if (err < 0)
return err;
}
SND_SOC_DAPM_INPUT("LLINEIN"),
};
-static const char *intercon[][3] = {
+static const struct snd_soc_dapm_route intercon[] = {
/* output mixer */
{"Output Mixer", "Line Bypass Switch", "Line Input"},
{"Output Mixer", "HiFi Playback Switch", "DAC"},
{"Line Input", NULL, "LLINEIN"},
{"Line Input", NULL, "RLINEIN"},
{"Mic Bias", NULL, "MICIN"},
-
- /* terminator */
- {NULL, NULL, NULL},
};
static int wm8731_add_widgets(struct snd_soc_codec *codec)
{
- int i;
-
- for(i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) {
- snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]);
- }
+ snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
+ ARRAY_SIZE(wm8731_dapm_widgets));
- /* set up audio path interconnects */
- for(i = 0; intercon[i][0] != NULL; i++) {
- snd_soc_dapm_connect_input(codec, intercon[i][0],
- intercon[i][1], intercon[i][2]);
- }
+ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
snd_soc_dapm_new_widgets(codec);
return 0;
}
}
-static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute)
+static int wm8731_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7;
return 0;
}
-static int wm8731_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
+static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = codec_dai->codec;
}
-static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
return 0;
}
-static int wm8731_dapm_event(struct snd_soc_codec *codec, int event)
+static int wm8731_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
{
u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f;
- switch (event) {
- case SNDRV_CTL_POWER_D0: /* full On */
+ switch (level) {
+ case SND_SOC_BIAS_ON:
/* vref/mid, osc on, dac unmute */
wm8731_write(codec, WM8731_PWR, reg);
break;
- case SNDRV_CTL_POWER_D1: /* partial On */
- case SNDRV_CTL_POWER_D2: /* partial On */
+ case SND_SOC_BIAS_PREPARE:
break;
- case SNDRV_CTL_POWER_D3hot: /* Off, with power */
+ case SND_SOC_BIAS_STANDBY:
/* everything off except vref/vmid, */
wm8731_write(codec, WM8731_PWR, reg | 0x0040);
break;
- case SNDRV_CTL_POWER_D3cold: /* Off, without power */
+ case SND_SOC_BIAS_OFF:
/* everything off, dac mute, inactive */
wm8731_write(codec, WM8731_ACTIVE, 0x0);
wm8731_write(codec, WM8731_PWR, 0xffff);
break;
}
- codec->dapm_state = event;
+ codec->bias_level = level;
return 0;
}
#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
-struct snd_soc_codec_dai wm8731_dai = {
+struct snd_soc_dai wm8731_dai = {
.name = "WM8731",
.playback = {
.stream_name = "Playback",
struct snd_soc_codec *codec = socdev->codec;
wm8731_write(codec, WM8731_ACTIVE, 0x0);
- wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
+ wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
data[1] = cache[i] & 0x00ff;
codec->hw_write(codec->control_data, data, 2);
}
- wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
- wm8731_dapm_event(codec, codec->suspend_dapm_state);
+ wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ wm8731_set_bias_level(codec, codec->suspend_bias_level);
return 0;
}
codec->owner = THIS_MODULE;
codec->read = wm8731_read_reg_cache;
codec->write = wm8731_write;
- codec->dapm_event = wm8731_dapm_event;
+ codec->set_bias_level = wm8731_set_bias_level;
codec->dai = &wm8731_dai;
codec->num_dai = 1;
- codec->reg_cache_size = sizeof(wm8731_reg);
+ codec->reg_cache_size = ARRAY_SIZE(wm8731_reg);
codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL);
if (codec->reg_cache == NULL)
return -ENOMEM;
}
/* power on device */
- wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
+ wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* set the update bits */
reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
static struct snd_soc_device *wm8731_socdev;
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/*
* WM8731 2 wire address is determined by GPIO5
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
ret = i2c_attach_client(i2c);
if (ret < 0) {
- err("failed to attach codec at addr %x\n", addr);
+ pr_err("failed to attach codec at addr %x\n", addr);
goto err;
}
ret = wm8731_init(socdev);
if (ret < 0) {
- err("failed to initialise WM8731\n");
+ pr_err("failed to initialise WM8731\n");
goto err;
}
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
static int wm8731_i2c_detach(struct i2c_client *client)
{
- struct snd_soc_codec* codec = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = i2c_get_clientdata(client);
i2c_detach_client(client);
kfree(codec->reg_cache);
kfree(client);
struct wm8731_priv *wm8731;
int ret = 0;
- info("WM8731 Audio Codec %s", WM8731_VERSION);
+ pr_info("WM8731 Audio Codec %s", WM8731_VERSION);
setup = socdev->codec_data;
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
INIT_LIST_HEAD(&codec->dapm_paths);
wm8731_socdev = socdev;
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
if (setup->i2c_address) {
normal_i2c[0] = setup->i2c_address;
codec->hw_write = (hw_write_t)i2c_master_send;
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
struct snd_soc_codec *codec = socdev->codec;
if (codec->control_data)
- wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
+ wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8731_i2c_driver);
#endif
kfree(codec->private_data);
.suspend = wm8731_suspend,
.resume = wm8731_resume,
};
-
EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
MODULE_DESCRIPTION("ASoC WM8731 driver");