diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-12-24 17:59:43 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-12-24 17:59:43 +0000 |
commit | a1d3ed25346ab4174cb7fd066158cebc8e29fc79 (patch) | |
tree | 9418cafbf4dbbc9b34ab31f1fc5123446204f645 | |
parent | 2ec443df12cda09bd5fee6f9857bca17b7e6aa3f (diff) | |
download | rockbox-a1d3ed25346ab4174cb7fd066158cebc8e29fc79.tar.gz rockbox-a1d3ed25346ab4174cb7fd066158cebc8e29fc79.zip |
ypr0: Cleanup and simplify ascodec functions. Fix audiohw_{pre,post}init() not being called.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31423 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/audio/as3514.c | 28 | ||||
-rw-r--r-- | firmware/target/hosted/pcm-alsa.c | 7 | ||||
-rw-r--r-- | firmware/target/hosted/ypr0/ascodec-target.h | 12 | ||||
-rw-r--r-- | firmware/target/hosted/ypr0/ascodec-ypr0.c | 137 |
4 files changed, 49 insertions, 135 deletions
diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 0fe3070c19..a430afdf88 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c | |||
@@ -78,13 +78,12 @@ const struct sound_settings_info audiohw_settings[] = { | |||
78 | #endif | 78 | #endif |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #ifndef SAMSUNG_YPR0 | ||
82 | /* Shadow registers */ | 81 | /* Shadow registers */ |
83 | static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */ | 82 | static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */ |
84 | 83 | ||
85 | /* | 84 | /* |
86 | * little helper method to set register values. | 85 | * little helper method to set register values. |
87 | * With the help of as3514_regs, we minimize i2c | 86 | * With the help of as3514_regs, we minimize i2c/syscall |
88 | * traffic. | 87 | * traffic. |
89 | */ | 88 | */ |
90 | static void as3514_write(unsigned int reg, unsigned int value) | 89 | static void as3514_write(unsigned int reg, unsigned int value) |
@@ -111,29 +110,7 @@ static void as3514_write_masked(unsigned int reg, unsigned int bits, | |||
111 | { | 110 | { |
112 | as3514_write(reg, (as3514_regs[reg] & ~mask) | (bits & mask)); | 111 | as3514_write(reg, (as3514_regs[reg] & ~mask) | (bits & mask)); |
113 | } | 112 | } |
114 | #else | ||
115 | static void as3514_write(unsigned int reg, unsigned int value) | ||
116 | { | ||
117 | ascodec_write(reg, value); | ||
118 | } | ||
119 | 113 | ||
120 | /* Helpers to set/clear bits */ | ||
121 | static void as3514_set(unsigned int reg, unsigned int bits) | ||
122 | { | ||
123 | ascodec_write(reg, ascodec_read(reg) | bits); | ||
124 | } | ||
125 | |||
126 | static void as3514_clear(unsigned int reg, unsigned int bits) | ||
127 | { | ||
128 | ascodec_write(reg, ascodec_read(reg) & ~bits); | ||
129 | } | ||
130 | |||
131 | static void as3514_write_masked(unsigned int reg, unsigned int bits, | ||
132 | unsigned int mask) | ||
133 | { | ||
134 | ascodec_write(reg, (ascodec_read(reg) & ~mask) | (bits & mask)); | ||
135 | } | ||
136 | #endif | ||
137 | /* convert tenth of dB volume to master volume register value */ | 114 | /* convert tenth of dB volume to master volume register value */ |
138 | int tenthdb2master(int db) | 115 | int tenthdb2master(int db) |
139 | { | 116 | { |
@@ -168,11 +145,8 @@ int sound_val2phys(int setting, int value) | |||
168 | */ | 145 | */ |
169 | void audiohw_preinit(void) | 146 | void audiohw_preinit(void) |
170 | { | 147 | { |
171 | |||
172 | #ifndef SAMSUNG_YPR0 | ||
173 | /* read all reg values */ | 148 | /* read all reg values */ |
174 | ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs); | 149 | ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs); |
175 | #endif | ||
176 | 150 | ||
177 | #ifdef HAVE_AS3543 | 151 | #ifdef HAVE_AS3543 |
178 | 152 | ||
diff --git a/firmware/target/hosted/pcm-alsa.c b/firmware/target/hosted/pcm-alsa.c index 928187993e..7daf485f18 100644 --- a/firmware/target/hosted/pcm-alsa.c +++ b/firmware/target/hosted/pcm-alsa.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "pcm-internal.h" | 50 | #include "pcm-internal.h" |
51 | #include "pcm_mixer.h" | 51 | #include "pcm_mixer.h" |
52 | #include "pcm_sampr.h" | 52 | #include "pcm_sampr.h" |
53 | #include "audiohw.h" | ||
53 | 54 | ||
54 | #include <pthread.h> | 55 | #include <pthread.h> |
55 | #include <signal.h> | 56 | #include <signal.h> |
@@ -320,7 +321,7 @@ void cleanup(void) | |||
320 | void pcm_play_dma_init(void) | 321 | void pcm_play_dma_init(void) |
321 | { | 322 | { |
322 | int err; | 323 | int err; |
323 | 324 | audiohw_preinit(); | |
324 | 325 | ||
325 | if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) | 326 | if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) |
326 | { | 327 | { |
@@ -343,6 +344,8 @@ void pcm_play_dma_init(void) | |||
343 | exit(EXIT_FAILURE); | 344 | exit(EXIT_FAILURE); |
344 | } | 345 | } |
345 | 346 | ||
347 | pcm_dma_apply_settings(); | ||
348 | |||
346 | #ifdef USE_ASYNC_CALLBACK | 349 | #ifdef USE_ASYNC_CALLBACK |
347 | pthread_mutexattr_t attr; | 350 | pthread_mutexattr_t attr; |
348 | pthread_mutexattr_init(&attr); | 351 | pthread_mutexattr_init(&attr); |
@@ -352,7 +355,6 @@ void pcm_play_dma_init(void) | |||
352 | tick_add_task(pcm_tick); | 355 | tick_add_task(pcm_tick); |
353 | #endif | 356 | #endif |
354 | 357 | ||
355 | |||
356 | atexit(cleanup); | 358 | atexit(cleanup); |
357 | return; | 359 | return; |
358 | } | 360 | } |
@@ -469,6 +471,7 @@ const void * pcm_play_dma_get_peak_buffer(int *count) | |||
469 | 471 | ||
470 | void pcm_play_dma_postinit(void) | 472 | void pcm_play_dma_postinit(void) |
471 | { | 473 | { |
474 | audiohw_postinit(); | ||
472 | } | 475 | } |
473 | 476 | ||
474 | 477 | ||
diff --git a/firmware/target/hosted/ypr0/ascodec-target.h b/firmware/target/hosted/ypr0/ascodec-target.h index f4ecf20a1b..2274d5f073 100644 --- a/firmware/target/hosted/ypr0/ascodec-target.h +++ b/firmware/target/hosted/ypr0/ascodec-target.h | |||
@@ -29,24 +29,12 @@ | |||
29 | #include "adc.h" | 29 | #include "adc.h" |
30 | #include "ascodec.h" | 30 | #include "ascodec.h" |
31 | 31 | ||
32 | /* ioctl parameter struct */ | ||
33 | |||
34 | struct codec_req_struct { | ||
35 | /* This works for every kind of afe.ko module requests */ | ||
36 | unsigned char reg; /* Main register address */ | ||
37 | unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/ | ||
38 | unsigned char value; /* To be read if reading a register; to be set if writing to a register */ | ||
39 | }; | ||
40 | |||
41 | int ascodec_init(void); | 32 | int ascodec_init(void); |
42 | void ascodec_close(void); | 33 | void ascodec_close(void); |
43 | int ascodec_write(unsigned int reg, unsigned int value); | 34 | int ascodec_write(unsigned int reg, unsigned int value); |
44 | int ascodec_read(unsigned int reg); | 35 | int ascodec_read(unsigned int reg); |
45 | void ascodec_write_pmu(unsigned int index, unsigned int subreg, unsigned int value); | 36 | void ascodec_write_pmu(unsigned int index, unsigned int subreg, unsigned int value); |
46 | int ascodec_read_pmu(unsigned int index, unsigned int subreg); | 37 | int ascodec_read_pmu(unsigned int index, unsigned int subreg); |
47 | void ascodec_set(unsigned int reg, unsigned int bits); | ||
48 | void ascodec_clear(unsigned int reg, unsigned int bits); | ||
49 | void ascodec_write_masked(unsigned int reg, unsigned int bits, unsigned int mask); | ||
50 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data); | 38 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data); |
51 | unsigned short adc_read(int channel); | 39 | unsigned short adc_read(int channel); |
52 | void ascodec_lock(void); | 40 | void ascodec_lock(void); |
diff --git a/firmware/target/hosted/ypr0/ascodec-ypr0.c b/firmware/target/hosted/ypr0/ascodec-ypr0.c index a4e92e6f6b..b3bc48290f 100644 --- a/firmware/target/hosted/ypr0/ascodec-ypr0.c +++ b/firmware/target/hosted/ypr0/ascodec-ypr0.c | |||
@@ -32,33 +32,36 @@ | |||
32 | 32 | ||
33 | int afe_dev = -1; | 33 | int afe_dev = -1; |
34 | 34 | ||
35 | /* ioctl parameter struct */ | ||
36 | struct codec_req_struct { | ||
37 | /* This works for every kind of afe.ko module requests */ | ||
38 | unsigned char reg; /* Main register address */ | ||
39 | unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/ | ||
40 | unsigned char value; /* To be read if reading a register; to be set if writing to a register */ | ||
41 | } __attribute__((packed)); | ||
42 | |||
43 | |||
35 | /* Write to a normal register */ | 44 | /* Write to a normal register */ |
36 | #define IOCTL_REG_WRITE 0x40034101 | 45 | #define IOCTL_REG_WRITE 0x40034101 |
37 | /* Write to a PMU register */ | 46 | /* Write to a PMU register */ |
38 | #define IOCTL_SUBREG_WRITE 0x40034103 | 47 | #define IOCTL_SUBREG_WRITE 0x40034103 |
39 | /* Read from a normal register */ | 48 | /* Read from a normal register */ |
40 | #define IOCTL_REG_READ 0x80034102 | 49 | #define IOCTL_REG_READ 0x80034102 |
41 | /* Read from a PMU register */ | 50 | /* Read from a PMU register */ |
42 | #define IOCTL_SUBREG_READ 0x80034103 | 51 | #define IOCTL_SUBREG_READ 0x80034103 |
43 | |||
44 | static struct mutex as_mtx; | ||
45 | 52 | ||
46 | int ascodec_init(void) { | ||
47 | 53 | ||
54 | int ascodec_init(void) | ||
55 | { | ||
48 | afe_dev = open("/dev/afe", O_RDWR); | 56 | afe_dev = open("/dev/afe", O_RDWR); |
49 | |||
50 | mutex_init(&as_mtx); | ||
51 | |||
52 | return afe_dev; | 57 | return afe_dev; |
53 | |||
54 | } | 58 | } |
55 | 59 | ||
56 | void ascodec_close(void) { | 60 | void ascodec_close(void) |
57 | 61 | { | |
58 | if (afe_dev >= 0) { | 62 | if (afe_dev >= 0) { |
59 | close(afe_dev); | 63 | close(afe_dev); |
60 | } | 64 | } |
61 | |||
62 | } | 65 | } |
63 | 66 | ||
64 | /* Read functions returns -1 if fail, otherwise the register's value if success */ | 67 | /* Read functions returns -1 if fail, otherwise the register's value if success */ |
@@ -66,24 +69,16 @@ void ascodec_close(void) { | |||
66 | 69 | ||
67 | int ascodec_write(unsigned int reg, unsigned int value) | 70 | int ascodec_write(unsigned int reg, unsigned int value) |
68 | { | 71 | { |
69 | struct codec_req_struct y; | 72 | struct codec_req_struct r = { .reg = reg, .value = value }; |
70 | struct codec_req_struct *p; | 73 | return ioctl(afe_dev, IOCTL_REG_WRITE, &r); |
71 | p = &y; | ||
72 | p->reg = reg; | ||
73 | p->value = value; | ||
74 | return ioctl(afe_dev, IOCTL_REG_WRITE, p); | ||
75 | } | 74 | } |
76 | 75 | ||
77 | int ascodec_read(unsigned int reg) | 76 | int ascodec_read(unsigned int reg) |
78 | { | 77 | { |
79 | int retval = -1; | 78 | struct codec_req_struct r = { .reg = reg }; |
80 | struct codec_req_struct y; | 79 | int retval = ioctl(afe_dev, IOCTL_REG_READ, &r); |
81 | struct codec_req_struct *p; | ||
82 | p = &y; | ||
83 | p->reg = reg; | ||
84 | retval = ioctl(afe_dev, IOCTL_REG_READ, p); | ||
85 | if (retval >= 0) | 80 | if (retval >= 0) |
86 | return p->value; | 81 | return r.value; |
87 | else | 82 | else |
88 | return retval; | 83 | return retval; |
89 | } | 84 | } |
@@ -91,114 +86,68 @@ int ascodec_read(unsigned int reg) | |||
91 | void ascodec_write_pmu(unsigned int index, unsigned int subreg, | 86 | void ascodec_write_pmu(unsigned int index, unsigned int subreg, |
92 | unsigned int value) | 87 | unsigned int value) |
93 | { | 88 | { |
94 | struct codec_req_struct y; | 89 | struct codec_req_struct r = {.reg = index, .subreg = subreg, .value = value}; |
95 | struct codec_req_struct *p; | 90 | ioctl(afe_dev, IOCTL_SUBREG_WRITE, &r); |
96 | p = &y; | ||
97 | p->reg = index; | ||
98 | p->subreg = subreg; | ||
99 | p->value = value; | ||
100 | ioctl(afe_dev, IOCTL_SUBREG_WRITE, p); | ||
101 | } | 91 | } |
102 | 92 | ||
103 | int ascodec_read_pmu(unsigned int index, unsigned int subreg) | 93 | int ascodec_read_pmu(unsigned int index, unsigned int subreg) |
104 | { | 94 | { |
105 | int retval = -1; | 95 | struct codec_req_struct r = { .reg = index, .subreg = subreg, }; |
106 | struct codec_req_struct y; | 96 | int retval = ioctl(afe_dev, IOCTL_SUBREG_READ, &r); |
107 | struct codec_req_struct *p; | ||
108 | p = &y; | ||
109 | p->reg = index; | ||
110 | p->subreg = subreg; | ||
111 | retval = ioctl(afe_dev, IOCTL_SUBREG_READ, p); | ||
112 | if (retval >= 0) | 97 | if (retval >= 0) |
113 | return p->value; | 98 | return r.value; |
114 | else | 99 | else |
115 | return retval; | 100 | return retval; |
116 | } | 101 | } |
117 | 102 | ||
118 | /* Helpers to set/clear bits */ | ||
119 | void ascodec_set(unsigned int reg, unsigned int bits) | ||
120 | { | ||
121 | ascodec_write(reg, ascodec_read(reg) | bits); | ||
122 | } | ||
123 | |||
124 | void ascodec_clear(unsigned int reg, unsigned int bits) | ||
125 | { | ||
126 | ascodec_write(reg, ascodec_read(reg) & ~bits); | ||
127 | } | ||
128 | |||
129 | void ascodec_write_masked(unsigned int reg, unsigned int bits, | ||
130 | unsigned int mask) | ||
131 | { | ||
132 | ascodec_write(reg, (ascodec_read(reg) & ~mask) | (bits & mask)); | ||
133 | } | ||
134 | |||
135 | /*FIXME: doesn't work */ | ||
136 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data) | 103 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data) |
137 | { | 104 | { |
138 | unsigned int i; | 105 | int i, val, ret = 0; |
139 | 106 | ||
140 | for (i=index; i<len; i++) { | 107 | for (i = index; i < (int)len; i++) { |
141 | data[i] = ascodec_read(i); | 108 | val = ascodec_read(i); |
142 | printf("Register %i: value=%i\n",index,data[i]); | 109 | if (val >= 0) data[i] = val; |
110 | else ret = -1; | ||
143 | } | 111 | } |
144 | 112 | ||
145 | printf("TOTAL: %i\n", i); | 113 | return ret ?: i; /* i means success */ |
146 | |||
147 | return i; | ||
148 | } | 114 | } |
149 | 115 | ||
150 | /* | 116 | /* |
151 | * NOTE: | 117 | * NOTE: |
152 | * After the conversion to interrupts, ascodec_(lock|unlock) are only used by | 118 | * After the conversion to interrupts, ascodec_(lock|unlock) are only used by |
153 | * adc-as3514.c to protect against other threads corrupting the result by using | 119 | * adc-as3514.c to protect against other threads corrupting the result by using |
154 | * the ADC at the same time. | 120 | * the ADC at the same time. this adc_read() doesn't yield but blocks, so |
121 | * lock/unlock is not needed | ||
155 | * | 122 | * |
156 | * Concurrent ascodec_(async_)?(read|write) calls are instead protected | 123 | * Additionally, concurrent ascodec_?(read|write) calls are instead protected |
157 | * by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically safe | 124 | * by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically |
125 | * safe | ||
158 | */ | 126 | */ |
159 | 127 | ||
160 | void ascodec_lock(void) | 128 | void ascodec_lock(void) |
161 | { | 129 | { |
162 | mutex_lock(&as_mtx); | ||
163 | } | 130 | } |
164 | 131 | ||
165 | void ascodec_unlock(void) | 132 | void ascodec_unlock(void) |
166 | { | 133 | { |
167 | mutex_unlock(&as_mtx); | ||
168 | } | 134 | } |
169 | 135 | ||
170 | /* Read 10-bit channel data */ | 136 | /* Read 10-bit channel data */ |
171 | unsigned short adc_read(int channel) | 137 | unsigned short adc_read(int channel) |
172 | { | 138 | { |
173 | unsigned short data = 0; | ||
174 | |||
175 | if ((unsigned)channel >= NUM_ADC_CHANNELS) | 139 | if ((unsigned)channel >= NUM_ADC_CHANNELS) |
176 | return 0; | 140 | return 0; |
177 | 141 | ||
178 | ascodec_lock(); | ||
179 | |||
180 | /* Select channel */ | 142 | /* Select channel */ |
181 | ascodec_write(AS3514_ADC_0, (channel << 4)); | 143 | ascodec_write(AS3514_ADC_0, (channel << 4)); |
182 | unsigned char buf[2]; | 144 | unsigned char buf[2]; |
183 | 145 | ||
184 | /* | 146 | /* Read data */ |
185 | * The AS3514 ADC will trigger an interrupt when the conversion | 147 | ascodec_readbytes(AS3514_ADC_0, sizeof(buf), buf); |
186 | * is finished, if the corresponding enable bit in IRQ_ENRD2 | 148 | |
187 | * is set. | 149 | /* decode to 10-bit and return */ |
188 | * Previously the code did not wait and this apparently did | 150 | return (((buf[0] & 0x3) << 8) | buf[1]); |
189 | * not pose any problems, but this should be more correct. | ||
190 | * Without the wait the data read back may be completely or | ||
191 | * partially (first one of the two bytes) stale. | ||
192 | */ | ||
193 | /*FIXME: not implemented*/ | ||
194 | ascodec_wait_adc_finished(); | ||
195 | |||
196 | /* Read data */ | ||
197 | ascodec_readbytes(AS3514_ADC_0, 2, buf); | ||
198 | data = (((buf[0] & 0x3) << 8) | buf[1]); | ||
199 | |||
200 | ascodec_unlock(); | ||
201 | return data; | ||
202 | } | 151 | } |
203 | 152 | ||
204 | void adc_init(void) | 153 | void adc_init(void) |