~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to sound/soc/ep93xx/edb93xx.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SoC audio for EDB93xx
 
3
 *
 
4
 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * This driver support CS4271 codec being master or slave, working
 
17
 * in control port mode, connected either via SPI or I2C.
 
18
 * The data format accepted is I2S or left-justified.
 
19
 * DAPM support not implemented.
 
20
 */
 
21
 
 
22
#include <linux/platform_device.h>
 
23
#include <linux/gpio.h>
 
24
#include <sound/core.h>
 
25
#include <sound/pcm.h>
 
26
#include <sound/soc.h>
 
27
#include <asm/mach-types.h>
 
28
#include <mach/hardware.h>
 
29
#include "ep93xx-pcm.h"
 
30
 
 
31
#define edb93xx_has_audio() (machine_is_edb9301() ||    \
 
32
                             machine_is_edb9302() ||    \
 
33
                             machine_is_edb9302a() ||   \
 
34
                             machine_is_edb9307a() ||   \
 
35
                             machine_is_edb9315a())
 
36
 
 
37
static int edb93xx_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
        int err;
 
44
        unsigned int mclk_rate;
 
45
        unsigned int rate = params_rate(params);
 
46
 
 
47
        /*
 
48
         * According to CS4271 datasheet we use MCLK/LRCK=256 for
 
49
         * rates below 50kHz and 128 for higher sample rates
 
50
         */
 
51
        if (rate < 50000)
 
52
                mclk_rate = rate * 64 * 4;
 
53
        else
 
54
                mclk_rate = rate * 64 * 2;
 
55
 
 
56
        err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
 
57
                                  SND_SOC_DAIFMT_NB_IF |
 
58
                                  SND_SOC_DAIFMT_CBS_CFS);
 
59
        if (err)
 
60
                return err;
 
61
 
 
62
        err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
 
63
                                  SND_SOC_DAIFMT_NB_IF |
 
64
                                  SND_SOC_DAIFMT_CBS_CFS);
 
65
        if (err)
 
66
                return err;
 
67
 
 
68
        err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate,
 
69
                                     SND_SOC_CLOCK_IN);
 
70
        if (err)
 
71
                return err;
 
72
 
 
73
        return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate,
 
74
                                      SND_SOC_CLOCK_OUT);
 
75
}
 
76
 
 
77
static struct snd_soc_ops edb93xx_ops = {
 
78
        .hw_params      = edb93xx_hw_params,
 
79
};
 
80
 
 
81
static struct snd_soc_dai_link edb93xx_dai = {
 
82
        .name           = "CS4271",
 
83
        .stream_name    = "CS4271 HiFi",
 
84
        .platform_name  = "ep93xx-pcm-audio",
 
85
        .cpu_dai_name   = "ep93xx-i2s",
 
86
        .codec_name     = "spi0.0",
 
87
        .codec_dai_name = "cs4271-hifi",
 
88
        .ops            = &edb93xx_ops,
 
89
};
 
90
 
 
91
static struct snd_soc_card snd_soc_edb93xx = {
 
92
        .name           = "EDB93XX",
 
93
        .dai_link       = &edb93xx_dai,
 
94
        .num_links      = 1,
 
95
};
 
96
 
 
97
static struct platform_device *edb93xx_snd_device;
 
98
 
 
99
static int __init edb93xx_init(void)
 
100
{
 
101
        int ret;
 
102
 
 
103
        if (!edb93xx_has_audio())
 
104
                return -ENODEV;
 
105
 
 
106
        ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
 
107
                                 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
 
108
                                 EP93XX_SYSCON_I2SCLKDIV_SPOL);
 
109
        if (ret)
 
110
                return ret;
 
111
 
 
112
        edb93xx_snd_device = platform_device_alloc("soc-audio", -1);
 
113
        if (!edb93xx_snd_device) {
 
114
                ret = -ENOMEM;
 
115
                goto free_i2s;
 
116
        }
 
117
 
 
118
        platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx);
 
119
        ret = platform_device_add(edb93xx_snd_device);
 
120
        if (ret)
 
121
                goto device_put;
 
122
 
 
123
        return 0;
 
124
 
 
125
device_put:
 
126
        platform_device_put(edb93xx_snd_device);
 
127
free_i2s:
 
128
        ep93xx_i2s_release();
 
129
        return ret;
 
130
}
 
131
module_init(edb93xx_init);
 
132
 
 
133
static void __exit edb93xx_exit(void)
 
134
{
 
135
        platform_device_unregister(edb93xx_snd_device);
 
136
        ep93xx_i2s_release();
 
137
}
 
138
module_exit(edb93xx_exit);
 
139
 
 
140
MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
 
141
MODULE_DESCRIPTION("ALSA SoC EDB93xx");
 
142
MODULE_LICENSE("GPL");