root/trunk/drv_HD44780.c

Revision 880, 37.2 kB (checked in by michael, 4 months ago)

widget_keypad.h added to drv_HD44780

  • Property svn:keywords set to Id URL Rev
Line 
1/* $Id$
2 * $URL$
3 *
4 * new style driver for HD44780-based displays
5 *
6 * Copyright (C) 2003 Michael Reinelt <michael@reinelt.co.at>
7 * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
8 *
9 * Support for I2C bus
10 * Copyright (C) 2005 Luis Correia <lfcorreia@users.sf.net>
11 *
12 * Modification for 4-Bit mode
13 * Copyright (C) 2003 Martin Hejl (martin@hejl.de)
14 *
15 * Modification for 2nd controller support
16 * Copyright (C) 2003 Jesse Brook Kovach <jkovach@wam.umd.edu>
17 *
18 * This file is part of LCD4Linux.
19 *
20 * LCD4Linux is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2, or (at your option)
23 * any later version.
24 *
25 * LCD4Linux is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 */
35
36/*
37 *
38 * exported fuctions:
39 *
40 * struct DRIVER drv_HD44780
41 *
42 */
43
44#include "config.h"
45
46#include <stdlib.h>
47#include <stdio.h>
48#include <string.h>
49#include <errno.h>
50#include <unistd.h>
51#include <termios.h>
52#include <fcntl.h>
53#include <sys/time.h>
54#include <sys/ioctl.h>
55
56#include "debug.h"
57#include "cfg.h"
58#include "udelay.h"
59#include "qprintf.h"
60#include "timer.h"
61#include "plugin.h"
62#include "widget.h"
63#include "widget_text.h"
64#include "widget_icon.h"
65#include "widget_bar.h"
66#include "widget_keypad.h"
67#include "drv.h"
68#include "drv_generic_text.h"
69#include "drv_generic_gpio.h"
70
71#ifdef WITH_PARPORT
72#include "drv_generic_parport.h"
73#include "drv_generic_keypad.h"
74#include "widget_keypad.h"
75#endif
76
77#ifdef WITH_I2C
78#include "drv_generic_i2c.h"
79#endif
80
81static char Name[] = "HD44780";
82
83static int Bus;
84static int Model;
85static int Capabilities;
86
87
88/* Timings */
89#ifdef WITH_PARPORT
90static int T_CY, T_PW, T_AS, T_AH;
91#endif
92static int T_INIT1, T_INIT2, T_EXEC, T_WRCG, T_CLEAR, T_HOME, T_ONOFF;
93#ifdef WITH_PARPORT
94static int T_POWER, T_GPO_ST, T_GPO_PW;
95#endif
96
97static int Bits = 0;
98static int numControllers = 0;
99static int allControllers = 0;
100static int currController = 0;
101
102/* size of every single controller */
103static int CROWS[4];
104static int CCOLS[4];
105
106static unsigned char SIGNAL_RW;
107static unsigned char SIGNAL_RS;
108static unsigned char SIGNAL_ENABLE;
109static unsigned char SIGNAL_ENABLE2;
110static unsigned char SIGNAL_ENABLE3;
111static unsigned char SIGNAL_ENABLE4;
112
113static unsigned char SIGNAL_GPO;
114#ifdef WITH_PARPORT
115static unsigned char SIGNAL_BACKLIGHT;
116static unsigned char SIGNAL_POWER;
117#endif
118
119/* maximum time to wait for the busy-flag (in usec) */
120#define MAX_BUSYFLAG_WAIT 10000
121
122/* maximum busy flag errors before falling back to busy-waiting */
123#define MAX_BUSYFLAG_ERRORS 20
124
125/* flag for busy-waiting vs. busy flag checking */
126#ifdef WITH_PARPORT
127static int UseBusy = 0;
128#endif
129
130/* buffer holding the GPO state */
131#ifdef WITH_PARPORT
132static unsigned char GPO = 0;
133#endif
134
135typedef struct {
136    int type;
137    char *name;
138    int capabilities;
139} MODEL;
140
141#define CAP_PARPORT    (1<<0)
142#define CAP_I2C        (1<<1)
143#define CAP_GPO        (1<<2)
144#define CAP_BACKLIGHT  (1<<3)
145#define CAP_BRIGHTNESS (1<<4)
146#define CAP_BUSY4BIT   (1<<5)
147#define CAP_HD66712    (1<<6)
148#define CAP_LCM162     (1<<7)
149
150#define BUS_PP  CAP_PARPORT
151#define BUS_I2C CAP_I2C
152
153
154static MODEL Models[] = {
155    {0x01, "generic", CAP_PARPORT | CAP_I2C | CAP_GPO | CAP_BACKLIGHT},
156    {0x02, "Noritake", CAP_PARPORT | CAP_I2C | CAP_GPO | CAP_BRIGHTNESS},
157    {0x03, "Soekris", CAP_PARPORT | CAP_BUSY4BIT},
158    {0x04, "HD66712", CAP_PARPORT | CAP_I2C | CAP_GPO | CAP_BACKLIGHT | CAP_HD66712},
159    {0x05, "LCM-162", CAP_PARPORT | CAP_LCM162},
160    {0xff, "Unknown", 0}
161};
162
163
164/****************************************/
165/***  generic functions               ***/
166/****************************************/
167
168static int (*drv_HD_load) (const char *section);
169static void (*drv_HD_command) (const unsigned char controller, const unsigned char cmd, const unsigned long delay);
170static void (*drv_HD_data) (const unsigned char controller, const char *string, const int len,
171          const unsigned long delay);
172static void (*drv_HD_stop) (void);
173
174
175
176/****************************************/
177/***  parport dependant functions     ***/
178/****************************************/
179
180#ifdef WITH_PARPORT
181
182static void drv_HD_PP_busy(const int controller)
183{
184    static unsigned int errors = 0;
185
186    unsigned char enable;
187    unsigned char data = 0xFF;
188    unsigned char busymask;
189    unsigned char ctrlmask;
190    unsigned int counter;
191
192    if (Bits == 8) {
193  busymask = 0x80;
194    } else {
195  /* Since in 4-Bit mode DB0 on the parport is mapped to DB4 on the LCD
196   * (and consequently, DB3 on the partport is mapped to DB7 on the LCD)
197   * we need to listen for DB3 on the parport to go low
198   */
199  busymask = 0x08;
200    }
201
202    ctrlmask = 0x08;
203    while (ctrlmask > 0) {
204
205  if (controller & ctrlmask) {
206
207      enable = 0;
208      if (ctrlmask & 0x01)
209    enable = SIGNAL_ENABLE;
210      else if (ctrlmask & 0x02)
211    enable = SIGNAL_ENABLE2;
212      else if (ctrlmask & 0x04)
213    enable = SIGNAL_ENABLE3;
214      else if (ctrlmask & 0x08)
215    enable = SIGNAL_ENABLE4;
216
217      /* set data-lines to input */
218      drv_generic_parport_direction(1);
219
220      if (Bits == 8) {
221    /* Set RW, clear RS */
222    drv_generic_parport_control(SIGNAL_RW | SIGNAL_RS, SIGNAL_RW);
223      } else {
224    drv_generic_parport_data(SIGNAL_RW);
225      }
226
227      /* Address set-up time */
228      ndelay(T_AS);
229
230      /* rise ENABLE */
231      if (Bits == 8) {
232    drv_generic_parport_control(enable, enable);
233      } else {
234    drv_generic_parport_data(SIGNAL_RW | enable);
235      }
236
237      counter = 0;
238      while (1) {
239    /* read the busy flag */
240    data = drv_generic_parport_read();
241    if ((data & busymask) == 0) {
242        errors = 0;
243        break;
244    }
245
246    /* make sure we don't wait forever
247     * - but only check after 5 iterations
248     * that way, we won't slow down normal mode
249     * (where we don't need the timeout anyway)
250     */
251    counter++;
252
253    if (counter >= 5) {
254        struct timeval now, end;
255
256        if (counter == 5) {
257      /* determine the time when the timeout has expired */
258      gettimeofday(&end, NULL);
259      end.tv_usec += MAX_BUSYFLAG_WAIT;
260      while (end.tv_usec > 1000000) {
261          end.tv_usec -= 1000000;
262          end.tv_sec++;
263      }
264        }
265
266        /* get the current time */
267        gettimeofday(&now, NULL);
268        if (now.tv_sec == end.tv_sec ? now.tv_usec >= end.tv_usec : now.tv_sec >= end.tv_sec) {
269      error("%s: timeout waiting for busy flag on controller %x (0x%02x)", Name, ctrlmask, data);
270      if (++errors >= MAX_BUSYFLAG_ERRORS) {
271          error("%s: too many busy flag failures, turning off busy flag checking.", Name);
272          UseBusy = 0;
273      }
274      break;
275        }
276    }
277      }
278
279      /* RS=low, RW=low, EN=low */
280      if (Bits == 8) {
281    /* Lower EN */
282    drv_generic_parport_control(enable, 0);
283
284    /* Address hold time */
285    ndelay(T_AH);
286
287    drv_generic_parport_control(SIGNAL_RW | SIGNAL_RS, 0);
288      } else {
289    /* Lower EN */
290    drv_generic_parport_data(SIGNAL_RW);
291    ndelay(T_AH);
292    drv_generic_parport_data(0);
293      }
294
295      /* set data-lines to output */
296      drv_generic_parport_direction(0);
297  }
298  ctrlmask >>= 1;
299    }
300}
301
302
303static void drv_HD_PP_nibble(const unsigned char controller, const unsigned char nibble)
304{
305    unsigned char enable;
306
307    /* enable signal: 'controller' is a bitmask */
308    /* bit n .. send to controller #n */
309    /* so we can send a byte to more controllers at the same time! */
310    enable = 0;
311    if (controller & 0x01)
312  enable |= SIGNAL_ENABLE;
313    if (controller & 0x02)
314  enable |= SIGNAL_ENABLE2;
315    if (controller & 0x04)
316  enable |= SIGNAL_ENABLE3;
317    if (controller & 0x08)
318  enable |= SIGNAL_ENABLE4;
319
320    /* clear ENABLE */
321    /* put data on DB1..DB4 */
322    /* nibble already contains RS bit! */
323    drv_generic_parport_data(nibble);
324
325    /* Address set-up time */
326    ndelay(T_AS);
327
328    /* rise ENABLE */
329    drv_generic_parport_data(nibble | enable);
330
331    /* Enable pulse width */
332    ndelay(T_PW);
333
334    /* lower ENABLE */
335    drv_generic_parport_data(nibble);
336}
337
338
339static void drv_HD_PP_byte(const unsigned char controller, const unsigned char data, const unsigned char RS)
340{
341    /* send high nibble of the data */
342    drv_HD_PP_nibble(controller, ((data >> 4) & 0x0f) | RS);
343
344    /* Make sure we honour T_CY */
345    ndelay(T_CY - T_AS - T_PW);
346
347    /* send low nibble of the data */
348    drv_HD_PP_nibble(controller, (data & 0x0f) | RS);
349}
350
351
352static void drv_HD_PP_command(const unsigned char controller, const unsigned char cmd, const unsigned long delay)
353{
354    unsigned char enable;
355
356    if (UseBusy)
357  drv_HD_PP_busy(controller);
358
359    if (Bits == 8) {
360
361  /* enable signal: 'controller' is a bitmask */
362  /* bit n .. send to controller #n */
363  /* so we can send a byte to more controllers at the same time! */
364  enable = 0;
365  if (controller & 0x01)
366      enable |= SIGNAL_ENABLE;
367  if (controller & 0x02)
368      enable |= SIGNAL_ENABLE2;
369  if (controller & 0x04)
370      enable |= SIGNAL_ENABLE3;
371  if (controller & 0x08)
372      enable |= SIGNAL_ENABLE4;
373
374  /* put data on DB1..DB8 */
375  drv_generic_parport_data(cmd);
376
377  /* clear RW and RS */
378  drv_generic_parport_control(SIGNAL_RW | SIGNAL_RS, 0);
379
380  /* Address set-up time */
381  ndelay(T_AS);
382
383  /* send command */
384  drv_generic_parport_toggle(enable, 1, T_PW);
385
386    } else {
387
388  drv_HD_PP_byte(controller, cmd, 0);
389
390    }
391
392    /* wait for command completion */
393    if (!UseBusy)
394  udelay(delay);
395
396}
397
398
399static void drv_HD_PP_data(const unsigned char controller, const char *string, const int len, const unsigned long delay)
400{
401    int l = len;
402    unsigned char enable;
403
404    /* sanity check */
405    if (len <= 0)
406  return;
407
408    if (Bits == 8) {
409
410  /* enable signal: 'controller' is a bitmask */
411  /* bit n .. send to controller #n */
412  /* so we can send a byte to more controllers at the same time! */
413  enable = 0;
414  if (controller & 0x01)
415      enable |= SIGNAL_ENABLE;
416  if (controller & 0x02)
417      enable |= SIGNAL_ENABLE2;
418  if (controller & 0x04)
419      enable |= SIGNAL_ENABLE3;
420  if (controller & 0x08)
421      enable |= SIGNAL_ENABLE4;
422
423  if (!UseBusy) {
424      /* clear RW, set RS */
425      drv_generic_parport_control(SIGNAL_RW | SIGNAL_RS, SIGNAL_RS);
426      /* Address set-up time */
427      ndelay(T_AS);
428  }
429
430  while (l--) {
431
432      if (UseBusy) {
433    drv_HD_PP_busy(controller);
434    /* clear RW, set RS */
435    drv_generic_parport_control(SIGNAL_RW | SIGNAL_RS, SIGNAL_RS);
436    /* Address set-up time */
437    ndelay(T_AS);
438      }
439
440      /* put data on DB1..DB8 */
441      drv_generic_parport_data(*(string++));
442
443      /* send command */
444      drv_generic_parport_toggle(enable, 1, T_PW);
445
446      /* wait for command completion */
447      if (!UseBusy)
448    udelay(delay);
449  }
450
451    } else {      /* 4 bit mode */
452
453  while (l--) {
454      if (UseBusy)
455    drv_HD_PP_busy(controller);
456
457      /* send data with RS enabled */
458      drv_HD_PP_byte(controller, *(string++), SIGNAL_RS);
459
460      /* wait for command completion */
461      if (!UseBusy)
462    udelay(delay);
463  }
464    }
465}
466
467
468static int drv_HD_PP_load(const char *section)
469{
470    if (cfg_number(section, "Bits", 8, 4, 8, &Bits) < 0)
471  return -1;
472
473    if (Bits != 4 && Bits != 8) {
474  error("%s: bad %s.Bits '%d' from %s, should be '4' or '8'", Name, section, Bits, cfg_source());
475  return -1;
476    }
477
478    /* LCM-162 only supports 8-bit-mode */
479    if (Capabilities & CAP_LCM162 && Bits != 8) {
480  error("%s: Model '%s' does not support %d bit mode!", Name, Models[Model].name, Bits);
481  Bits = 8;
482    }
483    info("%s: using %d bit mode", Name, Bits);
484
485    if (drv_generic_parport_open(section, Name) != 0) {
486  error("%s: could not initialize parallel port!", Name);
487  return -1;
488    }
489
490    /* Soft-Wiring */
491    if (Capabilities & CAP_LCM162) {
492  /* the LCM-162 is hardwired */
493  if ((SIGNAL_RS = drv_generic_parport_hardwire_ctrl("RS", "SLCTIN")) == 0xff)
494      return -1;
495  if ((SIGNAL_RW = drv_generic_parport_hardwire_ctrl("RW", "INIT")) == 0xff)
496      return -1;
497  if ((SIGNAL_ENABLE = drv_generic_parport_hardwire_ctrl("ENABLE", "AUTOFD")) == 0xff)
498      return -1;
499  if ((SIGNAL_ENABLE2 = drv_generic_parport_hardwire_ctrl("ENABLE2", "GND")) == 0xff)
500      return -1;
501  if ((SIGNAL_ENABLE3 = drv_generic_parport_hardwire_ctrl("ENABLE3", "GND")) == 0xff)
502      return -1;
503  if ((SIGNAL_ENABLE4 = drv_generic_parport_hardwire_ctrl("ENABLE4", "GND")) == 0xff)
504      return -1;
505  if ((SIGNAL_BACKLIGHT = drv_generic_parport_hardwire_ctrl("BACKLIGHT", "GND")) == 0xff)
506      return -1;
507  if ((SIGNAL_GPO = drv_generic_parport_hardwire_ctrl("GPO", "GND")) == 0xff)
508      return -1;
509  if ((SIGNAL_POWER = drv_generic_parport_hardwire_ctrl("POWER", "GND")) == 0xff)
510      return -1;
511    } else {
512  if (Bits == 8) {
513      if ((SIGNAL_RS = drv_generic_parport_wire_ctrl("RS", "AUTOFD")) == 0xff)
514    return -1;
515      if ((SIGNAL_RW = drv_generic_parport_wire_ctrl("RW", "GND")) == 0xff)
516    return -1;
517      if ((SIGNAL_ENABLE = drv_generic_parport_wire_ctrl("ENABLE", "STROBE")) == 0xff)
518    return -1;
519      if ((SIGNAL_ENABLE2 = drv_generic_parport_wire_ctrl("ENABLE2", "GND")) == 0xff)
520    return -1;
521      if ((SIGNAL_ENABLE3 = drv_generic_parport_wire_ctrl("ENABLE3", "GND")) == 0xff)
522    return -1;
523      if ((SIGNAL_ENABLE4 = drv_generic_parport_wire_ctrl("ENABLE4", "GND")) == 0xff)
524    return -1;
525  } else {
526      if ((SIGNAL_RS = drv_generic_parport_wire_data("RS", "DB4")) == 0xff)
527    return -1;
528      if ((SIGNAL_RW = drv_generic_parport_wire_data("RW", "DB5")) == 0xff)
529    return -1;
530      if ((SIGNAL_ENABLE = drv_generic_parport_wire_data("ENABLE", "DB6")) == 0xff)
531    return -1;
532      if ((SIGNAL_ENABLE2 = drv_generic_parport_wire_data("ENABLE2", "GND")) == 0xff)
533    return -1;
534      if ((SIGNAL_ENABLE3 = drv_generic_parport_wire_data("ENABLE3", "GND")) == 0xff)
535    return -1;
536      if ((SIGNAL_ENABLE4 = drv_generic_parport_wire_data("ENABLE4", "GND")) == 0xff)
537    return -1;
538  }
539  /* backlight GPO and power are always control signals */
540  if ((SIGNAL_BACKLIGHT = drv_generic_parport_wire_ctrl("BACKLIGHT", "GND")) == 0xff)
541      return -1;
542  if ((SIGNAL_GPO = drv_generic_parport_wire_ctrl("GPO", "GND")) == 0xff)
543      return -1;
544  if ((SIGNAL_POWER = drv_generic_parport_wire_ctrl("POWER", "GND")) == 0xff)
545      return -1;
546    }
547
548    /* clear capabilities if corresponding signal is GND */
549    if (SIGNAL_BACKLIGHT == 0) {
550  Capabilities &= ~CAP_BACKLIGHT;
551    }
552    if (SIGNAL_GPO == 0) {
553  Capabilities &= ~CAP_GPO;
554    }
555
556    /* Timings */
557
558    /* low level communication timings [nanoseconds]
559     * as these values differ from spec to spec,
560     * we use the worst-case default values, but allow
561     * modification from the config file.
562     */
563    T_CY = timing(Name, section, "CY", 1000, "ns"); /* Enable cycle time */
564    T_PW = timing(Name, section, "PW", 450, "ns");  /* Enable pulse width */
565    T_AS = timing(Name, section, "AS", 140, "ns");  /* Address setup time */
566    T_AH = timing(Name, section, "AH", 20, "ns"); /* Address hold time */
567
568    /* GPO timing */
569    if (SIGNAL_GPO != 0) {
570  T_GPO_ST = timing(Name, section, "GPO_ST", 20, "ns"); /* 74HCT573 set-up time */
571  T_GPO_PW = timing(Name, section, "GPO_PW", 230, "ns");  /* 74HCT573 enable pulse width */
572    } else {
573  T_GPO_ST = 0;
574  T_GPO_PW = 0;
575    }
576
577    /* HD44780 execution timings [microseconds]
578     * as these values differ from spec to spec,
579     * we use the worst-case default values, but allow
580     * modification from the config file.
581     */
582    T_INIT1 = timing(Name, section, "INIT1", 4100, "us"); /* first init sequence: 4.1 msec */
583    T_INIT2 = timing(Name, section, "INIT2", 100, "us");  /* second init sequence: 100 usec */
584    T_EXEC = timing(Name, section, "EXEC", 80, "us"); /* normal execution time */
585    T_WRCG = timing(Name, section, "WRCG", 120, "us");  /* CG RAM Write */
586    T_CLEAR = timing(Name, section, "CLEAR", 2250, "us"); /* Clear Display */
587    T_HOME = timing(Name, section, "HOME", 2250, "us"); /* Return Cursor Home */
588    T_ONOFF = timing(Name, section, "ONOFF", 2250, "us"); /* Display On/Off Control */
589
590    /* Power-on delay */
591    if (SIGNAL_POWER != 0) {
592  T_POWER = timing(Name, section, "POWER", 500, "ms");
593    } else {
594  T_POWER = 0;
595    }
596
597    /* clear all signals */
598    if (Bits == 8) {
599  drv_generic_parport_control(SIGNAL_RS | SIGNAL_RW |
600            SIGNAL_ENABLE | SIGNAL_ENABLE2 | SIGNAL_ENABLE3 | SIGNAL_ENABLE4 |
601            SIGNAL_BACKLIGHT | SIGNAL_GPO | SIGNAL_POWER, 0);
602    } else {
603  drv_generic_parport_control(SIGNAL_BACKLIGHT | SIGNAL_GPO | SIGNAL_POWER, 0);
604  drv_generic_parport_data(0);
605    }
606
607    /* set direction: write */
608    drv_generic_parport_direction(0);
609
610    /* raise power pin */
611    if (SIGNAL_POWER != 0) {
612  drv_generic_parport_control(SIGNAL_POWER, SIGNAL_POWER);
613  udelay(1000 * T_POWER);
614    }
615
616    /* initialize *all* controllers */
617    if (Bits == 8) {
618  drv_HD_PP_command(allControllers, 0x30, T_INIT1); /* 8 Bit mode, wait 4.1 ms */
619  drv_HD_PP_command(allControllers, 0x30, T_INIT2); /* 8 Bit mode, wait 100 us */
620  drv_HD_PP_command(allControllers, 0x38, T_EXEC);  /* 8 Bit mode, 1/16 duty cycle, 5x8 font */
621    } else {
622  drv_HD_PP_nibble(allControllers, 0x03);
623  udelay(T_INIT1);  /* 4 Bit mode, wait 4.1 ms */
624  drv_HD_PP_nibble(allControllers, 0x03);
625  udelay(T_INIT2);  /* 4 Bit mode, wait 100 us */
626  drv_HD_PP_nibble(allControllers, 0x03);
627  udelay(T_INIT1);  /* 4 Bit mode, wait 4.1 ms */
628  drv_HD_PP_nibble(allControllers, 0x02);
629  udelay(T_INIT2);  /* 4 Bit mode, wait 100 us */
630  drv_HD_PP_command(allControllers, 0x28, T_EXEC);  /* 4 Bit mode, 1/16 duty cycle, 5x8 font */
631    }
632
633    /* maybe use busy-flag from now on  */
634    /* (we can't use the busy flag during the init sequence) */
635    cfg_number(section, "UseBusy", 0, 0, 1, &UseBusy);
636
637    /* make sure we don't use the busy flag with RW wired to GND */
638    if (UseBusy && !SIGNAL_RW) {
639  error("%s: busy-flag checking is impossible with RW wired to GND!", Name);
640  UseBusy = 0;
641    }
642
643    /* make sure the display supports busy-flag checking in 4-Bit-Mode */
644    /* at the moment this is inly possible with Martin Hejl's gpio driver, */
645    /* which allows to use 4 bits as input and 4 bits as output */
646    if (UseBusy && Bits == 4 && !(Capabilities & CAP_BUSY4BIT)) {
647  error("%s: Model '%s' does not support busy-flag checking in 4 bit mode", Name, Models[Model].name);
648  UseBusy = 0;
649    }
650
651    info("%s: %susing busy-flag checking", Name, UseBusy ? "" : "not ");
652
653    /* The LCM-162 should really use BusyFlag checking */
654    if (!UseBusy && (Capabilities & CAP_LCM162)) {
655  error("%s: Model '%s' should definitely use busy-flag checking!", Name, Models[Model].name);
656    }
657
658    return 0;
659}
660
661
662static void drv_HD_PP_stop(void)
663{
664    /* clear all signals */
665    if (Bits == 8) {
666  drv_generic_parport_control(SIGNAL_RS |
667            SIGNAL_RW | SIGNAL_ENABLE | SIGNAL_ENABLE2 | SIGNAL_ENABLE3 | SIGNAL_ENABLE4 |
668            SIGNAL_BACKLIGHT | SIGNAL_GPO, 0);
669    } else {
670  drv_generic_parport_data(0);
671  drv_generic_parport_control(SIGNAL_BACKLIGHT | SIGNAL_GPO | SIGNAL_POWER, 0);
672    }
673
674    drv_generic_parport_close();
675
676}
677
678#endif
679
680
681#ifdef WITH_I2C
682
683/****************************************/
684/***  i2c dependant functions         ***/
685/****************************************/
686
687    /*
688       DISCLAIMER!!!!
689
690       The following code is WORK IN PROGRESS, since it basicly 'works for us...'
691
692       (C) 2005 Paul Kamphuis & Luis Correia
693
694       We have removed all of the delays from this code, as the I2C bus is slow enough...
695       (maximum possible speed is 100KHz only)
696
697     */
698
699static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble)
700{
701    unsigned char enable;
702    unsigned char command;  /* this is actually the first data byte on the PCF8574 */
703    unsigned char data_block[2];
704    /* enable signal: 'controller' is a bitmask */
705    /* bit n .. send to controller #n */
706    /* so we can send a byte to more controllers at the same time! */
707    enable = 0;
708    if (controller & 0x01)
709  enable |= SIGNAL_ENABLE;
710    if (controller & 0x02)
711  enable |= SIGNAL_ENABLE2;
712    if (controller & 0x04)
713  enable |= SIGNAL_ENABLE3;
714    if (controller & 0x08)
715  enable |= SIGNAL_ENABLE4;
716
717    /*
718       The new method Paul Kamphuis has concocted places the 3 needed writes to the I2C device
719       as a single operation, using the 'i2c_smbus_write_block_data' function.
720       These actual writes are performed by putting the nibble along with the 'EN' signal.
721
722       command = first byte to be written, which contains the nibble (DB0..DB3)
723       data [0]   = second byte to be written, which contains the nibble plus the EN signal
724       data [1]   = third byte to be written, which contains the nibble (DB0..DB3)
725
726       Then we write the block as a whole.
727
728       The main advantage we see is that we do 2 less IOCTL's from our driver.
729     */
730
731    command = nibble;
732    data_block[0] = nibble | enable;
733    data_block[1] = nibble;
734
735    drv_generic_i2c_command(command, data_block, 2);
736}
737
738
739static void drv_HD_I2C_byte(const unsigned char controller, const unsigned char data)
740{
741    /* send data with RS enabled */
742    drv_HD_I2C_nibble(controller, ((data >> 4) & 0x0f) | SIGNAL_RS);
743    drv_HD_I2C_nibble(controller, (data & 0x0f) | SIGNAL_RS);
744}
745
746
747static void drv_HD_I2C_command(const unsigned char controller, const unsigned char cmd, __attribute__ ((unused))
748             const unsigned long delay)
749{
750    /* send data with RS disabled */
751    drv_HD_I2C_nibble(controller, ((cmd >> 4) & 0x0f));
752    drv_HD_I2C_nibble(controller, ((cmd) & 0x0f));
753}
754
755static void drv_HD_I2C_data(const unsigned char controller, const char *string, const int len, __attribute__ ((unused))
756          const unsigned long delay)
757{
758    int l = len;
759
760    /* sanity check */
761    if (len <= 0)
762  return;
763
764    while (l--) {
765  drv_HD_I2C_byte(controller, *(string++));
766    }
767}
768
769
770static int drv_HD_I2C_load(const char *section)
771{
772    if (cfg_number(section, "Bits", 8, 4, 8, &Bits) < 0)
773  return -1;
774    if (Bits != 4) {
775  error("%s: bad %s.Bits '%d' from %s, should be '4'", Name, section, Bits, cfg_source());
776  return -1;
777    }
778
779    info("%s: using %d bit mode", Name, Bits);
780
781    if (drv_generic_i2c_open(section, Name) != 0) {
782  error("%s: could not initialize i2c attached device!", Name);
783  return -1;
784    }
785
786    if ((SIGNAL_RS = drv_generic_i2c_wire