2 ** =============================================================================
3 ** Copyright (c) 2016 Texas Instruments Inc.
4 ** Copyright (C) 2017 XiaoMi, Inc.
6 ** This program is free software; you can redistribute it and/or modify it under
7 ** the terms of the GNU General Public License as published by the Free Software
8 ** Foundation; version 2.
10 ** This program is distributed in the hope that it will be useful, but WITHOUT
11 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ** TAS2559 common functions for Android Linux
20 ** =============================================================================
23 #include <linux/module.h>
24 #include <linux/moduleparam.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
28 #include <linux/i2c.h>
29 #include <linux/gpio.h>
30 #include <linux/regulator/consumer.h>
31 #include <linux/firmware.h>
32 #include <linux/regmap.h>
34 #include <linux/of_gpio.h>
35 #include <linux/slab.h>
36 #include <linux/syscalls.h>
37 #include <linux/fcntl.h>
38 #include <linux/uaccess.h>
39 #include <linux/crc8.h>
42 #include "tas2559-core.h"
44 #define TAS2559_CAL_NAME "/persist/audio/tas2559_cal.bin"
47 static int tas2559_load_calibration(struct tas2559_priv *pTAS2559,
49 static int tas2559_load_data(struct tas2559_priv *pTAS2559, struct TData *pData,
51 static void tas2559_clear_firmware(struct TFirmware *pFirmware);
52 static int tas2559_load_block(struct tas2559_priv *pTAS2559, struct TBlock *pBlock);
53 static int tas2559_load_configuration(struct tas2559_priv *pTAS2559,
54 unsigned int nConfiguration, bool bLoadSame);
56 #define TAS2559_UDELAY 0xFFFFFFFE
57 #define TAS2559_MDELAY 0xFFFFFFFD
59 #define FW_ERR_HEADER -1
60 #define FW_ERR_SIZE -2
62 #define TAS2559_BLOCK_PLL 0x00
63 #define TAS2559_BLOCK_PGM_ALL 0x0d
64 #define TAS2559_BLOCK_PGM_DEV_A 0x01
65 #define TAS2559_BLOCK_PGM_DEV_B 0x08
66 #define TAS2559_BLOCK_CFG_COEFF_DEV_A 0x03
67 #define TAS2559_BLOCK_CFG_COEFF_DEV_B 0x0a
68 #define TAS2559_BLOCK_CFG_PRE_DEV_A 0x04
69 #define TAS2559_BLOCK_CFG_PRE_DEV_B 0x0b
70 #define TAS2559_BLOCK_CFG_POST 0x05
71 #define TAS2559_BLOCK_CFG_POST_POWER 0x06
72 #define TAS2559_BLOCK_PST_POWERUP_DEV_B 0x0e
74 #define PPC_DRIVER_CRCCHK 0x00000200
75 #define PPC_DRIVER_CONFDEV 0x00000300
76 #define PPC_DRIVER_CFGDEV_NONCRC 0x00000101
78 static unsigned int p_tas2559_default_data[] = {
79 DevA, TAS2559_SAR_ADC2_REG, 0x05,/* enable SAR ADC */
80 DevA, TAS2559_CLK_ERR_CTRL2, 0x21,/*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/
81 DevA, TAS2559_CLK_ERR_CTRL3, 0x21,/*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */
82 DevB, TAS2560_CLK_ERR_CTRL2, 0x21,/*rampDown 15dB/us, clock1 hysteresis, 0.34ms; clock2 hysteresis, 10.6us */
83 DevA, TAS2559_SAFE_GUARD_REG, TAS2559_SAFE_GUARD_PATTERN,/* safe guard */
84 DevA, TAS2559_CLK_ERR_CTRL, 0x00,/*enable clock error detection*/
85 DevB, TAS2560_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
86 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
89 static unsigned int p_tas2559_irq_config[] = {
90 DevA, TAS2559_CLK_HALT_REG, 0x71,/* enable clk halt detect2 interrupt */
91 DevA, TAS2559_INT_GEN1_REG, 0x11,/* enable spk OC and OV*/
92 DevA, TAS2559_INT_GEN2_REG, 0x11,/* enable clk err1 and die OT*/
93 DevA, TAS2559_INT_GEN3_REG, 0x11,/* enable clk err2 and brownout*/
94 DevA, TAS2559_INT_GEN4_REG, 0x01,/* disable SAR, enable clk halt*/
95 DevB, TAS2560_INT_GEN_REG, 0xff,/* enable spk OC and OV*/
96 DevA, TAS2559_GPIO4_PIN_REG, 0x07,/* set GPIO4 as int1, default*/
97 DevB, TAS2560_IRQ_PIN_REG, 0x41,
98 DevA, TAS2559_INT_MODE_REG, 0x80,/* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
99 DevB, TAS2560_INT_MODE_REG, 0x80,/* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
100 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
103 static unsigned int p_tas2559_startup_data[] = {
104 DevA, TAS2559_GPIO1_PIN_REG, 0x01,/* enable BCLK */
105 DevA, TAS2559_GPIO2_PIN_REG, 0x01,/* enable WCLK */
106 DevA, TAS2559_POWER_CTRL2_REG, 0xA0,/*Class-D, Boost power up*/
107 DevA, TAS2559_POWER_CTRL2_REG, 0xA3,/*Class-D, Boost, IV sense power up*/
108 DevA, TAS2559_POWER_CTRL1_REG, 0xF8,/*PLL, DSP, clock dividers power up*/
109 DevBoth, TAS2559_UDELAY, 2000,/*delay*/
110 DevB, TAS2560_DEV_MODE_REG, 0x02,
111 DevB, TAS2560_MUTE_REG, 0x41,
112 DevBoth, TAS2559_UDELAY, 2000,/*delay*/
113 DevA, TAS2559_CLK_ERR_CTRL, 0x2B,/*enable clock error detection*/
114 DevB, TAS2560_CLK_ERR_CTRL, 0x0B,/* disable clock error detection */
115 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
118 static unsigned int p_tas2559_mute_data[] = {
119 DevA, TAS2559_SOFT_MUTE_REG, 0x01,/*soft mute*/
120 DevB, TAS2560_MUTE_REG, 0x41,
121 DevA, TAS2559_MDELAY, 10,/*delay 10ms*/
122 DevA, TAS2559_MUTE_REG, 0x03,/*mute*/
123 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
126 static unsigned int p_tas2559_unmute_data[] = {
127 DevA, TAS2559_MUTE_REG, 0x00, /*unmute*/
128 DevB, TAS2560_MUTE_REG, 0x40,
129 DevA, TAS2559_SOFT_MUTE_REG, 0x00, /*soft unmute*/
130 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
133 static unsigned int p_tas2559_shutdown_data[] = {
134 DevA, TAS2559_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
135 DevB, TAS2560_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
136 DevA, TAS2559_SOFT_MUTE_REG, 0x01,/*soft mute*/
137 DevB, TAS2560_MUTE_REG, 0x41,
138 DevB, TAS2560_MUTE_REG, 0x01,
139 DevBoth, TAS2559_MDELAY, 10,/*delay 10ms*/
140 DevB, TAS2559_MDELAY, 20,/*delay 20ms*/
141 DevA, TAS2559_POWER_CTRL1_REG, 0x60,/*DSP power down*/
142 DevA, TAS2559_MDELAY, 2,/*delay 20ms*/
143 DevA, TAS2559_MUTE_REG, 0x03,/*mute*/
144 DevA, TAS2559_POWER_CTRL2_REG, 0x00,/*Class-D, Boost power down*/
145 DevA, TAS2559_POWER_CTRL1_REG, 0x00,/*all power down*/
146 DevB, TAS2560_DEV_MODE_REG, 0x01,
147 DevA, TAS2559_GPIO1_PIN_REG, 0x00,/* disable BCLK */
148 DevA, TAS2559_GPIO2_PIN_REG, 0x00,/* disable WCLK */
149 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
152 static unsigned int p_tas2559_shutdown_DevB_data[] = {
153 DevA, TAS2559_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
154 DevB, TAS2560_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
155 DevB, TAS2560_MUTE_REG, 0x41,
156 DevB, TAS2560_MUTE_REG, 0x01,
157 DevA, TAS2559_POWER_CTRL1_REG, 0x60,/*DSP power down*/
158 DevBoth, TAS2559_MDELAY, 30,/*delay 2ms*/
159 DevB, TAS2560_DEV_MODE_REG, 0x01,
160 DevA, TAS2559_POWER_CTRL2_REG, 0x00,/*Class-D, Boost power down*/
161 DevA, TAS2559_POWER_CTRL1_REG, 0x00,/*all power down*/
162 DevA, TAS2559_GPIO1_PIN_REG, 0x00,/* disable BCLK */
163 DevA, TAS2559_GPIO2_PIN_REG, 0x00,/* disable WCLK */
164 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
167 static int tas2559_dev_load_data(struct tas2559_priv *pTAS2559,
168 enum channel dev, unsigned int *pData)
172 unsigned int nRegister;
179 if (chl == 0xffffffff)
183 nRegister = pData[n * 3 + 1];
184 nData = pData[n * 3 + 2];
186 if (nRegister == TAS2559_UDELAY) {
188 dev_dbg(pTAS2559->dev, "%s, udelay %d\n", __func__, nData);
189 } else if (nRegister == TAS2559_MDELAY) {
191 dev_dbg(pTAS2559->dev, "%s, msleep %d\n", __func__, nData);
192 } else if (nRegister != 0xFFFFFFFF) {
193 dev_dbg(pTAS2559->dev, "%s, write chl=%d, B[%d]P[%d]R[%d]=0x%x\n",
194 __func__, chl, TAS2559_BOOK_ID(nRegister),
195 TAS2559_PAGE_ID(nRegister), TAS2559_PAGE_REG(nRegister), nData);
196 nResult = pTAS2559->write(pTAS2559, chl, nRegister, nData);
203 } while (nRegister != 0xFFFFFFFF);
209 *static int tas2559_dev_load_blk_data(struct tas2559_priv *pTAS2559,
210 * enum channel chl, unsigned int *pData)
212 * unsigned int nRegister;
213 * unsigned int *nData;
214 * unsigned char Buf[128];
215 * unsigned int nLength = 0;
217 * unsigned int nSize = 0;
221 * nRegister = pData[nLength];
222 * nSize = pData[nLength + 1];
223 * nData = &pData[nLength + 2];
224 * if (nRegister == TAS2559_MDELAY) {
226 * dev_dbg(pTAS2559->dev, "%s, mDelay %d\n", __func__, nData[0]);
227 * } else if (nRegister == 0xFFFFFFFF) {
228 * dev_dbg(pTAS2559->dev, "%s, end\n", __func__);
230 * } else if (nSize > 128) {
231 * dev_err(pTAS2559->dev, "%s, maximum is 128 bytes!\n",
234 * } else if (nSize == 0) {
235 * dev_err(pTAS2559->dev, "%s, minimum is 1 bytes!\n",
240 * for(i = 0; i < nSize; i++)
241 * Buf[i] = (unsigned char)nData[i];
242 * dev_dbg(pTAS2559->dev, "%s, BW B[%d]P[%d]R[%d], size=%d, D0=0x%x\n",
243 * __func__, TAS2559_BOOK_ID(nRegister), TAS2559_PAGE_ID(nRegister),
244 * TAS2559_PAGE_REG(nRegister), nSize, Buf[0]);
245 * nResult = pTAS2559->bulk_write(pTAS2559, chl, nRegister, Buf, nSize);
247 * dev_dbg(pTAS2559->dev, "%s, W B[%d]P[%d]R[%d], Data=0x%x\n",
248 * __func__, TAS2559_BOOK_ID(nRegister), TAS2559_PAGE_ID(nRegister),
249 * TAS2559_PAGE_REG(nRegister), nData[0]);
250 * nResult = pTAS2559->write(pTAS2559,chl,nRegister, nData[0]);
255 * nLength = nLength + 2 + pData[nLength+1] ;
256 * } while (nRegister != 0xFFFFFFFF);
262 static int tas2559_DevStartup(struct tas2559_priv *pTAS2559,
266 enum channel chl = dev;
271 dev_dbg(pTAS2559->dev, "%s, chl=%d\n", __func__, chl);
272 nResult = tas2559_dev_load_data(pTAS2559, chl, p_tas2559_startup_data);
277 static int tas2559_DevShutdown(struct tas2559_priv *pTAS2559,
282 dev_dbg(pTAS2559->dev, "%s, dev=%d\n", __func__, dev);
285 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_shutdown_DevB_data);
287 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_shutdown_data);
292 int tas2559_configIRQ(struct tas2559_priv *pTAS2559, enum channel dev)
294 return tas2559_dev_load_data(pTAS2559, dev, p_tas2559_irq_config);
297 int tas2559_SA_DevChnSetup(struct tas2559_priv *pTAS2559, unsigned int mode)
300 struct TProgram *pProgram;
301 unsigned char buf_mute[16] = {0};
302 unsigned char buf_DevA_Left_DevB_Right[16] = {0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
303 unsigned char buf_DevA_Right_DevB_Left[16] = {0, 0, 0, 0, 0x40, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0};
304 unsigned char buf_DevA_MonoMix_DevB_MonoMix[16] = {0x20, 0, 0, 0, 0x20, 0, 0, 0, 0x20, 0, 0, 0, 0x20, 0, 0, 0};
305 unsigned char *pDevBuf = NULL;
307 dev_dbg(pTAS2559->dev, "%s, mode %d\n", __func__, mode);
308 if ((pTAS2559->mpFirmware->mnPrograms == 0)
309 || (pTAS2559->mpFirmware->mnConfigurations == 0)) {
310 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
314 pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
315 if (pProgram->mnAppMode != TAS2559_APP_TUNINGMODE) {
316 dev_err(pTAS2559->dev, "%s, not tuning mode\n", __func__);
320 if (pTAS2559->mbLoadConfigurationPrePowerUp) {
321 dev_dbg(pTAS2559->dev, "%s, setup channel after coeff update\n", __func__);
322 pTAS2559->mnChannelState = mode;
328 pDevBuf = pTAS2559->mnDefaultChlData;
336 pDevBuf = buf_DevA_Left_DevB_Right;
340 pDevBuf = buf_DevA_Right_DevB_Left;
344 pDevBuf = buf_DevA_MonoMix_DevB_MonoMix;
352 nResult = pTAS2559->bulk_write(pTAS2559, DevA,
353 TAS2559_SA_CHL_CTRL_REG, pDevBuf, 16);
356 pTAS2559->mnChannelState = mode;
363 int tas2559_SA_ctl_echoRef(struct tas2559_priv *pTAS2559)
369 * TAS2559 echo-ref is on DOUT left channel,
370 * TAS2560 echo-ref is on DOUT right channel
375 int tas2559_set_DAC_gain(struct tas2559_priv *pTAS2559,
376 enum channel chl, unsigned int nGain)
379 int gain = (nGain & 0x0f);
382 nResult = pTAS2559->update_bits(pTAS2559, DevA,
383 TAS2559_SPK_CTRL_REG, 0x78, (gain << 3));
390 nResult = pTAS2559->update_bits(pTAS2559, DevB,
391 TAS2560_SPK_CTRL_REG, 0x0f, gain);
398 int tas2559_get_DAC_gain(struct tas2559_priv *pTAS2559,
399 enum channel chl, unsigned char *pnGain)
405 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SPK_CTRL_REG, &nGain);
408 *pnGain = ((nGain >> 3) & 0x0f);
411 nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_SPK_CTRL_REG, &nGain);
414 *pnGain = (nGain & 0x0f);
420 int tas2559_set_bit_rate(struct tas2559_priv *pTAS2559, unsigned int nBitRate)
422 int nResult = 0, n = -1;
424 dev_dbg(pTAS2559->dev, "%s: nBitRate = %d\n", __func__, nBitRate);
445 nResult = pTAS2559->update_bits(pTAS2559, DevA,
446 TAS2559_ASI1_DAC_FORMAT_REG, 0x18, n << 3);
448 /* The ASIM is always configured for 16-bits, hardcode the TAS2560 to 16-bits */
449 nResult = pTAS2559->update_bits(pTAS2559, DevB,
450 TAS2560_DAI_FMT, 0x03, 0);
457 int tas2559_get_bit_rate(struct tas2559_priv *pTAS2559, unsigned char *pBitRate)
460 unsigned int nValue = 0;
461 unsigned char bitRate;
463 nResult = pTAS2559->read(pTAS2559, DevA,
464 TAS2559_ASI1_DAC_FORMAT_REG, &nValue);
467 bitRate = (nValue & 0x18) >> 3;
486 int tas2559_DevMute(struct tas2559_priv *pTAS2559, enum channel dev, bool mute)
490 dev_dbg(pTAS2559->dev, "%s, dev=%d, mute=%d\n", __func__, dev, mute);
493 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_mute_data);
495 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_unmute_data);
500 int tas2559_DevMuteStatus(struct tas2559_priv *pTAS2559, enum channel dev, bool *pMute)
506 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SOFT_MUTE_REG, &nMute);
507 else if (dev == DevB)
508 nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_MUTE_REG, &nMute);
512 *pMute = ((nMute & 0x01) == 0x00);
519 * die temperature calculation:
520 * DieTemp = readout / 2^23
522 int tas2559_get_die_temperature(struct tas2559_priv *pTAS2559, int *pTemperature)
525 unsigned char nBuf[4];
528 if (!pTAS2559->mpFirmware->mnConfigurations) {
529 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
533 if (!pTAS2559->mbPowerUp) {
534 dev_err(pTAS2559->dev, "%s, device not powered on\n", __func__);
538 /* TAS2559 should always be enabled */
539 nResult = pTAS2559->bulk_read(pTAS2559, DevA, TAS2559_DIE_TEMP_REG, nBuf, 4);
542 temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | ((int)nBuf[2] << 8) | nBuf[3];
543 *pTemperature = temp;
551 int tas2559_update_VBstVolt(struct tas2559_priv *pTAS2559, enum channel chn)
554 int nVBstVoltSet = -1;
556 switch (pTAS2559->mnVBoostVoltage) {
557 case TAS2559_VBST_8P5V:
559 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be 0dB\n", __func__);
562 case TAS2559_VBST_8P1V:
564 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -1dB\n", __func__);
567 case TAS2559_VBST_7P6V:
569 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -2dB\n", __func__);
572 case TAS2559_VBST_6P6V:
574 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -3dB\n", __func__);
577 case TAS2559_VBST_5P6V:
579 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -4dB\n", __func__);
583 dev_err(pTAS2559->dev, "%s, error volt %d\n", __func__, pTAS2559->mnVBoostVoltage);
587 if (nVBstVoltSet >= 0) {
589 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_VBST_VOLT_REG, 0xe0, (nVBstVoltSet << 5));
591 nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_VBST_VOLT_REG, 0xe0, (nVBstVoltSet << 5));
593 dev_dbg(pTAS2559->dev, "%s, set vbst voltage (%d channel) 0x%x\n", __func__, chn, (nVBstVoltSet << 5));
599 int tas2559_get_VBoost(struct tas2559_priv *pTAS2559, int *pVBoost)
603 dev_dbg(pTAS2559->dev, "%s, VBoost state %d\n", __func__, pTAS2559->mnVBoostState);
604 switch (pTAS2559->mnVBoostState) {
605 case TAS2559_VBST_NEED_DEFAULT:
606 case TAS2559_VBST_DEFAULT:
610 case TAS2559_VBST_A_ON:
611 case TAS2559_VBST_B_ON:
612 case TAS2559_VBST_A_ON_B_ON:
616 dev_err(pTAS2559->dev, "%s, error state %d\n", __func__, pTAS2559->mnVBoostState);
623 static int tas2559_restore_VBstCtl(struct tas2559_priv *pTAS2559, enum channel chn)
626 unsigned int nDevAVBstCtrl, nDevASlpCtrl, nDevABstLevel;
627 unsigned int nDevBVBstCtrl, nDevBSlpCtrl, nDevBBstLevel;
630 nDevAVBstCtrl = pTAS2559->mnVBoostDefaultCfg[0];
631 nDevASlpCtrl = pTAS2559->mnVBoostDefaultCfg[1];
632 nDevABstLevel = pTAS2559->mnVBoostDefaultCfg[2];
633 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_VBOOST_CTL_REG, nDevAVBstCtrl);
636 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_SLEEPMODE_CTL_REG, nDevASlpCtrl);
639 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_VBST_VOLT_REG, nDevABstLevel);
646 nDevBVBstCtrl = pTAS2559->mnVBoostDefaultCfg[3];
647 nDevBSlpCtrl = pTAS2559->mnVBoostDefaultCfg[4];
648 nDevBBstLevel = pTAS2559->mnVBoostDefaultCfg[5];
649 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_VBOOST_CTL_REG, nDevBVBstCtrl);
652 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_SLEEPMODE_CTL_REG, nDevBSlpCtrl);
655 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_VBST_VOLT_REG, nDevBBstLevel);
663 int tas2559_set_VBoost(struct tas2559_priv *pTAS2559, int vboost, bool bPowerOn)
666 struct TConfiguration *pConfiguration;
667 unsigned int nConfig;
669 if ((!pTAS2559->mpFirmware->mnConfigurations)
670 || (!pTAS2559->mpFirmware->mnPrograms)) {
671 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
676 dev_info(pTAS2559->dev, "%s, will load VBoost state next time before power on\n", __func__);
677 pTAS2559->mbLoadVBoostPrePowerUp = true;
678 pTAS2559->mnVBoostNewState = vboost;
682 if (pTAS2559->mbLoadConfigurationPrePowerUp)
683 nConfig = pTAS2559->mnNewConfiguration;
685 nConfig = pTAS2559->mnCurrentConfiguration;
687 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nConfig]);
689 if (pTAS2559->mnVBoostState == TAS2559_VBST_NEED_DEFAULT) {
690 if (pConfiguration->mnDevices & DevA) {
691 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_VBOOST_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[0]);
694 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SLEEPMODE_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[1]);
697 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_VBST_VOLT_REG, &pTAS2559->mnVBoostDefaultCfg[2]);
701 if (pConfiguration->mnDevices & DevB) {
702 nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_VBOOST_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[3]);
705 nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_SLEEPMODE_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[4]);
708 nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_VBST_VOLT_REG, &pTAS2559->mnVBoostDefaultCfg[5]);
712 dev_dbg(pTAS2559->dev, "%s, get default VBoost\n", __func__);
713 pTAS2559->mnVBoostState = TAS2559_VBST_DEFAULT;
714 if ((vboost == TAS2559_VBST_DEFAULT)
715 || (vboost == TAS2559_VBST_NEED_DEFAULT)) {
716 dev_dbg(pTAS2559->dev, "%s, already default, bypass\n", __func__);
722 if (pConfiguration->mnDevices & DevA) {
723 if (!(pTAS2559->mnVBoostState & TAS2559_VBST_A_ON)) {
724 nResult = tas2559_update_VBstVolt(pTAS2559, DevA);
727 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_VBOOST_CTL_REG, 0x40, 0x40);
730 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_SLEEPMODE_CTL_REG, 0x40, 0x00);
733 pTAS2559->mnVBoostState |= TAS2559_VBST_A_ON;
734 dev_dbg(pTAS2559->dev, "%s, devA Boost On, %d\n", __func__, pTAS2559->mnVBoostState);
737 if (pTAS2559->mnVBoostState & TAS2559_VBST_A_ON) {
738 nResult = tas2559_restore_VBstCtl(pTAS2559, DevA);
741 pTAS2559->mnVBoostState &= ~TAS2559_VBST_A_ON;
742 dev_dbg(pTAS2559->dev, "%s, devA Boost Off, %d\n", __func__, pTAS2559->mnVBoostState);
746 if (pConfiguration->mnDevices & DevB) {
747 if (!(pTAS2559->mnVBoostState & TAS2559_VBST_B_ON)) {
748 nResult = tas2559_update_VBstVolt(pTAS2559, DevB);
751 nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_VBOOST_CTL_REG, 0x01, 0x01);
754 nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_SLEEPMODE_CTL_REG, 0x08, 0x08);
757 pTAS2559->mnVBoostState |= TAS2559_VBST_B_ON;
758 dev_dbg(pTAS2559->dev, "%s, devB Boost On, %d\n", __func__, pTAS2559->mnVBoostState);
761 if (pTAS2559->mnVBoostState & TAS2559_VBST_B_ON) {
762 nResult = tas2559_restore_VBstCtl(pTAS2559, DevB);
765 pTAS2559->mnVBoostState &= ~TAS2559_VBST_B_ON;
766 dev_dbg(pTAS2559->dev, "%s, devB Boost Off, %d\n", __func__, pTAS2559->mnVBoostState);
770 if (pTAS2559->mnVBoostState & TAS2559_VBST_A_ON) {
771 nResult = tas2559_restore_VBstCtl(pTAS2559, DevA);
774 pTAS2559->mnVBoostState &= ~TAS2559_VBST_A_ON;
775 dev_dbg(pTAS2559->dev, "%s, devA Boost default, %d\n", __func__, pTAS2559->mnVBoostState);
777 if (pTAS2559->mnVBoostState & TAS2559_VBST_B_ON) {
778 nResult = tas2559_restore_VBstCtl(pTAS2559, DevB);
781 pTAS2559->mnVBoostState &= ~TAS2559_VBST_B_ON;
782 dev_dbg(pTAS2559->dev, "%s, devB Boost default, %d\n", __func__, pTAS2559->mnVBoostState);
791 int tas2559_load_platdata(struct tas2559_priv *pTAS2559)
796 dev_dbg(pTAS2559->dev, "%s\n", __func__);
798 if (gpio_is_valid(pTAS2559->mnDevAGPIOIRQ))
801 if (gpio_is_valid(pTAS2559->mnDevBGPIOIRQ))
805 nResult = tas2559_configIRQ(pTAS2559, nDev);
811 nResult = tas2559_set_bit_rate(pTAS2559, pTAS2559->mnBitRate);
816 nResult = tas2559_SA_ctl_echoRef(pTAS2559);
826 int tas2559_load_default(struct tas2559_priv *pTAS2559)
830 dev_dbg(pTAS2559->dev, "%s\n", __func__);
831 nResult = tas2559_dev_load_data(pTAS2559, DevBoth, p_tas2559_default_data);
836 nResult = tas2559_load_platdata(pTAS2559);
841 /* enable DOUT tri-state for extra BCLKs */
842 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_ASI1_DAC_FORMAT_REG, 0x01, 0x01);
847 nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_ASI_CFG_1, 0x02, 0x02);
852 /* Interrupt pin, low-highZ, high active driven */
853 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_GPIO_HIZ_CTRL2_REG, 0x30, 0x30);
860 static void failsafe(struct tas2559_priv *pTAS2559)
862 dev_err(pTAS2559->dev, "%s\n", __func__);
863 pTAS2559->mnErrCode |= ERROR_FAILSAFE;
865 if (hrtimer_active(&pTAS2559->mtimer))
866 hrtimer_cancel(&pTAS2559->mtimer);
868 if (pTAS2559->mnRestart < RESTART_MAX) {
869 pTAS2559->mnRestart++;
871 dev_err(pTAS2559->dev, "I2C COMM error, restart SmartAmp.\n");
872 queue_delayed_work(system_power_efficient_wq, &pTAS2559->irq_work, msecs_to_jiffies(100));
876 pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
877 tas2559_DevShutdown(pTAS2559, DevBoth);
878 pTAS2559->mbPowerUp = false;
879 pTAS2559->hw_reset(pTAS2559);
880 pTAS2559->write(pTAS2559, DevBoth, TAS2559_SW_RESET_REG, 0x01);
882 pTAS2559->write(pTAS2559, DevA, TAS2559_SPK_CTRL_REG, 0x04);
883 pTAS2559->write(pTAS2559, DevB, TAS2560_SPK_CTRL_REG, 0x50);
885 if (pTAS2559->mpFirmware != NULL)
886 tas2559_clear_firmware(pTAS2559->mpFirmware);
889 int tas2559_checkPLL(struct tas2559_priv *pTAS2559)
900 * tas2559_load_coefficient
902 static int tas2559_load_coefficient(struct tas2559_priv *pTAS2559,
903 int nPrevConfig, int nNewConfig, bool bPowerOn)
907 struct TProgram *pProgram = NULL;
908 struct TConfiguration *pPrevConfiguration;
909 struct TConfiguration *pNewConfiguration;
911 bool bRestorePower = false;
913 dev_dbg(pTAS2559->dev, "%s, Prev=%d, new=%d, Pow=%d\n",
914 __func__, nPrevConfig, nNewConfig, bPowerOn);
916 if (!pTAS2559->mpFirmware->mnConfigurations) {
917 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
921 if (nNewConfig >= pTAS2559->mpFirmware->mnConfigurations) {
922 dev_err(pTAS2559->dev, "%s, invalid configuration New=%d, total=%d\n",
923 __func__, nNewConfig, pTAS2559->mpFirmware->mnConfigurations);
927 if (nPrevConfig < 0) {
928 pPrevConfiguration = NULL;
931 if (nPrevConfig == nNewConfig) {
932 dev_dbg(pTAS2559->dev, "%d configuration is already loaded\n", nNewConfig);
935 pPrevConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nPrevConfig]);
936 chl = pPrevConfiguration->mnDevices;
939 pNewConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nNewConfig]);
940 pTAS2559->mnCurrentConfiguration = nNewConfig;
942 if (pPrevConfiguration) {
943 if ((pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL)
944 && (pPrevConfiguration->mnDevices == pNewConfiguration->mnDevices)) {
945 dev_dbg(pTAS2559->dev, "%s, PLL and device same\n", __func__);
946 goto prog_coefficient;
950 pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
953 if (hrtimer_active(&pTAS2559->mtimer))
954 hrtimer_cancel(&pTAS2559->mtimer);
956 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE)
957 pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
959 nResult = tas2559_DevShutdown(pTAS2559, chl);
964 bRestorePower = true;
968 pPLL = &(pTAS2559->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
969 dev_dbg(pTAS2559->dev, "load PLL: %s block for Configuration %s\n",
970 pPLL->mpName, pNewConfiguration->mpName);
971 nResult = tas2559_load_block(pTAS2559, &(pPLL->mBlock));
976 pTAS2559->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
978 dev_dbg(pTAS2559->dev, "load configuration %s conefficient pre block\n",
979 pNewConfiguration->mpName);
981 if (pNewConfiguration->mnDevices & DevA) {
982 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData), TAS2559_BLOCK_CFG_PRE_DEV_A);
988 if (pNewConfiguration->mnDevices & DevB) {
989 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData), TAS2559_BLOCK_CFG_PRE_DEV_B);
996 dev_dbg(pTAS2559->dev, "load new configuration: %s, coeff block data\n",
997 pNewConfiguration->mpName);
999 if (pNewConfiguration->mnDevices & DevA) {
1000 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData),
1001 TAS2559_BLOCK_CFG_COEFF_DEV_A);
1006 if (pNewConfiguration->mnDevices & DevB) {
1007 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData),
1008 TAS2559_BLOCK_CFG_COEFF_DEV_B);
1013 if (pTAS2559->mnChannelState == TAS2559_AD_BD) {
1014 nResult = pTAS2559->bulk_read(pTAS2559,
1015 DevA, TAS2559_SA_CHL_CTRL_REG, pTAS2559->mnDefaultChlData, 16);
1019 nResult = tas2559_SA_DevChnSetup(pTAS2559, pTAS2559->mnChannelState);
1024 if (pTAS2559->mpCalFirmware->mnCalibrations) {
1025 nResult = tas2559_set_calibration(pTAS2559, pTAS2559->mnCurrentCalibration);
1030 if (bRestorePower) {
1031 dev_dbg(pTAS2559->dev, "%s, set vboost, before power on %d\n",
1032 __func__, pTAS2559->mnVBoostState);
1033 nResult = tas2559_set_VBoost(pTAS2559, pTAS2559->mnVBoostState, false);
1037 pTAS2559->clearIRQ(pTAS2559);
1038 nResult = tas2559_DevStartup(pTAS2559, pNewConfiguration->mnDevices);
1042 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1043 nResult = tas2559_checkPLL(pTAS2559);
1046 nResult = tas2559_DevShutdown(pTAS2559, pNewConfiguration->mnDevices);
1047 pTAS2559->mbPowerUp = false;
1052 if (pNewConfiguration->mnDevices & DevB) {
1053 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData),
1054 TAS2559_BLOCK_PST_POWERUP_DEV_B);
1060 dev_dbg(pTAS2559->dev,
1061 "device powered up, load unmute\n");
1062 nResult = tas2559_DevMute(pTAS2559, pNewConfiguration->mnDevices, false);
1067 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1068 pTAS2559->enableIRQ(pTAS2559, pNewConfiguration->mnDevices, true);
1070 if (!hrtimer_active(&pTAS2559->mtimer)) {
1071 pTAS2559->mnDieTvReadCounter = 0;
1072 hrtimer_start(&pTAS2559->mtimer,
1073 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1081 dev_err(pTAS2559->dev, "%s, load new conf %s error\n", __func__, pNewConfiguration->mpName);
1086 int tas2559_enable(struct tas2559_priv *pTAS2559, bool bEnable)
1089 struct TProgram *pProgram;
1090 struct TConfiguration *pConfiguration;
1091 unsigned int nValue;
1093 dev_dbg(pTAS2559->dev, "%s: %s\n", __func__, bEnable ? "On" : "Off");
1095 if ((pTAS2559->mpFirmware->mnPrograms == 0)
1096 || (pTAS2559->mpFirmware->mnConfigurations == 0)) {
1097 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
1101 /* check safe guard*/
1102 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SAFE_GUARD_REG, &nValue);
1105 if ((nValue & 0xff) != TAS2559_SAFE_GUARD_PATTERN) {
1106 dev_err(pTAS2559->dev, "ERROR DevA safe guard (0x%x) failure!\n", nValue);
1108 pTAS2559->mnErrCode = ERROR_SAFE_GUARD;
1109 pTAS2559->mbPowerUp = true;
1113 pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
1115 if (!pTAS2559->mbPowerUp) {
1116 if (!pTAS2559->mbCalibrationLoaded) {
1117 tas2559_set_calibration(pTAS2559, 0xFF);
1118 pTAS2559->mbCalibrationLoaded = true;
1121 if (pTAS2559->mbLoadConfigurationPrePowerUp) {
1122 pTAS2559->mbLoadConfigurationPrePowerUp = false;
1123 nResult = tas2559_load_coefficient(pTAS2559,
1124 pTAS2559->mnCurrentConfiguration, pTAS2559->mnNewConfiguration, false);
1130 if (pTAS2559->mbLoadVBoostPrePowerUp) {
1131 dev_dbg(pTAS2559->dev, "%s, cfg boost before power on new %d, current=%d\n",
1132 __func__, pTAS2559->mnVBoostNewState, pTAS2559->mnVBoostState);
1133 nResult = tas2559_set_VBoost(pTAS2559, pTAS2559->mnVBoostNewState, false);
1136 pTAS2559->mbLoadVBoostPrePowerUp = false;
1139 pTAS2559->clearIRQ(pTAS2559);
1140 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
1141 nResult = tas2559_DevStartup(pTAS2559, pConfiguration->mnDevices);
1145 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1146 nResult = tas2559_checkPLL(pTAS2559);
1148 nResult = tas2559_DevShutdown(pTAS2559, pConfiguration->mnDevices);
1153 if (pConfiguration->mnDevices & DevB) {
1154 nResult = tas2559_load_data(pTAS2559, &(pConfiguration->mData),
1155 TAS2559_BLOCK_PST_POWERUP_DEV_B);
1160 nResult = tas2559_DevMute(pTAS2559, pConfiguration->mnDevices, false);
1164 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1166 pTAS2559->enableIRQ(pTAS2559, pConfiguration->mnDevices, true);
1167 if (!hrtimer_active(&pTAS2559->mtimer)) {
1168 pTAS2559->mnDieTvReadCounter = 0;
1169 hrtimer_start(&pTAS2559->mtimer,
1170 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1174 pTAS2559->mbPowerUp = true;
1175 pTAS2559->mnRestart = 0;
1178 if (pTAS2559->mbPowerUp) {
1179 if (hrtimer_active(&pTAS2559->mtimer))
1180 hrtimer_cancel(&pTAS2559->mtimer);
1182 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
1184 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1186 pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
1189 nResult = tas2559_DevShutdown(pTAS2559, pConfiguration->mnDevices);
1193 pTAS2559->mbPowerUp = false;
1194 pTAS2559->mnRestart = 0;
1203 if (pTAS2559->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD))
1207 dev_dbg(pTAS2559->dev, "%s: exit\n", __func__);
1211 int tas2559_set_sampling_rate(struct tas2559_priv *pTAS2559, unsigned int nSamplingRate)
1214 struct TConfiguration *pConfiguration;
1215 unsigned int nConfiguration;
1217 dev_dbg(pTAS2559->dev, "%s: nSamplingRate = %d [Hz]\n", __func__,
1220 if ((!pTAS2559->mpFirmware->mpPrograms) ||
1221 (!pTAS2559->mpFirmware->mpConfigurations)) {
1222 dev_err(pTAS2559->dev, "Firmware not loaded\n");
1227 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
1229 if (pConfiguration->mnSamplingRate == nSamplingRate) {
1230 dev_info(pTAS2559->dev, "Sampling rate for current configuration matches: %d\n",
1236 for (nConfiguration = 0;
1237 nConfiguration < pTAS2559->mpFirmware->mnConfigurations;
1240 &(pTAS2559->mpFirmware->mpConfigurations[nConfiguration]);
1242 if ((pConfiguration->mnSamplingRate == nSamplingRate)
1243 && (pConfiguration->mnProgram == pTAS2559->mnCurrentProgram)) {
1244 dev_info(pTAS2559->dev,
1245 "Found configuration: %s, with compatible sampling rate %d\n",
1246 pConfiguration->mpName, nSamplingRate);
1247 nResult = tas2559_load_configuration(pTAS2559, nConfiguration, false);
1252 dev_err(pTAS2559->dev, "Cannot find a configuration that supports sampling rate: %d\n",
1260 static void fw_print_header(struct tas2559_priv *pTAS2559, struct TFirmware *pFirmware)
1262 dev_info(pTAS2559->dev, "FW Size = %d", pFirmware->mnFWSize);
1263 dev_info(pTAS2559->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
1264 dev_info(pTAS2559->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
1265 dev_info(pTAS2559->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
1266 dev_info(pTAS2559->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
1267 dev_info(pTAS2559->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
1268 dev_info(pTAS2559->dev, "DDC Name = %s", pFirmware->mpDDCName);
1269 dev_info(pTAS2559->dev, "Description = %s", pFirmware->mpDescription);
1272 inline unsigned int fw_convert_number(unsigned char *pData)
1274 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
1277 static int fw_parse_header(struct tas2559_priv *pTAS2559,
1278 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1280 unsigned char *pDataStart = pData;
1282 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
1285 dev_err(pTAS2559->dev, "Firmware: Header too short");
1289 if (memcmp(pData, pMagicNumber, 4)) {
1290 dev_err(pTAS2559->dev, "Firmware: Magic number doesn't match");
1296 pFirmware->mnFWSize = fw_convert_number(pData);
1299 pFirmware->mnChecksum = fw_convert_number(pData);
1302 pFirmware->mnPPCVersion = fw_convert_number(pData);
1305 pFirmware->mnFWVersion = fw_convert_number(pData);
1308 pFirmware->mnDriverVersion = fw_convert_number(pData);
1311 pFirmware->mnTimeStamp = fw_convert_number(pData);
1314 memcpy(pFirmware->mpDDCName, pData, 64);
1318 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1321 if ((pData - pDataStart) >= nSize) {
1322 dev_err(pTAS2559->dev, "Firmware: Header too short after DDC description");
1326 pFirmware->mnDeviceFamily = fw_convert_number(pData);
1329 if (pFirmware->mnDeviceFamily != 0) {
1330 dev_err(pTAS2559->dev,
1331 "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
1335 pFirmware->mnDevice = fw_convert_number(pData);
1338 if (pFirmware->mnDevice != 4) {
1339 dev_err(pTAS2559->dev,
1340 "device %d, not TAS2559", pFirmware->mnDevice);
1344 fw_print_header(pTAS2559, pFirmware);
1346 return pData - pDataStart;
1349 static int fw_parse_block_data(struct tas2559_priv *pTAS2559, struct TFirmware *pFirmware,
1350 struct TBlock *pBlock, unsigned char *pData)
1352 unsigned char *pDataStart = pData;
1355 pBlock->mnType = fw_convert_number(pData);
1358 if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
1359 pBlock->mbPChkSumPresent = pData[0];
1362 pBlock->mnPChkSum = pData[0];
1365 pBlock->mbYChkSumPresent = pData[0];
1368 pBlock->mnYChkSum = pData[0];
1371 pBlock->mbPChkSumPresent = 0;
1372 pBlock->mbYChkSumPresent = 0;
1375 pBlock->mnCommands = fw_convert_number(pData);
1378 n = pBlock->mnCommands * 4;
1379 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
1382 return pData - pDataStart;
1385 static int fw_parse_data(struct tas2559_priv *pTAS2559, struct TFirmware *pFirmware,
1386 struct TData *pImageData, unsigned char *pData)
1388 unsigned char *pDataStart = pData;
1389 unsigned int nBlock;
1392 memcpy(pImageData->mpName, pData, 64);
1396 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1399 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
1402 pImageData->mpBlocks =
1403 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
1405 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
1406 n = fw_parse_block_data(pTAS2559, pFirmware,
1407 &(pImageData->mpBlocks[nBlock]), pData);
1411 return pData - pDataStart;
1414 static int fw_parse_pll_data(struct tas2559_priv *pTAS2559,
1415 struct TFirmware *pFirmware, unsigned char *pData)
1417 unsigned char *pDataStart = pData;
1422 pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
1425 if (pFirmware->mnPLLs == 0)
1428 pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
1430 for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
1431 pPLL = &(pFirmware->mpPLLs[nPLL]);
1433 memcpy(pPLL->mpName, pData, 64);
1437 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1440 n = fw_parse_block_data(pTAS2559, pFirmware, &(pPLL->mBlock), pData);
1445 return pData - pDataStart;
1448 static int fw_parse_program_data(struct tas2559_priv *pTAS2559,
1449 struct TFirmware *pFirmware, unsigned char *pData)
1451 unsigned char *pDataStart = pData;
1453 unsigned int nProgram;
1454 struct TProgram *pProgram;
1456 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
1459 if (pFirmware->mnPrograms == 0)
1462 pFirmware->mpPrograms =
1463 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
1465 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
1466 pProgram = &(pFirmware->mpPrograms[nProgram]);
1467 memcpy(pProgram->mpName, pData, 64);
1471 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1474 pProgram->mnAppMode = pData[0];
1477 pProgram->mnBoost = (pData[0] << 8) + pData[1];
1480 n = fw_parse_data(pTAS2559, pFirmware, &(pProgram->mData), pData);
1486 return pData - pDataStart;
1489 static int fw_parse_configuration_data(struct tas2559_priv *pTAS2559,
1490 struct TFirmware *pFirmware, unsigned char *pData)
1492 unsigned char *pDataStart = pData;
1494 unsigned int nConfiguration;
1495 struct TConfiguration *pConfiguration;
1497 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
1500 if (pFirmware->mnConfigurations == 0)
1503 pFirmware->mpConfigurations =
1504 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
1507 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
1509 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
1510 memcpy(pConfiguration->mpName, pData, 64);
1514 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1517 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
1518 || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
1519 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {
1520 pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
1523 pConfiguration->mnDevices = DevBoth;
1525 pConfiguration->mnProgram = pData[0];
1528 pConfiguration->mnPLL = pData[0];
1531 pConfiguration->mnSamplingRate = fw_convert_number(pData);
1534 n = fw_parse_data(pTAS2559, pFirmware, &(pConfiguration->mData), pData);
1540 return pData - pDataStart;
1543 int fw_parse_calibration_data(struct tas2559_priv *pTAS2559,
1544 struct TFirmware *pFirmware, unsigned char *pData)
1546 unsigned char *pDataStart = pData;
1548 unsigned int nCalibration;
1549 struct TCalibration *pCalibration;
1551 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
1554 if (pFirmware->mnCalibrations == 0)
1557 pFirmware->mpCalibrations =
1558 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
1560 for (nCalibration = 0;
1561 nCalibration < pFirmware->mnCalibrations;
1563 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
1564 memcpy(pCalibration->mpName, pData, 64);
1568 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1571 pCalibration->mnProgram = pData[0];
1574 pCalibration->mnConfiguration = pData[0];
1577 n = fw_parse_data(pTAS2559, pFirmware, &(pCalibration->mData), pData);
1583 return pData - pDataStart;
1586 static int fw_parse(struct tas2559_priv *pTAS2559,
1587 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1591 nPosition = fw_parse_header(pTAS2559, pFirmware, pData, nSize);
1593 if (nPosition < 0) {
1594 dev_err(pTAS2559->dev, "Firmware: Wrong Header");
1598 if (nPosition >= nSize) {
1599 dev_err(pTAS2559->dev, "Firmware: Too short");
1607 nPosition = fw_parse_pll_data(pTAS2559, pFirmware, pData);
1613 nPosition = fw_parse_program_data(pTAS2559, pFirmware, pData);
1619 nPosition = fw_parse_configuration_data(pTAS2559, pFirmware, pData);
1626 nPosition = fw_parse_calibration_data(pTAS2559, pFirmware, pData);
1632 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
1633 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
1634 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
1635 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
1636 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
1637 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
1638 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
1639 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
1640 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
1641 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
1642 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
1643 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
1644 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
1645 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
1646 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
1647 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
1648 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
1651 static int DevAPageYRAM(struct tas2559_priv *pTAS2559,
1652 struct TYCRC *pCRCData,
1653 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1657 if (nBook == TAS2559_YRAM_BOOK1) {
1658 if (nPage == TAS2559_YRAM1_PAGE) {
1659 if (nReg >= TAS2559_YRAM1_START_REG) {
1660 pCRCData->mnOffset = nReg;
1661 pCRCData->mnLen = len;
1663 } else if ((nReg + len) > TAS2559_YRAM1_START_REG) {
1664 pCRCData->mnOffset = TAS2559_YRAM1_START_REG;
1665 pCRCData->mnLen = len - (TAS2559_YRAM1_START_REG - nReg);
1669 } else if (nPage == TAS2559_YRAM3_PAGE) {
1670 if (nReg > TAS2559_YRAM3_END_REG) {
1672 } else if (nReg >= TAS2559_YRAM3_START_REG) {
1673 if ((nReg + len) > TAS2559_YRAM3_END_REG) {
1674 pCRCData->mnOffset = nReg;
1675 pCRCData->mnLen = TAS2559_YRAM3_END_REG - nReg + 1;
1678 pCRCData->mnOffset = nReg;
1679 pCRCData->mnLen = len;
1683 if ((nReg + (len - 1)) < TAS2559_YRAM3_START_REG) {
1685 } else if ((nReg + (len - 1)) <= TAS2559_YRAM3_END_REG) {
1686 pCRCData->mnOffset = TAS2559_YRAM3_START_REG;
1687 pCRCData->mnLen = len - (TAS2559_YRAM3_START_REG - nReg);
1690 pCRCData->mnOffset = TAS2559_YRAM3_START_REG;
1691 pCRCData->mnLen = TAS2559_YRAM3_END_REG - TAS2559_YRAM3_START_REG + 1;
1696 } else if (nBook == TAS2559_YRAM_BOOK2) {
1697 if (nPage == TAS2559_YRAM5_PAGE) {
1698 if (nReg > TAS2559_YRAM5_END_REG) {
1700 } else if (nReg >= TAS2559_YRAM5_START_REG) {
1701 if ((nReg + len) > TAS2559_YRAM5_END_REG) {
1702 pCRCData->mnOffset = nReg;
1703 pCRCData->mnLen = TAS2559_YRAM5_END_REG - nReg + 1;
1706 pCRCData->mnOffset = nReg;
1707 pCRCData->mnLen = len;
1711 if ((nReg + (len - 1)) < TAS2559_YRAM5_START_REG) {
1713 } else if ((nReg + (len - 1)) <= TAS2559_YRAM5_END_REG) {
1714 pCRCData->mnOffset = TAS2559_YRAM5_START_REG;
1715 pCRCData->mnLen = len - (TAS2559_YRAM5_START_REG - nReg);
1718 pCRCData->mnOffset = TAS2559_YRAM5_START_REG;
1719 pCRCData->mnLen = TAS2559_YRAM5_END_REG - TAS2559_YRAM5_START_REG + 1;
1724 } else if (nBook == TAS2559_YRAM_BOOK3) {
1725 if (nPage == TAS2559_YRAM6_PAGE) {
1726 if (nReg > TAS2559_YRAM6_END_REG) {
1728 } else if (nReg >= TAS2559_YRAM6_START_REG) {
1729 if ((nReg + len) > TAS2559_YRAM6_END_REG) {
1730 pCRCData->mnOffset = nReg;
1731 pCRCData->mnLen = TAS2559_YRAM6_END_REG - nReg + 1;
1734 pCRCData->mnOffset = nReg;
1735 pCRCData->mnLen = len;
1739 if ((nReg + (len - 1)) < TAS2559_YRAM6_START_REG) {
1741 } else if ((nReg + (len - 1)) <= TAS2559_YRAM6_END_REG) {
1742 pCRCData->mnOffset = TAS2559_YRAM6_START_REG;
1743 pCRCData->mnLen = len - (TAS2559_YRAM6_START_REG - nReg);
1746 pCRCData->mnOffset = TAS2559_YRAM6_START_REG;
1747 pCRCData->mnLen = TAS2559_YRAM6_END_REG - TAS2559_YRAM6_START_REG + 1;
1759 static int isInPageYRAM(struct tas2559_priv *pTAS2559,
1760 enum channel dev, struct TYCRC *pCRCData,
1761 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1766 nResult = DevAPageYRAM(pTAS2559, pCRCData, nBook, nPage, nReg, len);
1771 static int DevABlockYRAM(struct tas2559_priv *pTAS2559,
1772 struct TYCRC *pCRCData,
1773 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1777 if (nBook == TAS2559_YRAM_BOOK1) {
1778 if (nPage < TAS2559_YRAM2_START_PAGE)
1780 else if (nPage <= TAS2559_YRAM2_END_PAGE) {
1781 if (nReg > TAS2559_YRAM2_END_REG) {
1783 } else if (nReg >= TAS2559_YRAM2_START_REG) {
1784 pCRCData->mnOffset = nReg;
1785 pCRCData->mnLen = len;
1788 if ((nReg + (len - 1)) < TAS2559_YRAM2_START_REG) {
1791 pCRCData->mnOffset = TAS2559_YRAM2_START_REG;
1792 pCRCData->mnLen = nReg + len - TAS2559_YRAM2_START_REG;
1799 } else if (nBook == TAS2559_YRAM_BOOK2) {
1800 if (nPage < TAS2559_YRAM4_START_PAGE) {
1802 } else if (nPage <= TAS2559_YRAM4_END_PAGE) {
1803 if ((nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
1804 && (nReg == TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
1806 dev_dbg(pTAS2559->dev, "bypass swap\n");
1808 } else if (nReg > TAS2559_YRAM2_END_REG) {
1810 } else if (nReg >= TAS2559_YRAM2_START_REG) {
1811 pCRCData->mnOffset = nReg;
1812 pCRCData->mnLen = len;
1815 if ((nReg + (len - 1)) < TAS2559_YRAM2_START_REG) {
1818 pCRCData->mnOffset = TAS2559_YRAM2_START_REG;
1819 pCRCData->mnLen = nReg + len - TAS2559_YRAM2_START_REG;
1833 static int DevBBlockYRAM(struct tas2559_priv *pTAS2559,
1834 struct TYCRC *pCRCData,
1835 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1839 if (nBook == TAS2560_YRAM_BOOK) {
1840 if (nPage < TAS2560_YRAM_START_PAGE) {
1842 } else if (nPage <= TAS2560_YRAM_END_PAGE) {
1843 if (nReg > TAS2560_YRAM_END_REG) {
1845 } else if (nReg >= TAS2560_YRAM_START_REG) {
1846 pCRCData->mnOffset = nReg;
1847 pCRCData->mnLen = len;
1850 if ((nReg + (len - 1)) < TAS2560_YRAM_START_REG) {
1853 pCRCData->mnOffset = TAS2560_YRAM_START_REG;
1854 pCRCData->mnLen = nReg + len - TAS2560_YRAM_START_REG;
1866 static int isInBlockYRAM(struct tas2559_priv *pTAS2559,
1867 enum channel dev, struct TYCRC *pCRCData,
1868 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1873 nResult = DevABlockYRAM(pTAS2559, pCRCData, nBook, nPage, nReg, len);
1876 nResult = DevBBlockYRAM(pTAS2559, pCRCData, nBook, nPage, nReg, len);
1882 static int isYRAM(struct tas2559_priv *pTAS2559,
1883 enum channel dev, struct TYCRC *pCRCData,
1884 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1888 nResult = isInPageYRAM(pTAS2559, dev, pCRCData, nBook, nPage, nReg, len);
1891 nResult = isInBlockYRAM(pTAS2559, dev, pCRCData, nBook, nPage, nReg, len);
1897 * crc8 - calculate a crc8 over the given input data.
1899 * table: crc table used for calculation.
1900 * pdata: pointer to data buffer.
1901 * nbytes: number of bytes in data buffer.
1902 * crc: previous returned crc8 value.
1904 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
1906 /* loop over the buffer data */
1907 while (nbytes-- > 0)
1908 crc = table[(crc ^ *pdata++) & 0xff];
1913 static int doSingleRegCheckSum(struct tas2559_priv *pTAS2559, enum channel chl,
1914 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
1917 struct TYCRC sCRCData;
1918 unsigned int nData1 = 0, nData2 = 0;
1919 unsigned char nRegVal;
1922 if ((nBook == TAS2559_BOOK_ID(TAS2559_SA_COEFF_SWAP_REG))
1923 && (nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
1924 && (nReg >= TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
1925 && (nReg <= (TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG) + 4))) {
1926 /* DSP swap command, pass */
1932 nResult = isYRAM(pTAS2559, chl, &sCRCData, nBook, nPage, nReg, 1);
1936 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_REG(nBook, nPage, nReg), &nData1);
1940 } else if (chl == DevB) {
1941 nResult = pTAS2559->read(pTAS2559, DevB, TAS2559_REG(nBook, nPage, nReg), &nData2);
1948 if (nData1 != nValue) {
1949 dev_err(pTAS2559->dev,
1950 "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1951 __LINE__, nBook, nPage, nReg, nValue, nData1);
1953 pTAS2559->mnErrCode |= ERROR_YRAM_CRCCHK;
1958 } else if (chl == DevB) {
1959 if (nData2 != nValue) {
1960 dev_err(pTAS2559->dev,
1961 "error (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1962 __LINE__, nBook, nPage, nReg, nValue, nData2);
1964 pTAS2559->mnErrCode |= ERROR_YRAM_CRCCHK;
1974 nResult = ti_crc8(crc8_lookup_table, &nRegVal, 1, 0);
1982 static int doMultiRegCheckSum(struct tas2559_priv *pTAS2559, enum channel chl,
1983 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
1986 unsigned char nCRCChkSum = 0;
1987 unsigned char nBuf1[128];
1988 unsigned char nBuf2[128];
1989 struct TYCRC TCRCData;
1990 unsigned char *pRegVal;
1992 if ((nReg + len - 1) > 127) {
1994 dev_err(pTAS2559->dev, "firmware error\n");
1998 if ((nBook == TAS2559_BOOK_ID(TAS2559_SA_COEFF_SWAP_REG))
1999 && (nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
2000 && (nReg == TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
2002 /* DSP swap command, pass */
2007 nResult = isYRAM(pTAS2559, chl, &TCRCData, nBook, nPage, nReg, len);
2011 dev_err(pTAS2559->dev, "firmware error\n");
2016 nResult = pTAS2559->bulk_read(pTAS2559, DevA,
2017 TAS2559_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
2021 } else if (chl == DevB) {
2022 nResult = pTAS2559->bulk_read(pTAS2559, DevB,
2023 TAS2559_REG(nBook, nPage, TCRCData.mnOffset), nBuf2, TCRCData.mnLen);
2031 } else if (chl == DevB)
2034 dev_err(pTAS2559->dev, "channel error %d\n", chl);
2039 for (i = 0; i < TCRCData.mnLen; i++) {
2040 if ((nBook == TAS2559_BOOK_ID(TAS2559_SA_COEFF_SWAP_REG))
2041 && (nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
2042 && ((i + TCRCData.mnOffset)
2043 >= TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
2044 && ((i + TCRCData.mnOffset)
2045 <= (TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG) + 4))) {
2046 /* DSP swap command, bypass */
2049 nCRCChkSum += ti_crc8(crc8_lookup_table, &pRegVal[i], 1, 0);
2053 nResult = nCRCChkSum;
2062 static int tas2559_load_block(struct tas2559_priv *pTAS2559, struct TBlock *pBlock)
2065 unsigned int nCommand = 0;
2066 unsigned char nBook;
2067 unsigned char nPage;
2068 unsigned char nOffset;
2069 unsigned char nData;
2070 unsigned int nValue1;
2071 unsigned int nLength;
2072 unsigned int nSleep;
2073 bool bDoYCRCChk = false;
2075 unsigned char nCRCChkSum = 0;
2077 unsigned char *pData = pBlock->mpData;
2079 dev_dbg(pTAS2559->dev, "%s: Type = %d, commands = %d\n", __func__,
2080 pBlock->mnType, pBlock->mnCommands);
2082 if (pBlock->mnType == TAS2559_BLOCK_PLL) {
2084 } else if ((pBlock->mnType == TAS2559_BLOCK_PGM_DEV_A)
2085 || (pBlock->mnType == TAS2559_BLOCK_CFG_COEFF_DEV_A)
2086 || (pBlock->mnType == TAS2559_BLOCK_CFG_PRE_DEV_A)) {
2088 } else if ((pBlock->mnType == TAS2559_BLOCK_PGM_DEV_B)
2089 || (pBlock->mnType == TAS2559_BLOCK_PST_POWERUP_DEV_B)
2090 || (pBlock->mnType == TAS2559_BLOCK_CFG_PRE_DEV_B)) {
2093 dev_err(pTAS2559->dev, "block type error %d\n", pBlock->mnType);
2098 if (pBlock->mbYChkSumPresent && pTAS2559->mbYCRCEnable)
2103 if (pBlock->mbPChkSumPresent) {
2105 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_CRC_RESET_REG, 1);
2109 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_CRC_CHK_REG, 1);
2120 while (nCommand < pBlock->mnCommands) {
2121 pData = pBlock->mpData + nCommand * 4;
2128 if (nOffset <= 0x7F) {
2129 nResult = pTAS2559->write(pTAS2559,
2130 chl, TAS2559_REG(nBook, nPage, nOffset), nData);
2135 nResult = doSingleRegCheckSum(pTAS2559,
2136 chl, nBook, nPage, nOffset, nData);
2139 nCRCChkSum += (unsigned char)nResult;
2141 } else if (nOffset == 0x81) {
2142 nSleep = (nBook << 8) + nPage;
2144 } else if (nOffset == 0x85) {
2146 nLength = (nBook << 8) + nPage;
2152 nResult = pTAS2559->bulk_write(pTAS2559,
2153 chl, TAS2559_REG(nBook, nPage, nOffset), pData + 3, nLength);
2158 nResult = doMultiRegCheckSum(pTAS2559,
2159 chl, nBook, nPage, nOffset, nLength);
2163 nCRCChkSum += (unsigned char)nResult;
2166 nResult = pTAS2559->write(pTAS2559,
2167 chl, TAS2559_REG(nBook, nPage, nOffset), pData[3]);
2172 nResult = doSingleRegCheckSum(pTAS2559,
2173 chl, nBook, nPage, nOffset, pData[3]);
2177 nCRCChkSum += (unsigned char)nResult;
2184 nCommand += ((nLength - 2) / 4) + 1;
2188 if (pBlock->mbPChkSumPresent) {
2190 nResult = pTAS2559->read(pTAS2559, DevA,
2191 TAS2559_CRC_CHECKSUM_REG, &nValue1);
2193 nResult = pTAS2559->read(pTAS2559, DevB,
2194 TAS2560_CRC_CHK_REG, &nValue1);
2199 if (nValue1 != pBlock->mnPChkSum) {
2200 dev_err(pTAS2559->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
2201 pBlock->mnPChkSum, (nValue1 & 0xff));
2203 pTAS2559->mnErrCode |= ERROR_PRAM_CRCCHK;
2208 pTAS2559->mnErrCode &= ~ERROR_PRAM_CRCCHK;
2209 dev_dbg(pTAS2559->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
2213 if (nCRCChkSum != pBlock->mnYChkSum) {
2214 dev_err(pTAS2559->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
2215 pBlock->mnYChkSum, nCRCChkSum);
2217 pTAS2559->mnErrCode |= ERROR_YRAM_CRCCHK;
2221 pTAS2559->mnErrCode &= ~ERROR_YRAM_CRCCHK;
2223 dev_dbg(pTAS2559->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
2228 if (nResult == -EAGAIN) {
2238 dev_err(pTAS2559->dev, "Block (%d) load error\n",
2244 static int tas2559_load_data(struct tas2559_priv *pTAS2559, struct TData *pData, unsigned int nType)
2247 unsigned int nBlock;
2248 struct TBlock *pBlock;
2250 dev_dbg(pTAS2559->dev,
2251 "TAS2559 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
2253 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
2254 pBlock = &(pData->mpBlocks[nBlock]);
2256 if (pBlock->mnType == nType) {
2257 nResult = tas2559_load_block(pTAS2559, pBlock);
2267 static int tas2559_load_configuration(struct tas2559_priv *pTAS2559,
2268 unsigned int nConfiguration, bool bLoadSame)
2271 struct TConfiguration *pCurrentConfiguration = NULL;
2272 struct TConfiguration *pNewConfiguration = NULL;
2274 dev_dbg(pTAS2559->dev, "%s: %d\n", __func__, nConfiguration);
2276 if ((!pTAS2559->mpFirmware->mpPrograms) ||
2277 (!pTAS2559->mpFirmware->mpConfigurations)) {
2278 dev_err(pTAS2559->dev, "Firmware not loaded\n");
2283 if (nConfiguration >= pTAS2559->mpFirmware->mnConfigurations) {
2284 dev_err(pTAS2559->dev, "Configuration %d doesn't exist\n",
2290 if ((!pTAS2559->mbLoadConfigurationPrePowerUp)
2291 && (nConfiguration == pTAS2559->mnCurrentConfiguration)
2293 dev_info(pTAS2559->dev, "Configuration %d is already loaded\n",
2299 pCurrentConfiguration =
2300 &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
2302 &(pTAS2559->mpFirmware->mpConfigurations[nConfiguration]);
2304 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
2305 dev_err(pTAS2559->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
2306 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
2311 if (pNewConfiguration->mnPLL >= pTAS2559->mpFirmware->mnPLLs) {
2312 dev_err(pTAS2559->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
2313 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
2318 if (pTAS2559->mbPowerUp) {
2319 dev_err(pTAS2559->dev, "%s, device power on, load new conf[%d] %s\n", __func__,
2320 nConfiguration, pNewConfiguration->mpName);
2321 nResult = tas2559_load_coefficient(pTAS2559, pTAS2559->mnCurrentConfiguration, nConfiguration, true);
2322 pTAS2559->mbLoadConfigurationPrePowerUp = false;
2324 dev_dbg(pTAS2559->dev,
2325 "TAS2559 was powered down, will load coefficient when power up\n");
2326 pTAS2559->mbLoadConfigurationPrePowerUp = true;
2327 pTAS2559->mnNewConfiguration = nConfiguration;
2333 if (pTAS2559->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
2340 int tas2559_set_config(struct tas2559_priv *pTAS2559, int config)
2342 struct TConfiguration *pConfiguration;
2343 struct TProgram *pProgram;
2344 unsigned int nProgram = pTAS2559->mnCurrentProgram;
2345 unsigned int nConfiguration = config;
2348 if ((!pTAS2559->mpFirmware->mpPrograms) ||
2349 (!pTAS2559->mpFirmware->mpConfigurations)) {
2350 dev_err(pTAS2559->dev, "Firmware not loaded\n");
2355 if (nConfiguration >= pTAS2559->mpFirmware->mnConfigurations) {
2356 dev_err(pTAS2559->dev, "Configuration %d doesn't exist\n",
2362 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nConfiguration]);
2363 pProgram = &(pTAS2559->mpFirmware->mpPrograms[nProgram]);
2365 if (nProgram != pConfiguration->mnProgram) {
2366 dev_err(pTAS2559->dev,
2367 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
2368 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
2369 nProgram, pProgram->mpName);
2374 dev_dbg(pTAS2559->dev, "%s, load new conf %s\n", __func__, pConfiguration->mpName);
2375 nResult = tas2559_load_configuration(pTAS2559, nConfiguration, false);
2382 void tas2559_clear_firmware(struct TFirmware *pFirmware)
2389 kfree(pFirmware->mpDescription);
2391 if (pFirmware->mpPLLs != NULL) {
2392 for (n = 0; n < pFirmware->mnPLLs; n++) {
2393 kfree(pFirmware->mpPLLs[n].mpDescription);
2394 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
2397 kfree(pFirmware->mpPLLs);
2400 if (pFirmware->mpPrograms != NULL) {
2401 for (n = 0; n < pFirmware->mnPrograms; n++) {
2402 kfree(pFirmware->mpPrograms[n].mpDescription);
2403 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
2405 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
2406 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
2408 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
2411 kfree(pFirmware->mpPrograms);
2414 if (pFirmware->mpConfigurations != NULL) {
2415 for (n = 0; n < pFirmware->mnConfigurations; n++) {
2416 kfree(pFirmware->mpConfigurations[n].mpDescription);
2417 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
2419 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
2420 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
2422 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
2425 kfree(pFirmware->mpConfigurations);
2428 if (pFirmware->mpCalibrations != NULL) {
2429 for (n = 0; n < pFirmware->mnCalibrations; n++) {
2430 kfree(pFirmware->mpCalibrations[n].mpDescription);
2431 kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
2433 for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
2434 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
2436 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
2439 kfree(pFirmware->mpCalibrations);
2442 memset(pFirmware, 0x00, sizeof(struct TFirmware));
2445 static int tas2559_load_calibration(struct tas2559_priv *pTAS2559, char *pFileName)
2450 unsigned char pBuffer[1000];
2453 dev_dbg(pTAS2559->dev, "%s:\n", __func__);
2457 nFile = sys_open(pFileName, O_RDONLY, 0);
2459 dev_info(pTAS2559->dev, "TAS2559 calibration file = %s, handle = %d\n",
2463 nSize = sys_read(nFile, pBuffer, 1000);
2466 dev_err(pTAS2559->dev, "TAS2559 cannot open calibration file: %s\n",
2476 tas2559_clear_firmware(pTAS2559->mpCalFirmware);
2477 dev_info(pTAS2559->dev, "TAS2559 calibration file size = %d\n", nSize);
2478 nResult = fw_parse(pTAS2559, pTAS2559->mpCalFirmware, pBuffer, nSize);
2481 dev_err(pTAS2559->dev, "TAS2559 calibration file is corrupt\n");
2483 dev_info(pTAS2559->dev, "TAS2559 calibration: %d calibrations\n",
2484 pTAS2559->mpCalFirmware->mnCalibrations);
2491 void tas2559_fw_ready(const struct firmware *pFW, void *pContext)
2493 struct tas2559_priv *pTAS2559 = (struct tas2559_priv *) pContext;
2495 unsigned int nProgram = 0;
2496 unsigned int nSampleRate = 0;
2498 #ifdef CONFIG_TAS2559_CODEC
2499 mutex_lock(&pTAS2559->codec_lock);
2502 #ifdef CONFIG_TAS2559_MISC
2503 mutex_lock(&pTAS2559->file_lock);
2505 dev_info(pTAS2559->dev, "%s:\n", __func__);
2507 if (unlikely(!pFW) || unlikely(!pFW->data)) {
2508 dev_err(pTAS2559->dev, "%s firmware is not loaded.\n",
2513 if (pTAS2559->mpFirmware->mpConfigurations) {
2514 nProgram = pTAS2559->mnCurrentProgram;
2515 nSampleRate = pTAS2559->mnCurrentSampleRate;
2516 dev_dbg(pTAS2559->dev, "clear current firmware\n");
2517 tas2559_clear_firmware(pTAS2559->mpFirmware);
2520 nResult = fw_parse(pTAS2559, pTAS2559->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
2521 release_firmware(pFW);
2524 dev_err(pTAS2559->dev, "firmware is corrupt\n");
2528 if (!pTAS2559->mpFirmware->mnPrograms) {
2529 dev_err(pTAS2559->dev, "firmware contains no programs\n");
2534 if (!pTAS2559->mpFirmware->mnConfigurations) {
2535 dev_err(pTAS2559->dev, "firmware contains no configurations\n");
2540 if (nProgram >= pTAS2559->mpFirmware->mnPrograms) {
2541 dev_info(pTAS2559->dev,
2542 "no previous program, set to default\n");
2546 pTAS2559->mnCurrentSampleRate = nSampleRate;
2547 nResult = tas2559_set_program(pTAS2559, nProgram, -1);
2551 #ifdef CONFIG_TAS2559_CODEC
2552 mutex_unlock(&pTAS2559->codec_lock);
2555 #ifdef CONFIG_TAS2559_MISC
2556 mutex_unlock(&pTAS2559->file_lock);
2560 int tas2559_set_program(struct tas2559_priv *pTAS2559,
2561 unsigned int nProgram, int nConfig)
2563 struct TProgram *pProgram;
2564 struct TConfiguration *pConfiguration;
2565 unsigned int nConfiguration = 0;
2566 unsigned int nSampleRate = 0;
2567 bool bFound = false;
2570 if ((!pTAS2559->mpFirmware->mpPrograms) ||
2571 (!pTAS2559->mpFirmware->mpConfigurations)) {
2572 dev_err(pTAS2559->dev, "Firmware not loaded\n");
2577 if (nProgram >= pTAS2559->mpFirmware->mnPrograms) {
2578 dev_err(pTAS2559->dev, "TAS2559: Program %d doesn't exist\n",
2586 nSampleRate = pTAS2559->mnCurrentSampleRate;
2588 while (!bFound && (nConfiguration < pTAS2559->mpFirmware->mnConfigurations)) {
2589 if (pTAS2559->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
2590 if (nSampleRate == 0) {
2592 dev_info(pTAS2559->dev, "find default configuration %d\n", nConfiguration);
2593 } else if (nSampleRate == pTAS2559->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
2595 dev_info(pTAS2559->dev, "find matching configuration %d\n", nConfiguration);
2605 dev_err(pTAS2559->dev,
2606 "Program %d, no valid configuration found for sample rate %d, ignore\n",
2607 nProgram, nSampleRate);
2612 if (pTAS2559->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
2613 dev_err(pTAS2559->dev, "%s, configuration program doesn't match\n", __func__);
2618 nConfiguration = nConfig;
2621 pProgram = &(pTAS2559->mpFirmware->mpPrograms[nProgram]);
2623 if (pTAS2559->mbPowerUp) {
2624 dev_info(pTAS2559->dev,
2625 "device powered up, power down to load program %d (%s)\n",
2626 nProgram, pProgram->mpName);
2628 if (hrtimer_active(&pTAS2559->mtimer))
2629 hrtimer_cancel(&pTAS2559->mtimer);
2631 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE)
2632 pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
2634 nResult = tas2559_DevShutdown(pTAS2559, DevBoth);
2640 pTAS2559->hw_reset(pTAS2559);
2641 nResult = pTAS2559->write(pTAS2559, DevBoth, TAS2559_SW_RESET_REG, 0x01);
2646 nResult = tas2559_load_default(pTAS2559);
2650 dev_info(pTAS2559->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
2651 nResult = tas2559_load_data(pTAS2559, &(pProgram->mData), TAS2559_BLOCK_PGM_DEV_A);
2655 nResult = tas2559_load_data(pTAS2559, &(pProgram->mData), TAS2559_BLOCK_PGM_DEV_B);
2659 pTAS2559->mnCurrentProgram = nProgram;
2660 pTAS2559->mnDevGain = 15;
2661 pTAS2559->mnDevCurrentGain = 15;
2663 nResult = tas2559_load_coefficient(pTAS2559, -1, nConfiguration, false);
2667 if (pTAS2559->mbPowerUp) {
2668 dev_info(pTAS2559->dev, "%s, load VBoost before power on %d\n", __func__, pTAS2559->mnVBoostState);
2669 nResult = tas2559_set_VBoost(pTAS2559, pTAS2559->mnVBoostState, false);
2673 pTAS2559->clearIRQ(pTAS2559);
2674 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
2675 nResult = tas2559_DevStartup(pTAS2559, pConfiguration->mnDevices);
2679 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
2680 nResult = tas2559_checkPLL(pTAS2559);
2682 nResult = tas2559_DevShutdown(pTAS2559, pConfiguration->mnDevices);
2683 pTAS2559->mbPowerUp = false;
2688 if (pConfiguration->mnDevices & DevB) {
2689 nResult = tas2559_load_data(pTAS2559, &(pConfiguration->mData),
2690 TAS2559_BLOCK_PST_POWERUP_DEV_B);
2695 nResult = tas2559_DevMute(pTAS2559, pConfiguration->mnDevices, false);
2699 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
2700 pTAS2559->enableIRQ(pTAS2559, pConfiguration->mnDevices, true);
2702 if (!hrtimer_active(&pTAS2559->mtimer)) {
2703 pTAS2559->mnDieTvReadCounter = 0;
2704 hrtimer_start(&pTAS2559->mtimer,
2705 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
2713 if (pTAS2559->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
2720 int tas2559_set_calibration(struct tas2559_priv *pTAS2559, int nCalibration)
2722 struct TCalibration *pCalibration = NULL;
2723 struct TConfiguration *pConfiguration;
2724 struct TProgram *pProgram;
2727 if ((!pTAS2559->mpFirmware->mpPrograms)
2728 || (!pTAS2559->mpFirmware->mpConfigurations)) {
2729 dev_err(pTAS2559->dev, "Firmware not loaded\n\r");
2734 if (nCalibration == 0x00FF) {
2735 dev_info(pTAS2559->dev, "load new calibration file %s\n", TAS2559_CAL_NAME);
2736 nResult = tas2559_load_calibration(pTAS2559, TAS2559_CAL_NAME);
2746 if (nCalibration >= pTAS2559->mpCalFirmware->mnCalibrations) {
2747 dev_err(pTAS2559->dev,
2748 "Calibration %d doesn't exist\n", nCalibration);
2753 pTAS2559->mnCurrentCalibration = nCalibration;
2755 if (pTAS2559->mbLoadConfigurationPrePowerUp)
2758 pCalibration = &(pTAS2559->mpCalFirmware->mpCalibrations[nCalibration]);
2759 pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
2760 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
2762 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
2763 dev_dbg(pTAS2559->dev, "Enable: load calibration\n");
2764 nResult = tas2559_load_data(pTAS2559, &(pCalibration->mData), TAS2559_BLOCK_CFG_COEFF_DEV_A);
2770 tas2559_clear_firmware(pTAS2559->mpCalFirmware);
2771 nResult = tas2559_set_program(pTAS2559, pTAS2559->mnCurrentProgram, pTAS2559->mnCurrentConfiguration);
2777 int tas2559_get_Cali_prm_r0(struct tas2559_priv *pTAS2559, enum channel chl, int *prm_r0)
2781 struct TCalibration *pCalibration;
2782 struct TData *pData;
2783 struct TBlock *pBlock;
2785 int nBook, nPage, nOffset;
2786 unsigned char *pCommands;
2788 bool bFound = false;
2791 if (!pTAS2559->mpCalFirmware->mnCalibrations) {
2792 dev_err(pTAS2559->dev, "%s, no calibration data\n", __func__);
2797 nReg = TAS2559_DEVA_CALI_R0_REG;
2798 else if (chl == DevB)
2799 nReg = TAS2559_DEVB_CALI_R0_REG;
2803 pCalibration = &(pTAS2559->mpCalFirmware->mpCalibrations[pTAS2559->mnCurrentCalibration]);
2804 pData = &(pCalibration->mData);
2806 for (n = 0; n < pData->mnBlocks; n++) {
2807 pBlock = &(pData->mpBlocks[n]);
2808 pCommands = pBlock->mpData;
2810 for (nn = 0 ; nn < pBlock->mnCommands;) {
2811 nBook = pCommands[4 * nn + 0];
2812 nPage = pCommands[4 * nn + 1];
2813 nOffset = pCommands[4 * nn + 2];
2815 if ((nOffset < 0x7f) || (nOffset == 0x81))
2818 if (nOffset == 0x85) {
2819 len = ((int)nBook << 8) | nPage;
2821 nBook = pCommands[4 * nn + 4];
2822 nPage = pCommands[4 * nn + 5];
2823 nOffset = pCommands[4 * nn + 6];
2825 if ((nBook == TAS2559_BOOK_ID(nReg))
2826 && (nPage == TAS2559_PAGE_ID(nReg))
2827 && (nOffset == TAS2559_PAGE_REG(nReg))) {
2828 nCali_Re = ((int)pCommands[4 * nn + 7] << 24)
2829 | ((int)pCommands[4 * nn + 8] << 16)
2830 | ((int)pCommands[4 * nn + 9] << 8)
2831 | (int)pCommands[4 * nn + 10];
2837 nn += ((len - 1) / 4);
2842 dev_err(pTAS2559->dev, "%s, format error %d\n", __func__, nOffset);
2856 int tas2559_parse_dt(struct device *dev, struct tas2559_priv *pTAS2559)
2858 struct device_node *np = dev->of_node;
2859 int rc = 0, ret = 0;
2862 pTAS2559->mnDevAGPIORST = of_get_named_gpio(np, "ti,tas2559-reset-gpio", 0);
2863 if (!gpio_is_valid(pTAS2559->mnDevAGPIORST))
2864 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2865 "ti,tas2559-reset-gpio", np->full_name, pTAS2559->mnDevAGPIORST);
2867 dev_dbg(pTAS2559->dev, "%s, tas2559 reset gpio %d\n", __func__, pTAS2559->mnDevAGPIORST);
2869 pTAS2559->mnDevBGPIORST = of_get_named_gpio(np, "ti,tas2560-reset-gpio", 0);
2870 if (!gpio_is_valid(pTAS2559->mnDevBGPIORST))
2871 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2872 "ti,tas2560-reset-gpio", np->full_name, pTAS2559->mnDevBGPIORST);
2874 dev_dbg(pTAS2559->dev, "%s, tas2560 reset gpio %d\n", __func__, pTAS2559->mnDevBGPIORST);
2876 pTAS2559->mnDevAGPIOIRQ = of_get_named_gpio(np, "ti,tas2559-irq-gpio", 0);
2877 if (!gpio_is_valid(pTAS2559->mnDevAGPIOIRQ))
2878 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2879 "ti,tas2559-irq-gpio", np->full_name, pTAS2559->mnDevAGPIOIRQ);
2881 pTAS2559->mnDevBGPIOIRQ = of_get_named_gpio(np, "ti,tas2560-irq-gpio", 0);
2882 if (!gpio_is_valid(pTAS2559->mnDevBGPIOIRQ))
2883 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2884 "ti,tas2560-irq-gpio", np->full_name, pTAS2559->mnDevBGPIOIRQ);
2886 rc = of_property_read_u32(np, "ti,tas2559-addr", &value);
2888 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2889 "ti,tas2559-addr", np->full_name, rc);
2893 pTAS2559->mnDevAAddr = value;
2894 dev_dbg(pTAS2559->dev, "ti,tas2559 addr=0x%x\n", pTAS2559->mnDevAAddr);
2897 rc = of_property_read_u32(np, "ti,tas2560-addr", &value);
2899 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2900 "ti,tas2560-addr", np->full_name, rc);
2904 pTAS2559->mnDevBAddr = value;
2905 dev_dbg(pTAS2559->dev, "ti,tas2560-addr=0x%x\n", pTAS2559->mnDevBAddr);
2908 rc = of_property_read_u32(np, "ti,tas2559-channel", &value);
2910 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2911 "ti,tas2559-channel", np->full_name, rc);
2913 pTAS2559->mnDevAChl = value;
2915 rc = of_property_read_u32(np, "ti,tas2560-channel", &value);
2917 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2918 "ti,tas2560-channel", np->full_name, rc);
2920 pTAS2559->mnDevBChl = value;
2922 rc = of_property_read_u32(np, "ti,echo-ref", &value);
2924 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2925 "ti,echo-ref", np->full_name, rc);
2927 pTAS2559->mnEchoRef = value;
2929 rc = of_property_read_u32(np, "ti,bit-rate", &value);
2931 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2932 "ti,i2s-bits", np->full_name, rc);
2934 pTAS2559->mnBitRate = value;
2936 rc = of_property_read_u32(np, "ti,ycrc-enable", &value);
2938 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2939 "ti,ycrc-enable", np->full_name, rc);
2941 pTAS2559->mbYCRCEnable = (value != 0);
2948 MODULE_AUTHOR("Texas Instruments Inc.");
2949 MODULE_DESCRIPTION("TAS2559 common functions for Android Linux");
2950 MODULE_LICENSE("GPL v2");