.. | .. |
---|
2 | 2 | /* |
---|
3 | 3 | * ALSA SoC Texas Instruments TAS6424 Quad-Channel Audio Amplifier |
---|
4 | 4 | * |
---|
5 | | - * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/ |
---|
| 5 | + * Copyright (C) 2016-2017 Texas Instruments Incorporated - https://www.ti.com/ |
---|
6 | 6 | * Author: Andreas Dannenberg <dannenberg@ti.com> |
---|
7 | 7 | * Andrew F. Davis <afd@ti.com> |
---|
8 | 8 | */ |
---|
.. | .. |
---|
41 | 41 | struct regmap *regmap; |
---|
42 | 42 | struct regulator_bulk_data supplies[TAS6424_NUM_SUPPLIES]; |
---|
43 | 43 | struct delayed_work fault_check_work; |
---|
| 44 | + unsigned int last_cfault; |
---|
44 | 45 | unsigned int last_fault1; |
---|
45 | 46 | unsigned int last_fault2; |
---|
46 | 47 | unsigned int last_warn; |
---|
.. | .. |
---|
251 | 252 | return 0; |
---|
252 | 253 | } |
---|
253 | 254 | |
---|
254 | | -static int tas6424_mute(struct snd_soc_dai *dai, int mute) |
---|
| 255 | +static int tas6424_mute(struct snd_soc_dai *dai, int mute, int direction) |
---|
255 | 256 | { |
---|
256 | 257 | struct snd_soc_component *component = dai->component; |
---|
257 | 258 | struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component); |
---|
.. | .. |
---|
377 | 378 | .non_legacy_dai_naming = 1, |
---|
378 | 379 | }; |
---|
379 | 380 | |
---|
380 | | -static struct snd_soc_dai_ops tas6424_speaker_dai_ops = { |
---|
| 381 | +static const struct snd_soc_dai_ops tas6424_speaker_dai_ops = { |
---|
381 | 382 | .hw_params = tas6424_hw_params, |
---|
382 | 383 | .set_fmt = tas6424_set_dai_fmt, |
---|
383 | 384 | .set_tdm_slot = tas6424_set_dai_tdm_slot, |
---|
384 | | - .digital_mute = tas6424_mute, |
---|
| 385 | + .mute_stream = tas6424_mute, |
---|
| 386 | + .no_capture_mute = 1, |
---|
385 | 387 | }; |
---|
386 | 388 | |
---|
387 | 389 | static struct snd_soc_dai_driver tas6424_dai[] = { |
---|
.. | .. |
---|
406 | 408 | unsigned int reg; |
---|
407 | 409 | int ret; |
---|
408 | 410 | |
---|
| 411 | + ret = regmap_read(tas6424->regmap, TAS6424_CHANNEL_FAULT, ®); |
---|
| 412 | + if (ret < 0) { |
---|
| 413 | + dev_err(dev, "failed to read CHANNEL_FAULT register: %d\n", ret); |
---|
| 414 | + goto out; |
---|
| 415 | + } |
---|
| 416 | + |
---|
| 417 | + if (!reg) { |
---|
| 418 | + tas6424->last_cfault = reg; |
---|
| 419 | + goto check_global_fault1_reg; |
---|
| 420 | + } |
---|
| 421 | + |
---|
| 422 | + /* |
---|
| 423 | + * Only flag errors once for a given occurrence. This is needed as |
---|
| 424 | + * the TAS6424 will take time clearing the fault condition internally |
---|
| 425 | + * during which we don't want to bombard the system with the same |
---|
| 426 | + * error message over and over. |
---|
| 427 | + */ |
---|
| 428 | + if ((reg & TAS6424_FAULT_OC_CH1) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH1)) |
---|
| 429 | + dev_crit(dev, "experienced a channel 1 overcurrent fault\n"); |
---|
| 430 | + |
---|
| 431 | + if ((reg & TAS6424_FAULT_OC_CH2) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH2)) |
---|
| 432 | + dev_crit(dev, "experienced a channel 2 overcurrent fault\n"); |
---|
| 433 | + |
---|
| 434 | + if ((reg & TAS6424_FAULT_OC_CH3) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH3)) |
---|
| 435 | + dev_crit(dev, "experienced a channel 3 overcurrent fault\n"); |
---|
| 436 | + |
---|
| 437 | + if ((reg & TAS6424_FAULT_OC_CH4) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH4)) |
---|
| 438 | + dev_crit(dev, "experienced a channel 4 overcurrent fault\n"); |
---|
| 439 | + |
---|
| 440 | + if ((reg & TAS6424_FAULT_DC_CH1) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH1)) |
---|
| 441 | + dev_crit(dev, "experienced a channel 1 DC fault\n"); |
---|
| 442 | + |
---|
| 443 | + if ((reg & TAS6424_FAULT_DC_CH2) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH2)) |
---|
| 444 | + dev_crit(dev, "experienced a channel 2 DC fault\n"); |
---|
| 445 | + |
---|
| 446 | + if ((reg & TAS6424_FAULT_DC_CH3) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH3)) |
---|
| 447 | + dev_crit(dev, "experienced a channel 3 DC fault\n"); |
---|
| 448 | + |
---|
| 449 | + if ((reg & TAS6424_FAULT_DC_CH4) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH4)) |
---|
| 450 | + dev_crit(dev, "experienced a channel 4 DC fault\n"); |
---|
| 451 | + |
---|
| 452 | + /* Store current fault1 value so we can detect any changes next time */ |
---|
| 453 | + tas6424->last_cfault = reg; |
---|
| 454 | + |
---|
| 455 | +check_global_fault1_reg: |
---|
409 | 456 | ret = regmap_read(tas6424->regmap, TAS6424_GLOB_FAULT1, ®); |
---|
410 | 457 | if (ret < 0) { |
---|
411 | | - dev_err(dev, "failed to read FAULT1 register: %d\n", ret); |
---|
| 458 | + dev_err(dev, "failed to read GLOB_FAULT1 register: %d\n", ret); |
---|
412 | 459 | goto out; |
---|
413 | 460 | } |
---|
414 | 461 | |
---|
.. | .. |
---|
429 | 476 | goto check_global_fault2_reg; |
---|
430 | 477 | } |
---|
431 | 478 | |
---|
432 | | - /* |
---|
433 | | - * Only flag errors once for a given occurrence. This is needed as |
---|
434 | | - * the TAS6424 will take time clearing the fault condition internally |
---|
435 | | - * during which we don't want to bombard the system with the same |
---|
436 | | - * error message over and over. |
---|
437 | | - */ |
---|
438 | 479 | if ((reg & TAS6424_FAULT_PVDD_OV) && !(tas6424->last_fault1 & TAS6424_FAULT_PVDD_OV)) |
---|
439 | 480 | dev_crit(dev, "experienced a PVDD overvoltage fault\n"); |
---|
440 | 481 | |
---|
.. | .. |
---|
453 | 494 | check_global_fault2_reg: |
---|
454 | 495 | ret = regmap_read(tas6424->regmap, TAS6424_GLOB_FAULT2, ®); |
---|
455 | 496 | if (ret < 0) { |
---|
456 | | - dev_err(dev, "failed to read FAULT2 register: %d\n", ret); |
---|
| 497 | + dev_err(dev, "failed to read GLOB_FAULT2 register: %d\n", ret); |
---|
457 | 498 | goto out; |
---|
458 | 499 | } |
---|
459 | 500 | |
---|
.. | .. |
---|
530 | 571 | /* Store current warn value so we can detect any changes next time */ |
---|
531 | 572 | tas6424->last_warn = reg; |
---|
532 | 573 | |
---|
533 | | - /* Clear any faults by toggling the CLEAR_FAULT control bit */ |
---|
| 574 | + /* Clear any warnings by toggling the CLEAR_FAULT control bit */ |
---|
534 | 575 | ret = regmap_write_bits(tas6424->regmap, TAS6424_MISC_CTRL3, |
---|
535 | 576 | TAS6424_CLEAR_FAULT, TAS6424_CLEAR_FAULT); |
---|
536 | 577 | if (ret < 0) |
---|