Base: LCDproc 0.5.2
[lcdproc-de200c.git] / server / drivers / hd44780-bwct-usb.c
blob7919c13fe3db4616c9528a1da2126a6f5879a46e
1 /*
2 * USB driver module for Hitachi HD44780 based LCD displays.
3 * http://www.bwct.de/lcd.html
5 * Copyright (c) 2004, Bernd Walter <bernd@bwct.de>
6 * Contributions:
7 * Copyright (c) 2004, Peter Marschall <peter@adpm.de>
9 * This file is released under the GNU General Public License. Refer to the
10 * COPYING file distributed with this package.
14 #include "hd44780-bwct-usb.h"
16 #include "report.h"
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <usb.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <fcntl.h>
27 #include <errno.h>
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
34 /* USB device handle & interface index we write to */
35 static usb_dev_handle *bwct_usb;
36 static int bwct_usb_i;
39 // initialize the driver
40 int
41 hd_init_bwct_usb(Driver *drvthis)
43 PrivateData *p = (PrivateData*) drvthis->private_data;
45 struct usb_bus *bus;
46 //char device_manufacturer[LCD_MAX_WIDTH+1] = "";
47 char device_serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO;
48 char serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO;
49 int contrast = -1; /* illegal contrast value (to detect errors) */
51 p->hd44780_functions->senddata = bwct_usb_HD44780_senddata;
52 p->hd44780_functions->backlight = bwct_usb_HD44780_backlight;
53 p->hd44780_functions->scankeypad = bwct_usb_HD44780_scankeypad;
54 p->hd44780_functions->close = bwct_usb_HD44780_close;
56 /* Read config file's contents: serial number and contrast */
58 strncpy(serial, drvthis->config_get_string(drvthis->name, "SerialNumber",
59 0, DEFAULT_SERIALNO), sizeof(serial));
60 serial[sizeof(serial)-1] = '\0';
61 if (*serial != '\0') {
62 report(RPT_INFO, "hd_init_bwct_usb: Using serial number: %s", serial);
65 contrast = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST);
67 /* try to find USB device */
68 #if 0
69 usb_debug = 2;
70 #endif
72 usb_init();
73 usb_find_busses();
74 usb_find_devices();
76 bwct_usb = NULL;
77 for (bus = usb_get_busses(); bus != NULL; bus = bus->next) {
78 struct usb_device *dev;
80 for (dev = bus->devices; dev != NULL; dev = dev->next) {
81 int c;
83 /* Check if this device is a BWCT device */
84 if (dev->descriptor.idVendor != BWCT_USB_VENDORID) {
85 continue;
87 /* Loop through all of the configurations */
88 for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
89 /* Loop through all of the interfaces */
90 for (bwct_usb_i = 0; bwct_usb_i < dev->config[c].bNumInterfaces; bwct_usb_i++) {
91 int a;
93 /* Loop through all of the alternate settings */
94 for (a = 0; a < dev->config[c].interface[bwct_usb_i].num_altsetting; a++) {
95 /* Check if this interface is a BWCT lcd */
96 if (((dev->config[c].interface[bwct_usb_i].altsetting[a].bInterfaceClass == 0xFF) &&
97 (dev->config[c].interface[bwct_usb_i].altsetting[a].bInterfaceSubClass == 0x01)) ||
98 (dev->descriptor.idProduct == BWCT_USB_PRODUCTID)) {
100 /* BWCT device found; try to find its description and serial number */
101 bwct_usb = usb_open(dev);
102 if (bwct_usb == NULL) {
103 report(RPT_WARNING, "hd_init_bwct_usb: unable to open device");
104 // return -1; /* it's better to continue */
106 else {
107 /* get device information & check for serial number */
108 //if (usb_get_string_simple(bwct_usb, dev->descriptor.iManufacturer,
109 // manufacturer, LCD_MAX_WIDTH) <= 0)
110 // *manufacturer = '\0';
111 //manufacturer[sizeof(manufacturer)-1] = '\0';
113 //if (usb_get_string_simple(bwct_usb, dev->descriptor.iProduct,
114 // product, LCD_MAX_WIDTH) <= 0)
115 // *product = '\0';
116 //product[sizeof(product)-1] = '\0';
118 if (usb_get_string_simple(bwct_usb, dev->descriptor.iSerialNumber,
119 device_serial, LCD_MAX_WIDTH) <= 0)
120 *device_serial = '\0';
121 device_serial[sizeof(device_serial)-1] = '\0';
122 if ((*serial != '\0') && (*device_serial == '\0')) {
123 report(RPT_ERR, "hd_init_bwct_usb: unable to get device's serial number");
124 usb_close(bwct_usb);
125 return -1;
128 /* succeed if no serial was given in the config or the 2 numbers match */
129 if ((*serial == '\0') || (strcmp(serial, device_serial) == 0))
130 goto done;
132 usb_close(bwct_usb);
133 bwct_usb = NULL;
142 done:
143 if (bwct_usb != NULL) {
144 debug(RPT_DEBUG, "hd_init_bwct_usb: opening device succeeded");
146 if (usb_claim_interface(bwct_usb, bwct_usb_i) < 0) {
147 #if defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP)
148 if ((usb_detach_kernel_driver_np(bwct_usb, bwct_usb_i) < 0) ||
149 (usb_claim_interface(bwct_usb, bwct_usb_i) < 0)) {
150 usb_close(bwct_usb);
151 report(RPT_ERR, "hd_init_bwct_usb: unable to re-claim interface");
152 return -1;
154 #else
155 usb_close(bwct_usb);
156 report(RPT_ERR, "hd_init_bwct_usb: unable to claim interface");
157 return -1;
158 #endif
161 else {
162 report(RPT_ERR, "hd_init_bwct_usb: no (matching) BWCT device found");
163 return -1;
166 common_init(p, IF_4BIT);
168 /* set contrast */
169 if ((0 <= contrast) && (contrast <= 1000)) {
170 int res = usb_control_msg(bwct_usb, USB_TYPE_VENDOR, BWCT_LCD_SET_CONTRAST,
171 (contrast * 255) / 1000, bwct_usb_i, NULL, 0, 1000);
172 if (res < 0)
173 report(RPT_WARNING, "hd_init_bwct_usb: setting contrast failed");
174 } else {
175 report(RPT_INFO, "hd_init_bwct_usb: Using default contrast value");
178 return 0;
182 // bwct_usb_HD44780_senddata
183 void
184 bwct_usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
186 int type = (flags == RS_DATA) ? BWCT_LCD_DATA : BWCT_LCD_CMD;
188 usb_control_msg(bwct_usb, USB_TYPE_VENDOR, type, ch, bwct_usb_i, NULL, 0, 1000);
192 void
193 bwct_usb_HD44780_backlight(PrivateData *p, unsigned char state)
198 unsigned char
199 bwct_usb_HD44780_scankeypad(PrivateData *p)
201 return 0;
205 void
206 bwct_usb_HD44780_close(PrivateData *p)
208 if (bwct_usb != NULL) {
209 usb_close(bwct_usb);
210 bwct_usb = NULL;
214 /* EOF */