brintos

brintos / linux-shallow public Read only

0
0
Text · 15.2 KiB · c434db4 Raw
699 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * pwm-fan.c - Hwmon driver for fans connected to PWM lines.4 *5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.6 *7 * Author: Kamil Debski <k.debski@samsung.com>8 */9 10#include <linux/hwmon.h>11#include <linux/interrupt.h>12#include <linux/mod_devicetable.h>13#include <linux/module.h>14#include <linux/mutex.h>15#include <linux/platform_device.h>16#include <linux/property.h>17#include <linux/pwm.h>18#include <linux/regulator/consumer.h>19#include <linux/sysfs.h>20#include <linux/thermal.h>21#include <linux/timer.h>22 23#define MAX_PWM 25524 25struct pwm_fan_tach {26	int irq;27	atomic_t pulses;28	unsigned int rpm;29};30 31enum pwm_fan_enable_mode {32	pwm_off_reg_off,33	pwm_disable_reg_enable,34	pwm_enable_reg_enable,35	pwm_disable_reg_disable,36};37 38struct pwm_fan_ctx {39	struct device *dev;40 41	struct mutex lock;42	struct pwm_device *pwm;43	struct pwm_state pwm_state;44	struct regulator *reg_en;45	enum pwm_fan_enable_mode enable_mode;46	bool regulator_enabled;47	bool enabled;48 49	int tach_count;50	struct pwm_fan_tach *tachs;51	u32 *pulses_per_revolution;52	ktime_t sample_start;53	struct timer_list rpm_timer;54 55	unsigned int pwm_value;56	unsigned int pwm_fan_state;57	unsigned int pwm_fan_max_state;58	unsigned int *pwm_fan_cooling_levels;59	struct thermal_cooling_device *cdev;60 61	struct hwmon_chip_info info;62	struct hwmon_channel_info fan_channel;63};64 65/* This handler assumes self resetting edge triggered interrupt. */66static irqreturn_t pulse_handler(int irq, void *dev_id)67{68	struct pwm_fan_tach *tach = dev_id;69 70	atomic_inc(&tach->pulses);71 72	return IRQ_HANDLED;73}74 75static void sample_timer(struct timer_list *t)76{77	struct pwm_fan_ctx *ctx = from_timer(ctx, t, rpm_timer);78	unsigned int delta = ktime_ms_delta(ktime_get(), ctx->sample_start);79	int i;80 81	if (delta) {82		for (i = 0; i < ctx->tach_count; i++) {83			struct pwm_fan_tach *tach = &ctx->tachs[i];84			int pulses;85 86			pulses = atomic_read(&tach->pulses);87			atomic_sub(pulses, &tach->pulses);88			tach->rpm = (unsigned int)(pulses * 1000 * 60) /89				(ctx->pulses_per_revolution[i] * delta);90		}91 92		ctx->sample_start = ktime_get();93	}94 95	mod_timer(&ctx->rpm_timer, jiffies + HZ);96}97 98static void pwm_fan_enable_mode_2_state(int enable_mode,99					struct pwm_state *state,100					bool *enable_regulator)101{102	switch (enable_mode) {103	case pwm_disable_reg_enable:104		/* disable pwm, keep regulator enabled */105		state->enabled = false;106		*enable_regulator = true;107		break;108	case pwm_enable_reg_enable:109		/* keep pwm and regulator enabled */110		state->enabled = true;111		*enable_regulator = true;112		break;113	case pwm_off_reg_off:114	case pwm_disable_reg_disable:115		/* disable pwm and regulator */116		state->enabled = false;117		*enable_regulator = false;118	}119}120 121static int pwm_fan_switch_power(struct pwm_fan_ctx *ctx, bool on)122{123	int ret = 0;124 125	if (!ctx->reg_en)126		return ret;127 128	if (!ctx->regulator_enabled && on) {129		ret = regulator_enable(ctx->reg_en);130		if (ret == 0)131			ctx->regulator_enabled = true;132	} else if (ctx->regulator_enabled && !on) {133		ret = regulator_disable(ctx->reg_en);134		if (ret == 0)135			ctx->regulator_enabled = false;136	}137	return ret;138}139 140static int pwm_fan_power_on(struct pwm_fan_ctx *ctx)141{142	struct pwm_state *state = &ctx->pwm_state;143	int ret;144 145	if (ctx->enabled)146		return 0;147 148	ret = pwm_fan_switch_power(ctx, true);149	if (ret < 0) {150		dev_err(ctx->dev, "failed to enable power supply\n");151		return ret;152	}153 154	state->enabled = true;155	ret = pwm_apply_might_sleep(ctx->pwm, state);156	if (ret) {157		dev_err(ctx->dev, "failed to enable PWM\n");158		goto disable_regulator;159	}160 161	ctx->enabled = true;162 163	return 0;164 165disable_regulator:166	pwm_fan_switch_power(ctx, false);167	return ret;168}169 170static int pwm_fan_power_off(struct pwm_fan_ctx *ctx, bool force_disable)171{172	struct pwm_state *state = &ctx->pwm_state;173	bool enable_regulator = false;174	int ret;175 176	if (!ctx->enabled)177		return 0;178 179	pwm_fan_enable_mode_2_state(ctx->enable_mode,180				    state,181				    &enable_regulator);182 183	if (force_disable)184		state->enabled = false;185	state->duty_cycle = 0;186	ret = pwm_apply_might_sleep(ctx->pwm, state);187	if (ret) {188		dev_err(ctx->dev, "failed to disable PWM\n");189		return ret;190	}191 192	pwm_fan_switch_power(ctx, enable_regulator);193 194	ctx->enabled = false;195 196	return 0;197}198 199static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)200{201	struct pwm_state *state = &ctx->pwm_state;202	unsigned long period;203	int ret = 0;204 205	if (pwm > 0) {206		if (ctx->enable_mode == pwm_off_reg_off)207			/* pwm-fan hard disabled */208			return 0;209 210		period = state->period;211		state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM);212		ret = pwm_apply_might_sleep(ctx->pwm, state);213		if (ret)214			return ret;215		ret = pwm_fan_power_on(ctx);216	} else {217		ret = pwm_fan_power_off(ctx, false);218	}219	if (!ret)220		ctx->pwm_value = pwm;221 222	return ret;223}224 225static int set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)226{227	int ret;228 229	mutex_lock(&ctx->lock);230	ret = __set_pwm(ctx, pwm);231	mutex_unlock(&ctx->lock);232 233	return ret;234}235 236static void pwm_fan_update_state(struct pwm_fan_ctx *ctx, unsigned long pwm)237{238	int i;239 240	for (i = 0; i < ctx->pwm_fan_max_state; ++i)241		if (pwm < ctx->pwm_fan_cooling_levels[i + 1])242			break;243 244	ctx->pwm_fan_state = i;245}246 247static int pwm_fan_update_enable(struct pwm_fan_ctx *ctx, long val)248{249	int ret = 0;250	int old_val;251 252	mutex_lock(&ctx->lock);253 254	if (ctx->enable_mode == val)255		goto out;256 257	old_val = ctx->enable_mode;258	ctx->enable_mode = val;259 260	if (val == 0) {261		/* Disable pwm-fan unconditionally */262		if (ctx->enabled)263			ret = __set_pwm(ctx, 0);264		else265			ret = pwm_fan_switch_power(ctx, false);266		if (ret)267			ctx->enable_mode = old_val;268		pwm_fan_update_state(ctx, 0);269	} else {270		/*271		 * Change PWM and/or regulator state if currently disabled272		 * Nothing to do if currently enabled273		 */274		if (!ctx->enabled) {275			struct pwm_state *state = &ctx->pwm_state;276			bool enable_regulator = false;277 278			state->duty_cycle = 0;279			pwm_fan_enable_mode_2_state(val,280						    state,281						    &enable_regulator);282 283			pwm_apply_might_sleep(ctx->pwm, state);284			pwm_fan_switch_power(ctx, enable_regulator);285			pwm_fan_update_state(ctx, 0);286		}287	}288out:289	mutex_unlock(&ctx->lock);290 291	return ret;292}293 294static int pwm_fan_write(struct device *dev, enum hwmon_sensor_types type,295			 u32 attr, int channel, long val)296{297	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);298	int ret;299 300	switch (attr) {301	case hwmon_pwm_input:302		if (val < 0 || val > MAX_PWM)303			return -EINVAL;304		ret = set_pwm(ctx, val);305		if (ret)306			return ret;307		pwm_fan_update_state(ctx, val);308		break;309	case hwmon_pwm_enable:310		if (val < 0 || val > 3)311			ret = -EINVAL;312		else313			ret = pwm_fan_update_enable(ctx, val);314 315		return ret;316	default:317		return -EOPNOTSUPP;318	}319 320	return 0;321}322 323static int pwm_fan_read(struct device *dev, enum hwmon_sensor_types type,324			u32 attr, int channel, long *val)325{326	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);327 328	switch (type) {329	case hwmon_pwm:330		switch (attr) {331		case hwmon_pwm_input:332			*val = ctx->pwm_value;333			return 0;334		case hwmon_pwm_enable:335			*val = ctx->enable_mode;336			return 0;337		}338		return -EOPNOTSUPP;339	case hwmon_fan:340		*val = ctx->tachs[channel].rpm;341		return 0;342 343	default:344		return -ENOTSUPP;345	}346}347 348static umode_t pwm_fan_is_visible(const void *data,349				  enum hwmon_sensor_types type,350				  u32 attr, int channel)351{352	switch (type) {353	case hwmon_pwm:354		return 0644;355 356	case hwmon_fan:357		return 0444;358 359	default:360		return 0;361	}362}363 364static const struct hwmon_ops pwm_fan_hwmon_ops = {365	.is_visible = pwm_fan_is_visible,366	.read = pwm_fan_read,367	.write = pwm_fan_write,368};369 370/* thermal cooling device callbacks */371static int pwm_fan_get_max_state(struct thermal_cooling_device *cdev,372				 unsigned long *state)373{374	struct pwm_fan_ctx *ctx = cdev->devdata;375 376	if (!ctx)377		return -EINVAL;378 379	*state = ctx->pwm_fan_max_state;380 381	return 0;382}383 384static int pwm_fan_get_cur_state(struct thermal_cooling_device *cdev,385				 unsigned long *state)386{387	struct pwm_fan_ctx *ctx = cdev->devdata;388 389	if (!ctx)390		return -EINVAL;391 392	*state = ctx->pwm_fan_state;393 394	return 0;395}396 397static int398pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)399{400	struct pwm_fan_ctx *ctx = cdev->devdata;401	int ret;402 403	if (!ctx || (state > ctx->pwm_fan_max_state))404		return -EINVAL;405 406	if (state == ctx->pwm_fan_state)407		return 0;408 409	ret = set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]);410	if (ret) {411		dev_err(&cdev->device, "Cannot set pwm!\n");412		return ret;413	}414 415	ctx->pwm_fan_state = state;416 417	return ret;418}419 420static const struct thermal_cooling_device_ops pwm_fan_cooling_ops = {421	.get_max_state = pwm_fan_get_max_state,422	.get_cur_state = pwm_fan_get_cur_state,423	.set_cur_state = pwm_fan_set_cur_state,424};425 426static int pwm_fan_get_cooling_data(struct device *dev, struct pwm_fan_ctx *ctx)427{428	int num, i, ret;429 430	if (!device_property_present(dev, "cooling-levels"))431		return 0;432 433	ret = device_property_count_u32(dev, "cooling-levels");434	if (ret <= 0) {435		dev_err(dev, "Wrong data!\n");436		return ret ? : -EINVAL;437	}438 439	num = ret;440	ctx->pwm_fan_cooling_levels = devm_kcalloc(dev, num, sizeof(u32),441						   GFP_KERNEL);442	if (!ctx->pwm_fan_cooling_levels)443		return -ENOMEM;444 445	ret = device_property_read_u32_array(dev, "cooling-levels",446					     ctx->pwm_fan_cooling_levels, num);447	if (ret) {448		dev_err(dev, "Property 'cooling-levels' cannot be read!\n");449		return ret;450	}451 452	for (i = 0; i < num; i++) {453		if (ctx->pwm_fan_cooling_levels[i] > MAX_PWM) {454			dev_err(dev, "PWM fan state[%d]:%d > %d\n", i,455				ctx->pwm_fan_cooling_levels[i], MAX_PWM);456			return -EINVAL;457		}458	}459 460	ctx->pwm_fan_max_state = num - 1;461 462	return 0;463}464 465static void pwm_fan_cleanup(void *__ctx)466{467	struct pwm_fan_ctx *ctx = __ctx;468 469	del_timer_sync(&ctx->rpm_timer);470	/* Switch off everything */471	ctx->enable_mode = pwm_disable_reg_disable;472	pwm_fan_power_off(ctx, true);473}474 475static int pwm_fan_probe(struct platform_device *pdev)476{477	struct thermal_cooling_device *cdev;478	struct device *dev = &pdev->dev;479	struct pwm_fan_ctx *ctx;480	struct device *hwmon;481	int ret;482	const struct hwmon_channel_info **channels;483	u32 *fan_channel_config;484	int channel_count = 1;	/* We always have a PWM channel. */485	int i;486 487	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);488	if (!ctx)489		return -ENOMEM;490 491	mutex_init(&ctx->lock);492 493	ctx->dev = &pdev->dev;494	ctx->pwm = devm_pwm_get(dev, NULL);495	if (IS_ERR(ctx->pwm))496		return dev_err_probe(dev, PTR_ERR(ctx->pwm), "Could not get PWM\n");497 498	platform_set_drvdata(pdev, ctx);499 500	ctx->reg_en = devm_regulator_get_optional(dev, "fan");501	if (IS_ERR(ctx->reg_en)) {502		if (PTR_ERR(ctx->reg_en) != -ENODEV)503			return PTR_ERR(ctx->reg_en);504 505		ctx->reg_en = NULL;506	}507 508	pwm_init_state(ctx->pwm, &ctx->pwm_state);509 510	/*511	 * PWM fans are controlled solely by the duty cycle of the PWM signal,512	 * they do not care about the exact timing. Thus set usage_power to true513	 * to allow less flexible hardware to work as a PWM source for fan514	 * control.515	 */516	ctx->pwm_state.usage_power = true;517 518	/*519	 * set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned520	 * long. Check this here to prevent the fan running at a too low521	 * frequency.522	 */523	if (ctx->pwm_state.period > ULONG_MAX / MAX_PWM + 1) {524		dev_err(dev, "Configured period too big\n");525		return -EINVAL;526	}527 528	ctx->enable_mode = pwm_disable_reg_enable;529 530	/*531	 * Set duty cycle to maximum allowed and enable PWM output as well as532	 * the regulator. In case of error nothing is changed533	 */534	ret = set_pwm(ctx, MAX_PWM);535	if (ret) {536		dev_err(dev, "Failed to configure PWM: %d\n", ret);537		return ret;538	}539	timer_setup(&ctx->rpm_timer, sample_timer, 0);540	ret = devm_add_action_or_reset(dev, pwm_fan_cleanup, ctx);541	if (ret)542		return ret;543 544	ctx->tach_count = platform_irq_count(pdev);545	if (ctx->tach_count < 0)546		return dev_err_probe(dev, ctx->tach_count,547				     "Could not get number of fan tachometer inputs\n");548	dev_dbg(dev, "%d fan tachometer inputs\n", ctx->tach_count);549 550	if (ctx->tach_count) {551		channel_count++;	/* We also have a FAN channel. */552 553		ctx->tachs = devm_kcalloc(dev, ctx->tach_count,554					  sizeof(struct pwm_fan_tach),555					  GFP_KERNEL);556		if (!ctx->tachs)557			return -ENOMEM;558 559		ctx->fan_channel.type = hwmon_fan;560		fan_channel_config = devm_kcalloc(dev, ctx->tach_count + 1,561						  sizeof(u32), GFP_KERNEL);562		if (!fan_channel_config)563			return -ENOMEM;564		ctx->fan_channel.config = fan_channel_config;565 566		ctx->pulses_per_revolution = devm_kmalloc_array(dev,567								ctx->tach_count,568								sizeof(*ctx->pulses_per_revolution),569								GFP_KERNEL);570		if (!ctx->pulses_per_revolution)571			return -ENOMEM;572 573		/* Setup default pulses per revolution */574		for (i = 0; i < ctx->tach_count; i++)575			ctx->pulses_per_revolution[i] = 2;576 577		device_property_read_u32_array(dev, "pulses-per-revolution",578					       ctx->pulses_per_revolution, ctx->tach_count);579	}580 581	channels = devm_kcalloc(dev, channel_count + 1,582				sizeof(struct hwmon_channel_info *), GFP_KERNEL);583	if (!channels)584		return -ENOMEM;585 586	channels[0] = HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_ENABLE);587 588	for (i = 0; i < ctx->tach_count; i++) {589		struct pwm_fan_tach *tach = &ctx->tachs[i];590 591		tach->irq = platform_get_irq(pdev, i);592		if (tach->irq == -EPROBE_DEFER)593			return tach->irq;594		if (tach->irq > 0) {595			ret = devm_request_irq(dev, tach->irq, pulse_handler, 0,596					       pdev->name, tach);597			if (ret) {598				dev_err(dev,599					"Failed to request interrupt: %d\n",600					ret);601				return ret;602			}603		}604 605		if (!ctx->pulses_per_revolution[i]) {606			dev_err(dev, "pulses-per-revolution can't be zero.\n");607			return -EINVAL;608		}609 610		fan_channel_config[i] = HWMON_F_INPUT;611 612		dev_dbg(dev, "tach%d: irq=%d, pulses_per_revolution=%d\n",613			i, tach->irq, ctx->pulses_per_revolution[i]);614	}615 616	if (ctx->tach_count > 0) {617		ctx->sample_start = ktime_get();618		mod_timer(&ctx->rpm_timer, jiffies + HZ);619 620		channels[1] = &ctx->fan_channel;621	}622 623	ctx->info.ops = &pwm_fan_hwmon_ops;624	ctx->info.info = channels;625 626	hwmon = devm_hwmon_device_register_with_info(dev, "pwmfan",627						     ctx, &ctx->info, NULL);628	if (IS_ERR(hwmon)) {629		dev_err(dev, "Failed to register hwmon device\n");630		return PTR_ERR(hwmon);631	}632 633	ret = pwm_fan_get_cooling_data(dev, ctx);634	if (ret)635		return ret;636 637	ctx->pwm_fan_state = ctx->pwm_fan_max_state;638	if (IS_ENABLED(CONFIG_THERMAL)) {639		cdev = devm_thermal_of_cooling_device_register(dev,640			dev->of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops);641		if (IS_ERR(cdev)) {642			ret = PTR_ERR(cdev);643			dev_err(dev,644				"Failed to register pwm-fan as cooling device: %d\n",645				ret);646			return ret;647		}648		ctx->cdev = cdev;649	}650 651	return 0;652}653 654static void pwm_fan_shutdown(struct platform_device *pdev)655{656	struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);657 658	pwm_fan_cleanup(ctx);659}660 661static int pwm_fan_suspend(struct device *dev)662{663	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);664 665	return pwm_fan_power_off(ctx, true);666}667 668static int pwm_fan_resume(struct device *dev)669{670	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);671 672	return set_pwm(ctx, ctx->pwm_value);673}674 675static DEFINE_SIMPLE_DEV_PM_OPS(pwm_fan_pm, pwm_fan_suspend, pwm_fan_resume);676 677static const struct of_device_id of_pwm_fan_match[] = {678	{ .compatible = "pwm-fan", },679	{},680};681MODULE_DEVICE_TABLE(of, of_pwm_fan_match);682 683static struct platform_driver pwm_fan_driver = {684	.probe		= pwm_fan_probe,685	.shutdown	= pwm_fan_shutdown,686	.driver	= {687		.name		= "pwm-fan",688		.pm		= pm_sleep_ptr(&pwm_fan_pm),689		.of_match_table	= of_pwm_fan_match,690	},691};692 693module_platform_driver(pwm_fan_driver);694 695MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");696MODULE_ALIAS("platform:pwm-fan");697MODULE_DESCRIPTION("PWM FAN driver");698MODULE_LICENSE("GPL");699