1*841bceb5SMichał Kopeć // SPDX-License-Identifier: GPL-2.0+
2*841bceb5SMichał Kopeć /*
3*841bceb5SMichał Kopeć * Dasharo ACPI Driver
4*841bceb5SMichał Kopeć */
5*841bceb5SMichał Kopeć
6*841bceb5SMichał Kopeć #include <linux/acpi.h>
7*841bceb5SMichał Kopeć #include <linux/array_size.h>
8*841bceb5SMichał Kopeć #include <linux/hwmon.h>
9*841bceb5SMichał Kopeć #include <linux/module.h>
10*841bceb5SMichał Kopeć #include <linux/platform_device.h>
11*841bceb5SMichał Kopeć #include <linux/types.h>
12*841bceb5SMichał Kopeć #include <linux/units.h>
13*841bceb5SMichał Kopeć
14*841bceb5SMichał Kopeć enum dasharo_feature {
15*841bceb5SMichał Kopeć DASHARO_FEATURE_TEMPERATURE = 0,
16*841bceb5SMichał Kopeć DASHARO_FEATURE_FAN_PWM,
17*841bceb5SMichał Kopeć DASHARO_FEATURE_FAN_TACH,
18*841bceb5SMichał Kopeć DASHARO_FEATURE_MAX
19*841bceb5SMichał Kopeć };
20*841bceb5SMichał Kopeć
21*841bceb5SMichał Kopeć enum dasharo_temperature {
22*841bceb5SMichał Kopeć DASHARO_TEMPERATURE_CPU_PACKAGE = 0,
23*841bceb5SMichał Kopeć DASHARO_TEMPERATURE_CPU_CORE,
24*841bceb5SMichał Kopeć DASHARO_TEMPERATURE_GPU,
25*841bceb5SMichał Kopeć DASHARO_TEMPERATURE_BOARD,
26*841bceb5SMichał Kopeć DASHARO_TEMPERATURE_CHASSIS,
27*841bceb5SMichał Kopeć DASHARO_TEMPERATURE_MAX
28*841bceb5SMichał Kopeć };
29*841bceb5SMichał Kopeć
30*841bceb5SMichał Kopeć enum dasharo_fan {
31*841bceb5SMichał Kopeć DASHARO_FAN_CPU = 0,
32*841bceb5SMichał Kopeć DASHARO_FAN_GPU,
33*841bceb5SMichał Kopeć DASHARO_FAN_CHASSIS,
34*841bceb5SMichał Kopeć DASHARO_FAN_MAX
35*841bceb5SMichał Kopeć };
36*841bceb5SMichał Kopeć
37*841bceb5SMichał Kopeć #define MAX_GROUPS_PER_FEAT 8
38*841bceb5SMichał Kopeć
39*841bceb5SMichał Kopeć static const char * const dasharo_group_names[DASHARO_FEATURE_MAX][MAX_GROUPS_PER_FEAT] = {
40*841bceb5SMichał Kopeć [DASHARO_FEATURE_TEMPERATURE] = {
41*841bceb5SMichał Kopeć [DASHARO_TEMPERATURE_CPU_PACKAGE] = "CPU Package",
42*841bceb5SMichał Kopeć [DASHARO_TEMPERATURE_CPU_CORE] = "CPU Core",
43*841bceb5SMichał Kopeć [DASHARO_TEMPERATURE_GPU] = "GPU",
44*841bceb5SMichał Kopeć [DASHARO_TEMPERATURE_BOARD] = "Board",
45*841bceb5SMichał Kopeć [DASHARO_TEMPERATURE_CHASSIS] = "Chassis",
46*841bceb5SMichał Kopeć },
47*841bceb5SMichał Kopeć [DASHARO_FEATURE_FAN_PWM] = {
48*841bceb5SMichał Kopeć [DASHARO_FAN_CPU] = "CPU",
49*841bceb5SMichał Kopeć [DASHARO_FAN_GPU] = "GPU",
50*841bceb5SMichał Kopeć [DASHARO_FAN_CHASSIS] = "Chassis",
51*841bceb5SMichał Kopeć },
52*841bceb5SMichał Kopeć [DASHARO_FEATURE_FAN_TACH] = {
53*841bceb5SMichał Kopeć [DASHARO_FAN_CPU] = "CPU",
54*841bceb5SMichał Kopeć [DASHARO_FAN_GPU] = "GPU",
55*841bceb5SMichał Kopeć [DASHARO_FAN_CHASSIS] = "Chassis",
56*841bceb5SMichał Kopeć },
57*841bceb5SMichał Kopeć };
58*841bceb5SMichał Kopeć
59*841bceb5SMichał Kopeć struct dasharo_capability {
60*841bceb5SMichał Kopeć unsigned int group;
61*841bceb5SMichał Kopeć unsigned int index;
62*841bceb5SMichał Kopeć char name[16];
63*841bceb5SMichał Kopeć };
64*841bceb5SMichał Kopeć
65*841bceb5SMichał Kopeć #define MAX_CAPS_PER_FEAT 24
66*841bceb5SMichał Kopeć
67*841bceb5SMichał Kopeć struct dasharo_data {
68*841bceb5SMichał Kopeć struct platform_device *pdev;
69*841bceb5SMichał Kopeć int caps_found[DASHARO_FEATURE_MAX];
70*841bceb5SMichał Kopeć struct dasharo_capability capabilities[DASHARO_FEATURE_MAX][MAX_CAPS_PER_FEAT];
71*841bceb5SMichał Kopeć };
72*841bceb5SMichał Kopeć
dasharo_get_feature_cap_count(struct dasharo_data * data,enum dasharo_feature feat,int cap)73*841bceb5SMichał Kopeć static int dasharo_get_feature_cap_count(struct dasharo_data *data, enum dasharo_feature feat, int cap)
74*841bceb5SMichał Kopeć {
75*841bceb5SMichał Kopeć struct acpi_object_list obj_list;
76*841bceb5SMichał Kopeć union acpi_object obj[2];
77*841bceb5SMichał Kopeć acpi_handle handle;
78*841bceb5SMichał Kopeć acpi_status status;
79*841bceb5SMichał Kopeć u64 count;
80*841bceb5SMichał Kopeć
81*841bceb5SMichał Kopeć obj[0].type = ACPI_TYPE_INTEGER;
82*841bceb5SMichał Kopeć obj[0].integer.value = feat;
83*841bceb5SMichał Kopeć obj[1].type = ACPI_TYPE_INTEGER;
84*841bceb5SMichał Kopeć obj[1].integer.value = cap;
85*841bceb5SMichał Kopeć obj_list.count = 2;
86*841bceb5SMichał Kopeć obj_list.pointer = &obj[0];
87*841bceb5SMichał Kopeć
88*841bceb5SMichał Kopeć handle = ACPI_HANDLE(&data->pdev->dev);
89*841bceb5SMichał Kopeć status = acpi_evaluate_integer(handle, "GFCP", &obj_list, &count);
90*841bceb5SMichał Kopeć if (ACPI_FAILURE(status))
91*841bceb5SMichał Kopeć return -ENODEV;
92*841bceb5SMichał Kopeć
93*841bceb5SMichał Kopeć return count;
94*841bceb5SMichał Kopeć }
95*841bceb5SMichał Kopeć
dasharo_read_channel(struct dasharo_data * data,char * method,enum dasharo_feature feat,int channel,long * value)96*841bceb5SMichał Kopeć static int dasharo_read_channel(struct dasharo_data *data, char *method, enum dasharo_feature feat, int channel, long *value)
97*841bceb5SMichał Kopeć {
98*841bceb5SMichał Kopeć struct acpi_object_list obj_list;
99*841bceb5SMichał Kopeć union acpi_object obj[2];
100*841bceb5SMichał Kopeć acpi_handle handle;
101*841bceb5SMichał Kopeć acpi_status status;
102*841bceb5SMichał Kopeć u64 val;
103*841bceb5SMichał Kopeć
104*841bceb5SMichał Kopeć if (feat >= ARRAY_SIZE(data->capabilities))
105*841bceb5SMichał Kopeć return -EINVAL;
106*841bceb5SMichał Kopeć
107*841bceb5SMichał Kopeć if (channel >= data->caps_found[feat])
108*841bceb5SMichał Kopeć return -EINVAL;
109*841bceb5SMichał Kopeć
110*841bceb5SMichał Kopeć obj[0].type = ACPI_TYPE_INTEGER;
111*841bceb5SMichał Kopeć obj[0].integer.value = data->capabilities[feat][channel].group;
112*841bceb5SMichał Kopeć obj[1].type = ACPI_TYPE_INTEGER;
113*841bceb5SMichał Kopeć obj[1].integer.value = data->capabilities[feat][channel].index;
114*841bceb5SMichał Kopeć obj_list.count = 2;
115*841bceb5SMichał Kopeć obj_list.pointer = &obj[0];
116*841bceb5SMichał Kopeć
117*841bceb5SMichał Kopeć handle = ACPI_HANDLE(&data->pdev->dev);
118*841bceb5SMichał Kopeć status = acpi_evaluate_integer(handle, method, &obj_list, &val);
119*841bceb5SMichał Kopeć if (ACPI_FAILURE(status))
120*841bceb5SMichał Kopeć return -ENODEV;
121*841bceb5SMichał Kopeć
122*841bceb5SMichał Kopeć *value = val;
123*841bceb5SMichał Kopeć return 0;
124*841bceb5SMichał Kopeć }
125*841bceb5SMichał Kopeć
dasharo_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)126*841bceb5SMichał Kopeć static int dasharo_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
127*841bceb5SMichał Kopeć u32 attr, int channel, long *val)
128*841bceb5SMichał Kopeć {
129*841bceb5SMichał Kopeć struct dasharo_data *data = dev_get_drvdata(dev);
130*841bceb5SMichał Kopeć long value;
131*841bceb5SMichał Kopeć int ret;
132*841bceb5SMichał Kopeć
133*841bceb5SMichał Kopeć switch (type) {
134*841bceb5SMichał Kopeć case hwmon_temp:
135*841bceb5SMichał Kopeć ret = dasharo_read_channel(data, "GTMP", DASHARO_FEATURE_TEMPERATURE, channel, &value);
136*841bceb5SMichał Kopeć if (!ret)
137*841bceb5SMichał Kopeć *val = value * MILLIDEGREE_PER_DEGREE;
138*841bceb5SMichał Kopeć break;
139*841bceb5SMichał Kopeć case hwmon_fan:
140*841bceb5SMichał Kopeć ret = dasharo_read_channel(data, "GFTH", DASHARO_FEATURE_FAN_TACH, channel, &value);
141*841bceb5SMichał Kopeć if (!ret)
142*841bceb5SMichał Kopeć *val = value;
143*841bceb5SMichał Kopeć break;
144*841bceb5SMichał Kopeć case hwmon_pwm:
145*841bceb5SMichał Kopeć ret = dasharo_read_channel(data, "GFDC", DASHARO_FEATURE_FAN_PWM, channel, &value);
146*841bceb5SMichał Kopeć if (!ret)
147*841bceb5SMichał Kopeć *val = value;
148*841bceb5SMichał Kopeć break;
149*841bceb5SMichał Kopeć default:
150*841bceb5SMichał Kopeć return -ENODEV;
151*841bceb5SMichał Kopeć break;
152*841bceb5SMichał Kopeć }
153*841bceb5SMichał Kopeć
154*841bceb5SMichał Kopeć return ret;
155*841bceb5SMichał Kopeć }
156*841bceb5SMichał Kopeć
dasharo_hwmon_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** str)157*841bceb5SMichał Kopeć static int dasharo_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
158*841bceb5SMichał Kopeć u32 attr, int channel, const char **str)
159*841bceb5SMichał Kopeć {
160*841bceb5SMichał Kopeć struct dasharo_data *data = dev_get_drvdata(dev);
161*841bceb5SMichał Kopeć
162*841bceb5SMichał Kopeć switch (type) {
163*841bceb5SMichał Kopeć case hwmon_temp:
164*841bceb5SMichał Kopeć if (channel >= data->caps_found[DASHARO_FEATURE_TEMPERATURE])
165*841bceb5SMichał Kopeć return -EINVAL;
166*841bceb5SMichał Kopeć
167*841bceb5SMichał Kopeć *str = data->capabilities[DASHARO_FEATURE_TEMPERATURE][channel].name;
168*841bceb5SMichał Kopeć break;
169*841bceb5SMichał Kopeć case hwmon_fan:
170*841bceb5SMichał Kopeć if (channel >= data->caps_found[DASHARO_FEATURE_FAN_TACH])
171*841bceb5SMichał Kopeć return -EINVAL;
172*841bceb5SMichał Kopeć
173*841bceb5SMichał Kopeć *str = data->capabilities[DASHARO_FEATURE_FAN_TACH][channel].name;
174*841bceb5SMichał Kopeć break;
175*841bceb5SMichał Kopeć default:
176*841bceb5SMichał Kopeć return -EOPNOTSUPP;
177*841bceb5SMichał Kopeć }
178*841bceb5SMichał Kopeć
179*841bceb5SMichał Kopeć return 0;
180*841bceb5SMichał Kopeć }
181*841bceb5SMichał Kopeć
dasharo_hwmon_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)182*841bceb5SMichał Kopeć static umode_t dasharo_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
183*841bceb5SMichał Kopeć u32 attr, int channel)
184*841bceb5SMichał Kopeć {
185*841bceb5SMichał Kopeć const struct dasharo_data *data = drvdata;
186*841bceb5SMichał Kopeć
187*841bceb5SMichał Kopeć switch (type) {
188*841bceb5SMichał Kopeć case hwmon_temp:
189*841bceb5SMichał Kopeć if (channel < data->caps_found[DASHARO_FEATURE_TEMPERATURE])
190*841bceb5SMichał Kopeć return 0444;
191*841bceb5SMichał Kopeć break;
192*841bceb5SMichał Kopeć case hwmon_pwm:
193*841bceb5SMichał Kopeć if (channel < data->caps_found[DASHARO_FEATURE_FAN_PWM])
194*841bceb5SMichał Kopeć return 0444;
195*841bceb5SMichał Kopeć break;
196*841bceb5SMichał Kopeć case hwmon_fan:
197*841bceb5SMichał Kopeć if (channel < data->caps_found[DASHARO_FEATURE_FAN_TACH])
198*841bceb5SMichał Kopeć return 0444;
199*841bceb5SMichał Kopeć break;
200*841bceb5SMichał Kopeć default:
201*841bceb5SMichał Kopeć break;
202*841bceb5SMichał Kopeć }
203*841bceb5SMichał Kopeć
204*841bceb5SMichał Kopeć return 0;
205*841bceb5SMichał Kopeć }
206*841bceb5SMichał Kopeć
207*841bceb5SMichał Kopeć static const struct hwmon_ops dasharo_hwmon_ops = {
208*841bceb5SMichał Kopeć .is_visible = dasharo_hwmon_is_visible,
209*841bceb5SMichał Kopeć .read_string = dasharo_hwmon_read_string,
210*841bceb5SMichał Kopeć .read = dasharo_hwmon_read,
211*841bceb5SMichał Kopeć };
212*841bceb5SMichał Kopeć
213*841bceb5SMichał Kopeć // Max 24 capabilities per feature
214*841bceb5SMichał Kopeć static const struct hwmon_channel_info * const dasharo_hwmon_info[] = {
215*841bceb5SMichał Kopeć HWMON_CHANNEL_INFO(fan,
216*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
217*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
218*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
219*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
220*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
221*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
222*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
223*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
224*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
225*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
226*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
227*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
228*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
229*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
230*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
231*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
232*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
233*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
234*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
235*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
236*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
237*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
238*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL,
239*841bceb5SMichał Kopeć HWMON_F_INPUT | HWMON_F_LABEL),
240*841bceb5SMichał Kopeć HWMON_CHANNEL_INFO(temp,
241*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
242*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
243*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
244*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
245*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
246*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
247*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
248*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
249*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
250*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
251*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
252*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
253*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
254*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
255*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
256*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
257*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
258*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
259*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
260*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
261*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
262*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
263*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL,
264*841bceb5SMichał Kopeć HWMON_T_INPUT | HWMON_T_LABEL),
265*841bceb5SMichał Kopeć HWMON_CHANNEL_INFO(pwm,
266*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
267*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
268*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
269*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
270*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
271*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
272*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
273*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
274*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
275*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
276*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
277*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
278*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
279*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
280*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
281*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
282*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
283*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
284*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
285*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
286*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
287*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
288*841bceb5SMichał Kopeć HWMON_PWM_INPUT,
289*841bceb5SMichał Kopeć HWMON_PWM_INPUT),
290*841bceb5SMichał Kopeć NULL
291*841bceb5SMichał Kopeć };
292*841bceb5SMichał Kopeć
293*841bceb5SMichał Kopeć static const struct hwmon_chip_info dasharo_hwmon_chip_info = {
294*841bceb5SMichał Kopeć .ops = &dasharo_hwmon_ops,
295*841bceb5SMichał Kopeć .info = dasharo_hwmon_info,
296*841bceb5SMichał Kopeć };
297*841bceb5SMichał Kopeć
dasharo_fill_feature_caps(struct dasharo_data * data,enum dasharo_feature feat)298*841bceb5SMichał Kopeć static void dasharo_fill_feature_caps(struct dasharo_data *data, enum dasharo_feature feat)
299*841bceb5SMichał Kopeć {
300*841bceb5SMichał Kopeć struct dasharo_capability *cap;
301*841bceb5SMichał Kopeć int cap_count = 0;
302*841bceb5SMichał Kopeć int count;
303*841bceb5SMichał Kopeć
304*841bceb5SMichał Kopeć for (int group = 0; group < MAX_GROUPS_PER_FEAT; ++group) {
305*841bceb5SMichał Kopeć count = dasharo_get_feature_cap_count(data, feat, group);
306*841bceb5SMichał Kopeć if (count <= 0)
307*841bceb5SMichał Kopeć continue;
308*841bceb5SMichał Kopeć
309*841bceb5SMichał Kopeć for (unsigned int i = 0; i < count; ++i) {
310*841bceb5SMichał Kopeć if (cap_count >= ARRAY_SIZE(data->capabilities[feat]))
311*841bceb5SMichał Kopeć break;
312*841bceb5SMichał Kopeć
313*841bceb5SMichał Kopeć cap = &data->capabilities[feat][cap_count];
314*841bceb5SMichał Kopeć cap->group = group;
315*841bceb5SMichał Kopeć cap->index = i;
316*841bceb5SMichał Kopeć scnprintf(cap->name, sizeof(cap->name), "%s %d",
317*841bceb5SMichał Kopeć dasharo_group_names[feat][group], i);
318*841bceb5SMichał Kopeć cap_count++;
319*841bceb5SMichał Kopeć }
320*841bceb5SMichał Kopeć }
321*841bceb5SMichał Kopeć data->caps_found[feat] = cap_count;
322*841bceb5SMichał Kopeć }
323*841bceb5SMichał Kopeć
dasharo_probe(struct platform_device * pdev)324*841bceb5SMichał Kopeć static int dasharo_probe(struct platform_device *pdev)
325*841bceb5SMichał Kopeć {
326*841bceb5SMichał Kopeć struct dasharo_data *data;
327*841bceb5SMichał Kopeć struct device *hwmon;
328*841bceb5SMichał Kopeć
329*841bceb5SMichał Kopeć data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
330*841bceb5SMichał Kopeć if (!data)
331*841bceb5SMichał Kopeć return -ENOMEM;
332*841bceb5SMichał Kopeć data->pdev = pdev;
333*841bceb5SMichał Kopeć
334*841bceb5SMichał Kopeć for (unsigned int i = 0; i < DASHARO_FEATURE_MAX; ++i)
335*841bceb5SMichał Kopeć dasharo_fill_feature_caps(data, i);
336*841bceb5SMichał Kopeć
337*841bceb5SMichał Kopeć hwmon = devm_hwmon_device_register_with_info(&pdev->dev, "dasharo_acpi", data,
338*841bceb5SMichał Kopeć &dasharo_hwmon_chip_info, NULL);
339*841bceb5SMichał Kopeć
340*841bceb5SMichał Kopeć return PTR_ERR_OR_ZERO(hwmon);
341*841bceb5SMichał Kopeć }
342*841bceb5SMichał Kopeć
343*841bceb5SMichał Kopeć static const struct acpi_device_id dasharo_device_ids[] = {
344*841bceb5SMichał Kopeć {"DSHR0001", 0},
345*841bceb5SMichał Kopeć {}
346*841bceb5SMichał Kopeć };
347*841bceb5SMichał Kopeć MODULE_DEVICE_TABLE(acpi, dasharo_device_ids);
348*841bceb5SMichał Kopeć
349*841bceb5SMichał Kopeć static struct platform_driver dasharo_driver = {
350*841bceb5SMichał Kopeć .driver = {
351*841bceb5SMichał Kopeć .name = "dasharo-acpi",
352*841bceb5SMichał Kopeć .acpi_match_table = dasharo_device_ids,
353*841bceb5SMichał Kopeć },
354*841bceb5SMichał Kopeć .probe = dasharo_probe,
355*841bceb5SMichał Kopeć };
356*841bceb5SMichał Kopeć module_platform_driver(dasharo_driver);
357*841bceb5SMichał Kopeć
358*841bceb5SMichał Kopeć MODULE_DESCRIPTION("Dasharo ACPI Driver");
359*841bceb5SMichał Kopeć MODULE_AUTHOR("Michał Kopeć <michal.kopec@3mdeb.com>");
360*841bceb5SMichał Kopeć MODULE_LICENSE("GPL");
361