symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/lm832x.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * National Semiconductor LM8322/8323 GPIO keyboard & PWM chips.
       
     3  *
       
     4  * Copyright (C) 2008 Nokia Corporation
       
     5  * Written by Andrzej Zaborowski <andrew@openedhand.com>
       
     6  *
       
     7  * This program is free software; you can redistribute it and/or
       
     8  * modify it under the terms of the GNU General Public License as
       
     9  * published by the Free Software Foundation; either version 2 or
       
    10  * (at your option) version 3 of the License.
       
    11  *
       
    12  * This program is distributed in the hope that it will be useful,
       
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15  * GNU General Public License for more details.
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License
       
    18  * along with this program; if not, write to the Free Software
       
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
       
    20  * MA 02111-1307 USA
       
    21  */
       
    22 
       
    23 #include "hw.h"
       
    24 #include "i2c.h"
       
    25 #include "qemu-timer.h"
       
    26 #include "console.h"
       
    27 
       
    28 struct lm_kbd_s {
       
    29     i2c_slave i2c;
       
    30     int i2c_dir;
       
    31     int i2c_cycle;
       
    32     int reg;
       
    33 
       
    34     qemu_irq nirq;
       
    35     uint16_t model;
       
    36 
       
    37     struct {
       
    38         qemu_irq out[2];
       
    39         int in[2][2];
       
    40     } mux;
       
    41 
       
    42     uint8_t config;
       
    43     uint8_t status;
       
    44     uint8_t acttime;
       
    45     uint8_t error;
       
    46     uint8_t clock;
       
    47 
       
    48     struct {
       
    49         uint16_t pull;
       
    50         uint16_t mask;
       
    51         uint16_t dir;
       
    52         uint16_t level;
       
    53         qemu_irq out[16];
       
    54     } gpio;
       
    55 
       
    56     struct {
       
    57         uint8_t dbnctime;
       
    58         uint8_t size;
       
    59         int start;
       
    60         int len;
       
    61         uint8_t fifo[16];
       
    62     } kbd;
       
    63 
       
    64     struct {
       
    65         uint16_t file[256];
       
    66 	uint8_t faddr;
       
    67         uint8_t addr[3];
       
    68         QEMUTimer *tm[3];
       
    69     } pwm;
       
    70 };
       
    71 
       
    72 #define INT_KEYPAD		(1 << 0)
       
    73 #define INT_ERROR		(1 << 3)
       
    74 #define INT_NOINIT		(1 << 4)
       
    75 #define INT_PWMEND(n)		(1 << (5 + n))
       
    76 
       
    77 #define ERR_BADPAR		(1 << 0)
       
    78 #define ERR_CMDUNK		(1 << 1)
       
    79 #define ERR_KEYOVR		(1 << 2)
       
    80 #define ERR_FIFOOVR		(1 << 6)
       
    81 
       
    82 static void lm_kbd_irq_update(struct lm_kbd_s *s)
       
    83 {
       
    84     qemu_set_irq(s->nirq, !s->status);
       
    85 }
       
    86 
       
    87 static void lm_kbd_gpio_update(struct lm_kbd_s *s)
       
    88 {
       
    89 }
       
    90 
       
    91 static void lm_kbd_reset(struct lm_kbd_s *s)
       
    92 {
       
    93     s->config = 0x80;
       
    94     s->status = INT_NOINIT;
       
    95     s->acttime = 125;
       
    96     s->kbd.dbnctime = 3;
       
    97     s->kbd.size = 0x33;
       
    98     s->clock = 0x08;
       
    99 
       
   100     lm_kbd_irq_update(s);
       
   101     lm_kbd_gpio_update(s);
       
   102 }
       
   103 
       
   104 static void lm_kbd_error(struct lm_kbd_s *s, int err)
       
   105 {
       
   106     s->error |= err;
       
   107     s->status |= INT_ERROR;
       
   108     lm_kbd_irq_update(s);
       
   109 }
       
   110 
       
   111 static void lm_kbd_pwm_tick(struct lm_kbd_s *s, int line)
       
   112 {
       
   113 }
       
   114 
       
   115 static void lm_kbd_pwm_start(struct lm_kbd_s *s, int line)
       
   116 {
       
   117     lm_kbd_pwm_tick(s, line);
       
   118 }
       
   119 
       
   120 static void lm_kbd_pwm0_tick(void *opaque)
       
   121 {
       
   122     lm_kbd_pwm_tick(opaque, 0);
       
   123 }
       
   124 static void lm_kbd_pwm1_tick(void *opaque)
       
   125 {
       
   126     lm_kbd_pwm_tick(opaque, 1);
       
   127 }
       
   128 static void lm_kbd_pwm2_tick(void *opaque)
       
   129 {
       
   130     lm_kbd_pwm_tick(opaque, 2);
       
   131 }
       
   132 
       
   133 enum {
       
   134     LM832x_CMD_READ_ID		= 0x80, /* Read chip ID. */
       
   135     LM832x_CMD_WRITE_CFG	= 0x81, /* Set configuration item. */
       
   136     LM832x_CMD_READ_INT		= 0x82, /* Get interrupt status. */
       
   137     LM832x_CMD_RESET		= 0x83, /* Reset, same as external one */
       
   138     LM823x_CMD_WRITE_PULL_DOWN	= 0x84, /* Select GPIO pull-up/down. */
       
   139     LM832x_CMD_WRITE_PORT_SEL	= 0x85, /* Select GPIO in/out. */
       
   140     LM832x_CMD_WRITE_PORT_STATE	= 0x86, /* Set GPIO pull-up/down. */
       
   141     LM832x_CMD_READ_PORT_SEL	= 0x87, /* Get GPIO in/out. */
       
   142     LM832x_CMD_READ_PORT_STATE	= 0x88, /* Get GPIO pull-up/down. */
       
   143     LM832x_CMD_READ_FIFO	= 0x89, /* Read byte from FIFO. */
       
   144     LM832x_CMD_RPT_READ_FIFO	= 0x8a, /* Read FIFO (no increment). */
       
   145     LM832x_CMD_SET_ACTIVE	= 0x8b, /* Set active time. */
       
   146     LM832x_CMD_READ_ERROR	= 0x8c, /* Get error status. */
       
   147     LM832x_CMD_READ_ROTATOR	= 0x8e, /* Read rotator status. */
       
   148     LM832x_CMD_SET_DEBOUNCE	= 0x8f, /* Set debouncing time. */
       
   149     LM832x_CMD_SET_KEY_SIZE	= 0x90, /* Set keypad size. */
       
   150     LM832x_CMD_READ_KEY_SIZE	= 0x91, /* Get keypad size. */
       
   151     LM832x_CMD_READ_CFG		= 0x92, /* Get configuration item. */
       
   152     LM832x_CMD_WRITE_CLOCK	= 0x93, /* Set clock config. */
       
   153     LM832x_CMD_READ_CLOCK	= 0x94, /* Get clock config. */
       
   154     LM832x_CMD_PWM_WRITE	= 0x95, /* Write PWM script. */
       
   155     LM832x_CMD_PWM_START	= 0x96, /* Start PWM engine. */
       
   156     LM832x_CMD_PWM_STOP		= 0x97, /* Stop PWM engine. */
       
   157 };
       
   158 
       
   159 #define LM832x_MAX_KPX		8
       
   160 #define LM832x_MAX_KPY		12
       
   161 
       
   162 static uint8_t lm_kbd_read(struct lm_kbd_s *s, int reg, int byte)
       
   163 {
       
   164     int ret;
       
   165 
       
   166     switch (reg) {
       
   167     case LM832x_CMD_READ_ID:
       
   168         ret = 0x0400;
       
   169         break;
       
   170 
       
   171     case LM832x_CMD_READ_INT:
       
   172         ret = s->status;
       
   173         if (!(s->status & INT_NOINIT)) {
       
   174             s->status = 0;
       
   175             lm_kbd_irq_update(s);
       
   176         }
       
   177         break;
       
   178 
       
   179     case LM832x_CMD_READ_PORT_SEL:
       
   180         ret = s->gpio.dir;
       
   181         break;
       
   182     case LM832x_CMD_READ_PORT_STATE:
       
   183         ret = s->gpio.mask;
       
   184         break;
       
   185 
       
   186     case LM832x_CMD_READ_FIFO:
       
   187         if (s->kbd.len <= 1)
       
   188             return 0x00;
       
   189 
       
   190         /* Example response from the two commands after a INT_KEYPAD
       
   191          * interrupt caused by the key 0x3c being pressed:
       
   192          * RPT_READ_FIFO: 55 bc 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
       
   193          *     READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
       
   194          * RPT_READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
       
   195          *
       
   196          * 55 is the code of the key release event serviced in the previous
       
   197          * interrupt handling.
       
   198          *
       
   199          * TODO: find out whether the FIFO is advanced a single character
       
   200          * before reading every byte or the whole size of the FIFO at the
       
   201          * last LM832x_CMD_READ_FIFO.  This affects LM832x_CMD_RPT_READ_FIFO
       
   202          * output in cases where there are more than one event in the FIFO.
       
   203          * Assume 0xbc and 0x3c events are in the FIFO:
       
   204          * RPT_READ_FIFO: 55 bc 3c 00 4e ff 0a 50 08 00 29 d9 08 01 c9
       
   205          *     READ_FIFO: bc 3c 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9
       
   206          * Does RPT_READ_FIFO now return 0xbc and 0x3c or only 0x3c?
       
   207          */
       
   208         s->kbd.start ++;
       
   209         s->kbd.start &= sizeof(s->kbd.fifo) - 1;
       
   210         s->kbd.len --;
       
   211 
       
   212         return s->kbd.fifo[s->kbd.start];
       
   213     case LM832x_CMD_RPT_READ_FIFO:
       
   214         if (byte >= s->kbd.len)
       
   215             return 0x00;
       
   216 
       
   217         return s->kbd.fifo[(s->kbd.start + byte) & (sizeof(s->kbd.fifo) - 1)];
       
   218 
       
   219     case LM832x_CMD_READ_ERROR:
       
   220         return s->error;
       
   221 
       
   222     case LM832x_CMD_READ_ROTATOR:
       
   223         return 0;
       
   224 
       
   225     case LM832x_CMD_READ_KEY_SIZE:
       
   226         return s->kbd.size;
       
   227 
       
   228     case LM832x_CMD_READ_CFG:
       
   229         return s->config & 0xf;
       
   230 
       
   231     case LM832x_CMD_READ_CLOCK:
       
   232         return (s->clock & 0xfc) | 2;
       
   233 
       
   234     default:
       
   235         lm_kbd_error(s, ERR_CMDUNK);
       
   236         fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
       
   237         return 0x00;
       
   238     }
       
   239 
       
   240     return ret >> (byte << 3);
       
   241 }
       
   242 
       
   243 static void lm_kbd_write(struct lm_kbd_s *s, int reg, int byte, uint8_t value)
       
   244 {
       
   245     switch (reg) {
       
   246     case LM832x_CMD_WRITE_CFG:
       
   247         s->config = value;
       
   248         /* This must be done whenever s->mux.in is updated (never).  */
       
   249         if ((s->config >> 1) & 1)			/* MUX1EN */
       
   250             qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 0) & 1]);
       
   251         if ((s->config >> 3) & 1)			/* MUX2EN */
       
   252             qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 2) & 1]);
       
   253         /* TODO: check that this is issued only following the chip reset
       
   254          * and not in the middle of operation and that it is followed by
       
   255          * the GPIO ports re-resablishing through WRITE_PORT_SEL and
       
   256          * WRITE_PORT_STATE (using a timer perhaps) and otherwise output
       
   257          * warnings.  */
       
   258         s->status = 0;
       
   259         lm_kbd_irq_update(s);
       
   260         s->kbd.len = 0;
       
   261         s->kbd.start = 0;
       
   262         s->reg = -1;
       
   263         break;
       
   264 
       
   265     case LM832x_CMD_RESET:
       
   266         if (value == 0xaa)
       
   267             lm_kbd_reset(s);
       
   268         else
       
   269             lm_kbd_error(s, ERR_BADPAR);
       
   270         s->reg = -1;
       
   271         break;
       
   272 
       
   273     case LM823x_CMD_WRITE_PULL_DOWN:
       
   274         if (!byte)
       
   275             s->gpio.pull = value;
       
   276         else {
       
   277             s->gpio.pull |= value << 8;
       
   278             lm_kbd_gpio_update(s);
       
   279             s->reg = -1;
       
   280         }
       
   281         break;
       
   282     case LM832x_CMD_WRITE_PORT_SEL:
       
   283         if (!byte)
       
   284             s->gpio.dir = value;
       
   285         else {
       
   286             s->gpio.dir |= value << 8;
       
   287             lm_kbd_gpio_update(s);
       
   288             s->reg = -1;
       
   289         }
       
   290         break;
       
   291     case LM832x_CMD_WRITE_PORT_STATE:
       
   292         if (!byte)
       
   293             s->gpio.mask = value;
       
   294         else {
       
   295             s->gpio.mask |= value << 8;
       
   296             lm_kbd_gpio_update(s);
       
   297             s->reg = -1;
       
   298         }
       
   299         break;
       
   300 
       
   301     case LM832x_CMD_SET_ACTIVE:
       
   302         s->acttime = value;
       
   303         s->reg = -1;
       
   304         break;
       
   305 
       
   306     case LM832x_CMD_SET_DEBOUNCE:
       
   307         s->kbd.dbnctime = value;
       
   308         s->reg = -1;
       
   309         if (!value)
       
   310             lm_kbd_error(s, ERR_BADPAR);
       
   311         break;
       
   312 
       
   313     case LM832x_CMD_SET_KEY_SIZE:
       
   314         s->kbd.size = value;
       
   315         s->reg = -1;
       
   316         if (
       
   317                         (value & 0xf) < 3 || (value & 0xf) > LM832x_MAX_KPY ||
       
   318                         (value >> 4) < 3 || (value >> 4) > LM832x_MAX_KPX)
       
   319             lm_kbd_error(s, ERR_BADPAR);
       
   320         break;
       
   321 
       
   322     case LM832x_CMD_WRITE_CLOCK:
       
   323         s->clock = value;
       
   324         s->reg = -1;
       
   325         if ((value & 3) && (value & 3) != 3) {
       
   326             lm_kbd_error(s, ERR_BADPAR);
       
   327             fprintf(stderr, "%s: invalid clock setting in RCPWM\n",
       
   328                             __FUNCTION__);
       
   329         }
       
   330         /* TODO: Validate that the command is only issued once */
       
   331         break;
       
   332 
       
   333     case LM832x_CMD_PWM_WRITE:
       
   334         if (byte == 0) {
       
   335             if (!(value & 3) || (value >> 2) > 59) {
       
   336                 lm_kbd_error(s, ERR_BADPAR);
       
   337                 s->reg = -1;
       
   338                 break;
       
   339             }
       
   340 
       
   341             s->pwm.faddr = value;
       
   342             s->pwm.file[s->pwm.faddr] = 0;
       
   343         } else if (byte == 1) {
       
   344             s->pwm.file[s->pwm.faddr] |= value << 8;
       
   345         } else if (byte == 2) {
       
   346             s->pwm.file[s->pwm.faddr] |= value << 0;
       
   347             s->reg = -1;
       
   348         }
       
   349         break;
       
   350     case LM832x_CMD_PWM_START:
       
   351         s->reg = -1;
       
   352         if (!(value & 3) || (value >> 2) > 59) {
       
   353             lm_kbd_error(s, ERR_BADPAR);
       
   354             break;
       
   355         }
       
   356 
       
   357         s->pwm.addr[(value & 3) - 1] = value >> 2;
       
   358         lm_kbd_pwm_start(s, (value & 3) - 1);
       
   359         break;
       
   360     case LM832x_CMD_PWM_STOP:
       
   361         s->reg = -1;
       
   362         if (!(value & 3)) {
       
   363             lm_kbd_error(s, ERR_BADPAR);
       
   364             break;
       
   365         }
       
   366 
       
   367         qemu_del_timer(s->pwm.tm[(value & 3) - 1]);
       
   368         break;
       
   369 
       
   370     case -1:
       
   371         lm_kbd_error(s, ERR_BADPAR);
       
   372         break;
       
   373     default:
       
   374         lm_kbd_error(s, ERR_CMDUNK);
       
   375         fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
       
   376         break;
       
   377     }
       
   378 }
       
   379 
       
   380 static void lm_i2c_event(i2c_slave *i2c, enum i2c_event event)
       
   381 {
       
   382     struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
       
   383 
       
   384     switch (event) {
       
   385     case I2C_START_RECV:
       
   386     case I2C_START_SEND:
       
   387         s->i2c_cycle = 0;
       
   388         s->i2c_dir = (event == I2C_START_SEND);
       
   389         break;
       
   390 
       
   391     default:
       
   392         break;
       
   393     }
       
   394 }
       
   395 
       
   396 static int lm_i2c_rx(i2c_slave *i2c)
       
   397 {
       
   398     struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
       
   399 
       
   400     return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
       
   401 }
       
   402 
       
   403 static int lm_i2c_tx(i2c_slave *i2c, uint8_t data)
       
   404 {
       
   405     struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
       
   406 
       
   407     if (!s->i2c_cycle)
       
   408         s->reg = data;
       
   409     else
       
   410         lm_kbd_write(s, s->reg, s->i2c_cycle - 1, data);
       
   411     s->i2c_cycle ++;
       
   412 
       
   413     return 0;
       
   414 }
       
   415 
       
   416 static void lm_kbd_save(QEMUFile *f, void *opaque)
       
   417 {
       
   418     struct lm_kbd_s *s = (struct lm_kbd_s *) opaque;
       
   419     int i;
       
   420 
       
   421     i2c_slave_save(f, &s->i2c);
       
   422     qemu_put_byte(f, s->i2c_dir);
       
   423     qemu_put_byte(f, s->i2c_cycle);
       
   424     qemu_put_byte(f, (uint8_t) s->reg);
       
   425 
       
   426     qemu_put_8s(f, &s->config);
       
   427     qemu_put_8s(f, &s->status);
       
   428     qemu_put_8s(f, &s->acttime);
       
   429     qemu_put_8s(f, &s->error);
       
   430     qemu_put_8s(f, &s->clock);
       
   431 
       
   432     qemu_put_be16s(f, &s->gpio.pull);
       
   433     qemu_put_be16s(f, &s->gpio.mask);
       
   434     qemu_put_be16s(f, &s->gpio.dir);
       
   435     qemu_put_be16s(f, &s->gpio.level);
       
   436 
       
   437     qemu_put_byte(f, s->kbd.dbnctime);
       
   438     qemu_put_byte(f, s->kbd.size);
       
   439     qemu_put_byte(f, s->kbd.start);
       
   440     qemu_put_byte(f, s->kbd.len);
       
   441     qemu_put_buffer(f, s->kbd.fifo, sizeof(s->kbd.fifo));
       
   442 
       
   443     for (i = 0; i < sizeof(s->pwm.file); i ++)
       
   444         qemu_put_be16s(f, &s->pwm.file[i]);
       
   445     qemu_put_8s(f, &s->pwm.faddr);
       
   446     qemu_put_buffer(f, s->pwm.addr, sizeof(s->pwm.addr));
       
   447     qemu_put_timer(f, s->pwm.tm[0]);
       
   448     qemu_put_timer(f, s->pwm.tm[1]);
       
   449     qemu_put_timer(f, s->pwm.tm[2]);
       
   450 }
       
   451 
       
   452 static int lm_kbd_load(QEMUFile *f, void *opaque, int version_id)
       
   453 {
       
   454     struct lm_kbd_s *s = (struct lm_kbd_s *) opaque;
       
   455     int i;
       
   456 
       
   457     i2c_slave_load(f, &s->i2c);
       
   458     s->i2c_dir = qemu_get_byte(f);
       
   459     s->i2c_cycle = qemu_get_byte(f);
       
   460     s->reg = (int8_t) qemu_get_byte(f);
       
   461 
       
   462     qemu_get_8s(f, &s->config);
       
   463     qemu_get_8s(f, &s->status);
       
   464     qemu_get_8s(f, &s->acttime);
       
   465     qemu_get_8s(f, &s->error);
       
   466     qemu_get_8s(f, &s->clock);
       
   467 
       
   468     qemu_get_be16s(f, &s->gpio.pull);
       
   469     qemu_get_be16s(f, &s->gpio.mask);
       
   470     qemu_get_be16s(f, &s->gpio.dir);
       
   471     qemu_get_be16s(f, &s->gpio.level);
       
   472 
       
   473     s->kbd.dbnctime = qemu_get_byte(f);
       
   474     s->kbd.size = qemu_get_byte(f);
       
   475     s->kbd.start = qemu_get_byte(f);
       
   476     s->kbd.len = qemu_get_byte(f);
       
   477     qemu_get_buffer(f, s->kbd.fifo, sizeof(s->kbd.fifo));
       
   478 
       
   479     for (i = 0; i < sizeof(s->pwm.file); i ++)
       
   480         qemu_get_be16s(f, &s->pwm.file[i]);
       
   481     qemu_get_8s(f, &s->pwm.faddr);
       
   482     qemu_get_buffer(f, s->pwm.addr, sizeof(s->pwm.addr));
       
   483     qemu_get_timer(f, s->pwm.tm[0]);
       
   484     qemu_get_timer(f, s->pwm.tm[1]);
       
   485     qemu_get_timer(f, s->pwm.tm[2]);
       
   486 
       
   487     lm_kbd_irq_update(s);
       
   488     lm_kbd_gpio_update(s);
       
   489 
       
   490     return 0;
       
   491 }
       
   492 
       
   493 struct i2c_slave *lm8323_init(i2c_bus *bus, qemu_irq nirq)
       
   494 {
       
   495     struct lm_kbd_s *s;
       
   496 
       
   497     s = (struct lm_kbd_s *) i2c_slave_init(bus, 0, sizeof(struct lm_kbd_s));
       
   498     s->model = 0x8323;
       
   499     s->pwm.tm[0] = qemu_new_timer(vm_clock, lm_kbd_pwm0_tick, s);
       
   500     s->pwm.tm[1] = qemu_new_timer(vm_clock, lm_kbd_pwm1_tick, s);
       
   501     s->pwm.tm[2] = qemu_new_timer(vm_clock, lm_kbd_pwm2_tick, s);
       
   502     s->nirq = nirq;
       
   503 
       
   504     s->i2c.event = lm_i2c_event;
       
   505     s->i2c.recv = lm_i2c_rx;
       
   506     s->i2c.send = lm_i2c_tx;
       
   507 
       
   508     lm_kbd_reset(s);
       
   509 
       
   510     qemu_register_reset((void *) lm_kbd_reset, s);
       
   511     register_savevm("LM8323", -1, 0, lm_kbd_save, lm_kbd_load, s);
       
   512 
       
   513     return &s->i2c;
       
   514 }
       
   515 
       
   516 void lm832x_key_event(struct i2c_slave *i2c, int key, int state)
       
   517 {
       
   518     struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
       
   519 
       
   520     if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
       
   521         return;
       
   522 
       
   523     if (s->kbd.len >= sizeof(s->kbd.fifo))
       
   524         return lm_kbd_error(s, ERR_FIFOOVR);
       
   525 
       
   526     s->kbd.fifo[(s->kbd.start + s->kbd.len ++) & (sizeof(s->kbd.fifo) - 1)] =
       
   527             key | (state << 7);
       
   528 
       
   529     /* We never set ERR_KEYOVR because we support multiple keys fine.  */
       
   530     s->status |= INT_KEYPAD;
       
   531     lm_kbd_irq_update(s);
       
   532 }