aboutsummaryrefslogtreecommitdiff
path: root/driver/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/platform.c')
-rw-r--r--driver/platform.c57
1 files changed, 57 insertions, 0 deletions
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;
}