00001
00044 #include <cfg/os.h>
00045 #include <cfg/clock.h>
00046 #include <dev/board.h>
00047 #include <dev/irqreg.h>
00048 #include <dev/twif.h>
00049
00050 #include <stdlib.h>
00051 #include <string.h>
00052
00053 #include <sys/event.h>
00054 #include <sys/timer.h>
00055
00056 #include "tlv320dac.h"
00057
00058 #include <stdio.h>
00059
00060 #ifndef TWI_SLA_DAC
00061 #define TWI_SLA_DAC 0x1A
00062 #endif
00063
00064
00065
00066
00067 #ifndef TLV320DAC_VOL
00068 #define TLV320DAC_VOL 0x18
00069 #endif
00070
00071
00072
00073
00074 #ifndef SAMPLE_BUFFERS
00075 #if defined (AT91SAM9260_EK)
00076 #define SAMPLE_BUFFERS 32
00077 #else
00078 #define SAMPLE_BUFFERS 3
00079 #endif
00080 #endif
00081
00082
00083
00084
00085 #if defined(AT91SAM7X_EK)
00086
00087 #define DACI2S_PIO_ID PIOA_ID
00088 #define DACI2S_PINS_A _BV(PA23_TD_A) | _BV(PA21_TF_A) | _BV(PA22_TK_A)
00089 #define DACI2S_PINS_B 0
00090
00091 #elif defined (AT91SAM9260_EK)
00092
00093 #define DACI2S_PIO_ID PIOB_ID
00094 #define DACI2S_PINS_A _BV(PB18_TD0_A) | _BV(PB17_TF0_A) | _BV(PB16_TK0_A)
00095 #define DACI2S_PINS_B 0
00096
00097 #else
00098 #warning "Unknown target board"
00099 #endif
00100
00101
00102
00103
00104 #if DACI2S_PIO_ID == PIOA_ID
00105 #define DACI2S_PDR PIOA_PDR
00106 #define DACI2S_ASR PIOA_ASR
00107 #define DACI2S_BSR PIOA_BSR
00108 #elif DACI2S_PIO_ID == PIOB_ID
00109 #define DACI2S_PDR PIOB_PDR
00110 #define DACI2S_ASR PIOB_ASR
00111 #define DACI2S_BSR PIOB_BSR
00112 #endif
00113
00117 static HANDLE i2s_que;
00118
00122 #define PCM_CHANS 2
00123
00127 #define PCM_BITS 16
00128
00132 typedef struct _PCM_BUFFER {
00133 u_short *wbf_dat;
00134 int wbf_siz;
00135 int wbf_len;
00136 } PCM_BUFFER;
00137
00138
00139 static PCM_BUFFER pcm_bufq[SAMPLE_BUFFERS];
00140
00141 static volatile u_int brd_idx;
00142
00143 static u_int bwr_idx;
00144
00150 static void I2sPdcFill(void)
00151 {
00152 if (brd_idx != bwr_idx) {
00153 if (inr(SSC_TNCR) == 0) {
00154 if (++brd_idx >= SAMPLE_BUFFERS) {
00155 brd_idx = 0;
00156 }
00157 outr(SSC_TNPR, (u_int) pcm_bufq[brd_idx].wbf_dat);
00158 outr(SSC_TNCR, pcm_bufq[brd_idx].wbf_len);
00159 }
00160 }
00161 }
00162
00168 static void I2sInterrupt(void *arg)
00169 {
00170 I2sPdcFill();
00171 NutEventPostFromIrq(&i2s_que);
00172 }
00173
00183 u_char Tlv320DacReadReg(u_int reg)
00184 {
00185 return 0xFF;
00186 }
00187
00196 void Tlv320DacWriteReg(u_int reg, u_int val)
00197 {
00198 u_char txdata[2];
00199
00200 txdata[0] = (u_char)(reg << 1) | (u_char)(val >> 8);
00201 txdata[1] = (u_char)val;
00202 TwMasterTransact(TWI_SLA_DAC, txdata, 2, NULL, 0, 0);
00203 }
00204
00212 static int Tlv320I2sEnable(u_int rate)
00213 {
00214
00215 outr(PMC_PCER, _BV(SSC_ID));
00216
00217
00218 outr(DACI2S_ASR, DACI2S_PINS_A);
00219 outr(DACI2S_BSR, DACI2S_PINS_B);
00220
00221
00222 outr(DACI2S_PDR, DACI2S_PINS_A | DACI2S_PINS_B);
00223
00224
00225 outr(SSC_CMR, 0);
00226 outr(SSC_TCMR,
00227 SSC_CKS_TK |
00228 SSC_START_EDGE_RF |
00229 (1 << SSC_STTDLY_LSB));
00230 outr(SSC_TFMR,
00231 ((PCM_BITS - 1) << SSC_DATLEN_LSB) |
00232 SSC_MSBF);
00233
00234
00235 outr(SSC_PTCR, PDC_TXTEN);
00236 outr(SSC_CR, SSC_TXEN);
00237
00238 return 0;
00239 }
00240
00246 static int Tlv320I2sDisable(void)
00247 {
00248
00249 outr(SSC_IDR, 0xFFFFFFFF);
00250
00251
00252 NutIrqDisable(&sig_SSC);
00253
00254
00255 outr(PMC_PCDR, _BV(SSC_ID));
00256
00257
00258 outr(SSC_CR, SSC_SWRST | SSC_RXDIS | SSC_TXDIS);
00259 outr(SSC_RCMR, 0);
00260 outr(SSC_RFMR, 0);
00261 outr(SSC_PTCR, PDC_RXTDIS);
00262 outr(SSC_PTCR, PDC_TXTDIS);
00263 outr(SSC_TNCR, 0);
00264 outr(SSC_TCR, 0);
00265
00266 return 0;
00267 }
00268
00276 static int Tlv320I2sInit(u_int rate)
00277 {
00278
00279 NutRegisterIrqHandler(&sig_SSC, I2sInterrupt, 0);
00280
00281 Tlv320I2sDisable();
00282 Tlv320I2sEnable(rate);
00283
00284
00285 NutIrqEnable(&sig_SSC);
00286
00287 return 0;
00288 }
00289
00290 int Tlv320DacSetRate(u_int rate)
00291 {
00292 switch(rate) {
00293 case 8000:
00294 #ifdef AT91SAM7X_EK
00295 Tlv320DacWriteReg(DAC_SRATE, (3 << DAC_SRATE_SR_LSB));
00296 #else
00297 Tlv320DacWriteReg(DAC_SRATE, (3 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00298 #endif
00299 break;
00300 case 8021:
00301 Tlv320DacWriteReg(DAC_SRATE, (11 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00302 break;
00303 case 44100:
00304 Tlv320DacWriteReg(DAC_SRATE, (8 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00305 break;
00306 case 48000:
00307 Tlv320DacWriteReg(DAC_SRATE, (0 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00308 break;
00309 case 88200:
00310 Tlv320DacWriteReg(DAC_SRATE, (15 << DAC_SRATE_SR_LSB) | DAC_SRATE_BOSR | DAC_SRATE_USB);
00311 break;
00312 case 96000:
00313 Tlv320DacWriteReg(DAC_SRATE, (7 << DAC_SRATE_SR_LSB) | DAC_SRATE_USB);
00314 break;
00315 default:
00316 return -1;
00317 }
00318 return 0;
00319 }
00320
00328 int Tlv320DacInit(u_int rate)
00329 {
00330
00331 TwInit(0);
00332
00333 Tlv320DacWriteReg(DAC_RESET, 0);
00334
00335 Tlv320DacWriteReg(DAC_PWRDN, DAC_PWRDN_LINE);
00336 Tlv320DacWriteReg(DAC_PWRDN, 0);
00337
00338 if (Tlv320DacSetRate(rate)) {
00339 Tlv320DacWriteReg(DAC_RESET, 0);
00340 return -1;
00341 }
00342 Tlv320DacWriteReg(DAC_ANA_PATH, DAC_ANA_PATH_DAC | DAC_ANA_PATH_INSEL | DAC_ANA_PATH_MICB);
00343 Tlv320DacWriteReg(DAC_DIG_PATH, 0);
00344
00345 Tlv320DacWriteReg(DAC_DAI_FMT, DAC_DAI_FMT_MS | DAC_DAI_FMT_FOR_I2S);
00346 Tlv320DacWriteReg(DAC_DI_ACT, DAC_DI_ACT_ACT);
00347
00348 Tlv320DacWriteReg(DAC_LHP_VOL, DAC_LHP_VOL_LRS | (0x60 << DAC_LHP_VOL_LHV_LSB));
00349
00350
00351 return Tlv320I2sInit(rate);
00352 }
00353
00359 static int Tlv320DacStart(void)
00360 {
00361 NutIrqDisable(&sig_SSC);
00362 I2sPdcFill();
00363 outr(SSC_IER, SSC_ENDTX);
00364 outr(SSC_CR, SSC_TXEN);
00365 NutIrqEnable(&sig_SSC);
00366
00367 return 0;
00368 }
00369
00375 int Tlv320DacFlush(void)
00376 {
00377 int rc = 0;
00378
00379 while (bwr_idx != brd_idx) {
00380 Tlv320DacStart();
00381 if ((rc = NutEventWait(&i2s_que, 500)) != 0) {
00382 break;
00383 }
00384 }
00385 return rc;
00386 }
00387
00396 int Tlv320DacWrite(void *buf, int len)
00397 {
00398 u_int idx;
00399
00400
00401 idx = bwr_idx + 1;
00402 if (idx >= SAMPLE_BUFFERS) {
00403 idx = 0;
00404 }
00405
00406
00407
00408 while (idx == brd_idx) {
00409 if (NutEventWait(&i2s_que, 100)) {
00410 Tlv320DacStart();
00411 }
00412 }
00413
00414
00415
00416
00417 if (pcm_bufq[idx].wbf_siz < len) {
00418 if (pcm_bufq[idx].wbf_siz) {
00419 free(pcm_bufq[idx].wbf_dat);
00420 pcm_bufq[idx].wbf_siz = 0;
00421 }
00422 pcm_bufq[idx].wbf_dat = malloc(len * 2);
00423 if (pcm_bufq[idx].wbf_dat == NULL) {
00424
00425 return -1;
00426 }
00427 pcm_bufq[idx].wbf_siz = len;
00428 }
00429
00430
00431
00432
00433
00434
00435 memcpy(pcm_bufq[idx].wbf_dat, buf, len * 2);
00436 pcm_bufq[idx].wbf_len = len;
00437 bwr_idx = idx;
00438
00439 return 0;
00440 }
00441
00452 int Tlv320DacSetVolume(int left, int right)
00453 {
00454
00455 if (left > DAC_MAX_VOLUME) {
00456 left = DAC_MAX_VOLUME;
00457 }
00458 else if (left < DAC_MIN_VOLUME) {
00459 left = DAC_MIN_VOLUME;
00460 }
00461 if (right > DAC_MAX_VOLUME) {
00462 right = DAC_MAX_VOLUME;
00463 }
00464 else if (right < DAC_MIN_VOLUME) {
00465 right = DAC_MIN_VOLUME;
00466 }
00467 Tlv320DacWriteReg(DAC_LHP_VOL, (u_int)(left + 121));
00468 Tlv320DacWriteReg(DAC_RHP_VOL, (u_int)(right + 121));
00469
00470 return 0;
00471 }