]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - tas2557sw-android/tas2557-android-driver.git/blob - tas2557-regmap.c
Fix warnings in some code scan
[tas2557sw-android/tas2557-android-driver.git] / tas2557-regmap.c
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 ** File:
14 **     tas2557-regmap.c
15 **
16 ** Description:
17 **     I2C driver with regmap for Texas Instruments TAS2557 High Performance 4W Smart Amplifier
18 **
19 ** =============================================================================
20 */
22 #ifdef CONFIG_TAS2557_REGMAP
24 #define DEBUG
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/pm.h>
30 #include <linux/i2c.h>
31 #include <linux/gpio.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/firmware.h>
34 #include <linux/regmap.h>
35 #include <linux/of.h>
36 #include <linux/of_gpio.h>
37 #include <linux/slab.h>
38 #include <linux/syscalls.h>
39 #include <linux/fcntl.h>
40 #include <linux/uaccess.h>
41 #include "tas2557.h"
42 #include "tas2557-core.h"
44 #ifdef CONFIG_TAS2557_CODEC
45 #include "tas2557-codec.h"
46 #endif
48 #ifdef CONFIG_TAS2557_MISC
49 #include "tas2557-misc.h"
50 #endif
52 #define ENABLE_TILOAD
53 #ifdef ENABLE_TILOAD
54 #include "tiload.h"
55 #endif
57 #define LOW_TEMPERATURE_GAIN 6
58 #define LOW_TEMPERATURE_COUNTER 12
60 static int tas2557_change_book_page(
61         struct tas2557_priv *pTAS2557,
62         unsigned char nBook,
63         unsigned char nPage)
64 {
65         int nResult = 0;
67         if ((pTAS2557->mnCurrentBook == nBook) 
68                 && pTAS2557->mnCurrentPage == nPage)
69                 goto end;
71         if (pTAS2557->mnCurrentBook != nBook) {
72                 nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, 0);
73                 if (nResult < 0) {
74                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
75                                 __func__, __LINE__, nResult);
76                         goto end;
77                 }
78                 pTAS2557->mnCurrentPage = 0;
79                 nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_REG, nBook);
80                 if (nResult < 0) {
81                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
82                                 __func__, __LINE__, nResult);
83                         goto end;
84                 }
85                 pTAS2557->mnCurrentBook = nBook;
86                 if (nPage != 0) {
87                         nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, nPage);
88                         if (nResult < 0) {
89                                 dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
90                                         __func__, __LINE__, nResult);
91                                 goto end;
92                         }
93                         pTAS2557->mnCurrentPage = nPage;
94                 }
95         } else if (pTAS2557->mnCurrentPage != nPage) {
96                 nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, nPage);
97                 if (nResult < 0) {
98                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
99                                 __func__, __LINE__, nResult);
100                         goto end;
101                 }
102                 pTAS2557->mnCurrentPage = nPage;
103         }
105 end:
106         if (nResult < 0)
107                 pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
108         else
109                 pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
111         return nResult;
114 static int tas2557_dev_read(
115         struct tas2557_priv *pTAS2557,
116         unsigned int nRegister,
117         unsigned int *pValue)
119         int nResult = 0;
120         unsigned int Value = 0;
122         mutex_lock(&pTAS2557->dev_lock);
124         if (pTAS2557->mbTILoadActive) {
125                 if (!(nRegister & 0x80000000))
126                         goto end; /* let only reads from TILoad pass. */
127                 nRegister &= ~0x80000000;
129                 dev_dbg(pTAS2557->dev, "TiLoad R REG B[%d]P[%d]R[%d]\n",
130                                 TAS2557_BOOK_ID(nRegister),
131                                 TAS2557_PAGE_ID(nRegister),
132                                 TAS2557_PAGE_REG(nRegister));
133         }
135         nResult = tas2557_change_book_page(pTAS2557, 
136                                 TAS2557_BOOK_ID(nRegister),
137                                 TAS2557_PAGE_ID(nRegister));
138         if (nResult >= 0) {
139                 nResult = regmap_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), &Value);
140                 if (nResult < 0) {
141                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
142                                 __func__, __LINE__, nResult);
143                         pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
144                         goto end;
145                 } else
146                         pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
147                 *pValue = Value;
148         }
150 end:
152         mutex_unlock(&pTAS2557->dev_lock);
153         return nResult;
156 static int tas2557_dev_write(
157         struct tas2557_priv *pTAS2557,
158         unsigned int nRegister,
159         unsigned int nValue)
161         int nResult = 0;
163         mutex_lock(&pTAS2557->dev_lock);
164         if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) {
165                 pTAS2557->mbTILoadActive = true;
166                 goto end;
167         }
169         if ((nRegister == 0xBABEBABE) && (nValue == 0xAFFEAFFE)) {
170                 pTAS2557->mbTILoadActive = false;
171                 goto end;
172         }
174         if (pTAS2557->mbTILoadActive) {
175                 if (!(nRegister & 0x80000000))
176                         goto end;/* let only writes from TILoad pass. */
177                 nRegister &= ~0x80000000;
179                 dev_dbg(pTAS2557->dev, "TiLoad W REG B[%d]P[%d]R[%d] =0x%x\n",
180                                                 TAS2557_BOOK_ID(nRegister),
181                                                 TAS2557_PAGE_ID(nRegister),
182                                                 TAS2557_PAGE_REG(nRegister),
183                                                 nValue);
184         }
186         nResult = tas2557_change_book_page(pTAS2557,
187                                 TAS2557_BOOK_ID(nRegister),
188                                 TAS2557_PAGE_ID(nRegister));
189         if (nResult >= 0) {
190                 nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nValue);
191                 if (nResult < 0) {
192                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
193                                 __func__, __LINE__, nResult);
194                         pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
195                 } else
196                         pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
197         }
199 end:
201         mutex_unlock(&pTAS2557->dev_lock);
203         return nResult;
206 static int tas2557_dev_bulk_read(
207         struct tas2557_priv *pTAS2557,
208         unsigned int nRegister,
209         u8 *pData,
210         unsigned int nLength)
212         int nResult = 0;
214         mutex_lock(&pTAS2557->dev_lock);
215         if (pTAS2557->mbTILoadActive) {
216                 if (!(nRegister & 0x80000000))
217                         goto end; /* let only writes from TILoad pass. */
219                 nRegister &= ~0x80000000;
220                 dev_dbg(pTAS2557->dev, "TiLoad BR REG B[%d]P[%d]R[%d], count=%d\n",
221                                 TAS2557_BOOK_ID(nRegister),
222                                 TAS2557_PAGE_ID(nRegister),
223                                 TAS2557_PAGE_REG(nRegister),
224                                 nLength);
225         }
227         nResult = tas2557_change_book_page(pTAS2557,
228                                 TAS2557_BOOK_ID(nRegister),
229                                 TAS2557_PAGE_ID(nRegister));
230         if (nResult >= 0) {
231                 nResult = regmap_bulk_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength);
232                 if (nResult < 0) {
233                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
234                                 __func__, __LINE__, nResult);
235                         pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
236                 } else
237                         pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
238         }
240 end:
242         mutex_unlock(&pTAS2557->dev_lock);
243         return nResult;
246 static int tas2557_dev_bulk_write(
247         struct tas2557_priv *pTAS2557,
248         unsigned int nRegister,
249         u8 *pData,
250         unsigned int nLength)
252         int nResult = 0;
254         mutex_lock(&pTAS2557->dev_lock);
255         if (pTAS2557->mbTILoadActive) {
256                 if (!(nRegister & 0x80000000))
257                         goto end; /* let only writes from TILoad pass. */
259                 nRegister &= ~0x80000000;
261                 dev_dbg(pTAS2557->dev, "TiLoad BW REG B[%d]P[%d]R[%d], count=%d\n",
262                                 TAS2557_BOOK_ID(nRegister),
263                                 TAS2557_PAGE_ID(nRegister),
264                                 TAS2557_PAGE_REG(nRegister),
265                                 nLength);
266         }
268         nResult = tas2557_change_book_page( pTAS2557,
269                                 TAS2557_BOOK_ID(nRegister),
270                                 TAS2557_PAGE_ID(nRegister));
271         if (nResult >= 0) {
272                 nResult = regmap_bulk_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength);
273                 if (nResult < 0) {
274                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
275                                 __func__, __LINE__, nResult);
276                         pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
277                 } else
278                         pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
279         }
281 end:
283         mutex_unlock(&pTAS2557->dev_lock);
284         return nResult;
287 static int tas2557_dev_update_bits(
288         struct tas2557_priv *pTAS2557,
289         unsigned int nRegister,
290         unsigned int nMask,
291         unsigned int nValue)
293         int nResult = 0;
295         mutex_lock(&pTAS2557->dev_lock);
297         if (pTAS2557->mbTILoadActive) {
298                 if (!(nRegister & 0x80000000))
299                         goto end; /* let only writes from TILoad pass. */
301                 nRegister &= ~0x80000000;
302                 dev_dbg(pTAS2557->dev, "TiLoad SB REG B[%d]P[%d]R[%d], mask=0x%x, value=0x%x\n",
303                                 TAS2557_BOOK_ID(nRegister),
304                                 TAS2557_PAGE_ID(nRegister),
305                                 TAS2557_PAGE_REG(nRegister),
306                                 nMask, nValue);
307         }
309         nResult = tas2557_change_book_page( pTAS2557,
310                                 TAS2557_BOOK_ID(nRegister),
311                                 TAS2557_PAGE_ID(nRegister));
312         if (nResult >= 0) {
313                 nResult = regmap_update_bits(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nMask, nValue);
314                 if (nResult < 0) {
315                         dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
316                                 __func__, __LINE__, nResult);
317                         pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
318                 } else
319                         pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
320         }
322 end:
323         mutex_unlock(&pTAS2557->dev_lock);
324         return nResult;
327 void tas2557_clearIRQ(struct tas2557_priv *pTAS2557)
329         unsigned int nValue;
330         int nResult = 0;
332         nResult = pTAS2557->read(pTAS2557, TAS2557_FLAGS_1, &nValue);
333         if (nResult >= 0)
334                 pTAS2557->read(pTAS2557, TAS2557_FLAGS_2, &nValue);
339 void tas2557_enableIRQ(struct tas2557_priv *pTAS2557, bool enable, bool startup_chk)
341         if (enable) {
342                 if (!pTAS2557->mbIRQEnable) {
343                         if (gpio_is_valid(pTAS2557->mnGpioINT)) {
344                                 enable_irq(pTAS2557->mnIRQ);
345                                 if (startup_chk) {
346                                         /* check after 10 ms */
347                                         schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(10));
348                                 }
349                                 pTAS2557->mbIRQEnable = true;
350                         }
351                 }
352         } else {
353                 if (gpio_is_valid(pTAS2557->mnGpioINT))
354                         disable_irq_nosync(pTAS2557->mnIRQ);
355                 pTAS2557->mbIRQEnable = false;
356         }
359 static void tas2557_hw_reset(struct tas2557_priv *pTAS2557)
361         if (gpio_is_valid(pTAS2557->mnResetGPIO)) {
362                 gpio_direction_output(pTAS2557->mnResetGPIO, 0);
363                 msleep(5);
364                 gpio_direction_output(pTAS2557->mnResetGPIO, 1);
365                 msleep(2);
366         }
368         pTAS2557->mnCurrentBook = -1;
369         pTAS2557->mnCurrentPage = -1;
370         if (pTAS2557->mnErrCode)
371                 dev_info(pTAS2557->dev, "before reset, ErrCode=0x%x\n", pTAS2557->mnErrCode);
372         pTAS2557->mnErrCode = 0;
375 static void irq_work_routine(struct work_struct *work)
377         int nResult = 0;
378         unsigned int nDevInt1Status = 0, nDevInt2Status = 0;
379         unsigned int nDevPowerUpFlag = 0;
380         int nCounter = 2;
381         struct tas2557_priv *pTAS2557 =
382                 container_of(work, struct tas2557_priv, irq_work.work);
384 #ifdef CONFIG_TAS2557_CODEC
385         mutex_lock(&pTAS2557->codec_lock);
386 #endif
388 #ifdef CONFIG_TAS2557_MISC
389         mutex_lock(&pTAS2557->file_lock);
390 #endif
392         if(pTAS2557->mnErrCode & ERROR_FAILSAFE)
393                 goto program;
395         if (pTAS2557->mbRuntimeSuspend) {
396                 dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__);
397                 goto end;
398         }
400         if (!pTAS2557->mbPowerUp) {
401                 dev_info(pTAS2557->dev, "%s, device not powered\n", __func__);
402                 goto end;
403         }
405         if ((!pTAS2557->mpFirmware->mnConfigurations)
406                 || (!pTAS2557->mpFirmware->mnPrograms)) {
407                 dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
408                 goto end;
409         }
410         nResult = tas2557_dev_write(pTAS2557, TAS2557_GPIO4_PIN_REG, 0x00);
411         if (nResult < 0)
412                 goto program;
413         nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_1, &nDevInt1Status);
414         if (nResult >= 0)
415                 nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_2, &nDevInt2Status);
416         if (nResult < 0)
417                 goto program;
419         if (((nDevInt1Status & 0xfc) != 0) || ((nDevInt2Status & 0x0c) != 0)) {
420                 /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */
421                 dev_err(pTAS2557->dev, "critical error: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status);
422                 if (nDevInt1Status & 0x80) {
423                         pTAS2557->mnErrCode |= ERROR_OVER_CURRENT;
424                         dev_err(pTAS2557->dev, "DEVA SPK over current!\n");
425                 } else
426                         pTAS2557->mnErrCode &= ~ERROR_OVER_CURRENT;
428                 if (nDevInt1Status & 0x40) {
429                         pTAS2557->mnErrCode |= ERROR_UNDER_VOLTAGE;
430                         dev_err(pTAS2557->dev, "DEVA SPK under voltage!\n");
431                 } else
432                         pTAS2557->mnErrCode &= ~ERROR_UNDER_VOLTAGE;
434                 if (nDevInt1Status & 0x20) {
435                         pTAS2557->mnErrCode |= ERROR_CLK_HALT;
436                         dev_err(pTAS2557->dev, "DEVA clk halted!\n");
437                 } else
438                         pTAS2557->mnErrCode &= ~ERROR_CLK_HALT;
440                 if (nDevInt1Status & 0x10) {
441                         pTAS2557->mnErrCode |= ERROR_DIE_OVERTEMP;
442                         dev_err(pTAS2557->dev, "DEVA die over temperature!\n");
443                 } else
444                         pTAS2557->mnErrCode &= ~ERROR_DIE_OVERTEMP;
446                 if (nDevInt1Status & 0x08) {
447                         pTAS2557->mnErrCode |= ERROR_BROWNOUT;
448                         dev_err(pTAS2557->dev, "DEVA brownout!\n");
449                 } else
450                         pTAS2557->mnErrCode &= ~ERROR_BROWNOUT;
452                 if (nDevInt1Status & 0x04) {
453                         pTAS2557->mnErrCode |= ERROR_CLK_LOST;
454                         dev_err(pTAS2557->dev, "DEVA clock lost!\n");
455                 } else
456                         pTAS2557->mnErrCode &= ~ERROR_CLK_LOST;
458                 if (nDevInt2Status & 0x08) {
459                         pTAS2557->mnErrCode |= ERROR_CLK_DET1;
460                         dev_err(pTAS2557->dev, "DEVA clk detection 1!\n");
461                 } else
462                         pTAS2557->mnErrCode &= ~ERROR_CLK_DET1;
464                 if (nDevInt2Status & 0x04) {
465                         pTAS2557->mnErrCode |= ERROR_CLK_DET2;
466                         dev_err(pTAS2557->dev, "DEVA clk detection 2!\n");
467                 } else
468                         pTAS2557->mnErrCode &= ~ERROR_CLK_DET2;
470                 goto program;
471         } else {
472                 dev_dbg(pTAS2557->dev, "IRQ Status: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status);
473                 nCounter = 2;
474                 while (nCounter > 0) {
475                         nResult = tas2557_dev_read(pTAS2557, TAS2557_POWER_UP_FLAG_REG, &nDevPowerUpFlag);
476                         if (nResult < 0)
477                                 goto program;
478                         if ((nDevPowerUpFlag & 0xc0) == 0xc0)
479                                 break;
480                         nCounter--;
481                         if (nCounter > 0) {
482                                 /* in case check pow status just after power on TAS2557 */
483                                 dev_dbg(pTAS2557->dev, "PowSts: 0x%x, check again after 10ms\n",
484                                         nDevPowerUpFlag);
485                                 msleep(10);
486                         }
487                 }
488                 if ((nDevPowerUpFlag & 0xc0) != 0xc0) {
489                         dev_err(pTAS2557->dev, "%s, Critical ERROR B[%d]_P[%d]_R[%d]= 0x%x\n",
490                                 __func__,
491                                 TAS2557_BOOK_ID(TAS2557_POWER_UP_FLAG_REG),
492                                 TAS2557_PAGE_ID(TAS2557_POWER_UP_FLAG_REG),
493                                 TAS2557_PAGE_REG(TAS2557_POWER_UP_FLAG_REG),
494                                 nDevPowerUpFlag);
495                         pTAS2557->mnErrCode |= ERROR_CLASSD_PWR;
496                         goto program;
497                 }
498                 pTAS2557->mnErrCode &= ~ERROR_CLASSD_PWR;
500                 dev_dbg(pTAS2557->dev, "%s: INT1=0x%x, INT2=0x%x; PowerUpFlag=0x%x\n",
501                         __func__, nDevInt1Status, nDevInt2Status, nDevPowerUpFlag);
502                 goto end;
503         }
505 program:
506         /* hardware reset and reload */
507         nResult = -1;
508         tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
510 end:
511         if (nResult >= 0) {
512                 tas2557_dev_write(pTAS2557, TAS2557_GPIO4_PIN_REG, 0x07);
513                 tas2557_enableIRQ(pTAS2557, true, false);
514         }
515 #ifdef CONFIG_TAS2557_MISC
516         mutex_unlock(&pTAS2557->file_lock);
517 #endif
519 #ifdef CONFIG_TAS2557_CODEC
520         mutex_unlock(&pTAS2557->codec_lock);
521 #endif
524 static irqreturn_t tas2557_irq_handler(int irq, void *dev_id)
526         struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)dev_id;
528         tas2557_enableIRQ(pTAS2557, false, false);
529         /* get IRQ status after 100 ms */
530         schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100));
531         return IRQ_HANDLED;
534 static enum hrtimer_restart temperature_timer_func(struct hrtimer *timer)
536         struct tas2557_priv *pTAS2557 = container_of(timer, struct tas2557_priv, mtimer);
538         if (pTAS2557->mbPowerUp) {
539                 schedule_work(&pTAS2557->mtimerwork);
540                 if (gpio_is_valid(pTAS2557->mnGpioINT)) {
541                         tas2557_enableIRQ(pTAS2557, false, false);
542                         schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(1));
543                 }
544         }
545         return HRTIMER_NORESTART;
548 static void timer_work_routine(struct work_struct *work)
550         struct tas2557_priv *pTAS2557 = container_of(work, struct tas2557_priv, mtimerwork);
551         int nResult, nActTemp;
552         int nTemp = 0;
553         struct TProgram *pProgram;
554         static int nAvg;
556 #ifdef CONFIG_TAS2557_CODEC
557         mutex_lock(&pTAS2557->codec_lock);
558 #endif
560 #ifdef CONFIG_TAS2557_MISC
561         mutex_lock(&pTAS2557->file_lock);
562 #endif
564         if (pTAS2557->mbRuntimeSuspend) {
565                 dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__);
566                 goto end;
567         }
569         if (!pTAS2557->mpFirmware->mnConfigurations) {
570                 dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
571                 goto end;
572         }
574         pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
575         if (!pTAS2557->mbPowerUp
576                 || (pProgram->mnAppMode != TAS2557_APP_TUNINGMODE)) {
577                 dev_info(pTAS2557->dev, "%s, pass, Pow=%d, program=%s\n",
578                         __func__, pTAS2557->mbPowerUp, pProgram->mpName);
579                 goto end;
580         }
582         nResult = tas2557_get_die_temperature(pTAS2557, &nTemp);
583         if (nResult >= 0) {
584                 nActTemp = (int)(nTemp >> 23);
585                 dev_dbg(pTAS2557->dev, "Die=0x%x, degree=%d\n", nTemp, nActTemp);
586                 if (!pTAS2557->mnDieTvReadCounter)
587                         nAvg = 0;
588                 pTAS2557->mnDieTvReadCounter++;
589                 nAvg += nActTemp;
590                 if (!(pTAS2557->mnDieTvReadCounter % LOW_TEMPERATURE_COUNTER)) {
591                         nAvg /= LOW_TEMPERATURE_COUNTER;
592                         dev_dbg(pTAS2557->dev, "check : avg=%d\n", nAvg);
593                         if (nAvg < -6) {
594                                 /* if Die temperature is below -6 degree C */
595                                 if (pTAS2557->mnDevCurrentGain != LOW_TEMPERATURE_GAIN) {
596                                         nResult = tas2557_set_DAC_gain(pTAS2557, LOW_TEMPERATURE_GAIN);
597                                         if (nResult < 0)
598                                                 goto end;
599                                         pTAS2557->mnDevCurrentGain = LOW_TEMPERATURE_GAIN;
600                                         dev_dbg(pTAS2557->dev, "LOW Temp: set gain to %d\n", LOW_TEMPERATURE_GAIN);
601                                 }
602                         } else if (nAvg > 5) {
603                                 /* if Die temperature is above 5 degree C */
604                                 if (pTAS2557->mnDevCurrentGain != pTAS2557->mnDevGain) {
605                                         nResult = tas2557_set_DAC_gain(pTAS2557, pTAS2557->mnDevGain);
606                                         if (nResult < 0)
607                                                 goto end;
608                                         pTAS2557->mnDevCurrentGain = pTAS2557->mnDevGain;
609                                         dev_dbg(pTAS2557->dev, "LOW Temp: set gain to original\n");
610                                 }
611                         }
612                         nAvg = 0;
613                 }
615                 if (pTAS2557->mbPowerUp)
616                         hrtimer_start(&pTAS2557->mtimer,
617                                 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
618         }
620 end:
622 #ifdef CONFIG_TAS2557_MISC
623         mutex_unlock(&pTAS2557->file_lock);
624 #endif
626 #ifdef CONFIG_TAS2557_CODEC
627         mutex_unlock(&pTAS2557->codec_lock);
628 #endif
631 static int tas2557_runtime_suspend(struct tas2557_priv *pTAS2557)
633         dev_dbg(pTAS2557->dev, "%s\n", __func__);
635         pTAS2557->mbRuntimeSuspend = true;
637         if (hrtimer_active(&pTAS2557->mtimer)) {
638                 dev_dbg(pTAS2557->dev, "cancel die temp timer\n");
639                 hrtimer_cancel(&pTAS2557->mtimer);
640         }
641         if (work_pending(&pTAS2557->mtimerwork)) {
642                 dev_dbg(pTAS2557->dev, "cancel timer work\n");
643                 cancel_work_sync(&pTAS2557->mtimerwork);
644         }
645         if (gpio_is_valid(pTAS2557->mnGpioINT)) {
646                 if (delayed_work_pending(&pTAS2557->irq_work)) {
647                         dev_dbg(pTAS2557->dev, "cancel IRQ work\n");
648                         cancel_delayed_work_sync(&pTAS2557->irq_work);
649                 }
650         }
652         return 0;
655 static int tas2557_runtime_resume(struct tas2557_priv *pTAS2557)
657         struct TProgram *pProgram;
659         dev_dbg(pTAS2557->dev, "%s\n", __func__);
660         if (!pTAS2557->mpFirmware->mpPrograms) {
661                 dev_dbg(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
662                 goto end;
663         }
665         if (pTAS2557->mnCurrentProgram >= pTAS2557->mpFirmware->mnPrograms) {
666                 dev_err(pTAS2557->dev, "%s, firmware corrupted\n", __func__);
667                 goto end;
668         }
670         pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
671         if (pTAS2557->mbPowerUp && (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)) {
672                 if (!hrtimer_active(&pTAS2557->mtimer)) {
673                         dev_dbg(pTAS2557->dev, "%s, start Die Temp check timer\n", __func__);
674                         pTAS2557->mnDieTvReadCounter = 0;
675                         hrtimer_start(&pTAS2557->mtimer,
676                                 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
677                 }
678         }
680         pTAS2557->mbRuntimeSuspend = false;
681 end:
683         return 0;
686 static bool tas2557_volatile(struct device *pDev, unsigned int nRegister)
688         return true;
691 static bool tas2557_writeable(struct device *pDev, unsigned int nRegister)
693         return true;
696 static const struct regmap_config tas2557_i2c_regmap = {
697         .reg_bits = 8,
698         .val_bits = 8,
699         .writeable_reg = tas2557_writeable,
700         .volatile_reg = tas2557_volatile,
701         .cache_type = REGCACHE_NONE,
702         .max_register = 128,
703 };
705 /* tas2557_i2c_probe :
706 * platform dependent
707 * should implement hardware reset functionality
708 */
709 static int tas2557_i2c_probe(struct i2c_client *pClient,
710         const struct i2c_device_id *pID)
712         struct tas2557_priv *pTAS2557;
713         int nResult = 0;
714         unsigned int nValue = 0;
715         const char *pFWName;
717         dev_info(&pClient->dev, "%s enter\n", __func__);
719         pTAS2557 = devm_kzalloc(&pClient->dev, sizeof(struct tas2557_priv), GFP_KERNEL);
720         if (!pTAS2557) {
721                 nResult = -ENOMEM;
722                 goto err;
723         }
725         pTAS2557->dev = &pClient->dev;
726         i2c_set_clientdata(pClient, pTAS2557);
727         dev_set_drvdata(&pClient->dev, pTAS2557);
729         pTAS2557->mpRegmap = devm_regmap_init_i2c(pClient, &tas2557_i2c_regmap);
730         if (IS_ERR(pTAS2557->mpRegmap)) {
731                 nResult = PTR_ERR(pTAS2557->mpRegmap);
732                 dev_err(&pClient->dev, "Failed to allocate register map: %d\n",
733                         nResult);
734                 goto err;
735         }
737         if (pClient->dev.of_node)
738                 tas2557_parse_dt(&pClient->dev, pTAS2557);
740         if (gpio_is_valid(pTAS2557->mnResetGPIO)) {
741                 nResult = gpio_request(pTAS2557->mnResetGPIO, "TAS2557-RESET");
742                 if (nResult < 0) {
743                         dev_err(pTAS2557->dev, "%s: GPIO %d request error\n",
744                                 __func__, pTAS2557->mnResetGPIO);
745                         goto err;
746                 }
747                 tas2557_hw_reset(pTAS2557);
748         }
750         pTAS2557->read = tas2557_dev_read;
751         pTAS2557->write = tas2557_dev_write;
752         pTAS2557->bulk_read = tas2557_dev_bulk_read;
753         pTAS2557->bulk_write = tas2557_dev_bulk_write;
754         pTAS2557->update_bits = tas2557_dev_update_bits;
755         pTAS2557->enableIRQ = tas2557_enableIRQ;
756         pTAS2557->clearIRQ = tas2557_clearIRQ;
757         pTAS2557->set_config = tas2557_set_config;
758         pTAS2557->set_calibration = tas2557_set_calibration;
759         pTAS2557->hw_reset = tas2557_hw_reset;
760         pTAS2557->runtime_suspend = tas2557_runtime_suspend;
761         pTAS2557->runtime_resume = tas2557_runtime_resume;
762         pTAS2557->mnRestart = 0;
763         pTAS2557->mnEdge = 4;
765         mutex_init(&pTAS2557->dev_lock);
767         /* Reset the chip */
768         nResult = tas2557_dev_write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
769         if (nResult < 0) {
770                 dev_err(&pClient->dev, "I2c fail, %d\n", nResult);
771                 goto err;
772         }
774         msleep(1);
775         tas2557_dev_read(pTAS2557, TAS2557_REV_PGID_REG, &nValue);
776         pTAS2557->mnPGID = nValue;
777         if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) {
778                 dev_info(pTAS2557->dev, "PG2.1 Silicon found\n");
779                 pFWName = TAS2557_FW_NAME;
780         } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) {
781                 dev_info(pTAS2557->dev, "PG1.0 Silicon found\n");
782                 pFWName = TAS2557_PG1P0_FW_NAME;
783         } else {
784                 nResult = -ENOTSUPP;
785                 dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", pTAS2557->mnPGID);
786                 goto err;
787         }
789         if (gpio_is_valid(pTAS2557->mnGpioINT)) {
790                 nResult = gpio_request(pTAS2557->mnGpioINT, "TAS2557-IRQ");
791                 if (nResult < 0) {
792                         dev_err(pTAS2557->dev,
793                                 "%s: GPIO %d request INT error\n",
794                                 __func__, pTAS2557->mnGpioINT);
795                         goto err;
796                 }
798                 gpio_direction_input(pTAS2557->mnGpioINT);
799                 pTAS2557->mnIRQ = gpio_to_irq(pTAS2557->mnGpioINT);
800                 dev_dbg(pTAS2557->dev, "irq = %d\n", pTAS2557->mnIRQ);
801                 INIT_DELAYED_WORK(&pTAS2557->irq_work, irq_work_routine);
802                 nResult = request_threaded_irq(pTAS2557->mnIRQ, tas2557_irq_handler,
803                                         NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
804                                 pClient->name, pTAS2557);
805                 if (nResult < 0) {
806                         dev_err(pTAS2557->dev,
807                                 "request_irq failed, %d\n", nResult);
808                         goto err;
809                 }
810                 disable_irq_nosync(pTAS2557->mnIRQ);
811         }
813         pTAS2557->mpFirmware = devm_kzalloc(&pClient->dev, sizeof(struct TFirmware), GFP_KERNEL);
814         if (!pTAS2557->mpFirmware) {
815                 nResult = -ENOMEM;
816                 goto err;
817         }
819         pTAS2557->mpCalFirmware = devm_kzalloc(&pClient->dev, sizeof(struct TFirmware), GFP_KERNEL);
820         if (!pTAS2557->mpCalFirmware) {
821                 nResult = -ENOMEM;
822                 goto err;
823         }
825 #ifdef CONFIG_TAS2557_CODEC
826         mutex_init(&pTAS2557->codec_lock);
827         tas2557_register_codec(pTAS2557);
828 #endif
830 #ifdef CONFIG_TAS2557_MISC
831         mutex_init(&pTAS2557->file_lock);
832         tas2557_register_misc(pTAS2557);
833 #endif
835 #ifdef ENABLE_TILOAD
836         tiload_driver_init(pTAS2557);
837 #endif
839         hrtimer_init(&pTAS2557->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
840         pTAS2557->mtimer.function = temperature_timer_func;
841         INIT_WORK(&pTAS2557->mtimerwork, timer_work_routine);
843         nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
844                 pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready);
846 err:
848         return nResult;
851 static int tas2557_i2c_remove(struct i2c_client *pClient)
853         struct tas2557_priv *pTAS2557 = i2c_get_clientdata(pClient);
855         dev_info(pTAS2557->dev, "%s\n", __func__);
857 #ifdef CONFIG_TAS2557_CODEC
858         tas2557_deregister_codec(pTAS2557);
859         mutex_destroy(&pTAS2557->codec_lock);
860 #endif
862 #ifdef CONFIG_TAS2557_MISC
863         tas2557_deregister_misc(pTAS2557);
864         mutex_destroy(&pTAS2557->file_lock);
865 #endif
867         mutex_destroy(&pTAS2557->dev_lock);
868         return 0;
871 static const struct i2c_device_id tas2557_i2c_id[] = {
872         {"tas2557", 0},
873         {}
874 };
876 MODULE_DEVICE_TABLE(i2c, tas2557_i2c_id);
878 #if defined(CONFIG_OF)
879 static const struct of_device_id tas2557_of_match[] = {
880         {.compatible = "ti,tas2557"},
881         {},
882 };
884 MODULE_DEVICE_TABLE(of, tas2557_of_match);
885 #endif
887 static struct i2c_driver tas2557_i2c_driver = {
888         .driver = {
889                         .name = "tas2557",
890                         .owner = THIS_MODULE,
891 #if defined(CONFIG_OF)
892                         .of_match_table = of_match_ptr(tas2557_of_match),
893 #endif
894                 },
895         .probe = tas2557_i2c_probe,
896         .remove = tas2557_i2c_remove,
897         .id_table = tas2557_i2c_id,
898 };
900 module_i2c_driver(tas2557_i2c_driver);
902 MODULE_AUTHOR("Texas Instruments Inc.");
903 MODULE_DESCRIPTION("TAS2557 I2C Smart Amplifier driver");
904 MODULE_LICENSE("GPL v2");
906 #endif