diff options
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r-- | sound/soc/codecs/wm8731.c | 271 |
1 files changed, 44 insertions, 227 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 86b1f6eaa599..d5ab3ba126a6 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -15,13 +15,9 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/pm.h> -#include <linux/i2c.h> #include <linux/slab.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> -#include <linux/spi/spi.h> -#include <linux/of_device.h> -#include <linux/mutex.h> #include <linux/clk.h> #include <sound/core.h> #include <sound/pcm.h> @@ -32,7 +28,6 @@ #include "wm8731.h" -#define WM8731_NUM_SUPPLIES 4 static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { "AVDD", "HPVDD", @@ -40,21 +35,6 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { "DBVDD", }; -/* codec private data */ -struct wm8731_priv { - struct regmap *regmap; - struct clk *mclk; - struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; - const struct snd_pcm_hw_constraint_list *constraints; - unsigned int sysclk; - int sysclk_type; - int playback_fs; - bool deemph; - - struct mutex lock; -}; - - /* * wm8731 register cache */ @@ -429,12 +409,11 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_component *component = codec_dai->component; u16 iface = 0; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface |= 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -570,11 +549,38 @@ static struct snd_soc_dai_driver wm8731_dai = { .symmetric_rate = 1, }; -static int wm8731_request_supplies(struct device *dev, - struct wm8731_priv *wm8731) +static const struct snd_soc_component_driver soc_component_dev_wm8731 = { + .set_bias_level = wm8731_set_bias_level, + .controls = wm8731_snd_controls, + .num_controls = ARRAY_SIZE(wm8731_snd_controls), + .dapm_widgets = wm8731_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), + .dapm_routes = wm8731_intercon, + .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +int wm8731_init(struct device *dev, struct wm8731_priv *wm8731) { int ret = 0, i; + wm8731->mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(wm8731->mclk)) { + ret = PTR_ERR(wm8731->mclk); + if (ret == -ENOENT) { + wm8731->mclk = NULL; + dev_warn(dev, "Assuming static MCLK\n"); + } else { + dev_err(dev, "Failed to get MCLK: %d\n", ret); + return ret; + } + } + + mutex_init(&wm8731->lock); + for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) wm8731->supplies[i].supply = wm8731_supply_names[i]; @@ -592,13 +598,6 @@ static int wm8731_request_supplies(struct device *dev, return ret; } - return 0; -} - -static int wm8731_hw_init(struct device *dev, struct wm8731_priv *wm8731) -{ - int ret = 0; - ret = wm8731_reset(wm8731->regmap); if (ret < 0) { dev_err(dev, "Failed to issue reset: %d\n", ret); @@ -619,36 +618,24 @@ static int wm8731_hw_init(struct device *dev, struct wm8731_priv *wm8731) regcache_mark_dirty(wm8731->regmap); + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_wm8731, &wm8731_dai, 1); + if (ret != 0) { + dev_err(dev, "Failed to register CODEC: %d\n", ret); + goto err_regulator_enable; + } + + return 0; + err_regulator_enable: /* Regulators will be enabled by bias management */ regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); return ret; } +EXPORT_SYMBOL_GPL(wm8731_init); -static const struct snd_soc_component_driver soc_component_dev_wm8731 = { - .set_bias_level = wm8731_set_bias_level, - .controls = wm8731_snd_controls, - .num_controls = ARRAY_SIZE(wm8731_snd_controls), - .dapm_widgets = wm8731_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), - .dapm_routes = wm8731_intercon, - .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), - .suspend_bias_off = 1, - .idle_bias_on = 1, - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -static const struct of_device_id wm8731_of_match[] = { - { .compatible = "wlf,wm8731", }, - { } -}; - -MODULE_DEVICE_TABLE(of, wm8731_of_match); - -static const struct regmap_config wm8731_regmap = { +const struct regmap_config wm8731_regmap = { .reg_bits = 7, .val_bits = 9, @@ -659,177 +646,7 @@ static const struct regmap_config wm8731_regmap = { .reg_defaults = wm8731_reg_defaults, .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults), }; - -#if defined(CONFIG_SPI_MASTER) -static int wm8731_spi_probe(struct spi_device *spi) -{ - struct wm8731_priv *wm8731; - int ret; - - wm8731 = devm_kzalloc(&spi->dev, sizeof(*wm8731), GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; - - wm8731->mclk = devm_clk_get(&spi->dev, "mclk"); - if (IS_ERR(wm8731->mclk)) { - ret = PTR_ERR(wm8731->mclk); - if (ret == -ENOENT) { - wm8731->mclk = NULL; - dev_warn(&spi->dev, "Assuming static MCLK\n"); - } else { - dev_err(&spi->dev, "Failed to get MCLK: %d\n", - ret); - return ret; - } - } - - mutex_init(&wm8731->lock); - - spi_set_drvdata(spi, wm8731); - - ret = wm8731_request_supplies(&spi->dev, wm8731); - if (ret != 0) - return ret; - - wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); - if (IS_ERR(wm8731->regmap)) { - ret = PTR_ERR(wm8731->regmap); - dev_err(&spi->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - - ret = wm8731_hw_init(&spi->dev, wm8731); - if (ret != 0) - return ret; - - ret = devm_snd_soc_register_component(&spi->dev, - &soc_component_dev_wm8731, &wm8731_dai, 1); - if (ret != 0) { - dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); - return ret; - } - - return 0; -} - -static struct spi_driver wm8731_spi_driver = { - .driver = { - .name = "wm8731", - .of_match_table = wm8731_of_match, - }, - .probe = wm8731_spi_probe, -}; -#endif /* CONFIG_SPI_MASTER */ - -#if IS_ENABLED(CONFIG_I2C) -static int wm8731_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8731_priv *wm8731; - int ret; - - wm8731 = devm_kzalloc(&i2c->dev, sizeof(struct wm8731_priv), - GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; - - wm8731->mclk = devm_clk_get(&i2c->dev, "mclk"); - if (IS_ERR(wm8731->mclk)) { - ret = PTR_ERR(wm8731->mclk); - if (ret == -ENOENT) { - wm8731->mclk = NULL; - dev_warn(&i2c->dev, "Assuming static MCLK\n"); - } else { - dev_err(&i2c->dev, "Failed to get MCLK: %d\n", - ret); - return ret; - } - } - - mutex_init(&wm8731->lock); - - i2c_set_clientdata(i2c, wm8731); - - ret = wm8731_request_supplies(&i2c->dev, wm8731); - if (ret != 0) - return ret; - - wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); - if (IS_ERR(wm8731->regmap)) { - ret = PTR_ERR(wm8731->regmap); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", - ret); - return ret; - } - - ret = wm8731_hw_init(&i2c->dev, wm8731); - if (ret != 0) - return ret; - - ret = devm_snd_soc_register_component(&i2c->dev, - &soc_component_dev_wm8731, &wm8731_dai, 1); - if (ret != 0) { - dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); - return ret; - } - - return 0; -} - -static int wm8731_i2c_remove(struct i2c_client *client) -{ - return 0; -} - -static const struct i2c_device_id wm8731_i2c_id[] = { - { "wm8731", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); - -static struct i2c_driver wm8731_i2c_driver = { - .driver = { - .name = "wm8731", - .of_match_table = wm8731_of_match, - }, - .probe = wm8731_i2c_probe, - .remove = wm8731_i2c_remove, - .id_table = wm8731_i2c_id, -}; -#endif - -static int __init wm8731_modinit(void) -{ - int ret = 0; -#if IS_ENABLED(CONFIG_I2C) - ret = i2c_add_driver(&wm8731_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n", - ret); - } -#endif -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8731_spi_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n", - ret); - } -#endif - return ret; -} -module_init(wm8731_modinit); - -static void __exit wm8731_exit(void) -{ -#if IS_ENABLED(CONFIG_I2C) - i2c_del_driver(&wm8731_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8731_spi_driver); -#endif -} -module_exit(wm8731_exit); +EXPORT_SYMBOL_GPL(wm8731_regmap); MODULE_DESCRIPTION("ASoC WM8731 driver"); MODULE_AUTHOR("Richard Purdie"); |