diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/adc.c | 3 | ||||
-rw-r--r-- | firmware/drivers/i2c-pp5020.c | 80 | ||||
-rw-r--r-- | firmware/drivers/rtc.c | 12 | ||||
-rw-r--r-- | firmware/drivers/wm8758.c | 21 |
4 files changed, 53 insertions, 63 deletions
diff --git a/firmware/drivers/adc.c b/firmware/drivers/adc.c index f4bdb7a54f..f1a6d7e667 100644 --- a/firmware/drivers/adc.c +++ b/firmware/drivers/adc.c | |||
@@ -294,10 +294,7 @@ static struct adc_struct adcdata[NUM_ADC_CHANNELS]; | |||
294 | 294 | ||
295 | static unsigned short adc_scan(struct adc_struct *adc) | 295 | static unsigned short adc_scan(struct adc_struct *adc) |
296 | { | 296 | { |
297 | /* Disable interrupts during the I2C transaction */ | ||
298 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
299 | unsigned short data = pcf50605_a2d_read(adc->channelnum); | 297 | unsigned short data = pcf50605_a2d_read(adc->channelnum); |
300 | set_irq_level(old_irq_level); | ||
301 | /* This gives us a 13 bit value corresponding to 0-5.4 volts | 298 | /* This gives us a 13 bit value corresponding to 0-5.4 volts |
302 | * The range of the value is 13FB-17FA */ | 299 | * The range of the value is 13FB-17FA */ |
303 | data = (data<<2)+0x13FB; | 300 | data = (data<<2)+0x13FB; |
diff --git a/firmware/drivers/i2c-pp5020.c b/firmware/drivers/i2c-pp5020.c index 522ddbed77..77671e79d8 100644 --- a/firmware/drivers/i2c-pp5020.c +++ b/firmware/drivers/i2c-pp5020.c | |||
@@ -57,42 +57,48 @@ static int ipod_i2c_wait_not_busy(void) | |||
57 | if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) { | 57 | if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) { |
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | yield(); | ||
60 | } | 61 | } |
61 | 62 | ||
62 | return -1; | 63 | return -1; |
63 | } | 64 | } |
64 | 65 | ||
65 | 66 | ||
66 | /* Public functions */ | 67 | static int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) |
67 | |||
68 | int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) | ||
69 | { | 68 | { |
70 | if (ipod_i2c_wait_not_busy() < 0) | 69 | if (ipod_i2c_wait_not_busy() < 0) |
71 | { | 70 | { |
72 | return -1; | 71 | return -1; |
73 | } | 72 | } |
74 | 73 | ||
75 | /* clear top 15 bits, left shift 1, or in 0x1 for a read */ | 74 | { |
76 | outb(((addr << 17) >> 16) | 0x1, IPOD_I2C_ADDR); | 75 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); |
77 | 76 | ||
78 | outb(inb(IPOD_I2C_CTRL) | 0x20, IPOD_I2C_CTRL); | 77 | /* clear top 15 bits, left shift 1, or in 0x1 for a read */ |
78 | outb(((addr << 17) >> 16) | 0x1, IPOD_I2C_ADDR); | ||
79 | 79 | ||
80 | outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); | 80 | outb(inb(IPOD_I2C_CTRL) | 0x20, IPOD_I2C_CTRL); |
81 | 81 | ||
82 | if (ipod_i2c_wait_not_busy() < 0) | 82 | outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); |
83 | { | ||
84 | return -1; | ||
85 | } | ||
86 | 83 | ||
87 | if (data) | 84 | set_irq_level(old_irq_level); |
88 | { | 85 | |
89 | *data = inb(IPOD_I2C_DATA0); | 86 | if (data) |
87 | { | ||
88 | if (ipod_i2c_wait_not_busy() < 0) | ||
89 | { | ||
90 | return -1; | ||
91 | } | ||
92 | old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
93 | *data = inb(IPOD_I2C_DATA0); | ||
94 | set_irq_level(old_irq_level); | ||
95 | } | ||
90 | } | 96 | } |
91 | 97 | ||
92 | return 0; | 98 | return 0; |
93 | } | 99 | } |
94 | 100 | ||
95 | int ipod_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data) | 101 | static int ipod_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data) |
96 | { | 102 | { |
97 | int data_addr; | 103 | int data_addr; |
98 | unsigned int i; | 104 | unsigned int i; |
@@ -107,26 +113,32 @@ int ipod_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data | |||
107 | return -2; | 113 | return -2; |
108 | } | 114 | } |
109 | 115 | ||
110 | /* clear top 15 bits, left shift 1 */ | 116 | { |
111 | outb((addr << 17) >> 16, IPOD_I2C_ADDR); | 117 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); |
112 | 118 | ||
113 | outb(inb(IPOD_I2C_CTRL) & ~0x20, IPOD_I2C_CTRL); | 119 | /* clear top 15 bits, left shift 1 */ |
120 | outb((addr << 17) >> 16, IPOD_I2C_ADDR); | ||
114 | 121 | ||
115 | data_addr = IPOD_I2C_DATA0; | 122 | outb(inb(IPOD_I2C_CTRL) & ~0x20, IPOD_I2C_CTRL); |
116 | for ( i = 0; i < len; i++ ) | 123 | |
117 | { | 124 | data_addr = IPOD_I2C_DATA0; |
118 | outb(*data++, data_addr); | 125 | for ( i = 0; i < len; i++ ) |
119 | data_addr += 4; | 126 | { |
120 | } | 127 | outb(*data++, data_addr); |
128 | data_addr += 4; | ||
129 | } | ||
121 | 130 | ||
122 | outb((inb(IPOD_I2C_CTRL) & ~0x26) | ((len-1) << 1), IPOD_I2C_CTRL); | 131 | outb((inb(IPOD_I2C_CTRL) & ~0x26) | ((len-1) << 1), IPOD_I2C_CTRL); |
123 | 132 | ||
124 | outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); | 133 | outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); |
134 | |||
135 | set_irq_level(old_irq_level); | ||
136 | } | ||
125 | 137 | ||
126 | return 0x0; | 138 | return 0x0; |
127 | } | 139 | } |
128 | 140 | ||
129 | int ipod_i2c_send_byte(unsigned int addr, int data0) | 141 | static int ipod_i2c_send_byte(unsigned int addr, int data0) |
130 | { | 142 | { |
131 | unsigned char data[1]; | 143 | unsigned char data[1]; |
132 | 144 | ||
@@ -135,25 +147,35 @@ int ipod_i2c_send_byte(unsigned int addr, int data0) | |||
135 | return ipod_i2c_send_bytes(addr, 1, data); | 147 | return ipod_i2c_send_bytes(addr, 1, data); |
136 | } | 148 | } |
137 | 149 | ||
150 | /* Public functions */ | ||
151 | static struct mutex i2c_mutex; | ||
138 | 152 | ||
139 | int i2c_readbyte(unsigned int dev_addr, int addr) | 153 | int i2c_readbyte(unsigned int dev_addr, int addr) |
140 | { | 154 | { |
155 | int retval; | ||
141 | int data; | 156 | int data; |
142 | 157 | ||
158 | mutex_lock(&i2c_mutex); | ||
143 | ipod_i2c_send_byte(dev_addr, addr); | 159 | ipod_i2c_send_byte(dev_addr, addr); |
144 | ipod_i2c_read_byte(dev_addr, &data); | 160 | ipod_i2c_read_byte(dev_addr, &data); |
161 | mutex_unlock(&i2c_mutex); | ||
145 | 162 | ||
146 | return data; | 163 | return data; |
147 | } | 164 | } |
148 | 165 | ||
149 | int ipod_i2c_send(unsigned int addr, int data0, int data1) | 166 | int ipod_i2c_send(unsigned int addr, int data0, int data1) |
150 | { | 167 | { |
168 | int retval; | ||
151 | unsigned char data[2]; | 169 | unsigned char data[2]; |
152 | 170 | ||
153 | data[0] = data0; | 171 | data[0] = data0; |
154 | data[1] = data1; | 172 | data[1] = data1; |
155 | 173 | ||
156 | return ipod_i2c_send_bytes(addr, 2, data); | 174 | mutex_lock(&i2c_mutex); |
175 | retval = ipod_i2c_send_bytes(addr, 2, data); | ||
176 | mutex_unlock(&i2c_mutex); | ||
177 | |||
178 | return retval; | ||
157 | } | 179 | } |
158 | 180 | ||
159 | void i2c_init(void) | 181 | void i2c_init(void) |
@@ -175,5 +197,7 @@ void i2c_init(void) | |||
175 | outl(0x0, 0x600060a4); | 197 | outl(0x0, 0x600060a4); |
176 | outl(0x80 | (0 << 8), 0x600060a4); | 198 | outl(0x80 | (0 << 8), 0x600060a4); |
177 | 199 | ||
200 | mutex_init(&i2c_mutex); | ||
201 | |||
178 | i2c_readbyte(0x8, 0); | 202 | i2c_readbyte(0x8, 0); |
179 | } | 203 | } |
diff --git a/firmware/drivers/rtc.c b/firmware/drivers/rtc.c index ecfd2ac6ba..4b4b45826f 100644 --- a/firmware/drivers/rtc.c +++ b/firmware/drivers/rtc.c | |||
@@ -36,28 +36,18 @@ void rtc_init(void) | |||
36 | } | 36 | } |
37 | int rtc_read_datetime(unsigned char* buf) | 37 | int rtc_read_datetime(unsigned char* buf) |
38 | { | 38 | { |
39 | int rc; | 39 | return pcf50605_read_multiple(0x0a, buf, 7); |
40 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
41 | |||
42 | rc = pcf50605_read_multiple(0x0a, buf, 7); | ||
43 | |||
44 | set_irq_level(old_irq_level); | ||
45 | |||
46 | return rc; | ||
47 | } | 40 | } |
48 | 41 | ||
49 | 42 | ||
50 | int rtc_write_datetime(unsigned char* buf) | 43 | int rtc_write_datetime(unsigned char* buf) |
51 | { | 44 | { |
52 | int i; | 45 | int i; |
53 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
54 | 46 | ||
55 | for (i=0;i<7;i++) { | 47 | for (i=0;i<7;i++) { |
56 | pcf50605_write(0x0a+i, buf[i]); | 48 | pcf50605_write(0x0a+i, buf[i]); |
57 | } | 49 | } |
58 | 50 | ||
59 | set_irq_level(old_irq_level); | ||
60 | |||
61 | return 1; | 51 | return 1; |
62 | } | 52 | } |
63 | #elif CONFIG_RTC == RTC_PCF50606 | 53 | #elif CONFIG_RTC == RTC_PCF50606 |
diff --git a/firmware/drivers/wm8758.c b/firmware/drivers/wm8758.c index 7c9ac77395..3867748417 100644 --- a/firmware/drivers/wm8758.c +++ b/firmware/drivers/wm8758.c | |||
@@ -86,8 +86,6 @@ void wm8758_write(int reg, int data) | |||
86 | * Note, I'm using the WM8750 datasheet as its apparently close. | 86 | * Note, I'm using the WM8750 datasheet as its apparently close. |
87 | */ | 87 | */ |
88 | int wmcodec_init(void) { | 88 | int wmcodec_init(void) { |
89 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
90 | |||
91 | /* normal outputs for CDI and I2S pin groups */ | 89 | /* normal outputs for CDI and I2S pin groups */ |
92 | outl(inl(0x70000020) & ~0x300, 0x70000020); | 90 | outl(inl(0x70000020) & ~0x300, 0x70000020); |
93 | 91 | ||
@@ -108,7 +106,6 @@ int wmcodec_init(void) { | |||
108 | /* external dev clock to 24MHz */ | 106 | /* external dev clock to 24MHz */ |
109 | outl(inl(0x70000018) & ~0xc, 0x70000018); | 107 | outl(inl(0x70000018) & ~0xc, 0x70000018); |
110 | 108 | ||
111 | set_irq_level(old_irq_level); | ||
112 | return 0; | 109 | return 0; |
113 | } | 110 | } |
114 | 111 | ||
@@ -117,8 +114,6 @@ void wmcodec_enable_output(bool enable) | |||
117 | { | 114 | { |
118 | if (enable) | 115 | if (enable) |
119 | { | 116 | { |
120 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
121 | |||
122 | /* reset the I2S controller into known state */ | 117 | /* reset the I2S controller into known state */ |
123 | i2s_reset(); | 118 | i2s_reset(); |
124 | 119 | ||
@@ -142,7 +137,6 @@ void wmcodec_enable_output(bool enable) | |||
142 | wm8758_write(LOUTMIX,0x1); /* Enable mixer */ | 137 | wm8758_write(LOUTMIX,0x1); /* Enable mixer */ |
143 | wm8758_write(ROUTMIX,0x1); /* Enable mixer */ | 138 | wm8758_write(ROUTMIX,0x1); /* Enable mixer */ |
144 | wmcodec_mute(0); | 139 | wmcodec_mute(0); |
145 | set_irq_level(old_irq_level); | ||
146 | } else { | 140 | } else { |
147 | wmcodec_mute(1); | 141 | wmcodec_mute(1); |
148 | } | 142 | } |
@@ -150,7 +144,6 @@ void wmcodec_enable_output(bool enable) | |||
150 | 144 | ||
151 | int wmcodec_set_master_vol(int vol_l, int vol_r) | 145 | int wmcodec_set_master_vol(int vol_l, int vol_r) |
152 | { | 146 | { |
153 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
154 | /* OUT1 */ | 147 | /* OUT1 */ |
155 | wm8758_write(LOUT1VOL, vol_l); | 148 | wm8758_write(LOUT1VOL, vol_l); |
156 | wm8758_write(ROUT1VOL, 0x100 | vol_r); | 149 | wm8758_write(ROUT1VOL, 0x100 | vol_r); |
@@ -159,8 +152,6 @@ int wmcodec_set_master_vol(int vol_l, int vol_r) | |||
159 | wm8758_write(LOUT2VOL, vol_l); | 152 | wm8758_write(LOUT2VOL, vol_l); |
160 | wm8758_write(ROUT2VOL, 0x100 | vol_r); | 153 | wm8758_write(ROUT2VOL, 0x100 | vol_r); |
161 | 154 | ||
162 | set_irq_level(old_irq_level); | ||
163 | |||
164 | return 0; | 155 | return 0; |
165 | } | 156 | } |
166 | 157 | ||
@@ -204,8 +195,6 @@ void wmcodec_set_treble(int value) | |||
204 | 195 | ||
205 | int wmcodec_mute(int mute) | 196 | int wmcodec_mute(int mute) |
206 | { | 197 | { |
207 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
208 | |||
209 | if (mute) | 198 | if (mute) |
210 | { | 199 | { |
211 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | 200 | /* Set DACMU = 1 to soft-mute the audio DACs. */ |
@@ -215,16 +204,12 @@ int wmcodec_mute(int mute) | |||
215 | wm8758_write(DACCTRL, 0x0); | 204 | wm8758_write(DACCTRL, 0x0); |
216 | } | 205 | } |
217 | 206 | ||
218 | set_irq_level(old_irq_level); | ||
219 | |||
220 | return 0; | 207 | return 0; |
221 | } | 208 | } |
222 | 209 | ||
223 | /* Nice shutdown of WM8758 codec */ | 210 | /* Nice shutdown of WM8758 codec */ |
224 | void wmcodec_close(void) | 211 | void wmcodec_close(void) |
225 | { | 212 | { |
226 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
227 | |||
228 | wmcodec_mute(1); | 213 | wmcodec_mute(1); |
229 | 214 | ||
230 | wm8758_write(PWRMGMT3, 0x0); | 215 | wm8758_write(PWRMGMT3, 0x0); |
@@ -232,8 +217,6 @@ void wmcodec_close(void) | |||
232 | wm8758_write(PWRMGMT1, 0x0); | 217 | wm8758_write(PWRMGMT1, 0x0); |
233 | 218 | ||
234 | wm8758_write(PWRMGMT2, 0x40); | 219 | wm8758_write(PWRMGMT2, 0x40); |
235 | |||
236 | set_irq_level(old_irq_level); | ||
237 | } | 220 | } |
238 | 221 | ||
239 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ | 222 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ |
@@ -245,8 +228,6 @@ void wmcodec_set_nsorder(int order) | |||
245 | /* Note: Disable output before calling this function */ | 228 | /* Note: Disable output before calling this function */ |
246 | void wmcodec_set_sample_rate(int sampling_control) | 229 | void wmcodec_set_sample_rate(int sampling_control) |
247 | { | 230 | { |
248 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
249 | |||
250 | /**** We force 44.1KHz for now. ****/ | 231 | /**** We force 44.1KHz for now. ****/ |
251 | (void)sampling_control; | 232 | (void)sampling_control; |
252 | 233 | ||
@@ -264,8 +245,6 @@ void wmcodec_set_sample_rate(int sampling_control) | |||
264 | 245 | ||
265 | /* set srate */ | 246 | /* set srate */ |
266 | wm8758_write(SRATECTRL, (0 << 1)); | 247 | wm8758_write(SRATECTRL, (0 << 1)); |
267 | |||
268 | set_irq_level(old_irq_level); | ||
269 | } | 248 | } |
270 | 249 | ||
271 | void wmcodec_enable_recording(bool source_mic) | 250 | void wmcodec_enable_recording(bool source_mic) |