2 * SoC audio for BCM94717AP Board
4 * Copyright (C) 2009, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: bcm94717ap.c,v 1.1 2009/10/30 20:40:14 Exp $
16 #include <linux/module.h>
17 #include <linux/moduleparam.h>
18 #include <linux/timer.h>
19 #include <linux/interrupt.h>
20 #include <linux/platform_device.h>
21 #include <sound/driver.h>
22 #include <sound/core.h>
23 #include <sound/pcm.h>
24 #include <sound/soc.h>
25 #include <sound/soc-dapm.h>
26 #include <linux/i2c-gpio.h>
40 #include "../codecs/wm8955.h"
41 #include "bcm947xx-pcm.h"
42 #include "bcm947xx-i2s.h"
44 #define BCM947XX_AP_DEBUG 0
46 #define DBG(x...) printk(KERN_ERR x)
52 /* MCLK in Hz - to bcm94717ap & Wolfson 8955 */
53 #define BCM94717AP_MCLK_FREQ 20000000 /* 20 MHz */
56 static int bcm94717ap_startup(struct snd_pcm_substream
*substream
)
58 //struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 //struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
60 //struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
63 DBG("%s:\n", __FUNCTION__
);
68 /* we need to unmute the HP at shutdown as the mute burns power on bcm94717ap */
69 static void bcm94717ap_shutdown(struct snd_pcm_substream
*substream
)
71 DBG("%s\n", __FUNCTION__
);
75 static int bcm94717ap_hw_params(struct snd_pcm_substream
*substream
,
76 struct snd_pcm_hw_params
*params
)
78 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
79 struct snd_soc_codec_dai
*codec_dai
= rtd
->dai
->codec_dai
;
80 struct snd_soc_cpu_dai
*cpu_dai
= rtd
->dai
->cpu_dai
;
83 //int freq = 11289600;
86 fmt
= SND_SOC_DAIFMT_I2S
| /* I2S mode audio */
87 SND_SOC_DAIFMT_NB_NF
| /* BCLK not inverted and normal LRCLK polarity */
88 SND_SOC_DAIFMT_CBM_CFM
; /* BCM947xx is I2S Slave */
90 /* set codec DAI configuration */
91 DBG("%s: calling set_fmt with fmt 0x%x\n", __FUNCTION__
, fmt
);
92 ret
= codec_dai
->dai_ops
.set_fmt(codec_dai
, fmt
);
96 /* set cpu DAI configuration */
97 ret
= cpu_dai
->dai_ops
.set_fmt(cpu_dai
, fmt
);
102 /* set up the PLL in codec */
103 ret
= codec_dai
->dai_ops
.set_pll(codec_dai
, 0, BCM94717AP_MCLK_FREQ
, freq
);
105 DBG("%s: Error CODEC DAI set_pll returned %d\n", __FUNCTION__
, ret
);
108 /* set the codec system clock for DAC and ADC */
109 ret
= codec_dai
->dai_ops
.set_sysclk(codec_dai
, WM8955_SYSCLK
, freq
,
111 DBG("%s: codec set_sysclk returned %d\n", __FUNCTION__
, ret
);
115 /* set the I2S system clock as input (unused) */
116 ret
= cpu_dai
->dai_ops
.set_sysclk(cpu_dai
, BCM947XX_I2S_SYSCLK
, freq
,
119 DBG("%s: cpu set_sysclk returned %d\n", __FUNCTION__
, ret
);
126 static struct snd_soc_ops bcm94717ap_ops
= {
127 .startup
= bcm94717ap_startup
,
128 .hw_params
= bcm94717ap_hw_params
,
129 .shutdown
= bcm94717ap_shutdown
,
135 static int bcm94717ap_wm8955_init(struct snd_soc_codec
*codec
)
137 DBG("%s\n", __FUNCTION__
);
139 snd_soc_dapm_sync_endpoints(codec
);
144 /* bcm94717ap digital audio interface glue - connects codec <--> CPU */
145 static struct snd_soc_dai_link bcm94717ap_dai
= {
147 .stream_name
= "WM8955",
148 .cpu_dai
= &bcm947xx_i2s_dai
,
149 .codec_dai
= &wm8955_dai
,
150 .init
= bcm94717ap_wm8955_init
,
151 .ops
= &bcm94717ap_ops
,
154 /* bcm94717ap audio machine driver */
155 static struct snd_soc_machine snd_soc_machine_bcm94717ap
= {
156 .name
= "Bcm94717ap",
157 .dai_link
= &bcm94717ap_dai
,
161 /* bcm94717ap audio private data */
162 static struct wm8955_setup_data bcm94717ap_wm8955_setup
= {
163 .i2c_address
= 0x1a, /* 2wire / I2C interface */
166 /* bcm94717ap audio subsystem */
167 static struct snd_soc_device bcm94717ap_snd_devdata
= {
168 .machine
= &snd_soc_machine_bcm94717ap
,
169 .platform
= &bcm947xx_soc_platform
,
170 .codec_dev
= &soc_codec_dev_wm8955
,
171 .codec_data
= &bcm94717ap_wm8955_setup
,
174 static struct platform_device
*bcm94717ap_snd_device
;
176 static int machine_is_bcm94717ap(void)
178 DBG("%s\n", __FUNCTION__
);
183 static struct i2c_gpio_platform_data i2c_gpio_data
= {
188 static struct platform_device i2c_gpio_device
= {
192 .platform_data
= &i2c_gpio_data
,
197 static int __init
bcm94717ap_init(void)
201 DBG("%s\n", __FUNCTION__
);
203 if (!machine_is_bcm94717ap())
206 ret
= platform_device_register(&i2c_gpio_device
);
208 platform_device_put(&i2c_gpio_device
);
212 bcm94717ap_snd_device
= platform_device_alloc("soc-audio", -1);
213 if (!bcm94717ap_snd_device
)
216 platform_set_drvdata(bcm94717ap_snd_device
, &bcm94717ap_snd_devdata
);
217 bcm94717ap_snd_devdata
.dev
= &bcm94717ap_snd_device
->dev
;
218 ret
= platform_device_add(bcm94717ap_snd_device
);
221 platform_device_put(bcm94717ap_snd_device
);
227 static void __exit
bcm94717ap_exit(void)
229 DBG("%s\n", __FUNCTION__
);
230 platform_device_unregister(bcm94717ap_snd_device
);
233 module_init(bcm94717ap_init
);
234 module_exit(bcm94717ap_exit
);
236 /* Module information */
237 MODULE_DESCRIPTION("ALSA SoC BCM94717AP");
238 MODULE_LICENSE("GPL");