^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Lochnagar regulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) 2017-2018 Cirrus Logic, Inc. and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Cirrus Logic International Semiconductor Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Author: Charles Keepax <ckeepax@opensource.cirrus.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/regulator/of_regulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mfd/lochnagar.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mfd/lochnagar1_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/mfd/lochnagar2_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static const struct regulator_ops lochnagar_micvdd_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .list_voltage = regulator_list_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .map_voltage = regulator_map_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const struct linear_range lochnagar_micvdd_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) REGULATOR_LINEAR_RANGE(1000000, 0, 0xC, 50000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) REGULATOR_LINEAR_RANGE(1700000, 0xD, 0x1F, 100000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int lochnagar_micbias_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct lochnagar *lochnagar = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mutex_lock(&lochnagar->analogue_config_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = regulator_enable_regmap(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ret = lochnagar_update_config(lochnagar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mutex_unlock(&lochnagar->analogue_config_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int lochnagar_micbias_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct lochnagar *lochnagar = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mutex_lock(&lochnagar->analogue_config_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ret = regulator_disable_regmap(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ret = lochnagar_update_config(lochnagar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mutex_unlock(&lochnagar->analogue_config_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static const struct regulator_ops lochnagar_micbias_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .enable = lochnagar_micbias_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .disable = lochnagar_micbias_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static const struct regulator_ops lochnagar_vddcore_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .list_voltage = regulator_list_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .map_voltage = regulator_map_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const struct linear_range lochnagar_vddcore_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) REGULATOR_LINEAR_RANGE(600000, 0x8, 0x41, 12500),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) enum lochnagar_regulators {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) LOCHNAGAR_MICVDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) LOCHNAGAR_MIC1VDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) LOCHNAGAR_MIC2VDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) LOCHNAGAR_VDDCORE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int lochnagar_micbias_of_parse(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const struct regulator_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct regulator_config *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct lochnagar *lochnagar = config->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int shift = (desc->id - LOCHNAGAR_MIC1VDD) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) LOCHNAGAR2_P2_MICBIAS_SRC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int mask = LOCHNAGAR2_P1_MICBIAS_SRC_MASK << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = of_property_read_u32(np, "cirrus,micbias-input", &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mutex_lock(&lochnagar->analogue_config_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = regmap_update_bits(lochnagar->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) LOCHNAGAR2_ANALOGUE_PATH_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mask, val << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mutex_unlock(&lochnagar->analogue_config_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dev_err(lochnagar->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "Failed to update micbias source: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static const struct regulator_desc lochnagar_regulators[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) [LOCHNAGAR_MICVDD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .name = "MICVDD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .supply_name = "SYSVDD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .n_voltages = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .ops = &lochnagar_micvdd_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .id = LOCHNAGAR_MICVDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .of_match = of_match_ptr("MICVDD"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .enable_reg = LOCHNAGAR2_MICVDD_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .enable_mask = LOCHNAGAR2_MICVDD_REG_ENA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .vsel_reg = LOCHNAGAR2_MICVDD_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .vsel_mask = LOCHNAGAR2_MICVDD_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .linear_ranges = lochnagar_micvdd_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .n_linear_ranges = ARRAY_SIZE(lochnagar_micvdd_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .enable_time = 3000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .ramp_delay = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) [LOCHNAGAR_MIC1VDD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .name = "MIC1VDD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .supply_name = "MICBIAS1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .ops = &lochnagar_micbias_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .id = LOCHNAGAR_MIC1VDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .of_match = of_match_ptr("MIC1VDD"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .of_parse_cb = lochnagar_micbias_of_parse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .enable_reg = LOCHNAGAR2_ANALOGUE_PATH_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .enable_mask = LOCHNAGAR2_P1_INPUT_BIAS_ENA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) [LOCHNAGAR_MIC2VDD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .name = "MIC2VDD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .supply_name = "MICBIAS2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .ops = &lochnagar_micbias_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .id = LOCHNAGAR_MIC2VDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .of_match = of_match_ptr("MIC2VDD"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .of_parse_cb = lochnagar_micbias_of_parse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .enable_reg = LOCHNAGAR2_ANALOGUE_PATH_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .enable_mask = LOCHNAGAR2_P2_INPUT_BIAS_ENA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) [LOCHNAGAR_VDDCORE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .name = "VDDCORE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .supply_name = "SYSVDD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .n_voltages = 66,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .ops = &lochnagar_vddcore_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .id = LOCHNAGAR_VDDCORE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .of_match = of_match_ptr("VDDCORE"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .enable_reg = LOCHNAGAR2_VDDCORE_CDC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .enable_mask = LOCHNAGAR2_VDDCORE_CDC_REG_ENA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .vsel_reg = LOCHNAGAR2_VDDCORE_CDC_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .vsel_mask = LOCHNAGAR2_VDDCORE_CDC_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .linear_ranges = lochnagar_vddcore_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .n_linear_ranges = ARRAY_SIZE(lochnagar_vddcore_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .enable_time = 3000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .ramp_delay = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .off_on_delay = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static const struct of_device_id lochnagar_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .compatible = "cirrus,lochnagar2-micvdd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .data = &lochnagar_regulators[LOCHNAGAR_MICVDD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .compatible = "cirrus,lochnagar2-mic1vdd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .data = &lochnagar_regulators[LOCHNAGAR_MIC1VDD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .compatible = "cirrus,lochnagar2-mic2vdd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .data = &lochnagar_regulators[LOCHNAGAR_MIC2VDD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .compatible = "cirrus,lochnagar2-vddcore",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .data = &lochnagar_regulators[LOCHNAGAR_VDDCORE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) MODULE_DEVICE_TABLE(of, lochnagar_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int lochnagar_regulator_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct lochnagar *lochnagar = dev_get_drvdata(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) const struct regulator_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) config.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) config.regmap = lochnagar->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) config.driver_data = lochnagar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) of_id = of_match_device(lochnagar_of_match, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!of_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) desc = of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rdev = devm_regulator_register(dev, desc, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_err(dev, "Failed to register %s regulator: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) desc->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static struct platform_driver lochnagar_regulator_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .name = "lochnagar-regulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .of_match_table = of_match_ptr(lochnagar_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .probe = lochnagar_regulator_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) module_platform_driver(lochnagar_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) MODULE_DESCRIPTION("Regulator driver for Cirrus Logic Lochnagar Board");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) MODULE_ALIAS("platform:lochnagar-regulator");