Ignore:
Timestamp:
Apr 19, 2025, 8:08:37 PM (4 months ago)
Author:
David Azarewicz
Message:

Merge in changes from 6.6-LTS branch.
Fixed additional 25+ problems.

Location:
GPL/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk

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

    r717 r772  
    150150};
    151151
    152 static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
    153 {
    154         struct snd_emu10k1_pcm *epcm = runtime->private_data;
    155 
    156         kfree(epcm);
    157 }
    158 
    159152/* open_playback callback */
    160153static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
    161154{
    162         struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    163         struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]);
    164         struct snd_emu10k1_pcm *epcm;
    165155        struct snd_pcm_runtime *runtime = substream->runtime;
    166156        int err;
    167157
    168         epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
    169         /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */
    170 
    171         if (epcm == NULL)
    172                 return -ENOMEM;
    173         epcm->emu = emu;
    174         epcm->substream = substream;
    175158        /*
    176159        dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
    177160                   substream->pcm->device, channel_id);
    178161        */
    179         runtime->private_data = epcm;
    180         runtime->private_free = snd_p16v_pcm_free_substream;
    181162 
    182163        runtime->hw = snd_p16v_playback_hw;
    183164
    184         channel->emu = emu;
    185         channel->number = channel_id;
    186 
    187         channel->use=1;
    188165#if 0 /* debug */
    189166        dev_dbg(emu->card->dev,
     
    194171#endif /* debug */
    195172        /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
    196         channel->epcm = epcm;
    197173        err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
    198174        if (err < 0)
     
    206182        return 0;
    207183}
     184
    208185/* open_capture callback */
    209186static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
    210187{
    211         struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    212         struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice);
    213         struct snd_emu10k1_pcm *epcm;
    214188        struct snd_pcm_runtime *runtime = substream->runtime;
    215189        int err;
    216190
    217         epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
    218         /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */
    219 
    220         if (epcm == NULL)
    221                 return -ENOMEM;
    222         epcm->emu = emu;
    223         epcm->substream = substream;
    224191        /*
    225192        dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
    226193                   substream->pcm->device, channel_id);
    227194        */
    228         runtime->private_data = epcm;
    229         runtime->private_free = snd_p16v_pcm_free_substream;
    230195 
    231196        runtime->hw = snd_p16v_capture_hw;
    232197
    233         channel->emu = emu;
    234         channel->number = channel_id;
    235 
    236         channel->use=1;
    237 #if 0 /* debug */
    238         dev_dbg(emu->card->dev,
    239                    "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
    240                    channel_id, channel, channel->use);
    241         dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n",
    242                channel_id, chip, channel);
    243 #endif /* debug */
    244         /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
    245         channel->epcm = epcm;
    246198        err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
    247199        if (err < 0)
     
    255207static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
    256208{
    257         struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    258         //struct snd_pcm_runtime *runtime = substream->runtime;
    259         //struct snd_emu10k1_pcm *epcm = runtime->private_data;
    260         emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0;
    261         /* FIXME: maybe zero others */
    262209        return 0;
    263210}
     
    266213static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
    267214{
    268         struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    269         //struct snd_pcm_runtime *runtime = substream->runtime;
    270         //struct snd_emu10k1_pcm *epcm = runtime->private_data;
    271         emu->p16v_capture_voice.use = 0;
    272         /* FIXME: maybe zero others */
    273215        return 0;
    274216}
     
    313255#endif /* debug */
    314256        tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
     257        tmp &= ~(A_SPDIF_RATE_MASK | A_EHC_SRC48_MASK);
    315258        switch (runtime->rate) {
    316259        case 44100:
    317           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
     260          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
     261                                tmp | A_SPDIF_44100 | A_EHC_SRC48_44);
    318262          break;
    319263        case 96000:
    320           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
     264          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
     265                                tmp | A_SPDIF_96000 | A_EHC_SRC48_96);
    321266          break;
    322267        case 192000:
    323           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
     268          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
     269                                tmp | A_SPDIF_192000 | A_EHC_SRC48_192);
    324270          break;
    325271        case 48000:
    326272        default:
    327           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
     273          snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
     274                                tmp | A_SPDIF_48000 | A_EHC_SRC48_BYPASS);
    328275          break;
    329276        }
     
    341288        snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
    342289        snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
    343         snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
    344         snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
     290        snd_emu10k1_ptr20_write(emu, PLAYBACK_FIFO_END_ADDRESS, channel, 0);
     291        snd_emu10k1_ptr20_write(emu, PLAYBACK_FIFO_POINTER, channel, 0);
    345292
    346293        return 0;
     
    353300        struct snd_pcm_runtime *runtime = substream->runtime;
    354301        int channel = substream->pcm->device - emu->p16v_device_offset;
    355         u32 tmp;
    356302
    357303        /*
     
    363309               frames_to_bytes(runtime, 1));
    364310        */
    365         tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
    366311        switch (runtime->rate) {
    367312        case 44100:
    368           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
     313          snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_44100);
    369314          break;
    370315        case 96000:
    371           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
     316          snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_96000);
    372317          break;
    373318        case 192000:
    374           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
     319          snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_192000);
    375320          break;
    376321        case 48000:
    377322        default:
    378           snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
     323          snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_48000);
    379324          break;
    380325        }
    381326        /* FIXME: Check emu->buffer.size before actually writing to it. */
    382         snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
     327        snd_emu10k1_ptr20_write(emu, CAPTURE_FIFO_POINTER, channel, 0);
    383328        snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
    384329        snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes
     
    412357}
    413358
     359static void snd_p16v_interrupt(struct snd_emu10k1 *emu)
     360{
     361        unsigned int status;
     362
     363        while ((status = inl(emu->port + IPR2)) != 0) {
     364                u32 mask = INTE2_PLAYBACK_CH_0_LOOP;  /* Full Loop */
     365
     366                /* dev_dbg(emu->card->dev, "p16v status=0x%x\n", status); */
     367                if (status & mask) {
     368                        struct snd_pcm_substream *substream =
     369                                        emu->pcm_p16v->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
     370                        struct snd_pcm_runtime *runtime = substream->runtime;
     371
     372                        if (runtime && runtime->private_data) {
     373                                snd_pcm_period_elapsed(substream);
     374                        } else {
     375                                dev_err(emu->card->dev,
     376                                        "p16v: status: 0x%08x, mask=0x%08x\n",
     377                                        status, mask);
     378                        }
     379                }
     380                if (status & 0x110000) {
     381                        struct snd_pcm_substream *substream =
     382                                        emu->pcm_p16v->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
     383                        struct snd_pcm_runtime *runtime = substream->runtime;
     384
     385                        /* dev_info(emu->card->dev, "capture int found\n"); */
     386                        if (runtime && runtime->private_data) {
     387                                /* dev_info(emu->card->dev, "capture period_elapsed\n"); */
     388                                snd_pcm_period_elapsed(substream);
     389                        }
     390                }
     391                outl(status, emu->port + IPR2); /* ack all */
     392        }
     393}
     394
    414395/* trigger_playback callback */
    415396static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
     
    418399        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    419400        struct snd_pcm_runtime *runtime;
    420         struct snd_emu10k1_pcm *epcm;
    421401        int channel;
    422402        int result = 0;
     
    440420                        continue;
    441421                runtime = s->runtime;
    442                 epcm = runtime->private_data;
    443422                channel = substream->pcm->device-emu->p16v_device_offset;
    444423                /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */
    445                 epcm->running = running;
     424                runtime->private_data = (void *)(ptrdiff_t)running;
    446425                basic |= (0x1<<channel);
    447426                inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
     
    472451        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    473452        struct snd_pcm_runtime *runtime = substream->runtime;
    474         struct snd_emu10k1_pcm *epcm = runtime->private_data;
    475453        int channel = 0;
    476454        int result = 0;
     
    481459                snd_p16v_intr_enable(emu, inte);
    482460                snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
    483                 epcm->running = 1;
     461                runtime->private_data = (void *)1;
    484462                break;
    485463        case SNDRV_PCM_TRIGGER_STOP:
     
    487465                snd_p16v_intr_disable(emu, inte);
    488466                //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
    489                 epcm->running = 0;
     467                runtime->private_data = NULL;
    490468                break;
    491469        default:
     
    502480        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    503481        struct snd_pcm_runtime *runtime = substream->runtime;
    504         struct snd_emu10k1_pcm *epcm = runtime->private_data;
    505482        snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
    506483        int channel = substream->pcm->device - emu->p16v_device_offset;
    507         if (!epcm->running)
     484
     485        if (!runtime->private_data)
    508486                return 0;
    509487
     
    527505        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
    528506        struct snd_pcm_runtime *runtime = substream->runtime;
    529         struct snd_emu10k1_pcm *epcm = runtime->private_data;
    530507        snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
    531508        int channel = 0;
    532509
    533         if (!epcm->running)
     510        if (!runtime->private_data)
    534511                return 0;
    535512
     
    592569        strcpy(pcm->name, "p16v");
    593570        emu->pcm_p16v = pcm;
     571        emu->p16v_interrupt = snd_p16v_interrupt;
    594572
    595573        for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
Note: See TracChangeset for help on using the changeset viewer.