summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/pcf50606.c38
1 files changed, 4 insertions, 34 deletions
diff --git a/firmware/drivers/pcf50606.c b/firmware/drivers/pcf50606.c
index a2045291ec..4fe04e6171 100644
--- a/firmware/drivers/pcf50606.c
+++ b/firmware/drivers/pcf50606.c
@@ -38,7 +38,7 @@
38#define SCL_INPUT and_l(~0x00001000, &GPIO_ENABLE) 38#define SCL_INPUT and_l(~0x00001000, &GPIO_ENABLE)
39#define SCL_OUTPUT or_l( 0x00001000, &GPIO_ENABLE) 39#define SCL_OUTPUT or_l( 0x00001000, &GPIO_ENABLE)
40#define SCL_LO and_l(~0x00001000, &GPIO_OUT) 40#define SCL_LO and_l(~0x00001000, &GPIO_OUT)
41#define SCL_HI or_l( 0x00001000, &GPIO_OUT) 41#define SCL_HI SCL_INPUT;while(!SCL){};or_l(0x1000, &GPIO_OUT);SCL_OUTPUT
42#define SCL ( 0x00001000 & GPIO_READ) 42#define SCL ( 0x00001000 & GPIO_READ)
43 43
44/* delay loop to achieve 400kHz at 120MHz CPU frequency */ 44/* delay loop to achieve 400kHz at 120MHz CPU frequency */
@@ -68,28 +68,13 @@ static void pcf50606_i2c_stop(void)
68 68
69static void pcf50606_i2c_ack(bool ack) 69static void pcf50606_i2c_ack(bool ack)
70{ 70{
71 /* Here's the deal. The slave is slow, and sometimes needs to wait
72 before it can receive the acknowledge. Therefore it forces the clock
73 low until it is ready. We need to poll the clock line until it goes
74 high before we release the ack.
75
76 In their infinite wisdom, iriver didn't pull up the SCL line, so
77 we have to drive the SCL high repeatedly to simulate a pullup. */
78
79 SCL_LO; /* Set the clock low */ 71 SCL_LO; /* Set the clock low */
80 if(ack) 72 if(ack)
81 SDA_LO; 73 SDA_LO;
82 else 74 else
83 SDA_HI; 75 SDA_HI;
84 76
85 SCL_INPUT; /* Set the clock to input */ 77 SCL_HI;
86 while(!SCL) /* and wait for the slave to release it */
87 {
88 SCL_OUTPUT; /* Set the clock to output */
89 SCL_HI;
90 SCL_INPUT; /* Set the clock to input */
91 DELAY;
92 }
93 78
94 DELAY; 79 DELAY;
95 SCL_OUTPUT; 80 SCL_OUTPUT;
@@ -100,23 +85,8 @@ static int pcf50606_i2c_getack(void)
100{ 85{
101 int ret = 1; 86 int ret = 1;
102 87
103 /* Here's the deal. The slave is slow, and sometimes needs to wait
104 before it can send the acknowledge. Therefore it forces the clock
105 low until it is ready. We need to poll the clock line until it goes
106 high before we read the ack.
107
108 In their infinite wisdom, iriver didn't pull up the SCL line, so
109 we have to drive the SCL high repeatedly to simulate a pullup. */
110
111 SDA_INPUT; /* And set to input */ 88 SDA_INPUT; /* And set to input */
112 SCL_INPUT; /* Set the clock to input */ 89 SCL_HI;
113 while(!SCL) /* and wait for the slave to release it */
114 {
115 SCL_OUTPUT; /* Set the clock to output */
116 SCL_HI;
117 SCL_INPUT; /* Set the clock to input */
118 DELAY;
119 }
120 90
121 if (SDA) 91 if (SDA)
122 /* ack failed */ 92 /* ack failed */