1/* 2 * Tegra machine ASoC driver for boards using a MAX90809 CODEC. 3 * 4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 * Based on code copyright/by: 19 * 20 * Copyright (C) 2010-2012 - NVIDIA, Inc. 21 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 22 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd. 23 * Copyright 2007 Wolfson Microelectronics PLC. 24 */ 25 26#include <linux/module.h> 27#include <linux/platform_device.h> 28#include <linux/slab.h> 29#include <linux/gpio.h> 30#include <linux/of_gpio.h> 31 32#include <sound/core.h> 33#include <sound/jack.h> 34#include <sound/pcm.h> 35#include <sound/pcm_params.h> 36#include <sound/soc.h> 37 38#include "tegra_asoc_utils.h" 39 40#define DRV_NAME "tegra-snd-max98090" 41 42struct tegra_max98090 { 43 struct tegra_asoc_utils_data util_data; 44 int gpio_hp_det; 45 int gpio_mic_det; 46}; 47 48static int tegra_max98090_asoc_hw_params(struct snd_pcm_substream *substream, 49 struct snd_pcm_hw_params *params) 50{ 51 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_dai *codec_dai = rtd->codec_dai; 53 struct snd_soc_card *card = rtd->card; 54 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); 55 int srate, mclk; 56 int err; 57 58 srate = params_rate(params); 59 switch (srate) { 60 case 8000: 61 case 16000: 62 case 24000: 63 case 32000: 64 case 48000: 65 case 64000: 66 case 96000: 67 mclk = 12288000; 68 break; 69 case 11025: 70 case 22050: 71 case 44100: 72 case 88200: 73 mclk = 11289600; 74 break; 75 default: 76 mclk = 12000000; 77 break; 78 } 79 80 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); 81 if (err < 0) { 82 dev_err(card->dev, "Can't configure clocks\n"); 83 return err; 84 } 85 86 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 87 SND_SOC_CLOCK_IN); 88 if (err < 0) { 89 dev_err(card->dev, "codec_dai clock not set\n"); 90 return err; 91 } 92 93 return 0; 94} 95 96static struct snd_soc_ops tegra_max98090_ops = { 97 .hw_params = tegra_max98090_asoc_hw_params, 98}; 99 100static struct snd_soc_jack tegra_max98090_hp_jack; 101 102static struct snd_soc_jack_pin tegra_max98090_hp_jack_pins[] = { 103 { 104 .pin = "Headphones", 105 .mask = SND_JACK_HEADPHONE, 106 }, 107}; 108 109static struct snd_soc_jack_gpio tegra_max98090_hp_jack_gpio = { 110 .name = "Headphone detection", 111 .report = SND_JACK_HEADPHONE, 112 .debounce_time = 150, 113 .invert = 1, 114}; 115 116static struct snd_soc_jack tegra_max98090_mic_jack; 117 118static struct snd_soc_jack_pin tegra_max98090_mic_jack_pins[] = { 119 { 120 .pin = "Mic Jack", 121 .mask = SND_JACK_MICROPHONE, 122 }, 123}; 124 125static struct snd_soc_jack_gpio tegra_max98090_mic_jack_gpio = { 126 .name = "Mic detection", 127 .report = SND_JACK_MICROPHONE, 128 .debounce_time = 150, 129 .invert = 1, 130}; 131 132static const struct snd_soc_dapm_widget tegra_max98090_dapm_widgets[] = { 133 SND_SOC_DAPM_HP("Headphones", NULL), 134 SND_SOC_DAPM_SPK("Speakers", NULL), 135 SND_SOC_DAPM_MIC("Mic Jack", NULL), 136 SND_SOC_DAPM_MIC("Int Mic", NULL), 137}; 138 139static const struct snd_kcontrol_new tegra_max98090_controls[] = { 140 SOC_DAPM_PIN_SWITCH("Headphones"), 141 SOC_DAPM_PIN_SWITCH("Speakers"), 142 SOC_DAPM_PIN_SWITCH("Mic Jack"), 143 SOC_DAPM_PIN_SWITCH("Int Mic"), 144}; 145 146static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) 147{ 148 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(rtd->card); 149 150 if (gpio_is_valid(machine->gpio_hp_det)) { 151 snd_soc_card_jack_new(rtd->card, "Headphones", 152 SND_JACK_HEADPHONE, 153 &tegra_max98090_hp_jack, 154 tegra_max98090_hp_jack_pins, 155 ARRAY_SIZE(tegra_max98090_hp_jack_pins)); 156 157 tegra_max98090_hp_jack_gpio.gpio = machine->gpio_hp_det; 158 snd_soc_jack_add_gpios(&tegra_max98090_hp_jack, 159 1, 160 &tegra_max98090_hp_jack_gpio); 161 } 162 163 if (gpio_is_valid(machine->gpio_mic_det)) { 164 snd_soc_card_jack_new(rtd->card, "Mic Jack", 165 SND_JACK_MICROPHONE, 166 &tegra_max98090_mic_jack, 167 tegra_max98090_mic_jack_pins, 168 ARRAY_SIZE(tegra_max98090_mic_jack_pins)); 169 170 tegra_max98090_mic_jack_gpio.gpio = machine->gpio_mic_det; 171 snd_soc_jack_add_gpios(&tegra_max98090_mic_jack, 172 1, 173 &tegra_max98090_mic_jack_gpio); 174 } 175 176 return 0; 177} 178 179static int tegra_max98090_card_remove(struct snd_soc_card *card) 180{ 181 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); 182 183 if (gpio_is_valid(machine->gpio_hp_det)) { 184 snd_soc_jack_free_gpios(&tegra_max98090_hp_jack, 1, 185 &tegra_max98090_hp_jack_gpio); 186 } 187 188 if (gpio_is_valid(machine->gpio_mic_det)) { 189 snd_soc_jack_free_gpios(&tegra_max98090_mic_jack, 1, 190 &tegra_max98090_mic_jack_gpio); 191 } 192 193 return 0; 194} 195 196static struct snd_soc_dai_link tegra_max98090_dai = { 197 .name = "max98090", 198 .stream_name = "max98090 PCM", 199 .codec_dai_name = "HiFi", 200 .init = tegra_max98090_asoc_init, 201 .ops = &tegra_max98090_ops, 202 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 203 SND_SOC_DAIFMT_CBS_CFS, 204}; 205 206static struct snd_soc_card snd_soc_tegra_max98090 = { 207 .name = "tegra-max98090", 208 .owner = THIS_MODULE, 209 .remove = tegra_max98090_card_remove, 210 .dai_link = &tegra_max98090_dai, 211 .num_links = 1, 212 .controls = tegra_max98090_controls, 213 .num_controls = ARRAY_SIZE(tegra_max98090_controls), 214 .dapm_widgets = tegra_max98090_dapm_widgets, 215 .num_dapm_widgets = ARRAY_SIZE(tegra_max98090_dapm_widgets), 216 .fully_routed = true, 217}; 218 219static int tegra_max98090_probe(struct platform_device *pdev) 220{ 221 struct device_node *np = pdev->dev.of_node; 222 struct snd_soc_card *card = &snd_soc_tegra_max98090; 223 struct tegra_max98090 *machine; 224 int ret; 225 226 machine = devm_kzalloc(&pdev->dev, 227 sizeof(struct tegra_max98090), GFP_KERNEL); 228 if (!machine) { 229 dev_err(&pdev->dev, "Can't allocate tegra_max98090\n"); 230 return -ENOMEM; 231 } 232 233 card->dev = &pdev->dev; 234 platform_set_drvdata(pdev, card); 235 snd_soc_card_set_drvdata(card, machine); 236 237 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); 238 if (machine->gpio_hp_det == -EPROBE_DEFER) 239 return -EPROBE_DEFER; 240 241 machine->gpio_mic_det = 242 of_get_named_gpio(np, "nvidia,mic-det-gpios", 0); 243 if (machine->gpio_mic_det == -EPROBE_DEFER) 244 return -EPROBE_DEFER; 245 246 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 247 if (ret) 248 goto err; 249 250 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); 251 if (ret) 252 goto err; 253 254 tegra_max98090_dai.codec_of_node = of_parse_phandle(np, 255 "nvidia,audio-codec", 0); 256 if (!tegra_max98090_dai.codec_of_node) { 257 dev_err(&pdev->dev, 258 "Property 'nvidia,audio-codec' missing or invalid\n"); 259 ret = -EINVAL; 260 goto err; 261 } 262 263 tegra_max98090_dai.cpu_of_node = of_parse_phandle(np, 264 "nvidia,i2s-controller", 0); 265 if (!tegra_max98090_dai.cpu_of_node) { 266 dev_err(&pdev->dev, 267 "Property 'nvidia,i2s-controller' missing or invalid\n"); 268 ret = -EINVAL; 269 goto err; 270 } 271 272 tegra_max98090_dai.platform_of_node = tegra_max98090_dai.cpu_of_node; 273 274 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 275 if (ret) 276 goto err; 277 278 ret = snd_soc_register_card(card); 279 if (ret) { 280 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 281 ret); 282 goto err_fini_utils; 283 } 284 285 return 0; 286 287err_fini_utils: 288 tegra_asoc_utils_fini(&machine->util_data); 289err: 290 return ret; 291} 292 293static int tegra_max98090_remove(struct platform_device *pdev) 294{ 295 struct snd_soc_card *card = platform_get_drvdata(pdev); 296 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); 297 298 snd_soc_unregister_card(card); 299 300 tegra_asoc_utils_fini(&machine->util_data); 301 302 return 0; 303} 304 305static const struct of_device_id tegra_max98090_of_match[] = { 306 { .compatible = "nvidia,tegra-audio-max98090", }, 307 {}, 308}; 309 310static struct platform_driver tegra_max98090_driver = { 311 .driver = { 312 .name = DRV_NAME, 313 .pm = &snd_soc_pm_ops, 314 .of_match_table = tegra_max98090_of_match, 315 }, 316 .probe = tegra_max98090_probe, 317 .remove = tegra_max98090_remove, 318}; 319module_platform_driver(tegra_max98090_driver); 320 321MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 322MODULE_DESCRIPTION("Tegra max98090 machine ASoC driver"); 323MODULE_LICENSE("GPL v2"); 324MODULE_ALIAS("platform:" DRV_NAME); 325MODULE_DEVICE_TABLE(of, tegra_max98090_of_match); 326