diff options
-rw-r--r-- | sound/soc/atmel/sam9g20_wm8731.c | 43 | ||||
-rw-r--r-- | sound/soc/codecs/wm8731.c | 334 | ||||
-rw-r--r-- | sound/soc/codecs/wm8731.h | 6 | ||||
-rw-r--r-- | sound/soc/pxa/corgi.c | 43 | ||||
-rw-r--r-- | sound/soc/pxa/poodle.c | 41 |
5 files changed, 256 insertions, 211 deletions
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index aa524235fd98..173a239a541c 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/timer.h> | 36 | #include <linux/timer.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/i2c.h> | ||
39 | 40 | ||
40 | #include <linux/atmel-ssc.h> | 41 | #include <linux/atmel-ssc.h> |
41 | 42 | ||
@@ -280,15 +281,41 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { | |||
280 | .set_bias_level = at91sam9g20ek_set_bias_level, | 281 | .set_bias_level = at91sam9g20ek_set_bias_level, |
281 | }; | 282 | }; |
282 | 283 | ||
283 | static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = { | 284 | /* |
284 | .i2c_bus = 0, | 285 | * FIXME: This is a temporary bodge to avoid cross-tree merge issues. |
285 | .i2c_address = 0x1b, | 286 | * New drivers should register the wm8731 I2C device in the machine |
286 | }; | 287 | * setup code (under arch/arm for ARM systems). |
288 | */ | ||
289 | static int wm8731_i2c_register(void) | ||
290 | { | ||
291 | struct i2c_board_info info; | ||
292 | struct i2c_adapter *adapter; | ||
293 | struct i2c_client *client; | ||
294 | |||
295 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
296 | info.addr = 0x1b; | ||
297 | strlcpy(info.type, "wm8731", I2C_NAME_SIZE); | ||
298 | |||
299 | adapter = i2c_get_adapter(0); | ||
300 | if (!adapter) { | ||
301 | printk(KERN_ERR "can't get i2c adapter 0\n"); | ||
302 | return -ENODEV; | ||
303 | } | ||
304 | |||
305 | client = i2c_new_device(adapter, &info); | ||
306 | i2c_put_adapter(adapter); | ||
307 | if (!client) { | ||
308 | printk(KERN_ERR "can't add i2c device at 0x%x\n", | ||
309 | (unsigned int)info.addr); | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | |||
313 | return 0; | ||
314 | } | ||
287 | 315 | ||
288 | static struct snd_soc_device at91sam9g20ek_snd_devdata = { | 316 | static struct snd_soc_device at91sam9g20ek_snd_devdata = { |
289 | .card = &snd_soc_at91sam9g20ek, | 317 | .card = &snd_soc_at91sam9g20ek, |
290 | .codec_dev = &soc_codec_dev_wm8731, | 318 | .codec_dev = &soc_codec_dev_wm8731, |
291 | .codec_data = &at91sam9g20ek_wm8731_setup, | ||
292 | }; | 319 | }; |
293 | 320 | ||
294 | static struct platform_device *at91sam9g20ek_snd_device; | 321 | static struct platform_device *at91sam9g20ek_snd_device; |
@@ -340,6 +367,10 @@ static int __init at91sam9g20ek_init(void) | |||
340 | } | 367 | } |
341 | ssc_p->ssc = ssc; | 368 | ssc_p->ssc = ssc; |
342 | 369 | ||
370 | ret = wm8731_i2c_register(); | ||
371 | if (ret != 0) | ||
372 | goto err_ssc; | ||
373 | |||
343 | at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); | 374 | at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); |
344 | if (!at91sam9g20ek_snd_device) { | 375 | if (!at91sam9g20ek_snd_device) { |
345 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | 376 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); |
@@ -359,6 +390,8 @@ static int __init at91sam9g20ek_init(void) | |||
359 | return ret; | 390 | return ret; |
360 | 391 | ||
361 | err_ssc: | 392 | err_ssc: |
393 | ssc_free(ssc); | ||
394 | ssc_p->ssc = NULL; | ||
362 | err_mclk: | 395 | err_mclk: |
363 | clk_put(mclk); | 396 | clk_put(mclk); |
364 | mclk = NULL; | 397 | mclk = NULL; |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 3ff971aeba21..a2c478e53d54 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -29,16 +29,18 @@ | |||
29 | 29 | ||
30 | #include "wm8731.h" | 30 | #include "wm8731.h" |
31 | 31 | ||
32 | static struct snd_soc_codec *wm8731_codec; | ||
32 | struct snd_soc_codec_device soc_codec_dev_wm8731; | 33 | struct snd_soc_codec_device soc_codec_dev_wm8731; |
33 | 34 | ||
34 | /* codec private data */ | 35 | /* codec private data */ |
35 | struct wm8731_priv { | 36 | struct wm8731_priv { |
37 | struct snd_soc_codec codec; | ||
38 | u16 reg_cache[WM8731_CACHEREGNUM]; | ||
36 | unsigned int sysclk; | 39 | unsigned int sysclk; |
37 | }; | 40 | }; |
38 | 41 | ||
39 | #ifdef CONFIG_SPI_MASTER | 42 | #ifdef CONFIG_SPI_MASTER |
40 | static int wm8731_spi_write(struct spi_device *spi, const char *data, int len); | 43 | static int wm8731_spi_write(struct spi_device *spi, const char *data, int len); |
41 | static struct spi_driver wm8731_spi_driver; | ||
42 | #endif | 44 | #endif |
43 | 45 | ||
44 | /* | 46 | /* |
@@ -485,55 +487,33 @@ static int wm8731_resume(struct platform_device *pdev) | |||
485 | return 0; | 487 | return 0; |
486 | } | 488 | } |
487 | 489 | ||
488 | /* | 490 | static int wm8731_probe(struct platform_device *pdev) |
489 | * initialise the WM8731 driver | ||
490 | * register the mixer and dsp interfaces with the kernel | ||
491 | */ | ||
492 | static int wm8731_init(struct snd_soc_device *socdev) | ||
493 | { | 491 | { |
494 | struct snd_soc_codec *codec = socdev->card->codec; | 492 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
495 | int reg, ret = 0; | 493 | struct snd_soc_codec *codec; |
494 | int ret = 0; | ||
496 | 495 | ||
497 | codec->name = "WM8731"; | 496 | if (wm8731_codec == NULL) { |
498 | codec->owner = THIS_MODULE; | 497 | dev_err(&pdev->dev, "Codec device not registered\n"); |
499 | codec->read = wm8731_read_reg_cache; | 498 | return -ENODEV; |
500 | codec->write = wm8731_write; | 499 | } |
501 | codec->set_bias_level = wm8731_set_bias_level; | ||
502 | codec->dai = &wm8731_dai; | ||
503 | codec->num_dai = 1; | ||
504 | codec->reg_cache_size = ARRAY_SIZE(wm8731_reg); | ||
505 | codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL); | ||
506 | if (codec->reg_cache == NULL) | ||
507 | return -ENOMEM; | ||
508 | 500 | ||
509 | wm8731_reset(codec); | 501 | socdev->card->codec = wm8731_codec; |
502 | codec = wm8731_codec; | ||
510 | 503 | ||
511 | /* register pcms */ | 504 | /* register pcms */ |
512 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 505 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
513 | if (ret < 0) { | 506 | if (ret < 0) { |
514 | printk(KERN_ERR "wm8731: failed to create pcms\n"); | 507 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); |
515 | goto pcm_err; | 508 | goto pcm_err; |
516 | } | 509 | } |
517 | 510 | ||
518 | /* power on device */ | ||
519 | wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
520 | |||
521 | /* set the update bits */ | ||
522 | reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); | ||
523 | wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); | ||
524 | reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); | ||
525 | wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); | ||
526 | reg = wm8731_read_reg_cache(codec, WM8731_LINVOL); | ||
527 | wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100); | ||
528 | reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); | ||
529 | wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100); | ||
530 | |||
531 | snd_soc_add_controls(codec, wm8731_snd_controls, | 511 | snd_soc_add_controls(codec, wm8731_snd_controls, |
532 | ARRAY_SIZE(wm8731_snd_controls)); | 512 | ARRAY_SIZE(wm8731_snd_controls)); |
533 | wm8731_add_widgets(codec); | 513 | wm8731_add_widgets(codec); |
534 | ret = snd_soc_init_card(socdev); | 514 | ret = snd_soc_init_card(socdev); |
535 | if (ret < 0) { | 515 | if (ret < 0) { |
536 | printk(KERN_ERR "wm8731: failed to register card\n"); | 516 | dev_err(codec->dev, "failed to register card: %d\n", ret); |
537 | goto card_err; | 517 | goto card_err; |
538 | } | 518 | } |
539 | 519 | ||
@@ -543,104 +523,6 @@ card_err: | |||
543 | snd_soc_free_pcms(socdev); | 523 | snd_soc_free_pcms(socdev); |
544 | snd_soc_dapm_free(socdev); | 524 | snd_soc_dapm_free(socdev); |
545 | pcm_err: | 525 | pcm_err: |
546 | kfree(codec->reg_cache); | ||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | static struct snd_soc_device *wm8731_socdev; | ||
551 | |||
552 | |||
553 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
554 | static struct i2c_driver wm8731_i2c_driver; | ||
555 | |||
556 | static int wm8731_add_i2c_device(struct platform_device *pdev, | ||
557 | const struct wm8731_setup_data *setup) | ||
558 | { | ||
559 | struct i2c_board_info info; | ||
560 | struct i2c_adapter *adapter; | ||
561 | struct i2c_client *client; | ||
562 | int ret; | ||
563 | |||
564 | ret = i2c_add_driver(&wm8731_i2c_driver); | ||
565 | if (ret != 0) { | ||
566 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
567 | return ret; | ||
568 | } | ||
569 | |||
570 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
571 | info.addr = setup->i2c_address; | ||
572 | strlcpy(info.type, "wm8731", I2C_NAME_SIZE); | ||
573 | |||
574 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
575 | if (!adapter) { | ||
576 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
577 | setup->i2c_bus); | ||
578 | goto err_driver; | ||
579 | } | ||
580 | |||
581 | client = i2c_new_device(adapter, &info); | ||
582 | i2c_put_adapter(adapter); | ||
583 | if (!client) { | ||
584 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
585 | (unsigned int)info.addr); | ||
586 | goto err_driver; | ||
587 | } | ||
588 | |||
589 | return 0; | ||
590 | |||
591 | err_driver: | ||
592 | i2c_del_driver(&wm8731_i2c_driver); | ||
593 | return -ENODEV; | ||
594 | } | ||
595 | #endif | ||
596 | |||
597 | static int wm8731_probe(struct platform_device *pdev) | ||
598 | { | ||
599 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
600 | struct wm8731_setup_data *setup; | ||
601 | struct snd_soc_codec *codec; | ||
602 | struct wm8731_priv *wm8731; | ||
603 | int ret = 0; | ||
604 | |||
605 | setup = socdev->codec_data; | ||
606 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
607 | if (codec == NULL) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); | ||
611 | if (wm8731 == NULL) { | ||
612 | kfree(codec); | ||
613 | return -ENOMEM; | ||
614 | } | ||
615 | |||
616 | codec->private_data = wm8731; | ||
617 | socdev->card->codec = codec; | ||
618 | mutex_init(&codec->mutex); | ||
619 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
620 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
621 | |||
622 | wm8731_socdev = socdev; | ||
623 | ret = -ENODEV; | ||
624 | |||
625 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
626 | if (setup->i2c_address) { | ||
627 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
628 | ret = wm8731_add_i2c_device(pdev, setup); | ||
629 | } | ||
630 | #endif | ||
631 | #if defined(CONFIG_SPI_MASTER) | ||
632 | if (setup->spi) { | ||
633 | codec->hw_write = (hw_write_t)wm8731_spi_write; | ||
634 | ret = spi_register_driver(&wm8731_spi_driver); | ||
635 | if (ret != 0) | ||
636 | printk(KERN_ERR "can't add spi driver"); | ||
637 | } | ||
638 | #endif | ||
639 | |||
640 | if (ret != 0) { | ||
641 | kfree(codec->private_data); | ||
642 | kfree(codec); | ||
643 | } | ||
644 | return ret; | 526 | return ret; |
645 | } | 527 | } |
646 | 528 | ||
@@ -648,22 +530,9 @@ static int wm8731_probe(struct platform_device *pdev) | |||
648 | static int wm8731_remove(struct platform_device *pdev) | 530 | static int wm8731_remove(struct platform_device *pdev) |
649 | { | 531 | { |
650 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 532 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
651 | struct snd_soc_codec *codec = socdev->card->codec; | ||
652 | |||
653 | if (codec->control_data) | ||
654 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
655 | 533 | ||
656 | snd_soc_free_pcms(socdev); | 534 | snd_soc_free_pcms(socdev); |
657 | snd_soc_dapm_free(socdev); | 535 | snd_soc_dapm_free(socdev); |
658 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
659 | i2c_unregister_device(codec->control_data); | ||
660 | i2c_del_driver(&wm8731_i2c_driver); | ||
661 | #endif | ||
662 | #if defined(CONFIG_SPI_MASTER) | ||
663 | spi_unregister_driver(&wm8731_spi_driver); | ||
664 | #endif | ||
665 | kfree(codec->private_data); | ||
666 | kfree(codec); | ||
667 | 536 | ||
668 | return 0; | 537 | return 0; |
669 | } | 538 | } |
@@ -676,37 +545,78 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = { | |||
676 | }; | 545 | }; |
677 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); | 546 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); |
678 | 547 | ||
679 | #if defined(CONFIG_SPI_MASTER) | 548 | static int wm8731_register(struct wm8731_priv *wm8731) |
680 | static int __devinit wm8731_spi_probe(struct spi_device *spi) | ||
681 | { | 549 | { |
682 | struct snd_soc_device *socdev = wm8731_socdev; | ||
683 | struct snd_soc_codec *codec = socdev->card->codec; | ||
684 | int ret; | 550 | int ret; |
551 | struct snd_soc_codec *codec = &wm8731->codec; | ||
552 | u16 reg; | ||
685 | 553 | ||
686 | codec->control_data = spi; | 554 | if (wm8731_codec) { |
555 | dev_err(codec->dev, "Another WM8731 is registered\n"); | ||
556 | return -EINVAL; | ||
557 | } | ||
687 | 558 | ||
688 | ret = wm8731_init(socdev); | 559 | mutex_init(&codec->mutex); |
689 | if (ret < 0) | 560 | INIT_LIST_HEAD(&codec->dapm_widgets); |
690 | dev_err(&spi->dev, "failed to initialise WM8731\n"); | 561 | INIT_LIST_HEAD(&codec->dapm_paths); |
691 | 562 | ||
692 | return ret; | 563 | codec->private_data = wm8731; |
693 | } | 564 | codec->name = "WM8731"; |
565 | codec->owner = THIS_MODULE; | ||
566 | codec->read = wm8731_read_reg_cache; | ||
567 | codec->write = wm8731_write; | ||
568 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
569 | codec->set_bias_level = wm8731_set_bias_level; | ||
570 | codec->dai = &wm8731_dai; | ||
571 | codec->num_dai = 1; | ||
572 | codec->reg_cache_size = WM8731_CACHEREGNUM; | ||
573 | codec->reg_cache = &wm8731->reg_cache; | ||
574 | |||
575 | memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); | ||
576 | |||
577 | wm8731_dai.dev = codec->dev; | ||
578 | |||
579 | wm8731_reset(codec); | ||
580 | wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
581 | |||
582 | /* Latch the update bits */ | ||
583 | reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); | ||
584 | wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); | ||
585 | reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); | ||
586 | wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); | ||
587 | reg = wm8731_read_reg_cache(codec, WM8731_LINVOL); | ||
588 | wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100); | ||
589 | reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); | ||
590 | wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100); | ||
591 | |||
592 | wm8731_codec = codec; | ||
593 | |||
594 | ret = snd_soc_register_codec(codec); | ||
595 | if (ret != 0) { | ||
596 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | ret = snd_soc_register_dai(&wm8731_dai); | ||
601 | if (ret != 0) { | ||
602 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); | ||
603 | snd_soc_unregister_codec(codec); | ||
604 | return ret; | ||
605 | } | ||
694 | 606 | ||
695 | static int __devexit wm8731_spi_remove(struct spi_device *spi) | ||
696 | { | ||
697 | return 0; | 607 | return 0; |
698 | } | 608 | } |
699 | 609 | ||
700 | static struct spi_driver wm8731_spi_driver = { | 610 | static void wm8731_unregister(struct wm8731_priv *wm8731) |
701 | .driver = { | 611 | { |
702 | .name = "wm8731", | 612 | wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); |
703 | .bus = &spi_bus_type, | 613 | snd_soc_unregister_dai(&wm8731_dai); |
704 | .owner = THIS_MODULE, | 614 | snd_soc_unregister_codec(&wm8731->codec); |
705 | }, | 615 | kfree(wm8731); |
706 | .probe = wm8731_spi_probe, | 616 | wm8731_codec = NULL; |
707 | .remove = __devexit_p(wm8731_spi_remove), | 617 | } |
708 | }; | ||
709 | 618 | ||
619 | #if defined(CONFIG_SPI_MASTER) | ||
710 | static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) | 620 | static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) |
711 | { | 621 | { |
712 | struct spi_transfer t; | 622 | struct spi_transfer t; |
@@ -730,37 +640,67 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) | |||
730 | 640 | ||
731 | return len; | 641 | return len; |
732 | } | 642 | } |
643 | |||
644 | static int __devinit wm8731_spi_probe(struct spi_device *spi) | ||
645 | { | ||
646 | struct snd_soc_codec *codec; | ||
647 | struct wm8731_priv *wm8731; | ||
648 | |||
649 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); | ||
650 | if (wm8731 == NULL) | ||
651 | return -ENOMEM; | ||
652 | |||
653 | codec = &wm8731->codec; | ||
654 | codec->control_data = spi; | ||
655 | codec->hw_write = (hw_write_t)wm8731_spi_write; | ||
656 | codec->dev = &spi->dev; | ||
657 | |||
658 | return wm8731_register(wm8731); | ||
659 | } | ||
660 | |||
661 | static int __devexit wm8731_spi_remove(struct spi_device *spi) | ||
662 | { | ||
663 | /* FIXME: This isn't actually implemented... */ | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static struct spi_driver wm8731_spi_driver = { | ||
668 | .driver = { | ||
669 | .name = "wm8731", | ||
670 | .bus = &spi_bus_type, | ||
671 | .owner = THIS_MODULE, | ||
672 | }, | ||
673 | .probe = wm8731_spi_probe, | ||
674 | .remove = __devexit_p(wm8731_spi_remove), | ||
675 | }; | ||
733 | #endif /* CONFIG_SPI_MASTER */ | 676 | #endif /* CONFIG_SPI_MASTER */ |
734 | 677 | ||
735 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 678 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
736 | /* | ||
737 | * WM8731 2 wire address is determined by GPIO5 | ||
738 | * state during powerup. | ||
739 | * low = 0x1a | ||
740 | * high = 0x1b | ||
741 | */ | ||
742 | |||
743 | static int wm8731_i2c_probe(struct i2c_client *i2c, | 679 | static int wm8731_i2c_probe(struct i2c_client *i2c, |
744 | const struct i2c_device_id *id) | 680 | const struct i2c_device_id *id) |
745 | { | 681 | { |
746 | struct snd_soc_device *socdev = wm8731_socdev; | 682 | struct wm8731_priv *wm8731; |
747 | struct snd_soc_codec *codec = socdev->card->codec; | 683 | struct snd_soc_codec *codec; |
748 | int ret; | ||
749 | 684 | ||
750 | i2c_set_clientdata(i2c, codec); | 685 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); |
686 | if (wm8731 == NULL) | ||
687 | return -ENOMEM; | ||
688 | |||
689 | codec = &wm8731->codec; | ||
690 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
691 | |||
692 | i2c_set_clientdata(i2c, wm8731); | ||
751 | codec->control_data = i2c; | 693 | codec->control_data = i2c; |
752 | 694 | ||
753 | ret = wm8731_init(socdev); | 695 | codec->dev = &i2c->dev; |
754 | if (ret < 0) | ||
755 | pr_err("failed to initialise WM8731\n"); | ||
756 | 696 | ||
757 | return ret; | 697 | return wm8731_register(wm8731); |
758 | } | 698 | } |
759 | 699 | ||
760 | static int wm8731_i2c_remove(struct i2c_client *client) | 700 | static int wm8731_i2c_remove(struct i2c_client *client) |
761 | { | 701 | { |
762 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 702 | struct wm8731_priv *wm8731 = i2c_get_clientdata(client); |
763 | kfree(codec->reg_cache); | 703 | wm8731_unregister(wm8731); |
764 | return 0; | 704 | return 0; |
765 | } | 705 | } |
766 | 706 | ||
@@ -783,13 +723,33 @@ static struct i2c_driver wm8731_i2c_driver = { | |||
783 | 723 | ||
784 | static int __init wm8731_modinit(void) | 724 | static int __init wm8731_modinit(void) |
785 | { | 725 | { |
786 | return snd_soc_register_dai(&wm8731_dai); | 726 | int ret; |
727 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
728 | ret = i2c_add_driver(&wm8731_i2c_driver); | ||
729 | if (ret != 0) { | ||
730 | printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n", | ||
731 | ret); | ||
732 | } | ||
733 | #endif | ||
734 | #if defined(CONFIG_SPI_MASTER) | ||
735 | ret = spi_register_driver(&wm8731_spi_driver); | ||
736 | if (ret != 0) { | ||
737 | printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n", | ||
738 | ret); | ||
739 | } | ||
740 | #endif | ||
741 | return 0; | ||
787 | } | 742 | } |
788 | module_init(wm8731_modinit); | 743 | module_init(wm8731_modinit); |
789 | 744 | ||
790 | static void __exit wm8731_exit(void) | 745 | static void __exit wm8731_exit(void) |
791 | { | 746 | { |
792 | snd_soc_unregister_dai(&wm8731_dai); | 747 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
748 | i2c_del_driver(&wm8731_i2c_driver); | ||
749 | #endif | ||
750 | #if defined(CONFIG_SPI_MASTER) | ||
751 | spi_unregister_driver(&wm8731_spi_driver); | ||
752 | #endif | ||
793 | } | 753 | } |
794 | module_exit(wm8731_exit); | 754 | module_exit(wm8731_exit); |
795 | 755 | ||
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h index 95190e9c0c14..cd7b806e8ad0 100644 --- a/sound/soc/codecs/wm8731.h +++ b/sound/soc/codecs/wm8731.h | |||
@@ -34,12 +34,6 @@ | |||
34 | #define WM8731_SYSCLK 0 | 34 | #define WM8731_SYSCLK 0 |
35 | #define WM8731_DAI 0 | 35 | #define WM8731_DAI 0 |
36 | 36 | ||
37 | struct wm8731_setup_data { | ||
38 | int spi; | ||
39 | int i2c_bus; | ||
40 | unsigned short i2c_address; | ||
41 | }; | ||
42 | |||
43 | extern struct snd_soc_dai wm8731_dai; | 37 | extern struct snd_soc_dai wm8731_dai; |
44 | extern struct snd_soc_codec_device soc_codec_dev_wm8731; | 38 | extern struct snd_soc_codec_device soc_codec_dev_wm8731; |
45 | 39 | ||
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 0d41be33d572..eaa66915a324 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -317,19 +317,44 @@ static struct snd_soc_card snd_soc_corgi = { | |||
317 | .num_links = 1, | 317 | .num_links = 1, |
318 | }; | 318 | }; |
319 | 319 | ||
320 | /* corgi audio private data */ | ||
321 | static struct wm8731_setup_data corgi_wm8731_setup = { | ||
322 | .i2c_bus = 0, | ||
323 | .i2c_address = 0x1b, | ||
324 | }; | ||
325 | |||
326 | /* corgi audio subsystem */ | 320 | /* corgi audio subsystem */ |
327 | static struct snd_soc_device corgi_snd_devdata = { | 321 | static struct snd_soc_device corgi_snd_devdata = { |
328 | .card = &snd_soc_corgi, | 322 | .card = &snd_soc_corgi, |
329 | .codec_dev = &soc_codec_dev_wm8731, | 323 | .codec_dev = &soc_codec_dev_wm8731, |
330 | .codec_data = &corgi_wm8731_setup, | ||
331 | }; | 324 | }; |
332 | 325 | ||
326 | /* | ||
327 | * FIXME: This is a temporary bodge to avoid cross-tree merge issues. | ||
328 | * New drivers should register the wm8731 I2C device in the machine | ||
329 | * setup code (under arch/arm for ARM systems). | ||
330 | */ | ||
331 | static int wm8731_i2c_register(void) | ||
332 | { | ||
333 | struct i2c_board_info info; | ||
334 | struct i2c_adapter *adapter; | ||
335 | struct i2c_client *client; | ||
336 | |||
337 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
338 | info.addr = 0x1b; | ||
339 | strlcpy(info.type, "wm8731", I2C_NAME_SIZE); | ||
340 | |||
341 | adapter = i2c_get_adapter(0); | ||
342 | if (!adapter) { | ||
343 | printk(KERN_ERR "can't get i2c adapter 0\n"); | ||
344 | return -ENODEV; | ||
345 | } | ||
346 | |||
347 | client = i2c_new_device(adapter, &info); | ||
348 | i2c_put_adapter(adapter); | ||
349 | if (!client) { | ||
350 | printk(KERN_ERR "can't add i2c device at 0x%x\n", | ||
351 | (unsigned int)info.addr); | ||
352 | return -ENODEV; | ||
353 | } | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
333 | static struct platform_device *corgi_snd_device; | 358 | static struct platform_device *corgi_snd_device; |
334 | 359 | ||
335 | static int __init corgi_init(void) | 360 | static int __init corgi_init(void) |
@@ -340,6 +365,10 @@ static int __init corgi_init(void) | |||
340 | machine_is_husky())) | 365 | machine_is_husky())) |
341 | return -ENODEV; | 366 | return -ENODEV; |
342 | 367 | ||
368 | ret = wm8731_i2c_setup(); | ||
369 | if (ret != 0) | ||
370 | return ret; | ||
371 | |||
343 | corgi_snd_device = platform_device_alloc("soc-audio", -1); | 372 | corgi_snd_device = platform_device_alloc("soc-audio", -1); |
344 | if (!corgi_snd_device) | 373 | if (!corgi_snd_device) |
345 | return -ENOMEM; | 374 | return -ENOMEM; |
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 3a62d4354ef6..fd683a0b742d 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
@@ -283,17 +283,42 @@ static struct snd_soc_card snd_soc_poodle = { | |||
283 | .num_links = 1, | 283 | .num_links = 1, |
284 | }; | 284 | }; |
285 | 285 | ||
286 | /* poodle audio private data */ | 286 | /* |
287 | static struct wm8731_setup_data poodle_wm8731_setup = { | 287 | * FIXME: This is a temporary bodge to avoid cross-tree merge issues. |
288 | .i2c_bus = 0, | 288 | * New drivers should register the wm8731 I2C device in the machine |
289 | .i2c_address = 0x1b, | 289 | * setup code (under arch/arm for ARM systems). |
290 | }; | 290 | */ |
291 | static int wm8731_i2c_register(void) | ||
292 | { | ||
293 | struct i2c_board_info info; | ||
294 | struct i2c_adapter *adapter; | ||
295 | struct i2c_client *client; | ||
296 | |||
297 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
298 | info.addr = 0x1b; | ||
299 | strlcpy(info.type, "wm8731", I2C_NAME_SIZE); | ||
300 | |||
301 | adapter = i2c_get_adapter(0); | ||
302 | if (!adapter) { | ||
303 | printk(KERN_ERR "can't get i2c adapter 0\n"); | ||
304 | return -ENODEV; | ||
305 | } | ||
306 | |||
307 | client = i2c_new_device(adapter, &info); | ||
308 | i2c_put_adapter(adapter); | ||
309 | if (!client) { | ||
310 | printk(KERN_ERR "can't add i2c device at 0x%x\n", | ||
311 | (unsigned int)info.addr); | ||
312 | return -ENODEV; | ||
313 | } | ||
314 | |||
315 | return 0; | ||
316 | } | ||
291 | 317 | ||
292 | /* poodle audio subsystem */ | 318 | /* poodle audio subsystem */ |
293 | static struct snd_soc_device poodle_snd_devdata = { | 319 | static struct snd_soc_device poodle_snd_devdata = { |
294 | .card = &snd_soc_poodle, | 320 | .card = &snd_soc_poodle, |
295 | .codec_dev = &soc_codec_dev_wm8731, | 321 | .codec_dev = &soc_codec_dev_wm8731, |
296 | .codec_data = &poodle_wm8731_setup, | ||
297 | }; | 322 | }; |
298 | 323 | ||
299 | static struct platform_device *poodle_snd_device; | 324 | static struct platform_device *poodle_snd_device; |
@@ -305,6 +330,10 @@ static int __init poodle_init(void) | |||
305 | if (!machine_is_poodle()) | 330 | if (!machine_is_poodle()) |
306 | return -ENODEV; | 331 | return -ENODEV; |
307 | 332 | ||
333 | ret = wm8731_i2c_setup(); | ||
334 | if (ret != 0) | ||
335 | return ret; | ||
336 | |||
308 | locomo_gpio_set_dir(&poodle_locomo_device.dev, | 337 | locomo_gpio_set_dir(&poodle_locomo_device.dev, |
309 | POODLE_LOCOMO_GPIO_AMP_ON, 0); | 338 | POODLE_LOCOMO_GPIO_AMP_ON, 0); |
310 | /* should we mute HP at startup - burning power ?*/ | 339 | /* should we mute HP at startup - burning power ?*/ |