linux/sound/soc/samsung/jive_wm8750.c
<<
>>
Prefs
   1/* sound/soc/samsung/jive_wm8750.c
   2 *
   3 * Copyright 2007,2008 Simtec Electronics
   4 *
   5 * Based on sound/soc/pxa/spitz.c
   6 *      Copyright 2005 Wolfson Microelectronics PLC.
   7 *      Copyright 2005 Openedhand Ltd.
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12*/
  13
  14#include <linux/module.h>
  15#include <sound/soc.h>
  16
  17#include <asm/mach-types.h>
  18
  19#include "s3c2412-i2s.h"
  20#include "../codecs/wm8750.h"
  21
  22static const struct snd_soc_dapm_route audio_map[] = {
  23        { "Headphone Jack", NULL, "LOUT1" },
  24        { "Headphone Jack", NULL, "ROUT1" },
  25        { "Internal Speaker", NULL, "LOUT2" },
  26        { "Internal Speaker", NULL, "ROUT2" },
  27        { "LINPUT1", NULL, "Line Input" },
  28        { "RINPUT1", NULL, "Line Input" },
  29};
  30
  31static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
  32        SND_SOC_DAPM_HP("Headphone Jack", NULL),
  33        SND_SOC_DAPM_SPK("Internal Speaker", NULL),
  34        SND_SOC_DAPM_LINE("Line In", NULL),
  35};
  36
  37static int jive_hw_params(struct snd_pcm_substream *substream,
  38                          struct snd_pcm_hw_params *params)
  39{
  40        struct snd_soc_pcm_runtime *rtd = substream->private_data;
  41        struct snd_soc_dai *codec_dai = rtd->codec_dai;
  42        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  43        struct s3c_i2sv2_rate_calc div;
  44        unsigned int clk = 0;
  45        int ret = 0;
  46
  47        switch (params_rate(params)) {
  48        case 8000:
  49        case 16000:
  50        case 48000:
  51        case 96000:
  52                clk = 12288000;
  53                break;
  54        case 11025:
  55        case 22050:
  56        case 44100:
  57                clk = 11289600;
  58                break;
  59        }
  60
  61        s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
  62                                s3c_i2sv2_get_clock(cpu_dai));
  63
  64        /* set codec DAI configuration */
  65        ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
  66                                  SND_SOC_DAIFMT_NB_NF |
  67                                  SND_SOC_DAIFMT_CBS_CFS);
  68        if (ret < 0)
  69                return ret;
  70
  71        /* set cpu DAI configuration */
  72        ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
  73                                  SND_SOC_DAIFMT_NB_NF |
  74                                  SND_SOC_DAIFMT_CBS_CFS);
  75        if (ret < 0)
  76                return ret;
  77
  78        /* set the codec system clock for DAC and ADC */
  79        ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
  80                                     SND_SOC_CLOCK_IN);
  81        if (ret < 0)
  82                return ret;
  83
  84        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div);
  85        if (ret < 0)
  86                return ret;
  87
  88        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER,
  89                                     div.clk_div - 1);
  90        if (ret < 0)
  91                return ret;
  92
  93        return 0;
  94}
  95
  96static struct snd_soc_ops jive_ops = {
  97        .hw_params      = jive_hw_params,
  98};
  99
 100static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
 101{
 102        struct snd_soc_codec *codec = rtd->codec;
 103        struct snd_soc_dapm_context *dapm = &codec->dapm;
 104
 105        /* These endpoints are not being used. */
 106        snd_soc_dapm_nc_pin(dapm, "LINPUT2");
 107        snd_soc_dapm_nc_pin(dapm, "RINPUT2");
 108        snd_soc_dapm_nc_pin(dapm, "LINPUT3");
 109        snd_soc_dapm_nc_pin(dapm, "RINPUT3");
 110        snd_soc_dapm_nc_pin(dapm, "OUT3");
 111        snd_soc_dapm_nc_pin(dapm, "MONO");
 112
 113        return 0;
 114}
 115
 116static struct snd_soc_dai_link jive_dai = {
 117        .name           = "wm8750",
 118        .stream_name    = "WM8750",
 119        .cpu_dai_name   = "s3c2412-i2s",
 120        .codec_dai_name = "wm8750-hifi",
 121        .platform_name  = "s3c2412-i2s",
 122        .codec_name     = "wm8750.0-001a",
 123        .init           = jive_wm8750_init,
 124        .ops            = &jive_ops,
 125};
 126
 127/* jive audio machine driver */
 128static struct snd_soc_card snd_soc_machine_jive = {
 129        .name           = "Jive",
 130        .owner          = THIS_MODULE,
 131        .dai_link       = &jive_dai,
 132        .num_links      = 1,
 133
 134        .dapm_widgets   = wm8750_dapm_widgets,
 135        .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
 136        .dapm_routes    = audio_map,
 137        .num_dapm_routes = ARRAY_SIZE(audio_map),
 138};
 139
 140static struct platform_device *jive_snd_device;
 141
 142static int __init jive_init(void)
 143{
 144        int ret;
 145
 146        if (!machine_is_jive())
 147                return 0;
 148
 149        printk("JIVE WM8750 Audio support\n");
 150
 151        jive_snd_device = platform_device_alloc("soc-audio", -1);
 152        if (!jive_snd_device)
 153                return -ENOMEM;
 154
 155        platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive);
 156        ret = platform_device_add(jive_snd_device);
 157
 158        if (ret)
 159                platform_device_put(jive_snd_device);
 160
 161        return ret;
 162}
 163
 164static void __exit jive_exit(void)
 165{
 166        platform_device_unregister(jive_snd_device);
 167}
 168
 169module_init(jive_init);
 170module_exit(jive_exit);
 171
 172MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 173MODULE_DESCRIPTION("ALSA SoC Jive Audio support");
 174MODULE_LICENSE("GPL");
 175