diff options
Diffstat (limited to 'firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c')
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c new file mode 100644 index 0000000000..670d6cd04c --- /dev/null +++ b/firmware/target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 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 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include <stdbool.h> | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include "logf.h" | ||
25 | #include "debug.h" | ||
26 | #include "string.h" | ||
27 | #include "generic_i2c.h" | ||
28 | |||
29 | static void i2c_sda_output(void) | ||
30 | { | ||
31 | GPECON |= (1 << 30); | ||
32 | } | ||
33 | |||
34 | static void i2c_sda_input(void) | ||
35 | { | ||
36 | GPECON &= ~(3 << 30); | ||
37 | } | ||
38 | |||
39 | static void i2c_sda_lo(void) | ||
40 | { | ||
41 | GPEDAT &= ~(1 << 15); | ||
42 | } | ||
43 | |||
44 | static void i2c_sda_hi(void) | ||
45 | { | ||
46 | GPEDAT |= (1 << 15); | ||
47 | } | ||
48 | |||
49 | static int i2c_sda(void) | ||
50 | { | ||
51 | return GPEDAT & (1 << 15); | ||
52 | } | ||
53 | |||
54 | static void i2c_scl_output(void) | ||
55 | { | ||
56 | GPECON |= (1 << 28); | ||
57 | } | ||
58 | |||
59 | static void i2c_scl_input(void) | ||
60 | { | ||
61 | GPECON &= ~(3 << 28); | ||
62 | } | ||
63 | |||
64 | static void i2c_scl_lo(void) | ||
65 | { | ||
66 | GPEDAT &= ~(1 << 14); | ||
67 | } | ||
68 | |||
69 | static int i2c_scl(void) | ||
70 | { | ||
71 | return GPEDAT & (1 << 14); | ||
72 | } | ||
73 | |||
74 | static void i2c_scl_hi(void) | ||
75 | { | ||
76 | i2c_scl_input(); | ||
77 | while(!i2c_scl()); | ||
78 | GPEDAT |= (1 << 14); | ||
79 | i2c_scl_output(); | ||
80 | } | ||
81 | |||
82 | |||
83 | |||
84 | static void i2c_delay(void) | ||
85 | { | ||
86 | unsigned _x; | ||
87 | |||
88 | /* The i2c can clock at 500KHz: 2uS period -> 1uS half period */ | ||
89 | /* about 30 cycles overhead + X * 7 */ | ||
90 | /* 300MHz: 1000nS @3.36nS/cyc = 297cyc: X = 38*/ | ||
91 | /* 100MHz: 1000nS @10nS/cyc = 100cyc : X = 10 */ | ||
92 | for (_x = 38; _x; _x--) | ||
93 | { | ||
94 | /* burn CPU cycles */ | ||
95 | /* gcc makes it an inc loop - check with objdump for asm timing */ | ||
96 | } | ||
97 | } | ||
98 | |||
99 | |||
100 | |||
101 | struct i2c_interface s3c2440_i2c = { | ||
102 | 0x34, /* Address */ | ||
103 | |||
104 | /* Bit-banged interface definitions */ | ||
105 | i2c_scl_hi, /* Drive SCL high, might sleep on clk stretch */ | ||
106 | i2c_scl_lo, /* Drive SCL low */ | ||
107 | i2c_sda_hi, /* Drive SDA high */ | ||
108 | i2c_sda_lo, /* Drive SDA low */ | ||
109 | i2c_sda_input, /* Set SDA as input */ | ||
110 | i2c_sda_output, /* Set SDA as output */ | ||
111 | i2c_scl_input, /* Set SCL as input */ | ||
112 | i2c_scl_output, /* Set SCL as output */ | ||
113 | i2c_scl, /* Read SCL, returns 0 or nonzero */ | ||
114 | i2c_sda, /* Read SDA, returns 0 or nonzero */ | ||
115 | |||
116 | i2c_delay, /* START SDA hold time (tHD:SDA) */ | ||
117 | i2c_delay, /* SDA hold time (tHD:DAT) */ | ||
118 | i2c_delay, /* SDA setup time (tSU:DAT) */ | ||
119 | i2c_delay, /* STOP setup time (tSU:STO) */ | ||
120 | i2c_delay, /* Rep. START setup time (tSU:STA) */ | ||
121 | i2c_delay, /* SCL high period (tHIGH) */ | ||
122 | }; | ||
123 | |||
124 | void i2c_init(void) | ||
125 | { | ||
126 | /* Set GPE15 (SDA) and GPE14 (SCL) to 1 */ | ||
127 | GPECON = (GPECON & ~(0xF<<28)) | 5<<28; | ||
128 | i2c_add_node(&s3c2440_i2c); | ||
129 | } | ||
130 | |||
131 | void i2c_send(int bus_address, int reg_address, const unsigned char buf) | ||
132 | { | ||
133 | i2c_write_data(bus_address, reg_address, &buf, 1); | ||
134 | } | ||