diff options
| author | Linus Nielsen Feltzing <linus@haxx.se> | 2005-03-18 11:34:26 +0000 |
|---|---|---|
| committer | Linus Nielsen Feltzing <linus@haxx.se> | 2005-03-18 11:34:26 +0000 |
| commit | a3176e4d828e335b16c60948fea10ba0b078057e (patch) | |
| tree | ddf4aed86c15dfa796e4a172b9438c023c1336bd | |
| parent | 752d0bb8be47b8c2b67c7b1a3bbf2a70fd582e92 (diff) | |
| download | rockbox-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.c | 166 | ||||
| -rw-r--r-- | firmware/export/i2c-h100.h | 64 |
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 |