xref: /openbmc/linux/sound/soc/pxa/spitz.c (revision 7fb290d0)
17fb290d0SLiam Girdwood /*
27fb290d0SLiam Girdwood  * spitz.c  --  SoC audio for Sharp SL-Cxx00 models Spitz, Borzoi and Akita
37fb290d0SLiam Girdwood  *
47fb290d0SLiam Girdwood  * Copyright 2005 Wolfson Microelectronics PLC.
57fb290d0SLiam Girdwood  * Copyright 2005 Openedhand Ltd.
67fb290d0SLiam Girdwood  *
77fb290d0SLiam Girdwood  * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
87fb290d0SLiam Girdwood  *          Richard Purdie <richard@openedhand.com>
97fb290d0SLiam Girdwood  *
107fb290d0SLiam Girdwood  *  This program is free software; you can redistribute  it and/or modify it
117fb290d0SLiam Girdwood  *  under  the terms of  the GNU General  Public License as published by the
127fb290d0SLiam Girdwood  *  Free Software Foundation;  either version 2 of the  License, or (at your
137fb290d0SLiam Girdwood  *  option) any later version.
147fb290d0SLiam Girdwood  *
157fb290d0SLiam Girdwood  *  Revision history
167fb290d0SLiam Girdwood  *    30th Nov 2005   Initial version.
177fb290d0SLiam Girdwood  *
187fb290d0SLiam Girdwood  */
197fb290d0SLiam Girdwood 
207fb290d0SLiam Girdwood #include <linux/module.h>
217fb290d0SLiam Girdwood #include <linux/moduleparam.h>
227fb290d0SLiam Girdwood #include <linux/timer.h>
237fb290d0SLiam Girdwood #include <linux/interrupt.h>
247fb290d0SLiam Girdwood #include <linux/platform_device.h>
257fb290d0SLiam Girdwood #include <sound/driver.h>
267fb290d0SLiam Girdwood #include <sound/core.h>
277fb290d0SLiam Girdwood #include <sound/pcm.h>
287fb290d0SLiam Girdwood #include <sound/soc.h>
297fb290d0SLiam Girdwood #include <sound/soc-dapm.h>
307fb290d0SLiam Girdwood 
317fb290d0SLiam Girdwood #include <asm/mach-types.h>
327fb290d0SLiam Girdwood #include <asm/hardware/scoop.h>
337fb290d0SLiam Girdwood #include <asm/arch/pxa-regs.h>
347fb290d0SLiam Girdwood #include <asm/arch/hardware.h>
357fb290d0SLiam Girdwood #include <asm/arch/akita.h>
367fb290d0SLiam Girdwood #include <asm/arch/spitz.h>
377fb290d0SLiam Girdwood #include <asm/mach-types.h>
387fb290d0SLiam Girdwood #include "../codecs/wm8750.h"
397fb290d0SLiam Girdwood #include "pxa2xx-pcm.h"
407fb290d0SLiam Girdwood 
417fb290d0SLiam Girdwood #define SPITZ_HP        0
427fb290d0SLiam Girdwood #define SPITZ_MIC       1
437fb290d0SLiam Girdwood #define SPITZ_LINE      2
447fb290d0SLiam Girdwood #define SPITZ_HEADSET   3
457fb290d0SLiam Girdwood #define SPITZ_HP_OFF    4
467fb290d0SLiam Girdwood #define SPITZ_SPK_ON    0
477fb290d0SLiam Girdwood #define SPITZ_SPK_OFF   1
487fb290d0SLiam Girdwood 
497fb290d0SLiam Girdwood  /* audio clock in Hz - rounded from 12.235MHz */
507fb290d0SLiam Girdwood #define SPITZ_AUDIO_CLOCK 12288000
517fb290d0SLiam Girdwood 
527fb290d0SLiam Girdwood static int spitz_jack_func;
537fb290d0SLiam Girdwood static int spitz_spk_func;
547fb290d0SLiam Girdwood 
557fb290d0SLiam Girdwood static void spitz_ext_control(struct snd_soc_codec *codec)
567fb290d0SLiam Girdwood {
577fb290d0SLiam Girdwood 	if (spitz_spk_func == SPITZ_SPK_ON)
587fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1);
597fb290d0SLiam Girdwood 	else
607fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Ext Spk", 0);
617fb290d0SLiam Girdwood 
627fb290d0SLiam Girdwood 	/* set up jack connection */
637fb290d0SLiam Girdwood 	switch (spitz_jack_func) {
647fb290d0SLiam Girdwood 	case SPITZ_HP:
657fb290d0SLiam Girdwood 		/* enable and unmute hp jack, disable mic bias */
667fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0);
677fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0);
687fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Line Jack", 0);
697fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1);
707fb290d0SLiam Girdwood 		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
717fb290d0SLiam Girdwood 		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
727fb290d0SLiam Girdwood 		break;
737fb290d0SLiam Girdwood 	case SPITZ_MIC:
747fb290d0SLiam Girdwood 		/* enable mic jack and bias, mute hp */
757fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0);
767fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0);
777fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Line Jack", 0);
787fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1);
797fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
807fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
817fb290d0SLiam Girdwood 		break;
827fb290d0SLiam Girdwood 	case SPITZ_LINE:
837fb290d0SLiam Girdwood 		/* enable line jack, disable mic bias and mute hp */
847fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0);
857fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0);
867fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0);
877fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Line Jack", 1);
887fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
897fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
907fb290d0SLiam Girdwood 		break;
917fb290d0SLiam Girdwood 	case SPITZ_HEADSET:
927fb290d0SLiam Girdwood 		/* enable and unmute headset jack enable mic bias, mute L hp */
937fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0);
947fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1);
957fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Line Jack", 0);
967fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headset Jack", 1);
977fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
987fb290d0SLiam Girdwood 		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
997fb290d0SLiam Girdwood 		break;
1007fb290d0SLiam Girdwood 	case SPITZ_HP_OFF:
1017fb290d0SLiam Girdwood 
1027fb290d0SLiam Girdwood 		/* jack removed, everything off */
1037fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0);
1047fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0);
1057fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0);
1067fb290d0SLiam Girdwood 		snd_soc_dapm_set_endpoint(codec, "Line Jack", 0);
1077fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
1087fb290d0SLiam Girdwood 		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
1097fb290d0SLiam Girdwood 		break;
1107fb290d0SLiam Girdwood 	}
1117fb290d0SLiam Girdwood 	snd_soc_dapm_sync_endpoints(codec);
1127fb290d0SLiam Girdwood }
1137fb290d0SLiam Girdwood 
1147fb290d0SLiam Girdwood static int spitz_startup(struct snd_pcm_substream *substream)
1157fb290d0SLiam Girdwood {
1167fb290d0SLiam Girdwood 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
1177fb290d0SLiam Girdwood 	struct snd_soc_codec *codec = rtd->socdev->codec;
1187fb290d0SLiam Girdwood 
1197fb290d0SLiam Girdwood 	/* check the jack status at stream startup */
1207fb290d0SLiam Girdwood 	spitz_ext_control(codec);
1217fb290d0SLiam Girdwood 	return 0;
1227fb290d0SLiam Girdwood }
1237fb290d0SLiam Girdwood 
1247fb290d0SLiam Girdwood static struct snd_soc_ops spitz_ops = {
1257fb290d0SLiam Girdwood 	.startup = spitz_startup,
1267fb290d0SLiam Girdwood };
1277fb290d0SLiam Girdwood 
1287fb290d0SLiam Girdwood static int spitz_get_jack(struct snd_kcontrol *kcontrol,
1297fb290d0SLiam Girdwood 	struct snd_ctl_elem_value *ucontrol)
1307fb290d0SLiam Girdwood {
1317fb290d0SLiam Girdwood 	ucontrol->value.integer.value[0] = spitz_jack_func;
1327fb290d0SLiam Girdwood 	return 0;
1337fb290d0SLiam Girdwood }
1347fb290d0SLiam Girdwood 
1357fb290d0SLiam Girdwood static int spitz_set_jack(struct snd_kcontrol *kcontrol,
1367fb290d0SLiam Girdwood 	struct snd_ctl_elem_value *ucontrol)
1377fb290d0SLiam Girdwood {
1387fb290d0SLiam Girdwood 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1397fb290d0SLiam Girdwood 
1407fb290d0SLiam Girdwood 	if (spitz_jack_func == ucontrol->value.integer.value[0])
1417fb290d0SLiam Girdwood 		return 0;
1427fb290d0SLiam Girdwood 
1437fb290d0SLiam Girdwood 	spitz_jack_func = ucontrol->value.integer.value[0];
1447fb290d0SLiam Girdwood 	spitz_ext_control(codec);
1457fb290d0SLiam Girdwood 	return 1;
1467fb290d0SLiam Girdwood }
1477fb290d0SLiam Girdwood 
1487fb290d0SLiam Girdwood static int spitz_get_spk(struct snd_kcontrol *kcontrol,
1497fb290d0SLiam Girdwood 	struct snd_ctl_elem_value *ucontrol)
1507fb290d0SLiam Girdwood {
1517fb290d0SLiam Girdwood 	ucontrol->value.integer.value[0] = spitz_spk_func;
1527fb290d0SLiam Girdwood 	return 0;
1537fb290d0SLiam Girdwood }
1547fb290d0SLiam Girdwood 
1557fb290d0SLiam Girdwood static int spitz_set_spk(struct snd_kcontrol *kcontrol,
1567fb290d0SLiam Girdwood 	struct snd_ctl_elem_value *ucontrol)
1577fb290d0SLiam Girdwood {
1587fb290d0SLiam Girdwood 	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
1597fb290d0SLiam Girdwood 
1607fb290d0SLiam Girdwood 	if (spitz_spk_func == ucontrol->value.integer.value[0])
1617fb290d0SLiam Girdwood 		return 0;
1627fb290d0SLiam Girdwood 
1637fb290d0SLiam Girdwood 	spitz_spk_func = ucontrol->value.integer.value[0];
1647fb290d0SLiam Girdwood 	spitz_ext_control(codec);
1657fb290d0SLiam Girdwood 	return 1;
1667fb290d0SLiam Girdwood }
1677fb290d0SLiam Girdwood 
1687fb290d0SLiam Girdwood static int spitz_mic_bias(struct snd_soc_dapm_widget *w, int event)
1697fb290d0SLiam Girdwood {
1707fb290d0SLiam Girdwood 	if (machine_is_borzoi() || machine_is_spitz()) {
1717fb290d0SLiam Girdwood 		if (SND_SOC_DAPM_EVENT_ON(event))
1727fb290d0SLiam Girdwood 			set_scoop_gpio(&spitzscoop2_device.dev,
1737fb290d0SLiam Girdwood 				SPITZ_SCP2_MIC_BIAS);
1747fb290d0SLiam Girdwood 		else
1757fb290d0SLiam Girdwood 			reset_scoop_gpio(&spitzscoop2_device.dev,
1767fb290d0SLiam Girdwood 				SPITZ_SCP2_MIC_BIAS);
1777fb290d0SLiam Girdwood 	}
1787fb290d0SLiam Girdwood 
1797fb290d0SLiam Girdwood 	if (machine_is_akita()) {
1807fb290d0SLiam Girdwood 		if (SND_SOC_DAPM_EVENT_ON(event))
1817fb290d0SLiam Girdwood 			akita_set_ioexp(&akitaioexp_device.dev,
1827fb290d0SLiam Girdwood 				AKITA_IOEXP_MIC_BIAS);
1837fb290d0SLiam Girdwood 		else
1847fb290d0SLiam Girdwood 			akita_reset_ioexp(&akitaioexp_device.dev,
1857fb290d0SLiam Girdwood 				AKITA_IOEXP_MIC_BIAS);
1867fb290d0SLiam Girdwood 	}
1877fb290d0SLiam Girdwood 	return 0;
1887fb290d0SLiam Girdwood }
1897fb290d0SLiam Girdwood 
1907fb290d0SLiam Girdwood /* spitz machine dapm widgets */
1917fb290d0SLiam Girdwood static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
1927fb290d0SLiam Girdwood 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
1937fb290d0SLiam Girdwood 	SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
1947fb290d0SLiam Girdwood 	SND_SOC_DAPM_SPK("Ext Spk", NULL),
1957fb290d0SLiam Girdwood 	SND_SOC_DAPM_LINE("Line Jack", NULL),
1967fb290d0SLiam Girdwood 
1977fb290d0SLiam Girdwood 	/* headset is a mic and mono headphone */
1987fb290d0SLiam Girdwood 	SND_SOC_DAPM_HP("Headset Jack", NULL),
1997fb290d0SLiam Girdwood };
2007fb290d0SLiam Girdwood 
2017fb290d0SLiam Girdwood /* Spitz machine audio_map */
2027fb290d0SLiam Girdwood static const char *audio_map[][3] = {
2037fb290d0SLiam Girdwood 
2047fb290d0SLiam Girdwood 	/* headphone connected to LOUT1, ROUT1 */
2057fb290d0SLiam Girdwood 	{"Headphone Jack", NULL, "LOUT1"},
2067fb290d0SLiam Girdwood 	{"Headphone Jack", NULL, "ROUT1"},
2077fb290d0SLiam Girdwood 
2087fb290d0SLiam Girdwood 	/* headset connected to ROUT1 and LINPUT1 with bias (def below) */
2097fb290d0SLiam Girdwood 	{"Headset Jack", NULL, "ROUT1"},
2107fb290d0SLiam Girdwood 
2117fb290d0SLiam Girdwood 	/* ext speaker connected to LOUT2, ROUT2  */
2127fb290d0SLiam Girdwood 	{"Ext Spk", NULL , "ROUT2"},
2137fb290d0SLiam Girdwood 	{"Ext Spk", NULL , "LOUT2"},
2147fb290d0SLiam Girdwood 
2157fb290d0SLiam Girdwood 	/* mic is connected to input 1 - with bias */
2167fb290d0SLiam Girdwood 	{"LINPUT1", NULL, "Mic Bias"},
2177fb290d0SLiam Girdwood 	{"Mic Bias", NULL, "Mic Jack"},
2187fb290d0SLiam Girdwood 
2197fb290d0SLiam Girdwood 	/* line is connected to input 1 - no bias */
2207fb290d0SLiam Girdwood 	{"LINPUT1", NULL, "Line Jack"},
2217fb290d0SLiam Girdwood 
2227fb290d0SLiam Girdwood 	{NULL, NULL, NULL},
2237fb290d0SLiam Girdwood };
2247fb290d0SLiam Girdwood 
2257fb290d0SLiam Girdwood static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
2267fb290d0SLiam Girdwood 	"Off"};
2277fb290d0SLiam Girdwood static const char *spk_function[] = {"On", "Off"};
2287fb290d0SLiam Girdwood static const struct soc_enum spitz_enum[] = {
2297fb290d0SLiam Girdwood 	SOC_ENUM_SINGLE_EXT(5, jack_function),
2307fb290d0SLiam Girdwood 	SOC_ENUM_SINGLE_EXT(2, spk_function),
2317fb290d0SLiam Girdwood };
2327fb290d0SLiam Girdwood 
2337fb290d0SLiam Girdwood static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
2347fb290d0SLiam Girdwood 	SOC_ENUM_EXT("Jack Function", spitz_enum[0], spitz_get_jack,
2357fb290d0SLiam Girdwood 		spitz_set_jack),
2367fb290d0SLiam Girdwood 	SOC_ENUM_EXT("Speaker Function", spitz_enum[1], spitz_get_spk,
2377fb290d0SLiam Girdwood 		spitz_set_spk),
2387fb290d0SLiam Girdwood };
2397fb290d0SLiam Girdwood 
2407fb290d0SLiam Girdwood /*
2417fb290d0SLiam Girdwood  * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
2427fb290d0SLiam Girdwood  */
2437fb290d0SLiam Girdwood static int spitz_wm8750_init(struct snd_soc_codec *codec)
2447fb290d0SLiam Girdwood {
2457fb290d0SLiam Girdwood 	int i, err;
2467fb290d0SLiam Girdwood 
2477fb290d0SLiam Girdwood 	/* NC codec pins */
2487fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "RINPUT1", 0);
2497fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "LINPUT2", 0);
2507fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "RINPUT2", 0);
2517fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "LINPUT3", 0);
2527fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "RINPUT3", 0);
2537fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "OUT3", 0);
2547fb290d0SLiam Girdwood 	snd_soc_dapm_set_endpoint(codec, "MONO", 0);
2557fb290d0SLiam Girdwood 
2567fb290d0SLiam Girdwood 	/* Add spitz specific controls */
2577fb290d0SLiam Girdwood 	for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) {
2587fb290d0SLiam Girdwood 		err = snd_ctl_add(codec->card,
2597fb290d0SLiam Girdwood 			snd_soc_cnew(&wm8750_spitz_controls[i], codec, NULL));
2607fb290d0SLiam Girdwood 		if (err < 0)
2617fb290d0SLiam Girdwood 			return err;
2627fb290d0SLiam Girdwood 	}
2637fb290d0SLiam Girdwood 
2647fb290d0SLiam Girdwood 	/* Add spitz specific widgets */
2657fb290d0SLiam Girdwood 	for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) {
2667fb290d0SLiam Girdwood 		snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]);
2677fb290d0SLiam Girdwood 	}
2687fb290d0SLiam Girdwood 
2697fb290d0SLiam Girdwood 	/* Set up spitz specific audio path audio_map */
2707fb290d0SLiam Girdwood 	for (i = 0; audio_map[i][0] != NULL; i++) {
2717fb290d0SLiam Girdwood 		snd_soc_dapm_connect_input(codec, audio_map[i][0],
2727fb290d0SLiam Girdwood 			audio_map[i][1], audio_map[i][2]);
2737fb290d0SLiam Girdwood 	}
2747fb290d0SLiam Girdwood 
2757fb290d0SLiam Girdwood 	snd_soc_dapm_sync_endpoints(codec);
2767fb290d0SLiam Girdwood 	return 0;
2777fb290d0SLiam Girdwood }
2787fb290d0SLiam Girdwood 
2797fb290d0SLiam Girdwood static unsigned int spitz_config_sysclk(struct snd_soc_pcm_runtime *rtd,
2807fb290d0SLiam Girdwood 	struct snd_soc_clock_info *info)
2817fb290d0SLiam Girdwood {
2827fb290d0SLiam Girdwood 	if (info->bclk_master & SND_SOC_DAIFMT_CBS_CFS) {
2837fb290d0SLiam Girdwood 		/* pxa2xx is i2s master  */
2847fb290d0SLiam Girdwood 		switch (info->rate) {
2857fb290d0SLiam Girdwood 		case 11025:
2867fb290d0SLiam Girdwood 		case 22050:
2877fb290d0SLiam Girdwood 		case 44100:
2887fb290d0SLiam Girdwood 		case 88200:
2897fb290d0SLiam Girdwood 			/* configure codec digital filters
2907fb290d0SLiam Girdwood 			 * for 11.025, 22.05, 44.1, 88.2 */
2917fb290d0SLiam Girdwood 			rtd->codec_dai->config_sysclk(rtd->codec_dai, info,
2927fb290d0SLiam Girdwood 				11289600);
2937fb290d0SLiam Girdwood 		break;
2947fb290d0SLiam Girdwood 		default:
2957fb290d0SLiam Girdwood 			/* configure codec digital filters for all other rates */
2967fb290d0SLiam Girdwood 			rtd->codec_dai->config_sysclk(rtd->codec_dai, info,
2977fb290d0SLiam Girdwood 				SPITZ_AUDIO_CLOCK);
2987fb290d0SLiam Girdwood 		break;
2997fb290d0SLiam Girdwood 		}
3007fb290d0SLiam Girdwood 		/* configure pxa2xx i2s interface clocks as master */
3017fb290d0SLiam Girdwood 		return rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info,
3027fb290d0SLiam Girdwood 			SPITZ_AUDIO_CLOCK);
3037fb290d0SLiam Girdwood 	} else {
3047fb290d0SLiam Girdwood 		/* codec is i2s master - only configure codec DAI clock */
3057fb290d0SLiam Girdwood 		return rtd->codec_dai->config_sysclk(rtd->codec_dai, info,
3067fb290d0SLiam Girdwood 			SPITZ_AUDIO_CLOCK);
3077fb290d0SLiam Girdwood 	}
3087fb290d0SLiam Girdwood }
3097fb290d0SLiam Girdwood 
3107fb290d0SLiam Girdwood /* spitz digital audio interface glue - connects codec <--> CPU */
3117fb290d0SLiam Girdwood static struct snd_soc_dai_link spitz_dai = {
3127fb290d0SLiam Girdwood 	.name = "wm8750",
3137fb290d0SLiam Girdwood 	.stream_name = "WM8750",
3147fb290d0SLiam Girdwood 	.cpu_dai = &pxa_i2s_dai,
3157fb290d0SLiam Girdwood 	.codec_dai = &wm8750_dai,
3167fb290d0SLiam Girdwood 	.init = spitz_wm8750_init,
3177fb290d0SLiam Girdwood 	.config_sysclk = spitz_config_sysclk,
3187fb290d0SLiam Girdwood };
3197fb290d0SLiam Girdwood 
3207fb290d0SLiam Girdwood /* spitz audio machine driver */
3217fb290d0SLiam Girdwood static struct snd_soc_machine snd_soc_machine_spitz = {
3227fb290d0SLiam Girdwood 	.name = "Spitz",
3237fb290d0SLiam Girdwood 	.dai_link = &spitz_dai,
3247fb290d0SLiam Girdwood 	.num_links = 1,
3257fb290d0SLiam Girdwood 	.ops = &spitz_ops,
3267fb290d0SLiam Girdwood };
3277fb290d0SLiam Girdwood 
3287fb290d0SLiam Girdwood /* spitz audio private data */
3297fb290d0SLiam Girdwood static struct wm8750_setup_data spitz_wm8750_setup = {
3307fb290d0SLiam Girdwood 	.i2c_address = 0x1b,
3317fb290d0SLiam Girdwood };
3327fb290d0SLiam Girdwood 
3337fb290d0SLiam Girdwood /* spitz audio subsystem */
3347fb290d0SLiam Girdwood static struct snd_soc_device spitz_snd_devdata = {
3357fb290d0SLiam Girdwood 	.machine = &snd_soc_machine_spitz,
3367fb290d0SLiam Girdwood 	.platform = &pxa2xx_soc_platform,
3377fb290d0SLiam Girdwood 	.codec_dev = &soc_codec_dev_wm8750,
3387fb290d0SLiam Girdwood 	.codec_data = &spitz_wm8750_setup,
3397fb290d0SLiam Girdwood };
3407fb290d0SLiam Girdwood 
3417fb290d0SLiam Girdwood static struct platform_device *spitz_snd_device;
3427fb290d0SLiam Girdwood 
3437fb290d0SLiam Girdwood static int __init spitz_init(void)
3447fb290d0SLiam Girdwood {
3457fb290d0SLiam Girdwood 	int ret;
3467fb290d0SLiam Girdwood 
3477fb290d0SLiam Girdwood 	if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
3487fb290d0SLiam Girdwood 		return -ENODEV;
3497fb290d0SLiam Girdwood 
3507fb290d0SLiam Girdwood 	spitz_snd_device = platform_device_alloc("soc-audio", -1);
3517fb290d0SLiam Girdwood 	if (!spitz_snd_device)
3527fb290d0SLiam Girdwood 		return -ENOMEM;
3537fb290d0SLiam Girdwood 
3547fb290d0SLiam Girdwood 	platform_set_drvdata(spitz_snd_device, &spitz_snd_devdata);
3557fb290d0SLiam Girdwood 	spitz_snd_devdata.dev = &spitz_snd_device->dev;
3567fb290d0SLiam Girdwood 	ret = platform_device_add(spitz_snd_device);
3577fb290d0SLiam Girdwood 
3587fb290d0SLiam Girdwood 	if (ret)
3597fb290d0SLiam Girdwood 		platform_device_put(spitz_snd_device);
3607fb290d0SLiam Girdwood 
3617fb290d0SLiam Girdwood 	return ret;
3627fb290d0SLiam Girdwood }
3637fb290d0SLiam Girdwood 
3647fb290d0SLiam Girdwood static void __exit spitz_exit(void)
3657fb290d0SLiam Girdwood {
3667fb290d0SLiam Girdwood 	platform_device_unregister(spitz_snd_device);
3677fb290d0SLiam Girdwood }
3687fb290d0SLiam Girdwood 
3697fb290d0SLiam Girdwood module_init(spitz_init);
3707fb290d0SLiam Girdwood module_exit(spitz_exit);
3717fb290d0SLiam Girdwood 
3727fb290d0SLiam Girdwood MODULE_AUTHOR("Richard Purdie");
3737fb290d0SLiam Girdwood MODULE_DESCRIPTION("ALSA SoC Spitz");
3747fb290d0SLiam Girdwood MODULE_LICENSE("GPL");
375