root/branches/volker_dev/drv_HD44780.c

Revision 771, 36.5 kB (checked in by michael, 23 months ago)

lots of compiler warnings removed, C++-style comments removed, changed struc initialisation from 'field:value' to '.field=value'

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