.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* Hwmon client for industrial I/O devices |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (c) 2011 Jonathan Cameron |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
7 | | - * the Free Software Foundation. |
---|
8 | 5 | */ |
---|
9 | 6 | |
---|
10 | 7 | #include <linux/kernel.h> |
---|
.. | .. |
---|
47 | 44 | int ret; |
---|
48 | 45 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); |
---|
49 | 46 | struct iio_hwmon_state *state = dev_get_drvdata(dev); |
---|
| 47 | + struct iio_channel *chan = &state->channels[sattr->index]; |
---|
| 48 | + enum iio_chan_type type; |
---|
50 | 49 | |
---|
51 | | - ret = iio_read_channel_processed(&state->channels[sattr->index], |
---|
52 | | - &result); |
---|
| 50 | + ret = iio_read_channel_processed(chan, &result); |
---|
53 | 51 | if (ret < 0) |
---|
54 | 52 | return ret; |
---|
| 53 | + |
---|
| 54 | + ret = iio_get_channel_type(chan, &type); |
---|
| 55 | + if (ret < 0) |
---|
| 56 | + return ret; |
---|
| 57 | + |
---|
| 58 | + if (type == IIO_POWER) |
---|
| 59 | + result *= 1000; /* mili-Watts to micro-Watts conversion */ |
---|
55 | 60 | |
---|
56 | 61 | return sprintf(buf, "%d\n", result); |
---|
57 | 62 | } |
---|
.. | .. |
---|
62 | 67 | struct iio_hwmon_state *st; |
---|
63 | 68 | struct sensor_device_attribute *a; |
---|
64 | 69 | int ret, i; |
---|
65 | | - int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1; |
---|
| 70 | + int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1, power_i = 1; |
---|
66 | 71 | enum iio_chan_type type; |
---|
67 | 72 | struct iio_channel *channels; |
---|
68 | | - const char *name = "iio_hwmon"; |
---|
69 | 73 | struct device *hwmon_dev; |
---|
70 | 74 | char *sname; |
---|
71 | | - |
---|
72 | | - if (dev->of_node && dev->of_node->name) |
---|
73 | | - name = dev->of_node->name; |
---|
74 | 75 | |
---|
75 | 76 | channels = devm_iio_channel_get_all(dev); |
---|
76 | 77 | if (IS_ERR(channels)) { |
---|
.. | .. |
---|
96 | 97 | return -ENOMEM; |
---|
97 | 98 | |
---|
98 | 99 | for (i = 0; i < st->num_channels; i++) { |
---|
| 100 | + const char *prefix; |
---|
| 101 | + int n; |
---|
| 102 | + |
---|
99 | 103 | a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL); |
---|
100 | 104 | if (a == NULL) |
---|
101 | 105 | return -ENOMEM; |
---|
.. | .. |
---|
107 | 111 | |
---|
108 | 112 | switch (type) { |
---|
109 | 113 | case IIO_VOLTAGE: |
---|
110 | | - a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, |
---|
111 | | - "in%d_input", |
---|
112 | | - in_i++); |
---|
| 114 | + n = in_i++; |
---|
| 115 | + prefix = "in"; |
---|
113 | 116 | break; |
---|
114 | 117 | case IIO_TEMP: |
---|
115 | | - a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, |
---|
116 | | - "temp%d_input", |
---|
117 | | - temp_i++); |
---|
| 118 | + n = temp_i++; |
---|
| 119 | + prefix = "temp"; |
---|
118 | 120 | break; |
---|
119 | 121 | case IIO_CURRENT: |
---|
120 | | - a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, |
---|
121 | | - "curr%d_input", |
---|
122 | | - curr_i++); |
---|
| 122 | + n = curr_i++; |
---|
| 123 | + prefix = "curr"; |
---|
| 124 | + break; |
---|
| 125 | + case IIO_POWER: |
---|
| 126 | + n = power_i++; |
---|
| 127 | + prefix = "power"; |
---|
123 | 128 | break; |
---|
124 | 129 | case IIO_HUMIDITYRELATIVE: |
---|
125 | | - a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, |
---|
126 | | - "humidity%d_input", |
---|
127 | | - humidity_i++); |
---|
| 130 | + n = humidity_i++; |
---|
| 131 | + prefix = "humidity"; |
---|
128 | 132 | break; |
---|
129 | 133 | default: |
---|
130 | 134 | return -EINVAL; |
---|
131 | 135 | } |
---|
| 136 | + |
---|
| 137 | + a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, |
---|
| 138 | + "%s%d_input", |
---|
| 139 | + prefix, n); |
---|
132 | 140 | if (a->dev_attr.attr.name == NULL) |
---|
133 | 141 | return -ENOMEM; |
---|
134 | 142 | |
---|
135 | 143 | a->dev_attr.show = iio_hwmon_read_val; |
---|
136 | | - a->dev_attr.attr.mode = S_IRUGO; |
---|
| 144 | + a->dev_attr.attr.mode = 0444; |
---|
137 | 145 | a->index = i; |
---|
138 | 146 | st->attrs[i] = &a->dev_attr.attr; |
---|
139 | 147 | } |
---|
.. | .. |
---|
141 | 149 | st->attr_group.attrs = st->attrs; |
---|
142 | 150 | st->groups[0] = &st->attr_group; |
---|
143 | 151 | |
---|
144 | | - sname = devm_kstrdup(dev, name, GFP_KERNEL); |
---|
145 | | - if (!sname) |
---|
146 | | - return -ENOMEM; |
---|
| 152 | + if (dev->of_node) { |
---|
| 153 | + sname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", dev->of_node); |
---|
| 154 | + if (!sname) |
---|
| 155 | + return -ENOMEM; |
---|
| 156 | + strreplace(sname, '-', '_'); |
---|
| 157 | + } else { |
---|
| 158 | + sname = "iio_hwmon"; |
---|
| 159 | + } |
---|
147 | 160 | |
---|
148 | | - strreplace(sname, '-', '_'); |
---|
149 | 161 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, sname, st, |
---|
150 | 162 | st->groups); |
---|
151 | 163 | return PTR_ERR_OR_ZERO(hwmon_dev); |
---|