1212#include <linux/platform_data/emc2305.h>
1313#include <linux/thermal.h>
1414
15+ #define EMC2305_REG_FAN_STATUS 0x24
16+ #define EMC2305_REG_FAN_STALL_STATUS 0x25
1517#define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
1618#define EMC2305_REG_VENDOR 0xfe
1719#define EMC2305_FAN_MAX 0xff
1820#define EMC2305_FAN_MIN 0x00
1921#define EMC2305_FAN_MAX_STATE 10
20- #define EMC2305_DEVICE 0x34
2122#define EMC2305_VENDOR 0x5d
2223#define EMC2305_REG_PRODUCT_ID 0xfd
2324#define EMC2305_TACH_REGS_UNUSE_BITS 3
3637#define EMC2305_RPM_FACTOR 3932160
3738
3839#define EMC2305_REG_FAN_DRIVE (n ) (0x30 + 0x10 * (n))
40+ #define EMC2305_REG_FAN_CFG (n ) (0x32 + 0x10 * (n))
3941#define EMC2305_REG_FAN_MIN_DRIVE (n ) (0x38 + 0x10 * (n))
4042#define EMC2305_REG_FAN_TACH (n ) (0x3e + 0x10 * (n))
4143
@@ -100,6 +102,7 @@ struct emc2305_data {
100102 u8 pwm_num ;
101103 bool pwm_separate ;
102104 u8 pwm_min [EMC2305_PWM_MAX ];
105+ u8 pwm_max ;
103106 struct emc2305_cdev_data cdev_data [EMC2305_PWM_MAX ];
104107};
105108
@@ -112,6 +115,8 @@ static char *emc2305_fan_name[] = {
112115 "emc2305_fan5" ,
113116};
114117
118+ static void emc2305_unset_tz (struct device * dev );
119+
115120static int emc2305_get_max_channel (const struct emc2305_data * data )
116121{
117122 return data -> pwm_num ;
@@ -270,7 +275,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
270275 struct i2c_client * client = data -> client ;
271276 int ret ;
272277
273- if (val < data -> pwm_min [channel ] || val > EMC2305_FAN_MAX )
278+ if (val < data -> pwm_min [channel ] || val > data -> pwm_max )
274279 return - EINVAL ;
275280
276281 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)
281286 return 0 ;
282287}
283288
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+
284332static int emc2305_set_single_tz (struct device * dev , int idx )
285333{
286334 struct emc2305_data * data = dev_get_drvdata (dev );
@@ -290,9 +338,16 @@ static int emc2305_set_single_tz(struct device *dev, int idx)
290338 cdev_idx = (idx ) ? idx - 1 : 0 ;
291339 pwm = data -> pwm_min [cdev_idx ];
292340
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 ,
296351 & emc2305_cooling_ops );
297352
298353 if (IS_ERR (data -> cdev_data [cdev_idx ].cdev )) {
@@ -331,9 +386,26 @@ static int emc2305_set_tz(struct device *dev)
331386 for (i = 0 ; i < data -> pwm_num ; i ++ ) {
332387 ret = emc2305_set_single_tz (dev , i + 1 );
333388 if (ret )
334- return ret ;
389+ goto thermal_cooling_device_register_fail ;
335390 }
336391 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+ }
337409}
338410
339411static umode_t
@@ -555,11 +627,18 @@ static int emc2305_probe(struct i2c_client *client)
555627 data -> pwm_separate = pdata -> pwm_separate ;
556628 for (i = 0 ; i < EMC2305_PWM_MAX ; i ++ )
557629 data -> pwm_min [i ] = pdata -> pwm_min [i ];
630+ data -> pwm_max = EMC2305_FAN_MAX ;
558631 } else {
559632 data -> max_state = EMC2305_FAN_MAX_STATE ;
560633 data -> pwm_separate = false;
561634 for (i = 0 ; i < EMC2305_PWM_MAX ; i ++ )
562635 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+ }
563642 }
564643
565644 data -> hwmon_dev = devm_hwmon_device_register_with_info (dev , "emc2305" , data ,
@@ -580,21 +659,39 @@ static int emc2305_probe(struct i2c_client *client)
580659 return ret ;
581660 }
582661
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+
583668 return 0 ;
584669}
585670
586671static const struct of_device_id of_emc2305_match_table [] = {
587672 { .compatible = "microchip,emc2305" , },
673+ { .compatible = "microchip,emc2303" , },
674+ { .compatible = "microchip,emc2302" , },
675+ { .compatible = "microchip,emc2301" , },
588676 {},
589677};
590678MODULE_DEVICE_TABLE (of , of_emc2305_match_table );
591679
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+
592688static struct i2c_driver emc2305_driver = {
593689 .driver = {
594690 .name = "emc2305" ,
595691 .of_match_table = of_emc2305_match_table ,
596692 },
597693 .probe = emc2305_probe ,
694+ .remove = emc2305_remove ,
598695 .id_table = emc2305_ids ,
599696};
600697
0 commit comments