source: GPL/trunk/alsa-kernel/pci/bt87x.c@ 76

Last change on this file since 76 was 76, checked in by vladest, 19 years ago

Latest ALSA patches
HDA patches
Patch for Intel from Rudy's
Fixes locks on NM256 chipsets
Fixes PM on Maestro3 chipsets

File size: 31.5 KB
Line 
1/*
2 * bt87x.c - Brooktree Bt878/Bt879 driver for ALSA
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 * based on btaudio.c by Gerd Knorr <kraxel@bytesex.org>
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29//#include <linux/moduleparam.h>
30#include <linux/bitops.h>
31#include <asm/io.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37
38MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
39MODULE_DESCRIPTION("Brooktree Bt87x audio driver");
40MODULE_LICENSE("GPL");
41MODULE_SUPPORTED_DEVICE("{{Brooktree,Bt878},"
42 "{Brooktree,Bt879}}");
43
44static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
47static int digital_rate[SNDRV_CARDS] = { 0,0,0,0,0,0,0,0 }; /* digital input rate */
48static int load_all; /* allow to load the non-whitelisted cards */
49
50//module_param_array(index, int, NULL, 0444);
51MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
52//module_param_array(id, charp, NULL, 0444);
53MODULE_PARM_DESC(id, "ID string for Bt87x soundcard");
54//module_param_array(enable, bool, NULL, 0444);
55MODULE_PARM_DESC(enable, "Enable Bt87x soundcard");
56//module_param_array(digital_rate, int, NULL, 0444);
57MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard");
58//module_param(load_all, bool, 0444);
59MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
60
61
62#ifndef PCI_VENDOR_ID_BROOKTREE
63#define PCI_VENDOR_ID_BROOKTREE 0x109e
64#endif
65#ifndef PCI_DEVICE_ID_BROOKTREE_878
66#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
67#endif
68#ifndef PCI_DEVICE_ID_BROOKTREE_879
69#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
70#endif
71
72/* register offsets */
73#define REG_INT_STAT 0x100 /* interrupt status */
74#define REG_INT_MASK 0x104 /* interrupt mask */
75#define REG_GPIO_DMA_CTL 0x10c /* audio control */
76#define REG_PACKET_LEN 0x110 /* audio packet lengths */
77#define REG_RISC_STRT_ADD 0x114 /* RISC program start address */
78#define REG_RISC_COUNT 0x120 /* RISC program counter */
79
80/* interrupt bits */
81#define INT_OFLOW (1 << 3) /* audio A/D overflow */
82#define INT_RISCI (1 << 11) /* RISC instruction IRQ bit set */
83#define INT_FBUS (1 << 12) /* FIFO overrun due to bus access latency */
84#define INT_FTRGT (1 << 13) /* FIFO overrun due to target latency */
85#define INT_FDSR (1 << 14) /* FIFO data stream resynchronization */
86#define INT_PPERR (1 << 15) /* PCI parity error */
87#define INT_RIPERR (1 << 16) /* RISC instruction parity error */
88#define INT_PABORT (1 << 17) /* PCI master or target abort */
89#define INT_OCERR (1 << 18) /* invalid opcode */
90#define INT_SCERR (1 << 19) /* sync counter overflow */
91#define INT_RISC_EN (1 << 27) /* DMA controller running */
92#define INT_RISCS_SHIFT 28 /* RISC status bits */
93
94/* audio control bits */
95#define CTL_FIFO_ENABLE (1 << 0) /* enable audio data FIFO */
96#define CTL_RISC_ENABLE (1 << 1) /* enable audio DMA controller */
97#define CTL_PKTP_4 (0 << 2) /* packet mode FIFO trigger point - 4 DWORDs */
98#define CTL_PKTP_8 (1 << 2) /* 8 DWORDs */
99#define CTL_PKTP_16 (2 << 2) /* 16 DWORDs */
100#define CTL_ACAP_EN (1 << 4) /* enable audio capture */
101#define CTL_DA_APP (1 << 5) /* GPIO input */
102#define CTL_DA_IOM_AFE (0 << 6) /* audio A/D input */
103#define CTL_DA_IOM_DA (1 << 6) /* digital audio input */
104#define CTL_DA_SDR_SHIFT 8 /* DDF first stage decimation rate */
105#define CTL_DA_SDR_MASK (0xf<< 8)
106#define CTL_DA_LMT (1 << 12) /* limit audio data values */
107#define CTL_DA_ES2 (1 << 13) /* enable DDF stage 2 */
108#define CTL_DA_SBR (1 << 14) /* samples rounded to 8 bits */
109#define CTL_DA_DPM (1 << 15) /* data packet mode */
110#define CTL_DA_LRD_SHIFT 16 /* ALRCK delay */
111#define CTL_DA_MLB (1 << 21) /* MSB/LSB format */
112#define CTL_DA_LRI (1 << 22) /* left/right indication */
113#define CTL_DA_SCE (1 << 23) /* sample clock edge */
114#define CTL_A_SEL_STV (0 << 24) /* TV tuner audio input */
115#define CTL_A_SEL_SFM (1 << 24) /* FM audio input */
116#define CTL_A_SEL_SML (2 << 24) /* mic/line audio input */
117#define CTL_A_SEL_SMXC (3 << 24) /* MUX bypass */
118#define CTL_A_SEL_SHIFT 24
119#define CTL_A_SEL_MASK (3 << 24)
120#define CTL_A_PWRDN (1 << 26) /* analog audio power-down */
121#define CTL_A_G2X (1 << 27) /* audio gain boost */
122#define CTL_A_GAIN_SHIFT 28 /* audio input gain */
123#define CTL_A_GAIN_MASK (0xf<<28)
124
125/* RISC instruction opcodes */
126#define RISC_WRITE (0x1 << 28) /* write FIFO data to memory at address */
127#define RISC_WRITEC (0x5 << 28) /* write FIFO data to memory at current address */
128#define RISC_SKIP (0x2 << 28) /* skip FIFO data */
129#define RISC_JUMP (0x7 << 28) /* jump to address */
130#define RISC_SYNC (0x8 << 28) /* synchronize with FIFO */
131
132/* RISC instruction bits */
133#define RISC_BYTES_ENABLE (0xf << 12) /* byte enable bits */
134#define RISC_RESYNC ( 1 << 15) /* disable FDSR errors */
135#define RISC_SET_STATUS_SHIFT 16 /* set status bits */
136#define RISC_RESET_STATUS_SHIFT 20 /* clear status bits */
137#define RISC_IRQ ( 1 << 24) /* interrupt */
138#define RISC_EOL ( 1 << 26) /* end of line */
139#define RISC_SOL ( 1 << 27) /* start of line */
140
141/* SYNC status bits values */
142#define RISC_SYNC_FM1 0x6
143#define RISC_SYNC_VRO 0xc
144
145#define ANALOG_CLOCK 1792000
146#ifdef CONFIG_SND_BT87X_OVERCLOCK
147#define CLOCK_DIV_MIN 1
148#else
149#define CLOCK_DIV_MIN 4
150#endif
151#define CLOCK_DIV_MAX 15
152
153#define ERROR_INTERRUPTS (INT_FBUS | INT_FTRGT | INT_PPERR | \
154 INT_RIPERR | INT_PABORT | INT_OCERR)
155#define MY_INTERRUPTS (INT_RISCI | ERROR_INTERRUPTS)
156
157/* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
158#define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8)
159
160typedef struct snd_bt87x bt87x_t;
161struct snd_bt87x {
162 snd_card_t *card;
163 struct pci_dev *pci;
164
165 void *mmio;
166 int irq;
167
168 int dig_rate;
169
170 spinlock_t reg_lock;
171 long opened;
172 snd_pcm_substream_t *substream;
173
174 struct snd_dma_buffer dma_risc;
175 unsigned int line_bytes;
176 unsigned int lines;
177
178 u32 reg_control;
179 u32 interrupt_mask;
180
181 int current_line;
182
183 int pci_parity_errors;
184};
185
186enum { DEVICE_DIGITAL, DEVICE_ANALOG };
187
188static inline u32 snd_bt87x_readl(bt87x_t *chip, u32 reg)
189{
190 return readl((char*)chip->mmio + reg);
191}
192
193static inline void snd_bt87x_writel(bt87x_t *chip, u32 reg, u32 value)
194{
195 writel(value, (char*)chip->mmio + reg);
196}
197
198static int snd_bt87x_create_risc(bt87x_t *chip, snd_pcm_substream_t *substream,
199 unsigned int periods, unsigned int period_bytes)
200{
201 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
202 unsigned int i, offset;
203 u32 *risc;
204
205 if (chip->dma_risc.area == NULL) {
206 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
207 PAGE_ALIGN(MAX_RISC_SIZE), &chip->dma_risc) < 0)
208 return -ENOMEM;
209 }
210 risc = (u32 *)chip->dma_risc.area;
211 offset = 0;
212 *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1);
213 *risc++ = cpu_to_le32(0);
214 for (i = 0; i < periods; ++i) {
215 u32 rest;
216
217 rest = period_bytes;
218 do {
219 u32 cmd, len;
220
221 len = PAGE_SIZE - (offset % PAGE_SIZE);
222 if (len > rest)
223 len = rest;
224 cmd = RISC_WRITE | len;
225 if (rest == period_bytes) {
226 u32 block = i * 16 / periods;
227 cmd |= RISC_SOL;
228 cmd |= block << RISC_SET_STATUS_SHIFT;
229 cmd |= (~block & 0xf) << RISC_RESET_STATUS_SHIFT;
230 }
231 if (len == rest)
232 cmd |= RISC_EOL | RISC_IRQ;
233 *risc++ = cpu_to_le32(cmd);
234 *risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset));
235 offset += len;
236 rest -= len;
237 } while (rest > 0);
238 }
239 *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_VRO);
240 *risc++ = cpu_to_le32(0);
241 *risc++ = cpu_to_le32(RISC_JUMP);
242 *risc++ = cpu_to_le32(chip->dma_risc.addr);
243 chip->line_bytes = period_bytes;
244 chip->lines = periods;
245 return 0;
246}
247
248static void snd_bt87x_free_risc(bt87x_t *chip)
249{
250 if (chip->dma_risc.area) {
251 snd_dma_free_pages(&chip->dma_risc);
252 chip->dma_risc.area = NULL;
253 }
254}
255
256static void snd_bt87x_pci_error(bt87x_t *chip, unsigned int status)
257{
258 u16 pci_status;
259
260 pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
261 pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
262 PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
263 PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
264 pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
265 if (pci_status != PCI_STATUS_DETECTED_PARITY)
266 snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
267 status & ERROR_INTERRUPTS, pci_status);
268 else {
269 snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n");
270 /* error 'handling' similar to aic7xxx_pci.c: */
271 chip->pci_parity_errors++;
272 if (chip->pci_parity_errors > 20) {
273 snd_printk(KERN_ERR "Too many PCI parity errors observed.\n");
274 snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n");
275 snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n");
276 snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n");
277 chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR);
278 snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
279 }
280 }
281}
282
283static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
284{
285 bt87x_t *chip = dev_id;
286 unsigned int status, irq_status;
287
288 status = snd_bt87x_readl(chip, REG_INT_STAT);
289 irq_status = status & chip->interrupt_mask;
290 if (!irq_status)
291 return IRQ_NONE;
292 snd_bt87x_writel(chip, REG_INT_STAT, irq_status);
293
294 if (irq_status & ERROR_INTERRUPTS) {
295 if (irq_status & (INT_FBUS | INT_FTRGT))
296 snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status);
297 if (irq_status & INT_OCERR)
298 snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status);
299 if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT))
300 snd_bt87x_pci_error(chip, irq_status);
301 }
302 if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
303 int current_block, irq_block;
304
305 /* assume that exactly one line has been recorded */
306 chip->current_line = (chip->current_line + 1) % chip->lines;
307 /* but check if some interrupts have been skipped */
308 current_block = chip->current_line * 16 / chip->lines;
309 irq_block = status >> INT_RISCS_SHIFT;
310 if (current_block != irq_block)
311 chip->current_line = (irq_block * chip->lines + 15) / 16;
312
313 snd_pcm_period_elapsed(chip->substream);
314 }
315#ifdef TARGET_OS2
316 eoi_irq(irq);
317#endif //TARGET_OS2
318
319 return IRQ_HANDLED;
320}
321
322static snd_pcm_hardware_t snd_bt87x_digital_hw = {
323 /*.info = */SNDRV_PCM_INFO_MMAP |
324 SNDRV_PCM_INFO_INTERLEAVED |
325 SNDRV_PCM_INFO_BLOCK_TRANSFER |
326 SNDRV_PCM_INFO_MMAP_VALID,
327 /* .formats = */SNDRV_PCM_FMTBIT_S16_LE,
328 /* .rates = */0, /* set at runtime */
329 0,0,
330 /* .channels_min = */2,
331 /* .channels_max = */2,
332 /* .buffer_bytes_max = */255 * 4092,
333 /* .period_bytes_min = */32,
334 /* .period_bytes_max = */4092,
335 /* .periods_min = */2,
336 /* .periods_max = */255,
337 0
338};
339
340static snd_pcm_hardware_t snd_bt87x_analog_hw = {
341 /*.info = */SNDRV_PCM_INFO_MMAP |
342 SNDRV_PCM_INFO_INTERLEAVED |
343 SNDRV_PCM_INFO_BLOCK_TRANSFER |
344 SNDRV_PCM_INFO_MMAP_VALID,
345 /* .formats = */SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
346 /* .rates = */SNDRV_PCM_RATE_KNOT,
347 /* .rate_min = */ANALOG_CLOCK / CLOCK_DIV_MAX,
348 /* .rate_max = */ANALOG_CLOCK / CLOCK_DIV_MIN,
349 /* .channels_min = */1,
350 /* .channels_max = */1,
351 /* .buffer_bytes_max = */255 * 4092,
352 /* .period_bytes_min = */32,
353 /* .period_bytes_max = */4092,
354 /* .periods_min = */2,
355 /* .periods_max = */255,
356 0
357};
358
359static int snd_bt87x_set_digital_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
360{
361 static struct {
362 int rate;
363 unsigned int bit;
364 } ratebits[] = {
365 {8000, SNDRV_PCM_RATE_8000},
366 {11025, SNDRV_PCM_RATE_11025},
367 {16000, SNDRV_PCM_RATE_16000},
368 {22050, SNDRV_PCM_RATE_22050},
369 {32000, SNDRV_PCM_RATE_32000},
370 {44100, SNDRV_PCM_RATE_44100},
371 {48000, SNDRV_PCM_RATE_48000}
372 };
373 int i;
374
375 chip->reg_control |= CTL_DA_IOM_DA;
376 runtime->hw = snd_bt87x_digital_hw;
377 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
378 for (i = 0; i < ARRAY_SIZE(ratebits); ++i)
379 if (chip->dig_rate == ratebits[i].rate) {
380 runtime->hw.rates = ratebits[i].bit;
381 break;
382 }
383 runtime->hw.rate_min = chip->dig_rate;
384 runtime->hw.rate_max = chip->dig_rate;
385 return 0;
386}
387
388static int snd_bt87x_set_analog_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
389{
390 static ratnum_t analog_clock = {
391 /*.num = */ANALOG_CLOCK,
392 /*.den_min = */CLOCK_DIV_MIN,
393 /*.den_max = */CLOCK_DIV_MAX,
394 /*.den_step = */1
395 };
396 static snd_pcm_hw_constraint_ratnums_t constraint_rates = {
397 /*.nrats = */1,
398 /*.rats = */&analog_clock
399 };
400
401 chip->reg_control &= ~CTL_DA_IOM_DA;
402 runtime->hw = snd_bt87x_analog_hw;
403 return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
404 &constraint_rates);
405}
406
407static int snd_bt87x_pcm_open(snd_pcm_substream_t *substream)
408{
409 bt87x_t *chip = snd_pcm_substream_chip(substream);
410 snd_pcm_runtime_t *runtime = substream->runtime;
411 int err;
412
413 if (test_and_set_bit(0, &chip->opened))
414 return -EBUSY;
415
416 if (substream->pcm->device == DEVICE_DIGITAL)
417 err = snd_bt87x_set_digital_hw(chip, runtime);
418 else
419 err = snd_bt87x_set_analog_hw(chip, runtime);
420 if (err < 0)
421 goto _error;
422
423 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
424 if (err < 0)
425 goto _error;
426
427 chip->substream = substream;
428 return 0;
429
430_error:
431 clear_bit(0, &chip->opened);
432#ifndef TARGET_OS2
433 smp_mb__after_clear_bit();
434#endif
435 return err;
436}
437
438static int snd_bt87x_close(snd_pcm_substream_t *substream)
439{
440 bt87x_t *chip = snd_pcm_substream_chip(substream);
441
442 chip->substream = NULL;
443 clear_bit(0, &chip->opened);
444#ifndef TARGET_OS2
445 smp_mb__after_clear_bit();
446#endif
447 return 0;
448}
449
450static int snd_bt87x_hw_params(snd_pcm_substream_t *substream,
451 snd_pcm_hw_params_t *hw_params)
452{
453 bt87x_t *chip = snd_pcm_substream_chip(substream);
454 int err;
455
456 err = snd_pcm_lib_malloc_pages(substream,
457 params_buffer_bytes(hw_params));
458 if (err < 0)
459 return err;
460 return snd_bt87x_create_risc(chip, substream,
461 params_periods(hw_params),
462 params_period_bytes(hw_params));
463}
464
465static int snd_bt87x_hw_free(snd_pcm_substream_t *substream)
466{
467 bt87x_t *chip = snd_pcm_substream_chip(substream);
468
469 snd_bt87x_free_risc(chip);
470 snd_pcm_lib_free_pages(substream);
471 return 0;
472}
473
474static int snd_bt87x_prepare(snd_pcm_substream_t *substream)
475{
476 bt87x_t *chip = snd_pcm_substream_chip(substream);
477 snd_pcm_runtime_t *runtime = substream->runtime;
478 int decimation;
479
480 spin_lock_irq(&chip->reg_lock);
481 chip->reg_control &= ~(CTL_DA_SDR_MASK | CTL_DA_SBR);
482 decimation = (ANALOG_CLOCK + runtime->rate / 4) / runtime->rate;
483 chip->reg_control |= decimation << CTL_DA_SDR_SHIFT;
484 if (runtime->format == SNDRV_PCM_FORMAT_S8)
485 chip->reg_control |= CTL_DA_SBR;
486 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
487 spin_unlock_irq(&chip->reg_lock);
488 return 0;
489}
490
491static int snd_bt87x_start(bt87x_t *chip)
492{
493 spin_lock(&chip->reg_lock);
494 chip->current_line = 0;
495 chip->reg_control |= CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN;
496 snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr);
497 snd_bt87x_writel(chip, REG_PACKET_LEN,
498 chip->line_bytes | (chip->lines << 16));
499 snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
500 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
501 spin_unlock(&chip->reg_lock);
502 return 0;
503}
504
505static int snd_bt87x_stop(bt87x_t *chip)
506{
507 spin_lock(&chip->reg_lock);
508 chip->reg_control &= ~(CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN);
509 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
510 snd_bt87x_writel(chip, REG_INT_MASK, 0);
511 snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
512 spin_unlock(&chip->reg_lock);
513 return 0;
514}
515
516static int snd_bt87x_trigger(snd_pcm_substream_t *substream, int cmd)
517{
518 bt87x_t *chip = snd_pcm_substream_chip(substream);
519
520 switch (cmd) {
521 case SNDRV_PCM_TRIGGER_START:
522 return snd_bt87x_start(chip);
523 case SNDRV_PCM_TRIGGER_STOP:
524 return snd_bt87x_stop(chip);
525 default:
526 return -EINVAL;
527 }
528}
529
530static snd_pcm_uframes_t snd_bt87x_pointer(snd_pcm_substream_t *substream)
531{
532 bt87x_t *chip = snd_pcm_substream_chip(substream);
533 snd_pcm_runtime_t *runtime = substream->runtime;
534
535 return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
536}
537
538static snd_pcm_ops_t snd_bt87x_pcm_ops = {
539 /*.open = */snd_bt87x_pcm_open,
540 /*.close = */snd_bt87x_close,
541 /*.ioctl = */snd_pcm_lib_ioctl,
542 /*.hw_params = */snd_bt87x_hw_params,
543 /*.hw_free = */snd_bt87x_hw_free,
544 /*.prepare = */snd_bt87x_prepare,
545 /*.trigger = */snd_bt87x_trigger,
546 /*.pointer = */snd_bt87x_pointer,0,0,
547 /*.page = */snd_pcm_sgbuf_ops_page,0
548};
549
550static int snd_bt87x_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
551{
552 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
553 info->count = 1;
554 info->value.integer.min = 0;
555 info->value.integer.max = 15;
556 return 0;
557}
558
559static int snd_bt87x_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
560{
561 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
562
563 value->value.integer.value[0] = (chip->reg_control & CTL_A_GAIN_MASK) >> CTL_A_GAIN_SHIFT;
564 return 0;
565}
566
567static int snd_bt87x_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
568{
569 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
570 u32 old_control;
571 int changed;
572
573 spin_lock_irq(&chip->reg_lock);
574 old_control = chip->reg_control;
575 chip->reg_control = (chip->reg_control & ~CTL_A_GAIN_MASK)
576 | (value->value.integer.value[0] << CTL_A_GAIN_SHIFT);
577 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
578 changed = old_control != chip->reg_control;
579 spin_unlock_irq(&chip->reg_lock);
580 return changed;
581}
582
583static snd_kcontrol_new_t snd_bt87x_capture_volume = {
584 /*.iface = */SNDRV_CTL_ELEM_IFACE_MIXER,0,0,
585 /*.name = */"Capture Volume",0,0,0,
586 /*.info = */snd_bt87x_capture_volume_info,
587 /*.get = */snd_bt87x_capture_volume_get,
588 /*.put = */snd_bt87x_capture_volume_put,0
589};
590
591static int snd_bt87x_capture_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
592{
593 info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
594 info->count = 1;
595 info->value.integer.min = 0;
596 info->value.integer.max = 1;
597 return 0;
598}
599
600static int snd_bt87x_capture_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
601{
602 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
603
604 value->value.integer.value[0] = !! (chip->reg_control & CTL_A_G2X);
605 return 0;
606}
607
608static int snd_bt87x_capture_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
609{
610 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
611 u32 old_control;
612 int changed;
613
614 spin_lock_irq(&chip->reg_lock);
615 old_control = chip->reg_control;
616 chip->reg_control = (chip->reg_control & ~CTL_A_G2X)
617 | (value->value.integer.value[0] ? CTL_A_G2X : 0);
618 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
619 changed = chip->reg_control != old_control;
620 spin_unlock_irq(&chip->reg_lock);
621 return changed;
622}
623
624static snd_kcontrol_new_t snd_bt87x_capture_boost = {
625 /*.iface = */SNDRV_CTL_ELEM_IFACE_MIXER,0,0,
626 /*.name = */"Capture Boost",0,0,0,
627 /*.info = */snd_bt87x_capture_boost_info,
628 /*.get = */snd_bt87x_capture_boost_get,
629 /*.put = */snd_bt87x_capture_boost_put,0
630};
631
632static int snd_bt87x_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
633{
634 static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"};
635
636 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
637 info->count = 1;
638 info->value.enumerated.items = 3;
639 if (info->value.enumerated.item > 2)
640 info->value.enumerated.item = 2;
641 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
642 return 0;
643}
644
645static int snd_bt87x_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
646{
647 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
648
649 value->value.enumerated.item[0] = (chip->reg_control & CTL_A_SEL_MASK) >> CTL_A_SEL_SHIFT;
650 return 0;
651}
652
653static int snd_bt87x_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
654{
655 bt87x_t *chip = snd_kcontrol_chip(kcontrol);
656 u32 old_control;
657 int changed;
658
659 spin_lock_irq(&chip->reg_lock);
660 old_control = chip->reg_control;
661 chip->reg_control = (chip->reg_control & ~CTL_A_SEL_MASK)
662 | (value->value.enumerated.item[0] << CTL_A_SEL_SHIFT);
663 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
664 changed = chip->reg_control != old_control;
665 spin_unlock_irq(&chip->reg_lock);
666 return changed;
667}
668
669static snd_kcontrol_new_t snd_bt87x_capture_source = {
670 /*.iface =*/ SNDRV_CTL_ELEM_IFACE_MIXER,0,0,
671 /*.name = */"Capture Source",0,0,0,
672 /*.info = */snd_bt87x_capture_source_info,
673 /*.get = */snd_bt87x_capture_source_get,
674 /*.put = */snd_bt87x_capture_source_put,0
675};
676
677static int snd_bt87x_free(bt87x_t *chip)
678{
679 if (chip->mmio) {
680 snd_bt87x_stop(chip);
681 if (chip->irq >= 0)
682 synchronize_irq(chip->irq);
683
684 iounmap(chip->mmio);
685 }
686 if (chip->irq >= 0)
687 free_irq(chip->irq, chip);
688 pci_release_regions(chip->pci);
689 pci_disable_device(chip->pci);
690 kfree(chip);
691 return 0;
692}
693
694static int snd_bt87x_dev_free(snd_device_t *device)
695{
696 bt87x_t *chip = device->device_data;
697 return snd_bt87x_free(chip);
698}
699
700static int __devinit snd_bt87x_pcm(bt87x_t *chip, int device, char *name)
701{
702 int err;
703 snd_pcm_t *pcm;
704
705 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
706 if (err < 0)
707 return err;
708 pcm->private_data = chip;
709 strcpy(pcm->name, name);
710 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_bt87x_pcm_ops);
711 return snd_pcm_lib_preallocate_pages_for_all(pcm,
712 SNDRV_DMA_TYPE_DEV_SG,
713 snd_dma_pci_data(chip->pci),
714 128 * 1024,
715 (255 * 4092 + 1023) & ~1023);
716}
717
718static int __devinit snd_bt87x_create(snd_card_t *card,
719 struct pci_dev *pci,
720 bt87x_t **rchip)
721{
722 bt87x_t *chip;
723 int err;
724 static snd_device_ops_t ops = {
725 /*.dev_free = */snd_bt87x_dev_free,0,0,0
726 };
727
728 *rchip = NULL;
729
730 err = pci_enable_device(pci);
731 if (err < 0)
732 return err;
733
734 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
735 if (!chip) {
736 pci_disable_device(pci);
737 return -ENOMEM;
738 }
739 chip->card = card;
740 chip->pci = pci;
741 chip->irq = -1;
742 spin_lock_init(&chip->reg_lock);
743
744 if ((err = pci_request_regions(pci, "Bt87x audio")) < 0) {
745 kfree(chip);
746 pci_disable_device(pci);
747 return err;
748 }
749 chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
750 pci_resource_len(pci, 0));
751 if (!chip->mmio) {
752 snd_bt87x_free(chip);
753 snd_printk(KERN_ERR "cannot remap io memory\n");
754 return -ENOMEM;
755 }
756
757 chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
758 chip->interrupt_mask = MY_INTERRUPTS;
759 snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
760 snd_bt87x_writel(chip, REG_INT_MASK, 0);
761 snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
762
763 if (request_irq(pci->irq, snd_bt87x_interrupt, SA_INTERRUPT | SA_SHIRQ,
764 "Bt87x audio", chip)) {
765 snd_bt87x_free(chip);
766 snd_printk(KERN_ERR "cannot grab irq\n");
767 return -EBUSY;
768 }
769 chip->irq = pci->irq;
770 pci_set_master(pci);
771 synchronize_irq(chip->irq);
772
773 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
774 if (err < 0) {
775 snd_bt87x_free(chip);
776 return err;
777 }
778 snd_card_set_dev(card, &pci->dev);
779 *rchip = chip;
780 return 0;
781}
782
783#define BT_DEVICE(chip, subvend, subdev, rate) \
784 { PCI_VENDOR_ID_BROOKTREE, \
785 PCI_DEVICE_ID_BROOKTREE_##chip, \
786 subvend, subdev, 0,0,\
787 rate }
788
789/* driver_data is the default digital_rate value for that device */
790static struct pci_device_id snd_bt87x_ids[] = {
791 BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
792 BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
793 BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
794 /* AVerMedia Studio No. 103, 203, ...? */
795 BT_DEVICE(878, 0x1461, 0x0003, 48000),
796 /* Leadtek Winfast tv 2000xp delux */
797 BT_DEVICE(878, 0x107d, 0x6606, 32000),
798 {0}
799};
800MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
801
802/* cards known not to have audio
803 * (DVB cards use the audio function to transfer MPEG data) */
804static struct {
805 unsigned short subvendor, subdevice;
806} blacklist[] __devinitdata = {
807 {0x0071, 0x0101}, /* Nebula Electronics DigiTV */
808 {0x11bd, 0x001c}, /* Pinnacle PCTV Sat */
809 {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
810 {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */
811 {0x1461, 0x0771}, /* AVermedia DVB-T 771 */
812 {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */
813 {0x18ac, 0xd500}, /* DVICO FusionHDTV 5 Lite */
814 {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */
815 {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
816 {0x7063, 0x2000}, /* pcHDTV HD-2000 TV */
817};
818
819/* return the rate of the card, or a negative value if it's blacklisted */
820static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
821{
822 int i;
823 const struct pci_device_id *supported;
824
825 supported = pci_match_device(snd_bt87x_ids, pci);
826 if (supported && supported->driver_data > 0)
827 return supported->driver_data;
828
829 for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
830 if (blacklist[i].subvendor == pci->subsystem_vendor &&
831 blacklist[i].subdevice == pci->subsystem_device) {
832 snd_printdd(KERN_INFO "card %#04x-%#04x:%#04x has no audio\n",
833 pci->device, pci->subsystem_vendor, pci->subsystem_device);
834 return -EBUSY;
835 }
836
837 snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default rate 32000\n",
838 pci->device, pci->subsystem_vendor, pci->subsystem_device);
839 snd_printk(KERN_DEBUG "please mail id, board name, and, "
840 "if it works, the correct digital_rate option to "
841 "<alsa-devel@lists.sf.net>\n");
842 return 32000; /* default rate */
843}
844
845static int __devinit snd_bt87x_probe(struct pci_dev *pci,
846 const struct pci_device_id *pci_id)
847{
848 static int dev;
849 snd_card_t *card;
850 bt87x_t *chip;
851 int err, rate;
852
853 rate = pci_id->driver_data;
854 if (! rate)
855 if ((rate = snd_bt87x_detect_card(pci)) <= 0)
856 return -ENODEV;
857
858 if (dev >= SNDRV_CARDS)
859 return -ENODEV;
860 if (!enable[dev]) {
861 ++dev;
862 return -ENOENT;
863 }
864
865 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
866 if (!card)
867 return -ENOMEM;
868
869 err = snd_bt87x_create(card, pci, &chip);
870 if (err < 0)
871 goto _error;
872
873 if (digital_rate[dev] > 0)
874 chip->dig_rate = digital_rate[dev];
875 else
876 chip->dig_rate = rate;
877
878 err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
879 if (err < 0)
880 goto _error;
881 err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
882 if (err < 0)
883 goto _error;
884
885 err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip));
886 if (err < 0)
887 goto _error;
888 err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip));
889 if (err < 0)
890 goto _error;
891 err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip));
892 if (err < 0)
893 goto _error;
894
895 strcpy(card->driver, "Bt87x");
896 sprintf(card->shortname, "Brooktree Bt%x", pci->device);
897 sprintf(card->longname, "%s at %#lx, irq %i",
898 card->shortname, pci_resource_start(pci, 0), chip->irq);
899 strcpy(card->mixername, "Bt87x");
900
901 err = snd_card_register(card);
902 if (err < 0)
903 goto _error;
904
905 pci_set_drvdata(pci, card);
906 ++dev;
907 return 0;
908
909_error:
910 snd_card_free(card);
911 return err;
912}
913
914static void __devexit snd_bt87x_remove(struct pci_dev *pci)
915{
916 snd_card_free(pci_get_drvdata(pci));
917 pci_set_drvdata(pci, NULL);
918}
919
920/* default entries for all Bt87x cards - it's not exported */
921/* driver_data is set to 0 to call detection */
922static struct pci_device_id snd_bt87x_default_ids[] = {
923 BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0),
924 BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0),
925 {0}
926};
927
928static struct pci_driver driver = {
929 0,0,0,
930 /*.name =*/ "Bt87x",
931 /*.id_table = */snd_bt87x_ids,
932 /*.probe = */snd_bt87x_probe,
933 /*.remove = */snd_bt87x_remove,
934 0,0
935};
936
937static int __init alsa_card_bt87x_init(void)
938{
939 if (load_all)
940 driver.id_table = snd_bt87x_default_ids;
941 return pci_module_init(&driver);
942}
943
944static void __exit alsa_card_bt87x_exit(void)
945{
946 pci_unregister_driver(&driver);
947}
948
949module_init(alsa_card_bt87x_init)
950module_exit(alsa_card_bt87x_exit)
Note: See TracBrowser for help on using the repository browser.