| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices |
|---|
| 3 | | - * |
|---|
| 4 | | - * Copyright 2007 Openmoko Inc |
|---|
| 5 | | - * Author: Graeme Gregory <graeme@openmoko.org> |
|---|
| 6 | | - * Copyright 2007 Wolfson Microelectronics PLC. |
|---|
| 7 | | - * Author: Graeme Gregory |
|---|
| 8 | | - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com |
|---|
| 9 | | - * Copyright 2009 Wolfson Microelectronics |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 12 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 13 | | - * Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 14 | | - * option) any later version. |
|---|
| 15 | | - */ |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 2 | +// |
|---|
| 3 | +// neo1973_wm8753.c - SoC audio for Openmoko Neo1973 and Freerunner devices |
|---|
| 4 | +// |
|---|
| 5 | +// Copyright 2007 Openmoko Inc |
|---|
| 6 | +// Author: Graeme Gregory <graeme@openmoko.org> |
|---|
| 7 | +// Copyright 2007 Wolfson Microelectronics PLC. |
|---|
| 8 | +// Author: Graeme Gregory |
|---|
| 9 | +// graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com |
|---|
| 10 | +// Copyright 2009 Wolfson Microelectronics |
|---|
| 16 | 11 | |
|---|
| 17 | 12 | #include <linux/module.h> |
|---|
| 18 | 13 | #include <linux/platform_device.h> |
|---|
| 19 | | -#include <linux/gpio.h> |
|---|
| 14 | +#include <linux/gpio/consumer.h> |
|---|
| 20 | 15 | |
|---|
| 21 | 16 | #include <sound/soc.h> |
|---|
| 22 | 17 | |
|---|
| 23 | | -#include <mach/gpio-samsung.h> |
|---|
| 24 | | -#include <asm/mach-types.h> |
|---|
| 25 | 18 | #include "regs-iis.h" |
|---|
| 26 | | - |
|---|
| 27 | 19 | #include "../codecs/wm8753.h" |
|---|
| 28 | 20 | #include "s3c24xx-i2s.h" |
|---|
| 29 | 21 | |
|---|
| 30 | 22 | static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, |
|---|
| 31 | 23 | struct snd_pcm_hw_params *params) |
|---|
| 32 | 24 | { |
|---|
| 33 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 34 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
|---|
| 35 | | - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
|---|
| 25 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 26 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
|---|
| 27 | + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
|---|
| 36 | 28 | unsigned int pll_out = 0, bclk = 0; |
|---|
| 37 | 29 | int ret = 0; |
|---|
| 38 | 30 | unsigned long iis_clkrate; |
|---|
| .. | .. |
|---|
| 104 | 96 | |
|---|
| 105 | 97 | static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) |
|---|
| 106 | 98 | { |
|---|
| 107 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 108 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
|---|
| 99 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 100 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
|---|
| 109 | 101 | |
|---|
| 110 | 102 | /* disable the PLL */ |
|---|
| 111 | 103 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); |
|---|
| .. | .. |
|---|
| 122 | 114 | static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, |
|---|
| 123 | 115 | struct snd_pcm_hw_params *params) |
|---|
| 124 | 116 | { |
|---|
| 125 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 126 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
|---|
| 117 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 118 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
|---|
| 127 | 119 | unsigned int pcmdiv = 0; |
|---|
| 128 | 120 | int ret = 0; |
|---|
| 129 | 121 | unsigned long iis_clkrate; |
|---|
| .. | .. |
|---|
| 159 | 151 | |
|---|
| 160 | 152 | static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) |
|---|
| 161 | 153 | { |
|---|
| 162 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 163 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
|---|
| 154 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 155 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
|---|
| 164 | 156 | |
|---|
| 165 | 157 | /* disable the PLL */ |
|---|
| 166 | 158 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); |
|---|
| .. | .. |
|---|
| 171 | 163 | .hw_free = neo1973_voice_hw_free, |
|---|
| 172 | 164 | }; |
|---|
| 173 | 165 | |
|---|
| 166 | +static struct gpio_desc *gpiod_hp_in, *gpiod_amp_shut; |
|---|
| 174 | 167 | static int gta02_speaker_enabled; |
|---|
| 175 | 168 | |
|---|
| 176 | 169 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, |
|---|
| .. | .. |
|---|
| 178 | 171 | { |
|---|
| 179 | 172 | gta02_speaker_enabled = ucontrol->value.integer.value[0]; |
|---|
| 180 | 173 | |
|---|
| 181 | | - gpio_set_value(S3C2410_GPJ(2), !gta02_speaker_enabled); |
|---|
| 174 | + gpiod_set_value(gpiod_hp_in, !gta02_speaker_enabled); |
|---|
| 182 | 175 | |
|---|
| 183 | 176 | return 0; |
|---|
| 184 | 177 | } |
|---|
| .. | .. |
|---|
| 193 | 186 | static int lm4853_event(struct snd_soc_dapm_widget *w, |
|---|
| 194 | 187 | struct snd_kcontrol *k, int event) |
|---|
| 195 | 188 | { |
|---|
| 196 | | - gpio_set_value(S3C2410_GPJ(1), SND_SOC_DAPM_EVENT_OFF(event)); |
|---|
| 189 | + gpiod_set_value(gpiod_amp_shut, SND_SOC_DAPM_EVENT_OFF(event)); |
|---|
| 197 | 190 | |
|---|
| 198 | 191 | return 0; |
|---|
| 199 | 192 | } |
|---|
| .. | .. |
|---|
| 271 | 264 | return 0; |
|---|
| 272 | 265 | } |
|---|
| 273 | 266 | |
|---|
| 267 | +SND_SOC_DAILINK_DEFS(wm8753, |
|---|
| 268 | + DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), |
|---|
| 269 | + DAILINK_COMP_ARRAY(COMP_CODEC("wm8753.0-001a", "wm8753-hifi")), |
|---|
| 270 | + DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); |
|---|
| 271 | + |
|---|
| 272 | +SND_SOC_DAILINK_DEFS(bluetooth, |
|---|
| 273 | + DAILINK_COMP_ARRAY(COMP_CPU("bt-sco-pcm")), |
|---|
| 274 | + DAILINK_COMP_ARRAY(COMP_CODEC("wm8753.0-001a", "wm8753-voice"))); |
|---|
| 275 | + |
|---|
| 274 | 276 | static struct snd_soc_dai_link neo1973_dai[] = { |
|---|
| 275 | 277 | { /* Hifi Playback - for similatious use with voice below */ |
|---|
| 276 | 278 | .name = "WM8753", |
|---|
| 277 | 279 | .stream_name = "WM8753 HiFi", |
|---|
| 278 | | - .platform_name = "s3c24xx-iis", |
|---|
| 279 | | - .cpu_dai_name = "s3c24xx-iis", |
|---|
| 280 | | - .codec_dai_name = "wm8753-hifi", |
|---|
| 281 | | - .codec_name = "wm8753.0-001a", |
|---|
| 282 | 280 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
|---|
| 283 | 281 | SND_SOC_DAIFMT_CBM_CFM, |
|---|
| 284 | 282 | .init = neo1973_wm8753_init, |
|---|
| 285 | 283 | .ops = &neo1973_hifi_ops, |
|---|
| 284 | + SND_SOC_DAILINK_REG(wm8753), |
|---|
| 286 | 285 | }, |
|---|
| 287 | 286 | { /* Voice via BT */ |
|---|
| 288 | 287 | .name = "Bluetooth", |
|---|
| 289 | 288 | .stream_name = "Voice", |
|---|
| 290 | | - .cpu_dai_name = "bt-sco-pcm", |
|---|
| 291 | | - .codec_dai_name = "wm8753-voice", |
|---|
| 292 | | - .codec_name = "wm8753.0-001a", |
|---|
| 293 | 289 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | |
|---|
| 294 | 290 | SND_SOC_DAIFMT_CBS_CFS, |
|---|
| 295 | 291 | .ops = &neo1973_voice_ops, |
|---|
| 292 | + SND_SOC_DAILINK_REG(bluetooth), |
|---|
| 296 | 293 | }, |
|---|
| 297 | 294 | }; |
|---|
| 298 | 295 | |
|---|
| 299 | 296 | static struct snd_soc_aux_dev neo1973_aux_devs[] = { |
|---|
| 300 | 297 | { |
|---|
| 301 | | - .name = "dfbmcs320", |
|---|
| 302 | | - .codec_name = "dfbmcs320.0", |
|---|
| 298 | + .dlc = COMP_AUX("dfbmcs320.0"), |
|---|
| 303 | 299 | }, |
|---|
| 304 | 300 | }; |
|---|
| 305 | 301 | |
|---|
| 306 | 302 | static struct snd_soc_codec_conf neo1973_codec_conf[] = { |
|---|
| 307 | 303 | { |
|---|
| 308 | | - .dev_name = "lm4857.0-007c", |
|---|
| 304 | + .dlc = COMP_CODEC_CONF("lm4857.0-007c"), |
|---|
| 309 | 305 | .name_prefix = "Amp", |
|---|
| 310 | 306 | }, |
|---|
| 311 | 307 | }; |
|---|
| 312 | 308 | |
|---|
| 313 | | -static const struct gpio neo1973_gta02_gpios[] = { |
|---|
| 314 | | - { S3C2410_GPJ(2), GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, |
|---|
| 315 | | - { S3C2410_GPJ(1), GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, |
|---|
| 316 | | -}; |
|---|
| 317 | | - |
|---|
| 318 | 309 | static struct snd_soc_card neo1973 = { |
|---|
| 319 | | - .name = "neo1973", |
|---|
| 310 | + .name = "neo1973gta02", |
|---|
| 320 | 311 | .owner = THIS_MODULE, |
|---|
| 321 | 312 | .dai_link = neo1973_dai, |
|---|
| 322 | 313 | .num_links = ARRAY_SIZE(neo1973_dai), |
|---|
| .. | .. |
|---|
| 334 | 325 | .fully_routed = true, |
|---|
| 335 | 326 | }; |
|---|
| 336 | 327 | |
|---|
| 337 | | -static struct platform_device *neo1973_snd_device; |
|---|
| 338 | | - |
|---|
| 339 | | -static int __init neo1973_init(void) |
|---|
| 328 | +static int neo1973_probe(struct platform_device *pdev) |
|---|
| 340 | 329 | { |
|---|
| 341 | | - int ret; |
|---|
| 330 | + struct device *dev = &pdev->dev; |
|---|
| 342 | 331 | |
|---|
| 343 | | - if (!machine_is_neo1973_gta02()) |
|---|
| 344 | | - return -ENODEV; |
|---|
| 345 | | - |
|---|
| 346 | | - if (machine_is_neo1973_gta02()) { |
|---|
| 347 | | - neo1973.name = "neo1973gta02"; |
|---|
| 348 | | - neo1973.num_aux_devs = 1; |
|---|
| 349 | | - |
|---|
| 350 | | - ret = gpio_request_array(neo1973_gta02_gpios, |
|---|
| 351 | | - ARRAY_SIZE(neo1973_gta02_gpios)); |
|---|
| 352 | | - if (ret) |
|---|
| 353 | | - return ret; |
|---|
| 332 | + gpiod_hp_in = devm_gpiod_get(dev, "hp", GPIOD_OUT_HIGH); |
|---|
| 333 | + if (IS_ERR(gpiod_hp_in)) { |
|---|
| 334 | + dev_err(dev, "missing gpio %s\n", "hp"); |
|---|
| 335 | + return PTR_ERR(gpiod_hp_in); |
|---|
| 336 | + } |
|---|
| 337 | + gpiod_amp_shut = devm_gpiod_get(dev, "amp-shut", GPIOD_OUT_HIGH); |
|---|
| 338 | + if (IS_ERR(gpiod_amp_shut)) { |
|---|
| 339 | + dev_err(dev, "missing gpio %s\n", "amp-shut"); |
|---|
| 340 | + return PTR_ERR(gpiod_amp_shut); |
|---|
| 354 | 341 | } |
|---|
| 355 | 342 | |
|---|
| 356 | | - neo1973_snd_device = platform_device_alloc("soc-audio", -1); |
|---|
| 357 | | - if (!neo1973_snd_device) { |
|---|
| 358 | | - ret = -ENOMEM; |
|---|
| 359 | | - goto err_gpio_free; |
|---|
| 360 | | - } |
|---|
| 361 | | - |
|---|
| 362 | | - platform_set_drvdata(neo1973_snd_device, &neo1973); |
|---|
| 363 | | - ret = platform_device_add(neo1973_snd_device); |
|---|
| 364 | | - |
|---|
| 365 | | - if (ret) |
|---|
| 366 | | - goto err_put_device; |
|---|
| 367 | | - |
|---|
| 368 | | - return 0; |
|---|
| 369 | | - |
|---|
| 370 | | -err_put_device: |
|---|
| 371 | | - platform_device_put(neo1973_snd_device); |
|---|
| 372 | | -err_gpio_free: |
|---|
| 373 | | - if (machine_is_neo1973_gta02()) { |
|---|
| 374 | | - gpio_free_array(neo1973_gta02_gpios, |
|---|
| 375 | | - ARRAY_SIZE(neo1973_gta02_gpios)); |
|---|
| 376 | | - } |
|---|
| 377 | | - return ret; |
|---|
| 343 | + neo1973.dev = dev; |
|---|
| 344 | + return devm_snd_soc_register_card(dev, &neo1973); |
|---|
| 378 | 345 | } |
|---|
| 379 | | -module_init(neo1973_init); |
|---|
| 380 | 346 | |
|---|
| 381 | | -static void __exit neo1973_exit(void) |
|---|
| 382 | | -{ |
|---|
| 383 | | - platform_device_unregister(neo1973_snd_device); |
|---|
| 384 | | - |
|---|
| 385 | | - if (machine_is_neo1973_gta02()) { |
|---|
| 386 | | - gpio_free_array(neo1973_gta02_gpios, |
|---|
| 387 | | - ARRAY_SIZE(neo1973_gta02_gpios)); |
|---|
| 388 | | - } |
|---|
| 389 | | -} |
|---|
| 390 | | -module_exit(neo1973_exit); |
|---|
| 347 | +struct platform_driver neo1973_audio = { |
|---|
| 348 | + .driver = { |
|---|
| 349 | + .name = "neo1973-audio", |
|---|
| 350 | + .pm = &snd_soc_pm_ops, |
|---|
| 351 | + }, |
|---|
| 352 | + .probe = neo1973_probe, |
|---|
| 353 | +}; |
|---|
| 354 | +module_platform_driver(neo1973_audio); |
|---|
| 391 | 355 | |
|---|
| 392 | 356 | /* Module information */ |
|---|
| 393 | 357 | MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); |
|---|
| 394 | 358 | MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner"); |
|---|
| 395 | 359 | MODULE_LICENSE("GPL"); |
|---|
| 360 | +MODULE_ALIAS("platform:neo1973-audio"); |
|---|