From 696b9d146b69b36fc309233f62d43f4f57f26823 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Tue, 13 Sep 2011 23:40:09 +0000 Subject: imx233/fuze+: implement lradc function and adc on top of it git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30534 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/imx233/lradc-imx233.c | 146 ++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 firmware/target/arm/imx233/lradc-imx233.c (limited to 'firmware/target/arm/imx233/lradc-imx233.c') diff --git a/firmware/target/arm/imx233/lradc-imx233.c b/firmware/target/arm/imx233/lradc-imx233.c new file mode 100644 index 0000000000..7da58c64b3 --- /dev/null +++ b/firmware/target/arm/imx233/lradc-imx233.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 by Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "system.h" +#include "system-target.h" +#include "lradc-imx233.h" + +static struct semaphore free_bm_sema; +static struct mutex free_bm_mutex; +static unsigned free_bm; + +void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) +{ + __REG_CLR(HW_LRADC_CHx(channel)) =HW_LRADC_CHx__NUM_SAMPLES_BM | HW_LRADC_CHx__ACCUMULATE; + __REG_SET(HW_LRADC_CHx(channel)) = nr_samples << HW_LRADC_CHx__NUM_SAMPLES_BP | + acc << HW_LRADC_CHx__ACCUMULATE; + if(div2) + __REG_SET(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__DIVIDE_BY_TWO(channel); + else + __REG_CLR(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__DIVIDE_BY_TWO(channel); + __REG_CLR(HW_LRADC_CTRL4) = HW_LRADC_CTRL4__LRADCxSELECT_BM(channel); + __REG_SET(HW_LRADC_CTRL4) = src << HW_LRADC_CTRL4__LRADCxSELECT_BP(channel); +} + +void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays, + int loop_count, int delay) +{ + HW_LRADC_DELAYx(dchan) = + trigger_lradc << HW_LRADC_DELAYx__TRIGGER_LRADCS_BP | + trigger_delays << HW_LRADC_DELAYx__TRIGGER_DELAYS_BP | + loop_count << HW_LRADC_DELAYx__LOOP_COUNT_BP | + delay << HW_LRADC_DELAYx__DELAY_BP; +} + +void imx233_lradc_kick_channel(int channel) +{ + __REG_CLR(HW_LRADC_CTRL1) = HW_LRADC_CTRL1__LRADCx_IRQ(channel); + __REG_SET(HW_LRADC_CTRL0) = HW_LRADC_CTRL0__SCHEDULE(channel); +} + +void imx233_lradc_kick_delay(int dchan) +{ + __REG_SET(HW_LRADC_DELAYx(dchan)) = HW_LRADC_DELAYx__KICK; +} + +void imx233_lradc_wait_channel(int channel) +{ + /* wait for completion */ + while(!(HW_LRADC_CTRL1 & HW_LRADC_CTRL1__LRADCx_IRQ(channel))) + yield(); +} + +int imx233_lradc_read_channel(int channel) +{ + return __XTRACT_EX(HW_LRADC_CHx(channel), HW_LRADC_CHx__VALUE); +} + +void imx233_lradc_clear_channel(int channel) +{ + __REG_CLR(HW_LRADC_CHx(channel)) = HW_LRADC_CHx__VALUE_BM; +} + +int imx233_lradc_acquire_channel(int timeout) +{ + int w = semaphore_wait(&free_bm_sema, timeout); + if(w == OBJ_WAIT_TIMEDOUT) + return w; + mutex_lock(&free_bm_mutex); + int chan = find_first_set_bit(free_bm); + if(chan >= HW_LRADC_NUM_CHANNELS) + panicf("imx233_lradc_acquire_channel cannot find a free channel !"); + free_bm &= ~(1 << chan); + mutex_unlock(&free_bm_mutex); + return chan; +} + +void imx233_lradc_release_channel(int chan) +{ + mutex_lock(&free_bm_mutex); + free_bm |= 1 << chan; + mutex_unlock(&free_bm_mutex); + semaphore_release(&free_bm_sema); +} + +void imx233_lradc_reserve_channel(int channel) +{ + semaphore_wait(&free_bm_sema, TIMEOUT_NOBLOCK); + mutex_lock(&free_bm_mutex); + free_bm &= ~(1 << channel); + mutex_unlock(&free_bm_mutex); +} + +int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) +{ + // mux sensors + __REG_CLR(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMPSENSE_PWD; + imx233_lradc_clear_channel(nmos_chan); + imx233_lradc_clear_channel(pmos_chan); + // schedule both channels + imx233_lradc_kick_channel(nmos_chan); + imx233_lradc_kick_channel(pmos_chan); + // wait completion + imx233_lradc_wait_channel(nmos_chan); + imx233_lradc_wait_channel(pmos_chan); + // mux sensors + __REG_SET(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMPSENSE_PWD; + // do the computation + int diff = imx233_lradc_read_channel(nmos_chan) - imx233_lradc_read_channel(pmos_chan); + // return diff * 1.012 / 4 + return (diff * 1012) / 4000; +} + +void imx233_lradc_init(void) +{ + mutex_init(&free_bm_mutex); + semaphore_init(&free_bm_sema, HW_LRADC_NUM_CHANNELS, HW_LRADC_NUM_CHANNELS); + free_bm = (1 << HW_LRADC_NUM_CHANNELS) - 1; + // enable block + imx233_reset_block(&HW_LRADC_CTRL0); + // disable ground ref + __REG_CLR(HW_LRADC_CTRL0) = HW_LRADC_CTRL0__ONCHIP_GROUNDREF; + // disable temperature sensors + __REG_CLR(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMP_SENSOR_IENABLE0 | + HW_LRADC_CTRL2__TEMP_SENSOR_IENABLE1; + __REG_SET(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMPSENSE_PWD; + // set frequency + __REG_CLR(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME_BM; + __REG_SET(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME__6MHz; +} -- cgit v1.2.3