diff options
| author | Jean Delvare <khali@linux-fr.org> | 2008-09-02 11:07:30 -0400 |
|---|---|---|
| committer | Jaroslav Kysela <perex@perex.cz> | 2008-09-09 03:11:13 -0400 |
| commit | 41759c2eab96ad67245acfbd24f93d126b0523a7 (patch) | |
| tree | 65a050a3052c1375f73196a9f4f5d02947422dd9 | |
| parent | b6471305bbda16fd0d8d96a5cfb01fa6aec87eb5 (diff) | |
sound: ASoC: Convert wm8510 to a new-style i2c driver
Convert the wm8510 codec driver to the new (standard) device
driver binding model.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Geoffrey Wossum <gwossum@acm.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
| -rw-r--r-- | sound/soc/at32/playpaq_wm8510.c | 1 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8510.c | 110 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8510.h | 1 |
3 files changed, 55 insertions, 57 deletions
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index 3f326219f1ec..7e6560ba7510 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c | |||
| @@ -377,6 +377,7 @@ static struct snd_soc_machine snd_soc_machine_playpaq = { | |||
| 377 | 377 | ||
| 378 | 378 | ||
| 379 | static struct wm8510_setup_data playpaq_wm8510_setup = { | 379 | static struct wm8510_setup_data playpaq_wm8510_setup = { |
| 380 | .i2c_bus = 0, | ||
| 380 | .i2c_address = 0x1a, | 381 | .i2c_address = 0x1a, |
| 381 | }; | 382 | }; |
| 382 | 383 | ||
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 3d998e6a997e..75ed0413ce49 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
| @@ -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); |
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h index f5d2e42eb3f4..c53683960456 100644 --- a/sound/soc/codecs/wm8510.h +++ b/sound/soc/codecs/wm8510.h | |||
| @@ -94,6 +94,7 @@ | |||
| 94 | #define WM8510_MCLKDIV_12 (7 << 5) | 94 | #define WM8510_MCLKDIV_12 (7 << 5) |
| 95 | 95 | ||
| 96 | struct wm8510_setup_data { | 96 | struct wm8510_setup_data { |
| 97 | int i2c_bus; | ||
| 97 | unsigned short i2c_address; | 98 | unsigned short i2c_address; |
| 98 | }; | 99 | }; |
| 99 | 100 | ||
