summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2016-02-04 20:12:02 +0100
committerCástor Muñoz <cmvidal@gmail.com>2016-05-15 21:16:54 +0200
commit469d64539007584241ccd475e81038ea4166f17b (patch)
tree2de03ef2c45cfa845afd8015775d7457029404f7
parent44ce4eebd61302a22cbcc8fdaa0851adc103550f (diff)
downloadrockbox-469d64539007584241ccd475e81038ea4166f17b.zip
rockbox-469d64539007584241ccd475e81038ea4166f17b.tar.gz
rockbox-469d64539007584241ccd475e81038ea4166f17b.tar.bz2
rockbox-469d64539007584241ccd475e81038ea4166f17b.tar.xz
iPod Classic: prepare i2c and PMU for bootloader
When the bootloader starts only IRAM is available, the first task is to ask the PMU to verify if the iPod has previously been hibernated by OF. Due to memory limitations, the kernel cannot be used on this stage. This patch modifies I2C and PMU low level functions to not to depend on kernel (removes mutexes, and uses HW timer instead of current_tick), actual kernel functions are modified to be 'mutexed' wrappers of the new functions. Change-Id: I7cef9e95dedaf176dc0659315f3dc33166d5b116
-rw-r--r--firmware/export/i2c-s5l8702.h6
-rw-r--r--firmware/target/arm/s5l8702/i2c-s5l8702.c87
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c24
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/pmu-target.h9
4 files changed, 73 insertions, 53 deletions
diff --git a/firmware/export/i2c-s5l8702.h b/firmware/export/i2c-s5l8702.h
index 02dc40d..3883c8a 100644
--- a/firmware/export/i2c-s5l8702.h
+++ b/firmware/export/i2c-s5l8702.h
@@ -28,5 +28,9 @@ void i2c_init(void);
int i2c_write(int bus, unsigned char slave, int address, int len, const unsigned char *data);
int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data);
-#endif /* _I2C_S5l8702_H */
+#ifdef BOOTLOADER
+int i2c_wr(int bus, unsigned char slave, int address, int len, const unsigned char *data);
+int i2c_rd(int bus, unsigned char slave, int address, int len, unsigned char *data);
+#endif
+#endif /* _I2C_S5l8702_H */
diff --git a/firmware/target/arm/s5l8702/i2c-s5l8702.c b/firmware/target/arm/s5l8702/i2c-s5l8702.c
index 4d0e418..6197684 100644
--- a/firmware/target/arm/s5l8702/i2c-s5l8702.c
+++ b/firmware/target/arm/s5l8702/i2c-s5l8702.c
@@ -18,7 +18,7 @@
* KIND, either express or implied.
*
****************************************************************************/
-
+
#include "config.h"
#include "system.h"
#include "kernel.h"
@@ -71,68 +71,52 @@ void i2c_init()
mutex_init(&i2c_mtx[1]);
}
-int i2c_write(int bus, unsigned char slave, int address, int len, const unsigned char *data)
+int i2c_wr(int bus, unsigned char slave, int address, int len, const unsigned char *data)
{
- mutex_lock(&i2c_mtx[bus]);
i2c_on(bus);
- long timeout = current_tick + HZ / 50;
+ long timeout = USEC_TIMER + 20000;
/* START */
IICDS(bus) = slave & ~1;
IICSTAT(bus) = 0xF0;
IICCON(bus) = 0xB3;
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 1;
- }
-
if (address >= 0) {
/* write address */
IICDS(bus) = address;
IICCON(bus) = 0xB3;
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 2;
- }
}
-
+
/* write data */
while (len--) {
IICDS(bus) = *data++;
IICCON(bus) = 0xB3;
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 4;
- }
}
/* STOP */
IICSTAT(bus) = 0xD0;
IICCON(bus) = 0xB3;
while ((IICSTAT(bus) & (1 << 5)) != 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 5;
- }
-
+
i2c_off(bus);
- mutex_unlock(&i2c_mtx[bus]);
return 0;
}
-int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data)
+int i2c_rd(int bus, unsigned char slave, int address, int len, unsigned char *data)
{
- mutex_lock(&i2c_mtx[bus]);
i2c_on(bus);
- long timeout = current_tick + HZ / 50;
+ long timeout = USEC_TIMER + 20000;
if (address >= 0) {
/* START */
@@ -140,42 +124,30 @@ int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *
IICSTAT(bus) = 0xF0;
IICCON(bus) = 0xB3;
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 1;
- }
/* write address */
IICDS(bus) = address;
IICCON(bus) = 0xB3;
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 2;
- }
}
-
+
/* (repeated) START */
IICDS(bus) = slave | 1;
IICSTAT(bus) = 0xB0;
IICCON(bus) = 0xB3;
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 3;
- }
-
+
while (len--) {
IICCON(bus) = (len == 0) ? 0x33 : 0xB3; /* NAK or ACK */
while ((IICCON(bus) & 0x10) == 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 4;
- }
*data++ = IICDS(bus);
}
@@ -183,14 +155,27 @@ int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *
IICSTAT(bus) = 0x90;
IICCON(bus) = 0xB3;
while ((IICSTAT(bus) & (1 << 5)) != 0)
- if (TIME_AFTER(current_tick, timeout))
- {
- mutex_unlock(&i2c_mtx[bus]);
+ if (TIME_AFTER(USEC_TIMER, timeout))
return 5;
- }
-
+
i2c_off(bus);
- mutex_unlock(&i2c_mtx[bus]);
return 0;
}
+int i2c_write(int bus, unsigned char slave, int address, int len, const unsigned char *data)
+{
+ int ret;
+ mutex_lock(&i2c_mtx[bus]);
+ ret = i2c_wr(bus, slave, address, len, data);
+ mutex_unlock(&i2c_mtx[bus]);
+ return ret;
+}
+
+int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data)
+{
+ int ret;
+ mutex_lock(&i2c_mtx[bus]);
+ ret = i2c_rd(bus, slave, address, len, data);
+ mutex_unlock(&i2c_mtx[bus]);
+ return ret;
+}
diff --git a/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
index 946beb1..2a92360 100644
--- a/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
@@ -142,3 +142,27 @@ void pmu_write_rtc(unsigned char* buffer)
{
pmu_write_multiple(0x59, 7, buffer);
}
+
+#ifdef BOOTLOADER
+int pmu_rd_multiple(int address, int count, unsigned char* buffer)
+{
+ return i2c_rd(0, 0xe6, address, count, buffer);
+}
+
+int pmu_wr_multiple(int address, int count, unsigned char* buffer)
+{
+ return i2c_wr(0, 0xe6, address, count, buffer);
+}
+
+unsigned char pmu_rd(int address)
+{
+ unsigned char val;
+ pmu_rd_multiple(address, 1, &val);
+ return val;
+}
+
+int pmu_wr(int address, unsigned char val)
+{
+ return pmu_wr_multiple(address, 1, &val);
+}
+#endif /* BOOTLOADER */
diff --git a/firmware/target/arm/s5l8702/ipod6g/pmu-target.h b/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
index 94fd170..3a90ad8 100644
--- a/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
+++ b/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
@@ -25,7 +25,7 @@
#include <stdbool.h>
#include "config.h"
-#include <pcf5063x.h>
+#include "pcf5063x.h"
/* undocummented PMU registers */
#define PCF50635_REG_INT6 0x85
@@ -77,4 +77,11 @@ void pmu_read_rtc(unsigned char* buffer);
void pmu_write_rtc(unsigned char* buffer);
void pmu_hdd_power(bool on);
+#ifdef BOOTLOADER
+unsigned char pmu_rd(int address);
+int pmu_wr(int address, unsigned char val);
+int pmu_rd_multiple(int address, int count, unsigned char* buffer);
+int pmu_wr_multiple(int address, int count, unsigned char* buffer);
#endif
+
+#endif /* __PMU_TARGET_H__ */