xref: /OK3568_Linux_fs/kernel/drivers/hwmon/gpio-fan.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * gpio-fan.c - Hwmon driver for fans connected to GPIO lines.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2010 LaCie
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Simon Guinot <sguinot@lacie.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/init.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/irq.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/err.h>
17*4882a593Smuzhiyun #include <linux/mutex.h>
18*4882a593Smuzhiyun #include <linux/hwmon.h>
19*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
20*4882a593Smuzhiyun #include <linux/of.h>
21*4882a593Smuzhiyun #include <linux/of_platform.h>
22*4882a593Smuzhiyun #include <linux/thermal.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun struct gpio_fan_speed {
25*4882a593Smuzhiyun 	int rpm;
26*4882a593Smuzhiyun 	int ctrl_val;
27*4882a593Smuzhiyun };
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun struct gpio_fan_data {
30*4882a593Smuzhiyun 	struct device		*dev;
31*4882a593Smuzhiyun 	struct device		*hwmon_dev;
32*4882a593Smuzhiyun 	/* Cooling device if any */
33*4882a593Smuzhiyun 	struct thermal_cooling_device *cdev;
34*4882a593Smuzhiyun 	struct mutex		lock; /* lock GPIOs operations. */
35*4882a593Smuzhiyun 	int			num_gpios;
36*4882a593Smuzhiyun 	struct gpio_desc	**gpios;
37*4882a593Smuzhiyun 	int			num_speed;
38*4882a593Smuzhiyun 	struct gpio_fan_speed	*speed;
39*4882a593Smuzhiyun 	int			speed_index;
40*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
41*4882a593Smuzhiyun 	int			resume_speed;
42*4882a593Smuzhiyun #endif
43*4882a593Smuzhiyun 	bool			pwm_enable;
44*4882a593Smuzhiyun 	struct gpio_desc	*alarm_gpio;
45*4882a593Smuzhiyun 	struct work_struct	alarm_work;
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun  * Alarm GPIO.
50*4882a593Smuzhiyun  */
51*4882a593Smuzhiyun 
fan_alarm_notify(struct work_struct * ws)52*4882a593Smuzhiyun static void fan_alarm_notify(struct work_struct *ws)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data =
55*4882a593Smuzhiyun 		container_of(ws, struct gpio_fan_data, alarm_work);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	sysfs_notify(&fan_data->hwmon_dev->kobj, NULL, "fan1_alarm");
58*4882a593Smuzhiyun 	kobject_uevent(&fan_data->hwmon_dev->kobj, KOBJ_CHANGE);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
fan_alarm_irq_handler(int irq,void * dev_id)61*4882a593Smuzhiyun static irqreturn_t fan_alarm_irq_handler(int irq, void *dev_id)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_id;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	schedule_work(&fan_data->alarm_work);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	return IRQ_NONE;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
fan1_alarm_show(struct device * dev,struct device_attribute * attr,char * buf)70*4882a593Smuzhiyun static ssize_t fan1_alarm_show(struct device *dev,
71*4882a593Smuzhiyun 			       struct device_attribute *attr, char *buf)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	return sprintf(buf, "%d\n",
76*4882a593Smuzhiyun 		       gpiod_get_value_cansleep(fan_data->alarm_gpio));
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun static DEVICE_ATTR_RO(fan1_alarm);
80*4882a593Smuzhiyun 
fan_alarm_init(struct gpio_fan_data * fan_data)81*4882a593Smuzhiyun static int fan_alarm_init(struct gpio_fan_data *fan_data)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	int alarm_irq;
84*4882a593Smuzhiyun 	struct device *dev = fan_data->dev;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	/*
87*4882a593Smuzhiyun 	 * If the alarm GPIO don't support interrupts, just leave
88*4882a593Smuzhiyun 	 * without initializing the fail notification support.
89*4882a593Smuzhiyun 	 */
90*4882a593Smuzhiyun 	alarm_irq = gpiod_to_irq(fan_data->alarm_gpio);
91*4882a593Smuzhiyun 	if (alarm_irq <= 0)
92*4882a593Smuzhiyun 		return 0;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
95*4882a593Smuzhiyun 	irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
96*4882a593Smuzhiyun 	return devm_request_irq(dev, alarm_irq, fan_alarm_irq_handler,
97*4882a593Smuzhiyun 				IRQF_SHARED, "GPIO fan alarm", fan_data);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /*
101*4882a593Smuzhiyun  * Control GPIOs.
102*4882a593Smuzhiyun  */
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /* Must be called with fan_data->lock held, except during initialization. */
__set_fan_ctrl(struct gpio_fan_data * fan_data,int ctrl_val)105*4882a593Smuzhiyun static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun 	int i;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	for (i = 0; i < fan_data->num_gpios; i++)
110*4882a593Smuzhiyun 		gpiod_set_value_cansleep(fan_data->gpios[i],
111*4882a593Smuzhiyun 					 (ctrl_val >> i) & 1);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
__get_fan_ctrl(struct gpio_fan_data * fan_data)114*4882a593Smuzhiyun static int __get_fan_ctrl(struct gpio_fan_data *fan_data)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	int i;
117*4882a593Smuzhiyun 	int ctrl_val = 0;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	for (i = 0; i < fan_data->num_gpios; i++) {
120*4882a593Smuzhiyun 		int value;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 		value = gpiod_get_value_cansleep(fan_data->gpios[i]);
123*4882a593Smuzhiyun 		ctrl_val |= (value << i);
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun 	return ctrl_val;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun /* Must be called with fan_data->lock held, except during initialization. */
set_fan_speed(struct gpio_fan_data * fan_data,int speed_index)129*4882a593Smuzhiyun static void set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun 	if (fan_data->speed_index == speed_index)
132*4882a593Smuzhiyun 		return;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	__set_fan_ctrl(fan_data, fan_data->speed[speed_index].ctrl_val);
135*4882a593Smuzhiyun 	fan_data->speed_index = speed_index;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
get_fan_speed_index(struct gpio_fan_data * fan_data)138*4882a593Smuzhiyun static int get_fan_speed_index(struct gpio_fan_data *fan_data)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	int ctrl_val = __get_fan_ctrl(fan_data);
141*4882a593Smuzhiyun 	int i;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	for (i = 0; i < fan_data->num_speed; i++)
144*4882a593Smuzhiyun 		if (fan_data->speed[i].ctrl_val == ctrl_val)
145*4882a593Smuzhiyun 			return i;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	dev_warn(fan_data->dev,
148*4882a593Smuzhiyun 		 "missing speed array entry for GPIO value 0x%x\n", ctrl_val);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	return -ENODEV;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
rpm_to_speed_index(struct gpio_fan_data * fan_data,unsigned long rpm)153*4882a593Smuzhiyun static int rpm_to_speed_index(struct gpio_fan_data *fan_data, unsigned long rpm)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	struct gpio_fan_speed *speed = fan_data->speed;
156*4882a593Smuzhiyun 	int i;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	for (i = 0; i < fan_data->num_speed; i++)
159*4882a593Smuzhiyun 		if (speed[i].rpm >= rpm)
160*4882a593Smuzhiyun 			return i;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	return fan_data->num_speed - 1;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
pwm1_show(struct device * dev,struct device_attribute * attr,char * buf)165*4882a593Smuzhiyun static ssize_t pwm1_show(struct device *dev, struct device_attribute *attr,
166*4882a593Smuzhiyun 			 char *buf)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
169*4882a593Smuzhiyun 	u8 pwm = fan_data->speed_index * 255 / (fan_data->num_speed - 1);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", pwm);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
pwm1_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)174*4882a593Smuzhiyun static ssize_t pwm1_store(struct device *dev, struct device_attribute *attr,
175*4882a593Smuzhiyun 			  const char *buf, size_t count)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
178*4882a593Smuzhiyun 	unsigned long pwm;
179*4882a593Smuzhiyun 	int speed_index;
180*4882a593Smuzhiyun 	int ret = count;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	if (kstrtoul(buf, 10, &pwm) || pwm > 255)
183*4882a593Smuzhiyun 		return -EINVAL;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	mutex_lock(&fan_data->lock);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	if (!fan_data->pwm_enable) {
188*4882a593Smuzhiyun 		ret = -EPERM;
189*4882a593Smuzhiyun 		goto exit_unlock;
190*4882a593Smuzhiyun 	}
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	speed_index = DIV_ROUND_UP(pwm * (fan_data->num_speed - 1), 255);
193*4882a593Smuzhiyun 	set_fan_speed(fan_data, speed_index);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun exit_unlock:
196*4882a593Smuzhiyun 	mutex_unlock(&fan_data->lock);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	return ret;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
pwm1_enable_show(struct device * dev,struct device_attribute * attr,char * buf)201*4882a593Smuzhiyun static ssize_t pwm1_enable_show(struct device *dev,
202*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", fan_data->pwm_enable);
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun 
pwm1_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)209*4882a593Smuzhiyun static ssize_t pwm1_enable_store(struct device *dev,
210*4882a593Smuzhiyun 				 struct device_attribute *attr,
211*4882a593Smuzhiyun 				 const char *buf, size_t count)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
214*4882a593Smuzhiyun 	unsigned long val;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	if (kstrtoul(buf, 10, &val) || val > 1)
217*4882a593Smuzhiyun 		return -EINVAL;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (fan_data->pwm_enable == val)
220*4882a593Smuzhiyun 		return count;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	mutex_lock(&fan_data->lock);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	fan_data->pwm_enable = val;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	/* Disable manual control mode: set fan at full speed. */
227*4882a593Smuzhiyun 	if (val == 0)
228*4882a593Smuzhiyun 		set_fan_speed(fan_data, fan_data->num_speed - 1);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	mutex_unlock(&fan_data->lock);
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	return count;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
pwm1_mode_show(struct device * dev,struct device_attribute * attr,char * buf)235*4882a593Smuzhiyun static ssize_t pwm1_mode_show(struct device *dev,
236*4882a593Smuzhiyun 			      struct device_attribute *attr, char *buf)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	return sprintf(buf, "0\n");
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun 
fan1_min_show(struct device * dev,struct device_attribute * attr,char * buf)241*4882a593Smuzhiyun static ssize_t fan1_min_show(struct device *dev,
242*4882a593Smuzhiyun 			     struct device_attribute *attr, char *buf)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", fan_data->speed[0].rpm);
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
fan1_max_show(struct device * dev,struct device_attribute * attr,char * buf)249*4882a593Smuzhiyun static ssize_t fan1_max_show(struct device *dev,
250*4882a593Smuzhiyun 			     struct device_attribute *attr, char *buf)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	return sprintf(buf, "%d\n",
255*4882a593Smuzhiyun 		       fan_data->speed[fan_data->num_speed - 1].rpm);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
fan1_input_show(struct device * dev,struct device_attribute * attr,char * buf)258*4882a593Smuzhiyun static ssize_t fan1_input_show(struct device *dev,
259*4882a593Smuzhiyun 			       struct device_attribute *attr, char *buf)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", fan_data->speed[fan_data->speed_index].rpm);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
set_rpm(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)266*4882a593Smuzhiyun static ssize_t set_rpm(struct device *dev, struct device_attribute *attr,
267*4882a593Smuzhiyun 		       const char *buf, size_t count)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
270*4882a593Smuzhiyun 	unsigned long rpm;
271*4882a593Smuzhiyun 	int ret = count;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	if (kstrtoul(buf, 10, &rpm))
274*4882a593Smuzhiyun 		return -EINVAL;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	mutex_lock(&fan_data->lock);
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (!fan_data->pwm_enable) {
279*4882a593Smuzhiyun 		ret = -EPERM;
280*4882a593Smuzhiyun 		goto exit_unlock;
281*4882a593Smuzhiyun 	}
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	set_fan_speed(fan_data, rpm_to_speed_index(fan_data, rpm));
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun exit_unlock:
286*4882a593Smuzhiyun 	mutex_unlock(&fan_data->lock);
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	return ret;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun static DEVICE_ATTR_RW(pwm1);
292*4882a593Smuzhiyun static DEVICE_ATTR_RW(pwm1_enable);
293*4882a593Smuzhiyun static DEVICE_ATTR_RO(pwm1_mode);
294*4882a593Smuzhiyun static DEVICE_ATTR_RO(fan1_min);
295*4882a593Smuzhiyun static DEVICE_ATTR_RO(fan1_max);
296*4882a593Smuzhiyun static DEVICE_ATTR_RO(fan1_input);
297*4882a593Smuzhiyun static DEVICE_ATTR(fan1_target, 0644, fan1_input_show, set_rpm);
298*4882a593Smuzhiyun 
gpio_fan_is_visible(struct kobject * kobj,struct attribute * attr,int index)299*4882a593Smuzhiyun static umode_t gpio_fan_is_visible(struct kobject *kobj,
300*4882a593Smuzhiyun 				   struct attribute *attr, int index)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	struct device *dev = container_of(kobj, struct device, kobj);
303*4882a593Smuzhiyun 	struct gpio_fan_data *data = dev_get_drvdata(dev);
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	if (index == 0 && !data->alarm_gpio)
306*4882a593Smuzhiyun 		return 0;
307*4882a593Smuzhiyun 	if (index > 0 && !data->gpios)
308*4882a593Smuzhiyun 		return 0;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	return attr->mode;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun static struct attribute *gpio_fan_attributes[] = {
314*4882a593Smuzhiyun 	&dev_attr_fan1_alarm.attr,		/* 0 */
315*4882a593Smuzhiyun 	&dev_attr_pwm1.attr,			/* 1 */
316*4882a593Smuzhiyun 	&dev_attr_pwm1_enable.attr,
317*4882a593Smuzhiyun 	&dev_attr_pwm1_mode.attr,
318*4882a593Smuzhiyun 	&dev_attr_fan1_input.attr,
319*4882a593Smuzhiyun 	&dev_attr_fan1_target.attr,
320*4882a593Smuzhiyun 	&dev_attr_fan1_min.attr,
321*4882a593Smuzhiyun 	&dev_attr_fan1_max.attr,
322*4882a593Smuzhiyun 	NULL
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun static const struct attribute_group gpio_fan_group = {
326*4882a593Smuzhiyun 	.attrs = gpio_fan_attributes,
327*4882a593Smuzhiyun 	.is_visible = gpio_fan_is_visible,
328*4882a593Smuzhiyun };
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun static const struct attribute_group *gpio_fan_groups[] = {
331*4882a593Smuzhiyun 	&gpio_fan_group,
332*4882a593Smuzhiyun 	NULL
333*4882a593Smuzhiyun };
334*4882a593Smuzhiyun 
fan_ctrl_init(struct gpio_fan_data * fan_data)335*4882a593Smuzhiyun static int fan_ctrl_init(struct gpio_fan_data *fan_data)
336*4882a593Smuzhiyun {
337*4882a593Smuzhiyun 	int num_gpios = fan_data->num_gpios;
338*4882a593Smuzhiyun 	struct gpio_desc **gpios = fan_data->gpios;
339*4882a593Smuzhiyun 	int i, err;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	for (i = 0; i < num_gpios; i++) {
342*4882a593Smuzhiyun 		/*
343*4882a593Smuzhiyun 		 * The GPIO descriptors were retrieved with GPIOD_ASIS so here
344*4882a593Smuzhiyun 		 * we set the GPIO into output mode, carefully preserving the
345*4882a593Smuzhiyun 		 * current value by setting it to whatever it is already set
346*4882a593Smuzhiyun 		 * (no surprise changes in default fan speed).
347*4882a593Smuzhiyun 		 */
348*4882a593Smuzhiyun 		err = gpiod_direction_output(gpios[i],
349*4882a593Smuzhiyun 					gpiod_get_value_cansleep(gpios[i]));
350*4882a593Smuzhiyun 		if (err)
351*4882a593Smuzhiyun 			return err;
352*4882a593Smuzhiyun 	}
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	fan_data->pwm_enable = true; /* Enable manual fan speed control. */
355*4882a593Smuzhiyun 	fan_data->speed_index = get_fan_speed_index(fan_data);
356*4882a593Smuzhiyun 	if (fan_data->speed_index < 0)
357*4882a593Smuzhiyun 		return fan_data->speed_index;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	return 0;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
gpio_fan_get_max_state(struct thermal_cooling_device * cdev,unsigned long * state)362*4882a593Smuzhiyun static int gpio_fan_get_max_state(struct thermal_cooling_device *cdev,
363*4882a593Smuzhiyun 				  unsigned long *state)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = cdev->devdata;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	if (!fan_data)
368*4882a593Smuzhiyun 		return -EINVAL;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	*state = fan_data->num_speed - 1;
371*4882a593Smuzhiyun 	return 0;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun 
gpio_fan_get_cur_state(struct thermal_cooling_device * cdev,unsigned long * state)374*4882a593Smuzhiyun static int gpio_fan_get_cur_state(struct thermal_cooling_device *cdev,
375*4882a593Smuzhiyun 				  unsigned long *state)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = cdev->devdata;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	if (!fan_data)
380*4882a593Smuzhiyun 		return -EINVAL;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	*state = fan_data->speed_index;
383*4882a593Smuzhiyun 	return 0;
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun 
gpio_fan_set_cur_state(struct thermal_cooling_device * cdev,unsigned long state)386*4882a593Smuzhiyun static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev,
387*4882a593Smuzhiyun 				  unsigned long state)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = cdev->devdata;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	if (!fan_data)
392*4882a593Smuzhiyun 		return -EINVAL;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	if (state >= fan_data->num_speed)
395*4882a593Smuzhiyun 		return -EINVAL;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	set_fan_speed(fan_data, state);
398*4882a593Smuzhiyun 	return 0;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun static const struct thermal_cooling_device_ops gpio_fan_cool_ops = {
402*4882a593Smuzhiyun 	.get_max_state = gpio_fan_get_max_state,
403*4882a593Smuzhiyun 	.get_cur_state = gpio_fan_get_cur_state,
404*4882a593Smuzhiyun 	.set_cur_state = gpio_fan_set_cur_state,
405*4882a593Smuzhiyun };
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun /*
408*4882a593Smuzhiyun  * Translate OpenFirmware node properties into platform_data
409*4882a593Smuzhiyun  */
gpio_fan_get_of_data(struct gpio_fan_data * fan_data)410*4882a593Smuzhiyun static int gpio_fan_get_of_data(struct gpio_fan_data *fan_data)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun 	struct gpio_fan_speed *speed;
413*4882a593Smuzhiyun 	struct device *dev = fan_data->dev;
414*4882a593Smuzhiyun 	struct device_node *np = dev->of_node;
415*4882a593Smuzhiyun 	struct gpio_desc **gpios;
416*4882a593Smuzhiyun 	unsigned i;
417*4882a593Smuzhiyun 	u32 u;
418*4882a593Smuzhiyun 	struct property *prop;
419*4882a593Smuzhiyun 	const __be32 *p;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	/* Alarm GPIO if one exists */
422*4882a593Smuzhiyun 	fan_data->alarm_gpio = devm_gpiod_get_optional(dev, "alarm", GPIOD_IN);
423*4882a593Smuzhiyun 	if (IS_ERR(fan_data->alarm_gpio))
424*4882a593Smuzhiyun 		return PTR_ERR(fan_data->alarm_gpio);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	/* Fill GPIO pin array */
427*4882a593Smuzhiyun 	fan_data->num_gpios = gpiod_count(dev, NULL);
428*4882a593Smuzhiyun 	if (fan_data->num_gpios <= 0) {
429*4882a593Smuzhiyun 		if (fan_data->alarm_gpio)
430*4882a593Smuzhiyun 			return 0;
431*4882a593Smuzhiyun 		dev_err(dev, "DT properties empty / missing");
432*4882a593Smuzhiyun 		return -ENODEV;
433*4882a593Smuzhiyun 	}
434*4882a593Smuzhiyun 	gpios = devm_kcalloc(dev,
435*4882a593Smuzhiyun 			     fan_data->num_gpios, sizeof(struct gpio_desc *),
436*4882a593Smuzhiyun 			     GFP_KERNEL);
437*4882a593Smuzhiyun 	if (!gpios)
438*4882a593Smuzhiyun 		return -ENOMEM;
439*4882a593Smuzhiyun 	for (i = 0; i < fan_data->num_gpios; i++) {
440*4882a593Smuzhiyun 		gpios[i] = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
441*4882a593Smuzhiyun 		if (IS_ERR(gpios[i]))
442*4882a593Smuzhiyun 			return PTR_ERR(gpios[i]);
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun 	fan_data->gpios = gpios;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	/* Get number of RPM/ctrl_val pairs in speed map */
447*4882a593Smuzhiyun 	prop = of_find_property(np, "gpio-fan,speed-map", &i);
448*4882a593Smuzhiyun 	if (!prop) {
449*4882a593Smuzhiyun 		dev_err(dev, "gpio-fan,speed-map DT property missing");
450*4882a593Smuzhiyun 		return -ENODEV;
451*4882a593Smuzhiyun 	}
452*4882a593Smuzhiyun 	i = i / sizeof(u32);
453*4882a593Smuzhiyun 	if (i == 0 || i & 1) {
454*4882a593Smuzhiyun 		dev_err(dev, "gpio-fan,speed-map contains zero/odd number of entries");
455*4882a593Smuzhiyun 		return -ENODEV;
456*4882a593Smuzhiyun 	}
457*4882a593Smuzhiyun 	fan_data->num_speed = i / 2;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	/*
460*4882a593Smuzhiyun 	 * Populate speed map
461*4882a593Smuzhiyun 	 * Speed map is in the form <RPM ctrl_val RPM ctrl_val ...>
462*4882a593Smuzhiyun 	 * this needs splitting into pairs to create gpio_fan_speed structs
463*4882a593Smuzhiyun 	 */
464*4882a593Smuzhiyun 	speed = devm_kcalloc(dev,
465*4882a593Smuzhiyun 			fan_data->num_speed, sizeof(struct gpio_fan_speed),
466*4882a593Smuzhiyun 			GFP_KERNEL);
467*4882a593Smuzhiyun 	if (!speed)
468*4882a593Smuzhiyun 		return -ENOMEM;
469*4882a593Smuzhiyun 	p = NULL;
470*4882a593Smuzhiyun 	for (i = 0; i < fan_data->num_speed; i++) {
471*4882a593Smuzhiyun 		p = of_prop_next_u32(prop, p, &u);
472*4882a593Smuzhiyun 		if (!p)
473*4882a593Smuzhiyun 			return -ENODEV;
474*4882a593Smuzhiyun 		speed[i].rpm = u;
475*4882a593Smuzhiyun 		p = of_prop_next_u32(prop, p, &u);
476*4882a593Smuzhiyun 		if (!p)
477*4882a593Smuzhiyun 			return -ENODEV;
478*4882a593Smuzhiyun 		speed[i].ctrl_val = u;
479*4882a593Smuzhiyun 	}
480*4882a593Smuzhiyun 	fan_data->speed = speed;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	return 0;
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun static const struct of_device_id of_gpio_fan_match[] = {
486*4882a593Smuzhiyun 	{ .compatible = "gpio-fan", },
487*4882a593Smuzhiyun 	{},
488*4882a593Smuzhiyun };
489*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, of_gpio_fan_match);
490*4882a593Smuzhiyun 
gpio_fan_stop(void * data)491*4882a593Smuzhiyun static void gpio_fan_stop(void *data)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun 	set_fan_speed(data, 0);
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun 
gpio_fan_probe(struct platform_device * pdev)496*4882a593Smuzhiyun static int gpio_fan_probe(struct platform_device *pdev)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	int err;
499*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data;
500*4882a593Smuzhiyun 	struct device *dev = &pdev->dev;
501*4882a593Smuzhiyun 	struct device_node *np = dev->of_node;
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	fan_data = devm_kzalloc(dev, sizeof(struct gpio_fan_data),
504*4882a593Smuzhiyun 				GFP_KERNEL);
505*4882a593Smuzhiyun 	if (!fan_data)
506*4882a593Smuzhiyun 		return -ENOMEM;
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	fan_data->dev = dev;
509*4882a593Smuzhiyun 	err = gpio_fan_get_of_data(fan_data);
510*4882a593Smuzhiyun 	if (err)
511*4882a593Smuzhiyun 		return err;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	platform_set_drvdata(pdev, fan_data);
514*4882a593Smuzhiyun 	mutex_init(&fan_data->lock);
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	/* Configure control GPIOs if available. */
517*4882a593Smuzhiyun 	if (fan_data->gpios && fan_data->num_gpios > 0) {
518*4882a593Smuzhiyun 		if (!fan_data->speed || fan_data->num_speed <= 1)
519*4882a593Smuzhiyun 			return -EINVAL;
520*4882a593Smuzhiyun 		err = fan_ctrl_init(fan_data);
521*4882a593Smuzhiyun 		if (err)
522*4882a593Smuzhiyun 			return err;
523*4882a593Smuzhiyun 		err = devm_add_action_or_reset(dev, gpio_fan_stop, fan_data);
524*4882a593Smuzhiyun 		if (err)
525*4882a593Smuzhiyun 			return err;
526*4882a593Smuzhiyun 	}
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	/* Make this driver part of hwmon class. */
529*4882a593Smuzhiyun 	fan_data->hwmon_dev =
530*4882a593Smuzhiyun 		devm_hwmon_device_register_with_groups(dev,
531*4882a593Smuzhiyun 						       "gpio_fan", fan_data,
532*4882a593Smuzhiyun 						       gpio_fan_groups);
533*4882a593Smuzhiyun 	if (IS_ERR(fan_data->hwmon_dev))
534*4882a593Smuzhiyun 		return PTR_ERR(fan_data->hwmon_dev);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	/* Configure alarm GPIO if available. */
537*4882a593Smuzhiyun 	if (fan_data->alarm_gpio) {
538*4882a593Smuzhiyun 		err = fan_alarm_init(fan_data);
539*4882a593Smuzhiyun 		if (err)
540*4882a593Smuzhiyun 			return err;
541*4882a593Smuzhiyun 	}
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	/* Optional cooling device register for Device tree platforms */
544*4882a593Smuzhiyun 	fan_data->cdev = devm_thermal_of_cooling_device_register(dev, np,
545*4882a593Smuzhiyun 				"gpio-fan", fan_data, &gpio_fan_cool_ops);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	dev_info(dev, "GPIO fan initialized\n");
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	return 0;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
gpio_fan_shutdown(struct platform_device * pdev)552*4882a593Smuzhiyun static void gpio_fan_shutdown(struct platform_device *pdev)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	if (fan_data->gpios)
557*4882a593Smuzhiyun 		set_fan_speed(fan_data, 0);
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
gpio_fan_suspend(struct device * dev)561*4882a593Smuzhiyun static int gpio_fan_suspend(struct device *dev)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	if (fan_data->gpios) {
566*4882a593Smuzhiyun 		fan_data->resume_speed = fan_data->speed_index;
567*4882a593Smuzhiyun 		set_fan_speed(fan_data, 0);
568*4882a593Smuzhiyun 	}
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	return 0;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
gpio_fan_resume(struct device * dev)573*4882a593Smuzhiyun static int gpio_fan_resume(struct device *dev)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	if (fan_data->gpios)
578*4882a593Smuzhiyun 		set_fan_speed(fan_data, fan_data->resume_speed);
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	return 0;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
584*4882a593Smuzhiyun #define GPIO_FAN_PM	(&gpio_fan_pm)
585*4882a593Smuzhiyun #else
586*4882a593Smuzhiyun #define GPIO_FAN_PM	NULL
587*4882a593Smuzhiyun #endif
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun static struct platform_driver gpio_fan_driver = {
590*4882a593Smuzhiyun 	.probe		= gpio_fan_probe,
591*4882a593Smuzhiyun 	.shutdown	= gpio_fan_shutdown,
592*4882a593Smuzhiyun 	.driver	= {
593*4882a593Smuzhiyun 		.name	= "gpio-fan",
594*4882a593Smuzhiyun 		.pm	= GPIO_FAN_PM,
595*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(of_gpio_fan_match),
596*4882a593Smuzhiyun 	},
597*4882a593Smuzhiyun };
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun module_platform_driver(gpio_fan_driver);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
602*4882a593Smuzhiyun MODULE_DESCRIPTION("GPIO FAN driver");
603*4882a593Smuzhiyun MODULE_LICENSE("GPL");
604*4882a593Smuzhiyun MODULE_ALIAS("platform:gpio-fan");
605