diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2009-07-09 22:08:54 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2009-07-09 22:08:54 +0000 |
commit | 8866342b1f9095d1d38a8d7f9ac021472803454f (patch) | |
tree | 67bc3dd5a78656677b2a1c3c3284d544bd9820c9 /firmware/target/arm/s5l8700/i2c-s5l8700.c | |
parent | 9ecde3d75c2986b566a46d55b5271f7298b4658d (diff) | |
download | rockbox-8866342b1f9095d1d38a8d7f9ac021472803454f.tar.gz rockbox-8866342b1f9095d1d38a8d7f9ac021472803454f.zip |
S5L8700: use wakeup_wait/wakeup_signal instead of polling for i2c communication
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21735 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s5l8700/i2c-s5l8700.c')
-rw-r--r-- | firmware/target/arm/s5l8700/i2c-s5l8700.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/firmware/target/arm/s5l8700/i2c-s5l8700.c b/firmware/target/arm/s5l8700/i2c-s5l8700.c index 564bfdd4bd..b2b2f37e2b 100644 --- a/firmware/target/arm/s5l8700/i2c-s5l8700.c +++ b/firmware/target/arm/s5l8700/i2c-s5l8700.c | |||
@@ -39,10 +39,20 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | static struct mutex i2c_mtx; | 41 | static struct mutex i2c_mtx; |
42 | static struct wakeup i2c_wakeup; | ||
43 | |||
44 | void INT_IIC(void) | ||
45 | { | ||
46 | /* disable interrupt (but don't clear it yet) */ | ||
47 | IICCON &= ~((1 << 4) | (1 << 5)); | ||
48 | |||
49 | wakeup_signal(&i2c_wakeup); | ||
50 | } | ||
42 | 51 | ||
43 | void i2c_init(void) | 52 | void i2c_init(void) |
44 | { | 53 | { |
45 | mutex_init(&i2c_mtx); | 54 | mutex_init(&i2c_mtx); |
55 | wakeup_init(&i2c_wakeup); | ||
46 | 56 | ||
47 | /* enable I2C pins */ | 57 | /* enable I2C pins */ |
48 | PCON10 = (2 << 2) | | 58 | PCON10 = (2 << 2) | |
@@ -61,6 +71,9 @@ void i2c_init(void) | |||
61 | 71 | ||
62 | /* serial output on */ | 72 | /* serial output on */ |
63 | IICSTAT = (1 << 4); | 73 | IICSTAT = (1 << 4); |
74 | |||
75 | /* enable interrupt */ | ||
76 | INTMSK |= (1 << 27); | ||
64 | } | 77 | } |
65 | 78 | ||
66 | int i2c_write(unsigned char slave, int address, int len, const unsigned char *data) | 79 | int i2c_write(unsigned char slave, int address, int len, const unsigned char *data) |
@@ -71,20 +84,20 @@ int i2c_write(unsigned char slave, int address, int len, const unsigned char *da | |||
71 | IICDS = slave & ~1; | 84 | IICDS = slave & ~1; |
72 | IICSTAT = 0xF0; | 85 | IICSTAT = 0xF0; |
73 | IICCON = 0xF3; | 86 | IICCON = 0xF3; |
74 | while ((IICCON & (1 << 4)) == 0); | 87 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
75 | 88 | ||
76 | if (address >= 0) { | 89 | if (address >= 0) { |
77 | /* write address */ | 90 | /* write address */ |
78 | IICDS = address; | 91 | IICDS = address; |
79 | IICCON = 0xF3; | 92 | IICCON = 0xF3; |
80 | while ((IICCON & (1 << 4)) == 0); | 93 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
81 | } | 94 | } |
82 | 95 | ||
83 | /* write data */ | 96 | /* write data */ |
84 | while (len--) { | 97 | while (len--) { |
85 | IICDS = *data++; | 98 | IICDS = *data++; |
86 | IICCON = 0xF3; | 99 | IICCON = 0xF3; |
87 | while ((IICCON & (1 << 4)) == 0); | 100 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
88 | } | 101 | } |
89 | 102 | ||
90 | /* STOP */ | 103 | /* STOP */ |
@@ -105,23 +118,23 @@ int i2c_read(unsigned char slave, int address, int len, unsigned char *data) | |||
105 | IICDS = slave & ~1; | 118 | IICDS = slave & ~1; |
106 | IICSTAT = 0xF0; | 119 | IICSTAT = 0xF0; |
107 | IICCON = 0xF3; | 120 | IICCON = 0xF3; |
108 | while ((IICCON & (1 << 4)) == 0); | 121 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
109 | 122 | ||
110 | /* write address */ | 123 | /* write address */ |
111 | IICDS = address; | 124 | IICDS = address; |
112 | IICCON = 0xF3; | 125 | IICCON = 0xF3; |
113 | while ((IICCON & (1 << 4)) == 0); | 126 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
114 | } | 127 | } |
115 | 128 | ||
116 | /* (repeated) START */ | 129 | /* (repeated) START */ |
117 | IICDS = slave | 1; | 130 | IICDS = slave | 1; |
118 | IICSTAT = 0xB0; | 131 | IICSTAT = 0xB0; |
119 | IICCON = 0xF3; | 132 | IICCON = 0xF3; |
120 | while ((IICCON & (1 << 4)) == 0); | 133 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
121 | 134 | ||
122 | while (len--) { | 135 | while (len--) { |
123 | IICCON = (len == 0) ? 0x73 : 0xF3; /* NACK or ACK */ | 136 | IICCON = (len == 0) ? 0x73 : 0xF3; /* NACK or ACK */ |
124 | while ((IICCON & (1 << 4)) == 0); | 137 | wakeup_wait(&i2c_wakeup, TIMEOUT_BLOCK); |
125 | *data++ = IICDS; | 138 | *data++ = IICDS; |
126 | } | 139 | } |
127 | 140 | ||