1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
5 * Based on the audio support from the tw6869 driver:
6 * Copyright 2015 www.starterkit.ru <info@starterkit.ru>
9 * Driver for Intersil|Techwell TW6869 based DVR cards
10 * (c) 2011-12 liran <jli11@intersil.com> [Intersil|Techwell China]
13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/kmod.h>
18 #include <linux/mutex.h>
19 #include <linux/pci.h>
20 #include <linux/delay.h>
22 #include <sound/core.h>
23 #include <sound/initval.h>
24 #include <sound/pcm.h>
25 #include <sound/control.h>
27 #include "tw686x-regs.h"
29 #define AUDIO_CHANNEL_OFFSET 8
31 void tw686x_audio_irq(struct tw686x_dev
*dev
, unsigned long requests
,
32 unsigned int pb_status
)
37 for_each_set_bit(ch
, &requests
, max_channels(dev
)) {
38 struct tw686x_audio_channel
*ac
= &dev
->audio_channels
[ch
];
39 struct tw686x_audio_buf
*done
= NULL
;
40 struct tw686x_audio_buf
*next
= NULL
;
41 struct tw686x_dma_desc
*desc
;
43 pb
= !!(pb_status
& BIT(AUDIO_CHANNEL_OFFSET
+ ch
));
45 spin_lock_irqsave(&ac
->lock
, flags
);
48 if (!ac
->ss
|| !ac
->curr_bufs
[0] || !ac
->curr_bufs
[1]) {
49 spin_unlock_irqrestore(&ac
->lock
, flags
);
53 if (!list_empty(&ac
->buf_list
)) {
54 next
= list_first_entry(&ac
->buf_list
,
55 struct tw686x_audio_buf
, list
);
56 list_move_tail(&next
->list
, &ac
->buf_list
);
57 done
= ac
->curr_bufs
[!pb
];
58 ac
->curr_bufs
[pb
] = next
;
60 spin_unlock_irqrestore(&ac
->lock
, flags
);
65 * Checking for a non-nil dma_desc[pb]->virt buffer is
66 * the same as checking for memcpy DMA mode.
68 desc
= &ac
->dma_descs
[pb
];
70 memcpy(done
->virt
, desc
->virt
,
73 u32 reg
= pb
? ADMA_B_ADDR
[ch
] : ADMA_P_ADDR
[ch
];
74 reg_write(dev
, reg
, next
->dma
);
76 ac
->ptr
= done
->dma
- ac
->buf
[0].dma
;
77 snd_pcm_period_elapsed(ac
->ss
);
82 * Audio parameters are global and shared among all
83 * capture channels. The driver prevents changes to
84 * the parameters if any audio channel is capturing.
86 static const struct snd_pcm_hardware tw686x_capture_hw
= {
87 .info
= (SNDRV_PCM_INFO_MMAP
|
88 SNDRV_PCM_INFO_INTERLEAVED
|
89 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
90 SNDRV_PCM_INFO_MMAP_VALID
),
91 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
92 .rates
= SNDRV_PCM_RATE_8000_48000
,
97 .buffer_bytes_max
= TW686X_AUDIO_PAGE_MAX
* AUDIO_DMA_SIZE_MAX
,
98 .period_bytes_min
= AUDIO_DMA_SIZE_MIN
,
99 .period_bytes_max
= AUDIO_DMA_SIZE_MAX
,
100 .periods_min
= TW686X_AUDIO_PERIODS_MIN
,
101 .periods_max
= TW686X_AUDIO_PERIODS_MAX
,
104 static int tw686x_pcm_open(struct snd_pcm_substream
*ss
)
106 struct tw686x_dev
*dev
= snd_pcm_substream_chip(ss
);
107 struct tw686x_audio_channel
*ac
= &dev
->audio_channels
[ss
->number
];
108 struct snd_pcm_runtime
*rt
= ss
->runtime
;
112 rt
->hw
= tw686x_capture_hw
;
114 err
= snd_pcm_hw_constraint_integer(rt
, SNDRV_PCM_HW_PARAM_PERIODS
);
121 static int tw686x_pcm_close(struct snd_pcm_substream
*ss
)
123 struct tw686x_dev
*dev
= snd_pcm_substream_chip(ss
);
124 struct tw686x_audio_channel
*ac
= &dev
->audio_channels
[ss
->number
];
130 static int tw686x_pcm_prepare(struct snd_pcm_substream
*ss
)
132 struct tw686x_dev
*dev
= snd_pcm_substream_chip(ss
);
133 struct tw686x_audio_channel
*ac
= &dev
->audio_channels
[ss
->number
];
134 struct snd_pcm_runtime
*rt
= ss
->runtime
;
135 unsigned int period_size
= snd_pcm_lib_period_bytes(ss
);
136 struct tw686x_audio_buf
*p_buf
, *b_buf
;
140 spin_lock_irqsave(&dev
->lock
, flags
);
142 * Given the audio parameters are global (i.e. shared across
143 * DMA channels), we need to check new params are allowed.
145 if (((dev
->audio_rate
!= rt
->rate
) ||
146 (dev
->period_size
!= period_size
)) && dev
->audio_enabled
)
149 tw686x_disable_channel(dev
, AUDIO_CHANNEL_OFFSET
+ ac
->ch
);
150 spin_unlock_irqrestore(&dev
->lock
, flags
);
152 if (dev
->audio_rate
!= rt
->rate
) {
155 dev
->audio_rate
= rt
->rate
;
156 reg
= ((125000000 / rt
->rate
) << 16) +
157 ((125000000 % rt
->rate
) << 16) / rt
->rate
;
159 reg_write(dev
, AUDIO_CONTROL2
, reg
);
162 if (dev
->period_size
!= period_size
) {
165 dev
->period_size
= period_size
;
166 reg
= reg_read(dev
, AUDIO_CONTROL1
);
167 reg
&= ~(AUDIO_DMA_SIZE_MASK
<< AUDIO_DMA_SIZE_SHIFT
);
168 reg
|= period_size
<< AUDIO_DMA_SIZE_SHIFT
;
170 reg_write(dev
, AUDIO_CONTROL1
, reg
);
173 if (rt
->periods
< TW686X_AUDIO_PERIODS_MIN
||
174 rt
->periods
> TW686X_AUDIO_PERIODS_MAX
)
177 spin_lock_irqsave(&ac
->lock
, flags
);
178 INIT_LIST_HEAD(&ac
->buf_list
);
180 for (i
= 0; i
< rt
->periods
; i
++) {
181 ac
->buf
[i
].dma
= rt
->dma_addr
+ period_size
* i
;
182 ac
->buf
[i
].virt
= rt
->dma_area
+ period_size
* i
;
183 INIT_LIST_HEAD(&ac
->buf
[i
].list
);
184 list_add_tail(&ac
->buf
[i
].list
, &ac
->buf_list
);
187 p_buf
= list_first_entry(&ac
->buf_list
, struct tw686x_audio_buf
, list
);
188 list_move_tail(&p_buf
->list
, &ac
->buf_list
);
190 b_buf
= list_first_entry(&ac
->buf_list
, struct tw686x_audio_buf
, list
);
191 list_move_tail(&b_buf
->list
, &ac
->buf_list
);
193 ac
->curr_bufs
[0] = p_buf
;
194 ac
->curr_bufs
[1] = b_buf
;
197 if (dev
->dma_mode
!= TW686X_DMA_MODE_MEMCPY
) {
198 reg_write(dev
, ADMA_P_ADDR
[ac
->ch
], p_buf
->dma
);
199 reg_write(dev
, ADMA_B_ADDR
[ac
->ch
], b_buf
->dma
);
202 spin_unlock_irqrestore(&ac
->lock
, flags
);
207 spin_unlock_irqrestore(&dev
->lock
, flags
);
211 static int tw686x_pcm_trigger(struct snd_pcm_substream
*ss
, int cmd
)
213 struct tw686x_dev
*dev
= snd_pcm_substream_chip(ss
);
214 struct tw686x_audio_channel
*ac
= &dev
->audio_channels
[ss
->number
];
219 case SNDRV_PCM_TRIGGER_START
:
220 if (ac
->curr_bufs
[0] && ac
->curr_bufs
[1]) {
221 spin_lock_irqsave(&dev
->lock
, flags
);
222 dev
->audio_enabled
= 1;
223 tw686x_enable_channel(dev
,
224 AUDIO_CHANNEL_OFFSET
+ ac
->ch
);
225 spin_unlock_irqrestore(&dev
->lock
, flags
);
227 mod_timer(&dev
->dma_delay_timer
,
228 jiffies
+ msecs_to_jiffies(100));
233 case SNDRV_PCM_TRIGGER_STOP
:
234 spin_lock_irqsave(&dev
->lock
, flags
);
235 dev
->audio_enabled
= 0;
236 tw686x_disable_channel(dev
, AUDIO_CHANNEL_OFFSET
+ ac
->ch
);
237 spin_unlock_irqrestore(&dev
->lock
, flags
);
239 spin_lock_irqsave(&ac
->lock
, flags
);
240 ac
->curr_bufs
[0] = NULL
;
241 ac
->curr_bufs
[1] = NULL
;
242 spin_unlock_irqrestore(&ac
->lock
, flags
);
250 static snd_pcm_uframes_t
tw686x_pcm_pointer(struct snd_pcm_substream
*ss
)
252 struct tw686x_dev
*dev
= snd_pcm_substream_chip(ss
);
253 struct tw686x_audio_channel
*ac
= &dev
->audio_channels
[ss
->number
];
255 return bytes_to_frames(ss
->runtime
, ac
->ptr
);
258 static const struct snd_pcm_ops tw686x_pcm_ops
= {
259 .open
= tw686x_pcm_open
,
260 .close
= tw686x_pcm_close
,
261 .prepare
= tw686x_pcm_prepare
,
262 .trigger
= tw686x_pcm_trigger
,
263 .pointer
= tw686x_pcm_pointer
,
266 static int tw686x_snd_pcm_init(struct tw686x_dev
*dev
)
268 struct snd_card
*card
= dev
->snd_card
;
270 struct snd_pcm_substream
*ss
;
274 err
= snd_pcm_new(card
, card
->driver
, 0, 0, max_channels(dev
), &pcm
);
278 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &tw686x_pcm_ops
);
279 snd_pcm_chip(pcm
) = dev
;
281 strscpy(pcm
->name
, "tw686x PCM", sizeof(pcm
->name
));
283 for (i
= 0, ss
= pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
;
284 ss
; ss
= ss
->next
, i
++)
285 snprintf(ss
->name
, sizeof(ss
->name
), "vch%u audio", i
);
287 snd_pcm_set_managed_buffer_all(pcm
,
290 TW686X_AUDIO_PAGE_MAX
* AUDIO_DMA_SIZE_MAX
,
291 TW686X_AUDIO_PAGE_MAX
* AUDIO_DMA_SIZE_MAX
);
295 static void tw686x_audio_dma_free(struct tw686x_dev
*dev
,
296 struct tw686x_audio_channel
*ac
)
300 for (pb
= 0; pb
< 2; pb
++) {
301 if (!ac
->dma_descs
[pb
].virt
)
303 dma_free_coherent(&dev
->pci_dev
->dev
, ac
->dma_descs
[pb
].size
,
304 ac
->dma_descs
[pb
].virt
,
305 ac
->dma_descs
[pb
].phys
);
306 ac
->dma_descs
[pb
].virt
= NULL
;
310 static int tw686x_audio_dma_alloc(struct tw686x_dev
*dev
,
311 struct tw686x_audio_channel
*ac
)
316 * In the memcpy DMA mode we allocate a coherent buffer
317 * and use it for the DMA capture. Otherwise, DMA
318 * acts on the ALSA buffers as received in pcm_prepare.
320 if (dev
->dma_mode
!= TW686X_DMA_MODE_MEMCPY
)
323 for (pb
= 0; pb
< 2; pb
++) {
324 u32 reg
= pb
? ADMA_B_ADDR
[ac
->ch
] : ADMA_P_ADDR
[ac
->ch
];
327 virt
= dma_alloc_coherent(&dev
->pci_dev
->dev
,
329 &ac
->dma_descs
[pb
].phys
, GFP_KERNEL
);
331 dev_err(&dev
->pci_dev
->dev
,
332 "dma%d: unable to allocate audio DMA %s-buffer\n",
333 ac
->ch
, pb
? "B" : "P");
336 ac
->dma_descs
[pb
].virt
= virt
;
337 ac
->dma_descs
[pb
].size
= AUDIO_DMA_SIZE_MAX
;
338 reg_write(dev
, reg
, ac
->dma_descs
[pb
].phys
);
343 void tw686x_audio_free(struct tw686x_dev
*dev
)
349 spin_lock_irqsave(&dev
->lock
, flags
);
350 dma_cmd
= reg_read(dev
, DMA_CMD
);
351 dma_ch_mask
= reg_read(dev
, DMA_CHANNEL_ENABLE
);
352 reg_write(dev
, DMA_CMD
, dma_cmd
& ~0xff00);
353 reg_write(dev
, DMA_CHANNEL_ENABLE
, dma_ch_mask
& ~0xff00);
354 spin_unlock_irqrestore(&dev
->lock
, flags
);
358 snd_card_free(dev
->snd_card
);
359 dev
->snd_card
= NULL
;
362 int tw686x_audio_init(struct tw686x_dev
*dev
)
364 struct pci_dev
*pci_dev
= dev
->pci_dev
;
365 struct snd_card
*card
;
368 /* Enable external audio */
369 reg_write(dev
, AUDIO_CONTROL1
, BIT(0));
371 err
= snd_card_new(&pci_dev
->dev
, SNDRV_DEFAULT_IDX1
,
373 THIS_MODULE
, 0, &card
);
377 dev
->snd_card
= card
;
378 strscpy(card
->driver
, "tw686x", sizeof(card
->driver
));
379 strscpy(card
->shortname
, "tw686x", sizeof(card
->shortname
));
380 strscpy(card
->longname
, pci_name(pci_dev
), sizeof(card
->longname
));
381 snd_card_set_dev(card
, &pci_dev
->dev
);
383 for (ch
= 0; ch
< max_channels(dev
); ch
++) {
384 struct tw686x_audio_channel
*ac
;
386 ac
= &dev
->audio_channels
[ch
];
387 spin_lock_init(&ac
->lock
);
391 err
= tw686x_audio_dma_alloc(dev
, ac
);
396 err
= tw686x_snd_pcm_init(dev
);
400 err
= snd_card_register(card
);
405 for (ch
= 0; ch
< max_channels(dev
); ch
++) {
406 if (!dev
->audio_channels
[ch
].dev
)
408 tw686x_audio_dma_free(dev
, &dev
->audio_channels
[ch
]);
411 dev
->snd_card
= NULL
;