root/sound/pcmcia/vx/vxp_ops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vxp_reg_addr
  2. vxp_inb
  3. vxp_outb
  4. vx_check_magic
  5. vxp_reset_dsp
  6. vxp_reset_codec
  7. vxp_load_xilinx_binary
  8. vxp_load_dsp
  9. vxp_test_and_ack
  10. vxp_validate_irq
  11. vx_setup_pseudo_dma
  12. vx_release_pseudo_dma
  13. vxp_dma_write
  14. vxp_dma_read
  15. vxp_write_codec_reg
  16. vx_set_mic_boost
  17. vx_compute_mic_level
  18. vx_set_mic_level
  19. vxp_change_audio_source
  20. vxp_set_clock_source
  21. vxp_reset_board

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Driver for Digigram VXpocket soundcards
   4  *
   5  * lowlevel routines for VXpocket soundcards
   6  *
   7  * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
   8  */
   9 
  10 #include <linux/delay.h>
  11 #include <linux/device.h>
  12 #include <linux/firmware.h>
  13 #include <linux/io.h>
  14 #include <sound/core.h>
  15 #include "vxpocket.h"
  16 
  17 
  18 static int vxp_reg_offset[VX_REG_MAX] = {
  19         [VX_ICR]        = 0x00,         // ICR
  20         [VX_CVR]        = 0x01,         // CVR
  21         [VX_ISR]        = 0x02,         // ISR
  22         [VX_IVR]        = 0x03,         // IVR
  23         [VX_RXH]        = 0x05,         // RXH
  24         [VX_RXM]        = 0x06,         // RXM
  25         [VX_RXL]        = 0x07,         // RXL
  26         [VX_DMA]        = 0x04,         // DMA
  27         [VX_CDSP]       = 0x08,         // CDSP
  28         [VX_LOFREQ]     = 0x09,         // LFREQ
  29         [VX_HIFREQ]     = 0x0a,         // HFREQ
  30         [VX_DATA]       = 0x0b,         // DATA
  31         [VX_MICRO]      = 0x0c,         // MICRO
  32         [VX_DIALOG]     = 0x0d,         // DIALOG
  33         [VX_CSUER]      = 0x0e,         // CSUER
  34         [VX_RUER]       = 0x0f,         // RUER
  35 };
  36 
  37 
  38 static inline unsigned long vxp_reg_addr(struct vx_core *_chip, int reg)
  39 {
  40         struct snd_vxpocket *chip = to_vxpocket(_chip);
  41         return chip->port + vxp_reg_offset[reg];
  42 }
  43 
  44 /*
  45  * snd_vx_inb - read a byte from the register
  46  * @offset: register offset
  47  */
  48 static unsigned char vxp_inb(struct vx_core *chip, int offset)
  49 {
  50         return inb(vxp_reg_addr(chip, offset));
  51 }
  52 
  53 /*
  54  * snd_vx_outb - write a byte on the register
  55  * @offset: the register offset
  56  * @val: the value to write
  57  */
  58 static void vxp_outb(struct vx_core *chip, int offset, unsigned char val)
  59 {
  60         outb(val, vxp_reg_addr(chip, offset));
  61 }
  62 
  63 /*
  64  * redefine macros to call directly
  65  */
  66 #undef vx_inb
  67 #define vx_inb(chip,reg)        vxp_inb((struct vx_core *)(chip), VX_##reg)
  68 #undef vx_outb
  69 #define vx_outb(chip,reg,val)   vxp_outb((struct vx_core *)(chip), VX_##reg,val)
  70 
  71 
  72 /*
  73  * vx_check_magic - check the magic word on xilinx
  74  *
  75  * returns zero if a magic word is detected, or a negative error code.
  76  */
  77 static int vx_check_magic(struct vx_core *chip)
  78 {
  79         unsigned long end_time = jiffies + HZ / 5;
  80         int c;
  81         do {
  82                 c = vx_inb(chip, CDSP);
  83                 if (c == CDSP_MAGIC)
  84                         return 0;
  85                 msleep(10);
  86         } while (time_after_eq(end_time, jiffies));
  87         snd_printk(KERN_ERR "cannot find xilinx magic word (%x)\n", c);
  88         return -EIO;
  89 }
  90 
  91 
  92 /*
  93  * vx_reset_dsp - reset the DSP
  94  */
  95 
  96 #define XX_DSP_RESET_WAIT_TIME          2       /* ms */
  97 
  98 static void vxp_reset_dsp(struct vx_core *_chip)
  99 {
 100         struct snd_vxpocket *chip = to_vxpocket(_chip);
 101 
 102         /* set the reset dsp bit to 1 */
 103         vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_DSP_RESET_MASK);
 104         vx_inb(chip, CDSP);
 105         mdelay(XX_DSP_RESET_WAIT_TIME);
 106         /* reset the bit */
 107         chip->regCDSP &= ~VXP_CDSP_DSP_RESET_MASK;
 108         vx_outb(chip, CDSP, chip->regCDSP);
 109         vx_inb(chip, CDSP);
 110         mdelay(XX_DSP_RESET_WAIT_TIME);
 111 }
 112 
 113 /*
 114  * reset codec bit
 115  */
 116 static void vxp_reset_codec(struct vx_core *_chip)
 117 {
 118         struct snd_vxpocket *chip = to_vxpocket(_chip);
 119 
 120         /* Set the reset CODEC bit to 1. */
 121         vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK);
 122         vx_inb(chip, CDSP);
 123         msleep(10);
 124         /* Set the reset CODEC bit to 0. */
 125         chip->regCDSP &= ~VXP_CDSP_CODEC_RESET_MASK;
 126         vx_outb(chip, CDSP, chip->regCDSP);
 127         vx_inb(chip, CDSP);
 128         msleep(1);
 129 }
 130 
 131 /*
 132  * vx_load_xilinx_binary - load the xilinx binary image
 133  * the binary image is the binary array converted from the bitstream file.
 134  */
 135 static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *fw)
 136 {
 137         struct snd_vxpocket *chip = to_vxpocket(_chip);
 138         unsigned int i;
 139         int c;
 140         int regCSUER, regRUER;
 141         const unsigned char *image;
 142         unsigned char data;
 143 
 144         /* Switch to programmation mode */
 145         chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
 146         vx_outb(chip, DIALOG, chip->regDIALOG);
 147 
 148         /* Save register CSUER and RUER */
 149         regCSUER = vx_inb(chip, CSUER);
 150         regRUER = vx_inb(chip, RUER);
 151 
 152         /* reset HF0 and HF1 */
 153         vx_outb(chip, ICR, 0);
 154 
 155         /* Wait for answer HF2 equal to 1 */
 156         snd_printdd(KERN_DEBUG "check ISR_HF2\n");
 157         if (vx_check_isr(_chip, ISR_HF2, ISR_HF2, 20) < 0)
 158                 goto _error;
 159 
 160         /* set HF1 for loading xilinx binary */
 161         vx_outb(chip, ICR, ICR_HF1);
 162         image = fw->data;
 163         for (i = 0; i < fw->size; i++, image++) {
 164                 data = *image;
 165                 if (vx_wait_isr_bit(_chip, ISR_TX_EMPTY) < 0)
 166                         goto _error;
 167                 vx_outb(chip, TXL, data);
 168                 /* wait for reading */
 169                 if (vx_wait_for_rx_full(_chip) < 0)
 170                         goto _error;
 171                 c = vx_inb(chip, RXL);
 172                 if (c != (int)data)
 173                         snd_printk(KERN_ERR "vxpocket: load xilinx mismatch at %d: 0x%x != 0x%x\n", i, c, (int)data);
 174         }
 175 
 176         /* reset HF1 */
 177         vx_outb(chip, ICR, 0);
 178 
 179         /* wait for HF3 */
 180         if (vx_check_isr(_chip, ISR_HF3, ISR_HF3, 20) < 0)
 181                 goto _error;
 182 
 183         /* read the number of bytes received */
 184         if (vx_wait_for_rx_full(_chip) < 0)
 185                 goto _error;
 186 
 187         c = (int)vx_inb(chip, RXH) << 16;
 188         c |= (int)vx_inb(chip, RXM) << 8;
 189         c |= vx_inb(chip, RXL);
 190 
 191         snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%zx\n", c, fw->size);
 192 
 193         vx_outb(chip, ICR, ICR_HF0);
 194 
 195         /* TEMPO 250ms : wait until Xilinx is downloaded */
 196         msleep(300);
 197 
 198         /* test magical word */
 199         if (vx_check_magic(_chip) < 0)
 200                 goto _error;
 201 
 202         /* Restore register 0x0E and 0x0F (thus replacing COR and FCSR) */
 203         vx_outb(chip, CSUER, regCSUER);
 204         vx_outb(chip, RUER, regRUER);
 205 
 206         /* Reset the Xilinx's signal enabling IO access */
 207         chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
 208         vx_outb(chip, DIALOG, chip->regDIALOG);
 209         vx_inb(chip, DIALOG);
 210         msleep(10);
 211         chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
 212         vx_outb(chip, DIALOG, chip->regDIALOG);
 213         vx_inb(chip, DIALOG);
 214 
 215         /* Reset of the Codec */
 216         vxp_reset_codec(_chip);
 217         vx_reset_dsp(_chip);
 218 
 219         return 0;
 220 
 221  _error:
 222         vx_outb(chip, CSUER, regCSUER);
 223         vx_outb(chip, RUER, regRUER);
 224         chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
 225         vx_outb(chip, DIALOG, chip->regDIALOG);
 226         return -EIO;
 227 }
 228 
 229 
 230 /*
 231  * vxp_load_dsp - load_dsp callback
 232  */
 233 static int vxp_load_dsp(struct vx_core *vx, int index, const struct firmware *fw)
 234 {
 235         int err;
 236 
 237         switch (index) {
 238         case 0:
 239                 /* xilinx boot */
 240                 if ((err = vx_check_magic(vx)) < 0)
 241                         return err;
 242                 if ((err = snd_vx_load_boot_image(vx, fw)) < 0)
 243                         return err;
 244                 return 0;
 245         case 1:
 246                 /* xilinx image */
 247                 return vxp_load_xilinx_binary(vx, fw);
 248         case 2:
 249                 /* DSP boot */
 250                 return snd_vx_dsp_boot(vx, fw);
 251         case 3:
 252                 /* DSP image */
 253                 return snd_vx_dsp_load(vx, fw);
 254         default:
 255                 snd_BUG();
 256                 return -EINVAL;
 257         }
 258 }
 259                 
 260 
 261 /*
 262  * vx_test_and_ack - test and acknowledge interrupt
 263  *
 264  * called from irq hander, too
 265  *
 266  * spinlock held!
 267  */
 268 static int vxp_test_and_ack(struct vx_core *_chip)
 269 {
 270         struct snd_vxpocket *chip = to_vxpocket(_chip);
 271 
 272         /* not booted yet? */
 273         if (! (_chip->chip_status & VX_STAT_XILINX_LOADED))
 274                 return -ENXIO;
 275 
 276         if (! (vx_inb(chip, DIALOG) & VXP_DLG_MEMIRQ_MASK))
 277                 return -EIO;
 278         
 279         /* ok, interrupts generated, now ack it */
 280         /* set ACQUIT bit up and down */
 281         vx_outb(chip, DIALOG, chip->regDIALOG | VXP_DLG_ACK_MEMIRQ_MASK);
 282         /* useless read just to spend some time and maintain
 283          * the ACQUIT signal up for a while ( a bus cycle )
 284          */
 285         vx_inb(chip, DIALOG);
 286         vx_outb(chip, DIALOG, chip->regDIALOG & ~VXP_DLG_ACK_MEMIRQ_MASK);
 287 
 288         return 0;
 289 }
 290 
 291 
 292 /*
 293  * vx_validate_irq - enable/disable IRQ
 294  */
 295 static void vxp_validate_irq(struct vx_core *_chip, int enable)
 296 {
 297         struct snd_vxpocket *chip = to_vxpocket(_chip);
 298 
 299         /* Set the interrupt enable bit to 1 in CDSP register */
 300         if (enable)
 301                 chip->regCDSP |= VXP_CDSP_VALID_IRQ_MASK;
 302         else
 303                 chip->regCDSP &= ~VXP_CDSP_VALID_IRQ_MASK;
 304         vx_outb(chip, CDSP, chip->regCDSP);
 305 }
 306 
 307 /*
 308  * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
 309  * @do_write: 0 = read, 1 = set up for DMA write
 310  */
 311 static void vx_setup_pseudo_dma(struct vx_core *_chip, int do_write)
 312 {
 313         struct snd_vxpocket *chip = to_vxpocket(_chip);
 314 
 315         /* Interrupt mode and HREQ pin enabled for host transmit / receive data transfers */
 316         vx_outb(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
 317         /* Reset the pseudo-dma register */
 318         vx_inb(chip, ISR);
 319         vx_outb(chip, ISR, 0);
 320 
 321         /* Select DMA in read/write transfer mode and in 16-bit accesses */
 322         chip->regDIALOG |= VXP_DLG_DMA16_SEL_MASK;
 323         chip->regDIALOG |= do_write ? VXP_DLG_DMAWRITE_SEL_MASK : VXP_DLG_DMAREAD_SEL_MASK;
 324         vx_outb(chip, DIALOG, chip->regDIALOG);
 325 
 326 }
 327 
 328 /*
 329  * vx_release_pseudo_dma - disable the pseudo-DMA mode
 330  */
 331 static void vx_release_pseudo_dma(struct vx_core *_chip)
 332 {
 333         struct snd_vxpocket *chip = to_vxpocket(_chip);
 334 
 335         /* Disable DMA and 16-bit accesses */
 336         chip->regDIALOG &= ~(VXP_DLG_DMAWRITE_SEL_MASK|
 337                              VXP_DLG_DMAREAD_SEL_MASK|
 338                              VXP_DLG_DMA16_SEL_MASK);
 339         vx_outb(chip, DIALOG, chip->regDIALOG);
 340         /* HREQ pin disabled. */
 341         vx_outb(chip, ICR, 0);
 342 }
 343 
 344 /*
 345  * vx_pseudo_dma_write - write bulk data on pseudo-DMA mode
 346  * @count: data length to transfer in bytes
 347  *
 348  * data size must be aligned to 6 bytes to ensure the 24bit alignment on DSP.
 349  * NB: call with a certain lock!
 350  */
 351 static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
 352                           struct vx_pipe *pipe, int count)
 353 {
 354         long port = vxp_reg_addr(chip, VX_DMA);
 355         int offset = pipe->hw_ptr;
 356         unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
 357 
 358         vx_setup_pseudo_dma(chip, 1);
 359         if (offset + count >= pipe->buffer_bytes) {
 360                 int length = pipe->buffer_bytes - offset;
 361                 count -= length;
 362                 length >>= 1; /* in 16bit words */
 363                 /* Transfer using pseudo-dma. */
 364                 for (; length > 0; length--) {
 365                         outw(*addr, port);
 366                         addr++;
 367                 }
 368                 addr = (unsigned short *)runtime->dma_area;
 369                 pipe->hw_ptr = 0;
 370         }
 371         pipe->hw_ptr += count;
 372         count >>= 1; /* in 16bit words */
 373         /* Transfer using pseudo-dma. */
 374         for (; count > 0; count--) {
 375                 outw(*addr, port);
 376                 addr++;
 377         }
 378         vx_release_pseudo_dma(chip);
 379 }
 380 
 381 
 382 /*
 383  * vx_pseudo_dma_read - read bulk data on pseudo DMA mode
 384  * @offset: buffer offset in bytes
 385  * @count: data length to transfer in bytes
 386  *
 387  * the read length must be aligned to 6 bytes, as well as write.
 388  * NB: call with a certain lock!
 389  */
 390 static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
 391                          struct vx_pipe *pipe, int count)
 392 {
 393         struct snd_vxpocket *pchip = to_vxpocket(chip);
 394         long port = vxp_reg_addr(chip, VX_DMA);
 395         int offset = pipe->hw_ptr;
 396         unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
 397 
 398         if (snd_BUG_ON(count % 2))
 399                 return;
 400         vx_setup_pseudo_dma(chip, 0);
 401         if (offset + count >= pipe->buffer_bytes) {
 402                 int length = pipe->buffer_bytes - offset;
 403                 count -= length;
 404                 length >>= 1; /* in 16bit words */
 405                 /* Transfer using pseudo-dma. */
 406                 for (; length > 0; length--)
 407                         *addr++ = inw(port);
 408                 addr = (unsigned short *)runtime->dma_area;
 409                 pipe->hw_ptr = 0;
 410         }
 411         pipe->hw_ptr += count;
 412         count >>= 1; /* in 16bit words */
 413         /* Transfer using pseudo-dma. */
 414         for (; count > 1; count--)
 415                 *addr++ = inw(port);
 416         /* Disable DMA */
 417         pchip->regDIALOG &= ~VXP_DLG_DMAREAD_SEL_MASK;
 418         vx_outb(chip, DIALOG, pchip->regDIALOG);
 419         /* Read the last word (16 bits) */
 420         *addr = inw(port);
 421         /* Disable 16-bit accesses */
 422         pchip->regDIALOG &= ~VXP_DLG_DMA16_SEL_MASK;
 423         vx_outb(chip, DIALOG, pchip->regDIALOG);
 424         /* HREQ pin disabled. */
 425         vx_outb(chip, ICR, 0);
 426 }
 427 
 428 
 429 /*
 430  * write a codec data (24bit)
 431  */
 432 static void vxp_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
 433 {
 434         int i;
 435 
 436         /* Activate access to the corresponding codec register */
 437         if (! codec)
 438                 vx_inb(chip, LOFREQ);
 439         else
 440                 vx_inb(chip, CODEC2);
 441                 
 442         /* We have to send 24 bits (3 x 8 bits). Start with most signif. Bit */
 443         for (i = 0; i < 24; i++, data <<= 1)
 444                 vx_outb(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
 445         
 446         /* Terminate access to codec registers */
 447         vx_inb(chip, HIFREQ);
 448 }
 449 
 450 
 451 /*
 452  * vx_set_mic_boost - set mic boost level (on vxp440 only)
 453  * @boost: 0 = 20dB, 1 = +38dB
 454  */
 455 void vx_set_mic_boost(struct vx_core *chip, int boost)
 456 {
 457         struct snd_vxpocket *pchip = to_vxpocket(chip);
 458 
 459         if (chip->chip_status & VX_STAT_IS_STALE)
 460                 return;
 461 
 462         mutex_lock(&chip->lock);
 463         if (pchip->regCDSP & P24_CDSP_MICS_SEL_MASK) {
 464                 if (boost) {
 465                         /* boost: 38 dB */
 466                         pchip->regCDSP &= ~P24_CDSP_MIC20_SEL_MASK;
 467                         pchip->regCDSP |=  P24_CDSP_MIC38_SEL_MASK;
 468                 } else {
 469                         /* minimum value: 20 dB */
 470                         pchip->regCDSP |=  P24_CDSP_MIC20_SEL_MASK;
 471                         pchip->regCDSP &= ~P24_CDSP_MIC38_SEL_MASK;
 472                 }
 473                 vx_outb(chip, CDSP, pchip->regCDSP);
 474         }
 475         mutex_unlock(&chip->lock);
 476 }
 477 
 478 /*
 479  * remap the linear value (0-8) to the actual value (0-15)
 480  */
 481 static int vx_compute_mic_level(int level)
 482 {
 483         switch (level) {
 484         case 5: level = 6 ; break;
 485         case 6: level = 8 ; break;
 486         case 7: level = 11; break;
 487         case 8: level = 15; break;
 488         default: break ;
 489         }
 490         return level;
 491 }
 492 
 493 /*
 494  * vx_set_mic_level - set mic level (on vxpocket only)
 495  * @level: the mic level = 0 - 8 (max)
 496  */
 497 void vx_set_mic_level(struct vx_core *chip, int level)
 498 {
 499         struct snd_vxpocket *pchip = to_vxpocket(chip);
 500 
 501         if (chip->chip_status & VX_STAT_IS_STALE)
 502                 return;
 503 
 504         mutex_lock(&chip->lock);
 505         if (pchip->regCDSP & VXP_CDSP_MIC_SEL_MASK) {
 506                 level = vx_compute_mic_level(level);
 507                 vx_outb(chip, MICRO, level);
 508         }
 509         mutex_unlock(&chip->lock);
 510 }
 511 
 512 
 513 /*
 514  * change the input audio source
 515  */
 516 static void vxp_change_audio_source(struct vx_core *_chip, int src)
 517 {
 518         struct snd_vxpocket *chip = to_vxpocket(_chip);
 519 
 520         switch (src) {
 521         case VX_AUDIO_SRC_DIGITAL:
 522                 chip->regCDSP |= VXP_CDSP_DATAIN_SEL_MASK;
 523                 vx_outb(chip, CDSP, chip->regCDSP);
 524                 break;
 525         case VX_AUDIO_SRC_LINE:
 526                 chip->regCDSP &= ~VXP_CDSP_DATAIN_SEL_MASK;
 527                 if (_chip->type == VX_TYPE_VXP440)
 528                         chip->regCDSP &= ~P24_CDSP_MICS_SEL_MASK;
 529                 else
 530                         chip->regCDSP &= ~VXP_CDSP_MIC_SEL_MASK;
 531                 vx_outb(chip, CDSP, chip->regCDSP);
 532                 break;
 533         case VX_AUDIO_SRC_MIC:
 534                 chip->regCDSP &= ~VXP_CDSP_DATAIN_SEL_MASK;
 535                 /* reset mic levels */
 536                 if (_chip->type == VX_TYPE_VXP440) {
 537                         chip->regCDSP &= ~P24_CDSP_MICS_SEL_MASK;
 538                         if (chip->mic_level)
 539                                 chip->regCDSP |=  P24_CDSP_MIC38_SEL_MASK;
 540                         else
 541                                 chip->regCDSP |= P24_CDSP_MIC20_SEL_MASK;
 542                         vx_outb(chip, CDSP, chip->regCDSP);
 543                 } else {
 544                         chip->regCDSP |= VXP_CDSP_MIC_SEL_MASK;
 545                         vx_outb(chip, CDSP, chip->regCDSP);
 546                         vx_outb(chip, MICRO, vx_compute_mic_level(chip->mic_level));
 547                 }
 548                 break;
 549         }
 550 }
 551 
 552 /*
 553  * change the clock source
 554  * source = INTERNAL_QUARTZ or UER_SYNC
 555  */
 556 static void vxp_set_clock_source(struct vx_core *_chip, int source)
 557 {
 558         struct snd_vxpocket *chip = to_vxpocket(_chip);
 559 
 560         if (source == INTERNAL_QUARTZ)
 561                 chip->regCDSP &= ~VXP_CDSP_CLOCKIN_SEL_MASK;
 562         else
 563                 chip->regCDSP |= VXP_CDSP_CLOCKIN_SEL_MASK;
 564         vx_outb(chip, CDSP, chip->regCDSP);
 565 }
 566 
 567 
 568 /*
 569  * reset the board
 570  */
 571 static void vxp_reset_board(struct vx_core *_chip, int cold_reset)
 572 {
 573         struct snd_vxpocket *chip = to_vxpocket(_chip);
 574 
 575         chip->regCDSP = 0;
 576         chip->regDIALOG = 0;
 577 }
 578 
 579 
 580 /*
 581  * callbacks
 582  */
 583 /* exported */
 584 struct snd_vx_ops snd_vxpocket_ops = {
 585         .in8 = vxp_inb,
 586         .out8 = vxp_outb,
 587         .test_and_ack = vxp_test_and_ack,
 588         .validate_irq = vxp_validate_irq,
 589         .write_codec = vxp_write_codec_reg,
 590         .reset_codec = vxp_reset_codec,
 591         .change_audio_source = vxp_change_audio_source,
 592         .set_clock_source = vxp_set_clock_source,
 593         .load_dsp = vxp_load_dsp,
 594         .add_controls = vxp_add_mic_controls,
 595         .reset_dsp = vxp_reset_dsp,
 596         .reset_board = vxp_reset_board,
 597         .dma_write = vxp_dma_write,
 598         .dma_read = vxp_dma_read,
 599 };

/* [<][>][^][v][top][bottom][index][help] */