f25d7122e2e8128c1cd427672cd0a431251f9238
[tas2770sw-android/tas2770sw-android.git] / tas2770-regmap.c
1 /*
2  * ALSA SoC Texas Instruments TAS2770 High Performance 4W Smart Amplifier
3  *
4  * Copyright (C) 2016 Texas Instruments, Inc.
5  *
6  * Author: saiprasad
7  *
8  * This package is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  */
17 #ifdef CONFIG_TAS2770_REGMAP
19 #define DEBUG
20 #include <linux/module.h>
21 #include <linux/moduleparam.h>
22 #include <linux/err.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/pm.h>
26 #include <linux/i2c.h>
27 #include <linux/gpio.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/firmware.h>
30 #include <linux/regmap.h>
31 #include <linux/of.h>
32 #include <linux/of_gpio.h>
33 #include <linux/slab.h>
34 #include <sound/soc.h>
36 #include "tas2770.h"
37 #include "tas2770-codec.h"
39 static const struct reg_default tas2770_reg_defaults[] = {
40         { TAS2770_Page, 0x00 },
41         { TAS2770_SoftwareReset, 0x00 },
42         { TAS2770_PowerControl, 0x0e },
43         { TAS2770_PlaybackConfigurationReg0, 0x10 },
44         { TAS2770_PlaybackConfigurationReg1, 0x01 },
45         { TAS2770_PlaybackConfigurationReg2, 0x00 },
46         { TAS2770_MiscConfigurationReg0, 0x07 },
47         { TAS2770_TDMConfigurationReg1, 0x02 },
48         { TAS2770_TDMConfigurationReg2, 0x0a },
49         { TAS2770_TDMConfigurationReg3, 0x10 },
50         { TAS2770_InterruptMaskReg0, 0xfc },
51         { TAS2770_InterruptMaskReg1, 0xb1 },
52         { TAS2770_InterruptConfiguration, 0x05 },
53         { TAS2770_MiscIRQ, 0x81 },
54         { TAS2770_ClockConfiguration, 0x0c },
56 };
58 static bool tas2770_volatile(struct device *dev, unsigned int reg)
59 {
60         switch (reg) {
61         case TAS2770_Page: /* regmap implementation requires this */
62         case TAS2770_SoftwareReset: /* always clears after write */
63         case TAS2770_BrownOutPreventionReg0:/* has a self clearing bit */
64         case TAS2770_LiveInterruptReg0: 
65         case TAS2770_LiveInterruptReg1: 
66         case TAS2770_LatchedInterruptReg0:/* Sticky interrupt flags */
67         case TAS2770_LatchedInterruptReg1:/* Sticky interrupt flags */
68         case TAS2770_VBATMSB:
69         case TAS2770_VBATLSB:
70         case TAS2770_TEMPMSB:
71         case TAS2770_TEMPLSB:
72                 return true;
73         }
74         return false;
75 }
77 static bool tas2770_writeable(struct device *dev, unsigned int reg)
78 {
79         switch (reg) {
80         case TAS2770_LiveInterruptReg0:
81         case TAS2770_LiveInterruptReg1:
82         case TAS2770_LatchedInterruptReg0:
83         case TAS2770_LatchedInterruptReg1:
84         case TAS2770_VBATMSB: 
85         case TAS2770_VBATLSB: 
86         case TAS2770_TEMPMSB: 
87         case TAS2770_TEMPLSB:
88         case TAS2770_TDMClockdetectionmonitor:
89         case TAS2770_RevisionandPGID:
90                 return false;
91         }
92         return true;
93 }
95 #if 0
96 static const struct regmap_range_cfg tas2770_ranges[] = {
97         {
98                 .range_min = 0,
99                 .range_max = 1 * 128,
100                 .selector_reg = TAS2770_Page,
101                 .selector_mask = 0xff,
102                 .selector_shift = 0,
103                 .window_start = 0,
104                 .window_len = 128,
105         },
106 };
107 #endif
109 static const struct regmap_config tas2770_i2c_regmap = {
110         .reg_bits = 8,
111         .val_bits = 8,
112         .writeable_reg = tas2770_writeable,
113         .volatile_reg = tas2770_volatile,
114         .reg_defaults = tas2770_reg_defaults,
115         .num_reg_defaults = ARRAY_SIZE(tas2770_reg_defaults),
116 //      .cache_type = REGCACHE_NONE,
117         .cache_type = REGCACHE_RBTREE,
118 //      .ranges = tas2770_ranges,
119 //      .num_ranges = ARRAY_SIZE(tas2770_ranges),
120         .max_register = 1 * 128,
121 };
124 static void tas2770_hw_reset(struct tas2770_priv *pTAS2770)
126         if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
127                 gpio_direction_output(pTAS2770->mnResetGPIO, 0);
128                 msleep(5);
129                 gpio_direction_output(pTAS2770->mnResetGPIO, 1);
130                 msleep(2);
131         }
133         pTAS2770->mnCurrentBook = -1;
134         pTAS2770->mnCurrentPage = -1;
137 void tas2770_clearIRQ(struct tas2770_priv *pTAS2770)
139 //      unsigned int nValue;
140 #if 0
141         int nResult = 0;
143         nResult = pTAS2770->read(pTAS2770, TAS2770_FLAGS_1, &nValue);
144         if (nResult >= 0)
145                 pTAS2770->read(pTAS2770, TAS2770_FLAGS_2, &nValue);
146 #endif
149 void tas2770_enableIRQ(struct tas2770_priv *pTAS2770, bool enable)
151         if (enable) {
152                 if (pTAS2770->mbIRQEnable)
153                         return;
155                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
156                         enable_irq(pTAS2770->mnIRQ);
158                 schedule_delayed_work(&pTAS2770->irq_work, msecs_to_jiffies(10));
159                 pTAS2770->mbIRQEnable = true;
160         } else {
161                 if (!pTAS2770->mbIRQEnable)
162                         return;
164                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
165                         disable_irq_nosync(pTAS2770->mnIRQ);
166                 pTAS2770->mbIRQEnable = false;
167         }
170 static void irq_work_routine(struct work_struct *work)
172         struct tas2770_priv *pTAS2770 =
173                 container_of(work, struct tas2770_priv, irq_work.work);
174 //      unsigned int nDevInt1Status = 0, nDevInt2Status = 0;
175 //      int nCounter = 2;
176 //      int nResult = 0;
178 #ifdef CONFIG_TAS2770_CODEC
179         mutex_lock(&pTAS2770->codec_lock);
180 #endif
182 #ifdef CONFIG_TAS2770_MISC
183         mutex_lock(&pTAS2770->file_lock);
184 #endif
185         if (pTAS2770->mbRuntimeSuspend) {
186                 dev_info(pTAS2770->dev, "%s, Runtime Suspended\n", __func__);
187                 goto end;
188         }
190         if (!pTAS2770->mbPowerUp) {
191                 dev_info(pTAS2770->dev, "%s, device not powered\n", __func__);
192                 goto end;
193         }
195 #if 0
196         nResult = tas2770_dev_write(pTAS2770, TAS2770_INT_GEN_REG, 0x00);
197         if (nResult < 0)
198                 goto reload;
200         nResult = tas2770_dev_read(pTAS2770, TAS2770_FLAGS_1, &nDevInt1Status);
201         if (nResult >= 0)
202                 nResult = tas2770_dev_read(pTAS2770, TAS2770_FLAGS_2, &nDevInt2Status);
203         else
204                 goto reload;
206         if (((nDevInt1Status & 0xfc) != 0) || ((nDevInt2Status & 0xc0) != 0)) {
207                 /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */
208                 dev_dbg(pTAS2770->dev, "IRQ critical Error : 0x%x, 0x%x\n",
209                         nDevInt1Status, nDevInt2Status);
211                 if (nDevInt1Status & 0x80) {
212                         pTAS2770->mnErrCode |= ERROR_OVER_CURRENT;
213                         dev_err(pTAS2770->dev, "SPK over current!\n");
214                 } else
215                         pTAS2770->mnErrCode &= ~ERROR_OVER_CURRENT;
217                 if (nDevInt1Status & 0x40) {
218                         pTAS2770->mnErrCode |= ERROR_UNDER_VOLTAGE;
219                         dev_err(pTAS2770->dev, "SPK under voltage!\n");
220                 } else
221                         pTAS2770->mnErrCode &= ~ERROR_UNDER_VOLTAGE;
223                 if (nDevInt1Status & 0x20) {
224                         pTAS2770->mnErrCode |= ERROR_CLK_HALT;
225                         dev_err(pTAS2770->dev, "clk halted!\n");
226                 } else
227                         pTAS2770->mnErrCode &= ~ERROR_CLK_HALT;
229                 if (nDevInt1Status & 0x10) {
230                         pTAS2770->mnErrCode |= ERROR_DIE_OVERTEMP;
231                         dev_err(pTAS2770->dev, "die over temperature!\n");
232                 } else
233                         pTAS2770->mnErrCode &= ~ERROR_DIE_OVERTEMP;
235                 if (nDevInt1Status & 0x08) {
236                         pTAS2770->mnErrCode |= ERROR_BROWNOUT;
237                         dev_err(pTAS2770->dev, "brownout!\n");
238                 } else
239                         pTAS2770->mnErrCode &= ~ERROR_BROWNOUT;
241                 if (nDevInt1Status & 0x04) {
242                         pTAS2770->mnErrCode |= ERROR_CLK_LOST;
243                 } else
244                         pTAS2770->mnErrCode &= ~ERROR_CLK_LOST;
246                 if (nDevInt2Status & 0x80) {
247                         pTAS2770->mnErrCode |= ERROR_CLK_DET1;
248                         dev_err(pTAS2770->dev, "clk detection 1!\n");
249                 } else
250                         pTAS2770->mnErrCode &= ~ERROR_CLK_DET1;
252                 if (nDevInt2Status & 0x40) {
253                         pTAS2770->mnErrCode |= ERROR_CLK_DET2;
254                         dev_err(pTAS2770->dev, "clk detection 2!\n");
255                 } else
256                         pTAS2770->mnErrCode &= ~ERROR_CLK_DET2;
258                 goto reload;
259         } else {
260                 dev_dbg(pTAS2770->dev, "IRQ status : 0x%x, 0x%x\n",
261                                 nDevInt1Status, nDevInt2Status);
262                 nCounter = 2;
264                 while (nCounter > 0) {
265                         nResult = tas2770_dev_read(pTAS2770, TAS2770_POWER_UP_FLAG_REG, &nDevInt1Status);
266                         if (nResult < 0)
267                                 goto reload;
269                         if ((nDevInt1Status & 0xc0) == 0xc0)
270                                 break;
272                         nCounter--;
273                         if (nCounter > 0) {
274                                 /* in case check pow status just after power on TAS2770 */
275                                 dev_dbg(pTAS2770->dev, "PowSts B: 0x%x, check again after 10ms\n",
276                                         nDevInt1Status);
277                                 msleep(10);
278                         }
279                 }
281                 if ((nDevInt1Status & 0xc0) != 0xc0) {
282                         dev_err(pTAS2770->dev, "%s, Critical ERROR B[%d]_P[%d]_R[%d]= 0x%x\n",
283                                 __func__,
284                                 TAS2770_BOOK_ID(TAS2770_POWER_UP_FLAG_REG),
285                                 TAS2770_PAGE_ID(TAS2770_POWER_UP_FLAG_REG),
286                                 TAS2770_PAGE_REG(TAS2770_POWER_UP_FLAG_REG),
287                                 nDevInt1Status);
288                         pTAS2770->mnErrCode |= ERROR_CLASSD_PWR;
289                         goto reload;
290                 }
291                 pTAS2770->mnErrCode &= ~ERROR_CLASSD_PWR;
292         }
294         nResult = tas2770_dev_write(pTAS2770, TAS2770_INT_GEN_REG, 0xff);
295         if (nResult < 0)
296                 goto reload;
298         goto end;
300 reload:
301         /* hardware reset and reload */
302         tas2770_LoadConfig(pTAS2770, true);
303 #endif
305 end:
306 /*
307         if (!hrtimer_active(&pTAS2770->mtimer)) {
308                 dev_dbg(pTAS2770->dev, "%s, start timer\n", __func__);
309                 hrtimer_start(&pTAS2770->mtimer,
310                         ns_to_ktime((u64)CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
311         }
312 */
314 #ifdef CONFIG_TAS2770_MISC
315         mutex_unlock(&pTAS2770->file_lock);
316 #endif
318 #ifdef CONFIG_TAS2770_CODEC
319         mutex_unlock(&pTAS2770->codec_lock);
320 #endif
323 static enum hrtimer_restart timer_func(struct hrtimer *timer)
325         struct tas2770_priv *pTAS2770 = container_of(timer, struct tas2770_priv, mtimer);
327         if (pTAS2770->mbPowerUp) {
328                 if (!delayed_work_pending(&pTAS2770->irq_work))
329                         schedule_delayed_work(&pTAS2770->irq_work, msecs_to_jiffies(20));
330         }
332         return HRTIMER_NORESTART;
335 static irqreturn_t tas2770_irq_handler(int irq, void *dev_id)
337         struct tas2770_priv *pTAS2770 = (struct tas2770_priv *)dev_id;
339         tas2770_enableIRQ(pTAS2770, false);
341         /* get IRQ status after 100 ms */
342         if (!delayed_work_pending(&pTAS2770->irq_work))
343                 schedule_delayed_work(&pTAS2770->irq_work, msecs_to_jiffies(100));
345         return IRQ_HANDLED;
348 static int tas2770_runtime_suspend(struct tas2770_priv *pTAS2770)
350         dev_dbg(pTAS2770->dev, "%s\n", __func__);
352         pTAS2770->mbRuntimeSuspend = true;
354         if (hrtimer_active(&pTAS2770->mtimer)) {
355                 dev_dbg(pTAS2770->dev, "cancel die temp timer\n");
356                 hrtimer_cancel(&pTAS2770->mtimer);
357         }
359         if (delayed_work_pending(&pTAS2770->irq_work)) {
360                 dev_dbg(pTAS2770->dev, "cancel IRQ work\n");
361                 cancel_delayed_work_sync(&pTAS2770->irq_work);
362         }
364         return 0;
367 static int tas2770_runtime_resume(struct tas2770_priv *pTAS2770)
369         dev_dbg(pTAS2770->dev, "%s\n", __func__);
371         if (pTAS2770->mbPowerUp) {
372 /*              if (!hrtimer_active(&pTAS2770->mtimer)) {
373                         dev_dbg(pTAS2770->dev, "%s, start check timer\n", __func__);
374                         hrtimer_start(&pTAS2770->mtimer,
375                                 ns_to_ktime((u64)CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
376                 }
377 */
378         }
380         pTAS2770->mbRuntimeSuspend = false;
382         return 0;
385 int tas2770_parse_dt(struct device *dev, struct tas2770_priv *pTAS2770)
387         struct device_node *np = dev->of_node;
388         int rc = 0, ret = 0;
390         rc = of_property_read_u32(np, "ti,asi-format", &pTAS2770->mnASIFormat);
391         if (rc) {
392                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
393                         "ti,asi-format", np->full_name, rc);
394         } else {
395                 dev_dbg(pTAS2770->dev, "ti,asi-format=%d", pTAS2770->mnASIFormat);
396         }
398         pTAS2770->mnResetGPIO = of_get_named_gpio(np, "ti,reset-gpio", 0);
399         if (!gpio_is_valid(pTAS2770->mnResetGPIO)) {
400                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
401                         "ti,reset-gpio", np->full_name, pTAS2770->mnResetGPIO);
402         } else {
403                 dev_dbg(pTAS2770->dev, "ti,reset-gpio=%d", pTAS2770->mnResetGPIO);
404         }
406         pTAS2770->mnIRQGPIO = of_get_named_gpio(np, "ti,irq-gpio", 0);
407         if (!gpio_is_valid(pTAS2770->mnIRQGPIO)) {
408                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
409                         "ti,irq-gpio", np->full_name, pTAS2770->mnIRQGPIO);
410         } else {
411                 dev_dbg(pTAS2770->dev, "ti,irq-gpio=%d", pTAS2770->mnIRQGPIO);
412         }
414         return ret;
417 static int tas2770_i2c_probe(struct i2c_client *client,
418                         const struct i2c_device_id *id)
420         struct tas2770_priv *pTAS2770;
421         int nResult;
423         dev_info(&client->dev, "%s enter\n", __func__);
425         pTAS2770 = devm_kzalloc(&client->dev, sizeof(struct tas2770_priv), GFP_KERNEL);
426         if (pTAS2770 == NULL) {
427                 dev_err(&client->dev, "%s, -ENOMEM \n", __func__);
428                 nResult = -ENOMEM;
429                 goto end;
430         }
432         pTAS2770->dev = &client->dev;
433         i2c_set_clientdata(client, pTAS2770);
434         dev_set_drvdata(&client->dev, pTAS2770);
436         pTAS2770->regmap = devm_regmap_init_i2c(client, &tas2770_i2c_regmap);
437         if (IS_ERR(pTAS2770->regmap)) {
438                 nResult = PTR_ERR(pTAS2770->regmap);
439                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
440                                         nResult);
441                 goto end;
442         }
444 //TODO
445         if (client->dev.of_node)
446                 tas2770_parse_dt(&client->dev, pTAS2770);
448         if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
449                 nResult = gpio_request(pTAS2770->mnResetGPIO, "TAS2770_RESET");
450                 if (nResult) {
451                         dev_err(pTAS2770->dev, "%s: Failed to request gpio %d\n", __func__,
452                                 pTAS2770->mnResetGPIO);
453                         nResult = -EINVAL;
454                         goto free_gpio;
455                 }
456         }
458         if (gpio_is_valid(pTAS2770->mnIRQGPIO)) {
459                 nResult = gpio_request(pTAS2770->mnIRQGPIO, "TAS2770-IRQ");
460                 if (nResult < 0) {
461                         dev_err(pTAS2770->dev, "%s: GPIO %d request error\n",
462                                 __func__, pTAS2770->mnIRQGPIO);
463                         goto free_gpio;
464                 }
465                 gpio_direction_input(pTAS2770->mnIRQGPIO);
466                 pTAS2770->mnIRQ = gpio_to_irq(pTAS2770->mnIRQGPIO);
467                 dev_dbg(pTAS2770->dev, "irq = %d\n", pTAS2770->mnIRQ);
468                 nResult = request_threaded_irq(pTAS2770->mnIRQ, tas2770_irq_handler,
469                                         NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
470                                         client->name, pTAS2770);
471                 if (nResult < 0) {
472                         dev_err(pTAS2770->dev,
473                                 "request_irq failed, %d\n", nResult);
474                         goto free_gpio;
475                 }
476                 disable_irq_nosync(pTAS2770->mnIRQ);
477                 INIT_DELAYED_WORK(&pTAS2770->irq_work, irq_work_routine);
478         }
480         pTAS2770->hw_reset = tas2770_hw_reset;
481         pTAS2770->enableIRQ = tas2770_enableIRQ;
482         pTAS2770->clearIRQ = tas2770_clearIRQ;
483         pTAS2770->runtime_suspend = tas2770_runtime_suspend;
484         pTAS2770->runtime_resume = tas2770_runtime_resume;
485         mutex_init(&pTAS2770->dev_lock);
487 //      nResult = tas2770_LoadConfig(pTAS2770, false);
488         if (nResult < 0)
489                 goto destroy_mutex;
491 #ifdef CONFIG_TAS2770_CODEC
492         mutex_init(&pTAS2770->codec_lock);
493         tas2770_register_codec(pTAS2770);
494 #endif
496 #ifdef CONFIG_TAS2770_MISC
497 //      mutex_init(&pTAS2770->file_lock);
498 //      tas2770_register_misc(pTAS2770);
499 #endif
501         hrtimer_init(&pTAS2770->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
502         pTAS2770->mtimer.function = timer_func;
504 destroy_mutex:
505         if (nResult < 0)
506                 mutex_destroy(&pTAS2770->dev_lock);
508 free_gpio:
509         if (nResult < 0) {
510                 if (gpio_is_valid(pTAS2770->mnResetGPIO))
511                         gpio_free(pTAS2770->mnResetGPIO);
512                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
513                         gpio_free(pTAS2770->mnIRQGPIO);
514         }
516 end:
517         return nResult;
520 static int tas2770_i2c_remove(struct i2c_client *client)
522         struct tas2770_priv *pTAS2770 = i2c_get_clientdata(client);
524         dev_info(pTAS2770->dev, "%s\n", __func__);
526 #ifdef CONFIG_TAS2770_CODEC
527         tas2770_deregister_codec(pTAS2770);
528         mutex_destroy(&pTAS2770->codec_lock);
529 #endif
531 #ifdef CONFIG_TAS2770_MISC
532 //      tas2770_deregister_misc(pTAS2770);
533         mutex_destroy(&pTAS2770->file_lock);
534 #endif
536         if (gpio_is_valid(pTAS2770->mnResetGPIO))
537                 gpio_free(pTAS2770->mnResetGPIO);
538         if (gpio_is_valid(pTAS2770->mnIRQGPIO))
539                 gpio_free(pTAS2770->mnIRQGPIO);
541         return 0;
545 static const struct i2c_device_id tas2770_i2c_id[] = {
546         { "tas2770", 0},
547         { }
548 };
549 MODULE_DEVICE_TABLE(i2c, tas2770_i2c_id);
551 #if defined(CONFIG_OF)
552 static const struct of_device_id tas2770_of_match[] = {
553         { .compatible = "ti,tas2770" },
554         {},
555 };
556 MODULE_DEVICE_TABLE(of, tas2770_of_match);
557 #endif
560 static struct i2c_driver tas2770_i2c_driver = {
561         .driver = {
562                 .name   = "tas2770",
563                 .owner  = THIS_MODULE,
564 #if defined(CONFIG_OF)
565                 .of_match_table = of_match_ptr(tas2770_of_match),
566 #endif
567         },
568         .probe      = tas2770_i2c_probe,
569         .remove     = tas2770_i2c_remove,
570         .id_table   = tas2770_i2c_id,
571 };
573 module_i2c_driver(tas2770_i2c_driver);
575 MODULE_AUTHOR("Texas Instruments Inc.");
576 MODULE_DESCRIPTION("TAS2770 I2C Smart Amplifier driver");
577 MODULE_LICENSE("GPL v2");
578 #endif