summaryrefslogtreecommitdiff
path: root/firmware/drivers/generic_i2c.c
diff options
context:
space:
mode:
authorBertrik Sikken <bertrik@sikken.nl>2010-06-21 21:41:07 +0000
committerBertrik Sikken <bertrik@sikken.nl>2010-06-21 21:41:07 +0000
commit206227096477f328dfe16fee2d9ec13d631bd6e6 (patch)
tree0edd9336df4bb217186aa7799a522d3cacebc4f9 /firmware/drivers/generic_i2c.c
parent06b9064205d3e8aaf7f743fb1486733dd369ce1c (diff)
downloadrockbox-206227096477f328dfe16fee2d9ec13d631bd6e6.tar.gz
rockbox-206227096477f328dfe16fee2d9ec13d631bd6e6.zip
Apply FS #11423 - Use udelay in AMS driver for FM radio I2C
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27035 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/generic_i2c.c')
-rw-r--r--firmware/drivers/generic_i2c.c94
1 files changed, 44 insertions, 50 deletions
diff --git a/firmware/drivers/generic_i2c.c b/firmware/drivers/generic_i2c.c
index 87e9091a3d..effb5372b4 100644
--- a/firmware/drivers/generic_i2c.c
+++ b/firmware/drivers/generic_i2c.c
@@ -32,55 +32,51 @@ static const struct i2c_interface *i2c_if[MAX_I2C_INTERFACES];
32 32
33static void i2c_start(const struct i2c_interface *iface) 33static void i2c_start(const struct i2c_interface *iface)
34{ 34{
35 iface->sda_output(); 35 iface->sda_dir(true);
36 36
37 iface->sda_hi(); 37 iface->sda_out(1);
38 iface->scl_hi(); 38 iface->scl_out(1);
39 iface->delay_su_sta(); 39 iface->delay(iface->delay_su_sta);
40 iface->sda_lo(); 40 iface->sda_out(0);
41 iface->delay_hd_sta(); 41 iface->delay(iface->delay_hd_sta);
42 iface->scl_lo(); 42 iface->scl_out(0);
43 iface->delay_hd_dat(); 43 iface->delay(iface->delay_hd_dat);
44} 44}
45 45
46static void i2c_stop(const struct i2c_interface *iface) 46static void i2c_stop(const struct i2c_interface *iface)
47{ 47{
48 iface->sda_output(); 48 iface->sda_dir(true);
49 49
50 iface->sda_lo(); 50 iface->sda_out(0);
51 iface->delay_su_dat(); 51 iface->delay(iface->delay_su_dat);
52 iface->scl_hi(); 52 iface->scl_out(1);
53 iface->delay_su_sto(); 53 iface->delay(iface->delay_su_sto);
54 iface->sda_hi(); 54 iface->sda_out(1);
55} 55}
56 56
57static void i2c_ack(const struct i2c_interface *iface, bool ack) 57static void i2c_ack(const struct i2c_interface *iface, bool ack)
58{ 58{
59 iface->sda_output(); 59 iface->sda_dir(true);
60 if ( ack ) 60 iface->sda_out(!ack);
61 iface->sda_lo(); 61 iface->delay(iface->delay_su_dat);
62 else 62 iface->scl_out(1);
63 iface->sda_hi(); 63 iface->delay(iface->delay_thigh);
64 64 iface->scl_out(0);
65 iface->delay_su_dat(); 65 iface->delay(iface->delay_hd_dat);
66 iface->scl_hi();
67 iface->delay_thigh();
68 iface->scl_lo();
69 iface->delay_hd_dat();
70} 66}
71 67
72static int i2c_getack(const struct i2c_interface *iface) 68static int i2c_getack(const struct i2c_interface *iface)
73{ 69{
74 int ret = 1; 70 int ret = 1;
75 71
76 iface->sda_input(); 72 iface->sda_dir(false);
77 iface->delay_su_dat(); 73 iface->delay(iface->delay_su_dat);
78 iface->scl_hi(); 74 iface->scl_out(1);
79 iface->delay_thigh(); 75 iface->delay(iface->delay_thigh);
80 if (iface->sda()) 76 if (iface->sda_in())
81 ret = 0; /* ack failed */ 77 ret = 0; /* ack failed */
82 iface->scl_lo(); 78 iface->scl_out(0);
83 iface->delay_hd_dat(); 79 iface->delay(iface->delay_hd_dat);
84 return ret; 80 return ret;
85} 81}
86 82
@@ -89,17 +85,17 @@ static unsigned char i2c_inb(const struct i2c_interface *iface, bool ack)
89 int i; 85 int i;
90 unsigned char byte = 0; 86 unsigned char byte = 0;
91 87
92 iface->sda_input(); 88 iface->sda_dir(false);
93 89
94 /* clock in each bit, MSB first */ 90 /* clock in each bit, MSB first */
95 for ( i=0x80; i; i>>=1 ) { 91 for ( i=0x80; i; i>>=1 ) {
96 iface->delay_su_dat(); 92 iface->delay(iface->delay_su_dat);
97 iface->scl_hi(); 93 iface->scl_out(1);
98 iface->delay_thigh(); 94 iface->delay(iface->delay_thigh);
99 if (iface->sda()) 95 if (iface->sda_in())
100 byte |= i; 96 byte |= i;
101 iface->scl_lo(); 97 iface->scl_out(0);
102 iface->delay_hd_dat(); 98 iface->delay(iface->delay_hd_dat);
103 } 99 }
104 100
105 i2c_ack(iface, ack); 101 i2c_ack(iface, ack);
@@ -111,18 +107,16 @@ static int i2c_outb(const struct i2c_interface *iface, unsigned char byte)
111{ 107{
112 int i; 108 int i;
113 109
114 iface->sda_output(); 110 iface->sda_dir(true);
115 111
116 /* clock out each bit, MSB first */ 112 /* clock out each bit, MSB first */
117 for (i=0x80; i; i>>=1) { 113 for (i=0x80; i; i>>=1) {
118 if (i & byte) 114 iface->sda_out(i & byte);
119 iface->sda_hi(); 115 iface->delay(iface->delay_su_dat);
120 else 116 iface->scl_out(1);
121 iface->sda_lo(); 117 iface->delay(iface->delay_thigh);
122 iface->delay_su_dat(); 118 iface->scl_out(0);
123 iface->scl_hi(); 119 iface->delay(iface->delay_hd_dat);
124 iface->delay_thigh();
125 iface->scl_lo();
126 } 120 }
127 121
128 return i2c_getack(iface); 122 return i2c_getack(iface);
@@ -215,7 +209,7 @@ int i2c_add_node(const struct i2c_interface *iface)
215 bus_index = i2c_num_ifs++; 209 bus_index = i2c_num_ifs++;
216 i2c_if[bus_index] = iface; 210 i2c_if[bus_index] = iface;
217 211
218 iface->scl_output(); 212 iface->scl_dir(true);
219 213
220 return bus_index; 214 return bus_index;
221} 215}