summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-10-18 22:06:05 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-10-18 22:06:05 +0000
commit7b70e5a8fae7ce8b0f9c74403c1efcc414297e35 (patch)
treeb07bffc5da4c952f0ff26a654579a245ad8acbe0
parent96f0464796639e241074a98b0a5dd7f07305d142 (diff)
downloadrockbox-7b70e5a8fae7ce8b0f9c74403c1efcc414297e35.tar.gz
rockbox-7b70e5a8fae7ce8b0f9c74403c1efcc414297e35.tar.bz2
rockbox-7b70e5a8fae7ce8b0f9c74403c1efcc414297e35.zip
imx233/fuze+: implement audioout functions (init, volume, frequency); add stubs for audioin
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30798 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/imx233/audioin-imx233.c33
-rw-r--r--firmware/target/arm/imx233/audioin-imx233.h4
-rw-r--r--firmware/target/arm/imx233/audioout-imx233.c179
-rw-r--r--firmware/target/arm/imx233/audioout-imx233.h95
4 files changed, 311 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/audioin-imx233.c b/firmware/target/arm/imx233/audioin-imx233.c
new file mode 100644
index 0000000000..4c2ee657f9
--- /dev/null
+++ b/firmware/target/arm/imx233/audioin-imx233.c
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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 "audioout-imx233.h"
+
+void imx233_audioin_preinit(void)
+{
+}
+
+void imx233_audioin_postinit(void)
+{
+}
+
+void imx233_audioin_close(void)
+{
+}
diff --git a/firmware/target/arm/imx233/audioin-imx233.h b/firmware/target/arm/imx233/audioin-imx233.h
index d4468f8d4a..c13f7cef56 100644
--- a/firmware/target/arm/imx233/audioin-imx233.h
+++ b/firmware/target/arm/imx233/audioin-imx233.h
@@ -24,4 +24,8 @@
#include "config.h"
#include "cpu.h"
+void imx233_audioin_preinit(void);
+void imx233_audioin_postinit(void);
+void imx233_audioin_close(void);
+
#endif /* __audioin_imx233__ */
diff --git a/firmware/target/arm/imx233/audioout-imx233.c b/firmware/target/arm/imx233/audioout-imx233.c
new file mode 100644
index 0000000000..0a48a909e8
--- /dev/null
+++ b/firmware/target/arm/imx233/audioout-imx233.c
@@ -0,0 +1,179 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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 "audioout-imx233.h"
+#include "clkctrl-imx233.h"
+#include "rtc-imx233.h"
+#include "pcm_sampr.h"
+
+void imx233_audioout_preinit(void)
+{
+ /* Enable AUDIOOUT block */
+ imx233_reset_block(&HW_AUDIOOUT_CTRL);
+ /* Enable digital filter clock */
+ imx233_enable_xtal_clock(XTAL_FILT, true);
+ /* Enable DAC */
+ __REG_CLR(HW_AUDIOOUT_ANACLKCTRL) = HW_AUDIOOUT_ANACLKCTRL__CLKGATE;
+ /* Set capless mode */
+ __REG_CLR(HW_AUDIOOUT_PWRDN) = HW_AUDIOOUT_PWRDN__CAPLESS;
+ /* Set word-length to 16-bit */
+ __REG_SET(HW_AUDIOOUT_CTRL) = HW_AUDIOOUT_CTRL__WORD_LENGTH;
+ /* Power up DAC */
+ __REG_CLR(HW_AUDIOOUT_PWRDN) = HW_AUDIOOUT_PWRDN__DAC;
+ /* Hold HP to ground to avoid pop, then release and power up HP */
+ __REG_SET(HW_AUDIOOUT_ANACTRL) = HW_AUDIOOUT_ANACTRL__HP_HOLD_GND;
+ __REG_SET(HW_RTC_PERSISTENT0) = HW_RTC_PERSISTENT0__SPARE__RELEASE_GND;
+ __REG_CLR(HW_AUDIOOUT_PWRDN) = HW_AUDIOOUT_PWRDN__HEADPHONE;
+ /* Set HP mode to AB */
+ __REG_SET(HW_AUDIOOUT_ANACTRL) = HW_AUDIOOUT_ANACTRL__HP_CLASSAB;
+ /* Stop holding to ground */
+ __REG_CLR(HW_AUDIOOUT_ANACTRL) = HW_AUDIOOUT_ANACTRL__HP_HOLD_GND;
+ /* Set dmawait count to 31 (see errata, workaround random stop) */
+ __REG_CLR(HW_AUDIOOUT_CTRL) = HW_AUDIOOUT_CTRL__DMAWAIT_COUNT_BM;
+ __REG_SET(HW_AUDIOOUT_CTRL) = 31 << HW_AUDIOOUT_CTRL__DMAWAIT_COUNT_BP;
+}
+
+void imx233_audioout_postinit(void)
+{
+ /* start converting audio */
+ __REG_SET(HW_AUDIOOUT_CTRL) = HW_AUDIOOUT_CTRL__RUN;
+}
+
+void imx233_audioout_close(void)
+{
+ /* Switch to class A */
+ __REG_CLR(HW_AUDIOOUT_ANACTRL) = HW_AUDIOOUT_ANACTRL__HP_CLASSAB;
+ /* Hold HP to ground */
+ __REG_SET(HW_AUDIOOUT_ANACTRL) = HW_AUDIOOUT_ANACTRL__HP_HOLD_GND;
+ /* Mute HP and power down */
+ __REG_SET(HW_AUDIOOUT_HPVOL) = HW_AUDIOOUT_HPVOL__MUTE;
+ /* Power down HP */
+ __REG_SET(HW_AUDIOOUT_PWRDN) = HW_AUDIOOUT_PWRDN__HEADPHONE;
+ /* Mute DAC */
+ __REG_SET(HW_AUDIOOUT_DACVOLUME) = HW_AUDIOOUT_DACVOLUME__MUTE_LEFT
+ | HW_AUDIOOUT_DACVOLUME__MUTE_RIGHT;
+ /* Power down DAC */
+ __REG_SET(HW_AUDIOOUT_PWRDN) = HW_AUDIOOUT_PWRDN__DAC;
+ /* Gate off DAC */
+ __REG_SET(HW_AUDIOOUT_ANACLKCTRL) = HW_AUDIOOUT_ANACLKCTRL__CLKGATE;
+ /* Disable digital filter clock */
+ imx233_enable_xtal_clock(XTAL_FILT, false);
+ /* will also gate off the module */
+ __REG_CLR(HW_AUDIOOUT_CTRL) = HW_AUDIOOUT_CTRL__RUN;
+}
+/* volume in half dB */
+void imx233_audioout_set_dac_vol(int vol_l, int vol_r)
+{
+ /* minimum is -100dB and max is 0dB */
+ vol_l = MAX(-200, MIN(vol_l, 0));
+ vol_r = MAX(-200, MIN(vol_r, 0));
+ /* unmute, enable zero cross and set volume.
+ * 0xff is 0dB */
+ HW_AUDIOOUT_DACVOLUME =
+ (0xff + vol_l) << HW_AUDIOOUT_DACVOLUME__VOLUME_LEFT_BP |
+ (0xff + vol_r) << HW_AUDIOOUT_DACVOLUME__VOLUME_RIGHT_BP |
+ HW_AUDIOOUT_DACVOLUME__EN_ZCD;
+}
+
+void imx233_audioout_set_hp_vol(int vol_l, int vol_r)
+{
+ uint32_t select = (HW_AUDIOOUT_HPVOL & HW_AUDIOOUT_HPVOL__SELECT);
+ /* minimum is -57.5dB and max is 6dB in DAC mode
+ * and -51.5dB / 12dB in Line1 mode */
+ int min = select ? -103 : -115;
+ int max = select ? 24 : 12;
+
+ vol_l = MAX(min, MIN(vol_l, max));
+ vol_r = MAX(min, MIN(vol_r, max));
+ /* unmute, enable zero cross and set volume. Keep select value. */
+ HW_AUDIOOUT_HPVOL =
+ (max - vol_l) << HW_AUDIOOUT_HPVOL__VOL_LEFT_BP |
+ (max - vol_r) << HW_AUDIOOUT_HPVOL__VOL_RIGHT_BP |
+ select |
+ HW_AUDIOOUT_HPVOL__EN_MSTR_ZCD;
+}
+
+void imx233_audioout_set_freq(int fsel)
+{
+ static struct
+ {
+ int base_mult;
+ int src_hold;
+ int src_int;
+ int src_frac;
+ }dacssr[HW_NUM_FREQ] =
+ {
+ HW_HAVE_8_([HW_FREQ_8] = { 0x1, 0x3, 0x17, 0xe00 } ,)
+ HW_HAVE_11_([HW_FREQ_11] = { 0x1, 0x3, 0x11, 0x37 } ,)
+ HW_HAVE_12_([HW_FREQ_12] = { 0x1, 0x3, 0xf, 0x13ff },)
+ HW_HAVE_16_([HW_FREQ_16] = { 0x1, 0x1, 0x17, 0xe00},)
+ HW_HAVE_22_([HW_FREQ_22] = { 0x1, 0x1, 0x11, 0x37 },)
+ HW_HAVE_24_([HW_FREQ_24] = { 0x1, 0x1, 0xf, 0x13ff },)
+ HW_HAVE_32_([HW_FREQ_32] = { 0x1, 0x0, 0x17, 0xe00},)
+ HW_HAVE_44_([HW_FREQ_44] = { 0x1, 0x0, 0x11, 0x37 },)
+ HW_HAVE_48_([HW_FREQ_48] = { 0x1, 0x0, 0xf, 0x13ff },)
+ HW_HAVE_64_([HW_FREQ_64] = { 0x2, 0x0, 0x17, 0xe00},)
+ HW_HAVE_88_([HW_FREQ_88] = { 0x2, 0x0, 0x11, 0x37 },)
+ HW_HAVE_96_([HW_FREQ_96] = { 0x2, 0x0, 0xf, 0x13ff },)
+ };
+
+ HW_AUDIOOUT_DACSRR =
+ dacssr[fsel].src_frac << HW_AUDIOOUT_DACSRR__SRC_FRAC_BP |
+ dacssr[fsel].src_int << HW_AUDIOOUT_DACSRR__SRC_INT_BP |
+ dacssr[fsel].src_hold << HW_AUDIOOUT_DACSRR__SRC_HOLD_BP |
+ dacssr[fsel].base_mult << HW_AUDIOOUT_DACSRR__BASEMULT_BP;
+
+ #if 0
+ /* Select base_mult and src_hold depending on the audio range:
+ * 0 < f <= 12000 --> base_mult = 1, src_hold = 3 (div by 4)
+ * 12000 < f <= 24000 --> base_mult = 1, src_hold = 1 (div by 2)
+ * 24000 < f <= 48000 --> base_mult = 1, src_hold = 0 (div by 1)
+ * 48000 < f <= 96000 --> base_mult = 2, src_hold = 0 (mul by 2)
+ * 96000 < f <= ..... --> base_mult = 4, src_hold = 0 (mul by 4) */
+ int base_mult = 1;
+ int src_hold = 0;
+ if(f > 96000)
+ base_mult = 4;
+ else if(f > 48000)
+ base_mult = 2;
+ else if(f <= 12000)
+ src_hold = 3;
+ else if(f <= 24000)
+ src_hold = 1;
+ /* compute the divisor (a tricky to keep to do it with 32-bit words only) */
+ int src_int = (750000 * base_mult) / (f * (src_hold + 1));
+ int src_frac = ((750000 * base_mult - src_int * f * (src_hold + 1)) << 13) / (f * (src_hold + 1));
+
+ HW_AUDIOOUT_DACSRR =
+ src_frac << HW_AUDIOOUT_DACSRR__SRC_FRAC_BP |
+ src_int << HW_AUDIOOUT_DACSRR__SRC_INT_BP |
+ src_hold << HW_AUDIOOUT_DACSRR__SRC_HOLD_BP |
+ base_mult << HW_AUDIOOUT_DACSRR__BASEMULT_BP;
+ #endif
+}
+
+/* select between DAC and Line1 */
+void imx233_audiout_select_hp_input(bool line1)
+{
+ if(line1)
+ __REG_SET(HW_AUDIOOUT_HPVOL) = HW_AUDIOOUT_HPVOL__SELECT;
+ else
+ __REG_CLR(HW_AUDIOOUT_HPVOL) = HW_AUDIOOUT_HPVOL__SELECT;
+}
diff --git a/firmware/target/arm/imx233/audioout-imx233.h b/firmware/target/arm/imx233/audioout-imx233.h
index 913e633de0..cd997e7d31 100644
--- a/firmware/target/arm/imx233/audioout-imx233.h
+++ b/firmware/target/arm/imx233/audioout-imx233.h
@@ -23,5 +23,100 @@
#include "config.h"
#include "cpu.h"
+#include "system.h"
+
+#define HW_AUDIOOUT_BASE 0x80048000
+
+#define HW_AUDIOOUT_CTRL (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x0))
+#define HW_AUDIOOUT_CTRL__RUN (1 << 0)
+#define HW_AUDIOOUT_CTRL__FIFO_ERROR_IRQ_EN (1 << 1)
+#define HW_AUDIOOUT_CTRL__FIFO_OVERFLOW_IRQ (1 << 2)
+#define HW_AUDIOOUT_CTRL__FIFO_UNDERFLOW_IRQ (1 << 3)
+#define HW_AUDIOOUT_CTRL__WORD_LENGTH (1 << 6)
+#define HW_AUDIOOUT_CTRL__SS3D_EFFECT_BP 8
+#define HW_AUDIOOUT_CTRL__SS3D_EFFECT_BM (3 << 8)
+#define HW_AUDIOOUT_CTRL__SS3D_EFFECT_OFF (0 << 8)
+#define HW_AUDIOOUT_CTRL__SS3D_EFFECT_3 (1 << 8)
+#define HW_AUDIOOUT_CTRL__SS3D_EFFECT_4P5 (2 << 8)
+#define HW_AUDIOOUT_CTRL__SS3D_EFFECT_6 (3 << 8)
+#define HW_AUDIOOUT_CTRL__DMAWAIT_COUNT_BP 16
+#define HW_AUDIOOUT_CTRL__DMAWAIT_COUNT_BM (0x1f << 16)
+
+#define HW_AUDIOOUT_DACSRR (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x20))
+#define HW_AUDIOOUT_DACSRR__SRC_FRAC_BP 0
+#define HW_AUDIOOUT_DACSRR__SRC_FRAC_BM (0x1ff << 0)
+#define HW_AUDIOOUT_DACSRR__SRC_INT_BP 16
+#define HW_AUDIOOUT_DACSRR__SRC_INT_BM (0x1f << 16)
+#define HW_AUDIOOUT_DACSRR__SRC_HOLD_BP 24
+#define HW_AUDIOOUT_DACSRR__SRC_HOLD_BM (0x7 << 24)
+#define HW_AUDIOOUT_DACSRR__BASEMULT_BP 28
+#define HW_AUDIOOUT_DACSRR__BASEMULT_BM (0x7 << 28)
+#define HW_AUDIOOUT_DACSRR__OSR (1 << 31)
+
+#define HW_AUDIOOUT_DACVOLUME (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x30))
+#define HW_AUDIOOUT_DACVOLUME__VOLUME_RIGHT_BP 0
+#define HW_AUDIOOUT_DACVOLUME__VOLUME_RIGHT_BM 0xff
+#define HW_AUDIOOUT_DACVOLUME__MUTE_RIGHT (1 << 8)
+#define HW_AUDIOOUT_DACVOLUME__VOLUME_UPDATE_RIGHT (1 << 12)
+#define HW_AUDIOOUT_DACVOLUME__VOLUME_LEFT_BP 16
+#define HW_AUDIOOUT_DACVOLUME__VOLUME_LEFT_BM (0xff << 16)
+#define HW_AUDIOOUT_DACVOLUME__MUTE_LEFT (1 << 24)
+#define HW_AUDIOOUT_DACVOLUME__EN_ZCD (1 << 25)
+#define HW_AUDIOOUT_DACVOLUME__VOLUME_UPDATE_LEFT (1 << 28)
+
+#define HW_AUDIOOUT_DACDEBUG (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x40))
+#define HW_AUDIOOUT_DACDEBUG__FIFO_STATUS 1
+
+
+#define HW_AUDIOOUT_HPVOL (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x50))
+#define HW_AUDIOOUT_HPVOL__VOL_RIGHT_BP 0
+#define HW_AUDIOOUT_HPVOL__VOL_RIGHT_BM (0x7f << 0)
+#define HW_AUDIOOUT_HPVOL__VOL_LEFT_BP 8
+#define HW_AUDIOOUT_HPVOL__VOL_LEFT_BM (0x7f << 8)
+#define HW_AUDIOOUT_HPVOL__SELECT (1 << 16)
+#define HW_AUDIOOUT_HPVOL__MUTE (1 << 24)
+#define HW_AUDIOOUT_HPVOL__EN_MSTR_ZCD (1 << 25)
+
+#define HW_AUDIOOUT_PWRDN (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x70))
+#define HW_AUDIOOUT_PWRDN__HEADPHONE (1 << 0)
+#define HW_AUDIOOUT_PWRDN__CAPLESS (1 << 4)
+#define HW_AUDIOOUT_PWRDN__ADC (1 << 8)
+#define HW_AUDIOOUT_PWRDN__DAC (1 << 12)
+#define HW_AUDIOOUT_PWRDN__RIGHT_ADC (1 << 16)
+#define HW_AUDIOOUT_PWRDN__SPEAKER (1 << 24)
+
+#define HW_AUDIOOUT_REFCTRL (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x80))
+#define HW_AUDIOOUT_REFCTRL__LOW_PWR (1 << 19)
+
+#define HW_AUDIOOUT_ANACTRL (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x90))
+#define HW_AUDIOOUT_ANACTRL__HP_CLASSAB (1 << 4)
+#define HW_AUDIOOUT_ANACTRL__HP_HOLD_GND (1 << 5)
+#define HW_AUDIOOUT_ANACTRL__SHORTMODE_LR_BP 17
+#define HW_AUDIOOUT_ANACTRL__SHORTMODE_LR_BM (3 << 17)
+#define HW_AUDIOOUT_ANACTRL__SHORTMODE_CM_BP 20
+#define HW_AUDIOOUT_ANACTRL__SHORTMODE_CM_BM (3 << 20)
+#define HW_AUDIOOUT_ANACTRL__SHORT_LR_STS (1 << 24)
+#define HW_AUDIOOUT_ANACTRL__SHORT_CM_STS (1 << 28)
+
+#define HW_AUDIOOUT_ANACLKCTRL (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0xe0))
+#define HW_AUDIOOUT_ANACLKCTRL__DACDIV_BP 0
+#define HW_AUDIOOUT_ANACLKCTRL__DACDIV_BM (7 << 0)
+#define HW_AUDIOOUT_ANACLKCTRL__CLKGATE (1 << 31)
+
+#define HW_AUDIOOUT_DATA (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0xf0))
+
+#define HW_AUDIOOUT_VERSION (*(volatile uint32_t *)(HW_AUDIOOUT_BASE + 0x200))
+
+
+void imx233_audioout_preinit(void);
+void imx233_audioout_postinit(void);
+void imx233_audioout_close(void);
+/* volume in half dB */
+void imx233_audioout_set_dac_vol(int vol_l, int vol_r);
+void imx233_audioout_set_hp_vol(int vol_l, int vol_r);
+/* frequency index, NOT the frequency itself */
+void imx233_audioout_set_freq(int fsel);
+/* select between DAC and Line1 */
+void imx233_audiout_select_hp_input(bool line1);
#endif /* __audioout_imx233__ */