tas5706a.c

Go to the documentation of this file.
00001 
00040 #include "tas5706a.h"
00041 #include <cfg/module.h>
00042 
00043 #include <drv/i2c.h>
00044 #include <drv/timer.h>
00045 
00046 #include "hw/hw_tas5706a.h"
00047 #include "cfg/cfg_tas5706a.h"
00048 
00049 #define TAS_ADDR 0x36
00050 
00051 typedef uint8_t tas_addr_t;
00052 
00053 static bool tas5706a_send(tas_addr_t addr, const void *buf, size_t len)
00054 {
00055     bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_send(buf, len);
00056     i2c_stop();
00057     return ret;
00058 }
00059 
00060 INLINE bool tas5706a_putc(tas_addr_t addr, uint8_t ch)
00061 {
00062     return tas5706a_send(addr, &ch, sizeof(ch));
00063 }
00064 
00065 static bool tas5706a_recv(tas_addr_t addr, void *buf, size_t len)
00066 {
00067     bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_start_r(TAS_ADDR) && i2c_recv(buf, len);
00068     i2c_stop();
00069     return ret;
00070 }
00071 
00072 INLINE int tas5706a_getc(tas_addr_t addr)
00073 {
00074     uint8_t ch;
00075     if (tas5706a_recv(addr, &ch, sizeof(ch)))
00076         return (int)(uint8_t)ch;
00077     else
00078         return EOF;
00079 }
00080 
00081 #define TRIM_REG   0x1B
00082 #define SYS_REG2   0x05
00083 #define VOLUME_REG 0x07
00084 #define MUTE_VOL 0xFF
00085 
00086 #define DB_TO_REG(db) ((24 - (db)) * 2)
00087 
00088 void tas5706a_init(void)
00089 {
00090     MOD_CHECK(i2c);
00091     MOD_CHECK(timer);
00092     TAS5706A_PIN_INIT();
00093     timer_delay(200);
00094     TAS5706A_SETPOWERDOWN(false);
00095     TAS5706A_SETMUTE(false);
00096     TAS5706A_MCLK_INIT();
00097     timer_delay(2);
00098     TAS5706A_SETRESET(false);
00099     timer_delay(20);
00100     tas5706a_putc(TRIM_REG, 0x00);
00101 
00102     tas5706a_putc(VOLUME_REG, DB_TO_REG(CONFIG_TAS_MAX_VOL));
00103 
00104     /* Unmute */
00105     tas5706a_putc(SYS_REG2, 0);
00106 }
00107 
00108 #define CH1_VOL_REG 0x08
00109 #define CH2_VOL_REG 0x09
00110 #define CH3_VOL_REG 0x0A
00111 #define CH4_VOL_REG 0x0B
00112 
00113 void tas5706a_setVolume(Tas5706aCh ch, tas5706a_vol_t vol)
00114 {
00115     ASSERT(ch < TAS_CNT);
00116     ASSERT(vol <= TAS_VOL_MAX);
00117 
00118     tas_addr_t addr1, addr2;
00119 
00120     switch(ch)
00121     {
00122         case TAS_CH1:
00123             addr1 = CH1_VOL_REG;
00124             addr2 = CH3_VOL_REG;
00125             break;
00126         case TAS_CH2:
00127             addr1 = CH2_VOL_REG;
00128             addr2 = CH4_VOL_REG;
00129             break;
00130         default:
00131             ASSERT(0);
00132             return;
00133     }
00134 
00135     uint8_t vol_att = 0xff - ((vol * 0xff) / TAS_VOL_MAX);
00136 
00137     tas5706a_putc(addr1, vol_att);
00138     tas5706a_putc(addr2, vol_att);
00139 }
00140 
00141 void tas5706a_setLowPower(bool val)
00142 {
00143     TAS5706A_SETPOWERDOWN(val);
00144     TAS5706A_SETMUTE(val);
00145 }
00146