Skip to content

Commit

Permalink
Initial version.
Browse files Browse the repository at this point in the history
  • Loading branch information
stefansundin committed Apr 10, 2015
0 parents commit 8557a78
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
powermate

Thumbs.db
.DS_Store
*.swp
2 changes: 2 additions & 0 deletions Makefile
@@ -0,0 +1,2 @@
powermate: main.c
gcc -o powermate main.c -O2 -s
23 changes: 23 additions & 0 deletions README.md
@@ -0,0 +1,23 @@
# PowerMate Linux Driver

This is a small Linux input driver for the Griffin PowerMate. Tested only on Ubuntu 14.10.


# Disclaimer

PowerMate is a registered trademark of Griffin Technologies Inc. This software is not affiliated or endorsed by them.


# Installation

Create a udev rule by creating the file `/etc/udev/rules.d/60-powermate.rules`

```
ACTION=="add", ENV{ID_USB_DRIVER}=="powermate", SYMLINK+="input/powermate", MODE="0666"
```

After creating the file, unplug and plug the PowerMate back in.

Compile the executable with `make` and run it with `./powermate`.

Make it run automatically on login somehow. The script should handle the device being disconnected and connected without problems.
90 changes: 90 additions & 0 deletions main.c
@@ -0,0 +1,90 @@
#include <stdio.h>
#include <linux/input.h>

int main(int argc, char *argv[]) {
// if (argc < 3) {
// fprintf(stderr, "Usage: %s /dev/input/powermate 1\n", argv[0]);
// fprintf(stderr, "The number is the percentage to change the volume with each input event.\n");
// return 1;
// }
// char *dev = argv[1];
// int p = atoi(argv[2]);

char dev[] = "/dev/input/powermate";
int p = 2;

// Test device
FILE *f = fopen(dev, "rb");
if (f == NULL) {
fprintf(stderr, "Could not open %s\n", dev);
return 2;
}
fclose(f);

// daemonize
int pid = fork();
if (pid == 0) {
// We're the child process!
// Release handle to working directory
chdir("/");
// Close things
fclose(stdin);
fclose(stdout);
fclose(stderr);
}
else if (pid < 0) {
fprintf(stderr, "Failed to become a daemon, whatevs.\n");
}
else {
printf("Just became a daemon, deal with it!\n");
return 0;
}

while (1) {
do {
f = fopen(dev, "rb");
if (f == NULL) {
fprintf(stderr, "Could not open %s\n", dev);
fprintf(stderr, "Sleeping 1 second.\n");
sleep(1);
}
} while (f == NULL);

while (!feof(f) && !ferror(f)) {
struct input_event ev;
size_t n = fread(&ev, 1, sizeof(ev), f);
// fprintf(stderr, "type: %d\n", ev.type);
// fprintf(stderr, "code: %d\n", ev.code);
// fprintf(stderr, "value: %d\n", ev.value);
// fprintf(stderr, "\n");
// fflush(stderr);

if (ev.type == 2 && ev.code == 7) {
char buf[100];
if (ev.value == -1) {
// counter clock-wise turn
sprintf(buf, "amixer -D pulse sset Master %d%%-", p);
system(buf);
}
else if (ev.value == 1) {
// clock-wise turn
sprintf(buf, "amixer -D pulse sset Master %d%%+", p);
system(buf);
}
}
if (ev.type == 1 && ev.code == 256) {
if (ev.value == 1) {
// knob depressed
system("amixer -D pulse set Master toggle");
}
else if (ev.value == 0) {
// knob released
}
}
}
fprintf(stderr, "Device disappeared.\n");
fclose(f);
}

return 0;
}

0 comments on commit 8557a78

Please sign in to comment.