00001
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <stddef.h>
00048 #include <string.h>
00049
00050 #include "compiler.h"
00051 #include "audio.h"
00052 #include "tlv320aic23b.h"
00053
00054 #include <avr32/io.h>
00055 #include "intc.h"
00056 #include "gpio.h"
00057 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_TWI
00058 #if AIC23B_TWI_ADDRESS != 0x1A && AIC23B_TWI_ADDRESS != 0x1B
00059 #error TLV320AIC23B: Invalid TWI address selected!
00060 #endif
00061 #include "twi.h"
00062 #elif AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
00063 #include "spi.h"
00064 #else
00065 #error TLV320AIC23B: Invalid control interface selected!
00066 #endif
00067 #include "ssc_i2s.h"
00068 #include "pdca.h"
00069
00070
00072 #define AIC23B_REG_COUNT (sizeof(aic23b_ctrl) / sizeof(aic23b_ctrl[0]))
00073
00075 #define AIC23B_CTRL_RESET \
00076 { \
00077 { \
00078 .addr = AIC23B_ADDRESS(AIC23B_LLICVC), \
00079 .data = AIC23B_DEFAULT(AIC23B_LLICVC) \
00080 }, \
00081 { \
00082 .addr = AIC23B_ADDRESS(AIC23B_RLICVC), \
00083 .data = AIC23B_DEFAULT(AIC23B_RLICVC) \
00084 }, \
00085 { \
00086 .addr = AIC23B_ADDRESS(AIC23B_LCHVC), \
00087 .data = AIC23B_DEFAULT(AIC23B_LCHVC) \
00088 }, \
00089 { \
00090 .addr = AIC23B_ADDRESS(AIC23B_RCHVC), \
00091 .data = AIC23B_DEFAULT(AIC23B_RCHVC) \
00092 }, \
00093 { \
00094 .addr = AIC23B_ADDRESS(AIC23B_AAPC), \
00095 .data = AIC23B_DEFAULT(AIC23B_AAPC) \
00096 }, \
00097 { \
00098 .addr = AIC23B_ADDRESS(AIC23B_DAPC), \
00099 .data = AIC23B_DEFAULT(AIC23B_DAPC) \
00100 }, \
00101 { \
00102 .addr = AIC23B_ADDRESS(AIC23B_PDC), \
00103 .data = AIC23B_DEFAULT(AIC23B_PDC) \
00104 }, \
00105 { \
00106 .addr = AIC23B_ADDRESS(AIC23B_DAIF), \
00107 .data = AIC23B_DEFAULT(AIC23B_DAIF) \
00108 }, \
00109 { \
00110 .addr = AIC23B_ADDRESS(AIC23B_SRC), \
00111 .data = AIC23B_DEFAULT(AIC23B_SRC) \
00112 }, \
00113 { \
00114 .addr = AIC23B_ADDRESS(AIC23B_DIA), \
00115 .data = AIC23B_DEFAULT(AIC23B_DIA) \
00116 }, \
00117 { \
00118 .addr = AIC23B_ADDRESS(AIC23B_RR), \
00119 .data = AIC23B_DEFAULT(AIC23B_RR) \
00120 } \
00121 }
00122
00123
00125 #if (AIC23B_MODE==AIC23B_MODE_CODEC)
00126 static const gpio_map_t AIC23B_SSC_CODEC_GPIO_MAP =
00127 {
00128 {AIC23B_SSC_TX_CLOCK_PIN, AIC23B_SSC_TX_CLOCK_FUNCTION },
00129 {AIC23B_SSC_TX_DATA_PIN, AIC23B_SSC_TX_DATA_FUNCTION },
00130 {AIC23B_SSC_TX_FRAME_SYNC_PIN, AIC23B_SSC_TX_FRAME_SYNC_FUNCTION },
00131 {AIC23B_SSC_RX_DATA_PIN, AIC23B_SSC_RX_DATA_FUNCTION },
00132 {AIC23B_SSC_RX_FRAME_SYNC_PIN, AIC23B_SSC_RX_FRAME_SYNC_FUNCTION }
00133 };
00134 #elif (AIC23B_MODE==AIC23B_MODE_ADC)
00135 static const gpio_map_t AIC23B_SSC_ADC_GPIO_MAP =
00136 {
00137 {AIC23B_SSC_TX_CLOCK_PIN, AIC23B_SSC_TX_CLOCK_FUNCTION },
00138 {AIC23B_SSC_RX_DATA_PIN, AIC23B_SSC_RX_DATA_FUNCTION },
00139 {AIC23B_SSC_RX_FRAME_SYNC_PIN, AIC23B_SSC_RX_FRAME_SYNC_FUNCTION }
00140 };
00141 #elif (AIC23B_MODE==AIC23B_MODE_DAC)
00142 static const gpio_map_t AIC23B_SSC_DAC_GPIO_MAP =
00143 {
00144 #if defined(AIC23B_DAC_USE_RX_CLOCK) && AIC23B_DAC_USE_RX_CLOCK == ENABLED
00145 {AVR32_SSC_RX_CLOCK_0_PIN, AVR32_SSC_RX_CLOCK_0_FUNCTION },
00146 #endif
00147 {AIC23B_SSC_TX_CLOCK_PIN, AIC23B_SSC_TX_CLOCK_FUNCTION },
00148 {AIC23B_SSC_TX_DATA_PIN, AIC23B_SSC_TX_DATA_FUNCTION },
00149 {AIC23B_SSC_TX_FRAME_SYNC_PIN, AIC23B_SSC_TX_FRAME_SYNC_FUNCTION }
00150 };
00151 #else
00152 #error No Mode defined in file 'conf_tlv320aic23b.h'
00153 #endif
00154
00156 static const aic23b_ctrl_t aic23b_ctrl_reset[] = AIC23B_CTRL_RESET;
00157
00159 static aic23b_ctrl_t aic23b_ctrl[] = AIC23B_CTRL_RESET;
00160
00162 static struct
00163 {
00164 U8 num_channels;
00165 void (*callback)(U32 arg);
00166 U32 callback_opt;
00167 } aic23b_output_params =
00168 {
00169 .num_channels = 0,
00170 .callback = NULL,
00171 .callback_opt = 0
00172 };
00173
00174
00177 #if (AIC23B_MODE==AIC23B_MODE_CODEC)||(AIC23B_MODE==AIC23B_MODE_DAC)
00178 #if (defined __GNUC__) && (defined __AVR32__)
00179 __attribute__((__interrupt__))
00180 #elif (defined __ICCAVR32__)
00181 __interrupt
00182 #endif
00183 static void aic23b_ssc_tx_pdca_int_handler(void)
00184 {
00185 if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00186 {
00187 pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
00188 if (aic23b_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00189 aic23b_output_params.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
00190 }
00191
00192 if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00193 {
00194 pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00195 if (aic23b_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
00196 aic23b_output_params.callback(AUDIO_DAC_RELOAD_CB);
00197 }
00198 }
00199 #endif
00200
00201
00204 #if (AIC23B_MODE==AIC23B_MODE_CODEC)||(AIC23B_MODE==AIC23B_MODE_ADC)
00205 #if (defined __GNUC__) && (defined __AVR32__)
00206 __attribute__((__interrupt__))
00207 #elif (defined __ICCAVR32__)
00208 __interrupt
00209 #endif
00210 static void aic23b_ssc_rx_pdca_int_handler(void)
00211 {
00212 if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00213 {
00214 pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
00215 if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB)
00216 aic23b_output_params.callback(AUDIO_ADC_OUT_OF_SAMPLE_CB);
00217 }
00218
00219 if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00220 {
00221 pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL);
00222 if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB)
00223 aic23b_output_params.callback(AUDIO_ADC_RELOAD_CB);
00224 }
00225 }
00226 #endif
00227
00230 static void aic23b_write_control_word(aic23b_ctrl_t ctrl)
00231 {
00232 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_TWI
00233 int twi_status;
00234 aic23b_ctrl_t my_ctrl = ctrl;
00235 twi_package_t twi_package =
00236 {
00237 .chip = AIC23B_TWI_ADDRESS,
00238 .addr_length = AVR32_TWI_MMR_IADRSZ_NO_ADDR,
00239 .buffer = &my_ctrl,
00240 .length = sizeof(my_ctrl)
00241 };
00242 do
00243 {
00244 twi_status=twi_master_write(AIC23B_TWI, &twi_package);
00245 }
00246 while( twi_status != TWI_SUCCESS );
00247 #elif AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
00248 spi_selectChip(AIC23B_SPI, AIC23B_SPI_NPCS);
00249 spi_write(AIC23B_SPI, *(U16 *)&ctrl);
00250 spi_unselectChip(AIC23B_SPI, AIC23B_SPI_NPCS);
00251 #endif
00252 }
00253
00254
00257
00258
00259 void aic23b_configure_freq(int master_clock_hz, int sample_rate_hz)
00260 {
00261 aic23b_src_t src;
00262
00263 src.data = AIC23B_DEFAULT(AIC23B_SRC);
00264 src.clkout = 0;
00265 src.clkin = 0;
00266
00267 switch (master_clock_hz)
00268 {
00269 case 12000000:
00270 src.usb = 1;
00271 if (sample_rate_hz < (8000 + 8021) / 2)
00272 {
00273 src.sr = 0x3;
00274 src.bosr = 0;
00275 }
00276 else if (sample_rate_hz < (8021 + 32000) / 2)
00277 {
00278 src.sr = 0xB;
00279 src.bosr = 1;
00280 }
00281 else if (sample_rate_hz < (32000 + 44100) / 2)
00282 {
00283 src.sr = 0x6;
00284 src.bosr = 0;
00285 }
00286 else if (sample_rate_hz < (44100 + 48000) / 2)
00287 {
00288 src.sr = 0x8;
00289 src.bosr = 1;
00290 }
00291 else if (sample_rate_hz < (48000 + 88200) / 2)
00292 {
00293 src.sr = 0x0;
00294 src.bosr = 0;
00295 }
00296 else if (sample_rate_hz < (88200 + 96000) / 2)
00297 {
00298 src.sr = 0xF;
00299 src.bosr = 1;
00300 }
00301 else
00302 {
00303 src.sr = 0x7;
00304 src.bosr = 0;
00305 }
00306 break;
00307 case 11289600:
00308 src.usb = 0;
00309 if (sample_rate_hz < (8021 + 22050) / 2)
00310 {
00311 src.sr = 0xB;
00312 src.bosr = 0;
00313 }
00314 else if (sample_rate_hz < (22050 + 88200) / 2)
00315 {
00316 src.sr = 0x8;
00317 src.bosr = 0;
00318 }
00319 else
00320 {
00321 src.sr = 0xF;
00322 src.bosr = 0;
00323 }
00324 break;
00325 case 18432000:
00326 src.usb = 0;
00327 src.sr = 0;
00328 src.bosr = 1;
00329 break;
00330 default:
00331
00332 return;
00333 }
00334
00335 aic23b_write_reg(AIC23B_SRC, src.data);
00336 }
00337
00338
00339
00340 U16 aic23b_read_reg(U8 reg)
00341 {
00342 if (reg >= AIC23B_REG_COUNT) return 0x0000;
00343 return aic23b_ctrl[reg].data;
00344 }
00345
00346
00347 void aic23b_write_reg(U8 reg, U16 val)
00348 {
00349 if (reg >= AIC23B_REG_COUNT) return;
00350 aic23b_ctrl[reg].data = val;
00351 if (reg == AIC23B_RR && aic23b_ctrl[reg].data == AIC23B_DEFAULT(AIC23B_RR))
00352 {
00353 memcpy(aic23b_ctrl, aic23b_ctrl_reset, sizeof(aic23b_ctrl));
00354 }
00355 aic23b_write_control_word(aic23b_ctrl[reg]);
00356 }
00357
00358
00360
00361
00364
00365
00366
00367 S8 aic23b_get_line_in_volume(U8 ch)
00368 {
00369 switch (ch)
00370 {
00371 case AIC23B_LEFT_CHANNEL:
00372 {
00373 aic23b_llicvc_t llicvc;
00374 llicvc.data = aic23b_read_reg(AIC23B_LLICVC);
00375 return (llicvc.lim) ?
00376 AIC23B_MUTED :
00377 llicvc.liv - AIC23B_LIN_VOL_OFFSET;
00378 }
00379 case AIC23B_RIGHT_CHANNEL:
00380 {
00381 aic23b_rlicvc_t rlicvc;
00382 rlicvc.data = aic23b_read_reg(AIC23B_RLICVC);
00383 return (rlicvc.rim) ?
00384 AIC23B_MUTED :
00385 rlicvc.riv - AIC23B_LIN_VOL_OFFSET;
00386 }
00387 default:
00388 return AIC23B_MUTED;
00389 }
00390 }
00391
00392
00393 void aic23b_set_line_in_volume(U8 ch_mask, S8 vol)
00394 {
00395 if (ch_mask & AIC23B_LEFT_CHANNEL)
00396 {
00397 aic23b_llicvc_t llicvc;
00398 llicvc.data = aic23b_read_reg(AIC23B_LLICVC);
00399 llicvc.lrs = ((ch_mask & AIC23B_RIGHT_CHANNEL) != 0);
00400 if (vol < AIC23B_LIN_VOL_MIN) llicvc.lim = 1;
00401 else
00402 {
00403 llicvc.lim = 0;
00404 llicvc.liv = min(vol, AIC23B_LIN_VOL_MAX) + AIC23B_LIN_VOL_OFFSET;
00405 }
00406 aic23b_write_reg(AIC23B_LLICVC, llicvc.data);
00407 }
00408 else if (ch_mask & AIC23B_RIGHT_CHANNEL)
00409 {
00410 aic23b_rlicvc_t rlicvc;
00411 rlicvc.data = aic23b_read_reg(AIC23B_RLICVC);
00412 rlicvc.rls = 0;
00413 if (vol < AIC23B_LIN_VOL_MIN) rlicvc.rim = 1;
00414 else
00415 {
00416 rlicvc.rim = 0;
00417 rlicvc.riv = min(vol, AIC23B_LIN_VOL_MAX) + AIC23B_LIN_VOL_OFFSET;
00418 }
00419 aic23b_write_reg(AIC23B_RLICVC, rlicvc.data);
00420 }
00421 }
00422
00423 U8 aic23b_dac_get_average_headphone_volume(void)
00424 {
00425 S32 volume, volume_avg = 0;
00426 aic23b_lchvc_t lchvc;
00427 aic23b_rchvc_t rchvc;
00428
00429 lchvc.data = aic23b_read_reg(AIC23B_LCHVC);
00430 rchvc.data = aic23b_read_reg(AIC23B_RCHVC);
00431 volume_avg = (lchvc.lhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00432 0 : lchvc.lhv - AIC23B_HP_VOL_OFFSET - AIC23B_HP_VOL_MIN;
00433 volume = (rchvc.rhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00434 0 : rchvc.rhv - AIC23B_HP_VOL_OFFSET - AIC23B_HP_VOL_MIN;
00435
00436 volume_avg = (volume_avg + volume) / 2;
00437
00438 volume_avg = (volume_avg * 255) / (AIC23B_HP_VOL_MAX - AIC23B_HP_VOL_MIN);
00439
00440 return (U8) volume_avg;
00441 }
00442
00443 void aic23b_dac_set_average_headphone_volume(U8 volume)
00444 {
00445 aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,volume,TRUE);
00446 }
00447
00448 Bool aic23b_dac_is_headphone_volume_muted(void)
00449 {
00450 return FALSE;
00451 }
00452
00453 Bool aic23b_dac_is_headphone_volume_boosted(void)
00454 {
00455 return FALSE;
00456 }
00457
00458 S8 aic23b_get_headphone_volume(U8 ch)
00459 {
00460 switch (ch)
00461 {
00462 case AIC23B_LEFT_CHANNEL:
00463 {
00464 aic23b_lchvc_t lchvc;
00465 lchvc.data = aic23b_read_reg(AIC23B_LCHVC);
00466 return (lchvc.lhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00467 AIC23B_MUTED :
00468 lchvc.lhv - AIC23B_HP_VOL_OFFSET;
00469 }
00470 case AIC23B_RIGHT_CHANNEL:
00471 {
00472 aic23b_rchvc_t rchvc;
00473 rchvc.data = aic23b_read_reg(AIC23B_RCHVC);
00474 return (rchvc.rhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00475 AIC23B_MUTED :
00476 rchvc.rhv - AIC23B_HP_VOL_OFFSET;
00477 }
00478 default:
00479 return AIC23B_MUTED;
00480 }
00481 }
00482
00483 void aic23b_set_headphone_volume(U8 ch_mask, S8 vol, Bool z_cross)
00484 {
00485 if (ch_mask & AIC23B_LEFT_CHANNEL)
00486 {
00487 aic23b_lchvc_t lchvc;
00488 lchvc.data = aic23b_read_reg(AIC23B_LCHVC);
00489 lchvc.lrs = ((ch_mask & AIC23B_RIGHT_CHANNEL) != 0);
00490 lchvc.lzc = z_cross;
00491 lchvc.lhv = (vol < AIC23B_HP_VOL_MIN) ?
00492 0 :
00493 min(vol, AIC23B_HP_VOL_MAX) + AIC23B_HP_VOL_OFFSET;
00494 aic23b_write_reg(AIC23B_LCHVC, lchvc.data);
00495 }
00496 if (ch_mask & AIC23B_RIGHT_CHANNEL)
00497 {
00498 aic23b_rchvc_t rchvc;
00499 rchvc.data = aic23b_read_reg(AIC23B_RCHVC);
00500 rchvc.rls = 0;
00501 rchvc.rzc = z_cross;
00502 rchvc.rhv = (vol < AIC23B_HP_VOL_MIN) ?
00503 0 :
00504 min(vol, AIC23B_HP_VOL_MAX) + AIC23B_HP_VOL_OFFSET;
00505 aic23b_write_reg(AIC23B_RCHVC, rchvc.data);
00506 }
00507 }
00508
00509
00510 aic23b_aapc_t aic23b_get_analog_audio_path(void)
00511 {
00512 aic23b_aapc_t aapc;
00513 aapc.data = aic23b_read_reg(AIC23B_AAPC);
00514 return aapc;
00515 }
00516
00517
00518 void aic23b_set_analog_audio_path(aic23b_aapc_t aapc)
00519 {
00520 aic23b_write_reg(AIC23B_AAPC, aapc.data);
00521 }
00522
00523
00524 aic23b_dapc_t aic23b_get_digital_audio_path(void)
00525 {
00526 aic23b_dapc_t dapc;
00527 dapc.data = aic23b_read_reg(AIC23B_DAPC);
00528 return dapc;
00529 }
00530
00531
00532 void aic23b_set_digital_audio_path(aic23b_dapc_t dapc)
00533 {
00534 aic23b_write_reg(AIC23B_DAPC, dapc.data);
00535 }
00536
00537
00538 aic23b_pdc_t aic23b_get_power_down_state(void)
00539 {
00540 aic23b_pdc_t pdc;
00541 pdc.data = aic23b_read_reg(AIC23B_PDC);
00542 return pdc;
00543 }
00544
00545
00546 void aic23b_set_power_down_state(aic23b_pdc_t pdc)
00547 {
00548 aic23b_write_reg(AIC23B_PDC, pdc.data);
00549 }
00550
00551
00552 Bool aic23b_is_dig_audio_activated(void)
00553 {
00554 aic23b_dia_t dia;
00555 dia.data = aic23b_read_reg(AIC23B_DIA);
00556 return dia.act;
00557 }
00558
00559
00560 void aic23b_activate_dig_audio(Bool act)
00561 {
00562 aic23b_dia_t dia;
00563 dia.data = aic23b_read_reg(AIC23B_DIA);
00564 dia.act = act;
00565 aic23b_write_reg(AIC23B_DIA, dia.data);
00566 }
00567
00568
00569 void aic23b_reset(void)
00570 {
00571 aic23b_rr_t rr;
00572 rr.data = aic23b_read_reg(AIC23B_RR);
00573 rr.res = AIC23B_DEFAULT(AIC23B_RR) >> AIC23B_OFFSET(AIC23B_RR, RES);
00574 aic23b_write_reg(AIC23B_RR, rr.data);
00575 }
00576
00577
00579
00580
00583
00584 #if (AIC23B_MODE==AIC23B_MODE_DAC)
00585 void aic23b_dac_start(U32 sample_rate_hz,
00586 U8 num_channels,
00587 U8 bits_per_sample,
00588 Bool swap_channels,
00589 void (*callback)(U32 arg),
00590 U32 callback_opt,
00591 U32 pba_hz)
00592 {
00593 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
00594 static const spi_options_t AIC23B_SPI_OPTIONS =
00595 {
00596 .reg = AIC23B_SPI_NPCS,
00597 .baudrate = AIC23B_SPI_MASTER_SPEED,
00598 .bits = AIC23B_CTRL_SIZE,
00599 .spck_delay = 0,
00600 .trans_delay = 0,
00601 .stay_act = 0,
00602 .spi_mode = 3,
00603 .modfdis = 1
00604 };
00605 spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
00606 #endif
00607
00608 aic23b_dac_stop();
00609
00610 gpio_enable_module(AIC23B_SSC_DAC_GPIO_MAP,
00611 sizeof(AIC23B_SSC_DAC_GPIO_MAP) / sizeof(AIC23B_SSC_DAC_GPIO_MAP[0]));
00612
00613 aic23b_pdc_t pdc;
00614 pdc.data = AIC23B_DEFAULT(AIC23B_PDC);
00615 pdc.off = 0;
00616 pdc.clk = 0;
00617 pdc.osc = 0;
00618 pdc.out = 0;
00619 pdc.dac = 0;
00620 pdc.adc = 1;
00621 pdc.mic = 1;
00622 pdc.line = 1;
00623 aic23b_set_power_down_state(pdc);
00624
00625 aic23b_dac_setup(sample_rate_hz,
00626 num_channels,
00627 bits_per_sample,
00628 swap_channels,
00629 callback,
00630 callback_opt,
00631 pba_hz);
00632
00633 aic23b_aapc_t aapc;
00634 aapc.data = AIC23B_DEFAULT(AIC23B_AAPC);
00635 aapc.ste = 0;
00636 aapc.dac = 1;
00637 aapc.byp = 0;
00638 aapc.micm = 1;
00639 aapc.micb = 0;
00640 aic23b_set_analog_audio_path(aapc);
00641
00642 aic23b_dapc_t dapc;
00643 dapc.data = AIC23B_DEFAULT(AIC23B_DAPC);
00644 dapc.dacm = 0;
00645 dapc.deemp = AIC23B_DAPC_DEEMP_NONE;
00646 dapc.adchp = 1;
00647 aic23b_set_digital_audio_path(dapc);
00648
00649
00650 aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
00651 -30,
00652 TRUE);
00653
00654 aic23b_activate_dig_audio(TRUE);
00655
00656 INTC_register_interrupt(&aic23b_ssc_tx_pdca_int_handler,
00657 AIC23B_SSC_TX_PDCA_IRQ,
00658 AIC23B_SSC_TX_PDCA_INT_LEVEL);
00659 }
00660
00661
00662 void aic23b_dac_setup(U32 sample_rate_hz,
00663 U8 num_channels,
00664 U8 bits_per_sample,
00665 Bool swap_channels,
00666 void (*callback)(U32 arg),
00667 U32 callback_opt,
00668 U32 pba_hz)
00669 {
00670 #if defined(AIC23B_DAC_USE_RX_CLOCK) && AIC23B_DAC_USE_RX_CLOCK == ENABLED
00671 #if defined(AIC23B_DAC_RX_CLOCK_SET_CALLBACK)
00672 AIC23B_DAC_RX_CLOCK_SET_CALLBACK(2 * sample_rate_hz *
00673 ((bits_per_sample <= 16) ? 16 :
00674 (bits_per_sample <= 20) ? 20 :
00675 (bits_per_sample <= 24) ? 24 :
00676 32));
00677 #endif
00678 ssc_i2s_init(AIC23B_SSC,
00679 sample_rate_hz,
00680 bits_per_sample,
00681 (bits_per_sample <= 16) ? 16 :
00682 (bits_per_sample <= 20) ? 20 :
00683 (bits_per_sample <= 24) ? 24 :
00684 32,
00685 SSC_I2S_MODE_STEREO_OUT_EXT_CLK,
00686 pba_hz);
00687 #else
00688 ssc_i2s_init(AIC23B_SSC,
00689 sample_rate_hz,
00690 bits_per_sample,
00691 (bits_per_sample <= 16) ? 16 :
00692 (bits_per_sample <= 20) ? 20 :
00693 (bits_per_sample <= 24) ? 24 :
00694 32,
00695 SSC_I2S_MODE_STEREO_OUT,
00696 pba_hz);
00697 #endif
00698
00699 pdca_channel_options_t aic23b_ssc_pdca_options =
00700 {
00701 .addr = NULL,
00702 .size = 0,
00703 .r_addr = NULL,
00704 .r_size = 0,
00705 .pid = AIC23B_SSC_TX_PDCA_PID,
00706 .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE :
00707 (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
00708 PDCA_TRANSFER_SIZE_WORD
00709 };
00710 pdca_init_channel(AIC23B_SSC_TX_PDCA_CHANNEL, &aic23b_ssc_pdca_options);
00711 pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);
00712
00713 #if !defined(AIC23B_DAC_USE_RX_CLOCK) || AIC23B_DAC_USE_RX_CLOCK == DISABLED || \
00714 !defined(AIC23B_DAC_RX_CLOCK_SET_CALLBACK)
00715
00716 aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz);
00717 #endif
00718
00719 aic23b_daif_t daif;
00720 daif.data = AIC23B_DEFAULT(AIC23B_DAIF);
00721 daif.ms = AIC23B_DAIF_MS_SLAVE;
00722 daif.lrswap = swap_channels;
00723 daif.lrp = 0;
00724 daif.iwl = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
00725 (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
00726 (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
00727 AIC23B_DAIF_IWL_32;
00728 daif.fmt = AIC23B_DAIF_FMT_I2S;
00729 aic23b_write_reg(AIC23B_DAIF, daif.data);
00730
00731 aic23b_output_params.num_channels = num_channels;
00732 aic23b_output_params.callback = callback;
00733 aic23b_output_params.callback_opt = callback_opt;
00734 }
00735 #endif
00736
00737 Bool aic23b_dac_output(void *sample_buffer, size_t sample_length)
00738 {
00739 Bool global_interrupt_enabled;
00740
00741 if (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
00742 PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
00743 return FALSE;
00744
00745 if (sample_length)
00746 {
00747 if (aic23b_output_params.num_channels == 1)
00748 {
00749 S16 *s16_sample_buffer = sample_buffer;
00750 int i;
00751
00752 for (i = sample_length - 1; i >= 0; i--)
00753 {
00754 s16_sample_buffer[2 * i + 1] =
00755 s16_sample_buffer[2 * i] = s16_sample_buffer[i];
00756 }
00757 }
00758
00759
00760
00761
00762 if ((global_interrupt_enabled = Is_global_interrupt_enabled()))
00763 Disable_global_interrupt();
00764 if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
00765 PDCA_TRANSFER_COMPLETE)
00766 {
00767 while (gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN));
00768 while (!gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN));
00769 }
00770 pdca_reload_channel(AIC23B_SSC_TX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
00771 pdca_get_reload_size(AIC23B_SSC_TX_PDCA_CHANNEL);
00772 if (global_interrupt_enabled)
00773 Enable_global_interrupt();
00774
00775 if (aic23b_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00776 pdca_enable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
00777 if (aic23b_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
00778 pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00779 }
00780 return TRUE;
00781 }
00782
00783
00784 void aic23b_dac_increase_volume(void)
00785 {
00786 S8 volume = aic23b_get_headphone_volume(AIC23B_LEFT_CHANNEL);
00787 if( volume < AIC23B_HP_VOL_MIN )
00788 volume = AIC23B_HP_VOL_MIN;
00789 aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
00790 volume + 1,
00791 TRUE);
00792 }
00793
00794
00795 void aic23b_dac_decrease_volume(void)
00796 {
00797 S8 volume = aic23b_get_headphone_volume(AIC23B_LEFT_CHANNEL);
00798 if( volume != AIC23B_MUTED )
00799 volume--;
00800 aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
00801 volume,
00802 TRUE);
00803 }
00804
00805 void aic23b_dac_mute(Bool mute)
00806 {
00807 #if (AIC23B_MODE==AIC23B_MODE_DAC)
00808
00809
00810
00811
00812
00813
00814
00815 if (mute)
00816 {
00817 U32 save_dac_reload_callback_opt;
00818
00819
00820 save_dac_reload_callback_opt = aic23b_output_params.callback_opt;
00821 aic23b_output_params.callback_opt = 0;
00822
00823 pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00824 while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
00825
00826 aic23b_output_params.callback_opt = save_dac_reload_callback_opt;
00827 }
00828 else
00829 {
00830
00831 pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00832 }
00833
00834 #endif
00835 }
00836
00837 #if (AIC23B_MODE==AIC23B_MODE_DAC)
00838 void aic23b_dac_flush(void)
00839 {
00840 pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
00841 pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00842
00843 while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
00844 PDCA_TRANSFER_COMPLETE));
00845 }
00846
00847
00848 void aic23b_dac_stop(void)
00849 {
00850 aic23b_dac_flush();
00851
00852
00853 aic23b_reset();
00854
00855 aic23b_pdc_t pdc;
00856 pdc.data = AIC23B_DEFAULT(AIC23B_PDC);
00857 pdc.off = 1;
00858 pdc.clk = 1;
00859 pdc.osc = 1;
00860 pdc.out = 1;
00861 pdc.dac = 1;
00862 pdc.adc = 1;
00863 pdc.mic = 1;
00864 pdc.line = 1;
00865 aic23b_set_power_down_state(pdc);
00866
00867
00868 pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL);
00869
00870 ssc_i2s_reset(AIC23B_SSC);
00871
00872
00873 gpio_enable_gpio(AIC23B_SSC_DAC_GPIO_MAP,
00874 sizeof(AIC23B_SSC_DAC_GPIO_MAP) / sizeof(AIC23B_SSC_DAC_GPIO_MAP[0]));
00875
00876 aic23b_output_params.num_channels = 0;
00877 aic23b_output_params.callback = NULL;
00878 aic23b_output_params.callback_opt = 0;
00879 }
00880 #endif
00881
00882 #if (AIC23B_MODE==AIC23B_MODE_ADC)
00883 void aic23b_adc_start(U32 sample_rate_hz,
00884 U8 num_channels,
00885 U8 bits_per_sample,
00886 Bool swap_channels,
00887 void (*callback)(U32 arg),
00888 U32 callback_opt,
00889 U32 pba_hz)
00890 {
00891 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
00892 static const spi_options_t AIC23B_SPI_OPTIONS =
00893 {
00894 .reg = AIC23B_SPI_NPCS,
00895 .baudrate = AIC23B_SPI_MASTER_SPEED,
00896 .bits = AIC23B_CTRL_SIZE,
00897 .spck_delay = 0,
00898 .trans_delay = 0,
00899 .stay_act = 0,
00900 .spi_mode = 3,
00901 .modfdis = 1
00902 };
00903 spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
00904 #endif
00905
00906 aic23b_adc_stop();
00907
00908 gpio_enable_module(AIC23B_SSC_ADC_GPIO_MAP,
00909 sizeof(AIC23B_SSC_ADC_GPIO_MAP) / sizeof(AIC23B_SSC_ADC_GPIO_MAP[0]));
00910
00911 aic23b_pdc_t pdc;
00912 pdc.data = AIC23B_DEFAULT(AIC23B_PDC);
00913 pdc.off = 0;
00914 pdc.clk = 0;
00915 pdc.osc = 0;
00916 pdc.out = 0;
00917 pdc.dac = 1;
00918 pdc.adc = 0;
00919 #if (AIC23B_INPUT==AIC23B_INPUT_LINE)
00920 pdc.mic = 1;
00921 pdc.line = 0;
00922 #elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
00923 pdc.mic = 0;
00924 pdc.line = 1;
00925 #else
00926 #error No Input defined in file 'conf_tlv320aic23b.h'
00927 #endif
00928 aic23b_set_power_down_state(pdc);
00929
00930 aic23b_adc_setup(sample_rate_hz,
00931 num_channels,
00932 bits_per_sample,
00933 swap_channels,
00934 callback,
00935 callback_opt,
00936 pba_hz);
00937
00938 aic23b_aapc_t aapc;
00939 aapc.data = AIC23B_DEFAULT(AIC23B_AAPC);
00940 #if (AIC23B_INPUT==AIC23B_INPUT_LINE)
00941 aapc.ste = 0;
00942 aapc.dac = 0;
00943 aapc.byp = 0;
00944 aapc.insel = 0;
00945 aapc.micm = 0;
00946 aapc.micb = 0;
00947 #elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
00948 aapc.ste = 0;
00949 aapc.dac = 0;
00950 aapc.byp = 0;
00951 aapc.insel = 1;
00952 aapc.micm = 0;
00953 aapc.micb = 0;
00954 #else
00955 #error No Input defined in file 'conf_tlv320aic23b.h'
00956 #endif
00957 aic23b_set_analog_audio_path(aapc);
00958
00959 aic23b_dapc_t dapc;
00960 dapc.data = AIC23B_DEFAULT(AIC23B_DAPC);
00961 dapc.dacm = 0;
00962 dapc.deemp = AIC23B_DAPC_DEEMP_NONE;
00963 dapc.adchp = 0;
00964 aic23b_set_digital_audio_path(dapc);
00965
00966
00967 aic23b_llicvc_t llivc;
00968 llivc.data = AIC23B_DEFAULT(AIC23B_LLICVC);
00969 llivc.liv = 20;
00970 llivc.lim = 0;
00971 llivc.lrs = 1;
00972 aic23b_write_reg(AIC23B_LLICVC, llivc.data);
00973
00974 aic23b_rlicvc_t rlivc;
00975 rlivc.data = AIC23B_DEFAULT(AIC23B_RLICVC);
00976 rlivc.riv = 20;
00977 rlivc.rim = 0;
00978 rlivc.rls = 1;
00979 aic23b_write_reg(AIC23B_RLICVC, rlivc.data);
00980
00981 INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler,
00982 AIC23B_SSC_RX_PDCA_IRQ,
00983 AIC23B_SSC_RX_PDCA_INT_LEVEL);
00984
00985 aic23b_activate_dig_audio(TRUE);
00986
00987 }
00988
00989 void aic23b_adc_setup(U32 sample_rate_hz,
00990 U8 num_channels,
00991 U8 bits_per_sample,
00992 Bool swap_channels,
00993 void (*callback)(U32 arg),
00994 callback_opt,
00995 U32 pba_hz)
00996 {
00997 ssc_i2s_init(AIC23B_SSC,
00998 sample_rate_hz,
00999 bits_per_sample,
01000 (bits_per_sample <= 16) ? 16 :
01001 (bits_per_sample <= 20) ? 20 :
01002 (bits_per_sample <= 24) ? 24 :
01003 32,
01004 SSC_I2S_MODE_STEREO_IN,
01005 pba_hz);
01006
01007 pdca_channel_options_t aic23b_ssc_pdca_options =
01008 {
01009 .addr = NULL,
01010 .size = 0,
01011 .r_addr = NULL,
01012 .r_size = 0,
01013 .pid = AIC23B_SSC_RX_PDCA_PID,
01014 .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE :
01015 (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
01016 PDCA_TRANSFER_SIZE_WORD
01017 };
01018 pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options);
01019 pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL);
01020
01021
01022 aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz);
01023
01024 aic23b_daif_t daif;
01025 daif.data = AIC23B_DEFAULT(AIC23B_DAIF);
01026 daif.ms = AIC23B_DAIF_MS_SLAVE;
01027 daif.lrswap = swap_channels;
01028 daif.lrp = 0;
01029 daif.iwl = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
01030 (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
01031 (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
01032 AIC23B_DAIF_IWL_32;
01033 daif.fmt = AIC23B_DAIF_FMT_I2S;
01034 aic23b_write_reg(AIC23B_DAIF, daif.data);
01035
01036 aic23b_output_params.num_channels = num_channels;
01037 aic23b_output_params.callback = callback;
01038 aic23b_output_params.callback_opt = callback_opt;
01039 }
01040
01041 void aic23b_adc_flush(void)
01042 {
01043 pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
01044
01045 while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
01046 PDCA_TRANSFER_COMPLETE));
01047 }
01048
01049
01050 void aic23b_adc_stop(void)
01051 {
01052 aic23b_adc_flush();
01053
01054 aic23b_reset();
01055
01056 aic23b_pdc_t pdc;
01057 pdc.data = AIC23B_DEFAULT(AIC23B_PDC);
01058 pdc.off = 1;
01059 pdc.clk = 1;
01060 pdc.osc = 1;
01061 pdc.out = 1;
01062 pdc.dac = 1;
01063 pdc.adc = 1;
01064 pdc.mic = 1;
01065 pdc.line = 1;
01066 aic23b_set_power_down_state(pdc);
01067
01068 pdca_disable(AIC23B_SSC_RX_PDCA_CHANNEL);
01069 ssc_i2s_reset(AIC23B_SSC);
01070
01071 gpio_enable_gpio(AIC23B_SSC_ADC_GPIO_MAP,
01072 sizeof(AIC23B_SSC_ADC_GPIO_MAP) / sizeof(AIC23B_SSC_ADC_GPIO_MAP[0]));
01073
01074 aic23b_output_params.num_channels = 0;
01075 aic23b_output_params.callback = NULL;
01076 aic23b_output_params.callback_opt = 0;
01077 }
01078 #endif
01079
01080 #if (AIC23B_MODE==AIC23B_MODE_ADC)||(AIC23B_MODE==AIC23B_MODE_CODEC)
01081 Bool aic23b_adc_input(void *sample_buffer, size_t sample_length)
01082 {
01083 if (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
01084 PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
01085 return FALSE;
01086
01087 if (sample_length)
01088 {
01089 pdca_reload_channel(AIC23B_SSC_RX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
01090 pdca_get_reload_size(AIC23B_SSC_RX_PDCA_CHANNEL);
01091
01092 if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB)
01093 pdca_enable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
01094 if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB)
01095 pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL);
01096 }
01097
01098 return TRUE;
01099 }
01100 #endif
01101
01102 #if (AIC23B_MODE==AIC23B_MODE_CODEC)
01103 void aic23b_codec_start(U32 sample_rate_hz,
01104 U8 num_channels,
01105 U8 bits_per_sample,
01106 Bool swap_channels,
01107 void (*callback)(U32 arg),
01108 U32 callback_opt,
01109 U32 pba_hz)
01110 {
01111 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
01112 static const spi_options_t AIC23B_SPI_OPTIONS =
01113 {
01114 .reg = AIC23B_SPI_NPCS,
01115 .baudrate = AIC23B_SPI_MASTER_SPEED,
01116 .bits = AIC23B_CTRL_SIZE,
01117 .spck_delay = 0,
01118 .trans_delay = 0,
01119 .stay_act = 0,
01120 .spi_mode = 3,
01121 .modfdis = 1
01122 };
01123 spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
01124 #endif
01125
01126 aic23b_codec_stop();
01127
01128 gpio_enable_module(AIC23B_SSC_CODEC_GPIO_MAP,
01129 sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0]));
01130
01131 aic23b_pdc_t pdc;
01132 pdc.data = AIC23B_DEFAULT(AIC23B_PDC);
01133 pdc.off = 0;
01134 pdc.clk = 0;
01135 pdc.osc = 0;
01136 pdc.out = 0;
01137 pdc.dac = 0;
01138 pdc.adc = 0;
01139 #if (AIC23B_INPUT==AIC23B_INPUT_LINE)
01140 pdc.mic = 1;
01141 pdc.line = 0;
01142 #elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
01143 pdc.mic = 0;
01144 pdc.line = 1;
01145 #else
01146 #error No Input defined in file 'conf_tlv320aic23b.h'
01147 #endif
01148 aic23b_set_power_down_state(pdc);
01149
01150 aic23b_codec_setup(sample_rate_hz,
01151 num_channels,
01152 bits_per_sample,
01153 swap_channels,
01154 callback,
01155 callback_opt,
01156 pba_hz);
01157
01158 aic23b_aapc_t aapc;
01159 aapc.data = AIC23B_DEFAULT(AIC23B_AAPC);
01160 #if (AIC23B_INPUT==AIC23B_INPUT_LINE)
01161 aapc.ste = 0;
01162 aapc.dac = 1;
01163 aapc.byp = 0;
01164 aapc.insel = 0;
01165 aapc.micm = 0;
01166 aapc.micb = 1;
01167 #elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
01168 aapc.ste = 0;
01169 aapc.dac = 1;
01170 aapc.sta = 4;
01171 aapc.byp = 0;
01172 aapc.insel = 1;
01173 aapc.micm = 0;
01174 aapc.micb = 1;
01175 #else
01176 #error No Input defined in file 'conf_tlv320aic23b.h'
01177 #endif
01178 aic23b_set_analog_audio_path(aapc);
01179
01180 aic23b_dapc_t dapc;
01181 dapc.data = AIC23B_DEFAULT(AIC23B_DAPC);
01182 dapc.dacm = 0;
01183 dapc.deemp = AIC23B_DAPC_DEEMP_NONE;
01184 dapc.adchp = 0;
01185 aic23b_set_digital_audio_path(dapc);
01186
01187
01188 aic23b_llicvc_t llivc;
01189 llivc.data = AIC23B_DEFAULT(AIC23B_LLICVC);
01190 llivc.liv = 20;
01191 llivc.lim = 0;
01192 llivc.lrs = 1;
01193 aic23b_write_reg(AIC23B_LLICVC, llivc.data);
01194
01195 aic23b_rlicvc_t rlivc;
01196 rlivc.data = AIC23B_DEFAULT(AIC23B_RLICVC);
01197 rlivc.riv = 20;
01198 rlivc.rim = 0;
01199 rlivc.rls = 1;
01200 aic23b_write_reg(AIC23B_RLICVC, rlivc.data);
01201
01202 INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler,
01203 AIC23B_SSC_RX_PDCA_IRQ,
01204 AIC23B_SSC_RX_PDCA_INT_LEVEL);
01205
01206
01207 aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
01208 -30,
01209 TRUE);
01210
01211 aic23b_activate_dig_audio(TRUE);
01212
01213 INTC_register_interrupt(&aic23b_ssc_tx_pdca_int_handler,
01214 AIC23B_SSC_TX_PDCA_IRQ,
01215 AIC23B_SSC_TX_PDCA_INT_LEVEL);
01216 }
01217
01218 void aic23b_codec_setup(U32 sample_rate_hz,
01219 U8 num_channels,
01220 U8 bits_per_sample,
01221 Bool swap_channels,
01222 void (*callback)(U32 opt),
01223 U32 callback_opt,
01224 U32 pba_hz)
01225 {
01226 ssc_i2s_init(AIC23B_SSC,
01227 sample_rate_hz,
01228 bits_per_sample,
01229 (bits_per_sample <= 16) ? 16 :
01230 (bits_per_sample <= 20) ? 20 :
01231 (bits_per_sample <= 24) ? 24 :
01232 32,
01233 SSC_I2S_MODE_STEREO_OUT_STEREO_IN,
01234 pba_hz);
01235
01236 pdca_channel_options_t aic23b_ssc_pdca_options_rx =
01237 {
01238 .addr = NULL,
01239 .size = 0,
01240 .r_addr = NULL,
01241 .r_size = 0,
01242 .pid = AIC23B_SSC_RX_PDCA_PID,
01243 .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE :
01244 (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
01245 PDCA_TRANSFER_SIZE_WORD
01246
01247 };
01248 pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_rx);
01249 pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL);
01250
01251 pdca_channel_options_t aic23b_ssc_pdca_options_tx =
01252 {
01253 .addr = NULL,
01254 .size = 0,
01255 .r_addr = NULL,
01256 .r_size = 0,
01257 .pid = AIC23B_SSC_TX_PDCA_PID,
01258 .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE :
01259 (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
01260 PDCA_TRANSFER_SIZE_WORD
01261 };
01262 pdca_init_channel(AIC23B_SSC_TX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_tx);
01263 pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);
01264
01265
01266 aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz);
01267
01268 aic23b_daif_t daif;
01269 daif.data = AIC23B_DEFAULT(AIC23B_DAIF);
01270 daif.ms = AIC23B_DAIF_MS_SLAVE;
01271 daif.lrswap = swap_channels;
01272 daif.lrp = 0;
01273 daif.iwl = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
01274 (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
01275 (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
01276 AIC23B_DAIF_IWL_32;
01277 daif.fmt = AIC23B_DAIF_FMT_I2S;
01278 aic23b_write_reg(AIC23B_DAIF, daif.data);
01279
01280 aic23b_output_params.num_channels = num_channels;
01281 aic23b_output_params.callback = callback;
01282 aic23b_output_params.callback_opt = callback_opt;
01283 }
01284
01285 void aic23b_codec_flush(void)
01286 {
01287 pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
01288 while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
01289 PDCA_TRANSFER_COMPLETE));
01290 pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
01291 while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
01292 PDCA_TRANSFER_COMPLETE));
01293 }
01294
01295 void aic23b_codec_stop(void)
01296 {
01297 aic23b_codec_flush();
01298
01299 aic23b_reset();
01300
01301 aic23b_pdc_t pdc;
01302 pdc.data = AIC23B_DEFAULT(AIC23B_PDC);
01303 pdc.off = 1;
01304 pdc.clk = 1;
01305 pdc.osc = 1;
01306 pdc.out = 1;
01307 pdc.dac = 1;
01308 pdc.adc = 1;
01309 pdc.mic = 1;
01310 pdc.line = 1;
01311 aic23b_set_power_down_state(pdc);
01312
01313 pdca_disable(AIC23B_SSC_RX_PDCA_CHANNEL);
01314 pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL);
01315
01316 ssc_i2s_reset(AIC23B_SSC);
01317
01318 gpio_enable_gpio(AIC23B_SSC_CODEC_GPIO_MAP,
01319 sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0]));
01320
01321 aic23b_output_params.num_channels = 0;
01322 aic23b_output_params.callback = NULL;
01323 aic23b_output_params.callback_opt = 0;
01324 }
01325 #endif
01326