📄 patch_cnxthsf.c
字号:
unsigned int OsHdaCodecGetRevisionId(PHDAOSHAL pHdaOsHal){ return ((struct hda_codec *)pHdaOsHal->hda_codec)->revision_id;}EXPORT_SYMBOL(OsHdaCodecGetRevisionId);__shimcall__unsigned int OsHdaCodecRead(PHDAOSHAL pHdaOsHal, unsigned short nid, int direct, unsigned int verb, unsigned int para){#if 1 return snd_hda_codec_read((struct hda_codec *)pHdaOsHal->hda_codec, nid, direct, verb, para);#else unsigned int res; res = snd_hda_codec_read((struct hda_codec *)pHdaOsHal->hda_codec, nid, direct, verb, para); printk(KERN_DEBUG"%s: nid=%x direct=%d verb=0x%x para=0x%x res=0x%08x\n", __FUNCTION__, nid, direct, verb, para, res); return res;#endif}EXPORT_SYMBOL(OsHdaCodecRead);__shimcall__unsigned int OsHdaCodecWallclock(PHDAOSHAL pHdaOsHal){ return snd_hda_codec_wallclock((struct hda_codec *)pHdaOsHal->hda_codec);}EXPORT_SYMBOL(OsHdaCodecWallclock);__shimcall__void OsHdaCodecSetEventCallback(PHDAOSHAL pHdaOsHal, void (*cbHdaEvent)(void *Context, unsigned int res), void *cbHdaEventContext, unsigned char *cbHdaTag){ struct cnxthsf_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec; *cbHdaTag = ((struct hda_codec *)pHdaOsHal->hda_codec)->mfg;// printk(KERN_DEBUG"%s: codec=%p %p(%p) tag=%d\n", __FUNCTION__, pHdaOsHal->hda_codec, cbHdaEvent, cbHdaEventContext, (int)*cbHdaTag); spec->cbHdaTag = *cbHdaTag; spec->cbHdaEventContext = cbHdaEventContext; spec->cbHdaEvent = (void*)cbHdaEvent;}EXPORT_SYMBOL(OsHdaCodecSetEventCallback);__shimcall__void OsHdaCodecClearEventCallback(PHDAOSHAL pHdaOsHal, unsigned char cbHdaTag){ struct cnxthsf_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec; if(spec) {// printk(KERN_DEBUG"%s: codec=%p Tag=%d\n", __FUNCTION__, pHdaOsHal->hda_codec, cbHdaTag); spec->cbHdaEvent = NULL; spec->cbHdaEventContext = NULL; spec->cbHdaTag = 0; }}EXPORT_SYMBOL(OsHdaCodecClearEventCallback);#include <sound/pcm_params.h>static int cnxthsf_snd_pcm_change_params(snd_pcm_substream_t *substream, int hw_param_buffer_bytes){ //snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_hw_params_t *sparams; int err; sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); if (/*!params ||*/ !sparams) { return -ENOMEM; } _snd_pcm_hw_params_any(sparams); _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, hw_param_buffer_bytes, 0);#if 0 _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, hw_param_buffer_bytes / 2, 0);#endif snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) { printk(KERN_ERR"%s: SNDRV_PCM_IOCTL_HW_PARAMS failed (%d)\n", __FUNCTION__, err); //return err; } return 0;}static int cnxthsf_snd_pcm_prepare_substream(PHDAOSHAL pHdaOsHal, snd_pcm_substream_t *substream){ int err; struct cnxthsf_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec;//printk(KERN_DEBUG"%s: substream=%p\n", __FUNCTION__, substream); if(spec->do_prepare[substream->stream]) { err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); if (err < 0) { printk(KERN_ERR"%s: SNDRV_PCM_IOCTL_PREPARE failed (%d)\n", __FUNCTION__, err); return err; } spec->do_prepare[substream->stream] = 0; }#if 0 runtime->oss.prepare = 0; runtime->oss.prev_hw_ptr_interrupt = 0; runtime->oss.period_ptr = 0; runtime->oss.buffer_used = 0;#endif return 0;}__shimcall__int OsHdaCodecOpenDMA(PHDAOSHAL pHdaOsHal, int hw_param_buffer_bytes, void **ppPlaybackStream, void **ppCaptureStream){ int err; snd_pcm_t *pcm = ((struct hda_codec *)pHdaOsHal->hda_codec)->pcm_info->pcm; struct cnxthsf_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec; snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;//printk(KERN_DEBUG"%s: pcm=%p hw_param_buffer_bytes=%d\n", __FUNCTION__, pcm, hw_param_buffer_bytes); if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_PLAYBACK, &psubstream)) < 0) { printk(KERN_ERR"%s: snd_pcm_open_substream STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err); return err; } if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE, &csubstream)) < 0) { printk(KERN_ERR"%s: snd_pcm_open_substream STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err); return err; } err = snd_pcm_hw_constraints_init(psubstream); if (err < 0) { printk(KERN_ERR"%s: snd_pcm_hw_constraints_init STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err); } if ((err = psubstream->ops->open(psubstream)) < 0) { printk(KERN_ERR"%s: ops open STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err); } //psubstream->ffile = file; err = snd_pcm_hw_constraints_complete(psubstream); if (err < 0) { printk(KERN_ERR"%s: snd_pcm_hw_constraints_complete STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err); } err = snd_pcm_hw_constraints_init(csubstream); if (err < 0) { printk(KERN_ERR"%s: snd_pcm_hw_constraints_init STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err); } if ((err = csubstream->ops->open(csubstream)) < 0) { printk(KERN_ERR"%s: ops open STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err); } //csubstream->ffile = file; err = snd_pcm_hw_constraints_complete(csubstream); if (err < 0) { printk(KERN_ERR"%s: snd_pcm_hw_constraints_complete STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err); } err = cnxthsf_snd_pcm_change_params(psubstream, hw_param_buffer_bytes); if (err < 0) { printk(KERN_ERR"%s: cnxthsf_snd_pcm_change_params STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err); } err = cnxthsf_snd_pcm_change_params(csubstream, hw_param_buffer_bytes); if (err < 0) { printk(KERN_ERR"%s: cnxthsf_snd_pcm_change_params STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err); }#if 0 printk(KERN_DEBUG"%s: psubstream=%p dma_buffer_p=%p area=%p addr=0x%lx bytes=%d\n", __FUNCTION__, psubstream, psubstream->runtime->dma_buffer_p, psubstream->runtime->dma_area, (unsigned long)psubstream->runtime->dma_addr, psubstream->runtime->dma_bytes); printk(KERN_DEBUG"%s: csubstream=%p dma_buffer_p=%p area=%p addr=0x%lx bytes=%d\n", __FUNCTION__, csubstream, csubstream->runtime->dma_buffer_p, csubstream->runtime->dma_area, (unsigned long)csubstream->runtime->dma_addr, csubstream->runtime->dma_bytes);#endif#if 0 // Link both streams together if (!snd_pcm_stream_linked(psubstream)) { psubstream->group = kmalloc(sizeof(snd_pcm_group_t), GFP_ATOMIC); if (psubstream->group == NULL) { res = -ENOMEM; goto _end; } spin_lock_init(&psubstream->group->lock); INIT_LIST_HEAD(&psubstream->group->psubstreams); list_add_tail(&psubstream->link_list, &psubstream->group->substreams); psubstream->group->count = 1; } list_add_tail(&csubstream->link_list, &psubstream->group->substreams); psubstream->group->count++; csubstream->group = psubstream->group;#endif spec->do_prepare[psubstream->stream] = 1; spec->do_prepare[csubstream->stream] = 1; if ((err = cnxthsf_snd_pcm_prepare_substream(pHdaOsHal, psubstream)) < 0) return err; if ((err = cnxthsf_snd_pcm_prepare_substream(pHdaOsHal, csubstream)) < 0) return err; *ppPlaybackStream = psubstream; *ppCaptureStream = csubstream; return 0;}EXPORT_SYMBOL(OsHdaCodecOpenDMA);static void cnxthsf_snd_pcm_close_stream(snd_pcm_substream_t *substream){// printk(KERN_DEBUG"%s: substream=%p\n", __FUNCTION__, substream); snd_pcm_stream_lock_irq(substream); if (snd_pcm_running(substream)) snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); snd_pcm_stream_unlock_irq(substream); if (substream->ops->hw_free != NULL) substream->ops->hw_free(substream); substream->ops->close(substream); snd_pcm_release_substream(substream);}__shimcall__void OsHdaCodecCloseDMA(PHDAOSHAL pHdaOsHal, void *pPlaybackStream, void *pCaptureStream){ if(pHdaOsHal && pHdaOsHal->bActive) { if(pPlaybackStream) cnxthsf_snd_pcm_close_stream(pPlaybackStream); if(pCaptureStream) cnxthsf_snd_pcm_close_stream(pCaptureStream); }}EXPORT_SYMBOL(OsHdaCodecCloseDMA);__shimcall__void OsHdaCodecDMAInfo(PHDAOSHAL pHdaOsHal, void *Stream, unsigned char *StreamID, ULONG *FifoSize, short unsigned int **ppBufAddr){ struct cnxthsf_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec; snd_pcm_substream_t *substream = (snd_pcm_substream_t *)Stream;#if 0 printk(KERN_DEBUG"%s: substream=%p stream=%u id/tag=%u fifo_size=%u bufAddr=%p\n", __FUNCTION__, substream, substream->stream, spec->stream_tags[substream->stream], substream->runtime->hw.fifo_size, substream->runtime->dma_area);#endif *StreamID = spec->stream_tags[substream->stream]; *FifoSize = substream->runtime->hw.fifo_size; // XXX *ppBufAddr = (short unsigned int *)substream->runtime->dma_area;}EXPORT_SYMBOL(OsHdaCodecDMAInfo);__shimcall__int OsHdaCodecSetDMAState(PHDAOSHAL pHdaOsHal, OSHDA_STREAM_STATE streamState, void *pPlaybackStream, void *pCaptureStream){ struct cnxthsf_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec; snd_pcm_substream_t *psubstream = (snd_pcm_substream_t *)pPlaybackStream; snd_pcm_substream_t *csubstream = (snd_pcm_substream_t *)pCaptureStream; int err = 0, cmd; unsigned long flags, flags2; switch(streamState) { case OsHdaStreamStateRun:// printk(KERN_DEBUG"%s: Run\n", __FUNCTION__); if ((err = cnxthsf_snd_pcm_prepare_substream(pHdaOsHal, psubstream)) < 0) return err; if ((err = cnxthsf_snd_pcm_prepare_substream(pHdaOsHal, csubstream)) < 0) return err; cmd = SNDRV_PCM_IOCTL_START; psubstream->runtime->start_threshold = 1; psubstream->runtime->stop_threshold = psubstream->runtime->boundary; csubstream->runtime->start_threshold = 1; csubstream->runtime->stop_threshold = csubstream->runtime->boundary; break; case OsHdaStreamStateStop:// printk(KERN_DEBUG"%s: Stop\n", __FUNCTION__); cmd = SNDRV_PCM_IOCTL_DROP; break; case OsHdaStreamStateReset:// printk(KERN_DEBUG"%s: Reset\n", __FUNCTION__); cmd = SNDRV_PCM_IOCTL_RESET; psubstream->runtime->start_threshold = psubstream->runtime->boundary; csubstream->runtime->start_threshold = csubstream->runtime->boundary; break; default: printk(KERN_ERR"%s: unknown state %d\n", __FUNCTION__, streamState); return -ENOSYS; } switch(cmd) { case SNDRV_PCM_IOCTL_START: snd_pcm_stream_lock_irqsave(psubstream, flags); snd_pcm_stream_lock_irqsave(csubstream, flags2); psubstream->ops->trigger(psubstream, SNDRV_PCM_TRIGGER_START); csubstream->ops->trigger(csubstream, SNDRV_PCM_TRIGGER_START); snd_pcm_stream_unlock_irqrestore(csubstream, flags2); snd_pcm_stream_unlock_irqrestore(psubstream, flags); break; case SNDRV_PCM_IOCTL_DROP: snd_pcm_stream_lock_irqsave(psubstream, flags); snd_pcm_stream_lock_irqsave(csubstream, flags2); psubstream->runtime->start_threshold = psubstream->runtime->boundary; csubstream->runtime->start_threshold = csubstream->runtime->boundary; psubstream->ops->trigger(psubstream, SNDRV_PCM_TRIGGER_STOP); csubstream->ops->trigger(csubstream, SNDRV_PCM_TRIGGER_STOP); snd_pcm_stream_unlock_irqrestore(csubstream, flags2); snd_pcm_stream_unlock_irqrestore(psubstream, flags); break; case SNDRV_PCM_IOCTL_RESET: //psubstream->ops->trigger(psubstream, SNDRV_PCM_TRIGGER_STOP); //csubstream->ops->trigger(csubstream, SNDRV_PCM_TRIGGER_STOP); /*FALLTHROUGH*/ default: err = snd_pcm_kernel_playback_ioctl(psubstream, cmd, NULL); if (err < 0) { printk(KERN_ERR"%s: snd_pcm_kernel_playback_ioctl failed (%d)\n", __FUNCTION__, err); } err = snd_pcm_kernel_capture_ioctl(csubstream, cmd, NULL); if (err < 0) { printk(KERN_ERR"%s: snd_pcm_kernel_capture_ioctl failed (%d)\n", __FUNCTION__, err); } break; } if(cmd != SNDRV_PCM_IOCTL_START) { spec->do_prepare[psubstream->stream] = 1; spec->do_prepare[csubstream->stream] = 1; } return err;}EXPORT_SYMBOL(OsHdaCodecSetDMAState);__shimcall__unsigned long OsHdaCodecGetDMAPos(PHDAOSHAL pHdaOsHal, void *Stream){ struct hda_codec *codec = (struct hda_codec *)pHdaOsHal->hda_codec; snd_pcm_substream_t *substream = (snd_pcm_substream_t *)Stream; int ret; if(codec->bus->ops.get_linkpos) ret = codec->bus->ops.get_linkpos(substream); else ret = frames_to_bytes(substream->runtime, substream->ops->pointer(substream)); //printk(KERN_DEBUG"%s: substream=%p pos=%ld, ret=%d\n", __FUNCTION__, substream, pos, ret); return ret;}EXPORT_SYMBOL(OsHdaCodecGetDMAPos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -