added fonera-mp3 support to k7.09
[openwrt/svn-archive/archive.git] / package / fonera-mp3-drv / src / vs10xx.c
1 /*
2 * a.lp_mp3 - VS1011B driver for Fonera
3 * Copyright (c) 2007 phrozen.org - John Crispin <john@phrozen.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
18 *
19 * Feedback, Bugs.... mail john@phrozen.org
20 *
21 */
22
23 #include <linux/module.h>
24 #include <linux/sched.h>
25 #include <linux/slab.h>
26 #include <linux/ioport.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/fs.h>
30 #include <linux/string.h>
31 #include <linux/poll.h>
32 #include <linux/init.h>
33 #include <linux/interrupt.h>
34 #include <linux/delay.h>
35
36 #include <asm/io.h>
37 #include <asm/system.h>
38 #include <asm/irq.h>
39 #include "ar531xlnx.h"
40
41 #define AR5315_DSLBASE 0xB1000000
42 #define AR5315_GPIO_DI (AR5315_DSLBASE + 0x0088)
43 #define AR5315_GPIO_DO (AR5315_DSLBASE + 0x0090)
44 #define AR5315_GPIO_CR (AR5315_DSLBASE + 0x0098)
45 #define AR5315_GPIO_INT (AR5315_DSLBASE + 0x00a0)
46
47 #define GPIO_0 1<<0
48 #define GPIO_1 1<<1
49 #define GPIO_2 1<<2
50 #define GPIO_3 1<<3
51 #define GPIO_4 1<<4
52 #define GPIO_6 1<<6
53 #define GPIO_7 1<<7
54
55 #define DREQ ((unsigned int)GPIO_7)
56 #define SCK ((unsigned int)GPIO_1)
57 #define SI ((unsigned int)GPIO_4)
58 #define BSYNC ((unsigned int)GPIO_3)
59 #define CS ((unsigned int)GPIO_0)
60 #define SO ((unsigned int)GPIO_6)
61 #define RES ((unsigned int)GPIO_2)
62
63 #define REG_MODE 0x0
64 #define REG_STATUS 0x1
65 #define REG_BASS 0x2
66 #define REG_CLOCKF 0x3
67 #define REG_DECODETIME 0x4
68 #define REG_AUDATA 0x5
69 #define REG_WRAM 0x6
70 #define REG_WRAMADDR 0x7
71 #define REG_HDAT0 0x8
72 #define REG_HDAT1 0x9
73 #define REG_A1ADDR 0xa
74 #define REG_VOL 0xb
75 #define REG_A1CTRL0 0xc
76 #define REG_A1CTRL1 0xd
77 #define REG_A1CTRL2 0xe
78
79 #define VS1011_NEEDS_DATA spi_get_bit(DREQ)
80 #define VS1011_NEEDS_NO_DATA (spi_get_bit(DREQ)== 0x00)
81 #define VS1011_WHILE_NEEDS_NO_DATA while(spi_get_bit(DREQ)== 0x00){}
82
83 #define VS_CS_LO spi_clear_bit(CS)
84 #define VS_CS_HI spi_set_bit(CS)
85
86 #define VS_BSYNC_LO spi_clear_bit(BSYNC)
87 #define VS_BSYNC_HI spi_set_bit(BSYNC)
88
89 #define VS_RESET_LO spi_clear_bit(RES)
90 #define VS_RESET_HI spi_set_bit(RES)
91
92 #define VS1011_READ SPI_io_vs1011b(0x03)
93 #define VS1011_WRITE SPI_io_vs1011b(0x02)
94
95 void msDelay(int ms) {
96 int i,a;
97 int delayvar=10;
98
99 for (a=0;a<ms;a++) {
100 for (i=0;i<33084;i++) {
101 delayvar*=2;
102 delayvar/=2;
103 }
104 }
105 }
106
107 int spi_get_bit(unsigned int pin){
108 return ((sysRegRead(AR5315_GPIO_DI)&pin)?(1):(0));
109 }
110
111 void spi_set_bit(unsigned int pin){
112 sysRegWrite(AR5315_GPIO_DO, (sysRegRead(AR5315_GPIO_DO) | pin));
113 }
114
115 void spi_clear_bit(unsigned int pin){
116 sysRegWrite(AR5315_GPIO_DO, (sysRegRead(AR5315_GPIO_DO) & ~pin));
117 }
118
119 void SPI_clock_vs1011b(void){
120 spi_clear_bit(SCK);
121 spi_set_bit(SCK);
122 }
123
124 unsigned char SPI_io_vs1011b(unsigned char byte){
125 int i;
126 unsigned char this_bit;
127 unsigned char byte_out = 0;
128 for(i = 7; i>=0; i--){
129 if(byte & (1<<i)){
130 this_bit = 1;
131 } else {
132 this_bit = 0;
133 }
134 if(this_bit){
135 spi_set_bit(SI);
136 } else {
137 spi_clear_bit(SI);
138 }
139 SPI_clock_vs1011b();
140 byte_out += spi_get_bit(SO)<<i;
141 }
142 return byte_out;
143 }
144
145 void SPI_init_vs1011(void){
146 sysRegWrite(AR5315_GPIO_CR, (sysRegRead(AR5315_GPIO_CR) | SI | SCK | CS | BSYNC | RES) & ~(SO|DREQ));
147 spi_clear_bit(SCK);
148 spi_clear_bit(SI);
149 VS_CS_HI;
150 VS_BSYNC_HI;
151 }
152
153 void VS1011_send_SCI(unsigned char reg, unsigned int data){
154 VS_CS_LO;
155 VS1011_WRITE;
156 SPI_io_vs1011b(reg);
157 SPI_io_vs1011b((data>>8)&0xff);
158 SPI_io_vs1011b(data&0xff);
159 VS_CS_HI;
160 }
161
162 unsigned int VS1011_read_SCI(unsigned char reg){
163 unsigned int data;
164 VS_CS_LO;
165 VS1011_READ;
166 SPI_io_vs1011b(reg);
167 data = 0;
168 data = SPI_io_vs1011b(0x00);
169 data <<= 8;
170 data += SPI_io_vs1011b(0x00);
171 VS_CS_HI;
172 return data;
173 }
174
175 void VS1011_send_SDI(unsigned char byte){
176 int i;
177 VS_BSYNC_LO;
178 for(i = 7; i>=0; i--){
179 if(byte & (1<<i)){
180 spi_set_bit(SI);
181
182 } else {
183 spi_clear_bit(SI);
184 }
185 spi_clear_bit(SCK);
186 spi_set_bit(SCK);
187 }
188 VS_BSYNC_HI;
189 }
190
191 void VS1011_send_SDI_32(unsigned char* data){
192 int i;
193 VS1011_WHILE_NEEDS_NO_DATA;
194 for(i=0; i<32; i++){
195 VS1011_send_SDI(data[i]);
196 }
197 }
198
199 void VS1011_send_zeros(unsigned char count){
200 do{
201 VS1011_send_SDI(0x0);
202 count--;
203 }while(count);
204 }
205
206 void VS1011_set_volume(unsigned int vol){
207 VS1011_send_SCI(REG_VOL, vol);
208 }
209
210 void VS1011_SW_reset(unsigned int _crystal_freq){
211 unsigned int regval = 0x0804;
212 unsigned long int i = 0;
213 msDelay(100);
214 VS1011_send_zeros(32);
215 VS1011_send_SCI(REG_MODE, regval);
216 msDelay(10);
217 while((VS1011_NEEDS_NO_DATA) && (i++<0xffff)){};
218 VS1011_send_SCI(REG_CLOCKF, _crystal_freq);
219 VS1011_send_zeros(16);
220 VS1011_set_volume(0x00);
221 }
222
223 void VS1011_HW_reset(void){
224
225 VS_RESET_LO;
226 msDelay(1);
227 VS_RESET_HI;
228 msDelay(1);
229 }
230
231 void VS1011_init(unsigned int _crystal_freq, unsigned char hw){
232 if(hw){
233 SPI_init_vs1011();
234 }
235 printk("mp3_drv.ko : Init start\n");
236 if(hw){
237 VS1011_HW_reset();
238 }
239 VS1011_SW_reset(_crystal_freq);
240 printk("mp3_drv.ko : init_ok\n");
241 }
242
243 void VS1011_sine(unsigned char state, unsigned char freq){
244 VS1011_send_zeros(16);
245 if(state == 0x01){
246 VS1011_send_SDI(0x53);
247 VS1011_send_SDI(0xEF);
248 VS1011_send_SDI(0x6E);
249 VS1011_send_SDI(freq);
250 VS1011_send_zeros(0x04);
251 } else {
252 VS1011_send_SDI(0x45);
253 VS1011_send_SDI(0x78);
254 VS1011_send_SDI(0x69);
255 VS1011_send_SDI(0x74);
256 VS1011_send_zeros(0x04);
257 }
258 }
259
260 unsigned int VS1011_get_volume(void){
261 return VS1011_read_SCI(REG_VOL);
262 }
263
264 unsigned int VS1011_get_decode_time(void){
265 return VS1011_read_SCI(REG_DECODETIME);
266 }
267
268 const unsigned int sample_rate_values[] = {0, 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
269
270 void VS1011_get_audio_data(AUDIO_DATA* audio){
271 unsigned int audata = VS1011_read_SCI(REG_AUDATA);
272 audio->sample_rate = sample_rate_values[(audata&0x1E00)>>9];
273 audio->bitrate = audata&0x1FF;
274 audio->is_stereo = (audata&0x8000)>>15;
275 }
276
277 void VS1011_print_registers(void){
278 unsigned char i;
279 for(i = 0; i< 14; i++){
280 unsigned int regval = VS1011_read_SCI(i);
281 printk("mp3_drv.ko : %d \n", regval);
282 }
283 }
284
285 void VS1011_volume(unsigned char left, unsigned char right){
286 unsigned int regval = left;
287 regval <<=8;
288 regval += right;
289 VS1011_send_SCI(REG_VOL, regval);
290 }
291
292 void VS1011_set_bass(unsigned int regval){
293 VS1011_send_SCI(REG_BASS, regval);
294 }
295
296 void VS1011_set_reg(unsigned int reg, unsigned int regval){
297 VS1011_send_SCI(reg, regval);
298 }
299
300 /*
301 int vs_test(void) {
302 SPI_init_vs1011();
303 printk("%u\n", *R_GEN_CONFIG);
304 VS1001_init(_crystal_freq);
305 VS1001_print_registers();
306 VS1001_volume(0x30, 0x30);
307 msDelay(1000);
308 VS1001_sine(1, 0x30);
309 msDelay(1000);
310 VS1001_sine(0, 0);
311 VS1001_send_zeros(0x20);
312 msDelay(1000);
313 VS1001_sine(1, 0x30);
314 msDelay(1000);
315 VS1001_sine(0, 0);
316 VS1001_send_zeros(0x20);
317 msDelay(1000);
318 VS1001_sine(1, 0x30);
319 msDelay(1000);
320 VS1001_sine(0, 0);
321
322 AUDIO_DATA a;
323 VS1001_get_audio_data(&a);
324 printk("mp3_drv.ko : rate : %d, bit : %d, stereo : %d \n", a.sample_rate, a.bitrate, a.is_stereo);
325 VS1001_SW_reset(_crystal_freq);
326 return 0;
327 }*/
328