summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/iriver
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2007-11-11 16:00:33 +0000
committerBarry Wardell <rockbox@barrywardell.net>2007-11-11 16:00:33 +0000
commitc495cdae5926c9245d7c943c72a97206d4a0e22a (patch)
tree86afcd473d1c151ffd26fcb8e941be44a0bbbf53 /firmware/target/arm/iriver
parent496027d8bb89ba6d503b544f5652f4d1683d43af (diff)
downloadrockbox-c495cdae5926c9245d7c943c72a97206d4a0e22a.tar.gz
rockbox-c495cdae5926c9245d7c943c72a97206d4a0e22a.zip
FS#8046: H10 FM tuner support. Thanks to Przemyslaw Holubowski for doing the hard work in figuring out how to communicate with the tuner.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15578 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/iriver')
-rw-r--r--firmware/target/arm/iriver/h10/fmradio_i2c-h10.c206
-rw-r--r--firmware/target/arm/iriver/h10/power-h10.c2
2 files changed, 206 insertions, 2 deletions
diff --git a/firmware/target/arm/iriver/h10/fmradio_i2c-h10.c b/firmware/target/arm/iriver/h10/fmradio_i2c-h10.c
new file mode 100644
index 0000000000..f3d3075df9
--- /dev/null
+++ b/firmware/target/arm/iriver/h10/fmradio_i2c-h10.c
@@ -0,0 +1,206 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ * Physical interface of the Philips TEA5767 in iriver H10 series
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+#include "logf.h"
+#include "system.h"
+
+/* cute little functions, atomic read-modify-write */
+
+#define SDA_OUTINIT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08)
+#define SDA_HI_IN GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08)
+#define SDA_LO_OUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08)
+#define SDA (GPIOD_INPUT_VAL & 0x08)
+
+#define SCL_INPUT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x10)
+#define SCL_OUTPUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x10)
+#define SCL_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x10)
+#define SCL_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL,0x10)
+#define SCL (GPIOD_INPUT_VAL & 0x10)
+
+#define DELAY udelay(2)
+
+static void fmradio_i2c_start(void)
+{
+ SCL_HI;
+ SCL_OUTPUT;
+ SDA_HI_IN;
+ SDA_OUTINIT;
+ DELAY;
+ SDA_LO_OUT;
+ DELAY;
+ SCL_LO;
+}
+
+static void fmradio_i2c_stop(void)
+{
+ SDA_LO_OUT;
+ DELAY;
+ SCL_HI;
+ DELAY;
+ SDA_HI_IN;
+}
+
+/* Generate ACK or NACK */
+static void fmradio_i2c_ack(bool nack)
+{
+ /* Here's the deal. The slave is slow, and sometimes needs to wait
+ before it can receive the acknowledge. Therefore it forces the clock
+ low until it is ready. We need to poll the clock line until it goes
+ high before we release the ack.
+
+ In their infinite wisdom, iriver didn't pull up the SCL line, so
+ we have to drive the SCL high repeatedly to simulate a pullup. */
+
+ if (nack)
+ SDA_HI_IN;
+ else
+ SDA_LO_OUT;
+ DELAY;
+
+ SCL_HI;
+ do
+ {
+ SCL_OUTPUT; /* Set the clock to output */
+ SCL_INPUT; /* Set the clock to input */
+ DELAY;
+ }
+ while(!SCL); /* and wait for the slave to release it */
+
+ SCL_OUTPUT;
+ SCL_LO;
+}
+
+static int fmradio_i2c_getack(void)
+{
+ int ret = 1;
+
+ /* Here's the deal. The slave is slow, and sometimes needs to wait
+ before it can send the acknowledge. Therefore it forces the clock
+ low until it is ready. We need to poll the clock line until it goes
+ high before we read the ack.
+
+ In their infinite wisdom, iriver didn't pull up the SCL line, so
+ we have to drive the SCL high repeatedly to simulate a pullup. */
+
+ SDA_HI_IN;
+ DELAY;
+
+ SCL_HI; /* set clock to high */
+ do
+ {
+ SCL_OUTPUT; /* Set the clock to output */
+ SCL_INPUT; /* Set the clock to input */
+ DELAY;
+ }
+ while(!SCL); /* and wait for the slave to release it */
+
+ if (SDA)
+ ret = 0; /* ack failed */
+
+ SCL_OUTPUT;
+ SCL_LO;
+
+ return ret;
+}
+
+static void fmradio_i2c_outb(unsigned char byte)
+{
+ int i;
+
+ /* clock out each bit, MSB first */
+ for ( i=0x80; i; i>>=1 ) {
+ if ( i & byte )
+ SDA_HI_IN;
+ else
+ SDA_LO_OUT;
+ DELAY;
+ SCL_HI;
+ DELAY;
+ SCL_LO;
+ }
+}
+
+static unsigned char fmradio_i2c_inb(void)
+{
+ int i;
+ unsigned char byte = 0;
+
+ SDA_HI_IN;
+ /* clock in each bit, MSB first */
+ for ( i=0x80; i; i>>=1 ) {
+ DELAY;
+ SCL_HI;
+ DELAY;
+ if ( SDA )
+ byte |= i;
+ SCL_LO;
+ }
+
+ return byte;
+}
+
+int fmradio_i2c_write(int address, const unsigned char* buf, int count)
+{
+ int i,x=0;
+
+ fmradio_i2c_start();
+ fmradio_i2c_outb(address & 0xfe);
+ if (fmradio_i2c_getack())
+ {
+ for (i=0; i<count; i++)
+ {
+ fmradio_i2c_outb(buf[i]);
+ if (!fmradio_i2c_getack())
+ {
+ x=-2;
+ break;
+ }
+ }
+ }
+ else
+ {
+ logf("fmradio_i2c_write() - no ack\n");
+ x=-1;
+ }
+ fmradio_i2c_stop();
+ return x;
+}
+
+int fmradio_i2c_read(int address, unsigned char* buf, int count)
+{
+ int i,x=0;
+
+ fmradio_i2c_start();
+ fmradio_i2c_outb(address | 1);
+
+ if (fmradio_i2c_getack())
+ {
+ for (i=count; i>0; i--)
+ {
+ *buf++ = fmradio_i2c_inb();
+ fmradio_i2c_ack(i == 1);
+ }
+ }
+ else
+ x=-1;
+ fmradio_i2c_stop();
+ return x;
+}
diff --git a/firmware/target/arm/iriver/h10/power-h10.c b/firmware/target/arm/iriver/h10/power-h10.c
index 7f3fb40b36..f4d5be49a6 100644
--- a/firmware/target/arm/iriver/h10/power-h10.c
+++ b/firmware/target/arm/iriver/h10/power-h10.c
@@ -35,7 +35,6 @@
bool charger_enabled;
#endif
-#if 0
#if CONFIG_TUNER
bool tuner_power(bool status)
@@ -46,7 +45,6 @@ bool tuner_power(bool status)
}
#endif /* #if CONFIG_TUNER */
-#endif
void power_init(void)
{