1 /*
2  * Copyright 2019 NXP
3  * All rights reserved.
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <assert.h>
12 #include "fsl_tfa9896.h"
13 #include "fsl_common.h"
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 #define TFA_SWAP_UINT16_BYTE_SEQUENCE(x) (__REV16(x))
18 
19 /*******************************************************************************
20  * Prototypes
21  ******************************************************************************/
22 
23 /*******************************************************************************
24  * Code
25  ******************************************************************************/
TFA9896_ReadRegister(tfa9896_handle_t * handle,uint8_t subaddress,unsigned short * value)26 status_t TFA9896_ReadRegister(tfa9896_handle_t *handle, uint8_t subaddress, unsigned short *value)
27 {
28     assert(handle->config != NULL);
29     assert(handle->config->slaveAddress != 0U);
30 
31     uint16_t readValue = 0U;
32 #if defined(DEMO_VERBOSE)
33     int i;
34 #endif
35 
36     if (CODEC_I2C_Receive(handle->i2cHandle, handle->config->slaveAddress, subaddress, 1U, (uint8_t *)&readValue, 2U) !=
37         kStatus_HAL_I2cSuccess)
38     {
39         return kStatus_TFA9896_I2C_Fatal;
40     }
41 
42     *value = TFA_SWAP_UINT16_BYTE_SEQUENCE(readValue);
43 #if defined(DEMO_VERBOSE)
44     TFA9896_Printf("R(0x%02x):", subaddress);
45     for (i = 0; i < transfer.dataSize; i++)
46     {
47         TFA9896_Printf("[0x%02x]", (unsigned char)((unsigned char *)transfer.data + i));
48     }
49     TFA9896_Printf("\r\n");
50 #endif
51 
52     return kStatus_TFA9896_Ok;
53 }
54 
tfa_read_reg(tfa9896_handle_t * handle,const uint16_t bf)55 int tfa_read_reg(tfa9896_handle_t *handle, const uint16_t bf)
56 {
57     status_t err = kStatus_TFA9896_Ok;
58     uint16_t regvalue;
59 
60     /* bitfield enum - 8..15 : address */
61     uint8_t address = (bf >> 8) & 0xff;
62 
63     err = TFA9896_ReadRegister(handle, address, &regvalue);
64     if (err)
65     {
66         return -err;
67     }
68 
69     return regvalue;
70 }
71 
TFA9896_WriteRegister(tfa9896_handle_t * handle,uint8_t subaddress,uint16_t value)72 status_t TFA9896_WriteRegister(tfa9896_handle_t *handle, uint8_t subaddress, uint16_t value)
73 {
74     assert(handle->config != NULL);
75     assert(handle->config->slaveAddress != 0U);
76 
77 #if defined(DEMO_VERBOSE)
78     int i;
79 #endif
80 
81     uint16_t writeValue = TFA_SWAP_UINT16_BYTE_SEQUENCE(value);
82 
83     if (kStatus_HAL_I2cSuccess !=
84         CODEC_I2C_Send(handle->i2cHandle, handle->config->slaveAddress, subaddress, 1U, (uint8_t *)&writeValue, 2U))
85     {
86         return kStatus_TFA9896_I2C_Fatal;
87     }
88 
89 #if defined(DEMO_VERBOSE)
90     TFA9896_Printf("W(0x%02x):", subaddress);
91     for (i = 0; i < transfer.dataSize; i++)
92     {
93         TFA9896_Printf("[0x%02x]", (unsigned char)((unsigned char *)transfer.data + i));
94     }
95     TFA9896_Printf("\r\n");
96 #endif
97 
98     return kStatus_TFA9896_Ok;
99 }
100 
TFA9896_GetBits(tfa9896_handle_t * handle,const uint16_t bf)101 uint16_t TFA9896_GetBits(tfa9896_handle_t *handle, const uint16_t bf)
102 {
103     uint16_t regvalue, msk;
104     status_t err = kStatus_TFA9896_Ok;
105     uint16_t value;
106     uint8_t len     = bf & 0x0f;
107     uint8_t pos     = (bf >> 4) & 0x0f;
108     uint8_t address = (bf >> 8) & 0xff;
109     err             = TFA9896_ReadRegister(handle, address, &regvalue);
110     if (err != kStatus_TFA9896_Ok)
111     {
112         return 0U;
113     }
114     msk = ((1 << (len + 1)) - 1) << pos;
115     regvalue &= msk;
116     value = regvalue >> pos;
117 
118     return value;
119 }
120 
TFA9896_isFactory(tfa9896_handle_t * handle)121 uint16_t TFA9896_isFactory(tfa9896_handle_t *handle)
122 {
123     return (TFA9896_GetBits(handle, TFA1_BF_MTPEX) == 1);
124 }
125 
TFA9896_SetBits(tfa9896_handle_t * handle,const uint16_t bf,const uint16_t value)126 status_t TFA9896_SetBits(tfa9896_handle_t *handle, const uint16_t bf, const uint16_t value)
127 {
128     status_t err = kStatus_TFA9896_Ok;
129     uint16_t regvalue, msk, oldvalue;
130     uint8_t len     = (bf & 0x0f) + 1;
131     uint8_t pos     = (bf >> 4) & 0x0f;
132     uint8_t address = (bf >> 8) & 0xff;
133     err             = TFA9896_ReadRegister(handle, address, &regvalue);
134     oldvalue        = regvalue;
135     msk             = ((1 << len) - 1) << pos;
136     regvalue &= ~msk;
137     regvalue |= value << pos;
138 
139     if (oldvalue != regvalue)
140     {
141         err = TFA9896_WriteRegister(handle, (bf >> 8) & 0xff, regvalue);
142     }
143 
144     return err;
145 }
146 
TFA9896_ReadData(tfa9896_handle_t * handle,unsigned char subaddress,int num_bytes,unsigned char data[])147 status_t TFA9896_ReadData(tfa9896_handle_t *handle, unsigned char subaddress, int num_bytes, unsigned char data[])
148 {
149     status_t err = kStatus_TFA9896_Ok;
150 #if defined(DEMO_VERBOSE)
151     int i;
152 #endif
153 
154     err =
155         CODEC_I2C_Receive(handle->i2cHandle, handle->config->slaveAddress, subaddress, 1U, (uint8_t *)data, num_bytes);
156 
157 #if defined(DEMO_VERBOSE)
158     TFA9896_Printf("R(0x%02x):", subaddress);
159     for (i = 0; i < transfer.dataSize; i++)
160         TFA9896_Printf("[0x%02x]", (unsigned char)((unsigned char *)transfer.data + i));
161     TFA9896_Printf("\r\n");
162 #endif
163 
164     return err;
165 }
166 
TFA9896_WriteData(tfa9896_handle_t * handle,unsigned char subaddress,int num_bytes,const unsigned char data[])167 status_t TFA9896_WriteData(tfa9896_handle_t *handle,
168                            unsigned char subaddress,
169                            int num_bytes,
170                            const unsigned char data[])
171 {
172     status_t err = kStatus_TFA9896_Ok;
173 #if defined(DEMO_VERBOSE)
174     int i;
175 #endif
176 
177     err = CODEC_I2C_Send(handle->i2cHandle, handle->config->slaveAddress, subaddress, 1U, (uint8_t *)data, num_bytes);
178 
179 #if defined(DEMO_VERBOSE)
180     TFA9896_Printf("W(0x%02x):", subaddress);
181     for (i = 0; i < transfer.dataSize; i++)
182     {
183         TFA9896_Printf("[0x%02x]", (unsigned char)((unsigned char *)transfer.data + i));
184     }
185     TFA9896_Printf("\r\n");
186 #endif
187 
188     return err;
189 }
190 
191 /* read the return code for the RPC call */
checkRpcStatus(tfa9896_handle_t * handle,int * pRpcStatus)192 status_t checkRpcStatus(tfa9896_handle_t *handle, int *pRpcStatus)
193 {
194     status_t error         = kStatus_TFA9896_Ok;
195     unsigned short cf_ctrl = 0x0002; /* the value to sent to the CF_CONTROLS register: cf_req=00000000, cf_int=0,
196                                         cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
197     unsigned short cf_mad = 0x0000;  /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */
198     unsigned char mem[3];            /* will be filled with the status read from DSP memory */
199     if (pRpcStatus == 0)
200         return kStatus_TFA9896_Bad_Parameter;
201 #ifdef OPTIMIZED_RPC
202     {
203         /* minimize the number of I2C transactions by making use of the autoincrement in I2C */
204         unsigned char buffer[4];
205         /* first the data for CF_CONTROLS */
206         buffer[0] = (unsigned char)((cf_ctrl >> 8) & 0xFF);
207         buffer[1] = (unsigned char)(cf_ctrl & 0xFF);
208         /* write the contents of CF_MAD which is the subaddress following CF_CONTROLS */
209         buffer[2] = (unsigned char)((cf_mad >> 8) & 0xFF);
210         buffer[3] = (unsigned char)(cf_mad & 0xFF);
211         error     = TFA9896_WriteData(handle, 0x70, sizeof(buffer), buffer);
212     }
213 #else
214     /* 1) write DMEM=XMEM to the DSP XMEM */
215     if (error == kStatus_TFA9896_Ok)
216     {
217         error = TFA9896_WriteRegister(handle, 0x70, cf_ctrl);
218     }
219     if (error == kStatus_TFA9896_Ok)
220     {
221         /* write the address in XMEM where to read */
222         TFA9896_WriteRegister(handle, 0x71, cf_mad);
223     }
224 #endif
225     if (error == kStatus_TFA9896_Ok)
226     {
227         /* read 1 word (24 bit) from XMEM */
228         error = TFA9896_ReadData(handle, 0x72, 3 /*sizeof(mem) */, mem);
229     }
230     if (error == kStatus_TFA9896_Ok)
231     {
232         *pRpcStatus = (mem[0] << 16) | (mem[1] << 8) | mem[2];
233     }
234     return error;
235 }
236 
237 /* check that num_byte matches the memory type selected */
check_size(tfa9896_DMEM_t which_mem,int num_bytes)238 status_t check_size(tfa9896_DMEM_t which_mem, int num_bytes)
239 {
240     status_t error  = kStatus_TFA9896_Ok;
241     int modulo_size = 1;
242     switch (which_mem)
243     {
244         case DMEM_PMEM:
245             /* 32 bit PMEM */
246             modulo_size = 4;
247             break;
248         case DMEM_XMEM:
249         case DMEM_YMEM:
250         case DMEM_IOMEM:
251             /* 24 bit MEM */
252             modulo_size = 3;
253             break;
254         default:
255             error = kStatus_TFA9896_Bad_Parameter;
256     }
257     if (error == kStatus_TFA9896_Ok)
258     {
259         if ((num_bytes % modulo_size) != 0)
260         {
261             error = kStatus_TFA9896_Bad_Parameter;
262         }
263     }
264     return error;
265 }
266 
writeParameter(tfa9896_handle_t * handle,unsigned char module_id,unsigned char param_id,int num_bytes,const unsigned char data[])267 status_t writeParameter(tfa9896_handle_t *handle,
268                         unsigned char module_id,
269                         unsigned char param_id,
270                         int num_bytes,
271                         const unsigned char data[])
272 {
273     status_t error;
274     unsigned short cf_ctrl = 0x0002; /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, cf_int=0,
275                                         cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
276     unsigned short cf_mad = 0x0001;  /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */
277     error                 = check_size(DMEM_XMEM, num_bytes);
278     if (error == kStatus_TFA9896_Ok)
279     {
280         if ((num_bytes <= 0) || (num_bytes > MAX_PARAM_SIZE))
281         {
282             return kStatus_TFA9896_Bad_Parameter;
283         }
284     }
285 #ifdef OPTIMIZED_RPC
286     {
287         /* minimize the number of I2C transactions by making use of the autoincrement in I2C */
288         unsigned char buffer[7];
289         /* first the data for CF_CONTROLS */
290         buffer[0] = (unsigned char)((cf_ctrl >> 8) & 0xFF);
291         buffer[1] = (unsigned char)(cf_ctrl & 0xFF);
292         /* write the contents of CF_MAD which is the subaddress following CF_CONTROLS */
293         buffer[2] = (unsigned char)((cf_mad >> 8) & 0xFF);
294         buffer[3] = (unsigned char)(cf_mad & 0xFF);
295         /* write the module and RPC id into CF_MEM, which follows CF_MAD */
296         buffer[4] = 0;
297         buffer[5] = module_id + 128;
298         buffer[6] = param_id;
299         /* TFA9896_Printf("calling TFA9896_WriteData\n");*/
300         error = TFA9896_WriteData(handle, 0x70, sizeof(buffer), buffer);
301     }
302 #else
303     if (error == kStatus_TFA9896_Ok)
304     {
305         error = TFA9896_WriteRegister(handle, 0x70, cf_ctrl);
306     }
307     if (error == kStatus_TFA9896_Ok)
308     {
309         TFA9896_WriteRegister(handle, 0x71, cf_mad);
310     }
311     if (error == kStatus_TFA9896_Ok)
312     {
313         unsigned char id[3];
314         id[0] = 0;
315         id[1] = module_id + 128;
316         id[2] = param_id;
317         error = TFA9896_WriteData(handle, 0x72, 3, id);
318     }
319 #endif /* OPTIMIZED_RPC */
320     if (error == kStatus_TFA9896_Ok)
321     {
322         int offset          = 0;
323         int chunk_size      = ROUND_DOWN(NXP_I2C_MAX_SIZE, 3 /* XMEM word size */);
324         int remaining_bytes = num_bytes;
325         /* due to autoincrement in cf_ctrl, next write will happen at the next address */
326         while ((error == kStatus_TFA9896_Ok) && (remaining_bytes > 0))
327         {
328             if (remaining_bytes < chunk_size)
329             {
330                 chunk_size = remaining_bytes;
331             }
332             /* else chunk_size remains at initialize value above*/
333             error = TFA9896_WriteData(handle, 0x72, chunk_size, data + offset);
334             if (error != kStatus_TFA9896_Ok)
335             {
336                 break;
337             }
338             remaining_bytes -= chunk_size;
339             offset += chunk_size;
340         }
341     }
342     return error;
343 }
344 
executeParam(tfa9896_handle_t * handle)345 status_t executeParam(tfa9896_handle_t *handle)
346 {
347     status_t error;
348     unsigned short cf_ctrl = 0x0002; /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, cf_int=0,
349                                         cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
350     cf_ctrl |= (1 << 8) | (1 << 4);  /* set the cf_req1 and cf_int bit */
351     error = TFA9896_WriteRegister(handle, 0x70, (uint16_t)cf_ctrl);
352     return error;
353 }
354 
waitResult(tfa9896_handle_t * handle)355 status_t waitResult(tfa9896_handle_t *handle)
356 {
357     status_t error;
358     unsigned short cf_status; /* the contents of the CF_STATUS register */
359     int tries = 0;
360     do
361     {
362         error = TFA9896_ReadRegister(handle, 0x73, &cf_status);
363         tries++;
364     } while ((error == kStatus_TFA9896_Ok) && ((cf_status & 0x0100) == 0) &&
365              (tries < TFA9896_API_WAITRESULT_NTRIES)); /* don't wait forever, DSP is pretty quick to respond (< 1ms) */
366     if (tries >= TFA9896_API_WAITRESULT_NTRIES)
367     {
368         /* something wrong with communication with DSP */
369         error = kStatus_TFA9896_DSP_not_running;
370     }
371     return error;
372 }
373 
TFA9896_DspSetParam(tfa9896_handle_t * handle,unsigned char module_id,unsigned char param_id,int num_bytes,const unsigned char data[])374 status_t TFA9896_DspSetParam(tfa9896_handle_t *handle,
375                              unsigned char module_id,
376                              unsigned char param_id,
377                              int num_bytes,
378                              const unsigned char data[])
379 {
380     status_t error;
381     int rpcStatus = STATUS_OK;
382     /* 1) write the id and data to the DSP XMEM */
383     error = writeParameter(handle, module_id, param_id, num_bytes, data);
384     /* 2) wake up the DSP and let it process the data */
385     if (error == kStatus_TFA9896_Ok)
386     {
387         error = executeParam(handle);
388     }
389     /* check the result when addressed an IC uniquely */
390     if (handle->config->slaveAddress != 0x1C)
391     {
392         /* 3) wait for the ack */
393         if (error == kStatus_TFA9896_Ok)
394         {
395             error = waitResult(handle);
396         }
397         /* 4) check the RPC return value */
398         if (error == kStatus_TFA9896_Ok)
399         {
400             error = checkRpcStatus(handle, &rpcStatus);
401             TFA9896_Printf("rpcStatus:%d\n", rpcStatus);
402         }
403         if (error == kStatus_TFA9896_Ok)
404         {
405             if (rpcStatus != STATUS_OK)
406             {
407                 /* DSP RPC call returned an error */
408                 error = (status_t)(rpcStatus + kStatus_TFA9896_RpcBase);
409             }
410         }
411     }
412     return error;
413 }
414 
tfa9896_convert_data2bytes(int num_data,const int data[],unsigned char bytes[])415 void tfa9896_convert_data2bytes(int num_data, const int data[], unsigned char bytes[])
416 {
417     int i; /* index for data */
418     int k; /* index for bytes */
419     int d;
420     /* note: cannot just take the lowest 3 bytes from the 32 bit
421      * integer, because also need to take care of clipping any
422      * value > 2&23 */
423     for (i = 0, k = 0; i < num_data; ++i, k += 3)
424     {
425         if (data[i] >= 0)
426         {
427             d = MIN(data[i], (1 << 23) - 1);
428         }
429         else
430         {
431             /* 2's complement */
432             d = (1 << 24) - MIN(-data[i], 1 << 23);
433         }
434         bytes[k]     = (d >> 16) & 0xFF; /* MSB */
435         bytes[k + 1] = (d >> 8) & 0xFF;
436         bytes[k + 2] = (d)&0xFF; /* LSB */
437     }
438 }
439 
tfa9896_convert_bytes2data(int num_bytes,const unsigned char bytes[],int data[])440 void tfa9896_convert_bytes2data(int num_bytes, const unsigned char bytes[], int data[])
441 {
442     int i; /* index for data */
443     int k; /* index for bytes */
444     int d;
445     int num_data = num_bytes / 3;
446 
447     for (i = 0, k = 0; i < num_data; ++i, k += 3)
448     {
449         d = (bytes[k] << 16) | (bytes[k + 1] << 8) | (bytes[k + 2]);
450         if (bytes[k] & 0x80) /* sign bit was set */
451         {
452             d = -((1 << 24) - d);
453         }
454 
455         data[i] = d;
456     }
457 }
458 
TFA9896_DspBiquad_Disable(tfa9896_handle_t * handle,int biquad_index)459 status_t TFA9896_DspBiquad_Disable(tfa9896_handle_t *handle, int biquad_index)
460 {
461     int coeff_buffer[6];
462     unsigned char bytes[6 * 3];
463     status_t error = kStatus_TFA9896_Ok;
464     /* set in correct order and format for the DSP */
465     coeff_buffer[0] = (int)-8388608; /* -1.0f */
466     coeff_buffer[1] = 0;
467     coeff_buffer[2] = 0;
468     coeff_buffer[3] = 0;
469     coeff_buffer[4] = 0;
470     coeff_buffer[5] = 0;
471     /* convert float to fixed point and then bytes suitable for transmaission over I2C */
472     tfa9896_convert_data2bytes(6, coeff_buffer, bytes);
473     error = TFA9896_DspSetParam(handle, 2, (unsigned char)biquad_index, (unsigned char)6 * 3, bytes);
474 
475     return error;
476 }
477 
478 #ifdef TFA9896_DEBUG_DATA
printArray(char * ptr,size_t size)479 void printArray(char *ptr, size_t size)
480 {
481     char *const end = ptr + size;
482     while (ptr < end)
483     {
484         TFA9896_Printf("[%x]-", *ptr++);
485     }
486 }
487 #endif
488 
TFA9896_Write_FilterBank(tfa9896_handle_t * handle,tfa9896FilterM_t * filter)489 status_t TFA9896_Write_FilterBank(tfa9896_handle_t *handle, tfa9896FilterM_t *filter)
490 {
491     unsigned char biquad_index;
492     status_t error = kStatus_TFA9896_Ok;
493     for (biquad_index = 0; biquad_index < 10; biquad_index++)
494     {
495         if (filter[biquad_index].enabled)
496         {
497             TFA9896_Printf("TFA9896_Write_FilterBank inside if block\n");
498             error = TFA9896_DspSetParam(handle, 2, biquad_index + 1, sizeof(filter[biquad_index].biquad.bytes),
499                                         filter[biquad_index].biquad.bytes);
500         }
501         else
502         {
503             TFA9896_Printf("TFA9896_Write_FilterBank inside else block\n");
504             error = TFA9896_DspBiquad_Disable(handle, biquad_index + 1);
505         }
506     }
507     return error;
508 }
509 
510 unsigned char vsfwdelay_table[] = {
511     0, 0, 2, /*Index 0 - Current/Volt Fractional Delay for 8KHz  */
512     0, 0, 0, /*Index 1 - Current/Volt Fractional Delay for 11KHz */
513     0, 0, 0, /*Index 2 - Current/Volt Fractional Delay for 12KHz */
514     0, 0, 2, /*Index 3 - Current/Volt Fractional Delay for 16KHz */
515     0, 0, 2, /*Index 4 - Current/Volt Fractional Delay for 22KHz */
516     0, 0, 2, /*Index 5 - Current/Volt Fractional Delay for 24KHz */
517     0, 0, 2, /*Index 6 - Current/Volt Fractional Delay for 32KHz */
518     0, 0, 2, /*Index 7 - Current/Volt Fractional Delay for 44KHz */
519     0, 0, 3  /*Index 8 - Current/Volt Fractional Delay for 48KHz */
520 };
521 unsigned char cvfracdelay_table[] = {
522     0, 0, 51, /*Index 0 - Current/Volt Fractional Delay for 8KHz  */
523     0, 0, 0,  /*Index 1 - Current/Volt Fractional Delay for 11KHz */
524     0, 0, 0,  /*Index 2 - Current/Volt Fractional Delay for 12KHz */
525     0, 0, 38, /*Index 3 - Current/Volt Fractional Delay for 16KHz */
526     0, 0, 34, /*Index 4 - Current/Volt Fractional Delay for 22KHz */
527     0, 0, 33, /*Index 5 - Current/Volt Fractional Delay for 24KHz */
528     0, 0, 11, /*Index 6 - Current/Volt Fractional Delay for 32KHz */
529     0, 0, 2,  /*Index 7 - Current/Volt Fractional Delay for 44KHz */
530     0, 0, 62  /*Index 8 - Current/Volt Fractional Delay for 48KHz */
531 };
532 
tfa_dsp_write_cvfracdelay_table(tfa9896_handle_t * handle)533 status_t tfa_dsp_write_cvfracdelay_table(tfa9896_handle_t *handle)
534 {
535     TFA9896_Printf("Bytes  cvfracdelay_table_96 to be written:%d\n", sizeof(cvfracdelay_table));
536     return TFA9896_DspSetParam(handle, MODULE_FRAMEWORK, 0x06, sizeof(cvfracdelay_table), cvfracdelay_table);
537 }
538 
tfa_dsp_write_vsfwdelay_table(tfa9896_handle_t * handle)539 status_t tfa_dsp_write_vsfwdelay_table(tfa9896_handle_t *handle)
540 {
541     TFA9896_Printf("Bytes  vsfwdelay_table_96 to be written:%d\n", sizeof(vsfwdelay_table));
542     return TFA9896_DspSetParam(handle, MODULE_FRAMEWORK, 0x03, sizeof(vsfwdelay_table), vsfwdelay_table);
543 }
544 
TFA9896_DSPWriteTables(tfa9896_handle_t * handle)545 status_t TFA9896_DSPWriteTables(tfa9896_handle_t *handle)
546 {
547     status_t error = kStatus_TFA9896_Ok;
548 
549     error = tfa_dsp_write_vsfwdelay_table(handle);
550     if (error == kStatus_TFA9896_Ok)
551     {
552         error = tfa_dsp_write_cvfracdelay_table(handle);
553         assert(error == kStatus_TFA9896_Ok);
554     }
555 
556     TFA9896_SetBits(handle, TFA1_BF_RST, 1);
557     assert(error == kStatus_TFA9896_Ok);
558     TFA9896_SetBits(handle, TFA1_BF_RST, 0);
559     assert(error == kStatus_TFA9896_Ok);
560     return error;
561 }
562 
TFA9896_ProcessPatchFile(tfa9896_handle_t * handle,int length,const unsigned char * bytes)563 status_t TFA9896_ProcessPatchFile(tfa9896_handle_t *handle, int length, const unsigned char *bytes)
564 {
565     unsigned short size;
566     int index;
567 
568     status_t err = kStatus_TFA9896_Ok;
569 #if defined(DEMO_VERBOSE)
570     int i;
571 #endif
572 
573     /* expect following format in patchBytes:
574      * 2 bytes length of I2C transaction in little endian, then the bytes, excluding the slave address which is added
575      * from the handle This repeats for the whole file
576      */
577     index = 0;
578 
579     while (index < length)
580     {
581         /* extract little endian length */
582         size = bytes[index] + bytes[index + 1] * 256;
583         index += 2;
584         if ((index + size) > length)
585         {
586             /* too big, outside the buffer, error in the input data */
587             return kStatus_TFA9896_Bad_Parameter;
588         }
589         if ((size + 1) > MAX_I2C_LENGTH)
590         {
591             /* too big, must fit buffer */
592             return kStatus_TFA9896_Bad_Parameter;
593         }
594 
595 #ifdef TFA9896_PRINT_DEBUG
596         /* TFA9896_Printf("Bytes to be written_patch:%d (index = %d bytes[index] = %d bytes[index+1] = %d\r\n",size,
597          index, bytes[index], bytes[index+1]);*/
598 #endif
599 
600         err = CODEC_I2C_Send(handle->i2cHandle, handle->config->slaveAddress, 0U, 0U, (void *)(bytes + index), size);
601 
602         if (err != kStatus_Success)
603         {
604 #ifdef TFA9896_PRINT_DEBUG
605             TFA9896_Printf("I2C write error at %d\r\n", size);
606 #endif
607             err = kStatus_TFA9896_I2C_Fatal;
608             break;
609         }
610 #if defined(DEMO_VERBOSE)
611         for (i = 0; i < transfer.dataSize; i++)
612             TFA9896_Printf("[%02x]-", (unsigned char)((unsigned char *)transfer.data + i));
613         TFA9896_Printf("\r\n");
614 #endif
615         index += size;
616     }
617 
618     return err;
619 }
620 
TFA9896_DspWritePreset(tfa9896_handle_t * handle,int length,const unsigned char * pPresetBytes)621 status_t TFA9896_DspWritePreset(tfa9896_handle_t *handle, int length, const unsigned char *pPresetBytes)
622 {
623     status_t error = kStatus_TFA9896_Ok;
624     if (pPresetBytes != 0)
625     {
626         TFA9896_Printf("Bytes to be written_preset_end:%d\n", length);
627         /* by design: keep the data opaque and no interpreting/calculation */
628         error = TFA9896_DspSetParam(handle, MODULE_SPEAKERBOOST, SB_PARAM_SET_PRESET, length, pPresetBytes);
629         TFA9896_Printf("Bytes  written_preset_end:%d\n", length);
630     }
631     else
632     {
633         error = kStatus_TFA9896_Bad_Parameter;
634     }
635     return error;
636 }
637 
TFA9896_DspWriteConfig(tfa9896_handle_t * handle,int length,const unsigned char * pConfigBytes)638 status_t TFA9896_DspWriteConfig(tfa9896_handle_t *handle, int length, const unsigned char *pConfigBytes)
639 {
640     status_t error = kStatus_TFA9896_Ok;
641     TFA9896_Printf("Bytes to be written_config:%d\n", length);
642     error = TFA9896_DspSetParam(handle, MODULE_SPEAKERBOOST, SB_PARAM_SET_CONFIG, length, pConfigBytes);
643     TFA9896_Printf("Bytes to written_config_end:%d\n", length);
644     return error;
645 }
646 
TFA9896_DspWriteSpeakerParameters(tfa9896_handle_t * handle,int length,const unsigned char * pSpeakerBytes)647 status_t TFA9896_DspWriteSpeakerParameters(tfa9896_handle_t *handle, int length, const unsigned char *pSpeakerBytes)
648 {
649     status_t error;
650     if (pSpeakerBytes != 0)
651     {
652         TFA9896_Printf("Bytes to be written_speaker:%d\n", length);
653         /* by design: keep the data opaque and no interpreting/calculation */
654         error = TFA9896_DspSetParam(handle, MODULE_SPEAKERBOOST, SB_PARAM_SET_LSMODEL, length, pSpeakerBytes);
655 
656         TFA9896_Printf("Bytes to written_speaker_end:%d\n", length);
657     }
658     else
659     {
660         error = kStatus_TFA9896_Bad_Parameter;
661     }
662 
663     return error;
664 }
665 
tfa_get_bf_value(const uint16_t bf,const uint16_t reg_value)666 uint16_t tfa_get_bf_value(const uint16_t bf, const uint16_t reg_value)
667 {
668     uint16_t msk, value;
669 
670     /*
671      * bitfield enum:
672      * - 0..3  : len
673      * - 4..7  : pos
674      * - 8..15 : address
675      */
676     uint8_t len = bf & 0x0f;
677     uint8_t pos = (bf >> 4) & 0x0f;
678 
679     msk   = ((1 << (len + 1)) - 1) << pos;
680     value = (reg_value & msk) >> pos;
681 
682     return value;
683 }
684 
685 #ifdef TFA9890_DEVICE
tfa9890_dsp_system_stable(tfa9896_handle_t * handle,int * ready)686 static uint16_t tfa9890_dsp_system_stable(tfa9896_handle_t *handle, int *ready)
687 {
688     char error;
689     unsigned short status, mtp0;
690     int result;
691     uint8_t tries;
692     /************************/
693     result = tfa_read_reg(handle, TFA1_BF_AREFS);
694     if (result < 0)
695     {
696         error = -result;
697         goto errorExit;
698     }
699     status = (unsigned short)result;
700 
701     /* if AMPS is set then we were already configured and running
702      *   no need to check further
703      */
704     *ready = (tfa_get_bf_value(TFA1_BF_AMPS, status) == 1);
705     if (*ready) /* if  ready go back */
706     {
707         return 0; /* will be kStatus_TFA9896_Ok */
708     }
709 
710     /* check AREFS and CLKS: not ready if either is clear */
711     *ready = !((tfa_get_bf_value(TFA1_BF_AREFS, status) == 0) || (tfa_get_bf_value(TFA1_BF_CLKS, status) == 0));
712     if (!*ready) /* if not ready go back */
713     {
714         return 0; /* will be kStatus_TFA9896_Ok */
715     }
716 
717     /* check MTPB
718      *   mtpbusy will be active when the subsys copies MTP to I2C
719      *   2 times retry avoids catching this short mtpbusy active period
720      */
721     for (tries = 2; tries > 0; tries--)
722     {
723         result = TFA9896_GetBits(handle, TFA1_BF_MTPB);
724         if (result < 0)
725         {
726             error = -result;
727             goto errorExit;
728         }
729         status = (unsigned short)result;
730 
731         /* check the contents of the STATUS register */
732         *ready = (status == 0);
733         if (*ready) /* if ready go on */
734         {
735             break;
736         }
737     }
738     if (tries == 0) /* ready will be 0 if retries exausted */
739     {
740         return 0;
741     }
742     /* check the contents of  MTP register for non-zero,
743      *  this indicates that the subsys is ready  */
744 
745     error = TFA9896_ReadRegister(handle, 0x84, &mtp0);
746     if (error)
747     {
748         goto errorExit;
749     }
750 
751     *ready = (mtp0 != 0); /* The MTP register written? */
752 
753     return error;
754 
755 errorExit:
756     *ready = 0;
757     return error;
758 }
759 #endif
760 
setOtc(tfa9896_handle_t * handle,int otcOn)761 status_t setOtc(tfa9896_handle_t *handle, int otcOn)
762 {
763     unsigned short mtp;
764     status_t err;
765     unsigned short status;
766     int mtpChanged = 0;
767     int i;
768 
769     TFA9896_Printf("Inside setOtc\n");
770     err = TFA9896_ReadRegister(handle, 0x80, &mtp);
771     if (err != kStatus_TFA9896_Ok)
772     {
773         return err;
774     }
775     TFA9896_Printf("mtp:%d--mtp & 0x01:%d--otcOn:%d\n", mtp, (mtp & 0x01), otcOn);
776     /* set reset MTPEX bit if needed */
777     if ((mtp & 0x01) != otcOn)
778     {
779         TFA9896_Printf("writing into 0x5A and setting OTC\n");
780         /* need to change the OTC bit, set MTPEX=0 in any case */
781         err = TFA9896_WriteRegister(handle, 0x0B, (uint16_t)0x5A);
782         if (err != kStatus_TFA9896_Ok)
783         {
784             return err;
785         }
786         err = TFA9896_WriteRegister(handle, 0x80, (uint16_t)otcOn);
787         if (err != kStatus_TFA9896_Ok)
788         {
789             return err;
790         }
791         err = TFA9896_WriteRegister(handle, 0x62, 1 << 11);
792         if (err != kStatus_TFA9896_Ok)
793         {
794             return err;
795         }
796         mtpChanged = 1;
797     }
798     do
799     {
800         for (i = 0; i < 0xfff; i++)
801             ;
802         err = TFA9896_ReadRegister(handle, 0x00, &status);
803         if (err != kStatus_TFA9896_Ok)
804         {
805             return err;
806         }
807 
808     } while ((status & 0x100) == 0x100);
809     assert((status & 0x100) == 0);
810     if (mtpChanged)
811     {
812         TFA9896_Printf("writing 0x01 into 0x70\n");
813         err = TFA9896_WriteRegister(handle, 0x70, (uint16_t)0x1);
814         if (err != kStatus_TFA9896_Ok)
815         {
816             return err;
817         }
818     }
819 
820     return kStatus_TFA9896_Ok;
821 }
822 
TFA9896_SetConfigured(tfa9896_handle_t * handle)823 status_t TFA9896_SetConfigured(tfa9896_handle_t *handle)
824 {
825     status_t error;
826     unsigned short value;
827     /* read the SystemControl register, modify the bit and write again */
828     error = TFA9896_ReadRegister(handle, 0x09, &value);
829     if (error != kStatus_TFA9896_Ok)
830     {
831         return error;
832     }
833     value |= 0x20;
834     error = TFA9896_WriteRegister(handle, 0x09, value);
835     return error;
836 }
837 
TFA9896_DspReadMem(tfa9896_handle_t * handle,unsigned short start_offset,int num_words,int * pValues)838 status_t TFA9896_DspReadMem(tfa9896_handle_t *handle, unsigned short start_offset, int num_words, int *pValues)
839 {
840     status_t error = kStatus_TFA9896_Ok;
841     unsigned short cf_ctrl; /* the value to sent to the CF_CONTROLS register */
842     unsigned char bytes[MAX_PARAM_SIZE /*MAX_I2C_LENGTH*/];
843     int burst_size; /* number of words per burst size */
844     int bytes_per_word = 3;
845     int num_bytes;
846     int *p;
847     /* first set DMEM and AIF, leaving other bits intact */
848     error = TFA9896_ReadRegister(handle, 0x70, &cf_ctrl);
849     if (error != kStatus_TFA9896_Ok)
850     {
851         return error;
852     }
853     cf_ctrl &= ~0x000E;          /* clear AIF & DMEM */
854     cf_ctrl |= (DMEM_XMEM << 1); /* set DMEM, leave AIF cleared for autoincrement */
855     error = TFA9896_WriteRegister(handle, 0x70, cf_ctrl);
856     if (error != kStatus_TFA9896_Ok)
857     {
858         return error;
859     }
860     error = TFA9896_WriteRegister(handle, 0x71, start_offset);
861     if (error != kStatus_TFA9896_Ok)
862     {
863         return error;
864     }
865     num_bytes = num_words * bytes_per_word;
866     p         = pValues;
867     for (; num_bytes > 0;)
868     {
869         burst_size = ROUND_DOWN(MAX_I2C_LENGTH, bytes_per_word);
870         if (num_bytes < burst_size)
871         {
872             burst_size = num_bytes;
873         }
874         assert(burst_size <= sizeof(bytes));
875         error = TFA9896_ReadData(handle, 0x72, burst_size, bytes);
876         if (error != kStatus_TFA9896_Ok)
877         {
878             return error;
879         }
880         tfa9896_convert_bytes2data(burst_size, bytes, p);
881         num_bytes -= burst_size;
882         p += burst_size / bytes_per_word;
883     }
884     return kStatus_TFA9896_Ok;
885 }
886 
TFA9896_DspExecuteRpc(tfa9896_handle_t * handle,unsigned char module_id,unsigned char param_id,int num_inbytes,unsigned char indata[],int num_outbytes,unsigned char outdata[])887 status_t TFA9896_DspExecuteRpc(tfa9896_handle_t *handle,
888                                unsigned char module_id,
889                                unsigned char param_id,
890                                int num_inbytes,
891                                unsigned char indata[],
892                                int num_outbytes,
893                                unsigned char outdata[])
894 {
895     status_t error;
896     int rpcStatus = STATUS_OK;
897     int i;
898 
899     /* 1) write the id and data to the DSP XMEM */
900     error = writeParameter(handle, module_id, param_id, num_inbytes, indata);
901 
902     /* 2) wake up the DSP and let it process the data */
903     if (error == kStatus_TFA9896_Ok)
904     {
905         error = executeParam(handle);
906     }
907 
908     /* 3) wait for the ack */
909     if (error == kStatus_TFA9896_Ok)
910     {
911         error = waitResult(handle);
912     }
913 
914     /* 4) check the RPC return value */
915     if (error == kStatus_TFA9896_Ok)
916     {
917         error = checkRpcStatus(handle, &rpcStatus);
918     }
919     if (error == kStatus_TFA9896_Ok)
920     {
921         if (rpcStatus != STATUS_OK)
922         {
923             /* DSP RPC call returned an error */
924             error = (status_t)(rpcStatus + kStatus_TFA9896_RpcBase);
925         }
926     }
927 
928     if (error == kStatus_TFA9896_Ok)
929     {
930         /* 5) read the resulting data */
931         error = TFA9896_WriteRegister(handle, 0x71, 2 /*start_offset*/);
932         if (error != kStatus_TFA9896_Ok)
933         {
934             return error;
935         }
936         /* read in chunks, limited by max I2C length */
937         for (i = 0; i < num_outbytes;)
938         {
939             int burst_size = ROUND_DOWN(MAX_I2C_LENGTH, 3 /*bytes_per_word*/);
940             if ((num_outbytes - i) < burst_size)
941             {
942                 burst_size = num_outbytes - i;
943             }
944             error = TFA9896_ReadData(handle, 0x72, burst_size, outdata + i);
945             if (error != kStatus_TFA9896_Ok)
946             {
947                 return error;
948             }
949             i += burst_size;
950         }
951     }
952 
953     return error;
954 }
955 
TFA9896_CheckICROMversion(tfa9896_handle_t * handle,const unsigned char patchheader[])956 status_t TFA9896_CheckICROMversion(tfa9896_handle_t *handle, const unsigned char patchheader[])
957 {
958     status_t error = kStatus_TFA9896_Ok;
959     unsigned short checkrev;
960     unsigned short checkaddress;
961     int checkvalue;
962     int value = 0;
963     unsigned short status;
964     checkrev = patchheader[0];
965     if ((checkrev != 0xFF) && (checkrev != 0x96))
966     {
967         return kStatus_TFA9896_Not_Supported;
968     }
969     checkaddress = (patchheader[1] << 8) + patchheader[2];
970     checkvalue   = (patchheader[3] << 16) + (patchheader[4] << 8) + patchheader[5];
971     if (checkaddress != 0xFFFF)
972     {
973         /* before reading XMEM, check if we can access the DSP */
974         error = TFA9896_ReadRegister(handle, 0x00, &status);
975         if (error == kStatus_TFA9896_Ok)
976         {
977             if ((status & 0x8000) != 0x8000)
978             {
979                 /* one of Vddd, PLL and clocks not ok */
980                 error = kStatus_TFA9896_DSP_not_running;
981             }
982         }
983         /* read some address register that allows checking the correct ROM version */
984         if (error == kStatus_TFA9896_Ok)
985         {
986             error = TFA9896_DspReadMem(handle, checkaddress, 1, &value);
987         }
988         if (error == kStatus_TFA9896_Ok)
989         {
990             if (value != checkvalue)
991             {
992                 error = kStatus_TFA9896_Not_Supported;
993             }
994         }
995     }
996     return error;
997 }
998 
tfa_write_reg(tfa9896_handle_t * handle,const uint16_t bf,const uint16_t reg_value)999 int tfa_write_reg(tfa9896_handle_t *handle, const uint16_t bf, const uint16_t reg_value)
1000 {
1001     status_t err;
1002 
1003     /* bitfield enum - 8..15 : address */
1004     uint8_t address = (bf >> 8) & 0xff;
1005 
1006     err = TFA9896_WriteRegister(handle, address, reg_value);
1007     if (err)
1008         return -err;
1009 
1010     return 0;
1011 }
1012 
TFA9896_DSP_System_Stable(tfa9896_handle_t * handle,int * ready)1013 status_t TFA9896_DSP_System_Stable(tfa9896_handle_t *handle, int *ready)
1014 {
1015 #ifndef TFA9890_DEVICE
1016     status_t error = kStatus_TFA9896_Ok;
1017     unsigned short status;
1018     int value;
1019 
1020     /* check the contents of the STATUS register */
1021     value = tfa_read_reg(handle, TFA1_BF_AREFS);
1022     if (value < 0)
1023     {
1024         error  = -value;
1025         *ready = 0;
1026         /* an error here can be fatal */
1027         TFA9896_Printf("FATAL ERROR#######\n");
1028         return error;
1029     }
1030     status = (unsigned short)value;
1031 
1032     /* check AREFS and CLKS: not ready if either is clear */
1033     *ready = !((tfa_get_bf_value(TFA1_BF_AREFS, status) == 0) || (tfa_get_bf_value(TFA1_BF_CLKS, status) == 0) ||
1034                (tfa_get_bf_value(TFA1_BF_MTPB, status) == 1));
1035 
1036     return error;
1037 #else
1038     return tfa9890_dsp_system_stable(handle, ready);
1039 #endif
1040 }
1041 
1042 #ifdef TFA9896_DEBUG
stateFlagsStr(int stateFlags)1043 static char *stateFlagsStr(int stateFlags)
1044 {
1045     static char flags[10];
1046 
1047     flags[0] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_ActivityLive)) ? 'A' : 'a';
1048     flags[1] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_S_CtrlLive)) ? 'S' : 's';
1049     flags[2] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_MutedLive)) ? 'M' : 'm';
1050     flags[3] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_X_CtrlLive)) ? 'X' : 'x';
1051     flags[4] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_T_CtrlLive)) ? 'T' : 't';
1052     flags[5] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_NewModelLive)) ? 'L' : 'l';
1053     flags[6] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_VolumeRdyLive)) ? 'V' : 'v';
1054     flags[7] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_DamagedLive)) ? 'D' : 'd';
1055     flags[8] = (stateFlags & (0x1 << tfa9896_SpeakerBoost_SignalClippingLive)) ? 'C' : 'c';
1056 
1057     flags[9] = 0;
1058     return flags;
1059 }
1060 #endif
1061 
1062 /* Execute RPC protocol to read something from the DSP */
TFA9896_DspGetParam(tfa9896_handle_t * handle,unsigned char module_id,unsigned char param_id,int num_bytes,unsigned char data[])1063 status_t TFA9896_DspGetParam(
1064     tfa9896_handle_t *handle, unsigned char module_id, unsigned char param_id, int num_bytes, unsigned char data[])
1065 {
1066     status_t error;
1067     unsigned short cf_ctrl = 0x0002; /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, cf_int=0,
1068                                         cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
1069     unsigned short cf_mad = 0x0001;  /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */
1070     unsigned short cf_status;        /* the contents of the CF_STATUS register */
1071     int rpcStatus = STATUS_OK;
1072 
1073     if (handle->config->slaveAddress == 0x1C)
1074     {
1075         /* cannot read */
1076         return kStatus_TFA9896_Bad_Parameter;
1077     }
1078     error = check_size(DMEM_XMEM, num_bytes);
1079 
1080     if (error == kStatus_TFA9896_Ok)
1081     {
1082         if ((num_bytes <= 0) || (num_bytes > MAX_PARAM_SIZE))
1083         {
1084             return kStatus_TFA9896_Bad_Parameter;
1085         }
1086     }
1087 #ifdef OPTIMIZED_RPC
1088     {
1089         /* minimize the number of I2C transactions by making use of the autoincrement in I2C */
1090         unsigned char buffer[7];
1091         /* first the data for CF_CONTROLS */
1092         buffer[0] = (unsigned char)((cf_ctrl >> 8) & 0xFF);
1093         buffer[1] = (unsigned char)(cf_ctrl & 0xFF);
1094         /* write the contents of CF_MAD which is the subaddress following CF_CONTROLS */
1095         buffer[2] = (unsigned char)((cf_mad >> 8) & 0xFF);
1096         buffer[3] = (unsigned char)(cf_mad & 0xFF);
1097         /* write the module and RPC id into CF_MEM, which follows CF_MAD */
1098         buffer[4] = 0;
1099         buffer[5] = module_id + 128;
1100         buffer[6] = param_id;
1101         error     = TFA9896_WriteData(handle, 0x70, sizeof(buffer), buffer);
1102     }
1103 #else
1104     /* 1) write the id and data to the DSP XMEM */
1105     if (error == kStatus_TFA9896_Ok)
1106     {
1107         error = TFA9896_WriteRegister(handle, 0x70, cf_ctrl);
1108     }
1109     if (error == kStatus_TFA9896_Ok)
1110     {
1111         error = TFA9896_WriteRegister(handle, 0x71, cf_mad);
1112     }
1113     if (error == kStatus_TFA9896_Ok)
1114     {
1115         unsigned char id[3];
1116         id[0] = 0;
1117         id[1] = module_id + 128;
1118         id[2] = param_id;
1119         /* only try MEM once, if error, need to resend mad as well */
1120         error = TFA9896_WriteData(handle, 0x72, 3, id);
1121     }
1122 #endif
1123     /* 2) wake up the DSP and let it process the data */
1124     if (error == kStatus_TFA9896_Ok)
1125     {
1126         cf_ctrl |= (1 << 8) | (1 << 4); /* set the cf_req1 and cf_int bit */
1127 
1128         error = TFA9896_WriteRegister(handle, 0x70, (uint16_t)cf_ctrl);
1129     }
1130     /* 3) wait for the ack */
1131     if (error == kStatus_TFA9896_Ok)
1132     {
1133         int tries = 0;
1134         do
1135         {
1136             error = TFA9896_ReadRegister(handle, 0x73, &cf_status);
1137             tries++;
1138         } while (
1139             (error == kStatus_TFA9896_Ok) && ((cf_status & 0x0100) == 0) &&
1140             (tries < TFA9896_API_WAITRESULT_NTRIES)); /* don't wait forever, DSP is pretty quick to respond (< 1ms) */
1141         if (tries >= TFA9896_API_WAITRESULT_NTRIES)
1142         {
1143             /* something wrong with communication with DSP */
1144             return kStatus_TFA9896_DSP_not_running;
1145         }
1146     }
1147     /* 4) check the RPC return value */
1148     if (error == kStatus_TFA9896_Ok)
1149     {
1150         error = checkRpcStatus(handle, &rpcStatus);
1151     }
1152     if (error == kStatus_TFA9896_Ok)
1153     {
1154         if (rpcStatus != STATUS_OK)
1155         {
1156             /* DSP RPC call returned an error */
1157             error = (status_t)(rpcStatus + kStatus_TFA9896_RpcBase);
1158         }
1159     }
1160     /* 5) read the resulting data */
1161     if (error == kStatus_TFA9896_Ok)
1162     {
1163         cf_mad = 0x0002; /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */
1164         error  = TFA9896_WriteRegister(handle, 0x71, (uint16_t)cf_mad);
1165     }
1166     if (error == kStatus_TFA9896_Ok)
1167     {
1168         int offset          = 0;
1169         int chunk_size      = ROUND_DOWN(NXP_I2C_MAX_SIZE, 3 /* XMEM word size */);
1170         int remaining_bytes = num_bytes;
1171         /* due to autoincrement in cf_ctrl, next write will happen at the next address */
1172         while ((error == kStatus_TFA9896_Ok) && (remaining_bytes > 0))
1173         {
1174             if (remaining_bytes < 252)
1175             {
1176                 chunk_size = remaining_bytes;
1177             }
1178             /* else chunk_size remains at initialize value above*/
1179             error = TFA9896_ReadData(handle, 0x72, chunk_size, data + offset);
1180             remaining_bytes -= chunk_size;
1181             offset += chunk_size;
1182         }
1183     }
1184     return error;
1185 }
1186 
1187 #ifdef TFA9896_LIVEDATA_CAPTURE
TFA9896_DspGetStateInfo(tfa9896_handle_t * handle,tfa9896_StateInfoLive_t * pInfo)1188 status_t TFA9896_DspGetStateInfo(tfa9896_handle_t *handle, tfa9896_StateInfoLive_t *pInfo)
1189 {
1190     status_t error = kStatus_TFA9896_Ok;
1191     int24 data[FW_STATE_MAX_SIZE]; /* allocate worst case */
1192     unsigned char bytes[FW_STATE_MAX_SIZE * 3];
1193     int stateSize =
1194         FW_STATE_SIZE; /* contains the actual amount of parameters transferred, depends on IC and ROM code version */
1195     int i;
1196 
1197     assert(pInfo != 0);
1198 
1199     /* init to default value to have sane values even when some features aren't supported */
1200     for (i = 0; i < FW_STATE_MAX_SIZE; i++)
1201     {
1202         data[i] = 0;
1203     }
1204 
1205     error = TFA9896_DspGetParam(handle, MODULE_FRAMEWORK, FW_PARAM_GET_STATE, 3 * stateSize, bytes);
1206     if (error != kStatus_TFA9896_Ok)
1207     {
1208         if (error == kStatus_TFA9896_RpcParamId)
1209         {
1210             /* old ROM code, ask SpeakerBoost and only do first portion */
1211             stateSize = 8;
1212             error     = TFA9896_DspGetParam(handle, MODULE_SPEAKERBOOST, SB_PARAM_GET_STATE, 3 * stateSize, bytes);
1213         }
1214         else
1215         {
1216             return error;
1217         }
1218     }
1219     tfa9896_convert_bytes2data(3 * stateSize, bytes, data);
1220     pInfo->agcGain    = (float)data[0] / (1 << (23 - SPKRBST_AGCGAIN_EXP)); /* /2^23*2^(SPKRBST_AGCGAIN_EXP) */
1221     pInfo->limGain    = (float)data[1] / (1 << (23 - SPKRBST_LIMGAIN_EXP)); /* /2^23*2^(SPKRBST_LIMGAIN_EXP) */
1222     pInfo->sMax       = (float)data[2] / (1 << (23 - SPKRBST_HEADROOM));    /* /2^23*2^(SPKRBST_HEADROOM)    */
1223     pInfo->T          = data[3] / (1 << (23 - SPKRBST_TEMPERATURE_EXP));    /* /2^23*2^(def.SPKRBST_TEMPERATURE_EXP) */
1224     pInfo->statusFlag = data[4];
1225     pInfo->X1         = (float)data[5] / (1 << (23 - SPKRBST_HEADROOM)); /* /2^23*2^(SPKRBST_HEADROOM)        */
1226 
1227     pInfo->X2          = 0;                                                      /* /2^23*2^(SPKRBST_HEADROOM)        */
1228     pInfo->Re          = (float)data[6] / (1 << (23 - SPKRBST_TEMPERATURE_EXP)); /* /2^23*2^(SPKRBST_TEMPERATURE_EXP) */
1229     pInfo->shortOnMips = data[7];
1230     return error;
1231 }
1232 
dump_state_infoLive(tfa9896_StateInfoLive_t * pState)1233 void dump_state_infoLive(tfa9896_StateInfoLive_t *pState)
1234 {
1235 #ifdef TFA9896_DEBUG
1236     TFA9896_Printf(
1237         "state: flags %s, agcGain %2.1f\tlimGain %2.1f\tsMax %2.1f\tT %d\tX1 %2.1f\tX2 %2.1f\tRe %2.2f\tshortOnMips "
1238         "%d\n",
1239         stateFlagsStr(pState->statusFlag), pState->agcGain, pState->limGain, pState->sMax, pState->T, pState->X1,
1240         pState->X2, pState->Re, pState->shortOnMips);
1241 #endif
1242 }
1243 #endif
1244 
TFA9896_WaitCalibrateDone(tfa9896_handle_t * handle,int * calibrateDone)1245 status_t TFA9896_WaitCalibrateDone(tfa9896_handle_t *handle, int *calibrateDone)
1246 {
1247     status_t err;
1248     int tries = 0;
1249     unsigned short mtp;
1250 #define WAIT_TRIES 30000
1251 
1252     err = TFA9896_ReadRegister(handle, 0x80, &mtp);
1253 
1254     /* in case of calibrate once wait for MTPEX */
1255     if (mtp & 0x1)
1256     {
1257         while ((*calibrateDone == 0) && (tries < TFA9896_API_WAITRESULT_NTRIES))
1258         { /* TODO optimise with wait estimation */
1259             err            = TFA9896_ReadRegister(handle, 0x80, &mtp);
1260             *calibrateDone = (mtp & 0x2); /* check MTP bit1 (MTPEX) */
1261             tries++;
1262         }
1263     }
1264     else /* poll xmem for calibrate always */
1265     {
1266         while ((*calibrateDone == 0) && (tries < WAIT_TRIES))
1267         { /* TODO optimise with wait estimation*/
1268             err = TFA9896_DspReadMem(handle, 231, 1, calibrateDone);
1269             tries++;
1270         }
1271         if (tries == WAIT_TRIES)
1272         {
1273             TFA9896_Printf("calibrateDone 231 timedout\n");
1274         }
1275     }
1276     return err;
1277 }
1278 
TFA9896_DspGetCalibrationImpedance(tfa9896_handle_t * handle,float * pRe25)1279 status_t TFA9896_DspGetCalibrationImpedance(tfa9896_handle_t *handle, float *pRe25)
1280 {
1281     status_t error = kStatus_TFA9896_Ok;
1282     unsigned char bytes[3];
1283     int24 data[1];
1284     int calibrateDone;
1285 
1286     assert(pRe25 != 0);
1287     *pRe25 = 0.0f; /* default 0.0 */
1288     {
1289         error = TFA9896_DspReadMem(handle, 231, 1, &calibrateDone);
1290         if (error == kStatus_TFA9896_Ok)
1291         {
1292             if (!calibrateDone)
1293             {
1294                 /* return the default */
1295                 return error;
1296             }
1297             error = TFA9896_DspGetParam(handle, MODULE_SPEAKERBOOST, 0x85, 3, bytes);
1298         }
1299         if (error == kStatus_TFA9896_Ok)
1300         {
1301             tfa9896_convert_bytes2data(3, bytes, data);
1302             *pRe25 = ((float)data[0] / (1 << (23 - SPKRBST_TEMPERATURE_EXP)) * 1024) /
1303                      1000; /* /2^23*2^(def.SPKRBST_TEMPERATURE_EXP) */
1304         }
1305     }
1306     return error;
1307 }
1308 
TFA9896_DSP_Write_Mem_Word(tfa9896_handle_t * handle,unsigned short address,int value,int memtype)1309 status_t TFA9896_DSP_Write_Mem_Word(tfa9896_handle_t *handle, unsigned short address, int value, int memtype)
1310 {
1311     status_t error = kStatus_TFA9896_Ok;
1312     unsigned char bytes[3];
1313 
1314     TFA9896_SetBits(handle, TFA1_BF_DMEM, (uint16_t)memtype);
1315     error = -tfa_write_reg(handle, TFA1_BF_MADD, address);
1316     if (error != kStatus_TFA9896_Ok)
1317     {
1318         return error;
1319     }
1320     tfa9896_convert_data2bytes(1, &value, bytes);
1321     error = TFA9896_WriteData(handle, 0x720f >> 8, 3, bytes);
1322 
1323     return error;
1324 }
1325 
1326 /*************************/
1327 #ifdef TFA9896_LIVEDATA_CAPTURE
tfa9896GetSpeakerModel(tfa9896_handle_t * handle,int xmodel,tfa9896SPKRBST_SpkrModel_t * record)1328 status_t tfa9896GetSpeakerModel(tfa9896_handle_t *handle, int xmodel, tfa9896SPKRBST_SpkrModel_t *record)
1329 {
1330     status_t error = kStatus_TFA9896_Ok;
1331     unsigned char bytes[3 * 141];
1332     int24 data[141];
1333     int i = 0;
1334 
1335     memset(bytes, 0, 423);
1336 
1337     /*PARAM_GET_LSMODELW*/
1338     error = TFA9896_DspGetParam(handle, 1, PARAM_GET_LSMODEL, 423, bytes);
1339     if (error != kStatus_TFA9896_Ok)
1340     {
1341         return error;
1342     }
1343 
1344     tfa9896_convert_bytes2data(sizeof(bytes), bytes, data);
1345 
1346     for (i = 0; i < 128; i++)
1347     {
1348         /*record->pFIR[i] = (double)data[i] / ((1 << 23) * 2);*/
1349         record->pFIR[i] = (double)data[i] / (1 << 22);
1350     }
1351 
1352     record->Shift_FIR     = data[i++];                        /* Exponent of HX data*/
1353     record->leakageFactor = (float)data[i++] / (1 << (23));   /* Excursion model integration leakage*/
1354     record->ReCorrection  = (float)data[i++] / (1 << (23));   /* Correction factor for Re*/
1355     record->xInitMargin = (float)data[i++] / (1 << (23 - 2)); /* (can change) Margin on excursion model during startup*/
1356     record->xDamageMargin =
1357         (float)data[i++] / (1 << (23 - 2));                /* Margin on excursion modelwhen damage has been detected*/
1358     record->xMargin  = (float)data[i++] / (1 << (23 - 2)); /* Margin on excursion model activated when LookaHead is 0*/
1359     record->Bl       = (float)data[i++] / (1 << (23 - 2)); /* Loudspeaker force factor*/
1360     record->fRes     = data[i++]; /* (can change) Estimated Speaker Resonance Compensation Filter cutoff frequency*/
1361     record->fResInit = data[i++]; /* Initial Speaker Resonance Compensation Filter cutoff frequency*/
1362     record->Qt       = (float)data[i++] / (1 << (23 - 6)); /* Speaker Resonance Compensation Filter Q-factor*/
1363     record->xMax     = (float)data[i++] / (1 << (23 - 7)); /* Maximum excursion of the speaker membrane*/
1364     record->tMax     = (float)data[i++] / (1 << (23 - 9)); /* Maximum Temperature of the speaker coil*/
1365     record->tCoefA   = (float)data[i++] / (1 << 23);       /* (can change) Temperature coefficient*/
1366 
1367     return error;
1368 }
1369 
dump_speaker_model(tfa9896SPKRBST_SpkrModel_t * pState,tfa9896_handle_t * handle)1370 void dump_speaker_model(tfa9896SPKRBST_SpkrModel_t *pState, tfa9896_handle_t *handle)
1371 {
1372     TFA9896_Printf("FRes:%d--SPKS:%d\n", pState->fRes, TFA9896_GetBits(handle, TFA1_BF_SPKS));
1373 }
1374 #endif
1375 
TFA9896_PrintCalibration(tfa9896_handle_t * handle)1376 status_t TFA9896_PrintCalibration(tfa9896_handle_t *handle)
1377 {
1378     status_t err = kStatus_TFA9896_Ok;
1379 #ifdef TFA9896_DEBUG
1380     unsigned char bytes[6] = {0};
1381     int24 data[2];
1382     float mohm;
1383 
1384     err = TFA9896_DspGetParam(handle, MODULE_SPEAKERBOOST, SB_PARAM_GET_RE0, 3, bytes);
1385     if (err != kStatus_TFA9896_Ok)
1386     {
1387         return err;
1388     }
1389 
1390     tfa9896_convert_bytes2data(3, bytes, data);
1391     mohm = ((float)data[0] * 1024) / TFA1_FW_ReZ_SCALE;
1392 
1393     TFA9896_Printf(" Calibrated value :%1.2f mOhms :\n", (mohm * 1024) / 1000);
1394 #endif
1395 
1396     return err;
1397 }
1398 
TFA9896_SetOneTimeCalibration(tfa9896_handle_t * handle)1399 status_t TFA9896_SetOneTimeCalibration(tfa9896_handle_t *handle)
1400 {
1401     unsigned short mtp = 0;
1402     status_t err       = kStatus_TFA9896_Ok;
1403     int tries = 0, mtpBusy = 0;
1404     int i;
1405     /* Read MTP register*/
1406     TFA9896_Printf("totest\n");
1407     /* Set MTPOTC=1*/
1408     mtp |= 0x01;
1409     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0x5A6B);
1410     if (err != kStatus_TFA9896_Ok)
1411     {
1412         return err;
1413     }
1414     err = TFA9896_WriteRegister(handle, 0x0B, (uint16_t)0x005A);
1415     if (err != kStatus_TFA9896_Ok)
1416     {
1417         return err;
1418     }
1419     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0);
1420     if (err != kStatus_TFA9896_Ok)
1421     {
1422         return err;
1423     }
1424     /* Update contents of MTP register*/
1425     err = TFA9896_WriteRegister(handle, 0x80, mtp);
1426     if (err != kStatus_TFA9896_Ok)
1427     {
1428         return err;
1429     }
1430     err = TFA9896_SetBits(handle, TFA1_BF_CIMTP, 0x01);
1431     if (err != kStatus_TFA9896_Ok)
1432     {
1433         return err;
1434     }
1435     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0x5A6B);
1436     if (err != kStatus_TFA9896_Ok)
1437     {
1438         return err;
1439     }
1440     err = TFA9896_WriteRegister(handle, 0x0B, (uint16_t)0);
1441     if (err != kStatus_TFA9896_Ok)
1442     {
1443         return err;
1444     }
1445     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0);
1446     if (err != kStatus_TFA9896_Ok)
1447     {
1448         return err;
1449     }
1450     tries = 0;
1451     do
1452     {
1453         tries++;
1454         for (i = 0; i < 0xfff; i++)
1455             ;
1456         mtpBusy = TFA9896_GetBits(handle, TFA1_BF_MTPB);
1457     } while ((mtpBusy == 0x01) && (tries < TFA9896_API_WAITRESULT_NTRIES));
1458 
1459     if (tries == TFA9896_API_WAITRESULT_NTRIES)
1460     {
1461         TFA9896_Printf("MTP Busy timedout\n");
1462         err = kStatus_TFA9896_StateTimedOut;
1463     }
1464 
1465     return err;
1466 }
1467 
TFA9896_SetFactoryValues(tfa9896_handle_t * handle)1468 status_t TFA9896_SetFactoryValues(tfa9896_handle_t *handle)
1469 {
1470     unsigned short mtp = 0, ron, regRead, xor;
1471     status_t err       = kStatus_TFA9896_Ok;
1472     int tries = 0, mtpBusy = 0;
1473     int i;
1474 
1475     TFA9896_Printf("totest\n");
1476     /*********Hardcoding MTPEX and MTPOTC***************************/
1477     mtp |= 0x03;
1478     /*********Hardcoding Ron  in MTP to 8 ohm***************************/
1479     ron = 0x1F40;
1480     err = TFA9896_ReadRegister(handle, 0x8B, &regRead);
1481     if (err != kStatus_TFA9896_Ok)
1482     {
1483         return err;
1484     }
1485     xor = regRead ^ 0x005A;
1486     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0x5A6B);
1487     if (err != kStatus_TFA9896_Ok)
1488     {
1489         return err;
1490     }
1491     err = TFA9896_WriteRegister(handle, 0x0B, (uint16_t)0x005A);
1492     if (err != kStatus_TFA9896_Ok)
1493     {
1494         return err;
1495     }
1496     err = TFA9896_WriteRegister(handle, 0x60, (uint16_t) xor);
1497     if (err != kStatus_TFA9896_Ok)
1498     {
1499         return err;
1500     }
1501     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0);
1502     if (err != kStatus_TFA9896_Ok)
1503     {
1504         return err;
1505     }
1506     err = TFA9896_ReadRegister(handle, 0x32, &regRead);
1507     if (err != kStatus_TFA9896_Ok)
1508     {
1509         return err;
1510     }
1511     /*Update contents of MTP register*/
1512     err = TFA9896_WriteRegister(handle, 0x83, ron);
1513     if (err != kStatus_TFA9896_Ok)
1514     {
1515         return err;
1516     }
1517     err = TFA9896_WriteRegister(handle, 0x80, mtp);
1518     if (err != kStatus_TFA9896_Ok)
1519     {
1520         return err;
1521     }
1522     err = TFA9896_SetBits(handle, TFA1_BF_CIMTP, 0x01);
1523     if (err != kStatus_TFA9896_Ok)
1524     {
1525         return err;
1526     }
1527     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0x5A6B);
1528     if (err != kStatus_TFA9896_Ok)
1529     {
1530         return err;
1531     }
1532     err = TFA9896_WriteRegister(handle, 0x0B, (uint16_t)0);
1533     if (err != kStatus_TFA9896_Ok)
1534     {
1535         return err;
1536     }
1537     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0);
1538     if (err != kStatus_TFA9896_Ok)
1539     {
1540         return err;
1541     }
1542     tries = 0;
1543     do
1544     {
1545         tries++;
1546         for (i = 0; i < 0xfff; i++)
1547             ;
1548         mtpBusy = TFA9896_GetBits(handle, TFA1_BF_MTPB);
1549     } while ((mtpBusy == 0x01) && (tries < TFA9896_API_WAITRESULT_NTRIES));
1550 
1551     if (tries == TFA9896_API_WAITRESULT_NTRIES)
1552     {
1553         TFA9896_Printf("MTP Busy timedout\n");
1554         err = kStatus_TFA9896_StateTimedOut;
1555     }
1556 
1557     return err;
1558 }
1559 
TFA9896_ClearOneTimeCalibration(tfa9896_handle_t * handle)1560 status_t TFA9896_ClearOneTimeCalibration(tfa9896_handle_t *handle)
1561 {
1562     status_t err = kStatus_TFA9896_Ok;
1563     unsigned short mtp;
1564     int tries = 0, mtpBusy = 0;
1565     int i;
1566 
1567     /* Read MTP register */
1568     err = TFA9896_ReadRegister(handle, 0x80, &mtp);
1569     if (err != kStatus_TFA9896_Ok)
1570     {
1571         return err;
1572     }
1573     /* Set MTPEX=0 and MTPOTC=0 to clear current calibration status*/
1574     mtp &= ~(0x03);
1575     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0x5A6B);
1576     if (err != kStatus_TFA9896_Ok)
1577     {
1578         return err;
1579     }
1580     err = TFA9896_WriteRegister(handle, 0x0B, (uint16_t)0x005A);
1581     if (err != kStatus_TFA9896_Ok)
1582     {
1583         return err;
1584     }
1585     err = TFA9896_WriteRegister(handle, 0x40, (uint16_t)0);
1586     if (err != kStatus_TFA9896_Ok)
1587     {
1588         return err;
1589     }
1590     /* Update contents of MTP register*/
1591     err = TFA9896_WriteRegister(handle, 0x80, mtp);
1592     if (err != kStatus_TFA9896_Ok)
1593     {
1594         return err;
1595     }
1596     err = TFA9896_SetBits(handle, TFA1_BF_CIMTP, 0x01);
1597     if (err != kStatus_TFA9896_Ok)
1598     {
1599         return err;
1600     }
1601 
1602     tries = 0;
1603     do
1604     {
1605         tries++;
1606         for (i = 0; i < 0xfff; i++)
1607             ;
1608         mtpBusy = TFA9896_GetBits(handle, TFA1_BF_MTPB);
1609     } while ((mtpBusy == 0x01) && (tries < TFA9896_API_WAITRESULT_NTRIES));
1610 
1611     if (tries == TFA9896_API_WAITRESULT_NTRIES)
1612     {
1613         TFA9896_Printf("MTP Busy timedout\n");
1614         err = kStatus_TFA9896_StateTimedOut;
1615     }
1616 
1617     return err;
1618 }
1619 
TFA9896_SetOVPBypass(tfa9896_handle_t * handle)1620 status_t TFA9896_SetOVPBypass(tfa9896_handle_t *handle)
1621 {
1622     status_t err;
1623 
1624     unsigned short value, xor;
1625 
1626     /* read the SystemControl register, modify the bit and write again */
1627     err = TFA9896_WriteRegister(handle, 0x40, 0x5A6B);
1628     if (err != kStatus_TFA9896_Ok)
1629     {
1630         return err;
1631     }
1632 
1633     err = TFA9896_ReadRegister(handle, 0x8B, &value);
1634     if (err != kStatus_TFA9896_Ok)
1635     {
1636         return err;
1637     }
1638 
1639     xor = value ^ 0x005A;
1640     err = TFA9896_WriteRegister(handle, 0x60, xor);
1641     if (err != kStatus_TFA9896_Ok)
1642     {
1643         return err;
1644     }
1645 
1646     err = TFA9896_ReadRegister(handle, 0x45, &value);
1647     if (err != kStatus_TFA9896_Ok)
1648     {
1649         return err;
1650     }
1651     TFA9896_Printf("before 0x45 regsiter is:%d\n", value);
1652     value |= (0x01 << 9);
1653 
1654     err = TFA9896_WriteRegister(handle, 0x45, value);
1655     if (err != kStatus_TFA9896_Ok)
1656     {
1657         return err;
1658     }
1659 
1660     err = TFA9896_ReadRegister(handle, 0x45, &value);
1661     if (err != kStatus_TFA9896_Ok)
1662     {
1663         return err;
1664     }
1665 
1666     TFA9896_Printf("after 0x45 regsiter is:%d\n", value);
1667 
1668     return err;
1669 }
1670 
TFA9896_SetMute(tfa9896_handle_t * handle,tfa9896_mute_t mute)1671 status_t TFA9896_SetMute(tfa9896_handle_t *handle, tfa9896_mute_t mute)
1672 {
1673     status_t error;
1674     unsigned short audioctrl_value;
1675     unsigned short sysctrl_value;
1676     error = TFA9896_ReadRegister(handle, TFA9896_AUDIO_CTR, &audioctrl_value);
1677     if (error != kStatus_TFA9896_Ok)
1678     {
1679         return error;
1680     }
1681     error = TFA9896_ReadRegister(handle, TFA9896_SYS_CTRL, &sysctrl_value);
1682 
1683     if (error != kStatus_TFA9896_Ok)
1684     {
1685         return error;
1686     }
1687     switch (mute)
1688     {
1689         case Mute_Off:
1690             /* previous state can be digital or amplifier mute,
1691              * clear the cf_mute and set the enbl_amplifier bits
1692              *
1693              * To reduce PLOP at power on it is needed to switch the
1694              * amplifier on with the DCDC in follower mode (enbl_boost = 0 ?).
1695              * This workaround is also needed when toggling the powerdown bit!
1696              */
1697             audioctrl_value &= ~(TFA9896_AUDIO_CTR_CFSM_MSK);
1698             sysctrl_value |= TFA9896_SYS_CTRL_AMPE_MSK;
1699             sysctrl_value |= TFA9896_SYS_CTRL_DCA_MSK;
1700             break;
1701         case Mute_Digital:
1702             /* expect the amplifier to run */
1703             /* set the cf_mute bit */
1704             audioctrl_value |= TFA9896_AUDIO_CTR_CFSM_MSK;
1705             /* set the enbl_amplifier bit */
1706             sysctrl_value |= (TFA9896_SYS_CTRL_AMPE_MSK);
1707             /* clear active mode */
1708             sysctrl_value &= ~(TFA9896_SYS_CTRL_DCA_MSK);
1709             break;
1710         case Mute_Amplifier:
1711             /* clear the cf_mute bit */
1712             audioctrl_value &= ~TFA9896_AUDIO_CTR_CFSM_MSK;
1713             /* clear the enbl_amplifier bit and active mode */
1714             sysctrl_value &= ~(TFA9896_SYS_CTRL_AMPE_MSK | TFA9896_SYS_CTRL_DCA_MSK);
1715             break;
1716         default:
1717             error = kStatus_TFA9896_Bad_Parameter;
1718     }
1719     if (error != kStatus_TFA9896_Ok)
1720     {
1721         return error;
1722     }
1723     error = TFA9896_WriteRegister(handle, TFA9896_AUDIO_CTR, audioctrl_value);
1724     if (error != kStatus_TFA9896_Ok)
1725     {
1726         return error;
1727     }
1728     error = TFA9896_WriteRegister(handle, TFA9896_SYS_CTRL, sysctrl_value);
1729 
1730     return error;
1731 }
1732