cs35l45.c (fa8c052b4c614aa1d2d60e5c9f40e9d885bf9511) cs35l45.c (6085f9e6dc1973cf98ee7f5dcf629939e50f1b84)
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2//
3// cs35l45.c - CS35L45 ALSA SoC audio driver
4//
5// Copyright 2019-2022 Cirrus Logic, Inc.
6//
7// Author: James Schulman <james.schulman@cirrus.com>
8

--- 572 unchanged lines hidden (view full) ---

581
582 ret = of_property_read_u32(child, "gpio-ctrl", &val);
583 if (!ret)
584 regmap_update_bits(cs35l45->regmap, pad_regs[i],
585 CS35L45_GPIO_CTRL_MASK,
586 val << CS35L45_GPIO_CTRL_SHIFT);
587
588 ret = of_property_read_u32(child, "gpio-invert", &val);
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2//
3// cs35l45.c - CS35L45 ALSA SoC audio driver
4//
5// Copyright 2019-2022 Cirrus Logic, Inc.
6//
7// Author: James Schulman <james.schulman@cirrus.com>
8

--- 572 unchanged lines hidden (view full) ---

581
582 ret = of_property_read_u32(child, "gpio-ctrl", &val);
583 if (!ret)
584 regmap_update_bits(cs35l45->regmap, pad_regs[i],
585 CS35L45_GPIO_CTRL_MASK,
586 val << CS35L45_GPIO_CTRL_SHIFT);
587
588 ret = of_property_read_u32(child, "gpio-invert", &val);
589 if (!ret)
589 if (!ret) {
590 regmap_update_bits(cs35l45->regmap, pad_regs[i],
591 CS35L45_GPIO_INVERT_MASK,
592 val << CS35L45_GPIO_INVERT_SHIFT);
590 regmap_update_bits(cs35l45->regmap, pad_regs[i],
591 CS35L45_GPIO_INVERT_MASK,
592 val << CS35L45_GPIO_INVERT_SHIFT);
593 if (i == 1)
594 cs35l45->irq_invert = val;
595 }
593
594 of_node_put(child);
595 }
596
597 if (device_property_read_u32(cs35l45->dev,
598 "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
599 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL3,
600 CS35L45_ASP_DOUT_HIZ_CTRL_MASK,
601 val << CS35L45_ASP_DOUT_HIZ_CTRL_SHIFT);
602 }
603
604 return 0;
605}
606
596
597 of_node_put(child);
598 }
599
600 if (device_property_read_u32(cs35l45->dev,
601 "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
602 regmap_update_bits(cs35l45->regmap, CS35L45_ASP_CONTROL3,
603 CS35L45_ASP_DOUT_HIZ_CTRL_MASK,
604 val << CS35L45_ASP_DOUT_HIZ_CTRL_SHIFT);
605 }
606
607 return 0;
608}
609
610static irqreturn_t cs35l45_pll_unlock(int irq, void *data)
611{
612 struct cs35l45_private *cs35l45 = data;
613
614 dev_dbg(cs35l45->dev, "PLL unlock detected!");
615
616 return IRQ_HANDLED;
617}
618
619static irqreturn_t cs35l45_pll_lock(int irq, void *data)
620{
621 struct cs35l45_private *cs35l45 = data;
622
623 dev_dbg(cs35l45->dev, "PLL lock detected!");
624
625 return IRQ_HANDLED;
626}
627
628static irqreturn_t cs35l45_spk_safe_err(int irq, void *data);
629
630static const struct cs35l45_irq cs35l45_irqs[] = {
631 CS35L45_IRQ(AMP_SHORT_ERR, "Amplifier short error", cs35l45_spk_safe_err),
632 CS35L45_IRQ(UVLO_VDDBATT_ERR, "VDDBATT undervoltage error", cs35l45_spk_safe_err),
633 CS35L45_IRQ(BST_SHORT_ERR, "Boost inductor error", cs35l45_spk_safe_err),
634 CS35L45_IRQ(BST_UVP_ERR, "Boost undervoltage error", cs35l45_spk_safe_err),
635 CS35L45_IRQ(TEMP_ERR, "Overtemperature error", cs35l45_spk_safe_err),
636 CS35L45_IRQ(AMP_CAL_ERR, "Amplifier calibration error", cs35l45_spk_safe_err),
637 CS35L45_IRQ(UVLO_VDDLV_ERR, "LV threshold detector error", cs35l45_spk_safe_err),
638 CS35L45_IRQ(GLOBAL_ERROR, "Global error", cs35l45_spk_safe_err),
639 CS35L45_IRQ(DSP_WDT_EXPIRE, "DSP Watchdog Timer", cs35l45_spk_safe_err),
640 CS35L45_IRQ(PLL_UNLOCK_FLAG_RISE, "PLL unlock", cs35l45_pll_unlock),
641 CS35L45_IRQ(PLL_LOCK_FLAG, "PLL lock", cs35l45_pll_lock),
642};
643
644static irqreturn_t cs35l45_spk_safe_err(int irq, void *data)
645{
646 struct cs35l45_private *cs35l45 = data;
647 int i;
648
649 i = irq - regmap_irq_get_virq(cs35l45->irq_data, 0);
650
651 dev_err(cs35l45->dev, "%s condition detected!\n", cs35l45_irqs[i].name);
652
653 return IRQ_HANDLED;
654}
655
656static const struct regmap_irq cs35l45_reg_irqs[] = {
657 CS35L45_REG_IRQ(IRQ1_EINT_1, AMP_SHORT_ERR),
658 CS35L45_REG_IRQ(IRQ1_EINT_1, UVLO_VDDBATT_ERR),
659 CS35L45_REG_IRQ(IRQ1_EINT_1, BST_SHORT_ERR),
660 CS35L45_REG_IRQ(IRQ1_EINT_1, BST_UVP_ERR),
661 CS35L45_REG_IRQ(IRQ1_EINT_1, TEMP_ERR),
662 CS35L45_REG_IRQ(IRQ1_EINT_3, AMP_CAL_ERR),
663 CS35L45_REG_IRQ(IRQ1_EINT_18, UVLO_VDDLV_ERR),
664 CS35L45_REG_IRQ(IRQ1_EINT_18, GLOBAL_ERROR),
665 CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_WDT_EXPIRE),
666 CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_UNLOCK_FLAG_RISE),
667 CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_LOCK_FLAG),
668};
669
670static const struct regmap_irq_chip cs35l45_regmap_irq_chip = {
671 .name = "cs35l45 IRQ1 Controller",
672 .main_status = CS35L45_IRQ1_STATUS,
673 .status_base = CS35L45_IRQ1_EINT_1,
674 .mask_base = CS35L45_IRQ1_MASK_1,
675 .ack_base = CS35L45_IRQ1_EINT_1,
676 .num_regs = 18,
677 .irqs = cs35l45_reg_irqs,
678 .num_irqs = ARRAY_SIZE(cs35l45_reg_irqs),
679 .runtime_pm = true,
680};
681
607static int cs35l45_initialize(struct cs35l45_private *cs35l45)
608{
609 struct device *dev = cs35l45->dev;
610 unsigned int dev_id[5];
611 unsigned int sts;
612 int ret;
613
614 ret = regmap_read_poll_timeout(cs35l45->regmap, CS35L45_IRQ1_EINT_4, sts,

--- 40 unchanged lines hidden (view full) ---

655 pm_runtime_enable(cs35l45->dev);
656
657 return 0;
658}
659
660int cs35l45_probe(struct cs35l45_private *cs35l45)
661{
662 struct device *dev = cs35l45->dev;
682static int cs35l45_initialize(struct cs35l45_private *cs35l45)
683{
684 struct device *dev = cs35l45->dev;
685 unsigned int dev_id[5];
686 unsigned int sts;
687 int ret;
688
689 ret = regmap_read_poll_timeout(cs35l45->regmap, CS35L45_IRQ1_EINT_4, sts,

--- 40 unchanged lines hidden (view full) ---

730 pm_runtime_enable(cs35l45->dev);
731
732 return 0;
733}
734
735int cs35l45_probe(struct cs35l45_private *cs35l45)
736{
737 struct device *dev = cs35l45->dev;
663 int ret;
738 unsigned long irq_pol = IRQF_ONESHOT | IRQF_SHARED;
739 int ret, i, irq;
664
665 cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");
666 if (IS_ERR(cs35l45->vdd_batt))
667 return dev_err_probe(dev, PTR_ERR(cs35l45->vdd_batt),
668 "Failed to request vdd-batt\n");
669
670 cs35l45->vdd_a = devm_regulator_get(dev, "vdd-a");
671 if (IS_ERR(cs35l45->vdd_a))

--- 28 unchanged lines hidden (view full) ---

700 }
701
702 usleep_range(CS35L45_RESET_US, CS35L45_RESET_US + 100);
703
704 ret = cs35l45_initialize(cs35l45);
705 if (ret < 0)
706 goto err_reset;
707
740
741 cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");
742 if (IS_ERR(cs35l45->vdd_batt))
743 return dev_err_probe(dev, PTR_ERR(cs35l45->vdd_batt),
744 "Failed to request vdd-batt\n");
745
746 cs35l45->vdd_a = devm_regulator_get(dev, "vdd-a");
747 if (IS_ERR(cs35l45->vdd_a))

--- 28 unchanged lines hidden (view full) ---

776 }
777
778 usleep_range(CS35L45_RESET_US, CS35L45_RESET_US + 100);
779
780 ret = cs35l45_initialize(cs35l45);
781 if (ret < 0)
782 goto err_reset;
783
784 if (cs35l45->irq) {
785 if (cs35l45->irq_invert)
786 irq_pol |= IRQF_TRIGGER_HIGH;
787 else
788 irq_pol |= IRQF_TRIGGER_LOW;
789
790 ret = devm_regmap_add_irq_chip(dev, cs35l45->regmap, cs35l45->irq, irq_pol, 0,
791 &cs35l45_regmap_irq_chip, &cs35l45->irq_data);
792 if (ret) {
793 dev_err(dev, "Failed to register IRQ chip: %d\n", ret);
794 goto err_reset;
795 }
796
797 for (i = 0; i < ARRAY_SIZE(cs35l45_irqs); i++) {
798 irq = regmap_irq_get_virq(cs35l45->irq_data, cs35l45_irqs[i].irq);
799 if (irq < 0) {
800 dev_err(dev, "Failed to get %s\n", cs35l45_irqs[i].name);
801 ret = irq;
802 goto err_reset;
803 }
804
805 ret = devm_request_threaded_irq(dev, irq, NULL, cs35l45_irqs[i].handler,
806 irq_pol, cs35l45_irqs[i].name, cs35l45);
807 if (ret) {
808 dev_err(dev, "Failed to request IRQ %s: %d\n",
809 cs35l45_irqs[i].name, ret);
810 goto err_reset;
811 }
812 }
813 }
814
708 ret = devm_snd_soc_register_component(dev, &cs35l45_component,
709 cs35l45_dai,
710 ARRAY_SIZE(cs35l45_dai));
711 if (ret < 0)
712 goto err_reset;
713
714 return 0;
715

--- 30 unchanged lines hidden ---
815 ret = devm_snd_soc_register_component(dev, &cs35l45_component,
816 cs35l45_dai,
817 ARRAY_SIZE(cs35l45_dai));
818 if (ret < 0)
819 goto err_reset;
820
821 return 0;
822

--- 30 unchanged lines hidden ---