Linux Device Driver to on/off keyboard LED

Theory:

Keyboard controller has three 8-bit registers:

  • Control Register (0x64)
  • Data Register (0x60)
  • Status Register (0x64)
If the CPU Reads from the port 0x64, the byte is interpreted as Status byte, if CPU writes to the port, the byte is interpreted as Command Port.

Procedure to set the keyboard leds
  • Wait until the keyboard controller until it is not busy
  • Send the command byte 0xED
  • Send the byte corresponding to which LED you want to ON/OFF
    • Bit 0 is scroll lock
    • Bit 1 is num lock
    • Bit 2 is caps lock

Code

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
#define KBD_DATA_REG 0x60 /* I/O port for keyboard data */
#define KBD_CONTROL_REG 0x64
#define KBD_SCANCODE_MASK 0x7f
#define KBD_STATUS_MASK 0x80
#define DELAY do { mdelay(1); if (++delay > 10) break; } while(0)
static void set_kbd_led_on(void)
{
long delay = 0;
//wait till the input buffer is empty
while (inb(KBD_CONTROL_REG) & 0x02)
DELAY;
outb(0xED, KBD_DATA_REG);
DELAY;
while (inb(KBD_CONTROL_REG) & 0x02)
DELAY;
outb(0x07, KBD_DATA_REG);
DELAY;
}
static void set_kbd_led_off(void)
{
long delay = 0;
//wait till the input buffer is empty
while (inb(KBD_CONTROL_REG) & 0x02)
DELAY;
outb(0xED, KBD_DATA_REG);
DELAY;
while (inb(KBD_CONTROL_REG) & 0x02)
DELAY;
outb(0x00, KBD_DATA_REG);
DELAY;
}
static int test_kbd_led_init(void)
{
pr_info("%s: In init\n", __func__);
set_kbd_led_on();
return 0;
}
static void test_kbd_led_exit(void)
{
pr_info("%s: In exit\n", __func__);
set_kbd_led_off();
}
module_init(test_kbd_led_init);
module_exit(test_kbd_led_exit);
view raw kbd_led.c hosted with ❤ by GitHub

Comments

Popular posts from this blog

bb.utils.contains yocto

Difference between RDEPENDS and DEPENDS in Yocto

PR, PN and PV Variable in Yocto