34 #include <asm/types.h>
39 #include "../../lms2012/source/lms2012.h"
40 #include "../../lms2012/source/am1808.h"
43 #define MODULE_NAME "ui_module"
44 #define DEVICE1_NAME UI_DEVICE
46 static int ModuleInit(
void);
47 static void ModuleExit(
void);
49 #include <linux/kernel.h>
52 #include <linux/sched.h>
56 #include <linux/hrtimer.h>
58 #include <linux/init.h>
59 #include <linux/uaccess.h>
60 #include <linux/debugfs.h>
62 #include <linux/ioport.h>
65 #include <linux/module.h>
66 #include <linux/miscdevice.h>
67 #include <asm/uaccess.h>
115 #define NO_OF_LEDS LEDS
116 #define NO_OF_BUTTONS BUTTONS
188 [
FINAL] = FINAL_UiLedPin,
189 [
FINALB] = FINALB_UiLedPin,
190 [
EP2] = EP2_UiLedPin,
196 [
FINAL] = FINAL_UiButPin,
197 [
FINALB] = FINALB_UiButPin,
198 [
EP2] = EP2_UiButPin,
205 static void __iomem *GpioBase;
226 printk(
" GP%d_%-2d 0x%08X and 0x%08X or 0x%08X\n",(Pin >> 4),(Pin & 0x0F),(
u32)Reg,
MuxRegMap[Tmp].Mask,
MuxRegMap[Tmp].Mode);
232 printk(
"* GP%d_%-2d ********* ERROR not found *********\n",(Pin >> 4),(Pin & 0x0F));
246 printk(
" Ui leds\n");
248 memcpy(UiLedPin,pUiLedPin[
Hw],
sizeof(EP2_UiLedPin));
249 if (memcmp((
const void*)UiLedPin,(
const void*)pUiLedPin[Hw],
sizeof(EP2_UiLedPin)) != 0)
256 if (UiLedPin[Pin].Pin >= 0)
258 UiLedPin[Pin].
pGpio = (
struct gpio_controller *__iomem)(GpioBase + ((UiLedPin[Pin].Pin >> 5) * 0x28) + 0x10);
259 UiLedPin[Pin].
Mask = (1 << (UiLedPin[Pin].
Pin & 0x1F));
266 printk(
" Ui buttons\n");
268 memcpy(UiButPin,pUiButPin[Hw],
sizeof(EP2_UiButPin));
269 if (memcmp((
const void*)UiButPin,(
const void*)pUiButPin[Hw],
sizeof(EP2_UiButPin)) != 0)
276 if (UiButPin[Pin].Pin >= 0)
278 UiButPin[Pin].
pGpio = (
struct gpio_controller *__iomem)(GpioBase + ((UiButPin[Pin].Pin >> 5) * 0x28) + 0x10);
279 UiButPin[Pin].
Mask = (1 << (UiButPin[Pin].
Pin & 0x1F));
293 static struct hrtimer Device1Timer;
294 static ktime_t Device1Time;
295 static struct hrtimer Device2Timer;
296 static ktime_t Device2Time;
299 static UI *pUi = &UiDefault;
301 #define BUTFloat(B) {\
302 (*UiButPin[B].pGpio).dir |= UiButPin[B].Mask;\
306 #define BUTRead(B) ((*UiButPin[B].pGpio).in_data & UiButPin[B].Mask)
309 #define DIODEInit(D) {\
310 (*UiLedPin[D].pGpio).clr_data = UiLedPin[D].Mask;\
311 (*UiLedPin[D].pGpio).dir &= ~UiLedPin[D].Mask;\
314 #define DIODEOn(D) {\
315 (*UiLedPin[D].pGpio).set_data = UiLedPin[D].Mask;\
318 #define DIODEOff(D) {\
319 (*UiLedPin[D].pGpio).clr_data = UiLedPin[D].Mask;\
325 { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0b00000000000000000000000000000000, 0b00000000000000000111110000011111, 0b00000000000000000111110000011111, 0b00000000000000000000000000000000, 0b00000000000000000000000001110111, 0b00000000000000000000000001110111 },
326 { 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0b00000000000000000111110000011111, 0b00000000000000000000000000000000, 0b00000000000000000111110000011111, 0b00000000000000000000000001110111, 0b00000000000000000000000000000000, 0b00000000000000000000000001110111 },
327 { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0b00000000000000000000000000000000, 0b00000000000000000111110000011111, 0b00000000000000000111110000011111, 0b00000000000000000000000000000000, 0b00000000000000000000000001110111, 0b00000000000000000000000001110111 },
328 { 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0b00000000000000000111110000011111, 0b00000000000000000000000000000000, 0b00000000000000000111110000011111, 0b00000000000000000000000001110111, 0b00000000000000000000000000000000, 0b00000000000000000000000001110111 },
339 static enum hrtimer_restart Device1TimerInterrupt1(
struct hrtimer *pTimer)
373 hrtimer_forward_now(pTimer,ktime_set(0,50000000));
375 return (HRTIMER_RESTART);
379 static enum hrtimer_restart Device2TimerInterrupt1(
struct hrtimer *pTimer)
388 (*pUi).Pressed[Tmp] = 1;
394 (*pUi).Pressed[Tmp] = 0;
400 hrtimer_forward_now(pTimer,ktime_set(0,10000000));
402 return (HRTIMER_RESTART);
435 static ssize_t Device1Write(
struct file *File,
const char *
Buffer,
size_t Count,loff_t *Data)
445 copy_from_user(Buf,Buffer,2);
447 if ((No >= 0) && (No < LEDPATTERNS))
467 static ssize_t Device1Read(
struct file *File,
char *Buffer,
size_t Count,loff_t *Offset)
471 Lng =
snprintf(Buffer,Count,
"V%c.%c0",HwId[0],HwId[1]);
477 #define SHM_LENGTH (sizeof(UiDefault))
478 #define NPAGES ((SHM_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
479 static void *kmalloc_ptr;
481 static int Device1Mmap(
struct file *filp,
struct vm_area_struct *vma)
485 ret = remap_pfn_range(vma,vma->vm_start,virt_to_phys((
void*)((
unsigned long)pUi)) >> PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
496 static const struct file_operations Device1Entries =
498 .owner = THIS_MODULE,
500 .write = Device1Write,
505 static struct miscdevice Device1 =
512 static int Device1Init(
void)
519 Result = misc_register(&Device1);
527 if ((kmalloc_ptr = kmalloc((
NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) !=
NULL)
529 pTmp = (
UWORD*)((((
unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
530 for (i = 0; i <
NPAGES * PAGE_SIZE; i += PAGE_SIZE)
532 SetPageReserved(virt_to_page(((
unsigned long)pTmp) + i));
535 memset(pUi,0,
sizeof(UI));
547 Device2Time = ktime_set(0,10000000);
548 hrtimer_init(&Device2Timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
549 Device2Timer.function = Device2TimerInterrupt1;
550 hrtimer_start(&Device2Timer,Device2Time,HRTIMER_MODE_REL);
553 Device1Time = ktime_set(0,50000000);
554 hrtimer_init(&Device1Timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
555 Device1Timer.function = Device1TimerInterrupt1;
556 hrtimer_start(&Device1Timer,Device1Time,HRTIMER_MODE_REL);
568 static void Device1Exit(
void)
574 hrtimer_cancel(&Device1Timer);
575 hrtimer_cancel(&Device2Timer);
586 for (i = 0; i <
NPAGES * PAGE_SIZE; i+= PAGE_SIZE)
588 ClearPageReserved(virt_to_page(((
unsigned long)pTmp) + i));
595 misc_deregister(&Device1);
609 static int ModuleInit(
void)
626 if (request_mem_region(DA8XX_GPIO_BASE,0xD8,
MODULE_NAME) >= 0)
628 GpioBase = (
void*)ioremap(DA8XX_GPIO_BASE,0xD8);
629 if (GpioBase !=
NULL)
645 static void ModuleExit(
void)
MODULE_AUTHOR("The LEGO Group")
ULONG TmpPattern[NO_OF_LEDS]
#define EP2
Schematics revision D.
#define FINAL
Final prototype.
ULONG LEDPATTERNDATA[NO_OF_LEDS+1][LEDPATTERNS]
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
ULONG ActPattern[NO_OF_LEDS]
#define FINALB
Schematics revision B and C.
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
module_param(HwId, charp, 0)
MODULE_DESCRIPTION(MODULE_NAME)
#define PLATFORM_END
Newest supported hardware (newer versions will use this)
#define PLATFORM_START
Oldest supported hardware (older versions will use this)