Tapan, Can you rename this file with a .old extension, replace it with attached in your intel536-537/coredrv/ directory, then $ make 537 from a root account: $ make uninstall $ make install This may crash or hang your computer if the 537 driver is not suited to your 537 modem board. - http://vouters.dyndns.org:8080/ Philippe Vouters (Fontainebleau/France)
/***************************************************************************** Copyright (c) 2001-2004, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************/ #include "afedsp_int.h" #include "softcore.h" #include "lock_lin.h" static void dsp_function(unsigned long x); void sound_function(void *x); DECLARE_TASKLET(dsp_tasklet, dsp_function, 0); DECLARE_WAIT_QUEUE_HEAD(sound_wait); struct file_operations proc_afe_operations; struct proc_dir_entry *afeproc; volatile unsigned char line_io_enabled=0; void RTS_Task(void *ptr); asmlinkage void linux_schedule(void) { schedule(); } extern void Precdialer_Task (void *t); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) struct tq_struct precdialer_task = { routine: (void (*) (void*)) Precdialer_Task, data: NULL }; DECLARE_TASKLET(sound_tasklet, sound_function, 0); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) DECLARE_WORK(prec_wq, (work_func_t)Precdialer_Task); DECLARE_WORK(sound_wq, (work_func_t)sound_function); #else DECLARE_WORK(prec_wq, Precdialer_Task, 0); DECLARE_WORK(sound_wq, sound_function, 0); #endif asmlinkage void schedule_precdialer(void) { #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) schedule_task(&precdialer_task); #else // tasklet_schedule(&rs_tasklet); schedule_work(&prec_wq); #endif } asmlinkage void *linux_kmalloc(unsigned int Sz) { return kmalloc(Sz, GFP_KERNEL); } asmlinkage void linux_kfree(void *p_) { if (p_) kfree(p_); } asmlinkage void *linux_memset(void *s, int c, unsigned long n) { return memset(s, c, (size_t)n); } asmlinkage void *linux_memcpy(void *s, const void *ct, unsigned long n) { return memcpy(s, ct, (size_t)n); } asmlinkage void linux_udelay(unsigned long usecs) { udelay(usecs); } asmlinkage long long linux_rdtscll(void) { long long t; rdtscll(t); return t; } asmlinkage void linux_gettimeofday(struct timeval *tv) { do_gettimeofday(tv); } // Used from DSP code, might be called from interrput, so GFP_ATOMIC asmlinkage void *malloc(unsigned int Sz) { return kmalloc(Sz, GFP_ATOMIC); } asmlinkage void free(void *p_) { if (p_) kfree(p_); } asmlinkage void KdPrintf(const char *fmt, ...) { char buf[512]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); #if defined (DEBUG_LINUX) printk(KERN_INFO"%s", buf); #endif } asmlinkage void DbgPrint(const char *fmt, ...) { KdPrintf(fmt); } asmlinkage int AllocateDmaResources (int dma_size) { michnl->dma_size = dma_size; michnl->bdbar = pci_alloc_consistent( devAfe->pcidev, michnl->dma_size, &michnl->bdbar_addr); if (michnl->bdbar == NULL) { return -ENOMEM; } memset(michnl->bdbar, 0, dma_size); mochnl->dma_size = dma_size; mochnl->bdbar = pci_alloc_consistent( devAfe->pcidev, mochnl->dma_size, &mochnl->bdbar_addr); if (mochnl->bdbar == NULL) { return -ENOMEM; } memset(mochnl->bdbar, 0, dma_size); return 0; } asmlinkage void release_resources (afe_device_t *dev, int level) { switch (level) { case 1: kfree(dev); break; case 2: if (sound_enabled) { remove_afeproc(); kfree((void *)dev->SysAudio.SoundBuffer); } kfree(dev->afeInternal); kfree(dev); break; default : printk(KERN_ERR"%s: Error in release_resources\n", DRIVER_NAME); } } /************************************************************************ Function name: modem_init Description: Main funktions for initializing the AFE and Hardware. it also includes allocation of buffers Inputs: Outputs: Status Err or Ok Notes: Should be called from init_module ************************************************************************** Date | Author | Change ************************************************************************** 1.06.2002 |Alex Komarov | Initial version **************************************************************************/ int modem_init (void *data) { int Status = 0; // Status information about modem initialization struct softcore_struct *driver = (struct softcore_struct *)data; //--------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------- devAfe->pcidev = driver->pci.pdev; devAfe->afe_type = driver->afe_type; switch (devAfe->afe_type) { case SELAH_PCI_VENDOR_ID + 1: case SI3052_VENDOR_ID + 2: devAfe->iobase = (unsigned int)ioremap_nocache( driver->mem_base, driver->mem_range); break; case TJ320_VENDOR_ID: devAfe->iobase = (unsigned int)ioremap_nocache( driver->io_base, driver->io_range); break; case INTEL_VENDOR_ID: case SIS_VENDOR_ID: case NVIDIA_VENDOR_ID: case TJ320_VENDOR_ID + 1: devAfe->iobase = driver->mem_base; devAfe->membase = driver->io_base; request_region(driver->io_base, driver->io_range, DRIVER_NAME); request_region(driver->mem_base, driver->mem_range, DRIVER_NAME); break; case ALI_VENDOR_ID: case VIA_VENDOR_ID: devAfe->iobase = driver->io_base; request_region(driver->io_base, driver->io_range, DRIVER_NAME); break; case ATI_VENDOR_ID: devAfe->iobase = (unsigned int)ioremap_nocache( driver->mem_base, driver->mem_range); break; default: printk(KERN_ERR"Unknown device, exiting\n"); return -1; } // Afe&DSP initialization ---------------------------------------------------------------- { unsigned int device_ids[3]; device_ids[0] = driver->pci.pdev->device; device_ids[1] = driver->pci.pdev->vendor; device_ids[2] = driver->pci.pdev->subsystem_device << 16 | driver->pci.pdev->subsystem_vendor; Status = afe_init(device_ids); if (0 != Status ) { printk(KERN_ERR"Can't initialize modem h/w\n"); release_resources((void*)devAfe, 2); return -1; } } printk(KERN_INFO "%s: Loaded\n", DRIVER_NAME); // calibrate_rdtsc(); return Status; } int sound_init(void) { // memory allocation block devAfe = (afe_device_t *)kmalloc(sizeof(afe_device_t), GFP_KERNEL); if (!devAfe) { printk(KERN_ERR "%s: Failed to init\n", DRIVER_NAME); return -ENOMEM; } memset((void*)devAfe, 0, sizeof(afe_device_t)); if (sound_enabled) { devAfe->SysAudio.SoundBuffer = kmalloc(1024, GFP_ATOMIC | GFP_DMA); if (devAfe->SysAudio.SoundBuffer == NULL) { printk(KERN_ERR"Can't allocate memory\n"); return ENOMEM; } create_afeproc(); printk(KERN_INFO"sound enabled\n"); } else { printk(KERN_INFO"sound disabled\n"); } return 0; } /************************************************************************ Function name: modem_kill Description: Cleans AFE and Layer 1 before removing module it also includes allocation of buffers Inputs: Outputs: Notes: Should be called from cleanup_module(RemoveDevice analgue) ************************************************************************** Date | Author | Change ************************************************************************** 1.06.2002 |Alex Komarov | Initial version **************************************************************************/ int modem_kill (void) { ModemCardStop(); #if !defined(AFE_S1724) if (michnl->bdbar != NULL) pci_free_consistent(devAfe->pcidev, michnl->dma_size, michnl->bdbar, michnl->bdbar_addr); if (mochnl->bdbar != NULL) pci_free_consistent(devAfe->pcidev, mochnl->dma_size, mochnl->bdbar, michnl->bdbar_addr); #endif afe_close(); if (devAfe) switch (devAfe->afe_type) { case SI3052_VENDOR_ID + 2: case TJ320_VENDOR_ID: iounmap((unsigned int*)devAfe->iobase); break; default: break; } return 0; } static void mt_function(unsigned long x) { ModemTask(pDspResources); } static void dsp_function(unsigned long x) { static unsigned long cr0; static unsigned long linux_fpe[27]; MT_AcquireLock_mt_dsp(); save_cr0_and_clts(cr0); save_fpenv(linux_fpe); DspTask(0); restore_fpenv(linux_fpe); restore_cr0(cr0); MT_ReleaseLock_mt_dsp(); } void sound_function(void *x) { SoundTask((void*)&devAfe->SysAudio); } asmlinkage int afe_irq(void) { if (sound_enabled) { #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) tasklet_schedule(&sound_tasklet); #else schedule_work(&sound_wq); #endif } tasklet_schedule(&dsp_tasklet); return 0; } // Layer 1 to process packet from Layer 2 asmlinkage void InterruptDSP(void *unused) { MT_AcquireLock_mt_dsp(); mt_function(0); MT_ReleaseLock_mt_dsp(); } static int soundSem = 0; asmlinkage int wake_up_sound(void) { wake_up_interruptible(&sound_wait); soundSem = 0; return 0; } int create_afeproc(void) { afeproc = create_proc_entry("afe", S_IFREG|S_IRUGO, NULL); if(afeproc == NULL) return -ENOMEM; afeproc->proc_fops = &proc_afe_operations; return 0; } void remove_afeproc(void) { remove_proc_entry("afe", NULL); } static int use_count = 0; static int afe_Open(struct inode * inode, struct file * file) { if (use_count) return -1; use_count++; soundSem = 1; wait_event_interruptible(sound_wait, soundSem == 0); return 0; } static int afe_Release(struct inode * inode, struct file * file) { use_count--; return 0; } static ssize_t afe_Write(struct file * file, const char * buf, size_t count, loff_t *ppos) { char tmpbuf[512]; if (file->f_flags & O_NONBLOCK) { return -EAGAIN; } if (copy_from_user(tmpbuf, buf, count)) return 0; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) circular_buffer_put(write_buffer, tmpbuf, count); #endif return count; } static ssize_t afe_Read(struct file *file, char *buf, size_t count, loff_t *ppos) { smpl_p sm = (smpl_p)buf; if (file->f_flags & O_NONBLOCK) { return -EAGAIN; } devAfe->SysAudio.wakeUpSound = 0; soundSem = 1; wait_event_interruptible(sound_wait, soundSem == 0); sm->sRate = devAfe->SysAudio.RenderSamplesPerSec; sm->sVol = devAfe->SysAudio.RenderVolumeLevel; sm->sBufLen = 96*2; // FIXME AK if(copy_to_user((void*)&sm->sBuf, (void*)devAfe->SysAudio.SoundBuffer, sm->sBufLen + sizeof(smpl_t)-1)) return -EFAULT; return sm->sBufLen + sizeof(smpl_t) - 1; } static unsigned int afe_Poll(struct file * file, poll_table * wait) { unsigned int mask = 0; poll_wait(file, &sound_wait, wait); // Wait until we have some data. This blocking behavior is unsuitable // for poll, but this call has the only client, so I can stand the consequences. mask |= POLLIN; return mask; } struct file_operations proc_afe_operations = { write: afe_Write, read: afe_Read, poll: afe_Poll, open: afe_Open, release: afe_Release, };