#include #include "fopdrv.h" #include "config.h" bool printed = false; // driver/char/mem.c read_null (/dev/null) ssize_t fop_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { printk("%s(, , %u, )\n", __PRETTY_FUNCTION__, count); if (count < 2) return 0; if (printed) return 0; ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE); barrier(); ti_am335x_word_t gpio = ioread32(gpio1 + GPIO_DATAIN); rmb(); bool on = (gpio & (1< 0; char output[10]; snprintf(output, 10, "%d\n", on); if (copy_to_user(buf, output + *ppos, 2)) return -EFAULT; *ppos += 2; printed = true; return 2; } ssize_t fop_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { printk("%s(, , %u, )\n", __PRETTY_FUNCTION__, count); // only allow single character as input if (count < 1) return count; if (count > 2) return count; // copy buffer for reading (see [kernel-labs-chrdev] in ../readme.md) char input_buf[10]; 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<, )\n", __PRETTY_FUNCTION__); printed = false; return 0; // 0 seems to be a safe return value as it's used in driver/char/mem.c. The // manual page for open(2) says that the system call returns a nonnegative // integer representing the file descriptor on success, but it does not // appears to be required. } int fop_release(struct inode * inode, struct file * file) { printk("%s(, )\n", __PRETTY_FUNCTION__); return 0; // same as above, but found in driver/char/lp.c }