00001
00015
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 #include "pdca.h"
00047 #include "abdac.h"
00048 #include "gpio.h"
00049 #include "intc.h"
00050 #include "board.h"
00051 #include "tpa6130.h"
00052 #include "conf_tpa6130.h"
00053 #include "audio.h"
00054
00055 #include "cs2200.h"
00056
00057 #include "twi.h"
00058
00059 #include "conf_audio_player.h"
00060
00061
00062
00063
00064 #define TPA6130_CONTROL 0x1
00065 #define TPA6130_VOLUME_AND_MUTE 0x2
00066 #define TPA6130_OUTPUT_IMPEDANCE 0x3
00067 #define TPA6130_I2C_ADDRESS_VERSION 0x4
00068
00069
00070 #define TPA6130_CONTROL_DEFAULT 0x00
00071
00072 #define TPA6130_VOLUME_AND_MUTE_DEFAULT 0x0F
00073 #define TPA6130_OUTPUT_IMPEDANCE_DEFAULT 0x00
00074 #define TPA6130_I2C_ADDRESS_VERSION_DEFAULT 0x02
00075
00076
00077 #define HP_EN_L 0x80
00078 #define HP_EN_R 0x40
00079 #define STEREO_HP 0x00
00080 #define DUAL_MONO_HP 0x10
00081 #define BRIDGE_TIED_LOAD 0x20
00082 #define SW_SHUTDOWN 0x01
00083 #define THERMAL 0x02
00084
00085 #define MUTE_L 0x80
00086 #define MUTE_R 0x40
00087
00088 #define HIZ_L 0x80
00089 #define HIZ_R 0x40
00090
00091 #define VERSION 0x02
00092
00093
00094
00095
00096 #define TPA6130_MAX_VOLUME 0x3F
00097
00098
00099
00100 #define TWI_READ_HW 0
00101
00102 #define TWI_READ_SR 1
00103
00104
00105
00106
00107
00108
00109 #if(TPA6130_MODE == TPA6130_MODE_STEREO)
00110 #if(TPA6130_SIG == TPA6130_SIG_DIFF)
00111 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00112 {
00113 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00114 {TPA6130_DATA1_PIN, TPA6130_DATA1_FUNCTION},
00115 {TPA6130_DATAN0_PIN, TPA6130_DATAN0_FUNCTION},
00116 {TPA6130_DATAN1_PIN, TPA6130_DATAN1_FUNCTION}
00117 };
00118 #elif(TPA6130_SIG == TPA6130_SIG_POS)
00119 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00120 {
00121 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00122 {TPA6130_DATA1_PIN, TPA6130_DATA1_FUNCTION}
00123 };
00124 #else
00125 #error No valid TPA6130_SIG is defined
00126 #endif
00127 #elif((TPA6130_MODE == TPA6130_MODE_MONO)
00128 #if(TPA6130_SIG == TPA6130_SIG_DIFF)
00129 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00130 {
00131 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00132 {TPA6130_DATAN0_PIN, TPA6130_DATAN0_FUNCTION}
00133 };
00134 #elif(TPA6130_SIG == TPA6130_SIG_POS)
00135 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00136 {
00137 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION}
00138 };
00139 #else
00140 #error No valid TPA6130_SIG is defined
00141 #endif
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 #else
00160 #error No output mode defined in configuration setup
00161 #endif
00162
00163
00164
00165 static struct
00166 {
00167 U8 num_channels;
00168 void (*callback)(U32 arg);
00169 U32 callback_opt;
00170 } tpa6130_output_param =
00171 {
00172 .num_channels = 0,
00173 .callback = NULL,
00174 .callback_opt = 0,
00175 };
00176
00178 extern U32 usb_stream_resync_frequency;
00179 volatile avr32_pm_t *pm = &AVR32_PM;
00180
00183 static struct
00184 {
00185 U8 control;
00186 U8 volume_and_mute;
00187 U8 output_impedance;
00188 U8 i2c_address_version;
00189 } tpa6130_shadow_regs =
00190 {
00191 .control = TPA6130_CONTROL_DEFAULT,
00192 .volume_and_mute = TPA6130_VOLUME_AND_MUTE_DEFAULT,
00193 .output_impedance = TPA6130_OUTPUT_IMPEDANCE_DEFAULT,
00194 .i2c_address_version = TPA6130_I2C_ADDRESS_VERSION_DEFAULT,
00195 };
00196
00197 #if (defined __GNUC__) && (defined __AVR32__)
00198 __attribute__((__interrupt__))
00199 #elif (defined __ICCAVR32__)
00200 __interrupt
00201 #endif
00202 static void tpa6130_abdac_tx_pdca_int_handler(void)
00203 {
00204 if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00205 {
00206 pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00207 if (tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00208 tpa6130_output_param.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
00209 }
00210
00211 if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00212 {
00213 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00214 if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
00215 tpa6130_output_param.callback(AUDIO_DAC_RELOAD_CB);
00216 }
00217 }
00218
00224 static void tpa6130_write_data(U8 reg, U8 data)
00225 {
00226 U16 message = (reg << 8) | data;
00227 int twi_status;
00228
00229 twi_package_t twi_package =
00230 {
00231 .chip = TPA6130_TWI_ADDRESS,
00232 .addr_length = 0,
00233 .buffer = &message,
00234 .length = sizeof(message)
00235 };
00236
00237 do
00238 {
00239 twi_status=twi_master_write(TPA6130_TWI, &twi_package);
00240 }
00241 while( twi_status != TWI_SUCCESS );
00242
00243
00244 *(((U8 *) &tpa6130_shadow_regs) + reg - 1) = data;
00245 }
00246
00254 static U8 tpa6130_read_data(U8 reg, Bool shadow)
00255 {
00256 U8 data;
00257
00258 if(shadow)
00259 {
00260 data = *((U8 *) &tpa6130_shadow_regs + reg - 1);
00261 }
00262 else
00263 {
00264 twi_package_t twi_package =
00265 {
00266 .chip = TPA6130_TWI_ADDRESS,
00267 .addr_length = 1,
00268 .addr = reg,
00269 .buffer = &data,
00270 .length = sizeof(data)
00271 };
00272 twi_master_read(TPA6130_TWI, &twi_package);
00273 }
00274
00275
00276
00277
00278
00279
00280 return data;
00281 }
00282
00293 S8 tpa6130_init(void)
00294 {
00295
00296 if(twi_probe(TPA6130_TWI, TPA6130_TWI_ADDRESS) != TWI_SUCCESS)
00297 return TWI_NO_CHIP_FOUND;
00298
00299 if(tpa6130_read_data(TPA6130_I2C_ADDRESS_VERSION, TWI_READ_HW)!= VERSION)
00300 {
00301 return -8;
00302 }
00303
00304
00305 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, tpa6130_shadow_regs.volume_and_mute);
00306
00307 tpa6130_write_data(TPA6130_CONTROL,(TPA6130_MODE << 4) | HP_EN_L | HP_EN_R);
00308
00309 return TWI_SUCCESS;
00310 }
00311
00315 void tpa6130_shutdown(void)
00316 {
00317 U8 data;
00318 data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
00319 tpa6130_write_data(TPA6130_CONTROL, data | SW_SHUTDOWN);
00320 }
00323 void tpa6130_powerup(void)
00324 {
00325 U8 data;
00326 data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
00327 tpa6130_write_data(TPA6130_CONTROL, data & (~SW_SHUTDOWN));
00328 }
00336 void tpa6130_set_volume(S8 volume)
00337 {
00338 S8 new_volume = volume;
00339
00340 if(volume > TPA6130_VOL_MAX)
00341 {
00342 new_volume = TPA6130_VOL_MAX;
00343 }
00344 else if(volume <= TPA6130_VOL_MIN )
00345 {
00346
00347 new_volume = MUTE_L|MUTE_R;
00348 }
00349
00350 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, new_volume );
00351 }
00352
00357 S8 tpa6130_get_volume(void)
00358 {
00359 return tpa6130_read_data(TPA6130_VOLUME_AND_MUTE, TWI_READ_SR);
00360 }
00361
00371 void tpa6130_dac_start(U32 sample_rate_hz,
00372 U8 num_channels,
00373 U8 bits_per_sample,
00374 Bool swap_channels,
00375 void (*callback)(U32 arg),
00376 U32 callback_opt,
00377 U32 pba_hz)
00378 {
00379
00380 tpa6130_dac_stop();
00381
00382
00383 gpio_enable_module(TPA6130_ABDAC_GPIO_MAP,
00384 sizeof(TPA6130_ABDAC_GPIO_MAP) /
00385 sizeof(TPA6130_ABDAC_GPIO_MAP[0]));
00386
00387
00388 tpa6130_dac_setup(sample_rate_hz,
00389 num_channels,
00390 bits_per_sample,
00391 swap_channels,
00392 callback,
00393 callback_opt,
00394 pba_hz);
00395
00396
00397
00398
00399 INTC_register_interrupt(&tpa6130_abdac_tx_pdca_int_handler,
00400 TPA6130_ABDAC_PDCA_IRQ,
00401 TPA6130_ABDAC_PDCA_INT_LEVEL);
00402
00403 tpa6130_powerup();
00404
00405 }
00406
00411 void tpa6130_dac_setup(U32 sample_rate_hz,
00412 U8 num_channels,
00413 U8 bits_per_sample,
00414 Bool swap_channels,
00415 void (*callback)(U32 arg),
00416 U32 callback_opt,
00417 U32 pba_hz)
00418 {
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 if (sample_rate_hz < (8000 + 8021) / 2)
00430 {
00431 }
00432 else if (sample_rate_hz < (8021 + 32000) / 2)
00433 {
00434 }
00435 else if (sample_rate_hz < (32000 + 44100) / 2)
00436 {
00437 usb_stream_resync_frequency = 8192000;
00438 cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency));
00439 pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(8192000);
00440 }
00441 else if (sample_rate_hz < (44100 + 48000) / 2)
00442 {
00443 usb_stream_resync_frequency = 11289600;
00444 cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency));
00445 pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(11289600);
00446 }
00447 else if (sample_rate_hz < (48000 + 88200) / 2)
00448 {
00449 usb_stream_resync_frequency = 12288000;
00450 cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency));
00451 pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(12288000);
00452 }
00453 else if (sample_rate_hz < (88200 + 96000) / 2)
00454 {
00455 }
00456 else
00457 {
00458 }
00459
00460
00461
00462
00463 tpa6130_output_param.num_channels = num_channels;
00464 tpa6130_output_param.callback = callback;
00465 tpa6130_output_param.callback_opt = callback_opt;
00466
00467
00468 tpa6130_init();
00469
00470 #if defined(TPA6130_DAC_CLOCK_SET_CALLBACK)
00471 TPA6130_DAC_CLOCK_SET_CALLBACK(sample_rate_hz);
00472 #else
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 pm->GCCTRL[ABDAC_GCLK].div= 0;
00484 pm->GCCTRL[ABDAC_GCLK].diven=0;
00485 pm->GCCTRL[ABDAC_GCLK].pllsel=0;
00486 pm->GCCTRL[ABDAC_GCLK].oscsel=1;
00487 #endif
00488
00489 if(swap_channels)
00490 {
00491 abdac_swap_channels(TPA6130_ABDAC);
00492 }
00493 abdac_enable(TPA6130_ABDAC);
00494
00495
00496
00497
00498
00499 pdca_channel_options_t tpa6130_abdac_pdca_options =
00500 {
00501 .addr = NULL,
00502 .size = 0,
00503 .r_addr = 0,
00504 .r_size = 0,
00505 .pid = TPA6130_ABDAC_PDCA_PID,
00506 .transfer_size = PDCA_TRANSFER_SIZE_WORD
00507 };
00508
00509
00510
00511
00512
00513 pdca_init_channel(TPA6130_ABDAC_PDCA_CHANNEL,
00514 &tpa6130_abdac_pdca_options);
00515
00516
00517 pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL);
00518
00519 }
00520
00527 Bool tpa6130_dac_output(void *sample_buffer, size_t sample_length)
00528 {
00529
00530
00531
00532
00533
00534 if(!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) &
00535 PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
00536 {
00537 return FALSE;
00538 }
00539
00540
00541 if(sample_length)
00542 {
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,
00553 sample_buffer, sample_length);
00554
00555
00556
00557
00558
00559
00560 if(tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00561 pdca_enable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00562 if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
00563 pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00564 }
00565 return TRUE;
00566 }
00567
00568 Bool tpa6130_dac_is_volume_muted(void)
00569 {
00570 return FALSE;
00571 }
00572
00573 void tpa6130_dac_mute(Bool mute)
00574 {
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 S8 volume = tpa6130_get_volume();
00599 if (mute)
00600 {
00601 U32 save_dac_reload_callback_opt;
00602
00603
00604 volume = volume | MUTE_L | MUTE_R;
00605 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
00606
00607 save_dac_reload_callback_opt = tpa6130_output_param.callback_opt;
00608 tpa6130_output_param.callback_opt = 0;
00609
00610 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00611 while (!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
00612
00613 tpa6130_output_param.callback_opt = save_dac_reload_callback_opt;
00614 }
00615 else
00616 {
00617
00618 pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00619
00620 volume = volume & (~(MUTE_L | MUTE_R));
00621 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
00622 }
00623 }
00624
00625 Bool tpa6130_dac_is_volume_boosted(void)
00626 {
00627 return FALSE;
00628 }
00629
00633 U8 tpa6130_dac_get_volume(void)
00634 {
00635
00636
00637
00638
00639 U16 raw_volume;
00640 raw_volume = (tpa6130_get_volume() & (~(MUTE_L | MUTE_R)));
00641 return (U8) ((raw_volume * 255) / TPA6130_VOL_MAX);
00642 }
00643
00646 void tpa6130_dac_set_volume(U8 volume)
00647 {
00648 tpa6130_set_volume(volume);
00649 }
00650
00655 void tpa6130_dac_increase_volume(void)
00656 {
00657 S8 volume = tpa6130_get_volume()& (~(MUTE_L | MUTE_R));
00658 if( volume < TPA6130_VOL_MIN )
00659 volume = TPA6130_VOL_MIN;
00660 tpa6130_set_volume(volume+1);
00661 }
00662
00667 void tpa6130_dac_decrease_volume(void)
00668 {
00669 S8 volume = tpa6130_get_volume()& (~(MUTE_L | MUTE_R));;
00670 if( volume > TPA6130_VOL_MIN )
00671 --volume;
00672 tpa6130_set_volume( volume );
00673 }
00674
00677 void tpa6130_dac_flush(void)
00678 {
00679 pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00680 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00681
00682
00683
00684
00685
00686 pdca_disable (TPA6130_ABDAC_PDCA_CHANNEL );
00687 pdca_load_channel (TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0);
00688 pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0);
00689 pdca_enable (TPA6130_ABDAC_PDCA_CHANNEL );
00690 }
00691
00696 void tpa6130_dac_stop(void)
00697 {
00698
00699 tpa6130_shutdown();
00700
00701
00702
00703
00704
00705
00706 abdac_disable(TPA6130_ABDAC);
00707
00708
00709 pdca_disable(TPA6130_ABDAC_PDCA_CHANNEL);
00710
00711
00712 gpio_enable_gpio(TPA6130_ABDAC_GPIO_MAP,
00713 sizeof(TPA6130_ABDAC_GPIO_MAP)
00714 / sizeof(TPA6130_ABDAC_GPIO_MAP[0]));
00715
00716 tpa6130_output_param.num_channels = 0;
00717 tpa6130_output_param.callback = NULL;
00718 tpa6130_output_param.callback_opt = 0;
00719 }