aboutsummaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
Diffstat (limited to 'driver')
-rw-r--r--driver/Makefile14
-rw-r--r--driver/main.c20
-rw-r--r--driver/platform.c57
3 files changed, 70 insertions, 21 deletions
diff --git a/driver/Makefile b/driver/Makefile
index 7de7424..f9cb359 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -9,9 +9,17 @@ obj-m += lork.o
lork-y += main.o
lork-y += platform.o
-all:
+# utility
+ifneq ($(shell id -u),0)
+AS_ROOT := sudo -n
+endif
+.PHONY: FORCE
+
+lork.ko: FORCE
$(MAKE) -C $(KERNEL) M=$(PWD) modules
+all: lork.ko FORCE
+
# the generated compile_commands.json needs to be edited to point to the kernel
# folder as working directory because the include paths are relative
compile_commands.json:
@@ -19,3 +27,7 @@ compile_commands.json:
jq --arg dir $(KERNEL) '.[].directory = $$dir' $@.tmp > $@
$(RM) $@.tmp
+poke: lork.ko FORCE
+ $(AS_ROOT) insmod $<
+ $(AS_ROOT) rmmod $<
+
diff --git a/driver/main.c b/driver/main.c
index a322616..76ba1d8 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -23,26 +23,6 @@ struct platform_driver lork_driver = {
static int mod_init(void) {
printk("%s()\n", __PRETTY_FUNCTION__);
-
- // // configure gpio mux
- // uint32_t* conf_gpmc_a3 = ioremap(TI_AM335X_CM_GPMC_A3_ADDR, sizeof(ti_am335x_word_t));
- // if (conf_gpmc_a3 == NULL)
- // return -EINVAL;
- // barrier();
- // uint32_t val = ioread32(conf_gpmc_a3); rmb();
- // val &= ~0x7;
- // val |= 0x7;
- // iowrite32(val, conf_gpmc_a3); wmb();
- // iounmap(conf_gpmc_a3);
-
- // // configure output pin
- // ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE);
- // barrier();
- // ti_am335x_word_t oe_reg = ioread32(gpio1 + GPIO_OE); rmb();
- // oe_reg &= ~(1<<PIN); // 0=output
- // iowrite32(oe_reg, gpio1 + GPIO_OE); wmb();
- // iounmap(gpio1);
-
return platform_driver_register(&lork_driver);
}
diff --git a/driver/platform.c b/driver/platform.c
index 85aefec..da84064 100644
--- a/driver/platform.c
+++ b/driver/platform.c
@@ -1,6 +1,63 @@
#include "platform.h"
+#include <linux/types.h>
+#include <linux/of.h>
+
+#include <dt-bindings/gpio/gpio.h>
+
+// NOTE: i believe any nonzero return value for the probe function is
+// recognized as an error because of
+// <https://github.com/torvalds/linux/blob/a5131c3fdf2608f1c15f3809e201cf540eb28489/drivers/base/platform.c#L1004>
int lork_probe(struct platform_device* dev) {
+ // read gpios field from device tree
+ uint32_t dt_gpios[3];
+ of_property_read_u32_array(dev->dev.of_node, "gpios", dt_gpios, 3);
+
+ struct device_node* gpio1 = of_find_node_by_phandle(dt_gpios[0]);
+ uint32_t pin = dt_gpios[1];
+ uint32_t gpio_mode = dt_gpios[2];
+ printk("lork: configure pin %u w/ mode 0x%02x\n", pin, gpio_mode);
+
+ // find the multiplexer that controls pin
+ size_t len = of_property_count_u32_elems(gpio1, "gpio-ranges");
+ struct device_node* am33xx_pinmux = NULL;
+ for (size_t i = 0; i < len; i += 4) {
+ uint32_t phandle, pin_start, pin_offset, pin_size;
+ of_property_read_u32_index(gpio1, "gpio-ranges", i+0, &phandle);
+ of_property_read_u32_index(gpio1, "gpio-ranges", i+1, &pin_start);
+ of_property_read_u32_index(gpio1, "gpio-ranges", i+2, &pin_offset);
+ of_property_read_u32_index(gpio1, "gpio-ranges", i+3, &pin_size);
+
+ // get phandle for multiplexer corresponding to configured pin number
+ if (pin_start > pin || pin >= pin_start + pin_size) continue;
+
+ am33xx_pinmux = of_find_node_by_phandle(phandle);
+ printk("0x%02x, %u -> %u + %u\n", phandle, pin_start, pin_offset, pin_size);
+ break;
+ }
+ if (am33xx_pinmux == NULL) return EINVAL;
+
+ // TODO: ???
+
+ // // configure gpio mux
+ // uint32_t* conf_gpmc_a3 = ioremap(TI_AM335X_CM_GPMC_A3_ADDR, sizeof(ti_am335x_word_t));
+ // if (conf_gpmc_a3 == NULL)
+ // return -EINVAL;
+ // barrier();
+ // uint32_t val = ioread32(conf_gpmc_a3); rmb();
+ // val &= ~0x7;
+ // val |= 0x7;
+ // iowrite32(val, conf_gpmc_a3); wmb();
+ // iounmap(conf_gpmc_a3);
+
+ // // configure output pin
+ // ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE);
+ // barrier();
+ // ti_am335x_word_t oe_reg = ioread32(gpio1 + GPIO_OE); rmb();
+ // oe_reg &= ~(1<<PIN); // 0=output
+ // iowrite32(oe_reg, gpio1 + GPIO_OE); wmb();
+ // iounmap(gpio1);
+
printk("%s(%s)\n", __PRETTY_FUNCTION__, dev->name);
return 0;
}