summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-03-18 11:34:26 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-03-18 11:34:26 +0000
commita3176e4d828e335b16c60948fea10ba0b078057e (patch)
treeddf4aed86c15dfa796e4a172b9438c023c1336bd
parent752d0bb8be47b8c2b67c7b1a3bbf2a70fd582e92 (diff)
downloadrockbox-a3176e4d828e335b16c60948fea10ba0b078057e.zip
rockbox-a3176e4d828e335b16c60948fea10ba0b078057e.tar.gz
rockbox-a3176e4d828e335b16c60948fea10ba0b078057e.tar.bz2
rockbox-a3176e4d828e335b16c60948fea10ba0b078057e.tar.xz
iRiver I2C driver by Andy Young
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6203 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/i2c-h100.c166
-rw-r--r--firmware/export/i2c-h100.h64
2 files changed, 230 insertions, 0 deletions
diff --git a/firmware/drivers/i2c-h100.c b/firmware/drivers/i2c-h100.c
new file mode 100644
index 0000000..e2fbea2
--- /dev/null
+++ b/firmware/drivers/i2c-h100.c
@@ -0,0 +1,166 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Andy Young
+ *
+ * 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 "cpu.h"
+#include "kernel.h"
+#include "debug.h"
+#include "system.h"
+#include "i2c-h100.h"
+
+#define I2C_DEVICE_1 ((volatile unsigned char *)&MADR)
+#define I2C_DEVICE_2 ((volatile unsigned char *)&MADR2)
+
+/* Local functions definitions */
+
+static int i2c_write_byte(int device, unsigned char data);
+static int i2c_gen_start(int device);
+static void i2c_gen_stop(int device);
+static volatile unsigned char *i2c_get_addr(int device);
+
+/* Public functions */
+
+void i2c_init(void)
+{
+ /* Audio Codec */
+ MADR = 0x6c; /* iRiver firmware uses this addr */
+ MBDR = 0; /* iRiver firmware does this */
+ MBCR = IEN; /* Enable interface */
+
+#if 0
+ /* FM Tuner */
+ MADR2 = 0x6c;
+ MBDR2 = 0;
+ MBCR2 = IEN;
+#endif
+}
+
+void i2c_close(void)
+{
+ MBCR = 0;
+
+#if 0
+ MBCR2 = 0;
+#endif
+}
+
+/**
+ * Writes bytes to the selected device.
+ *
+ * Use device=1 for bus 1 at 0x40000280 (Audio Codec)
+ * Use device=2 for bus 2 at 0x80000440 (Tuner ?)
+ *
+ * Returns number of bytes successfully send or -1 if START failed
+ */
+int i2c_write(int device, unsigned char *buf, int count)
+{
+ int i;
+
+ if (i2c_gen_start(device) == -1)
+ {
+ DEBUGF("i2c: gen_start failed (d=%d)", device);
+ return -1;
+ }
+
+ for (i=0; i<count; i++)
+ {
+ if (i2c_write_byte(device, buf[i]) == -1)
+ {
+ DEBUGF("i2c: write failed at (d=%d,i=%d)", device, i);
+ return i-1;
+ }
+ }
+
+ i2c_gen_stop(device);
+
+ return count;
+}
+
+/* Write a byte to the interface, returns 0 on success, -1 otherwise. */
+int i2c_write_byte(int device, unsigned char data)
+{
+ volatile unsigned char *regs = i2c_get_addr(device);
+
+ long count = 0;
+
+ regs[O_MBDR] = data; /* Write data byte */
+
+ /* Wait for bus busy */
+ while (!(regs[O_MBSR] & IBB) && count < MAX_LOOP)
+ {
+ yield();
+ count++;
+ }
+
+ if (count >= MAX_LOOP)
+ return -1;
+
+ /* Wait for interrupt flag */
+ while (!(regs[O_MBSR] & IFF) && count < MAX_LOOP)
+ {
+ yield();
+ count++;
+ }
+
+ if (count >= MAX_LOOP)
+ return -1;
+
+ regs[O_MBSR] &= ~IFF; /* Clear interrupt flag */
+
+ if (!(regs[O_MBSR] & ICF)) /* Check that transfer is complete */
+ return -1;
+
+ if (regs[O_MBSR] & RXAK) /* Check that the byte has been ACKed */
+ return -1;
+
+ return 0;
+}
+
+
+/* Returns 0 on success, -1 on failure */
+int i2c_gen_start(int device)
+{
+ volatile unsigned char *regs = i2c_get_addr(device);
+ long count = 0;
+
+ /* Wait for bus to become free */
+ while ((regs[O_MBSR] & IBB) && (count < MAX_LOOP))
+ count++;
+
+ if (count >= MAX_LOOP)
+ return -1;
+
+ regs[O_MBCR] |= MSTA | MTX; /* Generate START */
+
+ return 0;
+}
+
+void i2c_gen_stop(int device)
+{
+ volatile unsigned char *regs = i2c_get_addr(device);
+ regs[O_MBCR] &= ~MSTA; /* Clear MSTA to generate STOP */
+}
+
+
+volatile unsigned char *i2c_get_addr(int device)
+{
+ if (device == 1)
+ return I2C_DEVICE_1;
+
+ return I2C_DEVICE_2;
+}
diff --git a/firmware/export/i2c-h100.h b/firmware/export/i2c-h100.h
new file mode 100644
index 0000000..f8fd423
--- /dev/null
+++ b/firmware/export/i2c-h100.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/*
+ * Driver for MCF5249's I2C interface
+ * 2005-02-17 hubble@mochine.com
+ *
+ */
+
+#ifndef _I2C_H100_H
+#define _I2C_H100_H
+
+void i2c_init(void);
+int i2c_write(int device, unsigned char *buf, int count);
+void i2c_close(void);
+
+
+#define MAX_LOOP 0x10000 /* TODO: select a better value */
+
+/* PLLCR control */
+#define QSPISEL (1 << 11) /* Selects QSPI or I2C interface */
+
+/* Offsets to I2C registers from base address */
+#define O_MADR 0x00 /* Slave Address */
+#define O_MFDR 0x04 /* Frequency divider */
+#define O_MBCR 0x08 /* Control register */
+#define O_MBSR 0x0c /* Status register */
+#define O_MBDR 0x10 /* Data register */
+
+/* MBSR - Status register */
+#define ICF (1 << 7) /* Transfer Complete */
+#define IAAS (1 << 6) /* Addressed As Alave */
+#define IBB (1 << 5) /* Bus Busy */
+#define IAL (1 << 4) /* Arbitration Lost */
+#define SRW (1 << 2) /* Slave R/W */
+#define IFF (1 << 1) /* I2C Interrupt */
+#define RXAK (1 << 0) /* No Ack bit */
+
+/* MBCR - Control register */
+#define IEN (1 << 7) /* I2C Enable */
+#define IIEN (1 << 6) /* Interrupt Enable */
+#define MSTA (1 << 5) /* Master/Slave select */
+#define MTX (1 << 4) /* Transmit/Receive */
+#define TXAK (1 << 3) /* Transfer ACK */
+#define RSTA (1 << 2) /* Restart.. */
+
+
+#endif