c98cdc7e794bcd579f17df70c2857fe4d6d8f3f2
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)
108 {
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;
118 }
120 void tas2770_enableIRQ(struct tas2770_priv *pTAS2770, bool enable)
121 {
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 }
136 }
138 static void irq_work_routine(struct work_struct *work)
139 {
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
263 }
265 static enum hrtimer_restart timer_func(struct hrtimer *timer)
266 {
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;
277 }
279 static irqreturn_t tas2770_irq_handler(int irq, void *dev_id)
280 {
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;
291 }
293 static int tas2770_runtime_suspend(struct tas2770_priv *pTAS2770)
294 {
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;
310 }
312 #define CHECK_PERIOD 5000 /* 5 second */
313 static int tas2770_runtime_resume(struct tas2770_priv *pTAS2770)
314 {
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;
328 }
330 static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *pTAS2770)
331 {
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;
398 }
400 static int tas2770_i2c_probe(struct i2c_client *client,
401 const struct i2c_device_id *id)
402 {
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;
502 }
504 static int tas2770_i2c_remove(struct i2c_client *client)
505 {
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;
521 }
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