void sniffer_sniff_scan_irq(struct coa_info *dev, int irq) { volatile uint16_t *sc14421_base = dev->sc14421_base; int ret; uint8_t station[7]; if (dev->open) { SC14421_switch_to_bank(sc14421_base, SC14421_RAMBANK1); if ( (SC14421_READ(1) & 0xc0) == 0xc0) /* Checksum ok */ { uint8_t rssi = SC14421_READ(0); from_dip(fppacket + 5, sc14421_base + 6, 6); SC14421_WRITE(1, 0); /* Clear Checksum-Flag */ if (dect_is_RFPI_Packet(fppacket)) { station[0] = dev->sniffer_config->channel; station[1] = rssi; memcpy(&station[2], &fppacket[6], 5); /* RFPI */ ret = kfifo_in_locked(&dev->rx_fifo, station, 7, &dev->rx_fifo_lock); if (ret <= 0) { printk("com_on_air_cs: rx fifo full? " "kfifo_in_locked() = %d\n", ret); } } } } }
static ssize_t plp_kmem_write(struct file *filp, const char __user *buf,size_t count, loff_t *pos) { P_SERIAL_DEV *dev= filp->private_data; int bytes; printk (">>>>>>>>>In write call\n"); if (kfifo_is_full(&(dev->write_kfifo))) { if (filp->f_flags & O_NONBLOCK) return -EAGAIN; else wait_event_interruptible(dev->write_queue, !kfifo_is_full(&(dev->write_kfifo))) ; } if (access_ok (VERIFY_READ, (void __user *) buf, (unsigned long) count)) { bytes = kfifo_in_locked(&(dev->write_kfifo),(void __user *) buf,count,&(dev->wr_spinlock)); outb (0x03, base_addr + 1); //IER ,enabling Tx & Rx buffer interrupt ERBFI & EXBFI return bytes; } else return -EFAULT; }
/** * usb_serial_generic_write - generic write function for serial USB devices * @tty: Pointer to &struct tty_struct for the device * @port: Pointer to the &usb_serial_port structure for the device * @buf: Pointer to the data to write * @count: Number of bytes to write * * Returns the number of characters actually written, which may be anything * from zero to @count. If an error occurs, it returns the negative errno * value. */ int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; int result; dbg("%s - port %d", __func__, port->number); /* only do something if we have a bulk out endpoint */ if (!port->bulk_out_size) return -ENODEV; if (count == 0) { dbg("%s - write request of 0 bytes", __func__); return 0; } if (serial->type->max_in_flight_urbs) return usb_serial_multi_urb_write(tty, port, buf, count); count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port); if (result >= 0) result = count; return result; }
static int pollSwitches(void *unused) { while (!kthread_should_stop()) { unsigned char value = ioread8(switchesIOBase); if (value != lastValue) { if (lastValue != -1) { // Add new event to queue if (!kfifo_in_locked(&events, &value, 1, &eventsLock)) { printk(KERN_WARNING MODULE_LABEL "Event buffer is full, new event was ignored!\n"); } //printk("notify wait queue\n"); wake_up_interruptible_all(&areEventsAvailableWaitQueue); } lastValue = value; } if (!kthread_should_stop()) { msleep_interruptible(100); } } return 0; }
void srp_iu_put(struct iu_entry *iue) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); #else kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *), &iue->target->iu_queue.lock); #endif }
static void tmsi_enqueue_data(struct tmsi_data *dev, const char * buffer, size_t length) { if (length == 0) return; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) kfifo_in_spinlocked(dev->packet_buffer, buffer, length, &dev->buffer_lock); #elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32) kfifo_in_locked(dev->packet_buffer, buffer, length, &dev->buffer_lock); #else kfifo_put(dev->packet_buffer, buffer, length); #endif up(dev->fifo_sem); }
/** * usb_serial_generic_write - generic write function * @tty: tty for the port * @port: usb-serial port * @buf: data to write * @count: number of bytes to write * * Return: The number of characters buffered, which may be anything from * zero to @count, or a negative errno value. */ int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { int result; if (!port->bulk_out_size) return -ENODEV; if (!count) return 0; count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port, GFP_ATOMIC); if (result) return result; return count; }
/** * usb_serial_generic_write - generic write function for serial USB devices * @tty: Pointer to &struct tty_struct for the device * @port: Pointer to the &usb_serial_port structure for the device * @buf: Pointer to the data to write * @count: Number of bytes to write * * Returns the number of characters actually written, which may be anything * from zero to @count. If an error occurs, it returns the negative errno * value. */ int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { int result; /* only do something if we have a bulk out endpoint */ if (!port->bulk_out_size) return -ENODEV; if (!count) return 0; count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port); if (result) return result; return count; }
/* * V4L2 Subdevice IR Ops */ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled) { struct cx23888_ir_state *state = to_state(sd); struct cx23885_dev *dev = state->dev; unsigned long flags; u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG); union cx23888_ir_fifo_rec rx_data[FIFO_RX_DEPTH]; unsigned int i, j, k; u32 events, v; int tsr, rsr, rto, ror, tse, rse, rte, roe, kror; tsr = stats & STATS_TSR; /* Tx FIFO Service Request */ rsr = stats & STATS_RSR; /* Rx FIFO Service Request */ rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */ ror = stats & STATS_ROR; /* Rx FIFO Over Run */ tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */ rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */ rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */ roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */ *handled = false; v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n", tsr ? "tsr" : " ", rsr ? "rsr" : " ", rto ? "rto" : " ", ror ? "ror" : " ", stats & STATS_TBY ? "tby" : " ", stats & STATS_RBY ? "rby" : " "); v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n", tse ? "tse" : " ", rse ? "rse" : " ", rte ? "rte" : " ", roe ? "roe" : " "); /* * Transmitter interrupt service */ if (tse && tsr) { /* * TODO: * Check the watermark threshold setting * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo * Push the data to the hardware FIFO. * If there was nothing more to send in the tx_kfifo, disable * the TSR IRQ and notify the v4l2_device. * If there was something in the tx_kfifo, check the tx_kfifo * level and notify the v4l2_device, if it is low. */ /* For now, inhibit TSR interrupt until Tx is implemented */ irqenable_tx(dev, 0); events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ; v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events); *handled = true; } /* * Receiver interrupt service */ kror = 0; if ((rse && rsr) || (rte && rto)) { /* * Receive data on RSR to clear the STATS_RSR. * Receive data on RTO, since we may not have yet hit the RSR * watermark when we receive the RTO. */ for (i = 0, v = FIFO_RX_NDV; (v & FIFO_RX_NDV) && !kror; i = 0) { for (j = 0; (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) { v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG); rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV; i++; } if (i == 0) break; j = i * sizeof(union cx23888_ir_fifo_rec); k = kfifo_in_locked(&state->rx_kfifo, (unsigned char *) rx_data, j, &state->rx_kfifo_lock); if (k != j) kror++; /* rx_kfifo over run */ } *handled = true; } events = 0; v = 0; if (kror) { events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN; v4l2_err(sd, "IR receiver software FIFO overrun\n"); } if (roe && ror) { /* * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear * the Rx FIFO Over Run status (STATS_ROR) */ v |= CNTRL_RFE; events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN; v4l2_err(sd, "IR receiver hardware FIFO overrun\n"); } if (rte && rto) { /* * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear * the Rx Pulse Width Timer Time Out (STATS_RTO) */ v |= CNTRL_RXE; events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED; } if (v) { /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */ cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v); cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); *handled = true; } spin_lock_irqsave(&state->rx_kfifo_lock, flags); if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); if (events) v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); return 0; }
void srp_iu_put(struct iu_entry *iue) { kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *), &iue->target->iu_queue.lock); }
void sniffer_sniff_sync_irq(struct coa_info *dev, int irq) { volatile uint16_t *sc14421_base = dev->sc14421_base; struct sniffer_cfg *config = dev->sniffer_config; struct sniffed_packet packet; int ret; int slot; int a; int memofs; SC14421_switch_to_bank(sc14421_base, SC14421_RAMBANK1); if (!(config->status & SNIFF_STATUS_FOUNDSTATION)) { if (irq & 0x01) { #if 0 printk("N:"); for (i=0; i<16; i++) printk("%.2x ", SC14421_READ(i)); printk("\n"); #endif if ( (SC14421_READ(1) & 0xc0) == 0xc0) /* Checksum ok */ { SC14421_WRITE(1, 0); /* clear checksum flag */ from_dip(fppacket + 5,sc14421_base + 6, 6); if (dect_compare_RFPI(fppacket, config->RFPI)) { printk("found station for sync\n"); config->status |= SNIFF_STATUS_FOUNDSTATION; SC14421_switch_to_bank(sc14421_base,SC14421_CODEBANK); switch(dev->radio_type) { case COA_RADIO_TYPE_II: SC14421_write_cmd(sc14421_base, PPFoundII, BR, RecvNextII); break; case COA_RADIO_TYPE_III: SC14421_write_cmd(sc14421_base, PPFoundIII, BR, RecvNextIII); break; default: printk("ERROR: this radio type is currently not " "supported. please update the driver\n"); } } } } } else if (!(config->status & SNIFF_STATUS_INSYNC)) { if (irq & 0x01) { #if 0 printk("S:"); for (i=0; i<16; i++) printk("%.2x ", SC14421_READ(i)); printk("\n"); #endif if ( (SC14421_READ(1) & 0xc0) == 0xc0) /* Checksum ok */ { SC14421_WRITE(1, 0); /* clear checksum flag */ from_dip(fppacket + 5, sc14421_base + 6, 48); slot = dect_get_slot(fppacket); if (slot != -1) { printk("station in slot %u\n", slot); config->status |= SNIFF_STATUS_INSYNC; slot %= 12; if (slot%2) printk("slot not possible with this firmware\n"); config->slottable[slot].active = 1; config->slottable[slot].channel = config->channel; config->slottable[slot].type = DECT_SLOTTYPE_CARRIER; config->slottable[slot].errcnt = 0; sniffer_sync_patchloop(dev,config->slottable,SNIFF_SLOTPATCH_FP); sniffer_sync_patchloop(dev,config->slottable,SNIFF_SLOTPATCH_PP); SC14421_switch_to_bank(sc14421_base,SC14421_CODEBANK); printk("set jump to %u\n",sync_jumptable[slot]); switch(dev->radio_type) { case COA_RADIO_TYPE_II: SC14421_write_cmd(sc14421_base,PPFoundII,BR,sync_jumptable[slot]); break; case COA_RADIO_TYPE_III: SC14421_write_cmd(sc14421_base,PPFoundIII,BR,sync_jumptable[slot]); break; default: printk("ERROR: this radio type is currently not " "supported. please update the driver\n"); } printk("we are in sync :)\n"); packet.rssi = SC14421_READ(0x00); packet.channel = config->channel; packet.slot = slot; memcpy(packet.data, fppacket, 53); packet.timestamp = dev->irq_timestamp; ret = kfifo_in_locked(&dev->rx_fifo,(unsigned char*) &packet,sizeof(struct sniffed_packet), &dev->rx_fifo_lock); if (ret <= 0) printk("com_on_air_cs: rx fifo " "full? kfifo_in_locked() " "= %d\n", ret); } } } } else { if ( (irq & 0x09) == 0x09) printk("com_on_air-cs: interrupt processing too slow , lost packets!\n"); if (irq & 0x01) { for (a=0; a<12; a++) { if (config->slottable[a].active) { SC14421_switch_to_bank(sc14421_base,sync_banktable[a]); if ( (a/2) % 2) memofs = 0x80; else memofs = 0x00; #if 0 printk("F:"); for (i=0; i<16; i++) printk("%.2x ",(unsigned char) SC14421_READ(i+memofs)); printk(" : %.2x : %x\n", irq, a); #endif if ( (SC14421_READ(1+memofs) & 0xc0) == 0xc0) /* Checksum ok */ { unsigned char bfok = ((SC14421_READ(1+memofs) & 0x03) == 0x03)<<7; /* BField Checksum ok */ struct sniffed_packet packet; packet.rssi = SC14421_READ(memofs); packet.channel = config->slottable[a].channel; packet.slot = a; memcpy(packet.data,fppacket,5); from_dip(&packet.data[5],sc14421_base+memofs+6, 48); if (config->slottable[a].type == DECT_SLOTTYPE_SCAN) /* we received data on a scan-slot, * channel is incemented before, * but we want hear the old channel */ { packet.channel--; //printk("slot in scanmode\n"); } if (dect_is_multiframe_number(packet.data)) /* if there was a multiframe number, * then this packet was in frame 8 (0) */ { //printk("found multiframe number\n"); config->framenumber = 1; } /* if (dev->open) */ { if(config->framenumber) packet.frameflags = (config->framenumber-1)|bfok; else packet.frameflags = 7|bfok; packet.timestamp = dev->irq_timestamp; ret = kfifo_in_locked(&dev->rx_fifo, (unsigned char*) &packet, sizeof(struct sniffed_packet), &dev->rx_fifo_lock); if (ret <= 0) { printk("com_on_air_cs: rx fifo full? kfifo_in_locked() = %d\n", ret); } } #if 0 printk("F:"); for (i=0; i<16; i++) printk("%.2x ", SC14421_READ(i+memofs)); printk(" : %.2x : %x\n", irq, a); #endif SC14421_WRITE(1+memofs, 0); /* clear checksum flag */ if (dect_update_slottable(config->slottable, a, packet.data)) { config->updateppslots = 1; config->updatefpslots = 1; //printk("new slot , must update slots\n"); } } else { if (dect_receive_error(config->slottable, a)) { config->updateppslots = 1; config->updatefpslots = 1; //printk("1:died slot , must update slots\n"); } } } } if ( (!(irq & 0x08)) && (config->updatefpslots) ) { //printk("patching fp slots\n"); sniffer_sync_patchloop(dev, config->slottable, SNIFF_SLOTPATCH_FP); config->updatefpslots = 0; } } if (irq & 0x08) { for (a=12; a<24; a++) { if (config->slottable[a].active) { SC14421_switch_to_bank(sc14421_base, sync_banktable[a]); if ( (a/2) % 2) memofs = 0x80; else memofs = 0x00; if ( (SC14421_READ(1+memofs) & 0xc0) == 0xc0) /* Checksum ok */ { unsigned char bfok = ((SC14421_READ(1+memofs) & 0x03) == 0x03)<<7; /* BField Checksum ok */ struct sniffed_packet packet; packet.rssi = SC14421_READ(memofs); packet.channel = config->slottable[a].channel; packet.slot = a; memcpy(packet.data, pppacket, 5); from_dip(&packet.data[5], sc14421_base+memofs+6, 48); if (config->slottable[a].type == DECT_SLOTTYPE_SCAN) { packet.channel--; //printk("slot in scanmode\n"); } /* if (dev->open) */ { if(config->framenumber) packet.frameflags = (config->framenumber-1)|bfok; else packet.frameflags = 7|bfok; packet.timestamp = dev->irq_timestamp; ret = kfifo_in_locked( &dev->rx_fifo, (unsigned char*) &packet, sizeof(struct sniffed_packet), &dev->rx_fifo_lock); if (ret <= 0) { printk("com_on_air_cs: rx fifo full? kfifo_in_locked() = %d\n", ret); } } #if 0 printk("F:"); for (i=0; i<16; i++) printk("%.2x ", SC14421_READ(i+memofs)); printk(" : %.2x : %x\n", irq, a); #endif SC14421_WRITE(1+memofs, 0); /* clear checksum flag */ if (dect_update_slottable(config->slottable, a, packet.data)) { config->updateppslots = 1; config->updatefpslots = 1; //printk("new slot , must update slots\n"); } } else { if (dect_receive_error(config->slottable, a)) { config->updateppslots = 1; config->updatefpslots = 1; //printk("8:died slot , must update slots\n"); } } } } if ( (!(irq & 0x01)) && (config->updateppslots) ) { //printk("patching pp slots\n"); sniffer_sync_patchloop(dev, config->slottable, SNIFF_SLOTPATCH_PP); config->updateppslots = 0; } if (dect_update_scanchannels(config->slottable)) { config->updateppslots = 1; config->updatefpslots = 1; //printk("new slot , must update slots\n"); } if (config->framenumber >= 7) config->framenumber = 0; else config->framenumber++; } } }
irqreturn_t pseudo_serial_intr_handler(int irq_no, void *p_dev) { int ret_val,i,j; irqreturn_t irq_r_flag=0; P_SERIAL_DEV *dev = (P_SERIAL_DEV *)p_dev; char lk_buff[HW_FIFO_SIZE]; irq_r_flag |= IRQ_NONE; printk("\n\n>in irqreturn_t...!\n"); if(inb(base_addr+0x05) & 0x20) //comparing for Tx interrupt { printk("\n>in irqreturn_t Tx interrupt...!\n"); outb (0x01, base_addr + 1); //IER ,disabling Tx & enabling Rx buffer interrupt ERBFI & EXBFI //copying the data into local buffer from the kfifo buffer ret_val = kfifo_out_locked(&(dev->write_kfifo),lk_buff,HW_FIFO_SIZE, &(dev->wr_spinlock)); printk("\n>in irqreturn_t Tx interrupt ret_val = kfifo_out_locked %d...!\n", ret_val); if(ret_val > 0) { for(i = 0; i < ret_val ; i++) outb(lk_buff[i], base_addr+0x00); } wake_up_interruptible (&(dev->write_queue)); irq_r_flag |= IRQ_HANDLED; } if(inb(base_addr+0x05) & 0x01) //comparing for Rx interrupt { printk("\n>in irqreturn_t Rx interrupt...!\n"); for(j=0;j<16;j++) { if(inb(base_addr+0x05) & 0x01) { lk_buff[j] = inb(base_addr+0x00); } else break; } //copying the data from local buffer onto the kfifo buffer if(kfifo_is_full(&(dev->read_kfifo))) dropped += j; else { kfifo_in_locked(&(dev->read_kfifo),lk_buff,j,&(dev->rd_spinlock)); received += j; } wake_up_interruptible(&(dev->read_queue)); irq_r_flag |= IRQ_HANDLED; } return irq_r_flag; }
void AUDIO_Ctrl_Process( BRCM_AUDIO_ACTION_en_t action_code, void *arg_param, void *callback, int block ) { TMsgAudioCtrl msgAudioCtrl; unsigned int len; AUDIO_DRIVER_TYPE_t drv_type; UInt32 app_profile = 0 ; static AudioApp_t prev_app_profile = 0; static AudioMode_t prev_mode_profile = 0; static bool mode_restore = FALSE; if(arg_param == NULL) { DEBUG("AUDIO_Ctrl_Process: arg_param is NULL \n"); return; } switch (action_code) { case ACTION_AUD_StartPlay: { BRCM_AUDIO_Param_Start_t* param_start = (BRCM_AUDIO_Param_Start_t*) arg_param; //20110905 //prev_app_profile = AUDDRV_GetAudioApp(); app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_MUSIC); AUDIO_DRIVER_Ctrl(param_start->drv_handle,AUDIO_DRIVER_START,NULL); AUDIO_DRIVER_Ctrl(param_start->drv_handle,AUDIO_DRIVER_GET_DRV_TYPE,(void*)&drv_type); if (AUDIO_Policy_GetState() == BRCM_STATE_INCALL) { DEBUG("Play Music During Voice call \n"); musicduringcall = TRUE; if ( sgTableIDChannelOfDev[param_start->substream_number].speaker == AUDCTRL_SPK_HEADSET || sgTableIDChannelOfDev[param_start->substream_number].speaker == AUDCTRL_SPK_BTM ) { DEBUG("Play Music During Voice call to HEADSET or BTM\n"); if ( app_profile == AUDIO_APP_VOICE_CALL ) { DEBUG(" Play music during Voice call with BT Tap at 8k \r\n"); AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, 8000); } else { DEBUG(" Play music during Voice call with BT Tap at 16k \r\n"); if ( sgTableIDChannelOfDev[param_start->substream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, 8000); } else { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, 16000); } } AUDCTRL_EnablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_start->substream_number].hw_id, AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, param_start->channels, param_start->rate ); } else { DEBUG("Play Music During Voice call to HANDSET or LOUDSPEAKER\n"); if ( app_profile == AUDIO_APP_VOICE_CALL ) { DEBUG(" Play music during Voice call with BT Tap at 8k \r\n"); AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_HEADSET, 8000); } else { DEBUG(" Play music during Voice call with BT Tap at 16k \r\n"); AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_HEADSET, 16000); } AUDCTRL_EnablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_start->substream_number].hw_id, AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_HEADSET, param_start->channels, param_start->rate ); } } else { AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfDev[param_start->substream_number].speaker,app_profile); if( sgTableIDChannelOfDev[param_start->substream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, sgTableIDChannelOfDev[param_start->substream_number].speaker, 8000); // Enable the playback the path AUDCTRL_EnablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_start->substream_number].hw_id, AUDIO_HW_TAP_VOICE, sgTableIDChannelOfDev[param_start->substream_number].speaker, param_start->channels, param_start->rate ); } else { // Enable the playback the path AUDCTRL_EnablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_start->substream_number].hw_id, AUDIO_HW_NONE, sgTableIDChannelOfDev[param_start->substream_number].speaker, param_start->channels, param_start->rate ); //if (param_start->substream_number == 5) // Ring case if(extra_speaker) { DEBUG("Play to speaker as well \n"); AUDCTRL_AddPlaySpk(sgTableIDChannelOfDev[param_start->substream_number].hw_id, // AUDIO_HW_ID_t sink, AUDCTRL_SPK_LOUDSPK // AUDCTRL_SPEAKER_t spk ); } } } // set the slopgain register to max value AUDCTRL_SetPlayVolume(sgTableIDChannelOfDev[param_start->substream_number].hw_id, sgTableIDChannelOfDev[param_start->substream_number].speaker, AUDIO_GAIN_FORMAT_VOL_LEVEL, AUDIO_VOLUME_MAX, AUDIO_VOLUME_MAX ); // start DMA now AUDIO_DRIVER_Ctrl(param_start->drv_handle,AUDIO_DRIVER_RESUME,NULL); playback_prev_time = 0; playback_triggered = 1; } break; case ACTION_AUD_StopPlay: { BRCM_AUDIO_Param_Stop_t* param_stop = (BRCM_AUDIO_Param_Stop_t*) arg_param; // stop DMA first AUDIO_DRIVER_Ctrl(param_stop->drv_handle,AUDIO_DRIVER_PAUSE,NULL); AUDIO_DRIVER_Ctrl(param_stop->drv_handle,AUDIO_DRIVER_GET_DRV_TYPE,(void*)&drv_type); //if (param_stop->substream_number == 5) // Ring case if(extra_speaker) { DEBUG(" REMOVING LOUDSPK \n"); AUDCTRL_RemovePlaySpk(sgTableIDChannelOfDev[param_stop->substream_number].hw_id, // AUDIO_HW_ID_t sink, AUDCTRL_SPK_LOUDSPK // AUDCTRL_SPEAKER_t spk ); } //20110905 //AUDCTRL_SaveAudioModeFlag( AUDDRV_GetAudioMode(), prev_app_profile ); //disable the playback path if (AUDIO_Policy_GetState() == BRCM_STATE_INCALL) { musicduringcall = FALSE; if ( sgTableIDChannelOfDev[param_stop->substream_number].speaker == AUDCTRL_SPK_HEADSET || sgTableIDChannelOfDev[param_stop->substream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_DisablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_stop->substream_number].hw_id, AUDCTRL_SPK_BTM ); } else { AUDCTRL_DisablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_stop->substream_number].hw_id, AUDCTRL_SPK_HEADSET ); } AUDCTRL_DisableTap (AUDIO_HW_TAP_VOICE); } else { if( sgTableIDChannelOfDev[param_stop->substream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_DisablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_stop->substream_number].hw_id, sgTableIDChannelOfDev[param_stop->substream_number].speaker ); AUDCTRL_DisableTap (AUDIO_HW_TAP_VOICE); } else { AUDCTRL_DisablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_stop->substream_number].hw_id, sgTableIDChannelOfDev[param_stop->substream_number].speaker ); } } AUDIO_DRIVER_Ctrl(param_stop->drv_handle,AUDIO_DRIVER_STOP,NULL); playback_prev_time = 0; playback_triggered = 0; } break; case ACTION_AUD_PausePlay: { BRCM_AUDIO_Param_Pause_t* param_pause = (BRCM_AUDIO_Param_Pause_t*) arg_param; AUDIO_DRIVER_Ctrl(param_pause->drv_handle,AUDIO_DRIVER_GET_DRV_TYPE,(void*)&drv_type); //disable the playback path AUDCTRL_DisablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_pause->substream_number].hw_id, sgTableIDChannelOfDev[param_pause->substream_number].speaker ); if( sgTableIDChannelOfDev[param_pause->substream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_DisableTap (AUDIO_HW_TAP_VOICE); } AUDIO_DRIVER_Ctrl(param_pause->drv_handle,AUDIO_DRIVER_PAUSE,NULL); } break; case ACTION_AUD_ResumePlay: { BRCM_AUDIO_Param_Resume_t* param_resume = (BRCM_AUDIO_Param_Resume_t*) arg_param; AUDIO_DRIVER_Ctrl(param_resume->drv_handle,AUDIO_DRIVER_GET_DRV_TYPE,(void*)&drv_type); AUDIO_DRIVER_Ctrl(param_resume->drv_handle,AUDIO_DRIVER_RESUME,NULL); if( sgTableIDChannelOfDev[param_resume->substream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, sgTableIDChannelOfDev[param_resume->substream_number].speaker, param_resume->rate); // Enable the playback the path AUDCTRL_EnablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_resume->substream_number].hw_id, AUDIO_HW_TAP_VOICE, sgTableIDChannelOfDev[param_resume->substream_number].speaker, param_resume->channels, param_resume->rate ); } else { // Enable the playback the path AUDCTRL_EnablePlay(AUDIO_HW_NONE, sgTableIDChannelOfDev[param_resume->substream_number].hw_id, AUDIO_HW_NONE, sgTableIDChannelOfDev[param_resume->substream_number].speaker, param_resume->channels, param_resume->rate ); } } break; case ACTION_AUD_StartRecord: { AudioApp_t app_prof = AUDIO_APP_RECORDING; AudioMode_t new_mode = AUDIO_MODE_SPEAKERPHONE; AudioMode_t cur_mode; BRCM_AUDIO_Param_Start_t* param_start = (BRCM_AUDIO_Param_Start_t*) arg_param; DEBUG("ACTION_AUD_StartRecord : param_start->substream_number - %d \n",param_start->substream_number); prev_app_profile = AUDDRV_GetAudioApp(); cur_mode = AUDCTRL_GetAudioMode(); if ( cur_mode >= AUDIO_MODE_NUMBER ) cur_mode = (AudioMode_t) (cur_mode - AUDIO_MODE_NUMBER); if (param_start->substream_number == 6 || param_start->substream_number == 7) // record request with Google voice search profile { app_prof = AUDIO_APP_RECORDING_GVS; mode_restore = TRUE; prev_mode_profile = cur_mode; DEBUG("ACTION_AUD_StartRecord : [%d, %d]", prev_app_profile, prev_mode_profile); } if (param_start->substream_number == 9 || param_start->substream_number == 10) // record request with voip profile { app_prof = AUDIO_APP_VOIP; new_mode = cur_mode; // use current mode based on earpiece or speaker } if (param_start->substream_number == 11 || param_start->substream_number == 12) // record request with voip incomm profile { app_prof = AUDIO_APP_VOIP_INCOMM; new_mode = cur_mode; // use current mode based on earpiece or speaker } if (param_start->substream_number == 1 || param_start->substream_number == 7 || param_start->substream_number == 8 || param_start->substream_number == 10 || param_start->substream_number == 12) // record request with auxilary mic new_mode = AUDIO_MODE_HEADSET; app_profile = AUDIO_Policy_Get_Profile(app_prof); new_mode = AUDIO_Policy_Get_Mode(new_mode); AUDCTRL_SaveAudioModeFlag(new_mode,app_profile); AUDCTRL_EnableRecord(sgTableIDChannelOfCaptDev[param_start->substream_number].hw_id, AUDIO_HW_NONE, sgTableIDChannelOfCaptDev[param_start->substream_number].mic, param_start->channels, param_start->rate); AUDIO_DRIVER_Ctrl(param_start->drv_handle,AUDIO_DRIVER_START,NULL); AUDIO_Policy_SetState(BRCM_STATE_RECORD); } break; case ACTION_AUD_StopRecord: { BRCM_AUDIO_Param_Stop_t* param_stop = (BRCM_AUDIO_Param_Stop_t*) arg_param; AUDIO_DRIVER_Ctrl(param_stop->drv_handle,AUDIO_DRIVER_STOP,NULL); if (mode_restore) { mode_restore = FALSE; AUDCTRL_SaveAudioModeFlag( prev_mode_profile, prev_app_profile ); DEBUG("ACTION_AUD_StartRecord : [%d, %d]", prev_app_profile, prev_mode_profile); } else { AUDCTRL_SaveAudioModeFlag( AUDDRV_GetAudioMode(), prev_app_profile ); } AUDCTRL_DisableRecord(sgTableIDChannelOfCaptDev[param_stop->substream_number].hw_id, AUDIO_HW_NONE, sgTableIDChannelOfCaptDev[param_stop->substream_number].mic); AUDIO_Policy_RestoreState(); } break; case ACTION_AUD_OpenPlay: { BRCM_AUDIO_Param_Open_t* param_open = (BRCM_AUDIO_Param_Open_t*) arg_param; param_open->drv_handle = AUDIO_DRIVER_Open(sgTableIDChannelOfDev[param_open->substream_number].drv_type); DEBUG("param_open->drv_handle - 0x%x \n",param_open->drv_handle); } break; case ACTION_AUD_ClosePlay: { BRCM_AUDIO_Param_Close_t* param_close = (BRCM_AUDIO_Param_Close_t*) arg_param; DEBUG("param_close->drv_handle - 0x%x \n",param_close->drv_handle); AUDIO_DRIVER_Close(param_close->drv_handle); } break; case ACTION_AUD_OpenRecord: { BRCM_AUDIO_Param_Open_t* param_open = (BRCM_AUDIO_Param_Open_t*) arg_param; param_open->drv_handle = AUDIO_DRIVER_Open(sgTableIDChannelOfCaptDev[param_open->substream_number].drv_type); DEBUG("param_open->drv_handle - 0x%x \n",param_open->drv_handle); } break; case ACTION_AUD_CloseRecord: { BRCM_AUDIO_Param_Close_t* param_close = (BRCM_AUDIO_Param_Close_t*) arg_param; DEBUG("param_close->drv_handle - 0x%x \n",param_close->drv_handle); AUDIO_DRIVER_Close(param_close->drv_handle); } break; case ACTON_VOICECALL_START: { BRCM_VOICE_Param_Start_t* param_voice_start = (BRCM_VOICE_Param_Start_t*)arg_param; int vol_level; telephony_stream_number = param_voice_start->substream_number; if ( telephony_codecId == 10 ) { DEBUG("Enable telephony WB Call \r\n"); app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL_WB); AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].speaker + AUDIO_MODE_NUMBER,app_profile); } else if ( telephony_codecId == 6 ) { DEBUG("Enable telephony NB Call \r\n"); app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL); AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].speaker,app_profile); } else { DEBUG("Enable telephony Invalid Codec : Setting as NB \r\n"); app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL); AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].speaker,app_profile); } if ( (telephony_stream_number-VOICE_CALL_SUB_DEVICE) == 4 ) { if ( telephony_codecId == 10 ) { DEBUG("Enable telephony WB Call for BT NREC \r\n"); app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL_WB); AUDCTRL_SaveAudioModeFlag(AUDCTRL_SPK_HANDSFREE, app_profile); } else if ( telephony_codecId == 6 ) { DEBUG("Enable telephony NB Call BT NREC \r\n"); app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL); AUDCTRL_SaveAudioModeFlag(AUDCTRL_SPK_HANDSFREE, app_profile); } DEBUG(" Telephony : Turning Off EC and NS \r\n"); //AUDCTRL_EC(FALSE, 0); //AUDCTRL_NS(FALSE); } else { DEBUG(" Telephony : Turning On EC and NS \r\n"); //AUDCTRL_EC(TRUE, 0); //AUDCTRL_NS(TRUE); } vol_level= GetCtrlValue(BRCM_CTL_EAR_Playback_Volume); if(vol_level > 5) vol_level = 5; AUDCTRL_SetPlayVolume(AUDIO_HW_VOICE_OUT,AUDCTRL_SPK_HANDSET,AUDIO_GAIN_FORMAT_DSP_VOICE_VOL_GAIN,vol_level,vol_level); AUDCTRL_RateChangeTelephony(); AUDCTRL_EnableTelephony(AUDIO_HW_VOICE_IN,AUDIO_HW_VOICE_OUT,sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].mic,sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].speaker); telephony_started = 1; if(TRUE==GetCtrlValue(BRCM_CTL_Mic_Capture_Mute)) { DEBUG("Muting device \r\n"); AUDCTRL_SetTelephonyMicMute(AUDIO_HW_VOICE_OUT,AUDCTRL_MIC_MAIN,TRUE);; } AUDIO_Policy_SetState(BRCM_STATE_INCALL); } break; case ACTON_VOICECALL_STOP: { BRCM_VOICE_Param_Stop_t* param_voice_stop = (BRCM_VOICE_Param_Stop_t*)arg_param; telephony_stream_number = param_voice_stop->substream_number; DEBUG("DISABLE TELEPHONY substream = %d \r\n", telephony_stream_number); AUDCTRL_DisableTelephony(AUDIO_HW_VOICE_IN,AUDIO_HW_VOICE_OUT,sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].mic,sgTableIDChannelOfVoiceCallDev[telephony_stream_number-VOICE_CALL_SUB_DEVICE].speaker); telephony_started = 0; AUDIO_Policy_RestoreState(); } break; case ACTON_VOICECALL_UPDATE: { int local_sub_stream_number = 0; BRCM_VOICE_Param_Update_t* param_voice_update = (BRCM_VOICE_Param_Update_t*)arg_param; DEBUG("TELEPHONY UPDATE codecId = %d \r\n", param_voice_update->voicecall_codecId); if ( telephony_codecId != param_voice_update->voicecall_codecId ) { telephony_codecId = param_voice_update->voicecall_codecId; if (telephony_started) { if ( telephony_codecId == 10 ) { app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL_WB); DEBUG("call_CodedId_hander : changing Mode to AMR-WB ===>\r\n"); AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfVoiceCallDev[telephony_stream_number - VOICE_CALL_SUB_DEVICE].speaker + AUDIO_MODE_NUMBER,app_profile); DEBUG("call_CodedId_hander : changing Mode to AMR-WB <===\r\n"); } else { app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_VOICE_CALL); DEBUG("call_CodedId_hander : changing Mode to AMR-NB ===>\r\n"); AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfVoiceCallDev[telephony_stream_number - VOICE_CALL_SUB_DEVICE].speaker,app_profile ); DEBUG("call_CodedId_hander : changing Mode to AMR-NB <===\r\n"); } DEBUG("call_CodedId_hander : AUDCTRL_RateChangeTelephony ===>\r\n"); if ( musicduringcall == TRUE ) { local_sub_stream_number = (telephony_stream_number - VOICE_CALL_SUB_DEVICE)*2; // wired headphone if(telephony_stream_number == 17) { // set the substream number to same as headset local_sub_stream_number = 4; } AUDCTRL_DisableTap (AUDIO_HW_TAP_VOICE); if ( app_profile == AUDIO_APP_VOICE_CALL ) { AUDCTRL_RateChangeTelephony(); if( sgTableIDChannelOfDev[local_sub_stream_number].speaker == AUDCTRL_SPK_HEADSET || sgTableIDChannelOfDev[local_sub_stream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, 8000); } else { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_HEADSET, 8000); } } else { AUDCTRL_RateChangeTelephony(); if( sgTableIDChannelOfDev[local_sub_stream_number].speaker == AUDCTRL_SPK_HEADSET ) { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, 16000); } else if ( sgTableIDChannelOfDev[local_sub_stream_number].speaker == AUDCTRL_SPK_BTM ) { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_BTM, 8000); } else { AUDCTRL_EnableTap (AUDIO_HW_TAP_VOICE, AUDCTRL_SPK_HEADSET, 16000); } } } else { AUDCTRL_RateChangeTelephony(); } DEBUG("call_CodedId_hander : AUDCTRL_RateChangeTelephony <===\r\n"); } } } break; case ACTON_FM_START: { BRCM_FM_Param_Start_t* param_start = (BRCM_FM_Param_Start_t*) arg_param; app_profile = AUDIO_Policy_Get_Profile(AUDIO_APP_FM); AUDCTRL_SaveAudioModeFlag( sgTableIDChannelOfDev[param_start->substream_number].speaker,app_profile); // Enable the FM playback the path AUDCTRL_EnablePlay(AUDIO_HW_I2S_IN, sgTableIDChannelOfDev[param_start->substream_number].hw_id, AUDIO_HW_NONE, sgTableIDChannelOfDev[param_start->substream_number].speaker, param_start->channels, param_start->rate ); // set the slopgain register to max value // 20110530 FM radio volume is controlled by FM radio chip. AUDCTRL_SetPlayVolume(sgTableIDChannelOfDev[param_start->substream_number].hw_id, sgTableIDChannelOfDev[param_start->substream_number].speaker, AUDIO_GAIN_FORMAT_FM_RADIO_DIGITAL_VOLUME_TABLE, AUDIO_VOLUME_MAX, AUDIO_VOLUME_MAX ); AUDIO_Policy_SetState(BRCM_STATE_FM); } break; case ACTON_FM_STOP: { BRCM_FM_Param_Stop_t* param_fm_stop = (BRCM_FM_Param_Stop_t*)arg_param; //disable the FM playback path AUDCTRL_DisablePlay(AUDIO_HW_I2S_IN, sgTableIDChannelOfDev[param_fm_stop->substream_number].hw_id, sgTableIDChannelOfDev[param_fm_stop->substream_number].speaker ); AUDIO_Policy_RestoreState(); } break; case ACTON_ROUTE: { BRCM_AUDIO_Param_Route_t* parm_route = (BRCM_AUDIO_Param_Route_t*)arg_param; DEBUG("ACTON_ROUTE \n"); if(playback_triggered == 1){ if(parm_route->command == 1) { DEBUG(" ADDING SPK - %d \n",parm_route->speaker); AUDCTRL_AddPlaySpk(AUDIO_HW_PLR_OUT, parm_route->speaker ); extra_speaker = 1; } else if (parm_route->command == 0) { DEBUG(" REMOVING SPK - %d \n",parm_route->speaker); AUDCTRL_RemovePlaySpk(AUDIO_HW_PLR_OUT, parm_route->speaker ); extra_speaker = 0; } } else { if(parm_route->command == 1) extra_speaker = 1; else if (parm_route->command == 0) extra_speaker = 0; } } break; default: DEBUG("Error AUDIO_Ctrl_Process Invalid acction command \n"); } if(block) { // put the message in output fifo if waiting msgAudioCtrl.action_code = action_code; if(arg_param) memcpy(&msgAudioCtrl.param, arg_param, sizeof(BRCM_AUDIO_Control_Params_un_t)); else memset(&msgAudioCtrl.param, 0, sizeof(BRCM_AUDIO_Control_Params_un_t)); msgAudioCtrl.pCallBack = callback; msgAudioCtrl.block = block; len = kfifo_in_locked(&sgThreadData.m_pkfifo_out, (unsigned char *)&msgAudioCtrl, sizeof(TMsgAudioCtrl), &sgThreadData.m_lock_out); if(len != sizeof(TMsgAudioCtrl)) DEBUG("Error AUDIO_Ctrl_Process len=%d expected %d \n", len, sizeof(TMsgAudioCtrl)); #if 1 // release the semaphore DEBUG("Semaphore released - %d \n",action_code); OSSEMAPHORE_Release(sgThreadData.action_complete); #endif } }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //HAL_AUDIO_Ctrl // Client call this function to execute audio HAL functions. // This function for the message to worker thread to do actual work //---------------------------------------------------------------- Result_t AUDIO_Ctrl_Trigger( BRCM_AUDIO_ACTION_en_t action_code, void *arg_param, void *callback, int block ) { TMsgAudioCtrl msgAudioCtrl; Result_t status = RESULT_OK; unsigned int len; OSStatus_t osStatus; { //BRCM_AUDIO_Control_Params_un_t *paudioControlParam = (BRCM_AUDIO_Control_Params_un_t *)arg_param; DEBUG("AudioHalThread action=%d\r\n", action_code); } msgAudioCtrl.action_code = action_code; if(arg_param) memcpy(&msgAudioCtrl.param, arg_param, sizeof(BRCM_AUDIO_Control_Params_un_t)); else memset(&msgAudioCtrl.param, 0, sizeof(BRCM_AUDIO_Control_Params_un_t)); msgAudioCtrl.pCallBack = callback; msgAudioCtrl.block = block; len = kfifo_in_locked(&sgThreadData.m_pkfifo, (unsigned char *)&msgAudioCtrl, sizeof(TMsgAudioCtrl), &sgThreadData.m_lock); if(len != sizeof(TMsgAudioCtrl)) { DEBUG("Error AUDIO_Ctrl_Trigger len=%d expected %d \n", len, sizeof(TMsgAudioCtrl)); return RESULT_ERROR; } queue_work(sgThreadData.pWorkqueue_AudioControl, &sgThreadData.mwork); if(block) { // wait for 10sec osStatus = OSSEMAPHORE_Obtain(sgThreadData.action_complete,1280); if(osStatus != OSSTATUS_SUCCESS) { DEBUG("AUDIO_Ctrl_Trigger Timeout=%d\r\n",osStatus); } while(1) { //wait for output from output fifo len = kfifo_out_locked(&sgThreadData.m_pkfifo_out, (unsigned char *)&msgAudioCtrl, sizeof(TMsgAudioCtrl), &sgThreadData.m_lock_out); if( (len != sizeof(TMsgAudioCtrl)) && (len!=0) ) DEBUG("Error AUDIO_Ctrl_Trigger len=%d expected %d in=%d, out=%d\n", len, sizeof(TMsgAudioCtrl), sgThreadData.m_pkfifo_out.in, sgThreadData.m_pkfifo_out.out); if(len == 0) //FIFO empty sleep return status; if(arg_param) memcpy(arg_param,&msgAudioCtrl.param, sizeof(BRCM_AUDIO_Control_Params_un_t)); else memset(arg_param, 0, sizeof(BRCM_AUDIO_Control_Params_un_t)); } } return status; }