Lines Matching +full:pmic +full:- +full:specific

1 // SPDX-License-Identifier: GPL-2.0-only
3 * MediaTek MT6359 PMIC AUXADC IIO driver
25 #include <dt-bindings/iio/adc/mediatek,mt6357-auxadc.h>
26 #include <dt-bindings/iio/adc/mediatek,mt6358-auxadc.h>
27 #include <dt-bindings/iio/adc/mediatek,mt6359-auxadc.h>
28 #include <dt-bindings/iio/adc/mediatek,mt6363-auxadc.h>
36 /* For PMIC_RG_RESET_VAL and MT6358_IMP0_CLEAR, the bits specific purpose is unknown. */
103 * struct mt6359_auxadc - Main driver structure
105 * @regmap: Regmap from SoC PMIC Wrapper
106 * @chip_info: PMIC specific chip info
119 * struct mtk_pmic_auxadc_chan - PMIC AUXADC channel data
124 * @ext_sel_idx: PMIC GPIO channel register number
125 * @ext_sel_ch: PMIC GPIO number
126 * @ext_sel_pu: PMIC GPIO channel pullup resistor selector
143 * struct mtk_pmic_auxadc_info - PMIC specific chip info
144 * @model_name: PMIC model name
147 * @desc: PMIC AUXADC channel data
148 * @regs: List of PMIC specific registers
152 * @is_spmi: Defines whether this PMIC communicates over SPMI
153 * @no_reset: If true, this PMIC does not support ADC reset
189 -1, 0, 0, _samples, _rnum, _rdiv)
455 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6358_stop_imp_conv()
456 struct regmap *regmap = adc_dev->regmap; in mt6358_stop_imp_conv()
458 regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6358_IMP0_CLEAR); in mt6358_stop_imp_conv()
459 regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6358_IMP0_CLEAR); in mt6358_stop_imp_conv()
460 regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP1], MT6358_IMP1_AUTOREPEAT_EN); in mt6358_stop_imp_conv()
461 regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_DCM_CON], MT6358_DCM_CK_SW_EN); in mt6358_stop_imp_conv()
466 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6358_start_imp_conv()
467 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index]; in mt6358_start_imp_conv()
468 struct regmap *regmap = adc_dev->regmap; in mt6358_start_imp_conv()
472 regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_DCM_CON], MT6358_DCM_CK_SW_EN); in mt6358_start_imp_conv()
473 regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP1], MT6358_IMP1_AUTOREPEAT_EN); in mt6358_start_imp_conv()
475 ret = regmap_read_poll_timeout(regmap, cinfo->regs[desc->rdy_idx], in mt6358_start_imp_conv()
476 val, val & desc->rdy_mask, in mt6358_start_imp_conv()
489 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6358_read_imp()
490 struct regmap *regmap = adc_dev->regmap; in mt6358_read_imp()
491 u16 reg_adc0 = cinfo->regs[PMIC_AUXADC_ADC0]; in mt6358_read_imp()
500 regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v); in mt6358_read_imp()
515 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6359_read_imp()
516 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index]; in mt6359_read_imp()
517 struct regmap *regmap = adc_dev->regmap; in mt6359_read_imp()
522 regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6359_IMP0_CONV_EN); in mt6359_read_imp()
523 ret = regmap_read_poll_timeout(regmap, cinfo->regs[desc->rdy_idx], in mt6359_read_imp()
524 val, val & desc->rdy_mask, in mt6359_read_imp()
528 regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], 0); in mt6359_read_imp()
535 ret = regmap_read(regmap, cinfo->regs[PMIC_AUXADC_IMP3], &val_v); in mt6359_read_imp()
539 ret = regmap_read(regmap, cinfo->regs[PMIC_FGADC_R_CON0], &val_i); in mt6359_read_imp()
608 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6359_auxadc_reset()
609 struct regmap *regmap = adc_dev->regmap; in mt6359_auxadc_reset()
612 if (cinfo->no_reset) in mt6359_auxadc_reset()
616 if (cinfo->sec_unlock_key) in mt6359_auxadc_reset()
617 regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], cinfo->sec_unlock_key); in mt6359_auxadc_reset()
620 regmap_set_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL); in mt6359_auxadc_reset()
622 /* De-assert ADC reset. No wait required, as pwrap takes care of that for us. */ in mt6359_auxadc_reset()
623 regmap_clear_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL); in mt6359_auxadc_reset()
626 if (cinfo->sec_unlock_key) in mt6359_auxadc_reset()
627 regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], 0); in mt6359_auxadc_reset()
631 * mt6359_auxadc_sample_adc_val() - Start ADC channel sampling and read value
649 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6359_auxadc_sample_adc_val()
650 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index]; in mt6359_auxadc_sample_adc_val()
651 struct regmap *regmap = adc_dev->regmap; in mt6359_auxadc_sample_adc_val()
656 ret = regmap_write(regmap, cinfo->regs[desc->req_idx], desc->req_mask); in mt6359_auxadc_sample_adc_val()
661 fsleep(desc->num_samples * AUXADC_AVG_TIME_US); in mt6359_auxadc_sample_adc_val()
663 reg = cinfo->regs[PMIC_AUXADC_ADC0] + (chan->address << 1); in mt6359_auxadc_sample_adc_val()
673 if (cinfo->is_spmi) { in mt6359_auxadc_sample_adc_val()
681 dev_dbg(adc_dev->dev, "ADC read timeout for chan %lu\n", chan->address); in mt6359_auxadc_sample_adc_val()
685 if (cinfo->is_spmi) { in mt6359_auxadc_sample_adc_val()
686 ret = regmap_read(regmap, reg - 1, &lval); in mt6359_auxadc_sample_adc_val()
700 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6359_auxadc_read_adc()
701 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index]; in mt6359_auxadc_read_adc()
702 struct regmap *regmap = adc_dev->regmap; in mt6359_auxadc_read_adc()
707 if (desc->ext_sel_idx >= 0) { in mt6359_auxadc_read_adc()
708 ext_sel = FIELD_PREP(MT6363_EXT_PURES_MASK, desc->ext_sel_pu); in mt6359_auxadc_read_adc()
709 ext_sel |= FIELD_PREP(MT6363_EXT_CHAN_MASK, desc->ext_sel_ch); in mt6359_auxadc_read_adc()
711 ret = regmap_update_bits(regmap, cinfo->regs[desc->ext_sel_idx], in mt6359_auxadc_read_adc()
725 * stop after some time (depending on the PMIC model); if not, the next in mt6359_auxadc_read_adc()
726 * read attempt will return -ETIMEDOUT and, for models that support it, in mt6359_auxadc_read_adc()
731 adc_stop_err = regmap_write(regmap, cinfo->regs[desc->req_idx], 0); in mt6359_auxadc_read_adc()
733 dev_warn(adc_dev->dev, "Could not stop the ADC: %d\n,", adc_stop_err); in mt6359_auxadc_read_adc()
734 adc_dev->timed_out = true; in mt6359_auxadc_read_adc()
742 if (desc->ext_sel_idx >= 0) { in mt6359_auxadc_read_adc()
745 ret = regmap_update_bits(regmap, cinfo->regs[desc->ext_sel_idx], in mt6359_auxadc_read_adc()
752 *out = val & GENMASK(chan->scan_type.realbits - 1, 0); in mt6359_auxadc_read_adc()
759 return sysfs_emit(label, "%s\n", chan->datasheet_name); in mt6359_auxadc_read_label()
767 const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info; in mt6359_auxadc_read_raw()
768 const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index]; in mt6359_auxadc_read_raw()
772 *val = desc->r_ratio.numerator * cinfo->vref_mV; in mt6359_auxadc_read_raw()
774 if (desc->r_ratio.denominator > 1) { in mt6359_auxadc_read_raw()
775 *val2 = desc->r_ratio.denominator; in mt6359_auxadc_read_raw()
782 scoped_guard(mutex, &adc_dev->lock) { in mt6359_auxadc_read_raw()
783 switch (chan->scan_index) { in mt6359_auxadc_read_raw()
785 if (!adc_dev->chip_info->read_imp) in mt6359_auxadc_read_raw()
786 return -EOPNOTSUPP; in mt6359_auxadc_read_raw()
788 ret = adc_dev->chip_info->read_imp(adc_dev, chan, NULL, val); in mt6359_auxadc_read_raw()
791 if (!adc_dev->chip_info->read_imp) in mt6359_auxadc_read_raw()
792 return -EOPNOTSUPP; in mt6359_auxadc_read_raw()
794 ret = adc_dev->chip_info->read_imp(adc_dev, chan, val, NULL); in mt6359_auxadc_read_raw()
807 if (ret == -ETIMEDOUT) { in mt6359_auxadc_read_raw()
808 if (adc_dev->timed_out) { in mt6359_auxadc_read_raw()
809 dev_warn(adc_dev->dev, "Resetting stuck ADC!\r\n"); in mt6359_auxadc_read_raw()
812 adc_dev->timed_out = true; in mt6359_auxadc_read_raw()
816 adc_dev->timed_out = false; in mt6359_auxadc_read_raw()
829 struct device *dev = &pdev->dev; in mt6359_auxadc_probe()
830 struct device *mfd_dev = dev->parent; in mt6359_auxadc_probe()
839 return -EINVAL; in mt6359_auxadc_probe()
842 * SoC PMIC Wrapper and SPMI PMIC cases: in mt6359_auxadc_probe()
845 * this driver: this_device->parent(mfd). in mt6359_auxadc_probe()
847 * If this is under the SoC PMIC Wrapper, the regmap comes from the in mt6359_auxadc_probe()
848 * parent of the MT6397 MFD: this_device->parent(mfd)->parent(pwrap) in mt6359_auxadc_probe()
850 if (chip_info->is_spmi) in mt6359_auxadc_probe()
853 regmap_dev = mfd_dev->parent; in mt6359_auxadc_probe()
856 /* Regmap is from SoC PMIC Wrapper, parent of the mt6397 MFD */ in mt6359_auxadc_probe()
859 return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n"); in mt6359_auxadc_probe()
863 return -ENOMEM; in mt6359_auxadc_probe()
866 adc_dev->regmap = regmap; in mt6359_auxadc_probe()
867 adc_dev->dev = dev; in mt6359_auxadc_probe()
868 adc_dev->chip_info = chip_info; in mt6359_auxadc_probe()
870 mutex_init(&adc_dev->lock); in mt6359_auxadc_probe()
874 indio_dev->name = adc_dev->chip_info->model_name; in mt6359_auxadc_probe()
875 indio_dev->info = &mt6359_auxadc_iio_info; in mt6359_auxadc_probe()
876 indio_dev->modes = INDIO_DIRECT_MODE; in mt6359_auxadc_probe()
877 indio_dev->channels = adc_dev->chip_info->channels; in mt6359_auxadc_probe()
878 indio_dev->num_channels = adc_dev->chip_info->num_channels; in mt6359_auxadc_probe()
888 { .compatible = "mediatek,mt6357-auxadc", .data = &mt6357_chip_info },
889 { .compatible = "mediatek,mt6358-auxadc", .data = &mt6358_chip_info },
890 { .compatible = "mediatek,mt6359-auxadc", .data = &mt6359_chip_info },
891 { .compatible = "mediatek,mt6363-auxadc", .data = &mt6363_chip_info },
892 { .compatible = "mediatek,mt6373-auxadc", .data = &mt6373_chip_info },
899 .name = "mt6359-auxadc",
908 MODULE_DESCRIPTION("MediaTek MT6359 PMIC AUXADC Driver");