📄 hi_sio.c
字号:
put_user(result,(unsigned int *)arg); break; case GET_SIO_RX_BITWIDTH: HI_REG_READ16(SIO_I2S_CT_SET(0), result); result &= 0x02; result = result>>1; put_user(result,(unsigned int *)arg); break; case GET_SIO_I2SMODE: HI_REG_READ16(SIO_WORK_MODE(0), result); result &= 0x01; if (result) { result = 0; put_user(result,(unsigned int *)arg); break; } HI_REG_READ16(SIO_I2S_CT_SET(0), result); result &= 0x0c; result = result >> 2; if (result) result = 2; else result = 1; put_user(result,(unsigned int *)arg); break; case SET_SIO_SAMPLERATE: if(arg<0 || arg>12) { printk("the input samplerate is invalid\n"); } else { samplerate_record_0 = arg; ahbFreqtmp = ahbFreqDectect(); result = ahbFreqtmp/(32*samplerate_list[arg])-1; HI_REG_WRITE16(SIO_ICD_SET(0), result); } break; case SET_SIO_TX_BITWIDTH: if (arg) HI_REG_WRITE16(SIO_I2S_CT_SET(0), SIO_I2S_TX_16BIT_SET); else HI_REG_WRITE16(SIO_I2S_CT_CLR(0), SIO_I2S_TX_8BIT_CLR); break; case SET_SIO_RX_BITWIDTH: if (arg) HI_REG_WRITE16(SIO_I2S_CT_SET(0), SIO_I2S_RX_16BIT_SET); else HI_REG_WRITE16(SIO_I2S_CT_CLR(0), SIO_I2S_RX_8BIT_CLR); break; case SET_SIO_I2SMODE: if (arg == 2 ) { HI_REG_WRITE16(SIO_I2S_CT_SET(0), SIO_I2S_TX_WS_SEL_EX_SET); HI_REG_WRITE16(SIO_I2S_CT_SET(0), SIO_I2S_TX_CLK_SEL_EX_SET); } else if(arg == 1) { HI_REG_WRITE16(SIO_I2S_CT_CLR(0), SIO_I2S_TX_CLK_SEL_IN_CLR); HI_REG_WRITE16(SIO_I2S_CT_CLR(0), SIO_I2S_TX_WS_SEL_IN_CLR); } break; case I2S_RX_ENABLE: HI_REG_WRITE16(SIO_I2S_CT_SET(0), SIO_I2S_RX_ENABLE_SET); break; case I2S_RX_DISABLE: HI_REG_WRITE16(SIO_I2S_CT_CLR(0), SIO_I2S_RX_ENABLE_SET); break; case I2S_TX_ENABLE: HI_REG_WRITE16(SIO_I2S_CT_SET(0), SIO_I2S_TX_ENABLE_SET); break; case I2S_TX_DISABLE: HI_REG_WRITE16(SIO_I2S_CT_CLR(0), SIO_I2S_TX_ENABLE_SET); break; case SET_PCM_CT: HI_REG_WRITE16(SIO_PCM_CT_CLR(0), 0xff); HI_REG_WRITE16(SIO_PCM_CT_SET(0), arg); break; case GET_PCM_CT: HI_REG_READ16(SIO_PCM_CT_SET(0), result); put_user(result,(unsigned int *)arg); break; case ENABLE_LOOP: ret = request_irq(25,&sio_0_int,SA_INTERRUPT,"sio_0",NULL); if(ret != 0) { printk("request_irq_0 error!\n"); return -1; } break; case DISABLE_LOOP: free_irq(25,NULL); break; default: printk("Error SIO_0 setting cmd\n"); return -1; } return 0; }/* 设置 SIO 工作参数 * 参数cmd: 控制命令 * 参数arg: 命令参数 */static int hi_sio_1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ unsigned int ahbFreqtmp; unsigned int result; int ret; switch (cmd) { case GET_SIO_SAMPLERATE: put_user(samplerate_record_1,(unsigned int *)arg); break; case GET_SIO_TX_BITWIDTH: HI_REG_READ16(SIO_I2S_CT_SET(1), result); result &= 0x01; put_user(result,(unsigned int *)arg); break; case GET_SIO_RX_BITWIDTH: HI_REG_READ16(SIO_I2S_CT_SET(1), result); result &= 0x02; result = result>>1; put_user(result,(unsigned int *)arg); break; case GET_SIO_I2SMODE: HI_REG_READ16(SIO_WORK_MODE(1), result); result &= 0x01; if (result) { result = 0; put_user(result,(unsigned int *)arg); break; } HI_REG_READ16(SIO_I2S_CT_SET(1), result); result &= 0x0c; result = result >> 2; if (result) result = 2; else result = 1; put_user(result,(unsigned int *)arg); break; case SET_SIO_SAMPLERATE: if(arg<0 || arg>12) { printk("the input samplerate is invalid\n"); } else { samplerate_record_1 = arg; ahbFreqtmp = ahbFreqDectect(); result = ahbFreqtmp/(32*samplerate_list[arg])-1; HI_REG_WRITE16(SIO_ICD_SET(1), result); } break; case SET_SIO_TX_BITWIDTH: if (arg) HI_REG_WRITE16(SIO_I2S_CT_SET(1), SIO_I2S_TX_16BIT_SET); else HI_REG_WRITE16(SIO_I2S_CT_CLR(1), SIO_I2S_TX_8BIT_CLR); break; case SET_SIO_RX_BITWIDTH: if (arg) HI_REG_WRITE16(SIO_I2S_CT_SET(1), SIO_I2S_RX_16BIT_SET); else HI_REG_WRITE16(SIO_I2S_CT_CLR(1), SIO_I2S_RX_8BIT_CLR); break; case SET_SIO_I2SMODE: if (arg == 2 ) { HI_REG_WRITE16(SIO_I2S_CT_SET(1), SIO_I2S_TX_WS_SEL_EX_SET); HI_REG_WRITE16(SIO_I2S_CT_SET(1), SIO_I2S_TX_CLK_SEL_EX_SET); } else if(arg == 1) { HI_REG_WRITE16(SIO_I2S_CT_CLR(1), SIO_I2S_TX_CLK_SEL_IN_CLR); HI_REG_WRITE16(SIO_I2S_CT_CLR(1), SIO_I2S_TX_WS_SEL_IN_CLR); } break; case I2S_RX_ENABLE: HI_REG_WRITE16(SIO_I2S_CT_SET(1), SIO_I2S_RX_ENABLE_SET); break; case I2S_RX_DISABLE: HI_REG_WRITE16(SIO_I2S_CT_CLR(1), SIO_I2S_RX_ENABLE_SET); break; case I2S_TX_ENABLE: HI_REG_WRITE16(SIO_I2S_CT_SET(1), SIO_I2S_TX_ENABLE_SET); break; case I2S_TX_DISABLE: HI_REG_WRITE16(SIO_I2S_CT_CLR(1), SIO_I2S_TX_ENABLE_SET); break; case SET_PCM_CT: HI_REG_WRITE16(SIO_PCM_CT_CLR(1), 0xff); HI_REG_WRITE16(SIO_PCM_CT_SET(1), arg); break; case GET_PCM_CT: HI_REG_READ16(SIO_PCM_CT_SET(1), result); put_user(result,(unsigned int *)arg); break; case SIO_1_INIT: sio_drv_init(SIO_1); ch1 = 1; break; case ENABLE_LOOP: ret = request_irq(29,&sio_1_int,SA_INTERRUPT,"sio_1",NULL); if(ret != 0) { printk("request_irq_1 error!\n"); return -1; } break; case DISABLE_LOOP: free_irq(29,NULL); break; default: printk("Error SIO_0 setting cmd\n"); return -1; } return 0; }/* * device open. set counter */static int hi_sio_0_open(struct inode * inode, struct file * file){ open_cnt_0++; return 0; }/* * device open. set counter */static int hi_sio_1_open(struct inode * inode, struct file * file){ open_cnt_1++; return 0; }/* * Close device, Do nothing! */static int hi_sio_0_close(struct inode *inode ,struct file *file){ open_cnt_0--; return 0;}/* * Close device, Do nothing! */static int hi_sio_1_close(struct inode *inode ,struct file *file){ open_cnt_1--; return 0;}static struct file_operations hi_sio_0_fops = { .owner = THIS_MODULE, .ioctl = hi_sio_0_ioctl, .open = hi_sio_0_open, .release = hi_sio_0_close,};static struct file_operations hi_sio_1_fops = { .owner = THIS_MODULE, .ioctl = hi_sio_1_ioctl, .open = hi_sio_1_open, .release = hi_sio_1_close,};static struct miscdevice hi_sio_0_miscdev ={ .minor = MISC_DYNAMIC_MINOR, .name = "hi_sio_0", .fops = &hi_sio_0_fops,};static struct miscdevice hi_sio_1_miscdev ={ .minor = MISC_DYNAMIC_MINOR, .name = "hi_sio_1", .fops = &hi_sio_1_fops,};static int __init sio_module_init(void){ unsigned int ret; ret = misc_register(&hi_sio_0_miscdev); if (ret < 0) { printk(DEVICE_NAME_0 "can't register major number\n"); return ret; } ret = misc_register(&hi_sio_1_miscdev); if (ret < 0) { misc_deregister(&hi_sio_0_miscdev); printk(DEVICE_NAME_1 "can't register major number\n"); return ret; } sio_drv_init(SIO_0); if(ch1) sio_drv_init(SIO_1); /* ret = request_irq(25,&sio_0_int,SA_INTERRUPT,"sio_0",NULL); if(ret != 0) { misc_deregister(&hi_sio_0_miscdev); printk("request_irq_0 error!\n"); return ret; }*/ /* ret = request_irq(29,&sio_1_int,SA_INTERRUPT,"sio_1",NULL); if(ret != 0) { free_irq(29,NULL); misc_deregister(&hi_sio_1_miscdev); printk("request_irq_1 error!\n"); return ret; } */ //HI_REG_WRITE16(SIO_INTR_CLR(SIO_0),0x03); //HI_REG_WRITE16(SIO_INTR_CLR(SIO_1),0x03); printk("Hi3510 sio Driver v1.0\n"); return 0;}static void __exit sio_module_exit(void) { if(open_cnt_1 || open_cnt_0) printk("the sio is still in use!\n"); else { sio_drv_exit(SIO_0); if(ch1) sio_drv_exit(SIO_1); //free_irq(25,NULL); //free_irq(29,NULL); misc_deregister(&hi_sio_0_miscdev); misc_deregister(&hi_sio_1_miscdev); }}module_init(sio_module_init);module_exit(sio_module_exit);module_param(ch1, int, 0);MODULE_PARM_DESC(ch1, "enable sio_1:ch1=1;disable sio_1:ch1=0; defult enable!");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -