From 03bc533aff54929f0157a40a33685e9b021f3457 Mon Sep 17 00:00:00 2001 From: mmdolze Date: Sun, 7 Apr 2013 11:45:27 +0000 Subject: [PATCH] Add support for FreeBSD's iic I2C framework. --- ChangeLog | 1 + configure.ac | 2 +- server/drivers/hd44780-i2c.c | 60 ++++++++++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 350cf16..c3d9b33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ v0.5dev (ongoing development) * glcd driver: Add direct support for framebuffer with paged memory layout + hd44780: Added 'raspberrypi' connection type (P. Corner) * Build system: Rename configure.in to configure.ac + + hd44780: Add support for FreeBSD's iic I2C framework v0.5.6 - Remove deprecated CFontz633 driver. Use CFontzPacket with Model=633 instead! diff --git a/configure.ac b/configure.ac index 5010c42..1fde957 100644 --- a/configure.ac +++ b/configure.ac @@ -162,7 +162,7 @@ else fi x_ac_have_i2c=no -AC_CHECK_HEADERS([linux/i2c-dev.h], [x_ac_have_i2c=yes]) +AC_CHECK_HEADERS([linux/i2c-dev.h dev/iicbus/iic.h], [x_ac_have_i2c=yes]) if test "$x_ac_have_i2c" = yes; then AC_DEFINE(HAVE_I2C,[1],[Define to 1 if you have the i2c headers]) fi diff --git a/server/drivers/hd44780-i2c.c b/server/drivers/hd44780-i2c.c index aca8d83..0a5e45e 100644 --- a/server/drivers/hd44780-i2c.c +++ b/server/drivers/hd44780-i2c.c @@ -54,17 +54,26 @@ #include "hd44780-low.h" #include "report.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include #include #include #include #include #include + +#ifdef HAVE_DEV_IICBUS_IIC_H +#include +#else /* HAVE_LINUX_I2C_DEV_H */ #include /* I2C_SLAVE is missing in linux/i2c-dev.h from kernel headers of 2.4.x kernels */ #ifndef I2C_SLAVE #define I2C_SLAVE 0x0703 /* Change slave address */ #endif +#endif + // Generally, any function that accesses the LCD control lines needs to be // implemented separately for each HW design. This is typically (but not @@ -88,9 +97,14 @@ void i2c_HD44780_close(PrivateData *p); static void i2c_out(PrivateData *p, unsigned char val) { - __u8 data[2]; + char data[2]; int datalen; static int no_more_errormsgs=0; +#ifdef HAVE_DEV_IICBUS_IIC_H + struct iiccmd cmd; + bzero(&cmd, sizeof(cmd)); +#endif + if (p->port & I2C_PCAX_MASK) { // we have a PCA9554 or similar, that needs a 2-byte command data[0]=1; // command: read/write output port register data[1]=val; @@ -99,8 +113,18 @@ i2c_out(PrivateData *p, unsigned char val) data[0]=val; datalen=1; } + +#ifdef HAVE_DEV_IICBUS_IIC_H + cmd.slave = (p->port & I2C_ADDR_MASK) << 1; + cmd.last = 1; + cmd.count = datalen; + cmd.buf = data; + + if (ioctl(p->fd, I2CWRITE, &cmd) < 0) { +#else /* HAVE_LINUX_I2C_DEV_H */ if (write(p->fd,data,datalen) != datalen) { - p->hd44780_functions->drv_report(no_more_errormsgs?RPT_DEBUG:RPT_ERR, "HD44780: I2C: i2c write data %u to address %u failed: %s", +#endif + p->hd44780_functions->drv_report(no_more_errormsgs?RPT_DEBUG:RPT_ERR, "HD44780: I2C: i2c write data %u to address 0x%02X failed: %s", val, p->port & I2C_ADDR_MASK, strerror(errno)); no_more_errormsgs=1; } @@ -123,6 +147,11 @@ hd_init_i2c(Driver *drvthis) int enableLines = EN; char device[256] = DEFAULT_DEVICE; +#ifdef HAVE_DEV_IICBUS_IIC_H + struct iiccmd cmd; + bzero(&cmd, sizeof(cmd)); +#endif + p->backlight_bit = BL; /* READ CONFIG FILE */ @@ -130,7 +159,7 @@ hd_init_i2c(Driver *drvthis) /* Get serial device to use */ strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); device[sizeof(device)-1] = '\0'; - report(RPT_INFO,"HD44780: I2C: Using device '%s' and address %u for a %s", + report(RPT_INFO,"HD44780: I2C: Using device '%s' and address 0x%02X for a %s", device, p->port & I2C_ADDR_MASK, (p->port & I2C_PCAX_MASK) ? "PCA9554(A)" : "PCF8574(A)"); // Open the I2C device @@ -141,14 +170,27 @@ hd_init_i2c(Driver *drvthis) } // Set I2C address +#ifdef HAVE_DEV_IICBUS_IIC_H + cmd.slave = (p->port & I2C_ADDR_MASK) << 1; + cmd.last = 0; + cmd.count = 0; + if (ioctl(p->fd, I2CRSTCARD, &cmd) < 0) { + report(RPT_ERR, "HD44780: I2C: reset bus failed: %s", strerror(errno)); + return -1; + } + if (ioctl(p->fd, I2CSTART, &cmd) < 0) { + report(RPT_ERR, "HD44780: I2C: set address to 0x%02X: %s", p->port & I2C_ADDR_MASK, strerror(errno)); + return -1; + } +#else /* HAVE_LINUX_I2C_DEV_H */ if (ioctl(p->fd,I2C_SLAVE, p->port & I2C_ADDR_MASK) < 0) { report(RPT_ERR, "HD44780: I2C: set address to '%i': %s", p->port & I2C_ADDR_MASK, strerror(errno)); return(-1); } - +#endif if (p->port & I2C_PCAX_MASK) { // we have a PCA9554 or similar, that needs special config - __u8 data[2]; + char data[2]; data[0] = 2; // command: set polarity inversion data[1] = 0; // -> no polarity inversion if (write(p->fd,data,2) != 2) { @@ -216,14 +258,12 @@ hd_init_i2c(Driver *drvthis) return 0; } - -/** - * Close the device. - * \param p Pointer to driver's private data structure. - */ void i2c_HD44780_close(PrivateData *p) { if (p->fd >= 0) { +#ifdef HAVE_DEV_IICBUS_IIC_H + ioctl(p->fd, I2CSTOP); +#endif close(p->fd); } }