/* This clears the reset bit to enable monitoring immediately if monitoring recording sources or always if playback is in progress - we might be switching samplerates on the fly */ void pcm_dma_apply_settings(void) { int level = set_irq_level(DMA_IRQ_LEVEL); /* remember table entry */ freq_ent = pcm_freq_parms[pcm_fsel]; /* Reprogramming bits 15-12 requires FIFO to be in a reset condition - Users Manual 17-8, Note 11 */ or_l(IIS_FIFO_RESET, &IIS_PLAY); /* Important for TLV320 - this must happen in the correct order or starting recording will sound absolutely awful once in awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits */ IIS_PLAY = IIS_PLAY_DEFPARM | IIS_FIFO_RESET; restore_irq(level); audiohw_set_frequency(pcm_fsel); coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); level = set_irq_level(DMA_IRQ_LEVEL); IIS_PLAY = IIS_PLAY_DEFPARM; if ((DCR0 & DMA_EEXT) != 0 && is_playback_monitoring()) PDOR3 = 0; /* Kick FIFO out of reset by writing to it */ restore_irq(level); } /* pcm_dma_apply_settings */
void _backlight_set_brightness(int val) { int oldlevel; if (current_dim < val) { do { oldlevel = disable_irq_save(); GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80); udelay(10); GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80); restore_irq(oldlevel); udelay(10); } while (++current_dim < val); } else if (current_dim > val) { do { oldlevel = disable_irq_save(); GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80); udelay(200); GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80); restore_irq(oldlevel); udelay(10); } while (--current_dim > val); } brightness = val; }
void remove_thread(unsigned int thread_id) #endif { struct thread_entry *current = cores[CURRENT_CORE].running; struct thread_entry *thread = thread_id_entry(thread_id); SDL_Thread *t; SDL_sem *s; if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id) return; int oldlevel = disable_irq_save(); t = thread->context.t; s = thread->context.s; thread->context.t = NULL; if (thread != current) { switch (thread->state) { case STATE_BLOCKED: case STATE_BLOCKED_W_TMO: /* Remove thread from object it's waiting on */ remove_from_list_l(thread->bqp, thread); #ifdef HAVE_WAKEUP_EXT_CB if (thread->wakeup_ext_cb != NULL) thread->wakeup_ext_cb(thread); #endif break; } SDL_SemPost(s); } THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n", thread - threads, THREAD_SDL_GET_NAME(thread)); new_thread_id(thread->id, thread); thread->state = STATE_KILLED; thread_queue_wake(&thread->queue); SDL_DestroySemaphore(s); if (thread == current) { /* Do a graceful exit - perform the longjmp back into the thread function to return */ restore_irq(oldlevel); longjmp(thread_jmpbufs[current - threads], 1); } SDL_KillThread(t); restore_irq(oldlevel); }
static void ep_transfer(int ep, void *ptr, int len, bool out) { /* disable interrupts to avoid any race */ int oldlevel = disable_irq_save(); struct ep_type *endpoint = &endpoints[ep][out ? DIR_OUT : DIR_IN]; endpoint->busy = true; endpoint->size = len; endpoint->status = -1; if (out) DEPCTL(ep, out) &= ~DEPCTL_stall; int mps = usb_drv_port_speed() ? 512 : 64; int nb_packets = (len + mps - 1) / mps; if (nb_packets == 0) nb_packets = 1; DEPDMA(ep, out) = len ? (void*)PHYSICAL_ADDR(ptr) : NULL; DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len; if(out) discard_dcache_range(ptr, len); else commit_dcache_range(ptr, len); logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out)); // if (!out) while (((GNPTXSTS & 0xffff) << 2) < MIN(mps, length)); DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak; restore_irq(oldlevel); }
static void iis_play_reset_if_playback(bool if_playback) { int level = set_irq_level(DMA_IRQ_LEVEL); if (is_playback_monitoring() == if_playback) iis_play_reset(); restore_irq(level); }
/* Scan the keypad port and return the pressed buttons */ static int kpp_scan(void) { static const struct key_mask_shift { uint8_t mask; uint8_t shift; } kms[3] = { { 0x1f, 0 }, /* BUTTON_LEFT...BUTTON_SELECT */ { 0x03, 5 }, /* BUTTON_BACK...BUTTON_MENU */ { 0x1f, 7 }, /* BUTTON_VOL_UP...BUTTON_NEXT */ }; int button = BUTTON_NONE; int oldlevel = disable_irq_save(); int col; for (col = 0; col < 3; col++) /* Col */ { /* 2. Write 1s to KPDR[10:8] setting column data to 1s */ KPP_KPDR |= (0x7 << 8); /* 3. Configure columns as totem pole outputs(for quick * discharging of keypad capacitance) */ KPP_KPCR &= ~(0x7 << 8); /* Give the columns time to discharge */ udelay(2); /* 4. Configure columns as open-drain */ KPP_KPCR |= (0x7 << 8); /* 5. Write a single column to 0, others to 1. * 6. Sample row inputs and save data. Multiple key presses * can be detected on a single column. * 7. Repeat steps 2 - 6 for remaining columns. */ /* Col bit starts at 8th bit in KPDR */ KPP_KPDR &= ~(0x100 << col); /* Delay added to avoid propagating the 0 from column to row * when scanning. */ udelay(2); /* Read row input */ button |= (~KPP_KPDR & kms[col].mask) << kms[col].shift; } /* 8. Return all columns to 0 in preparation for standby mode. */ KPP_KPDR &= ~(0x7 << 8); /* 9. Clear KPKD and KPKR status bit(s) by writing to a .1., * set the KPKR synchronizer chain by writing "1" to KRSS register, * clear the KPKD synchronizer chain by writing "1" to KDSC register */ KPP_KPSR = KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKR | KPP_KPSR_KPKD; restore_irq(oldlevel); return button; }
/* Up the semaphore's count and release any thread waiting at the head of the * queue. The count is saturated to the value of the 'max' parameter specified * in 'semaphore_init'. */ void semaphore_release(struct semaphore *s) { unsigned int result = THREAD_NONE; int oldlevel = disable_irq_save(); corelock_lock(&s->cl); struct thread_entry *thread = WQ_THREAD_FIRST(&s->queue); if(LIKELY(thread != NULL)) { /* a thread was queued - wake it up and keep count at 0 */ KERNEL_ASSERT(s->count == 0, "semaphore_release->threads queued but count=%d!\n", s->count); result = wakeup_thread(thread, WAKEUP_DEFAULT); } else { int count = s->count; if(count < s->max) { /* nothing waiting - up it */ s->count = count + 1; } } corelock_unlock(&s->cl); restore_irq(oldlevel); #if defined(HAVE_PRIORITY_SCHEDULING) && defined(is_thread_context) /* No thread switch if not thread context */ if((result & THREAD_SWITCH) && is_thread_context()) switch_thread(); #endif (void)result; }
bool ide_powered(void) { int level = disable_irq_save(); int value = pcf50606_read(0x3c); restore_irq(level); return (value & 0x07) != 0; }
int rtc_read_datetime(struct tm *tm) { unsigned int i; int rc, oldlevel; unsigned char buf[7]; oldlevel = disable_irq_save(); if (get_pmu_type() == PCF50606) rc = pcf50606_read_multiple(PCF5060X_RTCSC, buf, sizeof(buf)); else rc = pcf50635_read_multiple(PCF5063X_REG_RTCSC, buf, sizeof(buf)); restore_irq(oldlevel); for (i = 0; i < sizeof(buf); i++) buf[i] = BCD2DEC(buf[i]); tm->tm_sec = buf[0]; tm->tm_min = buf[1]; tm->tm_hour = buf[2]; tm->tm_wday = buf[3]; tm->tm_mday = buf[4]; tm->tm_mon = buf[5] - 1; tm->tm_year = buf[6] + 100; return rc; }
void ide_power_enable(bool on) { /* GPOOD3 */ int level = disable_irq_save(); pcf50606_write(0x3c, on ? 0x07 : 0x00); restore_irq(level); }
/* Enables queue_send on the specified queue - caller allocates the extra * data structure. Only queues which are taken to be owned by a thread should * enable this however an official owner is not compulsory but must be * specified for priority inheritance to operate. * * Use of queue_wait(_w_tmo) by multiple threads on a queue using synchronous * messages results in an undefined order of message replies or possible default * replies if two or more waits happen before a reply is done. */ void queue_enable_queue_send(struct event_queue *q, struct queue_sender_list *send, unsigned int owner_id) { int oldlevel = disable_irq_save(); corelock_lock(&q->cl); if(send != NULL && q->send == NULL) { memset(send, 0, sizeof(*send)); #ifdef HAVE_PRIORITY_SCHEDULING send->blocker.wakeup_protocol = wakeup_priority_protocol_release; send->blocker.priority = PRIORITY_IDLE; if(owner_id != 0) { send->blocker.thread = thread_id_entry(owner_id); q->blocker_p = &send->blocker; } #endif q->send = send; } corelock_unlock(&q->cl); restore_irq(oldlevel); (void)owner_id; }
int tick_remove_task(void (*f)(void)) { int oldlevel = disable_irq_save(); int rc = remove_array_ptr((void **)tick_funcs, f); restore_irq(oldlevel); return rc; }
int rtc_write_datetime(const struct tm *tm) { unsigned int i; int rc, oldlevel; unsigned char buf[7]; buf[0] = tm->tm_sec; buf[1] = tm->tm_min; buf[2] = tm->tm_hour; buf[3] = tm->tm_wday; buf[4] = tm->tm_mday; buf[5] = tm->tm_mon + 1; buf[6] = tm->tm_year - 100; for (i = 0; i < sizeof(buf); i++) buf[i] = DEC2BCD(buf[i]); oldlevel = disable_irq_save(); if (get_pmu_type() == PCF50606) rc = pcf50606_write_multiple(PCF5060X_RTCSC, buf, sizeof(buf)); else rc = pcf50635_write_multiple(PCF5063X_REG_RTCSC, buf, sizeof(buf)); restore_irq(oldlevel); return rc; }
/* set brightness by changing the PWM */ void _backlight_set_brightness(int val) { /* disable IRQs while bitbanging */ int old_irq_level = disable_irq_save(); pcf50606_write(0x35, (val << 1) | 0x01); /* 512Hz, Enable PWM */ /* enable IRQs again */ restore_irq(old_irq_level); }
void usb_drv_cancel_all_transfers(void) { logf("usb_drv_cancel_all_transfers()\n"); return; int flags = disable_irq_save(); reset_endpoints(0); restore_irq(flags); }
/* Mask the DMA interrupt */ void pcm_play_lock(void) { if (++locked == 1) { int old = disable_irq_save(); INTC_IMR &= ~(1<<12); /* mask HDMA interrupt */ restore_irq(old); } }
/* Unmask the DMA interrupt if enabled */ void pcm_play_unlock(void) { if(--locked == 0) { int old = disable_irq_save(); INTC_IMR |= (1<<12); /* unmask HDMA interrupt */ restore_irq(old); } }
void _backlight_off(void) { int level = disable_irq_save(); pcf50606_write(0x38, 0x80); /* Backlight OFF, GPO1INV=1, GPO1ACT=000 */ restore_irq(level); #ifdef HAVE_LCD_ENABLE lcd_enable(false); /* power off visible display */ #endif }
void _backlight_on(void) { int level; #ifdef HAVE_LCD_ENABLE lcd_enable(true); /* power on lcd + visible display */ #endif level = disable_irq_save(); pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */ restore_irq(level); }
/* tuner abstraction layer: read something from the tuner */ int si4700_get(int setting) { int val = -1; /* default for unsupported query */ if(!tuner_powered() && setting != RADIO_PRESENT) return -1; mutex_lock(&fmr_mutex); switch(setting) { case RADIO_PRESENT: val = tuner_present; break; case RADIO_TUNED: val = si4700_tuned(); break; case RADIO_STEREO: val = si4700_st(); break; case RADIO_RSSI: val = STATUSRSSI_RSSIr(si4700_read_reg(STATUSRSSI)); break; case RADIO_RSSI_MIN: val = RSSI_MIN; break; case RADIO_RSSI_MAX: val = RSSI_MAX; break; #ifdef HAVE_RDS_CAP case RADIO_EVENT: { #ifdef RDS_ISR_PROCESSING int oldlevel = disable_irq_save(); #endif val = rds_event; rds_event = 0; #ifdef RDS_ISR_PROCESSING restore_irq(oldlevel); #endif break; } #endif } mutex_unlock(&fmr_mutex); return val; }
unsigned short adc_scan(int channel) { int level = disable_irq_save(); unsigned char data = 0; int i; CS_LO; DI_HI; /* Start bit */ DELAY; CLK_HI; DELAY; CLK_LO; DI_HI; /* Single channel */ DELAY; CLK_HI; DELAY; CLK_LO; if(channel & 1) /* LSB of channel number */ DI_HI; else DI_LO; DELAY; CLK_HI; DELAY; CLK_LO; if(channel & 2) /* MSB of channel number */ DI_HI; else DI_LO; DELAY; CLK_HI; DELAY; CLK_LO; DELAY; for(i = 0;i < 8;i++) /* 8 bits of data */ { CLK_HI; DELAY; CLK_LO; DELAY; data <<= 1; data |= DO?1:0; } CS_HI; restore_irq(level); return data; }
/* * set the flip attribute * better only call this when the queue is empty */ void button_set_flip(bool flip) { if (flip != flipped) /* not the current setting */ { /* avoid race condition with the button_tick() */ int oldlevel = disable_irq_save(); lastbtn = button_flip(lastbtn); flipped = flip; restore_irq(oldlevel); } }
void pcm_rec_unlock(void) { int oldlevel = disable_irq_save(); if (--rec_locked == 0 && is_recording) { VIC_INT_ENABLE = INTERRUPT_I2SIN; I2SIN_MASK = (1<<2); /* I2SIN_MASK_POAF */ } restore_irq(oldlevel); }
/* Cancels a timeout callback - can be called from the ISR */ void timeout_cancel(struct timeout *tmo) { int oldlevel = disable_irq_save(); int rc = remove_array_ptr((void **)tmo_list, tmo); if(rc >= 0 && *tmo_list == NULL) { tick_remove_task(timeout_tick); /* Last one - remove task */ } restore_irq(oldlevel); }
/* Down the semaphore's count or wait for 'timeout' ticks for it to go up if * it is already 0. 'timeout' as TIMEOUT_NOBLOCK (0) will not block and may * safely be used in an ISR. */ int semaphore_wait(struct semaphore *s, int timeout) { int ret = OBJ_WAIT_TIMEDOUT; int oldlevel = disable_irq_save(); corelock_lock(&s->cl); int count = s->count; if(LIKELY(count > 0)) { /* count is not zero; down it */ s->count = count - 1; ret = OBJ_WAIT_SUCCEEDED; } else if(timeout != 0) { ASSERT_CPU_MODE(CPU_MODE_THREAD_CONTEXT, oldlevel); /* too many waits - block until count is upped... */ struct thread_entry *current = __running_self_entry(); block_thread(current, timeout, &s->queue, NULL); corelock_unlock(&s->cl); /* ...and turn control over to next thread */ switch_thread(); /* if explicit wake indicated; do no more */ if(LIKELY(!wait_queue_ptr(current))) return OBJ_WAIT_SUCCEEDED; disable_irq(); corelock_lock(&s->cl); /* see if anyone got us after the expired wait */ if(wait_queue_try_remove(current)) { count = s->count; if(count > 0) { /* down it lately */ s->count = count - 1; ret = OBJ_WAIT_SUCCEEDED; } } } /* else just polling it */ corelock_unlock(&s->cl); restore_irq(oldlevel); return ret; }
bool timer_set(long cycles, bool start) { unsigned int divider = cycles, prescaler_bit = 0, prescaler = 1, old_irq; if(cycles < 1) return false; if(start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } /* Increase prescale values starting from 0 to make the cycle count fit */ while(divider > 65535 && prescaler <= 1024) { prescaler <<= 2; /* 1, 4, 16, 64, 256, 1024 */ prescaler_bit++; divider = cycles / prescaler; } old_irq = disable_irq_save(); __tcu_stop_counter(1); if(start) { __tcu_disable_pwm_output(1); __tcu_mask_half_match_irq(1); __tcu_unmask_full_match_irq(1); /* EXTAL clock = CFG_EXTAL (12Mhz in most targets) */ __tcu_select_extalclk(1); } REG_TCU_TCSR(1) = (REG_TCU_TCSR(1) & ~TCU_TCSR_PRESCALE_MASK) | (prescaler_bit << TCU_TCSR_PRESCALE_BIT); REG_TCU_TCNT(1) = 0; REG_TCU_TDHR(1) = 0; REG_TCU_TDFR(1) = divider; __tcu_clear_full_match_flag(1); if(start) { system_enable_irq(IRQ_TCU1); __tcu_start_counter(1); } restore_irq(old_irq); return true; }
/* Unmask the DMA interrupt if enabled */ void pcm_play_unlock(void) { if(--locked == 0 && is_playing) { int old = disable_irq_save(); if(play_callback_pending) { play_callback_pending = false; dma_callback(); } restore_irq(old); } }
void pcm_rec_lock(void) { int oldlevel = disable_irq_save(); if (++rec_locked == 1) { bitset32(&CGU_PERI, CGU_I2SIN_APB_CLOCK_ENABLE); VIC_INT_EN_CLEAR = INTERRUPT_I2SIN; I2SIN_MASK = 0; /* disables all interrupts */ } restore_irq(oldlevel); }
void _backlight_off(void) { if (get_pmu_type() == PCF50606) { GPIOA_CLEAR = (1<<6); } else { int level = disable_irq_save(); pcf50635_write(PCF5063X_REG_LEDENA, 0); restore_irq(level); } }
void audio_set_output_source(int source) { int level = set_irq_level(DMA_IRQ_LEVEL); unsigned long txsrc; if ((unsigned)source >= AUDIO_NUM_SOURCES) txsrc = (3 << 8); /* playback, PDOR3 */ else txsrc = (4 << 8); /* recording, iis1RcvData */ IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc; restore_irq(level); } /* audio_set_output_source */