mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-19 11:43:40 +00:00
Merge remote-tracking branches 'asoc/topic/wm8955', 'asoc/topic/wm8960', 'asoc/topic/wm8961', 'asoc/topic/wm8962' and 'asoc/topic/wm8974' into asoc-next
This commit is contained in:
commit
67a3adab9d
31
Documentation/devicetree/bindings/sound/wm8960.txt
Normal file
31
Documentation/devicetree/bindings/sound/wm8960.txt
Normal file
@ -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;
|
||||
};
|
@ -866,29 +866,6 @@ static struct snd_soc_dai_driver wm8955_dai = {
|
||||
.ops = &wm8955_dai_ops,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int wm8955_suspend(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
regcache_mark_dirty(wm8955->regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8955_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define wm8955_suspend NULL
|
||||
#define wm8955_resume NULL
|
||||
#endif
|
||||
|
||||
static int wm8955_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
|
||||
@ -964,18 +941,10 @@ err_enable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm8955_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
|
||||
.probe = wm8955_probe,
|
||||
.remove = wm8955_remove,
|
||||
.suspend = wm8955_suspend,
|
||||
.resume = wm8955_resume,
|
||||
.set_bias_level = wm8955_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
|
||||
.controls = wm8955_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(wm8955_snd_controls),
|
||||
|
@ -125,9 +125,10 @@ 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)
|
||||
#define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
|
||||
|
||||
/* enumerated controls */
|
||||
static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
|
||||
@ -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;
|
||||
|
||||
@ -942,56 +943,15 @@ static struct snd_soc_dai_driver wm8960_dai = {
|
||||
.symmetric_rates = 1,
|
||||
};
|
||||
|
||||
static int wm8960_suspend(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8960_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
int ret;
|
||||
struct wm8960_data *pdata = &wm8960->pdata;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ret = wm8960_reset(codec);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to issue reset\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
/* Latch the update bits */
|
||||
snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_LADC, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_RADC, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_LDAC, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_RDAC, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_LOUT1, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_ROUT1, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
|
||||
snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
|
||||
if (pdata->capless)
|
||||
wm8960->set_bias_level = wm8960_set_bias_level_capless;
|
||||
else
|
||||
wm8960->set_bias_level = wm8960_set_bias_level_out3;
|
||||
|
||||
snd_soc_add_codec_controls(codec, wm8960_snd_controls,
|
||||
ARRAY_SIZE(wm8960_snd_controls));
|
||||
@ -1000,21 +960,10 @@ static int wm8960_probe(struct snd_soc_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int wm8960_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
|
||||
.probe = wm8960_probe,
|
||||
.remove = wm8960_remove,
|
||||
.suspend = wm8960_suspend,
|
||||
.resume = wm8960_resume,
|
||||
.set_bias_level = wm8960_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
};
|
||||
|
||||
static const struct regmap_config wm8960_regmap = {
|
||||
@ -1029,6 +978,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)
|
||||
{
|
||||
@ -1045,7 +1006,18 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
|
||||
if (IS_ERR(wm8960->regmap))
|
||||
return PTR_ERR(wm8960->regmap);
|
||||
|
||||
if (pdata && pdata->shared_lrclk) {
|
||||
if (pdata)
|
||||
memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data));
|
||||
else if (i2c->dev.of_node)
|
||||
wm8960_set_pdata_from_of(i2c, &wm8960->pdata);
|
||||
|
||||
ret = wm8960_reset(wm8960->regmap);
|
||||
if (ret != 0) {
|
||||
dev_err(&i2c->dev, "Failed to issue reset\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (wm8960->pdata.shared_lrclk) {
|
||||
ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
|
||||
0x4, 0x4);
|
||||
if (ret != 0) {
|
||||
@ -1055,6 +1027,18 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
}
|
||||
|
||||
/* Latch the update bits */
|
||||
regmap_update_bits(wm8960->regmap, WM8960_LINVOL, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_RINVOL, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_LADC, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_RADC, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_LDAC, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_RDAC, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_LOUT1, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_ROUT1, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_LOUT2, 0x100, 0x100);
|
||||
regmap_update_bits(wm8960->regmap, WM8960_ROUT2, 0x100, 0x100);
|
||||
|
||||
i2c_set_clientdata(i2c, wm8960);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
@ -1075,10 +1059,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,
|
||||
|
@ -835,7 +835,6 @@ static struct snd_soc_dai_driver wm8961_dai = {
|
||||
|
||||
static int wm8961_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
u16 reg;
|
||||
|
||||
/* Enable class W */
|
||||
@ -871,50 +870,33 @@ static int wm8961_probe(struct snd_soc_codec *codec)
|
||||
reg &= ~WM8961_MANUAL_MODE;
|
||||
snd_soc_write(codec, WM8961_CLOCKING_3, reg);
|
||||
|
||||
wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
snd_soc_add_codec_controls(codec, wm8961_snd_controls,
|
||||
ARRAY_SIZE(wm8961_snd_controls));
|
||||
snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
|
||||
ARRAY_SIZE(wm8961_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8961_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int wm8961_suspend(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8961_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
snd_soc_cache_sync(codec);
|
||||
|
||||
wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define wm8961_suspend NULL
|
||||
#define wm8961_resume NULL
|
||||
#endif
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
|
||||
.probe = wm8961_probe,
|
||||
.remove = wm8961_remove,
|
||||
.suspend = wm8961_suspend,
|
||||
.resume = wm8961_resume,
|
||||
.set_bias_level = wm8961_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
|
||||
.controls = wm8961_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(wm8961_snd_controls),
|
||||
.dapm_widgets = wm8961_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets),
|
||||
.dapm_routes = audio_paths,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_paths),
|
||||
};
|
||||
|
||||
static const struct regmap_config wm8961_regmap = {
|
||||
|
@ -3554,8 +3554,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
|
||||
unsigned int reg;
|
||||
int ret, i, irq_pol, trigger;
|
||||
|
||||
wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv),
|
||||
GFP_KERNEL);
|
||||
wm8962 = devm_kzalloc(&i2c->dev, sizeof(*wm8962), GFP_KERNEL);
|
||||
if (wm8962 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -568,18 +568,6 @@ static struct snd_soc_dai_driver wm8974_dai = {
|
||||
.symmetric_rates = 1,
|
||||
};
|
||||
|
||||
static int wm8974_suspend(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8974_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct regmap_config wm8974_regmap = {
|
||||
.reg_bits = 7,
|
||||
.val_bits = 9,
|
||||
@ -599,24 +587,13 @@ static int wm8974_probe(struct snd_soc_codec *codec)
|
||||
return ret;
|
||||
}
|
||||
|
||||
wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int wm8974_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
|
||||
.probe = wm8974_probe,
|
||||
.remove = wm8974_remove,
|
||||
.suspend = wm8974_suspend,
|
||||
.resume = wm8974_resume,
|
||||
.set_bias_level = wm8974_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
|
||||
.controls = wm8974_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(wm8974_snd_controls),
|
||||
|
Loading…
x
Reference in New Issue
Block a user