Add gfrg240 support to gpio-mailbox.
Prowl has a temperature sensor and led controller
on the i2c bus. Teach gpio-mailbox about them.
Change-Id: Ia90bee0968bd961e3492b1f5f19bff1555bec0c4
diff --git a/gpio-mailbox/Makefile b/gpio-mailbox/Makefile
index bd29573..8d997a1 100644
--- a/gpio-mailbox/Makefile
+++ b/gpio-mailbox/Makefile
@@ -40,9 +40,7 @@
else ifeq ($(BR2_TARGET_GENERIC_PLATFORM_NAME),gfch100)
CFLAGS += -DGFCH100
else ifeq ($(BR2_TARGET_GENERIC_PLATFORM_NAME),gfrg240)
- # stub out gpio mailbox on gfrg240
- CFLAGS += -DSTUB
- LDFLAGS += -lm
+ CFLAGS += -DGFRG240
else ifeq ($(BR2_TARGET_GENERIC_PLATFORM_NAME),kvm)
CFLAGS += -DSTUB
LDFLAGS += -lm
diff --git a/gpio-mailbox/gfrg240.c b/gpio-mailbox/gfrg240.c
new file mode 100644
index 0000000..478953d
--- /dev/null
+++ b/gpio-mailbox/gfrg240.c
@@ -0,0 +1,133 @@
+#ifdef GFRG240
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fileops.h"
+#include "pin.h"
+
+struct PinHandle_s {
+ int unused;
+};
+
+struct systemp {
+ const char* value_path;
+};
+
+struct sysgpio {
+ const char* value_path;
+};
+
+struct platform_info {
+ const char *name;
+ struct systemp temp_cpu;
+ struct sysgpio led_red;
+ struct sysgpio led_activity;
+};
+
+struct platform_info platforms[] = {
+ {
+ .name = "GFRG240",
+ .temp_cpu = {
+ .value_path = "/sys/class/hwmon/hwmon0/temp1_input",
+ },
+ .led_red = {
+ .value_path = "/sys/class/leds/pca955x:1/brightness",
+ },
+ .led_activity = {
+ .value_path = "/sys/class/leds/pca955x:0/brightness",
+ },
+ }
+};
+
+struct platform_info *platform = &platforms[0];
+
+// Write the given sysfile
+static void set_sysfile(const char* s, int level) {
+ write_file_int(s, NULL, level);
+}
+
+// Read the given sysfile pin
+static int get_sysfile(const char* s) {
+ return read_file_long(s);
+}
+
+/* standard API follows */
+
+PinHandle PinCreate(void) {
+ PinHandle handle = (PinHandle) calloc(1, sizeof (*handle));
+ if (handle == NULL) {
+ perror("calloc(PinHandle)");
+ return NULL;
+ }
+ return handle;
+}
+
+void PinDestroy(PinHandle handle) {
+ if (handle == NULL)
+ return;
+
+ free(handle);
+}
+
+int PinIsPresent(PinHandle handle, PinId id) {
+ if (handle == NULL) return PIN_ERROR;
+ switch (id) {
+ case PIN_LED_RED:
+ case PIN_LED_ACTIVITY:
+ case PIN_TEMP_CPU:
+ return 1;
+
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+PinStatus PinValue(PinHandle handle, PinId id, int* valueP) {
+ if (handle == NULL) return PIN_ERROR;
+ switch (id) {
+ case PIN_LED_RED:
+ *valueP = get_sysfile(platform->led_red.value_path);
+ break;
+ case PIN_LED_ACTIVITY:
+ *valueP = get_sysfile(platform->led_activity.value_path);
+ break;
+ case PIN_TEMP_CPU:
+ *valueP = get_sysfile(platform->temp_cpu.value_path);
+ break;
+
+ default:
+ *valueP = -1;
+ return PIN_ERROR;
+ }
+ return PIN_OKAY;
+}
+
+PinStatus PinSetValue(PinHandle handle, PinId id, int value) {
+ int scaled;
+
+ if (handle == NULL) return PIN_ERROR;
+
+ /*
+ * gfrg240 led brightness control range is 0-255, value comes in 0-100.
+ * scale value up 2.5x so that we get the full brightness range.
+ */
+ scaled = (value * 25) / 10;
+ switch (id) {
+ case PIN_LED_RED:
+ set_sysfile(platform->led_red.value_path, scaled);
+ break;
+ case PIN_LED_ACTIVITY:
+ set_sysfile(platform->led_activity.value_path, scaled);
+ break;
+ default:
+ return PIN_ERROR;
+ }
+ return PIN_OKAY;
+}
+#endif /* GFRG240 */