diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/fmradio_i2c.c | 17 | ||||
-rw-r--r-- | firmware/drivers/i2c-coldfire.c | 229 | ||||
-rw-r--r-- | firmware/drivers/tlv320.c | 119 | ||||
-rw-r--r-- | firmware/drivers/uda1380.c | 26 |
4 files changed, 256 insertions, 135 deletions
diff --git a/firmware/drivers/fmradio_i2c.c b/firmware/drivers/fmradio_i2c.c index 2475084696..6f87e15b3e 100644 --- a/firmware/drivers/fmradio_i2c.c +++ b/firmware/drivers/fmradio_i2c.c | |||
@@ -27,6 +27,22 @@ | |||
27 | 27 | ||
28 | #if (CONFIG_TUNER & TEA5767) | 28 | #if (CONFIG_TUNER & TEA5767) |
29 | #if (CONFIG_I2C == I2C_COLDFIRE) | 29 | #if (CONFIG_I2C == I2C_COLDFIRE) |
30 | |||
31 | #ifdef IAUDIO_X5 | ||
32 | #include "i2c-coldfire.h" | ||
33 | |||
34 | int fmradio_i2c_write(unsigned char address, const unsigned char* buf, | ||
35 | int count) | ||
36 | { | ||
37 | return i2c_write(I2C_IFACE_0, address, buf, count); | ||
38 | } | ||
39 | |||
40 | int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | ||
41 | { | ||
42 | return i2c_read(I2C_IFACE_0, address, buf, count); | ||
43 | } | ||
44 | #else | ||
45 | |||
30 | /* cute little functions, atomic read-modify-write */ | 46 | /* cute little functions, atomic read-modify-write */ |
31 | /* SDA is GPIO1,23 */ | 47 | /* SDA is GPIO1,23 */ |
32 | 48 | ||
@@ -242,6 +258,7 @@ int fmradio_i2c_read(int address, unsigned char* buf, int count) | |||
242 | fmradio_i2c_stop(); | 258 | fmradio_i2c_stop(); |
243 | return x; | 259 | return x; |
244 | } | 260 | } |
261 | #endif /* ! IAUDIO_X5 */ | ||
245 | #else | 262 | #else |
246 | /* cute little functions, atomic read-modify-write */ | 263 | /* cute little functions, atomic read-modify-write */ |
247 | /* SDA is PB4 */ | 264 | /* SDA is PB4 */ |
diff --git a/firmware/drivers/i2c-coldfire.c b/firmware/drivers/i2c-coldfire.c index 47aeba757f..a628ce5f0e 100644 --- a/firmware/drivers/i2c-coldfire.c +++ b/firmware/drivers/i2c-coldfire.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * | ||
8 | * $Id$ | 9 | * $Id$ |
9 | * | 10 | * |
10 | * Copyright (C) 2005 by Andy Young | 11 | * Copyright (C) 2005 by Andy Young |
@@ -23,17 +24,16 @@ | |||
23 | #include "system.h" | 24 | #include "system.h" |
24 | #include "i2c-coldfire.h" | 25 | #include "i2c-coldfire.h" |
25 | 26 | ||
26 | #define I2C_DEVICE_1 ((volatile unsigned char *)&MADR) | ||
27 | #define I2C_DEVICE_2 ((volatile unsigned char *)&MADR2) | ||
28 | 27 | ||
29 | /* Local functions definitions */ | 28 | /* --- Local functions - declarations --- */ |
29 | |||
30 | static int i2c_start(volatile unsigned char *iface); | ||
31 | static int i2c_wait_for_slave(volatile unsigned char *iface); | ||
32 | static int i2c_outb(volatile unsigned char *iface, unsigned char byte); | ||
33 | inline void i2c_stop(volatile unsigned char *iface); | ||
30 | 34 | ||
31 | static int i2c_write_byte(int device, unsigned char data); | ||
32 | static int i2c_gen_start(int device); | ||
33 | static void i2c_gen_stop(int device); | ||
34 | static volatile unsigned char *i2c_get_addr(int device); | ||
35 | 35 | ||
36 | /* Public functions */ | 36 | /* --- Public functions - implementation --- */ |
37 | 37 | ||
38 | void i2c_init(void) | 38 | void i2c_init(void) |
39 | { | 39 | { |
@@ -55,14 +55,15 @@ void i2c_init(void) | |||
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | /* I2C Clock divisor = 160 => 124.1556 MHz / 2 / 160 = 388.08 kHz */ | 57 | /* I2C Clock divisor = 160 => 124.1556 MHz / 2 / 160 = 388.08 kHz */ |
58 | MFDR = 0x0d; | 58 | MFDR = 0x0d; |
59 | MFDR2 = 0x0d; | 59 | MFDR2 = 0x0d; |
60 | 60 | ||
61 | #ifdef IAUDIO_X5 | 61 | #ifdef IAUDIO_X5 |
62 | MBCR = IEN; /* Enable interface */ | 62 | MBCR = IEN; /* Enable interface */ |
63 | MBCR2 = IEN; | ||
63 | #endif | 64 | #endif |
64 | 65 | ||
65 | #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) | 66 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) |
66 | /* Audio Codec */ | 67 | /* Audio Codec */ |
67 | MBDR = 0; /* iRiver firmware does this */ | 68 | MBDR = 0; /* iRiver firmware does this */ |
68 | MBCR = IEN; /* Enable interface */ | 69 | MBCR = IEN; /* Enable interface */ |
@@ -72,109 +73,169 @@ void i2c_init(void) | |||
72 | void i2c_close(void) | 73 | void i2c_close(void) |
73 | { | 74 | { |
74 | MBCR = 0; | 75 | MBCR = 0; |
76 | MBCR2 = 0; | ||
75 | } | 77 | } |
76 | 78 | ||
77 | /** | 79 | /* |
78 | * Writes bytes to the selected device. | 80 | * Writes bytes to a I2C device. |
79 | * | 81 | * |
80 | * Use device=1 for bus 1 at 0x40000280 | 82 | * Returns number of bytes successfully sent or a negative value on error. |
81 | * Use device=2 for bus 2 at 0x80000440 | ||
82 | * | ||
83 | * Returns number of bytes successfully send or -1 if START failed | ||
84 | */ | 83 | */ |
85 | int i2c_write(int device, unsigned char *buf, int count) | 84 | int i2c_write(volatile unsigned char *iface, unsigned char addr, |
85 | const unsigned char *buf, int count) | ||
86 | { | 86 | { |
87 | int i; | 87 | int i, rc; |
88 | int rc; | ||
89 | 88 | ||
90 | rc = i2c_gen_start(device); | 89 | if ( ! count) |
90 | return 0; | ||
91 | |||
92 | rc = i2c_start(iface); | ||
91 | if (rc < 0) | 93 | if (rc < 0) |
94 | return rc; | ||
95 | |||
96 | rc = i2c_outb(iface, addr & 0xfe); | ||
97 | if (rc < 0) | ||
98 | return rc; | ||
99 | |||
100 | for (i = 0; i < count; i++) | ||
92 | { | 101 | { |
93 | logf("i2c: gen_start failed (d=%d)", device); | 102 | rc = i2c_outb(iface, *buf++); |
94 | return rc*10 - 1; | ||
95 | } | ||
96 | |||
97 | for (i=0; i<count; i++) | ||
98 | { | ||
99 | rc = i2c_write_byte(device, buf[i]); | ||
100 | if (rc < 0) | 103 | if (rc < 0) |
101 | { | 104 | return rc; |
102 | logf("i2c: write failed at (d=%d,i=%d)", device, i); | ||
103 | return rc*10 - 2; | ||
104 | } | ||
105 | } | 105 | } |
106 | 106 | i2c_stop(iface); | |
107 | i2c_gen_stop(device); | 107 | |
108 | |||
109 | return count; | 108 | return count; |
110 | } | 109 | } |
111 | 110 | ||
112 | /* Write a byte to the interface, returns 0 on success, -1 otherwise. */ | 111 | /* |
113 | int i2c_write_byte(int device, unsigned char data) | 112 | * Reads bytes from a I2C device. |
113 | * | ||
114 | * Returns number of bytes successfully received or a negative value on error. | ||
115 | */ | ||
116 | int i2c_read(volatile unsigned char *iface, unsigned char addr, | ||
117 | unsigned char *buf, int count) | ||
114 | { | 118 | { |
115 | volatile unsigned char *regs = i2c_get_addr(device); | 119 | int i, rc; |
116 | 120 | ||
117 | long count = 0; | 121 | if ( ! count) |
122 | return 0; | ||
123 | |||
124 | rc = i2c_start(iface); | ||
125 | if (rc < 0) | ||
126 | return rc; | ||
118 | 127 | ||
119 | regs[O_MBDR] = data; /* Write data byte */ | 128 | rc = i2c_outb(iface, addr | 1); |
129 | if (rc < 0) | ||
130 | return rc; | ||
131 | |||
132 | /* Switch to Rx mode */ | ||
133 | iface[O_MBCR] &= ~MTX; | ||
134 | iface[O_MBCR] &= ~TXAK; | ||
135 | |||
136 | /* Dummy read */ | ||
137 | rc = (int) iface[O_MBDR]; | ||
138 | |||
139 | for (i = 0; i < count; i++) | ||
140 | { | ||
141 | rc = i2c_wait_for_slave(iface); | ||
142 | if (rc < 0) | ||
143 | return rc; | ||
120 | 144 | ||
121 | /* Wait for bus busy */ | 145 | if (i == count-2) |
122 | while (!(regs[O_MBSR] & IBB) && count < MAX_LOOP) | 146 | /* Don't ACK the next-to-last byte */ |
123 | count++; | 147 | iface[O_MBCR] |= TXAK; |
148 | |||
149 | if (i == count-1) | ||
150 | /* Generate STOP before reading last byte */ | ||
151 | i2c_stop(iface); | ||
124 | 152 | ||
125 | if (count >= MAX_LOOP) | 153 | *buf++ = iface[O_MBDR]; |
126 | return -1; | 154 | } |
155 | return count; | ||
156 | } | ||
127 | 157 | ||
128 | count = 0; | 158 | /* --- Local functions - implementation --- */ |
129 | 159 | ||
130 | /* Wait for interrupt flag */ | 160 | /* Begin I2C session on the given interface. |
131 | while (!(regs[O_MBSR] & IFF) && count < MAX_LOOP) | 161 | * |
132 | count++; | 162 | * Returns 0 on success, negative value on error. |
163 | */ | ||
164 | int i2c_start(volatile unsigned char *iface) | ||
165 | { | ||
166 | /* Wait for bus to become free */ | ||
167 | int j = MAX_LOOP; | ||
168 | while (--j && (iface[O_MBSR] & IBB)) | ||
169 | ; | ||
170 | if (!j) | ||
171 | { | ||
172 | logf("i2c: bus is busy (iface=%08x)", iface); | ||
173 | return -1; | ||
174 | } | ||
175 | |||
176 | /* Generate START and prepare for write */ | ||
177 | iface[O_MBCR] |= (MSTA | TXAK | MTX); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
133 | 181 | ||
134 | if (count >= MAX_LOOP) | 182 | /* Wait for slave to act on given I2C interface. |
183 | * | ||
184 | * Returns 0 on success, negative value on error. | ||
185 | */ | ||
186 | int i2c_wait_for_slave(volatile unsigned char *iface) | ||
187 | { | ||
188 | int j = MAX_LOOP; | ||
189 | while (--j && ! (iface[O_MBSR] & IFF)) | ||
190 | ; | ||
191 | if (!j) | ||
192 | { | ||
193 | logf("i2c: IFF not set (iface=%08x)", iface); | ||
194 | i2c_stop(iface); | ||
135 | return -2; | 195 | return -2; |
136 | 196 | } | |
137 | regs[O_MBSR] &= ~IFF; /* Clear interrupt flag */ | 197 | |
138 | 198 | /* Clear interrupt flag */ | |
139 | if (!(regs[O_MBSR] & ICF)) /* Check that transfer is complete */ | 199 | iface[O_MBSR] &= ~IFF; |
140 | return -3; | 200 | |
141 | |||
142 | if (regs[O_MBSR] & RXAK) /* Check that the byte has been ACKed */ | ||
143 | return -4; | ||
144 | |||
145 | return 0; | 201 | return 0; |
146 | } | 202 | } |
147 | 203 | ||
148 | 204 | /* Write the given byte to the given I2C interface. | |
149 | /* Returns 0 on success, -1 on failure */ | 205 | * |
150 | int i2c_gen_start(int device) | 206 | * Returns 0 on success, negative value on error. |
207 | */ | ||
208 | int i2c_outb(volatile unsigned char *iface, unsigned char byte) | ||
151 | { | 209 | { |
152 | volatile unsigned char *regs = i2c_get_addr(device); | 210 | int rc; |
153 | long count = 0; | ||
154 | |||
155 | /* Wait for bus to become free */ | ||
156 | while ((regs[O_MBSR] & IBB) && (count < MAX_LOOP)) | ||
157 | count++; | ||
158 | |||
159 | if (count >= MAX_LOOP) | ||
160 | return -1; | ||
161 | 211 | ||
162 | regs[O_MBCR] |= MSTA | MTX; /* Generate START */ | 212 | iface[O_MBDR] = byte; |
163 | 213 | ||
214 | rc = i2c_wait_for_slave(iface); | ||
215 | if (rc < 0) | ||
216 | return rc; | ||
217 | |||
218 | /* Check that transfer is complete */ | ||
219 | if ( !(iface[O_MBSR] & ICF)) | ||
220 | { | ||
221 | logf("i2c: transfer error (iface=%08x)", iface); | ||
222 | i2c_stop(iface); | ||
223 | return -3; | ||
224 | } | ||
225 | |||
226 | /* Check that the byte has been ACKed */ | ||
227 | if (iface[O_MBSR] & RXAK) | ||
228 | { | ||
229 | logf("i2c: no ACK (iface=%08x)", iface); | ||
230 | i2c_stop(iface); | ||
231 | return -4; | ||
232 | } | ||
233 | |||
164 | return 0; | 234 | return 0; |
165 | } | ||
166 | |||
167 | void i2c_gen_stop(int device) | ||
168 | { | ||
169 | volatile unsigned char *regs = i2c_get_addr(device); | ||
170 | regs[O_MBCR] &= ~MSTA; /* Clear MSTA to generate STOP */ | ||
171 | } | 235 | } |
172 | 236 | ||
173 | 237 | /* End I2C session on the given interface. */ | |
174 | volatile unsigned char *i2c_get_addr(int device) | 238 | inline void i2c_stop(volatile unsigned char *iface) |
175 | { | 239 | { |
176 | if (device == 1) | 240 | iface[O_MBCR] &= ~MSTA; |
177 | return I2C_DEVICE_1; | ||
178 | |||
179 | return I2C_DEVICE_2; | ||
180 | } | 241 | } |
diff --git a/firmware/drivers/tlv320.c b/firmware/drivers/tlv320.c index 8ef32919ce..39cd2a5536 100644 --- a/firmware/drivers/tlv320.c +++ b/firmware/drivers/tlv320.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "string.h" | 28 | #include "string.h" |
29 | #include "file.h" | 29 | #include "file.h" |
30 | #include "buffer.h" | 30 | #include "buffer.h" |
31 | #include "audio.h" | ||
31 | 32 | ||
32 | #include "i2c-coldfire.h" | 33 | #include "i2c-coldfire.h" |
33 | #include "tlv320.h" | 34 | #include "tlv320.h" |
@@ -46,14 +47,13 @@ unsigned tlv320_regs[0xf]; | |||
46 | 47 | ||
47 | void tlv320_write_reg(unsigned reg, unsigned value) | 48 | void tlv320_write_reg(unsigned reg, unsigned value) |
48 | { | 49 | { |
49 | unsigned char data[3]; | 50 | unsigned char data[2]; |
50 | 51 | ||
51 | data[0] = TLV320_ADDR; | ||
52 | /* The register address is the high 7 bits and the data the low 9 bits */ | 52 | /* The register address is the high 7 bits and the data the low 9 bits */ |
53 | data[1] = (reg << 1) | ((value >> 8) & 1); | 53 | data[0] = (reg << 1) | ((value >> 8) & 1); |
54 | data[2] = value & 0xff; | 54 | data[1] = value & 0xff; |
55 | 55 | ||
56 | if (i2c_write(1, data, 3) != 3) | 56 | if (i2c_write(I2C_IFACE_0, TLV320_ADDR, data, 2) != 2) |
57 | { | 57 | { |
58 | logf("tlv320 error reg=0x%x", reg); | 58 | logf("tlv320 error reg=0x%x", reg); |
59 | return; | 59 | return; |
@@ -73,15 +73,16 @@ void tlv320_init(void) | |||
73 | 73 | ||
74 | /* Initialize all registers */ | 74 | /* Initialize all registers */ |
75 | 75 | ||
76 | tlv320_write_reg(REG_PC, 0x00); /* All ON */ | 76 | tlv320_write_reg(REG_PC, PC_ADC|PC_MIC|PC_LINE); /* All ON except ADC, MIC and LINE */ |
77 | tlv320_set_linein_vol(0, 0); | 77 | tlv320_set_recvol(0, 0, AUDIO_GAIN_MIC); |
78 | tlv320_set_recvol(0, 0, AUDIO_GAIN_LINEIN); | ||
78 | tlv320_mute(true); | 79 | tlv320_mute(true); |
79 | tlv320_write_reg(REG_AAP, AAP_DAC|AAP_MICM); | 80 | tlv320_write_reg(REG_AAP, AAP_DAC|AAP_MICM); |
80 | tlv320_write_reg(REG_DAP, 0x00); /* No deemphasis */ | 81 | tlv320_write_reg(REG_DAP, 0x00); /* No deemphasis */ |
81 | tlv320_write_reg(REG_DAIF, DAIF_IWL_16|DAIF_FOR_I2S); | 82 | tlv320_write_reg(REG_DAIF, DAIF_IWL_16|DAIF_FOR_I2S); |
82 | tlv320_set_headphone_vol(0, 0); | 83 | tlv320_set_headphone_vol(0, 0); |
83 | tlv320_write_reg(REG_DIA, DIA_ACT); | 84 | tlv320_write_reg(REG_DIA, DIA_ACT); |
84 | tlv320_write_reg(REG_SRC, (8 << 2)); /* 44.1kHz */ | 85 | tlv320_write_reg(REG_SRC, (1 << 5)); /* 44.1kHz */ |
85 | } | 86 | } |
86 | 87 | ||
87 | /** | 88 | /** |
@@ -114,18 +115,30 @@ void tlv320_set_headphone_vol(int vol_l, int vol_r) | |||
114 | } | 115 | } |
115 | 116 | ||
116 | /** | 117 | /** |
117 | * Sets left and right linein volume (31(max) to 0(muted)) | 118 | * Set recording volume |
119 | * | ||
120 | * Line in : 0 .. 31 => Volume -34.5 .. 12 dB | ||
121 | * Mic (left): 0 .. 1 => Volume 0 .. 20 dB | ||
122 | * | ||
118 | */ | 123 | */ |
119 | void tlv320_set_linein_vol(int vol_l, int vol_r) | 124 | void tlv320_set_recvol(int left, int right, int type) |
120 | { | 125 | { |
121 | unsigned value_l = tlv320_regs[REG_LLIV]; | 126 | if (type == AUDIO_GAIN_MIC) |
122 | unsigned value_r = tlv320_regs[REG_RLIV]; | 127 | { |
123 | 128 | unsigned value_aap = tlv320_regs[REG_AAP]; | |
124 | value_l |= LLIV_LIV(vol_l); | 129 | |
125 | value_r |= RLIV_RIV(vol_r); | 130 | if (left) |
126 | 131 | value_aap |= AAP_MICB; /* Enable mic boost (20dB) */ | |
127 | tlv320_write_reg(REG_LLIV, value_l); | 132 | else |
128 | tlv320_write_reg(REG_RLIV, value_r); | 133 | value_aap &= ~AAP_MICB; |
134 | |||
135 | tlv320_write_reg(REG_AAP, value_aap); | ||
136 | |||
137 | } else if (type == AUDIO_GAIN_LINEIN) | ||
138 | { | ||
139 | tlv320_write_reg(REG_LLIV, LLIV_LIV(left)); | ||
140 | tlv320_write_reg(REG_RLIV, RLIV_RIV(right)); | ||
141 | } | ||
129 | } | 142 | } |
130 | 143 | ||
131 | /** | 144 | /** |
@@ -148,10 +161,11 @@ void tlv320_mute(bool mute) | |||
148 | value_r = RHV_RHV(tlv320.vol_r); | 161 | value_r = RHV_RHV(tlv320.vol_r); |
149 | } | 162 | } |
150 | 163 | ||
151 | tlv320_write_reg(REG_LHV, value_r); | 164 | tlv320_write_reg(REG_LHV, value_l); |
152 | tlv320_write_reg(REG_RHV, value_r); | 165 | tlv320_write_reg(REG_RHV, value_r); |
153 | } | 166 | } |
154 | 167 | ||
168 | /* Nice shutdown of TLV320 codec */ | ||
155 | void tlv320_close() | 169 | void tlv320_close() |
156 | { | 170 | { |
157 | tlv320_write_reg(REG_PC, 0xFF); /* All OFF */ | 171 | tlv320_write_reg(REG_PC, 0xFF); /* All OFF */ |
@@ -159,35 +173,66 @@ void tlv320_close() | |||
159 | 173 | ||
160 | void tlv320_enable_recording(bool source_mic) | 174 | void tlv320_enable_recording(bool source_mic) |
161 | { | 175 | { |
162 | unsigned value_pc = tlv320_regs[REG_PC]; | 176 | unsigned value_daif = tlv320_regs[REG_DAIF]; |
163 | unsigned value_aap = tlv320_regs[REG_AAP]; | 177 | unsigned value_aap, value_pc; |
164 | 178 | ||
165 | /* select source*/ | ||
166 | if (source_mic) | 179 | if (source_mic) |
167 | { | 180 | { |
168 | value_aap &= ~AAP_INSEL; | 181 | /* select mic and enable mic boost (20 dB) */ |
169 | value_pc |= PC_MIC; | 182 | value_aap = AAP_DAC | AAP_INSEL | AAP_MICB; |
183 | value_pc = PC_LINE; /* power down line-in */ | ||
170 | } | 184 | } |
171 | else | 185 | else |
172 | { | 186 | { |
173 | value_aap |= AAP_INSEL; | 187 | value_aap = AAP_DAC | AAP_MICM; |
174 | value_pc |= PC_LINE; | 188 | value_pc = PC_MIC; /* power down mic */ |
175 | } | 189 | } |
176 | 190 | ||
177 | /* poweron adc */ | 191 | tlv320_write_reg(REG_PC, value_pc); |
178 | value_pc |= PC_ADC; | 192 | sleep(HZ/8); |
179 | 193 | ||
180 | tlv320_write_reg(REG_AAP, value_aap); | 194 | tlv320_write_reg(REG_AAP, value_aap); |
181 | tlv320_write_reg(REG_PC, value_pc); | 195 | sleep(HZ/8); |
196 | |||
197 | /* Enable MASTER mode (start sending I2S data to the CPU) */ | ||
198 | value_daif |= DAIF_MS; | ||
199 | tlv320_write_reg(REG_DAIF, value_daif); | ||
182 | } | 200 | } |
183 | 201 | ||
184 | void tlv320_disable_recording() | 202 | void tlv320_disable_recording() |
185 | { | 203 | { |
186 | unsigned value = tlv320_regs[REG_PC]; | 204 | unsigned value_pc = tlv320_regs[REG_PC]; |
187 | 205 | unsigned value_aap = tlv320_regs[REG_AAP]; | |
188 | /* powerdown mic, linein and adc */ | 206 | unsigned value_daif = tlv320_regs[REG_DAIF]; |
189 | value &= ~(PC_MIC | PC_LINE | PC_ADC); | 207 | |
208 | value_daif &= ~DAIF_MS; /* disable MASTER mode */ | ||
209 | tlv320_write_reg(REG_DAIF, value_daif); | ||
210 | |||
211 | value_aap |= AAP_MICM; /* mute mic */ | ||
212 | tlv320_write_reg(REG_PC, value_aap); | ||
213 | |||
214 | value_pc |= (PC_MIC|PC_LINE|PC_ADC); /* power down mic, line-in and adc */ | ||
215 | tlv320_write_reg(REG_PC, value_pc); | ||
216 | |||
217 | sleep(HZ/8); | ||
218 | } | ||
190 | 219 | ||
191 | /* powerdown mic, linein and adc */ | 220 | void tlv320_set_monitor(bool enable) |
192 | tlv320_write_reg(REG_PC, value); | 221 | { |
222 | unsigned value_aap, value_pc; | ||
223 | if (enable) | ||
224 | { | ||
225 | value_aap = AAP_BYPASS | AAP_MICM; | ||
226 | value_pc = (PC_MIC|PC_DAC|PC_ADC); /* power down mic, dac and adc */ | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | value_aap = AAP_DAC | AAP_MICM; | ||
231 | value_pc = (PC_MIC|PC_LINE|PC_ADC); /* power down mic, line-in and adc */ | ||
232 | } | ||
233 | tlv320_write_reg(REG_AAP, value_aap); | ||
234 | tlv320_write_reg(REG_PC, value_pc); | ||
235 | |||
236 | sleep(HZ/8); | ||
193 | } | 237 | } |
238 | |||
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c index ef19dcf1c5..241a117385 100644 --- a/firmware/drivers/uda1380.c +++ b/firmware/drivers/uda1380.c | |||
@@ -76,14 +76,13 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = | |||
76 | /* Returns 0 if register was written or -1 if write failed */ | 76 | /* Returns 0 if register was written or -1 if write failed */ |
77 | int uda1380_write_reg(unsigned char reg, unsigned short value) | 77 | int uda1380_write_reg(unsigned char reg, unsigned short value) |
78 | { | 78 | { |
79 | unsigned char data[4]; | 79 | unsigned char data[3]; |
80 | 80 | ||
81 | data[0] = UDA1380_ADDR; | 81 | data[0] = reg; |
82 | data[1] = reg; | 82 | data[1] = value >> 8; |
83 | data[2] = value >> 8; | 83 | data[2] = value & 0xff; |
84 | data[3] = value & 0xff; | ||
85 | 84 | ||
86 | if (i2c_write(1, data, 4) != 4) | 85 | if (i2c_write(I2C_IFACE_0, UDA1380_ADDR, data, 3) != 3) |
87 | { | 86 | { |
88 | DEBUGF("uda1380 error reg=0x%x", reg); | 87 | DEBUGF("uda1380 error reg=0x%x", reg); |
89 | return -1; | 88 | return -1; |
@@ -322,21 +321,20 @@ void uda1380_set_recvol(int left, int right, int type) | |||
322 | { | 321 | { |
323 | /* for this order we can combine both registers, | 322 | /* for this order we can combine both registers, |
324 | making the glitch even smaller */ | 323 | making the glitch even smaller */ |
325 | unsigned char data[6]; | 324 | unsigned char data[5]; |
326 | unsigned short value_dec; | 325 | unsigned short value_dec; |
327 | unsigned short value_pga; | 326 | unsigned short value_pga; |
328 | value_dec = DEC_VOLL(left) | DEC_VOLR(right); | 327 | value_dec = DEC_VOLL(left) | DEC_VOLR(right); |
329 | value_pga = (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) | 328 | value_pga = (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) |
330 | | PGA_GAINL(left_ag) | PGA_GAINR(right_ag); | 329 | | PGA_GAINL(left_ag) | PGA_GAINR(right_ag); |
331 | 330 | ||
332 | data[0] = UDA1380_ADDR; | 331 | data[0] = REG_DEC_VOL; |
333 | data[1] = REG_DEC_VOL; | 332 | data[1] = value_dec >> 8; |
334 | data[2] = value_dec >> 8; | 333 | data[2] = value_dec & 0xff; |
335 | data[3] = value_dec & 0xff; | 334 | data[3] = value_pga >> 8; |
336 | data[4] = value_pga >> 8; | 335 | data[4] = value_pga & 0xff; |
337 | data[5] = value_pga & 0xff; | ||
338 | 336 | ||
339 | if (i2c_write(1, data, 6) != 6) | 337 | if (i2c_write(I2C_IFACE_0, UDA1380_ADDR, data, 5) != 5) |
340 | { | 338 | { |
341 | DEBUGF("uda1380 error reg=combi rec gain"); | 339 | DEBUGF("uda1380 error reg=combi rec gain"); |
342 | } | 340 | } |