1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2022 Richtek Technology Corp. 4 * 5 * Author: ChiaEn Wu <chiaen_wu@richtek.com> 6 */ 7 8 #include <linux/bits.h> 9 #include <linux/bitfield.h> 10 #include <linux/iio/iio.h> 11 #include <linux/kernel.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/mutex.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 #include <linux/sysfs.h> 18 #include <linux/units.h> 19 20 #include <dt-bindings/iio/adc/mediatek,mt6370_adc.h> 21 22 #define MT6370_REG_CHG_CTRL3 0x113 23 #define MT6370_REG_CHG_CTRL7 0x117 24 #define MT6370_REG_CHG_ADC 0x121 25 #define MT6370_REG_ADC_DATA_H 0x14C 26 27 #define MT6370_ADC_START_MASK BIT(0) 28 #define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4) 29 #define MT6370_AICR_ICHG_MASK GENMASK(7, 2) 30 31 #define MT6370_AICR_100_mA 0x0 32 #define MT6370_AICR_150_mA 0x1 33 #define MT6370_AICR_200_mA 0x2 34 #define MT6370_AICR_250_mA 0x3 35 #define MT6370_AICR_300_mA 0x4 36 #define MT6370_AICR_350_mA 0x5 37 38 #define MT6370_ICHG_100_mA 0x0 39 #define MT6370_ICHG_200_mA 0x1 40 #define MT6370_ICHG_300_mA 0x2 41 #define MT6370_ICHG_400_mA 0x3 42 #define MT6370_ICHG_500_mA 0x4 43 #define MT6370_ICHG_600_mA 0x5 44 #define MT6370_ICHG_700_mA 0x6 45 #define MT6370_ICHG_800_mA 0x7 46 47 #define ADC_CONV_TIME_MS 35 48 #define ADC_CONV_POLLING_TIME_US 1000 49 50 struct mt6370_adc_data { 51 struct device *dev; 52 struct regmap *regmap; 53 /* 54 * This mutex lock is for preventing the different ADC channels 55 * from being read at the same time. 56 */ 57 struct mutex adc_lock; 58 }; 59 60 static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan, 61 unsigned long addr, int *val) 62 { 63 unsigned int reg_val; 64 __be16 be_val; 65 int ret; 66 67 mutex_lock(&priv->adc_lock); 68 69 reg_val = MT6370_ADC_START_MASK | 70 FIELD_PREP(MT6370_ADC_IN_SEL_MASK, addr); 71 ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, reg_val); 72 if (ret) 73 goto adc_unlock; 74 75 msleep(ADC_CONV_TIME_MS); 76 77 ret = regmap_read_poll_timeout(priv->regmap, 78 MT6370_REG_CHG_ADC, reg_val, 79 !(reg_val & MT6370_ADC_START_MASK), 80 ADC_CONV_POLLING_TIME_US, 81 ADC_CONV_TIME_MS * MILLI * 3); 82 if (ret) { 83 dev_err(priv->dev, "Failed to read ADC register (%d)\n", ret); 84 goto adc_unlock; 85 } 86 87 ret = regmap_raw_read(priv->regmap, MT6370_REG_ADC_DATA_H, 88 &be_val, sizeof(be_val)); 89 if (ret) 90 goto adc_unlock; 91 92 *val = be16_to_cpu(be_val); 93 ret = IIO_VAL_INT; 94 95 adc_unlock: 96 mutex_unlock(&priv->adc_lock); 97 98 return ret; 99 } 100 101 static int mt6370_adc_read_scale(struct mt6370_adc_data *priv, 102 int chan, int *val1, int *val2) 103 { 104 unsigned int reg_val; 105 int ret; 106 107 switch (chan) { 108 case MT6370_CHAN_VBAT: 109 case MT6370_CHAN_VSYS: 110 case MT6370_CHAN_CHG_VDDP: 111 *val1 = 5; 112 return IIO_VAL_INT; 113 case MT6370_CHAN_IBUS: 114 ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL3, ®_val); 115 if (ret) 116 return ret; 117 118 reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); 119 switch (reg_val) { 120 case MT6370_AICR_100_mA: 121 case MT6370_AICR_150_mA: 122 case MT6370_AICR_200_mA: 123 case MT6370_AICR_250_mA: 124 case MT6370_AICR_300_mA: 125 case MT6370_AICR_350_mA: 126 *val1 = 3350; 127 break; 128 default: 129 *val1 = 5000; 130 break; 131 } 132 133 *val2 = 100; 134 135 return IIO_VAL_FRACTIONAL; 136 case MT6370_CHAN_IBAT: 137 ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL7, ®_val); 138 if (ret) 139 return ret; 140 141 reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); 142 switch (reg_val) { 143 case MT6370_ICHG_100_mA: 144 case MT6370_ICHG_200_mA: 145 case MT6370_ICHG_300_mA: 146 case MT6370_ICHG_400_mA: 147 *val1 = 2375; 148 break; 149 case MT6370_ICHG_500_mA: 150 case MT6370_ICHG_600_mA: 151 case MT6370_ICHG_700_mA: 152 case MT6370_ICHG_800_mA: 153 *val1 = 2680; 154 break; 155 default: 156 *val1 = 5000; 157 break; 158 } 159 160 *val2 = 100; 161 162 return IIO_VAL_FRACTIONAL; 163 case MT6370_CHAN_VBUSDIV5: 164 *val1 = 25; 165 return IIO_VAL_INT; 166 case MT6370_CHAN_VBUSDIV2: 167 *val1 = 10; 168 return IIO_VAL_INT; 169 case MT6370_CHAN_TS_BAT: 170 *val1 = 25; 171 *val2 = 10000; 172 return IIO_VAL_FRACTIONAL; 173 case MT6370_CHAN_TEMP_JC: 174 *val1 = 2000; 175 return IIO_VAL_INT; 176 default: 177 return -EINVAL; 178 } 179 } 180 181 static int mt6370_adc_read_offset(struct mt6370_adc_data *priv, 182 int chan, int *val) 183 { 184 *val = -20; 185 186 return IIO_VAL_INT; 187 } 188 189 static int mt6370_adc_read_raw(struct iio_dev *iio_dev, 190 const struct iio_chan_spec *chan, 191 int *val, int *val2, long mask) 192 { 193 struct mt6370_adc_data *priv = iio_priv(iio_dev); 194 195 switch (mask) { 196 case IIO_CHAN_INFO_RAW: 197 return mt6370_adc_read_channel(priv, chan->channel, 198 chan->address, val); 199 case IIO_CHAN_INFO_SCALE: 200 return mt6370_adc_read_scale(priv, chan->channel, val, val2); 201 case IIO_CHAN_INFO_OFFSET: 202 return mt6370_adc_read_offset(priv, chan->channel, val); 203 default: 204 return -EINVAL; 205 } 206 } 207 208 static const char * const mt6370_channel_labels[MT6370_CHAN_MAX] = { 209 [MT6370_CHAN_VBUSDIV5] = "vbusdiv5", 210 [MT6370_CHAN_VBUSDIV2] = "vbusdiv2", 211 [MT6370_CHAN_VSYS] = "vsys", 212 [MT6370_CHAN_VBAT] = "vbat", 213 [MT6370_CHAN_TS_BAT] = "ts_bat", 214 [MT6370_CHAN_IBUS] = "ibus", 215 [MT6370_CHAN_IBAT] = "ibat", 216 [MT6370_CHAN_CHG_VDDP] = "chg_vddp", 217 [MT6370_CHAN_TEMP_JC] = "temp_jc", 218 }; 219 220 static int mt6370_adc_read_label(struct iio_dev *iio_dev, 221 struct iio_chan_spec const *chan, char *label) 222 { 223 return sysfs_emit(label, "%s\n", mt6370_channel_labels[chan->channel]); 224 } 225 226 static const struct iio_info mt6370_adc_iio_info = { 227 .read_raw = mt6370_adc_read_raw, 228 .read_label = mt6370_adc_read_label, 229 }; 230 231 #define MT6370_ADC_CHAN(_idx, _type, _addr, _extra_info) { \ 232 .type = _type, \ 233 .channel = MT6370_CHAN_##_idx, \ 234 .address = _addr, \ 235 .scan_index = MT6370_CHAN_##_idx, \ 236 .indexed = 1, \ 237 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 238 BIT(IIO_CHAN_INFO_SCALE) | \ 239 _extra_info, \ 240 } 241 242 static const struct iio_chan_spec mt6370_adc_channels[] = { 243 MT6370_ADC_CHAN(VBUSDIV5, IIO_VOLTAGE, 1, 0), 244 MT6370_ADC_CHAN(VBUSDIV2, IIO_VOLTAGE, 2, 0), 245 MT6370_ADC_CHAN(VSYS, IIO_VOLTAGE, 3, 0), 246 MT6370_ADC_CHAN(VBAT, IIO_VOLTAGE, 4, 0), 247 MT6370_ADC_CHAN(TS_BAT, IIO_VOLTAGE, 6, 0), 248 MT6370_ADC_CHAN(IBUS, IIO_CURRENT, 8, 0), 249 MT6370_ADC_CHAN(IBAT, IIO_CURRENT, 9, 0), 250 MT6370_ADC_CHAN(CHG_VDDP, IIO_VOLTAGE, 11, 0), 251 MT6370_ADC_CHAN(TEMP_JC, IIO_TEMP, 12, BIT(IIO_CHAN_INFO_OFFSET)), 252 }; 253 254 static int mt6370_adc_probe(struct platform_device *pdev) 255 { 256 struct device *dev = &pdev->dev; 257 struct mt6370_adc_data *priv; 258 struct iio_dev *indio_dev; 259 struct regmap *regmap; 260 int ret; 261 262 regmap = dev_get_regmap(pdev->dev.parent, NULL); 263 if (!regmap) 264 return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n"); 265 266 indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); 267 if (!indio_dev) 268 return -ENOMEM; 269 270 priv = iio_priv(indio_dev); 271 priv->dev = dev; 272 priv->regmap = regmap; 273 mutex_init(&priv->adc_lock); 274 275 ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, 0); 276 if (ret) 277 return dev_err_probe(dev, ret, "Failed to reset ADC\n"); 278 279 indio_dev->name = "mt6370-adc"; 280 indio_dev->info = &mt6370_adc_iio_info; 281 indio_dev->modes = INDIO_DIRECT_MODE; 282 indio_dev->channels = mt6370_adc_channels; 283 indio_dev->num_channels = ARRAY_SIZE(mt6370_adc_channels); 284 285 return devm_iio_device_register(dev, indio_dev); 286 } 287 288 static const struct of_device_id mt6370_adc_of_id[] = { 289 { .compatible = "mediatek,mt6370-adc", }, 290 {} 291 }; 292 MODULE_DEVICE_TABLE(of, mt6370_adc_of_id); 293 294 static struct platform_driver mt6370_adc_driver = { 295 .driver = { 296 .name = "mt6370-adc", 297 .of_match_table = mt6370_adc_of_id, 298 }, 299 .probe = mt6370_adc_probe, 300 }; 301 module_platform_driver(mt6370_adc_driver); 302 303 MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>"); 304 MODULE_DESCRIPTION("MT6370 ADC Driver"); 305 MODULE_LICENSE("GPL v2"); 306