//////////////////////////////////////////////////// // 功能: 开打声音设备 // 输入: // 输出: // 返回: // 说明: //////////////////////////////////////////////////// void OpenMediaDevice(unsigned long sample,unsigned long channle , char mode) { //统一设置成48000,双声道,16BIT PCM模式 pcm_ioctl(PCM_SET_SAMPLE_RATE,sample); pcm_ioctl(PCM_SET_CHANNEL,channle); pcm_ioctl(PCM_SET_FORMAT,16); if( !mode ) { pcm_ioctl(PCM_SET_REPLAY,0); if( hPlayer == NULL ) hPlayer = IrqAttach(IRQ_DMA_0 + PLAYBACK_CHANNEL, IPL_AUDIO, 0, intr_handler_playback_dma, NULL); } else { pcm_ioctl(PCM_SET_RECORD,0); if( hRecord == NULL ) hRecord = IrqAttach(IRQ_DMA_0 + RECORD_CHANNEL, IPL_AUDIO, 0, intr_handler_record_dma, NULL); } if( !mode ) { #ifdef CONFIG_MAC_BDS6100A pcm_ioctl(PCM_SET_VOL,28); #else pcm_ioctl(PCM_SET_VOL,24); #endif } else pcm_ioctl(PCM_SET_VOL,0); }
void SetAudioVol(int vol) { unsigned char val=0; // printf("the vol = %d\n",vol);//treckle /* vol 0 - 99 */ /* Set the volume 0 - 31 */ switch(vol) { case 0: val=0; break; case 1: val=15; break; case 2: val=20; break; case 3: val=25; break; case 4: val=30; break; default: val=25; break; } // printf("val=%d\n",val);//treckle pcm_ioctl(PCM_SET_HP_VOL,val); // pcm_ioctl(PCM_SET_VOL,vol); return; }
static ssize_t pcm_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct pcm *pcm = file->private_data; struct audio_client *ac; struct audio_buffer *ab; const char __user *start = buf; int xfer; pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); if (!pcm->ac) pcm_ioctl(file, AUDIO_START, 0); ac = pcm->ac; if (!ac) return -ENODEV; while (count > 0) { ab = ac->buf + ac->cpu_buf; if (ab->used) if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { audio_client_dump(ac); pr_err("[%s:%s] timeout. dsp dead?\n", __MM_FILE__, __func__); q6audio_dsp_not_responding(); } pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d", __MM_FILE__, __func__, ab->data, ac->cpu_buf); xfer = count; if (xfer > ab->size) xfer = ab->size; if (copy_from_user(ab->data, buf, xfer)) return -EFAULT; buf += xfer; count -= xfer; ab->used = 1; ab->actual_size = xfer; q6audio_write(ac, ab); ac->cpu_buf ^= 1; } return buf - start; }
static ssize_t pcm_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct pcm *pcm = file->private_data; struct audio_client *ac; struct audio_buffer *ab; const char __user *start = buf; int xfer; AUDIO_INFO("%s: size = %d\n", __func__, count); if (!pcm->ac) pcm_ioctl(file, AUDIO_START, 0); ac = pcm->ac; if (!ac) return -ENODEV; while (count > 0) { ab = ac->buf + ac->cpu_buf; if (ab->used) if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { audio_client_dump(ac); pr_err("pcm_write: timeout. dsp dead?\n"); //BUG(); return -EFAULT; } xfer = count; if (xfer > ab->size) xfer = ab->size; if (copy_from_user(ab->data, buf, xfer)) return -EFAULT; buf += xfer; count -= xfer; ab->used = xfer; q6audio_write(ac, ab); ac->cpu_buf ^= 1; } return buf - start; }
void SetAudioVol(int vol) { unsigned char c, val=0; /* vol 0 - 99 it's persation */ if(vol>4) c = vol/20; else c = val; // printf("the vol=%d c=%d\n",vol,c);//treckle /* Set the volume 0 - 31 */ switch(c) { case 0: val=0; break; case 1: val=15; break; case 2: val=20; break; case 3: val=25; break; case 4: val=30; break; default: val=25; break; } // printf("val=%d\n",val);//treckle pcm_ioctl(PCM_SET_HP_VOL,val); // pcm_ioctl(PCM_SET_VOL,vol); return; }
//////////////////////////////////////////////////// // 功能: 音频初始化 // 输入: // 输出: // 返回: // 说明: //////////////////////////////////////////////////// int pcm_ioctl(unsigned int cmd, unsigned long arg) { unsigned int data, temp, aicfr, aiccr; switch (cmd) { case PCM_SET_SAMPLE_RATE: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_SAMPLE_RATE,arg = %d\n", arg); #endif set_sample_rate(arg); break; case PCM_SET_CHANNEL: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_CHANNEL,arg = %d.\n", arg); #endif if (arg == 2) __aic_disable_mono2stereo(); //CLRREG32(AIC_CR, AICCR_M2S); else if (arg == 1) __aic_enable_mono2stereo(); //SETREG32(AIC_CR, AICCR_M2S); break; case PCM_SET_FORMAT: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_FORMAT, arg = %d.\n",arg); #endif // Config for Playback aicfr = INREG32(AIC_FR) & (~AIC_FR_TFTH_MASK); aiccr = INREG32(AIC_CR) & (~AIC_CR_OSS_MASK); temp = INREG32(A_DMA_DCM(PLAYBACK_CHANNEL)) & (~DCM_DP_MASK); if (arg == 16) { aicfr |= AICFR_TFTH(16); temp |= DCM_DP_16BIT; aiccr &= ~AIC_CR_AVSTSU; aiccr |= AIC_CR_OSS_16BIT; } else if (arg == 8) { aicfr |= AICFR_TFTH(16); temp |= DCM_DP_08BIT; aiccr |= AIC_CR_AVSTSU; aiccr |= AIC_CR_OSS_8BIT; } OUTREG32(AIC_FR, aicfr); OUTREG32(AIC_CR, aiccr); OUTREG32(A_DMA_DCM(PLAYBACK_CHANNEL), temp); // Config for Recorder temp = INREG32(A_DMA_DCM(RECORD_CHANNEL)) & (~DCM_DP_MASK); if (arg == 16) temp |= DCM_DP_16BIT; else if (arg == 8) temp |= DCM_DP_08BIT; OUTREG32(A_DMA_DCM(RECORD_CHANNEL), temp); break; case PCM_SET_MUTE: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_MUTE, arg = %d.\n", arg); #endif if ((g_volume == 0) || arg == 1) { codec_reg_set(A_CODEC_CR1, DAC_MUTE); } else { codec_reg_clear(A_CODEC_CR1, DAC_MUTE); } break; case PCM_SET_VOL: case PCM_SET_HP_VOL: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_HP_VOL, val = %d.\n", arg); #endif { int RegVolume = 0, VolDif = 0, JumpCoun = 0; data = arg > 31 ? 31 : arg; g_volume = data; RegVolume = get_volume_reg(); VolDif = RegVolume > data ? (RegVolume - data) : (data - RegVolume); #ifdef KPRINTF_DEF kprintf("set volume: voldif = %d,data = %d\n",VolDif,data); #endif if (VolDif > 7) { for (JumpCoun = 0; JumpCoun <= data; JumpCoun++) { set_volume_reg(JumpCoun); //MillinsecoundDelay(10); } } else { set_volume_reg(data); } } break; case PCM_SET_PAUSE: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_PAUSE\n"); #endif MillinsecoundDelay(10); CLRREG32(AIC_CR, AIC_CR_ERPL); CLRREG32(A_DMA_DCS(PLAYBACK_CHANNEL), DCS_AR | DCS_HLT | DCS_CTE | DCS_CT); SETREG32(AIC_CR, AIC_CR_FLUSH_FIFO); OUTREG32(AIC_SR, 0x00000000); break; case PCM_SET_PLAY: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_PLAY\n"); #endif codec_reg_clear(A_CODEC_PMR1, SB_ADC); jz_audio_reset(); MillinsecoundDelay(10); codec_reg_clear(A_CODEC_CR1, HP_DIS); codec_reg_set(A_CODEC_PMR1, SB_LIN); codec_reg_clear(A_CODEC_PMR1, SB_DAC); codec_reg_set(A_CODEC_PMR1, SB_ADC); SETREG32(AIC_CR, AIC_CR_ERPL); break; case PCM_SET_REPLAY: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_REPLAY\n"); #endif CLRREG32(AIC_CR, AIC_CR_EREC); CLRREG32(A_DMA_DCS(RECORD_CHANNEL), DCS_AR | DCS_HLT | DCS_CTE | DCS_CT); codec_reg_clear(A_CODEC_CR2, ADC_HPF); codec_reg_set(A_CODEC_CR1, SB_MICBIAS); codec_reg_clear(A_CODEC_CR1, BYPASS); codec_reg_set(A_CODEC_CR1, DACSEL); codec_reg_write(A_CODEC_CR3, 0xC0); codec_reg_clear(A_CODEC_PMR2, GIM); pcm_ioctl(PCM_SET_PLAY, 0); break; case PCM_SET_RECORD: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_RECORD\n"); #endif jz_audio_reset(); codec_reg_clear(A_CODEC_CR1, SB_MICBIAS); codec_reg_write(A_CODEC_CR3, 0x40); codec_reg_set(A_CODEC_PMR2, GIM); codec_reg_set(A_CODEC_PMR1, SB_LIN); codec_reg_set(A_CODEC_CR2, ADC_HPF); codec_reg_clear(A_CODEC_PMR1, SB_ADC); codec_reg_write(A_CODEC_CGR10, 0x88); break; case PCM_SET_RECORD_FM: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_SET_RECORD_FM\n"); #endif jz_audio_reset(); codec_reg_clear(A_CODEC_CR1, DACSEL); codec_reg_set(A_CODEC_CR2, ADC_HPF); codec_reg_write(A_CODEC_CGR10, 0xff); break; case PCM_RESET: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_RESET\n"); #endif CLRREG32(A_DMA_DCS(PLAYBACK_CHANNEL), DCS_AR | DCS_HLT | DCS_CTE | DCS_CT); break; case PCM_GET_HP_VOL: return get_volume_reg(); case PCM_GET_VOL: return get_volume_reg(); case PCM_POWER_OFF: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_POWER_OFF\n"); #endif codec_reg_set(A_CODEC_CR1, DAC_MUTE); return 1; case PCM_POWER_ON: #ifdef KPRINTF_DEF kprintf("pcm_ioctl, PCM_POWER_ON\n"); #endif codec_reg_clear(A_CODEC_CR1, DAC_MUTE); return 1; default: #ifdef KPRINTF_DEF kprintf("pcm_ioctl:Unsupported I/O command: %08x\n", cmd); #endif return -1; } return 0; }
// Jagan- static ssize_t pcm_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct pcm *pcm = file->private_data; struct audio_client *ac; struct audio_buffer *ab; const char __user *start = buf; int xfer; #if 0 // Jagan+ if(!task_has_rt_policy(current)) { struct sched_param param = { .sched_priority = 99 }; printk(KERN_INFO "pcm_write to change to RT tid = %d\n", current->pid); if(sched_setscheduler_nocheck(current, SCHED_FIFO, ¶m )!=0) { printk(KERN_ERR "pcm_write fail to change to RT\n"); } } // Jagan- #endif if (!pcm->ac) pcm_ioctl(file, AUDIO_START, 0); ac = pcm->ac; if (!ac) return -ENODEV; while (count > 0) { ab = ac->buf + ac->cpu_buf; if (ab->used) if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { audio_client_dump(ac); pr_err("[%s:%s] timeout. dsp dead?\n", __MM_FILE__, __func__); q6audio_dsp_not_responding(); } xfer = count; if (xfer > ab->size) xfer = ab->size; if (copy_from_user(ab->data, buf, xfer)) return -EFAULT; buf += xfer; count -= xfer; ab->used = 1; ab->actual_size = xfer; q6audio_write(ac, ab); ac->cpu_buf ^= 1; } return buf - start; } static int pcm_release(struct inode *inode, struct file *file) { struct pcm *pcm = file->private_data; if (pcm->ac) q6audio_close(pcm->ac); kfree(pcm); pr_info("[%s:%s] release\n", __MM_FILE__, __func__); // Jagan+ if (unlikely(1 == Is_first_boot_flag)) Is_first_boot_flag = 0; // Jagan- return 0; } static struct file_operations pcm_fops = { .owner = THIS_MODULE, .open = pcm_open, .write = pcm_write, .release = pcm_release, .unlocked_ioctl = pcm_ioctl, }; struct miscdevice pcm_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "msm_pcm_out", .fops = &pcm_fops, }; static int __init pcm_init(void) { return misc_register(&pcm_misc); } device_initcall(pcm_init);
/* * Open /dev/dsp for reading or writing: */ DSPFILE *OpenDSP(WAVFILE *wfile,int omode) { int t; /* Work int */ unsigned long ul; /* Work unsigned long */ DSPFILE *dfile; if(g_dfile) CloseDSP(g_dfile); dfile = (DSPFILE *) mem_malloc(sizeof (DSPFILE)); if ( dfile == NULL ) { printf("Opening DSP device\n"); return NULL; } memset(dfile,0,sizeof *dfile); dfile->dspbuf = NULL; dfile->fd=-1; dfile->dspblksiz = 8*1024; /* * Check the range on the buffer sizes: */ /* Minimum was 4096 but es1370 returns 1024 for 44.1kHz, 16 bit */ /* and 64 for 8130Hz, 8 bit */ if ( dfile->dspblksiz < 32 || dfile->dspblksiz > 65536 ) { printf("Audio block size (%d bytes)", (int)dfile->dspblksiz); goto errxit; } /* * Allocate a buffer to do the I/O through: */ if ( (dfile->dspbuf = (char *) mem_malloc(dfile->dspblksiz)) == NULL ) { printf("For DSP I/O buffer\n"); goto errxit; } /* Reset the I2S codec */ pcm_ioctl(PCM_RESET, 0); /* * Set the data bit size: */ t = wfile->wavinfo.DataBits; if (t==8) pcm_ioctl(PCM_SET_FORMAT, 8); else pcm_ioctl(PCM_SET_FORMAT, 16); /* * Set the mode to be Stereo or Mono: */ t = wfile->wavinfo.Channels == Stereo ? 2 : 1; pcm_ioctl(PCM_SET_CHANNEL, t); /* * Set the sampling rate: */ ul = wfile->wavinfo.SamplingRate; pcm_ioctl(PCM_SET_SAMPLE_RATE,ul); /* * Return successfully opened device: */ return dfile; /* Return file descriptor */ /* * Failed to open/initialize properly: */ errxit: if ( dfile->fd >= 0 ) close(dfile->fd); /* Close device */ if ( dfile->dspbuf != NULL ) mem_free(dfile->dspbuf); mem_free(dfile); return NULL; /* Return error indication */ }