1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Functions to access SY3686A power management chip temperature 4 * 5 * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/ 6 * 7 * Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com> 8 * Alistair Francis <alistair@alistair23.me> 9 */ 10 11 #include <linux/err.h> 12 #include <linux/hwmon.h> 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 #include <linux/regulator/machine.h> 18 19 #include <linux/mfd/sy7636a.h> 20 21 static int sy7636a_read(struct device *dev, enum hwmon_sensor_types type, 22 u32 attr, int channel, long *temp) 23 { 24 struct regmap *regmap = dev_get_drvdata(dev); 25 int ret, reg_val; 26 27 ret = regmap_read(regmap, 28 SY7636A_REG_TERMISTOR_READOUT, ®_val); 29 if (ret) 30 return ret; 31 32 *temp = reg_val * 1000; 33 34 return 0; 35 } 36 37 static umode_t sy7636a_is_visible(const void *data, 38 enum hwmon_sensor_types type, 39 u32 attr, int channel) 40 { 41 if (type != hwmon_temp) 42 return 0; 43 44 if (attr != hwmon_temp_input) 45 return 0; 46 47 return 0444; 48 } 49 50 static const struct hwmon_ops sy7636a_hwmon_ops = { 51 .is_visible = sy7636a_is_visible, 52 .read = sy7636a_read, 53 }; 54 55 static const struct hwmon_channel_info *sy7636a_info[] = { 56 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 57 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), 58 NULL 59 }; 60 61 static const struct hwmon_chip_info sy7636a_chip_info = { 62 .ops = &sy7636a_hwmon_ops, 63 .info = sy7636a_info, 64 }; 65 66 static int sy7636a_sensor_probe(struct platform_device *pdev) 67 { 68 struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); 69 struct regulator *regulator; 70 struct device *hwmon_dev; 71 int err; 72 73 if (!regmap) 74 return -EPROBE_DEFER; 75 76 regulator = devm_regulator_get(&pdev->dev, "vcom"); 77 if (IS_ERR(regulator)) 78 return PTR_ERR(regulator); 79 80 err = regulator_enable(regulator); 81 if (err) 82 return err; 83 84 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, 85 "sy7636a_temperature", regmap, 86 &sy7636a_chip_info, NULL); 87 88 if (IS_ERR(hwmon_dev)) { 89 err = PTR_ERR(hwmon_dev); 90 dev_err(&pdev->dev, "Unable to register hwmon device, returned %d\n", err); 91 return err; 92 } 93 94 return 0; 95 } 96 97 static struct platform_driver sy7636a_sensor_driver = { 98 .probe = sy7636a_sensor_probe, 99 .driver = { 100 .name = "sy7636a-temperature", 101 }, 102 }; 103 module_platform_driver(sy7636a_sensor_driver); 104 105 MODULE_DESCRIPTION("SY7636A sensor driver"); 106 MODULE_LICENSE("GPL"); 107