brintos

brintos / linux-shallow public Read only

0
0
Text · 2.9 KiB · 316454b Raw
137 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Synaptics AS370 SoC Hardware Monitoring Driver4 *5 * Copyright (C) 2018 Synaptics Incorporated6 * Author: Jisheng Zhang <jszhang@kernel.org>7 */8 9#include <linux/bitops.h>10#include <linux/hwmon.h>11#include <linux/init.h>12#include <linux/io.h>13#include <linux/module.h>14#include <linux/mod_devicetable.h>15#include <linux/platform_device.h>16 17#define CTRL		0x018#define  PD		BIT(0)19#define  EN		BIT(1)20#define  T_SEL		BIT(2)21#define  V_SEL		BIT(3)22#define  NMOS_SEL	BIT(8)23#define  PMOS_SEL	BIT(9)24#define STS		0x425#define  BN_MASK	GENMASK(11, 0)26#define  EOC		BIT(12)27 28struct as370_hwmon {29	void __iomem *base;30};31 32static void init_pvt(struct as370_hwmon *hwmon)33{34	u32 val;35	void __iomem *addr = hwmon->base + CTRL;36 37	val = PD;38	writel_relaxed(val, addr);39	val |= T_SEL;40	writel_relaxed(val, addr);41	val |= EN;42	writel_relaxed(val, addr);43	val &= ~PD;44	writel_relaxed(val, addr);45}46 47static int as370_hwmon_read(struct device *dev, enum hwmon_sensor_types type,48			    u32 attr, int channel, long *temp)49{50	int val;51	struct as370_hwmon *hwmon = dev_get_drvdata(dev);52 53	switch (attr) {54	case hwmon_temp_input:55		val = readl_relaxed(hwmon->base + STS) & BN_MASK;56		*temp = DIV_ROUND_CLOSEST(val * 251802, 4096) - 85525;57		break;58	default:59		return -EOPNOTSUPP;60	}61 62	return 0;63}64 65static umode_t66as370_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,67		       u32 attr, int channel)68{69	if (type != hwmon_temp)70		return 0;71 72	switch (attr) {73	case hwmon_temp_input:74		return 0444;75	default:76		return 0;77	}78}79 80static const struct hwmon_channel_info * const as370_hwmon_info[] = {81	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),82	NULL83};84 85static const struct hwmon_ops as370_hwmon_ops = {86	.is_visible = as370_hwmon_is_visible,87	.read = as370_hwmon_read,88};89 90static const struct hwmon_chip_info as370_chip_info = {91	.ops = &as370_hwmon_ops,92	.info = as370_hwmon_info,93};94 95static int as370_hwmon_probe(struct platform_device *pdev)96{97	struct device *hwmon_dev;98	struct as370_hwmon *hwmon;99	struct device *dev = &pdev->dev;100 101	hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);102	if (!hwmon)103		return -ENOMEM;104 105	hwmon->base = devm_platform_ioremap_resource(pdev, 0);106	if (IS_ERR(hwmon->base))107		return PTR_ERR(hwmon->base);108 109	init_pvt(hwmon);110 111	hwmon_dev = devm_hwmon_device_register_with_info(dev,112							 "as370",113							 hwmon,114							 &as370_chip_info,115							 NULL);116	return PTR_ERR_OR_ZERO(hwmon_dev);117}118 119static const struct of_device_id as370_hwmon_match[] = {120	{ .compatible = "syna,as370-hwmon" },121	{},122};123MODULE_DEVICE_TABLE(of, as370_hwmon_match);124 125static struct platform_driver as370_hwmon_driver = {126	.probe = as370_hwmon_probe,127	.driver = {128		.name = "as370-hwmon",129		.of_match_table = as370_hwmon_match,130	},131};132module_platform_driver(as370_hwmon_driver);133 134MODULE_AUTHOR("Jisheng Zhang<jszhang@kernel.org>");135MODULE_DESCRIPTION("Synaptics AS370 SoC hardware monitor");136MODULE_LICENSE("GPL v2");137