e052cb20f7a58709e6317ac51bda9df70044d84f
[tas2557sw-android/tas2557-ftc.git] / tas2557.c
1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016  Texas Instruments Inc.
4 **
5 ** File:
6 **     tas2555.c
7 **
8 ** Description:
9 **     functions for configurating TAS2555 Android device
10 **
11 ** =============================================================================
12 */
14 #include "tas2557.h"
15 #include "system.h"
17 #include <sys/types.h>
18 #include <stdio.h>
19 #include <time.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <string.h>
27 #define TILOAD_NODE "/dev/tiload_node"
29 static int gTILoad = 0;
30 static int gBinFile = 0;
32 #define MAX_BIN_SIZE 2048
33 static char gpBin[MAX_BIN_SIZE];
34 static unsigned int gnBinIndex = 0;
35 static unsigned int gnBinBlockIndex = 0;
36 static char gpDevABlock[MAX_BIN_SIZE/2];
37 static unsigned int gnDevABlockIndex = 0;
38 static unsigned char gnDevA;
39 static unsigned char gnDev;
41 static void tas2557_check_node(void);
43 void tas2557_mixer_command(char *pCommand, int nData)
44 {
45         char *pMixer[] = {AUDIO_MIXER, pCommand, "0", NULL};
46         char *pEnv[] = {NULL};
48         char pData[16];
50         printf("TAS2557 mixer command %s = %d.\n\r", pCommand, nData);
52         sprintf(pData, "%d", nData);
53         pMixer[2] = pData;
54         
55         if (0 == (fork()))
56         {
57                 if (execve(AUDIO_MIXER, pMixer, pEnv) == -1)
58                 {
59                         printf("factorytest: Can't find mixer. Please install %s. \n\r", AUDIO_MIXER);
60                         exit(-1);
61                 }
62         }
64         sys_delay(500);
65 }
67 void tas2557_load_calibration(int nCalibration)
68 {
69         tas2557_check_node();
70         
71         ioctl(gTILoad, TILOAD_IOCTL_SET_CALIBRATION, &nCalibration);
72         sys_delay(500);
73 }
75 static void tas2557_check_node(void)
76 {
77         if (gTILoad) return;
79         gTILoad = open(TILOAD_NODE, O_RDWR);
81         if (gTILoad < 0)
82         {
83                 printf("factorytest: Can't find tiload. Please create %s. \n\r", TILOAD_NODE);
84                 exit(-1);
85         }
87         printf("factorytest: %s handle = %d\n\r", TILOAD_NODE, gTILoad);
88 }
90 uint8_t tas2557_get_PGID(void)
91 {
92         unsigned char pPageZero[] = {0x00, 0x00};
93         unsigned char pBook[] = {0x7F, 0x00};
94         unsigned char pPage[] = {0x00, 0x00};
95         unsigned char pData[] = {0x03, 0x00, 0x00, 0x00, 0x00};
97         tas2557_check_node();
99         write(gTILoad, pPageZero, 2);
100         write(gTILoad, pBook, 2);
101         write(gTILoad, pPage, 2);
102         read(gTILoad, pData, 1);
104         return pData[0];
107 uint32_t tas2557_coeff_read(uint32_t reg)
109         uint8_t nbook = TAS2557_BOOK_ID(reg);
110         uint8_t npage = TAS2557_PAGE_ID(reg);
111         uint8_t nreg = TAS2557_PAGE_REG(reg);
112         unsigned char pPageZero[] = {0x00, 0x00};
113         unsigned char pBook[] = {0x7F, nbook};
114         unsigned char pPage[] = {0x00, npage};
115         unsigned char pData[] = {nreg, 0x00, 0x00, 0x00, 0x00};
117         tas2557_check_node();
119         write(gTILoad, pPageZero, 2);
120         write(gTILoad, pBook, 2);
121         write(gTILoad, pPage, 2);
122         read(gTILoad, pData, 4);
124         return ((pData[0] << 24) | (pData[1] << 16) | (pData[2] << 8) | (pData[3]));
128 #define TAS2557_mCDSP_SWAP_REG  TAS2557_REG(0x8c, 0x19, 0x7c)
129 #define TAS2557_uCDSP_SWAP_REG  TAS2557_REG(0x00, 0x35, 0x2c)
131 void tas2557_coeff_write(uint32_t reg, uint32_t data)
133         unsigned int nByte;
134         uint8_t nbook, npage, nreg;
136         nbook = TAS2557_BOOK_ID(reg);
137         npage = TAS2557_PAGE_ID(reg);
138         nreg = TAS2557_PAGE_REG(reg);
140         // if the bin file is open, write the coefficients to the bin file
141         if (gBinFile) {
142                 /* if the bin file is open, write the coefficients to the bin file */
143                         unsigned int index = gnDevABlockIndex*4;
145                         gpDevABlock[index] = 0;
146                         gpDevABlock[index + 1] = 4;
147                         gpDevABlock[index + 2] = 0x85;
148                         gpDevABlock[index + 4] = nbook;
149                         gpDevABlock[index + 5] = npage;
150                         gpDevABlock[index + 6] = nreg;
152                         for (nByte = 0; nByte < 4; nByte++)
153                                 gpDevABlock[index + 7 + nByte] = (data >> ((3 - nByte) * 8)) & 0xFF;
155                         gnDevABlockIndex += 3;
156         } else {
157                 unsigned char pPageZero[] = {0x00, 0x00};
158                 unsigned char pBook[] = {0x7F, nbook};
159                 unsigned char pPage[] = {0x00, npage};
160                 unsigned char pData[] = {nreg, (data & 0xFF000000) >> 24, (data & 0x00FF0000) >> 16, (data & 0x0000FF00) >> 8, data & 0x000000FF};
162                 tas2557_check_node();
164                 write(gTILoad, pPageZero, 2);
165                 write(gTILoad, pBook, 2);
166                 write(gTILoad, pPage, 2);
167                 write(gTILoad, pData, 5);
169                 pBook[1] = TAS2557_BOOK_ID(TAS2557_mCDSP_SWAP_REG);
170                 pPage[1] = TAS2557_PAGE_ID(TAS2557_mCDSP_SWAP_REG);
172                 pData[0] = TAS2557_PAGE_REG(TAS2557_mCDSP_SWAP_REG);
173                 pData[1] = 0x00;
174                 pData[2] = 0x00;
175                 pData[3] = 0x00;
176                 pData[4] = 0x01;
178                 write(gTILoad, pPageZero, 2);
179                 write(gTILoad, pBook, 2);
180                 write(gTILoad, pPage, 2);
181                 write(gTILoad, pData, 5);
183                 pBook[1] = TAS2557_BOOK_ID(TAS2557_uCDSP_SWAP_REG);;
184                 pPage[1] = TAS2557_PAGE_ID(TAS2557_uCDSP_SWAP_REG);
186                 pData[0] = TAS2557_PAGE_REG(TAS2557_uCDSP_SWAP_REG);
187                 pData[1] = 0x00;
188                 pData[2] = 0x00;
189                 pData[3] = 0x00;
190                 pData[4] = 0x01;
192                 write(gTILoad, pPageZero, 2);
193                 write(gTILoad, pBook, 2);
194                 write(gTILoad, pPage, 2);
195                 write(gTILoad, pData, 5);
196         }
199 void tas2557_save_cal(struct TFTCConfiguration *pFTCC, 
200         double dev_a_re, uint32_t dev_a_rms_pow, uint32_t dev_a_t_limit, 
201         double t_cal,  uint32_t nResult, char * pFileName)
203         printf("TAS2557 calibration values:\n\r");
204         printf("    DevA Re = %1.2f Ohm\n\r", dev_a_re);
205         printf("    DevA rms_pow       = 0x%08X\n\r", dev_a_rms_pow);
206         printf("    DevA t_limit       = 0x%08X\n\r", dev_a_t_limit);
208         if((nResult & RE1_CHK_MSK) == RESULT_PASS)
209                 printf(" SPK A calibration success! \n\r");
210         else {
211                 if(nResult & RE1_FAIL_HI)
212                         printf(" SPK A Calibration fail : Re is too high (limit: %1.2f).\n\r", pFTCC->nTSpkCharDevA.nReHi);
213                 else
214                         printf(" SPK A Calibration fail : Re is too low (limit: %1.2f).\n\r", pFTCC->nTSpkCharDevA.nReLo);
215         }
217         FILE *pFile = fopen(pFileName, "w+");
219         fprintf(pFile, "DevA Re = %1.2f\n\r", dev_a_re);
220         fprintf(pFile, "DevA rms_pow       = 0x%08X\n\r", dev_a_rms_pow);
221         fprintf(pFile, "DevA t_limit       = 0x%08X\n\r", dev_a_t_limit);
222         fprintf(pFile, "Ambient temperature = %2.2f\n\r\n\r", t_cal);
223         fprintf(pFile, "Result = 0x%x\n\r\n\r", nResult);
225         fclose(pFile);
228 #define DDC_DESCRIPTION "Calibration Data File for TAS2557 Mono"
229 #define CALIBRATION_DESCRIPTION "Calibration snapshot for TAS2557 Mono"
230 #define DATA_DESCRIPTION "data blocks for TAS2557 Mono FTC"
232 void tas2557_open_bin(char * pFileName)
234         time_t timestamp; 
236         gBinFile = open(pFileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
238         gnBinIndex = 0;
239         memset(gpBin, 0, MAX_BIN_SIZE);
240         memset(gpDevABlock, 0, MAX_BIN_SIZE/2);
241         gnDevABlockIndex = 0;
243         //magic number
244         gpBin[gnBinIndex++] = '5';
245         gpBin[gnBinIndex++] = '5';
246         gpBin[gnBinIndex++] = '5';
247         gpBin[gnBinIndex++] = '2';
249         gnBinIndex += 4;        /* bypass size int */
250         gnBinIndex += 4;        /* bypass checksum int */
251         gnBinIndex += 4;        /* bypass PPC3 version int */
252         gnBinIndex += 4;        /* bypass DSP version int */
254         gpBin[gnBinIndex++] = 0;
255         gpBin[gnBinIndex++] = 0;
256         gpBin[gnBinIndex++] = 1;
257         gpBin[gnBinIndex++] = 0; /* driver version 0x00000100 */
259         time(&timestamp);
260         gpBin[gnBinIndex++] = (unsigned char)((timestamp&0xff000000)>>24);
261         gpBin[gnBinIndex++] = (unsigned char)((timestamp&0x00ff0000)>>16);;
262         gpBin[gnBinIndex++] = (unsigned char)((timestamp&0x0000ff00)>>8);;
263         gpBin[gnBinIndex++] = (unsigned char)((timestamp&0x000000ff));;
265         strcpy(&gpBin[gnBinIndex], "Calibration Data File");    /* DDC name */
266         gnBinIndex += 64;
268         strcpy(&gpBin[gnBinIndex], DDC_DESCRIPTION);
269         gnBinIndex += strlen(DDC_DESCRIPTION) + 1;
271         gnBinIndex += 4; /* device family index */
273         gpBin[gnBinIndex++] = 0; /* device index */
274         gpBin[gnBinIndex++] = 0; /* device index */
275         gpBin[gnBinIndex++] = 0; /* device index */
276         gpBin[gnBinIndex++] = 2; /* device index, TAS2557 Mono */
278         gnBinIndex +=
279                 2 +     /* num PLL index */
280                 0 +     /* array PLL index */
281                 2 +     /* num programs index */
282                 0 +     /* array programs index */
283                 2 +     /* num configurations index */
284                 0;      /* array configurations index */
286         gpBin[gnBinIndex++] = 0x00;
287         gpBin[gnBinIndex++] = 0x01; /* one calibration data block */
289         strcpy(&gpBin[gnBinIndex], "Calibration snapshot");
290         gnBinIndex += 64;
291         strcpy(&gpBin[gnBinIndex], CALIBRATION_DESCRIPTION);
292         gnBinIndex += strlen(CALIBRATION_DESCRIPTION) + 1;
294         gpBin[gnBinIndex++] = 0x00; /* compatible program = smart amp (index 0) */
295         gpBin[gnBinIndex++] = 0x00; /* compatible configuration */
297         strcpy(&gpBin[gnBinIndex], "Calibration Data");
298         gnBinIndex += 64;
299         strcpy(&gpBin[gnBinIndex], DATA_DESCRIPTION);
300         gnBinIndex += strlen(DATA_DESCRIPTION) + 1;
302         gpBin[gnBinIndex++] = 0x00; 
303         gpBin[gnBinIndex++] = 1;        /* one blocks */
305         gpDevABlock[0] = 0;
306         gpDevABlock[1] = 0;
307         gpDevABlock[2] = 0;
308         gpDevABlock[3] = 0x03;  /* COEFF_DEVICE_A – 0x03 */
309         gnDevABlockIndex = 2;
312 void tas2557_close_bin(void)
314         unsigned int nCommands;
315         unsigned char pCommit[] = {
316                 0x00, 0x04, 0x85, 0x00,
317                 TAS2557_BOOK_ID(TAS2557_mCDSP_SWAP_REG), TAS2557_PAGE_ID(TAS2557_mCDSP_SWAP_REG), TAS2557_PAGE_REG(TAS2557_mCDSP_SWAP_REG), 0x00,
318                 0x00, 0x00, 0x01, 0x00,
319                 0x00, 0x04, 0x85, 0x00,
320                 TAS2557_BOOK_ID(TAS2557_uCDSP_SWAP_REG), TAS2557_PAGE_ID(TAS2557_uCDSP_SWAP_REG), TAS2557_PAGE_REG(TAS2557_uCDSP_SWAP_REG), 0x00,
321                 0x00, 0x00, 0x01, 0x00
322         };
324         /* write the commit sequence */
325         memcpy(&gpDevABlock[gnDevABlockIndex*4], pCommit, 24);
326         gnDevABlockIndex += 6;
328         /* write number of commands for calibration block */
329         gpDevABlock[4] = ((gnDevABlockIndex-2) & 0xFF000000) >> 24;
330         gpDevABlock[5] = ((gnDevABlockIndex-2) & 0x00FF0000) >> 16;
331         gpDevABlock[6] = ((gnDevABlockIndex-2) & 0x0000FF00) >> 8;
332         gpDevABlock[7] = ((gnDevABlockIndex-2) & 0x000000FF);
334         memcpy(&gpBin[gnBinIndex], gpDevABlock, gnDevABlockIndex*4);
335         gnBinIndex += (gnDevABlockIndex*4);
337         /* write bin file size */
338         gpBin[4] = (gnBinIndex & 0xFF000000) >> 24;
339         gpBin[5] = (gnBinIndex & 0x00FF0000) >> 16;
340         gpBin[6] = (gnBinIndex & 0x0000FF00) >> 8;
341         gpBin[7] = (gnBinIndex & 0x000000FF);
343         write(gBinFile, gpBin, gnBinIndex);
344         close(gBinFile);
346         gBinFile = 0;
349 // ----------------------------------------------------------------------------- 
350 // check_spk_bounds 
351 // ----------------------------------------------------------------------------- 
352 // Description: 
353 //      Checks if speaker paramters are within bounds. 
354 // ----------------------------------------------------------------------------- 
355 uint32_t check_spk_bounds(struct TFTCConfiguration *pFTCC, double re1) 
356
357         uint32_t result = RESULT_PASS; 
359         if(re1>pFTCC->nTSpkCharDevA.nReHi) 
360                 result |= RE1_FAIL_HI; 
361         if(re1<pFTCC->nTSpkCharDevA.nReLo) 
362                 result |= RE1_FAIL_LO; 
364         return result; 
365
367 void tas2557_ftc_release(void)
369         if (gTILoad > 0) {
370                 close(gTILoad);
371                 gTILoad = 0;
372         }