55 * Copyright (C) 2023 Ivor Wanders <ivor@iwanders.net>
66 */
77
8- #include <linux/acpi.h>
98#include <linux/hwmon.h>
109#include <linux/kernel.h>
1110#include <linux/module.h>
1413#include <linux/thermal.h>
1514#include <linux/types.h>
1615
17- // This is a non-SSAM client driver as per the surface documentation.
18- // It registers itself as an ACPI driver for PNP0C0B, which requires removing
19- // the default fan module.
16+ // This is a SSAM client driver as per the surface documentation.
2017// It both sets up as a cooling device through the thermal cooling device as
2118// well as a hwmon fan for monitoring.
2219
2926
3027struct fan_data {
3128 struct device * dev ;
32- struct ssam_controller * ctrl ;
33- struct acpi_device * acpi_fan ;
34-
3529 struct thermal_cooling_device * cdev ;
30+
31+ struct ssam_device * sdev ;
32+
3633 struct device * hdev ;
3734};
3835
@@ -51,13 +48,6 @@ SSAM_DEFINE_SYNC_REQUEST_R(__ssam_fan_get, __le16, {
5148 .instance_id = 0x01 ,
5249});
5350
54- // ACPI
55- static const struct acpi_device_id surface_fan_match [] = {
56- { "PNP0C0B" },
57- {},
58- };
59- MODULE_DEVICE_TABLE (acpi , surface_fan_match );
60-
6151
6252// Thermal cooling device
6353static int surface_fan_set_cur_state (struct thermal_cooling_device * cdev ,
@@ -66,7 +56,7 @@ static int surface_fan_set_cur_state(struct thermal_cooling_device *cdev,
6656 __le16 value ;
6757 struct fan_data * d = cdev -> devdata ;
6858 value = cpu_to_le16 (clamp (state , 0lu , (1lu << 16 )));
69- return __ssam_fan_set (d -> ctrl , & value );
59+ return __ssam_fan_set (d -> sdev -> ctrl , & value );
7060}
7161
7262static int surface_fan_get_cur_state (struct thermal_cooling_device * cdev ,
@@ -75,7 +65,7 @@ static int surface_fan_get_cur_state(struct thermal_cooling_device *cdev,
7565 int res ;
7666 struct fan_data * d = cdev -> devdata ;
7767 __le16 value = 0 ;
78- res = __ssam_fan_get (d -> ctrl , & value );
68+ res = __ssam_fan_get (d -> sdev -> ctrl , & value );
7969 * state = le16_to_cpu (value );
8070 return res ;
8171}
@@ -121,15 +111,15 @@ static int surface_fan_hwmon_read(struct device *dev,
121111 enum hwmon_sensor_types type ,
122112 u32 attr , int channel , long * val )
123113{
124- struct fan_data * data = dev_get_drvdata (dev );
114+ struct fan_data * d = dev_get_drvdata (dev );
125115 __le16 value ;
126116 int res ;
127117
128118 switch (type ) {
129119 case hwmon_fan :
130120 switch (attr ) {
131121 case hwmon_fan_input :
132- res = __ssam_fan_get (data -> ctrl , & value );
122+ res = __ssam_fan_get (d -> sdev -> ctrl , & value );
133123 if (res ) {
134124 return -1 ;
135125 }
@@ -161,14 +151,14 @@ static int surface_fan_hwmon_write(struct device *dev,
161151 u32 attr , int channel , long val )
162152{
163153 __le16 value ;
164- struct fan_data * data = dev_get_drvdata (dev );
154+ struct fan_data * d = dev_get_drvdata (dev );
165155
166156 switch (type ) {
167157 case hwmon_fan :
168158 switch (attr ) {
169159 case hwmon_fan_target :
170160 value = cpu_to_le16 (clamp (val , 0l , (1l << 16 )));
171- return __ssam_fan_set (data -> ctrl , & value );
161+ return __ssam_fan_set (d -> sdev -> ctrl , & value );
172162 default :
173163 break ;
174164 }
@@ -200,29 +190,23 @@ static const struct hwmon_chip_info surface_fan_chip_info = {
200190 .info = surface_fan_info ,
201191};
202192
203- static int surface_fan_probe (struct platform_device * pdev )
193+ static int surface_fan_probe (struct ssam_device * sdev )
204194{
205- struct acpi_device * acpi_fan = ACPI_COMPANION (& pdev -> dev );
206-
207- struct ssam_controller * ctrl ;
208195 struct fan_data * data ;
209196 struct thermal_cooling_device * cdev ;
210197 struct device * hdev ;
211198 __le16 value ;
212199 int status ;
213200
214- ctrl = ssam_client_bind (& pdev -> dev );
215- if (IS_ERR (ctrl ))
216- return PTR_ERR (ctrl ) == - ENODEV ? - EPROBE_DEFER : PTR_ERR (ctrl );
217-
201+ printk (KERN_INFO "In probe!" );
218202 // Probe the fan to confirm we actually have it by retrieving the
219203 // speed.
220- status = __ssam_fan_get (ctrl , & value );
204+ status = __ssam_fan_get (sdev -> ctrl , & value );
221205 if (status ) {
222206 return - ENODEV ;
223207 }
224208
225- data = devm_kzalloc (& pdev -> dev , sizeof (* data ), GFP_KERNEL );
209+ data = devm_kzalloc (& sdev -> dev , sizeof (* data ), GFP_KERNEL );
226210 if (!data )
227211 return - ENOMEM ;
228212
@@ -232,55 +216,45 @@ static int surface_fan_probe(struct platform_device *pdev)
232216 return PTR_ERR (cdev );
233217
234218
235- hdev = devm_hwmon_device_register_with_info (& pdev -> dev , "fan" , data ,
219+ hdev = devm_hwmon_device_register_with_info (& sdev -> dev , "fan" , data ,
236220 & surface_fan_chip_info ,
237221 NULL );
238222 if (IS_ERR (hdev )) {
239223 return PTR_ERR (hdev );
240224 }
241225
242- data -> dev = & pdev -> dev ;
243- data -> ctrl = ctrl ;
244- data -> acpi_fan = acpi_fan ;
245-
226+ data -> sdev = sdev ;
246227 data -> cdev = cdev ;
247228 data -> hdev = hdev ;
248229
249- acpi_fan -> driver_data = data ;
250- platform_set_drvdata (pdev , data );
230+ ssam_device_set_drvdata (sdev , data );
251231
252232 return 0 ;
253233}
254234
255- static int surface_fan_remove (struct platform_device * pdev )
235+ static void surface_fan_remove (struct ssam_device * sdev )
256236{
257- struct fan_data * d = platform_get_drvdata ( pdev );
237+ struct fan_data * d = ssam_device_get_drvdata ( sdev );
258238 thermal_cooling_device_unregister (d -> cdev );
259- return 0 ;
260239}
261240
262241
263- static struct platform_driver surface_fan = {
242+ static const struct ssam_device_id ssam_fan_match [] = {
243+ { SSAM_SDEV (FAN , SAM , SSAM_SSH_IID_ANY , SSAM_SSH_FUN_ANY ) },
244+ { },
245+ };
246+ MODULE_DEVICE_TABLE (ssam , ssam_fan_match );
247+
248+ static struct ssam_device_driver surface_fan = {
264249 .probe = surface_fan_probe ,
265250 .remove = surface_fan_remove ,
251+ .match_table = ssam_fan_match ,
266252 .driver = {
267253 .name = "surface_fan" ,
268- .acpi_match_table = surface_fan_match ,
269254 .probe_type = PROBE_PREFER_ASYNCHRONOUS ,
270255 },
271256};
272-
273- static int __init surface_fan_init (void )
274- {
275- return platform_driver_register (& surface_fan );
276- }
277- module_init (surface_fan_init );
278-
279- static void __exit surface_fan_exit (void )
280- {
281- platform_driver_unregister (& surface_fan );
282- }
283- module_exit (surface_fan_exit );
257+ module_ssam_device_driver (surface_fan );
284258
285259MODULE_AUTHOR ("Ivor Wanders <ivor@iwanders.net>" );
286260MODULE_DESCRIPTION ("Fan Driver for Surface System Aggregator Module" );
0 commit comments