ASoC: samsung: add missing \n to end of pr_err messages
[cascardo/linux.git] / sound / soc / samsung / s3c24xx_uda134x.c
1 /*
2  * Modifications by Christian Pellegrin <chripell@evolware.org>
3  *
4  * s3c24xx_uda134x.c  --  S3C24XX_UDA134X ALSA SoC Audio board driver
5  *
6  * Copyright 2007 Dension Audio Systems Ltd.
7  * Author: Zoltan Devai
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/clk.h>
15 #include <linux/gpio.h>
16 #include <linux/module.h>
17
18 #include <sound/soc.h>
19 #include <sound/s3c24xx_uda134x.h>
20
21 #include "regs-iis.h"
22
23 #include "s3c24xx-i2s.h"
24
25 /* #define ENFORCE_RATES 1 */
26 /*
27   Unfortunately the S3C24XX in master mode has a limited capacity of
28   generating the clock for the codec. If you define this only rates
29   that are really available will be enforced. But be careful, most
30   user level application just want the usual sampling frequencies (8,
31   11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
32   operation for embedded systems. So if you aren't very lucky or your
33   hardware engineer wasn't very forward-looking it's better to leave
34   this undefined. If you do so an approximate value for the requested
35   sampling rate in the range -/+ 5% will be chosen. If this in not
36   possible an error will be returned.
37 */
38
39 static struct clk *xtal;
40 static struct clk *pclk;
41 /* this is need because we don't have a place where to keep the
42  * pointers to the clocks in each substream. We get the clocks only
43  * when we are actually using them so we don't block stuff like
44  * frequency change or oscillator power-off */
45 static int clk_users;
46 static DEFINE_MUTEX(clk_lock);
47
48 static unsigned int rates[33 * 2];
49 #ifdef ENFORCE_RATES
50 static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
51         .count  = ARRAY_SIZE(rates),
52         .list   = rates,
53         .mask   = 0,
54 };
55 #endif
56
57 static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
58 {
59         int ret = 0;
60 #ifdef ENFORCE_RATES
61         struct snd_pcm_runtime *runtime = substream->runtime;
62 #endif
63
64         mutex_lock(&clk_lock);
65
66         if (clk_users == 0) {
67                 xtal = clk_get(rtd->dev, "xtal");
68                 if (IS_ERR(xtal)) {
69                         dev_err(rtd->dev, "%s cannot get xtal\n", __func__);
70                         ret = PTR_ERR(xtal);
71                 } else {
72                         pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
73                                        "pclk");
74                         if (IS_ERR(pclk)) {
75                                 dev_err(rtd->dev, "%s cannot get pclk\n",
76                                         __func__);
77                                 clk_put(xtal);
78                                 ret = PTR_ERR(pclk);
79                         }
80                 }
81                 if (!ret) {
82                         int i, j;
83
84                         for (i = 0; i < 2; i++) {
85                                 int fs = i ? 256 : 384;
86
87                                 rates[i*33] = clk_get_rate(xtal) / fs;
88                                 for (j = 1; j < 33; j++)
89                                         rates[i*33 + j] = clk_get_rate(pclk) /
90                                                 (j * fs);
91                         }
92                 }
93         }
94         clk_users += 1;
95         mutex_unlock(&clk_lock);
96         if (!ret) {
97 #ifdef ENFORCE_RATES
98                 ret = snd_pcm_hw_constraint_list(runtime, 0,
99                                                  SNDRV_PCM_HW_PARAM_RATE,
100                                                  &hw_constraints_rates);
101                 if (ret < 0)
102                         dev_err(rtd->dev, "%s cannot set constraints\n",
103                                 __func__);
104 #endif
105         }
106         return ret;
107 }
108
109 static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
110 {
111         mutex_lock(&clk_lock);
112         clk_users -= 1;
113         if (clk_users == 0) {
114                 clk_put(xtal);
115                 xtal = NULL;
116                 clk_put(pclk);
117                 pclk = NULL;
118         }
119         mutex_unlock(&clk_lock);
120 }
121
122 static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
123                                         struct snd_pcm_hw_params *params)
124 {
125         struct snd_soc_pcm_runtime *rtd = substream->private_data;
126         struct snd_soc_dai *codec_dai = rtd->codec_dai;
127         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
128         unsigned int clk = 0;
129         int ret = 0;
130         int clk_source, fs_mode;
131         unsigned long rate = params_rate(params);
132         long err, cerr;
133         unsigned int div;
134         int i, bi;
135
136         err = 999999;
137         bi = 0;
138         for (i = 0; i < 2*33; i++) {
139                 cerr = rates[i] - rate;
140                 if (cerr < 0)
141                         cerr = -cerr;
142                 if (cerr < err) {
143                         err = cerr;
144                         bi = i;
145                 }
146         }
147         if (bi / 33 == 1)
148                 fs_mode = S3C2410_IISMOD_256FS;
149         else
150                 fs_mode = S3C2410_IISMOD_384FS;
151         if (bi % 33 == 0) {
152                 clk_source = S3C24XX_CLKSRC_MPLL;
153                 div = 1;
154         } else {
155                 clk_source = S3C24XX_CLKSRC_PCLK;
156                 div = bi % 33;
157         }
158
159         dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi);
160
161         clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
162
163         dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__,
164                 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
165                 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
166                 div, clk, err);
167
168         if ((err * 100 / rate) > 5) {
169                 dev_err(rtd->dev, "effective frequency too different "
170                                   "from desired (%ld%%)\n", err * 100 / rate);
171                 return -EINVAL;
172         }
173
174         ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
175                         SND_SOC_CLOCK_IN);
176         if (ret < 0)
177                 return ret;
178
179         ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
180         if (ret < 0)
181                 return ret;
182
183         ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
184                         S3C2410_IISMOD_32FS);
185         if (ret < 0)
186                 return ret;
187
188         ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
189                         S3C24XX_PRESCALE(div, div));
190         if (ret < 0)
191                 return ret;
192
193         /* set the codec system clock for DAC and ADC */
194         ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
195                         SND_SOC_CLOCK_OUT);
196         if (ret < 0)
197                 return ret;
198
199         return 0;
200 }
201
202 static struct snd_soc_ops s3c24xx_uda134x_ops = {
203         .startup = s3c24xx_uda134x_startup,
204         .shutdown = s3c24xx_uda134x_shutdown,
205         .hw_params = s3c24xx_uda134x_hw_params,
206 };
207
208 static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
209         .name = "UDA134X",
210         .stream_name = "UDA134X",
211         .codec_name = "uda134x-codec",
212         .codec_dai_name = "uda134x-hifi",
213         .cpu_dai_name = "s3c24xx-iis",
214         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
215                    SND_SOC_DAIFMT_CBS_CFS,
216         .ops = &s3c24xx_uda134x_ops,
217         .platform_name  = "s3c24xx-iis",
218 };
219
220 static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
221         .name = "S3C24XX_UDA134X",
222         .owner = THIS_MODULE,
223         .dai_link = &s3c24xx_uda134x_dai_link,
224         .num_links = 1,
225 };
226
227 static int s3c24xx_uda134x_probe(struct platform_device *pdev)
228 {
229         struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
230         int ret;
231
232         platform_set_drvdata(pdev, card);
233         card->dev = &pdev->dev;
234
235         ret = devm_snd_soc_register_card(&pdev->dev, card);
236         if (ret)
237                 dev_err(&pdev->dev, "failed to register card: %d\n", ret);
238
239         return ret;
240 }
241
242 static struct platform_driver s3c24xx_uda134x_driver = {
243         .probe  = s3c24xx_uda134x_probe,
244         .driver = {
245                 .name = "s3c24xx_uda134x",
246         },
247 };
248 module_platform_driver(s3c24xx_uda134x_driver);
249
250 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
251 MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
252 MODULE_LICENSE("GPL");