12
12
#include <linux/platform_data/emc2305.h>
13
13
#include <linux/thermal.h>
14
14
15
+ #define EMC2305_REG_FAN_STATUS 0x24
16
+ #define EMC2305_REG_FAN_STALL_STATUS 0x25
15
17
#define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
16
18
#define EMC2305_REG_VENDOR 0xfe
17
19
#define EMC2305_FAN_MAX 0xff
18
20
#define EMC2305_FAN_MIN 0x00
19
21
#define EMC2305_FAN_MAX_STATE 10
20
- #define EMC2305_DEVICE 0x34
21
22
#define EMC2305_VENDOR 0x5d
22
23
#define EMC2305_REG_PRODUCT_ID 0xfd
23
24
#define EMC2305_TACH_REGS_UNUSE_BITS 3
36
37
#define EMC2305_RPM_FACTOR 3932160
37
38
38
39
#define EMC2305_REG_FAN_DRIVE (n ) (0x30 + 0x10 * (n))
40
+ #define EMC2305_REG_FAN_CFG (n ) (0x32 + 0x10 * (n))
39
41
#define EMC2305_REG_FAN_MIN_DRIVE (n ) (0x38 + 0x10 * (n))
40
42
#define EMC2305_REG_FAN_TACH (n ) (0x3e + 0x10 * (n))
41
43
@@ -100,6 +102,7 @@ struct emc2305_data {
100
102
u8 pwm_num ;
101
103
bool pwm_separate ;
102
104
u8 pwm_min [EMC2305_PWM_MAX ];
105
+ u8 pwm_max ;
103
106
struct emc2305_cdev_data cdev_data [EMC2305_PWM_MAX ];
104
107
};
105
108
@@ -112,6 +115,8 @@ static char *emc2305_fan_name[] = {
112
115
"emc2305_fan5" ,
113
116
};
114
117
118
+ static void emc2305_unset_tz (struct device * dev );
119
+
115
120
static int emc2305_get_max_channel (const struct emc2305_data * data )
116
121
{
117
122
return data -> pwm_num ;
@@ -270,7 +275,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
270
275
struct i2c_client * client = data -> client ;
271
276
int ret ;
272
277
273
- if (val < data -> pwm_min [channel ] || val > EMC2305_FAN_MAX )
278
+ if (val < data -> pwm_min [channel ] || val > data -> pwm_max )
274
279
return - EINVAL ;
275
280
276
281
ret = i2c_smbus_write_byte_data (client , EMC2305_REG_FAN_DRIVE (channel ), val );
@@ -281,6 +286,49 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
281
286
return 0 ;
282
287
}
283
288
289
+ static int emc2305_get_tz_of (struct device * dev )
290
+ {
291
+ struct device_node * np = dev -> of_node ;
292
+ struct emc2305_data * data = dev_get_drvdata (dev );
293
+ int ret = 0 ;
294
+ u8 val ;
295
+ int i ;
296
+
297
+ /* OF parameters are optional - overwrite default setting
298
+ * if some of them are provided.
299
+ */
300
+
301
+ ret = of_property_read_u8 (np , "emc2305,cooling-levels" , & val );
302
+ if (!ret )
303
+ data -> max_state = val ;
304
+ else if (ret != - EINVAL )
305
+ return ret ;
306
+
307
+ ret = of_property_read_u8 (np , "emc2305,pwm-max" , & val );
308
+ if (!ret )
309
+ data -> pwm_max = val ;
310
+ else if (ret != - EINVAL )
311
+ return ret ;
312
+
313
+ ret = of_property_read_u8 (np , "emc2305,pwm-min" , & val );
314
+ if (!ret )
315
+ for (i = 0 ; i < EMC2305_PWM_MAX ; i ++ )
316
+ data -> pwm_min [i ] = val ;
317
+ else if (ret != - EINVAL )
318
+ return ret ;
319
+
320
+ /* Not defined or 0 means one thermal zone over all cooling devices.
321
+ * Otherwise - separated thermal zones for each PWM channel.
322
+ */
323
+ ret = of_property_read_u8 (np , "emc2305,pwm-channel" , & val );
324
+ if (!ret )
325
+ data -> pwm_separate = (val != 0 );
326
+ else if (ret != - EINVAL )
327
+ return ret ;
328
+
329
+ return 0 ;
330
+ }
331
+
284
332
static int emc2305_set_single_tz (struct device * dev , int idx )
285
333
{
286
334
struct emc2305_data * data = dev_get_drvdata (dev );
@@ -290,9 +338,16 @@ static int emc2305_set_single_tz(struct device *dev, int idx)
290
338
cdev_idx = (idx ) ? idx - 1 : 0 ;
291
339
pwm = data -> pwm_min [cdev_idx ];
292
340
293
- data -> cdev_data [cdev_idx ].cdev =
294
- devm_thermal_of_cooling_device_register (dev , dev -> of_node ,
295
- emc2305_fan_name [idx ], data ,
341
+ if (dev -> of_node )
342
+ data -> cdev_data [cdev_idx ].cdev =
343
+ devm_thermal_of_cooling_device_register (dev , dev -> of_node ,
344
+ emc2305_fan_name [idx ],
345
+ data ,
346
+ & emc2305_cooling_ops );
347
+ else
348
+ data -> cdev_data [cdev_idx ].cdev =
349
+ thermal_cooling_device_register (emc2305_fan_name [idx ],
350
+ data ,
296
351
& emc2305_cooling_ops );
297
352
298
353
if (IS_ERR (data -> cdev_data [cdev_idx ].cdev )) {
@@ -331,9 +386,26 @@ static int emc2305_set_tz(struct device *dev)
331
386
for (i = 0 ; i < data -> pwm_num ; i ++ ) {
332
387
ret = emc2305_set_single_tz (dev , i + 1 );
333
388
if (ret )
334
- return ret ;
389
+ goto thermal_cooling_device_register_fail ;
335
390
}
336
391
return 0 ;
392
+
393
+ thermal_cooling_device_register_fail :
394
+ emc2305_unset_tz (dev );
395
+ return ret ;
396
+ }
397
+
398
+ static void emc2305_unset_tz (struct device * dev )
399
+ {
400
+ struct emc2305_data * data = dev_get_drvdata (dev );
401
+ int i ;
402
+
403
+ /* Unregister cooling device. */
404
+ if (!dev -> of_node ) {
405
+ for (i = 0 ; i < EMC2305_PWM_MAX ; i ++ )
406
+ if (data -> cdev_data [i ].cdev )
407
+ thermal_cooling_device_unregister (data -> cdev_data [i ].cdev );
408
+ }
337
409
}
338
410
339
411
static umode_t
@@ -555,11 +627,18 @@ static int emc2305_probe(struct i2c_client *client)
555
627
data -> pwm_separate = pdata -> pwm_separate ;
556
628
for (i = 0 ; i < EMC2305_PWM_MAX ; i ++ )
557
629
data -> pwm_min [i ] = pdata -> pwm_min [i ];
630
+ data -> pwm_max = EMC2305_FAN_MAX ;
558
631
} else {
559
632
data -> max_state = EMC2305_FAN_MAX_STATE ;
560
633
data -> pwm_separate = false;
561
634
for (i = 0 ; i < EMC2305_PWM_MAX ; i ++ )
562
635
data -> pwm_min [i ] = EMC2305_FAN_MIN ;
636
+ data -> pwm_max = EMC2305_FAN_MAX ;
637
+ if (dev -> of_node ) {
638
+ ret = emc2305_get_tz_of (dev );
639
+ if (ret < 0 )
640
+ return ret ;
641
+ }
563
642
}
564
643
565
644
data -> hwmon_dev = devm_hwmon_device_register_with_info (dev , "emc2305" , data ,
@@ -580,21 +659,39 @@ static int emc2305_probe(struct i2c_client *client)
580
659
return ret ;
581
660
}
582
661
662
+ /* Acknowledge any existing faults. Stops the device responding on the
663
+ * SMBus alert address.
664
+ */
665
+ i2c_smbus_read_byte_data (client , EMC2305_REG_FAN_STALL_STATUS );
666
+ i2c_smbus_read_byte_data (client , EMC2305_REG_FAN_STATUS );
667
+
583
668
return 0 ;
584
669
}
585
670
586
671
static const struct of_device_id of_emc2305_match_table [] = {
587
672
{ .compatible = "microchip,emc2305" , },
673
+ { .compatible = "microchip,emc2303" , },
674
+ { .compatible = "microchip,emc2302" , },
675
+ { .compatible = "microchip,emc2301" , },
588
676
{},
589
677
};
590
678
MODULE_DEVICE_TABLE (of , of_emc2305_match_table );
591
679
680
+ static void emc2305_remove (struct i2c_client * client )
681
+ {
682
+ struct device * dev = & client -> dev ;
683
+
684
+ if (IS_REACHABLE (CONFIG_THERMAL ))
685
+ emc2305_unset_tz (dev );
686
+ }
687
+
592
688
static struct i2c_driver emc2305_driver = {
593
689
.driver = {
594
690
.name = "emc2305" ,
595
691
.of_match_table = of_emc2305_match_table ,
596
692
},
597
693
.probe = emc2305_probe ,
694
+ .remove = emc2305_remove ,
598
695
.id_table = emc2305_ids ,
599
696
};
600
697
0 commit comments