aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/ad1848
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2008-07-31 15:09:32 -0400
committerJaroslav Kysela <perex@perex.cz>2008-08-06 09:39:56 -0400
commitead893c0deeec165524cc8a06e7e739d7d84b4c4 (patch)
tree86881775a9f4e7052eded95747fd8854d043fdda /sound/isa/ad1848
parent5664daa1c1fa250dd7f6b336278b0402638e8edc (diff)
ALSA: wss_lib: use wss pcm code instead of ad1848 one
Use the wss pcm code and kill the ad1848 pcm code. The AD1848 chip is much slower than CS4231 chips so the waiting loop was increased 100x (10x is not enough). Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Reviewed-by: Rene Herman <rene.herman@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/isa/ad1848')
-rw-r--r--sound/isa/ad1848/ad1848.c2
-rw-r--r--sound/isa/ad1848/ad1848_lib.c544
2 files changed, 11 insertions, 535 deletions
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index d5a96631587c..17970c2f27e7 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -102,7 +102,7 @@ static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
102 102
103 card->private_data = chip; 103 card->private_data = chip;
104 104
105 error = snd_ad1848_pcm(chip, 0, &pcm); 105 error = snd_wss_pcm(chip, 0, &pcm);
106 if (error < 0) 106 if (error < 0)
107 goto out; 107 goto out;
108 108
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 5de046014337..aa803d38a8ad 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -46,34 +46,6 @@ MODULE_LICENSE("GPL");
46 * Some variables 46 * Some variables
47 */ 47 */
48 48
49static unsigned char freq_bits[14] = {
50 /* 5510 */ 0x00 | AD1848_XTAL2,
51 /* 6620 */ 0x0E | AD1848_XTAL2,
52 /* 8000 */ 0x00 | AD1848_XTAL1,
53 /* 9600 */ 0x0E | AD1848_XTAL1,
54 /* 11025 */ 0x02 | AD1848_XTAL2,
55 /* 16000 */ 0x02 | AD1848_XTAL1,
56 /* 18900 */ 0x04 | AD1848_XTAL2,
57 /* 22050 */ 0x06 | AD1848_XTAL2,
58 /* 27042 */ 0x04 | AD1848_XTAL1,
59 /* 32000 */ 0x06 | AD1848_XTAL1,
60 /* 33075 */ 0x0C | AD1848_XTAL2,
61 /* 37800 */ 0x08 | AD1848_XTAL2,
62 /* 44100 */ 0x0A | AD1848_XTAL2,
63 /* 48000 */ 0x0C | AD1848_XTAL1
64};
65
66static unsigned int rates[14] = {
67 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
68 27042, 32000, 33075, 37800, 44100, 48000
69};
70
71static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
72 .count = ARRAY_SIZE(rates),
73 .list = rates,
74 .mask = 0,
75};
76
77static unsigned char snd_ad1848_original_image[16] = 49static unsigned char snd_ad1848_original_image[16] =
78{ 50{
79 0x00, /* 00 - lic */ 51 0x00, /* 00 - lic */
@@ -128,15 +100,6 @@ void snd_ad1848_out(struct snd_wss *chip,
128 100
129EXPORT_SYMBOL(snd_ad1848_out); 101EXPORT_SYMBOL(snd_ad1848_out);
130 102
131static void snd_ad1848_dout(struct snd_wss *chip,
132 unsigned char reg, unsigned char value)
133{
134 snd_ad1848_wait(chip);
135 outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL));
136 outb(value, chip->port + CS4231P(REG));
137 mb();
138}
139
140static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg) 103static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg)
141{ 104{
142 snd_ad1848_wait(chip); 105 snd_ad1848_wait(chip);
@@ -261,315 +224,6 @@ static void snd_ad1848_mce_down(struct snd_wss *chip)
261 inb(chip->port + CS4231P(REGSEL))); 224 inb(chip->port + CS4231P(REGSEL)));
262} 225}
263 226
264static unsigned int snd_ad1848_get_count(unsigned char format,
265 unsigned int size)
266{
267 switch (format & 0xe0) {
268 case AD1848_LINEAR_16:
269 size >>= 1;
270 break;
271 }
272 if (format & AD1848_STEREO)
273 size >>= 1;
274 return size;
275}
276
277static int snd_ad1848_trigger(struct snd_wss *chip, unsigned char what,
278 int channel, int cmd)
279{
280 int result = 0;
281
282#if 0
283 printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(AD1848P(card, STATUS)));
284#endif
285 spin_lock(&chip->reg_lock);
286 if (cmd == SNDRV_PCM_TRIGGER_START) {
287 if (chip->image[AD1848_IFACE_CTRL] & what) {
288 spin_unlock(&chip->reg_lock);
289 return 0;
290 }
291 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what);
292 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
293 if (!(chip->image[AD1848_IFACE_CTRL] & what)) {
294 spin_unlock(&chip->reg_lock);
295 return 0;
296 }
297 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what);
298 } else {
299 result = -EINVAL;
300 }
301 spin_unlock(&chip->reg_lock);
302 return result;
303}
304
305/*
306 * CODEC I/O
307 */
308
309static unsigned char snd_ad1848_get_rate(unsigned int rate)
310{
311 int i;
312
313 for (i = 0; i < ARRAY_SIZE(rates); i++)
314 if (rate == rates[i])
315 return freq_bits[i];
316 snd_BUG();
317 return freq_bits[ARRAY_SIZE(rates) - 1];
318}
319
320static int snd_ad1848_ioctl(struct snd_pcm_substream *substream,
321 unsigned int cmd, void *arg)
322{
323 return snd_pcm_lib_ioctl(substream, cmd, arg);
324}
325
326static unsigned char snd_ad1848_get_format(int format, int channels)
327{
328 unsigned char rformat;
329
330 rformat = AD1848_LINEAR_8;
331 switch (format) {
332 case SNDRV_PCM_FORMAT_A_LAW: rformat = AD1848_ALAW_8; break;
333 case SNDRV_PCM_FORMAT_MU_LAW: rformat = AD1848_ULAW_8; break;
334 case SNDRV_PCM_FORMAT_S16_LE: rformat = AD1848_LINEAR_16; break;
335 }
336 if (channels > 1)
337 rformat |= AD1848_STEREO;
338#if 0
339 snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
340#endif
341 return rformat;
342}
343
344static void snd_ad1848_calibrate_mute(struct snd_wss *chip, int mute)
345{
346 unsigned long flags;
347
348 mute = mute ? 1 : 0;
349 spin_lock_irqsave(&chip->reg_lock, flags);
350 if (chip->calibrate_mute == mute) {
351 spin_unlock_irqrestore(&chip->reg_lock, flags);
352 return;
353 }
354 if (!mute) {
355 snd_ad1848_dout(chip, AD1848_LEFT_INPUT, chip->image[AD1848_LEFT_INPUT]);
356 snd_ad1848_dout(chip, AD1848_RIGHT_INPUT, chip->image[AD1848_RIGHT_INPUT]);
357 }
358 snd_ad1848_dout(chip, AD1848_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_LEFT_INPUT]);
359 snd_ad1848_dout(chip, AD1848_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_RIGHT_INPUT]);
360 snd_ad1848_dout(chip, AD1848_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_LEFT_INPUT]);
361 snd_ad1848_dout(chip, AD1848_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_RIGHT_INPUT]);
362 snd_ad1848_dout(chip, AD1848_LEFT_OUTPUT, mute ? 0x80 : chip->image[AD1848_LEFT_OUTPUT]);
363 snd_ad1848_dout(chip, AD1848_RIGHT_OUTPUT, mute ? 0x80 : chip->image[AD1848_RIGHT_OUTPUT]);
364 chip->calibrate_mute = mute;
365 spin_unlock_irqrestore(&chip->reg_lock, flags);
366}
367
368static void snd_ad1848_set_data_format(struct snd_wss *chip,
369 struct snd_pcm_hw_params *hw_params)
370{
371 if (hw_params == NULL) {
372 chip->image[AD1848_DATA_FORMAT] = 0x20;
373 } else {
374 chip->image[AD1848_DATA_FORMAT] =
375 snd_ad1848_get_format(params_format(hw_params), params_channels(hw_params)) |
376 snd_ad1848_get_rate(params_rate(hw_params));
377 }
378 // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]);
379}
380
381static int snd_ad1848_open(struct snd_wss *chip, unsigned int mode)
382{
383 unsigned long flags;
384
385 if (chip->mode & WSS_MODE_OPEN)
386 return -EAGAIN;
387
388 snd_ad1848_mce_down(chip);
389
390#ifdef SNDRV_DEBUG_MCE
391 snd_printk("open: (1)\n");
392#endif
393 snd_ad1848_mce_up(chip);
394 spin_lock_irqsave(&chip->reg_lock, flags);
395 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
396 AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO |
397 AD1848_CALIB_MODE);
398 chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB;
399 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
400 spin_unlock_irqrestore(&chip->reg_lock, flags);
401 snd_ad1848_mce_down(chip);
402
403#ifdef SNDRV_DEBUG_MCE
404 snd_printk("open: (2)\n");
405#endif
406
407 snd_ad1848_set_data_format(chip, NULL);
408
409 snd_ad1848_mce_up(chip);
410 spin_lock_irqsave(&chip->reg_lock, flags);
411 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
412 spin_unlock_irqrestore(&chip->reg_lock, flags);
413 snd_ad1848_mce_down(chip);
414
415#ifdef SNDRV_DEBUG_MCE
416 snd_printk("open: (3)\n");
417#endif
418
419 /* ok. now enable and ack CODEC IRQ */
420 spin_lock_irqsave(&chip->reg_lock, flags);
421 outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */
422 outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */
423 chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE;
424 snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
425 spin_unlock_irqrestore(&chip->reg_lock, flags);
426
427 chip->mode = mode;
428
429 return 0;
430}
431
432static void snd_ad1848_close(struct snd_wss *chip)
433{
434 unsigned long flags;
435
436 if (!chip->mode)
437 return;
438 /* disable IRQ */
439 spin_lock_irqsave(&chip->reg_lock, flags);
440 outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */
441 outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */
442 chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE;
443 snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
444 spin_unlock_irqrestore(&chip->reg_lock, flags);
445
446 /* now disable capture & playback */
447
448 snd_ad1848_mce_up(chip);
449 spin_lock_irqsave(&chip->reg_lock, flags);
450 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
451 AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
452 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
453 spin_unlock_irqrestore(&chip->reg_lock, flags);
454 snd_ad1848_mce_down(chip);
455
456 /* clear IRQ again */
457 spin_lock_irqsave(&chip->reg_lock, flags);
458 outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */
459 outb(0, chip->port + CS4231P(STATUS)); /* clear IRQ */
460 spin_unlock_irqrestore(&chip->reg_lock, flags);
461
462 chip->mode = 0;
463}
464
465/*
466 * ok.. exported functions..
467 */
468
469static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream,
470 int cmd)
471{
472 struct snd_wss *chip = snd_pcm_substream_chip(substream);
473 return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd);
474}
475
476static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream,
477 int cmd)
478{
479 struct snd_wss *chip = snd_pcm_substream_chip(substream);
480 return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd);
481}
482
483static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream,
484 struct snd_pcm_hw_params *hw_params)
485{
486 struct snd_wss *chip = snd_pcm_substream_chip(substream);
487 unsigned long flags;
488 int err;
489
490 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
491 return err;
492 snd_ad1848_calibrate_mute(chip, 1);
493 snd_ad1848_set_data_format(chip, hw_params);
494 snd_ad1848_mce_up(chip);
495 spin_lock_irqsave(&chip->reg_lock, flags);
496 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
497 spin_unlock_irqrestore(&chip->reg_lock, flags);
498 snd_ad1848_mce_down(chip);
499 snd_ad1848_calibrate_mute(chip, 0);
500 return 0;
501}
502
503static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream)
504{
505 return snd_pcm_lib_free_pages(substream);
506}
507
508static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream)
509{
510 struct snd_wss *chip = snd_pcm_substream_chip(substream);
511 struct snd_pcm_runtime *runtime = substream->runtime;
512 unsigned long flags;
513 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
514 unsigned int count = snd_pcm_lib_period_bytes(substream);
515
516 chip->p_dma_size = size;
517 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO);
518 snd_dma_program(chip->dma1, runtime->dma_addr, size,
519 DMA_MODE_WRITE | DMA_AUTOINIT);
520 count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
521 spin_lock_irqsave(&chip->reg_lock, flags);
522 snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
523 snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
524 spin_unlock_irqrestore(&chip->reg_lock, flags);
525 return 0;
526}
527
528static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream,
529 struct snd_pcm_hw_params *hw_params)
530{
531 struct snd_wss *chip = snd_pcm_substream_chip(substream);
532 unsigned long flags;
533 int err;
534
535 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
536 return err;
537 snd_ad1848_calibrate_mute(chip, 1);
538 snd_ad1848_set_data_format(chip, hw_params);
539 snd_ad1848_mce_up(chip);
540 spin_lock_irqsave(&chip->reg_lock, flags);
541 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
542 spin_unlock_irqrestore(&chip->reg_lock, flags);
543 snd_ad1848_mce_down(chip);
544 snd_ad1848_calibrate_mute(chip, 0);
545 return 0;
546}
547
548static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream)
549{
550 return snd_pcm_lib_free_pages(substream);
551}
552
553static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream)
554{
555 struct snd_wss *chip = snd_pcm_substream_chip(substream);
556 struct snd_pcm_runtime *runtime = substream->runtime;
557 unsigned long flags;
558 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
559 unsigned int count = snd_pcm_lib_period_bytes(substream);
560
561 chip->c_dma_size = size;
562 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
563 snd_dma_program(chip->dma2, runtime->dma_addr, size,
564 DMA_MODE_READ | DMA_AUTOINIT);
565 count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
566 spin_lock_irqsave(&chip->reg_lock, flags);
567 snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
568 snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
569 spin_unlock_irqrestore(&chip->reg_lock, flags);
570 return 0;
571}
572
573static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) 227static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id)
574{ 228{
575 struct snd_wss *chip = dev_id; 229 struct snd_wss *chip = dev_id;
@@ -582,28 +236,6 @@ static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id)
582 return IRQ_HANDLED; 236 return IRQ_HANDLED;
583} 237}
584 238
585static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream)
586{
587 struct snd_wss *chip = snd_pcm_substream_chip(substream);
588 size_t ptr;
589
590 if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
591 return 0;
592 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
593 return bytes_to_frames(substream->runtime, ptr);
594}
595
596static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream)
597{
598 struct snd_wss *chip = snd_pcm_substream_chip(substream);
599 size_t ptr;
600
601 if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
602 return 0;
603 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
604 return bytes_to_frames(substream->runtime, ptr);
605}
606
607/* 239/*
608 240
609 */ 241 */
@@ -728,6 +360,16 @@ static int snd_ad1848_probe(struct snd_wss *chip)
728 snd_ad1848_out(chip, i, *ptr++); 360 snd_ad1848_out(chip, i, *ptr++);
729 spin_unlock_irqrestore(&chip->reg_lock, flags); 361 spin_unlock_irqrestore(&chip->reg_lock, flags);
730 snd_ad1848_mce_up(chip); 362 snd_ad1848_mce_up(chip);
363 /* init needed for WSS pcm */
364 spin_lock_irqsave(&chip->reg_lock, flags);
365 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE |
366 AD1848_PLAYBACK_PIO |
367 AD1848_CAPTURE_ENABLE |
368 AD1848_CAPTURE_PIO |
369 AD1848_CALIB_MODE);
370 chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB;
371 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
372 spin_unlock_irqrestore(&chip->reg_lock, flags);
731 snd_ad1848_mce_down(chip); 373 snd_ad1848_mce_down(chip);
732 return 0; /* all things are ok.. */ 374 return 0; /* all things are ok.. */
733} 375}
@@ -736,102 +378,6 @@ static int snd_ad1848_probe(struct snd_wss *chip)
736 378
737 */ 379 */
738 380
739static struct snd_pcm_hardware snd_ad1848_playback =
740{
741 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
742 SNDRV_PCM_INFO_MMAP_VALID),
743 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
744 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
745 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
746 .rate_min = 5510,
747 .rate_max = 48000,
748 .channels_min = 1,
749 .channels_max = 2,
750 .buffer_bytes_max = (128*1024),
751 .period_bytes_min = 64,
752 .period_bytes_max = (128*1024),
753 .periods_min = 1,
754 .periods_max = 1024,
755 .fifo_size = 0,
756};
757
758static struct snd_pcm_hardware snd_ad1848_capture =
759{
760 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
761 SNDRV_PCM_INFO_MMAP_VALID),
762 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
763 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
764 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
765 .rate_min = 5510,
766 .rate_max = 48000,
767 .channels_min = 1,
768 .channels_max = 2,
769 .buffer_bytes_max = (128*1024),
770 .period_bytes_min = 64,
771 .period_bytes_max = (128*1024),
772 .periods_min = 1,
773 .periods_max = 1024,
774 .fifo_size = 0,
775};
776
777/*
778
779 */
780
781static int snd_ad1848_playback_open(struct snd_pcm_substream *substream)
782{
783 struct snd_wss *chip = snd_pcm_substream_chip(substream);
784 struct snd_pcm_runtime *runtime = substream->runtime;
785 int err;
786
787 err = snd_ad1848_open(chip, WSS_MODE_PLAY);
788 if (err < 0)
789 return err;
790 chip->playback_substream = substream;
791 runtime->hw = snd_ad1848_playback;
792 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
793 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
794 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
795 return 0;
796}
797
798static int snd_ad1848_capture_open(struct snd_pcm_substream *substream)
799{
800 struct snd_wss *chip = snd_pcm_substream_chip(substream);
801 struct snd_pcm_runtime *runtime = substream->runtime;
802 int err;
803
804 err = snd_ad1848_open(chip, WSS_MODE_RECORD);
805 if (err < 0)
806 return err;
807 chip->capture_substream = substream;
808 runtime->hw = snd_ad1848_capture;
809 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
810 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
811 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
812 return 0;
813}
814
815static int snd_ad1848_playback_close(struct snd_pcm_substream *substream)
816{
817 struct snd_wss *chip = snd_pcm_substream_chip(substream);
818
819 chip->mode &= ~WSS_MODE_PLAY;
820 chip->playback_substream = NULL;
821 snd_ad1848_close(chip);
822 return 0;
823}
824
825static int snd_ad1848_capture_close(struct snd_pcm_substream *substream)
826{
827 struct snd_wss *chip = snd_pcm_substream_chip(substream);
828
829 chip->mode &= ~WSS_MODE_RECORD;
830 chip->capture_substream = NULL;
831 snd_ad1848_close(chip);
832 return 0;
833}
834
835static int snd_ad1848_free(struct snd_wss *chip) 381static int snd_ad1848_free(struct snd_wss *chip)
836{ 382{
837 release_and_free_resource(chip->res_port); 383 release_and_free_resource(chip->res_port);
@@ -851,17 +397,6 @@ static int snd_ad1848_dev_free(struct snd_device *device)
851 return snd_ad1848_free(chip); 397 return snd_ad1848_free(chip);
852} 398}
853 399
854static const char *snd_ad1848_chip_id(struct snd_wss *chip)
855{
856 switch (chip->hardware) {
857 case AD1848_HW_AD1847: return "AD1847";
858 case AD1848_HW_AD1848: return "AD1848";
859 case AD1848_HW_CS4248: return "CS4248";
860 case AD1848_HW_CMI8330: return "CMI8330/C3D";
861 default: return "???";
862 }
863}
864
865int snd_ad1848_create(struct snd_card *card, 400int snd_ad1848_create(struct snd_card *card,
866 unsigned long port, 401 unsigned long port,
867 int irq, int dma, 402 int irq, int dma,
@@ -935,65 +470,6 @@ int snd_ad1848_create(struct snd_card *card,
935 470
936EXPORT_SYMBOL(snd_ad1848_create); 471EXPORT_SYMBOL(snd_ad1848_create);
937 472
938static struct snd_pcm_ops snd_ad1848_playback_ops = {
939 .open = snd_ad1848_playback_open,
940 .close = snd_ad1848_playback_close,
941 .ioctl = snd_ad1848_ioctl,
942 .hw_params = snd_ad1848_playback_hw_params,
943 .hw_free = snd_ad1848_playback_hw_free,
944 .prepare = snd_ad1848_playback_prepare,
945 .trigger = snd_ad1848_playback_trigger,
946 .pointer = snd_ad1848_playback_pointer,
947};
948
949static struct snd_pcm_ops snd_ad1848_capture_ops = {
950 .open = snd_ad1848_capture_open,
951 .close = snd_ad1848_capture_close,
952 .ioctl = snd_ad1848_ioctl,
953 .hw_params = snd_ad1848_capture_hw_params,
954 .hw_free = snd_ad1848_capture_hw_free,
955 .prepare = snd_ad1848_capture_prepare,
956 .trigger = snd_ad1848_capture_trigger,
957 .pointer = snd_ad1848_capture_pointer,
958};
959
960int snd_ad1848_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
961{
962 struct snd_pcm *pcm;
963 int err;
964
965 if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0)
966 return err;
967
968 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops);
969 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops);
970
971 pcm->private_data = chip;
972 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
973 strcpy(pcm->name, snd_ad1848_chip_id(chip));
974
975 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
976 snd_dma_isa_data(),
977 64 * 1024,
978 chip->dma1 > 3 ?
979 128 * 1024 : 64 * 1024);
980
981 chip->pcm = pcm;
982 if (rpcm)
983 *rpcm = pcm;
984 return 0;
985}
986
987EXPORT_SYMBOL(snd_ad1848_pcm);
988
989const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction)
990{
991 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
992 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
993}
994
995EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
996
997/* 473/*
998 * INIT part 474 * INIT part
999 */ 475 */