📄 dbri.c
字号:
return 0; for (i=0; CS4215_FREQ[i].freq; i++) { if (CS4215_FREQ[i].freq == rate) break; } if (CS4215_FREQ[i].freq == 0) return -1; dbri->mm.ctrl[1] &= ~ 0x38; dbri->mm.ctrl[1] |= CS4215_FREQ[i].csval; dbri->mm.ctrl[2] &= ~ 0x70; dbri->mm.ctrl[2] |= CS4215_FREQ[i].xtal; dbri->perchip_info.play.sample_rate = rate; mmcodec_setctrl(dbri); mmcodec_init_data(dbri); return 0;}static int dbri_get_output_rate(struct sparcaudio_driver *drv){ struct dbri *dbri = (struct dbri *) drv->private; return dbri->perchip_info.play.sample_rate;}static int dbri_set_input_rate(struct sparcaudio_driver *drv, int rate){ return dbri_set_output_rate(drv, rate);}static int dbri_get_input_rate(struct sparcaudio_driver *drv){ return dbri_get_output_rate(drv);}/******************* sparcaudio midlevel - ports ***********************/static int dbri_set_output_port(struct sparcaudio_driver *drv, int port){ struct dbri *dbri = (struct dbri *) drv->private; port &= dbri->perchip_info.play.avail_ports; dbri->perchip_info.play.port = port; mmcodec_setgain(dbri, 0); return 0;}static int dbri_get_output_port(struct sparcaudio_driver *drv){ struct dbri *dbri = (struct dbri *) drv->private; return dbri->perchip_info.play.port;}static int dbri_set_input_port(struct sparcaudio_driver *drv, int port){ struct dbri *dbri = (struct dbri *) drv->private; port &= dbri->perchip_info.record.avail_ports; dbri->perchip_info.record.port = port; mmcodec_setgain(dbri, 0); return 0;}static int dbri_get_input_port(struct sparcaudio_driver *drv){ struct dbri *dbri = (struct dbri *) drv->private; return dbri->perchip_info.record.port;}static int dbri_get_output_ports(struct sparcaudio_driver *drv){ struct dbri *dbri = (struct dbri *) drv->private; return dbri->perchip_info.play.avail_ports;}static int dbri_get_input_ports(struct sparcaudio_driver *drv){ struct dbri *dbri = (struct dbri *) drv->private; return dbri->perchip_info.record.avail_ports;}/******************* sparcaudio midlevel - driver ID ********************/static void dbri_audio_getdev(struct sparcaudio_driver *drv, audio_device_t *audinfo){ struct dbri *dbri = (struct dbri *) drv->private; strncpy(audinfo->name, "SUNW,DBRI", sizeof(audinfo->name) - 1); audinfo->version[0] = dbri->dbri_version; audinfo->version[1] = '\0'; strncpy(audinfo->config, "onboard1", sizeof(audinfo->config) - 1);}static int dbri_sunaudio_getdev_sunos(struct sparcaudio_driver *drv){ return AUDIO_DEV_CODEC;}/******************* sparcaudio midlevel - open & close ******************/static int dbri_open(struct inode * inode, struct file * file, struct sparcaudio_driver *drv){ MOD_INC_USE_COUNT; return 0;}static void dbri_release(struct inode * inode, struct file * file, struct sparcaudio_driver *drv){ MOD_DEC_USE_COUNT;}static int dbri_ioctl(struct inode * inode, struct file * file, unsigned int x, unsigned long y, struct sparcaudio_driver *drv){ return -EINVAL;}/*********** sparcaudio midlevel - struct sparcaudio_driver ************/static struct sparcaudio_operations dbri_ops = { dbri_open, dbri_release, dbri_ioctl, dbri_start_output, dbri_stop_output, dbri_start_input, dbri_stop_input, dbri_audio_getdev, dbri_set_output_volume, dbri_get_output_volume, dbri_set_input_volume, dbri_get_input_volume, dbri_set_monitor_volume, dbri_get_monitor_volume, dbri_set_output_balance, dbri_get_output_balance, dbri_set_input_balance, dbri_get_input_balance, dbri_set_output_channels, dbri_get_output_channels, dbri_set_input_channels, dbri_get_input_channels, dbri_set_output_precision, dbri_get_output_precision, dbri_set_input_precision, dbri_get_input_precision, dbri_set_output_port, dbri_get_output_port, dbri_set_input_port, dbri_get_input_port, dbri_set_output_encoding, dbri_get_output_encoding, dbri_set_input_encoding, dbri_get_input_encoding, dbri_set_output_rate, dbri_get_output_rate, dbri_set_input_rate, dbri_get_input_rate, dbri_sunaudio_getdev_sunos, dbri_get_output_ports, dbri_get_input_ports, dbri_set_output_muted, dbri_get_output_muted,};/******************************************************************************************************* ISDN (Hisax) Interface *******************************************************************************************************/void dbri_isdn_init(struct dbri *dbri){ /* Pipe 0: Receive D channel * Pipe 8: Receive B1 channel * Pipe 9: Receive B2 channel * Pipe 1: Transmit D channel * Pipe 10: Transmit B1 channel * Pipe 11: Transmit B2 channel */ setup_pipe(dbri, 0, D_SDP_HDLC | D_SDP_FROM_SER | D_SDP_LSB); setup_pipe(dbri, 8, D_SDP_HDLC | D_SDP_FROM_SER | D_SDP_LSB); setup_pipe(dbri, 9, D_SDP_HDLC | D_SDP_FROM_SER | D_SDP_LSB); setup_pipe(dbri, 1, D_SDP_HDLC_D | D_SDP_TO_SER | D_SDP_LSB); setup_pipe(dbri,10, D_SDP_HDLC | D_SDP_TO_SER | D_SDP_LSB); setup_pipe(dbri,11, D_SDP_HDLC | D_SDP_TO_SER | D_SDP_LSB); link_time_slot(dbri, 0, PIPEinput, 0, 2, 17); link_time_slot(dbri, 8, PIPEinput, 0, 8, 0); link_time_slot(dbri, 9, PIPEinput, 8, 8, 8); link_time_slot(dbri, 1, PIPEoutput, 1, 2, 17); link_time_slot(dbri, 10, PIPEoutput, 1, 8, 0); link_time_slot(dbri, 11, PIPEoutput, 10, 8, 8);}int dbri_get_irqnum(int dev){ struct dbri *dbri; if (dev >= num_drivers) return(0); dbri = (struct dbri *) drivers[dev].private; tprintk(("dbri_get_irqnum()\n")); /* On the sparc, the cpu's irq number is only part of the "irq" */ return (dbri->irq & NR_IRQS);}int dbri_get_liu_state(int dev){ struct dbri *dbri; if (dev >= num_drivers) return(0); dbri = (struct dbri *) drivers[dev].private; tprintk(("dbri_get_liu_state() returns %d\n", dbri->liu_state)); return dbri->liu_state;}void dbri_liu_activate(int dev, int priority);void dbri_liu_init(int dev, void (*callback)(void *), void *callback_arg){ struct dbri *dbri; if (dev >= num_drivers) return; dbri = (struct dbri *) drivers[dev].private; tprintk(("dbri_liu_init()\n")); /* Set callback for LIU state change */ dbri->liu_callback = callback; dbri->liu_callback_arg = callback_arg; dbri_isdn_init(dbri); dbri_liu_activate(dev, 0);}void dbri_liu_activate(int dev, int priority){ struct dbri *dbri; int val; volatile s32 *cmd; if (dev >= num_drivers) return; dbri = (struct dbri *) drivers[dev].private; tprintk(("dbri_liu_activate()\n")); if (dbri->liu_state <= 3) { u32 tmp; cmd = dbri_cmdlock(dbri); /* Turn on the ISDN TE interface and request activation */ val = D_NT_IRM_IMM | D_NT_IRM_EN | D_NT_ACT;#ifdef LOOPBACK_D val |= D_NT_LLB(4);#endif *(cmd++) = DBRI_CMD(D_TE, 0, val); dbri_cmdsend(dbri, cmd); /* Activate the interface */ tmp = sbus_readl(dbri->regs + REG0); tmp |= D_T; sbus_writel(tmp, dbri->regs + REG0); }}void dbri_liu_deactivate(int dev){ struct dbri *dbri;#if 0 u32 tmp;#endif if (dev >= num_drivers) return; dbri = (struct dbri *) drivers[dev].private; tprintk(("dbri_liu_deactivate()\n"));#if 0 /* Turn off the ISDN TE interface */ tmp = sbus_readl(dbri->regs + REG0); tmp &= ~D_T; sbus_writel(tmp, dbri->regs + REG0); dbri->liu_state = 0;#endif}void dbri_dxmit(int dev, __u8 *buffer, unsigned int count, void (*callback)(void *, int), void *callback_arg){ struct dbri *dbri; if (dev >= num_drivers) return; dbri = (struct dbri *) drivers[dev].private; /* Pipe 1 is D channel transmit */ xmit_on_pipe(dbri, 1, buffer, count, callback, callback_arg);}void dbri_drecv(int dev, __u8 *buffer, unsigned int size, void (*callback)(void *, int, unsigned int), void *callback_arg){ struct dbri *dbri; if (dev >= num_drivers) return; dbri = (struct dbri *) drivers[dev].private; /* Pipe 0 is D channel receive */ recv_on_pipe(dbri, 0, buffer, size, callback, callback_arg);}int dbri_bopen(int dev, unsigned int chan, int hdlcmode, u_char xmit_idle_char){ struct dbri *dbri; if (dev >= num_drivers || chan > 1) return -1; dbri = (struct dbri *) drivers[dev].private; if (hdlcmode) { /* return -1; */ /* Pipe 8/9: receive B1/B2 channel */ setup_pipe(dbri, 8+chan, D_SDP_HDLC | D_SDP_FROM_SER|D_SDP_LSB); /* Pipe 10/11: transmit B1/B2 channel */ setup_pipe(dbri,10+chan, D_SDP_HDLC | D_SDP_TO_SER | D_SDP_LSB); } else { /* !hdlcmode means transparent */ /* Pipe 8/9: receive B1/B2 channel */ setup_pipe(dbri, 8+chan, D_SDP_MEM | D_SDP_FROM_SER|D_SDP_LSB); /* Pipe 10/11: transmit B1/B2 channel */ setup_pipe(dbri,10+chan, D_SDP_MEM | D_SDP_TO_SER | D_SDP_LSB); } return 0;}void dbri_bclose(int dev, unsigned int chan){ struct dbri *dbri; if (dev >= num_drivers || chan > 1) return; dbri = (struct dbri *) drivers[dev].private; reset_pipe(dbri, 8+chan); reset_pipe(dbri, 10+chan);}void dbri_bxmit(int dev, unsigned int chan, __u8 *buffer, unsigned long count, void (*callback)(void *, int), void *callback_arg){ struct dbri *dbri; if (dev >= num_drivers || chan > 1) return; dbri = (struct dbri *) drivers[dev].private; /* Pipe 10/11 is B1/B2 channel transmit */ xmit_on_pipe(dbri, 10+chan, buffer, count, callback, callback_arg);}void dbri_brecv(int dev, unsigned int chan, __u8 *buffer, unsigned long size, void (*callback)(void *, int, unsigned int), void *callback_arg){ struct dbri *dbri; if (dev >= num_drivers || chan > 1) return; dbri = (struct dbri *) drivers[dev].private; /* Pipe 8/9 is B1/B2 channel receive */ recv_on_pipe(dbri, 8+chan, buffer, size, callback, callback_arg);}#if defined(DBRI_ISDN)struct foreign_interface dbri_foreign_interface = { dbri_get_irqnum, dbri_get_liu_state, dbri_liu_init, dbri_liu_activate, dbri_liu_deactivate, dbri_dxmit, dbri_drecv, dbri_bopen, dbri_bclose, dbri_bxmit, dbri_brecv};EXPORT_SYMBOL(dbri_foreign_interface);#endif/********************************************************************************************************* Initialization *************************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -