Skip to content

Instantly share code, notes, and snippets.

@heiher
Last active March 11, 2023 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heiher/971d227a3ef19217a17913abd3807a19 to your computer and use it in GitHub Desktop.
Save heiher/971d227a3ef19217a17913abd3807a19 to your computer and use it in GitHub Desktop.
CPU Fan control for 3C5000+7A2000
/*
============================================================================
Name : fanctl.c
Author : hev <r@hev.cc>
Copyright : Copyright (c) 2023 hev
Description : CPU Fan control for 3C5000+7A2000
============================================================================
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
static FILE *fp;
static void *pwm;
static int
temp_init (void)
{
fp = fopen ("/sys/class/hwmon/hwmon0/temp1_input", "r");
if (!fp)
return -1;
return 0;
}
static void
temp_fini (void)
{
fclose (fp);
}
static int
temp_read (void)
{
char buf[32];
int res;
res = fseek (fp, 0, SEEK_SET);
if (res < 0)
return -1;
res = fread (buf, sizeof (char), sizeof (buf) - 1, fp);
if (res <= 0)
return -1;
buf[res] = '\0';
return atoi (buf) / 1000;
}
static int
pwm_init (void)
{
int fd;
fd = open ("/dev/mem", O_RDWR | O_DSYNC);
if (fd < 0)
return -1;
pwm = mmap (NULL, 16384, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
0x100a0000UL);
if (pwm == MAP_FAILED)
return -2;
close (fd);
return 0;
}
static void
pwm_fini (void)
{
munmap (pwm, 16384);
}
static void
pwm_set (int low, int full)
{
/* disable */
*(volatile unsigned int *)(pwm + 0xC) = 0;
/* set low */
*(volatile unsigned int *)(pwm + 0x4) = low;
/* set full */
*(volatile unsigned int *)(pwm + 0x8) = full;
/* enable */
*(volatile unsigned int *)(pwm + 0xC) = 1;
}
int
main (int argc, char *argv[])
{
int res;
res = pwm_init ();
if (res < 0)
return -1;
res = temp_init ();
if (res < 0)
return -2;
for (;;) {
int temp;
temp = temp_read ();
switch (temp)
{
case 0 ... 15:
pwm_set (9000, 10000);
break;
case 16 ... 20:
pwm_set (8500, 10000);
break;
case 21 ... 25:
pwm_set (8000, 10000);
break;
case 26 ... 30:
pwm_set (7500, 10000);
break;
case 31 ... 35:
pwm_set (7000, 10000);
break;
case 36 ... 40:
pwm_set (6500, 10000);
break;
case 41 ... 45:
pwm_set (6000, 10000);
break;
case 46 ... 50:
pwm_set (5000, 10000);
break;
case 51 ... 55:
pwm_set (4000, 10000);
break;
case 56 ... 60:
pwm_set (3000, 10000);
break;
case 61 ... 65:
pwm_set (2000, 10000);
break;
case 66 ... 70:
pwm_set (1000, 10000);
break;
default:
pwm_set (100, 10000);
break;
}
sleep (1);
}
temp_fini ();
pwm_fini ();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment