1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016 Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 **
13 ** You should have received a copy of the GNU General Public License along with
14 ** this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15 ** Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 **
17 ** File:
18 ** tas2555-core.c
19 **
20 ** Description:
21 ** TAS2555 common functions for Android Linux
22 **
23 ** =============================================================================
24 */
26 #define DEBUG
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/init.h>
30 #include <linux/delay.h>
31 #include <linux/pm.h>
32 #include <linux/i2c.h>
33 #include <linux/gpio.h>
34 #include <linux/regulator/consumer.h>
35 #include <linux/firmware.h>
36 #include <linux/regmap.h>
37 #include <linux/of.h>
38 #include <linux/of_gpio.h>
39 #include <linux/slab.h>
40 #include <linux/syscalls.h>
41 #include <linux/fcntl.h>
42 #include <asm/uaccess.h>
44 #include "tas2555.h"
45 #include "tas2555-core.h"
47 #define TAS2555_CAL_NAME "/data/tas2555_cal.bin"
49 //set default PLL CLKIN to GPI2 (MCLK) = 0x00
50 #define TAS2555_DEFAULT_PLL_CLKIN 0x00
52 static void tas2555_load_calibration(struct tas2555_priv *pTAS2555,
53 char *pFileName);
54 static void tas2555_load_data(struct tas2555_priv *pTAS2555, TData * pData,
55 unsigned int nType);
56 static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock);
57 static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
58 unsigned int nConfiguration, bool bLoadSame);
60 #define TAS2555_UDELAY 0xFFFFFFFE
62 #define FW_ERR_HEADER -1
63 #define FW_ERR_SIZE -2
65 #define TAS2555_BLOCK_PLL 0x00
66 #define TAS2555_BLOCK_MAIN_DEV_A 0x01
67 #define TAS2555_BLOCK_MAIN_DEV_B 0x08
68 #define TAS2555_BLOCK_COEFF_DEV_A 0x03
69 #define TAS2555_BLOCK_COEFF_DEV_B 0x0a
70 #define TAS2555_BLOCK_PRE_DEV_A 0x04
71 #define TAS2555_BLOCK_PRE_DEV_B 0x0B
72 #define TAS2555_BLOCK_POST 0x05
73 #define TAS2555_BLOCK_POST_POWER_UP 0x06
75 static unsigned int p_tas2555_default_data[] = {
76 channel_both, TAS2555_ASI1_DAC_FORMAT_REG, 0x10, //ASI1 DAC word length = 24 bits
78 channel_both, TAS2555_PLL_CLKIN_REG, TAS2555_DEFAULT_PLL_CLKIN, //PLL_CLKIN = GPIO1 (BCLK)
79 channel_both, TAS2555_MAIN_CLKIN_REG, 0x0F, //NDIV_MUX_CLKIN = PLL_CLK
80 channel_both, TAS2555_PLL_P_VAL_REG, 0x01, //PLL P = 1
81 // TAS2555_PLL_J_VAL_REG, 0x10, //PLL J = 16
82 channel_both, TAS2555_PLL_J_VAL_REG, 0x30, //PLL J = 48 -> PLL_CLK = 1.536MHz * 48 = 73.728MHz
83 channel_both, TAS2555_PLL_D_VAL_MSB_REG, 0x00, //PLL D = 0
84 channel_both, TAS2555_PLL_D_VAL_LSB_REG, 0x00,
85 channel_both, TAS2555_PLL_N_VAL_REG, 0x03, //PLL N = 3 -> NDIV_CLK = 24.576MHz
86 channel_both, TAS2555_DAC_MADC_VAL_REG, 0x08, //MDAC = 8
87 channel_both, TAS2555_CLK_MISC_REG, 0x20, //DSP CLK = PLL out
88 // TAS2555_ISENSE_DIV_REG, 0x40, //Isense div and MADC final divider configure auto
89 channel_both, TAS2555_ISENSE_DIV_REG, 0x00, //Isense div and MADC final divider configure auto
90 // TAS2555_RAMP_CLK_DIV_LSB_REG, 0x20, //ramp_clk divider = 32 so that 12.288MHz/32 = 384KHz
91 channel_both, TAS2555_RAMP_CLK_DIV_LSB_REG, 0x40, //ramp_clk divider = 64 so that 24.576MHz/64 = 384KHz
92 channel_both, TAS2555_DSP_MODE_SELECT_REG, 0x22, //DSP ROM mode 2, default coeffs
94 // TAS2555_SPK_CTRL_REG, 0x74, //DAC channel gain
95 channel_both, TAS2555_SPK_CTRL_REG, 0x7C, //DAC channel gain
96 // TAS2555_POWER_CTRL2_REG, 0xA3, //power up
97 // TAS2555_POWER_CTRL1_REG, 0xF8, //power up
98 // TAS2555_MUTE_REG, 0x00, //unmute
99 // TAS2555_SOFT_MUTE_REG, 0x00, //soft unmute
100 // TAS2555_CLK_ERR_CTRL, 0x09, //enable clock error detection on PLL
101 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
102 };
104 #define TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX 5
105 static unsigned int p_tas2555_startup_data[] = {
106 channel_both, TAS2555_CLK_ERR_CTRL, 0x00, //disable clock error detection on PLL
107 channel_both, TAS2555_PLL_CLKIN_REG, TAS2555_DEFAULT_PLL_CLKIN,
108 channel_both, TAS2555_POWER_CTRL2_REG, 0xA0, //Class-D, Boost power up
109 channel_both, TAS2555_POWER_CTRL2_REG, 0xA3, //Class-D, Boost, IV sense power up
110 channel_both, TAS2555_POWER_CTRL1_REG, 0xF8, //PLL, DSP, clock dividers power up
111 channel_both, TAS2555_UDELAY, 2000, //delay
112 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
113 };
115 static unsigned int p_tas2555_unmute_data[] = {
116 channel_both, TAS2555_MUTE_REG, 0x00, //unmute
117 channel_both, TAS2555_SOFT_MUTE_REG, 0x00, //soft unmute
118 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
119 };
121 static unsigned int p_tas2555_shutdown_data[] = {
122 channel_both, TAS2555_SOFT_MUTE_REG, 0x01, //soft mute
123 channel_both, TAS2555_UDELAY, 10000, //delay 10ms
124 channel_both, TAS2555_MUTE_REG, 0x03, //mute
125 channel_both, TAS2555_PLL_CLKIN_REG, 0x0F, //PLL clock input = osc
126 channel_both, TAS2555_POWER_CTRL1_REG, 0x60, //DSP power down
127 channel_both, TAS2555_UDELAY, 2000, //delay 2ms
128 channel_both, TAS2555_POWER_CTRL2_REG, 0x00, //Class-D, Boost power down
129 channel_both, TAS2555_POWER_CTRL1_REG, 0x00, //all power down
130 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
131 };
134 static unsigned int p_tas2555_mute_DSP_down_data[] = {
135 channel_both, TAS2555_MUTE_REG, 0x03, //mute
136 channel_both, TAS2555_PLL_CLKIN_REG, 0x0F, //PLL clock input = osc
137 channel_both, TAS2555_POWER_CTRL1_REG, 0x60, //DSP power down
138 channel_both, TAS2555_UDELAY, 0xFF, //delay
139 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
140 };
142 static int tas2555_dev_load_data(struct tas2555_priv *pTAS2555,
143 unsigned int *pData)
144 {
145 int ret = 0;
146 unsigned int n = 0;
147 enum channel chl;
148 unsigned int nRegister;
149 unsigned int nData;
151 do {
152 chl = pData[n * 3];
153 nRegister = pData[n * 3 + 1];
154 nData = pData[n * 3 + 2];
155 if (nRegister == TAS2555_UDELAY)
156 udelay(nData);
157 else if (nRegister != 0xFFFFFFFF){
158 ret = pTAS2555->write(pTAS2555, chl, nRegister, nData);
159 if(ret < 0) {
160 dev_err(pTAS2555->dev, "Reg Write err %d\n", ret);
161 break;
162 }
163 }
164 n++;
165 } while (nRegister != 0xFFFFFFFF);
167 return ret;
168 }
170 int tas2555_load_default(struct tas2555_priv *pTAS2555)
171 {
172 return tas2555_dev_load_data(pTAS2555, p_tas2555_default_data);
173 }
175 void tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable)
176 {
177 dev_dbg(pTAS2555->dev, "Enable: %d\n", bEnable);
178 if (bEnable) {
179 if (!pTAS2555->mbPowerUp) {
180 TConfiguration *pConfiguration;
182 if (!pTAS2555->mbCalibrationLoaded) {
183 tas2555_load_calibration(pTAS2555, TAS2555_CAL_NAME);
184 pTAS2555->mbCalibrationLoaded = true;
185 }
186 dev_dbg(pTAS2555->dev, "Enable: load startup sequence\n");
187 tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
188 if (pTAS2555->mpFirmware->mpConfigurations) {
189 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]);
190 tas2555_load_data(pTAS2555, &(pConfiguration->mData),
191 TAS2555_BLOCK_POST_POWER_UP);
192 if (pTAS2555->mbLoadConfigurationPostPowerUp) {
193 dev_dbg(pTAS2555->dev, "Enable: load configuration: %s, %s\n",
194 pConfiguration->mpName, pConfiguration->mpDescription);
195 tas2555_load_data(pTAS2555, &(pConfiguration->mData),
196 TAS2555_BLOCK_COEFF_DEV_A);
197 tas2555_load_data(pTAS2555, &(pConfiguration->mData),
198 TAS2555_BLOCK_COEFF_DEV_B);
199 pTAS2555->mbLoadConfigurationPostPowerUp = false;
200 if (pTAS2555->mpCalFirmware->mnCalibrations) {
201 dev_dbg(pTAS2555->dev, "Enable: load calibration\n");
202 tas2555_load_block(pTAS2555,
203 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
204 pTAS2555->mbLoadCalibrationPostPowerUp = false;
205 }
206 }else{
207 if (pTAS2555->mpCalFirmware->mnCalibrations) {
208 if(pTAS2555->mbLoadCalibrationPostPowerUp){
209 dev_dbg(pTAS2555->dev, "Enable: load calibration\n");
210 tas2555_load_block(pTAS2555,
211 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
212 pTAS2555->mbLoadCalibrationPostPowerUp = false;
213 }
214 }
215 }
216 }
217 dev_dbg(pTAS2555->dev, "Enable: load unmute sequence\n");
218 tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
219 pTAS2555->mbPowerUp = true;
220 }
221 } else {
222 if (pTAS2555->mbPowerUp) {
223 dev_dbg(pTAS2555->dev, "Enable: load shutdown sequence\n");
224 tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data);
225 //tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_clk_err);
226 pTAS2555->mbPowerUp = false;
227 }
228 }
229 }
231 int tas2555_set_bit_rate(struct tas2555_priv *pTAS2555,
232 enum channel chn, unsigned int nBitRate)
233 {
234 int ret = 0, n = -1;
236 dev_dbg(pTAS2555->dev, "tas2555_set_bit_rate: nBitRate = %d \n",
237 nBitRate);
238 switch(nBitRate){
239 case 16:
240 n = 0;
241 break;
242 case 20:
243 n = 1;
244 break;
245 case 24:
246 n = 2;
247 break;
248 case 32:
249 n = 3;
250 break;
251 }
253 if(n >= 0)
254 ret = pTAS2555->update_bits(pTAS2555, chn,
255 TAS2555_ASI1_DAC_FORMAT_REG, 0x18, n<<3);
257 return ret;
258 }
260 int tas2555_get_bit_rate(struct tas2555_priv *pTAS2555,
261 enum channel chn, unsigned char *pBitRate)
262 {
263 int ret = 0;
264 unsigned int nValue = 0;
265 unsigned char bitRate;
267 ret = pTAS2555->read(pTAS2555, chn,
268 TAS2555_ASI1_DAC_FORMAT_REG, &nValue);
269 if(ret >=0){
270 bitRate = (nValue&0x18)>>3;
271 if(bitRate == 0) bitRate = 16;
272 else if(bitRate == 1) bitRate = 20;
273 else if(bitRate == 2) bitRate = 24;
274 else if(bitRate == 3) bitRate = 32;
276 *pBitRate = bitRate;
277 }else{
278 dev_err(pTAS2555->dev, "read left channel error %d\n", ret);
279 }
281 return ret;
282 }
284 int tas2555_get_DAC_gain(struct tas2555_priv *pTAS2555, enum channel chl, unsigned char *pnGain)
285 {
286 int ret = 0;
287 unsigned int nValue = 0;
289 ret = pTAS2555->read(pTAS2555, chl,
290 TAS2555_SPK_CTRL_REG, &nValue);
291 if(ret >=0){
292 *pnGain =
293 ((nValue&TAS2555_DAC_GAIN_MASK)>>TAS2555_DAC_GAIN_SHIFT);
294 }
296 return ret;
297 }
299 int tas2555_set_DAC_gain(struct tas2555_priv *pTAS2555, enum channel chl, unsigned int nGain)
300 {
301 int ret = 0;
303 ret = pTAS2555->update_bits(pTAS2555, chl,
304 TAS2555_SPK_CTRL_REG,
305 TAS2555_DAC_GAIN_MASK,
306 (nGain<<TAS2555_DAC_GAIN_SHIFT));
308 return ret;
309 }
311 int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, unsigned int nSamplingRate)
312 {
313 TConfiguration *pConfiguration;
314 unsigned int nConfiguration;
316 dev_dbg(pTAS2555->dev, "tas2555_setup_clocks: nSamplingRate = %d [Hz]\n",
317 nSamplingRate);
319 if ((!pTAS2555->mpFirmware->mpPrograms) ||
320 (!pTAS2555->mpFirmware->mpConfigurations)) {
321 dev_err(pTAS2555->dev, "Firmware not loaded\n");
322 return -EINVAL;
323 }
325 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]);
326 if (pConfiguration->mnSamplingRate == nSamplingRate) {
327 dev_info(pTAS2555->dev, "Sampling rate for current configuration matches: %d\n",
328 nSamplingRate);
329 return 0;
330 }
332 for (nConfiguration = 0;
333 nConfiguration < pTAS2555->mpFirmware->mnConfigurations;
334 nConfiguration++) {
335 pConfiguration =
336 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
337 if ((pConfiguration->mnSamplingRate == nSamplingRate)
338 &&(pConfiguration->mnProgram == pTAS2555->mnCurrentProgram)){
339 dev_info(pTAS2555->dev,
340 "Found configuration: %s, with compatible sampling rate %d\n",
341 pConfiguration->mpName, nSamplingRate);
342 tas2555_load_configuration(pTAS2555, nConfiguration, false);
343 return 0;
344 }
345 }
347 dev_err(pTAS2555->dev, "Cannot find a configuration that supports sampling rate: %d\n",
348 nSamplingRate);
350 return -EINVAL;
351 }
353 static void fw_print_header(struct tas2555_priv *pTAS2555, TFirmware * pFirmware)
354 {
355 dev_info(pTAS2555->dev, " FW Size = %d", pFirmware->mnFWSize);
356 dev_info(pTAS2555->dev, " Checksum = 0x%04X", pFirmware->mnChecksum);
357 dev_info(pTAS2555->dev, " PPC Version = 0x%04X", pFirmware->mnPPCVersion);
358 dev_info(pTAS2555->dev, " DSPFWVersion = 0x%04X", pFirmware->mnDSPFWVersion);
359 dev_info(pTAS2555->dev, " DRVFWVersion = 0x%04X", pFirmware->mnDrvFWVersion);
360 dev_info(pTAS2555->dev, " Timestamp = %d", pFirmware->mnTimeStamp);
361 dev_info(pTAS2555->dev, " DDC Name = %s", pFirmware->mpDDCName);
362 dev_info(pTAS2555->dev, " Description = %s", pFirmware->mpDescription);
363 }
365 inline unsigned int fw_convert_number(unsigned char *pData)
366 {
367 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
368 }
370 static int fw_parse_header(struct tas2555_priv *pTAS2555,
371 TFirmware * pFirmware, unsigned char *pData,
372 unsigned int nSize)
373 {
374 unsigned char *pDataStart = pData;
375 unsigned int n;
376 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
377 if (nSize < 104) {
378 dev_err(pTAS2555->dev, "Firmware: Header too short");
379 return -1;
380 }
382 if (memcmp(pData, pMagicNumber, 4)) {
383 dev_err(pTAS2555->dev, "Firmware: Magic number doesn't match");
384 return -1;
385 }
387 pData += 4;
389 pFirmware->mnFWSize = fw_convert_number(pData);
390 pData += 4;
392 pFirmware->mnChecksum = fw_convert_number(pData);
393 pData += 4;
395 pFirmware->mnPPCVersion = fw_convert_number(pData);
396 pData += 4;
398 pFirmware->mnDSPFWVersion = fw_convert_number(pData);
399 pData += 4;
401 pFirmware->mnDrvFWVersion = fw_convert_number(pData);
402 pData += 4;
404 pFirmware->mnTimeStamp = fw_convert_number(pData);
405 pData += 4;
407 memcpy(pFirmware->mpDDCName, pData, 64);
408 pData += 64;
410 n = strlen(pData);
411 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
412 pData += n + 1;
414 if ((pData - pDataStart) >= nSize) {
415 dev_err(pTAS2555->dev, "Firmware: Header too short after DDC description");
416 return -1;
417 }
419 pFirmware->mnDeviceFamily = fw_convert_number(pData);
420 pData += 4;
422 pFirmware->mnDevice = fw_convert_number(pData);
423 pData += 4;
425 fw_print_header(pTAS2555, pFirmware);
427 return pData - pDataStart;
428 }
430 static int fw_parse_block_data(struct tas2555_priv *pTAS2555,
431 TBlock * pBlock, unsigned char *pData)
432 {
433 unsigned char *pDataStart = pData;
434 unsigned int n;
436 pBlock->mnType = fw_convert_number(pData);
437 pData += 4;
439 dev_dbg(pTAS2555->dev, "TBlock type[%d]\n", pBlock->mnType);
441 pBlock->mnCommands = fw_convert_number(pData);
442 pData += 4;
444 n = pBlock->mnCommands * 4;
445 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
446 pData += n;
448 return pData - pDataStart;
449 }
451 static int fw_parse_data(struct tas2555_priv *pTAS2555,
452 TData * pImageData, unsigned char *pData)
453 {
454 unsigned char *pDataStart = pData;
455 unsigned int nBlock;
456 unsigned int n;
458 memcpy(pImageData->mpName, pData, 64);
459 pData += 64;
461 n = strlen(pData);
462 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
463 pData += n + 1;
465 dev_dbg(pTAS2555->dev, "TData name=%s\n", pImageData->mpName);
466 dev_dbg(pTAS2555->dev, "TData Desc=%s\n", pImageData->mpDescription);
468 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
469 pData += 2;
471 pImageData->mpBlocks =
472 kmalloc(sizeof(TBlock) * pImageData->mnBlocks, GFP_KERNEL);
474 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
475 n = fw_parse_block_data(pTAS2555,
476 &(pImageData->mpBlocks[nBlock]), pData);
477 pData += n;
478 }
480 return pData - pDataStart;
481 }
483 static int fw_parse_pll_data(struct tas2555_priv *pTAS2555,
484 TFirmware * pFirmware, unsigned char *pData)
485 {
486 unsigned char *pDataStart = pData;
487 unsigned int n;
488 unsigned int nPLL;
489 TPLL *pPLL;
491 pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
492 pData += 2;
494 pFirmware->mpPLLs = kmalloc(sizeof(TPLL) * pFirmware->mnPLLs, GFP_KERNEL);
495 for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
496 pPLL = &(pFirmware->mpPLLs[nPLL]);
498 memcpy(pPLL->mpName, pData, 64);
499 pData += 64;
501 n = strlen(pData);
502 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
503 pData += n + 1;
505 dev_dbg(pTAS2555->dev, "PLL[%d] Name=%s\n", nPLL, pPLL->mpName);
506 dev_dbg(pTAS2555->dev, "PLL[%d] Desc=%s\n", nPLL, pPLL->mpDescription);
507 n = fw_parse_block_data(pTAS2555, &(pPLL->mBlock), pData);
508 pData += n;
509 }
511 return pData - pDataStart;
512 }
514 static int fw_parse_program_data(struct tas2555_priv *pTAS2555,
515 TFirmware * pFirmware, unsigned char *pData)
516 {
517 unsigned char *pDataStart = pData;
518 unsigned int n;
519 unsigned int nProgram;
520 TProgram *pProgram;
522 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
523 pData += 2;
525 pFirmware->mpPrograms =
526 kmalloc(sizeof(TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
527 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
528 pProgram = &(pFirmware->mpPrograms[nProgram]);
529 memcpy(pProgram->mpName, pData, 64);
530 pData += 64;
532 n = strlen(pData);
533 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
534 pData += n + 1;
536 dev_dbg(pTAS2555->dev, "Program[%d] Name=%s\n", nProgram, pProgram->mpName);
537 dev_dbg(pTAS2555->dev, "Program[%d] Desc=%s\n", nProgram, pProgram->mpDescription);
539 n = fw_parse_data(pTAS2555, &(pProgram->mData), pData);
540 pData += n;
541 }
543 return pData - pDataStart;
544 }
546 static int fw_parse_configuration_data(struct tas2555_priv *pTAS2555,
547 TFirmware * pFirmware,
548 unsigned char *pData)
549 {
550 unsigned char *pDataStart = pData;
551 unsigned int n;
552 unsigned int nConfiguration;
553 TConfiguration *pConfiguration;
555 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
556 pData += 2;
558 pFirmware->mpConfigurations =
559 kmalloc(sizeof(TConfiguration) * pFirmware->mnConfigurations,
560 GFP_KERNEL);
561 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
562 nConfiguration++) {
563 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
564 memcpy(pConfiguration->mpName, pData, 64);
565 pData += 64;
567 n = strlen(pData);
568 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
569 pData += n + 1;
571 pConfiguration->mnProgram = pData[0];
572 pData++;
574 dev_dbg(pTAS2555->dev, "Configuration[%d] Name=%s\n", nConfiguration, pConfiguration->mpName);
575 dev_dbg(pTAS2555->dev, "Configuration[%d] Desc=%s\n", nConfiguration, pConfiguration->mpDescription);
577 pConfiguration->mnPLL = pData[0];
578 pData++;
580 pConfiguration->mnSamplingRate = fw_convert_number(pData);
581 pData += 4;
583 n = fw_parse_data(pTAS2555, &(pConfiguration->mData), pData);
584 pData += n;
585 }
587 return pData - pDataStart;
588 }
590 int fw_parse_calibration_data(struct tas2555_priv *pTAS2555,
591 TFirmware * pFirmware, unsigned char *pData)
592 {
593 unsigned char *pDataStart = pData;
594 unsigned int n;
595 unsigned int nCalibration;
596 TCalibration *pCalibration;
598 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
599 pData += 2;
601 pFirmware->mpCalibrations =
602 kmalloc(sizeof(TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
603 for (nCalibration = 0;
604 nCalibration < pFirmware->mnCalibrations;
605 nCalibration++) {
606 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
607 memcpy(pCalibration->mpName, pData, 64);
608 pData += 64;
610 n = strlen(pData);
611 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
612 pData += n + 1;
614 pCalibration->mnProgram = pData[0];
615 pData++;
617 pCalibration->mnConfiguration = pData[0];
618 pData++;
620 n = fw_parse_block_data(pTAS2555, &(pCalibration->mBlock), pData);
621 pData += n;
622 }
624 return pData - pDataStart;
625 }
627 static int fw_parse(struct tas2555_priv *pTAS2555,
628 TFirmware * pFirmware,
629 unsigned char *pData,
630 unsigned int nSize)
631 {
632 int nPosition = 0;
634 nPosition = fw_parse_header(pTAS2555, pFirmware, pData, nSize);
635 if (nPosition < 0) {
636 dev_err(pTAS2555->dev, "Firmware: Wrong Header");
637 return FW_ERR_HEADER;
638 }
640 if (nPosition >= nSize) {
641 dev_err(pTAS2555->dev, "Firmware: Too short");
642 return FW_ERR_SIZE;
643 }
645 pData += nPosition;
646 nSize -= nPosition;
647 nPosition = 0;
649 nPosition = fw_parse_pll_data(pTAS2555, pFirmware, pData);
651 pData += nPosition;
652 nSize -= nPosition;
653 nPosition = 0;
655 nPosition = fw_parse_program_data(pTAS2555, pFirmware, pData);
657 pData += nPosition;
658 nSize -= nPosition;
659 nPosition = 0;
661 nPosition = fw_parse_configuration_data(pTAS2555, pFirmware, pData);
663 pData += nPosition;
664 nSize -= nPosition;
665 nPosition = 0;
667 if (nSize > 64)
668 nPosition = fw_parse_calibration_data(pTAS2555, pFirmware, pData);
670 return 0;
671 }
673 static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
674 {
675 unsigned int nCommand = 0;
676 unsigned char nBook;
677 unsigned char nPage;
678 unsigned char nOffset;
679 unsigned char nData;
680 unsigned int nLength;
681 enum channel chl;
682 unsigned char *pData = pBlock->mpData;
684 dev_dbg(pTAS2555->dev, "TAS2555 load block: Type = %d, commands = %d\n",
685 pBlock->mnType, pBlock->mnCommands);
687 if((pBlock->mnType == TAS2555_BLOCK_PLL)
688 ||(pBlock->mnType == TAS2555_BLOCK_POST)
689 ||(pBlock->mnType == TAS2555_BLOCK_POST_POWER_UP)){
690 chl = channel_both;
691 }else if((pBlock->mnType == TAS2555_BLOCK_MAIN_DEV_A)
692 ||(pBlock->mnType == TAS2555_BLOCK_COEFF_DEV_A)
693 ||(pBlock->mnType == TAS2555_BLOCK_PRE_DEV_A)){
694 chl = channel_left;
695 }else if((pBlock->mnType == TAS2555_BLOCK_MAIN_DEV_B)
696 ||(pBlock->mnType == TAS2555_BLOCK_COEFF_DEV_B)
697 ||(pBlock->mnType == TAS2555_BLOCK_PRE_DEV_B)){
698 chl = channel_right;
699 }else{
700 dev_err(pTAS2555->dev, "block type error %d\n", pBlock->mnType);
701 return;
702 }
704 while (nCommand < pBlock->mnCommands) {
705 pData = pBlock->mpData + nCommand * 4;
707 nBook = pData[0];
708 nPage = pData[1];
709 nOffset = pData[2];
710 nData = pData[3];
712 nCommand++;
714 if (nOffset <= 0x7F){
715 pTAS2555->write(pTAS2555,
716 chl,
717 TAS2555_REG(nBook, nPage, nOffset),
718 nData);
719 }else if (nOffset == 0x81) {
720 unsigned int nSleep = (nBook << 8) + nPage;
721 msleep(nSleep);
722 }else if (nOffset == 0x85) {
723 pData += 4;
724 nLength = (nBook << 8) + nPage;
725 nBook = pData[0];
726 nPage = pData[1];
727 nOffset = pData[2];
728 if (nLength > 1)
729 pTAS2555->bulk_write(pTAS2555,
730 chl,
731 TAS2555_REG(nBook, nPage, nOffset),
732 pData + 3,
733 nLength);
734 else
735 pTAS2555->write(pTAS2555,
736 chl,
737 TAS2555_REG(nBook, nPage, nOffset),
738 pData[3]);
740 nCommand++;
741 if (nLength >= 2)
742 nCommand += ((nLength - 2) / 4) + 1;
743 }
744 }
745 }
747 static void tas2555_load_data(struct tas2555_priv *pTAS2555, TData * pData,
748 unsigned int nType)
749 {
750 unsigned int nBlock;
751 TBlock *pBlock;
753 dev_dbg(pTAS2555->dev,
754 "TAS2555 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName,
755 pData->mnBlocks, nType);
757 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
758 pBlock = &(pData->mpBlocks[nBlock]);
759 if (pBlock->mnType == nType)
760 tas2555_load_block(pTAS2555, pBlock);
761 }
762 }
764 static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
765 unsigned int nConfiguration, bool bLoadSame)
766 {
767 TConfiguration *pCurrentConfiguration;
768 TConfiguration *pNewConfiguration;
769 TPLL *pNewPLL;
771 dev_dbg(pTAS2555->dev, "tas2555_load_configuration: %d\n", nConfiguration);
773 if ((!pTAS2555->mpFirmware->mpPrograms) ||
774 (!pTAS2555->mpFirmware->mpConfigurations)) {
775 dev_err(pTAS2555->dev, "Firmware not loaded\n");
776 return;
777 }
779 if (nConfiguration >= pTAS2555->mpFirmware->mnConfigurations) {
780 dev_err(pTAS2555->dev, "Configuration %d doesn't exist\n",
781 nConfiguration);
782 return;
783 }
785 if ((nConfiguration == pTAS2555->mnCurrentConfiguration) && (!bLoadSame)) {
786 dev_info(pTAS2555->dev, "Configuration %d is already loaded\n",
787 nConfiguration);
788 return;
789 }
791 pCurrentConfiguration =
792 &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]);
793 pNewConfiguration =
794 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
796 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
797 dev_err(pTAS2555->dev,
798 "Configuration %d, %s doesn't share the same program as current %d\n",
799 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
800 return;
801 }
803 if (pNewConfiguration->mnPLL >= pTAS2555->mpFirmware->mnPLLs) {
804 dev_err(pTAS2555->dev,
805 "Configuration %d, %s doesn't have a valid PLL index %d\n",
806 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
807 return;
808 }
810 pNewPLL = &(pTAS2555->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
812 if (pTAS2555->mbPowerUp) {
813 if (pNewConfiguration->mnPLL != pCurrentConfiguration->mnPLL) {
814 dev_dbg(pTAS2555->dev,
815 "TAS2555 is powered up -> mute and power down DSP before loading new configuration\n");
816 //tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data);
817 tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data);
819 dev_dbg(pTAS2555->dev,
820 "load post block from current configuration: %s, before loading new configuration: %s\n",
821 pCurrentConfiguration->mpName, pNewConfiguration->mpName);
822 tas2555_load_data(pTAS2555, &(pCurrentConfiguration->mData),
823 TAS2555_BLOCK_POST);
824 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n",
825 pNewPLL->mpName);
826 tas2555_load_block(pTAS2555, &(pNewPLL->mBlock));
827 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
828 dev_dbg(pTAS2555->dev,
829 "load new configuration: %s, pre block data\n",
830 pNewConfiguration->mpName);
831 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
832 TAS2555_BLOCK_PRE_DEV_A);
833 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
834 TAS2555_BLOCK_PRE_DEV_B);
835 dev_dbg(pTAS2555->dev, "TAS2555: power up TAS2555\n");
836 tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
837 dev_dbg(pTAS2555->dev,
838 "TAS2555: load new configuration: %s, post power up block data\n",
839 pNewConfiguration->mpName);
840 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
841 TAS2555_BLOCK_POST_POWER_UP);
842 dev_dbg(pTAS2555->dev,
843 "TAS2555: load new configuration: %s, coeff block data\n",
844 pNewConfiguration->mpName);
845 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
846 TAS2555_BLOCK_COEFF_DEV_A);
847 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
848 TAS2555_BLOCK_COEFF_DEV_B);
849 dev_dbg(pTAS2555->dev, "TAS2555: unmute TAS2555\n");
850 tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
851 } else {
852 dev_dbg(pTAS2555->dev,
853 "TAS2555 is powered up, no change in PLL: load new configuration: %s, coeff block data\n",
854 pNewConfiguration->mpName);
855 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
856 TAS2555_BLOCK_COEFF_DEV_A);
857 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
858 TAS2555_BLOCK_COEFF_DEV_B);
859 }
861 if (pTAS2555->mpCalFirmware->mnCalibrations) {
862 dev_dbg(pTAS2555->dev, "Enable: load calibration\n");
863 tas2555_load_block(pTAS2555,
864 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
865 pTAS2555->mbLoadCalibrationPostPowerUp = false;
866 }
868 pTAS2555->mbLoadConfigurationPostPowerUp = false;
869 } else {
870 dev_dbg(pTAS2555->dev,
871 "TAS2555 was powered down -> set flag to load configuration data when OS powers up the TAS2555 the next time\n");
872 if (pNewConfiguration->mnPLL != pCurrentConfiguration->mnPLL) {
873 dev_dbg(pTAS2555->dev,
874 "load post block from current configuration: %s, before loading new configuration: %s\n",
875 pCurrentConfiguration->mpName, pNewConfiguration->mpName);
876 tas2555_load_data(pTAS2555, &(pCurrentConfiguration->mData),
877 TAS2555_BLOCK_POST);
878 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n",
879 pNewPLL->mpName);
880 tas2555_load_block(pTAS2555, &(pNewPLL->mBlock));
881 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
882 dev_dbg(pTAS2555->dev,
883 "load new configuration: %s, pre block data\n",
884 pNewConfiguration->mpName);
885 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
886 TAS2555_BLOCK_PRE_DEV_A);
887 tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
888 TAS2555_BLOCK_PRE_DEV_B);
889 }
891 pTAS2555->mbLoadConfigurationPostPowerUp = true;
892 }
894 pTAS2555->mnCurrentConfiguration = nConfiguration;
895 }
897 int tas2555_set_config(struct tas2555_priv *pTAS2555, int config)
898 {
899 TConfiguration *pConfiguration;
900 TProgram *pProgram;
901 unsigned int nProgram = pTAS2555->mnCurrentProgram;
902 unsigned int nConfiguration = config;
904 if ((!pTAS2555->mpFirmware->mpPrograms) ||
905 (!pTAS2555->mpFirmware->mpConfigurations)) {
906 dev_err(pTAS2555->dev, "Firmware not loaded\n");
907 return -1;
908 }
910 if (nConfiguration >= pTAS2555->mpFirmware->mnConfigurations) {
911 dev_err(pTAS2555->dev, "Configuration %d doesn't exist\n",
912 nConfiguration);
913 return -1;
914 }
916 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
917 pProgram = &(pTAS2555->mpFirmware->mpPrograms[nProgram]);
919 if (nProgram != pConfiguration->mnProgram) {
920 dev_err(pTAS2555->dev,
921 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
922 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
923 nProgram, pProgram->mpName);
924 return -1;
925 }
927 tas2555_load_configuration(pTAS2555, nConfiguration, false);
929 return 0;
930 }
932 void tas2555_clear_firmware(TFirmware *pFirmware)
933 {
934 unsigned int n, nn;
935 if (!pFirmware) return;
936 if (pFirmware->mpDescription) kfree(pFirmware->mpDescription);
938 for (n = 0; n < pFirmware->mnPLLs; n++)
939 {
940 kfree(pFirmware->mpPLLs[n].mpDescription);
941 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
942 }
943 kfree(pFirmware->mpPLLs);
945 for (n = 0; n < pFirmware->mnPrograms; n++)
946 {
947 kfree(pFirmware->mpPrograms[n].mpDescription);
948 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
949 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
950 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
951 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
952 }
953 kfree(pFirmware->mpPrograms);
955 for (n = 0; n < pFirmware->mnConfigurations; n++)
956 {
957 kfree(pFirmware->mpConfigurations[n].mpDescription);
958 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
959 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
960 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
961 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
962 }
963 kfree(pFirmware->mpConfigurations);
965 for (n = 0; n < pFirmware->mnCalibrations; n++)
966 {
967 kfree(pFirmware->mpCalibrations[n].mpDescription);
968 kfree(pFirmware->mpCalibrations[n].mBlock.mpData);
969 }
970 kfree(pFirmware->mpCalibrations);
972 memset(pFirmware, 0x00, sizeof(TFirmware));
973 }
975 static void tas2555_load_calibration(struct tas2555_priv *pTAS2555,
976 char *pFileName)
977 {
978 int nResult;
979 int nFile;
980 mm_segment_t fs;
981 unsigned char pBuffer[512];
982 int nSize = 0;
984 dev_dbg(pTAS2555->dev, "%s:\n", __func__);
986 fs = get_fs();
987 set_fs(KERNEL_DS);
988 nFile = sys_open(pFileName, O_RDONLY, 0);
990 dev_info(pTAS2555->dev, "TAS2555 calibration file = %s, handle = %d\n",
991 pFileName, nFile);
993 if (nFile >= 0) {
994 nSize = sys_read(nFile, pBuffer, 512);
995 sys_close(nFile);
996 } else {
997 dev_err(pTAS2555->dev, "TAS2555 cannot open calibration file: %s\n",
998 pFileName);
999 }
1001 set_fs(fs);
1003 if (!nSize)
1004 return;
1006 tas2555_clear_firmware(pTAS2555->mpCalFirmware);
1008 dev_info(pTAS2555->dev, "TAS2555 calibration file size = %d\n", nSize);
1009 nResult = fw_parse(pTAS2555, pTAS2555->mpCalFirmware, pBuffer, nSize);
1011 if (nResult) {
1012 dev_err(pTAS2555->dev, "TAS2555 calibration file is corrupt\n");
1013 return;
1014 }
1016 dev_info(pTAS2555->dev, "TAS2555 calibration: %d calibrations\n",
1017 pTAS2555->mpCalFirmware->mnCalibrations);
1018 }
1020 void tas2555_fw_ready(const struct firmware *pFW, void *pContext)
1021 {
1022 struct tas2555_priv *pTAS2555 = (struct tas2555_priv *) pContext;
1023 int nResult;
1024 unsigned int nProgram = 0;
1025 unsigned int nSampleRate = 0;
1027 dev_info(pTAS2555->dev, "%s:\n", __func__);
1029 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1030 dev_err(pTAS2555->dev, "%s firmware is not loaded.\n",
1031 TAS2555_FW_NAME);
1032 return;
1033 }
1035 if (pTAS2555->mpFirmware->mpConfigurations){
1036 nProgram = pTAS2555->mnCurrentProgram;
1037 nSampleRate = pTAS2555->mnCurrentSampleRate;
1038 dev_dbg(pTAS2555->dev, "clear current firmware\n");
1039 tas2555_clear_firmware(pTAS2555->mpFirmware);
1040 }
1042 nResult = fw_parse(pTAS2555, pTAS2555->mpFirmware,
1043 (unsigned char *) (pFW->data), pFW->size);
1045 release_firmware(pFW);
1047 if (nResult) {
1048 dev_err(pTAS2555->dev, "firmware is corrupt\n");
1049 return;
1050 }
1052 if (!pTAS2555->mpFirmware->mnPrograms) {
1053 dev_err(pTAS2555->dev, "firmware contains no programs\n");
1054 return;
1055 }
1057 if (!pTAS2555->mpFirmware->mnConfigurations) {
1058 dev_err(pTAS2555->dev,
1059 "firmware contains no configurations\n");
1060 return;
1061 }
1063 if(nProgram >= pTAS2555->mpFirmware->mnPrograms){
1064 dev_info(pTAS2555->dev,
1065 "no previous program, set to default\n");
1066 nProgram = 0;
1067 }
1069 pTAS2555->mnCurrentSampleRate = nSampleRate;
1071 tas2555_set_program(pTAS2555, nProgram);
1072 }
1074 int tas2555_set_program(struct tas2555_priv *pTAS2555,
1075 unsigned int nProgram)
1076 {
1077 TPLL *pPLL;
1078 TConfiguration *pConfiguration;
1079 unsigned int nConfiguration = 0;
1080 unsigned int nSampleRate = 0;
1081 unsigned int Value = 0;
1082 bool bFound = false;
1083 int nResult = -1;
1085 if ((!pTAS2555->mpFirmware->mpPrograms) ||
1086 (!pTAS2555->mpFirmware->mpConfigurations)) {
1087 dev_err(pTAS2555->dev, "Firmware not loaded\n");
1088 return -1;
1089 }
1091 if (nProgram >= pTAS2555->mpFirmware->mnPrograms) {
1092 dev_err(pTAS2555->dev, "TAS2555: Program %d doesn't exist\n",
1093 nConfiguration);
1094 return -1;
1095 }
1097 nConfiguration = 0;
1098 nSampleRate = pTAS2555->mnCurrentSampleRate;
1100 while (!bFound
1101 && (nConfiguration < pTAS2555->mpFirmware->mnConfigurations)) {
1102 if (pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnProgram
1103 == nProgram){
1104 if(nSampleRate == 0){
1105 bFound = true;
1106 dev_info(pTAS2555->dev, "find default configuration %d\n", nConfiguration);
1107 }else if(nSampleRate
1108 == pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate){
1109 bFound = true;
1110 dev_info(pTAS2555->dev, "find matching configuration %d\n", nConfiguration);
1111 }else{
1112 nConfiguration++;
1113 }
1114 }else{
1115 nConfiguration++;
1116 }
1117 }
1119 if (!bFound) {
1120 dev_err(pTAS2555->dev,
1121 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1122 nProgram, nSampleRate);
1123 return -1;
1124 }
1126 pTAS2555->mnCurrentProgram = nProgram;
1127 if(pTAS2555->mbPowerUp)
1128 tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data);
1129 pTAS2555->write(pTAS2555, channel_both, TAS2555_SW_RESET_REG, 0x01);
1130 udelay(1000);
1132 dev_info(pTAS2555->dev, "load program %d\n", nProgram);
1133 tas2555_load_data(pTAS2555,
1134 &(pTAS2555->mpFirmware->mpPrograms[nProgram].mData),
1135 TAS2555_BLOCK_MAIN_DEV_A);
1136 tas2555_load_data(pTAS2555,
1137 &(pTAS2555->mpFirmware->mpPrograms[nProgram].mData),
1138 TAS2555_BLOCK_MAIN_DEV_B);
1140 pTAS2555->mnCurrentConfiguration = nConfiguration;
1142 pConfiguration =
1143 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
1144 pPLL = &(pTAS2555->mpFirmware->mpPLLs[pConfiguration->mnPLL]);
1145 dev_dbg(pTAS2555->dev,
1146 "TAS2555 load PLL: %s block for Configuration %s\n",
1147 pPLL->mpName, pConfiguration->mpName);
1149 tas2555_load_block(pTAS2555, &(pPLL->mBlock));
1150 pTAS2555->mnCurrentSampleRate = pConfiguration->mnSamplingRate;
1151 dev_dbg(pTAS2555->dev,
1152 "load configuration %s conefficient pre block\n",
1153 pConfiguration->mpName);
1154 tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_PRE_DEV_A);
1155 tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_PRE_DEV_B);
1157 nResult = pTAS2555->read(pTAS2555, channel_left, TAS2555_CRC_CHECKSUM_REG, &Value);
1158 dev_info(pTAS2555->dev, "Left uCDSP Checksum: 0x%02x\n", Value);
1159 nResult = pTAS2555->read(pTAS2555, channel_right, TAS2555_CRC_CHECKSUM_REG, &Value);
1160 dev_info(pTAS2555->dev, "Right uCDSP Checksum: 0x%02x\n", Value);
1161 nResult = pTAS2555->read(pTAS2555, channel_left, TAS2555_PLL_CLKIN_REG, &Value);
1162 dev_info(pTAS2555->dev, "TAS2555 PLL_CLKIN = 0x%02X\n", Value);
1163 p_tas2555_startup_data[TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX] = Value;
1165 if (pTAS2555->mbPowerUp){
1166 dev_dbg(pTAS2555->dev, "device powered up, load startup\n");
1167 tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
1168 dev_dbg(pTAS2555->dev,
1169 "device powered up, load configuration %s post power block\n",
1170 pConfiguration->mpName);
1171 tas2555_load_data(pTAS2555, &(pConfiguration->mData),
1172 TAS2555_BLOCK_POST_POWER_UP);
1173 }
1175 tas2555_load_configuration(pTAS2555, nConfiguration, true);
1176 if (pTAS2555->mbPowerUp){
1177 dev_dbg(pTAS2555->dev,
1178 "device powered up, load unmute\n");
1179 tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
1180 }
1182 return 0;
1183 }
1185 int tas2555_set_calibration(struct tas2555_priv *pTAS2555,
1186 int nCalibration)
1187 {
1188 if ((!pTAS2555->mpFirmware->mpPrograms) || (!pTAS2555->mpFirmware->mpConfigurations))
1189 {
1190 dev_err(pTAS2555->dev, "Firmware not loaded\n\r");
1191 return -1;
1192 }
1194 if (nCalibration == 0x00FF)
1195 {
1196 dev_info(pTAS2555->dev, "load new calibration file %s\n", TAS2555_CAL_NAME);
1197 tas2555_load_calibration(pTAS2555, TAS2555_CAL_NAME);
1198 nCalibration = 0;
1199 }
1201 if (nCalibration >= pTAS2555->mpFirmware->mnCalibrations) {
1202 dev_err(pTAS2555->dev,
1203 "Calibration %d doesn't exist\n", nCalibration);
1204 return -1;
1205 }
1207 pTAS2555->mnCurrentCalibration = nCalibration;
1208 if(pTAS2555->mbPowerUp){
1209 tas2555_load_block(pTAS2555,
1210 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
1211 pTAS2555->mbLoadCalibrationPostPowerUp = false;
1212 }else{
1213 pTAS2555->mbLoadCalibrationPostPowerUp = true;
1214 }
1216 return 0;
1217 }
1219 int tas2555_parse_dt(struct device *dev,
1220 struct tas2555_priv *pTAS2555)
1221 {
1222 struct device_node *np = dev->of_node;
1223 int rc= 0, ret = 0;
1224 unsigned int value;
1226 pTAS2555->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
1227 if (pTAS2555->mnResetGPIO < 0) {
1228 dev_err(pTAS2555->dev, "Looking up %s property in node %s failed %d\n",
1229 "ti,cdc-reset-gpio", np->full_name,
1230 pTAS2555->mnResetGPIO);
1231 ret = -1;
1232 }else{
1233 dev_dbg(pTAS2555->dev, "ti,cdc-reset-gpio=%d\n", pTAS2555->mnResetGPIO);
1234 }
1236 if(ret >=0){
1237 rc = of_property_read_u32(np, "ti,left-channel", &value);
1238 if (rc) {
1239 dev_err(pTAS2555->dev, "Looking up %s property in node %s failed %d\n",
1240 "ti,left-channel", np->full_name, rc);
1241 ret = -2;
1242 }else{
1243 pTAS2555->mnLAddr = value;
1244 dev_dbg(pTAS2555->dev, "ti,left-channel=0x%x\n", pTAS2555->mnLAddr);
1245 }
1246 }
1248 if(ret >=0){
1249 rc = of_property_read_u32(np, "ti,right-channel", &value);
1250 if (rc) {
1251 dev_err(pTAS2555->dev, "Looking up %s property in node %s failed %d\n",
1252 "ti,right-channel", np->full_name, rc);
1253 ret = -3;
1254 }else{
1255 pTAS2555->mnRAddr = value;
1256 dev_dbg(pTAS2555->dev, "ti,right-channel=0x%x", pTAS2555->mnRAddr);
1257 }
1258 }
1260 return ret;
1261 }
1263 MODULE_AUTHOR("Texas Instruments Inc.");
1264 MODULE_DESCRIPTION("TAS2555 common functions for Android Linux");
1265 MODULE_LICENSE("GPLv2");