]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/media/pci/tw686x/tw686x-audio.c
Merge tag 'pstore-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
[linux.git] / drivers / media / pci / tw686x / tw686x-audio.c
1 /*
2  * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
3  *
4  * Based on the audio support from the tw6869 driver:
5  * Copyright 2015 www.starterkit.ru <info@starterkit.ru>
6  *
7  * Based on:
8  * Driver for Intersil|Techwell TW6869 based DVR cards
9  * (c) 2011-12 liran <jli11@intersil.com> [Intersil|Techwell China]
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of version 2 of the GNU General Public License
13  * as published by the Free Software Foundation.
14  */
15
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/kmod.h>
21 #include <linux/mutex.h>
22 #include <linux/pci.h>
23 #include <linux/delay.h>
24
25 #include <sound/core.h>
26 #include <sound/initval.h>
27 #include <sound/pcm.h>
28 #include <sound/control.h>
29 #include "tw686x.h"
30 #include "tw686x-regs.h"
31
32 #define AUDIO_CHANNEL_OFFSET 8
33
34 void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests,
35                       unsigned int pb_status)
36 {
37         unsigned long flags;
38         unsigned int ch, pb;
39
40         for_each_set_bit(ch, &requests, max_channels(dev)) {
41                 struct tw686x_audio_channel *ac = &dev->audio_channels[ch];
42                 struct tw686x_audio_buf *done = NULL;
43                 struct tw686x_audio_buf *next = NULL;
44                 struct tw686x_dma_desc *desc;
45
46                 pb = !!(pb_status & BIT(AUDIO_CHANNEL_OFFSET + ch));
47
48                 spin_lock_irqsave(&ac->lock, flags);
49
50                 /* Sanity check */
51                 if (!ac->ss || !ac->curr_bufs[0] || !ac->curr_bufs[1]) {
52                         spin_unlock_irqrestore(&ac->lock, flags);
53                         continue;
54                 }
55
56                 if (!list_empty(&ac->buf_list)) {
57                         next = list_first_entry(&ac->buf_list,
58                                         struct tw686x_audio_buf, list);
59                         list_move_tail(&next->list, &ac->buf_list);
60                         done = ac->curr_bufs[!pb];
61                         ac->curr_bufs[pb] = next;
62                 }
63                 spin_unlock_irqrestore(&ac->lock, flags);
64
65                 desc = &ac->dma_descs[pb];
66                 if (done && next && desc->virt) {
67                         memcpy(done->virt, desc->virt, desc->size);
68                         ac->ptr = done->dma - ac->buf[0].dma;
69                         snd_pcm_period_elapsed(ac->ss);
70                 }
71         }
72 }
73
74 static int tw686x_pcm_hw_params(struct snd_pcm_substream *ss,
75                                 struct snd_pcm_hw_params *hw_params)
76 {
77         return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
78 }
79
80 static int tw686x_pcm_hw_free(struct snd_pcm_substream *ss)
81 {
82         return snd_pcm_lib_free_pages(ss);
83 }
84
85 /*
86  * The audio device rate is global and shared among all
87  * capture channels. The driver makes no effort to prevent
88  * rate modifications. User is free change the rate, but it
89  * means changing the rate for all capture sub-devices.
90  */
91 static const struct snd_pcm_hardware tw686x_capture_hw = {
92         .info                   = (SNDRV_PCM_INFO_MMAP |
93                                    SNDRV_PCM_INFO_INTERLEAVED |
94                                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
95                                    SNDRV_PCM_INFO_MMAP_VALID),
96         .formats                = SNDRV_PCM_FMTBIT_S16_LE,
97         .rates                  = SNDRV_PCM_RATE_8000_48000,
98         .rate_min               = 8000,
99         .rate_max               = 48000,
100         .channels_min           = 1,
101         .channels_max           = 1,
102         .buffer_bytes_max       = TW686X_AUDIO_PAGE_MAX * TW686X_AUDIO_PAGE_SZ,
103         .period_bytes_min       = TW686X_AUDIO_PAGE_SZ,
104         .period_bytes_max       = TW686X_AUDIO_PAGE_SZ,
105         .periods_min            = TW686X_AUDIO_PERIODS_MIN,
106         .periods_max            = TW686X_AUDIO_PERIODS_MAX,
107 };
108
109 static int tw686x_pcm_open(struct snd_pcm_substream *ss)
110 {
111         struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
112         struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
113         struct snd_pcm_runtime *rt = ss->runtime;
114         int err;
115
116         ac->ss = ss;
117         rt->hw = tw686x_capture_hw;
118
119         err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
120         if (err < 0)
121                 return err;
122
123         return 0;
124 }
125
126 static int tw686x_pcm_close(struct snd_pcm_substream *ss)
127 {
128         struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
129         struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
130
131         ac->ss = NULL;
132         return 0;
133 }
134
135 static int tw686x_pcm_prepare(struct snd_pcm_substream *ss)
136 {
137         struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
138         struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
139         struct snd_pcm_runtime *rt = ss->runtime;
140         unsigned int period_size = snd_pcm_lib_period_bytes(ss);
141         struct tw686x_audio_buf *p_buf, *b_buf;
142         unsigned long flags;
143         int i;
144
145         spin_lock_irqsave(&dev->lock, flags);
146         tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
147         spin_unlock_irqrestore(&dev->lock, flags);
148
149         if (dev->audio_rate != rt->rate) {
150                 u32 reg;
151
152                 dev->audio_rate = rt->rate;
153                 reg = ((125000000 / rt->rate) << 16) +
154                        ((125000000 % rt->rate) << 16) / rt->rate;
155
156                 reg_write(dev, AUDIO_CONTROL2, reg);
157         }
158
159         if (period_size != TW686X_AUDIO_PAGE_SZ ||
160             rt->periods < TW686X_AUDIO_PERIODS_MIN ||
161             rt->periods > TW686X_AUDIO_PERIODS_MAX) {
162                 return -EINVAL;
163         }
164
165         spin_lock_irqsave(&ac->lock, flags);
166         INIT_LIST_HEAD(&ac->buf_list);
167
168         for (i = 0; i < rt->periods; i++) {
169                 ac->buf[i].dma = rt->dma_addr + period_size * i;
170                 ac->buf[i].virt = rt->dma_area + period_size * i;
171                 INIT_LIST_HEAD(&ac->buf[i].list);
172                 list_add_tail(&ac->buf[i].list, &ac->buf_list);
173         }
174
175         p_buf = list_first_entry(&ac->buf_list, struct tw686x_audio_buf, list);
176         list_move_tail(&p_buf->list, &ac->buf_list);
177
178         b_buf = list_first_entry(&ac->buf_list, struct tw686x_audio_buf, list);
179         list_move_tail(&b_buf->list, &ac->buf_list);
180
181         ac->curr_bufs[0] = p_buf;
182         ac->curr_bufs[1] = b_buf;
183         ac->ptr = 0;
184         spin_unlock_irqrestore(&ac->lock, flags);
185
186         return 0;
187 }
188
189 static int tw686x_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
190 {
191         struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
192         struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
193         unsigned long flags;
194         int err = 0;
195
196         switch (cmd) {
197         case SNDRV_PCM_TRIGGER_START:
198                 if (ac->curr_bufs[0] && ac->curr_bufs[1]) {
199                         spin_lock_irqsave(&dev->lock, flags);
200                         tw686x_enable_channel(dev,
201                                 AUDIO_CHANNEL_OFFSET + ac->ch);
202                         spin_unlock_irqrestore(&dev->lock, flags);
203
204                         mod_timer(&dev->dma_delay_timer,
205                                   jiffies + msecs_to_jiffies(100));
206                 } else {
207                         err = -EIO;
208                 }
209                 break;
210         case SNDRV_PCM_TRIGGER_STOP:
211                 spin_lock_irqsave(&dev->lock, flags);
212                 tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
213                 spin_unlock_irqrestore(&dev->lock, flags);
214
215                 spin_lock_irqsave(&ac->lock, flags);
216                 ac->curr_bufs[0] = NULL;
217                 ac->curr_bufs[1] = NULL;
218                 spin_unlock_irqrestore(&ac->lock, flags);
219                 break;
220         default:
221                 err = -EINVAL;
222         }
223         return err;
224 }
225
226 static snd_pcm_uframes_t tw686x_pcm_pointer(struct snd_pcm_substream *ss)
227 {
228         struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
229         struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
230
231         return bytes_to_frames(ss->runtime, ac->ptr);
232 }
233
234 static struct snd_pcm_ops tw686x_pcm_ops = {
235         .open = tw686x_pcm_open,
236         .close = tw686x_pcm_close,
237         .ioctl = snd_pcm_lib_ioctl,
238         .hw_params = tw686x_pcm_hw_params,
239         .hw_free = tw686x_pcm_hw_free,
240         .prepare = tw686x_pcm_prepare,
241         .trigger = tw686x_pcm_trigger,
242         .pointer = tw686x_pcm_pointer,
243 };
244
245 static int tw686x_snd_pcm_init(struct tw686x_dev *dev)
246 {
247         struct snd_card *card = dev->snd_card;
248         struct snd_pcm *pcm;
249         struct snd_pcm_substream *ss;
250         unsigned int i;
251         int err;
252
253         err = snd_pcm_new(card, card->driver, 0, 0, max_channels(dev), &pcm);
254         if (err < 0)
255                 return err;
256
257         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &tw686x_pcm_ops);
258         snd_pcm_chip(pcm) = dev;
259         pcm->info_flags = 0;
260         strlcpy(pcm->name, "tw686x PCM", sizeof(pcm->name));
261
262         for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
263              ss; ss = ss->next, i++)
264                 snprintf(ss->name, sizeof(ss->name), "vch%u audio", i);
265
266         return snd_pcm_lib_preallocate_pages_for_all(pcm,
267                                 SNDRV_DMA_TYPE_DEV,
268                                 snd_dma_pci_data(dev->pci_dev),
269                                 TW686X_AUDIO_PAGE_MAX * TW686X_AUDIO_PAGE_SZ,
270                                 TW686X_AUDIO_PAGE_MAX * TW686X_AUDIO_PAGE_SZ);
271 }
272
273 static void tw686x_audio_dma_free(struct tw686x_dev *dev,
274                                   struct tw686x_audio_channel *ac)
275 {
276         int pb;
277
278         for (pb = 0; pb < 2; pb++) {
279                 if (!ac->dma_descs[pb].virt)
280                         continue;
281                 pci_free_consistent(dev->pci_dev, ac->dma_descs[pb].size,
282                                     ac->dma_descs[pb].virt,
283                                     ac->dma_descs[pb].phys);
284                 ac->dma_descs[pb].virt = NULL;
285         }
286 }
287
288 static int tw686x_audio_dma_alloc(struct tw686x_dev *dev,
289                                   struct tw686x_audio_channel *ac)
290 {
291         int pb;
292
293         for (pb = 0; pb < 2; pb++) {
294                 u32 reg = pb ? ADMA_B_ADDR[ac->ch] : ADMA_P_ADDR[ac->ch];
295                 void *virt;
296
297                 virt = pci_alloc_consistent(dev->pci_dev, TW686X_AUDIO_PAGE_SZ,
298                                             &ac->dma_descs[pb].phys);
299                 if (!virt) {
300                         dev_err(&dev->pci_dev->dev,
301                                 "dma%d: unable to allocate audio DMA %s-buffer\n",
302                                 ac->ch, pb ? "B" : "P");
303                         return -ENOMEM;
304                 }
305                 ac->dma_descs[pb].virt = virt;
306                 ac->dma_descs[pb].size = TW686X_AUDIO_PAGE_SZ;
307                 reg_write(dev, reg, ac->dma_descs[pb].phys);
308         }
309         return 0;
310 }
311
312 void tw686x_audio_free(struct tw686x_dev *dev)
313 {
314         unsigned long flags;
315         u32 dma_ch_mask;
316         u32 dma_cmd;
317
318         spin_lock_irqsave(&dev->lock, flags);
319         dma_cmd = reg_read(dev, DMA_CMD);
320         dma_ch_mask = reg_read(dev, DMA_CHANNEL_ENABLE);
321         reg_write(dev, DMA_CMD, dma_cmd & ~0xff00);
322         reg_write(dev, DMA_CHANNEL_ENABLE, dma_ch_mask & ~0xff00);
323         spin_unlock_irqrestore(&dev->lock, flags);
324
325         if (!dev->snd_card)
326                 return;
327         snd_card_free(dev->snd_card);
328         dev->snd_card = NULL;
329 }
330
331 int tw686x_audio_init(struct tw686x_dev *dev)
332 {
333         struct pci_dev *pci_dev = dev->pci_dev;
334         struct snd_card *card;
335         int err, ch;
336
337         /*
338          * AUDIO_CONTROL1
339          * DMA byte length [31:19] = 4096 (i.e. ALSA period)
340          * External audio enable [0] = enabled
341          */
342         reg_write(dev, AUDIO_CONTROL1, 0x80000001);
343
344         err = snd_card_new(&pci_dev->dev, SNDRV_DEFAULT_IDX1,
345                            SNDRV_DEFAULT_STR1,
346                            THIS_MODULE, 0, &card);
347         if (err < 0)
348                 return err;
349
350         dev->snd_card = card;
351         strlcpy(card->driver, "tw686x", sizeof(card->driver));
352         strlcpy(card->shortname, "tw686x", sizeof(card->shortname));
353         strlcpy(card->longname, pci_name(pci_dev), sizeof(card->longname));
354         snd_card_set_dev(card, &pci_dev->dev);
355
356         for (ch = 0; ch < max_channels(dev); ch++) {
357                 struct tw686x_audio_channel *ac;
358
359                 ac = &dev->audio_channels[ch];
360                 spin_lock_init(&ac->lock);
361                 ac->dev = dev;
362                 ac->ch = ch;
363
364                 err = tw686x_audio_dma_alloc(dev, ac);
365                 if (err < 0)
366                         goto err_cleanup;
367         }
368
369         err = tw686x_snd_pcm_init(dev);
370         if (err < 0)
371                 goto err_cleanup;
372
373         err = snd_card_register(card);
374         if (!err)
375                 return 0;
376
377 err_cleanup:
378         for (ch = 0; ch < max_channels(dev); ch++) {
379                 if (!dev->audio_channels[ch].dev)
380                         continue;
381                 tw686x_audio_dma_free(dev, &dev->audio_channels[ch]);
382         }
383         snd_card_free(card);
384         dev->snd_card = NULL;
385         return err;
386 }