aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8731.c
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/codecs/wm8731.c
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r--sound/soc/codecs/wm8731.c217
1 files changed, 66 insertions, 151 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0ab9b6355297..7da360ee1fee 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -32,9 +32,6 @@
32 32
33#include "wm8731.h" 33#include "wm8731.h"
34 34
35static struct snd_soc_codec *wm8731_codec;
36struct snd_soc_codec_device soc_codec_dev_wm8731;
37
38#define WM8731_NUM_SUPPLIES 4 35#define WM8731_NUM_SUPPLIES 4
39static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { 36static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
40 "AVDD", 37 "AVDD",
@@ -45,7 +42,8 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45 42
46/* codec private data */ 43/* codec private data */
47struct wm8731_priv { 44struct wm8731_priv {
48 struct snd_soc_codec codec; 45 enum snd_soc_control_type control_type;
46 void *control_data;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 47 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
50 u16 reg_cache[WM8731_CACHEREGNUM]; 48 u16 reg_cache[WM8731_CACHEREGNUM];
51 unsigned int sysclk; 49 unsigned int sysclk;
@@ -222,9 +220,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params, 220 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai) 221 struct snd_soc_dai *dai)
224{ 222{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct snd_soc_codec *codec = dai->codec;
226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 224 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 225 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 226 int i = get_coeff(wm8731->sysclk, params_rate(params));
@@ -252,9 +248,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
252static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, 248static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_dai *dai) 249 struct snd_soc_dai *dai)
254{ 250{
255 struct snd_soc_pcm_runtime *rtd = substream->private_data; 251 struct snd_soc_codec *codec = dai->codec;
256 struct snd_soc_device *socdev = rtd->socdev;
257 struct snd_soc_codec *codec = socdev->card->codec;
258 252
259 /* set active */ 253 /* set active */
260 snd_soc_write(codec, WM8731_ACTIVE, 0x0001); 254 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
@@ -265,9 +259,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
265static void wm8731_shutdown(struct snd_pcm_substream *substream, 259static void wm8731_shutdown(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai) 260 struct snd_soc_dai *dai)
267{ 261{
268 struct snd_soc_pcm_runtime *rtd = substream->private_data; 262 struct snd_soc_codec *codec = dai->codec;
269 struct snd_soc_device *socdev = rtd->socdev;
270 struct snd_soc_codec *codec = socdev->card->codec;
271 263
272 /* deactivate */ 264 /* deactivate */
273 if (!codec->active) { 265 if (!codec->active) {
@@ -428,8 +420,8 @@ static struct snd_soc_dai_ops wm8731_dai_ops = {
428 .set_fmt = wm8731_set_dai_fmt, 420 .set_fmt = wm8731_set_dai_fmt,
429}; 421};
430 422
431struct snd_soc_dai wm8731_dai = { 423static struct snd_soc_dai_driver wm8731_dai = {
432 .name = "WM8731", 424 .name = "wm8731-hifi",
433 .playback = { 425 .playback = {
434 .stream_name = "Playback", 426 .stream_name = "Playback",
435 .channels_min = 1, 427 .channels_min = 1,
@@ -445,24 +437,17 @@ struct snd_soc_dai wm8731_dai = {
445 .ops = &wm8731_dai_ops, 437 .ops = &wm8731_dai_ops,
446 .symmetric_rates = 1, 438 .symmetric_rates = 1,
447}; 439};
448EXPORT_SYMBOL_GPL(wm8731_dai);
449 440
450#ifdef CONFIG_PM 441#ifdef CONFIG_PM
451static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 442static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state)
452{ 443{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
454 struct snd_soc_codec *codec = socdev->card->codec;
455
456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 444 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
457 445
458 return 0; 446 return 0;
459} 447}
460 448
461static int wm8731_resume(struct platform_device *pdev) 449static int wm8731_resume(struct snd_soc_codec *codec)
462{ 450{
463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
464 struct snd_soc_codec *codec = socdev->card->codec;
465
466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 451 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
467 452
468 return 0; 453 return 0;
@@ -472,88 +457,18 @@ static int wm8731_resume(struct platform_device *pdev)
472#define wm8731_resume NULL 457#define wm8731_resume NULL
473#endif 458#endif
474 459
475static int wm8731_probe(struct platform_device *pdev) 460static int wm8731_probe(struct snd_soc_codec *codec)
476{
477 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
478 struct snd_soc_codec *codec;
479 int ret = 0;
480
481 if (wm8731_codec == NULL) {
482 dev_err(&pdev->dev, "Codec device not registered\n");
483 return -ENODEV;
484 }
485
486 socdev->card->codec = wm8731_codec;
487 codec = wm8731_codec;
488
489 /* register pcms */
490 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
491 if (ret < 0) {
492 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
493 goto pcm_err;
494 }
495
496 snd_soc_add_controls(codec, wm8731_snd_controls,
497 ARRAY_SIZE(wm8731_snd_controls));
498 wm8731_add_widgets(codec);
499
500 return ret;
501
502pcm_err:
503 return ret;
504}
505
506/* power down chip */
507static int wm8731_remove(struct platform_device *pdev)
508{ 461{
509 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 462 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
510 463 int ret = 0, i;
511 snd_soc_free_pcms(socdev);
512 snd_soc_dapm_free(socdev);
513
514 return 0;
515}
516
517struct snd_soc_codec_device soc_codec_dev_wm8731 = {
518 .probe = wm8731_probe,
519 .remove = wm8731_remove,
520 .suspend = wm8731_suspend,
521 .resume = wm8731_resume,
522};
523EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
524
525static int wm8731_register(struct wm8731_priv *wm8731,
526 enum snd_soc_control_type control)
527{
528 int ret, i;
529 struct snd_soc_codec *codec = &wm8731->codec;
530
531 if (wm8731_codec) {
532 dev_err(codec->dev, "Another WM8731 is registered\n");
533 ret = -EINVAL;
534 goto err;
535 }
536
537 mutex_init(&codec->mutex);
538 INIT_LIST_HEAD(&codec->dapm_widgets);
539 INIT_LIST_HEAD(&codec->dapm_paths);
540
541 snd_soc_codec_set_drvdata(codec, wm8731);
542 codec->name = "WM8731";
543 codec->owner = THIS_MODULE;
544 codec->bias_level = SND_SOC_BIAS_OFF;
545 codec->set_bias_level = wm8731_set_bias_level;
546 codec->dai = &wm8731_dai;
547 codec->num_dai = 1;
548 codec->reg_cache_size = WM8731_CACHEREGNUM;
549 codec->reg_cache = &wm8731->reg_cache;
550 464
551 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); 465 codec->bias_level = SND_SOC_BIAS_OFF,
466 codec->control_data = wm8731->control_data;
552 467
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 468 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
554 if (ret < 0) { 469 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 470 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
556 goto err; 471 return ret;
557 } 472 }
558 473
559 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) 474 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
@@ -563,7 +478,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
563 wm8731->supplies); 478 wm8731->supplies);
564 if (ret != 0) { 479 if (ret != 0) {
565 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 480 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
566 goto err; 481 return ret;
567 } 482 }
568 483
569 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 484 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
@@ -579,8 +494,6 @@ static int wm8731_register(struct wm8731_priv *wm8731,
579 goto err_regulator_enable; 494 goto err_regulator_enable;
580 } 495 }
581 496
582 wm8731_dai.dev = codec->dev;
583
584 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 497 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
585 498
586 /* Latch the update bits */ 499 /* Latch the update bits */
@@ -592,78 +505,79 @@ static int wm8731_register(struct wm8731_priv *wm8731,
592 /* Disable bypass path by default */ 505 /* Disable bypass path by default */
593 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); 506 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
594 507
595 wm8731_codec = codec; 508 snd_soc_add_controls(codec, wm8731_snd_controls,
596 509 ARRAY_SIZE(wm8731_snd_controls));
597 ret = snd_soc_register_codec(codec); 510 wm8731_add_widgets(codec);
598 if (ret != 0) {
599 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
600 goto err_regulator_enable;
601 }
602
603 ret = snd_soc_register_dai(&wm8731_dai);
604 if (ret != 0) {
605 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
606 snd_soc_unregister_codec(codec);
607 goto err_codec;
608 }
609 511
610 /* Regulators will have been enabled by bias management */ 512 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 513 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612 514
613 return 0; 515 return 0;
614 516
615err_codec:
616 snd_soc_unregister_codec(codec);
617err_regulator_enable: 517err_regulator_enable:
618 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 518 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
619err_regulator_get: 519err_regulator_get:
620 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 520 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
621err: 521
622 kfree(wm8731); 522 kfree(wm8731);
623 return ret; 523 return ret;
624} 524}
625 525
626static void wm8731_unregister(struct wm8731_priv *wm8731) 526/* power down chip */
527static int wm8731_remove(struct snd_soc_codec *codec)
627{ 528{
628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 529 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
629 snd_soc_unregister_dai(&wm8731_dai); 530
630 snd_soc_unregister_codec(&wm8731->codec); 531 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
532
533 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 534 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 535
633 wm8731_codec = NULL; 536 return 0;
634} 537}
635 538
539static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
540 .probe = wm8731_probe,
541 .remove = wm8731_remove,
542 .suspend = wm8731_suspend,
543 .resume = wm8731_resume,
544 .set_bias_level = wm8731_set_bias_level,
545 .reg_cache_size = sizeof(wm8731_reg),
546 .reg_word_size = sizeof(u16),
547 .reg_cache_default = wm8731_reg,
548};
549
636#if defined(CONFIG_SPI_MASTER) 550#if defined(CONFIG_SPI_MASTER)
637static int __devinit wm8731_spi_probe(struct spi_device *spi) 551static int __devinit wm8731_spi_probe(struct spi_device *spi)
638{ 552{
639 struct snd_soc_codec *codec;
640 struct wm8731_priv *wm8731; 553 struct wm8731_priv *wm8731;
554 int ret;
641 555
642 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 556 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
643 if (wm8731 == NULL) 557 if (wm8731 == NULL)
644 return -ENOMEM; 558 return -ENOMEM;
645 559
646 codec = &wm8731->codec; 560 wm8731->control_data = spi;
647 codec->control_data = spi; 561 wm8731->control_type = SND_SOC_SPI;
648 codec->dev = &spi->dev; 562 spi_set_drvdata(spi, wm8731);
649
650 dev_set_drvdata(&spi->dev, wm8731);
651 563
652 return wm8731_register(wm8731, SND_SOC_SPI); 564 ret = snd_soc_register_codec(&spi->dev,
565 &soc_codec_dev_wm8731, &wm8731_dai, 1);
566 if (ret < 0)
567 kfree(wm8731);
568 return ret;
653} 569}
654 570
655static int __devexit wm8731_spi_remove(struct spi_device *spi) 571static int __devexit wm8731_spi_remove(struct spi_device *spi)
656{ 572{
657 struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); 573 snd_soc_unregister_codec(&spi->dev);
658 574 kfree(spi_get_drvdata(spi));
659 wm8731_unregister(wm8731);
660
661 return 0; 575 return 0;
662} 576}
663 577
664static struct spi_driver wm8731_spi_driver = { 578static struct spi_driver wm8731_spi_driver = {
665 .driver = { 579 .driver = {
666 .name = "wm8731", 580 .name = "wm8731-codec",
667 .bus = &spi_bus_type, 581 .bus = &spi_bus_type,
668 .owner = THIS_MODULE, 582 .owner = THIS_MODULE,
669 }, 583 },
@@ -677,26 +591,27 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
677 const struct i2c_device_id *id) 591 const struct i2c_device_id *id)
678{ 592{
679 struct wm8731_priv *wm8731; 593 struct wm8731_priv *wm8731;
680 struct snd_soc_codec *codec; 594 int ret;
681 595
682 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 596 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
683 if (wm8731 == NULL) 597 if (wm8731 == NULL)
684 return -ENOMEM; 598 return -ENOMEM;
685 599
686 codec = &wm8731->codec;
687
688 i2c_set_clientdata(i2c, wm8731); 600 i2c_set_clientdata(i2c, wm8731);
689 codec->control_data = i2c; 601 wm8731->control_data = i2c;
602 wm8731->control_type = SND_SOC_I2C;
690 603
691 codec->dev = &i2c->dev; 604 ret = snd_soc_register_codec(&i2c->dev,
692 605 &soc_codec_dev_wm8731, &wm8731_dai, 1);
693 return wm8731_register(wm8731, SND_SOC_I2C); 606 if (ret < 0)
607 kfree(wm8731);
608 return ret;
694} 609}
695 610
696static __devexit int wm8731_i2c_remove(struct i2c_client *client) 611static __devexit int wm8731_i2c_remove(struct i2c_client *client)
697{ 612{
698 struct wm8731_priv *wm8731 = i2c_get_clientdata(client); 613 snd_soc_unregister_codec(&client->dev);
699 wm8731_unregister(wm8731); 614 kfree(i2c_get_clientdata(client));
700 return 0; 615 return 0;
701} 616}
702 617
@@ -708,7 +623,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 623
709static struct i2c_driver wm8731_i2c_driver = { 624static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 625 .driver = {
711 .name = "wm8731", 626 .name = "wm8731-codec",
712 .owner = THIS_MODULE, 627 .owner = THIS_MODULE,
713 }, 628 },
714 .probe = wm8731_i2c_probe, 629 .probe = wm8731_i2c_probe,
@@ -719,7 +634,7 @@ static struct i2c_driver wm8731_i2c_driver = {
719 634
720static int __init wm8731_modinit(void) 635static int __init wm8731_modinit(void)
721{ 636{
722 int ret; 637 int ret = 0;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 638#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8731_i2c_driver); 639 ret = i2c_add_driver(&wm8731_i2c_driver);
725 if (ret != 0) { 640 if (ret != 0) {
@@ -734,7 +649,7 @@ static int __init wm8731_modinit(void)
734 ret); 649 ret);
735 } 650 }
736#endif 651#endif
737 return 0; 652 return ret;
738} 653}
739module_init(wm8731_modinit); 654module_init(wm8731_modinit);
740 655