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 * 7d331124dSLiam Girdwood * Authors: Liam Girdwood <lrg@slimlogic.co.uk> 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 */ 167fb290d0SLiam Girdwood 177fb290d0SLiam Girdwood #include <linux/module.h> 187fb290d0SLiam Girdwood #include <linux/moduleparam.h> 197fb290d0SLiam Girdwood #include <linux/timer.h> 207fb290d0SLiam Girdwood #include <linux/interrupt.h> 217fb290d0SLiam Girdwood #include <linux/platform_device.h> 22fff14720SEric Miao #include <linux/gpio.h> 237fb290d0SLiam Girdwood #include <sound/core.h> 247fb290d0SLiam Girdwood #include <sound/pcm.h> 257fb290d0SLiam Girdwood #include <sound/soc.h> 267fb290d0SLiam Girdwood 277fb290d0SLiam Girdwood #include <asm/mach-types.h> 28a09e64fbSRussell King #include <mach/spitz.h> 297fb290d0SLiam Girdwood #include "../codecs/wm8750.h" 3097952f60SLiam Girdwood #include "pxa2xx-i2s.h" 317fb290d0SLiam Girdwood 327fb290d0SLiam Girdwood #define SPITZ_HP 0 337fb290d0SLiam Girdwood #define SPITZ_MIC 1 347fb290d0SLiam Girdwood #define SPITZ_LINE 2 357fb290d0SLiam Girdwood #define SPITZ_HEADSET 3 367fb290d0SLiam Girdwood #define SPITZ_HP_OFF 4 377fb290d0SLiam Girdwood #define SPITZ_SPK_ON 0 387fb290d0SLiam Girdwood #define SPITZ_SPK_OFF 1 397fb290d0SLiam Girdwood 407fb290d0SLiam Girdwood /* audio clock in Hz - rounded from 12.235MHz */ 417fb290d0SLiam Girdwood #define SPITZ_AUDIO_CLOCK 12288000 427fb290d0SLiam Girdwood 437fb290d0SLiam Girdwood static int spitz_jack_func; 447fb290d0SLiam Girdwood static int spitz_spk_func; 4504368d05SMarek Vasut static int spitz_mic_gpio; 467fb290d0SLiam Girdwood 470e66821fSLiam Girdwood static void spitz_ext_control(struct snd_soc_card *card) 487fb290d0SLiam Girdwood { 490e66821fSLiam Girdwood struct snd_soc_dapm_context *dapm = &card->dapm; 50ce6120ccSLiam Girdwood 517fb290d0SLiam Girdwood if (spitz_spk_func == SPITZ_SPK_ON) 52ce6120ccSLiam Girdwood snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 537fb290d0SLiam Girdwood else 54ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 557fb290d0SLiam Girdwood 567fb290d0SLiam Girdwood /* set up jack connection */ 577fb290d0SLiam Girdwood switch (spitz_jack_func) { 587fb290d0SLiam Girdwood case SPITZ_HP: 597fb290d0SLiam Girdwood /* enable and unmute hp jack, disable mic bias */ 60ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 61ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 62ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Line Jack"); 63ce6120ccSLiam Girdwood snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 64fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_L, 1); 65fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 667fb290d0SLiam Girdwood break; 677fb290d0SLiam Girdwood case SPITZ_MIC: 687fb290d0SLiam Girdwood /* enable mic jack and bias, mute hp */ 69ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 70ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 71ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Line Jack"); 72ce6120ccSLiam Girdwood snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 73fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 74fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 757fb290d0SLiam Girdwood break; 767fb290d0SLiam Girdwood case SPITZ_LINE: 777fb290d0SLiam Girdwood /* enable line jack, disable mic bias and mute hp */ 78ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 79ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 80ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 81ce6120ccSLiam Girdwood snd_soc_dapm_enable_pin(dapm, "Line Jack"); 82fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 83fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 847fb290d0SLiam Girdwood break; 857fb290d0SLiam Girdwood case SPITZ_HEADSET: 867fb290d0SLiam Girdwood /* enable and unmute headset jack enable mic bias, mute L hp */ 87ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 88ce6120ccSLiam Girdwood snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 89ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Line Jack"); 90ce6120ccSLiam Girdwood snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 91fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 92fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 937fb290d0SLiam Girdwood break; 947fb290d0SLiam Girdwood case SPITZ_HP_OFF: 957fb290d0SLiam Girdwood 967fb290d0SLiam Girdwood /* jack removed, everything off */ 97ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 98ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 99ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 100ce6120ccSLiam Girdwood snd_soc_dapm_disable_pin(dapm, "Line Jack"); 101fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 102fff14720SEric Miao gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 1037fb290d0SLiam Girdwood break; 1047fb290d0SLiam Girdwood } 105ce6120ccSLiam Girdwood snd_soc_dapm_sync(dapm); 1067fb290d0SLiam Girdwood } 1077fb290d0SLiam Girdwood 1087fb290d0SLiam Girdwood static int spitz_startup(struct snd_pcm_substream *substream) 1097fb290d0SLiam Girdwood { 1107fb290d0SLiam Girdwood struct snd_soc_pcm_runtime *rtd = substream->private_data; 111f0fba2adSLiam Girdwood struct snd_soc_codec *codec = rtd->codec; 1127fb290d0SLiam Girdwood 11371a29560SMark Brown mutex_lock(&codec->mutex); 11471a29560SMark Brown 1157fb290d0SLiam Girdwood /* check the jack status at stream startup */ 1167fb290d0SLiam Girdwood spitz_ext_control(codec); 11771a29560SMark Brown 11871a29560SMark Brown mutex_unlock(&codec->mutex); 11971a29560SMark Brown 1207fb290d0SLiam Girdwood return 0; 1217fb290d0SLiam Girdwood } 1227fb290d0SLiam Girdwood 12397952f60SLiam Girdwood static int spitz_hw_params(struct snd_pcm_substream *substream, 12497952f60SLiam Girdwood struct snd_pcm_hw_params *params) 12597952f60SLiam Girdwood { 12697952f60SLiam Girdwood struct snd_soc_pcm_runtime *rtd = substream->private_data; 127f0fba2adSLiam Girdwood struct snd_soc_dai *codec_dai = rtd->codec_dai; 128f0fba2adSLiam Girdwood struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 12997952f60SLiam Girdwood unsigned int clk = 0; 13097952f60SLiam Girdwood int ret = 0; 13197952f60SLiam Girdwood 13297952f60SLiam Girdwood switch (params_rate(params)) { 13397952f60SLiam Girdwood case 8000: 13497952f60SLiam Girdwood case 16000: 13597952f60SLiam Girdwood case 48000: 13697952f60SLiam Girdwood case 96000: 13797952f60SLiam Girdwood clk = 12288000; 13897952f60SLiam Girdwood break; 13997952f60SLiam Girdwood case 11025: 14097952f60SLiam Girdwood case 22050: 14197952f60SLiam Girdwood case 44100: 14297952f60SLiam Girdwood clk = 11289600; 14397952f60SLiam Girdwood break; 14497952f60SLiam Girdwood } 14597952f60SLiam Girdwood 14697952f60SLiam Girdwood /* set the codec system clock for DAC and ADC */ 14764105cfdSLiam Girdwood ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, 14897952f60SLiam Girdwood SND_SOC_CLOCK_IN); 14997952f60SLiam Girdwood if (ret < 0) 15097952f60SLiam Girdwood return ret; 15197952f60SLiam Girdwood 15297952f60SLiam Girdwood /* set the I2S system clock as input (unused) */ 15364105cfdSLiam Girdwood ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, 15497952f60SLiam Girdwood SND_SOC_CLOCK_IN); 15597952f60SLiam Girdwood if (ret < 0) 15697952f60SLiam Girdwood return ret; 15797952f60SLiam Girdwood 15897952f60SLiam Girdwood return 0; 15997952f60SLiam Girdwood } 16097952f60SLiam Girdwood 1617fb290d0SLiam Girdwood static struct snd_soc_ops spitz_ops = { 1627fb290d0SLiam Girdwood .startup = spitz_startup, 16397952f60SLiam Girdwood .hw_params = spitz_hw_params, 1647fb290d0SLiam Girdwood }; 1657fb290d0SLiam Girdwood 1667fb290d0SLiam Girdwood static int spitz_get_jack(struct snd_kcontrol *kcontrol, 1677fb290d0SLiam Girdwood struct snd_ctl_elem_value *ucontrol) 1687fb290d0SLiam Girdwood { 1697fb290d0SLiam Girdwood ucontrol->value.integer.value[0] = spitz_jack_func; 1707fb290d0SLiam Girdwood return 0; 1717fb290d0SLiam Girdwood } 1727fb290d0SLiam Girdwood 1737fb290d0SLiam Girdwood static int spitz_set_jack(struct snd_kcontrol *kcontrol, 1747fb290d0SLiam Girdwood struct snd_ctl_elem_value *ucontrol) 1757fb290d0SLiam Girdwood { 1760e66821fSLiam Girdwood struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 1777fb290d0SLiam Girdwood 1787fb290d0SLiam Girdwood if (spitz_jack_func == ucontrol->value.integer.value[0]) 1797fb290d0SLiam Girdwood return 0; 1807fb290d0SLiam Girdwood 1817fb290d0SLiam Girdwood spitz_jack_func = ucontrol->value.integer.value[0]; 1820e66821fSLiam Girdwood spitz_ext_control(card); 1837fb290d0SLiam Girdwood return 1; 1847fb290d0SLiam Girdwood } 1857fb290d0SLiam Girdwood 1867fb290d0SLiam Girdwood static int spitz_get_spk(struct snd_kcontrol *kcontrol, 1877fb290d0SLiam Girdwood struct snd_ctl_elem_value *ucontrol) 1887fb290d0SLiam Girdwood { 1897fb290d0SLiam Girdwood ucontrol->value.integer.value[0] = spitz_spk_func; 1907fb290d0SLiam Girdwood return 0; 1917fb290d0SLiam Girdwood } 1927fb290d0SLiam Girdwood 1937fb290d0SLiam Girdwood static int spitz_set_spk(struct snd_kcontrol *kcontrol, 1947fb290d0SLiam Girdwood struct snd_ctl_elem_value *ucontrol) 1957fb290d0SLiam Girdwood { 1960e66821fSLiam Girdwood struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 1977fb290d0SLiam Girdwood 1987fb290d0SLiam Girdwood if (spitz_spk_func == ucontrol->value.integer.value[0]) 1997fb290d0SLiam Girdwood return 0; 2007fb290d0SLiam Girdwood 2017fb290d0SLiam Girdwood spitz_spk_func = ucontrol->value.integer.value[0]; 2020e66821fSLiam Girdwood spitz_ext_control(card); 2037fb290d0SLiam Girdwood return 1; 2047fb290d0SLiam Girdwood } 2057fb290d0SLiam Girdwood 206338c7ed0SJarkko Nikula static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 207338c7ed0SJarkko Nikula struct snd_kcontrol *k, int event) 2087fb290d0SLiam Girdwood { 20904368d05SMarek Vasut gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event)); 2107fb290d0SLiam Girdwood return 0; 2117fb290d0SLiam Girdwood } 2127fb290d0SLiam Girdwood 2137fb290d0SLiam Girdwood /* spitz machine dapm widgets */ 2147fb290d0SLiam Girdwood static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { 2157fb290d0SLiam Girdwood SND_SOC_DAPM_HP("Headphone Jack", NULL), 2167fb290d0SLiam Girdwood SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), 2177fb290d0SLiam Girdwood SND_SOC_DAPM_SPK("Ext Spk", NULL), 2187fb290d0SLiam Girdwood SND_SOC_DAPM_LINE("Line Jack", NULL), 2197fb290d0SLiam Girdwood 2207fb290d0SLiam Girdwood /* headset is a mic and mono headphone */ 2217fb290d0SLiam Girdwood SND_SOC_DAPM_HP("Headset Jack", NULL), 2227fb290d0SLiam Girdwood }; 2237fb290d0SLiam Girdwood 2247fb290d0SLiam Girdwood /* Spitz machine audio_map */ 2257c274263SAxel Lin static const struct snd_soc_dapm_route spitz_audio_map[] = { 2267fb290d0SLiam Girdwood 2277fb290d0SLiam Girdwood /* headphone connected to LOUT1, ROUT1 */ 2287fb290d0SLiam Girdwood {"Headphone Jack", NULL, "LOUT1"}, 2297fb290d0SLiam Girdwood {"Headphone Jack", NULL, "ROUT1"}, 2307fb290d0SLiam Girdwood 2317fb290d0SLiam Girdwood /* headset connected to ROUT1 and LINPUT1 with bias (def below) */ 2327fb290d0SLiam Girdwood {"Headset Jack", NULL, "ROUT1"}, 2337fb290d0SLiam Girdwood 2347fb290d0SLiam Girdwood /* ext speaker connected to LOUT2, ROUT2 */ 2357fb290d0SLiam Girdwood {"Ext Spk", NULL , "ROUT2"}, 2367fb290d0SLiam Girdwood {"Ext Spk", NULL , "LOUT2"}, 2377fb290d0SLiam Girdwood 2387fb290d0SLiam Girdwood /* mic is connected to input 1 - with bias */ 2397fb290d0SLiam Girdwood {"LINPUT1", NULL, "Mic Bias"}, 2407fb290d0SLiam Girdwood {"Mic Bias", NULL, "Mic Jack"}, 2417fb290d0SLiam Girdwood 2427fb290d0SLiam Girdwood /* line is connected to input 1 - no bias */ 2437fb290d0SLiam Girdwood {"LINPUT1", NULL, "Line Jack"}, 2447fb290d0SLiam Girdwood }; 2457fb290d0SLiam Girdwood 2467fb290d0SLiam Girdwood static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", 2477fb290d0SLiam Girdwood "Off"}; 2487fb290d0SLiam Girdwood static const char *spk_function[] = {"On", "Off"}; 2497fb290d0SLiam Girdwood static const struct soc_enum spitz_enum[] = { 2507fb290d0SLiam Girdwood SOC_ENUM_SINGLE_EXT(5, jack_function), 2517fb290d0SLiam Girdwood SOC_ENUM_SINGLE_EXT(2, spk_function), 2527fb290d0SLiam Girdwood }; 2537fb290d0SLiam Girdwood 2547fb290d0SLiam Girdwood static const struct snd_kcontrol_new wm8750_spitz_controls[] = { 2557fb290d0SLiam Girdwood SOC_ENUM_EXT("Jack Function", spitz_enum[0], spitz_get_jack, 2567fb290d0SLiam Girdwood spitz_set_jack), 2577fb290d0SLiam Girdwood SOC_ENUM_EXT("Speaker Function", spitz_enum[1], spitz_get_spk, 2587fb290d0SLiam Girdwood spitz_set_spk), 2597fb290d0SLiam Girdwood }; 2607fb290d0SLiam Girdwood 2617fb290d0SLiam Girdwood /* 2627fb290d0SLiam Girdwood * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device 2637fb290d0SLiam Girdwood */ 264f0fba2adSLiam Girdwood static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) 2657fb290d0SLiam Girdwood { 266f0fba2adSLiam Girdwood struct snd_soc_codec *codec = rtd->codec; 267ce6120ccSLiam Girdwood struct snd_soc_dapm_context *dapm = &codec->dapm; 2687fb290d0SLiam Girdwood 2697fb290d0SLiam Girdwood /* NC codec pins */ 270ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "RINPUT1"); 271ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "LINPUT2"); 272ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "RINPUT2"); 273ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "LINPUT3"); 274ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "RINPUT3"); 275ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "OUT3"); 276ce6120ccSLiam Girdwood snd_soc_dapm_nc_pin(dapm, "MONO1"); 2777fb290d0SLiam Girdwood 2787fb290d0SLiam Girdwood return 0; 2797fb290d0SLiam Girdwood } 2807fb290d0SLiam Girdwood 2817fb290d0SLiam Girdwood /* spitz digital audio interface glue - connects codec <--> CPU */ 2827fb290d0SLiam Girdwood static struct snd_soc_dai_link spitz_dai = { 2837fb290d0SLiam Girdwood .name = "wm8750", 2847fb290d0SLiam Girdwood .stream_name = "WM8750", 285a3adfa00SDmitry Eremin-Solenikov .cpu_dai_name = "pxa2xx-i2s", 286f0fba2adSLiam Girdwood .codec_dai_name = "wm8750-hifi", 287f0fba2adSLiam Girdwood .platform_name = "pxa-pcm-audio", 288dc5de62bSMark Brown .codec_name = "wm8750.0-001b", 2897fb290d0SLiam Girdwood .init = spitz_wm8750_init, 290c0e94231SAxel Lin .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 291c0e94231SAxel Lin SND_SOC_DAIFMT_CBS_CFS, 29297952f60SLiam Girdwood .ops = &spitz_ops, 2937fb290d0SLiam Girdwood }; 2947fb290d0SLiam Girdwood 2957fb290d0SLiam Girdwood /* spitz audio machine driver */ 29687506549SMark Brown static struct snd_soc_card snd_soc_spitz = { 2977fb290d0SLiam Girdwood .name = "Spitz", 298561c6a17SAxel Lin .owner = THIS_MODULE, 2997fb290d0SLiam Girdwood .dai_link = &spitz_dai, 3007fb290d0SLiam Girdwood .num_links = 1, 3017c274263SAxel Lin 3027c274263SAxel Lin .controls = wm8750_spitz_controls, 3037c274263SAxel Lin .num_controls = ARRAY_SIZE(wm8750_spitz_controls), 3047c274263SAxel Lin .dapm_widgets = wm8750_dapm_widgets, 3057c274263SAxel Lin .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), 3067c274263SAxel Lin .dapm_routes = spitz_audio_map, 3077c274263SAxel Lin .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), 3087fb290d0SLiam Girdwood }; 3097fb290d0SLiam Girdwood 3107fb290d0SLiam Girdwood static struct platform_device *spitz_snd_device; 3117fb290d0SLiam Girdwood 3127fb290d0SLiam Girdwood static int __init spitz_init(void) 3137fb290d0SLiam Girdwood { 3147fb290d0SLiam Girdwood int ret; 3157fb290d0SLiam Girdwood 3167fb290d0SLiam Girdwood if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 3177fb290d0SLiam Girdwood return -ENODEV; 3187fb290d0SLiam Girdwood 31904368d05SMarek Vasut if (machine_is_borzoi() || machine_is_spitz()) 32004368d05SMarek Vasut spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS; 32104368d05SMarek Vasut else 32204368d05SMarek Vasut spitz_mic_gpio = AKITA_GPIO_MIC_BIAS; 32304368d05SMarek Vasut 32404368d05SMarek Vasut ret = gpio_request(spitz_mic_gpio, "MIC GPIO"); 32504368d05SMarek Vasut if (ret) 32604368d05SMarek Vasut goto err1; 32704368d05SMarek Vasut 32804368d05SMarek Vasut ret = gpio_direction_output(spitz_mic_gpio, 0); 32904368d05SMarek Vasut if (ret) 33004368d05SMarek Vasut goto err2; 33104368d05SMarek Vasut 3327fb290d0SLiam Girdwood spitz_snd_device = platform_device_alloc("soc-audio", -1); 33304368d05SMarek Vasut if (!spitz_snd_device) { 33404368d05SMarek Vasut ret = -ENOMEM; 33504368d05SMarek Vasut goto err2; 33604368d05SMarek Vasut } 3377fb290d0SLiam Girdwood 338f0fba2adSLiam Girdwood platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); 33904368d05SMarek Vasut 3407fb290d0SLiam Girdwood ret = platform_device_add(spitz_snd_device); 3417fb290d0SLiam Girdwood if (ret) 34204368d05SMarek Vasut goto err3; 3437fb290d0SLiam Girdwood 34404368d05SMarek Vasut return 0; 34504368d05SMarek Vasut 34604368d05SMarek Vasut err3: 34704368d05SMarek Vasut platform_device_put(spitz_snd_device); 34804368d05SMarek Vasut err2: 34904368d05SMarek Vasut gpio_free(spitz_mic_gpio); 35004368d05SMarek Vasut err1: 3517fb290d0SLiam Girdwood return ret; 3527fb290d0SLiam Girdwood } 3537fb290d0SLiam Girdwood 3547fb290d0SLiam Girdwood static void __exit spitz_exit(void) 3557fb290d0SLiam Girdwood { 3567fb290d0SLiam Girdwood platform_device_unregister(spitz_snd_device); 35704368d05SMarek Vasut gpio_free(spitz_mic_gpio); 3587fb290d0SLiam Girdwood } 3597fb290d0SLiam Girdwood 3607fb290d0SLiam Girdwood module_init(spitz_init); 3617fb290d0SLiam Girdwood module_exit(spitz_exit); 3627fb290d0SLiam Girdwood 3637fb290d0SLiam Girdwood MODULE_AUTHOR("Richard Purdie"); 3647fb290d0SLiam Girdwood MODULE_DESCRIPTION("ALSA SoC Spitz"); 3657fb290d0SLiam Girdwood MODULE_LICENSE("GPL"); 366