Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 120310
b: refs/heads/master
c: 78e19a3
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Dec 10, 2008
1 parent 2e72607 commit c9633ad
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 86 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0d0cf00a7fc63cee9a4c4a3b8612879b4f7f42ba
refs/heads/master: 78e19a39d3985e2a06354493a70a200c0d432de5
159 changes: 81 additions & 78 deletions trunk/sound/soc/codecs/wm8900.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@
struct snd_soc_codec_device soc_codec_dev_wm8900;

struct wm8900_priv {
struct snd_soc_codec codec;

u16 reg_cache[WM8900_MAXREG];

u32 fll_in; /* FLL input frequency */
u32 fll_out; /* FLL output frequency */
};
Expand Down Expand Up @@ -1282,50 +1286,57 @@ static int wm8900_resume(struct platform_device *pdev)
return 0;
}

/*
* initialise the WM8900 driver
* register the mixer and dsp interfaces with the kernel
*/
static int wm8900_init(struct snd_soc_device *socdev)
static struct snd_soc_codec *wm8900_codec;

static int wm8900_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct snd_soc_codec *codec = socdev->codec;
int ret = 0;
struct wm8900_priv *wm8900;
struct snd_soc_codec *codec;
unsigned int reg;
struct i2c_client *i2c_client = socdev->codec->control_data;
int ret;

wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
if (wm8900 == NULL)
return -ENOMEM;

codec = &wm8900->codec;
codec->private_data = wm8900;
codec->reg_cache = &wm8900->reg_cache[0];
codec->reg_cache_size = WM8900_MAXREG;

mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);

codec->name = "WM8900";
codec->owner = THIS_MODULE;
codec->read = wm8900_read;
codec->write = wm8900_write;
codec->dai = &wm8900_dai;
codec->num_dai = 1;
codec->reg_cache_size = WM8900_MAXREG;
codec->reg_cache = kmemdup(wm8900_reg_defaults,
sizeof(wm8900_reg_defaults), GFP_KERNEL);

if (codec->reg_cache == NULL)
return -ENOMEM;
codec->hw_write = (hw_write_t)i2c_master_send;
codec->control_data = i2c;
codec->set_bias_level = wm8900_set_bias_level;
codec->dev = &i2c->dev;

reg = wm8900_read(codec, WM8900_REG_ID);
if (reg != 0x8900) {
dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n",
reg);
return -ENODEV;
}

codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
if (codec->private_data == NULL) {
ret = -ENOMEM;
goto priv_err;
dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
ret = -ENODEV;
goto err;
}

/* Read back from the chip */
reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
reg = (reg >> 12) & 0xf;
dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg);
dev_info(&i2c->dev, "WM8900 revision %d\n", reg);

wm8900_reset(codec);

/* Turn the chip on */
wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

/* Latch the volume update bits */
wm8900_write(codec, WM8900_REG_LINVOL,
wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
Expand All @@ -1351,52 +1362,43 @@ static int wm8900_init(struct snd_soc_device *socdev)
/* Set the DAC and mixer output bias */
wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);

/* Register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
goto pcm_err;
}
wm8900_dai.dev = &i2c->dev;

/* Turn the chip on */
codec->bias_level = SND_SOC_BIAS_OFF;
wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
wm8900_codec = codec;

wm8900_add_controls(codec);
wm8900_add_widgets(codec);
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
goto err;
}

ret = snd_soc_init_card(socdev);
if (ret < 0) {
dev_err(&i2c_client->dev, "Failed to register card\n");
goto card_err;
ret = snd_soc_register_dai(&wm8900_dai);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
goto err_codec;
}
return ret;

card_err:
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
pcm_err:
kfree(codec->reg_cache);
priv_err:
kfree(codec->private_data);
return ret;
}

static struct i2c_client *wm8900_client;

static int wm8900_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
wm8900_client = i2c;
wm8900_dai.dev = &i2c->dev;
return snd_soc_register_dai(&wm8900_dai);
err_codec:
snd_soc_unregister_codec(codec);
err:
kfree(wm8900);
wm8900_codec = NULL;
return ret;
}

static int wm8900_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_dai(&wm8900_dai);
snd_soc_unregister_codec(wm8900_codec);

wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);

wm8900_dai.dev = NULL;
wm8900_client = NULL;
kfree(wm8900_codec->private_data);
wm8900_codec = NULL;

return 0;
}

Expand All @@ -1408,7 +1410,7 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);

static struct i2c_driver wm8900_i2c_driver = {
.driver = {
.name = "WM8900 I2C codec",
.name = "WM8900",
.owner = THIS_MODULE,
},
.probe = wm8900_i2c_probe,
Expand All @@ -1422,45 +1424,46 @@ static int wm8900_probe(struct platform_device *pdev)
struct snd_soc_codec *codec;
int ret = 0;

if (!wm8900_client) {
if (!wm8900_codec) {
dev_err(&pdev->dev, "I2C client not yet instantiated\n");
return -ENODEV;
}

codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (codec == NULL)
return -ENOMEM;

mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);

codec = wm8900_codec;
socdev->codec = codec;

codec->set_bias_level = wm8900_set_bias_level;
/* Register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register new PCMs\n");
goto pcm_err;
}

codec->hw_write = (hw_write_t)i2c_master_send;
codec->control_data = wm8900_client;
wm8900_add_controls(codec);
wm8900_add_widgets(codec);

ret = snd_soc_init_card(socdev);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register card\n");
goto card_err;
}

ret = wm8900_init(socdev);
if (ret != 0)
kfree(codec);
return ret;

card_err:
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
pcm_err:
return ret;
}

/* power down chip */
static int wm8900_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->codec;

if (codec->control_data)
wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);

snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
kfree(codec);

return 0;
}
Expand Down
7 changes: 0 additions & 7 deletions trunk/sound/soc/codecs/wm8900.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@
#define WM8900_DAC_CLKDIV_5_5 0x14
#define WM8900_DAC_CLKDIV_6 0x18

#define WM8900_

struct wm8900_setup_data {
int i2c_bus;
unsigned short i2c_address;
};

extern struct snd_soc_dai wm8900_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8900;

Expand Down

0 comments on commit c9633ad

Please sign in to comment.