diff options
| -rw-r--r-- | 1/config.h | 15 | ||||
| -rw-r--r-- | 1/fopdrv.c | 11 | ||||
| -rw-r--r-- | 1/main.c | 21 | ||||
| -rw-r--r-- | readme.md | 4 | 
4 files changed, 48 insertions, 3 deletions
@@ -9,7 +9,18 @@  typedef uint32_t ti_am335x_word_t;  // p. 180: "Control Module" -#define TI_AM335X_CM_ADDR ((ti_am335x_word_t*) 0x44E1_0000) +#define TI_AM335X_CM_ADDR 0x44E10000 +// p. 182: "GPIO1" +#define TI_AM335X_GPIO1_ADDR 0x4804C000  // p. 1459: "conf_gpmc_a3" -#define TI_AM335X_CM_GPMC_A3_ADDR ((ti_am335x_word_t*) TI_AM3358_CM_ADDR + 0x84Ch) +#define TI_AM335X_CM_GPMC_A3_ADDR (TI_AM335X_CM_ADDR + 0x84C) +// p. 4990, variable names copied as-is +#define GPIO_OE (0x134 / (sizeof(ti_am335x_word_t))) +#define GPIO_DATAIN (0x138 / (sizeof(ti_am335x_word_t))) +#define GPIO_CLEARDATAOUT (0x190 / (sizeof(ti_am335x_word_t))) +#define GPIO_SETDATAOUT (0x194 / (sizeof(ti_am335x_word_t))) +// total size of GPIO registers from p. 4990 (in bytes) +#define GPIO_REG_SIZE 0x198 + +#define PIN 19 @@ -1,4 +1,7 @@ +#include <linux/io.h> +  #include "fopdrv.h" +#include "config.h"  // driver/char/mem.c read_null (/dev/null)  ssize_t fop_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -6,7 +9,6 @@ ssize_t fop_read(struct file *file, char __user *buf, size_t count, loff_t *ppos  	return 0;  } -// driver/char/mem.c write_null  ssize_t fop_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {  	printk("%s(<file>, <buf>, %u, <ppos>)\n", __PRETTY_FUNCTION__, count); @@ -18,13 +20,20 @@ ssize_t fop_write(struct file *file, const char __user *buf, size_t count, loff_  	if (copy_from_user(input_buf + *ppos, buf, count))  		return -EFAULT; +	ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE); +	barrier(); +  	if (input_buf[0] == '0') {  		printk("TODO: TURN OFF OUTPUT\n"); +		iowrite32((1<<PIN), gpio1 + GPIO_CLEARDATAOUT); wmb();  	}  	if (input_buf[0] == '1') {  		printk("TODO: TURN ON OUTPUT\n"); +		iowrite32((1<<PIN), gpio1 + GPIO_SETDATAOUT); wmb();  	} +	iounmap(gpio1); +  	return count;  } @@ -1,6 +1,7 @@  #include <linux/cdev.h>  #include <linux/init.h>  #include <linux/module.h> +#include <linux/io.h>  #include "fopdrv.h"  #include "config.h" @@ -63,6 +64,26 @@ static int mod_init(void) {  	printk("%s() -> 0 (%d:%d)\n", __PRETTY_FUNCTION__, MAJOR(node), MINOR(node));  	printk("one = %d, two = %d\n", one, not_named_two); + +	// 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 0;  free_device: @@ -13,6 +13,8 @@  - [Linux kernel labs - character device drivers][kernel-labs-chrdev]  - [Core API][core-api]  - [Driver API][driver-api] +- [AM335x Technical reference manual][ti-am335x-rm] +- [BeagleBone Black system reference manual][bbb-srm]  [kbuild-obj-var]: https://docs.kernel.org/kbuild/makefiles.html#loadable-module-goals-obj-m  [kbuild-module-makefile]: https://www.kernel.org/doc/html/latest/kbuild/modules.html#creating-a-kbuild-file-for-an-external-module @@ -21,6 +23,8 @@  [kernel-labs-chrdev]: https://linux-kernel-labs.github.io/refs/heads/master/labs/device_drivers.html  [core-api]: https://docs.kernel.org/core-api/kernel-api.html  [driver-api]: https://www.kernel.org/doc/html/latest/driver-api/infrastructure.html +[ti-am335x-rm]: https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf +[bbb-srm]: https://cdn-shop.adafruit.com/datasheets/BBB_SRM.pdf  # tips  |