summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Arigo <markarigo@gmail.com>2009-02-13 03:35:23 +0000
committerMark Arigo <markarigo@gmail.com>2009-02-13 03:35:23 +0000
commit311595c60cb8a720e93205218042101b65830b29 (patch)
tree829f0e5f93cdc5faca682bbe24c476aaef458214
parent375d329308c8d0aec0ebca74af276c68df23a0a8 (diff)
downloadrockbox-311595c60cb8a720e93205218042101b65830b29.tar.gz
rockbox-311595c60cb8a720e93205218042101b65830b29.zip
FS#9865 - For Portalplayer i2c, read up to 4 bytes at a time instead of one at a time (need for the upcoming Philips HDD1630 radio commit).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19995 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/i2c-pp.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/firmware/target/arm/i2c-pp.c b/firmware/target/arm/i2c-pp.c
index 3db25c027c..175e2effd1 100644
--- a/firmware/target/arm/i2c-pp.c
+++ b/firmware/target/arm/i2c-pp.c
@@ -54,35 +54,46 @@ static int pp_i2c_wait_not_busy(void)
54 return -1; 54 return -1;
55} 55}
56 56
57static int pp_i2c_read_byte(unsigned int addr, unsigned int *data) 57static int pp_i2c_read_bytes(unsigned int addr, int len, unsigned char *data)
58{ 58{
59 if (pp_i2c_wait_not_busy() < 0) 59 int i;
60
61 if (len < 1 || len > 4)
60 { 62 {
61 return -1; 63 return -1;
62 } 64 }
63 65
66 if (pp_i2c_wait_not_busy() < 0)
67 {
68 return -2;
69 }
70
64 { 71 {
65 unsigned int byte;
66 int old_irq_level = disable_irq_save(); 72 int old_irq_level = disable_irq_save();
67 73
68 /* clear top 15 bits, left shift 1, or in 0x1 for a read */ 74 /* clear top 15 bits, left shift 1, or in 0x1 for a read */
69 I2C_ADDR = ((addr << 17) >> 16) | 0x1 ; 75 I2C_ADDR = ((addr << 17) >> 16) | 0x1;
70 76
71 I2C_CTRL |= 0x20; 77 I2C_CTRL |= 0x20;
72 78
79 I2C_CTRL = (I2C_CTRL & ~0x6) | ((len-1) << 1);
80
73 I2C_CTRL |= I2C_SEND; 81 I2C_CTRL |= I2C_SEND;
74 82
75 restore_irq(old_irq_level); 83 restore_irq(old_irq_level);
84
76 if (pp_i2c_wait_not_busy() < 0) 85 if (pp_i2c_wait_not_busy() < 0)
77 { 86 {
78 return -1; 87 return -2;
79 } 88 }
80 old_irq_level = disable_irq_save();
81 89
82 byte = I2C_DATA(0); 90 old_irq_level = disable_irq_save();
83 91
84 if (data) 92 if (data)
85 *data = byte; 93 {
94 for ( i = 0; i < len; i++ )
95 *data++ = I2C_DATA(i);
96 }
86 97
87 restore_irq(old_irq_level); 98 restore_irq(old_irq_level);
88 } 99 }
@@ -90,9 +101,9 @@ static int pp_i2c_read_byte(unsigned int addr, unsigned int *data)
90 return 0; 101 return 0;
91} 102}
92 103
93static int pp_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data) 104static int pp_i2c_send_bytes(unsigned int addr, int len, unsigned char *data)
94{ 105{
95 unsigned int i; 106 int i;
96 107
97 if (len < 1 || len > 4) 108 if (len < 1 || len > 4)
98 { 109 {
@@ -117,14 +128,14 @@ static int pp_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char
117 I2C_DATA(i) = *data++; 128 I2C_DATA(i) = *data++;
118 } 129 }
119 130
120 I2C_CTRL = (I2C_CTRL & ~0x26) | ((len-1) << 1); 131 I2C_CTRL = (I2C_CTRL & ~0x6) | ((len-1) << 1);
121 132
122 I2C_CTRL |= I2C_SEND; 133 I2C_CTRL |= I2C_SEND;
123 134
124 restore_irq(old_irq_level); 135 restore_irq(old_irq_level);
125 } 136 }
126 137
127 return 0x0; 138 return 0;
128} 139}
129 140
130static int pp_i2c_send_byte(unsigned int addr, int data0) 141static int pp_i2c_send_byte(unsigned int addr, int data0)
@@ -147,29 +158,42 @@ void i2c_unlock(void)
147 mutex_unlock(&i2c_mtx); 158 mutex_unlock(&i2c_mtx);
148} 159}
149 160
150int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data) { 161int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data)
151 unsigned int temp; 162{
152 int i; 163 int i, n;
164
153 mutex_lock(&i2c_mtx); 165 mutex_lock(&i2c_mtx);
154 pp_i2c_send_byte(dev_addr, addr); 166
155 for (i = 0; i < len; i++) { 167 if (addr >= 0)
156 pp_i2c_read_byte(dev_addr, &temp); 168 pp_i2c_send_byte(dev_addr, addr);
157 data[i] = temp; 169
170 i = 0;
171 while (len > 0)
172 {
173 n = (len < 4) ? len : 4;
174
175 if (pp_i2c_read_bytes(dev_addr, n, data + i) < 0)
176 break;
177
178 len -= n;
179 i += n;
158 } 180 }
181
159 mutex_unlock(&i2c_mtx); 182 mutex_unlock(&i2c_mtx);
183
160 return i; 184 return i;
161} 185}
162 186
163int i2c_readbyte(unsigned int dev_addr, int addr) 187int i2c_readbyte(unsigned int dev_addr, int addr)
164{ 188{
165 int data; 189 unsigned char data;
166 190
167 mutex_lock(&i2c_mtx); 191 mutex_lock(&i2c_mtx);
168 pp_i2c_send_byte(dev_addr, addr); 192 pp_i2c_send_byte(dev_addr, addr);
169 pp_i2c_read_byte(dev_addr, &data); 193 pp_i2c_read_bytes(dev_addr, 1, &data);
170 mutex_unlock(&i2c_mtx); 194 mutex_unlock(&i2c_mtx);
171 195
172 return data; 196 return (int)data;
173} 197}
174 198
175int pp_i2c_send(unsigned int addr, int data0, int data1) 199int pp_i2c_send(unsigned int addr, int data0, int data1)