diff options
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r-- | sound/soc/codecs/wm8731.c | 267 |
1 files changed, 44 insertions, 223 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index b14c6d104e6d..2408c4a591d5 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,59 +549,6 @@ static struct snd_soc_dai_driver wm8731_dai = { .symmetric_rate = 1, }; -static int wm8731_request_supplies(struct device *dev, - struct wm8731_priv *wm8731) -{ - int ret = 0, i; - - for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) - wm8731->supplies[i].supply = wm8731_supply_names[i]; - - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8731->supplies), - wm8731->supplies); - if (ret != 0) { - dev_err(dev, "Failed to request supplies: %d\n", ret); - return ret; - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), - wm8731->supplies); - if (ret != 0) { - dev_err(dev, "Failed to enable supplies: %d\n", ret); - 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); - goto err; - } - - /* Clear POWEROFF, keep everything else disabled */ - regmap_write(wm8731->regmap, WM8731_PWR, 0x7f); - - /* Latch the update bits */ - regmap_update_bits(wm8731->regmap, WM8731_LOUT1V, 0x100, 0); - regmap_update_bits(wm8731->regmap, WM8731_ROUT1V, 0x100, 0); - regmap_update_bits(wm8731->regmap, WM8731_LINVOL, 0x100, 0); - regmap_update_bits(wm8731->regmap, WM8731_RINVOL, 0x100, 0); - - /* Disable bypass path by default */ - regmap_update_bits(wm8731->regmap, WM8731_APANA, 0x8, 0); - - regcache_mark_dirty(wm8731->regmap); - -err: - return ret; -} - static const struct snd_soc_component_driver soc_component_dev_wm8731 = { .set_bias_level = wm8731_set_bias_level, .controls = wm8731_snd_controls, @@ -638,136 +564,65 @@ static const struct snd_soc_component_driver soc_component_dev_wm8731 = { .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 = { - .reg_bits = 7, - .val_bits = 9, - - .max_register = WM8731_RESET, - .volatile_reg = wm8731_volatile, - - .cache_type = REGCACHE_RBTREE, - .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) +int wm8731_init(struct device *dev, struct wm8731_priv *wm8731) { - struct wm8731_priv *wm8731; - int ret; - - wm8731 = devm_kzalloc(&spi->dev, sizeof(*wm8731), GFP_KERNEL); - if (wm8731 == NULL) - return -ENOMEM; + int ret = 0, i; - wm8731->mclk = devm_clk_get(&spi->dev, "mclk"); + 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(&spi->dev, "Assuming static MCLK\n"); + dev_warn(dev, "Assuming static MCLK\n"); } else { - dev_err(&spi->dev, "Failed to get MCLK: %d\n", - ret); + dev_err(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; + for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) + wm8731->supplies[i].supply = wm8731_supply_names[i]; - 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); + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8731->supplies), + wm8731->supplies); + if (ret != 0) { + dev_err(dev, "Failed to request supplies: %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); + ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), + wm8731->supplies); if (ret != 0) { - dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); + dev_err(dev, "Failed to enable supplies: %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; - } + ret = wm8731_reset(wm8731->regmap); + if (ret < 0) { + dev_err(dev, "Failed to issue reset: %d\n", ret); + goto err_regulator_enable; } - mutex_init(&wm8731->lock); - - i2c_set_clientdata(i2c, wm8731); + /* Clear POWEROFF, keep everything else disabled */ + regmap_write(wm8731->regmap, WM8731_PWR, 0x7f); - ret = wm8731_request_supplies(&i2c->dev, wm8731); - if (ret != 0) - return ret; + /* Latch the update bits */ + regmap_update_bits(wm8731->regmap, WM8731_LOUT1V, 0x100, 0); + regmap_update_bits(wm8731->regmap, WM8731_ROUT1V, 0x100, 0); + regmap_update_bits(wm8731->regmap, WM8731_LINVOL, 0x100, 0); + regmap_update_bits(wm8731->regmap, WM8731_RINVOL, 0x100, 0); - 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); - goto err_regulator_enable; - } + /* Disable bypass path by default */ + regmap_update_bits(wm8731->regmap, WM8731_APANA, 0x8, 0); - ret = wm8731_hw_init(&i2c->dev, wm8731); - if (ret != 0) - goto err_regulator_enable; + regcache_mark_dirty(wm8731->regmap); - ret = devm_snd_soc_register_component(&i2c->dev, + ret = devm_snd_soc_register_component(dev, &soc_component_dev_wm8731, &wm8731_dai, 1); if (ret != 0) { - dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + dev_err(dev, "Failed to register CODEC: %d\n", ret); goto err_regulator_enable; } @@ -779,54 +634,20 @@ err_regulator_enable: return ret; } +EXPORT_SYMBOL_GPL(wm8731_init); -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, - .id_table = wm8731_i2c_id, -}; -#endif +const struct regmap_config wm8731_regmap = { + .reg_bits = 7, + .val_bits = 9, -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); + .max_register = WM8731_RESET, + .volatile_reg = wm8731_volatile, -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); + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8731_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults), +}; +EXPORT_SYMBOL_GPL(wm8731_regmap); MODULE_DESCRIPTION("ASoC WM8731 driver"); MODULE_AUTHOR("Richard Purdie"); |