aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8510.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8510.c')
-rw-r--r--sound/soc/codecs/wm8510.c112
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
201static const struct snd_kcontrol_new wm8510_boost_controls[] = { 201static const struct snd_kcontrol_new wm8510_boost_controls[] = {
202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 0), 202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 1),
203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0), 203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0),
204SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0), 204SOC_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
670static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 669static 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 */
673I2C_CLIENT_INSMOD;
674
675static struct i2c_driver wm8510_i2c_driver;
676static 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
681static 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
715err:
716 kfree(i2c);
717 return ret; 683 return ret;
718} 684}
719 685
720static int wm8510_i2c_detach(struct i2c_client *client) 686static 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
729static int wm8510_i2c_attach(struct i2c_adapter *adap) 693static 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};
697MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
733 698
734/* corgi i2c codec control layer */
735static struct i2c_driver wm8510_i2c_driver = { 699static 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
746static struct i2c_client client_template = { 709static 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
744err_driver:
745 i2c_del_driver(&wm8510_i2c_driver);
746 return -ENODEV;
747}
750#endif 748#endif
751 749
752static int wm8510_probe(struct platform_device *pdev) 750static 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);