0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/err.h>
0011 #include <linux/hwmon.h>
0012 #include <linux/hwmon-sysfs.h>
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/slab.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/property.h>
0019
0020 #include <linux/mfd/da9052/da9052.h>
0021 #include <linux/mfd/da9052/reg.h>
0022 #include <linux/regulator/consumer.h>
0023
0024 struct da9052_hwmon {
0025 struct da9052 *da9052;
0026 struct mutex hwmon_lock;
0027 bool tsi_as_adc;
0028 int tsiref_mv;
0029 struct regulator *tsiref;
0030 struct completion tsidone;
0031 };
0032
0033 static const char * const input_names[] = {
0034 [DA9052_ADC_VDDOUT] = "VDDOUT",
0035 [DA9052_ADC_ICH] = "CHARGING CURRENT",
0036 [DA9052_ADC_TBAT] = "BATTERY TEMP",
0037 [DA9052_ADC_VBAT] = "BATTERY VOLTAGE",
0038 [DA9052_ADC_IN4] = "ADC IN4",
0039 [DA9052_ADC_IN5] = "ADC IN5",
0040 [DA9052_ADC_IN6] = "ADC IN6",
0041 [DA9052_ADC_TSI_XP] = "ADC TS X+",
0042 [DA9052_ADC_TSI_YP] = "ADC TS Y+",
0043 [DA9052_ADC_TSI_XN] = "ADC TS X-",
0044 [DA9052_ADC_TSI_YN] = "ADC TS Y-",
0045 [DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP",
0046 [DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE",
0047 };
0048
0049
0050 static inline int volt_reg_to_mv(int value)
0051 {
0052 return DIV_ROUND_CLOSEST(value * 2000, 1023) + 2500;
0053 }
0054
0055
0056 static inline int input_reg_to_mv(int value)
0057 {
0058 return DIV_ROUND_CLOSEST(value * 2500, 1023);
0059 }
0060
0061
0062 static inline int vbbat_reg_to_mv(int value)
0063 {
0064 return DIV_ROUND_CLOSEST(value * 5000, 1023);
0065 }
0066
0067 static inline int input_tsireg_to_mv(struct da9052_hwmon *hwmon, int value)
0068 {
0069 return DIV_ROUND_CLOSEST(value * hwmon->tsiref_mv, 1023);
0070 }
0071
0072 static inline int da9052_enable_vddout_channel(struct da9052 *da9052)
0073 {
0074 return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
0075 DA9052_ADCCONT_AUTOVDDEN,
0076 DA9052_ADCCONT_AUTOVDDEN);
0077 }
0078
0079 static inline int da9052_disable_vddout_channel(struct da9052 *da9052)
0080 {
0081 return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
0082 DA9052_ADCCONT_AUTOVDDEN, 0);
0083 }
0084
0085 static ssize_t da9052_vddout_show(struct device *dev,
0086 struct device_attribute *devattr, char *buf)
0087 {
0088 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0089 int ret, vdd;
0090
0091 mutex_lock(&hwmon->hwmon_lock);
0092
0093 ret = da9052_enable_vddout_channel(hwmon->da9052);
0094 if (ret < 0)
0095 goto hwmon_err;
0096
0097 vdd = da9052_reg_read(hwmon->da9052, DA9052_VDD_RES_REG);
0098 if (vdd < 0) {
0099 ret = vdd;
0100 goto hwmon_err_release;
0101 }
0102
0103 ret = da9052_disable_vddout_channel(hwmon->da9052);
0104 if (ret < 0)
0105 goto hwmon_err;
0106
0107 mutex_unlock(&hwmon->hwmon_lock);
0108 return sprintf(buf, "%d\n", volt_reg_to_mv(vdd));
0109
0110 hwmon_err_release:
0111 da9052_disable_vddout_channel(hwmon->da9052);
0112 hwmon_err:
0113 mutex_unlock(&hwmon->hwmon_lock);
0114 return ret;
0115 }
0116
0117 static ssize_t da9052_ich_show(struct device *dev,
0118 struct device_attribute *devattr, char *buf)
0119 {
0120 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0121 int ret;
0122
0123 ret = da9052_reg_read(hwmon->da9052, DA9052_ICHG_AV_REG);
0124 if (ret < 0)
0125 return ret;
0126
0127
0128 return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(ret * 39, 10));
0129 }
0130
0131 static ssize_t da9052_tbat_show(struct device *dev,
0132 struct device_attribute *devattr, char *buf)
0133 {
0134 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0135
0136 return sprintf(buf, "%d\n", da9052_adc_read_temp(hwmon->da9052));
0137 }
0138
0139 static ssize_t da9052_vbat_show(struct device *dev,
0140 struct device_attribute *devattr, char *buf)
0141 {
0142 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0143 int ret;
0144
0145 ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBAT);
0146 if (ret < 0)
0147 return ret;
0148
0149 return sprintf(buf, "%d\n", volt_reg_to_mv(ret));
0150 }
0151
0152 static ssize_t da9052_misc_channel_show(struct device *dev,
0153 struct device_attribute *devattr,
0154 char *buf)
0155 {
0156 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0157 int channel = to_sensor_dev_attr(devattr)->index;
0158 int ret;
0159
0160 ret = da9052_adc_manual_read(hwmon->da9052, channel);
0161 if (ret < 0)
0162 return ret;
0163
0164 return sprintf(buf, "%d\n", input_reg_to_mv(ret));
0165 }
0166
0167 static int da9052_request_tsi_read(struct da9052_hwmon *hwmon, int channel)
0168 {
0169 u8 val = DA9052_TSICONTB_TSIMAN;
0170
0171 switch (channel) {
0172 case DA9052_ADC_TSI_XP:
0173 val |= DA9052_TSICONTB_TSIMUX_XP;
0174 break;
0175 case DA9052_ADC_TSI_YP:
0176 val |= DA9052_TSICONTB_TSIMUX_YP;
0177 break;
0178 case DA9052_ADC_TSI_XN:
0179 val |= DA9052_TSICONTB_TSIMUX_XN;
0180 break;
0181 case DA9052_ADC_TSI_YN:
0182 val |= DA9052_TSICONTB_TSIMUX_YN;
0183 break;
0184 }
0185
0186 return da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_B_REG, val);
0187 }
0188
0189 static int da9052_get_tsi_result(struct da9052_hwmon *hwmon, int channel)
0190 {
0191 u8 regs[3];
0192 int msb, lsb, err;
0193
0194
0195 err = da9052_group_read(hwmon->da9052, DA9052_TSI_X_MSB_REG,
0196 ARRAY_SIZE(regs), regs);
0197 if (err)
0198 return err;
0199
0200 switch (channel) {
0201 case DA9052_ADC_TSI_XP:
0202 case DA9052_ADC_TSI_XN:
0203 msb = regs[0] << DA9052_TSILSB_TSIXL_BITS;
0204 lsb = regs[2] & DA9052_TSILSB_TSIXL;
0205 lsb >>= DA9052_TSILSB_TSIXL_SHIFT;
0206 break;
0207 case DA9052_ADC_TSI_YP:
0208 case DA9052_ADC_TSI_YN:
0209 msb = regs[1] << DA9052_TSILSB_TSIYL_BITS;
0210 lsb = regs[2] & DA9052_TSILSB_TSIYL;
0211 lsb >>= DA9052_TSILSB_TSIYL_SHIFT;
0212 break;
0213 default:
0214 return -EINVAL;
0215 }
0216
0217 return msb | lsb;
0218 }
0219
0220
0221 static ssize_t __da9052_read_tsi(struct device *dev, int channel)
0222 {
0223 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0224 int ret;
0225
0226 reinit_completion(&hwmon->tsidone);
0227
0228 ret = da9052_request_tsi_read(hwmon, channel);
0229 if (ret < 0)
0230 return ret;
0231
0232
0233 if (!wait_for_completion_timeout(&hwmon->tsidone,
0234 msecs_to_jiffies(500)))
0235 return -ETIMEDOUT;
0236
0237 return da9052_get_tsi_result(hwmon, channel);
0238 }
0239
0240 static ssize_t da9052_tsi_show(struct device *dev,
0241 struct device_attribute *devattr, char *buf)
0242 {
0243 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0244 int channel = to_sensor_dev_attr(devattr)->index;
0245 int ret;
0246
0247 mutex_lock(&hwmon->da9052->auxadc_lock);
0248 ret = __da9052_read_tsi(dev, channel);
0249 mutex_unlock(&hwmon->da9052->auxadc_lock);
0250
0251 if (ret < 0)
0252 return ret;
0253 else
0254 return sprintf(buf, "%d\n", input_tsireg_to_mv(hwmon, ret));
0255 }
0256
0257 static ssize_t da9052_tjunc_show(struct device *dev,
0258 struct device_attribute *devattr, char *buf)
0259 {
0260 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0261 int tjunc;
0262 int toffset;
0263
0264 tjunc = da9052_reg_read(hwmon->da9052, DA9052_TJUNC_RES_REG);
0265 if (tjunc < 0)
0266 return tjunc;
0267
0268 toffset = da9052_reg_read(hwmon->da9052, DA9052_T_OFFSET_REG);
0269 if (toffset < 0)
0270 return toffset;
0271
0272
0273
0274
0275
0276 return sprintf(buf, "%d\n", 1708 * (tjunc - toffset) - 108800);
0277 }
0278
0279 static ssize_t da9052_vbbat_show(struct device *dev,
0280 struct device_attribute *devattr, char *buf)
0281 {
0282 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0283 int ret;
0284
0285 ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBBAT);
0286 if (ret < 0)
0287 return ret;
0288
0289 return sprintf(buf, "%d\n", vbbat_reg_to_mv(ret));
0290 }
0291
0292 static ssize_t label_show(struct device *dev,
0293 struct device_attribute *devattr, char *buf)
0294 {
0295 return sprintf(buf, "%s\n",
0296 input_names[to_sensor_dev_attr(devattr)->index]);
0297 }
0298
0299 static umode_t da9052_channel_is_visible(struct kobject *kobj,
0300 struct attribute *attr, int index)
0301 {
0302 struct device *dev = kobj_to_dev(kobj);
0303 struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
0304 struct device_attribute *dattr = container_of(attr,
0305 struct device_attribute, attr);
0306 struct sensor_device_attribute *sattr = to_sensor_dev_attr(dattr);
0307
0308 if (!hwmon->tsi_as_adc) {
0309 switch (sattr->index) {
0310 case DA9052_ADC_TSI_XP:
0311 case DA9052_ADC_TSI_YP:
0312 case DA9052_ADC_TSI_XN:
0313 case DA9052_ADC_TSI_YN:
0314 return 0;
0315 }
0316 }
0317
0318 return attr->mode;
0319 }
0320
0321 static SENSOR_DEVICE_ATTR_RO(in0_input, da9052_vddout, DA9052_ADC_VDDOUT);
0322 static SENSOR_DEVICE_ATTR_RO(in0_label, label, DA9052_ADC_VDDOUT);
0323 static SENSOR_DEVICE_ATTR_RO(in3_input, da9052_vbat, DA9052_ADC_VBAT);
0324 static SENSOR_DEVICE_ATTR_RO(in3_label, label, DA9052_ADC_VBAT);
0325 static SENSOR_DEVICE_ATTR_RO(in4_input, da9052_misc_channel, DA9052_ADC_IN4);
0326 static SENSOR_DEVICE_ATTR_RO(in4_label, label, DA9052_ADC_IN4);
0327 static SENSOR_DEVICE_ATTR_RO(in5_input, da9052_misc_channel, DA9052_ADC_IN5);
0328 static SENSOR_DEVICE_ATTR_RO(in5_label, label, DA9052_ADC_IN5);
0329 static SENSOR_DEVICE_ATTR_RO(in6_input, da9052_misc_channel, DA9052_ADC_IN6);
0330 static SENSOR_DEVICE_ATTR_RO(in6_label, label, DA9052_ADC_IN6);
0331 static SENSOR_DEVICE_ATTR_RO(in9_input, da9052_vbbat, DA9052_ADC_VBBAT);
0332 static SENSOR_DEVICE_ATTR_RO(in9_label, label, DA9052_ADC_VBBAT);
0333
0334 static SENSOR_DEVICE_ATTR_RO(in70_input, da9052_tsi, DA9052_ADC_TSI_XP);
0335 static SENSOR_DEVICE_ATTR_RO(in70_label, label, DA9052_ADC_TSI_XP);
0336 static SENSOR_DEVICE_ATTR_RO(in71_input, da9052_tsi, DA9052_ADC_TSI_XN);
0337 static SENSOR_DEVICE_ATTR_RO(in71_label, label, DA9052_ADC_TSI_XN);
0338 static SENSOR_DEVICE_ATTR_RO(in72_input, da9052_tsi, DA9052_ADC_TSI_YP);
0339 static SENSOR_DEVICE_ATTR_RO(in72_label, label, DA9052_ADC_TSI_YP);
0340 static SENSOR_DEVICE_ATTR_RO(in73_input, da9052_tsi, DA9052_ADC_TSI_YN);
0341 static SENSOR_DEVICE_ATTR_RO(in73_label, label, DA9052_ADC_TSI_YN);
0342
0343 static SENSOR_DEVICE_ATTR_RO(curr1_input, da9052_ich, DA9052_ADC_ICH);
0344 static SENSOR_DEVICE_ATTR_RO(curr1_label, label, DA9052_ADC_ICH);
0345
0346 static SENSOR_DEVICE_ATTR_RO(temp2_input, da9052_tbat, DA9052_ADC_TBAT);
0347 static SENSOR_DEVICE_ATTR_RO(temp2_label, label, DA9052_ADC_TBAT);
0348 static SENSOR_DEVICE_ATTR_RO(temp8_input, da9052_tjunc, DA9052_ADC_TJUNC);
0349 static SENSOR_DEVICE_ATTR_RO(temp8_label, label, DA9052_ADC_TJUNC);
0350
0351 static struct attribute *da9052_attrs[] = {
0352 &sensor_dev_attr_in0_input.dev_attr.attr,
0353 &sensor_dev_attr_in0_label.dev_attr.attr,
0354 &sensor_dev_attr_in3_input.dev_attr.attr,
0355 &sensor_dev_attr_in3_label.dev_attr.attr,
0356 &sensor_dev_attr_in4_input.dev_attr.attr,
0357 &sensor_dev_attr_in4_label.dev_attr.attr,
0358 &sensor_dev_attr_in5_input.dev_attr.attr,
0359 &sensor_dev_attr_in5_label.dev_attr.attr,
0360 &sensor_dev_attr_in6_input.dev_attr.attr,
0361 &sensor_dev_attr_in6_label.dev_attr.attr,
0362 &sensor_dev_attr_in70_input.dev_attr.attr,
0363 &sensor_dev_attr_in70_label.dev_attr.attr,
0364 &sensor_dev_attr_in71_input.dev_attr.attr,
0365 &sensor_dev_attr_in71_label.dev_attr.attr,
0366 &sensor_dev_attr_in72_input.dev_attr.attr,
0367 &sensor_dev_attr_in72_label.dev_attr.attr,
0368 &sensor_dev_attr_in73_input.dev_attr.attr,
0369 &sensor_dev_attr_in73_label.dev_attr.attr,
0370 &sensor_dev_attr_in9_input.dev_attr.attr,
0371 &sensor_dev_attr_in9_label.dev_attr.attr,
0372 &sensor_dev_attr_curr1_input.dev_attr.attr,
0373 &sensor_dev_attr_curr1_label.dev_attr.attr,
0374 &sensor_dev_attr_temp2_input.dev_attr.attr,
0375 &sensor_dev_attr_temp2_label.dev_attr.attr,
0376 &sensor_dev_attr_temp8_input.dev_attr.attr,
0377 &sensor_dev_attr_temp8_label.dev_attr.attr,
0378 NULL
0379 };
0380
0381 static const struct attribute_group da9052_group = {
0382 .attrs = da9052_attrs,
0383 .is_visible = da9052_channel_is_visible,
0384 };
0385 __ATTRIBUTE_GROUPS(da9052);
0386
0387 static irqreturn_t da9052_tsi_datardy_irq(int irq, void *data)
0388 {
0389 struct da9052_hwmon *hwmon = data;
0390
0391 complete(&hwmon->tsidone);
0392 return IRQ_HANDLED;
0393 }
0394
0395 static int da9052_hwmon_probe(struct platform_device *pdev)
0396 {
0397 struct device *dev = &pdev->dev;
0398 struct da9052_hwmon *hwmon;
0399 struct device *hwmon_dev;
0400 int err;
0401
0402 hwmon = devm_kzalloc(dev, sizeof(struct da9052_hwmon), GFP_KERNEL);
0403 if (!hwmon)
0404 return -ENOMEM;
0405
0406 platform_set_drvdata(pdev, hwmon);
0407
0408 mutex_init(&hwmon->hwmon_lock);
0409 hwmon->da9052 = dev_get_drvdata(pdev->dev.parent);
0410
0411 init_completion(&hwmon->tsidone);
0412
0413 hwmon->tsi_as_adc =
0414 device_property_read_bool(pdev->dev.parent, "dlg,tsi-as-adc");
0415
0416 if (hwmon->tsi_as_adc) {
0417 hwmon->tsiref = devm_regulator_get(pdev->dev.parent, "tsiref");
0418 if (IS_ERR(hwmon->tsiref)) {
0419 err = PTR_ERR(hwmon->tsiref);
0420 dev_err(&pdev->dev, "failed to get tsiref: %d", err);
0421 return err;
0422 }
0423
0424 err = regulator_enable(hwmon->tsiref);
0425 if (err)
0426 return err;
0427
0428 hwmon->tsiref_mv = regulator_get_voltage(hwmon->tsiref);
0429 if (hwmon->tsiref_mv < 0) {
0430 err = hwmon->tsiref_mv;
0431 goto exit_regulator;
0432 }
0433
0434
0435 hwmon->tsiref_mv /= 1000;
0436
0437
0438 if (hwmon->tsiref_mv < 1800 || hwmon->tsiref_mv > 2600) {
0439 dev_err(hwmon->da9052->dev, "invalid TSIREF voltage: %d",
0440 hwmon->tsiref_mv);
0441 err = -ENXIO;
0442 goto exit_regulator;
0443 }
0444
0445
0446 da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00);
0447
0448
0449 da9052_reg_update(hwmon->da9052, DA9052_ADC_CONT_REG,
0450 DA9052_ADCCONT_ADCMODE,
0451 DA9052_ADCCONT_ADCMODE);
0452
0453 err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY,
0454 "tsiready-irq", da9052_tsi_datardy_irq,
0455 hwmon);
0456 if (err) {
0457 dev_err(&pdev->dev, "Failed to register TSIRDY IRQ: %d",
0458 err);
0459 goto exit_regulator;
0460 }
0461 }
0462
0463 hwmon_dev = devm_hwmon_device_register_with_groups(dev, "da9052",
0464 hwmon,
0465 da9052_groups);
0466 err = PTR_ERR_OR_ZERO(hwmon_dev);
0467 if (err)
0468 goto exit_irq;
0469
0470 return 0;
0471
0472 exit_irq:
0473 if (hwmon->tsi_as_adc)
0474 da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon);
0475 exit_regulator:
0476 if (hwmon->tsiref)
0477 regulator_disable(hwmon->tsiref);
0478
0479 return err;
0480 }
0481
0482 static int da9052_hwmon_remove(struct platform_device *pdev)
0483 {
0484 struct da9052_hwmon *hwmon = platform_get_drvdata(pdev);
0485
0486 if (hwmon->tsi_as_adc) {
0487 da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon);
0488 regulator_disable(hwmon->tsiref);
0489 }
0490
0491 return 0;
0492 }
0493
0494 static struct platform_driver da9052_hwmon_driver = {
0495 .probe = da9052_hwmon_probe,
0496 .remove = da9052_hwmon_remove,
0497 .driver = {
0498 .name = "da9052-hwmon",
0499 },
0500 };
0501
0502 module_platform_driver(da9052_hwmon_driver);
0503
0504 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
0505 MODULE_DESCRIPTION("DA9052 HWMON driver");
0506 MODULE_LICENSE("GPL");
0507 MODULE_ALIAS("platform:da9052-hwmon");