added libjson-c. added driver, webinterface and userspace daemon for the
[openwrt.git] / package / fonera-mp3-drv / src / vs10xx.c
diff --git a/package/fonera-mp3-drv/src/vs10xx.c b/package/fonera-mp3-drv/src/vs10xx.c
new file mode 100644 (file)
index 0000000..e7b7f68
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * a.lp_mp3 - VS1011B driver for Fonera 
+ * Copyright (c) 2007 phrozen.org - John Crispin <john@phrozen.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
+ *
+ * Feedback, Bugs.... mail john@phrozen.org
+ *
+ */ 
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include "ar531xlnx.h"
+
+#define AR5315_DSLBASE          0xB1000000
+#define AR5315_GPIO_DI          (AR5315_DSLBASE + 0x0088)
+#define AR5315_GPIO_DO          (AR5315_DSLBASE + 0x0090)
+#define AR5315_GPIO_CR          (AR5315_DSLBASE + 0x0098)
+#define AR5315_GPIO_INT         (AR5315_DSLBASE + 0x00a0)
+
+#define GPIO_0                 1<<0
+#define GPIO_1                 1<<1
+#define GPIO_2                 1<<2
+#define GPIO_3                 1<<3
+#define GPIO_4                 1<<4
+#define GPIO_6                 1<<6
+#define GPIO_7                 1<<7
+
+#define DREQ                           ((unsigned int)GPIO_7)
+#define SCK                            ((unsigned int)GPIO_1)
+#define SI                             ((unsigned int)GPIO_4)
+#define BSYNC                          ((unsigned int)GPIO_3)
+#define CS                             ((unsigned int)GPIO_0)
+#define SO                             ((unsigned int)GPIO_6)
+#define RES                            ((unsigned int)GPIO_2)
+
+#define REG_MODE                       0x0
+#define REG_STATUS                     0x1
+#define REG_BASS                       0x2
+#define REG_CLOCKF                     0x3
+#define REG_DECODETIME                 0x4
+#define REG_AUDATA                     0x5
+#define REG_WRAM                       0x6
+#define REG_WRAMADDR                   0x7
+#define REG_HDAT0                      0x8
+#define REG_HDAT1                      0x9
+#define REG_A1ADDR                     0xa
+#define REG_VOL                                0xb
+#define REG_A1CTRL0                    0xc
+#define REG_A1CTRL1                    0xd
+#define REG_A1CTRL2                    0xe
+
+#define VS1011_NEEDS_DATA              spi_get_bit(DREQ)
+#define VS1011_NEEDS_NO_DATA           (spi_get_bit(DREQ)== 0x00)
+#define VS1011_WHILE_NEEDS_NO_DATA     while(spi_get_bit(DREQ)== 0x00){}
+
+#define VS_CS_LO                       spi_clear_bit(CS)
+#define VS_CS_HI                       spi_set_bit(CS)
+
+#define VS_BSYNC_LO                    spi_clear_bit(BSYNC)
+#define VS_BSYNC_HI                    spi_set_bit(BSYNC)
+
+#define VS_RESET_LO                    spi_clear_bit(RES)
+#define VS_RESET_HI                    spi_set_bit(RES)
+
+#define VS1011_READ                    SPI_io_vs1011b(0x03)
+#define VS1011_WRITE                   SPI_io_vs1011b(0x02)
+
+void msDelay(int ms) {
+       int i,a;
+       int delayvar=10;
+
+       for (a=0;a<ms;a++) {
+               for (i=0;i<33084;i++) {
+                       delayvar*=2;        
+                       delayvar/=2;
+               } 
+       }
+}   
+
+int spi_get_bit(unsigned int pin){
+       return ((sysRegRead(AR5315_GPIO_DI)&pin)?(1):(0));
+}
+
+void spi_set_bit(unsigned int pin){
+       sysRegWrite(AR5315_GPIO_DO, (sysRegRead(AR5315_GPIO_DO) | pin));
+}
+
+void spi_clear_bit(unsigned int pin){
+       sysRegWrite(AR5315_GPIO_DO, (sysRegRead(AR5315_GPIO_DO) & ~pin));
+}
+
+void SPI_clock_vs1011b(void){
+       spi_clear_bit(SCK);
+       spi_set_bit(SCK);
+}
+
+unsigned char SPI_io_vs1011b(unsigned char byte){
+       int i;
+       unsigned char this_bit;
+       unsigned char byte_out = 0;
+       for(i = 7; i>=0; i--){
+               if(byte & (1<<i)){
+                       this_bit = 1;
+               } else {
+                       this_bit = 0;
+               }
+               if(this_bit){
+                       spi_set_bit(SI);
+               } else {
+                       spi_clear_bit(SI);
+               }
+               SPI_clock_vs1011b();
+               byte_out += spi_get_bit(SO)<<i;
+       }
+       return byte_out;
+}
+
+void SPI_init_vs1011(void){
+       sysRegWrite(AR5315_GPIO_CR, (sysRegRead(AR5315_GPIO_CR) | SI | SCK | CS | BSYNC | RES) & ~(SO|DREQ));
+       spi_clear_bit(SCK);
+       spi_clear_bit(SI);
+       VS_CS_HI;
+       VS_BSYNC_HI;
+}
+
+void VS1011_send_SCI(unsigned char reg, unsigned int data){
+       VS_CS_LO;
+       VS1011_WRITE;
+       SPI_io_vs1011b(reg);
+       SPI_io_vs1011b((data>>8)&0xff);
+       SPI_io_vs1011b(data&0xff);
+       VS_CS_HI;
+}
+
+unsigned int VS1011_read_SCI(unsigned char reg){
+       unsigned int data;      
+       VS_CS_LO;
+       VS1011_READ;
+       SPI_io_vs1011b(reg);
+       data = 0;
+       data = SPI_io_vs1011b(0x00);
+       data <<= 8;
+       data += SPI_io_vs1011b(0x00);
+       VS_CS_HI;
+       return data;
+}
+
+void VS1011_send_SDI(unsigned char byte){
+       int i;
+       VS_BSYNC_LO;
+       for(i = 7; i>=0; i--){
+               if(byte & (1<<i)){
+                       spi_set_bit(SI);
+                       
+               } else {
+                       spi_clear_bit(SI);
+               }                       
+               spi_clear_bit(SCK);
+               spi_set_bit(SCK);
+       }
+       VS_BSYNC_HI;
+}
+
+void VS1011_send_SDI_32(unsigned char* data){
+       int i;
+       VS1011_WHILE_NEEDS_NO_DATA;
+       for(i=0; i<32; i++){
+               VS1011_send_SDI(data[i]);
+       }
+}
+
+void VS1011_send_zeros(unsigned char count){
+       do{
+               VS1011_send_SDI(0x0);
+               count--;
+       }while(count);
+}
+
+void VS1011_set_volume(unsigned int vol){
+       VS1011_send_SCI(REG_VOL, vol);
+}
+
+void VS1011_SW_reset(unsigned int _crystal_freq){
+       unsigned int regval = 0x0804;
+       unsigned long int i = 0;
+       msDelay(100);
+       VS1011_send_zeros(32);
+       VS1011_send_SCI(REG_MODE, regval);
+       msDelay(10);
+       while((VS1011_NEEDS_NO_DATA) && (i++<0xffff)){};
+       VS1011_send_SCI(REG_CLOCKF, _crystal_freq);
+       VS1011_send_zeros(16);
+       VS1011_set_volume(0x00);
+}
+
+void VS1011_HW_reset(void){
+       
+       VS_RESET_LO;
+       msDelay(1);
+       VS_RESET_HI;
+       msDelay(1);
+}
+
+void VS1011_init(unsigned int _crystal_freq, unsigned char hw){
+       if(hw){
+               SPI_init_vs1011();
+       }
+       printk("mp3_drv.ko : Init start\n");
+       if(hw){
+               VS1011_HW_reset();
+       }
+       VS1011_SW_reset(_crystal_freq);
+       printk("mp3_drv.ko : init_ok\n");
+}
+
+void VS1011_sine(unsigned char state, unsigned char freq){
+       VS1011_send_zeros(16);
+       if(state == 0x01){
+               VS1011_send_SDI(0x53);
+               VS1011_send_SDI(0xEF);
+               VS1011_send_SDI(0x6E);
+               VS1011_send_SDI(freq);
+               VS1011_send_zeros(0x04);
+       } else {
+               VS1011_send_SDI(0x45);
+               VS1011_send_SDI(0x78);
+               VS1011_send_SDI(0x69);
+               VS1011_send_SDI(0x74);
+               VS1011_send_zeros(0x04);                
+       }
+}
+
+unsigned int VS1011_get_volume(void){
+       return VS1011_read_SCI(REG_VOL);
+}
+
+unsigned int VS1011_get_decode_time(void){
+       return VS1011_read_SCI(REG_DECODETIME);
+}
+
+const unsigned int sample_rate_values[]  = {0, 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
+
+void VS1011_get_audio_data(AUDIO_DATA* audio){
+       unsigned int audata = VS1011_read_SCI(REG_AUDATA);
+       audio->sample_rate = sample_rate_values[(audata&0x1E00)>>9];
+       audio->bitrate = audata&0x1FF;
+       audio->is_stereo = (audata&0x8000)>>15;
+}
+
+void VS1011_print_registers(void){
+       unsigned char i;
+       for(i = 0; i< 14; i++){
+               unsigned int regval = VS1011_read_SCI(i);
+               printk("mp3_drv.ko : %d \n", regval);           
+       }
+}
+
+void VS1011_volume(unsigned char left, unsigned char right){
+       unsigned int regval = left;
+       regval <<=8;
+       regval += right;
+       VS1011_send_SCI(REG_VOL, regval);
+}
+
+void VS1011_set_bass(unsigned int regval){
+       VS1011_send_SCI(REG_BASS, regval);
+}
+
+void VS1011_set_reg(unsigned int reg, unsigned int regval){
+       VS1011_send_SCI(reg, regval);
+}
+
+/*
+int vs_test(void) {    
+       SPI_init_vs1011();
+       printk("%u\n", *R_GEN_CONFIG);
+       VS1001_init(_crystal_freq);
+       VS1001_print_registers();
+       VS1001_volume(0x30, 0x30); 
+       msDelay(1000);
+       VS1001_sine(1, 0x30);
+       msDelay(1000);
+       VS1001_sine(0, 0);
+       VS1001_send_zeros(0x20);
+       msDelay(1000);
+       VS1001_sine(1, 0x30);
+       msDelay(1000);
+       VS1001_sine(0, 0);
+       VS1001_send_zeros(0x20);
+       msDelay(1000);
+       VS1001_sine(1, 0x30);
+       msDelay(1000);
+       VS1001_sine(0, 0);
+       
+       AUDIO_DATA a;
+       VS1001_get_audio_data(&a);
+       printk("mp3_drv.ko : rate : %d, bit : %d, stereo : %d \n", a.sample_rate, a.bitrate, a.is_stereo);
+       VS1001_SW_reset(_crystal_freq);
+       return 0;
+}*/
+
This page took 0.026091 seconds and 4 git commands to generate.