summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2018-06-29 16:09:28 -0400
committerSolomon Peachy <pizza@shaftnet.org>2019-01-02 08:10:01 -0500
commitd4942cc74c82c465ea395637c77ed06565b8b497 (patch)
tree8c1fa737c93f8a2ade5a1566857dc4dc8f578bd6 /firmware/drivers
parentaf9459a7992596e932c6d8cc0a6366ff0f0b0fca (diff)
Add Xuelin iHIFI 770/770C/800 support
Taken from the xvortex fork (Roman Stolyarov) Ported, rebased, and cleaned up by myself. Change-Id: I7b2bca2d29502f2e4544e42f3d122786dd4b7978
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/audio/es9018.c134
-rw-r--r--firmware/drivers/audio/wm8740.c106
2 files changed, 240 insertions, 0 deletions
diff --git a/firmware/drivers/audio/es9018.c b/firmware/drivers/audio/es9018.c
new file mode 100644
index 0000000000..89e8c1d46f
--- /dev/null
+++ b/firmware/drivers/audio/es9018.c
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2016 by Roman Stolyarov
+ *
+ * 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 "es9018.h"
+#include "config.h"
+#include "audio.h"
+#include "audiohw.h"
+
+/* NOTE: The register names are not known, as the register numbering
+ listed in the ES9018 datasheet does not match what is described below.. */
+
+static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */
+static uint8_t reg1 = 0x80; /* Input settings. Manual input, I2S, 32-bit (?) */
+static uint8_t reg4 = 0x00; /* Automute time. Default = disabled */
+static uint8_t reg5 = 0x68; /* Automute level. Default is some level */
+static uint8_t reg6 = 0x4A; /* Deemphasis. Default = disabled */
+static uint8_t reg7 = 0x83; /* General settings. Default sharp fir, pcm iir and muted */
+static uint8_t reg8 = 0x10; /* GPIO configuration */
+static uint8_t reg10 = 0x05; /* Master Mode Control. Default value: master mode off */
+static uint8_t reg11 = 0x02; /* Channel Mapping. Default stereo is Ch1=left, Ch2=right */
+static uint8_t reg12 = 0x50; /* DPLL Settings. Default = 005 for I2S, OFF for DSD */
+static uint8_t reg13 = 0x40; /* THD Compensation */
+static uint8_t reg14 = 0x8A; /* Soft Start Settings */
+static uint8_t reg21 = 0x00; /* Oversampling filter. Default: oversampling ON */
+
+#define bitSet(value, bit) ((value) |= (1UL << (bit)))
+#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
+
+static int vol_tenthdb2hw(const int tdb)
+{
+ if (tdb < ES9018_VOLUME_MIN) {
+ return 0xff;
+ } else if (tdb > ES9018_VOLUME_MAX) {
+ return 0x00;
+ } else {
+ return (-tdb/5);
+ }
+}
+
+void audiohw_set_volume(int vol_l, int vol_r)
+{
+ es9018_write_reg(15, vol_tenthdb2hw(vol_l));
+ es9018_write_reg(16, vol_tenthdb2hw(vol_r));
+}
+
+void audiohw_mute(void)
+{
+ bitSet(reg7, 0); /* Mute Channel 1 */
+ bitSet(reg7, 1); /* Mute Channel 2 */
+ es9018_write_reg(0x07, reg7);
+}
+
+void audiohw_unmute(void)
+{
+ bitClear(reg7, 0); /* Unmute Channel 1 */
+ bitClear(reg7, 1); /* Unmute Channel 2 */
+ es9018_write_reg(0x07, reg7);
+}
+
+void audiohw_init(void)
+{
+ es9018_write_reg(0x00, reg0);
+ es9018_write_reg(0x01, reg1);
+ es9018_write_reg(0x04, reg4);
+ es9018_write_reg(0x05, reg5);
+ es9018_write_reg(0x06, reg6);
+ es9018_write_reg(0x07, reg7);
+ es9018_write_reg(0x08, reg8);
+ es9018_write_reg(0x0A, reg10);
+ es9018_write_reg(0x0B, reg11);
+ es9018_write_reg(0x0C, reg12);
+ es9018_write_reg(0x0D, reg13);
+ es9018_write_reg(0x0E, reg14);
+ es9018_write_reg(0x15, reg21);
+}
+
+void audiohw_preinit(void)
+{
+}
+
+void audiohw_set_frequency(int fsel)
+{
+ (void)fsel;
+}
+
+void audiohw_set_filter_roll_off(int value)
+{
+ /* 0 = Sharp (Default)
+ 1 = Slow
+ 2 = Short
+ 3 = Bypass */
+ switch(value)
+ {
+ case 0:
+ bitClear(reg7, 5);
+ bitClear(reg7, 6);
+ bitClear(reg21, 0);
+ break;
+ case 1:
+ bitSet(reg7, 5);
+ bitClear(reg7, 6);
+ bitClear(reg21, 0);
+ break;
+ case 2:
+ bitClear(reg7, 5);
+ bitSet(reg7, 6);
+ bitClear(reg21, 0);
+ break;
+ case 3:
+ bitSet(reg21, 0);
+ break;
+ }
+ es9018_write_reg(0x07, reg7);
+ es9018_write_reg(0x15, reg21);
+}
diff --git a/firmware/drivers/audio/wm8740.c b/firmware/drivers/audio/wm8740.c
new file mode 100644
index 0000000000..d88f53bd75
--- /dev/null
+++ b/firmware/drivers/audio/wm8740.c
@@ -0,0 +1,106 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2016 by Roman Stolyarov
+ *
+ * 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 "wm8740.h"
+#include "config.h"
+#include "audio.h"
+#include "audiohw.h"
+
+static void wm8740_write_reg(const int reg, const unsigned int value)
+{
+ int i;
+
+ for (i = (1<<15); i; i >>= 1) {
+ udelay(1);
+ wm8740_set_mc(0);
+ if ((reg|value) & i) {
+ wm8740_set_md(1);
+ } else {
+ wm8740_set_md(0);
+ }
+ udelay(1);
+ wm8740_set_mc(1);
+ }
+ udelay(1);
+ wm8740_set_ml(0);
+ udelay(1);
+ wm8740_set_mc(0);
+ udelay(1);
+ wm8740_set_ml(1);
+ udelay(1);
+}
+
+static int vol_tenthdb2hw(const int tdb)
+{
+ if (tdb < WM8740_VOLUME_MIN) {
+ return 0x00;
+ } else if (tdb > WM8740_VOLUME_MAX) {
+ return 0xff;
+ } else {
+ return ((tdb / 5 + 0xff) & 0xff);
+ }
+}
+
+void audiohw_set_volume(int vol_l, int vol_r)
+{
+ wm8740_write_reg(WM8740_REG0, vol_tenthdb2hw(vol_l));
+ wm8740_write_reg(WM8740_REG1, vol_tenthdb2hw(vol_r) | WM8740_LDR);
+}
+
+void audiohw_mute(void)
+{
+ wm8740_write_reg(WM8740_REG2, WM8740_MUT);
+}
+
+void audiohw_unmute(void)
+{
+ wm8740_write_reg(WM8740_REG2, 0x00);
+}
+
+void audiohw_init(void)
+{
+ wm8740_write_reg(WM8740_REG0, 0x00);
+ wm8740_write_reg(WM8740_REG1, 0x00);
+ wm8740_write_reg(WM8740_REG2, WM8740_MUT);
+ wm8740_write_reg(WM8740_REG3, WM8740_I2S);
+ wm8740_write_reg(WM8740_REG4, 0x00);
+}
+
+void audiohw_preinit(void)
+{
+}
+
+void audiohw_set_frequency(int fsel)
+{
+ (void)fsel;
+}
+
+void audiohw_set_filter_roll_off(int value)
+{
+ /* 0 = fast (sharp);
+ 1 = slow */
+ if (value == 0) {
+ wm8740_write_reg(WM8740_REG3, WM8740_I2S);
+ } else {
+ wm8740_write_reg(WM8740_REG3, WM8740_I2S | WM8740_SR0);
+ }
+}