Skip to content

Commit

Permalink
ASoC: wm8960: Add device tree support
Browse files Browse the repository at this point in the history
Document the device tree binding for the WM8960 codec, and modify the
driver to extract the platform data from device tree, if present.

Signed-off-by: Zidan Wang <b50113@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Zidan Wang authored and Mark Brown committed Nov 21, 2014
1 parent f114040 commit e2280c9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 10 deletions.
31 changes: 31 additions & 0 deletions Documentation/devicetree/bindings/sound/wm8960.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
WM8960 audio CODEC

This device supports I2C only.

Required properties:

- compatible : "wlf,wm8960"

- reg : the I2C address of the device.

Optional properties:
- wlf,shared-lrclk: This is a boolean property. If present, the LRCM bit of
R24 (Additional control 2) gets set, indicating that ADCLRC and DACLRC pins
will be disabled only when ADC (Left and Right) and DAC (Left and Right)
are disabled.
When wm8960 works on synchronize mode and DACLRC pin is used to supply
frame clock, it will no frame clock for captrue unless enable DAC to enable
DACLRC pin. If shared-lrclk is present, no need to enable DAC for captrue.

- wlf,capless: This is a boolean property. If present, OUT3 pin will be
enabled and disabled together with HP_L and HP_R pins in response to jack
detect events.

Example:

codec: wm8960@1a {
compatible = "wlf,wm8960";
reg = <0x1a>;

wlf,shared-lrclk;
};
41 changes: 31 additions & 10 deletions sound/soc/codecs/wm8960.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct wm8960_priv {
struct snd_soc_dapm_widget *out3;
bool deemph;
int playback_fs;
struct wm8960_data pdata;
};

#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
Expand Down Expand Up @@ -440,8 +441,8 @@ static const struct snd_soc_dapm_route audio_paths_capless[] = {

static int wm8960_add_widgets(struct snd_soc_codec *codec)
{
struct wm8960_data *pdata = codec->dev->platform_data;
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
struct wm8960_data *pdata = &wm8960->pdata;
struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dapm_widget *w;

Expand Down Expand Up @@ -961,17 +962,13 @@ static int wm8960_resume(struct snd_soc_codec *codec)
static int wm8960_probe(struct snd_soc_codec *codec)
{
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
struct wm8960_data *pdata = dev_get_platdata(codec->dev);
struct wm8960_data *pdata = &wm8960->pdata;
int ret;

wm8960->set_bias_level = wm8960_set_bias_level_out3;

if (!pdata) {
dev_warn(codec->dev, "No platform data supplied\n");
} else {
if (pdata->capless)
wm8960->set_bias_level = wm8960_set_bias_level_capless;
}
if (pdata->capless)
wm8960->set_bias_level = wm8960_set_bias_level_capless;
else
wm8960->set_bias_level = wm8960_set_bias_level_out3;

ret = wm8960_reset(codec);
if (ret < 0) {
Expand Down Expand Up @@ -1029,6 +1026,18 @@ static const struct regmap_config wm8960_regmap = {
.volatile_reg = wm8960_volatile,
};

static void wm8960_set_pdata_from_of(struct i2c_client *i2c,
struct wm8960_data *pdata)
{
const struct device_node *np = i2c->dev.of_node;

if (of_property_read_bool(np, "wlf,capless"))
pdata->capless = true;

if (of_property_read_bool(np, "wlf,shared-lrclk"))
pdata->shared_lrclk = true;
}

static int wm8960_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
Expand All @@ -1045,6 +1054,11 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
if (IS_ERR(wm8960->regmap))
return PTR_ERR(wm8960->regmap);

if (pdata)
memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data));
else if (i2c->dev.of_node)
wm8960_set_pdata_from_of(i2c, &wm8960->pdata);

if (pdata && pdata->shared_lrclk) {
ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
0x4, 0x4);
Expand Down Expand Up @@ -1075,10 +1089,17 @@ static const struct i2c_device_id wm8960_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);

static const struct of_device_id wm8960_of_match[] = {
{ .compatible = "wlf,wm8960", },
{ }
};
MODULE_DEVICE_TABLE(of, wm8960_of_match);

static struct i2c_driver wm8960_i2c_driver = {
.driver = {
.name = "wm8960",
.owner = THIS_MODULE,
.of_match_table = wm8960_of_match,
},
.probe = wm8960_i2c_probe,
.remove = wm8960_i2c_remove,
Expand Down

0 comments on commit e2280c9

Please sign in to comment.