diff -Naur lirc-0.8.2.old/drivers/lirc_imon/lirc_imon.c lirc-0.8.2.new/drivers/lirc_imon/lirc_imon.c --- lirc-0.8.2.old/drivers/lirc_imon/lirc_imon.c 2007-04-29 14:23:04.000000000 +0000 +++ lirc-0.8.2.new/drivers/lirc_imon/lirc_imon.c 2007-09-03 03:11:15.000000000 +0000 @@ -114,6 +114,10 @@ static ssize_t vfd_write (struct file *file, const char *buf, size_t n_bytes, loff_t *pos); +/* LCD-specific file_operations function prototypes */ +static ssize_t lcd_write (struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + /* LIRC plugin function prototypes */ static int ir_open (void *data); static void ir_close (void *data); @@ -232,6 +236,7 @@ static DECLARE_MUTEX (disconnect_sem); static int debug = 0; +static int islcd = 1; /* This should default to "0" and we auto-detect */ #if !defined(KERNEL_2_5) @@ -260,6 +265,8 @@ MODULE_DEVICE_TABLE (usb, imon_usb_id_table); module_param (debug, int, 0); MODULE_PARM_DESC (debug, "Debug messages: 0=no, 1=yes (default: no)"); +module_param (islcd, int, 1); +MODULE_PARM_DESC (islcd, "Is iMON LCD (as opposed to VFD): 0=no, 1=yes (default: yes)"); static inline void delete_context (struct imon_context *context) { @@ -634,6 +641,67 @@ } /** + * Writes data to the LCD. The iMON OEM LCD screen excepts 8-byte + * packets. We accept data as 16 hexadecimal digits, followed by a + * newline (to make it easy to drive the device from a command-line + * -- even though the actual binary data is a bit complicated). + * + * The device itself is not a "traditional" text-mode display. It's + * actually a 16x96 pixel bitmap display. That means if you want to + * display text, you've got to have your own "font" and translate the + * text into bitmaps for display. This is really flexible (you can + * display whatever diacritics you need, and so on), but it's also + * a lot more complicated than most LCDs... + */ +static ssize_t lcd_write (struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + + int i, n; + int retval = SUCCESS; + struct imon_context *context; + + context = (struct imon_context *) file ->private_data; + if (!context) { + err ("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context ->dev_present) { + err ("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes != 8) { + err ("%s: invalid payload size: %d (expecting 8)", __FUNCTION__, (int) n_bytes); + retval = -EINVAL; + goto exit; + } + + /* + * Not sure if there's any point copying the data to tx.data_buf and then + * to usb_tx_buf, but I'm new here :-) + */ + copy_from_user (context ->tx.data_buf, buf, n_bytes); + memcpy(context->usb_tx_buf, context ->tx.data_buf, 8); + + if ((retval = send_packet (context)) != SUCCESS) { + + err ("%s: send packet failed!", + __FUNCTION__); + goto exit; + } else if (debug) { + info ("%s: write %d bytes to LCD", __FUNCTION__, (int) n_bytes); + } +exit: + UNLOCK_CONTEXT; + return (retval == SUCCESS) ? n_bytes : retval; +} + +/** * Callback function for USB core API: transmit data */ #if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) @@ -971,6 +1039,12 @@ info ("%s: found IMON device", __FUNCTION__); + // We SHOULD detect this now, rather than just doing whatever our module + // parameters tells us... + if (islcd) { + vfd_fops.write = &lcd_write; + } + #if !defined(KERNEL_2_5) for (subminor = 0; subminor < MAX_DEVICES; ++subminor) { if (minor_table [subminor] == NULL)