aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/pcm3008.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/pcm3008.c')
-rw-r--r--sound/soc/codecs/pcm3008.c150
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" 31static 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
44static 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
57static const struct snd_soc_dapm_widget pcm3008_dapm_widgets[] = {
58SND_SOC_DAPM_INPUT("VINL"),
59SND_SOC_DAPM_INPUT("VINR"),
60
61SND_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),
63SND_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
66SND_SOC_DAPM_OUTPUT("VOUTL"),
67SND_SOC_DAPM_OUTPUT("VOUTR"),
68};
69
70static 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
54static void pcm3008_gpio_free(struct pcm3008_setup_data *setup) 101static 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
62static int pcm3008_soc_probe(struct snd_soc_codec *codec) 108static 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
106gpio_err:
107 pcm3008_gpio_free(setup);
108 146
109 return ret;
110}
111
112static 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
121static 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
131static 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
145static 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
152static 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)
158static int pcm3008_codec_remove(struct platform_device *pdev) 151static 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