~hui.wang/alsa-driver/dkms-packaging.audiosdw-ppa

« back to all changes in this revision

Viewing changes to buildroot/src/oem-audiosdw-lp1836324-1ubuntu1.3/soc/codecs/wl1273.c

  • Committer: Hui Wang
  • Date: 2019-12-13 02:41:40 UTC
  • Revision ID: hui.wang@canonical.com-20191213024140-1cprdcbl3122fn85
insert pc-oem-dkms

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// SPDX-License-Identifier: GPL-2.0-only
 
2
/*
 
3
 * ALSA SoC WL1273 codec driver
 
4
 *
 
5
 * Author:      Matti Aaltonen, <matti.j.aaltonen@nokia.com>
 
6
 *
 
7
 * Copyright:   (C) 2010, 2011 Nokia Corporation
 
8
 */
 
9
 
 
10
#include <linux/mfd/wl1273-core.h>
 
11
#include <linux/slab.h>
 
12
#include <linux/module.h>
 
13
#include <sound/pcm.h>
 
14
#include <sound/pcm_params.h>
 
15
#include <sound/soc.h>
 
16
#include <sound/initval.h>
 
17
 
 
18
#include "wl1273.h"
 
19
 
 
20
enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };
 
21
 
 
22
/* codec private data */
 
23
struct wl1273_priv {
 
24
        enum wl1273_mode mode;
 
25
        struct wl1273_core *core;
 
26
        unsigned int channels;
 
27
};
 
28
 
 
29
static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,
 
30
                                      int rate, int width)
 
31
{
 
32
        struct device *dev = &core->client->dev;
 
33
        int r = 0;
 
34
        u16 mode;
 
35
 
 
36
        dev_dbg(dev, "rate: %d\n", rate);
 
37
        dev_dbg(dev, "width: %d\n", width);
 
38
 
 
39
        mutex_lock(&core->lock);
 
40
 
 
41
        mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;
 
42
 
 
43
        switch (rate) {
 
44
        case 48000:
 
45
                mode |= WL1273_IS2_RATE_48K;
 
46
                break;
 
47
        case 44100:
 
48
                mode |= WL1273_IS2_RATE_44_1K;
 
49
                break;
 
50
        case 32000:
 
51
                mode |= WL1273_IS2_RATE_32K;
 
52
                break;
 
53
        case 22050:
 
54
                mode |= WL1273_IS2_RATE_22_05K;
 
55
                break;
 
56
        case 16000:
 
57
                mode |= WL1273_IS2_RATE_16K;
 
58
                break;
 
59
        case 12000:
 
60
                mode |= WL1273_IS2_RATE_12K;
 
61
                break;
 
62
        case 11025:
 
63
                mode |= WL1273_IS2_RATE_11_025;
 
64
                break;
 
65
        case 8000:
 
66
                mode |= WL1273_IS2_RATE_8K;
 
67
                break;
 
68
        default:
 
69
                dev_err(dev, "Sampling rate: %d not supported\n", rate);
 
70
                r = -EINVAL;
 
71
                goto out;
 
72
        }
 
73
 
 
74
        switch (width) {
 
75
        case 16:
 
76
                mode |= WL1273_IS2_WIDTH_32;
 
77
                break;
 
78
        case 20:
 
79
                mode |= WL1273_IS2_WIDTH_40;
 
80
                break;
 
81
        case 24:
 
82
                mode |= WL1273_IS2_WIDTH_48;
 
83
                break;
 
84
        case 25:
 
85
                mode |= WL1273_IS2_WIDTH_50;
 
86
                break;
 
87
        case 30:
 
88
                mode |= WL1273_IS2_WIDTH_60;
 
89
                break;
 
90
        case 32:
 
91
                mode |= WL1273_IS2_WIDTH_64;
 
92
                break;
 
93
        case 40:
 
94
                mode |= WL1273_IS2_WIDTH_80;
 
95
                break;
 
96
        case 48:
 
97
                mode |= WL1273_IS2_WIDTH_96;
 
98
                break;
 
99
        case 64:
 
100
                mode |= WL1273_IS2_WIDTH_128;
 
101
                break;
 
102
        default:
 
103
                dev_err(dev, "Data width: %d not supported\n", width);
 
104
                r = -EINVAL;
 
105
                goto out;
 
106
        }
 
107
 
 
108
        dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n",  WL1273_I2S_DEF_MODE);
 
109
        dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);
 
110
        dev_dbg(dev, "mode: 0x%04x\n", mode);
 
111
 
 
112
        if (core->i2s_mode != mode) {
 
113
                r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);
 
114
                if (r)
 
115
                        goto out;
 
116
 
 
117
                core->i2s_mode = mode;
 
118
                r = core->write(core, WL1273_AUDIO_ENABLE,
 
119
                                WL1273_AUDIO_ENABLE_I2S);
 
120
                if (r)
 
121
                        goto out;
 
122
        }
 
123
out:
 
124
        mutex_unlock(&core->lock);
 
125
 
 
126
        return r;
 
127
}
 
128
 
 
129
static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
 
130
                                            int channel_number)
 
131
{
 
132
        struct device *dev = &core->client->dev;
 
133
        int r = 0;
 
134
 
 
135
        dev_dbg(dev, "%s\n", __func__);
 
136
 
 
137
        mutex_lock(&core->lock);
 
138
 
 
139
        if (core->channel_number == channel_number)
 
140
                goto out;
 
141
 
 
142
        if (channel_number == 1 && core->mode == WL1273_MODE_RX)
 
143
                r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
 
144
        else if (channel_number == 1 && core->mode == WL1273_MODE_TX)
 
145
                r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
 
146
        else if (channel_number == 2 && core->mode == WL1273_MODE_RX)
 
147
                r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
 
148
        else if (channel_number == 2 && core->mode == WL1273_MODE_TX)
 
149
                r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);
 
150
        else
 
151
                r = -EINVAL;
 
152
out:
 
153
        mutex_unlock(&core->lock);
 
154
 
 
155
        return r;
 
156
}
 
157
 
 
158
static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
 
159
                                      struct snd_ctl_elem_value *ucontrol)
 
160
{
 
161
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
162
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
163
 
 
164
        ucontrol->value.enumerated.item[0] = wl1273->mode;
 
165
 
 
166
        return 0;
 
167
}
 
168
 
 
169
/*
 
170
 * TODO: Implement the audio routing in the driver. Now this control
 
171
 * only indicates the setting that has been done elsewhere (in the user
 
172
 * space).
 
173
 */
 
174
static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
 
175
 
 
176
static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
 
177
                                      struct snd_ctl_elem_value *ucontrol)
 
178
{
 
179
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
180
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
181
 
 
182
        if (wl1273->mode == ucontrol->value.enumerated.item[0])
 
183
                return 0;
 
184
 
 
185
        /* Do not allow changes while stream is running */
 
186
        if (snd_soc_component_is_active(component))
 
187
                return -EPERM;
 
188
 
 
189
        if (ucontrol->value.enumerated.item[0] >=  ARRAY_SIZE(wl1273_audio_route))
 
190
                return -EINVAL;
 
191
 
 
192
        wl1273->mode = ucontrol->value.enumerated.item[0];
 
193
 
 
194
        return 1;
 
195
}
 
196
 
 
197
static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);
 
198
 
 
199
static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
 
200
                                   struct snd_ctl_elem_value *ucontrol)
 
201
{
 
202
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
203
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
204
 
 
205
        dev_dbg(component->dev, "%s: enter.\n", __func__);
 
206
 
 
207
        ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;
 
208
 
 
209
        return 0;
 
210
}
 
211
 
 
212
static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
 
213
                                   struct snd_ctl_elem_value *ucontrol)
 
214
{
 
215
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
216
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
217
        int val, r = 0;
 
218
 
 
219
        dev_dbg(component->dev, "%s: enter.\n", __func__);
 
220
 
 
221
        val = ucontrol->value.enumerated.item[0];
 
222
        if (wl1273->core->audio_mode == val)
 
223
                return 0;
 
224
 
 
225
        r = wl1273->core->set_audio(wl1273->core, val);
 
226
        if (r < 0)
 
227
                return r;
 
228
 
 
229
        return 1;
 
230
}
 
231
 
 
232
static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
 
233
 
 
234
static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);
 
235
 
 
236
static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
 
237
                                    struct snd_ctl_elem_value *ucontrol)
 
238
{
 
239
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
240
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
241
 
 
242
        dev_dbg(component->dev, "%s: enter.\n", __func__);
 
243
 
 
244
        ucontrol->value.integer.value[0] = wl1273->core->volume;
 
245
 
 
246
        return 0;
 
247
}
 
248
 
 
249
static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
 
250
                                    struct snd_ctl_elem_value *ucontrol)
 
251
{
 
252
        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
253
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
254
        int r;
 
255
 
 
256
        dev_dbg(component->dev, "%s: enter.\n", __func__);
 
257
 
 
258
        r = wl1273->core->set_volume(wl1273->core,
 
259
                                     ucontrol->value.integer.value[0]);
 
260
        if (r)
 
261
                return r;
 
262
 
 
263
        return 1;
 
264
}
 
265
 
 
266
static const struct snd_kcontrol_new wl1273_controls[] = {
 
267
        SOC_ENUM_EXT("Codec Mode", wl1273_enum,
 
268
                     snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),
 
269
        SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,
 
270
                     snd_wl1273_fm_audio_get,  snd_wl1273_fm_audio_put),
 
271
        SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,
 
272
                       snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
 
273
};
 
274
 
 
275
static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = {
 
276
        SND_SOC_DAPM_INPUT("RX"),
 
277
 
 
278
        SND_SOC_DAPM_OUTPUT("TX"),
 
279
};
 
280
 
 
281
static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
 
282
        { "Capture", NULL, "RX" },
 
283
 
 
284
        { "TX", NULL, "Playback" },
 
285
};
 
286
 
 
287
static int wl1273_startup(struct snd_pcm_substream *substream,
 
288
                          struct snd_soc_dai *dai)
 
289
{
 
290
        struct snd_soc_component *component = dai->component;
 
291
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
292
 
 
293
        switch (wl1273->mode) {
 
294
        case WL1273_MODE_BT:
 
295
                snd_pcm_hw_constraint_single(substream->runtime,
 
296
                                             SNDRV_PCM_HW_PARAM_RATE, 8000);
 
297
                snd_pcm_hw_constraint_single(substream->runtime,
 
298
                                             SNDRV_PCM_HW_PARAM_CHANNELS, 1);
 
299
                break;
 
300
        case WL1273_MODE_FM_RX:
 
301
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 
302
                        pr_err("Cannot play in RX mode.\n");
 
303
                        return -EINVAL;
 
304
                }
 
305
                break;
 
306
        case WL1273_MODE_FM_TX:
 
307
                if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 
308
                        pr_err("Cannot capture in TX mode.\n");
 
309
                        return -EINVAL;
 
310
                }
 
311
                break;
 
312
        default:
 
313
                return -EINVAL;
 
314
                break;
 
315
        }
 
316
 
 
317
        return 0;
 
318
}
 
319
 
 
320
static int wl1273_hw_params(struct snd_pcm_substream *substream,
 
321
                            struct snd_pcm_hw_params *params,
 
322
                            struct snd_soc_dai *dai)
 
323
{
 
324
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(dai->component);
 
325
        struct wl1273_core *core = wl1273->core;
 
326
        unsigned int rate, width, r;
 
327
 
 
328
        if (params_width(params) != 16) {
 
329
                dev_err(dai->dev, "%d bits/sample not supported\n",
 
330
                        params_width(params));
 
331
                return -EINVAL;
 
332
        }
 
333
 
 
334
        rate = params_rate(params);
 
335
        width =  hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
 
336
 
 
337
        if (wl1273->mode == WL1273_MODE_BT) {
 
338
                if (rate != 8000) {
 
339
                        pr_err("Rate %d not supported.\n", params_rate(params));
 
340
                        return -EINVAL;
 
341
                }
 
342
 
 
343
                if (params_channels(params) != 1) {
 
344
                        pr_err("Only mono supported.\n");
 
345
                        return -EINVAL;
 
346
                }
 
347
 
 
348
                return 0;
 
349
        }
 
350
 
 
351
        if (wl1273->mode == WL1273_MODE_FM_TX &&
 
352
            substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 
353
                pr_err("Only playback supported with TX.\n");
 
354
                return -EINVAL;
 
355
        }
 
356
 
 
357
        if (wl1273->mode == WL1273_MODE_FM_RX  &&
 
358
            substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 
359
                pr_err("Only capture supported with RX.\n");
 
360
                return -EINVAL;
 
361
        }
 
362
 
 
363
        if (wl1273->mode != WL1273_MODE_FM_RX  &&
 
364
            wl1273->mode != WL1273_MODE_FM_TX) {
 
365
                pr_err("Unexpected mode: %d.\n", wl1273->mode);
 
366
                return -EINVAL;
 
367
        }
 
368
 
 
369
        r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
 
370
        if (r)
 
371
                return r;
 
372
 
 
373
        wl1273->channels = params_channels(params);
 
374
        r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
 
375
        if (r)
 
376
                return r;
 
377
 
 
378
        return 0;
 
379
}
 
380
 
 
381
static const struct snd_soc_dai_ops wl1273_dai_ops = {
 
382
        .startup        = wl1273_startup,
 
383
        .hw_params      = wl1273_hw_params,
 
384
};
 
385
 
 
386
static struct snd_soc_dai_driver wl1273_dai = {
 
387
        .name = "wl1273-fm",
 
388
        .playback = {
 
389
                .stream_name = "Playback",
 
390
                .channels_min = 1,
 
391
                .channels_max = 2,
 
392
                .rates = SNDRV_PCM_RATE_8000_48000,
 
393
                .formats = SNDRV_PCM_FMTBIT_S16_LE},
 
394
        .capture = {
 
395
                .stream_name = "Capture",
 
396
                .channels_min = 1,
 
397
                .channels_max = 2,
 
398
                .rates = SNDRV_PCM_RATE_8000_48000,
 
399
                .formats = SNDRV_PCM_FMTBIT_S16_LE},
 
400
        .ops = &wl1273_dai_ops,
 
401
};
 
402
 
 
403
/* Audio interface format for the soc_card driver */
 
404
int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt)
 
405
{
 
406
        struct wl1273_priv *wl1273;
 
407
 
 
408
        if (component == NULL || fmt == NULL)
 
409
                return -EINVAL;
 
410
 
 
411
        wl1273 = snd_soc_component_get_drvdata(component);
 
412
 
 
413
        switch (wl1273->mode) {
 
414
        case WL1273_MODE_FM_RX:
 
415
        case WL1273_MODE_FM_TX:
 
416
                *fmt =  SND_SOC_DAIFMT_I2S |
 
417
                        SND_SOC_DAIFMT_NB_NF |
 
418
                        SND_SOC_DAIFMT_CBM_CFM;
 
419
 
 
420
                break;
 
421
        case WL1273_MODE_BT:
 
422
                *fmt =  SND_SOC_DAIFMT_DSP_A |
 
423
                        SND_SOC_DAIFMT_IB_NF |
 
424
                        SND_SOC_DAIFMT_CBM_CFM;
 
425
 
 
426
                break;
 
427
        default:
 
428
                return -EINVAL;
 
429
        }
 
430
 
 
431
        return 0;
 
432
}
 
433
EXPORT_SYMBOL_GPL(wl1273_get_format);
 
434
 
 
435
static int wl1273_probe(struct snd_soc_component *component)
 
436
{
 
437
        struct wl1273_core **core = component->dev->platform_data;
 
438
        struct wl1273_priv *wl1273;
 
439
 
 
440
        dev_dbg(component->dev, "%s.\n", __func__);
 
441
 
 
442
        if (!core) {
 
443
                dev_err(component->dev, "Platform data is missing.\n");
 
444
                return -EINVAL;
 
445
        }
 
446
 
 
447
        wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
 
448
        if (!wl1273)
 
449
                return -ENOMEM;
 
450
 
 
451
        wl1273->mode = WL1273_MODE_BT;
 
452
        wl1273->core = *core;
 
453
 
 
454
        snd_soc_component_set_drvdata(component, wl1273);
 
455
 
 
456
        return 0;
 
457
}
 
458
 
 
459
static void wl1273_remove(struct snd_soc_component *component)
 
460
{
 
461
        struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
462
 
 
463
        dev_dbg(component->dev, "%s\n", __func__);
 
464
        kfree(wl1273);
 
465
}
 
466
 
 
467
static const struct snd_soc_component_driver soc_component_dev_wl1273 = {
 
468
        .probe                  = wl1273_probe,
 
469
        .remove                 = wl1273_remove,
 
470
        .controls               = wl1273_controls,
 
471
        .num_controls           = ARRAY_SIZE(wl1273_controls),
 
472
        .dapm_widgets           = wl1273_dapm_widgets,
 
473
        .num_dapm_widgets       = ARRAY_SIZE(wl1273_dapm_widgets),
 
474
        .dapm_routes            = wl1273_dapm_routes,
 
475
        .num_dapm_routes        = ARRAY_SIZE(wl1273_dapm_routes),
 
476
        .idle_bias_on           = 1,
 
477
        .use_pmdown_time        = 1,
 
478
        .endianness             = 1,
 
479
        .non_legacy_dai_naming  = 1,
 
480
};
 
481
 
 
482
static int wl1273_platform_probe(struct platform_device *pdev)
 
483
{
 
484
        return devm_snd_soc_register_component(&pdev->dev,
 
485
                                      &soc_component_dev_wl1273,
 
486
                                      &wl1273_dai, 1);
 
487
}
 
488
 
 
489
static int wl1273_platform_remove(struct platform_device *pdev)
 
490
{
 
491
        return 0;
 
492
}
 
493
 
 
494
MODULE_ALIAS("platform:wl1273-codec");
 
495
 
 
496
static struct platform_driver wl1273_platform_driver = {
 
497
        .driver         = {
 
498
                .name   = "wl1273-codec",
 
499
        },
 
500
        .probe          = wl1273_platform_probe,
 
501
        .remove         = wl1273_platform_remove,
 
502
};
 
503
 
 
504
module_platform_driver(wl1273_platform_driver);
 
505
 
 
506
MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
 
507
MODULE_DESCRIPTION("ASoC WL1273 codec driver");
 
508
MODULE_LICENSE("GPL");