diff options
Diffstat (limited to 'sound/soc/codecs/pcm3008.c')
-rw-r--r-- | sound/soc/codecs/pcm3008.c | 150 |
1 files changed, 72 insertions, 78 deletions
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index f2a6282b41f4..b6618c4a7597 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c | |||
@@ -28,7 +28,54 @@ | |||
28 | 28 | ||
29 | #include "pcm3008.h" | 29 | #include "pcm3008.h" |
30 | 30 | ||
31 | #define PCM3008_VERSION "0.2" | 31 | static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w, |
32 | struct snd_kcontrol *kcontrol, | ||
33 | int event) | ||
34 | { | ||
35 | struct snd_soc_codec *codec = w->codec; | ||
36 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | ||
37 | |||
38 | gpio_set_value_cansleep(setup->pdda_pin, | ||
39 | SND_SOC_DAPM_EVENT_ON(event)); | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w, | ||
45 | struct snd_kcontrol *kcontrol, | ||
46 | int event) | ||
47 | { | ||
48 | struct snd_soc_codec *codec = w->codec; | ||
49 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | ||
50 | |||
51 | gpio_set_value_cansleep(setup->pdad_pin, | ||
52 | SND_SOC_DAPM_EVENT_ON(event)); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static const struct snd_soc_dapm_widget pcm3008_dapm_widgets[] = { | ||
58 | SND_SOC_DAPM_INPUT("VINL"), | ||
59 | SND_SOC_DAPM_INPUT("VINR"), | ||
60 | |||
61 | SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, pcm3008_dac_ev, | ||
62 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
63 | SND_SOC_DAPM_ADC_E("ADC", NULL, SND_SOC_NOPM, 0, 0, pcm3008_adc_ev, | ||
64 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
65 | |||
66 | SND_SOC_DAPM_OUTPUT("VOUTL"), | ||
67 | SND_SOC_DAPM_OUTPUT("VOUTR"), | ||
68 | }; | ||
69 | |||
70 | static const struct snd_soc_dapm_route pcm3008_dapm_routes[] = { | ||
71 | { "PCM3008 Capture", NULL, "ADC" }, | ||
72 | { "ADC", NULL, "VINL" }, | ||
73 | { "ADC", NULL, "VINR" }, | ||
74 | |||
75 | { "DAC", NULL, "PCM3008 Playback" }, | ||
76 | { "VOUTL", NULL, "DAC" }, | ||
77 | { "VOUTR", NULL, "DAC" }, | ||
78 | }; | ||
32 | 79 | ||
33 | #define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | 80 | #define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
34 | SNDRV_PCM_RATE_48000) | 81 | SNDRV_PCM_RATE_48000) |
@@ -51,20 +98,20 @@ static struct snd_soc_dai_driver pcm3008_dai = { | |||
51 | }, | 98 | }, |
52 | }; | 99 | }; |
53 | 100 | ||
54 | static void pcm3008_gpio_free(struct pcm3008_setup_data *setup) | 101 | static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { |
55 | { | 102 | .dapm_widgets = pcm3008_dapm_widgets, |
56 | gpio_free(setup->dem0_pin); | 103 | .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), |
57 | gpio_free(setup->dem1_pin); | 104 | .dapm_routes = pcm3008_dapm_routes, |
58 | gpio_free(setup->pdad_pin); | 105 | .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes), |
59 | gpio_free(setup->pdda_pin); | 106 | }; |
60 | } | ||
61 | 107 | ||
62 | static int pcm3008_soc_probe(struct snd_soc_codec *codec) | 108 | static int pcm3008_codec_probe(struct platform_device *pdev) |
63 | { | 109 | { |
64 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | 110 | struct pcm3008_setup_data *setup = pdev->dev.platform_data; |
65 | int ret = 0; | 111 | int ret; |
66 | 112 | ||
67 | printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); | 113 | if (!setup) |
114 | return -EINVAL; | ||
68 | 115 | ||
69 | /* DEM1 DEM0 DE-EMPHASIS_MODE | 116 | /* DEM1 DEM0 DE-EMPHASIS_MODE |
70 | * Low Low De-emphasis 44.1 kHz ON | 117 | * Low Low De-emphasis 44.1 kHz ON |
@@ -74,83 +121,29 @@ static int pcm3008_soc_probe(struct snd_soc_codec *codec) | |||
74 | */ | 121 | */ |
75 | 122 | ||
76 | /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */ | 123 | /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */ |
77 | ret = gpio_request(setup->dem0_pin, "codec_dem0"); | 124 | ret = devm_gpio_request_one(&pdev->dev, setup->dem0_pin, |
78 | if (ret == 0) | 125 | GPIOF_OUT_INIT_HIGH, "codec_dem0"); |
79 | ret = gpio_direction_output(setup->dem0_pin, 1); | ||
80 | if (ret != 0) | 126 | if (ret != 0) |
81 | goto gpio_err; | 127 | return ret; |
82 | 128 | ||
83 | /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */ | 129 | /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */ |
84 | ret = gpio_request(setup->dem1_pin, "codec_dem1"); | 130 | ret = devm_gpio_request_one(&pdev->dev, setup->dem1_pin, |
85 | if (ret == 0) | 131 | GPIOF_OUT_INIT_LOW, "codec_dem1"); |
86 | ret = gpio_direction_output(setup->dem1_pin, 0); | ||
87 | if (ret != 0) | 132 | if (ret != 0) |
88 | goto gpio_err; | 133 | return ret; |
89 | 134 | ||
90 | /* Configure PDAD GPIO. */ | 135 | /* Configure PDAD GPIO. */ |
91 | ret = gpio_request(setup->pdad_pin, "codec_pdad"); | 136 | ret = devm_gpio_request_one(&pdev->dev, setup->pdad_pin, |
92 | if (ret == 0) | 137 | GPIOF_OUT_INIT_LOW, "codec_pdad"); |
93 | ret = gpio_direction_output(setup->pdad_pin, 1); | ||
94 | if (ret != 0) | 138 | if (ret != 0) |
95 | goto gpio_err; | 139 | return ret; |
96 | 140 | ||
97 | /* Configure PDDA GPIO. */ | 141 | /* Configure PDDA GPIO. */ |
98 | ret = gpio_request(setup->pdda_pin, "codec_pdda"); | 142 | ret = devm_gpio_request_one(&pdev->dev, setup->pdda_pin, |
99 | if (ret == 0) | 143 | GPIOF_OUT_INIT_LOW, "codec_pdda"); |
100 | ret = gpio_direction_output(setup->pdda_pin, 1); | ||
101 | if (ret != 0) | 144 | if (ret != 0) |
102 | goto gpio_err; | 145 | return ret; |
103 | |||
104 | return ret; | ||
105 | |||
106 | gpio_err: | ||
107 | pcm3008_gpio_free(setup); | ||
108 | 146 | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static int pcm3008_soc_remove(struct snd_soc_codec *codec) | ||
113 | { | ||
114 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | ||
115 | |||
116 | pcm3008_gpio_free(setup); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | #ifdef CONFIG_PM | ||
121 | static int pcm3008_soc_suspend(struct snd_soc_codec *codec) | ||
122 | { | ||
123 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | ||
124 | |||
125 | gpio_set_value(setup->pdad_pin, 0); | ||
126 | gpio_set_value(setup->pdda_pin, 0); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int pcm3008_soc_resume(struct snd_soc_codec *codec) | ||
132 | { | ||
133 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | ||
134 | |||
135 | gpio_set_value(setup->pdad_pin, 1); | ||
136 | gpio_set_value(setup->pdda_pin, 1); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | #else | ||
141 | #define pcm3008_soc_suspend NULL | ||
142 | #define pcm3008_soc_resume NULL | ||
143 | #endif | ||
144 | |||
145 | static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { | ||
146 | .probe = pcm3008_soc_probe, | ||
147 | .remove = pcm3008_soc_remove, | ||
148 | .suspend = pcm3008_soc_suspend, | ||
149 | .resume = pcm3008_soc_resume, | ||
150 | }; | ||
151 | |||
152 | static int pcm3008_codec_probe(struct platform_device *pdev) | ||
153 | { | ||
154 | return snd_soc_register_codec(&pdev->dev, | 147 | return snd_soc_register_codec(&pdev->dev, |
155 | &soc_codec_dev_pcm3008, &pcm3008_dai, 1); | 148 | &soc_codec_dev_pcm3008, &pcm3008_dai, 1); |
156 | } | 149 | } |
@@ -158,6 +151,7 @@ static int pcm3008_codec_probe(struct platform_device *pdev) | |||
158 | static int pcm3008_codec_remove(struct platform_device *pdev) | 151 | static int pcm3008_codec_remove(struct platform_device *pdev) |
159 | { | 152 | { |
160 | snd_soc_unregister_codec(&pdev->dev); | 153 | snd_soc_unregister_codec(&pdev->dev); |
154 | |||
161 | return 0; | 155 | return 0; |
162 | } | 156 | } |
163 | 157 | ||