]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - tas2770sw-android/tas2770sw-android.git/blob - tas2770-regmap.c
c98cdc7e794bcd579f17df70c2857fe4d6d8f3f2
[tas2770sw-android/tas2770sw-android.git] / tas2770-regmap.c
1 /*
2  * ALSA SoC Texas Instruments TAS2770 20-W Digital Input Mono Class-D
3  * Audio Amplifier with Speaker I/V Sense
4  *
5  * Copyright (C) 2016 Texas Instruments, Inc.
6  *
7  * Author: saiprasad
8  *
9  * This package is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  */
18 #ifdef CONFIG_TAS2770_REGMAP
20 #define DEBUG
21 #include <linux/module.h>
22 #include <linux/moduleparam.h>
23 #include <linux/err.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/pm.h>
27 #include <linux/i2c.h>
28 #include <linux/gpio.h>
29 #include <linux/regulator/consumer.h>
30 #include <linux/firmware.h>
31 #include <linux/regmap.h>
32 #include <linux/of.h>
33 #include <linux/of_gpio.h>
34 #include <linux/slab.h>
35 #include <sound/soc.h>
37 #include "tas2770.h"
38 #include "tas2770-codec.h"
40 static const struct reg_default tas2770_reg_defaults[] = {
41         { TAS2770_Page, 0x00 },
42         { TAS2770_SoftwareReset, 0x00 },
43         { TAS2770_PowerControl, 0x0e },
44         { TAS2770_PlaybackConfigurationReg0, 0x10 },
45         { TAS2770_PlaybackConfigurationReg1, 0x01 },
46         { TAS2770_PlaybackConfigurationReg2, 0x00 },
47         { TAS2770_MiscConfigurationReg0, 0x07 },
48         { TAS2770_TDMConfigurationReg1, 0x02 },
49         { TAS2770_TDMConfigurationReg2, 0x0a },
50         { TAS2770_TDMConfigurationReg3, 0x10 },
51         { TAS2770_InterruptMaskReg0, 0xfc },
52         { TAS2770_InterruptMaskReg1, 0xb1 },
53         { TAS2770_InterruptConfiguration, 0x05 },
54         { TAS2770_MiscIRQ, 0x81 },
55         { TAS2770_ClockConfiguration, 0x0c },
57 };
59 static bool tas2770_volatile(struct device *dev, unsigned int reg)
60 {
61         switch (reg) {
62         case TAS2770_Page: /* regmap implementation requires this */
63         case TAS2770_SoftwareReset: /* always clears after write */
64         case TAS2770_BrownOutPreventionReg0:/* has a self clearing bit */
65         case TAS2770_LiveInterruptReg0:
66         case TAS2770_LiveInterruptReg1:
67         case TAS2770_LatchedInterruptReg0:/* Sticky interrupt flags */
68         case TAS2770_LatchedInterruptReg1:/* Sticky interrupt flags */
69         case TAS2770_VBATMSB:
70         case TAS2770_VBATLSB:
71         case TAS2770_TEMPMSB:
72         case TAS2770_TEMPLSB:
73                 return true;
74         }
75         return false;
76 }
78 static bool tas2770_writeable(struct device *dev, unsigned int reg)
79 {
80         switch (reg) {
81         case TAS2770_LiveInterruptReg0:
82         case TAS2770_LiveInterruptReg1:
83         case TAS2770_LatchedInterruptReg0:
84         case TAS2770_LatchedInterruptReg1:
85         case TAS2770_VBATMSB:
86         case TAS2770_VBATLSB:
87         case TAS2770_TEMPMSB:
88         case TAS2770_TEMPLSB:
89         case TAS2770_TDMClockdetectionmonitor:
90         case TAS2770_RevisionandPGID:
91                 return false;
92         }
93         return true;
94 }
95 static const struct regmap_config tas2770_i2c_regmap = {
96         .reg_bits = 8,
97         .val_bits = 8,
98         .writeable_reg = tas2770_writeable,
99         .volatile_reg = tas2770_volatile,
100         .reg_defaults = tas2770_reg_defaults,
101         .num_reg_defaults = ARRAY_SIZE(tas2770_reg_defaults),
102         .cache_type = REGCACHE_RBTREE,
103         .max_register = 1 * 128,
104 };
107 static void tas2770_hw_reset(struct tas2770_priv *pTAS2770)
109         if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
110                 gpio_direction_output(pTAS2770->mnResetGPIO, 0);
111                 msleep(5);
112                 gpio_direction_output(pTAS2770->mnResetGPIO, 1);
113                 msleep(2);
114         }
116         pTAS2770->mnCurrentBook = -1;
117         pTAS2770->mnCurrentPage = -1;
120 void tas2770_enableIRQ(struct tas2770_priv *pTAS2770, bool enable)
122         if (enable) {
123                 if (pTAS2770->mbIRQEnable)
124                         return;
126                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
127                         enable_irq(pTAS2770->mnIRQ);
129                 schedule_delayed_work(&pTAS2770->irq_work, msecs_to_jiffies(10));
130                 pTAS2770->mbIRQEnable = true;
131         } else {
132                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
133                         disable_irq_nosync(pTAS2770->mnIRQ);
134                 pTAS2770->mbIRQEnable = false;
135         }
138 static void irq_work_routine(struct work_struct *work)
140         struct tas2770_priv *pTAS2770 =
141                 container_of(work, struct tas2770_priv, irq_work.work);
142         unsigned int nDevInt1Status = 0, nDevInt2Status = 0;
143         int nCounter = 2;
144         int nResult = 0;
146         dev_info(pTAS2770->dev, "%s\n", __func__);
147 #ifdef CONFIG_TAS2770_CODEC
148         mutex_lock(&pTAS2770->codec_lock);
149 #endif
151         if (pTAS2770->mbRuntimeSuspend) {
152                 dev_info(pTAS2770->dev, "%s, Runtime Suspended\n", __func__);
153                 goto end;
154         }
156         if (pTAS2770->mnPowerState == TAS2770_POWER_SHUTDOWN) {
157                 dev_info(pTAS2770->dev, "%s, device not powered\n", __func__);
158                 goto end;
159         }
161         nResult = regmap_write(pTAS2770->regmap, TAS2770_InterruptMaskReg0,
162                                 TAS2770_InterruptMaskReg0_Disable);
163         nResult = regmap_write(pTAS2770->regmap, TAS2770_InterruptMaskReg1,
164                                 TAS2770_InterruptMaskReg1_Disable);
166         if (nResult < 0)
167                 goto reload;
169         nResult = regmap_read(pTAS2770->regmap, TAS2770_LatchedInterruptReg0, &nDevInt1Status);
170         if (nResult >= 0)
171                 nResult = regmap_read(pTAS2770->regmap, TAS2770_LatchedInterruptReg1, &nDevInt2Status);
172         else
173                 goto reload;
175         dev_info(pTAS2770->dev, "IRQ status : 0x%x, 0x%x\n",
176                         nDevInt1Status, nDevInt2Status);
178         if (((nDevInt1Status & 0x3) != 0) || ((nDevInt2Status & 0x0f) != 0)) {
179                 /* in case of INT_OC, INT_OT, INT_OVLT, INT_UVLT, INT_BO */
181                 if (nDevInt1Status & TAS2770_LatchedInterruptReg0_OCEFlagSticky_Interrupt) {
182                         pTAS2770->mnErrCode |= ERROR_OVER_CURRENT;
183                         dev_err(pTAS2770->dev, "SPK over current!\n");
184                 } else
185                         pTAS2770->mnErrCode &= ~ERROR_OVER_CURRENT;
187                 if (nDevInt1Status & TAS2770_LatchedInterruptReg0_OTEFlagSticky_Interrupt) {
188                         pTAS2770->mnErrCode |= ERROR_DIE_OVERTEMP;
189                         dev_err(pTAS2770->dev, "die over temperature!\n");
190                 } else
191                         pTAS2770->mnErrCode &= ~ERROR_DIE_OVERTEMP;
193                 if (nDevInt2Status & TAS2770_LatchedInterruptReg1_VBATOVLOSticky_Interrupt) {
194                         pTAS2770->mnErrCode |= ERROR_OVER_VOLTAGE;
195                         dev_err(pTAS2770->dev, "SPK over voltage!\n");
196                 } else
197                         pTAS2770->mnErrCode &= ~ERROR_UNDER_VOLTAGE;
199                 if (nDevInt2Status & TAS2770_LatchedInterruptReg1_VBATUVLOSticky_Interrupt) {
200                         pTAS2770->mnErrCode |= ERROR_UNDER_VOLTAGE;
201                         dev_err(pTAS2770->dev, "SPK under voltage!\n");
202                 } else
203                         pTAS2770->mnErrCode &= ~ERROR_UNDER_VOLTAGE;
205                 if (nDevInt2Status & TAS2770_LatchedInterruptReg1_BrownOutFlagSticky_Interrupt) {
206                         pTAS2770->mnErrCode |= ERROR_BROWNOUT;
207                         dev_err(pTAS2770->dev, "brownout!\n");
208                 } else
209                         pTAS2770->mnErrCode &= ~ERROR_BROWNOUT;
211                 goto reload;
212         } else {
213                 nCounter = 2;
215                 while (nCounter > 0) {
216                         nResult = regmap_read(pTAS2770->regmap, TAS2770_PowerControl, &nDevInt1Status);
217                         if (nResult < 0)
218                                 goto reload;
220                         if ((nDevInt1Status & TAS2770_PowerControl_OperationalMode10_Mask)
221                                 != TAS2770_PowerControl_OperationalMode10_Shutdown)
222                                 break;
224                         nCounter--;
225                         if (nCounter > 0) {
226                                 /* in case check pow status just after power on TAS2770 */
227                                 dev_dbg(pTAS2770->dev, "PowSts B: 0x%x, check again after 10ms\n",
228                                         nDevInt1Status);
229                                 msleep(10);
230                         }
231                 }
233                 if ((nDevInt1Status & TAS2770_PowerControl_OperationalMode10_Mask)
234                         == TAS2770_PowerControl_OperationalMode10_Shutdown) {
235                         dev_err(pTAS2770->dev, "%s, Critical ERROR REG[0x%x] = 0x%x\n",
236                                 __func__,
237                                 TAS2770_PowerControl,
238                                 nDevInt1Status);
239                         pTAS2770->mnErrCode |= ERROR_CLASSD_PWR;
240                         goto reload;
241                 }
242                 pTAS2770->mnErrCode &= ~ERROR_CLASSD_PWR;
243         }
245         nResult = regmap_write(pTAS2770->regmap, TAS2770_InterruptMaskReg0, 0xfc);
246         if (nResult < 0)
247                 goto reload;
249         nResult = regmap_write(pTAS2770->regmap, TAS2770_InterruptMaskReg1, 0xb1);
250         if (nResult < 0)
251                 goto reload;
253         goto end;
255 reload:
256         /* hardware reset and reload */
257         tas2770_LoadConfig(pTAS2770);
259 end:
260 #ifdef CONFIG_TAS2770_CODEC
261         mutex_unlock(&pTAS2770->codec_lock);
262 #endif
265 static enum hrtimer_restart timer_func(struct hrtimer *timer)
267         struct tas2770_priv *pTAS2770 = container_of(timer,
268                 struct tas2770_priv, mtimer);
270         if (pTAS2770->mnPowerState != TAS2770_POWER_SHUTDOWN) {
271                 if (!delayed_work_pending(&pTAS2770->irq_work))
272                         schedule_delayed_work(&pTAS2770->irq_work,
273                                 msecs_to_jiffies(20));
274         }
276         return HRTIMER_NORESTART;
279 static irqreturn_t tas2770_irq_handler(int irq, void *dev_id)
281         struct tas2770_priv *pTAS2770 = (struct tas2770_priv *)dev_id;
283         tas2770_enableIRQ(pTAS2770, false);
285         /* get IRQ status after 100 ms */
286         if (!delayed_work_pending(&pTAS2770->irq_work))
287                 schedule_delayed_work(&pTAS2770->irq_work,
288                         msecs_to_jiffies(100));
290         return IRQ_HANDLED;
293 static int tas2770_runtime_suspend(struct tas2770_priv *pTAS2770)
295         dev_dbg(pTAS2770->dev, "%s\n", __func__);
297         pTAS2770->mbRuntimeSuspend = true;
299         if (hrtimer_active(&pTAS2770->mtimer)) {
300                 dev_dbg(pTAS2770->dev, "cancel die temp timer\n");
301                 hrtimer_cancel(&pTAS2770->mtimer);
302         }
304         if (delayed_work_pending(&pTAS2770->irq_work)) {
305                 dev_dbg(pTAS2770->dev, "cancel IRQ work\n");
306                 cancel_delayed_work_sync(&pTAS2770->irq_work);
307         }
309         return 0;
312 #define CHECK_PERIOD    5000    /* 5 second */
313 static int tas2770_runtime_resume(struct tas2770_priv *pTAS2770)
315         dev_dbg(pTAS2770->dev, "%s\n", __func__);
317         if (pTAS2770->mnPowerState != TAS2770_POWER_SHUTDOWN) {
318                 if (!hrtimer_active(&pTAS2770->mtimer)) {
319                         hrtimer_start(&pTAS2770->mtimer,
320                                 ns_to_ktime((u64)CHECK_PERIOD * NSEC_PER_MSEC),
321                                 HRTIMER_MODE_REL);
322                 }
323         }
325         pTAS2770->mbRuntimeSuspend = false;
327         return 0;
330 static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *pTAS2770)
332         struct device_node *np = dev->of_node;
333         int rc = 0, ret = 0;
335         rc = of_property_read_u32(np, "ti,asi-format", &pTAS2770->mnASIFormat);
336         if (rc) {
337                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
338                         "ti,asi-format", np->full_name, rc);
339         } else {
340                 dev_dbg(pTAS2770->dev, "ti,asi-format=%d",
341                         pTAS2770->mnASIFormat);
342         }
344         pTAS2770->mnResetGPIO = of_get_named_gpio(np, "ti,reset-gpio", 0);
345         if (!gpio_is_valid(pTAS2770->mnResetGPIO)) {
346                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
347                         "ti,reset-gpio", np->full_name, pTAS2770->mnResetGPIO);
348         } else {
349                 dev_dbg(pTAS2770->dev, "ti,reset-gpio=%d",
350                         pTAS2770->mnResetGPIO);
351         }
353         pTAS2770->mnIRQGPIO = of_get_named_gpio(np, "ti,irq-gpio", 0);
354         if (!gpio_is_valid(pTAS2770->mnIRQGPIO)) {
355                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
356                         "ti,irq-gpio", np->full_name, pTAS2770->mnIRQGPIO);
357         } else {
358                 dev_dbg(pTAS2770->dev, "ti,irq-gpio=%d", pTAS2770->mnIRQGPIO);
359         }
361         of_property_read_u32(np, "ti,left-slot", &pTAS2770->mnLeftSlot);
362         if (rc) {
363                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
364                         "ti,left-slot", np->full_name, rc);
365         } else {
366                 dev_dbg(pTAS2770->dev, "ti,left-slot=%d",
367                         pTAS2770->mnLeftSlot);
368         }
370         of_property_read_u32(np, "ti,right-slot", &pTAS2770->mnRightSlot);
371         if (rc) {
372                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
373                         "ti,right-slot", np->full_name, rc);
374         } else {
375                 dev_dbg(pTAS2770->dev, "ti,right-slot=%d",
376                         pTAS2770->mnRightSlot);
377         }
379         of_property_read_u32(np, "ti,imon-slot-no", &pTAS2770->mnImon_slot_no);
380         if (rc) {
381                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
382                         "ti,imon-slot-no", np->full_name, rc);
383         } else {
384                 dev_dbg(pTAS2770->dev, "ti,imon-slot-no=%d",
385                         pTAS2770->mnImon_slot_no);
386         }
388         of_property_read_u32(np, "ti,vmon-slot-no", &pTAS2770->mnVmon_slot_no);
389         if (rc) {
390                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
391                         "ti,vmon-slot-no", np->full_name, rc);
392         } else {
393                 dev_dbg(pTAS2770->dev, "ti,vmon-slot-no=%d",
394                         pTAS2770->mnVmon_slot_no);
395         }
397         return ret;
400 static int tas2770_i2c_probe(struct i2c_client *client,
401                         const struct i2c_device_id *id)
403         struct tas2770_priv *pTAS2770;
404         int nResult;
406         dev_info(&client->dev, "%s enter\n", __func__);
408         pTAS2770 = devm_kzalloc(&client->dev,
409                 sizeof(struct tas2770_priv), GFP_KERNEL);
410         if (pTAS2770 == NULL) {
411                 nResult = -ENOMEM;
412                 dev_info(&client->dev, "Failed to allocate i2c device\n");
413                 goto end;
414         }
416         pTAS2770->dev = &client->dev;
417         i2c_set_clientdata(client, pTAS2770);
418         dev_set_drvdata(&client->dev, pTAS2770);
419         pTAS2770->mnPowerState = TAS2770_POWER_SHUTDOWN;
421         pTAS2770->regmap = devm_regmap_init_i2c(client, &tas2770_i2c_regmap);
422         if (IS_ERR(pTAS2770->regmap)) {
423                 nResult = PTR_ERR(pTAS2770->regmap);
424                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
425                                         nResult);
426                 goto end;
427         }
429         if (client->dev.of_node)
430                 tas2770_parse_dt(&client->dev, pTAS2770);
432         if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
433                 nResult = gpio_request(pTAS2770->mnResetGPIO, "TAS2770_RESET");
434                 if (nResult) {
435                         dev_err(pTAS2770->dev, "%s: Failed to request gpio %d\n",
436                                 __func__, pTAS2770->mnResetGPIO);
437                         nResult = -EINVAL;
438                         goto free_gpio;
439                 }
440         }
442         if (gpio_is_valid(pTAS2770->mnIRQGPIO)) {
443                 nResult = gpio_request(pTAS2770->mnIRQGPIO, "TAS2770-IRQ");
444                 if (nResult < 0) {
445                         dev_err(pTAS2770->dev, "%s: GPIO %d request error\n",
446                                 __func__, pTAS2770->mnIRQGPIO);
447                         goto free_gpio;
448                 }
449                 gpio_direction_input(pTAS2770->mnIRQGPIO);
450                 pTAS2770->mnIRQ = gpio_to_irq(pTAS2770->mnIRQGPIO);
451                 dev_info(pTAS2770->dev, "irq = %d\n", pTAS2770->mnIRQ);
452                 INIT_DELAYED_WORK(&pTAS2770->irq_work, irq_work_routine);
453                 nResult = request_threaded_irq(pTAS2770->mnIRQ,
454                                         tas2770_irq_handler, NULL,
455                                         IRQF_TRIGGER_LOW | IRQF_ONESHOT,
456                                         client->name, pTAS2770);
457                 if (nResult < 0) {
458                         dev_err(pTAS2770->dev,
459                                 "request_irq failed, %d\n", nResult);
460                         goto free_gpio;
461                 }
462                 disable_irq_nosync(pTAS2770->mnIRQ);
463         }
465         pTAS2770->hw_reset = tas2770_hw_reset;
466         pTAS2770->enableIRQ = tas2770_enableIRQ;
467         pTAS2770->runtime_suspend = tas2770_runtime_suspend;
468         pTAS2770->runtime_resume = tas2770_runtime_resume;
469         pTAS2770->mnCh_size = 0;
470         pTAS2770->mnSlot_width = 0;
472         tas2770_hw_reset(pTAS2770);
473         regmap_write(pTAS2770->regmap, TAS2770_SoftwareReset,
474                         TAS2770_SoftwareReset_SoftwareReset_Reset);
476         mutex_init(&pTAS2770->dev_lock);
477         if (nResult < 0)
478                 goto destroy_mutex;
480 #ifdef CONFIG_TAS2770_CODEC
481         mutex_init(&pTAS2770->codec_lock);
482         tas2770_register_codec(pTAS2770);
483 #endif
485         hrtimer_init(&pTAS2770->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
486         pTAS2770->mtimer.function = timer_func;
488 destroy_mutex:
489         if (nResult < 0)
490                 mutex_destroy(&pTAS2770->dev_lock);
492 free_gpio:
493         if (nResult < 0) {
494                 if (gpio_is_valid(pTAS2770->mnResetGPIO))
495                         gpio_free(pTAS2770->mnResetGPIO);
496                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
497                         gpio_free(pTAS2770->mnIRQGPIO);
498         }
500 end:
501         return nResult;
504 static int tas2770_i2c_remove(struct i2c_client *client)
506         struct tas2770_priv *pTAS2770 = i2c_get_clientdata(client);
508         dev_info(pTAS2770->dev, "%s\n", __func__);
510 #ifdef CONFIG_TAS2770_CODEC
511         tas2770_deregister_codec(pTAS2770);
512         mutex_destroy(&pTAS2770->codec_lock);
513 #endif
515         if (gpio_is_valid(pTAS2770->mnResetGPIO))
516                 gpio_free(pTAS2770->mnResetGPIO);
517         if (gpio_is_valid(pTAS2770->mnIRQGPIO))
518                 gpio_free(pTAS2770->mnIRQGPIO);
520         return 0;
524 static const struct i2c_device_id tas2770_i2c_id[] = {
525         { "tas2770", 0},
526         { }
527 };
528 MODULE_DEVICE_TABLE(i2c, tas2770_i2c_id);
530 #if defined(CONFIG_OF)
531 static const struct of_device_id tas2770_of_match[] = {
532         { .compatible = "ti,tas2770" },
533         {},
534 };
535 MODULE_DEVICE_TABLE(of, tas2770_of_match);
536 #endif
539 static struct i2c_driver tas2770_i2c_driver = {
540         .driver = {
541                 .name   = "tas2770",
542                 .owner  = THIS_MODULE,
543 #if defined(CONFIG_OF)
544                 .of_match_table = of_match_ptr(tas2770_of_match),
545 #endif
546         },
547         .probe      = tas2770_i2c_probe,
548         .remove     = tas2770_i2c_remove,
549         .id_table   = tas2770_i2c_id,
550 };
552 module_i2c_driver(tas2770_i2c_driver);
554 MODULE_AUTHOR("Texas Instruments Inc.");
555 MODULE_DESCRIPTION("TAS2770 I2C Smart Amplifier driver");
556 MODULE_LICENSE("GPL v2");
557 #endif