diff options
author | Philipp Zabel <philipp.zabel@gmail.com> | 2009-06-15 16:18:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-06-15 16:54:48 -0400 |
commit | 1abd91849990ed61d6468ffa8b7fc1ae61db4b1a (patch) | |
tree | 8922b2292765450fe3022c3ddbcea1cf848b9e2e | |
parent | b3b50b3f31775be5d2e441618bbc1c5cbee4d9f1 (diff) |
ASoC: UDA1380: refactor device registration
This patch mostly follows commit 5998102b9095fdb7c67755812038612afea315c5
"ASoC: Refactor WM8731 device registration" to make UDA1380 use standard
device instantiation. Similarly, the I2C device registration temporarily
moves into the magician machine driver before it will find its final
resting place in the board file.
At the same time, platform specific configuration is moved to platform data
and common power/reset GPIO handling moves into the codec driver.
Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | include/sound/uda1380.h | 22 | ||||
-rw-r--r-- | sound/soc/codecs/uda1380.c | 313 | ||||
-rw-r--r-- | sound/soc/codecs/uda1380.h | 8 | ||||
-rw-r--r-- | sound/soc/pxa/magician.c | 54 |
4 files changed, 221 insertions, 176 deletions
diff --git a/include/sound/uda1380.h b/include/sound/uda1380.h new file mode 100644 index 000000000000..381319c7000c --- /dev/null +++ b/include/sound/uda1380.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * UDA1380 ALSA SoC Codec driver | ||
3 | * | ||
4 | * Copyright 2009 Philipp Zabel | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __UDA1380_H | ||
12 | #define __UDA1380_H | ||
13 | |||
14 | struct uda1380_platform_data { | ||
15 | int gpio_power; | ||
16 | int gpio_reset; | ||
17 | int dac_clk; | ||
18 | #define UDA1380_DAC_CLK_SYSCLK 0 | ||
19 | #define UDA1380_DAC_CLK_WSPLL 1 | ||
20 | }; | ||
21 | |||
22 | #endif /* __UDA1380_H */ | ||
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 5b21594e0e58..92ec03442154 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -5,9 +5,7 @@ | |||
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | * | 7 | * |
8 | * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com> | 8 | * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel@gmail.com> |
9 | * Improved support for DAPM and audio routing/mixing capabilities, | ||
10 | * added TLV support. | ||
11 | * | 9 | * |
12 | * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC | 10 | * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC |
13 | * codec model. | 11 | * codec model. |
@@ -19,26 +17,32 @@ | |||
19 | #include <linux/module.h> | 17 | #include <linux/module.h> |
20 | #include <linux/init.h> | 18 | #include <linux/init.h> |
21 | #include <linux/types.h> | 19 | #include <linux/types.h> |
22 | #include <linux/string.h> | ||
23 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
24 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
25 | #include <linux/ioctl.h> | 22 | #include <linux/gpio.h> |
26 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
27 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
28 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
29 | #include <sound/core.h> | 26 | #include <sound/core.h> |
30 | #include <sound/control.h> | 27 | #include <sound/control.h> |
31 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
32 | #include <sound/info.h> | ||
33 | #include <sound/soc.h> | 29 | #include <sound/soc.h> |
34 | #include <sound/soc-dapm.h> | 30 | #include <sound/soc-dapm.h> |
35 | #include <sound/tlv.h> | 31 | #include <sound/tlv.h> |
32 | #include <sound/uda1380.h> | ||
36 | 33 | ||
37 | #include "uda1380.h" | 34 | #include "uda1380.h" |
38 | 35 | ||
39 | static struct work_struct uda1380_work; | ||
40 | static struct snd_soc_codec *uda1380_codec; | 36 | static struct snd_soc_codec *uda1380_codec; |
41 | 37 | ||
38 | /* codec private data */ | ||
39 | struct uda1380_priv { | ||
40 | struct snd_soc_codec codec; | ||
41 | u16 reg_cache[UDA1380_CACHEREGNUM]; | ||
42 | unsigned int dac_clk; | ||
43 | struct work_struct work; | ||
44 | }; | ||
45 | |||
42 | /* | 46 | /* |
43 | * uda1380 register cache | 47 | * uda1380 register cache |
44 | */ | 48 | */ |
@@ -473,6 +477,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd, | |||
473 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 477 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
474 | struct snd_soc_device *socdev = rtd->socdev; | 478 | struct snd_soc_device *socdev = rtd->socdev; |
475 | struct snd_soc_codec *codec = socdev->card->codec; | 479 | struct snd_soc_codec *codec = socdev->card->codec; |
480 | struct uda1380_priv *uda1380 = codec->private_data; | ||
476 | int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); | 481 | int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); |
477 | 482 | ||
478 | switch (cmd) { | 483 | switch (cmd) { |
@@ -480,13 +485,13 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd, | |||
480 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 485 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
481 | uda1380_write_reg_cache(codec, UDA1380_MIXER, | 486 | uda1380_write_reg_cache(codec, UDA1380_MIXER, |
482 | mixer & ~R14_SILENCE); | 487 | mixer & ~R14_SILENCE); |
483 | schedule_work(&uda1380_work); | 488 | schedule_work(&uda1380->work); |
484 | break; | 489 | break; |
485 | case SNDRV_PCM_TRIGGER_STOP: | 490 | case SNDRV_PCM_TRIGGER_STOP: |
486 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 491 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
487 | uda1380_write_reg_cache(codec, UDA1380_MIXER, | 492 | uda1380_write_reg_cache(codec, UDA1380_MIXER, |
488 | mixer | R14_SILENCE); | 493 | mixer | R14_SILENCE); |
489 | schedule_work(&uda1380_work); | 494 | schedule_work(&uda1380->work); |
490 | break; | 495 | break; |
491 | } | 496 | } |
492 | return 0; | 497 | return 0; |
@@ -670,44 +675,33 @@ static int uda1380_resume(struct platform_device *pdev) | |||
670 | return 0; | 675 | return 0; |
671 | } | 676 | } |
672 | 677 | ||
673 | /* | 678 | static int uda1380_probe(struct platform_device *pdev) |
674 | * initialise the UDA1380 driver | ||
675 | * register mixer and dsp interfaces with the kernel | ||
676 | */ | ||
677 | static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) | ||
678 | { | 679 | { |
679 | struct snd_soc_codec *codec = socdev->card->codec; | 680 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
681 | struct snd_soc_codec *codec; | ||
682 | struct uda1380_platform_data *pdata; | ||
680 | int ret = 0; | 683 | int ret = 0; |
681 | 684 | ||
682 | codec->name = "UDA1380"; | 685 | if (uda1380_codec == NULL) { |
683 | codec->owner = THIS_MODULE; | 686 | dev_err(&pdev->dev, "Codec device not registered\n"); |
684 | codec->read = uda1380_read_reg_cache; | 687 | return -ENODEV; |
685 | codec->write = uda1380_write; | 688 | } |
686 | codec->set_bias_level = uda1380_set_bias_level; | ||
687 | codec->dai = uda1380_dai; | ||
688 | codec->num_dai = ARRAY_SIZE(uda1380_dai); | ||
689 | codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg), | ||
690 | GFP_KERNEL); | ||
691 | if (codec->reg_cache == NULL) | ||
692 | return -ENOMEM; | ||
693 | codec->reg_cache_size = ARRAY_SIZE(uda1380_reg); | ||
694 | codec->reg_cache_step = 1; | ||
695 | uda1380_reset(codec); | ||
696 | 689 | ||
697 | uda1380_codec = codec; | 690 | socdev->card->codec = uda1380_codec; |
698 | INIT_WORK(&uda1380_work, uda1380_flush_work); | 691 | codec = uda1380_codec; |
692 | pdata = codec->dev->platform_data; | ||
699 | 693 | ||
700 | /* register pcms */ | 694 | /* register pcms */ |
701 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 695 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
702 | if (ret < 0) { | 696 | if (ret < 0) { |
703 | pr_err("uda1380: failed to create pcms\n"); | 697 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); |
704 | goto pcm_err; | 698 | goto pcm_err; |
705 | } | 699 | } |
706 | 700 | ||
707 | /* power on device */ | 701 | /* power on device */ |
708 | uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 702 | uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
709 | /* set clock input */ | 703 | /* set clock input */ |
710 | switch (dac_clk) { | 704 | switch (pdata->dac_clk) { |
711 | case UDA1380_DAC_CLK_SYSCLK: | 705 | case UDA1380_DAC_CLK_SYSCLK: |
712 | uda1380_write(codec, UDA1380_CLK, 0); | 706 | uda1380_write(codec, UDA1380_CLK, 0); |
713 | break; | 707 | break; |
@@ -716,13 +710,12 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) | |||
716 | break; | 710 | break; |
717 | } | 711 | } |
718 | 712 | ||
719 | /* uda1380 init */ | ||
720 | snd_soc_add_controls(codec, uda1380_snd_controls, | 713 | snd_soc_add_controls(codec, uda1380_snd_controls, |
721 | ARRAY_SIZE(uda1380_snd_controls)); | 714 | ARRAY_SIZE(uda1380_snd_controls)); |
722 | uda1380_add_widgets(codec); | 715 | uda1380_add_widgets(codec); |
723 | ret = snd_soc_init_card(socdev); | 716 | ret = snd_soc_init_card(socdev); |
724 | if (ret < 0) { | 717 | if (ret < 0) { |
725 | pr_err("uda1380: failed to register card\n"); | 718 | dev_err(codec->dev, "failed to register card: %d\n", ret); |
726 | goto card_err; | 719 | goto card_err; |
727 | } | 720 | } |
728 | 721 | ||
@@ -732,165 +725,201 @@ card_err: | |||
732 | snd_soc_free_pcms(socdev); | 725 | snd_soc_free_pcms(socdev); |
733 | snd_soc_dapm_free(socdev); | 726 | snd_soc_dapm_free(socdev); |
734 | pcm_err: | 727 | pcm_err: |
735 | kfree(codec->reg_cache); | ||
736 | return ret; | 728 | return ret; |
737 | } | 729 | } |
738 | 730 | ||
739 | static struct snd_soc_device *uda1380_socdev; | 731 | /* power down chip */ |
740 | 732 | static int uda1380_remove(struct platform_device *pdev) | |
741 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
742 | |||
743 | static int uda1380_i2c_probe(struct i2c_client *i2c, | ||
744 | const struct i2c_device_id *id) | ||
745 | { | 733 | { |
746 | struct snd_soc_device *socdev = uda1380_socdev; | 734 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
747 | struct uda1380_setup_data *setup = socdev->codec_data; | ||
748 | struct snd_soc_codec *codec = socdev->card->codec; | 735 | struct snd_soc_codec *codec = socdev->card->codec; |
749 | int ret; | ||
750 | |||
751 | i2c_set_clientdata(i2c, codec); | ||
752 | codec->control_data = i2c; | ||
753 | 736 | ||
754 | ret = uda1380_init(socdev, setup->dac_clk); | 737 | if (codec->control_data) |
755 | if (ret < 0) | 738 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); |
756 | pr_err("uda1380: failed to initialise UDA1380\n"); | ||
757 | 739 | ||
758 | return ret; | 740 | snd_soc_free_pcms(socdev); |
759 | } | 741 | snd_soc_dapm_free(socdev); |
760 | 742 | ||
761 | static int uda1380_i2c_remove(struct i2c_client *client) | ||
762 | { | ||
763 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | ||
764 | kfree(codec->reg_cache); | ||
765 | return 0; | 743 | return 0; |
766 | } | 744 | } |
767 | 745 | ||
768 | static const struct i2c_device_id uda1380_i2c_id[] = { | 746 | struct snd_soc_codec_device soc_codec_dev_uda1380 = { |
769 | { "uda1380", 0 }, | 747 | .probe = uda1380_probe, |
770 | { } | 748 | .remove = uda1380_remove, |
771 | }; | 749 | .suspend = uda1380_suspend, |
772 | MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); | 750 | .resume = uda1380_resume, |
773 | |||
774 | static struct i2c_driver uda1380_i2c_driver = { | ||
775 | .driver = { | ||
776 | .name = "UDA1380 I2C Codec", | ||
777 | .owner = THIS_MODULE, | ||
778 | }, | ||
779 | .probe = uda1380_i2c_probe, | ||
780 | .remove = uda1380_i2c_remove, | ||
781 | .id_table = uda1380_i2c_id, | ||
782 | }; | 751 | }; |
752 | EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); | ||
783 | 753 | ||
784 | static int uda1380_add_i2c_device(struct platform_device *pdev, | 754 | static int uda1380_register(struct uda1380_priv *uda1380) |
785 | const struct uda1380_setup_data *setup) | ||
786 | { | 755 | { |
787 | struct i2c_board_info info; | 756 | int ret, i; |
788 | struct i2c_adapter *adapter; | 757 | struct snd_soc_codec *codec = &uda1380->codec; |
789 | struct i2c_client *client; | 758 | struct uda1380_platform_data *pdata = codec->dev->platform_data; |
790 | int ret; | ||
791 | 759 | ||
792 | ret = i2c_add_driver(&uda1380_i2c_driver); | 760 | if (uda1380_codec) { |
793 | if (ret != 0) { | 761 | dev_err(codec->dev, "Another UDA1380 is registered\n"); |
794 | dev_err(&pdev->dev, "can't add i2c driver\n"); | 762 | return -EINVAL; |
795 | return ret; | 763 | } |
764 | |||
765 | if (!pdata || !pdata->gpio_power || !pdata->gpio_reset) | ||
766 | return -EINVAL; | ||
767 | |||
768 | ret = gpio_request(pdata->gpio_power, "uda1380 power"); | ||
769 | if (ret) | ||
770 | goto err_out; | ||
771 | ret = gpio_request(pdata->gpio_reset, "uda1380 reset"); | ||
772 | if (ret) | ||
773 | goto err_gpio; | ||
774 | |||
775 | gpio_direction_output(pdata->gpio_power, 1); | ||
776 | |||
777 | /* we may need to have the clock running here - pH5 */ | ||
778 | gpio_direction_output(pdata->gpio_reset, 1); | ||
779 | udelay(5); | ||
780 | gpio_set_value(pdata->gpio_reset, 0); | ||
781 | |||
782 | mutex_init(&codec->mutex); | ||
783 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
784 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
785 | |||
786 | codec->private_data = uda1380; | ||
787 | codec->name = "UDA1380"; | ||
788 | codec->owner = THIS_MODULE; | ||
789 | codec->read = uda1380_read_reg_cache; | ||
790 | codec->write = uda1380_write; | ||
791 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
792 | codec->set_bias_level = uda1380_set_bias_level; | ||
793 | codec->dai = uda1380_dai; | ||
794 | codec->num_dai = ARRAY_SIZE(uda1380_dai); | ||
795 | codec->reg_cache_size = ARRAY_SIZE(uda1380_reg); | ||
796 | codec->reg_cache = &uda1380->reg_cache; | ||
797 | codec->reg_cache_step = 1; | ||
798 | |||
799 | memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg)); | ||
800 | |||
801 | ret = uda1380_reset(codec); | ||
802 | if (ret < 0) { | ||
803 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
804 | goto err_reset; | ||
796 | } | 805 | } |
797 | 806 | ||
798 | memset(&info, 0, sizeof(struct i2c_board_info)); | 807 | INIT_WORK(&uda1380->work, uda1380_flush_work); |
799 | info.addr = setup->i2c_address; | 808 | |
800 | strlcpy(info.type, "uda1380", I2C_NAME_SIZE); | 809 | for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++) |
810 | uda1380_dai[i].dev = codec->dev; | ||
801 | 811 | ||
802 | adapter = i2c_get_adapter(setup->i2c_bus); | 812 | uda1380_codec = codec; |
803 | if (!adapter) { | 813 | |
804 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | 814 | ret = snd_soc_register_codec(codec); |
805 | setup->i2c_bus); | 815 | if (ret != 0) { |
806 | goto err_driver; | 816 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); |
817 | goto err_reset; | ||
807 | } | 818 | } |
808 | 819 | ||
809 | client = i2c_new_device(adapter, &info); | 820 | ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); |
810 | i2c_put_adapter(adapter); | 821 | if (ret != 0) { |
811 | if (!client) { | 822 | dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); |
812 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | 823 | goto err_dai; |
813 | (unsigned int)info.addr); | ||
814 | goto err_driver; | ||
815 | } | 824 | } |
816 | 825 | ||
817 | return 0; | 826 | return 0; |
818 | 827 | ||
819 | err_driver: | 828 | err_dai: |
820 | i2c_del_driver(&uda1380_i2c_driver); | 829 | snd_soc_unregister_codec(codec); |
821 | return -ENODEV; | 830 | err_reset: |
831 | gpio_set_value(pdata->gpio_power, 0); | ||
832 | gpio_free(pdata->gpio_reset); | ||
833 | err_gpio: | ||
834 | gpio_free(pdata->gpio_power); | ||
835 | err_out: | ||
836 | return ret; | ||
822 | } | 837 | } |
823 | #endif | ||
824 | 838 | ||
825 | static int uda1380_probe(struct platform_device *pdev) | 839 | static void uda1380_unregister(struct uda1380_priv *uda1380) |
826 | { | 840 | { |
827 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 841 | struct snd_soc_codec *codec = &uda1380->codec; |
828 | struct uda1380_setup_data *setup; | 842 | struct uda1380_platform_data *pdata = codec->dev->platform_data; |
843 | |||
844 | snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); | ||
845 | snd_soc_unregister_codec(&uda1380->codec); | ||
846 | |||
847 | gpio_set_value(pdata->gpio_power, 0); | ||
848 | gpio_free(pdata->gpio_reset); | ||
849 | gpio_free(pdata->gpio_power); | ||
850 | |||
851 | kfree(uda1380); | ||
852 | uda1380_codec = NULL; | ||
853 | } | ||
854 | |||
855 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
856 | static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, | ||
857 | const struct i2c_device_id *id) | ||
858 | { | ||
859 | struct uda1380_priv *uda1380; | ||
829 | struct snd_soc_codec *codec; | 860 | struct snd_soc_codec *codec; |
830 | int ret; | 861 | int ret; |
831 | 862 | ||
832 | setup = socdev->codec_data; | 863 | uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); |
833 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 864 | if (uda1380 == NULL) |
834 | if (codec == NULL) | ||
835 | return -ENOMEM; | 865 | return -ENOMEM; |
836 | 866 | ||
837 | socdev->card->codec = codec; | 867 | codec = &uda1380->codec; |
838 | mutex_init(&codec->mutex); | 868 | codec->hw_write = (hw_write_t)i2c_master_send; |
839 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
840 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
841 | 869 | ||
842 | uda1380_socdev = socdev; | 870 | i2c_set_clientdata(i2c, uda1380); |
843 | ret = -ENODEV; | 871 | codec->control_data = i2c; |
844 | 872 | ||
845 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 873 | codec->dev = &i2c->dev; |
846 | if (setup->i2c_address) { | ||
847 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
848 | ret = uda1380_add_i2c_device(pdev, setup); | ||
849 | } | ||
850 | #endif | ||
851 | 874 | ||
875 | ret = uda1380_register(uda1380); | ||
852 | if (ret != 0) | 876 | if (ret != 0) |
853 | kfree(codec); | 877 | kfree(uda1380); |
878 | |||
854 | return ret; | 879 | return ret; |
855 | } | 880 | } |
856 | 881 | ||
857 | /* power down chip */ | 882 | static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) |
858 | static int uda1380_remove(struct platform_device *pdev) | ||
859 | { | 883 | { |
860 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 884 | struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c); |
861 | struct snd_soc_codec *codec = socdev->card->codec; | 885 | uda1380_unregister(uda1380); |
862 | |||
863 | if (codec->control_data) | ||
864 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
865 | |||
866 | snd_soc_free_pcms(socdev); | ||
867 | snd_soc_dapm_free(socdev); | ||
868 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
869 | i2c_unregister_device(codec->control_data); | ||
870 | i2c_del_driver(&uda1380_i2c_driver); | ||
871 | #endif | ||
872 | kfree(codec); | ||
873 | |||
874 | return 0; | 886 | return 0; |
875 | } | 887 | } |
876 | 888 | ||
877 | struct snd_soc_codec_device soc_codec_dev_uda1380 = { | 889 | static const struct i2c_device_id uda1380_i2c_id[] = { |
878 | .probe = uda1380_probe, | 890 | { "uda1380", 0 }, |
879 | .remove = uda1380_remove, | 891 | { } |
880 | .suspend = uda1380_suspend, | ||
881 | .resume = uda1380_resume, | ||
882 | }; | 892 | }; |
883 | EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); | 893 | MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); |
894 | |||
895 | static struct i2c_driver uda1380_i2c_driver = { | ||
896 | .driver = { | ||
897 | .name = "UDA1380 I2C Codec", | ||
898 | .owner = THIS_MODULE, | ||
899 | }, | ||
900 | .probe = uda1380_i2c_probe, | ||
901 | .remove = __devexit_p(uda1380_i2c_remove), | ||
902 | .id_table = uda1380_i2c_id, | ||
903 | }; | ||
904 | #endif | ||
884 | 905 | ||
885 | static int __init uda1380_modinit(void) | 906 | static int __init uda1380_modinit(void) |
886 | { | 907 | { |
887 | return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); | 908 | int ret; |
909 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
910 | ret = i2c_add_driver(&uda1380_i2c_driver); | ||
911 | if (ret != 0) | ||
912 | pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); | ||
913 | #endif | ||
914 | return 0; | ||
888 | } | 915 | } |
889 | module_init(uda1380_modinit); | 916 | module_init(uda1380_modinit); |
890 | 917 | ||
891 | static void __exit uda1380_exit(void) | 918 | static void __exit uda1380_exit(void) |
892 | { | 919 | { |
893 | snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); | 920 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
921 | i2c_del_driver(&uda1380_i2c_driver); | ||
922 | #endif | ||
894 | } | 923 | } |
895 | module_exit(uda1380_exit); | 924 | module_exit(uda1380_exit); |
896 | 925 | ||
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h index c55c17a52a12..9cefa8a54770 100644 --- a/sound/soc/codecs/uda1380.h +++ b/sound/soc/codecs/uda1380.h | |||
@@ -72,14 +72,6 @@ | |||
72 | #define R22_SKIP_DCFIL 0x0002 | 72 | #define R22_SKIP_DCFIL 0x0002 |
73 | #define R23_AGC_EN 0x0001 | 73 | #define R23_AGC_EN 0x0001 |
74 | 74 | ||
75 | struct uda1380_setup_data { | ||
76 | int i2c_bus; | ||
77 | unsigned short i2c_address; | ||
78 | int dac_clk; | ||
79 | #define UDA1380_DAC_CLK_SYSCLK 0 | ||
80 | #define UDA1380_DAC_CLK_WSPLL 1 | ||
81 | }; | ||
82 | |||
83 | #define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */ | 75 | #define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */ |
84 | #define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ | 76 | #define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ |
85 | #define UDA1380_DAI_CAPTURE 2 /* capture DAI */ | 77 | #define UDA1380_DAI_CAPTURE 2 /* capture DAI */ |
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index c89a3cdf31e4..9fe4ad20615c 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c | |||
@@ -20,12 +20,14 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/i2c.h> | ||
23 | 24 | ||
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
26 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
27 | #include <sound/soc.h> | 28 | #include <sound/soc.h> |
28 | #include <sound/soc-dapm.h> | 29 | #include <sound/soc-dapm.h> |
30 | #include <sound/uda1380.h> | ||
29 | 31 | ||
30 | #include <mach/magician.h> | 32 | #include <mach/magician.h> |
31 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
@@ -447,34 +449,47 @@ static struct snd_soc_card snd_soc_card_magician = { | |||
447 | .platform = &pxa2xx_soc_platform, | 449 | .platform = &pxa2xx_soc_platform, |
448 | }; | 450 | }; |
449 | 451 | ||
450 | /* magician audio private data */ | ||
451 | static struct uda1380_setup_data magician_uda1380_setup = { | ||
452 | .i2c_address = 0x18, | ||
453 | .dac_clk = UDA1380_DAC_CLK_WSPLL, | ||
454 | }; | ||
455 | |||
456 | /* magician audio subsystem */ | 452 | /* magician audio subsystem */ |
457 | static struct snd_soc_device magician_snd_devdata = { | 453 | static struct snd_soc_device magician_snd_devdata = { |
458 | .card = &snd_soc_card_magician, | 454 | .card = &snd_soc_card_magician, |
459 | .codec_dev = &soc_codec_dev_uda1380, | 455 | .codec_dev = &soc_codec_dev_uda1380, |
460 | .codec_data = &magician_uda1380_setup, | ||
461 | }; | 456 | }; |
462 | 457 | ||
463 | static struct platform_device *magician_snd_device; | 458 | static struct platform_device *magician_snd_device; |
464 | 459 | ||
460 | /* | ||
461 | * FIXME: move into magician board file once merged into the pxa tree | ||
462 | */ | ||
463 | static struct uda1380_platform_data uda1380_info = { | ||
464 | .gpio_power = EGPIO_MAGICIAN_CODEC_POWER, | ||
465 | .gpio_reset = EGPIO_MAGICIAN_CODEC_RESET, | ||
466 | .dac_clk = UDA1380_DAC_CLK_WSPLL, | ||
467 | }; | ||
468 | |||
469 | static struct i2c_board_info i2c_board_info[] = { | ||
470 | { | ||
471 | I2C_BOARD_INFO("uda1380", 0x18), | ||
472 | .platform_data = &uda1380_info, | ||
473 | }, | ||
474 | }; | ||
475 | |||
465 | static int __init magician_init(void) | 476 | static int __init magician_init(void) |
466 | { | 477 | { |
467 | int ret; | 478 | int ret; |
479 | struct i2c_adapter *adapter; | ||
480 | struct i2c_client *client; | ||
468 | 481 | ||
469 | if (!machine_is_magician()) | 482 | if (!machine_is_magician()) |
470 | return -ENODEV; | 483 | return -ENODEV; |
471 | 484 | ||
472 | ret = gpio_request(EGPIO_MAGICIAN_CODEC_POWER, "CODEC_POWER"); | 485 | adapter = i2c_get_adapter(0); |
473 | if (ret) | 486 | if (!adapter) |
474 | goto err_request_power; | 487 | return -ENODEV; |
475 | ret = gpio_request(EGPIO_MAGICIAN_CODEC_RESET, "CODEC_RESET"); | 488 | client = i2c_new_device(adapter, i2c_board_info); |
476 | if (ret) | 489 | i2c_put_adapter(adapter); |
477 | goto err_request_reset; | 490 | if (!client) |
491 | return -ENODEV; | ||
492 | |||
478 | ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER"); | 493 | ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER"); |
479 | if (ret) | 494 | if (ret) |
480 | goto err_request_spk; | 495 | goto err_request_spk; |
@@ -491,14 +506,8 @@ static int __init magician_init(void) | |||
491 | if (ret) | 506 | if (ret) |
492 | goto err_request_in_sel1; | 507 | goto err_request_in_sel1; |
493 | 508 | ||
494 | gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 1); | ||
495 | gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0); | 509 | gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0); |
496 | 510 | ||
497 | /* we may need to have the clock running here - pH5 */ | ||
498 | gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 1); | ||
499 | udelay(5); | ||
500 | gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 0); | ||
501 | |||
502 | magician_snd_device = platform_device_alloc("soc-audio", -1); | 511 | magician_snd_device = platform_device_alloc("soc-audio", -1); |
503 | if (!magician_snd_device) { | 512 | if (!magician_snd_device) { |
504 | ret = -ENOMEM; | 513 | ret = -ENOMEM; |
@@ -526,10 +535,6 @@ err_request_mic: | |||
526 | err_request_ep: | 535 | err_request_ep: |
527 | gpio_free(EGPIO_MAGICIAN_SPK_POWER); | 536 | gpio_free(EGPIO_MAGICIAN_SPK_POWER); |
528 | err_request_spk: | 537 | err_request_spk: |
529 | gpio_free(EGPIO_MAGICIAN_CODEC_RESET); | ||
530 | err_request_reset: | ||
531 | gpio_free(EGPIO_MAGICIAN_CODEC_POWER); | ||
532 | err_request_power: | ||
533 | return ret; | 538 | return ret; |
534 | } | 539 | } |
535 | 540 | ||
@@ -540,15 +545,12 @@ static void __exit magician_exit(void) | |||
540 | gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0); | 545 | gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0); |
541 | gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0); | 546 | gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0); |
542 | gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0); | 547 | gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0); |
543 | gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 0); | ||
544 | 548 | ||
545 | gpio_free(EGPIO_MAGICIAN_IN_SEL1); | 549 | gpio_free(EGPIO_MAGICIAN_IN_SEL1); |
546 | gpio_free(EGPIO_MAGICIAN_IN_SEL0); | 550 | gpio_free(EGPIO_MAGICIAN_IN_SEL0); |
547 | gpio_free(EGPIO_MAGICIAN_MIC_POWER); | 551 | gpio_free(EGPIO_MAGICIAN_MIC_POWER); |
548 | gpio_free(EGPIO_MAGICIAN_EP_POWER); | 552 | gpio_free(EGPIO_MAGICIAN_EP_POWER); |
549 | gpio_free(EGPIO_MAGICIAN_SPK_POWER); | 553 | gpio_free(EGPIO_MAGICIAN_SPK_POWER); |
550 | gpio_free(EGPIO_MAGICIAN_CODEC_RESET); | ||
551 | gpio_free(EGPIO_MAGICIAN_CODEC_POWER); | ||
552 | } | 554 | } |
553 | 555 | ||
554 | module_init(magician_init); | 556 | module_init(magician_init); |