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

« back to all changes in this revision

Viewing changes to sound/soc/omap/omap-dmic.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:
3
3
 *
4
4
 * Copyright (C) 2010 Texas Instruments
5
5
 *
6
 
 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
 
6
 * Author: Liam Girdwood <lrg@ti.com>
7
7
 *         David Lambert <dlambert@ti.com>
8
8
 *         Misael Lopez Cruz <misael.lopez@ti.com>
9
9
 *
28
28
#include <linux/init.h>
29
29
#include <linux/module.h>
30
30
#include <linux/platform_device.h>
31
 
#include <linux/wait.h>
32
 
#include <linux/interrupt.h>
33
31
#include <linux/err.h>
34
32
#include <linux/clk.h>
35
 
#include <linux/delay.h>
36
33
#include <linux/io.h>
37
 
#include <linux/irq.h>
38
34
#include <linux/slab.h>
39
35
#include <linux/pm_runtime.h>
40
36
 
41
37
#include <plat/dma.h>
42
 
#include <plat/omap_hwmod.h>
 
38
#include <plat/dmic.h>
43
39
 
44
 
#include <sound/control.h>
45
40
#include <sound/core.h>
46
41
#include <sound/pcm.h>
47
42
#include <sound/pcm_params.h>
48
43
#include <sound/initval.h>
49
44
#include <sound/soc.h>
50
45
 
 
46
#include "omap-pcm.h"
51
47
#include "omap-dmic.h"
52
 
#include "omap-pcm.h"
53
48
 
54
49
#define OMAP_DMIC_RATES         (SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
55
50
#define OMAP_DMIC_FORMATS       SNDRV_PCM_FMTBIT_S32_LE
56
51
 
 
52
#define OMAP4_LEGACY_DMIC0              0
 
53
#define OMAP4_ABE_DMIC0         1
 
54
#define OMAP4_ABE_DMIC1         2
 
55
#define OMAP4_ABE_DMIC2         3
 
56
 
57
57
struct omap_dmic {
58
58
        struct device *dev;
59
59
        void __iomem *io_base;
60
 
        int irq;
61
60
        int clk_freq;
62
61
        int sysclk;
63
62
        int active;
64
 
        spinlock_t lock;
65
 
        struct omap_dmic_link *link;
66
 
};
67
 
 
68
 
static struct omap_dmic_link omap_dmic_link = {
69
 
        .irq_mask       = DMIC_IRQ_EMPTY | DMIC_IRQ_FULL,
70
 
        .threshold      = 2,
71
 
        .format         = DMICOUTFORMAT_LJUST,
72
 
        .polar          = DMIC_POLAR1 | DMIC_POLAR2 | DMIC_POLAR3,
 
63
        int running;
 
64
        int channels;
 
65
        int abe_mode;
 
66
        u32 up_enable;
 
67
        struct mutex mutex;
73
68
};
74
69
 
75
70
/*
80
75
        .data_type      = OMAP_DMA_DATA_TYPE_S32,
81
76
        .sync_mode      = OMAP_DMA_SYNC_PACKET,
82
77
        .packet_size    = 2,
83
 
        .port_addr      = OMAP44XX_DMIC_L3_BASE + DMIC_DATA,
 
78
        .port_addr      = OMAP44XX_DMIC_L3_BASE + OMAP_DMIC_DATA,
84
79
};
85
80
 
86
 
 
87
 
static inline void omap_dmic_write(struct omap_dmic *dmic,
88
 
                u16 reg, u32 val)
 
81
static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
89
82
{
90
83
        __raw_writel(val, dmic->io_base + reg);
91
84
}
95
88
        return __raw_readl(dmic->io_base + reg);
96
89
}
97
90
 
98
 
#ifdef DEBUG
99
 
static void omap_dmic_reg_dump(struct omap_dmic *dmic)
100
 
{
101
 
        dev_dbg(dmic->dev, "***********************\n");
102
 
        dev_dbg(dmic->dev, "DMIC_IRQSTATUS_RAW:  0x%04x\n",
103
 
                omap_dmic_read(dmic, DMIC_IRQSTATUS_RAW));
104
 
        dev_dbg(dmic->dev, "DMIC_IRQSTATUS:  0x%04x\n",
105
 
                omap_dmic_read(dmic, DMIC_IRQSTATUS));
106
 
        dev_dbg(dmic->dev, "DMIC_IRQENABLE_SET:  0x%04x\n",
107
 
                omap_dmic_read(dmic, DMIC_IRQENABLE_SET));
108
 
        dev_dbg(dmic->dev, "DMIC_IRQENABLE_CLR:  0x%04x\n",
109
 
                omap_dmic_read(dmic, DMIC_IRQENABLE_CLR));
110
 
        dev_dbg(dmic->dev, "DMIC_IRQWAKE_EN:  0x%04x\n",
111
 
                omap_dmic_read(dmic, DMIC_IRQWAKE_EN));
112
 
        dev_dbg(dmic->dev, "DMIC_DMAENABLE_SET:  0x%04x\n",
113
 
                omap_dmic_read(dmic, DMIC_DMAENABLE_SET));
114
 
        dev_dbg(dmic->dev, "DMIC_DMAENABLE_CLR:  0x%04x\n",
115
 
                omap_dmic_read(dmic, DMIC_DMAENABLE_CLR));
116
 
        dev_dbg(dmic->dev, "DMIC_DMAWAKEEN:  0x%04x\n",
117
 
                omap_dmic_read(dmic, DMIC_DMAWAKEEN));
118
 
        dev_dbg(dmic->dev, "DMIC_CTRL:  0x%04x\n",
119
 
                omap_dmic_read(dmic, DMIC_CTRL));
120
 
        dev_dbg(dmic->dev, "DMIC_DATA:  0x%04x\n",
121
 
                omap_dmic_read(dmic, DMIC_DATA));
122
 
        dev_dbg(dmic->dev, "DMIC_FIFO_CTRL:  0x%04x\n",
123
 
                omap_dmic_read(dmic, DMIC_FIFO_CTRL));
124
 
        dev_dbg(dmic->dev, "DMIC_FIFO_DMIC1R_DATA:  0x%08x\n",
125
 
                omap_dmic_read(dmic, DMIC_FIFO_DMIC1R_DATA));
126
 
        dev_dbg(dmic->dev, "DMIC_FIFO_DMIC1L_DATA:  0x%08x\n",
127
 
                omap_dmic_read(dmic, DMIC_FIFO_DMIC1L_DATA));
128
 
        dev_dbg(dmic->dev, "DMIC_FIFO_DMIC2R_DATA:  0x%08x\n",
129
 
                omap_dmic_read(dmic, DMIC_FIFO_DMIC2R_DATA));
130
 
        dev_dbg(dmic->dev, "DMIC_FIFO_DMIC2L_DATA:  0x%08x\n",
131
 
                omap_dmic_read(dmic, DMIC_FIFO_DMIC2L_DATA));
132
 
        dev_dbg(dmic->dev, "DMIC_FIFO_DMIC3R_DATA:  0x%08x\n",
133
 
                omap_dmic_read(dmic, DMIC_FIFO_DMIC3R_DATA));
134
 
        dev_dbg(dmic->dev, "DMIC_FIFO_DMIC3L_DATA:  0x%08x\n",
135
 
                omap_dmic_read(dmic, DMIC_FIFO_DMIC3L_DATA));
136
 
        dev_dbg(dmic->dev, "***********************\n");
137
 
}
138
 
#else
139
 
static void omap_dmic_reg_dump(struct omap_dmic *dmic) {}
140
 
#endif
141
 
 
142
 
/*
143
 
 * Enables the transfer through the DMIC interface
144
 
 */
145
 
static void omap_dmic_start(struct omap_dmic *dmic, int channels)
146
 
{
147
 
        int ctrl = omap_dmic_read(dmic, DMIC_CTRL);
148
 
        omap_dmic_write(dmic, DMIC_CTRL, ctrl | channels);
149
 
}
150
 
 
151
 
/*
152
 
 * Disables the transfer through the DMIC interface
153
 
 */
154
 
static void omap_dmic_stop(struct omap_dmic *dmic, int channels)
155
 
{
156
 
        int ctrl = omap_dmic_read(dmic, DMIC_CTRL);
157
 
        omap_dmic_write(dmic, DMIC_CTRL, ctrl & ~channels);
 
91
/*
 
92
 * Enables and disables DMIC channels through the DMIC interface
 
93
 */
 
94
static inline void dmic_set_up_channels(struct omap_dmic *dmic)
 
95
{
 
96
        u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL) & ~OMAP_DMIC_UP_ENABLE_MASK;
 
97
        omap_dmic_write(dmic, OMAP_DMIC_CTRL, ctrl | dmic->up_enable);
 
98
}
 
99
 
 
100
static inline int dmic_is_enabled(struct omap_dmic *dmic)
 
101
{
 
102
        return omap_dmic_read(dmic, OMAP_DMIC_CTRL) & OMAP_DMIC_UP_ENABLE_MASK;
 
103
}
 
104
 
 
105
static int omap_dmic_set_clkdiv(struct snd_soc_dai *dai,
 
106
                                int div_id, int div)
 
107
{
 
108
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
 
109
        int div_sel = -EINVAL;
 
110
        u32 ctrl;
 
111
 
 
112
        if (div_id != OMAP_DMIC_CLKDIV)
 
113
                return -ENODEV;
 
114
 
 
115
        switch (dmic->clk_freq) {
 
116
        case 19200000:
 
117
                switch (div) {
 
118
                case 5:
 
119
                        div_sel = 0x1;
 
120
                        break;
 
121
                case 8:
 
122
                        div_sel = 0x0;
 
123
                        break;
 
124
                default:
 
125
                        dev_err(dai->dev, "invalid div_sel (%d) for 19200000Hz", div);
 
126
                        return -EINVAL;
 
127
                }
 
128
                break;
 
129
        case 24000000:
 
130
                switch (div) {
 
131
                case 10:
 
132
                        div_sel = 0x2;
 
133
                        break;
 
134
                default:
 
135
                        dev_err(dai->dev, "invalid div_sel (%d) for 24000000Hz", div);
 
136
                        return -EINVAL;
 
137
                }
 
138
                break;
 
139
        case 24576000:
 
140
                switch (div) {
 
141
                case 8:
 
142
                        div_sel = 0x3;
 
143
                        break;
 
144
                case 16:
 
145
                        div_sel = 0x4;
 
146
                        break;
 
147
                default:
 
148
                        dev_err(dai->dev, "invalid div_sel (%d) for 24576000Hz", div);
 
149
                        return -EINVAL;
 
150
                }
 
151
                break;
 
152
        case 12000000:
 
153
                switch (div) {
 
154
                case 5:
 
155
                        div_sel = 0x5;
 
156
                        break;
 
157
                default:
 
158
                        dev_err(dai->dev, "invalid div_sel (%d) for 12000000Hz", div);
 
159
                        return -EINVAL;
 
160
                }
 
161
                break;
 
162
        default:
 
163
                dev_err(dai->dev, "invalid freq %d\n", dmic->clk_freq);
 
164
                return -EINVAL;
 
165
        }
 
166
 
 
167
        if (div_sel < 0) {
 
168
                dev_err(dai->dev, "divider not supported %d\n", div);
 
169
                return -EINVAL;
 
170
        }
 
171
 
 
172
        ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL) & ~OMAP_DMIC_CLK_DIV_MASK;
 
173
 
 
174
        omap_dmic_write(dmic, OMAP_DMIC_CTRL,
 
175
                        ctrl | (div_sel << OMAP_DMIC_CLK_DIV_SHIFT));
 
176
 
 
177
        return 0;
158
178
}
159
179
 
160
180
/*
161
181
 * Configures DMIC for audio recording.
162
182
 * This function should be called before omap_dmic_start.
163
183
 */
164
 
static int omap_dmic_open(struct omap_dmic *dmic)
 
184
static void omap_dmic_open(struct omap_dmic *dmic)
165
185
{
166
 
        struct omap_dmic_link *link = dmic->link;
167
 
        int ctrl;
168
 
 
169
 
        /* Enable irq request generation */
170
 
        omap_dmic_write(dmic, DMIC_IRQENABLE_SET,
171
 
                        link->irq_mask & DMIC_IRQ_MASK);
 
186
        u32 ctrl;
172
187
 
173
188
        /* Configure uplink threshold */
174
 
        if (link->threshold > DMIC_THRES_MAX)
175
 
                link->threshold = DMIC_THRES_MAX;
176
 
 
177
 
        omap_dmic_write(dmic, DMIC_FIFO_CTRL, link->threshold);
178
 
 
179
 
        /* Configure DMA controller */
180
 
        omap_dmic_write(dmic, DMIC_DMAENABLE_SET, DMIC_DMA_ENABLE);
 
189
        omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL, 2);
181
190
 
182
191
        /* Set dmic out format */
183
 
        ctrl = omap_dmic_read(dmic, DMIC_CTRL)
184
 
                & ~(DMIC_FORMAT | DMIC_POLAR_MASK);
185
 
        omap_dmic_write(dmic, DMIC_CTRL,
186
 
                        ctrl | link->format | link->polar);
187
 
 
188
 
        return 0;
 
192
        ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL)
 
193
                & ~(OMAP_DMIC_FORMAT | OMAP_DMIC_POLAR_MASK);
 
194
        omap_dmic_write(dmic, OMAP_DMIC_CTRL,
 
195
                        ctrl | OMAP_DMICOUTFORMAT_LJUST |
 
196
                        OMAP_DMIC_POLAR1 | OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
189
197
}
190
198
 
191
199
/*
192
200
 * Cleans DMIC uplink configuration.
193
201
 * This function should be called when the stream is closed.
194
202
 */
195
 
static int omap_dmic_close(struct omap_dmic *dmic)
 
203
static void omap_dmic_close(struct omap_dmic *dmic)
196
204
{
197
 
        struct omap_dmic_link *link = dmic->link;
198
 
 
199
 
        /* Disable irq request generation */
200
 
        omap_dmic_write(dmic, DMIC_IRQENABLE_CLR,
201
 
                        link->irq_mask & DMIC_IRQ_MASK);
202
 
 
203
205
        /* Disable DMA request generation */
204
 
        omap_dmic_write(dmic, DMIC_DMAENABLE_CLR, DMIC_DMA_ENABLE);
205
 
 
206
 
        return 0;
207
 
}
208
 
 
209
 
static irqreturn_t omap_dmic_irq_handler(int irq, void *dev_id)
210
 
{
211
 
        struct omap_dmic *dmic = dev_id;
212
 
        int irq_status;
213
 
 
214
 
        irq_status = omap_dmic_read(dmic, DMIC_IRQSTATUS);
215
 
 
216
 
        /* Acknowledge irq event */
217
 
        omap_dmic_write(dmic, DMIC_IRQSTATUS, irq_status);
218
 
        if (irq_status & DMIC_IRQ_FULL)
219
 
                dev_dbg(dmic->dev, "DMIC FIFO error %x\n", irq_status);
220
 
 
221
 
        if (irq_status & DMIC_IRQ_EMPTY)
222
 
                dev_dbg(dmic->dev, "DMIC FIFO error %x\n", irq_status);
223
 
 
224
 
        if (irq_status & DMIC_IRQ)
225
 
                dev_dbg(dmic->dev, "DMIC write request\n");
226
 
 
227
 
        return IRQ_HANDLED;
 
206
        omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR, OMAP_DMIC_DMA_ENABLE);
 
207
 
228
208
}
229
209
 
230
210
static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
231
211
                                  struct snd_soc_dai *dai)
232
212
{
233
213
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
234
 
 
235
 
        if (!dmic->active++)
 
214
        int ret = 0;
 
215
 
 
216
        mutex_lock(&dmic->mutex);
 
217
 
 
218
        if (!dmic->active) {
236
219
                pm_runtime_get_sync(dmic->dev);
237
220
 
238
 
        return 0;
 
221
                if (dai->id > OMAP4_LEGACY_DMIC0)
 
222
                        dmic->abe_mode = 1;
 
223
 
 
224
                omap_dmic_open(dmic);
 
225
        } else {
 
226
                /* legacy and ABE mode are mutually exclusive */
 
227
                if (dai->id > OMAP4_LEGACY_DMIC0 && !dmic->abe_mode) {
 
228
                        ret = -EBUSY;
 
229
                        goto out;
 
230
                }
 
231
        }
 
232
 
 
233
        dmic->active++;
 
234
 
 
235
out:
 
236
        mutex_unlock(&dmic->mutex);
 
237
        return ret;
239
238
}
240
239
 
241
240
static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
243
242
{
244
243
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
245
244
 
246
 
        if (!--dmic->active)
 
245
        mutex_lock(&dmic->mutex);
 
246
 
 
247
        if (--dmic->active == 0) {
 
248
                omap_dmic_close(dmic);
247
249
                pm_runtime_put_sync(dmic->dev);
 
250
                dmic->abe_mode = 0;
 
251
        }
 
252
 
 
253
        mutex_unlock(&dmic->mutex);
248
254
}
249
255
 
250
256
static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
252
258
                                    struct snd_soc_dai *dai)
253
259
{
254
260
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
255
 
        struct omap_dmic_link *link = dmic->link;
256
 
        int channels;
 
261
        int channels, rate, div;
257
262
        int ret = 0;
258
263
 
259
264
        channels = params_channels(params);
260
 
        switch (channels) {
261
 
        case 1:
262
 
        case 2:
263
 
                link->channels = 2;
 
265
        if (dai->id == OMAP4_LEGACY_DMIC0) {
 
266
                switch (channels) {
 
267
                case 2:
 
268
                case 4:
 
269
                case 6:
 
270
                        dmic->channels = channels;
 
271
                        break;
 
272
                default:
 
273
                        dev_err(dmic->dev, "invalid number of legacy channels\n");
 
274
                        return -EINVAL;
 
275
                }
 
276
        } else {
 
277
                if (channels != 2) {
 
278
                        dev_err(dmic->dev, "invalid number of ABE channels\n");
 
279
                        return -EINVAL;
 
280
                }
 
281
        }
 
282
 
 
283
        rate = params_rate(params);
 
284
        switch (rate) {
 
285
        case 96000:
 
286
                div = 8;
 
287
                break;
 
288
        case 192000:
 
289
                div = 5;
264
290
                break;
265
291
        default:
266
 
                dev_err(dmic->dev, "invalid number of channels\n");
 
292
                dev_err(dmic->dev, "rate %d not supported\n", rate);
267
293
                return -EINVAL;
268
294
        }
269
295
 
270
 
        omap_dmic_dai_dma_params.packet_size = link->threshold * link->channels;
 
296
        /* packet size is threshold * channels */
 
297
        omap_dmic_dai_dma_params.packet_size = 2 * channels;
271
298
        snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
272
299
 
273
 
        if (dmic->active == 1)
274
 
                ret = omap_dmic_open(dmic);
275
 
 
276
300
        return ret;
277
301
}
278
302
 
279
 
static int omap_dmic_dai_hw_free(struct snd_pcm_substream *substream,
 
303
static void dmic_config_up_channels(struct omap_dmic *dmic, int dai_id,
 
304
                int enable)
 
305
{
 
306
        if (enable) {
 
307
                switch (dai_id) {
 
308
                case OMAP4_LEGACY_DMIC0:
 
309
                        switch (dmic->channels) {
 
310
                        case 6:
 
311
                                dmic->up_enable = OMAP_DMIC_UP1_ENABLE | OMAP_DMIC_UP2_ENABLE
 
312
                                         | OMAP_DMIC_UP3_ENABLE;
 
313
                                break;
 
314
                        case 4:
 
315
                                dmic->up_enable = OMAP_DMIC_UP1_ENABLE | OMAP_DMIC_UP2_ENABLE;
 
316
                                break;
 
317
                        case 2:
 
318
                                dmic->up_enable = OMAP_DMIC_UP1_ENABLE;
 
319
                                break;
 
320
                        default:
 
321
                                break;
 
322
                        }
 
323
                        break;
 
324
                case OMAP4_ABE_DMIC0:
 
325
                case OMAP4_ABE_DMIC1:
 
326
                case OMAP4_ABE_DMIC2:
 
327
                        /*
 
328
                         * ABE expects all the DMIC interfaces to be
 
329
                         * enabled, so enabling them when at least one
 
330
                         * DMIC DAI is running
 
331
                         */
 
332
                        if (dmic->running)
 
333
                                dmic->up_enable |= OMAP_DMIC_UP1_ENABLE |
 
334
                                        OMAP_DMIC_UP2_ENABLE |
 
335
                                        OMAP_DMIC_UP3_ENABLE;
 
336
                        break;
 
337
                default:
 
338
                        break;
 
339
                }
 
340
        } else {
 
341
                switch (dai_id) {
 
342
                case OMAP4_LEGACY_DMIC0:
 
343
                        dmic->up_enable = 0;
 
344
                        break;
 
345
                case OMAP4_ABE_DMIC0:
 
346
                case OMAP4_ABE_DMIC1:
 
347
                case OMAP4_ABE_DMIC2:
 
348
                        /*
 
349
                         * Disable all DMIC interfaces only when
 
350
                         * all DAIs are stopped
 
351
                         */
 
352
                        if (!dmic->running)
 
353
                                dmic->up_enable = 0;
 
354
                        break;
 
355
                default:
 
356
                        break;
 
357
                }
 
358
        }
 
359
}
 
360
 
 
361
static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
280
362
                                  struct snd_soc_dai *dai)
281
363
{
282
364
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
283
 
        struct omap_dmic_link *link = dmic->link;
284
 
        int ret = 0;
285
 
 
286
 
        if (dmic->active == 1) {
287
 
                ret = omap_dmic_close(dmic);
288
 
                link->channels = 0;
289
 
        }
290
 
 
291
 
        return ret;
 
365
 
 
366
        /* Configure DMA controller */
 
367
        omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET, OMAP_DMIC_DMA_ENABLE);
 
368
 
 
369
        return 0;
292
370
}
293
371
 
294
372
static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
295
373
                                  int cmd, struct snd_soc_dai *dai)
296
374
{
297
375
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
298
 
        int dmic_id = 1 << dai->id;
299
 
 
300
 
        omap_dmic_reg_dump(dmic);
301
376
 
302
377
        switch (cmd) {
303
378
        case SNDRV_PCM_TRIGGER_START:
304
 
                omap_dmic_start(dmic, dmic_id);
305
 
                break;
306
 
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
307
 
                break;
308
 
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 
379
                dmic->running++;
 
380
                dmic_config_up_channels(dmic, dai->id, 1);
 
381
                dmic_set_up_channels(dmic);
309
382
                break;
310
383
        case SNDRV_PCM_TRIGGER_STOP:
311
 
                omap_dmic_stop(dmic, dmic_id);
 
384
                dmic->running--;
 
385
                dmic_config_up_channels(dmic, dai->id, 0);
 
386
                dmic_set_up_channels(dmic);
312
387
                break;
313
388
        default:
314
389
                break;
326
401
        int ret = 0;
327
402
 
328
403
        dmic_clk = clk_get(NULL, "dmic_fck");
329
 
        if (IS_ERR(dmic_clk))
 
404
        if (IS_ERR(dmic_clk)) {
 
405
                dev_err(dmic->dev, "cant get dmic_fck\n");
330
406
                return -ENODEV;
 
407
        }
331
408
 
332
409
        switch (clk_id) {
333
410
        case OMAP_DMIC_SYSCLK_PAD_CLKS:
334
411
                parent_clk = clk_get(NULL, "pad_clks_ck");
335
412
                if (IS_ERR(parent_clk)) {
 
413
                        dev_err(dmic->dev, "cant get pad_clks_ck\n");
336
414
                        ret = -ENODEV;
337
415
                        goto err_par;
338
416
                }
340
418
        case OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS:
341
419
                parent_clk = clk_get(NULL, "slimbus_clk");
342
420
                if (IS_ERR(parent_clk)) {
 
421
                        dev_err(dmic->dev, "cant get slimbus_clk\n");
343
422
                        ret = -ENODEV;
344
423
                        goto err_par;
345
424
                }
347
426
        case OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS:
348
427
                parent_clk = clk_get(NULL, "dmic_sync_mux_ck");
349
428
                if (IS_ERR(parent_clk)) {
 
429
                        dev_err(dmic->dev, "cant get dmic_sync_mux_ck\n");
350
430
                        ret = -ENODEV;
351
431
                        goto err_par;
352
432
                }
357
437
                goto err_par;
358
438
        }
359
439
 
360
 
        switch (freq) {
361
 
        case 19200000:
362
 
        case 24000000:
363
 
        case 24576000:
364
 
        case 12000000:
365
 
                dmic->clk_freq = freq;
366
 
                break;
367
 
        default:
368
 
                dev_err(dai->dev, "clk freq not supported %d\n", freq);
369
 
                ret = -EINVAL;
370
 
                goto err_freq;
371
 
        }
372
 
 
373
440
        if (dmic->sysclk != clk_id) {
374
 
                /* reparent not allowed if a stream is ongoing */
375
 
                if (dmic->active > 1)
376
 
                        return -EBUSY;
 
441
                /* re-parent not allowed if a stream is ongoing */
 
442
                if (dmic_is_enabled(dmic)) {
 
443
                        dev_err(dmic->dev, "cant re-parent when DMIC active\n");
 
444
                        ret = -EBUSY;
 
445
                        goto err_busy;
 
446
                }
377
447
 
378
448
                /* disable clock while reparenting */
379
 
                if (dmic->active == 1)
380
 
                        pm_runtime_put_sync(dmic->dev);
381
 
 
 
449
                pm_runtime_put_sync(dmic->dev);
382
450
                ret = clk_set_parent(dmic_clk, parent_clk);
383
 
 
384
 
                if (dmic->active == 1)
385
 
                        pm_runtime_get_sync(dmic->dev);
 
451
                pm_runtime_get_sync(dmic->dev);
 
452
                if (ret < 0) {
 
453
                        dev_err(dmic->dev, "re-parent failed\n");
 
454
                        goto err_busy;
 
455
                }
386
456
 
387
457
                dmic->sysclk = clk_id;
 
458
 
 
459
                //ret = clk_set_rate(dmic_clk, freq);
 
460
                if (ret < 0)
 
461
                        dev_err(dmic->dev, "clock set to %d Hz failed\n", freq);
 
462
                else
 
463
                        dmic->clk_freq = freq;
388
464
        }
389
465
 
390
 
err_freq:
 
466
err_busy:
391
467
        clk_put(parent_clk);
392
468
err_par:
393
469
        clk_put(dmic_clk);
395
471
        return ret;
396
472
}
397
473
 
398
 
static int omap_dmic_set_clkdiv(struct snd_soc_dai *dai,
399
 
                                int div_id, int div)
400
 
{
401
 
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
402
 
        int ctrl, div_sel = -EINVAL;
403
 
 
404
 
        if (div_id != OMAP_DMIC_CLKDIV)
405
 
                return -ENODEV;
406
 
 
407
 
        switch (dmic->clk_freq) {
408
 
        case 19200000:
409
 
                if (div == 5)
410
 
                        div_sel = 0x1;
411
 
                else if (div == 8)
412
 
                        div_sel = 0x0;
413
 
                break;
414
 
        case 24000000:
415
 
                if (div == 10)
416
 
                        div_sel = 0x2;
417
 
                break;
418
 
        case 24576000:
419
 
                if (div == 8)
420
 
                        div_sel = 0x3;
421
 
                else if (div == 16)
422
 
                        div_sel = 0x4;
423
 
                break;
424
 
        case 12000000:
425
 
                if (div == 5)
426
 
                        div_sel = 0x5;
427
 
                break;
428
 
        default:
429
 
                dev_err(dai->dev, "invalid freq %d\n", dmic->clk_freq);
430
 
                return -EINVAL;
431
 
        }
432
 
 
433
 
        if (div_sel < 0) {
434
 
                dev_err(dai->dev, "divider not supported %d\n", div);
435
 
                return -EINVAL;
436
 
        }
437
 
 
438
 
        ctrl = omap_dmic_read(dmic, DMIC_CTRL) & ~DMIC_CLK_DIV_MASK;
439
 
        omap_dmic_write(dmic, DMIC_CTRL,
440
 
                        ctrl | (div_sel << DMIC_CLK_DIV_SHIFT));
441
 
 
442
 
        return 0;
443
 
}
444
 
 
445
474
static struct snd_soc_dai_ops omap_dmic_dai_ops = {
446
475
        .startup        = omap_dmic_dai_startup,
447
476
        .shutdown       = omap_dmic_dai_shutdown,
448
477
        .hw_params      = omap_dmic_dai_hw_params,
 
478
        .prepare        = omap_dmic_dai_prepare,
449
479
        .trigger        = omap_dmic_dai_trigger,
450
 
        .hw_free        = omap_dmic_dai_hw_free,
451
 
        .set_sysclk     = omap_dmic_set_dai_sysclk,
452
 
        .set_clkdiv     = omap_dmic_set_clkdiv,
453
 
};
454
 
 
455
 
#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP) || \
456
 
    defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
457
 
static int omap_dmic_abe_dai_trigger(struct snd_pcm_substream *substream,
458
 
                                  int cmd, struct snd_soc_dai *dai)
459
 
{
460
 
        struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
461
 
        int dmic_id = DMIC_UP1_ENABLE | DMIC_UP2_ENABLE | DMIC_UP3_ENABLE;
462
 
 
463
 
        omap_dmic_reg_dump(dmic);
464
 
 
465
 
        switch (cmd) {
466
 
        case SNDRV_PCM_TRIGGER_START:
467
 
                if (dmic->active == 1)
468
 
                        omap_dmic_start(dmic, dmic_id);
469
 
                break;
470
 
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
471
 
                break;
472
 
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
473
 
                break;
474
 
        case SNDRV_PCM_TRIGGER_STOP:
475
 
                if (dmic->active == 1)
476
 
                        omap_dmic_stop(dmic, dmic_id);
477
 
                break;
478
 
        default:
479
 
                break;
480
 
        }
481
 
 
482
 
        return 0;
483
 
}
484
 
 
485
 
static struct snd_soc_dai_ops omap_dmic_abe_dai_ops = {
486
 
        .startup        = omap_dmic_dai_startup,
487
 
        .shutdown       = omap_dmic_dai_shutdown,
488
 
        .hw_params      = omap_dmic_dai_hw_params,
489
 
        .trigger        = omap_dmic_abe_dai_trigger,
490
 
        .hw_free        = omap_dmic_dai_hw_free,
491
 
        .set_sysclk     = omap_dmic_set_dai_sysclk,
492
 
        .set_clkdiv     = omap_dmic_set_clkdiv,
493
 
};
494
 
#endif
 
480
        .set_sysclk     = omap_dmic_set_dai_sysclk,
 
481
        .set_clkdiv     = omap_dmic_set_clkdiv,
 
482
};
495
483
 
496
484
static struct snd_soc_dai_driver omap_dmic_dai[] = {
497
485
{
498
486
        .name = "omap-dmic-dai-0",
 
487
        .id     = OMAP4_LEGACY_DMIC0,
499
488
        .capture = {
500
489
                .channels_min = 2,
501
 
                .channels_max = 2,
 
490
                .channels_max = 6,
502
491
                .rates = OMAP_DMIC_RATES,
503
492
                .formats = OMAP_DMIC_FORMATS,
504
493
        },
505
494
        .ops = &omap_dmic_dai_ops,
506
495
},
507
496
{
508
 
        .name = "omap-dmic-dai-1",
509
 
        .capture = {
510
 
                .channels_min = 2,
511
 
                .channels_max = 2,
512
 
                .rates = OMAP_DMIC_RATES,
513
 
                .formats = OMAP_DMIC_FORMATS,
514
 
        },
515
 
        .ops = &omap_dmic_abe_dai_ops,
516
 
},
517
 
{
518
 
        .name = "omap-dmic-dai-2",
519
 
        .capture = {
520
 
                .channels_min = 2,
521
 
                .channels_max = 2,
522
 
                .rates = OMAP_DMIC_RATES,
523
 
                .formats = OMAP_DMIC_FORMATS,
524
 
        },
525
 
        .ops = &omap_dmic_abe_dai_ops,
526
 
},
527
 
#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP) || \
528
 
    defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
529
 
{
530
497
        .name = "omap-dmic-abe-dai-0",
 
498
        .id     = OMAP4_ABE_DMIC0,
531
499
        .capture = {
532
500
                .channels_min = 2,
533
501
                .channels_max = 2,
534
502
                .rates = OMAP_DMIC_RATES,
535
503
                .formats = OMAP_DMIC_FORMATS,
536
504
        },
537
 
        .ops = &omap_dmic_abe_dai_ops,
 
505
        .ops = &omap_dmic_dai_ops,
538
506
},
539
507
{
540
508
        .name = "omap-dmic-abe-dai-1",
 
509
        .id     = OMAP4_ABE_DMIC1,
541
510
        .capture = {
542
511
                .channels_min = 2,
543
512
                .channels_max = 2,
544
513
                .rates = OMAP_DMIC_RATES,
545
514
                .formats = OMAP_DMIC_FORMATS,
546
515
        },
547
 
        .ops = &omap_dmic_abe_dai_ops,
 
516
        .ops = &omap_dmic_dai_ops,
548
517
},
549
518
{
550
519
        .name = "omap-dmic-abe-dai-2",
 
520
        .id     = OMAP4_ABE_DMIC2,
551
521
        .capture = {
552
522
                .channels_min = 2,
553
523
                .channels_max = 2,
554
524
                .rates = OMAP_DMIC_RATES,
555
525
                .formats = OMAP_DMIC_FORMATS,
556
526
        },
557
 
        .ops = &omap_dmic_abe_dai_ops,
 
527
        .ops = &omap_dmic_dai_ops,
558
528
},
559
 
#endif
560
529
};
561
530
 
562
531
static __devinit int asoc_dmic_probe(struct platform_device *pdev)
571
540
 
572
541
        platform_set_drvdata(pdev, dmic);
573
542
        dmic->dev = &pdev->dev;
574
 
        dmic->link = &omap_dmic_link;
 
543
        dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS;
575
544
 
576
 
        spin_lock_init(&dmic->lock);
 
545
        mutex_init(&dmic->mutex);
577
546
 
578
547
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
579
548
        if (!res) {
588
557
                goto err_res;
589
558
        }
590
559
 
591
 
        dmic->irq = platform_get_irq(pdev, 0);
592
 
        if (dmic->irq < 0) {
593
 
                ret = dmic->irq;
594
 
                goto err_irq;
595
 
        }
596
 
 
597
560
        res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
598
561
        if (!res) {
599
562
                dev_err(dmic->dev, "invalid dma resource\n");
600
563
                ret = -ENODEV;
601
 
                goto err_irq;
 
564
                goto err_dai;
602
565
        }
603
566
        omap_dmic_dai_dma_params.dma_req = res->start;
604
567
 
605
568
        pm_runtime_enable(dmic->dev);
606
569
 
607
570
        /* Disable lines while request is ongoing */
608
 
        omap_dmic_write(dmic, DMIC_CTRL, 0x00);
609
 
 
610
 
        ret = request_threaded_irq(dmic->irq, NULL, omap_dmic_irq_handler,
611
 
                                   IRQF_ONESHOT, "DMIC", (void *)dmic);
612
 
        if (ret) {
613
 
                dev_err(dmic->dev, "irq request failed\n");
614
 
                goto err_irq;
615
 
        }
 
571
        omap_dmic_write(dmic, OMAP_DMIC_CTRL, 0x00);
616
572
 
617
573
        ret = snd_soc_register_dais(&pdev->dev, omap_dmic_dai,
618
 
                                    ARRAY_SIZE(omap_dmic_dai));
 
574
                        ARRAY_SIZE(omap_dmic_dai));
619
575
        if (ret)
620
576
                goto err_dai;
621
577
 
622
578
        return 0;
623
579
 
624
580
err_dai:
625
 
        free_irq(dmic->irq, (void *)dmic);
626
 
err_irq:
627
581
        iounmap(dmic->io_base);
628
582
err_res:
629
583
        kfree(dmic);
634
588
{
635
589
        struct omap_dmic *dmic = platform_get_drvdata(pdev);
636
590
 
637
 
        snd_soc_unregister_dai(&pdev->dev);
 
591
        snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(omap_dmic_dai));
638
592
        iounmap(dmic->io_base);
639
 
        free_irq(dmic->irq, (void *)dmic);
 
593
        pm_runtime_disable(dmic->dev);
640
594
        kfree(dmic);
641
595
 
642
596
        return 0;
663
617
}
664
618
module_exit(snd_omap_dmic_exit);
665
619
 
 
620
MODULE_ALIAS("platform:omap-dmic-dai");
666
621
MODULE_AUTHOR("David Lambert <dlambert@ti.com>");
667
 
MODULE_DESCRIPTION("OMAP DMIC SoC Interface");
 
622
MODULE_DESCRIPTION("OMAP DMIC ASoC Interface");
668
623
MODULE_LICENSE("GPL");