Ignore:
Timestamp:
Apr 21, 2025, 7:17:25 PM (7 months ago)
Author:
David Azarewicz
Message:

Merge from uniaud32-exp branch

Location:
GPL/trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk

  • GPL/trunk/alsa-kernel/pci/emu10k1/emu10k1_callback.c

    r772 r777  
    256256                if (bp != best + V_OFF && bp != best + V_FREE &&
    257257                    (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
    258                         val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
     258                        val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch) - 64 + 3;
    259259                        if (val >= vp->reg.loopstart)
    260260                                bp = best + V_OFF;
     
    311311        unsigned int temp;
    312312        int ch;
     313        bool w_16;
    313314        u32 psst, dsl, map, ccca, vtarget;
    314315        unsigned int addr, mapped_offset;
     
    322323                return -EINVAL;
    323324        chan = vp->chan;
     325        w_16 = !(vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS);
    324326
    325327        emem = (struct snd_emu10k1_memblk *)vp->block;
     
    331333                return -ENOMEM;
    332334        }
    333         mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
     335        mapped_offset = snd_emu10k1_memblk_offset(emem) >> w_16;
    334336        vp->reg.start += mapped_offset;
    335337        vp->reg.end += mapped_offset;
     
    363365        map = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
    364366
    365         addr = vp->reg.start;
     367        addr = vp->reg.start + 64 - 3;
    366368        temp = vp->reg.parm.filterQ;
    367369        ccca = (temp << 28) | addr;
     
    372374                ccca |= shift << 25;
    373375        }
    374         if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
     376        if (!w_16)
    375377                ccca |= CCCA_8BITSELECT;
    376378
     
    431433                CCCA, ccca,
    432434
     435                /* cache */
     436                CCR, REG_VAL_PUT(CCR_CACHEINVALIDSIZE, 64),
     437
    433438                /* reset volume */
    434439                VTFT, vtarget | vp->ftarget,
  • GPL/trunk/alsa-kernel/pci/emu10k1/emu10k1_main.c

    r772 r777  
    673673}
    674674
    675 static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
    676                                      const struct firmware *fw_entry)
    677 {
    678         int n, i;
    679         u16 reg;
    680         u8 value;
    681         __always_unused u16 write_post;
    682 
    683         if (!fw_entry)
    684                 return -EIO;
    685 
    686         /* The FPGA is a Xilinx Spartan IIE XC2S50E */
    687         /* On E-MU 0404b it is a Xilinx Spartan III XC3S50 */
    688         /* GPIO7 -> FPGA PGMN
    689          * GPIO6 -> FPGA CCLK
    690          * GPIO5 -> FPGA DIN
    691          * FPGA CONFIG OFF -> FPGA PGMN
    692          */
    693         spin_lock_irq(&emu->emu_lock);
    694         outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
    695         write_post = inw(emu->port + A_GPIO);
    696         udelay(100);
    697         outw(0x80, emu->port + A_GPIO); /* Leave bit 7 set during netlist setup. */
    698         write_post = inw(emu->port + A_GPIO);
    699         udelay(100); /* Allow FPGA memory to clean */
    700         for (n = 0; n < fw_entry->size; n++) {
    701                 value = fw_entry->data[n];
    702                 for (i = 0; i < 8; i++) {
    703                         reg = 0x80;
    704                         if (value & 0x1)
    705                                 reg = reg | 0x20;
    706                         value = value >> 1;
    707                         outw(reg, emu->port + A_GPIO);
    708                         write_post = inw(emu->port + A_GPIO);
    709                         outw(reg | 0x40, emu->port + A_GPIO);
    710                         write_post = inw(emu->port + A_GPIO);
    711                 }
    712         }
    713         /* After programming, set GPIO bit 4 high again. */
    714         outw(0x10, emu->port + A_GPIO);
    715         write_post = inw(emu->port + A_GPIO);
    716         spin_unlock_irq(&emu->emu_lock);
    717 
    718         return 0;
    719 }
    720 
    721675/* firmware file names, per model, init-fw and dock-fw (optional) */
    722676static const char * const firmware_names[5][2] = {
     
    750704        }
    751705
    752         return snd_emu1010_load_firmware_entry(emu, *fw);
     706        snd_emu1010_load_firmware_entry(emu, dock, *fw);
     707        return 0;
    753708}
    754709
     
    765720
    766721        dev_info(emu->card->dev, "emu1010: Loading Audio Dock Firmware\n");
    767         /* Return to Audio Dock programming mode */
    768         snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
    769                                EMU_HANA_FPGA_CONFIG_AUDIODOCK);
    770722        err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw);
    771723        if (err < 0)
     
    837789#endif
    838790
     791        snd_emu1010_fpga_lock(emu);
     792
    839793        snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &sts);
    840794
     
    846800        if (sts & EMU_HANA_IRQ_WCLK_CHANGED)
    847801                emu1010_clock_event(emu);
     802
     803        snd_emu1010_fpga_unlock(emu);
    848804}
    849805
     
    880836        outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
    881837
    882         /* Disable 48Volt power to Audio Dock */
    883         snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
    884 
    885         /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
    886         snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
    887         dev_dbg(emu->card->dev, "reg1 = 0x%x\n", reg);
    888         if ((reg & 0x3f) == 0x15) {
    889                 /* FPGA netlist already present so clear it */
    890                 /* Return to programming mode */
    891 
    892                 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_HANA);
    893         }
    894         snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
    895         dev_dbg(emu->card->dev, "reg2 = 0x%x\n", reg);
    896         if ((reg & 0x3f) == 0x15) {
    897                 /* FPGA failed to return to programming mode */
    898                 dev_info(emu->card->dev,
    899                          "emu1010: FPGA failed to return to programming mode\n");
    900                 return -ENODEV;
    901         }
    902         dev_info(emu->card->dev, "emu1010: EMU_HANA_ID = 0x%x\n", reg);
     838        snd_emu1010_fpga_lock(emu);
     839
     840        dev_info(emu->card->dev, "emu1010: Loading Hana Firmware\n");
    903841
    904842        err = snd_emu1010_load_firmware(emu, 0, &emu->firmware);
    905843        if (err < 0) {
    906844                dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n");
    907                 return err;
     845                goto fail;
    908846        }
    909847
     
    915853                         "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n",
    916854                         reg);
    917                 return -ENODEV;
     855                err = -ENODEV;
     856                goto fail;
    918857        }
    919858
     
    975914        snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
    976915
    977         return 0;
     916fail:
     917        snd_emu1010_fpga_unlock(emu);
     918        return err;
    978919}
    979920/*
     
    997938        if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
    998939                /* Disable 48Volt power to Audio Dock */
    999                 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
     940                snd_emu1010_fpga_write_lock(emu, EMU_HANA_DOCK_PWR, 0);
    1000941        }
    1001942        cancel_work_sync(&emu->emu1010.work);
     943        mutex_destroy(&emu->emu1010.lock);
    1002944        release_firmware(emu->firmware);
    1003945        release_firmware(emu->dock_fw);
     
    15791521        emu->get_synth_voice = NULL;
    15801522        INIT_WORK(&emu->emu1010.work, emu1010_work);
     1523        mutex_init(&emu->emu1010.lock);
    15811524        /* read revision & serial */
    15821525#ifndef TARGET_OS2
  • GPL/trunk/alsa-kernel/pci/emu10k1/emumixer.c

    r772 r777  
    662662        if (change) {
    663663                emu->emu1010.output_source[channel] = val;
     664                snd_emu1010_fpga_lock(emu);
    664665                snd_emu1010_output_source_apply(emu, channel, val);
     666                snd_emu1010_fpga_unlock(emu);
    665667        }
    666668        return change;
     
    706708        if (change) {
    707709                emu->emu1010.input_source[channel] = val;
     710                snd_emu1010_fpga_lock(emu);
    708711                snd_emu1010_input_source_apply(emu, channel, val);
     712                snd_emu1010_fpga_unlock(emu);
    709713        }
    710714        return change;
     
    775779        change = (cache != emu->emu1010.adc_pads);
    776780        if (change) {
    777                 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );
     781                snd_emu1010_fpga_write_lock(emu, EMU_HANA_ADC_PADS, cache );
    778782                emu->emu1010.adc_pads = cache;
    779783        }
     
    833837        change = (cache != emu->emu1010.dac_pads);
    834838        if (change) {
    835                 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache );
     839                snd_emu1010_fpga_write_lock(emu, EMU_HANA_DAC_PADS, cache );
    836840                emu->emu1010.dac_pads = cache;
    837841        }
     
    981985        if (val >= emu_ci->num)
    982986                return -EINVAL;
     987        snd_emu1010_fpga_lock(emu);
    983988        spin_lock_irq(&emu->reg_lock);
    984989        change = (emu->emu1010.clock_source != val);
     
    9971002                spin_unlock_irq(&emu->reg_lock);
    9981003        }
     1004        snd_emu1010_fpga_unlock(emu);
    9991005        return change;
    10001006}
     
    10421048        if (change) {
    10431049                emu->emu1010.clock_fallback = val;
    1044                 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 1 - val);
     1050                snd_emu1010_fpga_write_lock(emu, EMU_HANA_DEFCLOCK, 1 - val);
    10451051        }
    10461052        return change;
     
    10941100                tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
    10951101                        (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
    1096                 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
     1102                snd_emu1010_fpga_write_lock(emu, EMU_HANA_OPTICAL_TYPE, tmp);
    10971103        }
    10981104        return change;
     
    11451151                tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
    11461152                        (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
    1147                 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
     1153                snd_emu1010_fpga_write_lock(emu, EMU_HANA_OPTICAL_TYPE, tmp);
    11481154        }
    11491155        return change;
     
    23242330                        emu->emu1010.output_source[i] =
    23252331                                emu1010_map_source(emu_ri, emu_ri->out_dflts[i]);
     2332                snd_emu1010_fpga_lock(emu);
    23262333                snd_emu1010_apply_sources(emu);
     2334                snd_emu1010_fpga_unlock(emu);
    23272335
    23282336                kctl = emu->ctl_clock_source = snd_ctl_new1(&snd_emu1010_clock_source, emu);
  • GPL/trunk/alsa-kernel/pci/emu10k1/emupcm.c

    r772 r777  
    148148};
    149149
    150 static const unsigned int capture_rates[8] = {
    151         8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000
    152 };
    153 
    154 static const struct snd_pcm_hw_constraint_list hw_constraints_capture_rates = {
    155         .count = 8,
    156         .list = capture_rates,
    157         .mask = 0
    158 };
    159 
    160150static unsigned int snd_emu10k1_capture_rate_reg(unsigned int rate)
    161151{
     
    174164        }
    175165}
    176 
    177 static const unsigned int audigy_capture_rates[9] = {
    178         8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
    179 };
    180 
    181 static const struct snd_pcm_hw_constraint_list hw_constraints_audigy_capture_rates = {
    182         .count = 9,
    183         .list = audigy_capture_rates,
    184         .mask = 0
    185 };
    186166
    187167static unsigned int snd_emu10k1_audigy_capture_rate_reg(unsigned int rate)
     
    208188        if (emu->card_capabilities->emu_model &&
    209189            emu->emu1010.word_clock == 44100) {
    210                 // This also sets the rate constraint by deleting SNDRV_PCM_RATE_KNOT
    211190                runtime->hw.rates = SNDRV_PCM_RATE_11025 | \
    212191                                    SNDRV_PCM_RATE_22050 | \
     
    214193                runtime->hw.rate_min = 11025;
    215194                runtime->hw.rate_max = 44100;
    216                 return;
    217         }
    218         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
    219                                    emu->audigy ? &hw_constraints_audigy_capture_rates :
    220                                                  &hw_constraints_capture_rates);
     195        } else if (emu->audigy) {
     196                runtime->hw.rates = SNDRV_PCM_RATE_8000_48000 |
     197                                    SNDRV_PCM_RATE_12000 |
     198                                    SNDRV_PCM_RATE_24000;
     199        }
    221200}
    222201
     
    10541033                                 SNDRV_PCM_INFO_MMAP_VALID),
    10551034        .formats =              SNDRV_PCM_FMTBIT_S16_LE,
    1056         .rates =                SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
     1035        .rates =                SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_24000,
    10571036        .rate_min =             8000,
    10581037        .rate_max =             48000,
  • GPL/trunk/alsa-kernel/pci/emu10k1/emuproc.c

    r772 r777  
    166166
    167167        if (emu->card_capabilities->emu_model) {
     168                snd_emu1010_fpga_lock(emu);
     169
    168170                // This represents the S/PDIF lock status on 0404b, which is
    169171                // kinda weird and unhelpful, because monitoring it via IRQ is
     
    198200                                    value & EMU_HANA_SPDIF_MODE_RX_PRO ? "professional" : "consumer",
    199201                                    value & EMU_HANA_SPDIF_MODE_RX_NOCOPY ? ", no copy" : "");
     202
     203                snd_emu1010_fpga_unlock(emu);
    200204        } else {
    201205                snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
     
    459463        u32 value;
    460464        int i;
     465
     466        snd_emu1010_fpga_lock(emu);
     467
    461468        snd_iprintf(buffer, "EMU1010 Registers:\n\n");
    462469
     
    497504                }
    498505        }
     506
     507        snd_emu1010_fpga_unlock(emu);
    499508}
    500509
  • GPL/trunk/alsa-kernel/pci/emu10k1/io.c

    r772 r777  
    291291void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
    292292{
    293         unsigned long flags;
    294 
    295         spin_lock_irqsave(&emu->emu_lock, flags);
     293#ifndef TARGET_OS2
     294        if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))
     295                return;
     296#endif
    296297        snd_emu1010_fpga_write_locked(emu, reg, value);
    297         spin_unlock_irqrestore(&emu->emu_lock, flags);
    298 }
    299 
    300 static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 *value)
     298}
     299
     300void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value)
     301{
     302        snd_emu1010_fpga_lock(emu);
     303        snd_emu1010_fpga_write_locked(emu, reg, value);
     304        snd_emu1010_fpga_unlock(emu);
     305}
     306
     307void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
    301308{
    302309        // The higest input pin is used as the designated interrupt trigger,
     
    305312        // so using this function often causes an IRQ as a side effect.
    306313        u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;
     314
     315#ifndef TARGET_OS2
     316        if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))
     317                return;
     318#endif
    307319        if (snd_BUG_ON(reg > 0x3f))
    308320                return;
     
    315327}
    316328
    317 void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
    318 {
    319         unsigned long flags;
    320 
    321         spin_lock_irqsave(&emu->emu_lock, flags);
    322         snd_emu1010_fpga_read_locked(emu, reg, value);
    323         spin_unlock_irqrestore(&emu->emu_lock, flags);
    324 }
    325 
    326329/* Each Destination has one and only one Source,
    327330 * but one Source can feed any number of Destinations simultaneously.
     
    329332void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)
    330333{
    331         unsigned long flags;
    332 
    333334        if (snd_BUG_ON(dst & ~0x71f))
    334335                return;
    335336        if (snd_BUG_ON(src & ~0x71f))
    336337                return;
    337         spin_lock_irqsave(&emu->emu_lock, flags);
    338         snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);
    339         snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);
    340         snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCHI, src >> 8);
    341         snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCLO, src & 0x1f);
    342         spin_unlock_irqrestore(&emu->emu_lock, flags);
     338        snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
     339        snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
     340        snd_emu1010_fpga_write(emu, EMU_HANA_SRCHI, src >> 8);
     341        snd_emu1010_fpga_write(emu, EMU_HANA_SRCLO, src & 0x1f);
    343342}
    344343
    345344u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst)
    346345{
    347         unsigned long flags;
    348346        u32 hi, lo;
    349347
    350348        if (snd_BUG_ON(dst & ~0x71f))
    351349                return 0;
    352         spin_lock_irqsave(&emu->emu_lock, flags);
    353         snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);
    354         snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);
    355         snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCHI, &hi);
    356         snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCLO, &lo);
    357         spin_unlock_irqrestore(&emu->emu_lock, flags);
     350        snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
     351        snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
     352        snd_emu1010_fpga_read(emu, EMU_HANA_SRCHI, &hi);
     353        snd_emu1010_fpga_read(emu, EMU_HANA_SRCLO, &lo);
    358354        return (hi << 8) | lo;
    359355}
     
    429425
    430426        snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
     427}
     428
     429void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock,
     430                                     const struct firmware *fw_entry)
     431{
     432        __always_unused u16 write_post;
     433
     434        // On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E.
     435        // On E-MU 0404b it is a Xilinx Spartan III XC3S50.
     436        // The wiring is as follows:
     437        // GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output
     438        //   In normal operation, the active low reset line is held up by
     439        //   an FPGA output, while the GPO pin performs its duty as control
     440        //   register access strobe signal. Writing the respective bit to
     441        //   EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at
     442        //   which point the GPO pin can control the reset line through the
     443        //   resistor.
     444        // GPO6 -> FPGA CCLK & FPGA input
     445        // GPO5 -> FPGA DIN (dual function)
     446
     447        // If the FPGA is already programmed, return it to programming mode
     448        snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
     449                               dock ? EMU_HANA_FPGA_CONFIG_AUDIODOCK :
     450                                      EMU_HANA_FPGA_CONFIG_HANA);
     451
     452        // Assert reset line for 100uS
     453        outw(0x00, emu->port + A_GPIO);
     454        write_post = inw(emu->port + A_GPIO);
     455        udelay(100);
     456        outw(0x80, emu->port + A_GPIO);
     457        write_post = inw(emu->port + A_GPIO);
     458        udelay(100);  // Allow FPGA memory to clean
     459
     460        // Upload the netlist. Keep reset line high!
     461        for (int n = 0; n < fw_entry->size; n++) {
     462                u8 value = fw_entry->data[n];
     463                for (int i = 0; i < 8; i++) {
     464                        u16 reg = 0x80;
     465                        if (value & 1)
     466                                reg |= 0x20;
     467                        value >>= 1;
     468                        outw(reg, emu->port + A_GPIO);
     469                        write_post = inw(emu->port + A_GPIO);
     470                        outw(reg | 0x40, emu->port + A_GPIO);
     471                        write_post = inw(emu->port + A_GPIO);
     472                }
     473        }
     474
     475        // After programming, set GPIO bit 4 high again.
     476        // This appears to be a config word that the rev1 Hana
     477        // firmware reads; weird things happen without this.
     478        outw(0x10, emu->port + A_GPIO);
     479        write_post = inw(emu->port + A_GPIO);
    431480}
    432481
  • GPL/trunk/alsa-kernel/pci/emu10k1/memory.c

    r772 r777  
    602602
    603603/*
    604  * bzero(blk + offset, size)
    605  */
    606 int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
    607                             int offset, int size)
     604 * memset(blk + offset, value, size)
     605 */
     606int snd_emu10k1_synth_memset(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
     607                             int offset, int size, u8 value)
    608608{
    609609        int page, nextofs, end_offset, temp, temp1;
    610610        void *ptr;
    611611        struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
     612
     613        if (snd_BUG_ON(offset + size > p->mem.size))
     614                return -EFAULT;
    612615
    613616        offset += blk->offset & (PAGE_SIZE - 1);
     
    622625                ptr = offset_ptr(emu, page + p->first_page, offset);
    623626                if (ptr)
    624                         memset(ptr, 0, temp);
     627                        memset(ptr, value, temp);
    625628                offset = nextofs;
    626629                page++;
     
    629632}
    630633
    631 EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
    632 
    633 /*
    634  * copy_from_user(blk + offset, data, size)
     634EXPORT_SYMBOL(snd_emu10k1_synth_memset);
     635
     636// Note that the value is assumed to be suitably repetitive.
     637static void xor_range(void *ptr, int size, u32 value)
     638{
     639        if ((long)ptr & 1) {
     640                *(u8 *)ptr ^= (u8)value;
     641                ptr++;
     642                size--;
     643        }
     644        if (size > 1 && ((long)ptr & 2)) {
     645                *(u16 *)ptr ^= (u16)value;
     646                ptr += 2;
     647                size -= 2;
     648        }
     649        while (size > 3) {
     650                *(u32 *)ptr ^= value;
     651                ptr += 4;
     652                size -= 4;
     653        }
     654        if (size > 1) {
     655                *(u16 *)ptr ^= (u16)value;
     656                ptr += 2;
     657                size -= 2;
     658        }
     659        if (size > 0)
     660                *(u8 *)ptr ^= (u8)value;
     661}
     662
     663/*
     664 * copy_from_user(blk + offset, data, size) ^ xor
    635665 */
    636666int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
    637                                      int offset, const char __user *data, int size)
     667                                     int offset, const char __user *data, int size, u32 xor)
    638668{
    639669        int page, nextofs, end_offset, temp, temp1;
    640670        void *ptr;
    641671        struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
     672
     673        if (snd_BUG_ON(offset + size > p->mem.size))
     674                return -EFAULT;
    642675
    643676        offset += blk->offset & (PAGE_SIZE - 1);
     
    651684                        temp = temp1;
    652685                ptr = offset_ptr(emu, page + p->first_page, offset);
    653                 if (ptr && copy_from_user(ptr, data, temp))
     686                if (ptr) {
     687                        if (copy_from_user(ptr, data, temp))
    654688                        return -EFAULT;
     689                        if (xor)
     690                                xor_range(ptr, temp, xor);
     691                }
    655692                offset = nextofs;
    656693                data += temp;
  • GPL/trunk/alsa-kernel/pci/emu10k1/p16v.c

    r772 r777  
    175175                return err;
    176176
    177         runtime->sync.id32[0] = substream->pcm->card->number;
    178         runtime->sync.id32[1] = 'P';
    179         runtime->sync.id32[2] = 16;
    180         runtime->sync.id32[3] = 'V';
    181 
    182177        return 0;
    183178}
     
    225220        // Only using channel 0 for now, but the card has 2 channels.
    226221        return snd_p16v_pcm_open_capture_channel(substream, 0);
     222}
     223
     224static int snd_p16v_pcm_ioctl_playback(struct snd_pcm_substream *substream,
     225                                       unsigned int cmd, void *arg)
     226{
     227        if (cmd == SNDRV_PCM_IOCTL1_SYNC_ID) {
     228                static const unsigned char id[4] = { 'P', '1', '6', 'V' };
     229                snd_pcm_set_sync_per_card(substream, arg, id, 4);
     230                return 0;
     231        }
     232        return snd_pcm_lib_ioctl(substream, cmd, arg);
    227233}
    228234
     
    532538        .open =        snd_p16v_pcm_open_playback_front,
    533539        .close =       snd_p16v_pcm_close_playback,
     540        .ioctl =       snd_p16v_pcm_ioctl_playback,
    534541        .prepare =     snd_p16v_pcm_prepare_playback,
    535542        .trigger =     snd_p16v_pcm_trigger_playback,
Note: See TracChangeset for help on using the changeset viewer.