fixup over ("LiteX: driver for XADC hwmon")
[linux/fpc-iii.git] / drivers / hwmon / litex-hwmon.c
blobc73ac6223c89bf0c8cffac51b1aa040dc88e371c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2019 Antmicro <www.antmicro.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/of.h>
22 #include <linux/hwmon.h>
23 #include <linux/litex.h>
25 #define TEMP_REG_OFFSET 0x0
26 #define TEMP_REG_SIZE 2
27 #define VCCINT_REG_OFFSET 0x8
28 #define VCCINT_REG_SIZE 2
29 #define VCCAUX_REG_OFFSET 0x10
30 #define VCCAUX_REG_SIZE 2
31 #define VCCBRAM_REG_OFFSET 0x18
32 #define VCCBRAM_REG_SIZE 2
34 #define CHANNEL_TEMP 0
35 #define CHANNEL_VCCINT 0
36 #define CHANNEL_VCCAUX 1
37 #define CHANNEL_VCCBRAM 2
39 struct litex_hwmon {
40 void __iomem *membase;
41 struct device *hdev;
44 /* Transfer functions taken from XILINX UG480 (v1.10.1)
45 * www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf
48 static inline long litex_temp_transfer_fun(long val)
50 return ((val * 503975ULL) / 4096ULL) - 273150ULL;
53 static inline long litex_supp_transfer_fun(long val)
55 return ((val * 3000) / 4096);
58 static inline int litex_read_temp(struct litex_hwmon *hwmon_s, u32 attr,
59 int channel, long *val)
61 unsigned long raw_data;
63 if (attr != hwmon_temp_input)
64 return -ENOTSUPP;
66 if (channel != CHANNEL_TEMP)
67 return -EINVAL;
69 raw_data = litex_read16(hwmon_s->membase + TEMP_REG_OFFSET);
70 *val = litex_temp_transfer_fun(raw_data);
71 return 0;
74 static inline int litex_read_in(struct litex_hwmon *hwmon_s, u32 attr,
75 int channel, long *val)
77 int offset;
78 unsigned long raw_data;
80 if (attr != hwmon_in_input)
81 return -ENOTSUPP;
83 switch (channel) {
84 case CHANNEL_VCCINT:
85 offset = VCCINT_REG_OFFSET;
86 break;
87 case CHANNEL_VCCAUX:
88 offset = VCCAUX_REG_OFFSET;
89 break;
90 case CHANNEL_VCCBRAM:
91 offset = VCCBRAM_REG_OFFSET;
92 break;
93 default:
94 return -EINVAL;
97 raw_data = litex_read16(hwmon_s->membase + offset);
98 *val = litex_supp_transfer_fun(raw_data);
99 return 0;
102 /* API functions */
104 umode_t litex_hwmon_is_visible(const void *drvdata,
105 enum hwmon_sensor_types type,
106 u32 attr, int channel)
108 return 0444;
111 int litex_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
112 u32 attr, int channel, long *val)
114 struct litex_hwmon *hwmon_s = dev_get_drvdata(dev);
116 switch (type) {
117 case hwmon_temp:
118 return litex_read_temp(hwmon_s, attr, channel, val);
119 case hwmon_in:
120 return litex_read_in(hwmon_s, attr, channel, val);
121 default:
122 return -ENOTSUPP;
125 return 0;
128 static const struct hwmon_ops litex_hwmon_ops = {
129 .is_visible = litex_hwmon_is_visible,
130 .read = litex_hwmon_read,
133 /* Attribute management */
135 static const unsigned int litex_temp_config[] = {
136 HWMON_T_INPUT,
140 static const struct hwmon_channel_info litex_hwmon_temp = {
141 .type = hwmon_temp,
142 .config = litex_temp_config
145 static const unsigned int litex_vcc_config[] = {
146 HWMON_I_INPUT,
147 HWMON_I_INPUT,
148 HWMON_I_INPUT,
152 static const struct hwmon_channel_info litex_hwmon_vcc = {
153 .type = hwmon_in,
154 .config = litex_vcc_config
157 static const struct hwmon_channel_info *litex_hwmon_channel_info[] = {
158 &litex_hwmon_temp,
159 &litex_hwmon_vcc,
160 NULL
163 static const struct hwmon_chip_info litex_chip_info = {
164 .ops = &litex_hwmon_ops,
165 .info = litex_hwmon_channel_info
168 /* Driver functions */
170 static int litex_hwmon_probe(struct platform_device *pdev)
172 struct device_node *node = pdev->dev.of_node;
173 struct litex_hwmon *hwmon_s;
174 struct resource *res;
176 if (!node)
177 return -ENODEV;
179 hwmon_s = devm_kzalloc(&pdev->dev, sizeof(*hwmon_s), GFP_KERNEL);
180 if (!hwmon_s)
181 return -ENOMEM;
183 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 if (!res)
185 return -EBUSY;
187 hwmon_s->membase = devm_of_iomap(&pdev->dev, node, 0, &res->end);
188 if (IS_ERR_OR_NULL(hwmon_s->membase))
189 return -EIO;
191 hwmon_s->hdev = devm_hwmon_device_register_with_info(&pdev->dev,
192 "litex_xadc",
193 hwmon_s,
194 &litex_chip_info,
195 NULL);
196 platform_set_drvdata(pdev, hwmon_s);
197 return PTR_ERR_OR_ZERO(hwmon_s->hdev);
200 static const struct of_device_id litex_of_match[] = {
201 {.compatible = "litex,hwmon-xadc"},
205 MODULE_DEVICE_TABLE(of, litex_of_match);
207 static struct platform_driver litex_hwmon_driver = {
208 .driver = {
209 .name = "litex-hwmon",
210 .of_match_table = of_match_ptr(litex_of_match)
212 .probe = litex_hwmon_probe,
215 module_platform_driver(litex_hwmon_driver);