wm8750.c (cf0dbba515415bb19b11f9323d5f7bebd7f24fd6) | wm8750.c (b2c812e22de88bb79c290c0e718280f10b64a48d) |
---|---|
1/* 2 * wm8750.c -- WM8750 ALSA SoC audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <richard@openedhand.com> 7 * 8 * Based on WM8753.c --- 6 unchanged lines hidden (view full) --- 15#include <linux/module.h> 16#include <linux/moduleparam.h> 17#include <linux/init.h> 18#include <linux/delay.h> 19#include <linux/pm.h> 20#include <linux/i2c.h> 21#include <linux/platform_device.h> 22#include <linux/spi/spi.h> | 1/* 2 * wm8750.c -- WM8750 ALSA SoC audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <richard@openedhand.com> 7 * 8 * Based on WM8753.c --- 6 unchanged lines hidden (view full) --- 15#include <linux/module.h> 16#include <linux/moduleparam.h> 17#include <linux/init.h> 18#include <linux/delay.h> 19#include <linux/pm.h> 20#include <linux/i2c.h> 21#include <linux/platform_device.h> 22#include <linux/spi/spi.h> |
23#include <linux/slab.h> | |
24#include <sound/core.h> 25#include <sound/pcm.h> 26#include <sound/pcm_params.h> 27#include <sound/soc.h> 28#include <sound/soc-dapm.h> 29#include <sound/initval.h> 30 31#include "wm8750.h" 32 | 23#include <sound/core.h> 24#include <sound/pcm.h> 25#include <sound/pcm_params.h> 26#include <sound/soc.h> 27#include <sound/soc-dapm.h> 28#include <sound/initval.h> 29 30#include "wm8750.h" 31 |
33#define WM8750_VERSION "0.12" 34 35/* codec private data */ 36struct wm8750_priv { 37 unsigned int sysclk; 38}; 39 | |
40/* 41 * wm8750 register cache 42 * We can't read the WM8750 register space when we 43 * are using 2 wire for device control, so we cache them instead. 44 */ 45static const u16 wm8750_reg[] = { 46 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 47 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 48 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 49 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 50 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 51 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 52 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 53 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 54 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 55 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 56 0x0079, 0x0079, 0x0079, /* 40 */ 57}; 58 | 32/* 33 * wm8750 register cache 34 * We can't read the WM8750 register space when we 35 * are using 2 wire for device control, so we cache them instead. 36 */ 37static const u16 wm8750_reg[] = { 38 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 39 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 40 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 41 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 42 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 43 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 44 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 45 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 46 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 47 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 48 0x0079, 0x0079, 0x0079, /* 40 */ 49}; 50 |
51/* codec private data */ 52struct wm8750_priv { 53 unsigned int sysclk; 54 struct snd_soc_codec codec; 55 u16 reg_cache[ARRAY_SIZE(wm8750_reg)]; 56}; 57 |
|
59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 60 61/* 62 * WM8750 Controls 63 */ 64static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"}; 65static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; 66static const char *wm8750_treble[] = {"8kHz", "4kHz"}; --- 411 unchanged lines hidden (view full) --- 478 mclk, rate); 479 return -EINVAL; 480} 481 482static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai, 483 int clk_id, unsigned int freq, int dir) 484{ 485 struct snd_soc_codec *codec = codec_dai->codec; | 58#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 59 60/* 61 * WM8750 Controls 62 */ 63static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"}; 64static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; 65static const char *wm8750_treble[] = {"8kHz", "4kHz"}; --- 411 unchanged lines hidden (view full) --- 477 mclk, rate); 478 return -EINVAL; 479} 480 481static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai, 482 int clk_id, unsigned int freq, int dir) 483{ 484 struct snd_soc_codec *codec = codec_dai->codec; |
486 struct wm8750_priv *wm8750 = codec->private_data; | 485 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); |
487 488 switch (freq) { 489 case 11289600: 490 case 12000000: 491 case 12288000: 492 case 16934400: 493 case 18432000: 494 wm8750->sysclk = freq; --- 62 unchanged lines hidden (view full) --- 557 558static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, 559 struct snd_pcm_hw_params *params, 560 struct snd_soc_dai *dai) 561{ 562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 563 struct snd_soc_device *socdev = rtd->socdev; 564 struct snd_soc_codec *codec = socdev->card->codec; | 486 487 switch (freq) { 488 case 11289600: 489 case 12000000: 490 case 12288000: 491 case 16934400: 492 case 18432000: 493 wm8750->sysclk = freq; --- 62 unchanged lines hidden (view full) --- 556 557static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, 558 struct snd_pcm_hw_params *params, 559 struct snd_soc_dai *dai) 560{ 561 struct snd_soc_pcm_runtime *rtd = substream->private_data; 562 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_codec *codec = socdev->card->codec; |
565 struct wm8750_priv *wm8750 = codec->private_data; | 564 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); |
566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 569 570 /* bit size */ 571 switch (params_format(params)) { 572 case SNDRV_PCM_FORMAT_S16_LE: 573 break; --- 35 unchanged lines hidden (view full) --- 609 u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e; 610 611 switch (level) { 612 case SND_SOC_BIAS_ON: 613 /* set vmid to 50k and unmute dac */ 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 615 break; 616 case SND_SOC_BIAS_PREPARE: | 565 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 566 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 567 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 569 /* bit size */ 570 switch (params_format(params)) { 571 case SNDRV_PCM_FORMAT_S16_LE: 572 break; --- 35 unchanged lines hidden (view full) --- 608 u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e; 609 610 switch (level) { 611 case SND_SOC_BIAS_ON: 612 /* set vmid to 50k and unmute dac */ 613 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 break; 615 case SND_SOC_BIAS_PREPARE: |
617 /* set vmid to 5k for quick power up */ 618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); | |
619 break; 620 case SND_SOC_BIAS_STANDBY: | 616 break; 617 case SND_SOC_BIAS_STANDBY: |
618 if (codec->bias_level == SND_SOC_BIAS_OFF) { 619 /* Set VMID to 5k */ 620 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 621 622 /* ...and ramp */ 623 msleep(1000); 624 } 625 |
|
621 /* mute dac and set vmid to 500k, enable VREF */ 622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 623 break; 624 case SND_SOC_BIAS_OFF: 625 snd_soc_write(codec, WM8750_PWR1, 0x0001); 626 break; 627 } 628 codec->bias_level = level; --- 27 unchanged lines hidden (view full) --- 656 .channels_min = 1, 657 .channels_max = 2, 658 .rates = WM8750_RATES, 659 .formats = WM8750_FORMATS,}, 660 .ops = &wm8750_dai_ops, 661}; 662EXPORT_SYMBOL_GPL(wm8750_dai); 663 | 626 /* mute dac and set vmid to 500k, enable VREF */ 627 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 628 break; 629 case SND_SOC_BIAS_OFF: 630 snd_soc_write(codec, WM8750_PWR1, 0x0001); 631 break; 632 } 633 codec->bias_level = level; --- 27 unchanged lines hidden (view full) --- 661 .channels_min = 1, 662 .channels_max = 2, 663 .rates = WM8750_RATES, 664 .formats = WM8750_FORMATS,}, 665 .ops = &wm8750_dai_ops, 666}; 667EXPORT_SYMBOL_GPL(wm8750_dai); 668 |
664static void wm8750_work(struct work_struct *work) 665{ 666 struct snd_soc_codec *codec = 667 container_of(work, struct snd_soc_codec, delayed_work.work); 668 wm8750_set_bias_level(codec, codec->bias_level); 669} 670 | |
671static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 672{ 673 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 674 struct snd_soc_codec *codec = socdev->card->codec; 675 676 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 677 return 0; 678} --- 12 unchanged lines hidden (view full) --- 691 continue; 692 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 693 data[1] = cache[i] & 0x00ff; 694 codec->hw_write(codec->control_data, data, 2); 695 } 696 697 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 698 | 669static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 670{ 671 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 672 struct snd_soc_codec *codec = socdev->card->codec; 673 674 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 675 return 0; 676} --- 12 unchanged lines hidden (view full) --- 689 continue; 690 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 691 data[1] = cache[i] & 0x00ff; 692 codec->hw_write(codec->control_data, data, 2); 693 } 694 695 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 696 |
699 /* charge wm8750 caps */ 700 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 701 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 702 codec->bias_level = SND_SOC_BIAS_ON; 703 schedule_delayed_work(&codec->delayed_work, 704 msecs_to_jiffies(1000)); | 697 return 0; 698} 699 700static struct snd_soc_codec *wm8750_codec; 701 702static int wm8750_probe(struct platform_device *pdev) 703{ 704 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 705 struct snd_soc_codec *codec; 706 int ret = 0; 707 708 if (!wm8750_codec) { 709 dev_err(&pdev->dev, "WM8750 codec not yet registered\n"); 710 return -EINVAL; |
705 } 706 | 711 } 712 |
713 socdev->card->codec = wm8750_codec; 714 codec = wm8750_codec; 715 716 /* register pcms */ 717 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 718 if (ret < 0) { 719 printk(KERN_ERR "wm8750: failed to create pcms\n"); 720 goto err; 721 } 722 723 snd_soc_add_controls(codec, wm8750_snd_controls, 724 ARRAY_SIZE(wm8750_snd_controls)); 725 wm8750_add_widgets(codec); 726 |
|
707 return 0; | 727 return 0; |
728 729err: 730 return ret; |
|
708} 709 | 731} 732 |
733/* power down chip */ 734static int wm8750_remove(struct platform_device *pdev) 735{ 736 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 737 738 snd_soc_free_pcms(socdev); 739 snd_soc_dapm_free(socdev); 740 741 return 0; 742} 743 744struct snd_soc_codec_device soc_codec_dev_wm8750 = { 745 .probe = wm8750_probe, 746 .remove = wm8750_remove, 747 .suspend = wm8750_suspend, 748 .resume = wm8750_resume, 749}; 750EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); 751 |
|
710/* 711 * initialise the WM8750 driver 712 * register the mixer and dsp interfaces with the kernel 713 */ | 752/* 753 * initialise the WM8750 driver 754 * register the mixer and dsp interfaces with the kernel 755 */ |
714static int wm8750_init(struct snd_soc_device *socdev, 715 enum snd_soc_control_type control) | 756static int wm8750_register(struct wm8750_priv *wm8750, 757 enum snd_soc_control_type control) |
716{ | 758{ |
717 struct snd_soc_codec *codec = socdev->card->codec; | 759 struct snd_soc_codec *codec = &wm8750->codec; |
718 int reg, ret = 0; 719 | 760 int reg, ret = 0; 761 |
762 if (wm8750_codec) { 763 dev_err(codec->dev, "Multiple WM8750 devices not supported\n"); 764 ret = -EINVAL; 765 goto err; 766 } 767 768 mutex_init(&codec->mutex); 769 INIT_LIST_HEAD(&codec->dapm_widgets); 770 INIT_LIST_HEAD(&codec->dapm_paths); 771 |
|
720 codec->name = "WM8750"; 721 codec->owner = THIS_MODULE; | 772 codec->name = "WM8750"; 773 codec->owner = THIS_MODULE; |
774 codec->bias_level = SND_SOC_BIAS_STANDBY; |
|
722 codec->set_bias_level = wm8750_set_bias_level; 723 codec->dai = &wm8750_dai; 724 codec->num_dai = 1; | 775 codec->set_bias_level = wm8750_set_bias_level; 776 codec->dai = &wm8750_dai; 777 codec->num_dai = 1; |
725 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg); 726 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 727 if (codec->reg_cache == NULL) 728 return -ENOMEM; | 778 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1; 779 codec->reg_cache = &wm8750->reg_cache; 780 snd_soc_codec_set_drvdata(codec, wm8750); |
729 | 781 |
782 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache)); 783 |
|
730 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 731 if (ret < 0) { 732 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); 733 goto err; 734 } 735 736 ret = wm8750_reset(codec); 737 if (ret < 0) { 738 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); 739 goto err; 740 } 741 | 784 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 785 if (ret < 0) { 786 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); 787 goto err; 788 } 789 790 ret = wm8750_reset(codec); 791 if (ret < 0) { 792 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); 793 goto err; 794 } 795 |
742 /* register pcms */ 743 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 744 if (ret < 0) { 745 printk(KERN_ERR "wm8750: failed to create pcms\n"); 746 goto err; 747 } 748 | |
749 /* charge output caps */ | 796 /* charge output caps */ |
750 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 751 codec->bias_level = SND_SOC_BIAS_STANDBY; 752 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); | 797 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
753 754 /* set the update bits */ 755 reg = snd_soc_read(codec, WM8750_LDAC); 756 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100); 757 reg = snd_soc_read(codec, WM8750_RDAC); 758 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100); 759 reg = snd_soc_read(codec, WM8750_LOUT1V); 760 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100); 761 reg = snd_soc_read(codec, WM8750_ROUT1V); 762 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100); 763 reg = snd_soc_read(codec, WM8750_LOUT2V); 764 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100); 765 reg = snd_soc_read(codec, WM8750_ROUT2V); 766 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100); 767 reg = snd_soc_read(codec, WM8750_LINVOL); 768 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100); 769 reg = snd_soc_read(codec, WM8750_RINVOL); 770 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 771 | 798 799 /* set the update bits */ 800 reg = snd_soc_read(codec, WM8750_LDAC); 801 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100); 802 reg = snd_soc_read(codec, WM8750_RDAC); 803 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100); 804 reg = snd_soc_read(codec, WM8750_LOUT1V); 805 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100); 806 reg = snd_soc_read(codec, WM8750_ROUT1V); 807 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100); 808 reg = snd_soc_read(codec, WM8750_LOUT2V); 809 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100); 810 reg = snd_soc_read(codec, WM8750_ROUT2V); 811 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100); 812 reg = snd_soc_read(codec, WM8750_LINVOL); 813 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100); 814 reg = snd_soc_read(codec, WM8750_RINVOL); 815 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 816 |
772 snd_soc_add_controls(codec, wm8750_snd_controls, 773 ARRAY_SIZE(wm8750_snd_controls)); 774 wm8750_add_widgets(codec); 775 return ret; | 817 wm8750_codec = codec; |
776 | 818 |
819 ret = snd_soc_register_codec(codec); 820 if (ret != 0) { 821 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 822 goto err; 823 } 824 825 ret = snd_soc_register_dais(&wm8750_dai, 1); 826 if (ret != 0) { 827 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); 828 goto err_codec; 829 } 830 831 return 0; 832 833err_codec: 834 snd_soc_unregister_codec(codec); |
|
777err: | 835err: |
778 kfree(codec->reg_cache); | 836 kfree(wm8750); |
779 return ret; 780} 781 | 837 return ret; 838} 839 |
782/* If the i2c layer weren't so broken, we could pass this kind of data 783 around */ 784static struct snd_soc_device *wm8750_socdev; | 840static void wm8750_unregister(struct wm8750_priv *wm8750) 841{ 842 wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF); 843 snd_soc_unregister_dais(&wm8750_dai, 1); 844 snd_soc_unregister_codec(&wm8750->codec); 845 kfree(wm8750); 846 wm8750_codec = NULL; 847} |
785 786#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 787 788/* 789 * WM8750 2 wire address is determined by GPIO5 790 * state during powerup. 791 * low = 0x1a 792 * high = 0x1b 793 */ 794 795static int wm8750_i2c_probe(struct i2c_client *i2c, 796 const struct i2c_device_id *id) 797{ | 848 849#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 850 851/* 852 * WM8750 2 wire address is determined by GPIO5 853 * state during powerup. 854 * low = 0x1a 855 * high = 0x1b 856 */ 857 858static int wm8750_i2c_probe(struct i2c_client *i2c, 859 const struct i2c_device_id *id) 860{ |
798 struct snd_soc_device *socdev = wm8750_socdev; 799 struct snd_soc_codec *codec = socdev->card->codec; 800 int ret; | 861 struct snd_soc_codec *codec; 862 struct wm8750_priv *wm8750; |
801 | 863 |
802 i2c_set_clientdata(i2c, codec); | 864 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 865 if (wm8750 == NULL) 866 return -ENOMEM; 867 868 codec = &wm8750->codec; |
803 codec->control_data = i2c; | 869 codec->control_data = i2c; |
870 i2c_set_clientdata(i2c, wm8750); |
|
804 | 871 |
805 ret = wm8750_init(socdev, SND_SOC_I2C); 806 if (ret < 0) 807 pr_err("failed to initialise WM8750\n"); | 872 codec->dev = &i2c->dev; |
808 | 873 |
809 return ret; | 874 return wm8750_register(wm8750, SND_SOC_I2C); |
810} 811 812static int wm8750_i2c_remove(struct i2c_client *client) 813{ | 875} 876 877static int wm8750_i2c_remove(struct i2c_client *client) 878{ |
814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 815 kfree(codec->reg_cache); | 879 struct wm8750_priv *wm8750 = i2c_get_clientdata(client); 880 wm8750_unregister(wm8750); |
816 return 0; 817} 818 819static const struct i2c_device_id wm8750_i2c_id[] = { 820 { "wm8750", 0 }, 821 { } 822}; 823MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id); 824 825static struct i2c_driver wm8750_i2c_driver = { 826 .driver = { 827 .name = "WM8750 I2C Codec", 828 .owner = THIS_MODULE, 829 }, 830 .probe = wm8750_i2c_probe, 831 .remove = wm8750_i2c_remove, 832 .id_table = wm8750_i2c_id, 833}; | 881 return 0; 882} 883 884static const struct i2c_device_id wm8750_i2c_id[] = { 885 { "wm8750", 0 }, 886 { } 887}; 888MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id); 889 890static struct i2c_driver wm8750_i2c_driver = { 891 .driver = { 892 .name = "WM8750 I2C Codec", 893 .owner = THIS_MODULE, 894 }, 895 .probe = wm8750_i2c_probe, 896 .remove = wm8750_i2c_remove, 897 .id_table = wm8750_i2c_id, 898}; |
834 835static int wm8750_add_i2c_device(struct platform_device *pdev, 836 const struct wm8750_setup_data *setup) 837{ 838 struct i2c_board_info info; 839 struct i2c_adapter *adapter; 840 struct i2c_client *client; 841 int ret; 842 843 ret = i2c_add_driver(&wm8750_i2c_driver); 844 if (ret != 0) { 845 dev_err(&pdev->dev, "can't add i2c driver\n"); 846 return ret; 847 } 848 849 memset(&info, 0, sizeof(struct i2c_board_info)); 850 info.addr = setup->i2c_address; 851 strlcpy(info.type, "wm8750", I2C_NAME_SIZE); 852 853 adapter = i2c_get_adapter(setup->i2c_bus); 854 if (!adapter) { 855 dev_err(&pdev->dev, "can't get i2c adapter %d\n", 856 setup->i2c_bus); 857 goto err_driver; 858 } 859 860 client = i2c_new_device(adapter, &info); 861 i2c_put_adapter(adapter); 862 if (!client) { 863 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", 864 (unsigned int)info.addr); 865 goto err_driver; 866 } 867 868 return 0; 869 870err_driver: 871 i2c_del_driver(&wm8750_i2c_driver); 872 return -ENODEV; 873} | |
874#endif 875 876#if defined(CONFIG_SPI_MASTER) 877static int __devinit wm8750_spi_probe(struct spi_device *spi) 878{ | 899#endif 900 901#if defined(CONFIG_SPI_MASTER) 902static int __devinit wm8750_spi_probe(struct spi_device *spi) 903{ |
879 struct snd_soc_device *socdev = wm8750_socdev; 880 struct snd_soc_codec *codec = socdev->card->codec; 881 int ret; | 904 struct snd_soc_codec *codec; 905 struct wm8750_priv *wm8750; |
882 | 906 |
907 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 908 if (wm8750 == NULL) 909 return -ENOMEM; 910 911 codec = &wm8750->codec; |
|
883 codec->control_data = spi; | 912 codec->control_data = spi; |
913 codec->dev = &spi->dev; |
|
884 | 914 |
885 ret = wm8750_init(socdev, SND_SOC_SPI); 886 if (ret < 0) 887 dev_err(&spi->dev, "failed to initialise WM8750\n"); | 915 dev_set_drvdata(&spi->dev, wm8750); |
888 | 916 |
889 return ret; | 917 return wm8750_register(wm8750, SND_SOC_SPI); |
890} 891 892static int __devexit wm8750_spi_remove(struct spi_device *spi) 893{ | 918} 919 920static int __devexit wm8750_spi_remove(struct spi_device *spi) 921{ |
922 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev); 923 wm8750_unregister(wm8750); |
|
894 return 0; 895} 896 897static struct spi_driver wm8750_spi_driver = { 898 .driver = { 899 .name = "wm8750", 900 .bus = &spi_bus_type, 901 .owner = THIS_MODULE, 902 }, 903 .probe = wm8750_spi_probe, 904 .remove = __devexit_p(wm8750_spi_remove), 905}; 906#endif 907 | 924 return 0; 925} 926 927static struct spi_driver wm8750_spi_driver = { 928 .driver = { 929 .name = "wm8750", 930 .bus = &spi_bus_type, 931 .owner = THIS_MODULE, 932 }, 933 .probe = wm8750_spi_probe, 934 .remove = __devexit_p(wm8750_spi_remove), 935}; 936#endif 937 |
908static int wm8750_probe(struct platform_device *pdev) | 938static int __init wm8750_modinit(void) |
909{ | 939{ |
910 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 911 struct wm8750_setup_data *setup = socdev->codec_data; 912 struct snd_soc_codec *codec; 913 struct wm8750_priv *wm8750; | |
914 int ret; | 940 int ret; |
915 916 pr_info("WM8750 Audio Codec %s", WM8750_VERSION); 917 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 918 if (codec == NULL) 919 return -ENOMEM; 920 921 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 922 if (wm8750 == NULL) { 923 kfree(codec); 924 return -ENOMEM; 925 } 926 927 codec->private_data = wm8750; 928 socdev->card->codec = codec; 929 mutex_init(&codec->mutex); 930 INIT_LIST_HEAD(&codec->dapm_widgets); 931 INIT_LIST_HEAD(&codec->dapm_paths); 932 wm8750_socdev = socdev; 933 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work); 934 935 ret = -ENODEV; 936 | |
937#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 941#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
938 if (setup->i2c_address) { 939 ret = wm8750_add_i2c_device(pdev, setup); 940 } | 942 ret = i2c_add_driver(&wm8750_i2c_driver); 943 if (ret != 0) 944 pr_err("Failed to register WM8750 I2C driver: %d\n", ret); |
941#endif 942#if defined(CONFIG_SPI_MASTER) | 945#endif 946#if defined(CONFIG_SPI_MASTER) |
943 if (setup->spi) { 944 ret = spi_register_driver(&wm8750_spi_driver); 945 if (ret != 0) 946 printk(KERN_ERR "can't add spi driver"); 947 } | 947 ret = spi_register_driver(&wm8750_spi_driver); 948 if (ret != 0) 949 pr_err("Failed to register WM8750 SPI driver: %d\n", ret); |
948#endif | 950#endif |
949 950 if (ret != 0) { 951 kfree(codec->private_data); 952 kfree(codec); 953 } 954 return ret; | 951 return 0; |
955} | 952} |
953module_init(wm8750_modinit); |
|
956 | 954 |
957/* 958 * This function forces any delayed work to be queued and run. 959 */ 960static int run_delayed_work(struct delayed_work *dwork) | 955static void __exit wm8750_exit(void) |
961{ | 956{ |
962 int ret; 963 964 /* cancel any work waiting to be queued. */ 965 ret = cancel_delayed_work(dwork); 966 967 /* if there was any work waiting then we run it now and 968 * wait for it's completion */ 969 if (ret) { 970 schedule_delayed_work(dwork, 0); 971 flush_scheduled_work(); 972 } 973 return ret; 974} 975 976/* power down chip */ 977static int wm8750_remove(struct platform_device *pdev) 978{ 979 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 980 struct snd_soc_codec *codec = socdev->card->codec; 981 982 if (codec->control_data) 983 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 984 run_delayed_work(&codec->delayed_work); 985 snd_soc_free_pcms(socdev); 986 snd_soc_dapm_free(socdev); | |
987#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 957#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
988 i2c_unregister_device(codec->control_data); | |
989 i2c_del_driver(&wm8750_i2c_driver); 990#endif 991#if defined(CONFIG_SPI_MASTER) 992 spi_unregister_driver(&wm8750_spi_driver); 993#endif | 958 i2c_del_driver(&wm8750_i2c_driver); 959#endif 960#if defined(CONFIG_SPI_MASTER) 961 spi_unregister_driver(&wm8750_spi_driver); 962#endif |
994 kfree(codec->private_data); 995 kfree(codec); 996 997 return 0; | |
998} | 963} |
999 1000struct snd_soc_codec_device soc_codec_dev_wm8750 = { 1001 .probe = wm8750_probe, 1002 .remove = wm8750_remove, 1003 .suspend = wm8750_suspend, 1004 .resume = wm8750_resume, 1005}; 1006EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); 1007 1008static int __init wm8750_modinit(void) 1009{ 1010 return snd_soc_register_dai(&wm8750_dai); 1011} 1012module_init(wm8750_modinit); 1013 1014static void __exit wm8750_exit(void) 1015{ 1016 snd_soc_unregister_dai(&wm8750_dai); 1017} | |
1018module_exit(wm8750_exit); 1019 1020MODULE_DESCRIPTION("ASoC WM8750 driver"); 1021MODULE_AUTHOR("Liam Girdwood"); 1022MODULE_LICENSE("GPL"); | 964module_exit(wm8750_exit); 965 966MODULE_DESCRIPTION("ASoC WM8750 driver"); 967MODULE_AUTHOR("Liam Girdwood"); 968MODULE_LICENSE("GPL"); |