diff options
Diffstat (limited to 'sound/soc/codecs/wm8510.c')
-rw-r--r-- | sound/soc/codecs/wm8510.c | 112 |
1 files changed, 54 insertions, 58 deletions
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 3d998e6a997e..9a37c8d95ed2 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -199,7 +199,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_MONOMIX, 0, 1, 0), | |||
199 | }; | 199 | }; |
200 | 200 | ||
201 | static const struct snd_kcontrol_new wm8510_boost_controls[] = { | 201 | static const struct snd_kcontrol_new wm8510_boost_controls[] = { |
202 | SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 0), | 202 | SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 1), |
203 | SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0), | 203 | SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0), |
204 | SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0), | 204 | SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0), |
205 | }; | 205 | }; |
@@ -665,88 +665,86 @@ static struct snd_soc_device *wm8510_socdev; | |||
665 | /* | 665 | /* |
666 | * WM8510 2 wire address is 0x1a | 666 | * WM8510 2 wire address is 0x1a |
667 | */ | 667 | */ |
668 | #define I2C_DRIVERID_WM8510 0xfefe /* liam - need a proper id */ | ||
669 | 668 | ||
670 | static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; | 669 | static int wm8510_i2c_probe(struct i2c_client *i2c, |
671 | 670 | const struct i2c_device_id *id) | |
672 | /* Magic definition of all other variables and things */ | ||
673 | I2C_CLIENT_INSMOD; | ||
674 | |||
675 | static struct i2c_driver wm8510_i2c_driver; | ||
676 | static struct i2c_client client_template; | ||
677 | |||
678 | /* If the i2c layer weren't so broken, we could pass this kind of data | ||
679 | around */ | ||
680 | |||
681 | static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind) | ||
682 | { | 671 | { |
683 | struct snd_soc_device *socdev = wm8510_socdev; | 672 | struct snd_soc_device *socdev = wm8510_socdev; |
684 | struct wm8510_setup_data *setup = socdev->codec_data; | ||
685 | struct snd_soc_codec *codec = socdev->codec; | 673 | struct snd_soc_codec *codec = socdev->codec; |
686 | struct i2c_client *i2c; | ||
687 | int ret; | 674 | int ret; |
688 | 675 | ||
689 | if (addr != setup->i2c_address) | ||
690 | return -ENODEV; | ||
691 | |||
692 | client_template.adapter = adap; | ||
693 | client_template.addr = addr; | ||
694 | |||
695 | i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); | ||
696 | if (i2c == NULL) | ||
697 | return -ENOMEM; | ||
698 | |||
699 | i2c_set_clientdata(i2c, codec); | 676 | i2c_set_clientdata(i2c, codec); |
700 | codec->control_data = i2c; | 677 | codec->control_data = i2c; |
701 | 678 | ||
702 | ret = i2c_attach_client(i2c); | ||
703 | if (ret < 0) { | ||
704 | pr_err("failed to attach codec at addr %x\n", addr); | ||
705 | goto err; | ||
706 | } | ||
707 | |||
708 | ret = wm8510_init(socdev); | 679 | ret = wm8510_init(socdev); |
709 | if (ret < 0) { | 680 | if (ret < 0) |
710 | pr_err("failed to initialise WM8510\n"); | 681 | pr_err("failed to initialise WM8510\n"); |
711 | goto err; | ||
712 | } | ||
713 | return ret; | ||
714 | 682 | ||
715 | err: | ||
716 | kfree(i2c); | ||
717 | return ret; | 683 | return ret; |
718 | } | 684 | } |
719 | 685 | ||
720 | static int wm8510_i2c_detach(struct i2c_client *client) | 686 | static int wm8510_i2c_remove(struct i2c_client *client) |
721 | { | 687 | { |
722 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 688 | struct snd_soc_codec *codec = i2c_get_clientdata(client); |
723 | i2c_detach_client(client); | ||
724 | kfree(codec->reg_cache); | 689 | kfree(codec->reg_cache); |
725 | kfree(client); | ||
726 | return 0; | 690 | return 0; |
727 | } | 691 | } |
728 | 692 | ||
729 | static int wm8510_i2c_attach(struct i2c_adapter *adap) | 693 | static const struct i2c_device_id wm8510_i2c_id[] = { |
730 | { | 694 | { "wm8510", 0 }, |
731 | return i2c_probe(adap, &addr_data, wm8510_codec_probe); | 695 | { } |
732 | } | 696 | }; |
697 | MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id); | ||
733 | 698 | ||
734 | /* corgi i2c codec control layer */ | ||
735 | static struct i2c_driver wm8510_i2c_driver = { | 699 | static struct i2c_driver wm8510_i2c_driver = { |
736 | .driver = { | 700 | .driver = { |
737 | .name = "WM8510 I2C Codec", | 701 | .name = "WM8510 I2C Codec", |
738 | .owner = THIS_MODULE, | 702 | .owner = THIS_MODULE, |
739 | }, | 703 | }, |
740 | .id = I2C_DRIVERID_WM8510, | 704 | .probe = wm8510_i2c_probe, |
741 | .attach_adapter = wm8510_i2c_attach, | 705 | .remove = wm8510_i2c_remove, |
742 | .detach_client = wm8510_i2c_detach, | 706 | .id_table = wm8510_i2c_id, |
743 | .command = NULL, | ||
744 | }; | 707 | }; |
745 | 708 | ||
746 | static struct i2c_client client_template = { | 709 | static int wm8510_add_i2c_device(struct platform_device *pdev, |
747 | .name = "WM8510", | 710 | const struct wm8510_setup_data *setup) |
748 | .driver = &wm8510_i2c_driver, | 711 | { |
749 | }; | 712 | struct i2c_board_info info; |
713 | struct i2c_adapter *adapter; | ||
714 | struct i2c_client *client; | ||
715 | int ret; | ||
716 | |||
717 | ret = i2c_add_driver(&wm8510_i2c_driver); | ||
718 | if (ret != 0) { | ||
719 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
724 | info.addr = setup->i2c_address; | ||
725 | strlcpy(info.type, "wm8510", I2C_NAME_SIZE); | ||
726 | |||
727 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
728 | if (!adapter) { | ||
729 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
730 | setup->i2c_bus); | ||
731 | goto err_driver; | ||
732 | } | ||
733 | |||
734 | client = i2c_new_device(adapter, &info); | ||
735 | i2c_put_adapter(adapter); | ||
736 | if (!client) { | ||
737 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
738 | (unsigned int)info.addr); | ||
739 | goto err_driver; | ||
740 | } | ||
741 | |||
742 | return 0; | ||
743 | |||
744 | err_driver: | ||
745 | i2c_del_driver(&wm8510_i2c_driver); | ||
746 | return -ENODEV; | ||
747 | } | ||
750 | #endif | 748 | #endif |
751 | 749 | ||
752 | static int wm8510_probe(struct platform_device *pdev) | 750 | static int wm8510_probe(struct platform_device *pdev) |
@@ -771,11 +769,8 @@ static int wm8510_probe(struct platform_device *pdev) | |||
771 | wm8510_socdev = socdev; | 769 | wm8510_socdev = socdev; |
772 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 770 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
773 | if (setup->i2c_address) { | 771 | if (setup->i2c_address) { |
774 | normal_i2c[0] = setup->i2c_address; | ||
775 | codec->hw_write = (hw_write_t)i2c_master_send; | 772 | codec->hw_write = (hw_write_t)i2c_master_send; |
776 | ret = i2c_add_driver(&wm8510_i2c_driver); | 773 | ret = wm8510_add_i2c_device(pdev, setup); |
777 | if (ret != 0) | ||
778 | printk(KERN_ERR "can't add i2c driver"); | ||
779 | } | 774 | } |
780 | #else | 775 | #else |
781 | /* Add other interfaces here */ | 776 | /* Add other interfaces here */ |
@@ -798,6 +793,7 @@ static int wm8510_remove(struct platform_device *pdev) | |||
798 | snd_soc_free_pcms(socdev); | 793 | snd_soc_free_pcms(socdev); |
799 | snd_soc_dapm_free(socdev); | 794 | snd_soc_dapm_free(socdev); |
800 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 795 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
796 | i2c_unregister_device(codec->control_data); | ||
801 | i2c_del_driver(&wm8510_i2c_driver); | 797 | i2c_del_driver(&wm8510_i2c_driver); |
802 | #endif | 798 | #endif |
803 | kfree(codec); | 799 | kfree(codec); |