2 * ALSA Soc PCM3008 codec support
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
7 * Based on AC97 Soc codec, original copyright follow:
8 * Copyright 2005 Wolfson Microelectronics PLC.
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
15 * Generic PCM3008 support.
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/device.h>
21 #include <linux/gpio.h>
22 #include <linux/slab.h>
23 #include <linux/module.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/initval.h>
27 #include <sound/soc.h>
31 static int pcm3008_dac_ev(struct snd_soc_dapm_widget
*w
,
32 struct snd_kcontrol
*kcontrol
,
35 struct snd_soc_codec
*codec
= snd_soc_dapm_to_codec(w
->dapm
);
36 struct pcm3008_setup_data
*setup
= codec
->dev
->platform_data
;
38 gpio_set_value_cansleep(setup
->pdda_pin
,
39 SND_SOC_DAPM_EVENT_ON(event
));
44 static int pcm3008_adc_ev(struct snd_soc_dapm_widget
*w
,
45 struct snd_kcontrol
*kcontrol
,
48 struct snd_soc_codec
*codec
= snd_soc_dapm_to_codec(w
->dapm
);
49 struct pcm3008_setup_data
*setup
= codec
->dev
->platform_data
;
51 gpio_set_value_cansleep(setup
->pdad_pin
,
52 SND_SOC_DAPM_EVENT_ON(event
));
57 static const struct snd_soc_dapm_widget pcm3008_dapm_widgets
[] = {
58 SND_SOC_DAPM_INPUT("VINL"),
59 SND_SOC_DAPM_INPUT("VINR"),
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
),
66 SND_SOC_DAPM_OUTPUT("VOUTL"),
67 SND_SOC_DAPM_OUTPUT("VOUTR"),
70 static const struct snd_soc_dapm_route pcm3008_dapm_routes
[] = {
71 { "PCM3008 Capture", NULL
, "ADC" },
72 { "ADC", NULL
, "VINL" },
73 { "ADC", NULL
, "VINR" },
75 { "DAC", NULL
, "PCM3008 Playback" },
76 { "VOUTL", NULL
, "DAC" },
77 { "VOUTR", NULL
, "DAC" },
80 #define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
83 static struct snd_soc_dai_driver pcm3008_dai
= {
84 .name
= "pcm3008-hifi",
86 .stream_name
= "PCM3008 Playback",
89 .rates
= PCM3008_RATES
,
90 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
93 .stream_name
= "PCM3008 Capture",
96 .rates
= PCM3008_RATES
,
97 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
101 static const struct snd_soc_codec_driver soc_codec_dev_pcm3008
= {
102 .component_driver
= {
103 .dapm_widgets
= pcm3008_dapm_widgets
,
104 .num_dapm_widgets
= ARRAY_SIZE(pcm3008_dapm_widgets
),
105 .dapm_routes
= pcm3008_dapm_routes
,
106 .num_dapm_routes
= ARRAY_SIZE(pcm3008_dapm_routes
),
110 static int pcm3008_codec_probe(struct platform_device
*pdev
)
112 struct pcm3008_setup_data
*setup
= pdev
->dev
.platform_data
;
118 /* DEM1 DEM0 DE-EMPHASIS_MODE
119 * Low Low De-emphasis 44.1 kHz ON
120 * Low High De-emphasis OFF
121 * High Low De-emphasis 48 kHz ON
122 * High High De-emphasis 32 kHz ON
125 /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
126 ret
= devm_gpio_request_one(&pdev
->dev
, setup
->dem0_pin
,
127 GPIOF_OUT_INIT_HIGH
, "codec_dem0");
131 /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
132 ret
= devm_gpio_request_one(&pdev
->dev
, setup
->dem1_pin
,
133 GPIOF_OUT_INIT_LOW
, "codec_dem1");
137 /* Configure PDAD GPIO. */
138 ret
= devm_gpio_request_one(&pdev
->dev
, setup
->pdad_pin
,
139 GPIOF_OUT_INIT_LOW
, "codec_pdad");
143 /* Configure PDDA GPIO. */
144 ret
= devm_gpio_request_one(&pdev
->dev
, setup
->pdda_pin
,
145 GPIOF_OUT_INIT_LOW
, "codec_pdda");
149 return snd_soc_register_codec(&pdev
->dev
,
150 &soc_codec_dev_pcm3008
, &pcm3008_dai
, 1);
153 static int pcm3008_codec_remove(struct platform_device
*pdev
)
155 snd_soc_unregister_codec(&pdev
->dev
);
160 MODULE_ALIAS("platform:pcm3008-codec");
162 static struct platform_driver pcm3008_codec_driver
= {
163 .probe
= pcm3008_codec_probe
,
164 .remove
= pcm3008_codec_remove
,
166 .name
= "pcm3008-codec",
170 module_platform_driver(pcm3008_codec_driver
);
172 MODULE_DESCRIPTION("Soc PCM3008 driver");
173 MODULE_AUTHOR("Hugo Villeneuve");
174 MODULE_LICENSE("GPL");