aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/ad1848/ad1848_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/ad1848/ad1848_lib.c')
-rw-r--r--sound/isa/ad1848/ad1848_lib.c544
1 files changed, 10 insertions, 534 deletions
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 */