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.tar.gz rockbox-a3176e4d828e335b16c60948fea10ba0b078057e.zip |
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 0000000000..e2fbea2573 --- /dev/null +++ b/firmware/drivers/i2c-h100.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Andy Young | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "cpu.h" | ||
21 | #include "kernel.h" | ||
22 | #include "debug.h" | ||
23 | #include "system.h" | ||
24 | #include "i2c-h100.h" | ||
25 | |||
26 | #define I2C_DEVICE_1 ((volatile unsigned char *)&MADR) | ||
27 | #define I2C_DEVICE_2 ((volatile unsigned char *)&MADR2) | ||
28 | |||
29 | /* Local functions definitions */ | ||
30 | |||
31 | static int i2c_write_byte(int device, unsigned char data); | ||
32 | static int i2c_gen_start(int device); | ||
33 | static void i2c_gen_stop(int device); | ||
34 | static volatile unsigned char *i2c_get_addr(int device); | ||
35 | |||
36 | /* Public functions */ | ||
37 | |||
38 | void i2c_init(void) | ||
39 | { | ||
40 | /* Audio Codec */ | ||
41 | MADR = 0x6c; /* iRiver firmware uses this addr */ | ||
42 | MBDR = 0; /* iRiver firmware does this */ | ||
43 | MBCR = IEN; /* Enable interface */ | ||
44 | |||
45 | #if 0 | ||
46 | /* FM Tuner */ | ||
47 | MADR2 = 0x6c; | ||
48 | MBDR2 = 0; | ||
49 | MBCR2 = IEN; | ||
50 | #endif | ||
51 | } | ||
52 | |||
53 | void i2c_close(void) | ||
54 | { | ||
55 | MBCR = 0; | ||
56 | |||
57 | #if 0 | ||
58 | MBCR2 = 0; | ||
59 | #endif | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Writes bytes to the selected device. | ||
64 | * | ||
65 | * Use device=1 for bus 1 at 0x40000280 (Audio Codec) | ||
66 | * Use device=2 for bus 2 at 0x80000440 (Tuner ?) | ||
67 | * | ||
68 | * Returns number of bytes successfully send or -1 if START failed | ||
69 | */ | ||
70 | int i2c_write(int device, unsigned char *buf, int count) | ||
71 | { | ||
72 | int i; | ||
73 | |||
74 | if (i2c_gen_start(device) == -1) | ||
75 | { | ||
76 | DEBUGF("i2c: gen_start failed (d=%d)", device); | ||
77 | return -1; | ||
78 | } | ||
79 | |||
80 | for (i=0; i<count; i++) | ||
81 | { | ||
82 | if (i2c_write_byte(device, buf[i]) == -1) | ||
83 | { | ||
84 | DEBUGF("i2c: write failed at (d=%d,i=%d)", device, i); | ||
85 | return i-1; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | i2c_gen_stop(device); | ||
90 | |||
91 | return count; | ||
92 | } | ||
93 | |||
94 | /* Write a byte to the interface, returns 0 on success, -1 otherwise. */ | ||
95 | int i2c_write_byte(int device, unsigned char data) | ||
96 | { | ||
97 | volatile unsigned char *regs = i2c_get_addr(device); | ||
98 | |||
99 | long count = 0; | ||
100 | |||
101 | regs[O_MBDR] = data; /* Write data byte */ | ||
102 | |||
103 | /* Wait for bus busy */ | ||
104 | while (!(regs[O_MBSR] & IBB) && count < MAX_LOOP) | ||
105 | { | ||
106 | yield(); | ||
107 | count++; | ||
108 | } | ||
109 | |||
110 | if (count >= MAX_LOOP) | ||
111 | return -1; | ||
112 | |||
113 | /* Wait for interrupt flag */ | ||
114 | while (!(regs[O_MBSR] & IFF) && count < MAX_LOOP) | ||
115 | { | ||
116 | yield(); | ||
117 | count++; | ||
118 | } | ||
119 | |||
120 | if (count >= MAX_LOOP) | ||
121 | return -1; | ||
122 | |||
123 | regs[O_MBSR] &= ~IFF; /* Clear interrupt flag */ | ||
124 | |||
125 | if (!(regs[O_MBSR] & ICF)) /* Check that transfer is complete */ | ||
126 | return -1; | ||
127 | |||
128 | if (regs[O_MBSR] & RXAK) /* Check that the byte has been ACKed */ | ||
129 | return -1; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | |||
135 | /* Returns 0 on success, -1 on failure */ | ||
136 | int i2c_gen_start(int device) | ||
137 | { | ||
138 | volatile unsigned char *regs = i2c_get_addr(device); | ||
139 | long count = 0; | ||
140 | |||
141 | /* Wait for bus to become free */ | ||
142 | while ((regs[O_MBSR] & IBB) && (count < MAX_LOOP)) | ||
143 | count++; | ||
144 | |||
145 | if (count >= MAX_LOOP) | ||
146 | return -1; | ||
147 | |||
148 | regs[O_MBCR] |= MSTA | MTX; /* Generate START */ | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | void i2c_gen_stop(int device) | ||
154 | { | ||
155 | volatile unsigned char *regs = i2c_get_addr(device); | ||
156 | regs[O_MBCR] &= ~MSTA; /* Clear MSTA to generate STOP */ | ||
157 | } | ||
158 | |||
159 | |||
160 | volatile unsigned char *i2c_get_addr(int device) | ||
161 | { | ||
162 | if (device == 1) | ||
163 | return I2C_DEVICE_1; | ||
164 | |||
165 | return I2C_DEVICE_2; | ||
166 | } | ||
diff --git a/firmware/export/i2c-h100.h b/firmware/export/i2c-h100.h new file mode 100644 index 0000000000..f8fd423b7e --- /dev/null +++ b/firmware/export/i2c-h100.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* | ||
21 | * Driver for MCF5249's I2C interface | ||
22 | * 2005-02-17 hubble@mochine.com | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifndef _I2C_H100_H | ||
27 | #define _I2C_H100_H | ||
28 | |||
29 | void i2c_init(void); | ||
30 | int i2c_write(int device, unsigned char *buf, int count); | ||
31 | void i2c_close(void); | ||
32 | |||
33 | |||
34 | #define MAX_LOOP 0x10000 /* TODO: select a better value */ | ||
35 | |||
36 | /* PLLCR control */ | ||
37 | #define QSPISEL (1 << 11) /* Selects QSPI or I2C interface */ | ||
38 | |||
39 | /* Offsets to I2C registers from base address */ | ||
40 | #define O_MADR 0x00 /* Slave Address */ | ||
41 | #define O_MFDR 0x04 /* Frequency divider */ | ||
42 | #define O_MBCR 0x08 /* Control register */ | ||
43 | #define O_MBSR 0x0c /* Status register */ | ||
44 | #define O_MBDR 0x10 /* Data register */ | ||
45 | |||
46 | /* MBSR - Status register */ | ||
47 | #define ICF (1 << 7) /* Transfer Complete */ | ||
48 | #define IAAS (1 << 6) /* Addressed As Alave */ | ||
49 | #define IBB (1 << 5) /* Bus Busy */ | ||
50 | #define IAL (1 << 4) /* Arbitration Lost */ | ||
51 | #define SRW (1 << 2) /* Slave R/W */ | ||
52 | #define IFF (1 << 1) /* I2C Interrupt */ | ||
53 | #define RXAK (1 << 0) /* No Ack bit */ | ||
54 | |||
55 | /* MBCR - Control register */ | ||
56 | #define IEN (1 << 7) /* I2C Enable */ | ||
57 | #define IIEN (1 << 6) /* Interrupt Enable */ | ||
58 | #define MSTA (1 << 5) /* Master/Slave select */ | ||
59 | #define MTX (1 << 4) /* Transmit/Receive */ | ||
60 | #define TXAK (1 << 3) /* Transfer ACK */ | ||
61 | #define RSTA (1 << 2) /* Restart.. */ | ||
62 | |||
63 | |||
64 | #endif | ||