📄 aud_inf.c
字号:
/*----------------------------------------------------------------------------+| This source code has been made available to you by IBM on an AS-IS| basis. Anyone receiving this source is licensed under IBM| copyrights to use it in any way he or she deems fit, including| copying it, modifying it, compiling it, and redistributing it either| with or without modifications. No license under IBM patents or| patent applications is to be implied by the copyright license.|| Any user of this software should understand that IBM cannot provide| technical support for this software and will not be responsible for| any consequences resulting from the use of this software.|| Any person who transfers this source code or any derivative work| must include the IBM copyright notice, this paragraph, and the| preceding two paragraphs in the transferred software.|| COPYRIGHT I B M CORPORATION 1997, 1999, 2003| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| File: aud_inf.c| Purpose: audio driver interface layer PALLAS| Changes:| Date: Comment:| ----- --------| 15-Oct-01 create| 17-Jun-03 Added IOCTL to get current audio status| 25-Jun-03 Added support for DTS/LPCM coreload| 23-Jul-03 Added microcode version print during module init+----------------------------------------------------------------------------*/#include <linux/kernel.h> /* We're doing kernel work */#include <linux/module.h> /* Specifically, a module */#include <linux/version.h>/* For character devices *///#include <linux/sched.h>//#include <linux/tqueue.h>//#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/mm.h> /* for verify_area *//* The character device definitions are here */#include <linux/fs.h>#include <linux/devfs_fs_kernel.h>#include <asm/uaccess.h> /* for get_user, copy_from_user */#include <asm/io.h>#include <os/drv_debug.h>#include "aud_osi.h"#include "aud_osd.h"#include <aud/aud_inf.h>AUD_WRITE_STRU _adec_main ;AUD_WRITE_STRU _adec_mixer;extern void* _seg1_log;static int _open_count = 0;static int _mixer_count = 0;static int _src = -1; //no sourcevoid aud_inf_init_main(){ PDEBUG("set adec main parameter\n"); memset(&_adec_main, 0, sizeof(_adec_main)); _adec_main.ulBufPhyStart = MPEG_A_CLIP_BUF_START; _adec_main.ulBufSize = MPEG_A_CLIP_BUF_LEN; _adec_main.aud_osi_clip_init = aud_osi_init_clip; _adec_main.aud_osi_clip_close = aud_osi_close_clip; _adec_main.aud_osi_get_dev = aud_osi_get_clipdev;}void aud_inf_init_mixer(){ memset(&_adec_mixer, 0, sizeof(_adec_mixer)); _adec_mixer.ulBufPhyStart = MPEG_A_MIXER_BUF_START; _adec_mixer.ulBufSize = MPEG_A_MIXER_BUF_LEN; _adec_mixer.aud_osi_clip_init = aud_osi_init_mixer; _adec_mixer.aud_osi_clip_close = aud_osi_close_mixer; _adec_mixer.aud_osi_get_dev = aud_osi_get_mixerdev; //_adec_mixer.uMapped = 0;}static int aud_inf_open(struct inode *inode, struct file *file){ int minor = MINOR(inode->i_rdev); /* We don't talk to two processes at the same time */ PDEBUG("open\n"); if (_open_count != 0) { if(minor == DRV_MINOR_AUD_MIXER && _mixer_count == 0) { aud_inf_init_mixer(); if(aud_osd_init_clip(&_adec_mixer) == 0) { _mixer_count ++ ; MOD_INC_USE_COUNT; return 0; } else { PDEBUG("open mixer error\n"); return -1; } } else { PDEBUG("MIXER in use\n"); return -EBUSY; } } _seg1_log = ioremap(MPEG_A_SEGMENT1, MPEG_A_SEGMENT1_SIZE); if(_seg1_log == NULL) { PDEBUG("ioremap error\n"); return -1; } PDEBUG("seg1 log = %p\n", _seg1_log); aud_inf_init_main(); switch(minor) { case DRV_MINOR_AUD_MPEG: if(aud_osi_init(AUD_MODE_STB_MPEG) != 0) { PDEBUG("MPEG init osi layer error\n"); goto openFail; } break; case DRV_MINOR_AUD_AC3: if(aud_osi_init(AUD_MODE_AC3) != 0) { PDEBUG("AC3 init osi layer error\n"); goto openFail; } break; case DRV_MINOR_AUD_PCM: if(aud_osi_init(AUD_MODE_STB_PCM) != 0) { PDEBUG("mpeg init osi layer error\n"); goto openFail; } break; case DRV_MINOR_AUD_MIXER: PDEBUG("open main device first\n"); goto openFail; case DRV_MINOR_AUD_DTS: if(aud_osi_init(AUD_MODE_DTS) != 0) { PDEBUG("AC3 init osi layer error\n"); goto openFail; } break; case DRV_MINOR_AUD_LPCM: if(aud_osi_init(AUD_MODE_LPCM) != 0) { PDEBUG("AC3 init osi layer error\n"); goto openFail; } break; default: goto openFail; } _open_count++; _adec_main.uMapped = 0; _src = -1; if(_seg1_log) { iounmap(_seg1_log); _seg1_log = NULL; } MOD_INC_USE_COUNT; return 0;openFail: if(_seg1_log) { iounmap(_seg1_log); _seg1_log = NULL; } return -1;}static int aud_inf_release(struct inode *inode, struct file *file){ int minor = MINOR(inode->i_rdev); PDEBUG("close\n"); if(minor == DRV_MINOR_AUD_MIXER) { aud_osd_close_clip(&_adec_mixer); _mixer_count--; _adec_mixer.uMapped = 0; } else { if(_src == 1) { aud_osd_close_clip(&_adec_main); } aud_osi_close(); _open_count--; _adec_main.uMapped = 0; _src = -1; } MOD_DEC_USE_COUNT; return 0;}static ssize_t aud_inf_read(struct file *file, char *buffer, /* The buffer to fill with the data */ size_t length, /* The length of the buffer */ loff_t * offset) /* offset to the file */{ /* Number of bytes actually written to the buffer */ printk("code not finished\n"); return length;}/* This function is called when somebody tries to * write into our device file. */static ssize_t aud_inf_write(struct file *file, const char *buffer, size_t length, loff_t * offset){ int minor; struct inode *inode = file->f_dentry->d_inode; minor = MINOR(inode->i_rdev); if( minor == DRV_MINOR_AUD_MIXER) { PDEBUG("mixer write\n"); return aud_osd_write(&_adec_mixer, file, (void*)buffer, length); } else { PDEBUG("main write\n"); return aud_osd_write(&_adec_main, file, (void*)buffer, length); }}static int aud_inf_mmap(struct file *file, struct vm_area_struct *vma){ int minor; struct inode *inode = file->f_dentry->d_inode; minor = MINOR(inode->i_rdev); if(minor == DRV_MINOR_AUD_MIXER) { return aud_osd_mmap(&_adec_mixer, vma); } else return aud_osd_mmap(&_adec_main, vma);}/* This function is called whenever a process tries to * do an ioctl on our device file. We get two extra * parameters (additional to the inode and file * structures, which all device functions get): the number * of the ioctl called and the parameter given to the * ioctl function. * * If the ioctl is write or read/write (meaning output * is returned to the calling process), the ioctl call * returns the output of this function. */static int aud_inf_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) /* The parameter to it */{ int ret = 0; int minor = MINOR(inode->i_rdev); audioStatus aud_stat; PDEBUG("AUD_INF:device ioctl param = %d\n", ioctl_num); switch (ioctl_num) { case MPEG_AUD_STOP: if(minor == DRV_MINOR_AUD_MIXER) { PDEBUG("stop-- not support in mixer\n"); return -1; } PDEBUG("AUDIO_STOP\n"); ret = aud_osi_stop(); break; //case MPEG_AUD_CONTINUE: case MPEG_AUD_PLAY: if(minor == DRV_MINOR_AUD_MIXER) { PDEBUG("play-- not support in mixer\n"); return -1; } PDEBUG("AUDIO_PLAY\n"); ret = aud_osi_play(); break; case MPEG_AUD_SET_MUTE: if(minor == DRV_MINOR_AUD_MIXER) { PDEBUG("set mute-- not support in mixer\n"); return -1; } if(ioctl_param) { PDEBUG("set mute\n"); ret = aud_osi_mute(); } else { PDEBUG("set mute\n"); ret = aud_osi_unmute(); } break; case MPEG_AUD_SET_STREAM_TYPE: if(minor == DRV_MINOR_AUD_MIXER) { PDEBUG("set stream type-- not support in mixer\n"); return -1; } PDEBUG("set stream type = %ld\n", ioctl_param); ret = aud_osi_set_stream_type(ioctl_param); break; case MPEG_AUD_SELECT_SOURCE: PDEBUG("select source = %d\n", ioctl_param); if(minor == DRV_MINOR_AUD_MIXER) { PDEBUG("select source-- not support in mixer\n"); return -1; } ret = -1; if(_src == -1) { //set source to tv if(ioctl_param == 0) { ret = aud_osi_init_tv(); goto SetSource; } if(ioctl_param == 1) { PDEBUG("init clip\n"); //aud_inf_init_main(); ret = aud_osd_init_clip(&_adec_main); goto SetSource; } } if(_src == 0) { if(ioctl_param == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -