1/* 2 * Machine driver for EVAL-ADAV801 and EVAL-ADAV803 on Analog Devices bfin 3 * evaluation boards. 4 * 5 * Copyright 2011 Analog Devices Inc. 6 * Author: Lars-Peter Clausen <lars@metafoo.de> 7 * 8 * Licensed under the GPL-2 or later. 9 */ 10 11#include <linux/init.h> 12#include <linux/platform_device.h> 13#include <linux/module.h> 14#include <sound/core.h> 15#include <sound/pcm.h> 16#include <sound/soc.h> 17 18#include "../codecs/adav80x.h" 19 20static const struct snd_soc_dapm_widget bfin_eval_adav80x_dapm_widgets[] = { 21 SND_SOC_DAPM_LINE("Line Out", NULL), 22 SND_SOC_DAPM_LINE("Line In", NULL), 23}; 24 25static const struct snd_soc_dapm_route bfin_eval_adav80x_dapm_routes[] = { 26 { "Line Out", NULL, "VOUTL" }, 27 { "Line Out", NULL, "VOUTR" }, 28 29 { "VINL", NULL, "Line In" }, 30 { "VINR", NULL, "Line In" }, 31}; 32 33static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream, 34 struct snd_pcm_hw_params *params) 35{ 36 struct snd_soc_pcm_runtime *rtd = substream->private_data; 37 struct snd_soc_dai *codec_dai = rtd->codec_dai; 38 int ret; 39 40 ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL, 41 27000000, params_rate(params) * 256); 42 if (ret) 43 return ret; 44 45 ret = snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_PLL1, 46 params_rate(params) * 256, SND_SOC_CLOCK_IN); 47 48 return ret; 49} 50 51static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd) 52{ 53 struct snd_soc_dai *codec_dai = rtd->codec_dai; 54 55 snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK1, 0, 56 SND_SOC_CLOCK_OUT); 57 snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK2, 0, 58 SND_SOC_CLOCK_OUT); 59 snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK3, 0, 60 SND_SOC_CLOCK_OUT); 61 62 snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_XTAL, 2700000, 0); 63 64 return 0; 65} 66 67static struct snd_soc_ops bfin_eval_adav80x_ops = { 68 .hw_params = bfin_eval_adav80x_hw_params, 69}; 70 71static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = { 72 { 73 .name = "adav80x", 74 .stream_name = "ADAV80x HiFi", 75 .cpu_dai_name = "bfin-i2s.0", 76 .codec_dai_name = "adav80x-hifi", 77 .platform_name = "bfin-i2s-pcm-audio", 78 .init = bfin_eval_adav80x_codec_init, 79 .ops = &bfin_eval_adav80x_ops, 80 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 81 SND_SOC_DAIFMT_CBM_CFM, 82 }, 83}; 84 85static struct snd_soc_card bfin_eval_adav80x = { 86 .name = "bfin-eval-adav80x", 87 .owner = THIS_MODULE, 88 .dai_link = bfin_eval_adav80x_dais, 89 .num_links = ARRAY_SIZE(bfin_eval_adav80x_dais), 90 91 .dapm_widgets = bfin_eval_adav80x_dapm_widgets, 92 .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adav80x_dapm_widgets), 93 .dapm_routes = bfin_eval_adav80x_dapm_routes, 94 .num_dapm_routes = ARRAY_SIZE(bfin_eval_adav80x_dapm_routes), 95}; 96 97enum bfin_eval_adav80x_type { 98 BFIN_EVAL_ADAV801, 99 BFIN_EVAL_ADAV803, 100}; 101 102static int bfin_eval_adav80x_probe(struct platform_device *pdev) 103{ 104 struct snd_soc_card *card = &bfin_eval_adav80x; 105 const char *codec_name; 106 107 switch (platform_get_device_id(pdev)->driver_data) { 108 case BFIN_EVAL_ADAV801: 109 codec_name = "spi0.1"; 110 break; 111 case BFIN_EVAL_ADAV803: 112 codec_name = "adav803.0-0034"; 113 break; 114 default: 115 return -EINVAL; 116 } 117 118 bfin_eval_adav80x_dais[0].codec_name = codec_name; 119 120 card->dev = &pdev->dev; 121 122 return snd_soc_register_card(&bfin_eval_adav80x); 123} 124 125static int bfin_eval_adav80x_remove(struct platform_device *pdev) 126{ 127 struct snd_soc_card *card = platform_get_drvdata(pdev); 128 129 snd_soc_unregister_card(card); 130 131 return 0; 132} 133 134static const struct platform_device_id bfin_eval_adav80x_ids[] = { 135 { "bfin-eval-adav801", BFIN_EVAL_ADAV801 }, 136 { "bfin-eval-adav803", BFIN_EVAL_ADAV803 }, 137 { }, 138}; 139MODULE_DEVICE_TABLE(platform, bfin_eval_adav80x_ids); 140 141static struct platform_driver bfin_eval_adav80x_driver = { 142 .driver = { 143 .name = "bfin-eval-adav80x", 144 .pm = &snd_soc_pm_ops, 145 }, 146 .probe = bfin_eval_adav80x_probe, 147 .remove = bfin_eval_adav80x_remove, 148 .id_table = bfin_eval_adav80x_ids, 149}; 150 151module_platform_driver(bfin_eval_adav80x_driver); 152 153MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 154MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver"); 155MODULE_LICENSE("GPL"); 156