ThanksView
|
一、原理图
当前风扇控制支持 gpio 与pwm控制
二、gpio控制
|
ThanksView
|
驱动注册 static int pwm_fan_probe(struct platform_device *pdev) {struct thermal_cooling_device *cdev; struct pwm_fan_ctx *ctx; #ifdef HWMON struct device *hwmon; #endif int duty_cycle; int ret; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; mutex_init(&ctx->lock); ctx->dev = &pdev->dev; ctx->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL); if (IS_ERR(ctx->pwm)) { dev_err(&pdev->dev, "Could not get PWM\n"); return PTR_ERR(ctx->pwm); } ctx->pwm->state.polarity = ctx->pwm->args.polarity; platform_set_drvdata(pdev, ctx); /* Set duty cycle to maximum allowed */ duty_cycle = ctx->pwm->args.period - 1; ctx->pwm_value = MAX_PWM; ret = pwm_config(ctx->pwm, duty_cycle, ctx->pwm->args.period); if (ret) { dev_err(&pdev->dev, "Failed to configure PWM\n"); return ret; } /* Enbale PWM output */ ret = pwm_enable(ctx->pwm); if (ret) { dev_err(&pdev->dev, "Failed to enable PWM\n"); return ret; } #ifdef HWMON hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwm-fan", ctx, pwm_fan_groups); if (IS_ERR(hwmon)) { dev_err(&pdev->dev, "Failed to register hwmon device\n"); pwm_disable(ctx->pwm); return PTR_ERR(hwmon); } #endif ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx); if (ret) return ret; ctx->pwm_fan_state = ctx->pwm_fan_max_state; if (IS_ENABLED(CONFIG_THERMAL)) { cdev = thermal_of_cooling_device_register(pdev->dev.of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops); if (IS_ERR(cdev)) { dev_err(&pdev->dev, "Failed to register pwm-fan as cooling device"); pwm_disable(ctx->pwm); return PTR_ERR(cdev); } ctx->cdev = cdev; thermal_cdev_update(cdev); } return 0; }
驱动操作函数的实现
static const struct thermal_cooling_device_ops pwm_fan_cooling_ops = { unsigned long *state) { struct pwm_fan_ctx *ctx = cdev->devdata; if (!ctx) return -EINVAL; *state = ctx->pwm_fan_max_state; return 0; } static int pwm_fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { struct pwm_fan_ctx *ctx = cdev->devdata; if (!ctx) return -EINVAL; *state = ctx->pwm_fan_state; return 0; } static int pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { struct pwm_fan_ctx *ctx = cdev->devdata; int ret; if (!ctx || (state > ctx->pwm_fan_max_state)) return -EINVAL; if (state == ctx->pwm_fan_state) return 0; ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]); if (ret) { dev_err(&cdev->device, "Cannot set pwm!\n"); return ret; } ctx->pwm_fan_state = state; return ret; } static int pwm_fan_get_requested_power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, u32 *power) { return 0; }
风扇温控运转机制
struct thermal_zone_device *tz, unsigned long state, u32 *power) { return 0; } static int pwm_fan_power2state(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, u32 power, unsigned long *state) { if(tz->temperature > 70000 && tz->temperature <= 80000) { *state = 1; } else if(tz->temperature > 80000 && tz->temperature <= 100000) { *state = 2; } else if(tz->temperature > 100000 && tz->temperature <= 114000) { *state = 3; } return 0; } static int pwm_fan_monitor_fan(int temperature,unsigned long *state) { if(temperature < 50000) { *state = 0; } else if(temperature > 70000 && temperature <= 75000) { *state = 1; } else if(temperature > 75000 && temperature <= 100000) { *state = 2; } else if(temperature > 100000 && temperature <= 114000) { *state = 3; } return 0; } 添加无条件监控操作函数
//kernel/include/linux/thermal.h 调用新增的监控操作函数
//kernel/drivers/thermal/thermal_core.c
DTS设备树配置 fan0: pwm-fan {compatible = "pwm-fan"; cooling-min-state = <0>; cooling-max-state = <3>; #cooling-cells = <2>; pwms = <&pwm0 0 10000000 0>; cooling-levels = <0 100 150 255>; };
文章引用: https://blog.csdn.net/qq_23327993/article/details/122297468 |
三维半岛官网: http://www.thanksview.com
进入首页-
产品展示
物联网与人工智能 -
方案定制
嵌入式系统与液晶屏方案定制开发 -
技术支持
常见问题分析与解决