59 #include <asm/types.h>
64 #include "../../lms2012/source/lms2012.h"
65 #include "../../lms2012/source/am1808.h"
67 #ifndef DISABLE_FIQ_IIC
75 #define DEBUG_IIC_WRITE
77 #define DEBUG_TRACE_MODE_CHANGE
82 #define MODULE_NAME "iic_module"
83 #define DEVICE1_NAME IIC_DEVICE
85 static int ModuleInit(
void);
86 static void ModuleExit(
void);
90 #include <linux/kernel.h>
93 #include <linux/sched.h>
97 #include <linux/circ_buf.h>
98 #include <linux/hrtimer.h>
100 #include <linux/mm.h>
101 #include <linux/hrtimer.h>
103 #include <linux/init.h>
104 #include <linux/uaccess.h>
105 #include <linux/debugfs.h>
107 #include <linux/ioport.h>
108 #include <asm/gpio.h>
110 #include <linux/module.h>
111 #include <linux/miscdevice.h>
112 #include <asm/uaccess.h>
127 #define NO_OF_IIC_PORTS INPUTS
130 #ifndef DISABLE_FIQ_IIC
240 #define PUDisable iowrite32(ioread32(da8xx_syscfg1_base + 0x0C) & ~0xFFFFFFFF,da8xx_syscfg1_base + 0x0C)
252 static void __iomem *GpioBase;
275 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);
280 printk(
"* GP%d_%-2d ********* ERROR not found *********\n",(Pin >> 4),(Pin & 0x0F));
294 memcpy(IicPortPin,pIicPortPin[
Hw],
sizeof(EP2_IicPortPin));
298 printk(
"FINALB_IicPortPin = %p\n",FINALB_IicPortPin);
299 printk(
"pIicPortPin[Hw] = %p\n",pIicPortPin[Hw]);
300 printk(
"sizeof(INPIN) = %d\n",
sizeof(
INPIN));
301 printk(
"sizeof(EP2_IicPortPin) = %d\n",
sizeof(EP2_IicPortPin));
305 if (memcmp((
const void*)IicPortPin,(
const void*)pIicPortPin[Hw],
sizeof(EP2_IicPortPin)) != 0)
307 printk(
"%s IicPortPin tabel broken!\n",
MODULE_NAME);
313 printk(
" Iic port %d\n",Port + 1);
319 if (IicPortPin[Port][Pin].Pin >= 0)
321 IicPortPin[Port][Pin].
pGpio = (
struct gpio_controller *__iomem)(GpioBase + ((IicPortPin[Port][Pin].Pin >> 5) * 0x28) + 0x10);
322 IicPortPin[Port][Pin].
Mask = (1 << (IicPortPin[Port][Pin].
Pin & 0x1F));
324 SetGpio(IicPortPin[Port][Pin].Pin);
341 #ifdef DISABLE_FIQ_IIC
342 #define PINFloat(port,pin) {\
343 (*IicPortPin[port][pin].pGpio).dir |= IicPortPin[port][pin].Mask;\
347 #define PINRead(port,pin) ((*IicPortPin[port][pin].pGpio).in_data & IicPortPin[port][pin].Mask)
350 #define PINHigh(port,pin) {\
351 (*IicPortPin[port][pin].pGpio).set_data = IicPortPin[port][pin].Mask;\
352 (*IicPortPin[port][pin].pGpio).dir &= ~IicPortPin[port][pin].Mask;\
355 #define PINLow(port,pin) {\
356 (*IicPortPin[port][pin].pGpio).clr_data = IicPortPin[port][pin].Mask;\
357 (*IicPortPin[port][pin].pGpio).dir &= ~IicPortPin[port][pin].Mask;\
411 #ifdef DEBUG_IIC_WRITE
413 #define IICBUFFERSIZE 250
414 static char IicBuffer[IICBUFFERSIZE];
416 #define LOGPOOLSIZE 100000
417 ULONG LogPointer = 0;
418 ULONG LogOutPointer = 0;
419 char LogPool[LOGPOOLSIZE];
421 void IicWrite(
char *pString)
427 LogPool[LogPointer] = *pString;
431 if (Tmp >= LOGPOOLSIZE)
435 if (Tmp != LogOutPointer)
453 static IIC IicDefault;
454 static IIC *pIic = &IicDefault;
458 #ifndef DISABLE_FIQ_IIC
461 #include <linux/circ_buf.h>
462 #include <linux/delay.h>
471 static void IicPortDisable(
UBYTE Port)
473 #ifndef DISABLE_FIQ_IIC
477 if (Port != DEBUG_UART)
487 static void IicPortEnable(
UBYTE Port)
489 #ifndef DISABLE_FIQ_IIC
512 #ifndef DISABLE_FIQ_IIC
525 static RESULT IicPortSend(
UBYTE Port)
529 #ifndef DISABLE_FIQ_IIC
535 snprintf(IicBuffer,IICBUFFERSIZE,
" %d Send %02X ",Port,IicPort[Port].OutBuffer[0]);
538 for (Tmp = 1;Tmp < IicPort[Port].
OutLength;Tmp++)
541 snprintf(IicBuffer,IICBUFFERSIZE,
"%02X ",IicPort[Port].OutBuffer[Tmp]);
547 snprintf(IicBuffer,IICBUFFERSIZE,
"\r\n");
566 static RESULT IicPortReceive(
UBYTE Port,
UBYTE *pTmpBuffer)
568 RESULT Result = BUSY;
570 #ifndef DISABLE_FIQ_IIC
575 memset((
void*)pTmpBuffer,0,IIC_DATA_LENGTH);
577 snprintf(IicBuffer,IICBUFFERSIZE,
" %d Receiving ",Port);
580 for (Tmp = 0;Tmp < IicPort[Port].
InLength;Tmp++)
589 snprintf(IicBuffer,IICBUFFERSIZE,
"\r\n");
647 "IIC_NXT_TEMP_START",
648 "IIC_NXT_TEMP_WRITE",
650 "MANUFACTURER_START",
651 "MANUFACTURER_WRITE",
673 #define IIC_TIMER_RESOLUTION 20 // [100u]
674 static struct hrtimer Device1Timer;
675 static ktime_t Device1Time;
678 static enum hrtimer_restart Device1TimerInterrupt1(
struct hrtimer *pTimer)
682 UBYTE TmpBuffer[IIC_DATA_LENGTH];
684 hrtimer_forward_now(pTimer,Device1Time);
689 switch (IicPort[Port].State)
695 (*pIic).Status[Port] = 0;
702 memset((
void*)IicStrings[Port].Manufacturer,0,IIC_NAME_LENGTH + 1);
703 memset((
void*)IicStrings[Port].SensorType,0,IIC_NAME_LENGTH + 1);
710 IicPortDisable(Port);
722 IicPort[Port].
Timer = 0;
743 IicPort[Port].
Time = 0;
744 IicPort[Port].
Timer = 0;
753 IicPort[Port].
Timer = 0;
760 if (IicPortReceive(Port,TmpBuffer) != BUSY)
762 if (TmpBuffer[0] == 0x60)
764 memcpy((
void*)IicStrings[Port].Manufacturer,(
void*)
"LEGO",IIC_NAME_LENGTH);
766 memcpy((
void*)IicStrings[Port].SensorType,(
void*)
"Temp.",IIC_NAME_LENGTH);
767 IicStrings[Port].
SensorType[IIC_NAME_LENGTH] = 0;
769 (*pIic).Changed[Port] = 1;
772 IicPort[Port].
Timer = 0;
777 IicPort[Port].
Timer = 0;
783 IicPort[Port].
Timer = 0;
800 IicPort[Port].
Time = 0;
801 IicPort[Port].
Timer = 0;
810 IicPort[Port].
Timer = 0;
817 if (IicPortReceive(Port,TmpBuffer) != BUSY)
819 memcpy((
void*)IicStrings[Port].Manufacturer,(
void*)TmpBuffer,IIC_NAME_LENGTH);
822 if (TmpBuffer[0] == 0x08)
824 if (IicPort[Port].Addr < 0x50)
826 IicPort[Port].
Addr++;
827 IicPort[Port].
Timer = 0;
832 if (--IicPort[Port].Retries > 0)
834 IicPort[Port].
Addr = 0x01;
835 IicPort[Port].
Timer = 0;
847 if (TmpBuffer[0] == 0)
849 memcpy((
void*)IicStrings[Port].Manufacturer,(
void*)
"LEGO",IIC_NAME_LENGTH);
859 printk(
"IIC timeout\n");
860 IicPort[Port].
Addr = 0x01;
877 IicPort[Port].
Time = 0;
878 IicPort[Port].
Timer = 0;
886 IicPort[Port].
Timer = 0;
893 if (IicPortReceive(Port,TmpBuffer) != BUSY)
895 memcpy((
void*)IicStrings[Port].SensorType,(
void*)TmpBuffer,IIC_NAME_LENGTH);
896 IicStrings[Port].
SensorType[IIC_NAME_LENGTH] = 0;
898 if (TmpBuffer[0] == 0)
900 memcpy((
void*)IicStrings[Port].SensorType,(
void*)
"Store",IIC_NAME_LENGTH);
904 (*pIic).Changed[Port] = 1;
907 IicPort[Port].
Timer = 0;
924 IicPort[Port].
Timer = 0;
932 #ifndef DISABLE_FAST_DATALOG_BUFFER
933 (*pIic).Actual[Port] = 0;
934 (*pIic).LogIn[Port] = 0;
937 if (IicStrings[Port].SetupLng)
939 IicPort[Port].
OutBuffer[0] = (
UBYTE)((IicStrings[Port].SetupString >> 24) & 0xFF);
940 IicPort[Port].
OutBuffer[1] = (
UBYTE)((IicStrings[Port].SetupString >> 16) & 0xFF);
941 IicPort[Port].
OutBuffer[2] = (
UBYTE)((IicStrings[Port].SetupString >> 8) & 0xFF);
942 IicPort[Port].
OutBuffer[3] = (
UBYTE)((IicStrings[Port].SetupString) & 0xFF);
946 IicPort[Port].
Time = 0;
953 IicPort[Port].
Timer = 0;
960 IicPort[Port].
Timer = 0;
967 if (IicPortReceive(Port,TmpBuffer) != BUSY)
970 if (IicStrings[Port].PollLng)
972 IicPort[Port].
OutBuffer[0] = (
UBYTE)((IicStrings[Port].PollString >> 24) & 0xFF);
973 IicPort[Port].
OutBuffer[1] = (
UBYTE)((IicStrings[Port].PollString >> 16) & 0xFF);
974 IicPort[Port].
OutBuffer[2] = (
UBYTE)((IicStrings[Port].PollString >> 8) & 0xFF);
975 IicPort[Port].
OutBuffer[3] = (
UBYTE)((IicStrings[Port].PollString) & 0xFF);
977 if (IicStrings[Port].ReadLng < 0)
988 IicPort[Port].
Time = IicStrings[Port].
Time;
989 IicPort[Port].
Timer = 0;
991 (*pIic).Status[Port] = 0;
1008 if (IicPortBusy(Port) == 0)
1010 IicPort[Port].
Timer = 0;
1026 if (IicPortReceive(Port,TmpBuffer) != BUSY)
1029 #ifndef DISABLE_FAST_DATALOG_BUFFER
1030 if (IicPort[Port].InLength > 1)
1032 if (IicPort[Port].Reverse)
1034 for (Tmp = 0;Tmp < IicPort[Port].
InLength;Tmp++)
1036 IicPort[Port].
InBuffer[Tmp] = TmpBuffer[Tmp];
1037 (*pIic).Raw[Port][(*pIic).LogIn[Port]][Tmp] = TmpBuffer[Tmp];
1042 for (Tmp = 0;Tmp < IicPort[Port].
InLength;Tmp++)
1044 IicPort[Port].
InBuffer[Tmp] = TmpBuffer[(IicPort[Port].
InLength - 1) - Tmp];
1045 (*pIic).Raw[Port][(*pIic).LogIn[Port]][Tmp] = TmpBuffer[(IicPort[Port].
InLength - 1) - Tmp];
1051 IicPort[Port].
InBuffer[0] = TmpBuffer[0];
1053 (*pIic).Raw[Port][(*pIic).LogIn[Port]][0] = TmpBuffer[0];
1054 (*pIic).Raw[Port][(*pIic).LogIn[Port]][1] = 0;
1057 (*pIic).Actual[Port] = (*pIic).LogIn[Port];
1058 (*pIic).Repeat[Port][(*pIic).Actual[Port]] = 0;
1060 if (++((*pIic).LogIn[Port]) >= DEVICE_LOGBUF_SIZE)
1062 (*pIic).LogIn[Port] = 0;
1065 if (IicPort[Port].InLength > 1)
1067 if (IicPort[Port].Reverse)
1069 for (Tmp = 0;Tmp < IicPort[Port].
InLength;Tmp++)
1071 IicPort[Port].
InBuffer[Tmp] = TmpBuffer[Tmp];
1072 (*pIic).Raw[Port][Tmp] = TmpBuffer[Tmp];
1077 for (Tmp = 0;Tmp < IicPort[Port].
InLength;Tmp++)
1079 IicPort[Port].
InBuffer[Tmp] = TmpBuffer[(IicPort[Port].
InLength - 1) - Tmp];
1080 (*pIic).Raw[Port][Tmp] = TmpBuffer[(IicPort[Port].
InLength - 1) - Tmp];
1086 IicPort[Port].
InBuffer[0] = TmpBuffer[0];
1088 (*pIic).Raw[Port][0] = TmpBuffer[0];
1089 (*pIic).Raw[Port][1] = 0;
1096 if (IicPort[Port].Repeat != 0)
1099 if (IicPort[Port].Repeat == 0)
1107 (*pIic).Status[Port] &= ~IIC_WRITE_REQUEST;
1116 if ((*pIic).Status[Port] & IIC_WRITE_REQUEST)
1125 IicPort[Port].
Timer = 0;
1134 IicPortDisable(Port);
1137 (*pIic).Status[Port] = 0;
1145 #ifndef DISABLE_FAST_DATALOG_BUFFER
1150 if (IicPort[Port].OldState != IicPort[Port].State)
1155 snprintf(IicBuffer,IICBUFFERSIZE,
" %d %s\r\n",Port,IicStateText[IicPort[Port].State]);
1159 snprintf(IicBuffer,IICBUFFERSIZE,
"*** %d %s ***\r\n",Port,IicStateText[IicPort[Port].State]);
1161 IicWrite(IicBuffer);
1168 return (HRTIMER_RESTART);
1172 static int Device1Ioctl(
struct inode *pNode,
struct file *File,
unsigned int Request,
unsigned long Pointer)
1184 pDevCon = (
DEVCON*)Pointer;
1186 for (Port = 0;Port <
INPUTS;Port++)
1188 if ((*pDevCon).Connection[Port] == CONN_NXT_IIC)
1190 if (IicConfigured[Port] == 0)
1192 #ifdef DEBUG_TRACE_MODE_CHANGE
1195 IicConfigured[Port] = 1;
1196 IicPortType[Port] = (*pDevCon).
Type[Port];
1201 if (IicPort[Port].Initialised)
1203 if (IicPort[Port].Mode != (*pDevCon).
Mode[Port])
1205 #ifdef DEBUG_TRACE_MODE_CHANGE
1208 IicPort[Port].
Mode = (*pDevCon).Mode[Port];
1218 #ifdef DEBUG_TRACE_MODE_CHANGE
1222 if (IicConfigured[Port])
1224 IicConfigured[Port] = 0;
1235 pIicStr = (
IICSTR*)Pointer;
1237 Port = (*pIicStr).
Port;
1239 memcpy((
void*)&IicStrings[Port],(
void*)pIicStr,
sizeof(
IICSTR));
1247 pIicDat = (
IICDAT*)Pointer;
1249 Port = (*pIicDat).
Port;
1250 (*pIicDat).Result = BUSY;
1253 if (!((*pIic).Status[Port] & IIC_WRITE_REQUEST))
1256 IicPort[Port].
Repeat = (*pIicDat).Repeat;
1257 IicPort[Port].
Time = (*pIicDat).Time;
1258 IicPort[Port].
OutLength = (*pIicDat).WrLng;
1259 if ((*pIicDat).RdLng < 0)
1261 IicPort[Port].
InLength = 0 - (*pIicDat).RdLng;
1266 IicPort[Port].
InLength = (*pIicDat).RdLng;
1270 if (IicPort[Port].OutLength > IIC_DATA_LENGTH)
1272 IicPort[Port].
OutLength = IIC_DATA_LENGTH;
1274 if (IicPort[Port].InLength > IIC_DATA_LENGTH)
1276 IicPort[Port].
InLength = IIC_DATA_LENGTH;
1279 memcpy((
void*)&IicPort[Port].OutBuffer[0],(
void*)&(*pIicDat).WrData[0],IicPort[Port].
OutLength);
1280 memset((
void*)&IicPort[Port].InBuffer[0],0,IIC_DATA_LENGTH);
1288 memcpy((
void*)&(*pIicDat).RdData[0],(
void*)&IicPort[Port].
InBuffer[0],IicPort[Port].
InLength);
1290 (*pIicDat).Result = OK;
1291 (*pIic).Status[Port] = 0;
1298 pIicStr = (
IICSTR*)Pointer;
1300 Port = (*pIicStr).
Port;
1301 memcpy((
void*)((*pIicStr).Manufacturer),(
void*)IicStrings[Port].
Manufacturer,IIC_NAME_LENGTH + 1);
1302 memcpy((
void*)((*pIicStr).SensorType),(
void*)IicStrings[Port].
SensorType,IIC_NAME_LENGTH + 1);
1304 (*pIic).Changed[Port] = 0;
1315 static ssize_t Device1Write(
struct file *File,
const char *
Buffer,
size_t Count,loff_t *Data)
1325 static ssize_t Device1Read(
struct file *File,
char *Buffer,
size_t Count,loff_t *Offset)
1329 #ifdef DEBUG_IIC_WRITE
1330 if (LogOutPointer != LogPointer)
1332 while ((Count--) && (LogOutPointer != LogPointer))
1334 Buffer[Lng++] = LogPool[LogOutPointer];
1338 if (LogOutPointer >= LOGPOOLSIZE)
1346 IicWrite(IicBuffer);
1347 snprintf(IicBuffer,IICBUFFERSIZE,
"-----------------------------------------------------------------\r\n");
1348 IicWrite(IicBuffer);
1349 snprintf(IicBuffer,IICBUFFERSIZE,
" IIC DUMP\r\n");
1350 IicWrite(IicBuffer);
1351 snprintf(IicBuffer,IICBUFFERSIZE,
"-----------------------------------------------------------------\r\n");
1352 IicWrite(IicBuffer);
1360 while ((Count > Tmp) && (Port < INPUTS))
1362 if (Port != (INPUTS - 1))
1364 Tmp =
snprintf(&Buffer[Lng],4,
"%2u ",(
UWORD)IicPort[Port].State);
1368 Tmp =
snprintf(&Buffer[Lng],5,
"%2u\r",(
UWORD)IicPort[Port].State);
1380 #define SHM_LENGTH (sizeof(IicDefault))
1381 #define NPAGES ((SHM_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
1382 static void *kmalloc_ptr;
1384 static int Device1Mmap(
struct file *filp,
struct vm_area_struct *vma)
1388 ret = remap_pfn_range(vma,vma->vm_start,virt_to_phys((
void*)((
unsigned long)pIic)) >> PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
1399 static const struct file_operations Device1Entries =
1401 .owner = THIS_MODULE,
1402 .read = Device1Read,
1403 .write = Device1Write,
1404 .mmap = Device1Mmap,
1405 .ioctl = Device1Ioctl,
1409 static struct miscdevice Device1 =
1417 static int Device1Init(
void)
1422 #ifndef DISABLE_FIQ_IIC
1426 Result = misc_register(&Device1);
1434 if ((kmalloc_ptr = kmalloc((
NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) !=
NULL)
1436 pTmp = (
UWORD*)((((
unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
1437 for (i = 0; i <
NPAGES * PAGE_SIZE; i += PAGE_SIZE)
1439 SetPageReserved(virt_to_page(((
unsigned long)pTmp) + i));
1442 memset(pIic,0,
sizeof(IIC));
1444 #ifndef DISABLE_FIQ_IIC
1447 for (Port = 0;Port <
INPUTS;Port++)
1450 IicConfigured[Port] = 0;
1454 if (Port == DEBUG_UART)
1463 hrtimer_init(&Device1Timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
1464 Device1Timer.function = Device1TimerInterrupt1;
1465 hrtimer_start(&Device1Timer,Device1Time,HRTIMER_MODE_REL);
1481 static void Device1Exit(
void)
1486 hrtimer_cancel(&Device1Timer);
1492 for (i = 0; i <
NPAGES * PAGE_SIZE; i+= PAGE_SIZE)
1494 ClearPageReserved(virt_to_page(((
unsigned long)pTmp) + i));
1496 printk(
" %s memory page %d unmapped\n",
DEVICE1_NAME,i);
1501 misc_deregister(&Device1);
1517 static int ModuleInit(
void)
1533 if (request_mem_region(DA8XX_GPIO_BASE,0xD8,
MODULE_NAME) >= 0)
1535 GpioBase = (
void*)ioremap(DA8XX_GPIO_BASE,0xD8);
1536 if (GpioBase !=
NULL)
1552 static void ModuleExit(
void)
signed char SBYTE
Basic Type used to symbolise 8 bit signed values.
struct IIC_data_package data_package[IIC_INPUTS]
#define EP2
Schematics revision D.
#define FINAL
Final prototype.
UBYTE InBuffer[IIC_DATA_LENGTH]
struct IIC_control_t IicCtrl
#define IIC_READ_TYPE_INFO
DATA8 IicPortType[INPUTS]
#define IIC_TIMER_RESOLUTION
UBYTE OutBuffer[IIC_DATA_LENGTH]
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
#define PINInput(port, pin)
INPIN IicPortPin[NO_OF_IIC_PORTS][IIC_PORT_PINS]
void iic_fiq_start_transfer(unsigned int time, bool fiq_nirq)
#define FINALB
Schematics revision B and C.
#define IIC_DATA_READY
Data is ready.
#define IIC_WRITE_REQUEST
Write request.
module_param(HwId, charp, 0)
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
DATA8 SensorType[IIC_NAME_LENGTH+1]
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
#define PINLow(port, pin)
#define PINOutput(port, pin)
DATA8 Manufacturer[IIC_NAME_LENGTH+1]
MODULE_DESCRIPTION(MODULE_NAME)
SBYTE DATA8
VM Type for 1 byte signed value.
#define INPUTS
Number of input ports in the system.
MODULE_AUTHOR("The LEGO Group")
#define PINHigh(port, pin)
#define PLATFORM_END
Newest supported hardware (newer versions will use this)
IICSTR IicStrings[INPUTS]
UBYTE IicConfigured[INPUTS]
char IicStateText[IIC_STATES][50]
#define PLATFORM_START
Oldest supported hardware (older versions will use this)